@raydium-io/raydium-sdk-v2
Version:
An SDK for building applications on top of Raydium.
1,015 lines (959 loc) • 46.6 kB
text/typescript
import { PublicKey, SystemProgram, TransactionInstruction } from "@solana/web3.js";
import BN from "bn.js";
import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token";
import {
InstructionType,
LIQUIDITY_POOL_PROGRAM_ID_V5_MODEL,
MEMO_PROGRAM_ID2,
accountMeta,
jsonInfo2PoolKeys,
getATAAddress,
ALL_PROGRAM_ID,
} from "@/common";
import { seq, struct, u128, u64, u8 } from "../../marshmallow";
import {
ClmmInstrument,
MAX_SQRT_PRICE_X64,
MAX_SQRT_PRICE_X64_SUB_ONE,
MIN_SQRT_PRICE_X64,
MIN_SQRT_PRICE_X64_ADD_ONE,
ONE,
getPdaExBitmapAccount,
} from "../clmm";
import { makeAMMSwapInstruction, makeAMMSwapV2Instruction } from "../liquidity/instruction";
import { AmmV4Keys, AmmV5Keys, ApiV3PoolInfoItem, ClmmKeys, CpmmKeys, PoolKeys } from "../../api/type";
import { makeSwapCpmmBaseInInstruction } from "../../raydium/cpmm";
import { ComputePoolType, MakeSwapInstructionParam, ReturnTypeMakeSwapInstruction } from "./type";
export function route1Instruction(
programId: PublicKey,
poolInfoA: ApiV3PoolInfoItem,
poolKeyA: PoolKeys,
poolKeyB: PoolKeys,
userSourceToken: PublicKey,
userRouteToken: PublicKey,
// userDestinationToken: PublicKey,
userPdaAccount: PublicKey,
ownerWallet: PublicKey,
inputMint: PublicKey,
amountIn: BN,
amountOut: BN,
tickArrayA?: PublicKey[],
// tickArrayB?: PublicKey[],
): TransactionInstruction {
const dataLayout = struct([u8("instruction"), u64("amountIn"), u64("amountOut")]);
const keys: { pubkey: PublicKey; isSigner: boolean; isWritable: boolean }[] = [
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: new PublicKey(poolKeyA.programId), isSigner: false, isWritable: false },
{ pubkey: new PublicKey(poolKeyA.id), isSigner: false, isWritable: true },
{ pubkey: new PublicKey(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 (poolInfoA.type === "Concentrated") {
const poolKey = jsonInfo2PoolKeys(poolKeyA as ClmmKeys);
keys.push(
...[
{ pubkey: poolKey.config.id, isSigner: false, isWritable: false },
{ pubkey: poolKey.id, isSigner: false, isWritable: true },
{
pubkey: poolKey.mintA.address.equals(inputMint) ? poolKey.vault.A : poolKey.vault.B,
isSigner: false,
isWritable: true,
},
{
pubkey: poolKey.mintA.address.equals(inputMint) ? poolKey.vault.B : poolKey.vault.A,
isSigner: false,
isWritable: true,
},
// { pubkey: poolKey.observationId, isSigner: false, isWritable: true }, // to do
{ pubkey: poolKey.id, isSigner: false, isWritable: true },
...tickArrayA!.map((i) => ({ pubkey: i, isSigner: false, isWritable: true })),
],
);
} else if (poolInfoA.pooltype.includes("StablePool")) {
const poolKey = jsonInfo2PoolKeys(poolKeyA as AmmV5Keys);
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.vault.A, isSigner: false, isWritable: true },
{ pubkey: poolKey.vault.B, 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 {
const poolKey = jsonInfo2PoolKeys(poolKeyA as AmmV4Keys);
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.vault.A, isSigner: false, isWritable: true },
{ pubkey: poolKey.vault.B, 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,
poolInfoB: ApiV3PoolInfoItem,
poolKeyA: PoolKeys,
poolKeyB: PoolKeys,
// userSourceToken: PublicKey,
userRouteToken: PublicKey,
userDestinationToken: PublicKey,
userPdaAccount: PublicKey,
ownerWallet: PublicKey,
routeMint: PublicKey,
// tickArrayA?: PublicKey[],
tickArrayB?: PublicKey[],
): TransactionInstruction {
const dataLayout = struct([u8("instruction")]);
const keys: { pubkey: PublicKey; isSigner: boolean; isWritable: boolean }[] = [
{ pubkey: SystemProgram.programId, 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 (poolInfoB.type === "Concentrated") {
const poolKey = jsonInfo2PoolKeys(poolKeyB as ClmmKeys);
keys.push(
...[
{ pubkey: poolKey.config.id, isSigner: false, isWritable: false },
{ pubkey: poolKey.id, isSigner: false, isWritable: true },
{
pubkey: poolKey.mintA.address.equals(routeMint) ? poolKey.vault.A : poolKey.vault.B,
isSigner: false,
isWritable: true,
},
{
pubkey: poolKey.mintA.address.equals(routeMint) ? poolKey.vault.B : poolKey.vault.A,
isSigner: false,
isWritable: true,
},
// { pubkey: poolKey.observationId, isSigner: false, isWritable: true }, // to do
{ pubkey: poolKey.id, isSigner: false, isWritable: true },
...tickArrayB!.map((i) => ({ pubkey: i, isSigner: false, isWritable: true })),
],
);
} else if (poolInfoB.pooltype.includes("StablePool")) {
const poolKey = jsonInfo2PoolKeys(poolKeyB as AmmV5Keys);
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.vault.A, isSigner: false, isWritable: true },
{ pubkey: poolKey.vault.B, 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 {
const poolKey = jsonInfo2PoolKeys(poolKeyB as AmmV4Keys);
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.vault.A, isSigner: false, isWritable: true },
{ pubkey: poolKey.vault.B, 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,
});
}
/*
function makeInnerInsKey(
itemPool: ComputePoolType,
itemPoolKey: PoolKeys,
inMint: string,
userInAccount: PublicKey,
userOutAccount: PublicKey,
remainingAccount: PublicKey[] | undefined,
): accountMeta[] {
if (itemPool.version === 4) {
const poolKey = jsonInfo2PoolKeys(itemPoolKey as AmmV4Keys);
return [
{ pubkey: poolKey.programId, isSigner: false, isWritable: false },
{ pubkey: userInAccount, isSigner: false, isWritable: true },
{ pubkey: userOutAccount, isSigner: false, isWritable: true },
{ pubkey: poolKey.id, isSigner: false, isWritable: true },
{ pubkey: poolKey.authority, isSigner: false, isWritable: false },
{ pubkey: poolKey.marketProgramId, isSigner: false, isWritable: false },
{ pubkey: poolKey.marketAuthority, isSigner: false, isWritable: true },
{ pubkey: poolKey.openOrders, isSigner: false, isWritable: true },
{ pubkey: poolKey.vault.A, isSigner: false, isWritable: true },
{ pubkey: poolKey.vault.B, 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 },
]),
];
} else if (itemPool.version === 5) {
const poolKey = jsonInfo2PoolKeys(itemPoolKey as AmmV4Keys);
return [
{ pubkey: poolKey.programId, isSigner: false, isWritable: false },
{ pubkey: userInAccount, isSigner: false, isWritable: true },
{ pubkey: userOutAccount, isSigner: false, isWritable: true },
{ pubkey: poolKey.id, isSigner: false, isWritable: true },
{ 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.vault.A, isSigner: false, isWritable: true },
{ pubkey: poolKey.vault.B, 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 (itemPool.version === 6) {
const pool = itemPool;
const poolKey = jsonInfo2PoolKeys(itemPoolKey as ClmmKeys);
const baseIn = pool.mintA.address === inMint;
return [
{ pubkey: new PublicKey(String(itemPool.programId)), isSigner: false, isWritable: false },
{ pubkey: userInAccount, isSigner: false, isWritable: true },
{ pubkey: userOutAccount, isSigner: false, isWritable: true },
{ pubkey: poolKey.config.id, isSigner: false, isWritable: false },
{ pubkey: poolKey.id, isSigner: false, isWritable: true },
{ pubkey: baseIn ? poolKey.vault.A : poolKey.vault.B, isSigner: false, isWritable: true },
{ pubkey: baseIn ? poolKey.vault.B : poolKey.vault.A, isSigner: false, isWritable: true },
{ pubkey: itemPool.observationId, isSigner: false, isWritable: true },
...(poolKey.mintA.programId.equals(TOKEN_2022_PROGRAM_ID) || poolKey.mintB.programId.equals(TOKEN_2022_PROGRAM_ID)
? [
{ pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: MEMO_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: baseIn ? poolKey.mintA.address : poolKey.mintB.address, isSigner: false, isWritable: false },
{ pubkey: baseIn ? poolKey.mintB.address : poolKey.mintA.address, isSigner: false, isWritable: false },
]
: []),
...(remainingAccount ?? []).map((i) => ({ pubkey: i, isSigner: false, isWritable: true })),
{
pubkey: getPdaExBitmapAccount(new PublicKey(String(itemPool.programId)), new PublicKey(itemPool.id)).publicKey,
isSigner: false,
isWritable: true,
},
];
} else if (itemPool.version === 7) {
const pool = itemPool;
const poolKey = jsonInfo2PoolKeys(itemPoolKey as CpmmKeys);
const baseIn = pool.mintA.address === inMint;
return [
{ pubkey: new PublicKey(String(itemPool.programId)), isSigner: false, isWritable: false },
{ pubkey: userInAccount, isSigner: false, isWritable: true },
{ pubkey: userOutAccount, isSigner: false, isWritable: true },
{ pubkey: poolKey.config.id, isSigner: false, isWritable: false },
{ pubkey: poolKey.id, isSigner: false, isWritable: true },
{ pubkey: baseIn ? poolKey.vault.A : poolKey.vault.B, isSigner: false, isWritable: true },
{ pubkey: baseIn ? poolKey.vault.B : poolKey.vault.A, isSigner: false, isWritable: true },
{ pubkey: itemPool.observationId, isSigner: false, isWritable: true },
...(poolKey.mintA.programId.equals(TOKEN_2022_PROGRAM_ID) || poolKey.mintB.programId.equals(TOKEN_2022_PROGRAM_ID)
? [
{ pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: MEMO_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: baseIn ? poolKey.mintA.address : poolKey.mintB.address, isSigner: false, isWritable: false },
{ pubkey: baseIn ? poolKey.mintB.address : poolKey.mintA.address, isSigner: false, isWritable: false },
]
: []),
...(remainingAccount ?? []).map((i) => ({ pubkey: i, isSigner: false, isWritable: true })),
{
pubkey: getPdaExBitmapAccount(new PublicKey(String(itemPool.programId)), new PublicKey(itemPool.id)).publicKey,
isSigner: false,
isWritable: true,
},
];
} else {
throw Error("make swap ins error");
}
}
*/
export function routeInstruction(
programId: PublicKey,
wallet: PublicKey,
userSourceToken: PublicKey,
userRouteToken: PublicKey,
userDestinationToken: PublicKey,
inputMint: string,
routeMint: string,
outputMint: string,
poolInfoA: ComputePoolType,
poolInfoB: ComputePoolType,
poolKeyA: PoolKeys,
poolKeyB: PoolKeys,
amountIn: BN,
amountOut: BN,
remainingAccounts: (PublicKey[] | undefined)[],
): TransactionInstruction {
const clmmPriceLimit: BN[] = [];
const keys = [
accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),
accountMeta({ pubkey: TOKEN_2022_PROGRAM_ID, isWritable: false }),
accountMeta({ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isWritable: false }),
accountMeta({ pubkey: SystemProgram.programId, isWritable: false }),
accountMeta({ pubkey: wallet, isSigner: true }),
];
keys.push(accountMeta({ pubkey: userSourceToken }));
keys.push(accountMeta({ pubkey: userDestinationToken }));
const poolInfos = [poolInfoA, poolInfoB];
const poolKeys = [poolKeyA, poolKeyB];
const routeMints = [inputMint, routeMint, outputMint];
for (let index = 0; index < poolInfos.length; index++) {
const _poolInfo = poolInfos[index];
const inputIsA = routeMints[index] === _poolInfo.mintA.address;
keys.push(accountMeta({ pubkey: new PublicKey(_poolInfo.programId), isWritable: false }));
if (index === poolInfos.length - 1) {
keys.push(accountMeta({ pubkey: userDestinationToken }));
} else {
keys.push(accountMeta({ pubkey: userRouteToken }));
}
keys.push(accountMeta({ pubkey: new PublicKey(routeMints[index]) }));
keys.push(accountMeta({ pubkey: new PublicKey(routeMints[index + 1]) }));
if (_poolInfo.version === 6) {
const _poolKey = poolKeys[index] as ClmmKeys;
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.config.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? _poolKey.vault.A : _poolKey.vault.B) }));
keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? _poolKey.vault.B : _poolKey.vault.A) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolInfo.observationId) })); //todo
keys.push(accountMeta({ pubkey: MEMO_PROGRAM_ID2 }));
keys.push(
accountMeta({
pubkey: getPdaExBitmapAccount(new PublicKey(_poolInfo.programId), new PublicKey(_poolInfo.id)).publicKey,
}),
);
clmmPriceLimit.push(clmmPriceLimitX64InsData(_poolInfo.sqrtPriceX64.toString(), inputIsA));
for (const item of remainingAccounts[index] ?? []) {
keys.push(accountMeta({ pubkey: new PublicKey(item) }));
}
} else if (_poolInfo.version === 5) {
const _poolKey = poolKeys[index] as AmmV5Keys;
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.authority), isWritable: false }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketProgramId) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketAuthority) }));
keys.push(accountMeta({ pubkey: LIQUIDITY_POOL_PROGRAM_ID_V5_MODEL, isWritable: false }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.openOrders) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.vault.A) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.vault.B) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketId) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketBids) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketAsks) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketEventQueue) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketBaseVault) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketQuoteVault) }));
} else if (_poolInfo.version === 4) {
const _poolKey = poolKeys[index] as AmmV4Keys;
const isSupportIdOnly = _poolInfo.status !== 1;
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.authority), isWritable: false }));
keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketProgramId) }));
keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketAuthority) }));
keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.openOrders) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.vault.A) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.vault.B) }));
keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketId) }));
keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketBids) }));
keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketAsks) }));
keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketEventQueue) }));
keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketBaseVault) }));
keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketQuoteVault) }));
} else if (_poolInfo.version === 7) {
const _poolKey = poolKeys[index] as CpmmKeys;
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.authority) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.config.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? _poolKey.vault.A : _poolKey.vault.B) }));
keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? _poolKey.vault.B : _poolKey.vault.A) }));
keys.push(accountMeta({ pubkey: new PublicKey(_poolInfo.observationId) }));
} else throw Error("pool type error");
}
const dataLayout = struct([
u8("insId"),
u64("amountIn"),
u64("amountOut"),
seq(u128(), clmmPriceLimit.length, "clmmPriceLimit"),
]);
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
insId: 0,
amountIn,
amountOut,
clmmPriceLimit,
},
data,
);
return new TransactionInstruction({
keys,
programId,
data,
});
}
function clmmPriceLimitX64InsData(x64Price: string | undefined, inputIsA: boolean): BN {
if (x64Price) {
if (inputIsA) {
const _m = new BN(x64Price).div(new BN(25));
return _m.gt(MIN_SQRT_PRICE_X64_ADD_ONE) ? _m : MIN_SQRT_PRICE_X64_ADD_ONE;
} else {
const _m = new BN(x64Price).mul(new BN(25));
return _m.lt(MAX_SQRT_PRICE_X64_SUB_ONE) ? _m : MAX_SQRT_PRICE_X64_SUB_ONE;
}
} else {
return inputIsA ? MIN_SQRT_PRICE_X64_ADD_ONE : MAX_SQRT_PRICE_X64_SUB_ONE;
}
}
export function makeSwapInstruction({
routeProgram,
ownerInfo,
inputMint,
swapInfo,
}: MakeSwapInstructionParam): ReturnTypeMakeSwapInstruction {
if (swapInfo.routeType === "amm") {
if (swapInfo.poolInfo[0].version === 6) {
const poolKeys = swapInfo.poolKey[0] as ClmmKeys;
const _poolKey = jsonInfo2PoolKeys(poolKeys);
const sqrtPriceLimitX64 = inputMint.equals(_poolKey.mintA.address)
? MIN_SQRT_PRICE_X64.add(ONE)
: MAX_SQRT_PRICE_X64.sub(ONE);
return ClmmInstrument.makeSwapBaseInInstructions({
poolInfo: poolKeys,
poolKeys,
observationId: swapInfo.poolInfo[0].observationId,
ownerInfo: {
wallet: ownerInfo.wallet,
tokenAccountA: _poolKey.mintA.address.equals(inputMint) ? ownerInfo.sourceToken : ownerInfo.destinationToken,
tokenAccountB: _poolKey.mintA.address.equals(inputMint) ? ownerInfo.destinationToken : ownerInfo.sourceToken,
},
inputMint,
amountIn: swapInfo.amountIn.amount.raw,
amountOutMin: swapInfo.minAmountOut.amount.raw.sub(swapInfo.minAmountOut.fee?.raw ?? new BN(0)),
sqrtPriceLimitX64,
remainingAccounts: swapInfo.remainingAccounts[0] ?? [],
});
} else if (swapInfo.poolInfo[0].version === 7) {
const poolInfo = swapInfo.poolInfo[0];
const baseIn = inputMint.toString() === swapInfo.poolInfo[0].mintA.address;
return {
signers: [],
instructions: [
makeSwapCpmmBaseInInstruction(
poolInfo.programId,
ownerInfo.wallet,
poolInfo.authority,
poolInfo.configId,
poolInfo.id,
ownerInfo.sourceToken!,
ownerInfo.destinationToken!,
baseIn ? poolInfo.vaultA : poolInfo.vaultB,
baseIn ? poolInfo.vaultB : poolInfo.vaultA,
baseIn ? poolInfo.mintProgramA : poolInfo.mintProgramB,
baseIn ? poolInfo.mintProgramB : poolInfo.mintProgramA,
new PublicKey(poolInfo[baseIn ? "mintA" : "mintB"].address),
new PublicKey(poolInfo[baseIn ? "mintB" : "mintA"].address),
poolInfo.observationId,
swapInfo.amountIn.amount.raw,
swapInfo.minAmountOut.amount.raw,
),
],
lookupTableAddress: [],
instructionTypes: [baseIn ? InstructionType.CpmmSwapBaseIn : InstructionType.CpmmSwapBaseOut],
address: {},
};
} else {
const _poolKey = swapInfo.poolKey[0] as AmmV4Keys | AmmV5Keys;
return {
signers: [],
instructions: [
swapInfo.poolInfo[0].pooltype.includes("StablePool")
? makeAMMSwapInstruction({
poolKeys: _poolKey,
version: swapInfo.poolInfo[0].pooltype.includes("StablePool") ? 5 : 4,
userKeys: {
tokenAccountIn: ownerInfo.sourceToken,
tokenAccountOut: ownerInfo.destinationToken,
owner: ownerInfo.wallet,
},
amountIn: swapInfo.amountIn.amount.raw,
amountOut: swapInfo.minAmountOut.amount.raw.sub(swapInfo.minAmountOut.fee?.raw ?? new BN(0)),
fixedSide: "in",
})
: makeAMMSwapV2Instruction({
poolKeys: _poolKey,
version: swapInfo.poolInfo[0].pooltype.includes("StablePool") ? 5 : 4,
userKeys: {
tokenAccountIn: ownerInfo.sourceToken,
tokenAccountOut: ownerInfo.destinationToken,
owner: ownerInfo.wallet,
},
amountIn: swapInfo.amountIn.amount.raw,
amountOut: swapInfo.minAmountOut.amount.raw.sub(swapInfo.minAmountOut.fee?.raw ?? new BN(0)),
fixedSide: "in",
}),
],
lookupTableAddress: _poolKey.lookupTableAccount ? [_poolKey.lookupTableAccount] : [],
instructionTypes: [
swapInfo.poolInfo[0].pooltype.includes("StablePool")
? InstructionType.AmmV5SwapBaseIn
: InstructionType.AmmV4SwapBaseIn,
],
address: {},
};
}
} else if (swapInfo.routeType === "route") {
const poolInfo1 = swapInfo.poolInfo[0];
const poolInfo2 = swapInfo.poolInfo[1];
const poolKey1 = swapInfo.poolKey[0];
const poolKey2 = swapInfo.poolKey[1];
if (ownerInfo.routeToken === undefined) throw Error("owner route token account check error");
return {
signers: [],
instructions: [
routeInstruction(
routeProgram,
ownerInfo.wallet,
ownerInfo.sourceToken,
ownerInfo.routeToken,
ownerInfo.destinationToken,
inputMint.toString(),
swapInfo.middleToken.mint.toString(),
swapInfo.outputMint.toString(),
poolInfo1,
poolInfo2,
poolKey1,
poolKey2,
swapInfo.amountIn.amount.raw,
swapInfo.minAmountOut.amount.raw.sub(swapInfo.minAmountOut.fee?.raw ?? new BN(0)),
swapInfo.remainingAccounts,
),
],
instructionTypes: [InstructionType.RouteSwap],
lookupTableAddress: [poolKey1.lookupTableAccount, poolKey2.lookupTableAccount].filter(
(a) => a !== undefined,
) as string[],
address: {},
};
} else {
throw Error("route type error");
}
}
export interface ApiSwapV1Out {
id: string;
success: boolean;
version: "V0" | "V1";
openTime?: undefined;
msg: undefined;
data: {
swapType: "BaseIn" | "BaseOut";
inputMint: string;
inputAmount: string;
outputMint: string;
outputAmount: string;
otherAmountThreshold: string;
slippageBps: number;
priceImpactPct: number;
routePlan: {
poolId: string;
inputMint: string;
outputMint: string;
feeMint: string;
feeRate: number;
feeAmount: string;
remainingAccounts?: string[];
lastPoolPriceX64?: string;
}[];
};
}
export function swapBaseInAutoAccount({
programId,
wallet,
amount,
inputAccount,
outputAccount,
routeInfo,
poolKeys,
}: {
programId: PublicKey;
wallet: PublicKey;
amount: BN;
inputAccount: PublicKey;
outputAccount: PublicKey;
routeInfo: ApiSwapV1Out;
poolKeys: PoolKeys[];
}): TransactionInstruction {
if (routeInfo.success === false) throw Error("route info error");
const clmmPriceLimit: BN[] = [];
const keys = [
accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),
accountMeta({ pubkey: TOKEN_2022_PROGRAM_ID, isWritable: false }),
accountMeta({ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isWritable: false }),
accountMeta({ pubkey: SystemProgram.programId, isWritable: false }),
accountMeta({ pubkey: wallet, isSigner: true }),
];
const cacheAccount: { [mint: string]: PublicKey } = {
[routeInfo.data.inputMint]: inputAccount,
[routeInfo.data.outputMint]: outputAccount,
};
keys.push(accountMeta({ pubkey: cacheAccount[routeInfo.data.inputMint] }));
keys.push(accountMeta({ pubkey: cacheAccount[routeInfo.data.outputMint] }));
for (let index = 0; index < poolKeys.length; index++) {
const _routeInfo = routeInfo.data.routePlan[index];
const _poolKey = poolKeys[index];
const inputIsA = _routeInfo.inputMint === _poolKey.mintA.address;
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.programId), isWritable: false }));
if (index === poolKeys.length - 1) {
keys.push(accountMeta({ pubkey: cacheAccount[_routeInfo.outputMint] }));
} else {
const mint = _routeInfo.outputMint;
if (cacheAccount[mint] === undefined) {
const ata = getATAAddress(
wallet,
new PublicKey(mint),
_poolKey.programId === ALL_PROGRAM_ID.CLMM_PROGRAM_ID.toBase58() ||
_poolKey.programId === ALL_PROGRAM_ID.CREATE_CPMM_POOL_PROGRAM.toBase58()
? new PublicKey(inputIsA ? _poolKey.mintB.programId : _poolKey.mintA.programId)
: TOKEN_PROGRAM_ID,
).publicKey;
cacheAccount[mint] = ata;
}
keys.push(accountMeta({ pubkey: cacheAccount[mint] }));
}
keys.push(accountMeta({ pubkey: new PublicKey(_routeInfo.inputMint) }));
keys.push(accountMeta({ pubkey: new PublicKey(_routeInfo.outputMint) }));
if (_poolKey.programId === ALL_PROGRAM_ID.CLMM_PROGRAM_ID.toBase58()) {
const poolKey = _poolKey as ClmmKeys;
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.config.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolKey.vault.A : poolKey.vault.B) }));
keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolKey.vault.B : poolKey.vault.A) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.observationId) }));
keys.push(accountMeta({ pubkey: MEMO_PROGRAM_ID2, isWritable: false }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.exBitmapAccount) }));
clmmPriceLimit.push(clmmPriceLimitX64InsData(_routeInfo.lastPoolPriceX64, inputIsA));
for (const item of _routeInfo.remainingAccounts ?? []) {
keys.push(accountMeta({ pubkey: new PublicKey(item) }));
}
} else if (_poolKey.programId === ALL_PROGRAM_ID.AMM_STABLE.toBase58()) {
const poolKey = _poolKey as AmmV5Keys;
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.authority), isWritable: false }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketProgramId), isWritable: false }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketAuthority), isWritable: false }));
keys.push(accountMeta({ pubkey: LIQUIDITY_POOL_PROGRAM_ID_V5_MODEL, isWritable: false }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.openOrders) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.A) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.B) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketId) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketBids) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketAsks) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketEventQueue) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketBaseVault) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketQuoteVault) }));
} else if (_poolKey.programId === ALL_PROGRAM_ID.AMM_V4.toBase58()) {
const poolKey = _poolKey as AmmV4Keys;
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.authority), isWritable: false }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.A) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.B) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketProgramId), isWritable: false }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketAuthority), isWritable: false }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.openOrder) }))
// keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.A) }))
// keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.B) }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketId) }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.bids) }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.asks) }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.eventQueue) }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketVaultA) }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketVaultB) }))
} else if (_poolKey.programId === ALL_PROGRAM_ID.CREATE_CPMM_POOL_PROGRAM.toBase58()) {
const poolKey = _poolKey as CpmmKeys;
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.authority) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.config.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolKey.vault.A : poolKey.vault.B) }));
keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolKey.vault.B : poolKey.vault.A) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.observationId) }));
} else throw Error("pool type error");
}
const dataLayout = struct([
u8("insId"),
u64("amountIn"),
u64("amountOut"),
seq(u128(), clmmPriceLimit.length, "clmmPriceLimit"),
]);
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
insId: 0,
amountIn: amount,
amountOut: new BN(routeInfo.data.otherAmountThreshold),
clmmPriceLimit,
},
data,
);
return new TransactionInstruction({
keys,
programId,
data,
});
}
export function swapBaseOutAutoAccount({
programId,
wallet,
inputAccount,
outputAccount,
routeInfo,
poolKeys,
}: {
programId: PublicKey;
wallet: PublicKey;
inputAccount: PublicKey;
outputAccount: PublicKey;
routeInfo: ApiSwapV1Out;
poolKeys: PoolKeys[];
}): TransactionInstruction {
if (routeInfo.success === false) throw Error("route info error");
const clmmPriceLimit: BN[] = [];
const keys = [
accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),
accountMeta({ pubkey: TOKEN_2022_PROGRAM_ID, isWritable: false }),
accountMeta({ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isWritable: false }),
accountMeta({ pubkey: SystemProgram.programId, isWritable: false }),
accountMeta({ pubkey: wallet, isSigner: true }),
];
const cacheAccount: { [mint: string]: PublicKey } = {
[routeInfo.data.inputMint]: inputAccount,
[routeInfo.data.outputMint]: outputAccount,
};
for (let index = poolKeys.length - 1; index >= 0; index--) {
const _routeInfo = routeInfo.data.routePlan[index];
const _poolKey = poolKeys[index];
const inputIsA = _routeInfo.inputMint === _poolKey.mintA.address;
keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.programId) }));
if (index === 0) {
keys.push(accountMeta({ pubkey: cacheAccount[_routeInfo.inputMint] }));
} else {
const mint = _routeInfo.inputMint;
if (cacheAccount[mint] === undefined) {
const ata = getATAAddress(
wallet,
new PublicKey(mint),
_poolKey.programId === ALL_PROGRAM_ID.CLMM_PROGRAM_ID.toBase58() ||
_poolKey.programId === ALL_PROGRAM_ID.CREATE_CPMM_POOL_PROGRAM.toBase58()
? new PublicKey(inputIsA ? _poolKey.mintA.programId : _poolKey.mintB.programId)
: TOKEN_PROGRAM_ID,
).publicKey;
cacheAccount[mint] = ata;
}
keys.push(accountMeta({ pubkey: cacheAccount[mint] }));
}
if (index === poolKeys.length - 1) {
keys.push(accountMeta({ pubkey: cacheAccount[_routeInfo.outputMint] }));
} else {
const mint = _routeInfo.outputMint;
if (cacheAccount[mint] === undefined) {
const ata = getATAAddress(
wallet,
new PublicKey(mint),
_poolKey.programId === ALL_PROGRAM_ID.CLMM_PROGRAM_ID.toBase58() ||
_poolKey.programId === ALL_PROGRAM_ID.CREATE_CPMM_POOL_PROGRAM.toBase58()
? new PublicKey(inputIsA ? _poolKey.mintB.programId : _poolKey.mintA.programId)
: TOKEN_PROGRAM_ID,
).publicKey;
cacheAccount[mint] = ata;
}
keys.push(accountMeta({ pubkey: cacheAccount[mint] }));
}
keys.push(accountMeta({ pubkey: new PublicKey(_routeInfo.inputMint) }));
keys.push(accountMeta({ pubkey: new PublicKey(_routeInfo.outputMint) }));
if (_poolKey.programId === ALL_PROGRAM_ID.CLMM_PROGRAM_ID.toBase58()) {
const poolKey = _poolKey as ClmmKeys;
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.config.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolKey.vault.A : poolKey.vault.B) }));
keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolKey.vault.B : poolKey.vault.A) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.observationId) }));
keys.push(accountMeta({ pubkey: MEMO_PROGRAM_ID2, isWritable: false }));
keys.push(accountMeta({ pubkey: new PublicKey(poolKey.exBitmapAccount) }));
clmmPriceLimit.push(clmmPriceLimitX64InsData(_routeInfo.lastPoolPriceX64, inputIsA));
for (const item of _routeInfo.remainingAccounts ?? []) {
keys.push(accountMeta({ pubkey: new PublicKey(item) }));
}
} else if (_poolKey.programId === ALL_PROGRAM_ID.AMM_STABLE.toBase58()) {
const poolkey = _poolKey as AmmV5Keys;
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.authority), isWritable: false }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketProgramId), isWritable: false }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketAuthority), isWritable: false }));
keys.push(accountMeta({ pubkey: LIQUIDITY_POOL_PROGRAM_ID_V5_MODEL, isWritable: false }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.openOrders) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.vault.A) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.vault.B) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketId) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketBids) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketAsks) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketEventQueue) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketBaseVault) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketQuoteVault) }));
} else if (_poolKey.programId === ALL_PROGRAM_ID.AMM_V4.toBase58()) {
const poolkey = _poolKey as AmmV4Keys;
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.authority), isWritable: false }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.vault.A) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.vault.B) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketProgramId), isWritable: false }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketAuthority), isWritable: false }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.openOrder) }))
// keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.A) }))
// keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.B) }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketId) }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.bids) }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.asks) }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.eventQueue) }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketVaultA) }))
// keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketVaultB) }))
} else if (_poolKey.programId === ALL_PROGRAM_ID.CREATE_CPMM_POOL_PROGRAM.toBase58()) {
const poolkey = _poolKey as CpmmKeys;
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.authority) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.config.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));
keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolkey.vault.A : poolkey.vault.B) }));
keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolkey.vault.B : poolkey.vault.A) }));
keys.push(accountMeta({ pubkey: new PublicKey(poolkey.observationId) }));
} else throw Error("pool type error");
}
const dataLayout = struct([
u8("insId"),
u64("amountIn"),
u64("amountOut"),
seq(u128(), clmmPriceLimit.length, "clmmPriceLimit"),
]);
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
insId: 1,
amountIn: new BN(routeInfo.data.otherAmountThreshold),
amountOut: new BN(routeInfo.data.outputAmount),
clmmPriceLimit,
},
data,
);
return new TransactionInstruction({
keys,
programId,
data,
});
}