Skip to content

Buy (manual implementation)

This shows the complete build-sign-submit flow without using the SDK. This is exactly what sdk.buy() does internally. Use this as a reference for custom integrations or porting to other languages.

This is the full orchestration for a buy transaction:

  1. Build (POST /v1/tx/buy) → get unsignedTransaction and submissionToken
  2. Sign locally (decode base64 wire → sign → encode base64 wire)
  3. Submit (POST /v1/tx/submit)

For the full endpoint references, see:

import bs58 from 'bs58';
import axios from 'axios';
import https from 'https';
import {
getTransactionDecoder,
createKeyPairFromBytes,
signTransaction,
getBase64EncodedWireTransaction,
} from '@solana/kit';
// Hardcoded config (load from env in production)
const API_KEY = 'api_your_key_here';
const SECRET_KEY_BASE58 = 'PASTE_BASE58_64_BYTE_SECRET_KEY_HERE';
const MINT = 'TOKEN_MINT';
const SOL_AMOUNT = 0.002;
const SLIPPAGE = 0.05;
const PRIORITY = 'fast'; // see: /api/priority/
// HTTPS agent with keepalive for connection reuse
const httpsAgent = new https.Agent({
keepAlive: true,
keepAliveMsecs: 1000,
maxSockets: 10,
maxFreeSockets: 5,
timeout: 60000,
});
const api = axios.create({
baseURL: 'https://api.darkfibre.dev/v1',
headers: { 'Authorization': `Bearer ${API_KEY}` },
timeout: 30000,
httpsAgent,
});
async function fetchBuyTx() {
const res: any = await api.post('/tx/buy', {
mint: MINT,
solAmount: SOL_AMOUNT,
slippage: SLIPPAGE,
priority: PRIORITY,
});
return res.data.data; // { submissionToken, unsignedTransaction, ... }
}
async function submitTx(submissionToken: string, signedTransaction: string) {
const res: any = await api.post('/tx/submit', {
submissionToken,
signedTransaction,
});
return res.data.data; // { signature, status, ... }
}
async function signTx(unsignedTxBase64Wire: string) {
const signer: CryptoKeyPair = await createKeyPairFromBytes(bs58.decode(SECRET_KEY_BASE58));
// 1) Deserialize base64 wire → Transaction
const unsignedTx = getTransactionDecoder().decode(Buffer.from(unsignedTxBase64Wire, 'base64'));
// 2) Sign
const signed = await signTransaction([signer], unsignedTx as any);
// 3) Serialize Transaction → base64 wire
return getBase64EncodedWireTransaction(signed);
}
async function main() {
// 1) Build
const { submissionToken, unsignedTransaction } = await fetchBuyTx();
// 2) Sign (do it immediately; tx expires quickly)
const signedTransaction = await signTx(unsignedTransaction);
// 3) Submit
const { signature } = await submitTx(submissionToken, signedTransaction);
console.log(`https://solscan.io/tx/${signature}`);
}
main().catch(console.error);
  • Sign fast: expiresAt is short (~30s). Build and sign immediately before submitting.
  • Keep the message unchanged: the submit endpoint validates message bytes against what the server built.