@raydium-io/raydium-sdk-v2
Version:
An SDK for building applications on top of Raydium.
599 lines (516 loc) • 19.8 kB
text/typescript
import { PublicKey, SystemProgram, TransactionInstruction, AccountMeta } from "@solana/web3.js";
import { ASSOCIATED_TOKEN_PROGRAM_ID } from "@solana/spl-token";
import BN from "bn.js";
import { publicKey, str, struct, u64, u8 } from "@/marshmallow";
import { RENT_PROGRAM_ID, METADATA_PROGRAM_ID } from "@/common";
import { getPdaCpiEvent } from "./pad";
export const anchorDataBuf = {
initialize: Buffer.from([175, 175, 109, 31, 13, 152, 155, 237]),
buyExactIn: Buffer.from([250, 234, 13, 123, 213, 156, 19, 236]),
buyExactOut: Buffer.from([24, 211, 116, 40, 105, 3, 153, 56]),
sellExactIn: Buffer.from([149, 39, 222, 155, 211, 124, 152, 26]),
sellExactOut: Buffer.from([95, 200, 71, 34, 8, 9, 11, 166]),
createVestingAccount: Buffer.from([129, 178, 2, 13, 217, 172, 230, 218]),
claimVestedToken: Buffer.from([49, 33, 104, 30, 189, 157, 79, 35]),
createPlatformConfig: Buffer.from([176, 90, 196, 175, 253, 113, 220, 20]),
claimPlatformFee: Buffer.from([156, 39, 208, 135, 76, 237, 61, 72]),
updatePlaformConfig: Buffer.from([195, 60, 76, 129, 146, 45, 67, 143]),
};
export function initialize(
programId: PublicKey,
payer: PublicKey,
creator: PublicKey,
configId: PublicKey,
platformId: PublicKey,
auth: PublicKey,
poolId: PublicKey,
mintA: PublicKey,
mintB: PublicKey,
vaultA: PublicKey,
vaultB: PublicKey,
metadataId: PublicKey,
tokenProgramA: PublicKey,
tokenProgramB: PublicKey,
decimals: number,
name: string,
symbol: string,
uri: string,
curveParam: ({ type: "ConstantCurve"; totalSellA: BN } | { type: "FixedCurve" } | { type: "LinearCurve" }) & {
migrateType: "amm" | "cpmm";
supply: BN;
totalFundRaisingB: BN;
},
totalLockedAmount: BN,
cliffPeriod: BN,
unlockPeriod: BN,
): TransactionInstruction {
const dataLayout1 = struct([u8("decimals"), str("name"), str("symbol"), str("uri")]);
const dataLayout3 = struct([u64("totalLockedAmount"), u64("cliffPeriod"), u64("unlockPeriod")]);
const dataLayout21 = struct([u8("index"), u64("supply"), u64("totalFundRaisingB"), u8("migrateType")]);
const dataLayout22 = struct([
u8("index"),
u64("supply"),
u64("totalSellA"),
u64("totalFundRaisingB"),
u8("migrateType"),
]);
const keys: Array<AccountMeta> = [
{ pubkey: payer, isSigner: true, isWritable: false },
{ pubkey: creator, isSigner: false, isWritable: false },
{ pubkey: configId, isSigner: false, isWritable: false },
{ pubkey: platformId, isSigner: false, isWritable: false },
{ pubkey: auth, isSigner: false, isWritable: false },
{ pubkey: poolId, isSigner: false, isWritable: true },
{ pubkey: mintA, isSigner: true, isWritable: true },
{ pubkey: mintB, isSigner: false, isWritable: false },
{ pubkey: vaultA, isSigner: false, isWritable: true },
{ pubkey: vaultB, isSigner: false, isWritable: true },
{ pubkey: metadataId, isSigner: false, isWritable: true },
{ pubkey: tokenProgramA, isSigner: false, isWritable: false },
{ pubkey: tokenProgramB, isSigner: false, isWritable: false },
{ pubkey: METADATA_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: getPdaCpiEvent(programId).publicKey, isSigner: false, isWritable: false },
{ pubkey: programId, isSigner: false, isWritable: false },
];
const data1 = Buffer.alloc(
Buffer.from(name, "utf-8").length +
Buffer.from(symbol, "utf-8").length +
Buffer.from(uri, "utf-8").length +
4 * 3 +
1,
);
const data3 = Buffer.alloc(dataLayout3.span);
const data2 = Buffer.alloc(curveParam.type === "ConstantCurve" ? dataLayout22.span : dataLayout21.span);
dataLayout1.encode({ decimals, name, symbol, uri }, data1);
if (curveParam.type === "ConstantCurve") {
dataLayout22.encode({ index: 0, ...curveParam, migrateType: curveParam.migrateType === "amm" ? 0 : 1 }, data2);
} else if (curveParam.type === "FixedCurve") {
dataLayout21.encode({ index: 1, ...curveParam, migrateType: curveParam.migrateType === "amm" ? 0 : 1 }, data2);
} else if (curveParam.type === "LinearCurve") {
dataLayout21.encode({ index: 2, ...curveParam, migrateType: curveParam.migrateType === "amm" ? 0 : 1 }, data2);
}
dataLayout3.encode({ totalLockedAmount, cliffPeriod, unlockPeriod }, data3);
return new TransactionInstruction({
keys,
programId,
data: Buffer.from([...anchorDataBuf.initialize, ...data1, ...data2, ...data3]),
});
}
export function buyExactInInstruction(
programId: PublicKey,
owner: PublicKey,
auth: PublicKey,
configId: PublicKey,
platformId: PublicKey,
poolId: PublicKey,
userTokenAccountA: PublicKey,
userTokenAccountB: PublicKey,
vaultA: PublicKey,
vaultB: PublicKey,
mintA: PublicKey,
mintB: PublicKey,
tokenProgramA: PublicKey,
tokenProgramB: PublicKey,
amountB: BN,
minAmountA: BN,
shareFeeRate?: BN,
shareFeeReceiver?: PublicKey,
): TransactionInstruction {
const dataLayout = struct([u64("amountB"), u64("minAmountA"), u64("shareFeeRate")]);
const keys: Array<AccountMeta> = [
{ pubkey: owner, isSigner: true, isWritable: false },
{ pubkey: auth, isSigner: false, isWritable: false },
{ pubkey: configId, isSigner: false, isWritable: false },
{ pubkey: platformId, isSigner: false, isWritable: false },
{ pubkey: poolId, isSigner: false, isWritable: true },
{ pubkey: userTokenAccountA, isSigner: false, isWritable: true },
{ pubkey: userTokenAccountB, isSigner: false, isWritable: true },
{ pubkey: vaultA, isSigner: false, isWritable: true },
{ pubkey: vaultB, isSigner: false, isWritable: true },
{ pubkey: mintA, isSigner: false, isWritable: false },
{ pubkey: mintB, isSigner: false, isWritable: false },
{ pubkey: tokenProgramA, isSigner: false, isWritable: false },
{ pubkey: tokenProgramB, isSigner: false, isWritable: false },
{ pubkey: getPdaCpiEvent(programId).publicKey, isSigner: false, isWritable: false },
{ pubkey: programId, isSigner: false, isWritable: false },
];
if (shareFeeReceiver) {
keys.push({ pubkey: shareFeeReceiver, isSigner: false, isWritable: true });
}
console.log({
amountB: amountB.toString(),
minAmountA: minAmountA.toString(),
});
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
amountB,
minAmountA,
shareFeeRate: shareFeeRate ?? new BN(0),
},
data,
);
return new TransactionInstruction({
keys,
programId,
data: Buffer.from([...anchorDataBuf.buyExactIn, ...data]),
});
}
export function buyExactOutInstruction(
programId: PublicKey,
owner: PublicKey,
auth: PublicKey,
configId: PublicKey,
platformId: PublicKey,
poolId: PublicKey,
userTokenAccountA: PublicKey,
userTokenAccountB: PublicKey,
vaultA: PublicKey,
vaultB: PublicKey,
mintA: PublicKey,
mintB: PublicKey,
tokenProgramA: PublicKey,
tokenProgramB: PublicKey,
amountA: BN,
maxAmountB: BN,
shareFeeRate?: BN,
shareFeeReceiver?: PublicKey,
): TransactionInstruction {
const dataLayout = struct([u64("amountA"), u64("maxAmountB"), u64("shareFeeRate")]);
const keys: Array<AccountMeta> = [
{ pubkey: owner, isSigner: true, isWritable: false },
{ pubkey: auth, isSigner: false, isWritable: false },
{ pubkey: configId, isSigner: false, isWritable: false },
{ pubkey: platformId, isSigner: false, isWritable: false },
{ pubkey: poolId, isSigner: false, isWritable: true },
{ pubkey: userTokenAccountA, isSigner: false, isWritable: true },
{ pubkey: userTokenAccountB, isSigner: false, isWritable: true },
{ pubkey: vaultA, isSigner: false, isWritable: true },
{ pubkey: vaultB, isSigner: false, isWritable: true },
{ pubkey: mintA, isSigner: false, isWritable: false },
{ pubkey: mintB, isSigner: false, isWritable: false },
{ pubkey: tokenProgramA, isSigner: false, isWritable: false },
{ pubkey: tokenProgramB, isSigner: false, isWritable: false },
{ pubkey: getPdaCpiEvent(programId).publicKey, isSigner: false, isWritable: false },
{ pubkey: programId, isSigner: false, isWritable: false },
];
if (shareFeeReceiver) {
keys.push({ pubkey: shareFeeReceiver, isSigner: false, isWritable: true });
}
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
amountA,
maxAmountB,
shareFeeRate: shareFeeRate ?? new BN(0),
},
data,
);
return new TransactionInstruction({
keys,
programId,
data: Buffer.from([...anchorDataBuf.buyExactOut, ...data]),
});
}
export function sellExactInInstruction(
programId: PublicKey,
owner: PublicKey,
auth: PublicKey,
configId: PublicKey,
platformId: PublicKey,
poolId: PublicKey,
userTokenAccountA: PublicKey,
userTokenAccountB: PublicKey,
vaultA: PublicKey,
vaultB: PublicKey,
mintA: PublicKey,
mintB: PublicKey,
tokenProgramA: PublicKey,
tokenProgramB: PublicKey,
amountA: BN,
minAmountB: BN,
shareFeeRate?: BN,
shareFeeReceiver?: PublicKey,
): TransactionInstruction {
const dataLayout = struct([u64("amountA"), u64("minAmountB"), u64("shareFeeRate")]);
const keys: Array<AccountMeta> = [
{ pubkey: owner, isSigner: true, isWritable: false },
{ pubkey: auth, isSigner: false, isWritable: false },
{ pubkey: configId, isSigner: false, isWritable: false },
{ pubkey: platformId, isSigner: false, isWritable: false },
{ pubkey: poolId, isSigner: false, isWritable: true },
{ pubkey: userTokenAccountA, isSigner: false, isWritable: true },
{ pubkey: userTokenAccountB, isSigner: false, isWritable: true },
{ pubkey: vaultA, isSigner: false, isWritable: true },
{ pubkey: vaultB, isSigner: false, isWritable: true },
{ pubkey: mintA, isSigner: false, isWritable: false },
{ pubkey: mintB, isSigner: false, isWritable: false },
{ pubkey: tokenProgramA, isSigner: false, isWritable: false },
{ pubkey: tokenProgramB, isSigner: false, isWritable: false },
{ pubkey: getPdaCpiEvent(programId).publicKey, isSigner: false, isWritable: false },
{ pubkey: programId, isSigner: false, isWritable: false },
];
if (shareFeeReceiver) {
keys.push({ pubkey: shareFeeReceiver, isSigner: false, isWritable: true });
}
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
amountA,
minAmountB,
shareFeeRate: shareFeeRate ?? new BN(0),
},
data,
);
return new TransactionInstruction({
keys,
programId,
data: Buffer.from([...anchorDataBuf.sellExactIn, ...data]),
});
}
export function sellExactOut(
programId: PublicKey,
owner: PublicKey,
auth: PublicKey,
configId: PublicKey,
platformId: PublicKey,
poolId: PublicKey,
userTokenAccountA: PublicKey,
userTokenAccountB: PublicKey,
vaultA: PublicKey,
vaultB: PublicKey,
mintA: PublicKey,
mintB: PublicKey,
tokenProgramA: PublicKey,
tokenProgramB: PublicKey,
amountB: BN,
maxAmountA: BN,
shareFeeRate?: BN,
shareFeeReceiver?: PublicKey,
): TransactionInstruction {
const dataLayout = struct([u64("amountB"), u64("maxAmountA"), u64("shareFeeRate")]);
const keys: Array<AccountMeta> = [
{ pubkey: owner, isSigner: true, isWritable: false },
{ pubkey: auth, isSigner: false, isWritable: false },
{ pubkey: configId, isSigner: false, isWritable: false },
{ pubkey: platformId, isSigner: false, isWritable: false },
{ pubkey: poolId, isSigner: false, isWritable: true },
{ pubkey: userTokenAccountA, isSigner: false, isWritable: true },
{ pubkey: userTokenAccountB, isSigner: false, isWritable: true },
{ pubkey: vaultA, isSigner: false, isWritable: true },
{ pubkey: vaultB, isSigner: false, isWritable: true },
{ pubkey: mintA, isSigner: false, isWritable: false },
{ pubkey: mintB, isSigner: false, isWritable: false },
{ pubkey: tokenProgramA, isSigner: false, isWritable: false },
{ pubkey: tokenProgramB, isSigner: false, isWritable: false },
{ pubkey: getPdaCpiEvent(programId).publicKey, isSigner: false, isWritable: false },
{ pubkey: programId, isSigner: false, isWritable: false },
];
if (shareFeeReceiver) {
keys.push({ pubkey: shareFeeReceiver, isSigner: false, isWritable: true });
}
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode(
{
amountB,
maxAmountA,
shareFeeRate: shareFeeRate ?? new BN(0),
},
data,
);
return new TransactionInstruction({
keys,
programId,
data: Buffer.from([...anchorDataBuf.sellExactOut, ...data]),
});
}
export function claimVestedToken(
programId: PublicKey,
owner: PublicKey,
auth: PublicKey,
poolId: PublicKey,
vestingRecord: PublicKey,
userTokenAccountA: PublicKey,
vaultA: PublicKey,
mintA: PublicKey,
tokenProgramA: PublicKey,
): TransactionInstruction {
const dataLayout = struct([]);
const keys: Array<AccountMeta> = [
{ pubkey: owner, isSigner: true, isWritable: false },
{ pubkey: auth, isSigner: false, isWritable: false },
{ pubkey: poolId, isSigner: false, isWritable: true },
{ pubkey: vestingRecord, isSigner: false, isWritable: true },
{ pubkey: userTokenAccountA, isSigner: false, isWritable: true },
{ pubkey: vaultA, isSigner: false, isWritable: true },
{ pubkey: mintA, isSigner: false, isWritable: false },
{ pubkey: tokenProgramA, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
];
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode({}, data);
return new TransactionInstruction({
keys,
programId,
data: Buffer.from([...anchorDataBuf.claimVestedToken, ...data]),
});
}
export function createVestingAccount(
programId: PublicKey,
owner: PublicKey,
beneficiary: PublicKey,
poolId: PublicKey,
vestingRecord: PublicKey,
shareAmount: BN,
): TransactionInstruction {
const dataLayout = struct([u64("shareAmount")]);
const keys: Array<AccountMeta> = [
{ pubkey: owner, isSigner: true, isWritable: false },
{ pubkey: beneficiary, isSigner: false, isWritable: false },
{ pubkey: poolId, isSigner: false, isWritable: true },
{ pubkey: vestingRecord, isSigner: false, isWritable: true },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
];
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode({ shareAmount }, data);
return new TransactionInstruction({
keys,
programId,
data: Buffer.from([...anchorDataBuf.createVestingAccount, ...data]),
});
}
export function claimPlatformFee(
programId: PublicKey,
platformClaimFeeWallet: PublicKey,
auth: PublicKey,
poolId: PublicKey,
platformId: PublicKey,
vaultB: PublicKey,
userTokenAccountB: PublicKey,
mintB: PublicKey,
tokenProgramB: PublicKey,
): TransactionInstruction {
const keys: Array<AccountMeta> = [
{ pubkey: platformClaimFeeWallet, isSigner: true, isWritable: false },
{ pubkey: auth, isSigner: false, isWritable: false },
{ pubkey: poolId, isSigner: false, isWritable: true },
{ pubkey: platformId, isSigner: false, isWritable: true },
{ pubkey: vaultB, isSigner: false, isWritable: true },
{ pubkey: userTokenAccountB, isSigner: false, isWritable: true },
{ pubkey: mintB, isSigner: false, isWritable: true },
{ pubkey: tokenProgramB, isSigner: false, isWritable: true },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: true },
{ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: true },
];
return new TransactionInstruction({
keys,
programId,
data: anchorDataBuf.claimPlatformFee,
});
}
export function createPlatformConfig(
programId: PublicKey,
platformAdmin: PublicKey,
platformClaimFeeWallet: PublicKey,
platformLockNftWallet: PublicKey,
platformId: PublicKey,
migrateCpLockNftScale: {
platformScale: BN;
creatorScale: BN;
burnScale: BN;
},
feeRate: BN,
name: string,
web: string,
img: string,
): TransactionInstruction {
const dataLayout = struct([
u64("platformScale"),
u64("creatorScale"),
u64("burnScale"),
u64("feeRate"),
str("name"),
str("web"),
str("img"),
]);
const keys: Array<AccountMeta> = [
{ pubkey: platformAdmin, isSigner: true, isWritable: true },
{ pubkey: platformClaimFeeWallet, isSigner: false, isWritable: false },
{ pubkey: platformLockNftWallet, isSigner: false, isWritable: false },
{ pubkey: platformId, isSigner: false, isWritable: true },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
];
const data = Buffer.alloc(
8 * 4 +
Buffer.from(name, "utf-8").length +
Buffer.from(web, "utf-8").length +
Buffer.from(img, "utf-8").length +
4 * 3,
);
dataLayout.encode(
{
platformScale: migrateCpLockNftScale.platformScale,
creatorScale: migrateCpLockNftScale.creatorScale,
burnScale: migrateCpLockNftScale.burnScale,
feeRate,
name,
web,
img,
},
data,
);
return new TransactionInstruction({
keys,
programId,
data: Buffer.from([...anchorDataBuf.createPlatformConfig, ...data]),
});
}
export function updatePlatformConfig(
programId: PublicKey,
platformAdmin: PublicKey,
platformId: PublicKey,
updateInfo:
| { type: "updateClaimFeeWallet" | "updateLockNftWallet"; value: PublicKey }
| { type: "updateFeeRate"; value: BN }
| { type: "updateName" | "updateImg" | "updateWeb"; value: string }
| { type: "migrateCpLockNftScale"; value: { platformScale: BN; creatorScale: BN; burnScale: BN } },
): TransactionInstruction {
const keys: Array<AccountMeta> = [
{ pubkey: platformAdmin, isSigner: true, isWritable: false },
{ pubkey: platformId, isSigner: false, isWritable: true },
];
let data: Buffer;
if (updateInfo.type === "updateClaimFeeWallet") {
const dataLayout = struct([u8("index"), publicKey("value")]);
data = Buffer.alloc(dataLayout.span);
dataLayout.encode({ index: 0, value: updateInfo.value }, data);
} else if (updateInfo.type === "updateLockNftWallet") {
const dataLayout = struct([u8("index"), publicKey("value")]);
data = Buffer.alloc(dataLayout.span);
dataLayout.encode({ index: 1, value: updateInfo.value }, data);
} else if (updateInfo.type === "migrateCpLockNftScale") {
const dataLayout = struct([u8("index"), u64("platformScale"), u64("creatorScale"), u64("burnScale")]);
data = Buffer.alloc(dataLayout.span);
dataLayout.encode({ index: 2, ...updateInfo.value }, data);
} else if (updateInfo.type === "updateFeeRate") {
const dataLayout = struct([u8("index"), u64("value")]);
data = Buffer.alloc(dataLayout.span);
dataLayout.encode({ index: 3, value: updateInfo.value }, data);
} else if (updateInfo.type === "updateImg" || updateInfo.type === "updateName" || updateInfo.type === "updateWeb") {
const dataLayout = struct([u8("index"), str("value")]);
data = Buffer.alloc(dataLayout.span);
if (updateInfo.type === "updateName") dataLayout.encode({ index: 4, value: updateInfo.value }, data);
else if (updateInfo.type === "updateWeb") dataLayout.encode({ index: 5, value: updateInfo.value }, data);
else if (updateInfo.type === "updateImg") dataLayout.encode({ index: 6, value: updateInfo.value }, data);
} else {
throw Error("updateInfo params type error");
}
return new TransactionInstruction({
keys,
programId,
data: Buffer.from([...anchorDataBuf.updatePlaformConfig, ...data]),
});
}