Use the V3 SDK to place orders, manage positions and read Smart Account balances.
Install
The examples use Node.js 22 and SDK 1.1.0:
npm install @storm-trade/trading-sdk@1.1.0 @ton/ton@^15.2.0Connect
First, fund the user's Smart Account and register a signing key. Get the market's vAMM address from markets.
import { Address, toNano } from '@ton/ton';
import {
OrderType, V3Client, prepareOrder, prepareCancel,
} from '@storm-trade/trading-sdk/v3';
const api = new V3Client('https://api.storm.tg/v3-node-0');
const smartAccount = Address.parse('YOUR_SMART_ACCOUNT');
const market = Address.parse('MARKET_VAMM_ADDRESS');Replace the two addresses with your own. This URL is Mainnet. For testing, get matching API and contract addresses during builder onboarding.
The examples below use three values from your application:
signer: the registered key's 32-bytepublicKeyand asign(hash)function that returns a 64-byte Ed25519 signature. It signs the cell hash directly.queryId: an unused ID reserved for this Smart Account. The SDK does not reserve IDs for you.minimumBaseAmount: the minimum base asset size you accept, based on your quote and slippage setting, with 9 decimals.
For complete account and signer setup, use the runnable examples. Wallet transaction signatures and ton_proof cannot replace the intent signer.
Place a market order
This opens a long position with 100 collateral and 3Γ leverage:
const now = Math.floor(Date.now() / 1000);
const prepared = await prepareOrder({
smartAccount,
market,
signer,
queryId,
createdAt: now - 5,
order: {
type: OrderType.Market,
expiration: now + 600,
direction: 0, // 0 = long, 1 = short
amount: toNano('100'),
leverage: toNano('3'),
minBaseAssetAmount: minimumBaseAmount,
limitPrice: 0n,
stopTriggerPrice: 0n,
takeTriggerPrice: 0n,
},
});Save prepared.hash, prepared.request and prepared.orderRequestHashes in your application before sending. Then submit:
await api.placeOrder(prepared.request);To earn builder fees, add your registered builder address to prepareOrder. See Builder Fees.
Check the result
const status = await api.getIntentStatus(prepared.hash);
const positions = await api.getPositions(smartAccount.toRawString());accepted means the API received the order. Neither accepted nor done proves a fill. Confirm the result through account bundles, transactions and position state.
If a request times out, check the saved hash before creating another order. The first order may already be accepted. The SDK does not retry automatically.
Add SL/TP or use a limit price
In the opening order above:
| Action | Change |
|---|---|
| Stop loss | Set stopTriggerPrice to your stop price |
| Take profit | Set takeTriggerPrice to your target price |
| Limit order | Use OrderType.Limit, set limitPrice, and replace minBaseAssetAmount with stopPrice: 0n |
| Stop market | Use OrderType.Limit, set stopPrice, keep limitPrice: 0n, and omit minBaseAssetAmount |
| Stop limit | Use OrderType.Limit, set both stopPrice and limitPrice, and omit minBaseAssetAmount |
Use toNano('65000') for a price of 65,000. For attached SL/TP, reserve one query ID for the opening order plus one for each trigger. The SDK assigns the extra IDs consecutively. Limit orders open or increase a position; they do not reduce it.
Close a position
This prepares a close of 0.001 units of the base asset. Use the position's direction and a new reserved closeQueryId:
const close = await prepareOrder({
smartAccount, market, signer,
queryId: closeQueryId,
createdAt: Math.floor(Date.now() / 1000) - 5,
order: {
type: OrderType.TakeProfit,
expiration: Math.floor(Date.now() / 1000) + 600,
direction: 0,
amount: toNano('0.001'),
triggerPrice: 0n,
},
});Save the result, then submit close.request with api.placeOrder. For a full close, use the current position size as amount.
Cancel an order
Use the resting order's orderHash, either a hex hash or an ID starting with @offchain::
const cancellation = await prepareCancel(smartAccount, orderHash, signer);Save the target orderHash and the cancellation's hash and request before sending:
await api.cancelOrder(cancellation.request);Cancellation needs no new query ID. Check the target order's final status to confirm it was cancelled; a successful request alone is not confirmation.
Amounts and account setup
V3 order amounts, position sizes, prices and leverage use 9 decimals: toNano('100') means 100. Deposits and withdrawals use the token's own decimals: 6 for USDT, 9 for TON. Times use Unix seconds. Keep large values as bigint or strings.
The owner wallet handles deposits, withdrawals and signing keys. The SDK provides getSmartAccountAddress, depositPayload, withdrawalPayload and keyPayload; follow the account examples to send the wallet transactions.