goodrdotfun-sdk
Version:
SDK for interacting with goodr.fun and Sonic on Solana
177 lines (176 loc) • 7.62 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getBalanceChange = exports.getTxDetails = exports.buildVersionedTx = exports.calculateWithSlippageSell = exports.calculateWithSlippageBuy = void 0;
exports.generateVanityAddress = generateVanityAddress;
exports.mintTokenTo = mintTokenTo;
exports.wrappedSOLInstruction = wrappedSOLInstruction;
exports.getOrCreateTokenAccountTx = getOrCreateTokenAccountTx;
exports.isToken2022Mint = isToken2022Mint;
exports.sendTx = sendTx;
const spl_token_1 = require("@solana/spl-token");
const web3_js_1 = require("@solana/web3.js");
const bs58_1 = __importDefault(require("bs58"));
const constant_1 = require("../constant");
/**
* Generates a Solana vanity address that ends with "pump".
* @returns {Keypair} The generated Keypair.
*/
async function generateVanityAddress() {
let keypair;
let publicKey;
let attempts = 0;
console.log("Searching for a vanity address ending with 'pump'...");
do {
keypair = web3_js_1.Keypair.generate();
publicKey = keypair.publicKey;
attempts++;
if (attempts % 1000 === 0) {
console.log(`Attempts: ${attempts}, Last: ${publicKey.toBase58()}`);
}
} while (!publicKey.toBase58().startsWith('Poly'));
console.log(`Found matching address after ${attempts} attempts!`);
console.log(`Public Key: ${publicKey.toBase58()}`);
console.log(`Secret Key (Base58): ${bs58_1.default.encode(keypair.secretKey)}`);
return keypair;
}
async function mintTokenTo(connection, tokenMint, mintAuthority, payer, to, amount) {
const userTokenAccount = await (0, spl_token_1.getOrCreateAssociatedTokenAccount)(connection, payer, tokenMint, to, true);
const mintInfo = await (0, spl_token_1.getMint)(connection, tokenMint);
const txhash = await (0, spl_token_1.mintTo)(connection, payer, tokenMint, userTokenAccount.address, mintAuthority, amount * 10 ** mintInfo.decimals);
return txhash;
}
async function wrappedSOLInstruction(connection, recipient, amount) {
const { tokenAccount: ata, tx: tx } = await getOrCreateTokenAccountTx(connection, spl_token_1.NATIVE_MINT, // mint
recipient, // owner
recipient);
if (!tx) {
throw new Error('Transaction not found');
}
tx.add(web3_js_1.SystemProgram.transfer({
fromPubkey: recipient,
toPubkey: ata,
lamports: amount,
}), (0, spl_token_1.createSyncNativeInstruction)(ata));
return tx;
}
async function getOrCreateTokenAccountTx(connection, mint, payer, owner) {
const programId = (await isToken2022Mint(connection, mint))
? spl_token_1.TOKEN_2022_PROGRAM_ID
: spl_token_1.TOKEN_PROGRAM_ID;
const tokenAccount = await (0, spl_token_1.getAssociatedTokenAddress)(mint, owner, true, programId);
try {
await (0, spl_token_1.getAccount)(connection, tokenAccount, 'confirmed', programId);
return { tokenAccount: tokenAccount, tx: null };
}
catch (error) {
const transaction = new web3_js_1.Transaction();
transaction.add((0, spl_token_1.createAssociatedTokenAccountInstruction)(payer, tokenAccount, owner, mint, programId, spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID));
return { tokenAccount: tokenAccount, tx: transaction };
}
}
async function isToken2022Mint(connection, mint) {
const accountInfo = await connection.getAccountInfo(mint);
if (accountInfo?.owner.toString() == spl_token_1.TOKEN_2022_PROGRAM_ID.toString()) {
return true;
}
return false;
}
const calculateWithSlippageBuy = (amount, basisPoints) => {
return amount.plus(amount.multipliedBy(basisPoints).dividedBy(10000));
};
exports.calculateWithSlippageBuy = calculateWithSlippageBuy;
const calculateWithSlippageSell = (amount, basisPoints) => {
return amount.minus(amount.multipliedBy(basisPoints).dividedBy(10000));
};
exports.calculateWithSlippageSell = calculateWithSlippageSell;
async function sendTx(connection, tx, payer, signers, priorityFees, commitment = constant_1.DEFAULT_COMMITMENT, finality = constant_1.DEFAULT_FINALITY) {
const newTx = new web3_js_1.Transaction();
if (priorityFees) {
const modifyComputeUnits = web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
units: priorityFees.unitLimit,
});
const addPriorityFee = web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
microLamports: priorityFees.unitPrice,
});
newTx.add(modifyComputeUnits);
newTx.add(addPriorityFee);
}
newTx.add(tx);
const versionedTx = await (0, exports.buildVersionedTx)(connection, payer, newTx, commitment);
versionedTx.sign(signers);
try {
const sig = await connection.sendTransaction(versionedTx, {
skipPreflight: false,
});
const txResult = await (0, exports.getTxDetails)(connection, sig, commitment, finality);
if (!txResult) {
return {
success: false,
error: 'Transaction failed',
};
}
return {
success: true,
signature: sig,
results: txResult,
};
}
catch (e) {
if (e instanceof web3_js_1.SendTransactionError) {
const ste = e;
console.log('SendTransactionError' + (await ste.getLogs(connection)));
}
else {
console.error(e);
}
return {
error: e,
success: false,
};
}
}
const buildVersionedTx = async (connection, payer, tx, commitment = constant_1.DEFAULT_COMMITMENT) => {
const blockHash = (await connection.getLatestBlockhash(commitment)).blockhash;
const messageV0 = new web3_js_1.TransactionMessage({
payerKey: payer,
recentBlockhash: blockHash,
instructions: tx.instructions,
}).compileToV0Message();
return new web3_js_1.VersionedTransaction(messageV0);
};
exports.buildVersionedTx = buildVersionedTx;
const getTxDetails = async (connection, sig, commitment = constant_1.DEFAULT_COMMITMENT, finality = constant_1.DEFAULT_FINALITY) => {
const latestBlockHash = await connection.getLatestBlockhash();
await connection.confirmTransaction({
blockhash: latestBlockHash.blockhash,
lastValidBlockHeight: latestBlockHash.lastValidBlockHeight,
signature: sig,
}, commitment);
return connection.getTransaction(sig, {
maxSupportedTransactionVersion: 0,
commitment: finality,
});
};
exports.getTxDetails = getTxDetails;
const getBalanceChange = async (connection, txHash, accountPubkey) => {
const transactionWithMeta = await connection.getParsedTransaction(txHash);
const accountKeys = transactionWithMeta?.transaction.message.accountKeys;
if (!accountKeys) {
throw new Error('Account keys not found');
}
const accountIndex = accountKeys.findIndex(accountKey => accountKey.pubkey.toBase58() === accountPubkey.toBase58());
if (accountIndex === -1) {
throw new Error('Account not found');
}
if (!transactionWithMeta?.meta) {
throw new Error('Transaction meta not found');
}
const preBalance = transactionWithMeta.meta.preBalances[accountIndex];
const postBalance = transactionWithMeta.meta.postBalances[accountIndex];
const balanceChange = postBalance - preBalance;
return { preBalance, postBalance, balanceChange };
};
exports.getBalanceChange = getBalanceChange;