@luckyswaps/sdk
v1.4.1
Published
LuckySwaps integrates tightly with Jupiter and thus uses mostly similar interfaces. If you ever integrated with Jupiter, it should be easy for you to also integrate with Luckyswaps.
Readme
Luckyswaps SDK
LuckySwaps integrates tightly with Jupiter and thus uses mostly similar interfaces. If you ever integrated with Jupiter, it should be easy for you to also integrate with Luckyswaps.
Howto
Integrate with LuckySwaps using the SDK
1. Install required libraries
Running this example requires a minimum of NodeJS 16. In your command line terminal, install the libraries.
npm i @luckyswaps/sdk2. Get a program instance
import { PublicKey, Keypair } from "@solana/web3.js";
import assert from "assert";
import {
getProgram,
swap,
LuckySwapParams,
MAX_THRESHOLD,
} from "@luckyswaps/sdk";
const keyPair = Keypair.generate();
const program = getProgram("https://api.mainnet-beta.solana.com", keyPair);4. Get the route for a swap
Here, we are getting a quote to swap from SOL to USDC.
// Swapping SOL to USDC with input 0.1 SOL and 0.5% slippage
const params: LuckySwapParams = {
// Payer that signs the transactions
payerAccount: new PublicKey(
"G2FJbtHdaBP5qaFTKyBuTGYHqenTFFpmpz2DSD5A5BH7",
),
// input and output mint (will be used for Jupiter swap)
inputMint: new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // USDC
outputMint: new PublicKey("So11111111111111111111111111111111111111112"), // WSOL
// associated token accounts for both mint owned by the user
userSourceAccount: new PublicKey(
"CqMKa8z4WHpcW4pR7vWEAB96nerRPwBYi1ZJJhsP4bNw",
),
userTargetAccount: new PublicKey(
"FBAoSPT2L5qJJPmMJ1w9uo9ExuTXC4SHK4322ESuBpg7",
),
// a reference to our program (e.g. API connection)
program: program,
// The amount to swap (ExactIn)
amount: amount,
// The threshold defines the winning probability and the multiplier
// if you want a 50% win chance (including house-edge, you chose multiplier: 2)
threshold: Math.round(MAX_THRESHOLD / multiplier),
// optional parameters when calling /quote on jupiter
// https://station.jup.ag/api-v6/get-quote
jupiterQuoteParams: {},
// optional parameters when calling /swap-instruction on jupiter
// https://station.jup.ag/api-v6/post-swap-instructions
jupiterSwapParams: {},
};5. Get the serialized transactions to perform the swap
Once we have the quote, we need to serialize the quote into a swap transaction that can be submitted on chain.
// get serialized transactions for the swap
const instructions = await swap(params);The returned instructions are identical to what you would expect when calling
https://quote-api.jup.ag/v6/swap-instructions.
6. Deserialize and sign the transaction
The following is standard Jupiter
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;
// A withdraw instruction that will increase the user input token account amount.
const withdrawInstruction = ...;
// 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) => ({
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) => ({
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))
);
const messageV0 = new TransactionMessage({
payerKey: payerPublicKey,
recentBlockhash: blockhash,
instructions: [tokenLedgerInstruction, withdrawInstruction, swapInstruction],
}).compileToV0Message(addressLookupTableAccounts);
const transaction = new VersionedTransaction(messageV0);