How to bring a trading process live on Nado and operate it: configuration and preflight, account and linked-signer setup, testnet and faucet, rollout order, health checks, failure diagnosis, and key rotation.
TL;DR
- Network configuration is fail closed: the network value (mainnet/testnet) selects the gateway and chain id; a typo aborts startup instead of silently selecting a default network. At startup, compare chain id with the
contractsquery; mismatch aborts startup. Sub-account name is an explicit parameter (1–12 ASCII characters) and is logged with its bytes32. → §1 - Geo-block: Russia is fully blocked; the United States and Canada are view-only. Check the server jurisdiction before the first request. → §2
- Testnet is Ink Sepolia (chain id 763373,
gateway.test.nado.xyz), with thetestnet.nado.xyz/portfolio/faucetfaucet plus gas ETH from Ink faucets. Run the order smoke test there first, or use micro-orders on mainnet. → §3 - Keys: keep the master wallet only in the browser (popup for
LinkSigner); the server holds the linked-signer key and master address. Revoke = link the zero address; limit 50 operations per 7 days. → §4, §8 - Manual orders are forbidden on the bot’s sub-account: an order without the nonce tag becomes unmanaged and prevents the conclusion that the account is empty until it is canceled manually. → §7
- Go live in stages: first complete the testnet checklist with live orders, then move to mainnet with a small deposit. → §5
- If orders for an asset are not being placed: grep the journal for
2117/2069, inspecttrading_statusinsymbols, check symbols-cache freshness (a rename can freeze it—restart), and inspectordersCompletein the snapshot. → §6
1. Configuration and preflight
| Parameter | Value | Fail closed |
|---|---|---|
| network | mainnet / testnet | anything else → abort startup |
| gateway | derived from network (gateway.prod.nado.xyz/v1 / gateway.test.nado.xyz/v1), overridable | http/https only |
| chain id | derived from network (57073 / 763373), overridable | non-integer → abort startup; mismatch with contracts → abort startup |
| sub-account name | default by default | 1–12 printable ASCII characters, otherwise abort startup |
| resting minimum | $100 | do not set manually without measurement |
| IOC minimum | = resting minimum by default | lower only after measuring the floor (orders.md §5) |
Startup preflight:
contracts→ chain id matches andendpoint_addris recorded. Otherwise throw (every signature would target the wrong network).- If the account address is already known: query
subaccount_infowith bytes32 (address + name).exists:falseor value 0 → a loud warning (log + operator alert): “sub-account is empty or does not exist; if a deposit exists, the configured sub-account name is wrong—check the UI.” This is not fatal: starting before a deposit is legitimate. - Key-binding check: address derived from the key equals the sub-account’s
linked_signeror the master address (account-and-fees.md§7). - A preflight read failure (network) is a warning and startup continues: the main loop handles degraded reads.
2. Geo-block and jurisdiction
IP block: Russia is fully blocked; the United States and Canada are view-only (according to Nado documentation and observation). Before starting, ensure that the server’s egress address is in an allowed jurisdiction. Access to the web UI and compliance with the ToS are the operator’s responsibility, not the code’s.
3. Testnet
- Ink Sepolia, chain id 763373, gateway
https://gateway.test.nado.xyz/v1(chain id confirmed bycontracts). - USDT0 faucet:
testnet.nado.xyz/portfolio/faucet; gas ETH: Ink faucets (docs.inkonchain.com/tools/faucets). - Testnet checklist (
orders.md§12): oversized RO IOC, IOC floor, GTC cycle, IOC fill by delta, complete small-size cycle (entry → partial reduction → close to zero). - Minimum and fill checks can also use micro-orders on mainnet (tens of dollars): the fee is cents, and the response comes from mainnet matching, which matters more than the testnet book.
4. Account setup
- Use a separate EVM wallet (master) for the bot. Put USDT0 on Ink and deposit it into Nado; the deposit creates the
defaultsub-account. One process—one sub-account. - Bot key: generate a second key pair (
generatePrivateKeyfromviem), pass the address to the link operation and the private key to the process (through secure input or an environment variable without a trailing newline). - Link from a browser page:
nonces→tx_nonce,contracts→endpoint_addr; MetaMask signs theLinkSignertyped data (add/switch to Ink withwallet_addEthereumChain); send the signedlink_signerexecute to the gateway (in the verified design, through a local proxy rather than directly from the page; weight 30). Thenlinked_signermust show the bot-key address. Documented requirement: the sub-account already holds ≥ 5 USDT0. - A less secure alternative is to give the process the master key itself (self-signing); the binding check permits this. Not recommended: a linked signer can withdraw only to the master, while the master can withdraw elsewhere.
- Verify in the UI that funds are on the sub-account with the same name as the configuration.
5. Rollout order
- Network
testnet+ the §3 checklist with live orders. - Mainnet with a small deposit; increase it only after resolving the open checklist items (oversized RO IOC, IOC floor, §11).
6. Health and diagnostics
6.1. What to inspect
- Placement journal: asset, side, size and price, type (IOC/GTC, RO), and outcome—filled, in the book, or rejected with
error_code; code-bearing rejections are the first thing to grep. - Your orders in the book grouped by asset, with the order-read completeness flag beside them: when
ordersComplete=false, “empty” proves nothing. - Labeled throttle counters (
rate-limits.md§3).
6.2. Symptom → cause → action
| Symptom | Check | Action |
|---|---|---|
| Orders for an asset are not being placed | grep 2117 → market is post_only; grep 2069 → not_tradable | If 2117 repeats for DEFAULT, the symbols cache is stale/frozen → restart (§6.3). If not_tradable, wait for listing and do not enable the market for trading |
2117 rejections on IOC with an open position | stock perpetual on a weekend / pre-listing | Expected: IOC does not pass on a post_only market, so close is rejected. Do not restart. Check execute budget (rate-limits.md §5) |
| “New asset is not listed,” but it appears in the UI | symbols cache froze after a rename | §6.3 |
Equity is UNKNOWN, no errors | subaccount_info.exists, sub-account name | Compare the name with the UI |
| “Empty account,” but the UI shows orders | order read is partial (ordersComplete=false) or orders have no tag (manual) | Wait for a complete survey; cancel manual orders manually |
Every market action is REJECTED without a code | IOC minimum below its floor? price/size quantizes to 0? | Measure the floor; log quantization |
| Every execute is rejected after deployment | chain id / gateway | preflight §1 |
| Every request returns 403 | manually set Accept-Encoding header | remove it (api-and-signing.md §2) |
6.3. Frozen symbols cache
Symptom: a symbols cache with a stability check (“reject refresh if a previously verified asset disappeared”) rejects every refresh and serves the stale cache. Cause: a market rename or removal (for example, CIRCLE → CRCL on 2026-08-10). Trading does not crash, but new listings remain invisible until restart. Remedy: restart the process. Before restarting, request {type:'symbols', product_type:'perp'} three times in a row and compare the size and presence of your assets: the stability check protects against truncated responses, and restarting on a truncated response would make it the new baseline.
7. Manual orders are forbidden
Do not trade manually on a sub-account managed by the process. An order without the nonce tag is “foreign”: the process neither cancels nor matches it, but it counts as exposure and blocks conclusions such as “the account is empty” until it is canceled manually. If the operator must act manually, first stop the process, then clear the book, then act.
One process—one sub-account. Two processes on one sub-account will cancel one another’s book.
8. Key rotation
- A new linked signer replaces the old one with a single link operation (including 1-Click Trading from the UI). Limit: 50 link/revoke operations per sub-account per rolling 7 days.
- Sequence: stop the process gracefully and wait for the tick to finish → link the new address in the browser → verify
linked_signer→ put the new key into the process → start → preflight confirms the binding. - Revoke = link the zero address. Revoke does not close positions or cancel orders.
- The master key never enters the server.
9. Shutdown and restart
- Graceful shutdown waits for the current cycle to finish, or the process may stop between canceling its orders and sending IOC.
- After restart, stored digests of your orders are gone; the first
ordersread restores them. Until an order survey is complete, “empty” has not been proven.
10. Pitfalls
| What breaks | Why | Correct approach |
|---|---|---|
| Testnet orders went to mainnet | gateway for one network, chain id for another in configuration | preflight with contracts; abort startup |
| Process is silent and equity is unknown | sub-account name differs from the UI | explicit parameter, print bytes32, loud alert on exists:false |
| “Not listed,” but the market exists | frozen symbols cache | 3 requests → restart |
| Master key is in server environment | linking used a CLI script on the server | browser popup; only the signer is on the server |
| Operator order remains “foreign” | manual trading on the bot’s sub-account | stop → clear → act |
| Restart between order cancellation and IOC | shutdown did not wait for the cycle | wait for the current cycle to finish |
| Duplicate process on one sub-account | a second instance started with the same key | one process—one sub-account; compare addresses, not keys |
| Panic restarts on weekends | 2117 rejections because stock perpetuals are post_only | this is not a failure; read the rejection code |
11. Open questions / not verified
- Geo-block: exact behavior (response code) for a request from a blocked jurisdiction was not captured.
- API withdrawals, including the signer restriction “only to master,” were not performed.
- Multiple sub-accounts under one master across multiple processes are possible by design but were not verified.
- Exchange behavior when a signer expires or is rotated while orders are open was not verified (orders presumably remain).
- Oversized RO IOC and exact IOC floor (testnet checklist items): responses were not captured; verify on testnet or with micro-orders on mainnet (
orders.md§12).
Facts verified through 2026-09-16. Nado changes: verify the gateway, modes, and linked-signer rules against documentation and live requests.
© markpaper authors. Licensed under CC BY 4.0: when publishing or adapting this material, credit “markpaper — Nado knowledge base” and link to the original and the license.