import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import BN from "bn.js"; import { AmmV3PoolInfo } from "../ammV3"; import { jsonInfo2PoolKeys, SYSTEM_PROGRAM_ID } from "../common"; import { LiquidityPoolKeysV4 } from "../liquidity"; import { struct, u64, u8 } from "../marshmallow"; import { PoolType } from "./trade"; export function route1Instruction( programId: PublicKey, poolKeyA: PoolType, poolKeyB: PoolType, userSourceToken: PublicKey, userRouteToken: PublicKey, // userDestinationToken: PublicKey, userPdaAccount: PublicKey, ownerWallet: PublicKey, inputMint: PublicKey, amountIn: BN, amountOut: BN, tickArrayA?: PublicKey[], // tickArrayB?: PublicKey[], ) { const dataLayout = struct([ u8("instruction"), u64("amountIn"), u64("amountOut"), ]); const keys: { pubkey: PublicKey, isSigner: boolean, isWritable: boolean }[] = [ { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: new PublicKey(String(poolKeyA.programId)), isSigner: false, isWritable: false }, { pubkey: new PublicKey(String(poolKeyA.id)), isSigner: false, isWritable: true }, { pubkey: new PublicKey(String(poolKeyB.id)), isSigner: false, isWritable: true }, { pubkey: userSourceToken, isSigner: false, isWritable: true }, { pubkey: userRouteToken, isSigner: false, isWritable: true }, { pubkey: userPdaAccount, isSigner: false, isWritable: true }, { pubkey: ownerWallet, isSigner: true, isWritable: false }, ]; if (poolKeyA.version === 6) { const poolKey = poolKeyA as AmmV3PoolInfo keys.push(...[ { pubkey: poolKey.ammConfig.id, isSigner: false, isWritable: false }, { pubkey: poolKey.id, isSigner: false, isWritable: true }, { pubkey: poolKey.mintA.mint.equals(inputMint) ? poolKey.mintA.vault : poolKey.mintB.vault, isSigner: false, isWritable: true }, { pubkey: poolKey.mintA.mint.equals(inputMint) ? poolKey.mintB.vault : poolKey.mintA.vault, isSigner: false, isWritable: true }, { pubkey: poolKey.observationId, isSigner: false, isWritable: true }, ...tickArrayA!.map(i => ({ pubkey: i, isSigner: false, isWritable: true })) ]) } else if (poolKeyA.version === 5) { const poolKey = jsonInfo2PoolKeys(poolKeyA) as LiquidityPoolKeysV4 keys.push(...[ { pubkey: poolKey.authority, isSigner: false, isWritable: false }, { pubkey: poolKey.marketProgramId, isSigner: false, isWritable: false }, { pubkey: poolKey.id, isSigner: false, isWritable: true }, { pubkey: new PublicKey('CDSr3ssLcRB6XYPJwAfFt18MZvEZp4LjHcvzBVZ45duo'), isSigner: false, isWritable: false }, { pubkey: poolKey.openOrders, isSigner: false, isWritable: true }, { pubkey: poolKey.baseVault, isSigner: false, isWritable: true }, { pubkey: poolKey.quoteVault, isSigner: false, isWritable: true }, { pubkey: poolKey.marketId, isSigner: false, isWritable: true }, { pubkey: poolKey.marketBids, isSigner: false, isWritable: true }, { pubkey: poolKey.marketAsks, isSigner: false, isWritable: true }, { pubkey: poolKey.marketEventQueue, isSigner: false, isWritable: true }, { pubkey: poolKey.id, isSigner: false, isWritable: true }, { pubkey: poolKey.id, isSigner: false, isWritable: true }, ]) } else if (poolKeyA.version === 4) { const poolKey = jsonInfo2PoolKeys(poolKeyA) as LiquidityPoolKeysV4 keys.push(...[ { pubkey: poolKey.authority, isSigner: false, isWritable: false }, { pubkey: poolKey.marketProgramId, isSigner: false, isWritable: false }, { pubkey: poolKey.marketAuthority, isSigner: false, isWritable: false }, { pubkey: poolKey.openOrders, isSigner: false, isWritable: true }, { pubkey: poolKey.baseVault, isSigner: false, isWritable: true }, { pubkey: poolKey.quoteVault, isSigner: false, isWritable: true }, { pubkey: poolKey.marketId, isSigner: false, isWritable: true }, { pubkey: poolKey.marketBids, isSigner: false, isWritable: true }, { pubkey: poolKey.marketAsks, isSigner: false, isWritable: true }, { pubkey: poolKey.marketEventQueue, isSigner: false, isWritable: true }, ...(poolKey.marketProgramId.toString() === 'srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX' ? [ { pubkey: poolKey.marketBaseVault, isSigner: false, isWritable: true }, { pubkey: poolKey.marketQuoteVault, isSigner: false, isWritable: true }, ] : [ { pubkey: poolKey.id, isSigner: false, isWritable: true }, { pubkey: poolKey.id, isSigner: false, isWritable: true }, ]) ]) } const data = Buffer.alloc(dataLayout.span); dataLayout.encode( { instruction: 4, amountIn, amountOut, }, data ); return new TransactionInstruction({ keys, programId, data, }); } export function route2Instruction( programId: PublicKey, poolKeyA: PoolType, poolKeyB: PoolType, // userSourceToken: PublicKey, userRouteToken: PublicKey, userDestinationToken: PublicKey, userPdaAccount: PublicKey, ownerWallet: PublicKey, routeMint: PublicKey, // tickArrayA?: PublicKey[], tickArrayB?: PublicKey[], ) { const dataLayout = struct([ u8("instruction"), ]); const keys: { pubkey: PublicKey, isSigner: boolean, isWritable: boolean }[] = [ { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: new PublicKey(String(poolKeyB.programId)), isSigner: false, isWritable: false }, { pubkey: new PublicKey(String(poolKeyB.id)), isSigner: false, isWritable: true }, { pubkey: new PublicKey(String(poolKeyA.id)), isSigner: false, isWritable: true }, { pubkey: userRouteToken, isSigner: false, isWritable: true }, { pubkey: userDestinationToken, isSigner: false, isWritable: true }, { pubkey: userPdaAccount, isSigner: false, isWritable: true }, { pubkey: ownerWallet, isSigner: true, isWritable: false }, ]; if (poolKeyB.version === 6) { const poolKey = poolKeyB as AmmV3PoolInfo keys.push(...[ { pubkey: poolKey.ammConfig.id, isSigner: false, isWritable: false }, { pubkey: poolKey.id, isSigner: false, isWritable: true }, { pubkey: poolKey.mintA.mint.equals(routeMint) ? poolKey.mintA.vault : poolKey.mintB.vault, isSigner: false, isWritable: true }, { pubkey: poolKey.mintA.mint.equals(routeMint) ? poolKey.mintB.vault : poolKey.mintA.vault, isSigner: false, isWritable: true }, { pubkey: poolKey.observationId, isSigner: false, isWritable: true }, ...tickArrayB!.map(i => ({ pubkey: i, isSigner: false, isWritable: true })) ]) } else if (poolKeyB.version === 5) { const poolKey = jsonInfo2PoolKeys(poolKeyB) as LiquidityPoolKeysV4 keys.push(...[ { pubkey: poolKey.authority, isSigner: false, isWritable: false }, { pubkey: poolKey.marketProgramId, isSigner: false, isWritable: false }, { pubkey: poolKey.id, isSigner: false, isWritable: true }, { pubkey: new PublicKey('CDSr3ssLcRB6XYPJwAfFt18MZvEZp4LjHcvzBVZ45duo'), isSigner: false, isWritable: false }, { pubkey: poolKey.openOrders, isSigner: false, isWritable: true }, { pubkey: poolKey.baseVault, isSigner: false, isWritable: true }, { pubkey: poolKey.quoteVault, isSigner: false, isWritable: true }, { pubkey: poolKey.marketId, isSigner: false, isWritable: true }, { pubkey: poolKey.marketBids, isSigner: false, isWritable: true }, { pubkey: poolKey.marketAsks, isSigner: false, isWritable: true }, { pubkey: poolKey.marketEventQueue, isSigner: false, isWritable: true }, { pubkey: poolKey.id, isSigner: false, isWritable: true }, { pubkey: poolKey.id, isSigner: false, isWritable: true }, ]) } else if (poolKeyB.version === 4) { const poolKey = jsonInfo2PoolKeys(poolKeyB) as LiquidityPoolKeysV4 keys.push(...[ { pubkey: poolKey.authority, isSigner: false, isWritable: false }, { pubkey: poolKey.marketProgramId, isSigner: false, isWritable: false }, { pubkey: poolKey.marketAuthority, isSigner: false, isWritable: false }, { pubkey: poolKey.openOrders, isSigner: false, isWritable: true }, { pubkey: poolKey.baseVault, isSigner: false, isWritable: true }, { pubkey: poolKey.quoteVault, isSigner: false, isWritable: true }, { pubkey: poolKey.marketId, isSigner: false, isWritable: true }, { pubkey: poolKey.marketBids, isSigner: false, isWritable: true }, { pubkey: poolKey.marketAsks, isSigner: false, isWritable: true }, { pubkey: poolKey.marketEventQueue, isSigner: false, isWritable: true }, ...(poolKey.marketProgramId.toString() === 'srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX' ? [ { pubkey: poolKey.marketBaseVault, isSigner: false, isWritable: true }, { pubkey: poolKey.marketQuoteVault, isSigner: false, isWritable: true }, ] : [ { pubkey: poolKey.id, isSigner: false, isWritable: true }, { pubkey: poolKey.id, isSigner: false, isWritable: true }, ]) ]) } const data = Buffer.alloc(dataLayout.span); dataLayout.encode( { instruction: 5, }, data ); return new TransactionInstruction({ keys, programId, data, }); }