UNPKG

goodrdotfun-sdk

Version:

SDK for interacting with goodr.fun and Sonic on Solana

177 lines (176 loc) 7.62 kB
"use strict"; 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;