Skip to content

Instantly share code, notes, and snippets.

@nshen
Created February 9, 2025 03:42
Show Gist options
  • Save nshen/d88b4354aa9328eca49059a606e27f43 to your computer and use it in GitHub Desktop.
Save nshen/d88b4354aa9328eca49059a606e27f43 to your computer and use it in GitHub Desktop.
sell.ts
/*
接口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