This page covers the vocabulary and mechanics you need before touching the SDK or the REST APIs.
๐ Two Trading Paths: v2 and v3
Storm runs two trading paths side by side.
| v2 | v3 | |
|---|---|---|
| Wallet | User's own TON wallet (TON Connect) | Smart Account owned by the user, operated through signed intents |
| How an order reaches the chain | The user signs and broadcasts a TON transaction | The user signs an intent off-chain, the Storm sequencer bundles it and sends it on-chain |
| Gas | Paid by the user per transaction | Prepaid gas units on the Smart Account, or gasless mode |
| Latency | One TON transaction per action | Sub-second acceptance, on-chain confirmation follows |
| Public API | Data API for reads, on-chain messages for writes | Data API for markets and history, Trading API (V3) for orders and Smart Account state |
New integrations should target v3. It is the path used by the Storm app, it supports builder attribution, and it does not require the user to sign every action in a wallet popup.
๐ Smart Account
A Smart Account is a per-user contract that holds collateral and executes trading actions on the user's behalf. It is controlled by the user's public key. Anyone who can produce a valid signature for that key can submit intents for the account.
The Smart Account address is the identifier you pass to every account-scoped endpoint, for example balances, positions, bundles and query ids. Both raw (0:<64 hex>) and user-friendly (EQ... / UQ...) formats are accepted.
โ๏ธ Signed Intents
An intent is a TON cell that describes one action: place a market or limit order, cancel, change margin, and so on. The flow is:
- Build the intent cell. The Go SDK does this for you.
- Sign the cell hash with the user's key.
- Submit
message,public_keyandsignature(all base64) together with the Smart Account addresssatoPOST /order/place. - The sequencer emulates the intent, and if it passes, includes it in a bundle.
An accepted response means the intent passed emulation and was queued. It does not mean the order is executed on-chain. Track the bundle or the intent hash to learn the final result.
๐ข Query IDs
Every intent carries a query id that must be strictly increasing per Smart Account. Reusing a query id is rejected with QUERY_ID_ALREADY_USED.
- Fetch the next id from
GET /smartaccount/{address}/queryIDbefore your first intent. - Increment locally after every accepted submit.
- If the sequencer rejects an id as already used, refetch and continue from the returned value.
The id is a high-load wallet style value made of a shift and a bit_number. The Go SDK hides this behind a counter.
๐ฆ Bundles
The sequencer groups intents into bundles and sends each bundle as one external message. A bundle moves through these states:
| Status | Meaning |
|---|---|
pending | Accumulating intents, not built yet |
sealed | Built and emulated, external message ready |
sent | Broadcast, waiting for the on-chain result |
confirmed | Terminal. Succeeded on-chain |
failed | Terminal. Failed on-chain or the contract threw |
Use GET /smartaccount/{address}/bundles to list a user's bundles, or GET /smartaccount/{address}/bundles/{query_id} for a single one.
๐งฎ Numbers and Units
- All amounts, prices, rates and leverage values are integers scaled by 10^9 unless an endpoint states otherwise.
1.5is sent as1500000000. - Builder rebate rates use the same scale:
1,000,000,000equals 100 %. See Builder Fees. - Timestamps are Unix milliseconds in the V3 API and ISO 8601 strings in the Data API.
- Market and asset identifiers are TON contract addresses of the vAMM. The full list comes from
GET /marketson the Data API.
โ๏ธ Fees at a Glance
- Trading Fee is charged on open and close, as a rate on the notional.
- Execution Fee pays the executor that processes the order. It is separate from the Trading Fee and is not part of any rebate.
- Funding and rollover are periodic and are excluded from builder rebates.
The full model is described under Fees and Fees Distribution.
๐จ Errors
The V3 API returns a JSON object with code, error, msg and, when known, externalQueryId. Codes you should handle:
| Code | What happened | What to do |
|---|---|---|
EMULATE_ERROR | The intent failed pre-execution emulation. The response includes the contract exit code | Inspect the exit code, fix the order parameters |
NOT_ENOUGH_BALANCE | The Smart Account cannot cover margin plus fees | Top up or reduce size |
QUERY_ID_ALREADY_USED | The query id was already consumed | Refetch the query id and resubmit |