Documentation

Own the index,
not the complexity.

bskts are fixed-quantity index tokens on Robinhood Chain (an Arbitrum Orbit L2, chain id 4663). Each basket is an ERC-20 whose supply is a proportional claim on a fixed set of Stock Tokens and crypto held in an on-chain vault. You buy and redeem at net asset value, from your own bskts account with the gas paid for you, and the protocol never custodies your funds. This page is the complete guide.

01

Overview

Every basket bundles a fixed quantity of each constituent per unit. Hold one unit of DIGI64 and you hold a fixed amount of the S&P 500 token and of ETH — not a re-weighted slice that silently changes underneath you. Weights drift as prices move; scheduled rebalances restore targets without hiding that drift.

bskts is non-custodial by construction. Buying swaps USDG into the exact constituents and deposits them; redeeming returns the constituents (or swaps them back). The contract holding your assets never touches a DEX on your behalf, and you can always exit in kind.

Three primitives do the core work: the Vault holds the assets and is the index token, the Zapper converts USDG to and from the basket, and the NavOracle prices everything from on-chain pools. Your bskts account, a Safe that only you control, holds your USDG and baskets and trades without a popup per trade. Resting orders are held by ownerless escrow contracts that anyone may fill under price floors you set.
02

Getting started

  1. Log in with email, Google, X, GitHub, a passkey or an existing wallet. There is no password to keep: a wallet is created for you if you don’t bring one.
  2. Create your account — one signature. It deploys your bskts account (a Safe owned by your login wallet) and sets up instant trading on this browser. bskts pays the gas.
  3. Add funds with Deposit on your portfolio: USDG on Robinhood Chain, USDC bridged from Base, Arbitrum, Optimism or Ethereum, or a card (deposits & wallets).
  4. Buy a basket from any market page. It fills in seconds with no wallet popup.

You can also trade directly from a connected wallet on Robinhood Chain; you then sign each transaction and pay its gas in ETH yourself.

03

Accounts & gasless trading

Your bskts account is a Safe smart account deployed for your login wallet by the AccountFactory. Your wallet is its only owner: only you can withdraw, and you can withdraw everything at any time, with or without bskts. Withdrawing through bskts is gasless and costs a flat $1, taken from the amount ($100 out, $99 arrives); basket units pay the same $1 in USDG. Doing it directly from your Safe costs only your own gas.

Instant trading (session keys)

Creating the account also installs a session key that lives only in this browser. The BsktsSessionModule lets it do a fixed set of things and nothing else: buy, sell, place and cancel limit and exit orders, and stop a recurring buy. It can never withdraw or send funds anywhere. On-chain limits bound it further:

  • it expires after 30 days (the app renews it with one signature when a week is left);
  • every trade is capped at 3.00% slippage, and daily volume is capped, so even a stolen browser key could only trade your funds inside your own account, within those bounds;
  • you can revoke it, and a new browser simply gets a key of its own.

Gasless, with a network fee in USDG

Trades from your account are relayed: bskts submits them and pays the gas in ETH. Each trade adds a small network fee in USDG to the same transaction, the trade’s own gas at the current base fee, priced from the WETH/USDG pool. It is shown before you confirm. Account trades have a $5 minimum (selling your whole position can be smaller, so nothing gets stuck). The relayer can only submit transactions you or your session key signed; it cannot move your funds.

05

The baskets

