Fee coin · mode: "standard"
Trades on a 1% pool. Trading fees split 50/50 between the creator and the platform; the creator claims their half from the token page or by wallet.
Reward coin · mode: "reward"
Trades on a 4% pool and pays 85% of trading fees straight to holders, automatically, in the token it is paired against. No creator fee position.
Raydium pairs — what you launch against
Every token is priced against a real asset rather than SOL: tokenized stocks (xStocks), pre-IPO stocks (PreStocks), currencies, or a custom mint. Fetch the current list from GET /pairs and pass one as quoteMint.
import {
Connection, Keypair, Transaction,
} from '@solana/web3.js';
import fs from 'node:fs';
const API = 'https://www.stonkfun.xyz/api/public/v1';
const creator = Keypair.fromSecretKey( // your own wallet, never sent anywhere
Uint8Array.from(JSON.parse(fs.readFileSync('creator.json', 'utf8')))
);
const headers = { 'Content-Type': 'application/json' }; // no key, nothing to sign up for
const call = async (path, init) => {
const response = await fetch(API + path, init);
const body = await response.json();
if (!response.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
return body.data;
};
// 1. Pick a pair to launch against.
const { pairs } = await call('/pairs?launchable=true');
const pair = pairs.find((item) => item.symbol === 'NVDAx') ?? pairs[0];
// 2. Prepare. Returns an UNSIGNED payment transaction.
const logo = 'data:image/png;base64,' + fs.readFileSync('logo.png').toString('base64');
const prepared = await call('/launches/prepare', {
method: 'POST',
headers,
body: JSON.stringify({
creatorWallet: creator.publicKey.toBase58(),
quoteMint: pair.mint,
name: 'My Token',
symbol: 'MYTKN',
mode: 'standard', // 'standard' splits trading fees 50/50 with you
logo,
}),
});
// 3. Sign the fee payment locally. Your key never leaves this process.
const tx = Transaction.from(Buffer.from(prepared.paymentTransaction, 'base64'));
tx.sign(creator);
// 4. Submit. Usually returns a finished token in this one call.
let result = await call('/launches/submit', {
method: 'POST',
headers,
body: JSON.stringify({
signedQuote: prepared.signedQuote,
signedTransaction: tx.serialize().toString('base64'),
logo, // must be byte-identical to step 2
}),
});
// 5. If the platform's launch slots were busy, poll. NEVER pay again.
while (result.status === 'processing') {
await new Promise((resolve) => setTimeout(resolve, 5000));
result = await call(`/launches/${result.paymentSignature}`);
}
console.log('Live:', result.mint);
If submit returns "processing"
Your payment landed and the launch is queued behind the platform's concurrent launch limit. The work is checkpointed against your payment signature and will be completed automatically even if your process dies. Poll GET /launches/{paymentSignature} until it reads completed. Never pay twice — a second payment creates a second token.