justi.fun
§03 · Start

TypeScript SDK

@justifun/sdk: typed client, launch, quote, buy, sell, subscribe, verifyWebhook.

Install

bash
npm install @justifun/sdk

ESM and CommonJS, full types, no runtime dependencies. The types and the method list are generated from the live OpenAPI spec. If the @justifun scope is not on npm yet, the same package is justi-sdk.

Client

ts
import { Justi } from "@justifun/sdk";

const justi = new Justi({
  apiKey: process.env.JUSTI_API_KEY, // optional
  // baseUrl, fetch, timeoutMs (45000), retries (2, GET only), onRateLimit
});
justi.rateLimit; // RateLimit headers of the last response

Signers

The SDK signs serialized transactions as bytes, so it needs no Solana library. Keys never leave your process.

You havePass
Keypair from @solana/web3.jssigner: keypair
Secret key bytes or a solana-keygen JSON arraykeypairSigner(secret)
Browser wallet (wallet adapter, Phantom, Solflare, Backpack)new Justi({ VersionedTransaction }) then signer: wallet
KMS, MPC or hardware key that signs raw bytesmessageSigner(publicKey, signFn)
Anything else{ publicKey: string, signTransaction(bytes) }
import { VersionedTransaction } from "@solana/web3.js";
import { useWallet } from "@solana/wallet-adapter-react";
import { Justi } from "@justifun/sdk";

const justi = new Justi({ VersionedTransaction });

function BuyButton({ mint }: { mint: string }) {
  const wallet = useWallet();
  return <button onClick={() => justi.buy({ mint, sol: 0.1, signer: wallet })}>Buy 0.1 SOL</button>;
}

Helpers

MethodWhat it does
launch(input)Build, sign (wallet and optional mintSigner), submit, wait until live. dryRun: true returns the signed transaction without sending.
quote({ mint, side, sol | tokens | amount })Decimal SOL or tokens are converted exactly (no float rounding).
buy({ mint, sol, signer })Build, sign, submit, poll until confirmed, failed or expired.
sell({ mint, tokens, signer })Same, for a sell.
getCoin(mint), listCoins(query)Aliases of getToken and listTokens.
coins(query)Async iterator over every page.
subscribe(channels, onEvent, opts)WebSocket with reconnect, backoff, resubscribe and a heartbeat watchdog.
verifyWebhook(raw, header, secret), parseWebhook(...)HMAC check with a 5 minute window, constant-time compare.
createApiKey({ wallet, label })Signs the key message and returns a free key.
waitForSwap(id), waitForLaunch(id)Polling helpers.

Every method

Each API operation is a method named by its operationId. Path parameters come first, then the body or query object.

getProtocol()GET /v1/protocolWhat a terminal needs to tag justi.fun coinsgetPad()GET /v1/padPad config, fee tiers, fee splits and the sniper window schedulegetStatus()GET /v1/statusService status: switches and live ingestgetOpenApi()GET /v1/openapi.jsonThis OpenAPI 3.1 documentlistTokens()GET /v1/tokensCoins, with filters, sort, search and paginationgetTokenList()GET /v1/tokenlistEvery coin in one list (for terminals)getToken()GET /v1/tokens/{mint}Coin detail: metadata, safety facts, curve, graduation, sniper window, totalsgetTokenMetadata()GET /v1/tokens/{mint}/metadataMetaplex metadata JSON for a coinlistTrades()GET /v1/tokens/{mint}/tradesTrades, newest first, cursor paginated (curve and DAMM v2)getCandles()GET /v1/tokens/{mint}/candlesOHLCV candles from indexed tradeslistHolders()GET /v1/tokens/{mint}/holdersHolders from the latest snapshot (every 10 minutes)listTokenBurns()GET /v1/tokens/{mint}/burnsBuybacks and burns of one coin, with signatureslistBuybacks()GET /v1/buybacksAll buybacks and burns ($JUSTI and sniper-window coin burns)getTokenRewards()GET /v1/tokens/{mint}/rewardsHolder reward rounds of one coingetWalletRewards()GET /v1/wallets/{address}/rewardsWhat a wallet earned from holding, and its payouts with signatureslistPayouts()GET /v1/payoutsConfirmed holder payouts, newest firstgetCreator()GET /v1/creators/{wallet}Creator stats: coins, fees earned and claimable (read live from the pools)getPlatformStats()GET /v1/platform/statsPlatform totalsgetMintPool()GET /v1/mint-poolVanity (...JUST) mint pool statusgetLaunchMetadata()GET /v1/meta/{id}Metadata JSON by launch id (the uri stored on chain)getQuote()GET /v1/quoteQuote a buy or sell (exact in) on the curve or the DAMM v2 poolbuildSwap()POST /v1/swapBuild an unsigned v0 swap transaction for a walletsubmitSwap()POST /v1/submitRelay a signed swap built by POST /v1/swapgetSwap()GET /v1/swaps/{id}Status of a swap built through the APIgetTransactionStatus()GET /v1/tx/{signature}Status of any transaction signature (and the swap or launch it belongs to)buildLaunch()POST /v1/launchesBuild a launch exactly like the site doessubmitLaunch()POST /v1/launches/{id}/submitSend a signed launch (Jito, private)getLaunch()GET /v1/launches/{id}Launch statuscreateWebhook()POST /v1/webhooksRegister a webhook (the secret is shown once)listWebhooks()GET /v1/webhooksWebhooks of this API keygetWebhook()GET /v1/webhooks/{id}One webhookupdateWebhook()PATCH /v1/webhooks/{id}Change a webhook; enabled=true re-enables one that was disableddeleteWebhook()DELETE /v1/webhooks/{id}Delete a webhook and its delivery loglistWebhookDeliveries()GET /v1/webhooks/{id}/deliveriesDelivery log, newest firsttestWebhook()POST /v1/webhooks/{id}/testSend one signed webhook.test delivery nowcreateFreeKey()POST /v1/keysSelf-serve: a wallet signs a message and gets a free-tier keygetMyKey()GET /v1/keys/meThe calling key, its tier and limitsrevokeMyKey()DELETE /v1/keys/meRevoke the calling key (its webhooks stop)

Errors

ts
import { JustiError } from "@justifun/sdk";
try {
  await justi.buy({ mint, sol: 1, signer });
} catch (e) {
  if (e instanceof JustiError) console.log(e.code, e.status, e.message, e.details, e.retryAfter);
}

Runtimes

Node 18+, browsers, Bun, Deno, Cloudflare Workers and Vercel Edge. Signing and webhook checks use Web Crypto (Ed25519, HMAC). Node 18 and 20 have no global WebSocket: pass { WebSocket } from the ws package to subscribe.

Source
Examples in the repo: a Node launch script, a Telegram-style buy bot, and Next.js route handlers for webhooks and swaps.