@solsdk/relay_sdk
Version:
Pumpfun SDK — create, buy, sell tokens with support for Jito bundles and multiple relayer integrations. Rebuilt and fixed pumpdotfun-sdk.
343 lines (340 loc) • 9.51 kB
JavaScript
import BN from "../_virtual/bn.mjs";
import { getAssociatedTokenAddress } from "@solana/spl-token";
import { Transaction } from "@solana/web3.js";
import { GlobalAccount } from "../globalAccount.mjs";
import { DEFAULT_COMMITMENT, DEFAULT_FINALITY } from "../pumpFun.consts.mjs";
import {
calculateWithSlippageBuy,
calculateWithSlippageSell,
} from "../slippage.mjs";
import { sendTx } from "../tx.mjs";
import { Keypair as UtilsKeypair } from "@nealireverse_dev/utils";
class TradeModule {
sdk;
constructor(sdk) {
this.sdk = sdk;
}
async createAndBuy(
creator,
mint,
metadata,
buyAmountSol,
slippageBasisPoints = 500n,
priorityFees,
commitment = DEFAULT_COMMITMENT,
finality = DEFAULT_FINALITY
) {
UtilsKeypair.from({ keypair: creator });
const tokenMetadata = await this.sdk.token.createTokenMetadata(metadata);
const createIx = await this.getCreateInstructions(
creator.publicKey,
metadata.name,
metadata.symbol,
tokenMetadata.metadataUri,
mint
);
const transaction = new Transaction().add(createIx);
if (buyAmountSol > 0n) {
const globalAccount = await this.sdk.token.getGlobalAccount(commitment);
const buyAmount = globalAccount.getInitialBuyPrice(buyAmountSol);
const buyAmountWithSlippage = calculateWithSlippageBuy(
buyAmountSol,
slippageBasisPoints
);
await this.buildBuyIx(
creator.publicKey,
mint.publicKey,
buyAmount,
buyAmountWithSlippage,
transaction,
commitment,
true
);
}
return await sendTx(
this.sdk.connection,
transaction,
creator.publicKey,
[creator, mint],
priorityFees,
commitment,
finality
);
}
async buy(
buyer,
mint,
buyAmountSol,
slippageBasisPoints = 500n,
priorityFees,
commitment = DEFAULT_COMMITMENT,
finality = DEFAULT_FINALITY
) {
const bondingAccount = await this.sdk.token.getBondingCurveAccount(
mint,
commitment
);
if (!bondingAccount) {
throw new Error(`Bonding curve account not found: ${mint.toBase58()}`);
}
const buyAmount = bondingAccount.getBuyPrice(buyAmountSol);
const buyAmountWithSlippage = calculateWithSlippageBuy(
buyAmountSol,
slippageBasisPoints
);
const transaction = new Transaction();
await this.buildBuyIx(
buyer.publicKey,
mint,
buyAmount,
buyAmountWithSlippage,
transaction,
commitment,
false
);
return await sendTx(
this.sdk.connection,
transaction,
buyer.publicKey,
[buyer],
priorityFees,
commitment,
finality
);
}
async getBuyInstructionsBySolAmount(
buyer,
mint,
buyAmountSol,
slippageBasisPoints = 500n,
commitment = DEFAULT_COMMITMENT
) {
const bondingCurveAccount = await this.sdk.token.getBondingCurveAccount(
mint,
commitment
);
if (!bondingCurveAccount) {
throw new Error(`Bonding curve account not found: ${mint.toBase58()}`);
}
const buyAmount = bondingCurveAccount.getBuyPrice(buyAmountSol);
const buyAmountWithSlippage = calculateWithSlippageBuy(
buyAmountSol,
slippageBasisPoints
);
const transaction = new Transaction();
await this.buildBuyIx(
buyer,
mint,
buyAmount,
buyAmountWithSlippage,
transaction,
commitment,
false
);
return transaction;
}
async buildBuyIx(
buyer,
mint,
amount,
maxSolCost,
tx,
commitment,
shouldUseBuyerAsBonding
) {
const bondingCurve = this.sdk.pda.getBondingCurvePDA(mint);
const associatedBonding = await getAssociatedTokenAddress(
mint,
bondingCurve,
true
);
const associatedUser =
await this.sdk.token.createAssociatedTokenAccountIfNeeded(
buyer,
buyer,
mint,
tx,
commitment
);
const globalPda = this.sdk.pda.getGlobalAccountPda();
const globalAccBuf = await this.sdk.connection.getAccountInfo(
globalPda,
commitment
);
const feeRecipient = GlobalAccount.fromBuffer(
globalAccBuf.data
).feeRecipient;
const bondingCreator = shouldUseBuyerAsBonding
? this.sdk.pda.getCreatorVaultPda(buyer)
: await this.sdk.token.getBondingCurveCreator(bondingCurve, commitment);
const creatorVault = shouldUseBuyerAsBonding
? bondingCreator
: this.sdk.pda.getCreatorVaultPda(bondingCreator);
const eventAuthority = this.sdk.pda.getEventAuthorityPda();
const ix = await this.sdk.program.methods
.buy(new BN(amount.toString()), new BN(maxSolCost.toString()))
.accounts({
global: globalPda,
feeRecipient,
mint,
bondingCurve,
associatedBondingCurve: associatedBonding,
associatedUser,
user: buyer,
creatorVault,
eventAuthority,
})
.instruction();
tx.add(ix);
}
//create token instructions
async getCreateInstructions(creator, name, symbol, uri, mint) {
const mintAuthority = this.sdk.pda.getMintAuthorityPDA();
const bondingCurve = this.sdk.pda.getBondingCurvePDA(mint.publicKey);
const associatedBonding = await getAssociatedTokenAddress(
mint.publicKey,
bondingCurve,
true
);
const global = this.sdk.pda.getGlobalAccountPda();
const metadata = this.sdk.pda.getMetadataPDA(mint.publicKey);
const eventAuthority = this.sdk.pda.getEventAuthorityPda();
const ix = await this.sdk.program.methods
.create(name, symbol, uri, creator)
.accounts({
mint: mint.publicKey,
mintAuthority,
bondingCurve,
associatedBondingCurve: associatedBonding,
global,
metadata,
user: creator,
eventAuthority,
})
.instruction();
return new Transaction().add(ix);
}
async buildSellIx(seller, mint, tokenAmount, minSolOutput, tx, commitment) {
const bondingCurve = this.sdk.pda.getBondingCurvePDA(mint);
const associatedBonding = await getAssociatedTokenAddress(
mint,
bondingCurve,
true
);
const associatedUser =
await this.sdk.token.createAssociatedTokenAccountIfNeeded(
seller,
seller,
mint,
tx,
commitment
);
const globalPda = this.sdk.pda.getGlobalAccountPda();
const globalBuf = await this.sdk.connection.getAccountInfo(
globalPda,
commitment
);
const feeRecipient = GlobalAccount.fromBuffer(globalBuf.data).feeRecipient;
const bondingCreator = await this.sdk.token.getBondingCurveCreator(
bondingCurve,
commitment
);
const creatorVault = this.sdk.pda.getCreatorVaultPda(bondingCreator);
const eventAuthority = this.sdk.pda.getEventAuthorityPda();
const ix = await this.sdk.program.methods
.sell(new BN(tokenAmount.toString()), new BN(minSolOutput.toString()))
.accounts({
global: globalPda,
feeRecipient,
mint,
bondingCurve,
associatedBondingCurve: associatedBonding,
associatedUser,
user: seller,
creatorVault,
eventAuthority,
})
.instruction();
tx.add(ix);
}
async sell(
seller,
mint,
sellTokenAmount,
slippageBasisPoints = 500n,
priorityFees,
commitment = DEFAULT_COMMITMENT,
finality = DEFAULT_FINALITY
) {
const bondingAccount = await this.sdk.token.getBondingCurveAccount(
mint,
commitment
);
if (!bondingAccount)
throw new Error(`Bonding curve account not found: ${mint.toBase58()}`);
const globalAccount = await this.sdk.token.getGlobalAccount(commitment);
const minSolOutput = bondingAccount.getSellPrice(
sellTokenAmount,
globalAccount.feeBasisPoints
);
let sellAmountWithSlippage = calculateWithSlippageSell(
minSolOutput,
slippageBasisPoints
);
if (sellAmountWithSlippage < 1n) sellAmountWithSlippage = 1n;
const transaction = new Transaction();
await this.buildSellIx(
seller.publicKey,
mint,
sellTokenAmount,
sellAmountWithSlippage,
transaction,
commitment
);
return await sendTx(
this.sdk.connection,
transaction,
seller.publicKey,
[seller],
priorityFees,
commitment,
finality
);
}
async getSellInstructionsByTokenAmount(
seller,
mint,
sellTokenAmount,
slippageBasisPoints = 500n,
commitment = DEFAULT_COMMITMENT
) {
const bondingAccount = await this.sdk.token.getBondingCurveAccount(
mint,
commitment
);
if (!bondingAccount)
throw new Error(`Bonding curve account not found: ${mint.toBase58()}`);
const globalAccount = await this.sdk.token.getGlobalAccount(commitment);
const minSolOutput = bondingAccount.getSellPrice(
sellTokenAmount,
globalAccount.feeBasisPoints
);
let sellAmountWithSlippage = calculateWithSlippageSell(
minSolOutput,
slippageBasisPoints
);
if (sellAmountWithSlippage < 1n) sellAmountWithSlippage = 1n;
const transaction = new Transaction();
await this.buildSellIx(
seller,
mint,
sellTokenAmount,
sellAmountWithSlippage,
transaction,
commitment
);
return transaction;
}
}
export { TradeModule };
//# sourceMappingURL=TradeModule.mjs.map