TickerNameConstituentsRebalanceMgmt fee
DIGI64Digital 60/40SPY 60% · ETH 40%monthly0.65%/yr
MAG6Mega-cap TechNVDA 17% · AAPL 17% · MSFT 17% · GOOGL 17% · META 17% · TSLA 17%quarterly0.75%/yr
INDEX2Broad BetaSPY 50% · QQQ 50%quarterly0.50%/yr
FRONTIERMoonshot GrowthSPCX 33% · TSLA 33% · NVDA 33%quarterly0.95%/yr
CRYPTOEQCrypto ComplexCOIN 25% · MSTR 25% · CRCL 25% · ETH 25%monthly0.95%/yr
OPUSAI CoreNVDA 50% · MSFT 30% · GOOGL 20%quarterly0.85%/yr
FABLEAI CapexMU 30% · TSM 25% · AMD 20% · INTC 15% · SNDK 10%quarterly0.75%/yr
ORBITBTC, Space & NasdaqcbBTC 33% · SPCX 33% · QQQ 33%quarterly0.95%/yr
MAXBETAHigh-Volatility FourTSLA 25% · MSTR 25% · COIN 25% · SPCX 25%quarterly0.85%/yr
SILICONChipmaker TrioNVDA 33% · AMD 33% · TSM 33%quarterly0.75%/yr
ETHSTACKEthereum EconomyETH 50% · COIN 25% · CRCL 25%monthly0.75%/yr
NATIVERobinhood OriginalsPONS 25% · UP 25% · ETH 25% · cbBTC 25%monthly0.95%/yr
HARDHard AssetsGLD 50% · cbBTC 25% · SLV 15% · USO 10%monthly0.75%/yr
BEDROCKAll WeatherSPY 34% · SGOV 33% · GLD 33%monthly0.50%/yr
TURBOLeveraged TechNVDAx3L 40% · MSTR 30% · SPCX 30%monthly0.95%/yr

Weights shown are targets. Between rebalances, live weights drift with price; each market page shows the real drift against target for every constituent.

Higher-risk baskets. NATIVE: Holds Robinhood Chain’s own native tokens rather than Stock Tokens. Two have no published price feed — they’re valued from their own liquidity pools — so expect thinner liquidity and wider spreads than a common basket. TURBO: Holds NVDAx3L, a daily-reset 3x leveraged NVIDIA token issued by Lighter × Long. Its issuer can pause or upgrade it with a single key, and a pause would block every TURBO sell and redemption — including the MSTR and SPCX legs — until it is lifted. Leveraged tokens also lose value in choppy markets. Size positions accordingly.

BSKTS, the whole shelf in one token

BSKTS is a basket of baskets: an index vault whose constituents are other baskets’ shares rather than raw assets, so one token holds a slice of the shelf. It prices and redeems the same way — in kind, it returns the basket shares it holds.

06

Buying & swapping

Buy with USDG. The Zapper routes it through each constituent’s deepest Uniswap pool into the exact quantities the vault needs, then mints your units. It takes the mint fee (0.20%) off the top and sizes the mint by the vault’s live composition, sweeping any dust back to you — it holds nothing between calls.

Your protection is a minimum you agree to before signing, enforced on-chain, so you can never receive fewer units than quoted. Each leg is quoted independently; an unreliable route is rejected rather than filled at a bad price. From your account there is nothing to approve and no popup. From a connected wallet, the first USDG buy needs a one-time approval, and you can also pay with ETH.

Swap buys and sells any basket against USDG, and switches directly from one basket to another in a single step.

07

Deposits & wallets

Up to three addresses take part in a deposit. Knowing which is which makes the Deposit screen simple:

  • Your bskts account — the Safe that holds your USDG and your baskets, and where every trade runs. Every deposit ends up here, whatever it is sent from. Its address is on your portfolio under Cash, and it is your deposit address.
  • Your login wallet — the account’s owner: the key that set it up and signs withdrawals. If you logged in with MetaMask or another wallet, it is that wallet. If you logged in with email, Google, X, GitHub or a passkey, it is a wallet made for you at sign-up. It is a key, not a place to keep money, so it is normally empty, and the Deposit screen doesn’t offer it as a place to send from.
  • The wallet you send from — any wallet that holds the money. It can be your login wallet, or a different one you connect just for the deposit. Connecting it does not link it to your login and does not change your account.

Ways to add funds

  • USDG from your login wallet (wallet logins): one signature, no fee, and bskts pays the gas.
  • USDG from another wallet: a plain transfer into your account. No bskts fee; that wallet pays a few cents of Robinhood Chain gas in ETH.
  • USDC from Base, Arbitrum, Optimism or Ethereum, from your login wallet or another: bridged by Across and delivered as USDG (below).
  • Card or Apple Pay (email and social logins): USDC bought on Base through Stripe or MoonPay, then bridged into your account. For now that last step needs a little ETH on Base for gas; covering it for you is coming.
  • From an exchange: withdraw USDG on Robinhood Chain to your account address. Send nothing else there, and no other network.

