The TypeScript SDK
Build a hook, a companion or both for a launch on Bordrless from your own terminal, or anything on the standard: the TypeScript SDK builds every instruction of the programs, decodes every account and event, and resolves a hook's accounts.
Start here#
- What you build
- A hook: your program, run inside every trade of the token, which takes a cut, refuses, or writes what it wants into each holding. A companion: your program too, a script that Bordrless’s companion program calls with the launch’s accounts to spend the companion fee, its pot. Or both, as a pair: the hook records at transfer time, the script reads the record and pays.
- Two lanes
- The Workshop: you submit the source; Bordrless checks it, deploys it under its own key and lists it, and you earn the share you choose of every launch someone else makes with it: for a hook, 0% to 50% of the creator fee in 5% steps; for a companion or a pair, half of the launcher’s part of the creator fee, or nothing. Self-serve: you deploy it, make it immutable, make a config and paste its key on the launch page (a script: launch with it through the SDK or the API). The site shows a Workshop program with Bordrless’s reading of it; one deployed outside it as not read by Bordrless, unless you submit its source with its address for the reading.
- Your agent
- Build with your agent has the brief to paste into Claude Code, Cursor or any coding agent for a hook, a companion or a pair: the template, every rule, the test plan, the Workshop.
The two layers#
A hook runs inside the trade: the token program calls it before and after every transfer, mint and burn of the token and applies its answer (up to three cuts, a refusal, 64 bytes of state in each holding); it never holds money and never gets anyone’s signature. A companion never runs inside a trade: Bordrless’s companion program holds the launch’s companion fee in a pot and calls your script on a timer with the launch’s accounts (the mint, the launch, the companion, the pool, your state, then whatever the sender passed); your script reads whatever it likes, its hook’s data in the holdings, the pool, its own state, and acts as the companion address, and Bordrless’s program executes that inside hard bounds: it trades on the launch pool, buys back and burns, pays holders or wallets from the pot within the terms the launch fixed when the script answers a payout, and refuses a step that spends more than the pot, touches the dev bag, takes the companion address’s rent or breaks custody. Bordrless’s program is never upgraded for a builder’s program, only for a new kind of action.
Install#
npm install @bordrless/sdk @bordrless/shared
Both on npm; the IDLs ship inside the package. The current release is 0.14.0 (15 Oct 2026: native SOL, swap_v2 and router.swapV2; the package’s CHANGELOG says what each release holds). The next release, with companion.setPayoutTerms, is pending: until it is published, an export named here may be missing from npm. New to the standard? Start with why Bordrless.
For your coding agent#
Building a custom hook to launch with on Bordrless? Build with your agent has a brief for a hook, one for a companion and one for a pair, and takes you through testing it and submitting it to the Workshop, or deploying it yourself. The prompt below is for building anything else on the standard with the SDK.
You are helping me build on Bordrless, a token standard of its own on Solana: not Token-2022, not SPL.
Tokens live in the Bordrless token program, which calls a mint's hook before and after every transfer, mint
and burn and applies what the hook answers; the Bordrless DEX does the same with pool hooks on every swap.
INSTALL (published on npm; the IDLs ship inside the package):
npm install @bordrless/sdk @bordrless/shared
IMPORTS (real export names):
import { token, swap, bridge, launch, kit } from '@bordrless/sdk'; // instruction builders
import { holdingAddress, poolAddress, launchAddress, registryAddress } from '@bordrless/sdk'; // PDAs
import { decodeMint, decodeHolding, decodePool, decodeLaunch, fetchAccount } from '@bordrless/sdk'; // decoders
import { eventsOf, typedEvent, explainFailure } from '@bordrless/sdk'; // events, errors
import { fetchTokenHook, tokenHookOf, resolveHookAccounts, kitTokenHook } from '@bordrless/sdk'; // hook accounts
import { buildV0Transaction, protocolLookupTable } from '@bordrless/sdk'; // v0 transactions
import { buildCreateConfig, inspectConfig, taxHook, TAX_HOOK_FLAGS } from '@bordrless/sdk'; // build your own
import { companion, companionAddress, companionCreatorAddress, decodeCompanion, companionVested,
COMPANION_TEMPLATES, COMPANION_DEFAULTS, companionReady } from '@bordrless/sdk'; // companions
import { decodeScript, decodeApproval, inspectScriptProgram, scriptDue, scriptClaimAuthor,
scriptInitDataBytes, templateHook, buildCreateListedConfig } from '@bordrless/sdk'; // custom companions, your hook
import { checkKeeperJson, checkHookJson, encodePayoutAnswer, decodePayoutTerms } from '@bordrless/sdk'; // keeper.json, hook.json, payouts
import { PROGRAM_IDS, TOKEN_HOOK_FLAGS, POOL_HOOK_FLAGS } from '@bordrless/shared';
NATIVE SOL (since 15 Oct 2026 launches, pools and pots are native SOL, lamports; bridged SOL only on coins launched
before; same pool addresses, quote_mint stays A49oVh…):
decodePool(data).quoteNative / decodeLaunch(data).isNative tell a native pool or launch.
launch.swap(launchKeysOf(decodedLaunch), trader, recipient, dir, amountIn, minOut) builds swap_v2 for a native launch
(wallet pays the buy, a sell delivers SOL to the recipient wallet: no wrap/unwrap); launch.swapV2 / swap.swapV2 build it explicitly.
router.swapV2 wraps a DEX swap_v2 with an integrator fee in SOL. Claims: launch.claimCreatorFeesSol, kit.claimSol.
The old swap keeps working on a native pool through its bridged-SOL buffer; what the buffer can't cover of a sell is paid as SOL to the
trader's wallet only for a top-level swap by the delivery holding's owner on a native launch, else it fails with BufferShort (CPI callers, held coins:
use swap_v2; launch.swap(launchKeysOf(l, hook, { poolNative: pool.quoteNative })) does).
PROGRAM IDS (one set: the same on mainnet, devnet and localnet):
token 2XoEWp8cF3kRXg74eVwPAyTFhVCAztn3V88komxAvr22
DEX GyzKSnnEu2uN5bBRecE4XYY2enbfR2D2MtxnbJPGy7hk
bridge CtLkuFVitoXHTa86Hfp8KmfSDfqJaMYFWr6EGmQVsKb7
launchpad 1jcBymHxBjniZDhNPy51Vgm5Nz7pLUdxa9UBHc4TavC
kit 14RJQXPdJfkehit6ezktjd3xujamf8nVSKw2shKamaEH
tax_hook 8tjnVSreJGBRQFyDBf1SyyhBgLsdBxa2rHYh9sbxFyX7
companion 6ZUM1gWBH9hBBNoJoaVAGwSftyZ6CUda6vUZTW9MsJuo
CLUSTER: the programs are live on mainnet; the RPC from SOLANA_RPC_URL (any Solana RPC, e.g. Helius).
HOOKS: a hook is an ordinary Solana program written against the Rust crate bordrless-hook (crates/bordrless-hook).
A token hook implements before_/after_ transfer, mint, burn; a pool hook before_/after_ initialize, add_liquidity,
remove_liquidity, swap. A before_* callback (and a pool's after_swap) returns, in its return data:
pub struct HookReturn {
pub deltas: Vec<Delta>, // up to 3 cuts { amount: u64, account: u8 } from the amount
pub burn: u64, // pool swap callbacks only
pub lp_fee_bps: Option<u16>, // before_swap only
pub source_hook_data: Option<[u8; 64]>, // token callbacks only: the holding's 64 bytes of hook state
pub destination_hook_data: Option<[u8; 64]>,
}
A mint's hook_flags (TOKEN_HOOK_FLAGS) say which callbacks run and what they may answer; Pool.hook_flags likewise.
REGISTRY: extra accounts a hook needs are published at PDA(["bordrless-hook-accounts", mint-or-pool], hook_program)
as a HookAccountList of fixed keys and PDAs; the SDK resolves it (fetchTokenHook) and appends them after the 5 fixed
accounts (hook signer, mint, source, destination, authority).
RULE: a hook never gets the user's signature. It answers, and the token program (or the DEX) checks and applies the
answer, never more than the amount being moved, signing every call with PDA(["hook-authority", hook_program]).
PUT A HOOK ON A MINT: token.createMint(payer, mint, { ..., hookProgram, hookFlags, hookAuthority }) names it;
token.setHook changes it while a hook authority is held; token.setAuthority(authority, mint, 'hook', null) locks it.
Every transfer of a hooked mint takes the hook's accounts: token.transfer(auth, src, dst, mint, amount, hook).
LAUNCH IT ON THE LAUNCHPAD (build your own): the rules travel in a LaunchConfig account made once with
buildCreateConfig(creator, { rules, creatorFeeBps, customHook, customHookFlags, label }) from '@bordrless/sdk'
(send its instruction signed by the creator and its keypair; its address is pasted into the launch page under
"Custom config"). The launch creates the mint, so prepare the hook for the mint address the page shows first:
its registry at PDA(["bordrless-hook-accounts", mint], hook) (taxHook.prepare is the worked example; a hook on
the Workshop's template has the standard prepare: templateHook.prepare(hook, payer, mint)). A config with a hook
may have burn and a creator fee, not holder rewards, max wallet or the locks (one token hook per mint).
inspectTokenHook(connection, hook, mint) and inspectConfig(connection, config, mint) run the page's checks.
buildCreateListedConfig(creator, args, 5000) makes a listed config: the share named (1 to 5000 bps; 5000 is half,
the most) of the creator fee of every launch someone else makes from it goes to its creator. Bordrless takes 25% of what a launch's rules collect on each
swap (creator fee, holder rewards, your hook's cuts), in SOL; a config can't change that.
TWO LANES: this one, self-serve, where nobody reads the code: the site shows such a token's hook as a custom
hook written by its creator, with who can upgrade it and no reading (not read by Bordrless, unless its source is
submitted with its address on https://bordrless.app/workshop/submit: the reading lane). Or the Workshop
(https://bordrless.app/workshop, the briefs on https://bordrless.app/sdk/build): the builder submits the source, Bordrless
checks it (the template's rules, the build, a trading test, one reading by AI that states its rules as exact rows
and judges the code), approves it by itself once the rules, the build and the trading test pass, deploys it under
its own key and lists it, and the site shows Bordrless's reading of it; a hook's builder earns the share they chose
at the submission, 0% to 50% of the creator fee in 5% steps, of every launch someone else makes with it (a
companion's or a pair's builder: half of the launcher's part of the creator fee, or nothing). The chain takes both
lanes.
UPGRADE AUTHORITY (required to launch from a config): the hook program MUST be immutable, or upgradeable only by
Bordrless (CS1NRyXNCPxEUP4CRoa26cHQSeSJCxXh5SPijwFhDW6W or 5xsibKwtiN6ruxsYrEyWVpV3KcwuzSPbQd1n28a7spEd). The launch program's create_config refuses any other hook
(HookUpgradeable). Right after deploying your own hook, make it immutable (signed by its current upgrade authority):
solana program set-upgrade-authority <PROGRAM_ID> --final
A config made before that rule whose hook someone else can upgrade can't launch either: the launch page says
"This config’s hook can be upgraded by someone outside Bordrless, so it can’t launch here." and the API answers 400 hook_upgrade_authority. Check it
before making the config: `solana program show <PROGRAM_ID>` shows the Authority (inspectTokenHook and
inspectConfig say so too). Hooks deployed through the Workshop are held by Bordrless's key. Do not keep the
authority yourself.
COMPANIONS (live on mainnet): a launch whose creator is a program. The companion creates the launch and signs as
its creator from the companion address, companionCreatorAddress(mint) = PDA(["creator", mint], companion), so the
launch's whole fee lands with it and only its code spends it, by a split fixed at create. Its account:
companionAddress(mint) = PDA(["companion", mint]).
THE SPLIT of every fee claim: { buybackBps, holdersBps, beneficiaryBps } (a script's or a game's potBps beside them),
whole basis points summing to 10,000 (bought back and burned / streamed to holders through the kit / paid to the
launcher in SOL / the pot). On chain a launch has one creatorFeeBps, the whole fee; the launch page shows it as two
rows: "Creator fee", the launcher's part (beneficiaryBps), and "Companion fee", the part the companion spends (the
rest): each row 0, 0.5%, 1% or 2% (the Companion fee from 0.5%), together at most 5% of a trade, 1% by default;
a Workshop config's fee is any quarter percent up to 5%. The page's old choice "where the creator fee goes"
(You, Buy back & burn, Holders, Split) is gone; its splits remain only on older coins.
TEMPLATES (COMPANION_TEMPLATES; preset splits, accepted by name too):
buysItself buyback+burn 100% / holders 0% / launcher 0%; no dev, no first buy
rugProofDev buyback+burn 0% / holders 50% / launcher 50%; first buy vests to the launcher; needs holder rewards on
buybackAndReward buyback+burn 50% / holders 50% / launcher 0%; first buy vests to the launcher; needs holder rewards on
LAUNCH WITH ONE THROUGH THE API (base https://bordrless.app/api; what the launch page does):
1. POST upload (multipart: image, creator, mint, name, symbol, description) -> { uploadId }.
2. POST launch/prepare with { creator, mint, uploadId, creatorFeeBps (the whole fee: 0, 50, 100
or 200; with a companion the creator row plus the companion row, 50, 100 or 200), devBuyLamports, rules,
companion: { split: { buybackBps, holdersBps, beneficiaryBps }, vestDays? } } (or { template, vestDays? }; vestDays
0-365, default 30) -> { intentId, transactions, devBuyMaxLamports }.
The transactions are, in stage order: "Set up the companion" (companion.create), the launch, the first buy.
3. Sign each (base64; legacy or v0 per its version) with the wallet, then the mint keypair where extraSigners
includes 'mint'; POST tx/submit { transactions: [{ transaction, stage, label }], intentId }; poll
GET tx/submission/:id until state is no longer 'pending'.
RULES (the API answers 400 companion_rules otherwise): the shares sum to 10,000; creatorFeeBps above 0; no creator
wallet lock (creatorLockDays 0: the companion vests the first buy instead); holder rewards on when holdersBps > 0 (and
then the launching wallet must be a plain wallet); a launch config only a plain one (a listed config is refused:
the companion takes no author share), and no holders' share beside a custom hook (one token hook per mint; since
the 2026-10-12 upgrade a companion of any kind may run a token with a custom hook, and every step that moves the
token carries the hook's slice, LaunchKeys.customHook). The first buy is capped by max wallet
(devBuyMaxLamports; 400 max_wallet); a split that buys back everything has no dev, so send no first buy. The
beneficiary is the launching wallet.
LOTTERY COINS (companion v2, live on mainnet; docs/games.md): a companion that runs a lottery. Part of every fee
claim, the companion fee, goes into a pot it holds; each round (15 minutes to 30 days on the site; the program takes 5 minutes) every holder's tokens held since the round began are
their tickets; once it ends, anyone draws (randomness by ORAO VRF) and the pot pays the holder of the drawn ticket
in SOL. The coin's token hook is Bordrless's lottery hook (HqFWsCBQ416DAfevJ9TspyT5yXGGoYTCpcreiGkCgWcr, flags 145), which keeps the
tickets and takes no cut. Launch one through the API as a companion launch with
companion: { split: { buybackBps, holdersBps: 0, beneficiaryBps }, vestDays?, game: { kind: 'lottery', roundSecs
(300-2592000 for the programs; the site offers 900 and up), potBps, minPotLamports ('100000000'-'1000000000000'),
prizeBps (1000-10000), claimWindowSecs (60-86400), maxAttempts (1-16; windows × attempts × 2 ≤ roundSecs) } }
(LOTTERY_DEFAULTS in @bordrless/shared); the split's parts plus potBps sum to 10,000, rules must be NO_RULES (a
lottery coin has no other token rules), creatorFeeBps above 0 and one Bordrless has a lottery launch config
for (503 lottery_off otherwise; mainnet has one for 0.5%, 1% and 2%, LOTTERY_HOOK.launchConfigs in
@bordrless/shared). The transactions: "Set up the lottery" (companion.create, lotteryHook.prepare, companion.createGame;
the mint signs), the launch, the first buy (450k compute units). GET companion/:mint?wallet=<holder> answers
CompanionStatus.game (GameStatus): the pot, the round and its end, the tickets, the holder's tickets and odds, the
draws with each round's ORAO request account. POST game/enter/prepare { wallet, mint } -> the holder's own entry
(their tokens registered as the round's tickets; a trade this round does it too; SDK: lotteryHook.enter(mint,
owner), sent by anyone). Cranking a draw: docs/games.md "A keeper's loop" (companion.draw from fetchSeedSlot, sent
at once without preflight; reveal; claimPrize for findWinningHolding). The site calls this coin the Jackpot. Say it
as the docs do: "randomness by ORAO VRF"; Bordrless's lottery hook has an audited HookStatus on mainnet, so its
pots are not capped and it cannot be blocked; of a game on any other hook: "pot capped at 10 SOL until audited",
"Bordrless can stop this game: its pot would be bought back and burned". Never "provably fair" or "guaranteed".
OTHER GAME KINDS: the companion program also takes kind 'jackpot' (the last buyer before a timer) and 'streak'
(holders who held through an epoch) on a game hook written on the bordrless-game crate (createGameV2, settle,
closeEpoch, claimShare in @bordrless/sdk; docs/games.md "Phase 2"). Bordrless offers no hook for them and the
site does not present them: never offer them as something a user can launch on https://bordrless.app.
SNOWBALL (live on mainnet, docs/snowball.md): a companion whose pot makes volume in its own token. Through the
API: companion: { split, snowball: { potBps, buyStepBps, sellStepBps, buyBps, sellBps, poolBps, interval,
flatTrades } } (SNOWBALL_PRESETS, SNOWBALL_BOUNDS, snowballProblem in @bordrless/shared). Builders:
companion.createSnowball(payer, mint, args) after create and before launch (the mint signs);
companion.snowballStep(cranker, keys) by anyone, once an interval; decodeSnowball, snowballMove(s, c, earlyWindowEnd,
spot, now) says which side a step would trade.
KEEP THE MINT KEYPAIR (write it to disk before signing) until the launch transaction confirms. If "Set up the
companion" landed and the launch didn't, only that key can launch it or take its SOL back: GET companion/:mint
answers { state: 'none' | 'set-up' | 'launched', refundable }; for 'set-up', POST companion/refund/prepare
{ wallet, mint } -> { transaction, refundable }, signed by the wallet then the mint (SDK: companion.refund(sender,
mint, beneficiary), the mint signing). The API won't prepare that mint again: launch with a fresh one.
WITH THE BUILDERS: companion.create(payer, beneficiary, mint, { split (any, or COMPANION_TEMPLATES.<template>),
...COMPANION_DEFAULTS, fund }) signed by payer and mint (fund = the LaunchConfig's launchFeeLamports + 50_000_000
rent + 890_880); then companion.launch(launcher, mint, launch.createLaunch(companionCreatorAddress(mint), mint,
config.treasury, config.quoteMint, config.lpFeeBps, args), args), signed by the launcher and the mint, as a v0
transaction with a lookup table holding PROTOCOL_LOOKUP_TABLE in order (Bordrless keeps one on mainnet:
4vxVcYLdkqT1rMfGHjAu4kMa9XSEhUdQU5ThVfU5grGQ; companionReady(table) must be true; it
doesn't fit without); then optionally companion.devBuy(beneficiary, launchKeys(...), lamports, minOut) within 10 minutes.
CRANK ANY COMPANION (permissionless; each step checks on chain that it is due and pays its sender bountyBps of what
it moves, 0.5% for launches made through the API, at most 1%): companion.claimFees(cranker, mint) (the launch's fees in,
split), companion.buyback(cranker, keys, rewards) (buys on the pool and burns; at most maxBuyback and 1% of the
pool's SOL, buybackInterval apart, waits while the price is over 3% above its reference), companion.share(cranker,
mint) (holders' part into the kit), companion.withdraw(sender, mint, beneficiary) (launcher's part, in SOL),
companion.release(cranker, keys, rewards, beneficiary) (vested first buy). keys = launchKeysOf(decodeLaunch(...)),
rewards = rewardsOn(launchRulesInputOf(launch.rules)). One step a transaction, claimFees first.
READ ONE: decodeCompanion(data) gives split, pendingBuyback, pendingHolders, pendingBeneficiary, lastBuybackAt,
burnedTotal, sharedTotal, paidBeneficiaryTotal, devTokens, devReleased; companionVested(c, now) - c.devReleased is
what release sends now. GET https://bordrless.app/api/launches/:mint answers LaunchDetail.companion with the same figures.
The API takes the three templates; with the builders any split summing to 10,000 bps works (the token page then
names no template).
CUSTOM COMPANIONS (docs/scripts.md; on the launch page, a Workshop companion under "Companion fee"): a companion
program of your own is a script, a program the companion program calls to spend the pot, which the companion fee
fills. Two layers: a hook runs inside every trade
and writes into the holdings; a script never does: Bordrless's companion program holds the pot and calls your
script on a timer with the launch's accounts (companion_init once at the setup with [creator (signer), mint,
state, system program] and up to 512 bytes of init data; companion_step from a minute after the launch, once an
interval of 10 s to a day, with [creator (signer), mint, launch, companion, pool, state] then the sender's extra
accounts, none signing). The script reads what it likes (its hook's data in the holdings, the pool, its state at
scriptStateAddress(mint), up to 10,240 bytes the companion makes for it) and acts as the companion address: it may
trade on the launch pool, buy back, burn; the companion program refuses a step that overspends the pot
(ScriptOverspent), takes the dev bag (ScriptTookDevBag), takes the companion address's rent (ScriptTookLamports; on a
native coin the pot is its lamports above rent) or breaks custody
(ScriptBrokeCustody), or runs code that is neither approved nor immutable (NotApproved). Bordrless's program is
never upgraded for a builder's program, only for a new kind of action; payouts are one: a script made with
companion.createScriptV2 (payout terms) answers a PayoutAnswer (encodePayoutAnswer; a wallet answer with
encodeWalletPayoutAnswer once allowWalletPayouts was sent) that the companion pays from the pot within the terms
and has the hook record (record_payout); companion.payoutAccounts leads such a step's extras. A Workshop script
launches with open payout terms (a step may pay the whole pot) unless its keeper.json's payoutTerms sets them; the
launch's beneficiary or the script approver can change them after launch (companion.setPayoutTerms(authority,
mint, terms)). A script that pays holders ships keeper.json (checkKeeperJson, KEEPER_EXAMPLE: which holdings
Bordrless's keeper brings to each step, and stepSecs, how often it steps; mintWritable true passes the coin's mint
writable in every step, which any burn needs (without it a burn fails the whole step; a burn never reaches the dev
bag); payoutTerms fixes the payout terms; launcherShareBps, 0 to 9,500, fixes the launcher's share of the fee); a
hook with a SOL cut (quote_cut) ships hook.json (checkHookJson, HOOK_JSON_EXAMPLE).
Builders: companion.createScript(payer, mint, { split, potBps, program, interval, stateLen, initData }) after
create and before launch (the mint signs; the four parts sum to 10,000); companion.scriptStep(cranker, keys,
program, extras) by anyone once scriptDue(c, s, now); companion.claimFeesScript(cranker, mint, scriptClaimAuthor(s, c));
companion.createScriptV2(payer, mint, args, terms) for a script with payout terms, companion.setPayoutTerms after launch;
decodeScript at scriptAddress(mint), decodeApproval at approvalAddress(program); inspectScriptProgram(connection,
program) says which lane a program is on ('workshop': approved on chain; 'self-serve': immutable; null: neither,
with the reason). Through the API: companion: { split, script: { potBps, program, interval, initData (hex or
base64), stateLen } } (scriptProblem in @bordrless/shared; 400 script_not_approved otherwise). The Workshop lane:
submit the source at https://bordrless.app/workshop; Bordrless deploys it under its key and approves its code on chain, launchers
pick it under the launch page's "Companion fee" with Bordrless's reading, and the author earns half of the
launcher's part of the creator fee each claim takes (or nothing, as chosen at the submission), paid by the companion
program out of that part, never from the pot. The self-serve lane: deploy it yourself and make it immutable; it
runs with no approval, unreviewed, with no author's share, and the site names it a custom hook (unreviewed). A PAIR
is a hook on the trades and a companion on the pot shipped as one Workshop item (the hook takes a cut, keeps a score
or funds the pot; the companion pays from the pot, filled by the companion fee or by the hook, whose SOL cut lands
whole in the pot): a plain config on the hook (never listed) plus the script in the same setup. The config fixes how
its fee splits between the launcher's creator fee and the companion fee (half each unless its builder sets it;
keeper.json's launcherShareBps wins); the launcher can't adjust the fee or the split. The API's
ConfigInspection.requiredCompanion says which script a config requires (companion_required, config_required
otherwise). A launch whose creator fee goes to a program of your
own instead of the companion program is allowed by the chain and hidden on the site.
STATUS: the programs are live on mainnet and keep an upgrade authority until audited; the SDK is on npm (0.14.0 is
the current release, 15 Oct 2026: native SOL, swap_v2 and router.swapV2; the next release, with
companion.setPayoutTerms, is pending: until it is published, an export named here may be missing from npm).
READ: https://bordrless.app/sdk (the SDK), https://bordrless.app/sdk/build (building with your agent: the briefs, the Workshop),
https://bordrless.app/sdk/hooks (writing a hook), https://bordrless.app/sdk/companions (companions and scripts) and https://bordrless.app/docs (the
standard in full).
SOURCE: the SDK https://github.com/BordrlessDex/bordrless-sdk and the programs with the hook crate https://github.com/BordrlessDex/bordrless-programs; read them before guessing an API.What you can build#
Anything on the standard, not only a hook for Bordrless’s launchpad. The token program, the DEX and the bridge are permissionless; build on Bordrless says what is open, what it costs and what stays Bordrless’s.
- A token
- A mint of your own with a hook of your own, named at creation and locked by revoking the hook authority: token.createMint.
- A hook
- An ordinary Solana program against the crate
bordrless-hook: cuts, hook data and a refusal, and for a pool hook the swap’s fee and a burn: write a hook. - A pool, a launchpad
- An ordinary pool for any pair, or a bonding curve a program of yours opens as its own pool hook and graduates itself: swap.createPool, finalizeCurve. Every cut its hook takes is yours.
- A quote asset
- SOL, an SPL or a Token-2022 token brought into the standard one for one:
bridge.register,bridge.wrap. - A launch here
- A launch on Bordrless’s launchpad with a hook you wrote, from a config: buildCreateConfig; with a companion you wrote, a script: companion.createScript.
What’s in it#
import {
token, swap, bridge, launch, kit, // instruction builders, one object per program
holdingAddress, poolAddress, launchAddress, // every PDA
decodeMint, decodeHolding, decodePool, // typed accounts from the IDL coders
eventsOf, typedEvent, // events from a transaction's inner instructions
fetchTokenHook, kitTokenHook, // a hook's accounts, resolved for one operation
buildV0Transaction, protocolLookupTable, // v0 transactions with the protocol table
explainFailure, // a failed transaction, in words
companion, decodeCompanion, // companions: launch one, crank one, read one
decodeScript, decodeApproval, // a custom companion's script, Bordrless's approval of a program
inspectConfig, inspectScriptProgram, // a config, a script program: what the chain would say
templateHook, buildCreateConfig, // a hook of yours: prepared for the mint, made into a config
checkKeeperJson, checkHookJson, // keeper.json and hook.json, checked as the Workshop checks them
} from '@bordrless/sdk';
| Module | Gives |
|---|---|
instructions.ts | Builders for every program: token, swap, bridge, launch, kit, tax_hook, half_life, in each program’s account order. |
addresses.ts | Program ids and every PDA; the tests hold each fixed one to the value compiled into the programs. |
accounts.ts | Typed accounts: mints, holdings, pools, launches, configs, the kit’s config. Integers as bigint. |
hooks.ts | A hook’s registry: decode, encode, and resolve it for one operation, as the Rust does. |
template.ts | The hook template’s standard prepare (templateHook.prepare), for a hook you deployed yourself. |
events.ts | Events from a transaction’s inner instructions, in execution order. |
errors.ts | Program errors in words, keyed by the program that failed. |
transactions.ts | v0 transactions with the protocol lookup table: create_launch with kit rules only fits with it (1,042 bytes, 1,366 without). |
inspect.ts | A LaunchConfig read and checked as create_launch checks it (inspectConfig, inspectTokenHook), and buildCreateConfig or buildCreateListedConfig to make one. |
companion.ts | Companions: create, launch, the dev buy, every permissionless step, the refund, the games, Snowball, and the account decoded. |
scripts.ts | Custom companions: createScript, scriptStep, claimFeesScript, the approvals (approve, revokeApproval), decodeScript, decodeApproval, inspectScriptProgram. |
snowball.ts | Snowball, the market-maker companion: its terms, decodeSnowball, and snowballMove (which side a step would trade). |
router.ts | Your app’s fee on any DEX swap: router.swapV2 wraps a native swap (router.swap a classic one), routerTreasuryQuote and routerFeeSplit. |
balances.ts | SPL-shaped pre and post balances of Bordrless holdings from any transaction (tokenBalanceChanges), decimals read from the mint. |
cli/ | bordrless mm, a market maker you run on your own fee wallet; bordrless hook and strategy: deploy immutable or timelocked, status, verify. |
keeper.ts | keeper.json, what a companion asks Bordrless’s keeper to bring to each step: checkKeeperJson (the Workshop’s own check), KEEPER_EXAMPLE, the schema and its words. |
hookDeclaration.ts | hook.json, the caps of a hook’s SOL cut: checkHookJson, HOOK_JSON_EXAMPLE, the schema and its words. |
lossCover.ts | The companion’s payout path: encodePayoutAnswer, encodeWalletPayoutAnswer, decodePayoutTerms, PAYOUT_LIMITS; and Lossback’s own hook and script. |
coders.ts | Borsh coders from the programs’ IDLs: no layout is written by hand. |
Status#
- Package
- @bordrless/sdk and @bordrless/shared on npm; 0.14.0 is the current release (15 Oct 2026, native SOL; the CHANGELOG says what it holds). The next release is pending.
- Programs
- Live on mainnet, one set of ids on every cluster; upgradeable until audited (who holds each key).
- Your hook
- Goes on a mint you create or a pool your program opens, with nobody’s permission; or launches from a config once nobody outside Bordrless can upgrade it (deploying it), shown as not read by Bordrless; or goes through the Workshop, which reads it, deploys it and lists it.
- Your companion
- A script the companion program calls (custom companions): through the Workshop, approved on chain; or deployed by you and made immutable, which the companion program runs with no approval. A launch whose creator fee goes to a program of your own instead is allowed by the chain and hidden on the site.
- Companions
- Live on mainnet: launch with one, crank any, Jackpot and Snowball included (companions).
- Tested
- Every builder against the IDLs and the programs’ vectors, v0 sizes to the byte, layouts, events and errors through the coders, and the hook crate’s checks.