Documentation Index
Fetch the complete documentation index at: https://docs.meteora.ag/llms.txt
Use this file to discover all available pages before exploring further.
These examples show the SDK flow shape. They return unsigned transactions that your app should sign, simulate, submit, and confirm through its own wallet or backend signer flow.
Create A Fixed-price Presale
import { Connection, PublicKey } from "@solana/web3.js";
import BN from "bn.js";
import Decimal from "decimal.js";
import Presale, { PRESALE_PROGRAM_ID } from "@meteora-ag/presale";
import {
Rounding,
UnsoldTokenAction,
WhitelistMode,
} from "@meteora-ag/presale";
const connection = new Connection(process.env.RPC_URL!, "confirmed");
const tx = await Presale.createFixedPricePresale(
connection,
PRESALE_PROGRAM_ID,
{
baseMintPubkey: new PublicKey("BASE_MINT"),
quoteMintPubkey: new PublicKey("QUOTE_MINT"),
basePubkey: baseKeypair.publicKey,
creatorPubkey: creator.publicKey,
feePayerPubkey: creator.publicKey,
presaleArgs: {
presaleMaximumCap: new BN("100000000"),
presaleMinimumCap: new BN("1000000"),
presaleStartTime: new BN(0),
presaleEndTime: new BN(Math.floor(Date.now() / 1000) + 3600),
whitelistMode: WhitelistMode.Permissionless,
unsoldTokenAction: UnsoldTokenAction.Refund,
disableEarlierPresaleEndOnceCapReached: false,
},
presaleRegistries: [
{
buyerMinimumDepositCap: new BN("100000"),
buyerMaximumDepositCap: new BN("100000000"),
presaleSupply: new BN("2000000000"),
depositFeeBps: new BN(0),
},
],
lockedVestingArgs: {
immediateReleaseBps: new BN(10_000),
immediateReleaseTimestamp: new BN(Math.floor(Date.now() / 1000) + 3600),
lockDuration: new BN(0),
vestDuration: new BN(0),
},
},
{
price: new Decimal(0.1),
rounding: Rounding.Down,
disableWithdraw: false,
}
);
// Sign with creator and baseKeypair, then simulate and send.
Use Presale.createProrataPresale or Presale.createFcfsPresale with the same common presale params when you do not need fixed-price price and disableWithdraw inputs.
Create A Client
import { Connection, PublicKey } from "@solana/web3.js";
import Presale, { PRESALE_PROGRAM_ID } from "@meteora-ag/presale";
const connection = new Connection(process.env.RPC_URL!, "confirmed");
const presaleAddress = new PublicKey("PRESALE_ADDRESS");
const presale = await Presale.create(
connection,
presaleAddress,
PRESALE_PROGRAM_ID
);
Permissionless Deposit
deposit automatically creates the permissionless escrow if it does not exist.
import BN from "bn.js";
const tx = await presale.deposit({
owner: wallet.publicKey,
amount: new BN("500000000"),
});
Permissioned Merkle Deposit
For Merkle proof presales, create the Merkle root config and proof responses off-chain, then build deposits with the proof data. The SDK also has an auto-fetch path that reads PermissionedServerMetadata.server_url.
const tx = await presale.createPermissionedEscrowWithMerkleProof({
owner: buyer.publicKey,
payer: buyer.publicKey,
registryIndex: new BN(0),
depositCap: new BN("100000000"),
merkleRootConfig,
proof,
});
After the escrow exists, call deposit with the same owner and registry index:
const depositTx = await presale.deposit({
owner: buyer.publicKey,
registryIndex: new BN(0),
amount: new BN("50000000"),
});
Permissioned Authority Deposit
Authority-permissioned presales use an operator account. If the escrow is missing, the SDK deposit flow requests a partially signed escrow creation and deposit transaction from the creator-managed server URL stored in PermissionedServerMetadata.
const operatorTx = await presale.createOperator({
creator: creator.publicKey,
operator: operator.publicKey,
});
const depositTx = await presale.deposit({
owner: buyer.publicKey,
registryIndex: new BN(0),
amount: new BN("50000000"),
});
Claim
const escrows = await presale.getPresaleEscrowByOwner(wallet.publicKey);
const claimTxs = await Promise.all(
escrows.map((escrow) =>
presale.claim({
owner: wallet.publicKey,
registryIndex: new BN(escrow.getEscrowAccount().registryIndex),
})
)
);
Withdraw During Presale
const tx = await presale.withdraw({
owner: wallet.publicKey,
registryIndex: new BN(0),
amount: new BN("10000000"),
});
Withdrawals are available in prorata mode and in fixed-price mode unless the creator disabled them. FCFS does not allow withdrawals.
Withdraw Remaining Quote
const tx = await presale.withdrawRemainingQuote({
owner: wallet.publicKey,
registryIndex: new BN(0),
});
Use this for failed presales or completed prorata presales with refundable oversubscription.
Creator Actions
| Flow | Method |
|---|
| Withdraw raised quote or failed-presale base tokens | presale.creatorWithdraw({ creator }) |
| Collect deposit fees | presale.creatorCollectFee() |
| Burn or refund unsold base tokens | presale.performUnsoldBaseTokenAction(payer) |
| Create permissioned metadata URL | presale.createPermissionedServerMetadata({ owner, serverUrl }) |
| Close permissioned metadata | presale.closePermissionedServerMetadata({ owner, rentReceiver }) |
Read State
const parsed = presale.getParsedPresale();
console.log(parsed.getPresaleModeName());
console.log(parsed.getWhitelistModeName());
console.log(parsed.getPresaleProgressState());
console.log(parsed.getRemainingDepositUiQuota());
console.log(parsed.canDeposit());
console.log(parsed.canClaim());