One login, one account

Your account belongs to the wallet you first logged in with. Logging in a different way as a new user gives you a different account, with its own balance and baskets. Adding another login method later (under Ways to log in) never changes the owner: it is another way into the same account.

Cross-chain deposits

You don’t need funds on Robinhood Chain first. Bridge USDC from Base, Arbitrum, Optimism or Ethereum: Across delivers it as USDG straight into your bskts account, usually within seconds. You pay the source chain’s gas and Across’s fee (about 0.25%, shown before you confirm); if Across can’t fill, it refunds the USDC to your wallet.

Deposits are the only cross-chain step: once the USDG is in your account, every trade pays from it, on Robinhood Chain.

Before accounts (until 2026-09-29) a wallet could pay for a basket straight from those chains through the IntentEscrow. That path is closed to new orders; any intent that never filled still rests in the escrow and is withdrawable by you at any time. Nothing can get stuck.
08

Orders

Besides a market buy (fill now), every market page offers resting orders. All of them are held by ownerless contracts, and anyone may fill a triggered order for a small fee — so none of them depends on bskts staying online — but only at or better than a price floor you agreed to.

  • Limit buy — your USDG is escrowed in the LimitEscrow now and fills when NAV reaches your trigger (leave it out for a market order). The floor is priced at fill time: the better of spot and the reference NAV, opening near the basket’s quoted cost and easing, only while nobody can fill, to at most 3.00%. Withdraw it any time before it fills.
  • TWAP and Recurring — a schedule on the SpendPermitManagerV4: a fixed buy each period, capped in total and per period, until it ends or you stop it. The USDG stays in your account or wallet until each buy runs, and every buy has the same kind of floor.
  • Stop-loss, take-profit and brackets — on a basket you hold, arm an exit on the SellEscrowV4: the shares are escrowed and sold to USDG when the reference NAV crosses your level (a bracket is one-cancels-the-other). The sale must return at least NAV less the basket’s quoted trading cost plus 0.45% (0.5% at the least), easing toward 3% only while nobody can fill. Cancel it any time.

Whoever fills a triggered order earns the filler fee (see Fees). Orders are unavailable for a basket holding a token with no pool price history yet (today TURBO), because the time-weighted trigger has nothing to read.

09

Redemption

Redemption is always open and can never be paused — and it never reads the oracle for its accounting, so you can exit even while prices are frozen. Two ways out:

  • In kind — receive every underlying constituent token, proportional to your units. No swap, no slippage, free.
  • Sell to USDG — the Zapper sells each constituent to USDG through its pool in one step, net of the zap-out fee (0.20%) and slippage.

Redeem amounts round down so the vault stays solvent: the whole supply can always be redeemed without exceeding what the vault holds.

10

Fees

FeeAmountWhen
Mint0.20%Off the top when you buy, to the bskts treasury.
Zap-out0.20%On the proceeds when you sell to USDG, to the treasury. In-kind redemption is free.
Management0.50%–0.95%/yrPer basket (see the table above), streamed continuously as newly minted shares to the treasury — it never touches custody.
Filler feemax($0.25, 0.15%), ≤ 1%On resting orders and scheduled buys, to whoever executes them, covering the fill’s gas.
Network feegas, in USDGOn account trades: that trade’s own gas, charged in USDG in the same transaction, shown before you confirm.
Withdrawal$1Per withdrawal from your bskts account through bskts, USDG or basket units, to the bskts relayer, which pays the gas for every account. For USDG it comes out of the amount.
Bridge~0.25%Across’s fee on cross-chain deposits, quoted live.

Where the fees go

Mint, zap-out, management and network fees go to the bskts treasury. The $1 withdrawal fee goes to the bskts relayer, the wallet that pays the gas for every account’s trades and withdrawals. (Until 2026-09-08 the mint and zap-out fees were recycled into each basket through per-basket FeeDistributor contracts; that was retired, and nothing feeds those contracts any more.)

11

Architecture

  • BasketFactory — deploys vaults and owns the NavOracle. Register a constituent (token + its pool price feed) here, then create baskets from registered constituents only. Assets are pinned by address, never resolved by symbol.
  • BasketVault — the ERC-20 index token and the custody core. Only in-kind mint and redeem live here; all swapping is peripheral, so the contract holding assets never touches a DEX.
  • ZapperV2 and the Router — the swap periphery: USDG ↔ basket through pinned pools, with per-leg token checks and a full dust sweep back to you.
  • NavOracle, PoolPriceFeeds and PoolPrices — pool-derived pricing: spot from each asset’s deepest pool, cross-checked against a second venue; PoolPrices gives the reference for order triggers and floors (10-minute pool averages, or the live pool price for a v4-only token), read through the PriceRouter.
  • LimitEscrow, SellEscrowV4 and SpendPermitManagerV4 — ownerless order contracts for limit buys, exits and recurring / TWAP schedules. Anyone may execute; floors are enforced on-chain.
  • IntentEscrow — settlement for cross-chain buys from a wallet.
  • AccountFactory and BsktsSessionModule — your Safe account and its browser-only trading keys.
  • IndexVault and IndexZapper — BSKTS, the basket of baskets.
  • BasketSwapRouter — switches directly between baskets.

Off-chain, a relayer submits your account’s signed transactions and pays their gas, and a keeper indexes orders and fills triggered ones (as anyone may). Neither can move your funds.

12

Security model

  • Solvency by rounding — mint rounds amounts up, redeem rounds down; custody stays proportional, so redeeming the whole supply can never exceed the vault’s balances.
  • Unconditional exit — redeem never reads the oracle and has no pause. Holders can always leave in kind.
  • Pool prices only — no external price feed anywhere; every price is read from the asset’s own pools, cross-checked, and orders trigger on a 10-minute pool average no single transaction can move (a v4-only token, which has no average to read, is taken at its live pool price).
  • Your account, your keys — only your wallet can withdraw from your account. Session keys can only trade inside it, within expiry, slippage and daily caps; the relayer can only submit what you signed.
  • Ownerless order contracts — the escrows and schedule manager have no admin, no pause and no upgrade path. Anyone may fill, but every fill is held to a floor you agreed to, priced on-chain rather than by the route the filler chose.
  • Segregated liability — a fill can take exactly one order’s escrowed amount; no path nets one order against another.
  • Inflation-attack floor — the first mint burns a small amount of dead shares, neutralizing the classic first-depositor share-price attack.
  • Address-pinned constituents — because impersonator tokens share real symbols and names on-chain, baskets reference every asset by address only.
13

Contract addresses

Live on Robinhood Chain (id 4663). Tap any address to open it in the block explorer. Every contract below is exact-match verified on Sourcify: its deployed bytecode matches the bskts source exactly, metadata hash included. Check any address yourself at repo.sourcify.dev/4663/<address>. The Robinhood Chain explorer attaches source by bytecode similarity and may show an unrelated contract, so Sourcify is the authoritative record.

Core

Orders

Accounts

Basket vaults

Earlier versions (read-only: existing orders can still be cancelled)

14

Developers & agents

Everything you can trade in the app is open to code and AI agents, through an MCP server, a TypeScript SDK and a REST API. All three follow one rule: nothing is ever signed or sent for you. They read markets and accounts and prepare transactions; your wallet signs each one.

Connect an AI agent (MCP)

bskts runs a Model Context Protocol server at https://api.bskts.xyz/mcp. Add it to Claude, ChatGPT, Cursor or any MCP client, and your agent can read the baskets, check a wallet, and prepare buys, sells and orders for you to sign. No install, no key, no account.

Claude Code

claude mcp add --transport http bskts https://api.bskts.xyz/mcp

Cursor and other clients (mcpServers config)

{ "mcpServers": { "bskts": { "url": "https://api.bskts.xyz/mcp" } } }
  • Claude (desktop and web): Settings → Connectors → Add custom connector, and paste the URL.
  • ChatGPT: on plans with Developer mode, add a custom connector with the URL and no authentication.

To set your own limits, run it on your machine instead. The agent then can’t prepare a trade above your size cap or outside the baskets you allow:

Local, with limits

{ "mcpServers": { "bskts": {
  "command": "npx", "args": ["-y", "@bskts/mcp"],
  "env": { "BSKTS_MAX_USD_PER_TRADE": "100", "BSKTS_ALLOWED_TICKERS": "DIGI64,MAG6" }
} } }

The tools:

  • bskts_markets, bskts_basket: every basket’s NAV, 24h change and buy cost; one basket’s holdings, risk note and recent performance.
  • bskts_account: a wallet’s USDG, ETH for gas, positions with PnL and open orders.
  • bskts_buy, bskts_sell, bskts_order: prepare a buy, a sale to USDG, a limit buy, a stop-loss / take-profit, or a cancel.
  • bskts_guide: the full trading guide, read on demand.
Your agent proposes, your wallet signs. A prepared trade comes back as an optional token approval and then the trade itself, with a dry run of it from your address. Sign the approval first, then the trade, and never send one whose dry run failed. These wallet tools trade from a regular wallet and pay gas in ETH. An agent trading from your bskts account (below) needs no ETH: network fees come out of the account’s USDG.

TypeScript SDK

@bskts/sdk is a typed client for the API, for your own app, bot or agent: every response checked against its schema, amounts as exact bigints, a dry-run guard and optional limits. It signs through viem, in a browser or on a server.

npm i @bskts/sdk viem

import { BsktsClient, robinhood, viemSender } from "@bskts/sdk";
import { createPublicClient, createWalletClient, custom } from "viem";

const wallet = createWalletClient({ chain: robinhood, transport: custom(window.ethereum) });
const [address] = await wallet.requestAddresses();
const sender = viemSender(
  createWalletClient({ account: address, chain: robinhood, transport: custom(window.ethereum) }),
  createPublicClient({ chain: robinhood, transport: custom(window.ethereum) }),
);

// guard rails, checked before anything is built
const bskts = new BsktsClient({ policy: { maxUsdPerTrade: 250 } });

const { markets } = await bskts.markets();        // NAV, 24h change, buy cost
const account = await bskts.wallet(address);      // USDG, ETH for gas

// buy $100: approval first if needed, then the buy (your wallet signs both)
await bskts.execute(await bskts.buildBuy({ ticker: "DIGI64", amountUsdg: 100, address }), sender, { wait: true });

// later: sell everything back to USDG
await bskts.execute(await bskts.buildSell({ ticker: "DIGI64", address }), sender, { wait: true });

Errors carry a stable code (POLICY, SIMULATION_FAILED, INSUFFICIENT_SHARES, NO_ROUTE and so on) and say whether a retry may succeed. Source, full reference and the MCP server live in the open at github.com/Tokenise-au/bskts-sdk.

REST API

Under both sits a public, keyless API at api.bskts.xyz: read endpoints return market and account data, and the /v1/tx/* endpoints return unsigned calldata you sign with your own wallet. It never holds keys and never broadcasts on your behalf.

  • Approval, then transaction. Each /v1/tx/* response is { approval, tx, simulation }. When approval isn’t null, send it and wait for it to confirm before sending tx.
  • Dry run. simulation.ok is true when the transaction passed as your address, false (with a reason) when it would revert, and null when it can’t run yet (send the approval first).
  • Units. Dollars, NAVs and PnL are plain numbers; on-chain amounts (anything ending in Wei, and shares in requests) are integer strings in base units: 18 decimals for shares, 6 for USDG. Send walletSharesWei back exactly as you received it.
  • Errors are { error, code, retryable }: branch on code, not the message.
  • Compact by default. Responses are minified; ?fields= trims rows, ?format=summary turns NAV history into five numbers, and ?pretty=1 indents for reading.

Connecting an autonomous agent

New to agents? Start with the overview. Give your agent its own signing key through its host wallet or secure signer. Share only the public address. In the Agents tab (next to Portfolio), connect that address and approve its limits once; Portfolio’s Agents view then lists everything the agent does. The suggested daily turnover is 10% of available account USDG (at least $10), capped at $100, with 0.5% maximum slippage and seven days of access. Deposits do not increase the approved limit.

Agents with a shell (OpenClaw, Hermes, Claude Code) can use the bskts skill: a SKILL.md and a small signer that keeps the agent’s key on its own machine. The Agents tab gives you one message to paste, with your wallet filled in: the agent installs the skill and sends you its approval link. Trades are dry runs unless the agent adds --send, which the skill tells it to do only after you say so, and each live trade is journalled so a retry never sends it twice.

The agent checks /v1/agent/session?owner=0x…&key=0x…, then builds buys or sells with /v1/agent/trade. Its host signs the returned session Action and submits it to the relayer. Trades need no owner popup or ETH in the owner or agent wallet; network fees are paid separately in account USDG. Only your wallet can approve changed limits or renew access.

The SDK provides agentSession, buildAgentTrade,executeSession and sessionRelayer. The MCP toolsbskts_agent_session and bskts_agent_trade return unsigned plans for your host signer. Never paste a private key into the MCP, API or dashboard. Revoking a key stops new requests; existing orders and schedules must be cancelled or stopped separately in Portfolio.

For an agent that can restart, SDK 0.5.0+ provides executeSessionOnceand sessionActionState. Save the unsigned plan before signing and retain its outcome. Node hosts can use fileSessionStore from@bskts/sdk/node. Keep the journal, even after success: restarting checks the original nonce and never submits that operation again. Use a new journal ID only for a deliberate new trade after reconciliation. Store no keys or signatures in the journal.

Agent trading is newly released and still being tested. Agents can also buy Weekend Cover on baskets the account holds, once Cover is enabled for the account: take offers, request cover or cancel their own request (/v1/cover/* to read,POST /v1/agent/cover to build). Cover counts spending separately against the same daily limit, and a session pays at most 3% of the cover. The agent tools never underwrite: offering cover needs the owner’s own allowance. Open Cover listings remain after an individual key is revoked; withdraw them in My cover.

GET/v1/basketsEvery basket with live NAV, 24h change, buy cost and risk note
GET/v1/baskets/:tickerOne basket: constituents with addresses, weights and live prices
GET/v1/marketsCompact NAV + change + cost table for all baskets
GET/v1/statsProtocol totals: TVL and volume
GET/v1/nav/:ticker/historyNAV candles
GET/v1/wallet/:addressETH (gas) and USDG balances and basket shares: can this wallet trade?
GET/v1/positions/:addressAn address's basket positions and PnL
GET/v1/orders/:addressOpen exits and limit buys, each with its escrow
GET/v1/jobsEvery order or schedule anyone may execute right now, with calldata and fee
POST/v1/tx/buyUnsigned calldata to buy a basket
POST/v1/tx/sellUnsigned calldata to sell a basket for USDG in one transaction
POST/v1/tx/redeemUnsigned calldata to redeem in kind
POST/v1/tx/limitUnsigned calldata for a limit buy
POST/v1/tx/exitUnsigned calldata to arm a stop-loss / take-profit / bracket
POST/v1/tx/cancelUnsigned calldata to cancel an order (its escrow is looked up)
POST/mcpThe MCP server above, over Streamable HTTP

Earn fees by executing orders

Resting orders and scheduled buys are public jobs: anyone may execute a triggered one and keep its fee, max($0.25, 0.15%) of the order, up to 1%. GET /v1/jobs lists every job executable right now with its calldata and fee. Each fill is held to the order’s on-chain price floor, so simulate before sending.

Building on basket tokens

A basket share is an ordinary ERC-20 with two properties that make it safe to build on: anyone holding it can redeem in kind at any time, with no fee and no permission, and its price is readable on-chain — navPerShareE18() computes it from the vault’s own balances and its constituents’ pool prices, with no external feed and no trust in bskts.

  • Price a share from NAV, never from a share/USDG pool. Such pools are thin; a small trade moves their quote far more than the basket’s value. NAV is the number the redemption right enforces.
  • Liquidation doesn’t need a share market: redeem in kind and sell each constituent into its own, much deeper pool (/v1/leverage/sell-routes returns those swaps).
  • navPerShareE18() reverts while a price read fails; in-kind redeem keeps working throughout, because it reads no prices.
  • Baskets holding Stock Tokens trade around the clock but follow equity market hours, so overnight and weekend gaps are real; size margins for them.

Machine-readable: openapi.json, and for AI agents the API’s trading guide, this page as markdown and the product’s llms.txt.