Skip to content

Instantly share code, notes, and snippets.

@coffiasd
Last active April 1, 2024 13:46
Show Gist options
  • Save coffiasd/2efb9ec4cea42eaa6700b020db26e736 to your computer and use it in GitHub Desktop.
Save coffiasd/2efb9ec4cea42eaa6700b020db26e736 to your computer and use it in GitHub Desktop.
jup swap demo code
require('dotenv').config();
import {
Connection,
VersionedTransaction,
Keypair,
PublicKey,
TransactionInstruction,
AddressLookupTableAccount,
TransactionMessage
} from '@solana/web3.js';
import * as Fs from 'fs';
import { AES, enc } from 'crypto-js';
//===================config====================//
const RPC_URL = process.env.RPC_URL || '';
const basePath = process.env.basePath as string;
const authKeypairPath = process.env.AUTH || '';
const pk = 'xxxxx';
const keypair = Keypair.fromSecretKey(decodedKey);
const connection = new Connection(RPC_URL, 'confirmed');
export async function main() {
const quoteResponse = await (
await fetch('https://quote-api.jup.ag/v6/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=50000000&slippageBps=100&onlyDirectRoutes=true')).json();
console.log(quoteResponse);
const instructionsResponse = await fetch('https://quote-api.jup.ag/v6/swap-instructions', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
quoteResponse,
useTokenLedger: true,
userPublicKey: keypair.publicKey.toBase58(),
wrapAndUnwrapSol: false,
})
});
// console.log(await instructions.json());
const instructions = (await instructionsResponse.json());
//check error:
if (instructions.error) {
throw new Error("Failed to get swap instructions: " + instructions.error);
}
const {
tokenLedgerInstruction: tokenLedgerPayload, // If you are using `useTokenLedger = true`.
swapInstruction: swapInstructionPayload, // The actual swap instruction.
addressLookupTableAddresses, // The lookup table addresses that you can use if you are using versioned transaction.
} = instructions;
console.log("tokenLedgerInstruction:", tokenLedgerPayload);
console.log("swapInstructionPayload:", swapInstructionPayload);
// Coupled with the tokenLedgerInstruction, the swap instruction will use the
// user increased amount of the input token account after the withdrawal as input amount.
const tokenLedgerInstruction = new TransactionInstruction({
programId: new PublicKey(tokenLedgerPayload.programId),
keys: tokenLedgerPayload.accounts.map((key:any) => ({
pubkey: new PublicKey(key.pubkey),
isSigner: key.isSigner,
isWritable: key.isWritable,
})),
data: Buffer.from(tokenLedgerPayload.data, "base64"),
});
const swapInstruction = new TransactionInstruction({
programId: new PublicKey(swapInstructionPayload.programId),
keys: swapInstructionPayload.accounts.map((key:any) => ({
pubkey: new PublicKey(key.pubkey),
isSigner: key.isSigner,
isWritable: key.isWritable,
})),
data: Buffer.from(swapInstructionPayload.data, "base64"),
});
const getAdressLookupTableAccounts = async (
keys: string[]
): Promise<AddressLookupTableAccount[]> => {
const addressLookupTableAccountInfos =
await 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>());
};
const addressLookupTableAccounts: AddressLookupTableAccount[] = [];
addressLookupTableAccounts.push(
...(await getAdressLookupTableAccounts(addressLookupTableAddresses))
);
let resp = await connection.getLatestBlockhash('processed');
const messageV0 = new TransactionMessage({
payerKey: keypair.publicKey,
recentBlockhash: resp.blockhash,
instructions: [tokenLedgerInstruction, swapInstruction],
}).compileToV0Message(addressLookupTableAccounts);
const transaction = new VersionedTransaction(messageV0);
//sign the transaction....
transaction.sign([keypair]);
// We first simulate whether the transaction would be successful
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 });
}
// Execute the transaction
// const rawTransaction = transaction.serialize()
// const txid = await connection.sendRawTransaction(rawTransaction, {
// skipPreflight: true,
// maxRetries: 1
// });
// await connection.confirmTransaction(txid);
// console.log(`https://solscan.io/tx/${txid}`);
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment