Skip to content

Instantly share code, notes, and snippets.

@NotoriousPyro
Created March 15, 2024 21:31
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save NotoriousPyro/ff0f9a3596984cbfca596aca552661ad to your computer and use it in GitHub Desktop.
Save NotoriousPyro/ff0f9a3596984cbfca596aca552661ad to your computer and use it in GitHub Desktop.
ConnectionManager Solana class for SexBot
import {
Instruction,
SwapInstructionsResponse
} from "@jup-ag/api";
import {
AddressLookupTableAccount,
ComputeBudgetProgram,
Connection,
Keypair,
PublicKey,
TransactionInstruction,
TransactionMessage,
VersionedTransaction
} from "@solana/web3.js";
import BlockContextInfoManager from "./blockcontextinfo";
class ConnectionManager {
private blockAndContextInfo: BlockContextInfoManager;
constructor(
private keyPair: Keypair,
private connection: Connection,
) {
this.keyPair = keyPair;
this.connection = connection;
this.blockAndContextInfo = new BlockContextInfoManager(connection);
this.blockAndContextInfo.run();
}
private signAndSend = async (
tx: VersionedTransaction
) => {
tx.sign([this.keyPair]);
return await this.connection.sendTransaction(tx, { minContextSlot: this.blockAndContextInfo.minContextSlot, skipPreflight: true, maxRetries: 3 });
};
public sendTransactionInstructions = async (
swapinstructions: {
instructions: TransactionInstruction[],
addressLookupTableAccounts: AddressLookupTableAccount[],
}[],
) => {
const [txs] = await this.prepareVersionedTransactions(swapinstructions);
return await this.signAndSend(txs);
};
public prepareVersionedTransactions = async (
swapInstructions: {
instructions: TransactionInstruction[],
addressLookupTableAccounts: AddressLookupTableAccount[],
}[]
) => await Promise.all(
swapInstructions.map(async (swapInstructions) => {
const { instructions, addressLookupTableAccounts } = swapInstructions;
const messageV0 = new TransactionMessage({
payerKey: this.keyPair.publicKey,
recentBlockhash: this.blockAndContextInfo.blockHash,
instructions: instructions,
}).compileToV0Message(addressLookupTableAccounts);
return new VersionedTransaction(messageV0);
})
);
private getAddressLookupTableAccounts = async (keys: string[]): Promise<AddressLookupTableAccount[]> => {
const addressLookupTableAccountInfos =
await this.connection.getMultipleAccountsInfo(
keys.map((key) => new PublicKey(key))
);
return addressLookupTableAccountInfos.reduce((acc, accountInfo, index) => {
const addressLookupTableAddress = keys[index];
if (accountInfo) {
const addressLookupTableAccount = new AddressLookupTableAccount({
key: new PublicKey(addressLookupTableAddress),
state: AddressLookupTableAccount.deserialize(accountInfo.data),
});
acc.push(addressLookupTableAccount);
}
return acc;
}, new Array<AddressLookupTableAccount>());
};
private deserializeInstruction = (instruction: Instruction) =>
new TransactionInstruction({
programId: new PublicKey(instruction.programId),
keys: instruction.accounts.map((key: { pubkey: any; isSigner: any; isWritable: any; }) => ({
pubkey: new PublicKey(key.pubkey),
isSigner: key.isSigner,
isWritable: key.isWritable,
})),
data: Buffer.from(instruction.data, "base64"),
});
private createTokenLedgerInstruction = (tokenLedgerInstruction: Instruction) =>
new TransactionInstruction({
programId: new PublicKey(tokenLedgerInstruction.programId),
keys: tokenLedgerInstruction?.accounts.map((key) => ({
pubkey: new PublicKey(key.pubkey),
isSigner: key.isSigner,
isWritable: key.isWritable,
})),
data: Buffer.from(tokenLedgerInstruction.data, "base64"),
});
public createComputeBudgetInstruction = async () => {
return [
ComputeBudgetProgram.setComputeUnitLimit({
units: 1400000 // compute units
}),
ComputeBudgetProgram.setComputeUnitPrice({
microLamports: 1 // priority fee
})
];
}
public prepareSwapInstruction = async (swap: SwapInstructionsResponse): Promise<{
instructions: TransactionInstruction[],
addressLookupTableAccounts: AddressLookupTableAccount[],
}> => {
const instructions = [];
if (swap.tokenLedgerInstruction) {
instructions.push(this.createTokenLedgerInstruction(swap.tokenLedgerInstruction));
}
instructions.push(
...await this.createComputeBudgetInstruction(),
//swap.computeBudgetInstructions.map(this.deserializeInstruction)
//...swapB.computeBudgetInstructions.map(this.deserializeInstruction),
...swap.setupInstructions.map(this.deserializeInstruction),
)
instructions.push(this.deserializeInstruction(swap.swapInstruction));
if (swap.cleanupInstruction) {
instructions.push(this.deserializeInstruction(swap.cleanupInstruction));
}
return {
instructions,
addressLookupTableAccounts: [
...(await this.getAddressLookupTableAccounts(
[...swap.addressLookupTableAddresses]
)),
],
};
};
}
export default ConnectionManager;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment