Created
February 9, 2025 03:42
-
-
Save nshen/d88b4354aa9328eca49059a606e27f43 to your computer and use it in GitHub Desktop.
sell.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
接口3: 输入钱包和币地址,卖出比例,立即按照当前价格卖出。 | |
依赖: | |
npm i @jup-ag/api | |
用法: | |
import bs58 from 'bs58'; | |
const privateKey = process.env.PRIVATE_KEY || ''; | |
const keypair = Keypair.fromSecretKey(bs58.decode(privateKey)); | |
try { | |
// 参数:钱包,币mint地址,卖出比例(0 ~ 100) | |
await sell(keypair, '3LXcSxHfESuW6oZ7D1FpjqajsKEACJD6pKJ4xrG7pump', 50) | |
} catch (error) { | |
console.log(error.toString()); | |
} | |
*/ | |
import { createJupiterApiClient } from '@jup-ag/api'; | |
import { Connection, Keypair, PublicKey, VersionedTransaction } from '@solana/web3.js'; | |
export async function sell(wallet: Keypair, mint: string, percent: number) { | |
if (percent <= 0 || percent > 100) | |
throw '卖出比例必须在 0 ~ 100 之间'; | |
try { | |
const connection = new Connection(process.env.HTTP_PROVIDER as string) | |
const tokenAccounts = await connection.getTokenAccountsByOwner( | |
wallet.publicKey, | |
{ mint: new PublicKey(mint) } | |
); | |
if (tokenAccounts.value.length <= 0) | |
throw '代币余额不足'; | |
const tokenAccount = tokenAccounts.value[0]; | |
/* | |
balance: | |
{ | |
context: { apiVersion: '2.2.0', slot: 319334125 }, | |
value: { | |
amount: '2021018696', | |
decimals: 6, | |
uiAmount: 2021.018696, | |
uiAmountString: '2021.018696' | |
} | |
} | |
*/ | |
const balance = await connection.getTokenAccountBalance(tokenAccount.pubkey); | |
const rawAmount = Number(balance.value.amount); | |
// 计算卖出数量 | |
const sellAmount = Math.floor(rawAmount * percent / 100); | |
// 报价 | |
const api = createJupiterApiClient(); | |
const quote = await api.quoteGet({ | |
inputMint: mint, | |
outputMint: 'So11111111111111111111111111111111111111112', // SOL | |
amount: sellAmount, | |
}) | |
if (!quote || quote.routePlan.length <= 0) | |
throw '无法获取报价'; | |
// swap | |
const swapResponse = await api.swapPost({ | |
swapRequest: { | |
quoteResponse: quote, | |
userPublicKey: wallet.publicKey.toBase58(), | |
dynamicComputeUnitLimit: true, | |
dynamicSlippage: { | |
// This will set an optimized slippage to ensure high success rate | |
maxBps: 300, // Make sure to set a reasonable cap here to prevent MEV | |
}, | |
prioritizationFeeLamports: { | |
priorityLevelWithMaxLamports: { | |
maxLamports: 10000000, | |
priorityLevel: "veryHigh", // If you want to land transaction fast, set this to use `veryHigh`. You will pay on average higher priority fee. | |
}, | |
}, | |
correctLastValidBlockHeight: true, | |
}, | |
}); | |
// sign | |
const transactionBase64 = swapResponse.swapTransaction | |
const transaction = VersionedTransaction.deserialize(Buffer.from(transactionBase64, 'base64')); | |
transaction.sign([wallet]); | |
// 模拟交易 | |
// simulatTX(connection, transaction) | |
// return | |
// 发送交易 | |
const transactionBinary = transaction.serialize(); | |
const signature = await connection.sendRawTransaction(transactionBinary, { | |
maxRetries: 2, | |
skipPreflight: true | |
}); | |
console.log(`https://solscan.io/tx/${signature}`); | |
// 等待确认(可以忽略) | |
const confirmation = await connection.confirmTransaction(signature, "finalized"); | |
if (confirmation.value.err) { | |
throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}\nhttps://solscan.io/tx/${signature}/`); | |
} else { | |
console.log(`Transaction successful: https://solscan.io/tx/${signature}/`); | |
} | |
} catch (error) { | |
throw error | |
} | |
} | |
// simulate whether the transaction would be successful | |
async function simulatTX(connection: Connection, transaction: VersionedTransaction) { | |
const { value: simulatedTransactionResponse } = await connection.simulateTransaction( | |
transaction, | |
{ | |
replaceRecentBlockhash: true, | |
commitment: "processed", | |
} | |
); | |
const { err, logs } = simulatedTransactionResponse; | |
if (err) { | |
// Simulation error, we can check the logs for more details | |
// If you are getting an invalid account error, make sure that you have the input mint account to actually swap from. | |
console.error("Simulation Error:"); | |
console.error({ err, logs }); | |
return; | |
} | |
console.log(logs); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment