@robertprp/intents-sdk
Version:
Shogun Network Intent-based cross-chain swaps SDK
82 lines • 4.6 kB
JavaScript
import { address, addSignersToTransactionMessage, appendTransactionMessageInstructions, createNoopSigner, createSolanaRpc, createTransactionMessage, fetchEncodedAccount, generateKeyPairSigner, getAddressEncoder, getProgramDerivedAddress, getTransactionCodec, partiallySignTransactionMessageWithSigners, pipe, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, } from '@solana/kit';
import { getDefaultSolanaRPC } from '../client.js';
import { genSecretHashAndNumber } from '../utils.js';
import { NATIVE_SOLANA_TOKEN_ADDRESS, SINGLE_CHAIN_GUARD_ADDRESSES, WRAPPED_SOL_MINT_ADDRESS, } from '../../../constants.js';
import { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, fetchMint, getCreateAssociatedTokenInstructionAsync, getSyncNativeInstruction, } from '@solana-program/token';
import { ChainID } from '../../../chains.js';
import { getTransferSolInstruction } from '@solana-program/system';
import { getCreateDcaOrderInstructionAsync } from '../generated/single-chain/index.js';
export async function getSolanaDcaSingleChainOrderInstructions(order, options) {
const rpc = options?.rpcUrl ? createSolanaRpc(options.rpcUrl) : getDefaultSolanaRPC();
const orderSigner = await generateKeyPairSigner();
const signer = createNoopSigner(order.user);
let tokenInMint = address(order.tokenIn);
const { secretHash, secretNumber } = genSecretHashAndNumber(order);
const orderUserAddress = address(order.user);
const spendingNative = tokenInMint === NATIVE_SOLANA_TOKEN_ADDRESS;
if (spendingNative) {
tokenInMint = WRAPPED_SOL_MINT_ADDRESS;
}
const tokenMintProgram = await fetchMint(rpc, tokenInMint);
const guardAddress = address(SINGLE_CHAIN_GUARD_ADDRESSES[ChainID.Solana]); // Assuming DCA uses same guard
const addressEncoder = getAddressEncoder();
const instructions = [];
const [tokenInProgramAccount] = await getProgramDerivedAddress({
programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
seeds: [
addressEncoder.encode(orderUserAddress),
addressEncoder.encode(tokenMintProgram.programAddress),
addressEncoder.encode(tokenInMint),
],
});
const userTokenInAccount = await fetchEncodedAccount(rpc, tokenInProgramAccount);
if (!userTokenInAccount.exists) {
const createAccountIx = await getCreateAssociatedTokenInstructionAsync({
payer: signer,
ata: tokenInProgramAccount,
owner: orderUserAddress,
mint: tokenMintProgram.address,
tokenProgram: tokenMintProgram.programAddress,
});
instructions.push(createAccountIx);
}
const totalAmountIn = BigInt(order.amountInPerInterval) * BigInt(order.totalIntervals);
if (spendingNative) {
const transferIx = getTransferSolInstruction({
amount: totalAmountIn,
destination: userTokenInAccount.address,
source: signer,
});
instructions.push(transferIx);
const syncNativeIx = getSyncNativeInstruction({
account: userTokenInAccount.address,
});
instructions.push(syncNativeIx);
}
const createDcaOrderIx = await getCreateDcaOrderInstructionAsync({
user: signer,
order: orderSigner,
guard: guardAddress,
tokenInMint: tokenInMint,
userTokenInAccount: userTokenInAccount.address,
tokenInProgram: tokenMintProgram.programAddress,
amountInPerInterval: order.amountInPerInterval,
totalIntervals: order.totalIntervals,
intervalDuration: order.intervalDuration,
deadline: order.deadline,
amountOutMin: order.amountOutMin,
secretHash: Uint8Array.from(secretHash),
extraTransfersAmounts: [], // TODO: Implement extra transfers
});
instructions.push(createDcaOrderIx);
const { value: latestBlockhash } = await rpc.getLatestBlockhash({ commitment: 'confirmed' }).send();
const txMessage = pipe(createTransactionMessage({ version: 0 }), (tx) => setTransactionMessageFeePayerSigner(signer, tx), (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) => appendTransactionMessageInstructions(instructions, tx), (tx) => addSignersToTransactionMessage([orderSigner], tx));
const partiallySignedTransaction = await partiallySignTransactionMessageWithSigners(txMessage);
const txBytes = getTransactionCodec().encode(partiallySignedTransaction);
return {
orderAddress: orderSigner.address,
txBytes,
secretNumber,
};
}
//# sourceMappingURL=create-order.js.map