Author SHA1 Message Date
discountry 73d34434b0 fix size 2026-02-04 13:25:21 +08:00
discountry d0154e5721 fix den 2026-02-03 18:48:06 +08:00
discountry 52b6a8a076 Add invitation links for Nado registration in trading tutorial 2026-02-03 12:04:36 +08:00
discountry db6a9cfc68 Add Nado trading tutorial for ritmex-bot 2026-02-03 12:02:55 +08:00
DisneyandGitHub 03b8e53d30 Merge pull request #19 from discountry/feat/arb
Feat/arb
2026-02-01 11:15:42 +08:00
discountry 8d79ace8b3 Refactor triggerType handling in order placement logic
- Updated the triggerType assignment in placeStopLossOrder and related functions to default to "STOP_LOSS" instead of conditionally setting it based on the order side.
- This change simplifies the logic for stop market orders across the order coordinator and GRVT exchange gateway, ensuring consistent behavior.
2026-02-01 11:15:00 +08:00
discountry 1fb6d3d62d Add swing trading configuration options to .env.example
- Added new environment variables for swing trading, including SWING_DIRECTION and SWING_STOP_LOSS_PCT.
- Updated documentation in .env.example to reflect the new swing trading parameters for better clarity and usability.
2026-01-31 16:19:19 +08:00
discountry c4559cb0d7 Add swing trading strategy with RSI signals and Binance integration
- Introduced a new swing trading strategy utilizing the RSI indicator on the ETHBTC pair from Binance.
- Implemented the `SwingEngine` to manage trading logic, including entry and exit conditions based on RSI thresholds.
- Added configuration options for swing direction, trade amount, and RSI parameters in `config.ts`.
- Created new documentation for the swing strategy, detailing its behavior and configuration.
- Enhanced CLI to support the new swing strategy option.
- Added tests for swing logic to ensure correct behavior under various market conditions.
2026-01-31 16:15:07 +08:00
discountry 1d88ddefb5 Enhance account snapshot handling and staleness checks in MakerPointsEngine
- Updated `emitAccountSnapshot` method in `StandxGateway` to accept an optional `updateTime` parameter, allowing for more accurate timestamping.
- Introduced logic to determine the appropriate `updateTime` based on the latest position or balance data.
- Added `time` property to `StandxPosition` interface for improved timestamp management.
- Implemented `applyAccountSnapshot` method in `MakerPointsEngine` to streamline account snapshot processing and ensure accurate time tracking.
- Added tests to validate the behavior of account staleness checks and defense mode activation based on account data freshness.
2026-01-24 23:53:36 +08:00
discountry 683352f737 Add changeMarginMode method to ExchangeAdapter and Standx classes
- Introduced `changeMarginMode` method in `ExchangeAdapter` interface to allow margin mode adjustments.
- Implemented the `changeMarginMode` method in `StandxExchangeAdapter` to interact with the gateway for changing margin modes.
- Added corresponding `changeMarginMode` method in `StandxGateway` to handle API requests for margin mode changes.
- Enhanced `MakerPointsEngine` to ensure isolated margin mode before order placement, with appropriate logging and defense mode activation if the change fails.
- Created tests for margin mode functionality to validate behavior under different scenarios.
2026-01-24 22:57:03 +08:00
discountry a629bc940c Enhance environment variable parsing and account snapshot validation
- Introduced `normalizeEnvValue` function to improve handling of environment variable values, including trimming, unquoting, and stripping inline comments.
- Updated `resolveSymbolFromEnv` and parsing functions to utilize the new normalization logic.
- Added `validateAccountSnapshotForSymbol` function to validate account snapshots, ensuring numeric fields are correctly formatted and flagging any issues.
- Implemented tests for environment variable parsing and account snapshot validation to ensure robustness and correctness.
2026-01-24 22:46:14 +08:00
discountry fe7b8eb6f3 Update Binance WebSocket configuration and enhance depth handling
- Changed WebSocket base URL to support both spot and futures trading.
- Adjusted depth tracking parameters for improved performance, increasing the ratio and reducing speed.
- Enhanced payload parsing to accommodate additional data structures from Binance, ensuring robust handling of bids and asks.
- Updated comments for clarity on connection behavior and heartbeat monitoring.
2026-01-22 10:23:07 +08:00
discountry 24339929dc Enhance MakerPoints functionality and configuration
- Updated `filterMinDepth` in `config.ts` from 1 to 50 to improve depth filtering logic.
- Added new translation entries for band depth display in `i18n/index.ts`.
- Introduced `bandDepths` to `MakerPointsSnapshot` in `maker-points-engine.ts` to track depth across different bands.
- Enhanced `BinanceDepthTracker` to support dynamic depth levels and speed settings.
- Updated `MakerPointsApp` to display band depth information, improving user interface clarity.
2026-01-22 02:27:45 +08:00
discountry ed855f6859 Refine data staleness checks in MakerPointsEngine
- Updated the logic to only consider depth data for staleness checks, excluding account data from the criteria.
- Removed unnecessary account staleness checks from defense mode activation, streamlining the data validation process.
- Enhanced comments for clarity on the rationale behind the changes.
2026-01-21 16:30:51 +08:00
discountry e144c1822f Implement data staleness defense mode in MakerPointsEngine
- Introduced a defense mode that activates when data from StandX or Binance is stale for over 5 seconds.
- Added methods to check data freshness, enter and exit defense mode, and cancel all orders during defense mode.
- Enhanced logging to provide insights into data staleness and defense mode transitions.
- Updated connection state management for clarity and consistency.
2026-01-21 16:24:17 +08:00
discountry 69271d33ca Refactor MakerPointsEngine and BinanceDepthTracker for improved connection management
- Renamed connection state variable in MakerPointsEngine for clarity.
- Added connection state change listeners in BinanceDepthTracker to handle connection status updates.
- Implemented heartbeat monitoring and connection duration checks in BinanceDepthTracker to enhance WebSocket reliability.
- Introduced data staleness checks and improved error handling for WebSocket connections.
- Enhanced logging for connection events to provide better insights into connection status changes.
2026-01-21 16:03:34 +08:00
discountry f1140f106a Enhance WebSocket connection management and data handling
- Introduced constants for WebSocket reconnection delays, heartbeat timeout, and data staleness thresholds.
- Implemented heartbeat monitoring to ensure timely reconnections on inactivity.
- Added data staleness checks to trigger REST API calls when market or account data is outdated.
- Enhanced the StandxGateway class with methods for managing heartbeat and data checks, improving overall connection reliability and data integrity.
2026-01-21 15:40:28 +08:00
discountry 3b935b7979 Refactor MakerPoints configuration and depth handling
- Renamed `band0To10MinDepth` to `filterMinDepth` in `config.ts` for clarity.
- Updated `MakerPointsEngine` to utilize the new `filterMinDepth` for depth checks across all bands.
- Introduced a method to track depth status changes, enhancing order placement logic based on market depth.
- Improved logging for depth-related order skips to provide clearer insights into trading decisions.
2026-01-21 11:26:21 +08:00
discountry 00388f9166 add filter 2026-01-21 11:11:58 +08:00
discountry a32efa2ba0 Refine target price calculation in LiquidityMakerEngine
- Updated target price logic to consider entry price when no recent fills are available, enhancing order placement accuracy.
- Adjusted conditions to ensure target prices are set appropriately based on market conditions and entry prices, preventing potential losses.
- Improved comments for clarity on the logic behind target price adjustments.
2026-01-20 01:28:24 +08:00
discountry 76704b6bdd Enhance entry price logic in Maker and Liquidity Maker strategies
- Added `entryDepthLevel` configuration option to `MakerConfig` and `LiquidityMakerConfig` for specifying order entry levels.
- Implemented `getPricesAtLevel` utility function to retrieve bid and ask prices at specified depth levels.
- Updated `MakerEngine`, `LiquidityMakerEngine`, and `OffsetMakerEngine` to utilize the new entry level logic for determining opening prices based on market depth.
- Improved price handling to ensure more accurate order placements in varying market conditions.
2026-01-20 01:03:38 +08:00
discountry 168d8cbb08 Add Claude instructions and enhance stop-loss logic
- Introduced a new `CLAUDE.md` file with instructions for using Bun as the package manager.
- Adjusted stop-loss cooldown and check intervals in `MakerPointsEngine` for improved responsiveness.
- Implemented a new method to compute real-time PnL using live depth data, enhancing stop-loss decision-making.
- Added retry logic for stop-loss execution to ensure positions are closed effectively, with detailed logging for failures.
2026-01-20 00:51:15 +08:00
discountry 9629c22496 Enhance MakerPoints configuration and logic
- Added new configuration options for band-specific order amounts in `config.ts`.
- Implemented conditional logic in `MakerPointsEngine` to utilize the new band amounts based on the Binance depth cancel setting.
- Refactored order amount handling to improve clarity and maintainability.
2026-01-18 01:49:36 +08:00
discountry a34d06f9b4 fix slprice 2026-01-16 23:05:30 +08:00
discountry 2ba3e80ad9 fix sl 2026-01-16 22:59:38 +08:00
discountry 12e8e3e064 Update API token creation date in documentation and configuration
- Revised the `.env.example` and `maker-points-guide.md` to reflect the updated token creation date from 2025-01-15 to 2026-01-15.
- Enhanced the `order-coordinator.ts`, `order-schema.ts`, and `types.ts` files to support stop-loss and take-profit price parameters in order intents.
- Updated the `StandxGateway` and `order.ts` to handle new stop-loss and take-profit parameters in order creation.
- Improved the `MakerPointsEngine` to calculate stop-loss prices based on order type, enhancing order management capabilities.
2026-01-16 11:29:26 +08:00
discountry aa24995d28 Enhance WebSocket and API documentation; implement connection protection features
- Added a note in the HTTP API documentation regarding the non-guaranteed sequence of price levels in order book responses.
- Updated WebSocket documentation to include a connection duration limit and a note on local sorting requirements for price levels.
- Introduced connection event handling in the ExchangeAdapter interface, allowing for disconnection and reconnection events.
- Implemented connection protection logic in the StandxExchangeAdapter and MakerPointsEngine to manage order states during connection disruptions.
- Enhanced the StandxGateway with methods for querying open orders and forcefully canceling all orders, improving reliability during network issues.
2026-01-16 10:49:16 +08:00
discountry d493642935 update doc 2026-01-15 22:06:10 +08:00
discountry 86670486a6 Update StandX API documentation and configuration
- Revised `.env.example` to reflect new API token generation process, emphasizing the use of creation date and validity days for token expiry management.
- Enhanced `auth.md` with detailed instructions for obtaining API tokens and signing transactions for both EVM and Solana wallets.
- Updated `maker-points-guide.md` to clarify the API token retrieval process and the significance of the Ed25519 private key.
- Refactored `config.ts` and `gateway.ts` to support new token expiry configuration methods and improved private key handling, including Base58 decoding.
- Improved overall documentation clarity and user guidance for new and existing users.
2026-01-15 16:11:08 +08:00
discountry 6496011d8f Add Nado exchange support to README
- Included details for the Nado USDC perpetuals, specifying required environment variables and configuration options.
- Updated both English and Chinese versions of the README to reflect the new exchange integration, enhancing user guidance and clarity.
2026-01-14 18:28:14 +08:00
discountry 792351ab8a Add Liquidity Maker strategy and related configurations
- Introduced a new `LiquidityMakerConfig` interface and corresponding configuration settings in `config.ts`.
- Updated CLI argument handling to include the new "liquidity-maker" strategy option.
- Implemented the `LiquidityMakerEngine` class to manage the liquidity making strategy, including order handling and risk management.
- Added a new `LiquidityMakerApp` component for user interaction and display of strategy status.
- Enhanced internationalization support with translations for the liquidity maker strategy.
- Updated the main application to integrate the new liquidity maker strategy into the existing framework.
2026-01-14 00:56:29 +08:00
discountry 4915dc574e Implement precision error handling in MakerPointsEngine
- Added a new `isPrecisionError` function to identify precision-related errors in the error utility module.
- Updated the MakerPointsEngine to handle precision errors by logging warnings and synchronizing precision when such errors occur during order processing and stop-loss execution.
- Enhanced the `syncPrecision` method to allow forced synchronization, improving the handling of precision-related issues.
2026-01-13 20:23:18 +08:00
discountry 9866e8068f Clarify instructions in Maker Points guide regarding the proxy wallet private key format and environment variable setup. Emphasize that the private key should be copied as is, without the '0x' prefix, to enhance user understanding and security practices. 2026-01-12 18:03:26 +08:00
discountry 099af3ce01 Update Maker Points guide to clarify proxy wallet private key format and environment variable instructions. Specify that the private key should generally not include the '0x' prefix, enhancing user understanding and security practices. 2026-01-12 18:02:05 +08:00
discountry 445e634aa1 Refactor Telegram notification handling and remove unused functions
- Removed deprecated functions for masking sensitive data and previewing text, streamlining the Telegram notification process.
- Simplified logging by eliminating unnecessary console outputs related to notification configuration and sending.
- Updated the `TelegramNotifier` class to enhance clarity and maintainability, focusing on essential notification functionality.
2026-01-12 12:39:37 +08:00
discountry 4bb1fee995 Refactor Telegram notification handling in MakerPointsEngine
- Introduced a dedicated `notify` method to streamline notification sending and improve logging for Telegram notifications.
- Added a new environment variable check for enabling debug logging of Telegram notifications.
- Enhanced logging to include detailed information about notification attempts, including masked sensitive data for security.
- Updated various notification calls to utilize the new `notify` method, ensuring consistent logging and functionality.
2026-01-12 12:23:24 +08:00
discountry aad14395e0 Enhance Telegram notification functionality
- Introduced functions to mask sensitive information and preview notification text for improved logging and security.
- Added detailed logging for notification sending process, including configuration details and response handling.
- Implemented checks to prevent sending notifications when bot token or chat ID is missing, with appropriate warnings logged.
2026-01-12 12:12:14 +08:00
discountry 598f2a0eb6 Add token expiry and Telegram notification features
- Introduced `STANDX_TOKEN_EXPIRY` configuration to manage token expiration, including handling logic for active, expired, and silent states.
- Implemented Telegram notifications for key events such as order filled, position opened/closed, stop loss triggered, and token expiration.
- Updated Maker Points engine to integrate token expiry checks and notification sending, enhancing user awareness of trading conditions.
- Enhanced documentation to include details on configuring token expiry and Telegram notifications for improved user guidance.
2026-01-10 12:44:52 +08:00
discountry cb1cef6f1b Revise Maker Points guide to provide a comprehensive step-by-step tutorial for new users. Update installation instructions for Bun, enhance clarity on obtaining StandX login credentials, and improve environment variable configuration details. Add safety tips and common troubleshooting questions to support user onboarding. 2026-01-09 01:11:10 +08:00
discountry fd034d493f Enhance README with language setting instructions, updated referral links, and additional documentation for StandX and Nado exchanges. Clarify environment variable setup and improve formatting for better readability. 2026-01-07 23:39:40 +08:00
discountry 2551670874 Update README and Maker Points guide to clarify the export of StandX login credentials, specifying token and proxy wallet private key for enhanced user security. 2026-01-07 02:46:38 +08:00
discountry 3ec7e9b8d6 Update Maker Points guide to include details on exporting the generated proxy wallet private key along with the token, enhancing security instructions for users. 2026-01-06 21:49:28 +08:00
discountry 499ee692da Merge branch 'main' into feat/mm 2026-01-06 20:17:49 +08:00
discountry de13142950 Add StandX Maker Points strategy tutorial and update README with configuration details. Include steps for obtaining login token and environment variable setup for new users, enhancing documentation clarity and usability. 2026-01-06 20:08:38 +08:00
DisneyandGitHub 597e41f053 Merge pull request #16 from discountry/feat/mm
Feat/mm
2026-01-06 17:50:38 +08:00
discountry b0a33a58d1 Remove market maker documentation from StandX. This deletion includes all content related to Maker Points, order management, and WebSocket API details, streamlining the documentation for clarity and focus. 2026-01-06 17:49:29 +08:00
discountry 65b9f21981 Add new PM2 start command for Maker Points strategy in package.json. This includes a dedicated command for 'maker-points' with specific exchange settings, enhancing deployment options for the application. 2026-01-06 16:37:51 +08:00
discountry 33b5407245 Refactor Maker Points logic by removing dislocation calculations and related UI elements. Update MakerPointsEngine to utilize new price fetching methods and streamline order synchronization. Adjust translations and tests accordingly to reflect these changes. 2026-01-06 16:18:54 +08:00
discountry 7aafc3b69d Add Maker Points strategy support in StandX. Introduce new configuration for Maker Points, including point bands and order management logic. Implement MakerPointsEngine for handling order placement and tracking. Update CLI and UI components to integrate Maker Points functionality, enhancing user experience and strategy options. 2026-01-06 16:01:10 +08:00
discountry 9a093459bc Add debugging options and enhance WebSocket handling in StandxGateway. Introduce debugWs and debugWsRaw flags for improved logging of WebSocket events and payloads. Implement decrossDepthBook function for better order book management and update message handling to support multiple JSON payloads. 2025-12-21 16:54:14 +08:00
discountry aa36b0cfdc Implement depth level normalization in StandxGateway for improved order book handling. Refactor depth data processing to utilize the new normalizeDepthLevels function, ensuring consistent bid and ask sorting. Update symbol handling to accommodate fallback logic. 2025-12-21 16:15:44 +08:00
discountry 93c6409688 Integrate StandX exchange support by updating configuration files, adding environment variables, and enhancing documentation. Include new API endpoints and authentication details for StandX in README and dedicated documentation files. Update CLI and adapter logic to accommodate StandX functionalities. 2025-12-21 15:37:03 +08:00
discountry 84d5e1f3d7 Update README files to include Nado referral link and detailed setup instructions for Nado integration, enhancing user guidance for configuration and usage. 2025-12-20 14:53:25 +08:00
discountry 6e5413ec1e Refactor order status handling in NadoGateway and MakerEngine. Introduce isOrderActiveStatus utility to streamline order filtering logic. Add tests for error handling and order status utilities. 2025-12-20 13:10:48 +08:00
discountry 84e8ce1d43 Enhance NadoGateway with min size policy handling and related utility functions. Update .env.example to include NADO_MIN_SIZE_POLICY configuration option. 2025-12-19 11:11:35 +08:00
discountry c69ea72860 Add Nado documentation and examples, including new API endpoints, FAQs, and guides for using the TypeScript SDK. Update .env.example with additional configuration options. 2025-12-19 01:38:09 +08:00
discountry 624fecfa70 add nado packages 2025-12-18 03:14:20 +08:00
discountry 6dcf13481d Enhance README.md with a detailed description of the Bun-powered multi-exchange perpetuals workstation, highlighting key features such as the SMA30 trend engine, Guardian stop sentinel, and market-making modes. 2025-12-09 00:38:23 +08:00
discountry 3fd0f715a1 Update README.md to instruct users to set LANG=en in .env for English interface support. 2025-12-09 00:36:50 +08:00
discountry 85e7f245c0 Implement internationalization support by adding translation functionality and updating UI components to use translated strings. Add language configuration in .env.example and integrate translations across various strategy and UI components. 2025-12-09 00:35:28 +08:00
discountry 03df1006cc Update README.md to include a link for English users and remove the outdated English README reference. 2025-12-09 00:00:28 +08:00
DisneyandGitHub 3099cb1319 Merge pull request #13 from discountry/feat/lighter-spot
Feat/lighter spot
2025-12-08 23:57:07 +08:00
217 changed files with 32055 additions and 400 deletions
+56 -1
View File
@@ -1,14 +1,36 @@
# UI language (zh | en)
LANG=zh
# Exchange selection
EXCHANGE=aster # Pick aster (default) or grvt/lighter/backpack/paradex
EXCHANGE=aster # Pick aster (default) or standx/grvt/lighter/backpack/paradex/nado
# Aster API credentials
ASTER_API_KEY=
ASTER_API_SECRET=
# StandX authentication (set when EXCHANGE=standx)
STANDX_TOKEN=
STANDX_SYMBOL=BTC-USD
# STANDX_BASE_URL=https://perps.standx.com
# STANDX_WS_URL=wss://perps.standx.com/ws-stream/v1
# STANDX_SESSION_ID=
# Optional: request signing key (ed25519 private key, supports hex or base58 format)
# STANDX_REQUEST_PRIVATE_KEY=
# Token expiry configuration (recommended method: creation date + validity days)
# Get these values when generating API token at https://standx.com/user/session
# STANDX_TOKEN_CREATE_DATE=2026-01-15 # Token creation date (YYYY-MM-DD format)
# STANDX_TOKEN_VALIDITY_DAYS=30 # Token validity period in days
# Legacy method: direct expiry timestamp (Unix seconds)
# STANDX_TOKEN_EXPIRY=1737092800
# Core trading symbol and sizing
TRADE_SYMBOL=BTCUSDT # Trading pair symbol
TRADE_AMOUNT=0.001 # Base order quantity (base asset, e.g. BTC)
# Swing Trading
SWING_DIRECTION=short # short | long | both
SWING_STOP_LOSS_PCT=0.05 # 0.05 = 5%
# Risk management (USD amounts unless noted)
LOSS_LIMIT=0.04 # Max loss per trade in USDT before forced close
TRAILING_PROFIT=0.2 # Trailing stop activation profit (USDT)
@@ -114,3 +136,36 @@ PARADEX_WALLET_ADDRESS=
# Enable verbose adapter logging: set to "1" or "true"
# PARADEX_DEBUG=false
# Nado exchange configuration (Ink mainnet)
# Requires a linked signer private key + your original subaccount owner EVM address.
# When EXCHANGE=nado these values are used automatically.
NADO_ENV=inkMainnet # inkMainnet | inkTestnet
NADO_SYMBOL=BTC-PERP # Trading product symbol (e.g., BTC-PERP / ETH-PERP)
NADO_SIGNER_PRIVATE_KEY= # 32-byte 0x-prefixed private key (0x...)
NADO_SUBACCOUNT_OWNER= # EVM address of the subaccount owner (0x...)
NADO_SUBACCOUNT_NAME=default # Subaccount name (bytes12, default "default")
# Optional: market-order slippage buffer (used for IOC limit-as-market, e.g. 0.01 => 1%)
NADO_MARKET_SLIPPAGE_PCT=0.01
# Optional: stop trigger source for STOP_MARKET orders (oracle | last | mid)
NADO_STOP_TRIGGER_SOURCE=oracle
# Optional: how to handle orders smaller than Nado min_size (USDT0 notional)
# - adjust: round quantity up to the minimum allowed size (default)
# - reject: throw an error instead of auto-adjusting
NADO_MIN_SIZE_POLICY=adjust
# Optional endpoint overrides
# NADO_GATEWAY_WS_URL=wss://gateway.prod.nado.xyz/v1/ws
# NADO_SUBSCRIPTIONS_WS_URL=wss://gateway.prod.nado.xyz/v1/subscribe
# NADO_ARCHIVE_URL=https://archive.prod.nado.xyz/v1
# NADO_TRIGGER_URL=https://trigger.prod.nado.xyz/v1
# NADO_DEBUG=false
# Telegram notification configuration
# TELEGRAM_BOT_TOKEN= # Telegram bot token from @BotFather
# TELEGRAM_CHAT_ID= # Chat ID to receive notifications
# TELEGRAM_ACCOUNT_LABEL= # Account label to distinguish multiple bot instances (e.g., "Account-A")
+12
View File
@@ -0,0 +1,12 @@
# RitMEX Bot - Claude Instructions
## Package Manager
**必须使用 Bun** - 这个项目使用 Bun 作为包管理器和运行时。所有能用 bun 执行的命令都必须使用 bun:
- 安装依赖: `bun install`
- 运行脚本: `bun run <script>`
- 执行测试: `bun test`
- 类型检查: `bun run typecheck`
**不要使用 npm、yarn 或 npx**
+48 -2
View File
@@ -1,20 +1,27 @@
# ritmex-bot
> For English users, please see [README_en.md](README_en.md).
Please set `LANG=en` in `.env` for English interface.
A Bun-powered multi-exchange perpetuals workstation that ships an SMA30 trend engine, a Guardian stop sentinel, and two market-making modes. It offers instant restarts, realtime market data, structured logging, and an Ink-based CLI dashboard.
基于 Bun 的多交易所永续合约量化终端,内置趋势跟随(SMA30)、Guardian 防守与做市策略,支持快速恢复、实时行情订阅、日志追踪与 CLI 仪表盘。
如果您希望获取优惠并支持本项目,请考虑使用以下注册链接:
* [Lighter 手续费优惠注册链接](https://app.lighter.xyz/?referral=111909FA)
* [Aster 手续费优惠注册链接](https://www.asterdex.com/zh-CN/referral/4665f3)
* [StandX 手续费优惠注册链接](https://standx.com/referral?code=xingxingjun)
* [Binance 手续费优惠注册链接](https://www.binance.com/join?ref=KNKCA9XC)
* [GRVT 手续费优惠注册链接](https://grvt.io/exchange/sign-up?ref=sea)
* [Nado 手续费优惠注册链接](https://app.nado.xyz?join=LKbIUs5)
* [Backpack 手续费优惠注册链接](https://backpack.exchange/join/ritmex)
* [edgex 手续费优惠注册链接](https://pro.edgex.exchange/referral/BULL)
* [Paradex 手续费优惠注册链接](https://paradex.io/ref/xingxingjun)
* [Apex 手续费优惠注册链接](https://join.omni.apex.exchange/SEA)
## 文档索引
- [English README](README_en.md)
- [简明上手指南(零基础)](simple-readme.md)
- [基础网格策略使用教程](grid-trading.md)
@@ -29,10 +36,12 @@
| 交易所 | 合约类型 | 必填环境变量 | 备注 |
| --- | --- | --- | --- |
| Aster | USDT 永续 | `ASTER_API_KEY`, `ASTER_API_SECRET` | 默认交易所;兼容脚本引导
| StandX | USD 永续 | `STANDX_TOKEN` | 使用 JWT Token 登录,优先走 WebSocket 推送
| GRVT | USDT 永续 | `GRVT_API_KEY`, `GRVT_API_SECRET`, `GRVT_SUB_ACCOUNT_ID` | `GRVT_ENV` 可切换 `prod`/`testnet`
| Lighter | zkLighter 永续 | `LIGHTER_ACCOUNT_INDEX`, `LIGHTER_API_PRIVATE_KEY` | 默认 `LIGHTER_ENV=testnet`
| Backpack | USDC 永续 | `BACKPACK_API_KEY`, `BACKPACK_API_SECRET`, `BACKPACK_PASSWORD` | `BACKPACK_SANDBOX=true` 启用沙盒
| Paradex | StarkEx 永续 | `PARADEX_PRIVATE_KEY`, `PARADEX_WALLET_ADDRESS` | `PARADEX_SANDBOX=true` 使用测试网
| Nado | USDC 永续 | `NADO_SIGNER_PRIVATE_KEY`, `NADO_SUBACCOUNT_OWNER` | `NADO_ENV` 可切换 `inkMainnet`/`inkTestnet`
## 系统要求
- Bun ≥ 1.2(需同时包含 `bun``bunx` 命令)
@@ -77,7 +86,7 @@ curl -fsSL https://github.com/discountry/ritmex-bot/raw/refs/heads/main/setup.sh
| 变量 | 说明 |
| --- | --- |
| `EXCHANGE` | 选择交易所(`aster`/`grvt`/`lighter`/`backpack`/`paradex` |
| `EXCHANGE` | 选择交易所(`aster`/`standx`/`grvt`/`lighter`/`backpack`/`paradex`/`nado` |
| `TRADE_SYMBOL` | 交易对(默认 `BTCUSDT` |
| `TRADE_AMOUNT` | 单笔下单数量(标的资产计) |
| `LOSS_LIMIT` | 单笔最大亏损触发的强平额度(USDT) |
@@ -102,6 +111,36 @@ curl -fsSL https://github.com/discountry/ritmex-bot/raw/refs/heads/main/setup.sh
3. 根据交易对调整 `TRADE_SYMBOL`、`PRICE_TICK`、`QTY_STEP` 等精度参数。
4. 一键脚本会自动写入这些变量,手动部署时需自行维护。
### StandX
* [StandX 做市策略教程](docs/standx/maker-points-guide.md)
策略需要 StandX 的 API Token 和签名私钥才能下单。
**获取方式(使用 StandX 官方 API 生成功能):**
1. 打开 StandX 官方 API 创建页面:https://standx.com/user/session
2. 连接钱包并登录
3. 点击 **"Generate API Token"** 按钮
4. 页面会显示以下信息:
- **Token**(以 `eyJ` 开头的 JWT 字符串)→ 填入 `STANDX_TOKEN`
- **Ed25519 Private Key**Base58 格式私钥,类似 `HdsyJD7oWgT...`)→ 填入 `STANDX_REQUEST_PRIVATE_KEY`
- **创建日期** 和 **有效期天数** → 用于配置 Token 过期提醒
> Ed25519 Private Key 是系统自动生成的签名私钥,仅用于交易请求签名,你的资产仍在主钱包中,非常安全。
请妥善保存这些凭证,不要分享给他人。
**配置步骤:**
1. 设置 `EXCHANGE=standx`。
2. 填写 `STANDX_TOKEN`Perps API 的 JWT Token)。
3. 填写 `STANDX_REQUEST_PRIVATE_KEY`Ed25519 签名私钥,Base58 格式)。
4. 设置 `STANDX_SYMBOL`(默认 `BTC-USD`),并校准 `PRICE_TICK` / `QTY_STEP`。
5. 推荐配置 Token 过期时间:
- `STANDX_TOKEN_CREATE_DATE`(创建日期,格式 `YYYY-MM-DD`
- `STANDX_TOKEN_VALIDITY_DAYS`(有效期天数)
6. 可选:`STANDX_BASE_URL`、`STANDX_WS_URL`、`STANDX_SESSION_ID` 用于自定义环境。
### GRVT
1. 在 `.env` 中设置 `EXCHANGE=grvt`。
2. 填写 `GRVT_API_KEY`、`GRVT_API_SECRET`、`GRVT_SUB_ACCOUNT_ID`。
@@ -126,6 +165,13 @@ curl -fsSL https://github.com/discountry/ritmex-bot/raw/refs/heads/main/setup.sh
3. 默认连接主网,若需测试网,将 `PARADEX_SANDBOX=true` 并根据需要调整 `PARADEX_SYMBOL`。
4. 复杂环境可额外设置 `PARADEX_USE_PRO`、`PARADEX_RECONNECT_DELAY_MS` 或调试开关。
### Nado
1. 设置 `EXCHANGE=nado`。
2. 在 Nado 官网(交易界面)打开开发者工具(F12)→ 切换到 `Application` → `Local Storage`,找到 `nado.userSettings`,在其内容中取出 `privateKey` 字段并填入 `.env` 的 `NADO_SIGNER_PRIVATE_KEY`。
3. 提供 `NADO_SUBACCOUNT_OWNER`(或 `NADO_EVM_ADDRESS`)。
4. 选择网络 `NADO_ENV=inkMainnet`(主网)或 `inkTestnet`(测试网)。
5. 设置交易品种 `NADO_SYMBOL`(交易对格式类似 `BTC-PERP`;也支持输入 `BTCUSDT0`,会自动映射为 `BTC-PERP`)。
## 命令速查
```bash
bun run index.ts # 启动 CLI(默认入口)
+53 -8
View File
@@ -1,19 +1,25 @@
# ritmex-bot
**Language Setting**: Set `LANG=en` in your `.env` file to display the CLI interface in English.
A Bun-powered multi-exchange perpetuals workstation that ships an SMA30 trend engine, a Guardian stop sentinel, and two market-making modes. It offers instant restarts, realtime market data, structured logging, and an Ink-based CLI dashboard.
If you'd like to support this project and get fee discounts, please consider using these referral links:
* [Lighter referral link](https://app.lighter.xyz/?referral=111909FA)
* [Aster referral link](https://www.asterdex.com/en/referral/4665f3)
* [StandX referral link](https://standx.com/referral?code=xingxingjun)
* [Binance referral link](https://www.binance.com/join?ref=KNKCA9XC)
* [GRVT referral link](https://grvt.io/exchange/sign-up?ref=sea)
* [Nado referral link](https://app.nado.xyz?join=LKbIUs5)
* [Backpack referral link](https://backpack.exchange/join/ritmex)
* [edgex referral link](https://pro.edgex.exchange/referral/BULL)
* [Paradex referral link](https://paradex.io/ref/xingxingjun)
* [Apex referral link](https://join.omni.apex.exchange/RITHMEX)
* [Apex referral link](https://join.omni.apex.exchange/SEA)
## Documentation Map
- [中文 README](README.md)
- [Beginner-friendly Quick Start](simple-readme.md)
- [Grid Trading Strategy Guide](grid-trading.md)
## Highlights
- **Live data & risk sync** via websockets with REST fallbacks and full reconciliation on restart.
@@ -26,13 +32,15 @@ A Bun-powered multi-exchange perpetuals workstation that ships an SMA30 trend en
| Exchange | Contract Type | Required Environment Variables | Notes |
| --- | --- | --- | --- |
| Aster | USDT perpetuals | `ASTER_API_KEY`, `ASTER_API_SECRET` | Default venue; works with the bootstrap script |
| StandX | USD perpetuals | `STANDX_TOKEN` | Uses JWT token auth; prefer websocket streams |
| GRVT | USDT perpetuals | `GRVT_API_KEY`, `GRVT_API_SECRET`, `GRVT_SUB_ACCOUNT_ID` | Switch `GRVT_ENV` between `prod` and `testnet` |
| Lighter | zkLighter perpetuals | `LIGHTER_ACCOUNT_INDEX`, `LIGHTER_API_PRIVATE_KEY` | Defaults to `LIGHTER_ENV=testnet` |
| Backpack | USDC perpetuals | `BACKPACK_API_KEY`, `BACKPACK_API_SECRET`, `BACKPACK_PASSWORD` | Set `BACKPACK_SANDBOX=true` for the sandbox |
| Paradex | StarkEx perpetuals | `PARADEX_PRIVATE_KEY`, `PARADEX_WALLET_ADDRESS` | Toggle `PARADEX_SANDBOX=true` for the testnet |
| Nado | USDC perpetuals | `NADO_SIGNER_PRIVATE_KEY`, `NADO_SUBACCOUNT_OWNER` | Switch `NADO_ENV` between `inkMainnet` and `inkTestnet` |
## Requirements
- Bun 1.2 (both `bun` and `bunx` on PATH)
- Bun >= 1.2 (both `bun` and `bunx` on PATH)
- macOS, Linux, or Windows via WSL (native Windows works but WSL is recommended)
- Node.js is optional unless your tooling requires it
@@ -74,7 +82,7 @@ The script installs Bun, project dependencies, collects Aster API credentials, g
| Variable | Purpose |
| --- | --- |
| `EXCHANGE` | Choose the venue (`aster` / `grvt` / `lighter` / `backpack` / `paradex`) |
| `EXCHANGE` | Choose the venue (`aster` / `standx` / `grvt` / `lighter` / `backpack` / `paradex` / `nado`) |
| `TRADE_SYMBOL` | Contract symbol (defaults to `BTCUSDT`) |
| `TRADE_AMOUNT` | Order size in base asset units |
| `LOSS_LIMIT` | Max per-trade loss in USDT before forced close |
@@ -93,12 +101,42 @@ The script installs Bun, project dependencies, collects Aster API credentials, g
> ```
## Exchange Setup Guides
### Aster
1. Keep `EXCHANGE=aster` (default value).
2. Supply `ASTER_API_KEY` and `ASTER_API_SECRET`.
3. Adjust `TRADE_SYMBOL`, `PRICE_TICK`, and `QTY_STEP` to match the requested market.
4. The bootstrap script auto-populates these variables; manual installs must maintain them.
### StandX
* [StandX Maker Points Strategy Guide](docs/standx/maker-points-guide.md)
The strategy requires a StandX API Token and signing private key to place orders.
**How to obtain (using StandX's official API generation feature):**
1. Open the StandX official API creation page: https://standx.com/user/session
2. Connect your wallet and log in
3. Click the **"Generate API Token"** button
4. The page will display the following information:
- **Token** (JWT string starting with `eyJ`) → Fill in `STANDX_TOKEN`
- **Ed25519 Private Key** (Base58 format, like `HdsyJD7oWgT...`) → Fill in `STANDX_REQUEST_PRIVATE_KEY`
- **Creation date** and **Validity days** → Used to configure token expiry reminders
> The Ed25519 Private Key is an auto-generated signing key used only for trade request signatures. Your assets remain in your main wallet and are completely safe.
Please keep these credentials safe and do not share them with anyone.
**Configuration steps:**
1. Set `EXCHANGE=standx`.
2. Provide `STANDX_TOKEN` (JWT token for perps API).
3. Provide `STANDX_REQUEST_PRIVATE_KEY` (Ed25519 signing private key, Base58 format).
4. Set `STANDX_SYMBOL` (defaults to `BTC-USD`) and align `PRICE_TICK` / `QTY_STEP`.
5. Recommended: configure token expiry settings:
- `STANDX_TOKEN_CREATE_DATE` (creation date, format `YYYY-MM-DD`)
- `STANDX_TOKEN_VALIDITY_DAYS` (validity days)
6. Optional: `STANDX_BASE_URL`, `STANDX_WS_URL`, or `STANDX_SESSION_ID` for custom endpoints.
### GRVT
1. Set `EXCHANGE=grvt` inside `.env`.
2. Fill `GRVT_API_KEY`, `GRVT_API_SECRET`, and `GRVT_SUB_ACCOUNT_ID`.
@@ -107,22 +145,29 @@ The script installs Bun, project dependencies, collects Aster API credentials, g
### Lighter
1. Set `EXCHANGE=lighter`.
2. Provide `LIGHTER_ACCOUNT_INDEX` and `LIGHTER_API_PRIVATE_KEY` (40-byte hex private key).
2. Provide `LIGHTER_ACCOUNT_INDEX` and `LIGHTER_API_PRIVATE_KEY` (40-byte hex private key). `LIGHTER_ACCOUNT_INDEX` is your account index, which you can find by opening DevTools (F12) on the official website and observing API requests. `LIGHTER_API_PRIVATE_KEY` is your API private key.
3. Switch `LIGHTER_ENV` to `mainnet`, `staging`, or `dev` when necessary; override `LIGHTER_BASE_URL` if endpoints differ.
4. `LIGHTER_SYMBOL` defaults to `BTCUSDT`; override price/size decimals when markets differ.
### Backpack
1. Set `EXCHANGE=backpack`.
2. Populate `BACKPACK_API_KEY`, `BACKPACK_API_SECRET`, and `BACKPACK_PASSWORD`; add `BACKPACK_SUBACCOUNT` if you trade from a subaccount.
2. Populate `BACKPACK_API_KEY`, `BACKPACK_API_SECRET`, and `BACKPACK_PASSWORD`; add `BACKPACK_SUBACCOUNT` if you trade from a subaccount (defaults to main account ID).
3. Toggle `BACKPACK_SANDBOX=true` for the sandbox environment and verify `BACKPACK_SYMBOL` matches the contract (defaults to `BTC_USD_PERP`).
4. Enable `BACKPACK_DEBUG=true` for verbose adapter logging.
### Paradex
1. Set `EXCHANGE=paradex`.
2. Provide `PARADEX_PRIVATE_KEY` (EVM private key) and `PARADEX_WALLET_ADDRESS`.
2. Provide `PARADEX_PRIVATE_KEY` (EVM private key) and `PARADEX_WALLET_ADDRESS`. Note: These are your EVM wallet address and private key. It is recommended to create a brand new wallet and avoid storing unrelated assets in it.
3. The adapter connects to mainnet by default; enable `PARADEX_SANDBOX=true` and adjust `PARADEX_SYMBOL` for testnet usage.
4. Advanced tuning: use `PARADEX_USE_PRO`, `PARADEX_RECONNECT_DELAY_MS`, or debug flags as needed.
### Nado
1. Set `EXCHANGE=nado`.
2. On the Nado web app (trading interface), open DevTools (F12) -> switch to the `Application` tab -> `Local Storage`, locate `nado.userSettings`, then grab the `privateKey` field from its JSON value and paste it into `.env` as `NADO_SIGNER_PRIVATE_KEY`.
3. Provide `NADO_SUBACCOUNT_OWNER` (or `NADO_EVM_ADDRESS`).
4. Select network via `NADO_ENV=inkMainnet` (mainnet) or `inkTestnet` (testnet).
5. Set `NADO_SYMBOL` using Nado product symbols like `BTC-PERP` (it also accepts `BTCUSDT0` and maps it to `BTC-PERP`).
## Command Cheatsheet
```bash
bun run index.ts # Launch the CLI (default entrypoint)
@@ -170,7 +215,7 @@ bun x vitest --watch
```
## Troubleshooting
- Keep at least 50100 USDT in the account before deploying a live strategy.
- Keep at least 50-100 USDT in the account before deploying a live strategy.
- Configure leverage on the exchange manually (~50x is recommended); the bot will not change it.
- Ensure your server or workstation clock is in sync to avoid signature errors.
- Accounts must run in one-way position mode.
+78 -21
View File
@@ -1,17 +1,22 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "ritmex-bot",
"dependencies": {
"@grvt/client": "^1.6.4",
"@nadohq/client": "^0.1.0-alpha.41",
"@noble/ed25519": "^3.0.0",
"axios": "^1.12.2",
"bignumber.js": "^9.3.1",
"ccxt": "^4.5.12",
"dotenv": "^17.2.2",
"ethereum-cryptography": "^2.1.3",
"ink": "^6.3.1",
"react": "^19.1.1",
"trading-signals": "^7.4.3",
"viem": "^2.43.1",
"ws": "^8.18.3",
},
"devDependencies": {
@@ -24,7 +29,9 @@
},
},
"packages": {
"@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-qI/5TaaaCZE4yeSZ83lu0+xi1r88JSxUjnH4OP/iZF7+KKZ75u3ee5isd0LxX+6N8U0npL61YrpbthILHB6BnA=="],
"@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.11.1", "", {}, "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ=="],
"@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.4", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-HTgrrTgZ9Jgeo6Z3oqbQ7lifOVvRR14vaDuBGPPUxk9Thm+vObaO4QfYYYWw4Zo5CWQDBEfsinFA6Gre+AqwNQ=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.10", "", { "os": "aix", "cpu": "ppc64" }, "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw=="],
@@ -78,10 +85,22 @@
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.10", "", { "os": "win32", "cpu": "x64" }, "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw=="],
"@grvt/client": ["@grvt/client@1.6.4", "", { "dependencies": { "axios": "^1.12.2" } }, "sha512-yZfEvsC/BtkcdMjoB7Eh6gshBraz/9810qCllvNXDx6OmdxR+NfxPO+ucNlPbyjEt1HfSVzHBWB1yGnVl1usNA=="],
"@grvt/client": ["@grvt/client@1.6.25", "", { "dependencies": { "axios": "^1.13.2" } }, "sha512-LG3oZSJDq1Qz6mLiHDmg+v/Hp+Nd+yOp8GIvkBVyIdOcPVzuzC8UQD7IxvS+g5EfQQKLiKzXSjKLc39a11Uj1A=="],
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
"@nadohq/client": ["@nadohq/client@0.1.0-alpha.45", "", { "dependencies": { "@nadohq/engine-client": "^0.1.0-alpha.45", "@nadohq/indexer-client": "^0.1.0-alpha.45", "@nadohq/shared": "^0.1.0-alpha.45", "@nadohq/trigger-client": "^0.1.0-alpha.45", "ts-mixer": "*" }, "peerDependencies": { "viem": "*" } }, "sha512-63S7eT5xSk3hxEXRLGDI94mPeu/zd1Nu4oUOZrY8wzhaT7Gl7PVP2snb8JH/PduVQzgs7+qblr4aTBI/j6QvLQ=="],
"@nadohq/engine-client": ["@nadohq/engine-client@0.1.0-alpha.45", "", { "dependencies": { "@nadohq/shared": "^0.1.0-alpha.45", "axios": "*", "ts-mixer": "*" }, "peerDependencies": { "viem": "*" } }, "sha512-GqaRrsB0Z2EgNY6wu4nG5OTc5hF+buNRMc0+jPLlOQonlPJAC4OiMCgCigm4nJecYwsdiQD05W3Z4YUqggxbyw=="],
"@nadohq/indexer-client": ["@nadohq/indexer-client@0.1.0-alpha.45", "", { "dependencies": { "@nadohq/engine-client": "^0.1.0-alpha.45", "@nadohq/shared": "^0.1.0-alpha.45", "axios": "*", "ts-mixer": "*" }, "peerDependencies": { "viem": "*" } }, "sha512-8PzG9taYh380lsKT8i4UvGfhZiPpt+zPisx+ErVqMifyhcJAhgMeYNcfijwMQFNJdgTaBvtI0R5JK98l4Y0YQw=="],
"@nadohq/shared": ["@nadohq/shared@0.1.0-alpha.45", "", { "peerDependencies": { "bignumber.js": "^9.3.0", "viem": "*" } }, "sha512-4Ml8dO9mkwnIidflpunwVMLX2KJA79b53T9xTBkH1Yzy0iOnbEE27r25wvgJgyszU0aznbPBv2++FZ0d0B5Zhg=="],
"@nadohq/trigger-client": ["@nadohq/trigger-client@0.1.0-alpha.45", "", { "dependencies": { "@nadohq/engine-client": "^0.1.0-alpha.45", "@nadohq/shared": "^0.1.0-alpha.45", "axios": "*", "ts-mixer": "*" }, "peerDependencies": { "viem": "*" } }, "sha512-Xt8W9zxOZhMvoXSRnx9kUR26wWuHc3EgTVTBbUXt7SlI9v3IP9I3idS6SU3j2f08flcvNqRmC2EbXyYDC2XeyQ=="],
"@noble/ciphers": ["@noble/ciphers@1.3.0", "", {}, "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw=="],
"@noble/curves": ["@noble/curves@1.4.2", "", { "dependencies": { "@noble/hashes": "1.4.0" } }, "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw=="],
"@noble/ed25519": ["@noble/ed25519@3.0.0", "", {}, "sha512-QyteqMNm0GLqfa5SoYbSC3+Pvykwpn95Zgth4MFVSMKBB75ELl9tX1LAVsN4c3HXOrakHsF2gL4zWDAYCcsnzg=="],
@@ -138,7 +157,7 @@
"@scure/bip39": ["@scure/bip39@1.3.0", "", { "dependencies": { "@noble/hashes": "~1.4.0", "@scure/base": "~1.1.6" } }, "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ=="],
"@types/bun": ["@types/bun@1.2.22", "", { "dependencies": { "bun-types": "1.2.22" } }, "sha512-5A/KrKos2ZcN0c6ljRSOa1fYIyCKhZfIVYeuyb4snnvomnpFqC0tTsEkdqNxbAgExV384OETQ//WAjl3XbYqQA=="],
"@types/bun": ["@types/bun@1.3.8", "", { "dependencies": { "bun-types": "1.3.8" } }, "sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA=="],
"@types/chai": ["@types/chai@5.2.2", "", { "dependencies": { "@types/deep-eql": "*" } }, "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg=="],
@@ -152,8 +171,6 @@
"@types/node": ["@types/node@24.5.2", "", { "dependencies": { "undici-types": "~7.12.0" } }, "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ=="],
"@types/react": ["@types/react@19.1.13", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ=="],
"@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="],
"@vitest/mocker": ["@vitest/mocker@3.2.4", "", { "dependencies": { "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ=="],
@@ -168,7 +185,9 @@
"@vitest/utils": ["@vitest/utils@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA=="],
"ansi-escapes": ["ansi-escapes@7.1.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-YdhtCd19sKRKfAAUsrcC1wzm4JuzJoiX4pOJqIoW2qmKj5WzG/dL8uUJ0361zaXtHqK7gEhOwtAtz7t3Yq3X5g=="],
"abitype": ["abitype@1.2.3", "", { "peerDependencies": { "typescript": ">=5.0.4", "zod": "^3.22.0 || ^4.0.0" }, "optionalPeers": ["typescript", "zod"] }, "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg=="],
"ansi-escapes": ["ansi-escapes@7.2.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw=="],
"ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
@@ -180,15 +199,17 @@
"auto-bind": ["auto-bind@5.0.1", "", {}, "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg=="],
"axios": ["axios@1.12.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw=="],
"axios": ["axios@1.13.4", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg=="],
"bun-types": ["bun-types@1.2.22", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-hwaAu8tct/Zn6Zft4U9BsZcXkYomzpHJX28ofvx7k0Zz2HNz54n1n+tDgxoWFGB4PcFvJXJQloPhaV2eP3Q6EA=="],
"bignumber.js": ["bignumber.js@9.3.1", "", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="],
"bun-types": ["bun-types@1.3.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q=="],
"cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="],
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
"ccxt": ["ccxt@4.5.12", "", { "dependencies": { "ws": "^8.8.1" } }, "sha512-2lfL2TKjq4vBkQUQWJfDqFywhvYCZmk9r0SWC8GqA4AHZ6qozKVUJowxQTvdRsLX9jBwYSE0nc7JVurBrQ6SHg=="],
"ccxt": ["ccxt@4.5.35", "", { "dependencies": { "ws": "^8.8.1" } }, "sha512-aFn1jq/vR9wD3Vxu/2UFoS8snqlvfYn/iYrNhyZZfzB3N+kAHhP5+sAgO6ZwNHkHiUT9IPPahC1ZSFdPtjpIYA=="],
"chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="],
@@ -200,7 +221,7 @@
"cli-cursor": ["cli-cursor@4.0.0", "", { "dependencies": { "restore-cursor": "^4.0.0" } }, "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg=="],
"cli-truncate": ["cli-truncate@4.0.0", "", { "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^7.0.0" } }, "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA=="],
"cli-truncate": ["cli-truncate@5.1.1", "", { "dependencies": { "slice-ansi": "^7.1.0", "string-width": "^8.0.0" } }, "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A=="],
"code-excerpt": ["code-excerpt@4.0.0", "", { "dependencies": { "convert-to-spaces": "^2.0.1" } }, "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA=="],
@@ -208,15 +229,13 @@
"convert-to-spaces": ["convert-to-spaces@2.0.1", "", {}, "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
"deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="],
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
"dotenv": ["dotenv@17.2.2", "", {}, "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q=="],
"dotenv": ["dotenv@17.2.3", "", {}, "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w=="],
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
@@ -244,6 +263,8 @@
"ethereum-cryptography": ["ethereum-cryptography@2.2.1", "", { "dependencies": { "@noble/curves": "1.4.2", "@noble/hashes": "1.4.0", "@scure/bip32": "1.4.0", "@scure/bip39": "1.3.0" } }, "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg=="],
"eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="],
"expect-type": ["expect-type@1.2.2", "", {}, "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA=="],
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
@@ -272,12 +293,14 @@
"indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="],
"ink": ["ink@6.3.1", "", { "dependencies": { "@alcalzone/ansi-tokenize": "^0.2.0", "ansi-escapes": "^7.0.0", "ansi-styles": "^6.2.1", "auto-bind": "^5.0.1", "chalk": "^5.6.0", "cli-boxes": "^3.0.0", "cli-cursor": "^4.0.0", "cli-truncate": "^4.0.0", "code-excerpt": "^4.0.0", "es-toolkit": "^1.39.10", "indent-string": "^5.0.0", "is-in-ci": "^2.0.0", "patch-console": "^2.0.0", "react-reconciler": "^0.32.0", "signal-exit": "^3.0.7", "slice-ansi": "^7.1.0", "stack-utils": "^2.0.6", "string-width": "^7.2.0", "type-fest": "^4.27.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0", "ws": "^8.18.0", "yoga-layout": "~3.2.1" }, "peerDependencies": { "@types/react": ">=19.0.0", "react": ">=19.0.0", "react-devtools-core": "^6.1.2" }, "optionalPeers": ["@types/react", "react-devtools-core"] }, "sha512-3wGwITGrzL6rkWsi2gEKzgwdafGn4ZYd3u4oRp+sOPvfoxEHlnoB5Vnk9Uy5dMRUhDOqF3hqr4rLQ4lEzBc2sQ=="],
"ink": ["ink@6.6.0", "", { "dependencies": { "@alcalzone/ansi-tokenize": "^0.2.1", "ansi-escapes": "^7.2.0", "ansi-styles": "^6.2.1", "auto-bind": "^5.0.1", "chalk": "^5.6.0", "cli-boxes": "^3.0.0", "cli-cursor": "^4.0.0", "cli-truncate": "^5.1.1", "code-excerpt": "^4.0.0", "es-toolkit": "^1.39.10", "indent-string": "^5.0.0", "is-in-ci": "^2.0.0", "patch-console": "^2.0.0", "react-reconciler": "^0.33.0", "signal-exit": "^3.0.7", "slice-ansi": "^7.1.0", "stack-utils": "^2.0.6", "string-width": "^8.1.0", "type-fest": "^4.27.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0", "ws": "^8.18.0", "yoga-layout": "~3.2.1" }, "peerDependencies": { "@types/react": ">=19.0.0", "react": ">=19.0.0", "react-devtools-core": "^6.1.2" }, "optionalPeers": ["@types/react", "react-devtools-core"] }, "sha512-QDt6FgJxgmSxAelcOvOHUvFxbIUjVpCH5bx+Slvc5m7IEcpGt3dYwbz/L+oRnqEGeRvwy1tineKK4ect3nW1vQ=="],
"is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="],
"is-in-ci": ["is-in-ci@2.0.0", "", { "bin": { "is-in-ci": "cli.js" } }, "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w=="],
"isows": ["isows@1.0.7", "", { "peerDependencies": { "ws": "*" } }, "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg=="],
"js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="],
"loupe": ["loupe@3.2.1", "", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="],
@@ -298,6 +321,8 @@
"onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
"ox": ["ox@0.11.3", "", { "dependencies": { "@adraffy/ens-normalize": "^1.11.0", "@noble/ciphers": "^1.3.0", "@noble/curves": "1.9.1", "@noble/hashes": "^1.8.0", "@scure/bip32": "^1.7.0", "@scure/bip39": "^1.6.0", "abitype": "^1.2.3", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-1bWYGk/xZel3xro3l8WGg6eq4YEKlaqvyMtVhfMFpbJzK2F6rj4EDRtqDCWVEJMkzcmEi9uW2QxsqELokOlarw=="],
"patch-console": ["patch-console@2.0.0", "", {}, "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA=="],
"pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
@@ -312,15 +337,15 @@
"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
"react": ["react@19.1.1", "", {}, "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ=="],
"react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
"react-reconciler": ["react-reconciler@0.32.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-2NPMOzgTlG0ZWdIf3qG+dcbLSoAc/uLfOwckc3ofy5sSK0pLJqnQLpUFxvGcN2rlXSjnVtGeeFLNimCQEj5gOQ=="],
"react-reconciler": ["react-reconciler@0.33.0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA=="],
"restore-cursor": ["restore-cursor@4.0.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg=="],
"rollup": ["rollup@4.52.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.52.0", "@rollup/rollup-android-arm64": "4.52.0", "@rollup/rollup-darwin-arm64": "4.52.0", "@rollup/rollup-darwin-x64": "4.52.0", "@rollup/rollup-freebsd-arm64": "4.52.0", "@rollup/rollup-freebsd-x64": "4.52.0", "@rollup/rollup-linux-arm-gnueabihf": "4.52.0", "@rollup/rollup-linux-arm-musleabihf": "4.52.0", "@rollup/rollup-linux-arm64-gnu": "4.52.0", "@rollup/rollup-linux-arm64-musl": "4.52.0", "@rollup/rollup-linux-loong64-gnu": "4.52.0", "@rollup/rollup-linux-ppc64-gnu": "4.52.0", "@rollup/rollup-linux-riscv64-gnu": "4.52.0", "@rollup/rollup-linux-riscv64-musl": "4.52.0", "@rollup/rollup-linux-s390x-gnu": "4.52.0", "@rollup/rollup-linux-x64-gnu": "4.52.0", "@rollup/rollup-linux-x64-musl": "4.52.0", "@rollup/rollup-openharmony-arm64": "4.52.0", "@rollup/rollup-win32-arm64-msvc": "4.52.0", "@rollup/rollup-win32-ia32-msvc": "4.52.0", "@rollup/rollup-win32-x64-gnu": "4.52.0", "@rollup/rollup-win32-x64-msvc": "4.52.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-+IuescNkTJQgX7AkIDtITipZdIGcWF0pnVvZTWStiazUmcGA2ag8dfg0urest2XlXUi9kuhfQ+qmdc5Stc3z7g=="],
"scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="],
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
"siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="],
@@ -336,7 +361,7 @@
"std-env": ["std-env@3.9.0", "", {}, "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw=="],
"string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
"string-width": ["string-width@8.1.1", "", { "dependencies": { "get-east-asian-width": "^1.3.0", "strip-ansi": "^7.1.0" } }, "sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw=="],
"strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
@@ -354,12 +379,18 @@
"tinyspy": ["tinyspy@4.0.4", "", {}, "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q=="],
"trading-signals": ["trading-signals@7.4.3", "", {}, "sha512-kOyzd85qhuhU7yGkB5z74MVP6j30xBCfZy5+bgBnvfxY1ZdvaQsdD+C5j+CoIRtCAgSOuxB7jmPpBrqO6h17sQ=="],
"ts-mixer": ["ts-mixer@6.0.4", "", {}, "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA=="],
"type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
"undici-types": ["undici-types@7.12.0", "", {}, "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ=="],
"viem": ["viem@2.45.1", "", { "dependencies": { "@noble/curves": "1.9.1", "@noble/hashes": "1.8.0", "@scure/bip32": "1.7.0", "@scure/bip39": "1.6.0", "abitype": "1.2.3", "isows": "1.0.7", "ox": "0.11.3", "ws": "8.18.3" }, "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-LN6Pp7vSfv50LgwhkfSbIXftAM5J89lP9x8TeDa8QM7o41IxlHrDh0F9X+FfnCWtsz11pEVV5sn+yBUoOHNqYA=="],
"vite": ["vite@7.1.7", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA=="],
"vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="],
@@ -372,12 +403,38 @@
"wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="],
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
"ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="],
"yoga-layout": ["yoga-layout@3.2.1", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="],
"cli-truncate/slice-ansi": ["slice-ansi@5.0.0", "", { "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" } }, "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ=="],
"ox/@noble/curves": ["@noble/curves@1.9.1", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA=="],
"cli-truncate/slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@4.0.0", "", {}, "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ=="],
"ox/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
"ox/@scure/bip32": ["@scure/bip32@1.7.0", "", { "dependencies": { "@noble/curves": "~1.9.0", "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw=="],
"ox/@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="],
"viem/@noble/curves": ["@noble/curves@1.9.1", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA=="],
"viem/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
"viem/@scure/bip32": ["@scure/bip32@1.7.0", "", { "dependencies": { "@noble/curves": "~1.9.0", "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw=="],
"viem/@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="],
"viem/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
"widest-line/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
"wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
"ox/@scure/bip32/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="],
"ox/@scure/bip39/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="],
"viem/@scure/bip32/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="],
"viem/@scure/bip39/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="],
}
}
+136
View File
@@ -0,0 +1,136 @@
# SUMMARY
> Source: https://docs.nado.xyz
## Pages
- https://docs.nado.xyz
- https://docs.nado.xyz/mission
- https://docs.nado.xyz/orderbook-architecture
- https://docs.nado.xyz/products
- https://docs.nado.xyz/margin-types
- https://docs.nado.xyz/subaccounts-and-health
- https://docs.nado.xyz/liquidations
- https://docs.nado.xyz/pnl-settlements
- https://docs.nado.xyz/oracles
- https://docs.nado.xyz/fees-and-rebates
- https://docs.nado.xyz/funding-rates
- https://docs.nado.xyz/order-types
- https://docs.nado.xyz/nlp
- https://docs.nado.xyz/onboarding-tutorial
- https://docs.nado.xyz/onboarding-tutorial/bridging-usdt0-to-ink
- https://docs.nado.xyz/faqs
- https://docs.nado.xyz/contracts
- https://docs.nado.xyz/legal
- https://docs.nado.xyz/legal/restricted-territories
- https://docs.nado.xyz/maintenance-windows
- https://docs.nado.xyz/market-parameters
- https://docs.nado.xyz/developer-resources/api
- https://docs.nado.xyz/developer-resources/api/endpoints
- https://docs.nado.xyz/developer-resources/api/gateway
- https://docs.nado.xyz/developer-resources/api/gateway/executes
- https://docs.nado.xyz/developer-resources/api/gateway/executes/place-order
- https://docs.nado.xyz/developer-resources/api/gateway/executes/place-orders
- https://docs.nado.xyz/developer-resources/api/gateway/executes/cancel-orders
- https://docs.nado.xyz/developer-resources/api/gateway/executes/cancel-product-orders
- https://docs.nado.xyz/developer-resources/api/gateway/executes/cancel-and-place
- https://docs.nado.xyz/developer-resources/api/gateway/executes/withdraw-collateral
- https://docs.nado.xyz/developer-resources/api/gateway/executes/transfer-quote
- https://docs.nado.xyz/developer-resources/api/gateway/executes/liquidate-subaccount
- https://docs.nado.xyz/developer-resources/api/gateway/executes/mint-nlp
- https://docs.nado.xyz/developer-resources/api/gateway/executes/burn-nlp
- https://docs.nado.xyz/developer-resources/api/gateway/executes/link-signer
- https://docs.nado.xyz/developer-resources/api/gateway/queries
- https://docs.nado.xyz/developer-resources/api/gateway/queries/status
- https://docs.nado.xyz/developer-resources/api/gateway/queries/contracts
- https://docs.nado.xyz/developer-resources/api/gateway/queries/nonces
- https://docs.nado.xyz/developer-resources/api/gateway/queries/order
- https://docs.nado.xyz/developer-resources/api/gateway/queries/orders
- https://docs.nado.xyz/developer-resources/api/gateway/queries/subaccount-info
- https://docs.nado.xyz/developer-resources/api/gateway/queries/isolated-positions
- https://docs.nado.xyz/developer-resources/api/gateway/queries/market-liquidity
- https://docs.nado.xyz/developer-resources/api/gateway/queries/symbols
- https://docs.nado.xyz/developer-resources/api/gateway/queries/all-products
- https://docs.nado.xyz/developer-resources/api/gateway/queries/edge-all-products
- https://docs.nado.xyz/developer-resources/api/gateway/queries/market-prices
- https://docs.nado.xyz/developer-resources/api/gateway/queries/max-order-size
- https://docs.nado.xyz/developer-resources/api/gateway/queries/max-withdrawable
- https://docs.nado.xyz/developer-resources/api/gateway/queries/max-nlp-mintable
- https://docs.nado.xyz/developer-resources/api/gateway/queries/max-nlp-burnable
- https://docs.nado.xyz/developer-resources/api/gateway/queries/nlp-pool-info
- https://docs.nado.xyz/developer-resources/api/gateway/queries/nlp-locked-balances
- https://docs.nado.xyz/developer-resources/api/gateway/queries/fee-rates
- https://docs.nado.xyz/developer-resources/api/gateway/queries/health-groups
- https://docs.nado.xyz/developer-resources/api/gateway/queries/linked-signer
- https://docs.nado.xyz/developer-resources/api/gateway/queries/insurance
- https://docs.nado.xyz/developer-resources/api/gateway/signing
- https://docs.nado.xyz/developer-resources/api/gateway/signing/examples
- https://docs.nado.xyz/developer-resources/api/gateway/signing/q-and-a
- https://docs.nado.xyz/developer-resources/api/subscriptions
- https://docs.nado.xyz/developer-resources/api/subscriptions/authentication
- https://docs.nado.xyz/developer-resources/api/subscriptions/streams
- https://docs.nado.xyz/developer-resources/api/subscriptions/events
- https://docs.nado.xyz/developer-resources/api/subscriptions/rate-limits
- https://docs.nado.xyz/developer-resources/api/archive-indexer
- https://docs.nado.xyz/developer-resources/api/archive-indexer/orders
- https://docs.nado.xyz/developer-resources/api/archive-indexer/matches
- https://docs.nado.xyz/developer-resources/api/archive-indexer/events
- https://docs.nado.xyz/developer-resources/api/archive-indexer/candlesticks
- https://docs.nado.xyz/developer-resources/api/archive-indexer/edge-candlesticks
- https://docs.nado.xyz/developer-resources/api/archive-indexer/product-snapshots
- https://docs.nado.xyz/developer-resources/api/archive-indexer/funding-rate
- https://docs.nado.xyz/developer-resources/api/archive-indexer/interest-and-funding-payments
- https://docs.nado.xyz/developer-resources/api/archive-indexer/oracle-price
- https://docs.nado.xyz/developer-resources/api/archive-indexer/oracle-snapshots
- https://docs.nado.xyz/developer-resources/api/archive-indexer/perp-prices
- https://docs.nado.xyz/developer-resources/api/archive-indexer/market-snapshots
- https://docs.nado.xyz/developer-resources/api/archive-indexer/edge-market-snapshots
- https://docs.nado.xyz/developer-resources/api/archive-indexer/subaccounts
- https://docs.nado.xyz/developer-resources/api/archive-indexer/subaccount-snapshots
- https://docs.nado.xyz/developer-resources/api/archive-indexer/linked-signers
- https://docs.nado.xyz/developer-resources/api/archive-indexer/linked-signer-rate-limit
- https://docs.nado.xyz/developer-resources/api/archive-indexer/isolated-subaccounts
- https://docs.nado.xyz/developer-resources/api/archive-indexer/signatures
- https://docs.nado.xyz/developer-resources/api/archive-indexer/fast-withdrawal-signature
- https://docs.nado.xyz/developer-resources/api/archive-indexer/nlp-funding-payments
- https://docs.nado.xyz/developer-resources/api/archive-indexer/nlp-interest-payments
- https://docs.nado.xyz/developer-resources/api/archive-indexer/nlp-snapshots
- https://docs.nado.xyz/developer-resources/api/archive-indexer/liquidation-feed
- https://docs.nado.xyz/developer-resources/api/archive-indexer/sequencer-backlog
- https://docs.nado.xyz/developer-resources/api/archive-indexer/direct-deposit-address
- https://docs.nado.xyz/developer-resources/api/archive-indexer/quote-price
- https://docs.nado.xyz/developer-resources/api/archive-indexer/ink-airdrop
- https://docs.nado.xyz/developer-resources/api/trigger
- https://docs.nado.xyz/developer-resources/api/trigger/executes
- https://docs.nado.xyz/developer-resources/api/trigger/executes/place-order
- https://docs.nado.xyz/developer-resources/api/trigger/executes/place-orders
- https://docs.nado.xyz/developer-resources/api/trigger/executes/cancel-orders
- https://docs.nado.xyz/developer-resources/api/trigger/executes/cancel-product-orders
- https://docs.nado.xyz/developer-resources/api/trigger/queries
- https://docs.nado.xyz/developer-resources/api/trigger/queries/list-trigger-orders
- https://docs.nado.xyz/developer-resources/api/trigger/queries/list-twap-executions
- https://docs.nado.xyz/developer-resources/api/v2
- https://docs.nado.xyz/developer-resources/api/v2/assets
- https://docs.nado.xyz/developer-resources/api/v2/pairs
- https://docs.nado.xyz/developer-resources/api/v2/apr
- https://docs.nado.xyz/developer-resources/api/v2/orderbook
- https://docs.nado.xyz/developer-resources/api/v2/tickers
- https://docs.nado.xyz/developer-resources/api/v2/contracts
- https://docs.nado.xyz/developer-resources/api/v2/trades
- https://docs.nado.xyz/developer-resources/api/order-appendix
- https://docs.nado.xyz/developer-resources/api/rate-limits
- https://docs.nado.xyz/developer-resources/api/errors
- https://docs.nado.xyz/developer-resources/api/symbols
- https://docs.nado.xyz/developer-resources/api/depositing
- https://docs.nado.xyz/developer-resources/api/withdrawing-on-chain
- https://docs.nado.xyz/developer-resources/api/integrate-via-smart-contracts
- https://docs.nado.xyz/developer-resources/api/definitions-formulas
- https://docs.nado.xyz/developer-resources/api/api-changelog
- https://docs.nado.xyz/developer-resources/typescript-sdk
- https://docs.nado.xyz/developer-resources/typescript-sdk/getting-started
- https://docs.nado.xyz/developer-resources/typescript-sdk/how-to
- https://docs.nado.xyz/developer-resources/typescript-sdk/how-to/create-a-nado-client
- https://docs.nado.xyz/developer-resources/typescript-sdk/how-to/useful-common-functions
- https://docs.nado.xyz/developer-resources/typescript-sdk/how-to/query-markets-and-products
- https://docs.nado.xyz/developer-resources/typescript-sdk/how-to/deposit-funds
- https://docs.nado.xyz/developer-resources/typescript-sdk/how-to/withdraw-funds
- https://docs.nado.xyz/developer-resources/typescript-sdk/how-to/manage-orders
+35
View File
@@ -0,0 +1,35 @@
# Contracts
> **Nado Github Repo**: <https://github.com/nadohq/nado-contracts>
### Mainnet Contracts — Ink
> **Explorer URL**: [https://explorer.inkonchain.com](https://explorer.inkonchain.com/)
| Contract Name | Address |
| :---------------: | :------------------------------------------------------------------------------------------------------------------------------: |
| **Deployer** | [0xC1cC56caB60e832665E6c3780BfEBe3C1C971603](https://explorer.inkonchain.com/address/0xC1cC56caB60e832665E6c3780BfEBe3C1C971603) |
| **Quote** | [0x0200C29006150606B650577BBE7B6248F58470c1](https://explorer.inkonchain.com/address/0x0200C29006150606B650577BBE7B6248F58470c1) |
| **Querier** | [0x68798229F88251b31D534733D6C4098318c9dff8](https://explorer.inkonchain.com/address/0x68798229F88251b31D534733D6C4098318c9dff8) |
| **Clearinghouse** | [0xD218103918C19D0A10cf35300E4CfAfbD444c5fE](https://explorer.inkonchain.com/address/0xD218103918C19D0A10cf35300E4CfAfbD444c5fE) |
| **Endpoint** | [0x05ec92D78ED421f3D3Ada77FFdE167106565974E](https://explorer.inkonchain.com/address/0x05ec92D78ED421f3D3Ada77FFdE167106565974E) |
| **SpotEngine** | [0xFcD94770B95fd9Cc67143132BB172EB17A0907fE](https://explorer.inkonchain.com/address/0xFcD94770B95fd9Cc67143132BB172EB17A0907fE) |
| **PerpEngine** | [0xF8599D58d1137fC56EcDd9C16ee139C8BDf96da1](https://explorer.inkonchain.com/address/0xF8599D58d1137fC56EcDd9C16ee139C8BDf96da1) |
| **WithdrawPool** | [0x09fb495AA7859635f755E827d64c4C9A2e5b9651](https://explorer.inkonchain.com/address/0x09fb495AA7859635f755E827d64c4C9A2e5b9651) |
***
### Testnet Contracts — Ink Sepolia
> **Explorer URL**: <https://explorer-sepolia.inkonchain.com/>
| | |
| :---------------: | :--------------------------------------------------------------------------------------------------------------------------------------: |
| **Deployer** | [0x59841b3761Ed1D089a783E4d7CB49E4534CD4F85](https://explorer-sepolia.inkonchain.com/address/0x59841b3761Ed1D089a783E4d7CB49E4534CD4F85) |
| **Quote** | [0x60F50F902b2E91aef7D6c700Eb22599e297fa86F](https://explorer-sepolia.inkonchain.com/address/0x60F50F902b2E91aef7D6c700Eb22599e297fa86F) |
| **Querier** | [0x8E693BEa316bcC0F4f8be403081b954a0E3743C8](https://explorer-sepolia.inkonchain.com/address/0x8E693BEa316bcC0F4f8be403081b954a0E3743C8) |
| **Clearinghouse** | [0x23a283B359D55A941bBeEC58801B6b17D955CC73](https://explorer-sepolia.inkonchain.com/address/0x23a283B359D55A941bBeEC58801B6b17D955CC73) |
| **Endpoint** | [0x698D87105274292B5673367DEC81874Ce3633Ac2](https://explorer-sepolia.inkonchain.com/address/0x698D87105274292B5673367DEC81874Ce3633Ac2) |
| **SpotEngine** | [0x3352b2fF0fAc4ce38A6eA1C188cF4F924df54E5D](https://explorer-sepolia.inkonchain.com/address/0x3352b2fF0fAc4ce38A6eA1C188cF4F924df54E5D) |
| **PerpEngine** | [0x4E859C47fea3666B5053B16C81AF64e77567702e](https://explorer-sepolia.inkonchain.com/address/0x4E859C47fea3666B5053B16C81AF64e77567702e) |
| **WithdrawPool** | [0xBD672Fe513acbA5c1ceE7b02F998A1B542852b3b](https://explorer-sepolia.inkonchain.com/address/0xBD672Fe513acbA5c1ceE7b02F998A1B542852b3b) |
+31
View File
@@ -0,0 +1,31 @@
# API
## Overview
Nado's API is divided into the following categories:
1. A **websocket/REST** API (**gateway**) that supports writes (executes) and polling (queries).
2. A **subscriptions** API that allows to subscribe to live data feeds.
3. An **indexer** API (**archive**) that allows you to query historical data.
4. A **trigger** API that allows to execute orders only under specified price conditions.
{% hint style="info" %} <mark style="color:purple;">**NOTE**</mark>: To contact the Nado team with any questions or inquiries about Private Gateway connections, such as increased limits, please reach out on the Telegram channel below:
* **Telegram Group =** TBD
{% endhint %}
{% content-ref url="api/gateway" %}
[gateway](https://docs.nado.xyz/developer-resources/api/gateway)
{% endcontent-ref %}
{% content-ref url="api/subscriptions" %}
[subscriptions](https://docs.nado.xyz/developer-resources/api/subscriptions)
{% endcontent-ref %}
{% content-ref url="api/archive-indexer" %}
[archive-indexer](https://docs.nado.xyz/developer-resources/api/archive-indexer)
{% endcontent-ref %}
{% content-ref url="api/trigger" %}
[trigger](https://docs.nado.xyz/developer-resources/api/trigger)
{% endcontent-ref %}
@@ -0,0 +1,409 @@
# API Changelog
This document tracks all changes to the Nado API.
***
<details>
<summary><strong>December 11, 2025</strong></summary>
**Risk System Updates**
**Spread Weight Caps**
* Introduced upper bounds for spread weights to manage risk at extreme leverage levels:
* <mark style="color:red;">`initial_spread_weight`</mark>: Maximum **0.99**
* <mark style="color:red;">`maintenance_spread_weight`</mark>: Maximum **0.994**
* **Impact**:
* Existing markets (≤20x leverage): No change in behavior
* Future high-leverage markets (30x+): Spread positions will have capped health benefits
* Prevents extreme leverage abuse via spread positions
* **Technical Details**:
* Base spread weight calculated as: `spread_weight = 1 - (1 - product_weight) / 5`
* Final spread weight: `min(spread_weight, cap)`
* Cap applies during health calculations for spread positions
**Minimum Liquidation Penalties**
* Introduced minimum distance requirements between oracle price and liquidation price:
* <mark style="color:red;">**Non-spread liquidations**</mark>: Minimum **0.5%** from oracle price
* <mark style="color:red;">**Spread liquidations**</mark>: Minimum **0.25%** from oracle price
* **Impact**:
* Ensures liquidators always have sufficient incentive to execute liquidations
* Prevents unprofitable liquidation scenarios for low-volatility assets
* Particularly important for high-leverage positions where natural penalties may be very small
* **Technical Details**:
* **Non-spread longs**: `oracle_price × (1 - max((1 - maint_asset_weight) / 5, 0.005))`
* **Non-spread shorts**: `oracle_price × (1 + max((maint_liability_weight - 1) / 5, 0.005))`
* **Spread selling**: `spot_price × (1 - max((1 - perp_maint_asset_weight) / 10, 0.0025))`
* **Spread buying**: `spot_price × (1 + max((spot_maint_liability_weight - 1) / 10, 0.0025))`
**API Response Changes**
* No breaking changes to API response structure
* Health calculations and liquidation prices automatically reflect new risk parameters
**Documentation Updates**
* See [Subaccounts & Health](https://docs.nado.xyz/subaccounts-and-health#spreads) for spread weight cap details
* See [Liquidations](https://docs.nado.xyz/liquidations#liquidation-price) for minimum liquidation penalty details
</details>
***
<details>
<summary><strong>December 1, 2025</strong></summary>
**Query Enhancements**
**Pre-State Simulation for SubaccountInfo Query**
* Added <mark style="color:red;">`pre_state`</mark> parameter to <mark style="color:red;">`SubaccountInfo`</mark> query
* Type: <mark style="color:red;">`string`</mark> (accepts <mark style="color:red;">`"true"`</mark> or <mark style="color:red;">`"false"`</mark>)
* When set to <mark style="color:red;">`"true"`</mark> along with <mark style="color:red;">`txns`</mark>, returns a <mark style="color:red;">`pre_state`</mark> object in the response
* <mark style="color:red;">`pre_state`</mark> contains the subaccount state **before** the simulated transactions were applied
* Useful for comparing before/after states when simulating trades
* <mark style="color:red;">`pre_state`</mark> includes:
* <mark style="color:red;">`healths`</mark>: Health information before transactions
* <mark style="color:red;">`health_contributions`</mark>: Per-product health contributions before transactions
* <mark style="color:red;">`spot_balances`</mark>: Spot balances before transactions
* <mark style="color:red;">`perp_balances`</mark>: Perpetual balances before transactions
**Use Cases:**
* Position simulation and preview
* Risk analysis for potential trades
* UI/UX for showing before/after comparisons
* Testing transaction impacts without on-chain execution
**Documentation:** See [Subaccount Info Query](https://docs.nado.xyz/developer-resources/gateway/queries/subaccount-info#example-with-pre_state) for detailed examples.
</details>
***
<details>
<summary><strong>November 20, 2025 - Initial Launch</strong></summary>
#### Core Changes
**1. Removal of LP Functionality**
* <mark style="color:red;">`SubaccountInfo`</mark> no longer has:
* <mark style="color:red;">`lp_balance`</mark> in <mark style="color:red;">`spot_balances`</mark> and <mark style="color:red;">`perp_balances`</mark>
* <mark style="color:red;">`lp_state`</mark> in <mark style="color:red;">`spot_products`</mark> and <mark style="color:red;">`perp_products`</mark>
* <mark style="color:red;">`lp_spread_x18`</mark> in <mark style="color:red;">`book_info`</mark> of both <mark style="color:red;">`spot_products`</mark> and <mark style="color:red;">`perp_products`</mark>
* Historical <mark style="color:red;">`events`</mark> no longer include:
* <mark style="color:red;">`net_entry_lp_unrealized`</mark>
* <mark style="color:red;">`net_entry_lp_cumulative`</mark>
**2. Removal of Redundant Fields**
* <mark style="color:red;">`SubaccountInfo`</mark> no longer has:
* <mark style="color:red;">`last_cumulative_multiplier_x18`</mark> in <mark style="color:red;">`balance`</mark> of <mark style="color:red;">`spot_balances`</mark>
**3. Products Config Model Updates**
* Added: <mark style="color:red;">`withdraw_fee_x18`</mark> and <mark style="color:red;">`min_deposit_rate_x18`</mark> to <mark style="color:red;">`spot_products.config`</mark>
**4. Products Risk Model Updates**
* Added: <mark style="color:red;">`price_x18`</mark> to both <mark style="color:red;">`spot_products.risk`</mark> and <mark style="color:red;">`perp_products.risk`</mark>
* Removed: <mark style="color:red;">`large_position_penalty_x18`</mark>
**5. Deposit Rate Query**
* Removed: <mark style="color:red;">`min_deposit_rates`</mark> query
* Use <mark style="color:red;">`min_deposit_rate_x18`</mark> in <mark style="color:red;">`spot_products.config`</mark> instead
#### Market Structure Changes
**6. Removal of Virtual Books**
* <mark style="color:red;">`Contracts`</mark> query no longer returns <mark style="color:red;">`book_addrs`</mark>
* <mark style="color:red;">`PlaceOrder`</mark> verify contract is now <mark style="color:red;">`address(product_id)`</mark>\
\&#xNAN;*Example: product <mark style="color:red;">18</mark> → <mark style="color:red;">`0x0000000000000000000000000000000000000012`</mark>*
**7. Minimum Size denomination**
* <mark style="color:red;">`min_size`</mark> is now **USDT0 denominated** (not base denominated)
* <mark style="color:red;">`min_size = 10`</mark> → minimum order size = 10 USDT0 (<mark style="color:red;">`order_price * order_amount`</mark>)
* <mark style="color:red;">`size_increment`</mark> remains **base denominated**
* Example: BTC with <mark style="color:red;">`size_increment = 0.0001`</mark> and <mark style="color:red;">`min_size = 20`</mark>:
* ✅ Valid: 100,000 \* 0.0002 = 20 USDT0
* ❌ Invalid: 100,000 \* 0.0001 = 10 USDT0
* ❌ Invalid: 100,000 \* 0.00025 (not multiple of 0.0001)
#### Orders & Signing
**8. Place Orders Execute**
* Added: <mark style="color:red;">`place_orders`</mark> execute - place multiple orders in a single request
* Accepts array of orders with same structure as <mark style="color:red;">`place_order`</mark>
* Optional <mark style="color:red;">`stop_on_failure`</mark> parameter to stop processing remaining orders on first failure
* Returns array of results with <mark style="color:red;">`digest`</mark> (if successful) or <mark style="color:red;">`error`</mark> (if failed) for each order
* Rate limit weight calculated per order
See [Place Orders](https://docs.nado.xyz/developer-resources/api/gateway/executes/place-orders) for details.
**9. EIP712 `Order` Struct Update**
```solidity
struct Order {
bytes32 sender;
int128 priceX18;
int128 amount;
uint64 expiration;
uint64 nonce;
uint128 appendix;
}
```
* New field: <mark style="color:red;">`appendix`</mark>
* All order flags (IOC, post only, reduce-only, triggers) moved into <mark style="color:red;">`appendix`</mark>
* <mark style="color:red;">`expiration`</mark> is now strictly a timestamp
* <mark style="color:red;">`appendix`</mark> bitfield:
```json
| value | reserved | trigger | reduce only | order type | isolated | version |
| 64 bits | 50 bits | 2 bits | 1 bit | 2 bits | 1 bit | 8 bits |
```
* Special encodings:
* <mark style="color:red;">`trigger`</mark> = 2 or 3 → <mark style="color:red;">`value`</mark> encodes TWAP settings (<mark style="color:red;">`times`</mark>, <mark style="color:red;">`slippage_x6`</mark>)
* <mark style="color:red;">`isolated = 1`</mark> → <mark style="color:red;">`value`</mark> encodes isolated margin
* Constraints:
* Isolated orders cannot be TWAP
* TWAP orders must use IOC execution type
See [Order Appendix Docs](https://docs.nado.xyz/developer-resources/api/order-appendix).
**10. TWAP Order Execution**
* Added <mark style="color:red;">`list_twap_executions`</mark> query to trigger service
* TWAP orders track individual execution status (pending, executed, failed, cancelled)
* TWAP execution statuses include execution time and engine response data
**11. Trigger Service Rate Limits**
* Updated trigger order limits from 100 pending orders per subaccount to <mark style="color:red;">`25 pending orders per product per subaccount`</mark>
**12. EIP712 Domain Change**
* Signing domain updated from **`Vertex``Nado`**\
See [Signing Docs](https://docs.nado.xyz/developer-resources/api/gateway/signing).
#### Query Updates
**13.&#x20;**<mark style="color:red;">**`max_order_size`**</mark>
* Added: <mark style="color:red;">`isolated`</mark> parameter - when set to `true`, calculates max order size for an isolated margin position. Defaults to `false`.
**14.&#x20;**<mark style="color:red;">**`orders`**</mark>**&#x20;Query**
* Added: <mark style="color:red;">`trigger_types`</mark> parameter - filter orders by trigger type(s)
**15. Historical Events**
* Added: <mark style="color:red;">`quote_volume_cumulative`</mark> - tracks cumulative trading volume for the subaccount in quote units
* Available in: `events` and `subaccount_snapshots` queries
**16.&#x20;**<mark style="color:red;">**`subaccount_snapshots`**</mark>**&#x20;Query**
* Added: <mark style="color:red;">`active`</mark> parameter - filter snapshots by position status
* <mark style="color:red;">`true`</mark>: returns only products with **non-zero balance** at the timestamp
* <mark style="color:red;">`false`</mark>: returns products with **event history** before the timestamp (default)
**17. Trigger Orders**
* Added: <mark style="color:red;">`place_at`</mark> field - timestamp when trigger order should be placed
**18. Removal of&#x20;**<mark style="color:red;">**`summary`**</mark>**&#x20;Query**
* Removed: <mark style="color:red;">`summary`</mark> query from indexer API
* Use <mark style="color:red;">`subaccount_snapshots`</mark> query instead for historical subaccount data
**19. Query Renaming**
* Renamed: <mark style="color:red;">`usdc_price`</mark> → <mark style="color:red;">`quote_price`</mark> query
* See [Quote Price](https://docs.nado.xyz/developer-resources/api/archive-indexer/quote-price)
**20. Multi-Subaccount `events`, `matches`, `orders`**
* The indexer <mark style="color:red;">`events`</mark>, <mark style="color:red;">`matches`</mark>, and <mark style="color:red;">`orders`</mark> queries now accept a <mark style="color:red;">`subaccounts`</mark> array so you can fetch history for multiple subaccounts in a single request instead of fanning out per subaccount. Please note that the old single-subaccount version is **no longer supported**.
#### Streams
{% hint style="info" %}
See [Subscriptions > Streams](https://docs.nado.xyz/developer-resources/api/subscriptions/streams) for more details
{% endhint %}
**21.&#x20;**<mark style="color:red;">**`OrderUpdate`**</mark>
* Can now subscribe across all products by setting <mark style="color:red;">`product_id = null`</mark>
* <mark style="color:red;">`product_id`</mark> type changed from `u32``Option<u32>`
**22.&#x20;**<mark style="color:red;">**`Fill`**</mark>
* Added: <mark style="color:red;">`fee`</mark>, <mark style="color:red;">`submission_idx`</mark>, and <mark style="color:red;">`appendix`</mark>
* Can now subscribe across all products by setting <mark style="color:red;">`product_id = null`</mark>
**23.&#x20;**<mark style="color:red;">**`PositionChange`**</mark>
* Can now subscribe across all products by setting <mark style="color:red;">`product_id = null`</mark>
* <mark style="color:red;">`product_id`</mark> type changed from `u32``Option<u32>`
* Added: <mark style="color:red;">`isolated`</mark> - indicates whether the position change is for an isolated margin position
**24.&#x20;**<mark style="color:red;">**`FundingPayment`**</mark>
* New stream: <mark style="color:red;">`FundingPayment`</mark>
* Param: <mark style="color:red;">`product_id: u32`</mark>
* Emits hourly funding payment events
**Request**
```json
{
"method": "subscribe",
"stream": {
"type": "funding_payment",
"product_id": 1
},
"id": 123
}
```
**Response**
```json
{
"type": "funding_payment",
"timestamp": 1234567890000,
"product_id": 1,
"payment_amount": "1000000000000000000",
"open_interest": "50000000000000000000",
"cumulative_funding_long_x18": "100000000000000000",
"cumulative_funding_short_x18": "-100000000000000000",
"dt": 3600000
}
```
**25.&#x20;**<mark style="color:red;">**`Liquidation`**</mark>
* New stream: <mark style="color:red;">`Liquidation`</mark>
* Param: <mark style="color:red;">`product_id`</mark> or <mark style="color:red;">`null`</mark> (all products)
* Emits liquidation info (liquidator, liquidatee, amount, price)
**Request**
```json
{
"method": "subscribe",
"stream": {
"type": "liquidation",
"product_id": 1
},
"id": 123
}
```
**Response**
```json
{
"type": "liquidation",
"timestamp": "1234567890000",
"product_ids": [1],
"liquidator": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"liquidatee": "0x8b6fd3859f7065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"amount": "1000000000000000000",
"price": "50000000000000000000"
}
```
**26.&#x20;**<mark style="color:red;">**`LatestCandlestick`**</mark>
* New stream: <mark style="color:red;">`LatestCandlestick`</mark>
* Params: <mark style="color:red;">`product_id`</mark>, <mark style="color:red;">`granularity`</mark> (seconds)
* Emits candlestick updates on every trade
**Request**
```json
{
"method": "subscribe",
"stream": {
"type": "latest_candlestick",
"product_id": 1,
"granularity": 60
},
"id": 123
}
```
**Response**
```json
{
"type": "latest_candlestick",
"timestamp": 1234567890000,
"product_id": 1,
"granularity": 60,
"open_x18": "50000000000000000000",
"high_x18": "51000000000000000000",
"low_x18": "49000000000000000000",
"close_x18": "50500000000000000000",
"volume": "1000000000000000000"
}
```
**27.&#x20;**<mark style="color:red;">**`FundingRate`**</mark>
* New stream: <mark style="color:red;">`FundingRate`</mark>
* Param: <mark style="color:red;">`product_id`</mark> or <mark style="color:red;">`null`</mark> (all products)
* Emits funding rate updates every 20 seconds
* <mark style="color:red;">`funding_rate_x18`</mark> and <mark style="color:red;">`update_time`</mark> values are identical to those from the [Funding Rate](https://docs.nado.xyz/developer-resources/api/archive-indexer/funding-rate) indexer endpoint
**Request**
```json
{
"method": "subscribe",
"stream": {
"type": "funding_rate",
"product_id": 1
},
"id": 123
}
```
**Subscribe to all products:**
```json
{
"method": "subscribe",
"stream": {
"type": "funding_rate",
"product_id": null
},
"id": 123
}
```
**Response**
```json
{
"type": "funding_rate",
"timestamp": "1234567890123456789",
"product_id": 1,
"funding_rate_x18": "50000000000000000",
"update_time": "1234567890"
}
```
</details>
@@ -0,0 +1,127 @@
# Archive (indexer)
Using Nado's indexer API you can access historical data in the platform as it is processed by our offchain sequencer. This includes: trading activity, events, candlesticks and more.
You can interact with our indexer by sending <mark style="color:red;">`HTTP`</mark> requests at <mark style="color:red;">`POST [ARCHIVE_ENDPOINT]`</mark> alongside a json payload of the query. Endpoints:
<mark style="color:red;">`HTTP`</mark> requests must set the `Accept-Encoding` to include `gzip`, `br` or `deflate`
## Endpoints
### Testnet:
* <mark style="color:red;">`https://archive.test.nado.xyz/v1`</mark>
## Available Queries:
{% content-ref url="archive-indexer/orders" %}
[orders](https://docs.nado.xyz/developer-resources/api/archive-indexer/orders)
{% endcontent-ref %}
{% content-ref url="archive-indexer/matches" %}
[matches](https://docs.nado.xyz/developer-resources/api/archive-indexer/matches)
{% endcontent-ref %}
{% content-ref url="archive-indexer/events" %}
[events](https://docs.nado.xyz/developer-resources/api/archive-indexer/events)
{% endcontent-ref %}
{% content-ref url="archive-indexer/candlesticks" %}
[candlesticks](https://docs.nado.xyz/developer-resources/api/archive-indexer/candlesticks)
{% endcontent-ref %}
{% content-ref url="archive-indexer/edge-candlesticks" %}
[edge-candlesticks](https://docs.nado.xyz/developer-resources/api/archive-indexer/edge-candlesticks)
{% endcontent-ref %}
{% content-ref url="archive-indexer/product-snapshots" %}
[product-snapshots](https://docs.nado.xyz/developer-resources/api/archive-indexer/product-snapshots)
{% endcontent-ref %}
{% content-ref url="archive-indexer/funding-rate" %}
[funding-rate](https://docs.nado.xyz/developer-resources/api/archive-indexer/funding-rate)
{% endcontent-ref %}
{% content-ref url="archive-indexer/interest-and-funding-payments" %}
[interest-and-funding-payments](https://docs.nado.xyz/developer-resources/api/archive-indexer/interest-and-funding-payments)
{% endcontent-ref %}
{% content-ref url="archive-indexer/oracle-price" %}
[oracle-price](https://docs.nado.xyz/developer-resources/api/archive-indexer/oracle-price)
{% endcontent-ref %}
{% content-ref url="archive-indexer/oracle-snapshots" %}
[oracle-snapshots](https://docs.nado.xyz/developer-resources/api/archive-indexer/oracle-snapshots)
{% endcontent-ref %}
{% content-ref url="archive-indexer/perp-prices" %}
[perp-prices](https://docs.nado.xyz/developer-resources/api/archive-indexer/perp-prices)
{% endcontent-ref %}
{% content-ref url="archive-indexer/market-snapshots" %}
[market-snapshots](https://docs.nado.xyz/developer-resources/api/archive-indexer/market-snapshots)
{% endcontent-ref %}
{% content-ref url="archive-indexer/edge-market-snapshots" %}
[edge-market-snapshots](https://docs.nado.xyz/developer-resources/api/archive-indexer/edge-market-snapshots)
{% endcontent-ref %}
{% content-ref url="archive-indexer/subaccounts" %}
[subaccounts](https://docs.nado.xyz/developer-resources/api/archive-indexer/subaccounts)
{% endcontent-ref %}
{% content-ref url="archive-indexer/subaccount-snapshots" %}
[subaccount-snapshots](https://docs.nado.xyz/developer-resources/api/archive-indexer/subaccount-snapshots)
{% endcontent-ref %}
{% content-ref url="archive-indexer/linked-signers" %}
[linked-signers](https://docs.nado.xyz/developer-resources/api/archive-indexer/linked-signers)
{% endcontent-ref %}
{% content-ref url="archive-indexer/linked-signer-rate-limit" %}
[linked-signer-rate-limit](https://docs.nado.xyz/developer-resources/api/archive-indexer/linked-signer-rate-limit)
{% endcontent-ref %}
{% content-ref url="archive-indexer/isolated-subaccounts" %}
[isolated-subaccounts](https://docs.nado.xyz/developer-resources/api/archive-indexer/isolated-subaccounts)
{% endcontent-ref %}
{% content-ref url="archive-indexer/signatures" %}
[signatures](https://docs.nado.xyz/developer-resources/api/archive-indexer/signatures)
{% endcontent-ref %}
{% content-ref url="archive-indexer/fast-withdrawal-signature" %}
[fast-withdrawal-signature](https://docs.nado.xyz/developer-resources/api/archive-indexer/fast-withdrawal-signature)
{% endcontent-ref %}
{% content-ref url="archive-indexer/nlp-funding-payments" %}
[nlp-funding-payments](https://docs.nado.xyz/developer-resources/api/archive-indexer/nlp-funding-payments)
{% endcontent-ref %}
{% content-ref url="archive-indexer/nlp-interest-payments" %}
[nlp-interest-payments](https://docs.nado.xyz/developer-resources/api/archive-indexer/nlp-interest-payments)
{% endcontent-ref %}
{% content-ref url="archive-indexer/nlp-snapshots" %}
[nlp-snapshots](https://docs.nado.xyz/developer-resources/api/archive-indexer/nlp-snapshots)
{% endcontent-ref %}
{% content-ref url="archive-indexer/liquidation-feed" %}
[liquidation-feed](https://docs.nado.xyz/developer-resources/api/archive-indexer/liquidation-feed)
{% endcontent-ref %}
{% content-ref url="archive-indexer/sequencer-backlog" %}
[sequencer-backlog](https://docs.nado.xyz/developer-resources/api/archive-indexer/sequencer-backlog)
{% endcontent-ref %}
{% content-ref url="archive-indexer/direct-deposit-address" %}
[direct-deposit-address](https://docs.nado.xyz/developer-resources/api/archive-indexer/direct-deposit-address)
{% endcontent-ref %}
{% content-ref url="archive-indexer/quote-price" %}
[quote-price](https://docs.nado.xyz/developer-resources/api/archive-indexer/quote-price)
{% endcontent-ref %}
{% content-ref url="archive-indexer/ink-airdrop" %}
[ink-airdrop](https://docs.nado.xyz/developer-resources/api/archive-indexer/ink-airdrop)
{% endcontent-ref %}
@@ -0,0 +1,97 @@
# Candlesticks
## Rate limits
* Dynamic based on <mark style="color:red;">`limit`</mark> param provided (**weight = 1 + limit / 20**)
* E.g: With <mark style="color:red;">`limit=100`</mark>, you can make up to 400 requests per min or 66 requests / 10 secs.
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Available Granularities
The following granularities / periods are supported (in seconds):
| Granularity name | Granularity value (in seconds) |
| :--------------: | :----------------------------: |
| 1 minute | 60 |
| 5 minutes | 300 |
| 15 minutes | 900 |
| 1 hour | 3600 |
| 2 hours | 7200 |
| 4 hours | 14400 |
| 1 day | 86400 |
| 1 week | 604800 |
| 4 weeks | 2419200 |
## Request
{% tabs %}
{% tab title="Product candlesticks" %}
Query product candlesticks ordered by <mark style="color:red;">`timestamp`</mark> desc.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"candlesticks": {
"product_id": 1,
"granularity": 60,
"limit": 2
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="113" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of product to fetch candlesticks for.</td></tr><tr><td align="center">granularity</td><td align="center">number</td><td align="center">Yes</td><td>Granularity value in seconds.</td></tr><tr><td align="center">max_time</td><td align="center">number / string</td><td align="center">No</td><td>When providing <mark style="color:red;"><code>max_time</code></mark> (unix epoch in seconds), only return candlesticks with timestamp &#x3C;= <mark style="color:red;"><code>max_time</code></mark></td></tr><tr><td align="center">limit</td><td align="center">number</td><td align="center">No</td><td>Max number of candlesticks to return. defaults to <mark style="color:red;"><code>100</code></mark>. max possible of <mark style="color:red;"><code>500</code></mark>.</td></tr></tbody></table>
## Response
```json
{
"candlesticks": [
{
"product_id": 1,
"granularity": 60,
"submission_idx": "627709",
"timestamp": "1680118140",
"open_x18": "27235000000000000000000",
"high_x18": "27298000000000000000000",
"low_x18": "27235000000000000000000",
"close_x18": "27298000000000000000000",
"volume": "1999999999999999998"
},
{
"product_id": 1,
"granularity": 60,
"submission_idx": "627699",
"timestamp": "1680118080",
"open_x18": "27218000000000000000000",
"high_x18": "27245000000000000000000",
"low_x18": "27218000000000000000000",
"close_x18": "27245000000000000000000",
"volume": "11852999999999999995"
}
]
}
```
## Response Fields
| Field name | Description |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| submission\_idx | Id of the latest recorded transaction that contributes to the candle. |
| product\_id | Id of product candle is associated to. |
| granularity | Candle time interval, expressed in seconds, representing the aggregation period for trading volume and price data |
| open\_x18 | The first fill price of the candle, multiplied by 10^18 |
| high\_x18 | The highest recorded fill price during the defined interval of the candle, multiplied by 10^18 |
| low\_x18 | The lowest recorded fill price during the defined interval of the candle, multiplied by 10^18 |
| close\_x18 | The last price of the candle, multiplied by 10^18 |
| volume | Asset volume, which represents the absolute cumulative fill amounts during the time interval of the candle, multiplied by 10^18 |
@@ -0,0 +1,54 @@
# Direct Deposit Address
## Rate limits
* 240 requests/min or 40 requests/10secs per IP address. (**weight = 10**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Direct Deposit Address" %}
Query the unique direct deposit address for a subaccount.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"direct_deposit_address": {
"subaccount": "0x79cc76364b5fb263a25bd52930e3d9788fcfeea864656661756c740000000000"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="150" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">subaccount</td><td align="center">string</td><td align="center">Yes</td><td>Hex string of the subaccount to fetch the direct deposit address for.</td></tr></tbody></table>
## Response
```json
{
"subaccount": "0x79cc76364b5fb263a25bd52930e3d9788fcfeea864656661756c740000000000",
"deposit_address": "0x1234567890123456789012345678901234567890",
"created_at": "1683315718"
}
```
## Response Fields
### Direct Deposit Address
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>subaccount</td><td>Hex string of the subaccount</td></tr><tr><td>deposit_address</td><td>Unique deposit address for this subaccount</td></tr><tr><td>created_at</td><td>Unix epoch time in seconds when the deposit address was created</td></tr></tbody></table>
{% hint style="info" %}
Direct deposit addresses allow users to deposit funds directly to their subaccount without needing to interact with the smart contract. Funds sent to this address will automatically be credited to the associated subaccount.
{% endhint %}
@@ -0,0 +1,97 @@
# Edge Candlesticks
## Rate limits
* Dynamic based on <mark style="color:red;">`limit`</mark> param provided (**weight = 1 + limit / 20**)
* E.g: With <mark style="color:red;">`limit=100`</mark>, you can make up to 400 requests per min or 66 requests / 10 secs.
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Available Granularities
The following granularities / periods are supported (in seconds):
| Granularity name | Granularity value (in seconds) |
| :--------------: | :----------------------------: |
| 1 minute | 60 |
| 5 minutes | 300 |
| 15 minutes | 900 |
| 1 hour | 3600 |
| 2 hours | 7200 |
| 4 hours | 14400 |
| 1 day | 86400 |
| 1 week | 604800 |
| 4 weeks | 2419200 |
## Request
{% tabs %}
{% tab title="Ede candlesticks" %}
Query edge candlesticks ordered by <mark style="color:red;">`timestamp`</mark> desc.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"edge_candlesticks": {
"product_id": 1,
"granularity": 60,
"limit": 2
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="113" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of product to fetch candlesticks for.</td></tr><tr><td align="center">granularity</td><td align="center">number</td><td align="center">Yes</td><td>Granularity value in seconds.</td></tr><tr><td align="center">max_time</td><td align="center">number / string</td><td align="center">No</td><td>When providing <mark style="color:red;"><code>max_time</code></mark> (unix epoch in seconds), only return candlesticks with timestamp &#x3C;= <mark style="color:red;"><code>max_time</code></mark></td></tr><tr><td align="center">limit</td><td align="center">number</td><td align="center">No</td><td>Max number of candlesticks to return. defaults to <mark style="color:red;"><code>100</code></mark>. max possible of <mark style="color:red;"><code>500</code></mark>.</td></tr></tbody></table>
## Response
```json
{
"candlesticks": [
{
"product_id": 1,
"granularity": 60,
"submission_idx": "627709",
"timestamp": "1680118140",
"open_x18": "27235000000000000000000",
"high_x18": "27298000000000000000000",
"low_x18": "27235000000000000000000",
"close_x18": "27298000000000000000000",
"volume": "1999999999999999998"
},
{
"product_id": 1,
"granularity": 60,
"submission_idx": "627699",
"timestamp": "1680118080",
"open_x18": "27218000000000000000000",
"high_x18": "27245000000000000000000",
"low_x18": "27218000000000000000000",
"close_x18": "27245000000000000000000",
"volume": "11852999999999999995"
}
]
}
```
## Response Fields
| Field name | Description |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| submission\_idx | Id of the latest recorded transaction that contributes to the candle. |
| product\_id | Id of product candle is associated to. |
| granularity | Candle time interval, expressed in seconds, representing the aggregation period for trading volume and price data |
| open\_x18 | The first fill price of the candle, multiplied by 10^18 |
| high\_x18 | The highest recorded fill price during the defined interval of the candle, multiplied by 10^18 |
| low\_x18 | The lowest recorded fill price during the defined interval of the candle, multiplied by 10^18 |
| close\_x18 | The last price of the candle, multiplied by 10^18 |
| volume | Asset volume, which represents the absolute cumulative fill amounts during the time interval of the candle, multiplied by 10^18 |
@@ -0,0 +1,193 @@
# Edge Market Snapshots
## Rate limits
**Dynamic based on interval.count.**
* IP weight = <mark style="color:red;">`(interval.count.min(500) / 20) + (interval.count.clamp(2, 20) * 2)`</mark>
* Scales mainly with interval count.
* Example: <mark style="color:red;">`interval.count=500 → weight=65`</mark>, <mark style="color:red;">`interval.count=100 → weight=45`</mark>.
* Minimum weight per request is <mark style="color:red;">`4`</mark>.
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
### Request
{% tabs %}
{% tab title="Market snapshots" %}
Query market snapshots ordered by <mark style="color:red;">`timestamp`</mark> desc.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"edge_market_snapshots": {
"interval": {
"count": 2,
"granularity": 3600,
"max_time": 1691083697,
},
"product_ids": [1, 2]
}
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="192" align="center">Parameter</th><th width="103" align="center">Type</th><th width="101" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">interval</td><td align="center">object</td><td align="center">Yes</td><td>Object to specify desired time period for data</td></tr><tr><td align="center">interval.count</td><td align="center">number</td><td align="center">Yes</td><td>Number of snapshots to return, limit 100. Also limited to <code>interval.count * # product_ids &#x3C; 2000</code></td></tr><tr><td align="center">interval.granularity</td><td align="center">number</td><td align="center">Yes</td><td>Granularity value in seconds</td></tr><tr><td align="center">interval.max_time</td><td align="center">number / string</td><td align="center">No</td><td>When providing <mark style="color:red;"><code>max_time</code></mark> (unix epoch in seconds), only return snapshots with timestamp &#x3C;= <mark style="color:red;"><code>max_time</code></mark>. If no value is entered, <code>max_time</code> defaults to the current time.</td></tr><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">No</td><td>list of product ids to fetch snapshots for, defaults to all products</td></tr></tbody></table>
### Response
{% hint style="info" %}
**Note**:
* Returns a mapping of <mark style="color:orange;">`chain_id -> snapshots`</mark>
{% endhint %}
```json
{
"snapshots": {
"42161": [
{
"timestamp": 1689965194,
"cumulative_users": 2774,
"daily_active_users": 251,
"cumulative_trades": {
"1": 54287,
"2": 172435
},
"cumulative_volumes": {
"1": "259549132367035103631071564",
"2": "1134008547778337985156988339"
},
"cumulative_trade_sizes": {
"1": "9209508999999999995173",
"2": "40246259000000000000000"
},
"cumulative_taker_fees": {
"1": "88916428908427788322799",
"2": "259205794197801680292645"
},
"cumulative_sequencer_fees": {
"1": "11038200000000000000000",
"2": "32353000000000000000000"
},
"cumulative_maker_fees": {
"1": "-12421730086012739050725",
"2": "-36124007075181485948604"
},
"cumulative_liquidation_amounts": {
"1": "848311398835000694508",
"2": "1013231566414935056343898"
},
"open_interests": {
"2": "2907581091676822842104781"
},
"total_deposits": {
"1": "37722308770940799414"
},
"total_borrows": {
"1": "1441397740941092000"
},
"funding_rates": {
"2": "3611102723387"
},
"deposit_rates": {
"1": "1001376785714"
},
"borrow_rates": {
"1": "32059880416879"
},
"cumulative_inflows": {
"1": "238791614019999999853",
"2": "0"
},
"cumulative_outflows": {
"1": "-202514202990000000306",
"2": "0"
},
"tvl": "7560079507311601381352742"
}
],
"5000": [
{
"timestamp": 1689965194,
"cumulative_users": 2774,
"daily_active_users": 251,
"cumulative_trades": {
"1": 54287,
"2": 172435
},
"cumulative_volumes": {
"1": "259549132367035103631071564",
"2": "1134008547778337985156988339"
},
"cumulative_trade_sizes": {
"1": "9209508999999999995173",
"2": "40246259000000000000000"
},
"cumulative_taker_fees": {
"1": "88916428908427788322799",
"2": "259205794197801680292645"
},
"cumulative_sequencer_fees": {
"1": "11038200000000000000000",
"2": "32353000000000000000000"
},
"cumulative_maker_fees": {
"1": "-12421730086012739050725",
"2": "-36124007075181485948604"
},
"cumulative_liquidation_amounts": {
"1": "848311398835000694508",
"2": "1013231566414935056343898"
},
"open_interests": {
"2": "2907581091676822842104781"
},
"total_deposits": {
"1": "37722308770940799414"
},
"total_borrows": {
"1": "1441397740941092000"
},
"funding_rates": {
"2": "3611102723387"
},
"deposit_rates": {
"1": "1001376785714"
},
"borrow_rates": {
"1": "32059880416879"
},
"cumulative_inflows": {
"1": "238791614019999999853",
"2": "0"
},
"cumulative_outflows": {
"1": "-202514202990000000306",
"2": "0"
},
"tvl": "7560079507311601381352742"
}
]
}
}
```
### Response Fields
#### Snapshots
{% hint style="info" %}
**Note**: For product specific fields (i.e. cumulative\_volume, open\_interests), the value is an object which maps product\_ids to their corresponding values.
{% endhint %}
<table><thead><tr><th width="260">Field name</th><th>Description</th></tr></thead><tbody><tr><td>timestamp</td><td>Timestamp of the snapshot. This may not be perfectly rounded to the granularity since it uses the nearest transaction timestamp less than or equal to <mark style="color:red;"><code>max_time</code></mark></td></tr><tr><td>cumulative_users</td><td>The cumulative number of subaccounts on Nado. It is updated daily at 9AM ET for historical counts. For current day counts, it is updated every hour.</td></tr><tr><td>daily_active_users</td><td>Daily active users count, updated daily at 9AM ET for historical counts. For current day counts, it is updated every hour.</td></tr><tr><td>cumulative_trades</td><td>A map of product_id -> the cumulative number of trades for the given product_id.</td></tr><tr><td>cumulative_volumes</td><td>A map of product_id -> cumulative volumes in USDT0 units.</td></tr><tr><td>cumulative_trade_sizes</td><td>A map of product_id -> cumulative trade sizes in base token</td></tr><tr><td>cumulative_taker_fees</td><td>A map of product_id -> cumulative taker fees. Taker fees include sequencer fees.</td></tr><tr><td>cumulative_sequencer_fees</td><td>A map of product_id -> cumulative sequencer fees.</td></tr><tr><td>cumulative_maker_fees</td><td>A map of product_id -> cumulative maker rebates.</td></tr><tr><td>cumulative_liquidation_amounts</td><td>A map of product_id -> cumulative liquidation amounts in USDT0 units.</td></tr><tr><td>open_interests</td><td>A map of product_id -> open interests in USDT0 units.</td></tr><tr><td>total_deposits</td><td>A map of product_id -> total deposits held by Nado for a given product at the given time in the base token units.</td></tr><tr><td>total_borrows</td><td>A map of product_id -> total borrows lent by Nado for a given product at the given time in the base token units.</td></tr><tr><td>funding_rates</td><td>A map of product_id -> <strong>hourly</strong> historical funding rates, value returned as <strong>decimal rates</strong> (% = rate * 100), derived from funding payment amounts. Requires a minimum granularity of 3600 to see non-zero funding rates. Use a granularity where granularity % 3600 = 0 for best results.</td></tr><tr><td>deposit_rates</td><td>A map of product_id -> <strong>daily</strong> deposit rates, values returned as <strong>decimal rates</strong> (% = rate * 100).</td></tr><tr><td>borrow_rates</td><td>A map of product_id -> <strong>daily</strong> borrow rates, values returned as <strong>decimal rates</strong> (% = rate * 100).</td></tr><tr><td>cumulative_inflows</td><td>A map of product_id -> cumulative inflows a.k.a deposits in base token units.</td></tr><tr><td>cumulative_outflows</td><td>A map of product_id -> cumulative outflows a.k.a withdraws in base token units.</td></tr><tr><td>tvl</td><td>The total value locked in USD.</td></tr></tbody></table>
@@ -0,0 +1,268 @@
# Events
## Rate limits
* IP weight = <mark style="color:red;">`2 + (limit * subaccounts.length / 10)`</mark> where <mark style="color:red;">`limit`</mark> defaults to 100 (max 500) and <mark style="color:red;">`subaccounts.length`</mark> defaults to 1
* E.g: With <mark style="color:red;">`limit=100`</mark> and 1 subaccount, weight = 12, allowing up to 200 requests per min or 33 requests / 10 secs.
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Available Events
Each event corresponds to a transaction type in Nado. See below available events and their <mark style="color:red;">`event_type`</mark> mapping:
| Event Name | Event Type Value |
| :---------------------------------------------------: | :-------------------: |
| <mark style="color:red;">`LiquidateSubaccount`</mark> | liquidate\_subaccount |
| <mark style="color:red;">`DepositCollateral`</mark> | deposit\_collateral |
| <mark style="color:red;">`WithdrawCollateral`</mark> | withdraw\_collateral |
| <mark style="color:red;">`SettlePnl`</mark> | settle\_pnl |
| <mark style="color:red;">`MatchOrders`</mark> | match\_orders |
| <mark style="color:red;">`MintLp`</mark> | mint\_lp |
| <mark style="color:red;">`BurnLp`</mark> | burn\_lp |
## Event Limits
You can specify 2 types of <mark style="color:red;">`limit`</mark> on the query:
* <mark style="color:red;">`raw`</mark>: the max number of events to return.
* <mark style="color:red;">`txs`</mark>: the max number of transactions to return. **note**: one transaction can emit multiple events, by specifying this limit, you will get all the events associated to the transactions in the response.
## Request
{% tabs %}
{% tab title="Events by subaccount" %}
Query events corresponding to specific subaccounts, ordered by <mark style="color:red;">`submission index`</mark> desc. E.g: all <mark style="color:red;">`MatchOrder`</mark> events for subaccounts <mark style="color:red;">`xxx`</mark> specific to spot wBTC.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"events": {
"product_ids": [
1
],
"subaccounts": [
"0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000"
],
"event_types": ["match_orders"],
"max_time": 1679728762,
"limit": {
"raw": 1
},
"isolated": false
}
}
```
{% endtab %}
{% tab title="Events by product" %}
Query events corresponding to specific products, ordered by <mark style="color:red;">`submission index`</mark> desc. Uses <mark style="color:red;">`txs`</mark> limit, will only return a single <mark style="color:red;">`tx`</mark> and one or more events associated with the <mark style="color:red;">`tx`</mark>.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"events": {
"product_ids": [
1,
2
],
"max_time": "1679728762",
"limit": {
"txs": 1
}
}
}
```
{% endtab %}
{% tab title="Events by type" %}
Query events corresponding to specific types, ordered by <mark style="color:red;">`submission index`</mark> desc.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"events": {
"event_types": ["deposit_collateral", "withdraw_collateral"],
"max_time": "1679728762",
"limit": {
"raw": 1
}
}
}
```
{% endtab %}
{% tab title="All events" %}
Query all events ordered by <mark style="color:red;">`submission index`</mark> desc.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"events": {
"max_time": "1679728762",
"limit": {
"raw": 1
}
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="162" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">subaccounts</td><td align="center">string[]</td><td align="center">No</td><td>Array of <mark style="color:red;"><code>bytes32</code></mark> sent as hex strings; each includes the address and the subaccount identifier. When provided, only return events for the specified subaccounts.</td></tr><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">No</td><td>when provided, only return events for the specified product ids; return events for all products otherwise.</td></tr><tr><td align="center">event_types</td><td align="center">string[]</td><td align="center">No</td><td>when provided, only return events for the specified event types; return all events otherwise.</td></tr><tr><td align="center">idx</td><td align="center">number / string</td><td align="center">No</td><td>when provided, only return events with <mark style="color:red;"><code>submission_idx</code></mark> &#x3C;= <mark style="color:red;"><code>idx</code></mark></td></tr><tr><td align="center">max_time</td><td align="center">number / string</td><td align="center">No</td><td>when <mark style="color:red;"><code>idx</code></mark> is not provided, <mark style="color:red;"><code>max_time</code></mark> (unix epoch in seconds) can be used to only return events created &#x3C;= <mark style="color:red;"><code>max_time</code></mark></td></tr><tr><td align="center">limit</td><td align="center"><p>object<br>{"raw": number } or</p><p>{"txs": number }</p></td><td align="center">No</td><td><ul><li>specifying <mark style="color:red;"><code>raw</code></mark> limit: max number of events to return. defaults to <mark style="color:red;"><code>100</code></mark>. max possible of <mark style="color:red;"><code>500</code></mark>.</li><li>specifying <mark style="color:red;"><code>txs</code></mark> limit: max number of txs to return.</li></ul></td></tr><tr><td align="center">isolated</td><td align="center">bool</td><td align="center">No</td><td>When provided --<br>- <mark style="color:red;"><code>true</code></mark>: only returns evens associated to isolated positions.<br>- <mark style="color:red;"><code>false</code></mark>: only return events associated to the cross-subaccount.<br>defaults to <mark style="color:red;"><code>null</code></mark>. In which case it returns everything.<br><br>See <a href="https://github.com/nadohq/nado-docs/blob/main/docs/basics/isolated-margin.md">Isolated Margin</a> to learn more.</td></tr></tbody></table>
## Response
{% hint style="info" %}
**Note:**
* the response includes a <mark style="color:red;">`txs`</mark> field which contains the relevant transactions to the events. There are <mark style="color:red;">`>=1 events`</mark> per transaction.
* both <mark style="color:red;">`events`</mark> and <mark style="color:red;">`txs`</mark> are in descending order by <mark style="color:red;">`submission_idx`</mark>`.`
* use the <mark style="color:red;">`submission_idx`</mark> to associate an <mark style="color:red;">`event`</mark> to it's corresponding transaction.
{% endhint %}
```json
{
"events": [
{
"subaccount": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
"product_id": 1,
"submission_idx": "563011",
"event_type": "match_orders",
"isolated": false,
"isolated_product_id": null,
"pre_balance": {
"spot": {
"product_id": 1,
"balance": {
"amount": "26766781157882079846319"
}
}
},
"post_balance": {
"spot": {
"product_id": 1,
"balance": {
"amount": "26767505157882079846318",
"last_cumulative_multiplier_x18": "1001292804799204317"
}
}
},
"product": {
"product_id": 1,
"oracle_price_x18": "115575316424148798147115",
"risk": {
"long_weight_initial_x18": "900000000000000000",
"short_weight_initial_x18": "1100000000000000000",
"long_weight_maintenance_x18": "950000000000000000",
"short_weight_maintenance_x18": "1050000000000000000",
"price_x18": "115575316424148798147115"
},
"config": {
"token": "0xc57c1c64561a37ac9e8f9039cb6deab7539d99fc",
"interest_inflection_util_x18": "800000000000000000",
"interest_floor_x18": "10000000000000000",
"interest_small_cap_x18": "40000000000000000",
"interest_large_cap_x18": "1000000000000000000",
"withdraw_fee_x18": "40000000000000",
"min_deposit_rate_x18": "0"
},
"state": {
"cumulative_deposits_multiplier_x18": "1000000000000318713",
"cumulative_borrows_multiplier_x18": "1000347390679880473",
"total_deposits_normalized": "9000399823280682696107190850",
"total_borrows_normalized": "9580268570661550719"
},
"book_info": {
"size_increment": "1000000000000000",
"price_increment_x18": "1000000000000000000",
"min_size": "4000000000000000",
"collected_fees": "0"
}
},
"net_interest_unrealized": "49040544804593257",
"net_interest_cumulative": "51596254598679857",
"net_funding_unrealized": "0",
"net_funding_cumulative": "0",
"net_entry_unrealized": "748947727410369682388339518",
"net_entry_cumulative": "749148081870171307027129958",
"quote_volume_cumulative": "1234567890123456789"
}
],
"txs": [
{
"tx": {
"match_orders": {
"product_id": 1,
"amm": true,
"taker": {
"order": {
"sender": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
"price_x18": "27540000000000000000000",
"amount": "2000000000000000000",
"appendix": "1537",
"expiration": 4611686020107120000,
"nonce": 1761322602510418000
},
"signature": "0x826c68f1a3f76d9ffbe8041f8d45e969d31f1ab6f2ae2f6379d1493e479e56436091d6cf4c72e212dd2f1d2fa17c627c4c21bd6d281c77172b8af030488478b71c"
},
"maker": {
"order": {
"sender": "0xf8d240d9514c9a4715d66268d7af3b53d619642564656661756c740000000000",
"price_x18": "27540000000000000000000",
"amount": "-724000000000000000",
"appendix": "1537",
"expiration": 1679731656,
"nonce": 1761322565506171000
},
"signature": "0xd8b6505b8d9b8c3cbfe793080976388035682c02a27893fb26b48a5b2bfe943f4162dea3a42e24e0dff5e2f74fbf77e33d83619140a2a581117c55e6cc236bdb1c"
}
}
},
"submission_idx": "563011",
"timestamp": "1679728127"
}
]
}
```
## Response Fields
### Events
{% hint style="info" %}
* **Net cumulative**: the net difference in that quantity since the beginning of time. For example, if I want to compute total amount paid out in funding between two events, you can subtract the `net_funding_cumulative` of the larger event by the `net_funding_cumulative` of the smaller event.
* **Net unrealized**: similar to `net_cumulative`, but for `net_unrealized`, we have the caveat that when the magnitude of your position decreases, the magnitude of net\_unrealized `decreases` by the same amount.
{% endhint %}
<table><thead><tr><th width="307">Field name</th><th>Description</th></tr></thead><tbody><tr><td>submission_idx</td><td>Used to uniquely identify the blockchain transaction that generated the event; you can use it to grab the relevant transaction in the <code>txs</code> section.</td></tr><tr><td>product_id</td><td>The id of of the product the event is associated with.</td></tr><tr><td>event_type</td><td>Name of the transaction type this event corresponds to.</td></tr><tr><td>subaccount</td><td>The subaccount associated to the event.</td></tr><tr><td>pre_balance</td><td>The state of your balance before the event happened.</td></tr><tr><td>post_balance</td><td>The state of your balance after the event happened.</td></tr><tr><td>product</td><td>The state of the product throughout the event.</td></tr></tbody></table>
### Txs
| Field name | Description |
| --------------- | --------------------------------------------------------------------------------------- |
| submission\_idx | Unique identifier of the transaction. |
| product\_id | Product associated to the transaction. |
| tx | Raw data of the corresponding transaction e.g: `match_orders` with all associated data. |
| timestamp | The unix epoch in seconds of when the transaction took place. |
@@ -0,0 +1,53 @@
# Fast Withdrawal Signature
## Rate limits
* 240 requests/min or 40 requests/10secs per IP address. (**weight = 10**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Fast Withdrawal Signature" %}
Query the signature required for a fast withdrawal at a specific submission index.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"fast_withdrawal_signature": {
"idx": "12345"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="150" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">idx</td><td align="center">number / string</td><td align="center">Yes</td><td>Submission index to fetch the fast withdrawal signature for.</td></tr></tbody></table>
## Response
```json
{
"signature": "0x1234567890abcdef...",
"submission_idx": "12345",
"subaccount": "0x79cc76364b5fb263a25bd52930e3d9788fcfeea864656661756c740000000000",
"product_id": 0,
"amount": "1000000000000000000",
"nonce": "1"
}
```
## Response Fields
### Fast Withdrawal Signature
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>signature</td><td>Hex string of the signature for fast withdrawal</td></tr><tr><td>submission_idx</td><td>Transaction submission index</td></tr><tr><td>subaccount</td><td>Hex string of the subaccount</td></tr><tr><td>product_id</td><td>Product ID (0 for quote asset)</td></tr><tr><td>amount</td><td>Withdrawal amount (x18 format)</td></tr><tr><td>nonce</td><td>Nonce for the withdrawal transaction</td></tr></tbody></table>
@@ -0,0 +1,94 @@
# Funding Rate
## Rate limits
* 1200 requests/min or 20 requests/sec per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Single Product
### Request
{% tabs %}
{% tab title="Funding Rate" %}
Query perp product 24hr funding rate.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"funding_rate": {
"product_id": 2
}
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="113" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of perp product to fetch funding rate for.</td></tr></tbody></table>
### Response
```json
{
"product_id": 2,
"funding_rate_x18": "2447900598160952",
"update_time": "1680116326"
}
```
## Multiple Products
### Request
{% tabs %}
{% tab title="Perp Prices" %} <mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"funding_rates": {
"product_ids": [2]
}
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="113" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">Yes</td><td>Ids of perp products to fetch funding rate for.</td></tr></tbody></table>
### Response
{% hint style="info" %}
**Note**: the response is a map of <mark style="color:red;">`product_id -> funding_rate`</mark> for each requested product.
{% endhint %}
```json
{
"2": {
"product_id": 2,
"funding_rate_x18": "-697407056090986",
"update_time": "1692825387"
}
}
```
## Response Fields
| Field name | Description |
| ------------------ | ----------------------------------------------------------------------- |
| product\_id | Id of the perp product this funding rate corresponds to. |
| funding\_rate\_x18 | Latest 24hr funding rate for the specified product, multiplied by 10^18 |
| update\_time | Epoch time in seconds this funding rate was last updated at |
@@ -0,0 +1,51 @@
# Ink Airdrop
Query the Ink token airdrop allocation for a specific wallet address.
## Rate limits
* 1200 requests/min or 200 requests/10secs per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Ink Airdrop" %} <mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"ink_airdrop": {
"address": "0x1234567890123456789012345678901234567890"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="178" align="center">Parameter</th><th width="229" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">address</td><td align="center">string</td><td align="center">Yes</td><td>Wallet address (20-byte address) sent as a hex string.</td></tr></tbody></table>
## Response
{% hint style="info" %}
**Note**: The amount is returned as a string to preserve precision.
{% endhint %}
```json
{
"amount": "1000000000000000000"
}
```
## Response Fields
| Field name | Description |
| ---------- | ------------------------------------------------------ |
| amount | The Ink token airdrop amount allocated to the address. |
@@ -0,0 +1,89 @@
# Interest & funding payments
## Rate limits
* 480 requests/min or 80 requests/10secs per IP address. (**weight = 5**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Interest and funding" %}
Query subaccount historical interest and funding payments.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"interest_and_funding": {
"subaccount": "0xD028878bF5c96218E53DA859e587cb8398B17b3f64656661756c740000000000",
"product_ids": [1, 2],
"limit": 10,
"max_idx": 1315836
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="140" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">subaccount</td><td align="center">string</td><td align="center">Yes</td><td>A bytes32 sent as a hex string; includes the address and the subaccount identifier.</td></tr><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">Yes</td><td>Ids of products to historical interest/funding payments for.</td></tr><tr><td align="center">max_idx</td><td align="center">string/number</td><td align="center">No</td><td>When provided, only return records with <mark style="color:red;"><code>idx</code></mark> &#x3C;= <mark style="color:red;"><code>max_idx</code></mark>.</td></tr><tr><td align="center">limit</td><td align="center">number</td><td align="center">Yes</td><td>Max number of records to return. Max possible of <mark style="color:red;"><code>100</code></mark>.</td></tr></tbody></table>
## Response
```json
{
"interest_payments": [
{
"product_id": 4,
"idx": "5968022",
"timestamp": "1701698400",
"amount": "-12273223338657163",
"balance_amount": "1000000000000000000",
"rate_x18": "47928279191008320",
"oracle_price_x18": "2243215034242228224820"
},
...
],
"funding_payments": [
{
"product_id": 2,
"idx": "5968022",
"timestamp": "1701698400",
"amount": "-12273223338657163",
"balance_amount": "1000000000000000000",
"rate_x18": "47928279191008320",
"oracle_price_x18": "2243215034242228224820"
},
...
],
"next_idx": "1314805"
}
```
## Response Fields
| Field name | Description |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| interest\_payments.product\_id | Id of spot product the interest payment is associated to. |
| interest\_payments.idx | Id of transaction that triggered the interest payment. |
| interest\_payments.timestamp | Timestamp of the transaction that triggered the interest payment. |
| interest\_payments.amount | Amount of interest paid multiplied by 10\*\*18. |
| interest\_payments.balance\_amount | Previous spot balance at the moment of payment (exclusive of payment amount) |
| interest\_payments.rate\_x18 | Spot interest rate at the moment of payment, multiplied by 10\*\*18. |
| interest\_payments.oracle\_price\_x18 | Oracle price for the spot product at the moment of payment, multiplied by 10\*\*18. |
| funding\_payments.product\_id | Id of perp product the funding payment is associated to. |
| funding\_payments.idx | Id of transaction that triggered the funding payment. |
| funding\_payments.timestamp | Timestamp of the transaction that triggered the funding payment. |
| funding\_payments.amount | Amount of funding paid multiplied by 10\*\*18. |
| funding\_payments.balance\_amount | Previous perp balance at the moment of payment +amount of perps locked in LPs (exclusive of payment amount). |
| funding\_payments.rate\_x18 | Perp funding rate at the moment of payment, multiplied by 10\*\*18. |
| funding\_payments.oracle\_price\_x18 | Oracle price for the perp product at the moment of payment, multiplied by 10\*\*18. |
| next\_idx | Id of the next payment snapshot. Use this as <mark style="color:red;">`max_idx`</mark> on a subsequent call to get the next page. This will be <mark style="color:red;">`null`</mark> when there are no more records. |
@@ -0,0 +1,74 @@
# Isolated Subaccounts
## Rate limits
* 1200 requests/min or 200 requests/10secs per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="List all isolated subaccounts" %}
Query all isolated subaccounts.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"isolated_subaccounts": {
"start_idx": 0,
"limit": 100
}
}
```
{% endtab %}
{% tab title="List isolated subaccounts for a subaccount" %}
Query isolated subaccounts associated with a specific subaccount.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"isolated_subaccounts": {
"subaccount": "0x79cc76364b5fb263a25bd52930e3d9788fcfeea864656661756c740000000000",
"limit": 100
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="150" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">subaccount</td><td align="center">string</td><td align="center">No</td><td>Hex string of the parent subaccount to filter by.</td></tr><tr><td align="center">start_idx</td><td align="center">number / string</td><td align="center">No</td><td>Starting index for pagination. Defaults to 0.</td></tr><tr><td align="center">limit</td><td align="center">number</td><td align="center">No</td><td>Max number of isolated subaccounts to return. Defaults to <mark style="color:red;"><code>100</code></mark>. Max of <mark style="color:red;"><code>500</code></mark>.</td></tr></tbody></table>
## Response
```json
{
"isolated_subaccounts": [
{
"subaccount": "0x79cc76364b5fb263a25bd52930e3d9788fcfeea864656661756c740000000000",
"isolated_subaccount": "0x79cc76364b5fb263a25bd52930e3d9788fcfeea800000000000000010069736f",
"product_id": 1,
"created_at": "1683315718"
}
]
}
```
## Response Fields
### Isolated Subaccounts
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>subaccount</td><td>Hex string of the parent subaccount</td></tr><tr><td>isolated_subaccount</td><td>Hex string of the isolated margin subaccount</td></tr><tr><td>product_id</td><td>Product ID for which this isolated subaccount was created</td></tr><tr><td>created_at</td><td>Unix epoch time in seconds when the isolated subaccount was created</td></tr></tbody></table>
@@ -0,0 +1,52 @@
# Linked Signer Rate Limit
A subaccount can perform a max of 50 [LinkSigner](https://docs.nado.xyz/developer-resources/api/gateway/executes/link-signer) requests in 7 days. Use this query to check current usage and wait time.
## Rate limits
* 1200 requests/min or 200 requests/10secs per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Link Signer Rate Limit" %}
Queries a subaccount's linked signer rate limits.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"linked_signer_rate_limit": {
"subaccount": "0x9b9989a4E0b260B84a5f367d636298a8bfFb7a9b42544353504f540000000000"
}
}
```
{% endtab %}
{% endtabs %}
## Response
```json
{
"remaining_tx": "50",
"wait_time": 0,
"signer": "0x0000000000000000000000000000000000000000",
"total_tx_limit": "50"
}
```
{% hint style="info" %}
**Notes**:
* <mark style="color:red;">`remaining_tx`</mark>: keeps track of the remaining <mark style="color:red;">`LinkSigner`</mark> executes that can be performed.
* <mark style="color:red;">`total_tx_limit`</mark>: that max weekly tx limit.
* <mark style="color:red;">`wait_time`</mark>: the total seconds you need to wait before performing another <mark style="color:red;">`LinkSigner`</mark> execute. Can only perform another request when <mark style="color:red;">`wait_time`</mark> is `0`.
* <mark style="color:red;">`signer`</mark>: the current linked signer address (20 bytes) associated to the provided `subaccount`. It returns the zero address when no signer is linked.
{% endhint %}
@@ -0,0 +1,55 @@
# Linked Signers
## Rate limits
* 1200 requests/min or 200 requests/10secs per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="List linked signers" %}
Query linked signers ordered by creation time.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"linked_signers": {
"start_idx": 0,
"limit": 100
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="150" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">start_idx</td><td align="center">number / string</td><td align="center">No</td><td>Starting index for pagination. Defaults to 0.</td></tr><tr><td align="center">limit</td><td align="center">number</td><td align="center">No</td><td>Max number of linked signers to return. Defaults to <mark style="color:red;"><code>100</code></mark>. Max of <mark style="color:red;"><code>500</code></mark>.</td></tr></tbody></table>
## Response
```json
{
"linked_signers": [
{
"subaccount": "0x79cc76364b5fb263a25bd52930e3d9788fcfeea864656661756c740000000000",
"signer": "0x1234567890123456789012345678901234567890",
"created_at": "1683315718"
}
]
}
```
## Response Fields
### Linked Signers
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>subaccount</td><td>Hex string of the subaccount</td></tr><tr><td>signer</td><td>Hex string of the linked signer address</td></tr><tr><td>created_at</td><td>Unix epoch time in seconds when the signer was linked</td></tr></tbody></table>
@@ -0,0 +1,58 @@
# Liquidation Feed
## Rate limits
* 1200 requests/min or 200 requests/10secs per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Liquidation feed" %}
Queries liquidatable accounts.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"liquidation_feed": {}
}
```
{% endtab %}
{% endtabs %}
## Response
```json
[
{
"subaccount": "0xf2b7cec33cac30582b94979bf03a3cbc73954b2c64656661756c740000000000",
"update_time": 1680118943
},
{
"subaccount": "0xcb6f1e2ece124a150dcc681c180df2a890432d6a64656661756c740000000000",
"update_time": 1680118943
},
{
"subaccount": "0x9e6e13be7ea2866c2c7c6e4a118a6c05eee6b44e64656661756c740000000000",
"update_time": 1680118943
},
{
"subaccount": "0x75008754ffae2889c055961c1b0c5c3ab743c59664656661756c740000000000",
"update_time": 1680118943
}
]
```
## Response Fields
| Field name | Description |
| ------------ | ------------------------------------ |
| subaccount | Subaccount eligible for liquidation. |
| update\_time | Last time feed was updated. |
@@ -0,0 +1,124 @@
# Market Snapshots
## Rate limits
* IP weight = <mark style="color:red;">`max((snapshot_count * product_ids.length / 100), 2)`</mark> where <mark style="color:red;">`snapshot_count = interval.count.min(500)`</mark>. If no <mark style="color:red;">`product_ids`</mark> are specified, <mark style="color:red;">`product_ids.length = 100`</mark>.
* E.g: With <mark style="color:red;">`product_ids=[1, 2, 3, 4]`</mark> and <mark style="color:red;">`interval.count=60`</mark>, weight = max((60 \* 4 / 100), 2) = 2, allowing up to 1200 requests per min or 200 requests/10 secs.
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
### Request
{% tabs %}
{% tab title="Market snapshots" %}
Query market snapshots ordered by <mark style="color:red;">`timestamp`</mark> desc.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"market_snapshots": {
"interval": {
"count": 2,
"granularity": 3600,
"max_time": 1691083697,
},
"product_ids": [1, 2]
}
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="192" align="center">Parameter</th><th width="103" align="center">Type</th><th width="101" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">interval</td><td align="center">object</td><td align="center">Yes</td><td>Object to specify desired time period for data</td></tr><tr><td align="center">interval.count</td><td align="center">number</td><td align="center">Yes</td><td>Number of snapshots to return, limit 100. Also limited to <code>interval.count * # product_ids &#x3C; 2000</code></td></tr><tr><td align="center">interval.granularity</td><td align="center">number</td><td align="center">Yes</td><td>Granularity value in seconds</td></tr><tr><td align="center">interval.max_time</td><td align="center">number / string</td><td align="center">No</td><td>When providing <mark style="color:red;"><code>max_time</code></mark> (unix epoch in seconds), only return snapshots with timestamp &#x3C;= <mark style="color:red;"><code>max_time</code></mark>. If no value is entered, <code>max_time</code> defaults to the current time.</td></tr><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">No</td><td>list of product ids to fetch snapshots for, defaults to all products</td></tr></tbody></table>
### Response
{% hint style="info" %}
**Note**: Please note that this endpoint is currently in beta stage. This feature might be subject to changes without prior notice.
{% endhint %}
```json
{
"snapshots": [
{
"timestamp": 1689965194,
"cumulative_users": 2774,
"daily_active_users": 251,
"cumulative_trades": {
"1": 54287,
"2": 172435
},
"cumulative_volumes": {
"1": "259549132367035103631071564",
"2": "1134008547778337985156988339"
},
"cumulative_trade_sizes": {
"1": "9209508999999999995173",
"2": "40246259000000000000000"
},
"cumulative_taker_fees": {
"1": "88916428908427788322799",
"2": "259205794197801680292645"
},
"cumulative_sequencer_fees": {
"1": "11038200000000000000000",
"2": "32353000000000000000000"
},
"cumulative_maker_fees": {
"1": "-12421730086012739050725",
"2": "-36124007075181485948604"
},
"cumulative_liquidation_amounts": {
"1": "848311398835000694508",
"2": "1013231566414935056343898"
},
"open_interests": {
"2": "2907581091676822842104781"
},
"total_deposits": {
"1": "37722308770940799414"
},
"total_borrows": {
"1": "1441397740941092000"
},
"funding_rates": {
"2": "3611102723387"
},
"deposit_rates": {
"1": "1001376785714"
},
"borrow_rates": {
"1": "32059880416879"
},
"cumulative_inflows": {
"1": "238791614019999999853",
"2": "0"
},
"cumulative_outflows": {
"1": "-202514202990000000306",
"2": "0"
},
"tvl": "7560079507311601381352742"
},
...
]
}
```
### Response Fields
#### Snapshots
{% hint style="info" %}
**Note**: For product specific fields (i.e. cumulative\_volume, open\_interests), the value is an object which maps product\_ids to their corresponding values.
{% endhint %}
<table><thead><tr><th width="260">Field name</th><th>Description</th></tr></thead><tbody><tr><td>timestamp</td><td>Timestamp of the snapshot. This may not be perfectly rounded to the granularity since it uses the nearest transaction timestamp less than or equal to <mark style="color:red;"><code>max_time</code></mark></td></tr><tr><td>cumulative_users</td><td>The cumulative number of subaccounts on Nado. It is updated daily at 9AM ET for historical counts. For current day counts, it is updated every hour.</td></tr><tr><td>daily_active_users</td><td>Daily active users count, updated daily at 9AM ET for historical counts. For current day counts, it is updated every hour.</td></tr><tr><td>cumulative_trades</td><td>A map of product_id -> the cumulative number of trades for the given product_id.</td></tr><tr><td>cumulative_volumes</td><td>A map of product_id -> cumulative volumes in USDT0 units.</td></tr><tr><td>cumulative_trade_sizes</td><td>A map of product_id -> cumulative trade sizes in base token</td></tr><tr><td>cumulative_taker_fees</td><td>A map of product_id -> cumulative taker fees. Taker fees include sequencer fees.</td></tr><tr><td>cumulative_sequencer_fees</td><td>A map of product_id -> cumulative sequencer fees.</td></tr><tr><td>cumulative_maker_fees</td><td>A map of product_id -> cumulative maker rebates.</td></tr><tr><td>cumulative_liquidation_amounts</td><td>A map of product_id -> cumulative liquidation amounts in USDT0 units.</td></tr><tr><td>open_interests</td><td>A map of product_id -> open interests in USDT0 units.</td></tr><tr><td>total_deposits</td><td>A map of product_id -> total deposits held by Nado for a given product at the given time in the base token units.</td></tr><tr><td>total_borrows</td><td>A map of product_id -> total borrows lent by Nado for a given product at the given time in the base token units.</td></tr><tr><td>funding_rates</td><td>A map of product_id -> <strong>hourly</strong> historical funding rates, value returned as <strong>decimal rates</strong> (% = rate * 100), derived from funding payment amounts. Requires a minimum granularity of 3600 to see non-zero funding rates. Use a granularity where granularity % 3600 = 0 for best results.</td></tr><tr><td>deposit_rates</td><td>A map of product_id -> <strong>daily</strong> deposit rates, values returned as <strong>decimal rates</strong> (% = rate * 100).</td></tr><tr><td>borrow_rates</td><td>A map of product_id -> <strong>daily</strong> borrow rates, values returned as <strong>decimal rates</strong> (% = rate * 100).</td></tr><tr><td>cumulative_inflows</td><td>A map of product_id -> cumulative inflows a.k.a deposits in base token units.</td></tr><tr><td>cumulative_outflows</td><td>A map of product_id -> cumulative outflows a.k.a withdraws in base token units.</td></tr><tr><td>tvl</td><td>The total value locked in USD.</td></tr></tbody></table>
@@ -0,0 +1,279 @@
# Matches
## Rate limits
* IP weight = <mark style="color:red;">`2 + (limit * subaccounts.length / 10)`</mark> where <mark style="color:red;">`limit`</mark> defaults to 100 (max 500) and <mark style="color:red;">`subaccounts.length`</mark> defaults to 1
* E.g: With <mark style="color:red;">`limit=100`</mark> and 1 subaccount, weight = 12, allowing up to 200 requests per min or 33 requests / 10 secs.
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Matches by subaccount" %}
Query subaccounts matches ordered by <mark style="color:red;">`submission index`</mark> desc. Response includes order fill and fee information.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"matches": {
"product_ids": [
1,
2
],
"subaccounts": [
"0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000"
],
"max_time": 1679728762,
"limit": 5,
"isolated": false
}
}
```
{% endtab %}
{% tab title="Matches by product" %}
Query matches for provided products ordered by <mark style="color:red;">`submission index`</mark> desc. Response includes order fill and fee information.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"matches": {
"product_ids": [
1,
2
],
"max_time": "1679728762",
"limit": 5
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="113" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">subaccounts</td><td align="center">string[]</td><td align="center">No</td><td>Array of <mark style="color:red;"><code>bytes32</code></mark> sent as hex strings; each includes the address and the subaccount identifier. When provided, only return matches for the specified subaccounts.</td></tr><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">No</td><td>When provided, only return matches for the specified product ids; return matches for all products otherwise.</td></tr><tr><td align="center">idx</td><td align="center">number / string</td><td align="center">No</td><td>When provided, only return matches with <mark style="color:red;"><code>submission_idx</code></mark> &#x3C;= <mark style="color:red;"><code>idx</code></mark></td></tr><tr><td align="center">max_time</td><td align="center">number / string</td><td align="center">No</td><td>When <mark style="color:red;"><code>idx</code></mark> is not provided, <mark style="color:red;"><code>max_time</code></mark> (unix epoch in seconds) can be used to only return matches created &#x3C;= <mark style="color:red;"><code>max_time</code></mark></td></tr><tr><td align="center">limit</td><td align="center">number</td><td align="center">No</td><td>Max number of matches to return. defaults to <mark style="color:red;"><code>100</code></mark>. max possible of <mark style="color:red;"><code>500</code></mark>.</td></tr><tr><td align="center">isolated</td><td align="center">boolean</td><td align="center">No</td><td>When provided --<br>- <mark style="color:red;"><code>true</code></mark>: only returns matches associated to isolated positions.<br>- <mark style="color:red;"><code>false</code></mark>: only return matches associated to the cross-subaccount.<br>defaults to <mark style="color:red;"><code>null</code></mark>. In which case it returns everything.<br><br>See <a href="https://github.com/nadohq/nado-docs/blob/main/docs/basics/isolated-margin.md">Isolated Margin</a> to learn more.</td></tr></tbody></table>
## Response
{% hint style="info" %}
**Note:**
* the response includes a <mark style="color:red;">`txs`</mark> field which contains the relevant transactions for the returned matches. There are <mark style="color:red;">`>=1 match events`</mark> per transaction.
* both <mark style="color:red;">`matches`</mark> and <mark style="color:red;">`txs`</mark> are in descending order by <mark style="color:red;">`submission_idx`</mark>`.`
* use the <mark style="color:red;">`submission_idx`</mark> to associate a match to it's corresponding transaction.
* the <mark style="color:red;">`fee`</mark> provided in the response includes taker / maker fees + sequencer fees. See [fees](https://github.com/nadohq/nado-docs/blob/main/docs/basics/fees.md) for more details.
{% endhint %}
```json
{
"matches": [
{
"digest": "0x80ce789702b670b7d33f2aa67e12c85f124395c3f9acdb422dde3b4973ccd50c",
"order": {
"sender": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
"priceX18": "27544000000000000000000",
"amount": "2000000000000000000",
"expiration": "4611686020107119633",
"nonce": "1761322608857448448"
},
"base_filled": "736000000000000000",
"quote_filled": "-20276464287857571514302",
"fee": "4055287857571514302",
"sequencer_fee": "0",
"cumulative_fee": "4055287857571514302",
"cumulative_base_filled": "736000000000000000",
"cumulative_quote_filled": "-20276464287857571514302",
"submission_idx": "563012",
"isolated": false,
"is_taker": true,
"pre_balance": {
"base": {
"perp": {
"product_id": 2,
"balance": {
"amount": "2686684000000000000000",
"v_quote_balance": "-76348662407149297671587247",
"last_cumulative_funding_x18": "134999841911604906604576"
}
}
},
"quote": null
},
"post_balance": {
"base": {
"perp": {
"product_id": 2,
"balance": {
"amount": "2686013000000000000000",
"v_quote_balance": "-76328351274188497671587247",
"last_cumulative_funding_x18": "134999841911604906604576"
}
}
},
"quote": null
}
},
{
"digest": "0x0f6e5a0434e36d8e6d4fed950d3624b0d8c91a8a84efd156bb25c1382561c0c2",
"order": {
"sender": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
"priceX18": "27540000000000000000000",
"amount": "2000000000000000000",
"appendix": "1537",
"expiration": "4611686020107119623",
"nonce": "1761322602510417920"
},
"base_filled": "723999999999999999",
"quote_filled": "-19944943483044913474043",
"fee": "5983483044913474042",
"sequencer_fee": "0",
"cumulative_fee": "11958484645393618085",
"cumulative_base_filled": "1446999999999999998",
"cumulative_quote_filled": "-39861640484645393618087",
"submission_idx": "563011",
"isolated": false,
"is_taker": true,
"pre_balance": {
"base": {
"perp": {
"product_id": 2,
"balance": {
"amount": "2686684000000000000000",
"v_quote_balance": "-76348662407149297671587247",
"last_cumulative_funding_x18": "134999841911604906604576"
}
}
},
"quote": null
},
"post_balance": {
"base": {
"perp": {
"product_id": 2,
"balance": {
"amount": "2686013000000000000000",
"v_quote_balance": "-76328351274188497671587247",
"last_cumulative_funding_x18": "134999841911604906604576"
}
}
},
"quote": null
}
}
],
"txs": [
{
"tx": {
"match_orders": {
"product_id": 2,
"amm": true,
"taker": {
"order": {
"sender": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
"price_x18": "27544000000000000000000",
"amount": "2000000000000000000",
"expiration": 4611686020107120000,
"appendix": "1537",
"nonce": 1761322608857448400
},
"signature": "0xe8fa7151bde348afa3b46dc52798046b7c8318f1b0a7f689710debbc094658cc1bf5a7e478ccc8278b625da0b9402c86b580d2e31e13831337dfd6153f4b37811b"
},
"maker": {
"order": {
"sender": "0xebdbbcdbd2646c5f23a1e0806027eee5f71b074664656661756c740000000000",
"price_x18": "27544000000000000000000",
"amount": "-736000000000000000",
"expiration": 1679731669,
"appendix": "1537",
"nonce": 1761322585591644200
},
"signature": "0x47f9d47f0777f3ca0b13f07b7682dbeea098c0e377b87dcb025754fe34c900e336b8c7744e021fb9c46a4f8c6a1478bafa28bf0d023ae496aa3efa4d8e81df181c"
}
}
},
"submission_idx": "563012",
"timestamp": "1679728133"
},
{
"tx": {
"match_orders": {
"product_id": 1,
"amm": true,
"taker": {
"order": {
"sender": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
"price_x18": "27540000000000000000000",
"amount": "2000000000000000000",
"appendix": "1537",
"expiration": 4611686020107120000,
"nonce": 1761322602510418000
},
"signature": "0x826c68f1a3f76d9ffbe8041f8d45e969d31f1ab6f2ae2f6379d1493e479e56436091d6cf4c72e212dd2f1d2fa17c627c4c21bd6d281c77172b8af030488478b71c"
},
"maker": {
"order": {
"sender": "0xf8d240d9514c9a4715d66268d7af3b53d619642564656661756c740000000000",
"price_x18": "27540000000000000000000",
"amount": "-724000000000000000",
"appendix": "1537",
"expiration": 1679731656,
"nonce": 1761322565506171000
},
"signature": "0xd8b6505b8d9b8c3cbfe793080976388035682c02a27893fb26b48a5b2bfe943f4162dea3a42e24e0dff5e2f74fbf77e33d83619140a2a581117c55e6cc236bdb1c"
}
}
},
"submission_idx": "563011",
"timestamp": "1679728127"
}
]
}
```
## Response Fields
### Matches
| Field name | Description |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| submission\_idx | Wsed to uniquely identify the blockchain transaction that generated the match; you can use it to grab the relevant transaction in the `txs` section. |
| isolated | Whether the match is associated with an isolated position. `true` for isolated positions, `false` for cross-subaccount positions. |
| is\_taker | Whether the order in this match was the taker. `true` if the order was the taker, `false` if the order was the maker. |
| digest | The unique hash of the order. |
| order.sender | The sender that placed the order. |
| order.priceX18 | The original order price. |
| order.amount | The original order amount. |
| order.expiration | The original order expiration. |
| order.nonce | The original order nonce. |
| order.appendix | The original order appendix. |
| pre\_balance | The state of your balance before the match happened. |
| post\_balance | The state of your balance after the match happened. |
| base\_filled | The amount of base (e.g: BTC) filled on this match. |
| quote\_filled | The amount of quote (e.g: USDT0) filled on this match. |
| fee | The amount of trading fees + sequencer fees paid on this match. |
| sequencer\_fee | The amount of sequencer fees paid on this match. |
| cumulative\_base\_filled | The total amount of base (e.g: BTC) filled on this order up this match. |
| cumulative\_quote\_filled | The total amount of quote (e.g: USDT0) filled up to this match. |
| cumulative\_fee | The total amount of fee paid up to this match. |
### Txs
| Field name | Description |
| --------------- | ------------------------------------------------------------- |
| submission\_idx | Unique identifier of the transaction. |
| product\_id | Product associated to the transaction. |
| taker | The taker order. |
| maker | The maker order. |
| timestamp | The unix epoch in seconds of when the transaction took place. |
@@ -0,0 +1,60 @@
# NLP Funding Payments
## Rate limits
* 480 requests/min or 80 requests/10secs per IP address. (**weight = 5**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="NLP Funding Payments" %}
Query historical NLP funding payments.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"nlp_funding_payments": {
"max_idx": "1315836",
"max_time": "1683315718",
"limit": 100
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="150" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">max_idx</td><td align="center">number / string</td><td align="center">No</td><td>When provided, only return payments with <mark style="color:red;"><code>idx</code></mark> &#x3C;= <mark style="color:red;"><code>max_idx</code></mark>.</td></tr><tr><td align="center">max_time</td><td align="center">number / string</td><td align="center">No</td><td>When provided, only return payments with <mark style="color:red;"><code>timestamp</code></mark> &#x3C;= <mark style="color:red;"><code>max_time</code></mark> (unix epoch in seconds).</td></tr><tr><td align="center">limit</td><td align="center">number</td><td align="center">No</td><td>Max number of payments to return. Defaults to <mark style="color:red;"><code>100</code></mark>. Max of <mark style="color:red;"><code>500</code></mark>.</td></tr></tbody></table>
## Response
```json
{
"funding_payments": [
{
"product_id": 2,
"idx": "5968022",
"timestamp": "1701698400",
"total_payment": "12273223338657163",
"rate_x18": "47928279191008320",
"oracle_price_x18": "2243215034242228224820"
}
],
"next_idx": "5968021"
}
```
## Response Fields
### Funding Payments
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>product_id</td><td>Id of the perp product</td></tr><tr><td>idx</td><td>Submission index of the transaction that triggered the payment</td></tr><tr><td>timestamp</td><td>Unix epoch time in seconds when the payment occurred</td></tr><tr><td>total_payment</td><td>Total funding payment amount (x18 format)</td></tr><tr><td>rate_x18</td><td>Funding rate used for calculation (x18 format)</td></tr><tr><td>oracle_price_x18</td><td>Oracle price at the time of payment (x18 format)</td></tr></tbody></table>
@@ -0,0 +1,59 @@
# NLP Interest Payments
## Rate limits
* 480 requests/min or 80 requests/10secs per IP address. (**weight = 5**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="NLP Interest Payments" %}
Query historical NLP interest payments.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"nlp_interest_payments": {
"max_idx": "1315836",
"max_time": "1683315718",
"limit": 100
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="150" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">max_idx</td><td align="center">number / string</td><td align="center">No</td><td>When provided, only return payments with <mark style="color:red;"><code>idx</code></mark> &#x3C;= <mark style="color:red;"><code>max_idx</code></mark>.</td></tr><tr><td align="center">max_time</td><td align="center">number / string</td><td align="center">No</td><td>When provided, only return payments with <mark style="color:red;"><code>timestamp</code></mark> &#x3C;= <mark style="color:red;"><code>max_time</code></mark> (unix epoch in seconds).</td></tr><tr><td align="center">limit</td><td align="center">number</td><td align="center">No</td><td>Max number of payments to return. Defaults to <mark style="color:red;"><code>100</code></mark>. Max of <mark style="color:red;"><code>500</code></mark>.</td></tr></tbody></table>
## Response
```json
{
"interest_payments": [
{
"product_id": 0,
"idx": "5968022",
"timestamp": "1701698400",
"amount": "12273223338657163",
"balance_amount": "45382847293847329847"
}
],
"next_idx": "5968021"
}
```
## Response Fields
### Interest Payments
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>product_id</td><td>Id of the spot product (typically quote/collateral products)</td></tr><tr><td>idx</td><td>Submission index of the transaction that triggered the payment</td></tr><tr><td>timestamp</td><td>Unix epoch time in seconds when the payment occurred</td></tr><tr><td>amount</td><td>Interest payment amount (x18 format)</td></tr><tr><td>balance_amount</td><td>Balance amount at the time of payment (x18 format)</td></tr></tbody></table>
@@ -0,0 +1,82 @@
# NLP Snapshots
## Rate limits
* Dynamic based on snapshot count (**weight = (limit.min(500) / 100)**)
* E.g: With <mark style="color:red;">`limit=100`</mark>, weight = 1
* E.g: With <mark style="color:red;">`limit=500`</mark>, weight = 5
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="By interval" %}
Query NLP snapshots at specific time intervals.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"nlp_snapshots": {
"interval": {
"count": 10,
"max_time": "1683315718",
"granularity": 3600
}
}
}
```
{% endtab %}
{% tab title="By pagination" %}
Query NLP snapshots with pagination.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"nlp_snapshots": {
"idx": "12345",
"max_time": "1683315718",
"limit": 100
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="150" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">interval</td><td align="center">object</td><td align="center">No</td><td>Object specifying time interval parameters: <mark style="color:red;"><code>count</code></mark>, <mark style="color:red;"><code>max_time</code></mark>, <mark style="color:red;"><code>granularity</code></mark></td></tr><tr><td align="center">idx</td><td align="center">number / string</td><td align="center">No</td><td>Submission index for pagination.</td></tr><tr><td align="center">max_time</td><td align="center">number / string</td><td align="center">No</td><td>Unix epoch time in seconds. Only return snapshots with timestamp &#x3C;= <mark style="color:red;"><code>max_time</code></mark></td></tr><tr><td align="center">limit</td><td align="center">number</td><td align="center">No</td><td>Max number of snapshots to return. Defaults to <mark style="color:red;"><code>100</code></mark>. Max of <mark style="color:red;"><code>500</code></mark>.</td></tr></tbody></table>
## Response
```json
{
"snapshots": [
{
"submission_idx": "12345",
"timestamp": "1683315718",
"total_deposits": "1000000000000000000000",
"total_borrows": "500000000000000000000",
"base_interest_rate": "50000000000000000",
"quote_interest_rate": "30000000000000000"
}
]
}
```
## Response Fields
### NLP Snapshots
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>submission_idx</td><td>Transaction submission index</td></tr><tr><td>timestamp</td><td>Unix epoch time in seconds when snapshot was taken</td></tr><tr><td>total_deposits</td><td>Total deposits in the NLP pool (x18 format)</td></tr><tr><td>total_borrows</td><td>Total borrows from the NLP pool (x18 format)</td></tr><tr><td>base_interest_rate</td><td>Interest rate for base assets (x18 format)</td></tr><tr><td>quote_interest_rate</td><td>Interest rate for quote assets (x18 format)</td></tr></tbody></table>
@@ -0,0 +1,70 @@
# Oracle Price
## Rate limits
* 1200 requests/min or 200 requests/10secs per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Oracle Price" %} <mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"oracle_price": {
"product_ids": [1, 2, 3, 4]
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="113" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">Yes</td><td>Ids of products to fetch oracles price for.</td></tr></tbody></table>
## Response
```json
{
"prices": [
{
"product_id": 1,
"oracle_price_x18": "29464023750000000000000",
"update_time": "1683315718"
},
{
"product_id": 2,
"oracle_price_x18": "29430225194712740000000",
"update_time": "1683315721"
},
{
"product_id": 3,
"oracle_price_x18": "1983367400000000000000",
"update_time": "1683315720"
},
{
"product_id": 4,
"oracle_price_x18": "1981528989642697000000",
"update_time": "1683315721"
}
]
}
```
## Response Fields
### Prices
| Field name | Description |
| ------------------ | ------------------------------------------------------ |
| product\_id | Id of product oracle price corresponds to. |
| oracle\_price\_x18 | Latest oracle price multiplied by 10^18. |
| update\_time | Epoch in seconds the oracle price was last updated at. |
@@ -0,0 +1,67 @@
# Oracle Snapshots
## Rate limits
* IP weight = <mark style="color:red;">`max((snapshot_count * product_ids.length / 100), 2)`</mark> where <mark style="color:red;">`snapshot_count = interval.count.min(500)`</mark>. If no <mark style="color:red;">`product_ids`</mark> are specified, <mark style="color:red;">`product_ids.length = 100`</mark>.
* E.g: With <mark style="color:red;">`product_ids=[1, 2, 3, 4]`</mark> and <mark style="color:red;">`interval.count=60`</mark>, weight = max((60 \* 4 / 100), 2) = 2, allowing up to 1200 requests per min or 200 requests/10 secs.
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Oracle Price" %}
Query oracle snapshots ordered by <mark style="color:red;">`timestamp`</mark> desc.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"oracle_snapshots": {
"interval": {
"count": 2,
"granularity": 3600,
"max_time": 1691083697,
},
"product_ids": [1, 2]
}
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="192" align="center">Parameter</th><th width="103" align="center">Type</th><th width="101" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">interval</td><td align="center">object</td><td align="center">Yes</td><td>Object to specify desired time period for data</td></tr><tr><td align="center">interval.count</td><td align="center">number</td><td align="center">Yes</td><td>Number of snapshots to return, limit 100. Also limited to <code>interval.count * # product_ids &#x3C; 2000</code></td></tr><tr><td align="center">interval.granularity</td><td align="center">number</td><td align="center">Yes</td><td>Granularity value in seconds</td></tr><tr><td align="center">interval.max_time</td><td align="center">number / string</td><td align="center">No</td><td>When providing <mark style="color:red;"><code>max_time</code></mark> (unix epoch in seconds), only return snapshots with timestamp &#x3C;= <mark style="color:red;"><code>max_time</code></mark>. If no value is entered, <code>max_time</code> defaults to the current time.</td></tr><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">No</td><td>list of product ids to fetch snapshots for, defaults to all products</td></tr></tbody></table>
## Response
{% hint style="info" %}
**Note**: Returns a map of <mark style="color:red;">`product_id -> oracle_price`</mark>
{% endhint %}
```json
{
"snapshots": [
{
"timestamp": 1750947789,
"oracle_prices": {
"1": "107070085854928675234384",
"2": "107142264360834928244199"
}
},
{
"timestamp": 1750946389,
"oracle_prices": {
"1": "106963557680819440289916",
"2": "106954360458642468300594"
}
}
]
}
```
@@ -0,0 +1,127 @@
# Orders
## Rate limits
* IP weight = <mark style="color:red;">`2 + (limit * subaccounts.length / 20)`</mark> where <mark style="color:red;">`limit`</mark> defaults to 100 (max 500) and <mark style="color:red;">`subaccounts.length`</mark> defaults to 1
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Subaccount orders" %}
Query subaccounts <mark style="color:red;">`matched`</mark> orders, ordered by <mark style="color:red;">`submission index`</mark> desc.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"orders": {
"product_ids": [
1,
2
],
"subaccounts": [
"0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000"
],
"max_time": 1679728762,
"trigger_types": [
"price_trigger",
"time_trigger"
],
"isolated": false,
"limit": 5
}
}
```
{% endtab %}
{% tab title="Orders by digests" %}
Query orders by digests.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
<pre class="language-json"><code class="lang-json"><strong>{
</strong> "orders": {
"digests": [
"0xf4f7a8767faf0c7f72251a1f9e5da590f708fd9842bf8fcdeacbaa0237958fff",
"0x0495a88fb3b1c9bed9b643b8e264a391d04cdd48890d81cd7c4006473f28e361"
]
}
}
</code></pre>
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="113" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">subaccounts</td><td align="center">string[]</td><td align="center">conditional</td><td>Array of <mark style="color:red;"><code>bytes32</code></mark> sent as hex strings; each includes the address and the subaccount identifier. Must be provided when querying by <mark style="color:red;"><code>subaccounts</code></mark><strong>.</strong></td></tr><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">No</td><td>When provided, only return orders for the specified product ids; return orders for all products otherwise.</td></tr><tr><td align="center">idx</td><td align="center">number / string</td><td align="center">No</td><td>When provided, only return orders with <mark style="color:red;"><code>submission_idx</code></mark> &#x3C;= <mark style="color:red;"><code>idx</code></mark></td></tr><tr><td align="center">max_time</td><td align="center">number / string</td><td align="center">No</td><td>When <mark style="color:red;"><code>idx</code></mark> is not provided, <mark style="color:red;"><code>max_time</code></mark> (unix epoch in seconds) can be used to only return orders created &#x3C;= <mark style="color:red;"><code>max_time</code></mark></td></tr><tr><td align="center">digests</td><td align="center">string[]</td><td align="center">conditional</td><td>Must be provided when querying by <mark style="color:red;"><code>digests</code></mark>. only return orders matching the specified digests. <strong>note</strong>: cannot specify digests alongside with <mark style="color:red;"><code>subaccounts</code></mark> , <mark style="color:red;"><code>product_ids</code></mark> or <mark style="color:red;"><code>max_time</code></mark></td></tr><tr><td align="center">trigger_types</td><td align="center">string[]</td><td align="center">No</td><td>When provided, only return orders matching the specified trigger types. Possible values: <mark style="color:red;"><code>price_trigger</code></mark>, <mark style="color:red;"><code>time_trigger</code></mark>, <mark style="color:red;"><code>none</code></mark>. If not provided, returns orders of all trigger types.</td></tr><tr><td align="center">limit</td><td align="center">number</td><td align="center">No</td><td>Max number of orders to return. defaults to <mark style="color:red;"><code>100</code></mark>. max possible of <mark style="color:red;"><code>500</code></mark>. <strong>note</strong>: when querying by <mark style="color:red;"><code>digests</code></mark> limit must be &#x3C;= total digests provided</td></tr><tr><td align="center">isolated</td><td align="center">bool</td><td align="center">No</td><td><p>When provided --</p><ul><li><mark style="color:red;"><code>true</code></mark>: only returns orders associated to isolated positions.</li><li><mark style="color:red;"><code>false</code></mark>: only return matches associated to the cross-subaccount.</li></ul><p>defaults to <mark style="color:red;"><code>null</code></mark>. In which case it returns everything.</p><p>See <a href="https://github.com/nadohq/nado-docs/blob/main/docs/basics/isolated-margin.md">Isolated Margin</a> to learn more.</p></td></tr></tbody></table>
## Response
```json
{
"orders": [
{
"digest": "0xf4f7a8767faf0c7f72251a1f9e5da590f708fd9842bf8fcdeacbaa0237958fff",
"subaccount": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
"product_id": 1,
"submission_idx": "563024",
"last_fill_submission_idx": "563024",
"amount": "20000000000000000000",
"price_x18": "1751900000000000000000",
"base_filled": "2320000000000000000",
"quote_filled": "-4064898974794958991797",
"fee": "812974794958991797",
"expiration": "4611686020107120163",
"appendix": "1537",
"nonce": "1761323164913106944",
"isolated": false
},
{
"digest": "0x0495a88fb3b1c9bed9b643b8e264a391d04cdd48890d81cd7c4006473f28e361",
"subaccount": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
"product_id": 2,
"submission_idx": "563019",
"last_fill_submission_idx": "563019",
"amount": "-20000000000000000000",
"price_x18": "1750800000000000000000",
"base_filled": "-1159999999999999999",
"quote_filled": "2030293721599999999999",
"fee": "609278400000000000",
"expiration": "4611686020107119905",
"appendix": "1537",
"nonce": "1761322893628669952",
"isolated": false
},
{
"digest": "0x29078702ad95615f0040eafdccc85cbf92569bf9656be928f9f17c5ccbb52041",
"subaccount": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
"product_id": 2,
"submission_idx": "563018",
"last_fill_submission_idx": "563018",
"amount": "-20000000000000000000",
"price_x18": "1750700000000000000000",
"base_filled": "-1160000000000000000",
"quote_filled": "2030380837600000000000",
"fee": "406162400000000000",
"expiration": "4611686020107119880",
"appendix": "1537",
"nonce": "1761322865074896896",
"isolated": false
},
]
}
```
## Response Fields
<table><thead><tr><th width="307">Field name</th><th>Description</th></tr></thead><tbody><tr><td>digest</td><td>The unique hash of the order.</td></tr><tr><td>subaccount</td><td>The subaccount that placed the order.</td></tr><tr><td>product_id</td><td>The id of of the product the order was executed for.</td></tr><tr><td>submission_idx</td><td>Used to uniquely identify the blockchain transaction that generated the order. For multi-fills orders, this is the submission_idx of the first fill.</td></tr><tr><td>last_fill_submission_idx</td><td>For multi-fills orders, this is the submission_idx of the last fill. For single fill orders, it has the same value as <code>submission_idx</code>.</td></tr><tr><td>amount</td><td>The original amount of base to buy or sell.</td></tr><tr><td>price_x18</td><td>The original order price.</td></tr><tr><td>base_filled</td><td>The total amount of base (e.g: BTC) filled on this order.</td></tr><tr><td>quote_filled</td><td>The total amount of quote (e.g: USDT0) filled on this order.</td></tr><tr><td>fee</td><td>The total amount of fee paid on this order.</td></tr><tr><td>expiration</td><td>The original order expiration.</td></tr><tr><td>nonce</td><td>The original order nonce.</td></tr><tr><td>appendix</td><td>The original order appendix.</td></tr></tbody></table>
@@ -0,0 +1,94 @@
# Perp Prices
## Rate limits
* 1200 requests/min or 200 requests/10secs per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Single Product
### Request
{% tabs %}
{% tab title="Perp Prices" %} <mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"price": {
"product_id": 2
}
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="113" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of perp product to fetch prices for.</td></tr></tbody></table>
### Response
```json
{
"product_id": 2,
"index_price_x18": "28180063400000000000000",
"mark_price_x18": "28492853627394637978665",
"update_time": "1680734493"
}
```
## Multiple Products
### Request
{% tabs %}
{% tab title="Perp Prices" %} <mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"perp_prices": {
"product_ids": [2]
}
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="113" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">Yes</td><td>Ids of perp products to fetch prices for.</td></tr></tbody></table>
### Response
{% hint style="info" %}
**Note**: the response is a map of <mark style="color:red;">`product_id -> perp_prices`</mark> for each requested product.
{% endhint %}
```json
{
"2": {
"product_id": 2,
"index_price_x18": "31483202055051853950444",
"mark_price_x18": "31514830401018841708801",
"update_time": "1689281222"
}
}
```
## Response Fields
| Field name | Description |
| ----------------- | ------------------------------------------------------------ |
| product\_id | Id of the perp product. |
| index\_price\_x18 | Latest index price of the perp product, multiplied by 10^18. |
| mark\_price\_x18 | Latest mark price of the perp product, multiplied by 10^18. |
| update\_time | Epoch time in seconds the perp prices were last updated at. |
@@ -0,0 +1,228 @@
# Product Snapshots
## Rate limits
* 240 requests/min or 40 requests/10secs per IP address. (**weight = 10**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Single Product
### Request
{% tabs %}
{% tab title="Product snapshots" %}
Query snapshots for a given product ordered by <mark style="color:red;">`submission index`</mark> desc.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"products": {
"product_id": 2,
"max_time": 1679728762,
"limit": 1
}
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="113" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_id</td><td align="center">number</td><td align="center">Yes</td><td>id of product to fetch snapshots for.</td></tr><tr><td align="center">idx</td><td align="center">number / string</td><td align="center">No</td><td>when provided, only return product snapshots with <mark style="color:red;"><code>submission_idx</code></mark> &#x3C;= <mark style="color:red;"><code>idx</code></mark></td></tr><tr><td align="center">max_time</td><td align="center">number / string</td><td align="center">No</td><td>when <mark style="color:red;"><code>idx</code></mark> is not provided, <mark style="color:red;"><code>max_time</code></mark> (unix epoch in seconds) can be used to only return snapshots created &#x3C;= <mark style="color:red;"><code>max_time</code></mark></td></tr><tr><td align="center">limit</td><td align="center">number</td><td align="center">No</td><td>max number of snapshots to return. defaults to <mark style="color:red;"><code>100</code></mark>. max possible of <mark style="color:red;"><code>500</code></mark>.</td></tr></tbody></table>
### Response
{% hint style="info" %}
**Note**:
* the response includes a <mark style="color:red;">`txs`</mark> field which contains the relevant transactions to the product snapshots. There are <mark style="color:red;">`>=1 product snapshots`</mark> per transaction.
* both <mark style="color:red;">`products`</mark> and <mark style="color:red;">`txs`</mark> are in descending order by <mark style="color:red;">`submission_idx`</mark>.
* use the <mark style="color:red;">`submission_idx`</mark> to associate a <mark style="color:red;">`product snapshot`</mark> to it's corresponding transaction.
{% endhint %}
```json
{
"products": [
{
"product_id": 1,
"submission_idx": "563014",
"product": {
"spot": {
"product_id": 1,
"oracle_price_x18": "115575316424148798147115",
"risk": {
"long_weight_initial_x18": "900000000000000000",
"short_weight_initial_x18": "1100000000000000000",
"long_weight_maintenance_x18": "950000000000000000",
"short_weight_maintenance_x18": "1050000000000000000",
"price_x18": "115575316424148798147115"
},
"config": {
"token": "0xc57c1c64561a37ac9e8f9039cb6deab7539d99fc",
"interest_inflection_util_x18": "800000000000000000",
"interest_floor_x18": "10000000000000000",
"interest_small_cap_x18": "40000000000000000",
"interest_large_cap_x18": "1000000000000000000",
"withdraw_fee_x18": "40000000000000",
"min_deposit_rate_x18": "0"
},
"state": {
"cumulative_deposits_multiplier_x18": "1000000000000318713",
"cumulative_borrows_multiplier_x18": "1000347390679880473",
"total_deposits_normalized": "9000399823280682696107190850",
"total_borrows_normalized": "9580268570661550719"
},
"book_info": {
"size_increment": "1000000000000000",
"price_increment_x18": "1000000000000000000",
"min_size": "4000000000000000",
"collected_fees": "0"
}
}
}
],
"txs": [
{
"tx": {
"update_price": {
"product_id": 3,
"price_x18": "1750710375000000000000"
}
},
"submission_idx": "563014",
"timestamp": "1679728271"
}
]
}
```
### Response Fields
#### Products
<table><thead><tr><th width="307">Field name</th><th>Description</th></tr></thead><tbody><tr><td>submission_idx</td><td>Used to uniquely identify the blockchain transaction that generated the product snapshot; you can use it to grab the relevant transaction in the <code>txs</code> section.</td></tr><tr><td>product_id</td><td>The id of of the product the event is associated with.</td></tr><tr><td>product</td><td>The state of the product at the time of the transaction.</td></tr></tbody></table>
#### Txs
| Field name | Description |
| --------------- | ------------------------------------------------------------- |
| submission\_idx | Unique identifier of the transaction. |
| tx | Raw data of the corresponding transaction |
| timestamp | The unix epoch in seconds of when the transaction took place. |
## Multiple Products
### Request
{% tabs %}
{% tab title="Multiple Products snapshots" %}
Query the latest snapshot for the provided products.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"product_snapshots": {
"product_ids": [1, 2],
"max_time": 1679728762
}
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="113" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">Yes</td><td>Ids of products to fetch snapshots for.</td></tr><tr><td align="center">max_time</td><td align="center">number / string</td><td align="center">No</td><td>When provided, returns the last snapshot created &#x3C;= <mark style="color:red;"><code>max_time</code></mark> for each product. Otherwise, the latest snapshot is returned.</td></tr></tbody></table>
### Response
{% hint style="info" %}
**Note**: the response is a map of <mark style="color:red;">`product_id -> snapshot`</mark> for each requested product.
{% endhint %}
```json
{
"1": {
"product_id": 1,
"submission_idx": "459743",
"product": {
"spot": {
"product_id": 1,
"oracle_price_x18": "115575316424148798147115",
"risk": {
"long_weight_initial_x18": "900000000000000000",
"short_weight_initial_x18": "1100000000000000000",
"long_weight_maintenance_x18": "950000000000000000",
"short_weight_maintenance_x18": "1050000000000000000",
"price_x18": "115575316424148798147115"
},
"config": {
"token": "0xc57c1c64561a37ac9e8f9039cb6deab7539d99fc",
"interest_inflection_util_x18": "800000000000000000",
"interest_floor_x18": "10000000000000000",
"interest_small_cap_x18": "40000000000000000",
"interest_large_cap_x18": "1000000000000000000",
"withdraw_fee_x18": "40000000000000",
"min_deposit_rate_x18": "0"
},
"state": {
"cumulative_deposits_multiplier_x18": "1000000000000318713",
"cumulative_borrows_multiplier_x18": "1000347390679880473",
"total_deposits_normalized": "9000399823280682696107190850",
"total_borrows_normalized": "9580268570661550719"
},
"book_info": {
"size_increment": "1000000000000000",
"price_increment_x18": "1000000000000000000",
"min_size": "4000000000000000",
"collected_fees": "0"
}
}
}
},
"2": {
"product_id": 2,
"submission_idx": "459842",
"product": {
"perp": {
"product_id": 2,
"oracle_price_x18": "115432187703236794231754",
"risk": {
"long_weight_initial_x18": "950000000000000000",
"short_weight_initial_x18": "1050000000000000000",
"long_weight_maintenance_x18": "970000000000000000",
"short_weight_maintenance_x18": "1030000000000000000",
"price_x18": "115432187703236794231754"
},
"state": {
"cumulative_funding_long_x18": "-394223711772447555304",
"cumulative_funding_short_x18": "-394223711772447555304",
"available_settle": "20092193239667417956947",
"open_interest": "113605000000000000000"
},
"book_info": {
"size_increment": "1000000000000000",
"price_increment_x18": "1000000000000000000",
"min_size": "4000000000000000",
"collected_fees": "0"
}
}
}
}
}
```
### Response Fields
<table><thead><tr><th width="307">Field name</th><th>Description</th></tr></thead><tbody><tr><td>submission_idx</td><td>Used to uniquely identify the blockchain transaction that generated the product snapshot.</td></tr><tr><td>product_id</td><td>The id of of the product the event is associated with.</td></tr><tr><td>product</td><td>The state of the product at the time of the transaction.</td></tr></tbody></table>
@@ -0,0 +1,33 @@
# Quote Price
## Rate limits
* 1200 requests/min or 200 requests/10secs per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Get quote price" %} <mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"quote_price": {}
}
```
{% endtab %}
{% endtabs %}
## Response
```json
{
"price_x18": "999944870000000000"
}
```
@@ -0,0 +1,49 @@
# Sequencer Backlog
## Rate limits
* 2400 requests/min or 400 requests/10secs per IP address. (**weight = 1**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Get sequencer backlog" %} <mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"backlog": {}
}
```
{% endtab %}
{% endtabs %}
## Response
```json
{
"total_txs": "45479039",
"total_submissions": "45478914",
"backlog_size": "125",
"updated_at": "1750365790",
"backlog_eta_in_seconds": "500",
"txs_per_second": "0.25"
}
```
### Response Fields
| Field name | Description |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| total\_txs | Total number of transactions stored in the indexer DB. |
| total\_submissions | Total number of transactions submitted on-chain. |
| backlog\_size | Number of unprocessed transactions (<mark style="color:red;">`total_txs - total_submissions`</mark>). |
| backlog\_eta\_in\_seconds | Estimated time in seconds (<mark style="color:red;">`float`</mark>) to clear the entire backlog (<mark style="color:red;">`null`</mark> if unavailable). |
| txs\_per\_second | Current submission rate in transactions per second (<mark style="color:red;">float</mark>) (<mark style="color:red;">`null`</mark> if unavailable). |
| updated\_at | UNIX timestamp (in seconds) of when the data was last updated. |
@@ -0,0 +1,60 @@
# Signatures
## Rate limits
* Dynamic based on <mark style="color:red;">`digests`</mark> param provided (**weight = 2 + len(digests) / 10**)
* E.g: With <mark style="color:red;">`digests=100`</mark>, you can make up to 200 requests per min or 33 requests / 10 secs.
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Get order signatures by digests" %} <mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"signatures": {
"digests": [
"0xf4f7a8767faf0c7f72251a1f9e5da590f708fd9842bf8fcdeacbaa0237958fff",
"0x0495a88fb3b1c9bed9b643b8e264a391d04cdd48890d81cd7c4006473f28e361"
]
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="113" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">digests</td><td align="center">string[]</td><td align="center">Yes</td><td>A list of order digests to retrieve signatures for.</td></tr></tbody></table>
## Response
```json
{
"signatures": [
{
"digest": "0xf4f7a8767faf0c7f72251a1f9e5da590f708fd9842bf8fcdeacbaa0237958fff",
"signature": "0xe8fa7151bde348afa3b46dc52798046b7c8318f1b0a7f689710debbc094658cc1bf5a7e478ccc8278b625da0b9402c86b580d2e31e13831337dfd6153f4b37811b",
"signer": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
"is_linked": false
},
{
"digest": "0x0495a88fb3b1c9bed9b643b8e264a391d04cdd48890d81cd7c4006473f28e361",
"signature": "0x826c68f1a3f76d9ffbe8041f8d45e969d31f1ab6f2ae2f6379d1493e479e56436091d6cf4c72e212dd2f1d2fa17c627c4c21bd6d281c77172b8af030488478b71c",
"signer": "0x44b525f7bf3441464e406a094bc5e791f13dd79f64656661756c740000000000",
"is_linked": true
},
]
}
```
## Response Fields
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>digest</td><td>The order's generated digest.</td></tr><tr><td>signature</td><td>The order's generated signature.</td></tr><tr><td>signer</td><td>The address that signed the order / generated the signature.</td></tr><tr><td>is_linked</td><td>Indicates whether this is a signature from a linked signer or the original sender.</td></tr></tbody></table>
@@ -0,0 +1,139 @@
# Subaccount Snapshots
Use this query to get a summary of the latest actions per product on Nado for provided subaccounts. Tracked variables (ex. net interest) are extrapolated to the timestamp or set of timestamps provided.
## Rate limits
* 480 requests/min or 80 requests/10secs per IP address. (**weight = 5**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Subaccount snapshots" %}
Query latest subaccount events/actions ordered by <mark style="color:red;">`submission index`</mark> desc.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"account_snapshots": {
"subaccounts": [
"0xec132d41e542c7129268d9d4431f105e0830a81164656661756c745f31000000"
],
"timestamps": [
1738703761
],
"isolated": false,
"active": true
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="113" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">subaccounts</td><td align="center">array</td><td align="center">Yes</td><td>A list of <mark style="color:red;"><code>bytes32</code></mark> sent as a hex string; includes the address and the subaccount identifier.</td></tr><tr><td align="center">timestamp</td><td align="center">array</td><td align="center">Yes</td><td>A list of timestamps to retrieve multiple subaccount snapshots (one per timestamp).</td></tr><tr><td align="center">isolated</td><td align="center">boolean</td><td align="center">No</td><td><p>A filter to include only isolated or cross margin events.</p><ul><li>If <mark style="color:red;"><code>true</code></mark>: returns only <strong>isolated</strong> margin events.</li><li>If <mark style="color:red;"><code>false</code></mark>: returns only <strong>cross</strong> margin events.</li><li>If omitted: returns <strong>both</strong> isolated and cross events.</li></ul></td></tr><tr><td align="center">active</td><td align="center">boolean</td><td align="center">No</td><td><p>Filters which products to include in the snapshot:</p><ul><li><mark style="color:red;"><code>true</code></mark>: returns only products with <strong>non-zero balance</strong> at the timestamp (currently active positions)</li><li><mark style="color:red;"><code>false</code></mark>: returns products with <strong>event history</strong> before the timestamp (any historical activity)</li><li>If omitted: defaults to <mark style="color:red;"><code>false</code></mark></li></ul></td></tr></tbody></table>
## Response
{% tabs %}
{% tab title="Single timestamp" %}
```json
{
"snapshots": {
"0xec132d41e542c7129268d9d4431f105e0830a81164656661756c745f31000000": {
"1738703761": [
{
"subaccount": "0xec132d41e542c7129268d9d4431f105e0830a81164656661756c745f31000000",
"product_id": 0,
"submission_idx": "17286676",
"event_type": "liquidate_subaccount",
"isolated": false,
"isolated_product_id": null,
"pre_balance": {
"spot": {
"product_id": 0,
"balance": {
"amount": "53278293456559329896"
}
}
},
"post_balance": {
"spot": {
"product_id": 0,
"balance": {
"amount": "0"
}
}
},
"product": {
"spot": {
"product_id": 0,
"oracle_price_x18": "1000000000000000000",
"risk": {
"long_weight_initial_x18": "1000000000000000000",
"short_weight_initial_x18": "1000000000000000000",
"long_weight_maintenance_x18": "1000000000000000000",
"short_weight_maintenance_x18": "1000000000000000000",
"price_x18": "1000000000000000000"
},
"config": {
"token": "0x5f65358d61a9a281ea3bb930d05889aca21e3f4f",
"interest_inflection_util_x18": "800000000000000000",
"interest_floor_x18": "10000000000000000",
"interest_small_cap_x18": "40000000000000000",
"interest_large_cap_x18": "1000000000000000000",
"withdraw_fee_x18": "1000000000000000000",
"min_deposit_rate_x18": "0"
},
"state": {
"cumulative_deposits_multiplier_x18": "1000000000025524653",
"cumulative_borrows_multiplier_x18": "1000347390837434279",
"total_deposits_normalized": "20001011744258817298755054194662",
"total_borrows_normalized": "1617724891363505323532211"
},
"book_info": {
"size_increment": "0",
"price_increment_x18": "0",
"min_size": "0",
"collected_fees": "0"
}
}
},
"net_interest_unrealized": "0",
"net_interest_cumulative": "1443761232166478119",
"net_funding_unrealized": "0",
"net_funding_cumulative": "0",
"net_entry_unrealized": "0",
"net_entry_cumulative": "13458165999999999998",
"quote_volume_cumulative": "1234567890123456789"
}
]
}
}
}
```
{% endtab %}
{% endtabs %}
## Response Fields
### Events
{% hint style="info" %}
* **Net cumulative**: the net difference in that quantity since the beginning of time. For example, if I want to compute total amount paid out in funding between two events, you can subtract the `net_funding_cumulative` of the larger event by the `net_funding_cumulative` of the smaller event.
* **Net unrealized**: similar to `net_cumulative`, but for `net_unrealized`, we have the caveat that when the magnitude of your position decreases, the magnitude of net\_unrealized `decreases` by the same amount.
{% endhint %}
<table><thead><tr><th width="307">Field name</th><th>Description</th></tr></thead><tbody><tr><td>submission_idx</td><td>Used to uniquely identify the blockchain transaction that generated the event; you can use it to grab the relevant transaction in the <code>txs</code> section.</td></tr><tr><td>product_id</td><td>The id of of the product the event is associated with.</td></tr><tr><td>event_type</td><td>Name of the transaction type this event corresponds to.</td></tr><tr><td>subaccount</td><td>The subaccount associated to the event.</td></tr><tr><td>pre_balance</td><td>The state of your balance before the event happened.</td></tr><tr><td>post_balance</td><td>The state of your balance after the event happened.</td></tr><tr><td>product</td><td>The state of the product throughout the event.</td></tr></tbody></table>
@@ -0,0 +1,91 @@
# Subaccounts
## Rate limits
* 1200 requests/min or 200 requests/10secs per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="List subaccounts" %}
Query subaccounts ordered by <mark style="color:red;">`subaccount id`</mark> ASC.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"subaccounts": {
"start": 100,
"limit": 10,
}
}
```
{% endtab %}
{% tab title="Find subaccounts by address" %}
Query all subaccounts associated to an address ordered by <mark style="color:red;">`subaccount id`</mark> ASC.
<mark style="color:orange;">`POST [ARCHIVE_ENDPOINT]`</mark>
**Body**
```json
{
"subaccounts": {
"address": "0x79CC76364b5Fb263A25bD52930E3d9788fCfEEA8"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="145" align="center">Parameter</th><th width="150" align="center">Type</th><th width="122" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">start</td><td align="center">string/number</td><td align="center">No</td><td>Subaccount id to start from (used for pagination). Defaults to 0.</td></tr><tr><td align="center">limit</td><td align="center">string/number</td><td align="center">No</td><td>Max number of subaccounts to return. Defaults to 100, max of 500.</td></tr><tr><td align="center">address</td><td align="center">string</td><td align="center">No</td><td>An optional wallet address to find all subaccounts associated to it.</td></tr></tbody></table>
## Response
```json
{
"subaccounts": [
{
"id": "25",
"subaccount": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
"address": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b6",
"subaccount_name": "default",
"created_at": "1699949771",
"isolated": false
},
{
"id": "948",
"subaccount": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c745f31000000",
"address": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b6",
"subaccount_name": "default_1",
"created_at": "1738000782",
"isolated": false
},
{
"id": "1094",
"subaccount": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b600000000000000020069736f",
"address": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b6",
"subaccount_name": "0x00000000000000020069736f",
"created_at": "1748982886",
"isolated": true
}
]
}
```
## Response Fields
### Subaccounts
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>Internal subaccount id</td></tr><tr><td>subaccount</td><td>Hex string of the subaccount (wallet + subaccount name)</td></tr><tr><td>address</td><td>Hex string of wallet address</td></tr><tr><td>subaccount_name</td><td>Subaccount identifier</td></tr><tr><td>created_at</td><td>When subaccount was created</td></tr><tr><td>isolated</td><td>Whether it's a subaccount for an isolated position</td></tr></tbody></table>
@@ -0,0 +1,62 @@
# Definitions / Formulas
## Definitions
### **Unsettled USDT0**
Perp balances have two main components:
* <mark style="color:red;">`amount`</mark>
* <mark style="color:red;">`v_quote_balance`</mark>
When you buy a perp, <mark style="color:red;">`amount`</mark> increments and <mark style="color:red;">`v_quote_balance`</mark> decrements, and vice versa for selling.
Settlement is the process of converting from <mark style="color:red;">v\_quote\_balance</mark> into actual USDT0 balance. This happens mostly on position close, but may happen on extremely negative PNL positions when we need to pay out positive PNL positions.
The amount that is transferred between <mark style="color:red;">`v_quote_balance`</mark> in the perp and your USDT0 balance is an amount that results in <mark style="color:red;">`amount * oracle_price + v_quote_balance == 0`</mark>. Unsettled USDT0 is the total amount that would be transferred between <mark style="color:red;">`v_quote_balance`</mark> and your USDT0 balance summed across all perps.
### **Unsettled PNL**
**Note:** Technically, there is no such concept as "Unsettled PNL" in our system. However, the UI displays "Unsettled PnL" in some places (e.g., in the USDT0 Balance section) for user clarity.
**What the UI actually shows:** When you see "Unsettled PnL" in the UI, it refers to **Unsettled USDT0** (see above) - the total unsettled quote balance across all perp positions.
**For developers:** Always use **Unsettled USDT0** when referring to this value programmatically. It represents the sum of <mark style="color:red;">`amount × oracle_price + v_quote_balance`</mark> across all perp positions, which is the amount that would be settled into your USDT0 balance.
### **Unrealized PNL**
Refers to the estimated gains or losses of a current position based on the difference between the average entry price and the current oracle price.
## Formulas
### **Unrealized PNL**
Using the [indexer's events query](https://docs.nado.xyz/developer-resources/api/archive-indexer/events), your unrealized PNL at the end of some event is given by:
{% code lineNumbers="true" %}
```python
unrealized_pnl = (
event.post_balance.amount * event.product.oracle_price_x18
- event.net_entry_unrealized
)
```
{% endcode %}
### Total PNL
Your total PNL between <mark style="color:red;">`event1`</mark> and <mark style="color:red;">`event2`</mark>, assuming <mark style="color:red;">`event1`</mark> is after <mark style="color:red;">`event2`</mark> - is given by:
<pre class="language-python" data-line-numbers><code class="lang-python"><strong>total_pnl = (
</strong><strong> (event1.post_balance.amount * event1.product.oracle_price_x18 - event1.net_entry_cumulative)
</strong><strong> - (event2.post_balance.amount * event2.product.oracle_price_x18 - event2.net_entry_cumulative)
</strong><strong>)
</strong></code></pre>
{% hint style="info" %}
**Notes**:
* You can use 0 for the second term for the PNL to compute since the beginning of time.
* For spots, we will count deposits and withdraws towards your PNL. i.e. if you deposit BTC, for PNL tracking purposes it is counted as a BTC long at the oracle price.
{% endhint %}
@@ -0,0 +1,170 @@
# Depositing
There are two ways to deposit funds into Nado:
1. **Direct Deposit** - Simple transfer to your unique deposit address (recommended for most users)
2. **On-Chain Contract Call** - Direct interaction with the Endpoint contract
***
## Method 1: Direct Deposit (Recommended)
Each subaccount has a unique deposit address. Simply send funds to this address and they will automatically be credited to your subaccount.
### Getting Your Deposit Address
Query your unique deposit address using the [Direct Deposit Address](https://docs.nado.xyz/developer-resources/api/archive-indexer/direct-deposit-address) endpoint:
**Request:**
```json
{
"direct_deposit_address": {
"subaccount": "0x79cc76364b5fb263a25bd52930e3d9788fcfeea864656661756c740000000000"
}
}
```
**Response:**
```json
{
"subaccount": "0x79cc76364b5fb263a25bd52930e3d9788fcfeea864656661756c740000000000",
"deposit_address": "0x1234567890123456789012345678901234567890",
"created_at": "1683315718"
}
```
### Depositing Funds
1. Get your deposit address using the API call above
2. Send the supported token to this address (e.g., USDT0, wETH, etc.)
3. Funds will be automatically credited to your subaccount within a few seconds
**Advantages:**
* No need to interact with smart contracts
* No need to approve allowances
* Works with any wallet (including CEX withdrawals)
* Simpler integration for users
**Notes:**
* Only send supported tokens to this address
* Find supported tokens via the [All Products](https://docs.nado.xyz/developer-resources/api/gateway/queries/all-products) query
* Deposits are processed automatically after blockchain confirmation
***
## Method 2: On-Chain Contract Call
Advanced users can deposit directly by calling the Endpoint contract.
### Contract Address
Find the Endpoint contract address at:
```
GET <nado-url>/query?type=contracts
```
### Function Interface
#### Basic Deposit
```solidity
function depositCollateral(
bytes12 subaccountName, // last 12 bytes of the subaccount bytes32
uint32 productId, // product ID for the token
uint128 amount // raw token amount (see decimals below)
) external
```
**Parameters:**
* `subaccountName`: The last 12 bytes of your subaccount identifier (e.g., `0x64656661756c740000000000` for "default")
* `productId`: The product ID for the token you're depositing
* `amount`: The raw amount in the token's smallest unit
* For USDT0 (6 decimals): 1 USDT0 = `1e6` = `1000000`
* For wETH (18 decimals): 1 wETH = `1e18`
* For wBTC (8 decimals): 1 wBTC = `1e8`
#### Deposit with Referral Code
```solidity
function depositCollateralWithReferral(
bytes32 subaccount, // full 32-byte subaccount identifier
uint32 productId, // product ID for the token
uint128 amount, // raw token amount
string memory referralCode // referral code (optional)
) public
```
### Prerequisites
Before depositing via contract call, you must:
1. **Approve Token Allowance**
```solidity
// Give the Endpoint contract permission to transfer your tokens
IERC20(tokenAddress).approve(endpointAddress, amount);
```
2. **Get Product Information**
* Use [All Products](https://docs.nado.xyz/developer-resources/api/gateway/queries/all-products) query to find:
* Product ID for your token
* Token contract address
* Token decimals
### Example: Depositing 100 USDT0
Assuming USDT0 has product ID `0` and 6 decimals:
```typescript
// 1. Approve allowance (one-time or as needed)
await usdtContract.approve(endpointAddress, ethers.constants.MaxUint256);
// 2. Deposit 100 USDT0
const subaccountName = ethers.utils.formatBytes32String("default").slice(0, 26); // bytes12
const productId = 0;
const amount = 100 * 1e6; // 100 USDT0 with 6 decimals
await endpointContract.depositCollateral(subaccountName, productId, amount);
```
### Processing Time
Deposits may take a few seconds to process after transaction confirmation. You can monitor your balance via:
* [Subaccount Info](https://docs.nado.xyz/developer-resources/api/gateway/queries/subaccount-info) query
* WebSocket subscriptions for real-time updates
***
## Important Notes
* **Use Correct Product ID**: Each token has a specific product ID. Using the wrong ID will cause the transaction to fail.
* **Check Token Decimals**: Always multiply by the correct decimal factor (6 for USDT0, 18 for wETH, etc.)
* **Minimum Deposit**: Some products may have minimum deposit amounts
* **Only Supported Tokens**: Only deposit tokens that are listed via the All Products query
***
## Getting Token Information
Use the [All Products](https://docs.nado.xyz/developer-resources/api/gateway/queries/all-products) query to get:
```json
{
"product_id": 0,
"symbol": "USDT0",
"token": "0x...", // token contract address
"decimals": 6
}
```
This information is essential for:
* Finding the correct `productId`
* Getting the token contract for approvals (Method 2 only)
* Calculating the correct `amount` with proper decimals
@@ -0,0 +1,25 @@
# Endpoints
## Mainnet
### <mark style="color:purple;">Ink Mainnet</mark>
* **Gateway Websocket**: <mark style="color:green;">`wss://gateway.prod.nado.xyz/v1/ws`</mark>
* **Gateway REST:** <mark style="color:green;">`https://gateway.prod.nado.xyz/v1`</mark>
* **Gateway V2:** <mark style="color:green;">`https://gateway.prod.nado.xyz/v2`</mark>
* **Subscriptions**: <mark style="color:green;">`wss://gateway.prod.nado.xyz/v1/subscribe`</mark>
* **Archive (Indexer):** <mark style="color:green;">`https://archive.prod.nado.xyz/v1`</mark>
* **Archive (Indexer) V2:** <mark style="color:green;">`https://archive.prod.nado.xyz/v2`</mark>
* **Trigger**: <mark style="color:green;">`https://trigger.prod.nado.xyz/v1`</mark>
## Testnet
### <mark style="color:purple;">Ink Sepolia</mark>
* **Gateway Websocket**: <mark style="color:red;">`wss://gateway.test.nado.xyz/v1/ws`</mark>
* **Gateway REST:** <mark style="color:red;">`https://gateway.test.nado.xyz/v1`</mark>
* **Gateway V2:** <mark style="color:red;">`https://gateway.test.nado.xyz/v2`</mark>
* **Subscriptions**: <mark style="color:red;">`wss://gateway.test.nado.xyz/v1/subscribe`</mark>
* **Archive (Indexer):** <mark style="color:red;">`https://archive.test.nado.xyz/v1`</mark>
* **Archive (Indexer) V2:** <mark style="color:red;">`https://archive.test.nado.xyz/v2`</mark>
* **Trigger**: <mark style="color:red;">`https://trigger.test.nado.xyz/v1`</mark>
File diff suppressed because one or more lines are too long
@@ -0,0 +1,33 @@
# Gateway
There are two types of actions. An <mark style="color:red;">`Execute`</mark> involves a modification to state, and a <mark style="color:red;">`Query`</mark> merely fetches information from state.
All actions can be sent over websocket as json payloads at <mark style="color:red;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
Additionally, you can send executes and queries over <mark style="color:red;">HTTP</mark>, at <mark style="color:red;">`POST [GATEWAY_REST_ENDPOINT]/execute`</mark> and <mark style="color:red;">`GET/POST [GATEWAY_REST_ENDPOINT]/query`</mark> respectively. For executes, the request should be sent with a json payload, while for queries, the payload should be encoded into url query strings.
<mark style="color:red;">`HTTP`</mark> requests must set the `Accept-Encoding` to include `gzip`, `br` or `deflate`
## Endpoints
### **Testnet**:
* Websocket: <mark style="color:red;">`wss://gateway.test.nado.xyz/v1/ws`</mark>
* REST: <mark style="color:red;">`https://gateway.test.nado.xyz/v1`</mark>
## Websocket
{% hint style="info" %}
**Notes on&#x20;*****keeping websocket connections alive*****:**
* When interacting with our API via websocket, you must send ping frames every 30 seconds to keep the websocket connection alive.
* Ping / Pong frames are built into the websocket protocol and should be supported natively by your websocket library. See [Ping/Pong frames](https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2) for more info.
{% endhint %}
{% content-ref url="gateway/executes" %}
[executes](https://docs.nado.xyz/developer-resources/api/gateway/executes)
{% endcontent-ref %}
{% content-ref url="gateway/queries" %}
[queries](https://docs.nado.xyz/developer-resources/api/gateway/queries)
{% endcontent-ref %}
@@ -0,0 +1,63 @@
# Executes
## Overview
All executes go through the following endpoint; the exact details of the execution are specified by the JSON payload.
* **Websocket**: <mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
* **REST**: <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/execute`</mark>
### **Signing**
All executes are signed using [EIP712](https://eips.ethereum.org/EIPS/eip-712). Each execute request contains:
1. A piece of structured data that includes the sender address
2. A signature of the hash of that structured data, signed by the sender
You can check the SDK for some examples of how to generate these signatures.
{% hint style="info" %}
See more info in the [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page.
{% endhint %}
### **Sender Field Structure**
The sender field is a solidity <mark style="color:red;">`bytes32`</mark> . There are two components:
* an <mark style="color:red;">`address`</mark> that is a <mark style="color:red;">`bytes20`</mark>
* a subaccount identifier that is a <mark style="color:red;">`bytes12`</mark>
For example, if your address was <mark style="color:red;">`0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43`</mark>, and you wanted to use the default subaccount identifier (i.e: the word <mark style="color:red;">`default`</mark>) you can set <mark style="color:red;">`sender`</mark> to <mark style="color:red;">`0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c4364656661756c740000000000`</mark> , which sets the subaccount identifier to <mark style="color:red;">`64656661756c740000000000`</mark>.
### **Amounts**
For <mark style="color:red;">`DepositCollateral`</mark> and <mark style="color:red;">`WithdrawCollateral`</mark>, the amount specifies the physical token amount that you want to receive. `i.e.` if USDT0 has 6 decimals, and you want to deposit or withdraw 1 USDT0, you specify <mark style="color:red;">`amount = 1e6`</mark>.
For all other transactions, amount is normalized to 18 decimals, so <mark style="color:red;">`1e18`</mark> == one unit of the underlying asset. For example, if you want to buy 1 wETH, regardless of the amount of decimals the wETH contract has on chain, you specify <mark style="color:red;">`1e18`</mark> in the amount field of the order.
## API Response
All `Execute` messages return the following information:
#### Success
```json
{
"status": "success",
"signature": "{signature}",
"data"?: {data_obj},
"request_type": "{request_type}"
}
```
#### Failure
```json
{
"status": "failure",
"signature": "{signature}",
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "{request_type}"
}
```
@@ -0,0 +1,116 @@
# Burn NLP
## Rate limits
* 60 burns/min or 10 burns every 10 seconds per wallet. (**weight = 10**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits).
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"burn_nlp": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"nlpAmount": "10001000000000000000000"
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% tab title="REST" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/execute`</mark>
**Body**
```json
{
"burn_lp": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"productId": 1,
"amount": "10001000000000000000000"
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="190" align="center">Parameter</th><th width="114" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">tx</td><td align="center">object</td><td align="center">Yes</td><td>Burn NLP transaction object. See <a href="#signing">Signing</a> section for details on the transaction fields.</td></tr><tr><td align="center">tx.sender</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing the subaccount's 32 bytes (address + subaccount name) of the tx sender.</td></tr><tr><td align="center">tx.nlpAmount</td><td align="center">string</td><td align="center">Yes</td><td>Amount of NLP tokens to burn multiplied by 1e18, sent as a string.</td></tr><tr><td align="center">tx.nonce</td><td align="center">string</td><td align="center">Yes</td><td>This is an incrementing nonce, can be obtained using the <a href="../queries/nonces">Nonces</a> query.</td></tr><tr><td align="center">signature</td><td align="center">string</td><td align="center">Yes</td><td>Signed transaction. See <a href="#signing">Signing</a> section for more details.</td></tr></tbody></table>
## Signing
{% hint style="info" %}
See more details and examples in our [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page.
{% endhint %}
The solidity typed data struct that needs to be signed is:
```solidity
struct BurnNlp {
bytes32 sender;
uint128 nlpAmount;
uint64 nonce;
}
```
<mark style="color:red;">`sender`</mark>: a <mark style="color:red;">`bytes32`</mark> sent as a hex string; includes the address and the subaccount identifier.
<mark style="color:red;">`nlpAmount`</mark>: amount of NLP tokens to burn, sent as a string. This must be positive and must be specified with 18 decimals.
<mark style="color:red;">`nonce`</mark>: the <mark style="color:red;">`tx_nonce`</mark>. This is an incrementing nonce, can be obtained using the [Nonces](https://docs.nado.xyz/developer-resources/api/gateway/queries/nonces) query.
{% hint style="warning" %}
**Note**: for signing you should always use the data type specified in the solidity struct which might be different from the type sent in the request e.g: <mark style="color:red;">`nonce`</mark> should be an <mark style="color:red;">`uint64`</mark> for **Signing** but should be sent as a <mark style="color:red;">`string`</mark> in the final payload.
{% endhint %}
## Response
```json
{
"status": "success",
}
```
#### Success
```json
{
"status": "success",
"signature": {signature},
"request_type": "execute_burn_nlp"
}
```
#### Failure
```json
{
"status": "failure",
"signature": {signature},
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "execute_burn_nlp"
}
```
@@ -0,0 +1,119 @@
# Cancel And Place
## Rate limits
* The sum of [Cancel Orders](https://docs.nado.xyz/developer-resources/api/gateway/cancel-orders#rate-limits) + [Place Order](https://docs.nado.xyz/developer-resources/api/gateway/place-order#rate-limits) limits
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits).
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"cancel_and_place": {
"cancel_tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"productIds": [2],
"digests": ["0x"],
"nonce": "1"
},
"cancel_signature": "0x",
"place_order": {
"product_id": 1,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "1000000000000000000",
"amount": "1000000000000000000",
"expiration": "4294967295",
"appendix": "1537",
"nonce": "1757062078359666688"
},
"signature": "0x",
}
}
}
```
{% endtab %}
{% tab title="REST" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/execute`</mark>
**Body**
```json
{
"cancel_and_place": {
"cancel_tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"productIds": [2],
"digests": ["0x"],
"nonce": "1"
},
"cancel_signature": "0x",
"place_order": {
"product_id": 1,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "1000000000000000000",
"amount": "1000000000000000000",
"expiration": "4294967295",
"nonce": "1757062078359666688"
},
"signature": "0x",
}
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="219" align="center">Parameter</th><th width="128" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">cancel_tx</td><td align="center">object</td><td align="center">Yes</td><td>Cancel order transaction object. See <a href="../cancel-orders#signing">Cancel order signing</a> for details on the transaction fields.</td></tr><tr><td align="center">cancel_tx.sender</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing the subaccount's 32 bytes (address + subaccount name) of the tx sender.</td></tr><tr><td align="center">cancel_tx.productIds</td><td align="center">number[]</td><td align="center">Yes</td><td>A list of product IDs, corresponding to the product ids of the orders in <mark style="color:red;"><code>digests</code></mark></td></tr><tr><td align="center">cancel_tx.digests</td><td align="center">string[]</td><td align="center">Yes</td><td>A list of order digests, represented as hex strings.</td></tr><tr><td align="center">cancel_tx.nonce</td><td align="center">string</td><td align="center">Yes</td><td>Used to differentiate between the same cancellation multiple times. See <a href="../cancel-orders#signing">Cancel order signing</a> section for more details.</td></tr><tr><td align="center">cancel_signature</td><td align="center">string</td><td align="center">Yes</td><td>Signed transaction. See <a href="#signing">Signing</a><a href="../cancel-orders#signing">Cancel order signing</a> for more details.</td></tr><tr><td align="center">place_order</td><td align="center">object</td><td align="center">Yes</td><td>Payload of order to be placed. See <a href="../../../trigger/executes/place-order#request-parameters">Place order request parameters</a> for payload details.</td></tr></tbody></table>
## Signing
{% hint style="warning" %}
**Note**: both <mark style="color:red;">`cancel_tx`</mark> and <mark style="color:red;">`place_order`</mark> objects must be signed using the same signer, otherwise the request will be rejected.
{% endhint %}
* See [Cancel orders signing](https://docs.nado.xyz/developer-resources/api/gateway/cancel-orders#signing) for details on how to sign the order cancellation.
* See [Place order signing](https://docs.nado.xyz/developer-resources/api/gateway/place-order#signing) for details on how to sign the order placement.
## Response
#### Success
```json
{
"status": "success",
"signature": {signature},
"data": {
"digest": {order digest}
},
"request_type": "execute_cancel_and_place"
}
```
#### Failure
```json
{
"status": "failure",
"signature": {signature}
"error": "{error_msg}"
"error_code": {error_code}
"request_type": "execute_cancel_and_place"
}
```
@@ -0,0 +1,139 @@
# Cancel Orders
## Rate limits
* When no **digests** are provided: 600 cancellations/min or 10 cancellations/sec per wallet. (**weight=1**)
* When **digests** are provided: 600/(total digests) cancellations per minute per wallet. (**weight=total digests**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits).
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"cancel_orders": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"productIds": [2],
"digests": ["0x"],
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% tab title="REST" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/execute`</mark>
**Body**
```json
{
"cancel_orders": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"productIds": [0],
"digests": ["0x"],
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="156" align="center">Parameter</th><th width="128" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">tx</td><td align="center">object</td><td align="center">Yes</td><td>Cancel order transaction object. See <a href="#signing">Signing</a> section for details on the transaction fields.</td></tr><tr><td align="center">tx.sender</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing the subaccount's 32 bytes (address + subaccount name) of the tx sender.</td></tr><tr><td align="center">tx.productIds</td><td align="center">number[]</td><td align="center">Yes</td><td>A list of product IDs, corresponding to the product ids of the orders in <mark style="color:red;"><code>digests</code></mark></td></tr><tr><td align="center">tx.digests</td><td align="center">string[]</td><td align="center">Yes</td><td>A list of order digests, represented as hex strings.</td></tr><tr><td align="center">tx.nonce</td><td align="center">string</td><td align="center">Yes</td><td>Used to differentiate between the same cancellation multiple times. See <a href="#signing">Signing</a> section for more details.</td></tr><tr><td align="center">signature</td><td align="center">string</td><td align="center">Yes</td><td>Signed transaction. See <a href="#signing">Signing</a> section for more details.</td></tr></tbody></table>
## Signing
{% hint style="info" %}
See more details and examples in our [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page.
{% endhint %}
The solidity typed data struct that needs to be signed is:
```solidity
struct Cancellation {
bytes32 sender;
uint32[] productIds;
bytes32[] digests;
uint64 nonce;
}
```
<mark style="color:red;">`sender`</mark>: a <mark style="color:red;">`bytes32`</mark> sent as a hex string; includes the address and the subaccount identifier
<mark style="color:red;">`productIds`</mark>: a list of product IDs, corresponding to the product ids of the orders in <mark style="color:red;">`digests`</mark>
<mark style="color:red;">`digests`</mark>: a list of order digests, represented as hex strings, for the orders you want to cancel.
<mark style="color:red;">`nonce`</mark>: used to differentiate between the same cancellation multiple times, and a user trying to place a cancellation with the same parameters twice. Sent as a string. Encodes two bit of information:
* Most significant <mark style="color:red;">`44`</mark> bits encoding the <mark style="color:red;">`recv_time`</mark> in milliseconds after which the cancellation should be ignored by the matching engine; the engine will accept cancellations where <mark style="color:red;">`current_time < recv_time <= current_time + 100000`</mark>
* Least significant <mark style="color:red;">`20`</mark> bits are a random integer used to avoid hash collisions
For example, to place a cancellation with a random integer of <mark style="color:red;">`1000`</mark>, and a discard time 50 ms from now, we would send a nonce of <mark style="color:red;">`(timestamp_ms() + 50) << 20 + 1000`</mark>
{% hint style="warning" %}
**Note**: for signing you should always use the data type specified in the solidity struct which might be different from the type sent in the request e.g: <mark style="color:red;">`nonce`</mark> should be an <mark style="color:red;">`uint64`</mark> for **Signing** but should be sent as a <mark style="color:red;">`string`</mark> in the final payload.
{% endhint %}
## Response
#### Success
```json
{
"status": "success",
"signature": {signature},
"data": {
"cancelled_orders": [
{
"product_id": 2,
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"price_x18": "20000000000000000000000",
"amount": "-100000000000000000",
"expiration": "1686332748",
"order_type": "post_only",
"nonce": "1768248100142339392",
"unfilled_amount": "-100000000000000000",
"digest": "0x3195a7929feb8307edecf9c045j5ced68925108f0aa305f0ee5773854159377c",
"appendix": "1537",
"placed_at": 1686332708
},
...
]
},
"request_type": "execute_cancel_orders"
}
```
#### Failure
```json
{
"status": "failure",
"signature": {signature},
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "execute_cancel_orders"
}
```
@@ -0,0 +1,135 @@
# Cancel Product Orders
## Rate limits
* When no **productIds** are provide&#x64;**:** 12 cancellations/min or 2 cancellations/sec per wallet. (**weight=50**)
* When **productIds** are provided: 600 / (5 \* total productIds) cancellations per minute per wallet. (**weight=5\*total productIds**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits).
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"cancel_product_orders": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"productIds": [2],
"nonce": "1"
},
"signature": "0x",
"digest": null
}
}
```
{% endtab %}
{% tab title="REST" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/execute`</mark>
**Body**
```json
{
"cancel_product_orders": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"productIds": [0],
"nonce": "1"
},
"signature": "0x",
"digest": "0x"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="178" align="center">Parameter</th><th width="142" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">tx</td><td align="center">object</td><td align="center">Yes</td><td>Cancel product orders transaction object. See <a href="#signing">Signing</a> section for details on transaction fields.</td></tr><tr><td align="center">tx.sender</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing the subaccount's 32 bytes (address + subaccount name) of the tx sender.</td></tr><tr><td align="center">tx.productIds</td><td align="center">number[]</td><td align="center">Yes</td><td>A list of product IDs to cancel orders for.</td></tr><tr><td align="center">tx.nonce</td><td align="center">string</td><td align="center">Yes</td><td>Used to differentiate between the same cancellation multiple times. See <a href="#signing">Signing</a> section for more details.</td></tr><tr><td align="center">signature</td><td align="center">string</td><td align="center">Yes</td><td>Signed transaction. See <a href="#signing">Signing</a> section for more details.</td></tr><tr><td align="center">digest</td><td align="center">string</td><td align="center">No</td><td>Hex string representing a hash of the <code>CancellationProducts</code> object.</td></tr></tbody></table>
## Signing
{% hint style="info" %}
See more details and examples in our [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page.
{% endhint %}
The solidity typed data struct that needs to be signed is:
```solidity
struct CancellationProducts {
bytes32 sender;
uint32[] productIds;
uint64 nonce;
}
```
<mark style="color:red;">`sender`</mark>: a <mark style="color:red;">`bytes32`</mark> sent as a hex string; includes the address and the subaccount identifier
<mark style="color:red;">`productIds`</mark>: a list of product Ids for which to cancel all subaccount orders. When left empty, orders from all products will be cancelled.
<mark style="color:red;">`nonce`</mark>: used to differentiate between the same cancellation multiple times, and a user trying to place a cancellation with the same parameters twice. Sent as a string. Encodes two bit of information:
* Most significant <mark style="color:red;">`44`</mark> bits encoding the <mark style="color:red;">`recv_time`</mark> in milliseconds after which the cancellation should be ignored by the matching engine; the engine will accept cancellations where <mark style="color:red;">`current_time < recv_time <= current_time + 100000`</mark>
* Least significant <mark style="color:red;">`20`</mark> bits are a random integer used to avoid hash collisions
For example, to place a cancellation with a random integer of <mark style="color:red;">`1000`</mark>, and a discard time 50 ms from now, we would send a nonce of <mark style="color:red;">`(timestamp_ms() + 50) << 20 + 1000`</mark>
{% hint style="warning" %}
**Note**: for signing you should always use the data type specified in the solidity struct which might be different from the type sent in the request e.g: <mark style="color:red;">`nonce`</mark> should be an <mark style="color:red;">`uint64`</mark> for **Signing** but should be sent as a <mark style="color:red;">`string`</mark> in the final payload.
{% endhint %}
## Response
#### Success
```json
{
"status": "success",
"signature": {signature},
"data": {
"cancelled_orders": [
{
"product_id": 2,
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"price_x18": "20000000000000000000000",
"amount": "-100000000000000000",
"expiration": "1686332748",
"order_type": "post_only",
"nonce": "1768248100142339392",
"unfilled_amount": "-100000000000000000",
"digest": "0x3195a7929feb8307edecf9c045j5ced68925108f0aa305f0ee5773854159377c",
"appendix": "1537",
"placed_at": 1686332708
},
...
]
},
"request_type": "execute_cancel_product_orders"
}
```
#### Failure
```json
{
"status": "failure",
"signature": {signature},
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "execute_cancel_product_orders"
}
```
@@ -0,0 +1,123 @@
# Link Signer
Each subaccount can have at most one linked signer at a time. A linked signer can perform any execute on behalf of the subaccount it is linked to. Use the [Linked Signer](https://docs.nado.xyz/developer-resources/api/gateway/queries/linked-signer) query to view your current linked signer.
{% hint style="warning" %}
**Please note**:
* To enable a linked signer, your subaccount must have a minimum of **5 USDT0** worth in account value.
{% endhint %}
## Rate limits
* A max of 50 link signer requests every 7 days per subaccount. (**weight=30**). Use the [Linked Signer Rate Limit](https://docs.nado.xyz/developer-resources/api/archive-indexer/linked-signer-rate-limit) query to check a subaccount's linked signer usage and remaining wait time.
{% hint style="info" %}
See more general details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits).
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"link_signer": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"signer": "0xeae27ae6412147ed6d5692fd91709dad6dbfc34264656661756c740000000000",
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% tab title="REST" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/execute`</mark>
**Body**
```json
{
"link_signer": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"signer": "0xeae27ae6412147ed6d5692fd91709dad6dbfc34264656661756c740000000000",
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="148" align="center">Parameter</th><th width="90" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">tx</td><td align="center">object</td><td align="center">Yes</td><td>A link signer transaction object. See <a href="#signing">Signing</a> section for details on the transaction fields.</td></tr><tr><td align="center">tx.sender</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing the subaccount's 32 bytes (address + subaccount name) of the tx sender.</td></tr><tr><td align="center">tx.signer</td><td align="center">string</td><td align="center">Yes</td><td>A <mark style="color:red;"><code>bytes32</code></mark> sent as a hex string; includes the address (first 20 bytes) that'll be used as the <mark style="color:red;"><code>sender's</code></mark> signer. the last 12 bytes can be set to anything.</td></tr><tr><td align="center">tx.nonce</td><td align="center">string</td><td align="center">Yes</td><td>This is an incrementing nonce, can be obtained using the <a href="../queries/nonces">Nonces</a> query.</td></tr><tr><td align="center">signature</td><td align="center">string</td><td align="center">Yes</td><td>Signed transaction. See <a href="#signing">Signing</a> section for more details.</td></tr></tbody></table>
## Signing
{% hint style="info" %}
See more details and examples in our [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page.
{% endhint %}
The solidity typed data struct that needs to be signed is:
```solidity
struct LinkSigner {
bytes32 sender;
bytes32 signer;
uint64 nonce;
}
```
<mark style="color:red;">`sender`</mark>: a <mark style="color:red;">`bytes32`</mark> sent as a hex string; includes the address and the subaccount identifier of the primary subaccount to add a signer to.
<mark style="color:red;">`signer`</mark>: a <mark style="color:red;">`bytes32`</mark> sent as a hex string; includes the address (first 20 bytes) that'll be used as the <mark style="color:red;">`sender's`</mark> signer.
{% hint style="info" %}
**Notes**:
* the last 12 bytes of the <mark style="color:red;">`signer`</mark> field do not matter and can be set to anything.
* set <mark style="color:red;">`signer`</mark> to the zero address to revoke current signer on the provided <mark style="color:red;">`sender`</mark>.
{% endhint %}
<mark style="color:red;">`nonce`</mark>: the <mark style="color:red;">`tx_nonce`</mark>. This is an incrementing nonce, can be obtained using the [Nonces](https://docs.nado.xyz/developer-resources/api/gateway/queries/nonces) query.
{% hint style="warning" %}
**Note**: for signing you should always use the data type specified in the solidity struct which might be different from the type sent in the request e.g: <mark style="color:red;">`nonce`</mark> should be an <mark style="color:red;">`uint64`</mark> for **Signing** but should be sent as a <mark style="color:red;">`string`</mark> in the final payload.
{% endhint %}
## Response
#### Success
```json
{
"status": "success",
"signature": {signature},
"request_type": "execute_link_signer"
}
```
#### Failure
```json
{
"status": "failure",
"signature": {signature},
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "execute_link_signer"
}
```
@@ -0,0 +1,138 @@
# Liquidate Subaccount
## Rate limits
* 30 liquidations/min or 5 liquidations every 10 seconds per wallet. (**weight=20**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits).
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"liquidate_subaccount": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"liquidatee": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"productId": 1,
"isEncodedSpread": false,
"amount": "1000000000000000000",
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% tab title="REST" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/execute`</mark>
**Body**
```json
{
"liquidate_subaccount": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"liquidatee": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"mode": 0,
"healthGroup": 1,
"amount": "1000000000000000000",
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="220" align="center">Parameter</th><th width="92" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">tx</td><td align="center">object</td><td align="center">Yes</td><td>Liquidate subaccount transaction object. See <a href="#signing">Signing</a> section for details on the transaction fields.</td></tr><tr><td align="center">tx.sender</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing the subaccount's 32 bytes (address + subaccount name) of the tx sender.</td></tr><tr><td align="center">tx.liquidatee</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing the subaccount's 32 bytes (address + subaccount name) of the subaccount being liquidated.</td></tr><tr><td align="center">tx.productId</td><td align="center">number</td><td align="center">Yes</td><td><p>Perp Liquidation:</p><ul><li>A valid perp product Id.</li></ul><p>Spot Liquidation:</p><ul><li>A valid spot product Id.</li></ul><p>Spread Liquidation:</p><ul><li>An encoded perp / spot product Ids, where the lower 16 bits represent the spot product and the higher 16 bits represent the perp product. <mark style="color:red;"><code>isEncodedSpread</code></mark> must be set to <mark style="color:red;"><code>true</code></mark> for spread liquidation. See <a href="#signing">Signing</a> section for more details.</li></ul></td></tr><tr><td align="center">tx.isEncodedSpread</td><td align="center">bool</td><td align="center">Yes</td><td>When set to <mark style="color:red;"><code>true</code></mark>, the <mark style="color:red;"><code>productId</code></mark> is expected to encode a perp and spot product Ids as follows: <mark style="color:red;"><code>(perp_id &#x3C;&#x3C; 16) | spot_id</code></mark></td></tr><tr><td align="center">tx.amount</td><td align="center">string</td><td align="center">Yes</td><td>The amount to liquidate multiplied by 1e18, sent as a string.</td></tr><tr><td align="center">tx.nonce</td><td align="center">string</td><td align="center">Yes</td><td>This is an incrementing nonce, can be obtained using the <a href="../queries/nonces">Nonces</a> query.</td></tr><tr><td align="center">signature</td><td align="center">string</td><td align="center">Yes</td><td>Signed transaction. See <a href="#signing">Signing</a> section for more details.</td></tr></tbody></table>
## Signing
{% hint style="info" %}
See more details and examples in our [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page.
{% endhint %}
The solidity typed data struct that needs to be signed is:
```solidity
struct LiquidateSubaccount {
bytes32 sender;
bytes32 liquidatee;
uint32 productId;
bool isEncodedSpread;
int128 amount;
uint64 nonce;
}
```
<mark style="color:red;">`sender`</mark>: a <mark style="color:red;">`bytes32`</mark> sent as a hex string; includes the address and the subaccount identifier.
<mark style="color:red;">`liquidatee`</mark>: a <mark style="color:red;">`bytes32`</mark> sent as a hex string; includes the address and the subaccount identifier.
<mark style="color:red;">`productId`</mark>: The product to liquidate as well as the liquidation mode.
* *Perp liquidation* ⇒ A valid <mark style="color:red;">`perp`</mark> product id is provided and <mark style="color:red;">`isEncodedSpread`</mark> is set to <mark style="color:red;">`false`</mark>.
* *Spot liquidation* ⇒ A valid <mark style="color:red;">`spot`</mark> product id is provided and <mark style="color:red;">`isEncodedSpread`</mark> is set to <mark style="color:red;">`false`</mark>
* *Spread Liquidation* => If there are perp and spot positions in different directions, liquidate both at the same time. Must be set to a 32 bits integer where the lower 16 bits represent the <mark style="color:red;">`spot`</mark> product and the higher 16 bits represent the <mark style="color:red;">`perp`</mark> product. <mark style="color:red;">`isEncodedSpread`</mark> must be set to <mark style="color:red;">`true`</mark>.
***Computing\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*&#x20;**<mark style="color:red;">**productId**</mark>**&#x20;\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*for Spread Liquidation***
```python
btc_spot = 1
btc_perp = 2
spread_product_id = (btc_perp << 16) | btc_spot
```
<mark style="color:red;">`isEncodedSpread`</mark>: indicates whether <mark style="color:red;">`productId`</mark> encodes both a <mark style="color:red;">`spot`</mark> and a <mark style="color:red;">`perp`</mark> product Id for spread liquidation.
<mark style="color:red;">`amount`</mark>: the amount to liquidate multiplied by 1e18, sent as a string. Can be positive or negative, depending on if the users balance is positive or negative.
<mark style="color:red;">`nonce`</mark>: the <mark style="color:red;">`tx_nonce`</mark>. This is an incrementing nonce, can be obtained using the [Nonces](https://docs.nado.xyz/developer-resources/api/gateway/queries/nonces) query.
{% hint style="warning" %}
**Note**: for signing you should always use the data type specified in the solidity struct which might be different from the type sent in the request e.g: <mark style="color:red;">`nonce`</mark> should be an <mark style="color:red;">`uint64`</mark> for **Signing** but should be sent as a <mark style="color:red;">`string`</mark> in the final payload.
{% endhint %}
## Response
#### Success
```json
{
"status": "success",
"signature": {signature},
"request_type": "execute_liquidate_subaccount"
}
```
#### Failure
```json
{
"status": "failure",
"signature": {signature},
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "execute_liquidate_subaccount"
}
```
@@ -0,0 +1,111 @@
# Mint NLP
## Rate limits
* Wallet weight = <mark style="color:red;">`10`</mark> - allows 60 mints/min or 10 mints every 10 seconds per wallet.
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits).
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"mint_nlp": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"quoteAmount": "1000000000000000000",
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% tab title="REST" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/execute`</mark>
**Body**
```json
{
"mint_lp": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"productId": 1,
"amountBase": "1000000000000000000",
"quoteAmountLow": "10000000000000000000000",
"quoteAmountHigh": "20000000000000000000000",
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="205" align="center">Parameter</th><th width="94" align="center">Type</th><th width="112" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">tx</td><td align="center">object</td><td align="center">Yes</td><td>Mint NLP transaction object. See <a href="#signing">Signing</a> section for details on the transaction fields.</td></tr><tr><td align="center">tx.sender</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing the subaccount's 32 bytes (address + subaccount name) of the tx sender.</td></tr><tr><td align="center">tx.quoteAmount</td><td align="center">string</td><td align="center">Yes</td><td>This amount of quote to be consumed by minting NLPs multiplied by 1e18, sent as a string.</td></tr><tr><td align="center">tx.nonce</td><td align="center">string</td><td align="center">Yes</td><td>This is an incrementing nonce, can be obtained using the <a href="../queries/nonces">Nonces</a> query.</td></tr><tr><td align="center">signature</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing hash of the <strong>signed</strong> transaction. See <a href="#signing">Signing</a> section for more details.</td></tr><tr><td align="center">spot_leverage</td><td align="center">boolean</td><td align="center">No</td><td>Indicates whether leverage should be used; when set to <mark style="color:red;"><code>false</code></mark> , the mint fails if the transaction causes a borrow on the subaccount. Defaults to <mark style="color:red;"><code>true</code></mark>.</td></tr></tbody></table>
## Signing
{% hint style="info" %}
See more details and examples in our [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page.
{% endhint %}
The solidity typed data struct that needs to be signed is:
```solidity
struct MintNlp {
bytes32 sender;
uint128 quoteAmount;
uint64 nonce;
}
```
<mark style="color:red;">`sender`</mark>: a <mark style="color:red;">`bytes32`</mark> sent as a hex string; includes the address and the subaccount identifier.
<mark style="color:red;">`quoteAmount`</mark>: this is the amount of quote to be consumed by minting NLPs, sent as a string. This must be positive and must be specified with 18 decimals.
<mark style="color:red;">`nonce`</mark>: the <mark style="color:red;">`tx_nonce`</mark>. This is an incrementing nonce, can be obtained using the [Nonces](https://docs.nado.xyz/developer-resources/api/gateway/queries/nonces) query.
{% hint style="warning" %}
**Note**: for signing you should always use the data type specified in the solidity struct which might be different from the type sent in the request e.g: <mark style="color:red;">`nonce`</mark> should be an <mark style="color:red;">`uint64`</mark> for **Signing** but should be sent as a <mark style="color:red;">`string`</mark> in the final payload.
{% endhint %}
## Response
#### Success
```json
{
"status": "success",
"signature": {signature},
"request_type": "execute_mint_nlp"
}
```
#### Failure
```json
{
"status": "failure",
"signature": {signature},
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "execute_min_nlp"
}
```
@@ -0,0 +1,185 @@
# Place Order
## Rate limits
* With spot leverage: 600 orders/minute or 10 orders/sec per wallet. (**weight=1**)
* Without spot leverage: 30 orders/min or 5 orders every 10 seconds per wallet. (**weight = 20**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits).
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"place_order": {
"product_id": 1,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "1000000000000000000",
"amount": "1000000000000000000",
"expiration": "4294967295",
"nonce": "1757062078359666688",
"appendix": "1"
},
"signature": "0x",
"id": 100
}
}
```
{% endtab %}
{% tab title="REST" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/execute`</mark>
**Body**
```json
{
"place_order": {
"product_id": 1,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "1000000000000000000",
"amount": "1000000000000000000",
"expiration": "4294967295",
"nonce": "1757062078359666688"
},
"signature": "0x",
"id": 100
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="180" align="center">Parameter</th><th width="94" align="center">Type</th><th width="112" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of spot / perp product for which to place order. Use <a href="../queries/all-products">All products</a> query to retrieve all valid product ids.</td></tr><tr><td align="center">order</td><td align="center">object</td><td align="center">Yes</td><td>Order object, see <a href="#signing">Signing</a> section for details on each order field.</td></tr><tr><td align="center">order.sender</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing the subaccount's 32 bytes (address + subaccount name) of the tx sender.</td></tr><tr><td align="center">order.priceX18</td><td align="center">string</td><td align="center">Yes</td><td>Price of the order multiplied by 1e18.</td></tr><tr><td align="center">order.amount</td><td align="center">string</td><td align="center">Yes</td><td>Quantity of the order multiplied by 1e18.</td></tr><tr><td align="center">order.expiration</td><td align="center">string</td><td align="center">Yes</td><td>A time after which the order should automatically be cancelled, as a timestamp in seconds after the unix epoch.</td></tr><tr><td align="center">order.nonce</td><td align="center">string</td><td align="center">Yes</td><td>Used to differentiate between the same order multiple times. See <a href="#signing">Signing</a> section for more details.</td></tr><tr><td align="center">order.appendix</td><td align="center">string</td><td align="center">Yes</td><td>Encodes various order properties including execution types, isolated positions, TWAP parameters, and trigger types. See order appendix section for more details.</td></tr><tr><td align="center">signature</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing hash of the <strong>signed</strong> order. See <a href="#signing">Signing</a> section for more details.</td></tr><tr><td align="center">digest</td><td align="center">string</td><td align="center">No</td><td>Hex string representing a hash of the order.</td></tr><tr><td align="center">spot_leverage</td><td align="center">boolean</td><td align="center">No</td><td>Indicates whether leverage should be used; when set to <mark style="color:red;"><code>false</code></mark> , placing the order fails if the transaction causes a borrow on the subaccount. Defaults to <mark style="color:red;"><code>true</code></mark>.</td></tr><tr><td align="center">id</td><td align="center">number</td><td align="center">No</td><td>An optional id that when provided is returned as part of <mark style="color:red;"><code>Fill</code></mark> and <mark style="color:red;"><code>OrderUpdate</code></mark> stream events. See <a href="../../subscriptions">subscriptions</a> for more details.<br><br><strong>NOTE</strong>: The client <mark style="color:red;"><code>id</code></mark> should not be used to differentiate orders, as it is not included in the order hash (i.e., the order <mark style="color:red;"><code>digest</code></mark>). Instead, use the last 20 bits of the order nonce to distinguish between similar orders. For more details, refer to <a href="#order-nonce">Order Nonce</a>.</td></tr></tbody></table>
## Signing
{% hint style="info" %}
See more details and examples in our [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page.
{% endhint %}
The solidity typed data struct that needs to be signed is:
```solidity
struct Order {
bytes32 sender;
int128 priceX18;
int128 amount;
uint64 expiration;
uint64 nonce;
uint128 appendix;
}
```
<mark style="color:red;">`sender`</mark>: a <mark style="color:red;">`bytes32`</mark> sent as a hex string; includes the address and the subaccount identifier
<mark style="color:red;">`priceX18`</mark>: an <mark style="color:red;">`int128`</mark> representing the price of the order multiplied by 1e18, sent as a string. For example, a price of 1 USDT0 would be sent as <mark style="color:red;">`"1000000000000000000"`</mark>
<mark style="color:red;">`amount`</mark>: an <mark style="color:red;">`int128`</mark> representing the quantity of the order multiplied by 1e18, sent as a string. A positive amount means that this is a buy order, and a negative amount means this is a sell order.
<mark style="color:red;">`expiration`</mark>: a time after which the order should automatically be cancelled, as a timestamp in seconds after the unix epoch, sent as a string.
### Order Nonce
<mark style="color:red;">`nonce`</mark>: used to differentiate between the same order multiple times, and a user trying to place an order with the same parameters twice. Sent as a string. Encodes two bit of information:
* Most significant <mark style="color:red;">`44`</mark> bits encoding the time in milliseconds (a `recv_time`) after which the order should be ignored by the matching engine
* Least significant <mark style="color:red;">`20`</mark> bits are a random integer used to avoid hash collisions
For example, to place an order with a random integer of <mark style="color:red;">`1000`</mark>, and a discard time 50 ms from now, we would send a nonce of <mark style="color:red;">`((timestamp_ms() + 50) << 20) + 1000)`</mark>
```python
import time
unix_epoch_ms = int(time.time()) * 1000
nonce = ((unix_epoch_ms + 50) << 20) + 1000
```
{% hint style="warning" %}
**Note**: for signing you should always use the data type specified in the solidity struct which might be different from the type sent in the request e.g: <mark style="color:red;">`nonce`</mark> should be an <mark style="color:red;">`uint64`</mark> for **Signing** but should be sent as a <mark style="color:red;">`string`</mark> in the final payload.
{% endhint %}
## Order Appendix
{% hint style="info" %}
See more details and examples in our [Order Appendix](https://docs.nado.xyz/developer-resources/api/order-appendix) page.
{% endhint %}
<mark style="color:red;">`appendix`</mark>: is a 128-bit integer that encodes extra order parameters like execution type, isolated margin, and trigger type.
### Bit Layout
```json
| value | reserved | trigger | reduce only | order type | isolated | version |
| 64 bits | 50 bits | 2 bits | 1 bit | 2 bits | 1 bit | 8 bits |
| 127..64 | 63..14 | 13..12 | 11 | 10..9 | 8 | 7..0 |
```
**Fields (from LSB to MSB):**
* <mark style="color:red;">**Version (8 bits, 07)**</mark> protocol version (currently `1`)
* <mark style="color:red;">**Isolated (1 bit, 8)**</mark> whether the order uses isolated margin
* <mark style="color:red;">**Order Type (2 bits, 910)**</mark> 0 = DEFAULT, 1 = IOC, 2 = FOK, 3 = POST\_ONLY
* <mark style="color:red;">`0`</mark> - <mark style="color:red;">`DEFAULT`</mark>: Standard limit order behavior
* <mark style="color:red;">`1`</mark> - <mark style="color:red;">`IOC (Immediate or Cancel)`</mark>: Execute immediately, cancel unfilled portion
* <mark style="color:red;">`2`</mark> - <mark style="color:red;">`FOK (Fill or Kill)`</mark>: Execute completely or cancel entire order
* <mark style="color:red;">`3`</mark> - <mark style="color:red;">`POST_ONLY`</mark>: Only add liquidity, reject if would take liquidity
* <mark style="color:red;">**Reduce Only (1 bit, 11)**</mark> only decreases an existing position.
* <mark style="color:red;">**Trigger Type (2 bits, 1213)**</mark> 0 = NONE, 1 = PRICE, 2 = TWAP, 3 = TWAP\_CUSTOM\_AMOUNTS
* <mark style="color:red;">**Reserved (50 bits, 1463)**</mark> future use
* <mark style="color:red;">**Value (64 bits, 64127)**</mark> extra data (isolated margin or TWAP parameters)
* if <mark style="color:red;">`trigger`</mark> is <mark style="color:red;">`2`</mark> or <mark style="color:red;">`3`</mark> ⇒ <mark style="color:red;">`value`</mark> represents how many times the TWAP order will execute and the maximum acceptable slippage. Encoded as:
```json
| times | slippage_x6 |
| 32 bits| 32 bits |
```
* <mark style="color:red;">`times`</mark> : Number of TWAP executions.
* <mark style="color:red;">`slippage_x6`</mark>: Maximum slippage × 1,000,000 (6 decimal precision).
* if <mark style="color:red;">`isolated`</mark> is <mark style="color:red;">`1`</mark> ⇒ <mark style="color:red;">`value`</mark> represents <mark style="color:red;">`margin_x6`</mark> (in x6 precision, 6 decimals) to be transferred to the isolated subaccount when the order gets its first match.
* otherwise, <mark style="color:red;">`value`</mark> is <mark style="color:red;">`0`</mark>.
## Response
#### Success
```json
{
"status": "success",
"signature": {signature},
"data": {
"digest": {order digest}
},
"request_type": "execute_place_order"
"id": 100
}
```
#### Failure
```json
{
"status": "failure",
"signature": {signature},
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "execute_place_order"
}
```
@@ -0,0 +1,193 @@
# Place Orders
Place multiple orders in a single request. This is more efficient than placing orders individually and allows for better control over batch order placement.
## Rate limits
* With spot leverage: 600 orders/minute or 10 orders/sec per wallet. (**weight=1 per order**)
* Without spot leverage: 30 orders/min or 5 orders every 10 seconds per wallet. (**weight = 20 per order**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits).
{% endhint %}
{% hint style="warning" %}
**Note**: There is a 50ms processing penalty for each `place_orders` request to ensure fair sequencing and prevent gaming of the matching engine.
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"place_orders": {
"orders": [
{
"product_id": 2,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "100000000000000000000000",
"amount": "1000000000000000000",
"expiration": "4294967295",
"nonce": "1757062078359666688",
"appendix": "1"
},
"signature": "0x...",
"id": 100
},
{
"product_id": 3,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "3800000000000000000000",
"amount": "2000000000000000000",
"expiration": "4294967295",
"nonce": "1757062078359666689",
"appendix": "1"
},
"signature": "0x...",
"id": 101
}
],
"stop_on_failure": false
}
}
```
{% endtab %}
{% tab title="REST" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/execute`</mark>
**Body**
```json
{
"place_orders": {
"orders": [
{
"product_id": 2,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "100000000000000000000000",
"amount": "1000000000000000000",
"expiration": "4294967295",
"nonce": "1757062078359666688",
"appendix": "1"
},
"signature": "0x...",
"id": 100
},
{
"product_id": 3,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "3800000000000000000000",
"amount": "2000000000000000000",
"expiration": "4294967295",
"nonce": "1757062078359666689",
"appendix": "1"
},
"signature": "0x...",
"id": 101
}
],
"stop_on_failure": false
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="200" align="center">Parameter</th><th width="94" align="center">Type</th><th width="112" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">orders</td><td align="center">array</td><td align="center">Yes</td><td>Array of order objects to place. Each order follows the same structure as <a href="place-order">Place Order</a>.</td></tr><tr><td align="center">orders[].product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of spot / perp product for which to place order.</td></tr><tr><td align="center">orders[].order</td><td align="center">object</td><td align="center">Yes</td><td>Order object (same structure as single order placement).</td></tr><tr><td align="center">orders[].signature</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing hash of the <strong>signed</strong> order.</td></tr><tr><td align="center">orders[].digest</td><td align="center">string</td><td align="center">No</td><td>Hex string representing a hash of the order.</td></tr><tr><td align="center">orders[].spot_leverage</td><td align="center">boolean</td><td align="center">No</td><td>Indicates whether leverage should be used for this order. Defaults to <mark style="color:red;"><code>true</code></mark>.</td></tr><tr><td align="center">orders[].id</td><td align="center">number</td><td align="center">No</td><td>An optional id returned in <mark style="color:red;"><code>Fill</code></mark> and <mark style="color:red;"><code>OrderUpdate</code></mark> events.</td></tr><tr><td align="center">stop_on_failure</td><td align="center">boolean</td><td align="center">No</td><td>If <mark style="color:red;"><code>true</code></mark>, stops processing remaining orders when the first order fails. Already successfully placed orders are NOT cancelled. Defaults to <mark style="color:red;"><code>false</code></mark>.</td></tr></tbody></table>
## Response
```json
{
"status": "success",
"data": {
"place_orders": [
{
"digest": "0x1234...",
"error": null
},
{
"digest": null,
"error": "insufficient margin"
}
]
}
}
```
### Response Fields
<table><thead><tr><th width="200">Field</th><th>Description</th></tr></thead><tbody><tr><td>digest</td><td>Order digest (32-byte hash) if successfully placed, <mark style="color:red;"><code>null</code></mark> if failed.</td></tr><tr><td>error</td><td>Error message if order failed, <mark style="color:red;"><code>null</code></mark> if successful.</td></tr></tbody></table>
## Behavior
* **Partial Success**: By default, orders are processed independently. Some orders may succeed while others fail.
* **Stop on Failure**: Set `stop_on_failure: true` to stop processing remaining orders when the first order fails. Already successfully placed orders remain on the book.
* **Order Signing**: Each order must be individually signed using EIP712 (see [Signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) for details).
* **Rate Limits**: Rate limit weight is calculated per order (1 per order with leverage, 20 per order without).
## Use Cases
* **Spread Trading**: Place both legs of a spread trade in one request
* **Multiple Markets**: Open positions across multiple products in one request
## Example
Placing BTC and ETH perp orders simultaneously:
```javascript
const placeOrdersParams = {
orders: [
{
product_id: 2, // BTC-PERP
order: {
sender: subaccount,
priceX18: toX18(100000), // $100k
amount: toX18(0.1),
expiration: getExpiration(OrderType.DEFAULT),
nonce: genOrderNonce(),
appendix: buildAppendix()
},
signature: await signOrder(btcOrder),
id: 1
},
{
product_id: 3, // ETH-PERP
order: {
sender: subaccount,
priceX18: toX18(3800), // $3.8k
amount: toX18(1),
expiration: getExpiration(OrderType.DEFAULT),
nonce: genOrderNonce(),
appendix: buildAppendix()
},
signature: await signOrder(ethOrder),
id: 2
}
],
stop_on_failure: false
};
const response = await client.execute({ place_orders: placeOrdersParams });
```
## See Also
* [Place Order](https://docs.nado.xyz/developer-resources/api/gateway/executes/place-order) - Single order placement
* [Cancel And Place](https://docs.nado.xyz/developer-resources/api/gateway/executes/cancel-and-place) - Atomic cancel and place
* [Signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) - EIP712 order signing
@@ -0,0 +1,132 @@
# Transfer Quote
## Fees
Transfers between subaccounts incur a network fee:
* **Standard transfers**: 1 USDT0
* **Isolated subaccount transfers**: 0.1 USDT0 (when either sender or recipient is an isolated subaccount)
The fee is automatically deducted from the sender's balance.
## Rate limits
* 60 transfer quotes/min or 10 every 10 seconds per wallet. (**weight=10**)
* A max of 5 transfer quotes to new recipients (subaccounts) every 24hrs.
* **Note**: Transferring quote to a subaccount that doesn't exist, creates the subaccount.
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits).
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"transfer_quote": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"recipient": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743100000000000000",
"amount": "10000000000000000000",
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% tab title="REST" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/execute`</mark>
**Body**
```json
{
"transfer_quote": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"recipient": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743100000000000000",
"amount": "10000000000000000000",
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="154" align="center">Parameter</th><th width="94" align="center">Type</th><th width="112" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">tx</td><td align="center">object</td><td align="center">Yes</td><td>Transfer Quote transaction object. See <a href="#signing">Signing</a> section for details on the transaction fields.</td></tr><tr><td align="center">tx.sender</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing the subaccount's 32 bytes (address + subaccount name) of the tx sender.</td></tr><tr><td align="center">tx.recipient</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing the subaccount's 32 bytes (address + subaccount name) of the quote recipient.</td></tr><tr><td align="center">tx.amount</td><td align="center">string</td><td align="center">Yes</td><td>The amount of USDT0 to transfer, denominated in <code>x18</code>. Transfr amount must be <mark style="color:red;"><code>>= 5 USDT0</code></mark> . See <a href="#signing">Signing</a> section for more details.</td></tr><tr><td align="center">tx.nonce</td><td align="center">string</td><td align="center">Yes</td><td>This is an incrementing nonce, can be obtained using the <a href="../queries/nonces">Nonces</a> query.</td></tr><tr><td align="center">signature</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing hash of the <strong>signed</strong> transaction. See <a href="#signing">Signing</a> section for more details.</td></tr></tbody></table>
## Signing
{% hint style="info" %}
See more details and examples in our [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page.
{% endhint %}
The solidity typed data struct that needs to be signed is:
```solidity
struct TransferQuote {
bytes32 sender;
bytes32 recipient;
uint128 amount;
uint64 nonce;
}
```
<mark style="color:red;">`sender`</mark>: a <mark style="color:red;">`bytes32`</mark> sent as a hex string; includes the address and the subaccount identifier.
<mark style="color:red;">`recipient`</mark>: a <mark style="color:red;">`bytes32`</mark> sent as a hex string; includes the address and the subaccount identifier.
<mark style="color:red;">`amount`</mark>: the amount of quote to transfer, sent as an `x18` string.
{% hint style="warning" %}
**Notes:**
* If you are transferring <mark style="color:red;">`5 USDT0`</mark>, must specify <mark style="color:red;">`5000000000000000000`</mark> i.e 5 USDT0 \* 1e18.
* Transfer amount should be <mark style="color:red;">>= 5 USDT0.</mark>
{% endhint %}
<mark style="color:red;">`nonce`</mark>: the <mark style="color:red;">`tx_nonce`</mark>. This is an incrementing nonce, can be obtained using the [Nonces](https://docs.nado.xyz/developer-resources/api/gateway/queries/nonces) query.
{% hint style="warning" %}
**Note**: for signing you should always use the data type specified in the solidity struct which might be different from the type sent in the request e.g: <mark style="color:red;">`nonce`</mark> should be an <mark style="color:red;">`uint64`</mark> for **Signing** but should be sent as a <mark style="color:red;">`string`</mark> in the final payload.
{% endhint %}
## Response
#### Success
```json
{
"status": "success",
"signature": {signature},
"request_type": "execute_transfer_quote"
}
```
#### Failure
```json
{
"status": "failure",
"signature": {signature},
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "execute_transfer_quote"
}
```
@@ -0,0 +1,120 @@
# Withdraw Collateral
{% hint style="info" %}
**Note**: use the [max withdrawable](https://docs.nado.xyz/developer-resources/api/gateway/queries/max-withdrawable) query to determine the max amount you can withdraw for a given spot product.
{% endhint %}
## Rate limits
* With spot leverage: 60 withdrawals/min or 10 withdrawals every 10 seconds per wallet. (**weight = 10**)
* Without spot leverage: 30 withdrawals/min or 5 withdrawals every 10 seconds per wallet. (**weight=20**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits).
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"withdraw_collateral": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"productId": 1,
"amount": "1000000000000000000",
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% tab title="REST" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/execute`</mark>
**Body**
```json
{
"withdraw_collateral": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"productId": 1,
"amount": "1000000000000000000",
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="154" align="center">Parameter</th><th width="94" align="center">Type</th><th width="112" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">tx</td><td align="center">object</td><td align="center">Yes</td><td>Withdraw collateral transaction object. See <a href="#signing">Signing</a> section for details on the transaction fields.</td></tr><tr><td align="center">tx.sender</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing the subaccount's 32 bytes (address + subaccount name) of the tx sender.</td></tr><tr><td align="center">tx.productId</td><td align="center">number</td><td align="center">Yes</td><td>A spot product ID to withdraw from.</td></tr><tr><td align="center">tx.amount</td><td align="center">string</td><td align="center">Yes</td><td>The amount of the asset to withdraw, denominated in the base ERC20 token of the specified product e.g: USDT0 (product=0) has 6 decimals whereas wETH (product=3) has 18. See <a href="#signing">Signing</a> section for more details.</td></tr><tr><td align="center">tx.nonce</td><td align="center">string</td><td align="center">Yes</td><td>This is an incrementing nonce, can be obtained using the <a href="../queries/nonces">Nonces</a> query.</td></tr><tr><td align="center">signature</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing hash of the <strong>signed</strong> transaction. See <a href="#signing">Signing</a> section for more details.</td></tr><tr><td align="center">spot_leverage</td><td align="center">boolean</td><td align="center">No</td><td>Indicates whether leverage should be used; when set to <mark style="color:red;"><code>false</code></mark> , the withdrawal fails if the transaction causes a borrow on the subaccount. Defaults to <mark style="color:red;"><code>true</code></mark>.</td></tr></tbody></table>
## Signing
{% hint style="info" %}
See more details and examples in our [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page.
{% endhint %}
The solidity typed data struct that needs to be signed is:
```solidity
struct WithdrawCollateral {
bytes32 sender;
uint32 productId;
uint128 amount;
uint64 nonce;
}
```
<mark style="color:red;">`sender`</mark>: a <mark style="color:red;">`bytes32`</mark> sent as a hex string; includes the address and the subaccount identifier.
<mark style="color:red;">`productId`</mark>: a <mark style="color:red;">`uint32`</mark> that specifies the product youd like to withdraw collateral from; must be for a spot product.
<mark style="color:red;">`amount`</mark>: the amount of asset to withdraw, sent as a string. Note that this is different from the amounts provided in transactions that arent <mark style="color:red;">`depositCollateral`</mark>. This is the raw amount of the ERC20 token you want to receive, i.e. if USDT0 has 6 decimals and you want to withdraw 1 USDT0, specify 1e6; if wETH has 18 decimals and you want to withdraw 1 wETH, specify 1e18. Use [all products](https://docs.nado.xyz/developer-resources/api/gateway/queries/all-products) query to view the token address of the corresponding product which can be used to determine the correct decimals to use.
<mark style="color:red;">`nonce`</mark>: the <mark style="color:red;">`tx_nonce`</mark>. This is an incrementing nonce, can be obtained using the [Nonces](https://docs.nado.xyz/developer-resources/api/gateway/queries/nonces) query.
{% hint style="warning" %}
**Note**: for signing you should always use the data type specified in the solidity struct which might be different from the type sent in the request e.g: <mark style="color:red;">`nonce`</mark> should be an <mark style="color:red;">`uint64`</mark> for **Signing** but should be sent as a <mark style="color:red;">`string`</mark> in the final payload.
{% endhint %}
## Response
#### Success
```json
{
"status": "success",
"signature": {signature},
"request_type": "execute_withdraw_collateral"
}
```
#### Failure
```json
{
"status": "failure",
"signature": {signature},
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "execute_withdraw_collateral"
}
```
@@ -0,0 +1,28 @@
# Queries
All queries go through the following endpoint; the exact details of the query are specified by query params or `Websocket` messages.
* **Websocket**: <mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
* **REST**: <mark style="color:green;">`GET [GATEWAY_REST_ENDPOINT]/query`</mark> or <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
## Overview
### **Amounts and Prices**
In general, amounts come back normalized to 18 decimal places. Meaning that for a balance of 1 USDT0, regardless of the number of decimals USDT0 has on-chain, a value of 1e18 will be returned.
Prices are in <mark style="color:red;">`x18`</mark>, so if the price of one wBTC is $20,000, regardless of the number of decimals wBTC has on-chain, the price will be returned as <mark style="color:red;">`20,000 * 1e18`</mark>.
## API Response
All `queries` return in the format:
```json
{
"status": "success" | "failure",
"data"?: {data},
"error"?: "{error_msg}",
"error_code"?: {error_code},
"request_type": "{request_type}"
}
```
@@ -0,0 +1,155 @@
# All Products
## Rate limits
* 480 requests/min or 8 requests/sec per IP address. (**weight = 5**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "all_products"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=all_products`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "all_products"
}
```
{% endtab %}
{% endtabs %}
## Response
{% hint style="info" %}
**Note**:
* A product is some asset / position an account can take on.
* A market is a venue for a product against USDT0.
* All products have a market quoted against USDT0, except for product 0.
* Product 0 is the USDT0 asset itself.
* You can retrieve product symbols via [symbols](https://docs.nado.xyz/developer-resources/api/symbols "mention") query.Body
{% endhint %}
```json
{
"status": "success",
"data": {
"spot_products": [
{
"product_id": 0,
"oracle_price_x18": "1000000000000000000",
"risk": {
"long_weight_initial_x18": "1000000000000000000",
"short_weight_initial_x18": "1000000000000000000",
"long_weight_maintenance_x18": "1000000000000000000",
"short_weight_maintenance_x18": "1000000000000000000",
"price_x18": "1000000000000000000"
},
"config": {
"token": "0x5f65358d61a9a281ea3bb930d05889aca21e3f4f",
"interest_inflection_util_x18": "800000000000000000",
"interest_floor_x18": "10000000000000000",
"interest_small_cap_x18": "40000000000000000",
"interest_large_cap_x18": "1000000000000000000",
"withdraw_fee_x18": "1000000000000000000",
"min_deposit_rate_x18": "0"
},
"state": {
"cumulative_deposits_multiplier_x18": "1000000000025524653",
"cumulative_borrows_multiplier_x18": "1000347390837434279",
"total_deposits_normalized": "20001011744258817298755054194662",
"total_borrows_normalized": "1617724891363505323532211"
},
"book_info": {
"size_increment": "0",
"price_increment_x18": "0",
"min_size": "0",
"collected_fees": "0"
}
},
{
"product_id": 1,
"oracle_price_x18": "115575316424148798147115",
"risk": {
"long_weight_initial_x18": "900000000000000000",
"short_weight_initial_x18": "1100000000000000000",
"long_weight_maintenance_x18": "950000000000000000",
"short_weight_maintenance_x18": "1050000000000000000",
"price_x18": "115575316424148798147115"
},
"config": {
"token": "0xc57c1c64561a37ac9e8f9039cb6deab7539d99fc",
"interest_inflection_util_x18": "800000000000000000",
"interest_floor_x18": "10000000000000000",
"interest_small_cap_x18": "40000000000000000",
"interest_large_cap_x18": "1000000000000000000",
"withdraw_fee_x18": "40000000000000",
"min_deposit_rate_x18": "0"
},
"state": {
"cumulative_deposits_multiplier_x18": "1000000000000318713",
"cumulative_borrows_multiplier_x18": "1000347390679880473",
"total_deposits_normalized": "9000399823280682696107190850",
"total_borrows_normalized": "9580268570661550719"
},
"book_info": {
"size_increment": "1000000000000000",
"price_increment_x18": "1000000000000000000",
"min_size": "4000000000000000",
"collected_fees": "0"
}
}
],
"perp_products": [
{
"product_id": 2,
"oracle_price_x18": "115432187703236794231754",
"risk": {
"long_weight_initial_x18": "950000000000000000",
"short_weight_initial_x18": "1050000000000000000",
"long_weight_maintenance_x18": "970000000000000000",
"short_weight_maintenance_x18": "1030000000000000000",
"price_x18": "115432187703236794231754"
},
"state": {
"cumulative_funding_long_x18": "-394223711772447555304",
"cumulative_funding_short_x18": "-394223711772447555304",
"available_settle": "20092193239667417956947",
"open_interest": "113605000000000000000"
},
"book_info": {
"size_increment": "1000000000000000",
"price_increment_x18": "1000000000000000000",
"min_size": "4000000000000000",
"collected_fees": "0"
}
}
]
},
"request_type": "query_all_products"
}
```
@@ -0,0 +1,62 @@
# Contracts
## Rate limits
* 2400 requests/min or 40 requests/sec per IP address. (**weight = 1**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "contracts"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=contracts`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "contracts"
}
```
{% endtab %}
{% endtabs %}
## Response
```json
{
"status": "success",
"data": {
"chain_id": "763373",
"endpoint_addr": "0xf8963f7860af7de9b94893edb9a3b5c155e1fc0c"
},
"request_type": "query_contracts"
}
```
{% hint style="info" %}
**Note:**
* <mark style="color:red;">`endpoint_addr`</mark> is the address of the Nado endpoint contracts. Deposits are sent to the endpoint address; **this to used sign every request except&#x20;**<mark style="color:red;">**`PlaceOrder`**</mark>
{% endhint %}
@@ -0,0 +1,160 @@
# Edge All Products
## Rate limits
* 480 requests/min or 8 requests/sec per IP address. (**weight = 5**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "edge_all_products"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=edge_all_products`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "edge_all_products"
}
```
{% endtab %}
{% endtabs %}
## Response
{% hint style="info" %}
**Note**:
* A product is some asset / position an account can take on.
* A market is a venue for a product against USDT0.
* All products have a market quoted against USDT0, except for product 0.
* Product 0 is the USDT0 asset itself.
* You can retrieve product symbols via [symbols](https://docs.nado.xyz/developer-resources/api/symbols "mention") query.Body
* Returns a mapping of <mark style="color:orange;">`chain_id -> all_products`</mark>
{% endhint %}
```json
{
"status": "success",
"data": {
"edge_all_products": {
"763373": {
"spot_products": [
{
"product_id": 0,
"oracle_price_x18": "1000000000000000000",
"risk": {
"long_weight_initial_x18": "1000000000000000000",
"short_weight_initial_x18": "1000000000000000000",
"long_weight_maintenance_x18": "1000000000000000000",
"short_weight_maintenance_x18": "1000000000000000000",
"price_x18": "1000000000000000000"
},
"config": {
"token": "0x5f65358d61a9a281ea3bb930d05889aca21e3f4f",
"interest_inflection_util_x18": "800000000000000000",
"interest_floor_x18": "10000000000000000",
"interest_small_cap_x18": "40000000000000000",
"interest_large_cap_x18": "1000000000000000000",
"withdraw_fee_x18": "1000000000000000000",
"min_deposit_rate_x18": "0"
},
"state": {
"cumulative_deposits_multiplier_x18": "1000000000025524653",
"cumulative_borrows_multiplier_x18": "1000347390837434279",
"total_deposits_normalized": "20001011744258817298755054194662",
"total_borrows_normalized": "1617724891363505323532211"
},
"book_info": {
"size_increment": "0",
"price_increment_x18": "0",
"min_size": "0",
"collected_fees": "0"
}
},
{
"product_id": 1,
"oracle_price_x18": "115575316424148798147115",
"risk": {
"long_weight_initial_x18": "900000000000000000",
"short_weight_initial_x18": "1100000000000000000",
"long_weight_maintenance_x18": "950000000000000000",
"short_weight_maintenance_x18": "1050000000000000000",
"price_x18": "115575316424148798147115"
},
"config": {
"token": "0xc57c1c64561a37ac9e8f9039cb6deab7539d99fc",
"interest_inflection_util_x18": "800000000000000000",
"interest_floor_x18": "10000000000000000",
"interest_small_cap_x18": "40000000000000000",
"interest_large_cap_x18": "1000000000000000000",
"withdraw_fee_x18": "40000000000000",
"min_deposit_rate_x18": "0"
},
"state": {
"cumulative_deposits_multiplier_x18": "1000000000000318713",
"cumulative_borrows_multiplier_x18": "1000347390679880473",
"total_deposits_normalized": "9000399823280682696107190850",
"total_borrows_normalized": "9580268570661550719"
},
"book_info": {
"size_increment": "1000000000000000",
"price_increment_x18": "1000000000000000000",
"min_size": "4000000000000000",
"collected_fees": "0"
}
}
],
"perp_products": [
{
"product_id": 2,
"oracle_price_x18": "115432187703236794231754",
"risk": {
"long_weight_initial_x18": "950000000000000000",
"short_weight_initial_x18": "1050000000000000000",
"long_weight_maintenance_x18": "970000000000000000",
"short_weight_maintenance_x18": "1030000000000000000",
"price_x18": "115432187703236794231754"
},
"state": {
"cumulative_funding_long_x18": "-394223711772447555304",
"cumulative_funding_short_x18": "-394223711772447555304",
"available_settle": "20092193239667417956947",
"open_interest": "113605000000000000000"
},
"book_info": {
"size_increment": "1000000000000000",
"price_increment_x18": "1000000000000000000",
"min_size": "4000000000000000",
"collected_fees": "0"
}
}
]
}
}
},
"request_type": "query_edge_all_products"
}
```
@@ -0,0 +1,93 @@
# Fee Rates
## Rate limits
* 1200 requests/min or 20 requests/sec per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "fee_rates",
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=fee_rates&sender={sender}`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Message**
```json
{
"type": "fee_rates",
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000"
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="140" align="center">Parameter</th><th width="97" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">sender</td><td align="center">string</td><td align="center">Yes</td><td>A <mark style="color:red;"><code>bytes32</code></mark> sent as a hex string; includes the address and the subaccount identifier.</td></tr></tbody></table>
## Response
```json
{
"status": "success",
"data": {
"taker_fee_rates_x18": [
"0",
"300000000000000",
"200000000000000",
"300000000000000",
"200000000000000"
],
"maker_fee_rates_x18": [
"0",
"0",
"0",
"0",
"0"
],
"liquidation_sequencer_fee": "250000000000000000",
"health_check_sequencer_fee": "100000000000000000",
"taker_sequencer_fee": "25000000000000000",
"withdraw_sequencer_fees": [
"10000000000000000",
"40000000000000",
"0",
"600000000000000",
"0"
]
},
"request_type": "query_fee_rates",
}
```
{% hint style="info" %}
* <mark style="color:red;">`taker_fee_rates_x18`</mark>: taker fee associated with a given product indexed by `product_id`. **Note**: this fee represents the basis point (BPS) on a taker order in <mark style="color:red;">`x18`</mark>.
* <mark style="color:red;">`maker_fee_rates_x18`</mark>: maker fee associated with a given produced indexed by <mark style="color:red;">`product_id`</mark>`.`
* <mark style="color:red;">`withdraw_sequencer_fees`</mark>: withdraw fees associated with a given product indexed by <mark style="color:red;">`product_id`</mark>. **Note**: this fee represents a fixed amount of product to be deducted as fee in <mark style="color:red;">`x18`</mark>.
{% endhint %}
See our [fees](https://github.com/nadohq/nado-docs/blob/main/docs/basics/fees.md) page for details about current fee rates.
@@ -0,0 +1,69 @@
# Health Groups
{% hint style="info" %}
**Note**: a health group is a perp and spot product whose health is calculated together (e.g. BTC and BTC-PERP).
{% endhint %}
## Rate limits
* 1200 requests/min or 20 requests/sec per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "health_groups"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=health_groups`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Message**
```json
{
"type": "health_groups"
}
```
{% endtab %}
{% endtabs %}
## Response
```json
{
"status": "success",
"data": {
"health_groups": [
[
1,
2
]
]
},
"request_type": "query_health_groups"
}
```
{% hint style="info" %}
* <mark style="color:red;">`health_groups`</mark>: list of all available health groups. **Note**: <mark style="color:red;">`health_groups[i]`</mark> is the spot / perp product pair of health group <mark style="color:red;">`i`</mark> where <mark style="color:red;">`health_groups[i][0]`</mark> is the spot <mark style="color:red;">`product_id`</mark> and <mark style="color:red;">`health_groups[i][1]`</mark> is the perp <mark style="color:red;">`product_id`</mark>. Additionally, it is possible for a health group to only have either a spot or perp product, in which case, the product that doesnt exist is set to <mark style="color:red;">`0`</mark>.
{% endhint %}
@@ -0,0 +1,55 @@
# Insurance
## Rate limits
* 1200 requests/min or 20 requests/sec per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "insurance"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=insurance`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Message**
```json
{
"type": "insurance"
}
```
{% endtab %}
{% endtabs %}
## Response
```json
{
"status": "success",
"data": {
"insurance": "552843342443351553629462"
},
"request_type": "query_insurance"
}
```
@@ -0,0 +1,171 @@
# Isolated Positions
## Rate limits
* 240 requests/min or 40 requests every 10 seconds per IP address. (**weight = 10**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "isolated_positions",
"subaccount": "0xeae27ae6412147ed6d5692fd91709dad6dbfc34264656661756c740000000000"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=isolated_positions&subaccount={subaccount}`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Message**
```json
{
"type": "isolated_positions",
"subaccount": "0xeae27ae6412147ed6d5692fd91709dad6dbfc34264656661756c740000000000"
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="140" align="center">Parameter</th><th width="100" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">subaccount</td><td align="center">string</td><td align="center">Yes</td><td>A <mark style="color:red;"><code>bytes32</code></mark> sent as a hex string; includes the address and the subaccount identifier. See <a href="../../executes#sender-field-structure">sender field structure</a> for details.</td></tr></tbody></table>
## Response
{% hint style="info" %}
**Note**:
* <mark style="color:red;">`isolated_positions[i].subaccount`</mark>: is the isolated subaccount for the base product.
* <mark style="color:red;">`healths`</mark>:
* <mark style="color:red;">`healths[0]`</mark>: info about your initial health, which is weighted by `long_weight_initial_x18` and `short_weight_initial_x18.`
* <mark style="color:red;">`healths[1]`</mark>: info about your maintenance health, which is weighted by `long_weight_maintenance_x18` and `short_weight_maintenance_x18.`
* <mark style="color:red;">`healths[2]`</mark>: info about your unweighted health.
{% endhint %}
```json
{
"status": "success",
"data": {
"isolated_positions": [
{
"subaccount": "0xeae27ae6412147ed6d5692fd91709dad6dbfc34200000000000000280269736f",
"quote_balance": {
"product_id": 0,
"balance": {
"amount": "200044412311089295472"
}
},
"base_balance": {
"product_id": 40,
"balance": {
"amount": "1720000000000000000000",
"v_quote_balance": "-800854578334374649165",
"last_cumulative_funding_x18": "85496772388082947"
}
},
"quote_product": {
"product_id": 0,
"oracle_price_x18": "1000000000000000000",
"risk": {
"long_weight_initial_x18": "1000000000000000000",
"short_weight_initial_x18": "1000000000000000000",
"long_weight_maintenance_x18": "1000000000000000000",
"short_weight_maintenance_x18": "1000000000000000000",
"price_x18": "1000000000000000000"
},
"config": {
"token": "0x5f65358d61a9a281ea3bb930d05889aca21e3f4f",
"interest_inflection_util_x18": "800000000000000000",
"interest_floor_x18": "10000000000000000",
"interest_small_cap_x18": "40000000000000000",
"interest_large_cap_x18": "1000000000000000000",
"withdraw_fee_x18": "1000000000000000000",
"min_deposit_rate_x18": "0"
},
"state": {
"cumulative_deposits_multiplier_x18": "1000000000025524653",
"cumulative_borrows_multiplier_x18": "1000347390837434279",
"total_deposits_normalized": "20001011744258817298755054194662",
"total_borrows_normalized": "1617724891363505323532211"
},
"book_info": {
"size_increment": "0",
"price_increment_x18": "0",
"min_size": "0",
"collected_fees": "0"
}
},
"base_product": {
"product_id": 2,
"oracle_price_x18": "115596528090565357611177",
"risk": {
"long_weight_initial_x18": "950000000000000000",
"short_weight_initial_x18": "1050000000000000000",
"long_weight_maintenance_x18": "970000000000000000",
"short_weight_maintenance_x18": "1030000000000000000",
"price_x18": "115596528090565357611177"
},
"state": {
"cumulative_funding_long_x18": "-394223711772447555304",
"cumulative_funding_short_x18": "-394223711772447555304",
"available_settle": "20092193239667417956947",
"open_interest": "113605000000000000000"
},
"book_info": {
"size_increment": "1000000000000000",
"price_increment_x18": "1000000000000000000",
"min_size": "4000000000000000",
"collected_fees": "0"
}
},
"quote_healths": [
"200044412311089295472",
"200044412311089295472",
"200044412311089295472"
],
"base_healths": [
"-109839746873700492625",
"-71450034014774150595",
"-33060321155847808565"
],
"healths": [
{
"assets": "200044412311089295472",
"liabilities": "109839746873700492625",
"health": "90204665437388802847"
},
{
"assets": "200044412311089295472",
"liabilities": "71450034014774150595",
"health": "128594378296315144877"
},
{
"assets": "200044412311089295472",
"liabilities": "33060321155847808565",
"health": "166984091155241486907"
}
]
}
]
},
"request_type": "query_isolated_positions"
}
```
@@ -0,0 +1,63 @@
# Linked Signer
## Rate limits
* 480 requests/min or 8 requests/sec per IP address. (**weight = 5**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "linked_signer",
"subaccount": "0x9b9989a4E0b260B84a5f367d636298a8bfFb7a9b42544353504f540000000000"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=linked_signer&subaccount=0x9b9989a4E0b260B84a5f367d636298a8bfFb7a9b42544353504f540000000000`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Message**
```json
{
"type": "linked_signer",
"subaccount": "0x9b9989a4E0b260B84a5f367d636298a8bfFb7a9b42544353504f540000000000"
}
```
{% endtab %}
{% endtabs %}
## Response
```json
{
"status": "success",
"data": {
"linked_signer": "0x0000000000000000000000000000000000000000"
},
"request_type": "query_linked_signer",
}
```
{% hint style="info" %}
**Notes**:
* <mark style="color:red;">`linked_signer`</mark>: the current linked signer address (20 bytes) associated to the provided `subaccount`. It returns the zero address when no signer is linked.
{% endhint %}
@@ -0,0 +1,91 @@
# Market Liquidity
## Rate limits
* 2400 requests/min or 40 requests/sec per IP address. (**weight = 1**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "market_liquidity",
"product_id": 1,
"depth": 10
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=market_liquidity&product_id={product_id}&depth={depth}`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "market_liquidity",
"product_id": 1,
"depth": 10
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="140" align="center">Parameter</th><th width="97" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of spot / perp product for which to retrieve market liquidity.</td></tr><tr><td align="center">depth</td><td align="center">number</td><td align="center">Yes</td><td>Number of price levels to retrieve. (<mark style="color:red;"><code>max: 100</code></mark>)</td></tr></tbody></table>
## Response
```json
{
"status": "success",
"data": {
"bids": [
[
"30234000000000000000000",
"663000000000000000"
],
[
"30170000000000000000000",
"24623000000000000000"
]
],
"asks": [
[
"30245000000000000000000",
"664000000000000000"
],
[
"30252000000000000000000",
"4646000000000000000"
]
],
"timestamp": "1681850046966693400",
"product_id": 1
},
"request_type": "query_market_liquidity"
}
```
{% hint style="info" %}
**Note:**
* Each entry inside bids and asks is an array of price and size respectively. **Note**: that price is represented using fixed point, so it is <mark style="color:red;">`1e18`</mark> times greater than the decimal price.
* <mark style="color:red;">`timestamp`</mark> is in nanoseconds.
{% endhint %}
@@ -0,0 +1,131 @@
# Market Prices
## Rate limits
* 2400 requests/min or 40 requests/sec per IP address. (**weight = 1**) or length of <mark style="color:red;">`product_ids`</mark> for [multi-product markets](#multiple-products) query.
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Single Product
### Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "market_price",
"product_id": 1
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=market_price&product_id={product_id}`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "market_price",
"product_id": 1
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="140" align="center">Parameter</th><th width="97" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of spot / perp product for which to retrieve market price data.</td></tr></tbody></table>
### Response
```json
{
"status": "success",
"data": {
"product_id": 1,
"bid_x18": "24224000000000000000000",
"ask_x18": "24243000000000000000000"
},
"request_type": "query_market_price",
}
```
{% hint style="info" %}
**Note**: that price is represented using fixed point, so it is <mark style="color:red;">`1e18`</mark> times greater than the decimal price.
{% endhint %}
## Multiple Products
### Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [CORE_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "market_prices",
"product_ids": [1, 2]
}
```
{% endtab %}
{% tab title="REST" %} <mark style="color:orange;">`POST /query`</mark>
**Body**
```json
{
"type": "market_prices",
"product_ids": [1, 2]
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="140" align="center">Parameter</th><th width="118" align="center">Type</th><th width="135.125" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">Yes</td><td>List of spot / perp products for which to retrieve market price data.</td></tr></tbody></table>
### Response
```json
{
"status": "success",
"data": {
"market_prices": [
{
"product_id": 1,
"bid_x18": "31315000000000000000000",
"ask_x18": "31326000000000000000000"
},
{
"product_id": 2,
"bid_x18": "31291000000000000000000",
"ask_x18": "31301000000000000000000"
},
]
},
"request_type": "query_market_prices"
}
```
@@ -0,0 +1,61 @@
# Max NLP Burnable
## Rate limits
* 120 requests/min or 20 requests every 10 seconds per IP address. (**weight = 20**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "max_nlp_burnable",
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=max_nlp_burnable&sender={sender}`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "max_nlp_burnable",
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000"
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="154" align="center">Parameter</th><th width="97" align="center">Type</th><th width="87" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">sender</td><td align="center">string</td><td align="center">Yes</td><td>A <mark style="color:red;"><code>bytes32</code></mark> sent as a hex string; includes the address and the subaccount identifier.</td></tr></tbody></table>
## Response
```json
{
"status": "success",
"data": {
"max_nlp_amount": "34250782930221490366619"
},
"request_type": "query_max_nlp_burnable",
}
```
@@ -0,0 +1,63 @@
# Max NLP Mintable
## Rate limits
* 120 requests/min or 20 requests every 10 seconds per IP address. (**weight = 20**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "max_nlp_mintable",
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"spot_leverage": "true"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=max_nlp_mintable&sender={sender}`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "max_nlp_mintable",
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"spot_leverage": "true"
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="154" align="center">Parameter</th><th width="97" align="center">Type</th><th width="87" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">sender</td><td align="center">string</td><td align="center">Yes</td><td>A <mark style="color:red;"><code>bytes32</code></mark> sent as a hex string; includes the address and the subaccount identifier.</td></tr><tr><td align="center">spot_leverage</td><td align="center">boolean</td><td align="center">No</td><td>Boolean sent as a string. indicates whether leverage should be used; when set to <mark style="color:red;"><code>false</code></mark> , returns the max amount of base LP mintable possible without borrow. Defaults to <mark style="color:red;"><code>true</code></mark></td></tr></tbody></table>
## Response
```json
{
"status": "success",
"data": {
"max_quote_amount": "34250782930221490366619"
},
"request_type": "query_max_nlp_mintable",
}
```
@@ -0,0 +1,73 @@
# Max Order Size
## Rate limits
* 480 requests/min or 80 requests every 10 seconds per IP address. (**weight = 5**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "max_order_size",
"product_id": 1,
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"price_x18": "23000000000000000000000",
"direction": "short",
"spot_leverage": "true",
"reduce_only": "false",
"isolated": "false"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=max_order_size&product_id={product_id}&sender={sender}&price_x18={price_x18}&direction={direction}`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "max_order_size",
"product_id": 1,
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"price_x18": "23000000000000000000000",
"direction": "short",
"spot_leverage": "true",
"reduce_only": "false",
"isolated": "false"
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="158" align="center">Parameter</th><th width="97" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">sender</td><td align="center">string</td><td align="center">Yes</td><td>A <mark style="color:red;"><code>bytes32</code></mark> sent as a hex string; includes the address and the subaccount identifier.</td></tr><tr><td align="center">product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of spot / perp product for which to retrieve max order size.</td></tr><tr><td align="center">price_x18</td><td align="center">string</td><td align="center">Yes</td><td>An <mark style="color:red;"><code>int128</code></mark> representing the price of the order multiplied by 1e18, sent as a string. For example, a price of 1 USDT0 would be sent as <code>"1000000000000000000"</code></td></tr><tr><td align="center">direction</td><td align="center">string</td><td align="center">Yes</td><td><mark style="color:red;"><code>long</code></mark> for max bid or <mark style="color:red;"><code>short</code></mark> for max ask.</td></tr><tr><td align="center">spot_leverage</td><td align="center">string</td><td align="center">No</td><td>Boolean sent as a string. Indicates whether leverage should be used; when set to <mark style="color:red;"><code>false</code></mark> , returns the max order possible without borrow. Defaults to <mark style="color:red;"><code>true</code></mark></td></tr><tr><td align="center">reduce_only</td><td align="center">string</td><td align="center">No</td><td>Boolean sent as a string. Indicates wether to retrieve the max order size to close / reduce a position. Defaults to <mark style="color:red;"><code>false</code></mark></td></tr><tr><td align="center">isolated</td><td align="center">string</td><td align="center">No</td><td>Boolean sent as a string. When set to <mark style="color:red;"><code>true</code></mark>, calculates max order size for an isolated margin position. Defaults to <mark style="color:red;"><code>false</code></mark>. See <a href="https://github.com/nadohq/nado-docs/blob/main/docs/basics/isolated-margin.md">Isolated Margin</a> to learn more.</td></tr></tbody></table>
## Response
```json
{
"status": "success",
"data": {
"max_order_size": "137847520631947079935"
},
"request_type": "query_max_order_size",
}
```
@@ -0,0 +1,65 @@
# Max Withdrawable
## Rate limits
* 480 requests/min or 80 requests every 10 seconds per IP address. (**weight = 5**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "max_withdrawable",
"product_id": 1,
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"spot_leverage": "true"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=max_withdrawable&product_id={product_id}&sender={sender}`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Message**
```json
{
"type": "max_withdrawable",
"product_id": 1,
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"spot_leverage": "true"
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="154" align="center">Parameter</th><th width="97" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">sender</td><td align="center">string</td><td align="center">Yes</td><td>A <mark style="color:red;"><code>bytes32</code></mark> sent as a hex string; includes the address and the subaccount identifier.</td></tr><tr><td align="center">product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of spot / perp product for which to retrieve max withdrawable amount.</td></tr><tr><td align="center">spot_leverage</td><td align="center">string</td><td align="center">No</td><td>Boolean sent as a string. Indicates whether leverage should be used; when set to <mark style="color:red;"><code>false</code></mark> , returns the max withdrawable amount possible without borrow. Defaults to <mark style="color:red;"><code>true</code></mark></td></tr></tbody></table>
## Response
```json
{
"status": "success",
"data": {
"max_withdrawable": "7968557932297078268650"
},
"request_type": "query_max_withdrawable",
}
```
@@ -0,0 +1,117 @@
# NLP Locked Balances
## Rate limits
* 120 requests/min or 20 requests every 10 seconds per IP address. (**weight = 20**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "nlp_locked_balances",
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=nlp_locked_balances&subaccount={subaccount}`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "nlp_locked_balances",
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000"
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="154" align="center">Parameter</th><th width="97" align="center">Type</th><th width="87" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">subaccount</td><td align="center">string</td><td align="center">Yes</td><td>A <mark style="color:red;"><code>bytes32</code></mark> sent as a hex string; includes the address and the subaccount identifier.</td></tr></tbody></table>
## Response
```json
{
"status": "success",
"data": {
"balance_locked": {
"product_id": 0,
"balance": {
"amount": "1000000000000000000000",
"last_cumulative_funding_x18": "0"
}
},
"balance_unlocked": {
"product_id": 0,
"balance": {
"amount": "500000000000000000000",
"last_cumulative_funding_x18": "0"
}
},
"locked_balances": [
{
"balance": {
"product_id": 0,
"balance": {
"amount": "250000000000000000000",
"last_cumulative_funding_x18": "0"
}
},
"unlocked_at": "1735689600"
},
{
"balance": {
"product_id": 0,
"balance": {
"amount": "750000000000000000000",
"last_cumulative_funding_x18": "0"
}
},
"unlocked_at": "1736035200"
}
]
},
"request_type": "query_nlp_locked_balances"
}
```
## Response Fields
### NLP Locked Balances Response
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>balance_locked</td><td>Total balance that is currently locked (SpotBalance object)</td></tr><tr><td>balance_unlocked</td><td>Total balance that is currently unlocked and available (SpotBalance object)</td></tr><tr><td>locked_balances</td><td>Array of individual locked balance entries with their unlock times</td></tr></tbody></table>
### Locked Balance Entry
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>balance</td><td>SpotBalance object containing the locked amount</td></tr><tr><td>unlocked_at</td><td>Unix epoch timestamp (in seconds) when this balance will unlock</td></tr></tbody></table>
### SpotBalance Object
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>product_id</td><td>The product ID (typically 0 for USDT0/quote asset)</td></tr><tr><td>balance</td><td>Balance details object</td></tr><tr><td>balance.amount</td><td>The balance amount in x18 format (string)</td></tr><tr><td>balance.last_cumulative_funding_x18</td><td>Last cumulative funding value in x18 format (string)</td></tr></tbody></table>
## Notes
* NLP positions have a 4-day lock period after minting before they can be burned (withdrawn)
* The `locked_balances` array shows individual lock entries, each with their own unlock timestamp
* `balance_locked` is the sum of all locked balances
* `balance_unlocked` represents balances that have passed their lock period and can be withdrawn
@@ -0,0 +1,89 @@
# NLP Pool Info
## Rate limits
* 120 requests/min or 20 requests every 10 seconds per IP address. (**weight = 20**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "nlp_pool_info"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=nlp_pool_info`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "nlp_pool_info"
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
This query does not require any parameters.
## Response
```json
{
"status": "success",
"data": {
"nlp_pools": [
{
"pool_id": 1,
"subaccount": "0x0000000000000000000000000000000000000000000000000000000000000002",
"owner": "0x1234567890123456789012345678901234567890",
"balance_weight_x18": "500000000000000000",
"subaccount_info": {
"subaccount": "0x0000000000000000000000000000000000000000000000000000000000000002",
"exists": true,
"health": {
"assets": "1000000000000000000000",
"liabilities": "500000000000000000000",
"initial_health": "250000000000000000000",
"maintenance_health": "100000000000000000000"
},
"spot_balances": [],
"perp_balances": []
},
"open_orders": []
}
]
},
"request_type": "query_nlp_pool_info"
}
```
## Response Fields
### NLP Pool Info
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>nlp_pools</td><td>Array of NLP pool objects</td></tr></tbody></table>
### NLP Pool Object
<table><thead><tr><th width="263">Field name</th><th>Description</th></tr></thead><tbody><tr><td>pool_id</td><td>Unique identifier for the pool</td></tr><tr><td>subaccount</td><td>The subaccount address associated with this pool (bytes32 hex string)</td></tr><tr><td>owner</td><td>The owner address of the pool (bytes20 hex string)</td></tr><tr><td>balance_weight_x18</td><td>Weight of this pool's balance in x18 format (string representation of u128)</td></tr><tr><td>subaccount_info</td><td>Complete subaccount information including health, balances, and positions</td></tr><tr><td>open_orders</td><td>Array of currently open orders for this pool</td></tr></tbody></table>
@@ -0,0 +1,66 @@
# Nonces
## Rate limits
* 1200 requests/min or 20 requests/sec per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "nonces",
"address": "0x0000000000000000000000000000000000000000"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GGET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=nonces&address={address}`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "nonces",
"address": "0x0000000000000000000000000000000000000000"
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="134" align="center">Parameter</th><th width="86" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">address</td><td align="center">string</td><td align="center">Yes</td><td>A <mark style="color:red;"><code>bytes20</code></mark> sent as a hex string representing the wallet address.</td></tr></tbody></table>
## Response
```json
{
"status":"success",
"data":{
"tx_nonce": 0,
"order_nonce": 1753048133299863552
},
"request_type": "query_nonces",
}
```
{% hint style="info" %}
**Note**: when doing any execute that is not <mark style="color:red;">`place_orders`</mark>, i.e. <mark style="color:red;">`withdraw_collateral`</mark>, <mark style="color:red;">`liquidate_subaccount`</mark>, you want to use <mark style="color:red;">`tx_nonce`</mark> as the nonce. <mark style="color:red;">`tx_nonce`</mark> increments by one each time a successful execute goes through. <mark style="color:red;">`order_nonce`</mark> is a historical artifact for the frontend, and simply returns the current timestamp in milliseconds plus 100000 multiplied by 2\*\*20.
{% endhint %}
@@ -0,0 +1,77 @@
# Order
## Rate limits
* 2400 requests/min or 40 requests/sec per IP address. (**weight = 1**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "order",
"product_id": 1,
"digest": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=order&product_id={product_id}&digest={digest}`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "order",
"product_id": 1,
"digest": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="140" align="center">Parameter</th><th width="97" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of spot / perp product for which to retrieve order.</td></tr><tr><td align="center">digest</td><td align="center">string</td><td align="center">Yes</td><td>Order digest to retrieve.</td></tr></tbody></table>
## Response
```json
{
"status": "success",
"data": {
"product_id": 1,
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"price_x18": "1000000000000000000",
"amount": "1000000000000000000",
"expiration": "2000000000",
"nonce": "1",
"unfilled_amount": "1000000000000000000",
"digest": "0x0000000000000000000000000000000000000000000000000000000000000000",
"placed_at": 1681951347,
"appendix": "1537",
"order_type": "ioc"
},
"request_type": "query_order",
}
```
{% hint style="info" %}
**Note**: that side of the order (buy/sell) is included in the sign of <mark style="color:red;">`amount`</mark> and <mark style="color:red;">`unfilled_amount`</mark> . They are positive if the order is a buy order, otherwise negative.
{% endhint %}
@@ -0,0 +1,162 @@
# Orders
## Rate limits
* 1200 requests/min or 20 requests/sec per IP address. (**weight = 2**) or 2 \* length of <mark style="color:red;">`product_ids`</mark> for [multi-product orders](#multiple-products) query.
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Single Product
### Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "subaccount_orders",
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"product_id": 1
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=subaccount_orders&sender={sender}&product_id={product_id}`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "subaccount_orders",
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"product_id": 1
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="140" align="center">Parameter</th><th width="97" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">sender</td><td align="center">string</td><td align="center">Yes</td><td>A <mark style="color:red;"><code>bytes32</code></mark> sent as a hex string; includes the address and the subaccount identifier.</td></tr><tr><td align="center">product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of spot / perp product for which to retrieve subaccount orders.</td></tr></tbody></table>
### Response
```json
{
"status": "success",
"data": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"product_id": 1,
"orders": [
{
"product_id": 1,
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"price_x18": "1000000000000000000",
"amount": "1000000000000000000",
"expiration": "2000000000",
"nonce": "1",
"unfilled_amount": "1000000000000000000",
"digest": "0x0000000000000000000000000000000000000000000000000000000000000000",
"placed_at": 1682437739,
"appendix": "1537",
"order_type": "ioc"
}
]
},
"request_type": "query_subaccount_orders"
}
```
{% hint style="info" %}
**Note**: that side of the order (buy/sell) is included in the sign of <mark style="color:red;">`amount`</mark> and <mark style="color:red;">`unfilled_amount`</mark> . They are positive if the order is a buy order, otherwise negative.
{% endhint %}
## Multiple Products
### Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [CORE_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "orders",
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"product_ids": [1, 2, 3]
}
```
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST /query`</mark>
**Body**
```json
{
"type": "orders",
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"product_ids": [1, 2, 3]
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="140" align="center">Parameter</th><th width="109" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">sender</td><td align="center">string</td><td align="center">Yes</td><td>A <mark style="color:red;"><code>bytes32</code></mark> sent as a hex string; includes the address and the subaccount identifier.</td></tr><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">Yes</td><td>List of spot / perp products for which to retrieve open orders.</td></tr></tbody></table>
### Response
```json
{
"status": "success",
"data": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"product_orders": [
{
"product_id": 1,
"orders": [
{
"product_id": 1,
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"price_x18": "1000000000000000000",
"amount": "1000000000000000000",
"expiration": "2000000000",
"nonce": "1",
"unfilled_amount": "1000000000000000000",
"digest": "0x0000000000000000000000000000000000000000000000000000000000000000",
"appendix": "1537",
"placed_at": 1682437739,
"order_type": "ioc"
}
]
},
{
"product_id": 2,
"orders": []
}
]
},
"request_type": "query_orders"
}
```
@@ -0,0 +1,60 @@
# Status
## Rate limits
* 2400 requests/min or 40 requests/sec per IP address. (**weight = 1**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "status"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=status`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "status"
}
```
{% endtab %}
{% endtabs %}
## Response
```json
{
"status": "success",
"data": "active",
"request_type": "query_status",
}
```
{% hint style="info" %}
The offchain sequencer could be in any of the following statuses:
* <mark style="color:red;">`active`</mark>: accepting incoming executes.
* <mark style="color:red;">`failed`</mark>: sequencer is in a failed state.
{% endhint %}
@@ -0,0 +1,353 @@
# Subaccount Info
## Rate limits
The rate limit weight varies based on the request parameters:
* **Basic query** (no `txns`): **weight = 2**
* 1200 requests/min or 200 requests every 10 seconds per IP address
* **With simulation** (`txns` provided): **weight = 10**
* 240 requests/min or 40 requests every 10 seconds per IP address
* **With simulation + pre\_state** (`txns` and `pre_state="true"`): **weight = 15**
* 160 requests/min or \~26 requests every 10 seconds per IP address
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "subaccount_info",
"subaccount": "0xeae27ae6412147ed6d5692fd91709dad6dbfc34264656661756c740000000000",
"txns": "[{\"apply_delta\":{\"product_id\":4,\"subaccount\":\"0xeae27ae6412147ed6d5692fd91709dad6dbfc34264656661756c740000000000\",\"amount_delta\":\"10790000000000000000\",\"v_quote_delta\":\"-35380410000000000000000\"}}]"
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=subaccount_info&subaccount={subaccount}&txns=[{"apply_delta":{"product_id":2,"subaccount":"0xeae27ae6412147ed6d5692fd91709dad6dbfc34264656661756c740000000000","amount_delta":"100000000000000000","v_quote_delta":"3033500000000000000000"}}]`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Message**
```json
{
"type": "subaccount_info",
"subaccount": "0xeae27ae6412147ed6d5692fd91709dad6dbfc34264656661756c740000000000",
"txns": "[{\"apply_delta\":{\"product_id\":4,\"subaccount\":\"0xeae27ae6412147ed6d5692fd91709dad6dbfc34264656661756c740000000000\",\"amount_delta\":\"10790000000000000000\",\"v_quote_delta\":\"-35380410000000000000000\"}}]"
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="140" align="center">Parameter</th><th width="100" align="center">Type</th><th width="104" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">subaccount</td><td align="center">string</td><td align="center">Yes</td><td>A <mark style="color:red;"><code>bytes32</code></mark> sent as a hex string; includes the address and the subaccount identifier. See <a href="../../executes#sender-field-structure">sender field structure</a> for details.</td></tr><tr><td align="center">txns</td><td align="center">string</td><td align="center">no</td><td>A list of transactions to get an estimated/simulated view. see more info below.</td></tr><tr><td align="center">pre_state</td><td align="center">string</td><td align="center">no</td><td>When <mark style="color:red;"><code>"true"</code></mark> and <mark style="color:red;"><code>txns</code></mark> are provided, returns the subaccount state before the transactions were applied in the <mark style="color:red;"><code>pre_state</code></mark> field. Defaults to <mark style="color:red;"><code>"false"</code></mark>.</td></tr></tbody></table>
### Supported txs for an estimated subaccount info
The following are the supported <mark style="color:red;">`txns`</mark> you can provide to get an estimated view of your subaccount.
{% hint style="info" %}
**Note**: these <mark style="color:red;">`txns`</mark> are only used to simulate what your subaccount would look like if they were executed.
{% endhint %}
#### ApplyDelta
Updates internal balances for the <mark style="color:red;">`product_id`</mark> and amount deltas provided.
```json
{
"apply_delta": {
"product_id": 2,
"subaccount": "0xeae27ae6412147ed6d5692fd91709dad6dbfc34264656661756c740000000000",
"amount_delta": "100000000000000000",
"v_quote_delta": "3033500000000000000000"
}
}
```
## Response
{% hint style="info" %}
**Note**:
* <mark style="color:red;">`healths`</mark>:
* <mark style="color:red;">`healths[0]`</mark>: info about your initial health, which is weighted by `long_weight_initial_x18` and `short_weight_initial_x18.`
* <mark style="color:red;">`healths[1]`</mark>: info about your maintenance health, which is weighted by `long_weight_maintenance_x18` and `short_weight_maintenance_x18.`
* <mark style="color:red;">`healths[2]`</mark>: info about your unweighted health.
* <mark style="color:red;">`health_contributions`</mark> is indexed by <mark style="color:red;">product\_id</mark> and represents the contribution of the corresponding product to the final health.
* <mark style="color:red;">`health_contributions[product_id][0]`</mark>`: contribution to healths[0]`
* <mark style="color:red;">`health_contributions[product_id][1]`</mark>`: contribution to healths[1]`
* <mark style="color:red;">`health_contributions[product_id][2]`</mark>`: contribution to healths[2]`
* <mark style="color:red;">`pre_state`</mark>: (Optional) When <mark style="color:red;">`pre_state="true"`</mark> is provided with <mark style="color:red;">`txns`</mark>, this field contains the subaccount state **before** the simulated transactions were applied. This allows you to compare the before/after states when simulating transactions.
* <mark style="color:red;">`pre_state.healths`</mark>: Same structure as the main `healths` field, but reflecting the state before transactions
* <mark style="color:red;">`pre_state.health_contributions`</mark>: Health contributions before transactions
* <mark style="color:red;">`pre_state.spot_balances`</mark>: Spot balances before transactions
* <mark style="color:red;">`pre_state.perp_balances`</mark>: Perpetual balances before transactions
{% endhint %}
```json
{
"status": "success",
"data": {
"subaccount": "0x8d7d64d6cf1d4f018dd101482ac71ad49e30c56064656661756c740000000000",
"exists": true,
"healths": [
{
"assets": "456895621098158389211471",
"liabilities": "76286259844766495292488",
"health": "380609361253391893918983"
},
{
"assets": "456895621098158389211471",
"liabilities": "72818702579095290924243",
"health": "384076918519063098287228"
},
{
"assets": "456895621098158389211471",
"liabilities": "69351145313424086671554",
"health": "387544475784734302539917"
}
],
"health_contributions": [
[
"456895621098158389211471",
"456895621098158389211471",
"456895621098158389211471"
],
[
"-76286259844766495292488",
"-72818702579095290924243",
"-69351145313424086671554"
],
[
"0",
"0",
"0"
]
],
"spot_count": 2,
"perp_count": 1,
"spot_balances": [
{
"product_id": 0,
"balance": {
"amount": "456895621098158389211471"
}
},
{
"product_id": 1,
"balance": {
"amount": "-600152323366021154"
}
}
],
"perp_balances": [
{
"product_id": 2,
"balance": {
"amount": "0",
"v_quote_balance": "0",
"last_cumulative_funding_x18": "-394223711772447555304"
}
}
],
"spot_products": [
{
"product_id": 0,
"oracle_price_x18": "1000000000000000000",
"risk": {
"long_weight_initial_x18": "1000000000000000000",
"short_weight_initial_x18": "1000000000000000000",
"long_weight_maintenance_x18": "1000000000000000000",
"short_weight_maintenance_x18": "1000000000000000000",
"price_x18": "1000000000000000000"
},
"config": {
"token": "0x5f65358d61a9a281ea3bb930d05889aca21e3f4f",
"interest_inflection_util_x18": "800000000000000000",
"interest_floor_x18": "10000000000000000",
"interest_small_cap_x18": "40000000000000000",
"interest_large_cap_x18": "1000000000000000000",
"withdraw_fee_x18": "1000000000000000000",
"min_deposit_rate_x18": "0"
},
"state": {
"cumulative_deposits_multiplier_x18": "1000000000025524653",
"cumulative_borrows_multiplier_x18": "1000347390837434279",
"total_deposits_normalized": "20001011744258817298755054194662",
"total_borrows_normalized": "1617724891363505323532211"
},
"book_info": {
"size_increment": "0",
"price_increment_x18": "0",
"min_size": "0",
"collected_fees": "0"
}
},
{
"product_id": 1,
"oracle_price_x18": "115555905748161505821744",
"risk": {
"long_weight_initial_x18": "900000000000000000",
"short_weight_initial_x18": "1100000000000000000",
"long_weight_maintenance_x18": "950000000000000000",
"short_weight_maintenance_x18": "1050000000000000000",
"price_x18": "115555905748161505821744"
},
"config": {
"token": "0xc57c1c64561a37ac9e8f9039cb6deab7539d99fc",
"interest_inflection_util_x18": "800000000000000000",
"interest_floor_x18": "10000000000000000",
"interest_small_cap_x18": "40000000000000000",
"interest_large_cap_x18": "1000000000000000000",
"withdraw_fee_x18": "40000000000000",
"min_deposit_rate_x18": "0"
},
"state": {
"cumulative_deposits_multiplier_x18": "1000000000000318713",
"cumulative_borrows_multiplier_x18": "1000347390679880473",
"total_deposits_normalized": "9000399823280682696107190850",
"total_borrows_normalized": "9580268570661550719"
},
"book_info": {
"size_increment": "1000000000000000",
"price_increment_x18": "1000000000000000000",
"min_size": "4000000000000000",
"collected_fees": "0"
}
}
],
"perp_products": [
{
"product_id": 2,
"oracle_price_x18": "115596528090565357611177",
"risk": {
"long_weight_initial_x18": "950000000000000000",
"short_weight_initial_x18": "1050000000000000000",
"long_weight_maintenance_x18": "970000000000000000",
"short_weight_maintenance_x18": "1030000000000000000",
"price_x18": "115596528090565357611177"
},
"state": {
"cumulative_funding_long_x18": "-394223711772447555304",
"cumulative_funding_short_x18": "-394223711772447555304",
"available_settle": "20092193239667417956947",
"open_interest": "113605000000000000000"
},
"book_info": {
"size_increment": "1000000000000000",
"price_increment_x18": "1000000000000000000",
"min_size": "4000000000000000",
"collected_fees": "0"
}
}
]
},
"request_type": "query_subaccount_info"
}
```
### Example with `pre_state`
When you want to simulate transactions and compare the before/after states, you can use the `pre_state` parameter:
#### Request
{% tabs %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=subaccount_info&subaccount={subaccount}&txns=[{"apply_delta":{"product_id":2,"subaccount":"0xeae27ae6412147ed6d5692fd91709dad6dbfc34264656661756c740000000000","amount_delta":"100000000000000000","v_quote_delta":"3033500000000000000000"}}]&pre_state="true"`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
```json
{
"type": "subaccount_info",
"subaccount": "0xeae27ae6412147ed6d5692fd91709dad6dbfc34264656661756c740000000000",
"txns": "[{\"apply_delta\":{\"product_id\":2,\"subaccount\":\"0xeae27ae6412147ed6d5692fd91709dad6dbfc34264656661756c740000000000\",\"amount_delta\":\"100000000000000000\",\"v_quote_delta\":\"3033500000000000000000\"}}]",
"pre_state": "true"
}
```
{% endtab %}
{% endtabs %}
#### Response
The response will now include a `pre_state` field showing the state before the simulated transactions:
```json
{
"status": "success",
"data": {
"subaccount": "0x8d7d64d6cf1d4f018dd101482ac71ad49e30c56064656661756c740000000000",
"exists": true,
"healths": [
{
"assets": "460000000000000000000000",
"liabilities": "80000000000000000000000",
"health": "380000000000000000000000"
}
],
"health_contributions": [...],
"spot_balances": [...],
"perp_balances": [
{
"product_id": 2,
"balance": {
"amount": "100000000000000000",
"v_quote_balance": "3033500000000000000000",
"last_cumulative_funding_x18": "-394223711772447555304"
}
}
],
"spot_products": [...],
"perp_products": [...],
"pre_state": {
"healths": [
{
"assets": "456895621098158389211471",
"liabilities": "76286259844766495292488",
"health": "380609361253391893918983"
}
],
"health_contributions": [...],
"spot_balances": [...],
"perp_balances": [
{
"product_id": 2,
"balance": {
"amount": "0",
"v_quote_balance": "0",
"last_cumulative_funding_x18": "-394223711772447555304"
}
}
]
}
},
"request_type": "query_subaccount_info"
}
```
{% hint style="success" %}
**Use Case**: The `pre_state` feature is particularly useful for:
* **Position Simulation**: Preview how a potential trade would affect your health and balances
* **Risk Analysis**: Compare health metrics before and after simulated transactions
* **UI/UX**: Display "before → after" views to users when they're about to execute trades
* **Testing**: Validate transaction impacts without executing them on-chain
{% endhint %}
@@ -0,0 +1,103 @@
# Symbols
## Rate limits
* 1200 requests/min or 20 requests/sec per IP address. (**weight = 2**)
{% hint style="info" %}
See more details in [API Rate limits](https://docs.nado.xyz/developer-resources/api/rate-limits)
{% endhint %}
## Request
{% tabs %}
{% tab title="Websocket" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]`</mark>
**Message**
```json
{
"type": "symbols",
"product_ids": [1, 2]
}
```
{% endtab %}
{% tab title="REST (GET)" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/query?type=symbols&product_type=spot`
{% endtab %}
{% tab title="REST (POST)" %} <mark style="color:orange;">`POST [GATEWAY_REST_ENDPOINT]/query`</mark>
**Message**
```json
{
"type": "symbols",
"product_ids": [1, 2, 3, 4],
"product_type": "spot"
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="155" align="center">Parameter</th><th width="108" align="center">Type</th><th width="132.125" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">No</td><td>An array of product ids. Only available for POST and WS requests.</td></tr><tr><td align="center">product_type</td><td align="center">string</td><td align="center">No</td><td>Type of products to return, must be:<br>"spot" | "perp".</td></tr></tbody></table>
## Response
{% hint style="info" %}
**Note**:
* All products have are quoted against USDT0, except for product 0.
{% endhint %}
```json
{
"status": "success",
"data": {
"symbols": {
"WBTC": {
"type": "spot",
"product_id": 1,
"symbol": "WBTC",
"price_increment_x18": "1000000000000000000",
"size_increment": "1000000000000000",
"min_size": "4000000000000000",
"maker_fee_rate_x18": "0",
"taker_fee_rate_x18": "200000000000000",
"long_weight_initial_x18": "900000000000000000",
"long_weight_maintenance_x18": "950000000000000000",
"max_open_interest_x18": null
},
"BTC-PERP": {
"type": "perp",
"product_id": 2,
"symbol": "BTC-PERP",
"price_increment_x18": "1000000000000000000",
"size_increment": "1000000000000000",
"min_size": "4000000000000000",
"maker_fee_rate_x18": "0",
"taker_fee_rate_x18": "200000000000000",
"long_weight_initial_x18": "950000000000000000",
"long_weight_maintenance_x18": "970000000000000000",
"max_open_interest_x18": null
}
}
},
"request_type": "query_symbols"
}
```
## Response fields
### Symbols
All numerical values are returned as strings and scaled by 1e18.
<table><thead><tr><th width="318">Field name</th><th>Description</th></tr></thead><tbody><tr><td>type</td><td>Product type, "spot" or "perp"</td></tr><tr><td>product_id</td><td>Product id</td></tr><tr><td>symbol</td><td>Product symbol</td></tr><tr><td>price_increment_x18</td><td>Price increment, a.k.a tick size</td></tr><tr><td>size_increment</td><td>Size increment, in base units</td></tr><tr><td>min_size</td><td>Minimum order size, in base units</td></tr><tr><td>maker_fee_rate_x18</td><td>Maker fee rate, given as decimal rate</td></tr><tr><td>taker_fee_rate_x18</td><td>Taker fee rate, given as decimal rate</td></tr><tr><td>long_weight_initial_x18</td><td>Long initial margin weight, given as decimal</td></tr><tr><td>long_weight_maintenance_x18</td><td>Long maintenance margin weight, given as decimal</td></tr><tr><td>max_open_interest_x18</td><td>Maximum open interest, null if no limit</td></tr></tbody></table>
@@ -0,0 +1,326 @@
# Signing
All executes are signed using [EIP712](https://eips.ethereum.org/EIPS/eip-712). Each execute request contains:
1. A piece of structured data that includes the sender address i.e: the <mark style="color:red;">`primaryType`</mark> that needs to be signed.
2. A signature of the hash of that structured data, signed by the sender.
## Domain
The following is the domain required as part of the EIP712 structure:
```json
{
name: 'Nado',
version: '0.0.1',
chainId: chainId,
verifyingContract: contractAddress
}
```
You can retrieve the corresponding chain id and verifying contract via the [contracts](https://docs.nado.xyz/developer-resources/api/gateway/queries/contracts) query.
{% hint style="warning" %}
**Note**: make sure to use the correct verifying contract for each execute:
* For place order: should use `address(producId)` i.e: the 20 bytes hex representation of the `productId` for the order. For example, the verify contract of product `18` is `0x0000000000000000000000000000000000000012` .
* For everything else: should use the endpoint address.
See more details in the [contracts](https://docs.nado.xyz/developer-resources/api/gateway/queries/contracts) query page.
{% endhint %}
```python
def gen_order_verifying_contract(product_id: int) -> str:
"""
Generates the order verifying contract address based on the product ID.
Args:
product_id (int): The product ID for which to generate the verifying contract address.
Returns:
str: The generated order verifying contract address in hexadecimal format.
"""
be_bytes = product_id.to_bytes(20, byteorder="big", signed=False)
return "0x" + be_bytes.hex()
```
## EIP712 Types
See below the EIP712 type for each execute:
{% hint style="info" %}
See more details in the **Signing** section of each execute's page.
{% endhint %}
### [Place Order](https://docs.nado.xyz/developer-resources/api/gateway/executes/place-order)
**Primary Type**: <mark style="color:red;">`Order`</mark>
Solidity struct that needs to be signed:
```solidity
struct Order {
bytes32 sender;
int128 priceX18;
int128 amount;
uint64 expiration;
uint64 nonce;
uint128 appendix;
}
```
**JSON representation:**
```typescript
{
Order: [
{ name: 'sender', type: 'bytes32' },
{ name: 'priceX18', type: 'int128' },
{ name: 'amount', type: 'int128' },
{ name: 'expiration', type: 'uint64' },
{ name: 'nonce', type: 'uint64' },
{ name: 'appendix', type: 'uint128' }
],
}
```
### [Cancel Orders](https://docs.nado.xyz/developer-resources/api/gateway/executes/cancel-orders)
**Primary Type:** <mark style="color:red;">`Cancellation`</mark>
Solidity struct that needs to be signed:
```solidity
struct Cancellation {
bytes32 sender;
uint32[] productIds;
bytes32[] digests;
uint64 nonce;
}
```
**JSON representation:**
```typescript
{
Cancellation: [
{ name: 'sender', type: 'bytes32' },
{ name: 'productIds', type: 'uint32[]' },
{ name: 'digests', type: 'bytes32[]' },
{ name: 'nonce', type: 'uint64' },
],
}
```
### [Cancel Product Orders](https://docs.nado.xyz/developer-resources/api/gateway/executes/cancel-product-orders)
**Primary Type**: <mark style="color:red;">`CancellationProducts`</mark>
Solidity struct that needs to be signed:
```solidity
struct CancellationProducts {
bytes32 sender;
uint32[] productIds;
uint64 nonce;
}
```
**JSON representation:**
```typescript
{
CancellationProducts: [
{ name: 'sender', type: 'bytes32' },
{ name: 'productIds', type: 'uint32[]' },
{ name: 'nonce', type: 'uint64' },
],
}
```
### [Withdraw Collateral](https://docs.nado.xyz/developer-resources/api/gateway/executes/withdraw-collateral)
**Primary Type:** <mark style="color:red;">`WithdrawCollateral`</mark>
Solidity struct that needs to be signed:
```solidity
struct WithdrawCollateral {
bytes32 sender;
uint32 productId;
uint128 amount;
uint64 nonce;
}
```
**JSON representation:**
```typescript
{
WithdrawCollateral: [
{ name: 'sender', type: 'bytes32' },
{ name: 'productId', type: 'uint32' },
{ name: 'amount', type: 'uint128' },
{ name: 'nonce', type: 'uint64' },
],
}
```
### [Liquidate Subaccount](https://docs.nado.xyz/developer-resources/api/gateway/executes/liquidate-subaccount)
**Primary Type:** <mark style="color:red;">`LiquidateSubaccount`</mark>
Solidity struct that needs to be signed:
```solidity
struct LiquidateSubaccount {
bytes32 sender;
bytes32 liquidatee;
uint32 productId;
bool isEncodedSpread;
int128 amount;
uint64 nonce;
}
```
**JSON representation:**
```typescript
{
LiquidateSubaccount: [
{ name: 'sender', type: 'bytes32' },
{ name: 'liquidatee', type: 'bytes32' },
{ name: 'productId', type: 'uint32' },
{ name: 'isEncodedSpread', type: 'bool' },
{ name: 'amount', type: 'int128' },
{ name: 'nonce', type: 'uint64' },
],
}
```
### [Mint NLP](https://docs.nado.xyz/developer-resources/api/gateway/executes/mint-nlp)
**Primary Type**: <mark style="color:red;">`MintNlp`</mark>
Solidity struct that needs to be signed:
```solidity
struct MintNlp {
bytes32 sender;
uint32 productId;
uint128 quoteAmount;
uint64 nonce;
}
```
**JSON representation:**
```typescript
{
MintLp: [
{ name: 'sender', type: 'bytes32' },
{ name: 'quoteAmount', type: 'uint128' },
{ name: 'nonce', type: 'uint64' },
],
}
```
## [Burn NLP](https://docs.nado.xyz/developer-resources/api/gateway/executes/burn-nlp)
**Primary Type:** <mark style="color:red;">`BurnNlp`</mark>
Solidity struct that needs to be signed:
```solidity
struct BurnLp {
bytes32 sender;
uint128 nlpAmount;
uint64 nonce;
}
```
**JSON representation:**
```typescript
{
BurnLp: [
{ name: 'sender', type: 'bytes32' },
{ name: 'nlpAmount', type: 'uint128' },
{ name: 'nonce', type: 'uint64' },
],
}
```
## [Link Signer](https://docs.nado.xyz/developer-resources/api/gateway/executes/link-signer)
**Primary Type**: <mark style="color:red;">`LinkSigner`</mark>
Solidity struct that needs to be signed:
```solidity
struct LinkSigner {
bytes32 sender;
bytes32 signer;
uint64 nonce;
}
```
**JSON representation:**
```typescript
{
LinkSigner: [
{ name: 'sender', type: 'bytes32' },
{ name: 'signer', type: 'bytes32' },
{ name: 'nonce', type: 'uint64' },
],
}
```
## [List Trigger Orders](https://docs.nado.xyz/developer-resources/api/trigger/queries/list-trigger-orders)
**Primary Type**: <mark style="color:red;">`ListTriggerOrders`</mark>
Solidity struct that needs to be signed:
```solidity
struct ListTriggerOrders {
bytes32 sender;
uint64 recvTime;
}
```
**JSON representation:**
```typescript
{
ListTriggerOrders: [
{ name: 'sender', type: 'bytes32' },
{ name: 'recvTime', type: 'uint64' },
],
}
```
## [Authenticate Subscription Streams](https://docs.nado.xyz/developer-resources/subscriptions#authentication)
**Primary Type**: <mark style="color:red;">`StreamAuthentication`</mark>
Struct that needs to be signed:
```solidity
struct StreamAuthentication {
bytes32 sender;
uint64 expiration;
}
```
**JSON representation:**
```typescript
{
StreamAuthentication: [
{ name: 'sender', type: 'bytes32' },
{ name: 'expiration', type: 'uint64' },
],
}
```
@@ -0,0 +1,376 @@
# Examples
The following are full examples of EIP12 typed data for each of Nado's executes. Each execute includes a <mark style="color:red;">`sender`</mark> field which is a solidity <mark style="color:red;">`bytes32`</mark> . There are two components to this field:
* an <mark style="color:red;">`address`</mark> that is a <mark style="color:red;">`bytes20`</mark>
* a subaccount identifier that is a <mark style="color:red;">`bytes12`</mark>
For example, if your address was <mark style="color:red;">`0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43`</mark>, and you wanted to use the default subaccount identifier (i.e: an empty identifier `""`) you can set <mark style="color:red;">`sender`</mark> to <mark style="color:red;">`0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000`</mark> , which sets all bytes of the subaccount identifier to <mark style="color:red;">`0`</mark>.
{% hint style="info" %}
**Note**: a <mark style="color:red;">`bytes32`</mark> representation of the sender must used when signing the request.
{% endhint %}
See below a sample util to convert a hex to a **bytes32**:
{% tabs %}
{% tab title="Python" %}
```python
def hex_to_bytes32(hex_string):
if hex_string.startswith("0x"):
hex_string = hex_string[2:]
data_bytes = bytes.fromhex(hex_string)
padded_data = data_bytes + b"\x00" * (32 - len(data_bytes))
return padded_data
sender = hex_to_bytes32('0x841fe4876763357975d60da128d8a54bb045d76a64656661756c740000000000')
```
{% endtab %}
{% tab title="Typescript" %}
```typescript
import { arrayify } from 'ethers/lib/utils';
export function hexToBytes32(subaccount: string) {
const subaccountBytes = arrayify(subaccount);
const bytes32 = new Uint8Array(32);
for (let i = 0; i < Math.min(subaccountBytes.length, 32); i++) {
bytes32[i] = subaccountBytes[i];
}
return bytes32;
}
const sender = hexToBytes32('0x841fe4876763357975d60da128d8a54bb045d76a64656661756c740000000000')
```
{% endtab %}
{% endtabs %}
## EIP712 Typed data examples
{% tabs %}
{% tab title="Place Order" %}
```python
{
'types': {
'EIP712Domain': [
{'name': 'name', 'type': 'string'},
{'name': 'version', 'type': 'string'},
{'name': 'chainId', 'type': 'uint256'},
{'name': 'verifyingContract', 'type': 'address'}
],
'Order': [
{'name': 'sender', 'type': 'bytes32'},
{'name': 'priceX18', 'type': 'int128'},
{'name': 'amount', 'type': 'int128'},
{'name': 'expiration', 'type': 'uint64'},
{'name': 'nonce', 'type': 'uint64'},
{'name': 'appendix', 'type': 'uint128'},
],
},
'primaryType': 'Order',
'domain': {
'name': 'Nado',
'version': '0.0.1',
'chainId': 763373,
'verifyingContract': '0x0000000000000000000000000000000000000001'
},
'message': {
'sender': hex_to_bytes32('0x841fe4876763357975d60da128d8a54bb045d76a64656661756c740000000000'),
'priceX18': 28898000000000000000000,
'amount': -10000000000000000,
'expiration': 4611687701117784255,
'appendix': 1537, # Version 1, POST_ONLY order
'nonce': 1764428860167815857,
},
}
```
{% endtab %}
{% tab title="Cancel Orders" %}
```python
{
'types': {
'EIP712Domain': [
{'name': 'name', 'type': 'string'},
{'name': 'version', 'type': 'string'},
{'name': 'chainId', 'type': 'uint256'},
{'name': 'verifyingContract', 'type': 'address'}
],
'Cancellation': [
{ 'name': 'sender', 'type': 'bytes32' },
{ 'name': 'productIds', 'type': 'uint32[]'},
{ 'name': 'digests', 'type': 'bytes32[]'},
{ 'name': 'nonce', 'type': 'uint64'},
],
},
'primaryType': 'Cancellation',
'domain': {
'name': 'Nado',
'version': '0.0.1',
'chainId': 763373,
'verifyingContract': '0xbf16e41fb4ac9922545bfc1500f67064dc2dcc3b'
},
'message': {
'sender': hex_to_bytes32('0x841fe4876763357975d60da128d8a54bb045d76a64656661756c740000000000'),
'productIds': [4],
'digests': [hex_to_bytes32('0x51ba8762bc5f77957a4e896dba34e17b553b872c618ffb83dba54878796f2821')],
'nonce': 1,
},
}
```
{% endtab %}
{% tab title="Cancel Product orders" %}
```python
{
'types': {
'EIP712Domain': [
{'name': 'name', 'type': 'string'},
{'name': 'version', 'type': 'string'},
{'name': 'chainId', 'type': 'uint256'},
{'name': 'verifyingContract', 'type': 'address'}
],
'CancellationProducts': [
{'name': 'sender', 'type': 'bytes32'},
{'name': 'productIds', 'type': 'uint32[]'},
{'name': 'nonce', 'type': 'uint64'},
],
},
'primaryType': 'CancellationProducts',
'domain': {
'name': 'Nado',
'version': '0.0.1',
'chainId': 763373,
'verifyingContract': '0xbf16e41fb4ac9922545bfc1500f67064dc2dcc3b'
},
'message': {
'sender': hex_to_bytes32('0x841fe4876763357975d60da128d8a54bb045d76a64656661756c740000000000'),
'productIds': [1, 2],
'nonce': 1,
},
}
```
{% endtab %}
{% tab title="Link Signer" %}
```python
{
'types': {
'EIP712Domain': [
{'name': 'name', 'type': 'string'},
{'name': 'version', 'type': 'string'},
{'name': 'chainId', 'type': 'uint256'},
{'name': 'verifyingContract', 'type': 'address'}
],
'LinkSigner': [
{'name': 'sender', 'type': 'bytes32'},
{'name': 'signer', 'type': 'bytes32'},
{'name': 'nonce', 'type': 'uint64'},
],
},
'primaryType': 'LinkSigner',
'domain': {
'name': 'Nado',
'version': '0.0.1',
'chainId': 763373,
'verifyingContract': '0xbf16e41fb4ac9922545bfc1500f67064dc2dcc3b'
},
'message': {
'sender': hex_to_bytes32('0x841fe4876763357975d60da128d8a54bb045d76a64656661756c740000000000'),
'signer': hex_to_bytes32('0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000'),
'nonce': 1,
},
}
```
{% endtab %}
{% endtabs %}
{% tabs %}
{% tab title="Withdraw Collateral" %}
```python
{
'types': {
'EIP712Domain': [
{'name': 'name', 'type': 'string'},
{'name': 'version', 'type': 'string'},
{'name': 'chainId', 'type': 'uint256'},
{'name': 'verifyingContract', 'type': 'address'}
],
'WithdrawCollateral': [
{'name': 'sender', 'type': 'bytes32'},
{'name': 'productId', 'type': 'uint32'},
{'name': 'amount', 'type': 'uint128'},
{'name': 'nonce', 'type': 'uint64'},
],
},
'primaryType': 'WithdrawCollateral',
'domain': {
'name': 'Nado',
'version': '0.0.1',
'chainId': 763373,
'verifyingContract': '0xbf16e41fb4ac9922545bfc1500f67064dc2dcc3b'
},
'message': {
'sender': hex_to_bytes32('0x841fe4876763357975d60da128d8a54bb045d76a64656661756c740000000000'),
'productId': 2,
'amount': 10000000000000000,
'nonce': 1
},
}
```
{% endtab %}
{% tab title="Liquidate Subaccount" %}
```python
{
'types': {
'EIP712Domain': [
{'name': 'name', 'type': 'string'},
{'name': 'version', 'type': 'string'},
{'name': 'chainId', 'type': 'uint256'},
{'name': 'verifyingContract', 'type': 'address'}
],
'LiquidateSubaccount': [
{'name': 'sender', 'type': 'bytes32'},
{'name': 'liquidatee', 'type': 'bytes32'},
{'name': 'productId', 'type': 'uint32'},
{'name': 'isEncodedSpread', 'type': 'bool'},
{'name': 'amount', 'type': 'int128'},
{'name': 'nonce', 'type': 'uint64'},
],
},
'primaryType': 'LiquidateSubaccount',
'domain': {
'name': 'Nado',
'version': '0.0.1',
'chainId': 763373,
'verifyingContract': '0xbf16e41fb4ac9922545bfc1500f67064dc2dcc3b'
},
'message': {
'sender': hex_to_bytes32('0x841fe4876763357975d60da128d8a54bb045d76a64656661756c740000000000'),
'liquidatee': hex_to_bytes32('0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000'),
'productId': 1,
'isEncodedSpread': false,
'amount': 10000000000000000,
'nonce': 1,
},
}
```
{% endtab %}
{% tab title="Mint NLP" %}
```python
{
'types': {
'EIP712Domain': [
{'name': 'name', 'type': 'string'},
{'name': 'version', 'type': 'string'},
{'name': 'chainId', 'type': 'uint256'},
{'name': 'verifyingContract', 'type': 'address'}
],
'MintLp': [
{'name': 'sender', 'type': 'bytes32' },
{'name': 'quoteAmount', 'type': 'uint128'},
{'name': 'nonce', 'type': 'uint64' },
],
},
'primaryType': 'MintNlp',
'domain': {
'name': 'Nado',
'version': '0.0.1',
'chainId': 763373,
'verifyingContract': '0xbf16e41fb4ac9922545bfc1500f67064dc2dcc3b'
},
'message': {
'sender': hex_to_bytes32('0x841fe4876763357975d60da128d8a54bb045d76a64656661756c740000000000'),
'quoteAmount': 20000000000000000000000,
'nonce': 1,
},
}
```
{% endtab %}
{% tab title="Burn NLP" %}
```python
{
'types': {
'EIP712Domain': [
{'name': 'name', 'type': 'string'},
{'name': 'version', 'type': 'string'},
{'name': 'chainId', 'type': 'uint256'},
{'name': 'verifyingContract', 'type': 'address'}
],
'BurnLp': [
{'name': 'sender', 'type': 'bytes32'},
{'name': 'nlpAmount', 'type': 'uint128'},
{'name': 'nonce', 'type': 'uint64'},
],
},
'primaryType': 'BurnNlp',
'domain': {
'name': 'Nado',
'version': '0.0.1',
'chainId': 763373,
'verifyingContract': '0xbf16e41fb4ac9922545bfc1500f67064dc2dcc3b'
},
'message': {
'sender': hex_to_bytes32('0x841fe4876763357975d60da128d8a54bb045d76a64656661756c740000000000'),
'nlpAmount': 1000000000000000000,
'nonce': 1,
},
}
```
{% endtab %}
{% tab title="List Trigger Orders" %}
```python
{
'types': {
'EIP712Domain': [
{'name': 'name', 'type': 'string'},
{'name': 'version', 'type': 'string'},
{'name': 'chainId', 'type': 'uint256'},
{'name': 'verifyingContract', 'type': 'address'}
],
'ListTriggerOrders': [
{'name': 'sender', 'type': 'bytes32' },
{'name': 'recvTime', 'type': 'uint64' }
],
},
'primaryType': 'WithdrawCollateral',
'domain': {
'name': 'Nado',
'version': '0.0.1',
'chainId': 763373,
'verifyingContract': '0xbf16e41fb4ac9922545bfc1500f67064dc2dcc3b'
},
'message': {
'sender': hex_to_bytes32('0x841fe4876763357975d60da128d8a54bb045d76a64656661756c740000000000'),
'recvTime': 1688939576000
},
}
```
{% endtab %}
{% endtabs %}
@@ -0,0 +1,49 @@
# Q\&A
### Q: **What is Nado's EIP712 domain?**
```json
{
name: 'Nado',
version: '0.0.1',
chainId: chainId,
verifyingContract: contractAddress
}
```
{% hint style="info" %}
See [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing/..#domain) for more details.
{% endhint %}
### Q: How can i retrieve the verifying contracts to use?
* Via the [contracts](https://docs.nado.xyz/developer-resources/api/gateway/queries/contracts) query for all executes except place orders.
### Q: Which contract should I use for each execute?
* For place orders: must be computed as <mark style="color:red;">`address(productId)`</mark>. For example, the verify contract of product <mark style="color:red;">`18`</mark> is <mark style="color:red;">`0x0000000000000000000000000000000000000012`</mark>.
* For everything else: use the endpoint contract from the contracts query.
{% hint style="info" %}
See the [contracts](https://docs.nado.xyz/developer-resources/api/queries/contracts#response) query for more details.
{% endhint %}
### Q: I am running into signature errors, how to fix?
Signature errors can arise for several reasons:
* **An invalid struct**: confirm you are signing the correct struct. See the [Signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page to verify the struct of each execute request.
* **An invalid chain id**: confirm you have the correct chain id for the network you are on.
* **An invalid verifying contract**: confirm you have the correct verifying contract address for the network and execute you are signing. i.e: confirm you are using the correct orderbook address for place orders and endpoint address for everything else.
### Q: Is any other signing standard supported?
No, only [EIP712](https://eips.ethereum.org/EIPS/eip-712).
### Q: Are there any examples you can provide?
See [examples](https://docs.nado.xyz/developer-resources/api/gateway/signing/examples).
### Q: What is the PrimaryType of execute X?
All primary types are listed in our [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page.
@@ -0,0 +1,64 @@
# Integrate via Smart Contracts
Smart contracts can use the <mark style="color:red;">`LinkSigner`</mark> transaction type (see [Link Signer](https://docs.nado.xyz/developer-resources/api/gateway/executes/link-signer)) to perform the following:
1. Deposit into Nado.
2. LinkSigner an externally owned account ([EOA](https://ethereum.org/en/developers/docs/accounts/#externally-owned-accounts-and-key-pairs)).
3. Have the externally owned account trade using the smart contract's assets on Nado.
## Setup: Depositing into Nado + Linking an EOA
1. Deposits are always on-chain, as such, users can simply have their smart contract call <mark style="color:red;">`depositCollateral`</mark> on our <mark style="color:red;">`Endpoint`</mark> contract (see [Contracts](https://docs.nado.xyz/developer-resources/api/broken-reference) for addresses).
2. The contract needs to have 1 USDT0 available to pay for slow-mode fee and approve the endpoint contract, assemble the bytes for a slow mode linked signer transaction, and submit it via [submitSlowModeTransaction](https://github.com/vertex-protocol/vertex-contracts/blob/1ab8c8ba11e9ddf82c4210a826aad0b899f342aa/contracts/Endpoint.sol#L258).
{% hint style="info" %}
You can find the requisite parsing logic in the [Endpoint](https://github.com/vertex-protocol/vertex-contracts/blob/1ab8c8ba11e9ddf82c4210a826aad0b899f342aa/contracts/Endpoint.sol#L429) contract.
{% endhint %}
### Example
```solidity
struct LinkSigner {
bytes32 sender;
bytes32 signer;
uint64 nonce;
}
function linkNadoSigner(
address nadoEndpoint,
address externalAccount,
address usdt0Address
) external {
// 1. a slow mode fee of 1 USDT0 needs to be avaliable and approved
ERC20 usdt0Token = ERC20(usdt0Address);
// NOTE: should double check the USDT0 decimals in the corresponding chain.
// e.g: it's 1e6 on arbitrum, whereas it's 1e18 on blast, etc.
uint256 SLOW_MODE_FEE = 1e6;
usdt0Token.transferFrom(msg.sender, address(this), SLOW_MODE_FEE);
usdt0Token.approve(nadoEndpoint, SLOW_MODE_FEE);
// 2. assamble the link signer slow mode transaction
bytes12 defaultSubaccountName = bytes12(abi.encodePacked("default"));
bytes32 contractSubaccount = bytes32(
abi.encodePacked(uint160(address(this)), defaultSubaccountName)
);
bytes32 externalSubaccount = bytes32(
uint256(uint160(externalAccount)) << 96
);
LinkSigner memory linkSigner = LinkSigner(
contractSubaccount,
externalSubaccount,
IEndpoint(nadoEndpoint).getNonce(externalAccount)
);
bytes memory txs = abi.encodePacked(
uint8(19),
abi.encode(linkSigner)
);
// 3. submit slow mode transaction
IEndpoint(nadoEndpoint).submitSlowModeTransaction(txs);
}
```
Once the transaction is confirmed, it may take a few seconds for it to make its way into the Nado offchain sequencer. Afterwards, you can sign transactions that have sender <mark style="color:red;">`contractSubaccount`</mark> using <mark style="color:red;">`externalSubaccount`</mark>, and they will be accepted by the sequencer and the blockchain.
@@ -0,0 +1,294 @@
# Order Appendix
The **Order Appendix** is a 128-bit integer that encodes extra order parameters like execution type, isolated margin, and trigger configurations.
## Bit Layout
```json
| value | reserved | trigger | reduce only | order type | isolated | version |
| 64 bits | 50 bits | 2 bits | 1 bit | 2 bits | 1 bit | 8 bits |
| 127..64 | 63..14 | 13..12 | 11 | 10..9 | 8 | 7..0 |
```
## Fields (from LSB to MSB)
### <mark style="color:red;">Version</mark>
**8-bits (0-7)**. Protocol version identifier. Currently <mark style="color:red;">`1`</mark>. May increment when encoding structure updates.
### <mark style="color:red;">Isolated</mark>
**1-bit (8)**. Indicates whether the order uses isolated margin. Isolated positions have dedicated margin for a specific product, creating a separate isolated subaccount. The original account becomes the "parent subaccount" that can manage the isolated position.
*Key Properties:*
* Creates isolated subaccount with dedicated margin
* Only quote transfers allowed between isolated and parent subaccounts
* Parent account can sign orders for isolated subaccount
* Cannot be combined with TWAP orders
*Example:*
```python
from nado_protocol.utils.appendix import build_appendix
from nado_protocol.utils.math import to_x6
# Create isolated order with 1000 USDT0 margin
appendix = build_appendix(
order_type=OrderType.DEFAULT,
isolated=True,
isolated_margin=to_x6(1000) # 1000 USDT0 (x6 precision)
)
```
### <mark style="color:red;">Order Type</mark>
**2-bits (9-10)**. Execution behavior for the order.
*Values:*
* <mark style="color:red;">`0`</mark> - <mark style="color:red;">`DEFAULT`</mark>: Standard limit order behavior.
* <mark style="color:red;">`1`</mark> - <mark style="color:red;">`IOC (Immediate or Cancel)`</mark>: Execute immediately, cancel unfilled portion.
* <mark style="color:red;">`2`</mark> - <mark style="color:red;">`FOK (Fill or Kill)`</mark>: Execute completely or cancel entire order.
* <mark style="color:red;">`3`</mark> - <mark style="color:red;">`POST_ONLY`</mark>: Only add liquidity, reject if would take liquidity.
*Example:*
```python
from nado_protocol.utils.appendix import build_appendix
# Post-only order that only provides liquidity
appendix = build_appendix(
order_type=OrderType.POST_ONLY
)
```
### <mark style="color:red;">Reduce Only</mark>
**1-bit (11)**. Restricts order to only decrease existing positions. Prevent accidentally increasing position size. Order will be rejected if it would increase the position in the same direction.
*Use Cases:*
* Risk management when closing positions.
* Taking profits without adding exposure.
* Automated position reduction strategies.
*Example:*
```python
from nado_protocol.utils.appendix import build_appendix
# Reduce-only order to close part of existing position
appendix = build_appendix(
order_type=OrderType.DEFAULT,
reduce_only=True
)
```
### <mark style="color:red;">Trigger Type</mark>
**2-bits (12-13)**. Conditional execution behavior.
*Values:*
* <mark style="color:red;">`0`</mark> - <mark style="color:red;">`NONE`</mark>: Execute immediately (regular order).
* <mark style="color:red;">`1`</mark> - <mark style="color:red;">`PRICE`</mark>: Price-based conditional order.
* <mark style="color:red;">`2`</mark> - <mark style="color:red;">`TWAP`</mark>: Time-Weighted Average Price execution.
* <mark style="color:red;">`3`</mark> - <mark style="color:red;">`TWAP_CUSTOM_AMOUNTS`</mark>: TWAP with randomized amounts.
*Example:*
```python
from nado_protocol.utils.appendix import build_appendix
# TWAP order executing 5 times with 0.5% max slippage
appendix = build_appendix(
order_type=OrderType.DEFAULT,
trigger_type=OrderAppendixTriggerType.TWAP,
twap_times=5,
twap_slippage_frac=0.005 # 0.5%
)
```
### <mark style="color:red;">Reserved</mark>
**50-bits (14-63)**. Reserved for future protocol extensions. Must be set to `0`.
### <mark style="color:red;">Value</mark>
**64-bits (64-127)**. Context-dependent data based on other flags.
#### <mark style="color:red;">**TWAP Configuration (when trigger = 2 or 3)**</mark>
Encodes TWAP execution parameters in the 64-bit value field:
```json
| times | slippage_x6 |
| 32 bits| 32 bits |
```
**Fields:**
* <mark style="color:red;">`times`</mark>: Number of TWAP executions.
* <mark style="color:red;">`slippage_x6`</mark>: Maximum slippage × 1\_000\_000 (6 decimal precision).
**Example:**
```python
from nado_protocol.utils.appendix import build_appendix, order_twap_data
# TWAP: 10 executions, 1% max slippage
appendix = build_appendix(
order_type=OrderType.DEFAULT,
trigger_type=OrderAppendixTriggerType.TWAP,
twap_times=10,
twap_slippage_frac=0.01 # 1%
)
# Extract TWAP data
times, slippage = order_twap_data(appendix)
# times = 10, slippage = 0.01
```
#### <mark style="color:red;">**Isolated Margin (when isolated = 1)**</mark>
Amount of quote (margin\_x6) to transfer to isolated subaccount on first fill, stored in the 64-bit value field.
{% hint style="warning" %}
**Important:** Isolated margin is stored in **x6 precision** (6 decimals) in the appendix value field.
* Stored as `margin_x6` (6 decimal places)
* Takes up 64 bits (bits 64-127 of the appendix)
{% endhint %}
*Example:*
```python
from nado_protocol.utils.appendix import build_appendix, order_isolated_margin
from nado_protocol.utils.math import to_x6
# Isolated order with 500 USDT0 margin
appendix = build_appendix(
order_type=OrderType.DEFAULT,
isolated=True,
isolated_margin=to_x6(500) # 500 USDT0 (x6 precision)
)
# Extract isolated margin
margin = order_isolated_margin(appendix)
# Returns: 500000000 (500 * 10^6 in x6 precision)
```
## Constraints
* **Isolated + TWAP**: Cannot combine isolated orders with TWAP (trigger types 2 or 3).
* **TWAP Requirements**: TWAP orders must specify both <mark style="color:red;">`twap_times`</mark> and <mark style="color:red;">`twap_slippage_frac`</mark> .
* **Isolated Margin**: Can only set <mark style="color:red;">`isolated_margin`</mark> when <mark style="color:red;">`isolated=True`</mark> .
## Migration from Legacy Format
**Before (deprecated):**
* Order type encoded in <mark style="color:red;">`expiration`</mark> field.
* Reduce-only flag encoded in <mark style="color:red;">`nonce`</mark> field.
* Limited trigger functionality.
**After (current):**
* All flags consolidated in 128-bit <mark style="color:red;">`appendix`</mark> .
* <mark style="color:red;">`expiration`</mark> is pure timestamp.
* <mark style="color:red;">`nonce`</mark> encodes <mark style="color:red;">`recv_time`</mark> only.
* Enhanced trigger and isolated margin support.
## Building Appendix Values
#### Using Python SDK (Recommended)
```python
from nado_protocol.utils.expiration import OrderType
from nado_protocol.utils.appendix import build_appendix, OrderAppendixTriggerType
# Simple market order
appendix = build_appendix(order_type=OrderType.DEFAULT)
# Post-only reduce order
appendix = build_appendix(
order_type=OrderType.POST_ONLY,
reduce_only=True
)
# Isolated order with margin
appendix = build_appendix(
order_type=OrderType.DEFAULT,
isolated=True,
isolated_margin=to_x6(1000) # 1000 USDT0 (x6 precision)
)
# TWAP order
appendix = build_appendix(
order_type=OrderType.DEFAULT,
trigger_type=OrderAppendixTriggerType.TWAP,
twap_times=5,
twap_slippage_frac=0.01 # 1%
)
```
#### Manual Bit Manipulation (Advanced)
{% hint style="info" %}
Refer to [nado\_protocol.utils.order](https://nadohq.github.io/nado-python-sdk/_modules/nado_protocol/utils/order.html) for a detailed implementation.
{% endhint %}
```python
# Build appendix manually
def build_manual_appendix(order_type=0, isolated=False, reduce_only=False,
trigger_type=0, value=0):
appendix = 0
# Version (bits 0-7)
appendix |= 1 # Version 1
# Isolated (bit 8)
if isolated:
appendix |= 1 << 8
# Order type (bits 9-10)
appendix |= (order_type & 0b11) << 9
# Reduce only (bit 11)
if reduce_only:
appendix |= 1 << 11
# Trigger type (bits 12-13)
appendix |= (trigger_type & 0b11) << 12
# Reserved bits 14-63 (set to 0)
# Value (bits 64-127)
# Note: Value is stored in x6 precision for isolated margin
appendix |= (value & ((1 << 64) - 1)) << 64
return appendix
# Example: Post-only reduce order
appendix = build_manual_appendix(
order_type=3, # POST_ONLY
reduce_only=True
)
```
### Utility Functions
```python
# Check order properties
is_reduce_only = order_reduce_only(appendix)
is_trigger = order_is_trigger_order(appendix)
is_isolated = order_is_isolated(appendix)
version = order_version(appendix)
order_type = order_execution_type(appendix)
trigger_type = order_trigger_type(appendix)
# Extract context data
twap_data = order_twap_data(appendix) # Returns (times, slippage) or None
isolated_margin = order_isolated_margin(appendix) # Returns margin or None
```
@@ -0,0 +1,120 @@
# Rate limits
## Overview
* Nado uses a weight-based rate-limiting system across queries and executes. We limit based on <mark style="color:red;">`IP address`</mark>, <mark style="color:red;">`Wallet address`</mark>, and a global <mark style="color:red;">`max # of orders per subaccount per market`</mark>.
* These limits equally apply to both <mark style="color:red;">`http`</mark> requests and <mark style="color:red;">`Websocket`</mark> messages.
* Limits are applied on a <mark style="color:red;">`1 minute`</mark> and <mark style="color:red;">`10 seconds`</mark> basis.
## Limits
* IP addresses have a max weight limit of <mark style="color:red;">`2400`</mark> per minute or <mark style="color:red;">`400`</mark> every 10 seconds applied only to queries.
* Wallet addresses have a max weight limit of <mark style="color:red;">`600`</mark> per minute or <mark style="color:red;">`100`</mark> every 10 seconds applied only to executes.
* Users can have up to <mark style="color:red;">`500`</mark> open orders per subaccount per market.
* Orders have the following additional limits:
* Place orders (with spot leverage): up to <mark style="color:red;">`600`</mark> per minute or <mark style="color:red;">`100`</mark> every 10 seconds across all markets.
* Place orders (without spot leverage): up to <mark style="color:red;">`30`</mark> per minute or <mark style="color:red;">`5`</mark> every 10 seconds across all markets. **Note**: orders without spot leverage are <mark style="color:red;">`20x`</mark> more expensive to place due to additional health checks needed.
* Order cancellations: up to <mark style="color:red;">`600`</mark> per minute or <mark style="color:red;">`100`</mark> every 10 seconds.
## Query Weights
Queries are rate-limited based on IP. The following weights are applied per query:
* [**Status**](https://docs.nado.xyz/developer-resources/api/gateway/queries/status): <mark style="color:red;">`IP weight = 1`</mark>
* [**Contracts**](https://docs.nado.xyz/developer-resources/api/gateway/queries/contracts): <mark style="color:red;">`IP weight = 1`</mark>
* [**Nonces**](https://docs.nado.xyz/developer-resources/api/gateway/queries/nonces): <mark style="color:red;">`IP weight = 2`</mark>
* [**Order**](https://docs.nado.xyz/developer-resources/api/gateway/queries/order)**:** <mark style="color:red;">`IP weight = 1`</mark>
* [**Orders**](https://docs.nado.xyz/developer-resources/api/gateway/queries/orders): <mark style="color:red;">`IP weight = 2 * product_ids.length`</mark>
* [**Subaccount Info**](https://docs.nado.xyz/developer-resources/api/gateway/queries/subaccount-info): <mark style="color:red;">`IP weight = 2`</mark> (or <mark style="color:red;">`10`</mark> with `txns`, or <mark style="color:red;">`15`</mark> with `txns` + `pre_state="true"`)
* [**Isolated Positions**](https://docs.nado.xyz/developer-resources/api/gateway/queries/isolated-positions): <mark style="color:red;">`IP weight = 10`</mark>
* [**Market Liquidity**](https://docs.nado.xyz/developer-resources/api/gateway/queries/market-liquidity): <mark style="color:red;">`IP weight = 1`</mark>
* [**Symbols**](https://docs.nado.xyz/developer-resources/api/gateway/queries/symbols): <mark style="color:red;">`IP weight = 2`</mark>
* [**All Products**](https://docs.nado.xyz/developer-resources/api/gateway/queries/all-products): <mark style="color:red;">`IP weight = 5`</mark>
* [**Edge All Products**](https://docs.nado.xyz/developer-resources/api/gateway/queries/edge-all-products): <mark style="color:red;">`IP weight = 5`</mark>
* [**Market Prices**](https://docs.nado.xyz/developer-resources/api/gateway/queries/market-prices)**:** <mark style="color:red;">`IP weight = product_ids.length`</mark>
* [**Max Order Size**](https://docs.nado.xyz/developer-resources/api/gateway/queries/max-order-size)**:** <mark style="color:red;">`IP weight = 5`</mark>
* [**Max Withdrawable**](https://docs.nado.xyz/developer-resources/api/gateway/queries/max-withdrawable)**:** <mark style="color:red;">`IP weight = 5`</mark>
* [**Max NLP Mintable**](https://docs.nado.xyz/developer-resources/api/gateway/queries/max-nlp-mintable)**:** <mark style="color:red;">`IP weight = 20`</mark>
* [**Max NLP Burnable**](https://docs.nado.xyz/developer-resources/api/gateway/queries/max-nlp-burnable)**:** <mark style="color:red;">`IP weight = 20`</mark>
* [**NLP Pool Info**](https://docs.nado.xyz/developer-resources/api/gateway/queries/nlp-pool-info)**:** <mark style="color:red;">`IP weight = 20`</mark>
* [**NLP Locked Balances**](https://docs.nado.xyz/developer-resources/api/gateway/queries/nlp-locked-balances)**:** <mark style="color:red;">`IP weight = 20`</mark>
* [**Health Groups**](https://docs.nado.xyz/developer-resources/api/gateway/queries/health-groups)**:** <mark style="color:red;">`IP weight = 2`</mark>
* [**Linked Signer**](https://docs.nado.xyz/developer-resources/api/gateway/queries/linked-signer)**:** <mark style="color:red;">`IP weight = 5`</mark>
* [**Insurance**](https://docs.nado.xyz/developer-resources/api/gateway/queries/insurance): <mark style="color:red;">`IP weight = 2`</mark>
* [**Fee Rates**](https://docs.nado.xyz/developer-resources/api/gateway/queries/fee-rates)**:** <mark style="color:red;">`IP weight = 2`</mark>
* [**Assets**](https://docs.nado.xyz/developer-resources/api/v2/assets): <mark style="color:red;">`IP weight = 2`</mark>
* [**Orderbook**](https://docs.nado.xyz/developer-resources/api/v2/orderbook): <mark style="color:red;">`IP weight = 1`</mark>
## Archive (indexer) Weights
* Archive (indexer) queries are rate-limited based on IP.
* IP addresses have a max weight limit of <mark style="color:red;">`2400`</mark> per minute or <mark style="color:red;">`400`</mark> every 10 seconds.
The following weights are applied per query:
* [**Orders**](https://docs.nado.xyz/developer-resources/api/archive-indexer/orders)**:** <mark style="color:red;">`IP Weight = 2 + (limit * subaccounts.length / 20)`</mark>; where <mark style="color:red;">`limit`</mark> and <mark style="color:red;">`subaccounts`</mark> are query params.
* [**Matches**](https://docs.nado.xyz/developer-resources/api/archive-indexer/matches)**:** <mark style="color:red;">`IP Weight = 2 + (limit * subaccounts.length / 10)`</mark>; where <mark style="color:red;">`limit`</mark> and <mark style="color:red;">`subaccounts`</mark> are query params.
* [**Events**](https://docs.nado.xyz/developer-resources/api/archive-indexer/events)**:** <mark style="color:red;">`IP Weight = 2 + (limit * subaccounts.length / 10)`</mark>; where <mark style="color:red;">`limit`</mark> and <mark style="color:red;">`subaccounts`</mark> are query params.
* [**Candlesticks**](https://docs.nado.xyz/developer-resources/api/archive-indexer/candlesticks)**:** <mark style="color:red;">`IP Weight = 1 + limit / 20`</mark>; where <mark style="color:red;">`limit`</mark> is a query param.
* [**Edge Candlesticks**](https://docs.nado.xyz/developer-resources/api/archive-indexer/edge-candlesticks): <mark style="color:red;">`IP Weight = 1 + limit / 20`</mark>; where <mark style="color:red;">`limit`</mark> is a query param.
* [**Product Snapshots**](https://docs.nado.xyz/developer-resources/api/archive-indexer/product-snapshots)**:** <mark style="color:red;">`IP Weight = 10`</mark> for single `products` query, or <mark style="color:red;">`10 * timestamps.length`</mark> for multiple `product_snapshots` query with max\_time parameter
* [**Funding Rate**](https://docs.nado.xyz/developer-resources/api/archive-indexer/funding-rate)**:** <mark style="color:red;">`IP Weight = 2`</mark>
* [**Interest & funding payments**](https://docs.nado.xyz/developer-resources/api/archive-indexer/interest-and-funding-payments)**:** <mark style="color:red;">`IP Weight = 5`</mark>
* [**Oracle Price**](https://docs.nado.xyz/developer-resources/api/archive-indexer/oracle-price)**:** <mark style="color:red;">`IP Weight = 2`</mark>
* [**Oracle Snapshots**](https://docs.nado.xyz/developer-resources/api/archive-indexer/oracle-snapshots): <mark style="color:red;">`IP Weight = max((snapshot_count * product_ids.length / 100), 2)`</mark>; where snapshot\_count is <mark style="color:red;">`interval.count.min(500)`</mark>
* [**Perp Prices**](https://docs.nado.xyz/developer-resources/api/archive-indexer/perp-prices)**:** <mark style="color:red;">`IP Weight = 2`</mark> (includes both single `price` and multiple `perp_prices` queries)
* [**Market Snapshots**](https://docs.nado.xyz/developer-resources/api/archive-indexer/market-snapshots)**:** <mark style="color:red;">`IP Weight = max((snapshot_count * product_ids.length / 100), 2)`</mark>; where snapshot\_count is <mark style="color:red;">`interval.count.min(500)`</mark>
* [**Edge Market Snapshots**](https://docs.nado.xyz/developer-resources/api/archive-indexer/edge-market-snapshots): <mark style="color:red;">`IP weight = (interval.count.min(500) / 20) + (interval.count.clamp(2, 20) * 2)`</mark>
* [**Subaccounts**](https://docs.nado.xyz/developer-resources/api/archive-indexer/subaccounts)**:** <mark style="color:red;">`IP Weight = 2`</mark>
* [**Subaccount Snapshots**](https://docs.nado.xyz/developer-resources/api/archive-indexer/subaccount-snapshots): <mark style="color:red;">`IP Weight = 2 + (limit * subaccounts.length / 10)`</mark>; where <mark style="color:red;">`limit`</mark> and <mark style="color:red;">`subaccounts`</mark> are query params.
* [**Linked Signers**](https://docs.nado.xyz/developer-resources/api/archive-indexer/linked-signers): <mark style="color:red;">`IP Weight = 2`</mark>
* [**Linked Signer Rate Limit**](https://docs.nado.xyz/developer-resources/api/archive-indexer/linked-signer-rate-limit)**:** <mark style="color:red;">`IP Weight = 2`</mark>
* [**Isolated Subaccounts**](https://docs.nado.xyz/developer-resources/api/archive-indexer/isolated-subaccounts): <mark style="color:red;">`IP Weight = 2`</mark>
* [**Signatures**](https://docs.nado.xyz/developer-resources/api/archive-indexer/signatures): <mark style="color:red;">`IP Weight = 2 + len(digests) / 10`</mark>; where <mark style="color:red;">`digests`</mark> is a query param.
* [**Fast Withdrawal Signature**](https://docs.nado.xyz/developer-resources/api/archive-indexer/fast-withdrawal-signature): <mark style="color:red;">`IP Weight = 10`</mark>
* [**NLP Funding Payments**](https://docs.nado.xyz/developer-resources/api/archive-indexer/nlp-funding-payments): <mark style="color:red;">`IP Weight = 5`</mark>
* [**NLP Interest Payments**](https://docs.nado.xyz/developer-resources/api/archive-indexer/nlp-interest-payments): <mark style="color:red;">`IP Weight = 5`</mark>
* [**NLP Snapshots**](https://docs.nado.xyz/developer-resources/api/archive-indexer/nlp-snapshots): <mark style="color:red;">`IP Weight = limit.min(500) / 100`</mark>; where <mark style="color:red;">`limit`</mark> is a query param.
* [**Tx Hashes**](https://docs.nado.xyz/developer-resources/api/archive-indexer/tx-hashes): <mark style="color:red;">`IP Weight = idxs.length * 2`</mark>; where <mark style="color:red;">`idxs`</mark> is an array of submission indices (max 100).
* [**Liquidation Feed**](https://docs.nado.xyz/developer-resources/api/archive-indexer/liquidation-feed)**:** <mark style="color:red;">`IP Weight = 2`</mark>
* [**Sequencer Backlog**](https://docs.nado.xyz/developer-resources/api/archive-indexer/sequencer-backlog): <mark style="color:red;">`IP Weight = 1`</mark>
* [**Direct Deposit Address**](https://docs.nado.xyz/developer-resources/api/archive-indexer/direct-deposit-address): <mark style="color:red;">`IP Weight = 10`</mark>
* [**Quote Price**](https://docs.nado.xyz/developer-resources/api/archive-indexer/quote-price): <mark style="color:red;">`IP Weight = 2`</mark>
* [**Ink Airdrop**](https://docs.nado.xyz/developer-resources/api/archive-indexer/ink-airdrop): <mark style="color:red;">`IP Weight = 2`</mark>
## Execute Weights
Executes are rate-limited based on Wallet address. The following weights are applied per execute:
* [**Place order**](https://docs.nado.xyz/developer-resources/api/gateway/executes/place-order)**:**
* With spot leverage: <mark style="color:red;">`Wallet weight = 1`</mark>
* Without spot leverage: <mark style="color:red;">`Wallet weight = 20`</mark>
* [**Place orders**](https://docs.nado.xyz/developer-resources/api/gateway/executes/place-orders)**:**
* With spot leverage: <mark style="color:red;">`Wallet weight = 1 per order`</mark>
* Without spot leverage: <mark style="color:red;">`Wallet weight = 20 per order`</mark>
* **Note**: 50ms processing penalty per request
* [**Cancel orders**](https://docs.nado.xyz/developer-resources/api/gateway/executes/cancel-orders)**:**
* When no **digests** are provided: <mark style="color:red;">`Wallet weight = 1`</mark>
* When **digests** are provided: <mark style="color:red;">`Wallet weight = total digests`</mark>
* [**Cancel Product Orders**](https://docs.nado.xyz/developer-resources/api/gateway/executes/cancel-product-orders)**:**
* When no **productIds** are provide&#x64;**:** <mark style="color:red;">`Wallet weight = 50`</mark>
* When **productIds** are provided: <mark style="color:red;">`Wallet weight = 5 * total productIds`</mark>
* [**Cancel And Place**](https://docs.nado.xyz/developer-resources/api/gateway/executes/cancel-and-place):
* The sum of [Cancel orders](https://docs.nado.xyz/developer-resources/api/gateway/executes/cancel-orders) + [Place order](https://docs.nado.xyz/developer-resources/api/gateway/executes/place-order) limits
* [**Withdraw Collateral**](https://docs.nado.xyz/developer-resources/api/gateway/executes/withdraw-collateral)**:**
* With spot leverage: <mark style="color:red;">`Wallet weight = 10`</mark>
* Without spot leverage: <mark style="color:red;">`Wallet weight = 20`</mark>
* [**Liquidate Subaccount**](https://docs.nado.xyz/developer-resources/api/gateway/executes/liquidate-subaccount): <mark style="color:red;">`Wallet weight = 20`</mark>
* [**Mint NLP**](https://docs.nado.xyz/developer-resources/api/gateway/executes/mint-nlp): <mark style="color:red;">`Wallet weight = 10`</mark>
* [**Burn NLP**](https://docs.nado.xyz/developer-resources/api/gateway/executes/burn-nlp): <mark style="color:red;">`Wallet weight = 10`</mark>
* [**Link Signer**](https://docs.nado.xyz/developer-resources/api/gateway/executes/link-signer): <mark style="color:red;">`Wallet weight = 30`</mark>
* Can only perform a max of 50 link signer requests every 7 days per subaccount.
* [**Transfer Quote:**](https://docs.nado.xyz/developer-resources/api/gateway/executes/transfer-quote) <mark style="color:red;">`Wallet weight = 10`</mark>
* Can only transfer to a max of 5 new recipients within 24hrs.
## Trigger Service Limits
The trigger service has additional limits specific to conditional orders:
* **Pending trigger orders**: Max of <mark style="color:red;">`25`</mark> pending trigger orders per product per subaccount
* **TWAP orders**: Must use IOC execution type and cannot be combined with isolated margin
@@ -0,0 +1,33 @@
# Subscriptions
## Overview
To interact with the subscription API, send websocket messages to <mark style="color:red;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>.
Subscription connections must set the `Sec-WebSocket-Extensions` header to include `permessage-deflate`.
## Endpoints
### Testnet:
* <mark style="color:red;">`wss://gateway.test.nado.xyz/v1/subscribe`</mark>
{% hint style="info" %}
**Note**: You must send ping frames every 30 seconds to keep the websocket connection alive.
{% endhint %}
{% content-ref url="subscriptions/authentication" %}
[authentication](https://docs.nado.xyz/developer-resources/api/subscriptions/authentication)
{% endcontent-ref %}
{% content-ref url="subscriptions/streams" %}
[streams](https://docs.nado.xyz/developer-resources/api/subscriptions/streams)
{% endcontent-ref %}
{% content-ref url="subscriptions/events" %}
[events](https://docs.nado.xyz/developer-resources/api/subscriptions/events)
{% endcontent-ref %}
{% content-ref url="subscriptions/rate-limits" %}
[rate-limits](https://docs.nado.xyz/developer-resources/api/subscriptions/rate-limits)
{% endcontent-ref %}
@@ -0,0 +1,82 @@
# Authentication
### Rate limits
A **single wallet address** can be authenticated by up to 5 websocket connections, regardless of the originating IP address. Connections exceeding these limits will be automatically disconnected.
{% hint style="info" %}
See [rate limits](https://docs.nado.xyz/developer-resources/api/subscriptions/rate-limits) for more details.
{% endhint %}
### Request
To access streams that require authentication, submit a request with the <mark style="color:red;">`method`</mark> field set to <mark style="color:red;">`authenticate`</mark>.
{% tabs %}
{% tab title="Authenticate" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
```json
{
"method": "authenticate",
"id": 0,
"tx": {
"sender": "0x...",
"expiration": "1..."
},
"signature": "0x..."
}
```
{% endtab %}
{% endtabs %}
### Request Parameters
<table><thead><tr><th width="198" align="center">Parameter</th><th width="142" align="center">Type</th><th width="112" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">method</td><td align="center">string</td><td align="center">Yes</td><td><mark style="color:red;"><code>authenticate</code></mark></td></tr><tr><td align="center">id</td><td align="center">number</td><td align="center">Yes</td><td>Can be set to any positive integer. Can be used to identify the websocket request / response.</td></tr><tr><td align="center">tx</td><td align="center">object</td><td align="center">Yes</td><td><mark style="color:red;"><code>StreamAuthentication</code></mark> object that needs to be signed. See <a href="#signing">Signing</a> section for more details.</td></tr><tr><td align="center">tx.sender</td><td align="center">string</td><td align="center">Yes</td><td>A hex string representing a <mark style="color:red;"><code>bytes32</code></mark> of a specific subaccount.</td></tr><tr><td align="center">tx.expiration</td><td align="center">string</td><td align="center">Yes</td><td>Represents the expiration time in milliseconds since the Unix epoch.</td></tr><tr><td align="center">signature</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing hash of the <strong>signed</strong> <mark style="color:red;"><code>StreamAuthentication</code></mark> object.See <a href="#signing">Signing</a> section for more details.</td></tr></tbody></table>
{% hint style="info" %}
**Notes**:
* Although <mark style="color:red;">sender</mark> specifies a specific subaccount, authentication applies to the entire wallet address, enabling access to authenticated streams for different subaccounts under that address.
* Once authenticated, the authentication status of that websocket connection cannot be changed and stays for the duration of the connection.
{% endhint %}
## Signing
{% hint style="info" %}
See more details and examples in our [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page.
{% endhint %}
The typed data struct that needs to be signed is:
```solidity
struct StreamAuthentication {
bytes32 sender;
uint64 expiration;
}
```
<mark style="color:red;">`sender`</mark>: A hex string representing a <mark style="color:red;">`bytes32`</mark> of a specific subaccount. The signature must be signed by the wallet address specified by sender.
<mark style="color:red;">`expiration`</mark>: Represents the expiration time in milliseconds since the Unix epoch. Requests will be denied if the expiration is either smaller than the current time or more than 100 seconds ahead of it.
{% hint style="info" %}
**Notes**:
* Should use the endpoint address as <mark style="color:red;">`verifyingContract`</mark>.
* For signing, you should always use the data type specified in the typed data struct which might be different from the type sent in the request e.g: <mark style="color:red;">`expiration`</mark> should be an <mark style="color:red;">`uint64`</mark> for **Signing** but should be sent as a <mark style="color:red;">`string`</mark> in the final payload.
{% endhint %}
### **Response**
```json
{
"result": null,
"id": 10
}
```
@@ -0,0 +1,284 @@
# Events
## **Order Update**
**Update speed: real-time**
```json
{
"type": "order_update",
// timestamp of the event in nanoseconds
"timestamp": "1695081920633151000",
"product_id": 1,
// order digest
"digest": "0xf7712b63ccf70358db8f201e9bf33977423e7a63f6a16f6dab180bdd580f7c6c",
// remaining amount to be filled.
// will be `0` if the order is either fully filled or cancelled.
"amount": "82000000000000000",
// any of: "filled", "cancelled", "placed"
"reason": "filled",
// an optional `order id` that can be provided when placing an order
"id": 100
}
```
### Example Scenarios:
Let's assume your initial order amount is 100 units and each match occurs for an amount of 10 units.
{% hint style="info" %}
**Note**: The following events only include <mark style="color:red;">`amount`</mark> and <mark style="color:red;">`reason`</mark> for simplicity.
{% endhint %}
#### Scenario 1: Limit Order Partially Fills and Gets Placed
Your limit order matches against existing orders in the book.
You will receive the following events over websocket, each with the same timestamp but in sequential order:
* Event 1: `(90, "filled")` — 10 units of your order are filled.
* Event 2: `(80, "filled")` — Another 10 units are filled.
* Event 3: `(80, "placed")` — The remaining 80 units are placed on the book.
#### Scenario 2: Immediate-Or-Cancel (IOC) Order Partially Fills
Your IOC order matches against existing orders but is not completely filled.
The events you will receive are as follows:
* Event 1: `(90, "filled")` — 10 units are filled.
* Event 2: `(80, "filled")` — Another 10 units are filled.
* Event 3: `(0, "cancelled")` — The remaining order is cancelled. **Note**: If your IOC order is fully filled, the last event you will receive is `(0, "filled")`.
#### Scenario 3: Resting Limit Order Gets Matched
Your existing, or "resting," limit order matches against an incoming order.
You will receive the following event: `(90, "filled")` — 10 units of your resting limit order are filled.
#### Scenario 4: Resting Limit Order Gets Cancelled
Your resting limit order could be cancelled for various reasons, such as manual cancellation, expiration, failing health checks, or self-trade prevention.
In any of these cases, you will receive: `(0, "cancelled")`
#### **Scenario 5: IOC order doesn't cross the book or FOK order fails to be entirely filled**
In any of these cases, you will receive: `(0, "cancelled")`
## **Trade**
**Update speed: real-time**
```json
{
"type": "trade",
"timestamp": "1676151190656903000", // timestamp of the event in nanoseconds
"product_id": 1,
"price": "1000", // price the trade happened at, multiplied by 1e18
// both taker_qty and maker_qty have the same value;
// set to filled amount (min amount of taker and maker) when matching against book
"taker_qty": "1000",
"maker_qty": "1000",
"is_taker_buyer": true
}
```
## **Best Bid Offer**
**Update speed: real-time**
```json
{
"type": "best_bid_offer",
"timestamp": "1676151190656903000", // timestamp of the event in nanoseconds
"product_id": 1,
"bid_price": "1000", // the highest bid price, multiplied by 1e18
"bid_qty": "1000", // quantity at the highest bid, multiplied by 1e18.
// i.e. if this is USDT0 with 6 decimals, one USDT0
// would be 1e12
"ask_price": "1000", // lowest ask price
"ask_qty": "1000" // quantity at the lowest ask
}
```
## **Fill**
**Update speed: real-time**
```json
{
"type": "fill",
"timestamp": "1676151190656903000", // timestamp of the event in nanoseconds
"product_id": 1,
// the subaccount that placed this order
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
// hash of the order that uniquely identifies it
"order_digest": "0xf4f7a8767faf0c7f72251a1f9e5da590f708fd9842bf8fcdeacbaa0237958fff",
// order appendix containing execution type, reduce-only flag, etc.
"appendix": "4096",
// the amount filled, multiplied by 1e18
"filled_qty": "1000",
// the amount outstanding unfilled, multiplied by 1e18
"remaining_qty": "2000",
// the original order amount, multiplied by 1e18
"original_qty": "3000",
// fill price
"price": "24991000000000000000000",
// true for `taker`, false for `maker`
"is_taker": true,
"is_bid": true,
// the amount of fee paid, multiplied by 1e18
"fee": "100",
// the submission_idx of the transaction (n_submissions - 1)
// can use to map `fills` to historical `matches`.
"submission_idx": 100,
// an optional `order id` that can be provided when placing an order
"id": 100
}
```
## **Position Change**
**Update speed: real-time**
```json
{
"type":"position_change",
"timestamp": "1676151190656903000", // timestamp of event in nanoseconds
"product_id":1,
// subaccount who's position changed
"subaccount":"0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43706d00000000000000000000",
// whether this position change is for an isolated margin position
"isolated": false,
// new amount for this product
"amount":"51007390115411548",
// new quote balance for this product; zero for everything except non lp perps
// the negative of the entry cost of the perp
"v_quote_amount":"0",
// any of: "deposit_collateral", "match_orders", "withdraw_collateral", "transfer_quote", "settle_pnl", "mint_nlp", "burn_nlp", "liquidate_subaccount"
"reason": "deposit_collateral"
}
```
{% hint style="info" %}
**Note:** that it is possible that back to back <mark style="color:red;">`position_change`</mark> events have the same fields except for <mark style="color:red;">`timestamp`</mark>. Additionally, <mark style="color:red;">`position_change`</mark> events are not sent on interest and funding payments, and also are not sent on actions done through slow mode (except deposits). The full list of actions that will trigger a <mark style="color:red;">`PositionChange`</mark> event are:
* Minting or burning NLP tokens
* Liquidating a subaccount
* Matching orders
* Depositing or withdrawing spot
* Settling PNL
{% endhint %}
## **Book Depth**
**Update speed: once every 50ms**
```json
{
"type":"book_depth",
// book depth aggregates a number of events once every 50ms
// these are the minimum and maximum timestamps from
// events that contributed to this response
"min_timestamp": "1683805381879572835",
"max_timestamp": "1683805381879572835",
// the max_timestamp of the last book_depth event for this product
"last_max_timestamp": "1683805381771464799",
"product_id":1,
// changes to the bid side of the book in the form of [[price, new_qty]]
"bids":[["21594490000000000000000","51007390115411548"]],
// changes to the ask side of the book in the form of [[price, new_qty]]
"asks":[["21694490000000000000000","0"],["21695050000000000000000","0"]]
}
```
{% hint style="info" %}
**Note**: To keep an updated local orderbook, do the following:
1. Subscribe to the `book_depth` stream and queue up events.
2. Get a market data snapshot by calling [MarketLiquidity](https://docs.vertexprotocol.com/developer-resources/api/gateway/queries/market-liquidity). The snapshot contains a `timestamp` in the response.
3. Apply events with `max_timestamp` > snapshot `timestamp`.
4. When you receive an event where its `last_max_timestamp` is not equal to the `max_timestamp` of the last event you've received, it means some events were lost and you should repeat 1-3 again.
{% endhint %}
## **Liquidation**
**Update speed: real-time**
```json
{
"type": "liquidation",
"timestamp": "1234567890000", // timestamp of the event in nanoseconds
// single element for regular liquidations, two elements for spread liquidations (spot_id, perp_id)
"product_ids": [1],
// liquidator subaccount (32 bytes)
"liquidator": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
// liquidatee subaccount (32 bytes)
"liquidatee": "0x8b6fd3859f7065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
// amount liquidated (positive for long, negative for short)
"amount": "1000000000000000000",
// price at which liquidation occurred
"price": "50000000000000000000"
}
```
## Latest Candlestick
**Update speed: real-time**
```json
{
"type": "latest_candlestick",
"timestamp": 1234567890000,
"product_id": 1,
"granularity": 60,
"open_x18": "50000000000000000000",
"high_x18": "51000000000000000000",
"low_x18": "49000000000000000000",
"close_x18": "50500000000000000000",
"volume": "1000000000000000000"
}
```
## Funding Payment
**Update speed: real-time at the time of payment (payments happen hourly).**
```json
{
"type": "funding_payment",
"timestamp": 1234567890000,
"product_id": 1,
// funding payment amount (positive = receive, negative = pay)
"payment_amount": "1000000000000000000",
// open interest at time of funding
"open_interest": "50000000000000000000",
// cumulative funding values, multiplied by 1e18
"cumulative_funding_long_x18": "100000000000000000",
"cumulative_funding_short_x18": "-100000000000000000",
// time delta over which the funding payment was calculated
"dt": 3600000
}
```
## Funding Rate
**Update speed: real-time (updates occur every 20 seconds).**
{% hint style="info" %}
**Note**: The `funding_rate_x18` and `update_time` values are identical to those returned by the [Funding Rate](https://docs.nado.xyz/developer-resources/api/archive-indexer/funding-rate) indexer endpoint.
{% endhint %}
```json
{
"type": "funding_rate",
// timestamp when the event was generated, in nanoseconds
"timestamp": "1234567890123456789",
"product_id": 1,
// latest 24hr funding rate, multiplied by 1e18
"funding_rate_x18": "50000000000000000",
// timestamp when the funding rate was updated, in seconds
"update_time": "1234567890"
}
```
@@ -0,0 +1,3 @@
# Rate limits
Each IP address is restricted to a maximum of **100** active websocket connections. Additionally, a **single wallet address** can be authenticated by up to **5** websocket connections, regardless of the originating IP address. Connections exceeding these limits will be automatically disconnected.
@@ -0,0 +1,538 @@
# Streams
## Available Streams
See below the available streams you can subscribe to:
```rust
pub enum StreamSubscription {
// pass `null` product_id to subscribe to all products
OrderUpdate { product_id: Option<u32>, subaccount: H256 },
Trade { product_id: u32 },
BestBidOffer { product_id: u32 },
// pass `null` product_id to subscribe to all products
Fill { product_id: Option<u32>, subaccount: H256 },
// pass `null` product_id to subscribe to all products
PositionChange { product_id: Option<u32>, subaccount: H256},
BookDepth { product_id: u32 },
// pass `null` product_id to subscribe to all products
Liquidation { product_id: Option<u32> },
LatestCandlestick {
product_id: u32,
// time interval in seconds (e.g., 60, 300, 900, 3600)
granularity: i32
},
FundingPayment { product_id: u32 },
// pass `null` product_id to subscribe to all products
FundingRate { product_id: Option<u32> }
}
```
## **Subscribing to a stream**
{% tabs %}
{% tab title="Order Update" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
*Requires Authentication: Yes.*
{% hint style="info" %}
**Note**: Set <mark style="color:red;">`product_id`</mark> to <mark style="color:red;">`null`</mark> to subscribe to order updates across all products for the subaccount.
{% endhint %}
```json
{
"method": "subscribe",
"stream": {
"type": "order_update",
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"product_id": 1
},
"id": 10
}
```
**Subscribe to all products:**
```json
{
"method": "subscribe",
"stream": {
"type": "order_update",
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"product_id": null
},
"id": 10
}
```
{% endtab %}
{% tab title="Trade" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
*Requires Authentication: No.*
```json
{
"method": "subscribe",
"stream": {
"type": "trade",
"product_id": 0
},
"id": 10
}
```
{% endtab %}
{% tab title="Best Bid Offer" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
*Requires Authentication: No.*
```json
{
"method": "subscribe",
"stream": {
"type": "best_bid_offer",
"product_id": 0
},
"id": 10
}
```
{% endtab %}
{% endtabs %}
{% tabs %}
{% tab title="Fill" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
*Requires Authentication: No.*
{% hint style="info" %}
**Note**: Set <mark style="color:red;">`product_id`</mark> to <mark style="color:red;">`null`</mark> to subscribe to fills across all products for the subaccount.
{% endhint %}
```json
{
"method": "subscribe",
"stream": {
"type": "fill",
"product_id": 1,
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000"
},
"id": 10
}
```
**Subscribe to all products:**
```json
{
"method": "subscribe",
"stream": {
"type": "fill",
"product_id": null,
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000"
},
"id": 10
}
```
{% endtab %}
{% tab title="Position Change" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
*Requires Authentication: No.*
{% hint style="info" %}
**Note**: Set <mark style="color:red;">`product_id`</mark> to <mark style="color:red;">`null`</mark> to subscribe to position changes across all products for the subaccount.
{% endhint %}
```json
{
"method": "subscribe",
"stream": {
"type": "position_change",
"product_id": 0,
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000"
},
"id": 10
}
```
**Subscribe to all products:**
```json
{
"method": "subscribe",
"stream": {
"type": "position_change",
"product_id": null,
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000"
},
"id": 10
}
```
{% endtab %}
{% tab title="Book Depth" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
*Requires Authentication: No.*
```json
{
"method": "subscribe",
"stream": {
"type": "book_depth",
"product_id": 0
},
"id": 10
}
```
{% endtab %}
{% endtabs %}
{% tabs %}
{% tab title="Liquidation" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
*Requires Authentication: No.*
{% hint style="info" %}
**Note**: Set <mark style="color:red;">`product_id`</mark> to <mark style="color:red;">`null`</mark> to subscribe to liquidations across all products.
{% endhint %}
```json
{
"method": "subscribe",
"stream": {
"type": "liquidation",
"product_id": 1
},
"id": 10
}
```
**Subscribe to all products:**
```json
{
"method": "subscribe",
"stream": {
"type": "liquidation",
"product_id": null
},
"id": 10
}
```
{% endtab %}
{% tab title="Latest Candlestick" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
{% hint style="info" %}
See all supportes <mark style="color:red;">`granularity`</mark> values in [Available Granularities](https://docs.nado.xyz/developer-resources/archive-indexer/candlesticks#available-granularities)
{% endhint %}
*Requires Authentication: No.*
```json
{
"method": "subscribe",
"stream": {
"type": "latest_candlestick",
"product_id": 1,
"granularity": 60
},
"id": 10
}
```
{% endtab %}
{% tab title="Funding Payment" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
*Requires Authentication: No.*
```json
{
"method": "subscribe",
"stream": {
"type": "funding_payment",
"product_id": 2
},
"id": 10
}
```
{% endtab %}
{% tab title="Funding Rate" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
*Requires Authentication: No.*
{% hint style="info" %}
**Note**: Set <mark style="color:red;">`product_id`</mark> to <mark style="color:red;">`null`</mark> to subscribe to funding rate updates across all products.
{% endhint %}
```json
{
"method": "subscribe",
"stream": {
"type": "funding_rate",
"product_id": 2
},
"id": 10
}
```
**Subscribe to all products:**
```json
{
"method": "subscribe",
"stream": {
"type": "funding_rate",
"product_id": null
},
"id": 10
}
```
{% endtab %}
{% endtabs %}
### **Response**
```json
{
"result": null,
"id": 10
}
```
## **Unsubscribing**
{% tabs %}
{% tab title="Order Update" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
```json
{
"method": "unsubscribe",
"stream": {
"type": "order_update",
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"product_id": 1
},
"id": 10
}
```
**Unsubscribe from all products:**
```json
{
"method": "unsubscribe",
"stream": {
"type": "order_update",
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"product_id": null
},
"id": 10
}
```
{% endtab %}
{% tab title="Trade" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
```json
{
"method": "unsubscribe",
"stream": {
"type": "trade",
"product_id": 0
},
"id": 10
}
```
{% endtab %}
{% tab title="Best Bid Offer" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
```json
{
"method": "unsubscribe",
"stream": {
"type": "best_bid_offer",
"product_id": 0
},
"id": 10
}
```
{% endtab %}
{% tab title="Fill" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
```json
{
"method": "unsubscribe",
"stream": {
"type": "fill",
"product_id": 0,
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000"
},
"id": 10
}
```
{% endtab %}
{% tab title="Position Change" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
```json
{
"method": "unsubscribe",
"stream": {
"type": "position_change",
"product_id": 0,
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000"
},
"id": 10
}
```
{% endtab %}
{% tab title="Book Depth" %}
**Connect**
<mark style="color:orange;">`WEBSOCKET [SUBSCRIPTIONS_ENDPOINT]`</mark>
**Message**
```json
{
"method": "unsubscribe",
"stream": {
"type": "book_depth",
"product_id": 0,
},
"id": 10
}
```
{% endtab %}
{% endtabs %}
### **Response**
```json
{
"result": null,
"id": 10
}
```
## **Listing subscribed streams**
```json
{
"method": "list",
"id": 10
}
```
### Response
```json
{
"result": [
{
"type": "default"
},
{
"type": "trade",
"product_id": 0
}
],
"id": 10
}
```
@@ -0,0 +1,80 @@
# Symbols
## Request
{% tabs %}
{% tab title="REST" %} <mark style="color:green;">**GET**</mark> `[GATEWAY_REST_ENDPOINT]/symbols`
{% endtab %}
{% endtabs %}
## Response
```json
[
{
"product_id": 0,
"symbol": "USDT0",
"delisted": false
},
{
"product_id": 1,
"symbol": "KBTC",
"delisted": false
},
{
"product_id": 2,
"symbol": "BTC-PERP",
"delisted": false
},
{
"product_id": 3,
"symbol": "WETH",
"delisted": false
},
{
"product_id": 4,
"symbol": "ETH-PERP",
"delisted": false
},
{
"product_id": 5,
"symbol": "USDC",
"delisted": false
},
{
"product_id": 8,
"symbol": "SOL-PERP",
"delisted": false
},
{
"product_id": 10,
"symbol": "XRP-PERP",
"delisted": false
},
{
"product_id": 14,
"symbol": "BNB-PERP",
"delisted": false
},
{
"product_id": 16,
"symbol": "HYPE-PERP",
"delisted": false
},
{
"product_id": 18,
"symbol": "ZEC-PERP",
"delisted": false
},
{
"product_id": 20,
"symbol": "MON-PERP",
"delisted": false
},
{
"product_id": 22,
"symbol": "FARTCOIN-PERP",
"delisted": false
}
]
```
@@ -0,0 +1,65 @@
# Trigger
The trigger service enables sophisticated order execution strategies through conditional triggers:
## Order Types
### **Price Triggers**
Execute orders when price conditions are met:
* **Stop orders**: Trigger when price moves above or below a threshold
* **Take profit/Stop loss**: Automated position management
* **Support multiple price sources**: Oracle price, last trade price, or mid-book price
### **Time Triggers (TWAP)**
Execute large orders over time using Time-Weighted Average Price:
* **Split large orders**: Break into smaller executions to reduce market impact
* **Configurable intervals**: Set time between executions
* **Slippage protection**: Built-in slippage limits for each execution
* **Custom amounts**: Specify exact amounts for each execution or split evenly
## API Structure
There are two types of actions:
* <mark style="color:red;">`Execute`</mark>: Modifies state (place/cancel orders)
* <mark style="color:red;">`Query`</mark>: Fetches information (list orders, TWAP status)
**HTTP Endpoints:**
* <mark style="color:red;">`POST [TRIGGER_ENDPOINT]/execute`</mark> for order placement and cancellation
* <mark style="color:red;">`POST [TRIGGER_ENDPOINT]/query`</mark> for querying trigger order status
<mark style="color:red;">`HTTP`</mark> requests must set the `Accept-Encoding` to include `gzip`, `br` or `deflate`
## Rate Limits
* **Maximum pending orders**: 25 pending trigger orders per product per subaccount
* **TWAP constraints**: Must use IOC execution type, cannot combine with isolated margin
## Key Requirements
### **Order Appendix Configuration**
All trigger orders require proper [Order Appendix](https://docs.nado.xyz/developer-resources/api/order-appendix) configuration:
* **Trigger type**: Specify price (1), TWAP (2), or TWAP with custom amounts (3) in appendix bits
* **Execution type**: TWAP orders **must** use IOC execution
* **TWAP parameters**: Encode execution count and slippage limits in appendix value field
## Endpoints
### Testnet:
* <mark style="color:red;">`https://trigger.test.nado.xyz/v1`</mark>
{% content-ref url="trigger/executes" %}
[executes](https://docs.nado.xyz/developer-resources/api/trigger/executes)
{% endcontent-ref %}
{% content-ref url="trigger/queries" %}
[queries](https://docs.nado.xyz/developer-resources/api/trigger/queries)
{% endcontent-ref %}
@@ -0,0 +1,34 @@
# Executes
## Overview
All executes go through the following endpoint; the exact details of the execution are specified by the JSON payload.
* **REST**: <mark style="color:orange;">`POST [TRIGGER_ENDPOINT]/execute`</mark>
## API Response
All `Execute` messages return the following information:
```json
{
"status": "success" | "failure",
"error"?: "{error_msg}",
"error_code"?: {error_code},
"request_type": "{request_type}",
}
```
## Available Executes:
{% content-ref url="executes/place-order" %}
[place-order](https://docs.nado.xyz/developer-resources/api/trigger/executes/place-order)
{% endcontent-ref %}
{% content-ref url="executes/cancel-orders" %}
[cancel-orders](https://docs.nado.xyz/developer-resources/api/trigger/executes/cancel-orders)
{% endcontent-ref %}
{% content-ref url="executes/cancel-product-orders" %}
[cancel-product-orders](https://docs.nado.xyz/developer-resources/api/trigger/executes/cancel-product-orders)
{% endcontent-ref %}
@@ -0,0 +1,54 @@
# Cancel Orders
## Request
{% tabs %}
{% tab title="REST" %} <mark style="color:orange;">`POST [TRIGGER_ENDPOINT]/execute`</mark>
**Body**
```json
{
"cancel_orders": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"productIds": [0],
"digests": ["0x"],
"nonce": "1"
},
"signature": "0x"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
See [Core > Executes > Cancel Orders](https://docs.nado.xyz/developer-resources/gateway/executes/cancel-orders#request-parameters)
## Response
#### Success
```json
{
"status": "success",
"signature": {signature},
"request_type": "execute_cancel_orders"
}
```
#### Failure
```json
{
"status": "failure",
"signature": {signature},
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "execute_cancel_orders"
}
```
@@ -0,0 +1,53 @@
# Cancel Product Orders
## Request
{% tabs %}
{% tab title="REST" %} <mark style="color:orange;">`POST [TRIGGER_ENDPOINT]/execute`</mark>
**Body**
```json
{
"cancel_product_orders": {
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"productIds": [0],
"nonce": "1"
},
"signature": "0x",
"digest": "0x"
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
See [Core > Executes > Cancel Product Orders](https://docs.nado.xyz/developer-resources/gateway/executes/cancel-product-orders#request-parameters)
## Response
#### Success
```json
{
"status": "success",
"signature": {signature},
"request_type": "execute_cancel_product_orders"
}
```
#### Failure
```json
{
"status": "failure",
"signature": {signature},
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "execute_cancel_product_orders"
}
```
@@ -0,0 +1,240 @@
# Place Order
## Rate limits
* A max of 25 pending trigger orders per product per subaccount
{% hint style="info" %}
See more details in [Trigger Service Limits](https://docs.nado.xyz/developer-resources/rate-limits#trigger-service-limits).
{% endhint %}
## Request
{% tabs %}
{% tab title="Price Trigger" %} <mark style="color:orange;">`POST [TRIGGER_ENDPOINT]/execute`</mark>
**Body**
```json
{
"place_order": {
"product_id": 1,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "9900000000000000000000",
"amount": "1000000000000000000",
"expiration": "4294967295",
"nonce": "1757062078359666688"
},
"trigger": {
"price_trigger": {
"price_requirement": {
"oracle_price_below": "9900000000000000000000"
}
}
},
"signature": "0x",
"id": 100
}
}
```
{% endtab %}
{% tab title="TWAP Trigger" %} <mark style="color:orange;">`POST [TRIGGER_ENDPOINT]/execute`</mark>
**Body**
```json
{
"place_order": {
"product_id": 1,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "9900000000000000000000",
"amount": "5000000000000000000",
"expiration": "4294967295",
"nonce": "1757062078359666688",
"appendix": "21474836490"
},
"trigger": {
"time_trigger": {
"interval": 30,
"amounts": ["1000000000000000000", "1000000000000000000", "1000000000000000000", "1000000000000000000", "1000000000000000000"]
}
},
"signature": "0x",
"id": 100
}
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="180" align="center">Parameter</th><th width="94" align="center">Type</th><th width="112" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of spot / perp product for which to place order. Use <a href="../../gateway/queries/all-products">All products</a> query to retrieve all valid product ids.</td></tr><tr><td align="center">order</td><td align="center">object</td><td align="center">Yes</td><td>Order object, see <a href="../../../gateway/executes/place-order#signing">Signing</a> section for details on each order field.</td></tr><tr><td align="center">signature</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing hash of the <strong>signed</strong> order. See <a href="../../../gateway/executes/place-order#signing">Signing</a> section for more details.</td></tr><tr><td align="center">trigger</td><td align="center">object</td><td align="center">Yes</td><td>Trigger criteria can be either:<br><strong>Price-based:</strong> <mark style="color:red;"><code>{"price_trigger": {"price_requirement": {"oracle_price_above": "{PRICE}"}}}</code></mark><br><strong>Time-based (TWAP):</strong> <mark style="color:red;"><code>{"time_trigger": {"interval": {SECONDS}, "amounts": ["{AMOUNT1}", "{AMOUNT2}", ...]}}</code></mark></td></tr><tr><td align="center">digest</td><td align="center">string</td><td align="center">No</td><td>Hex string representing a hash of the order.</td></tr><tr><td align="center">spot_leverage</td><td align="center">boolean</td><td align="center">No</td><td>Indicates whether leverage should be used; when set to <mark style="color:red;"><code>false</code></mark> , placing the order fails if the transaction causes a borrow on the subaccount. Defaults to <mark style="color:red;"><code>true</code></mark>.</td></tr><tr><td align="center">id</td><td align="center">number</td><td align="center">No</td><td>An optional id that when provided is returned as part of <mark style="color:red;"><code>Fill</code></mark> and <mark style="color:red;"><code>OrderUpdate</code></mark> stream events when the order is triggered / executed. See <a href="../../gateway/executes/place-order">gateway > place order</a> and <a href="../../subscriptions">subscriptions</a> for more details.</td></tr></tbody></table>
{% hint style="info" %}
**Price Trigger Options:**
* <mark style="color:red;">`oracle_price_above`</mark>: Order is triggered if the oracle price is above or at the indicated price.
* <mark style="color:red;">`oracle_price_below`</mark>: Order is triggered if the oracle price is below or at the indicated price.
* <mark style="color:red;">`last_price_above`</mark>: Order is triggered if the last trade price is above or at the indicated price.
* <mark style="color:red;">`last_price_below`</mark>: Order is triggered if the last trade price is below or at the indicated price.
* <mark style="color:red;">`mid_price_above`</mark>: Order is triggered if the mid book price is above or at the indicated price.
* <mark style="color:red;">`mid_price_below`</mark>: Order is triggered if the mid book price is below or at the indicated price.
**TWAP (Time-Weighted Average Price) Trigger:**
* <mark style="color:red;">`time_trigger`</mark>: Executes orders at regular intervals over time.
* <mark style="color:red;">`interval`</mark>: Time in seconds between each execution.
* <mark style="color:red;">`amounts`</mark>: Optional array specifying the exact amount for each execution. If not provided, the total order amount is split evenly across executions.
* **TWAP orders must use IOC (Immediate or Cancel) execution type only**
* **TWAP orders cannot be combined with isolated margin**
* Use the <mark style="color:red;">`list_twap_executions`</mark> query to track individual execution statuses.
{% endhint %}
## Trigger Order Dependencies
**Price triggers** can optionally depend on other orders being filled first. This allows creating complex order chains where one trigger only activates after another order executes.
**Dependency Configuration:**
```json
{
"trigger": {
"price_trigger": {
"price_requirement": {
"oracle_price_above": "50000000000000000000000"
},
"dependency": {
"digest": "0x1234567890abcdef1234567890abcdef12345678",
"on_partial_fill": false
}
}
}
}
```
**Parameters:**
* <mark style="color:red;">`digest`</mark>: The order digest (32-byte hex string) that must be filled before this trigger activates
* <mark style="color:red;">`on_partial_fill`</mark>:
* `true`: Trigger activates when the dependency order is partially filled
* `false`: Trigger only activates when the dependency order is completely filled
**Important Notes:**
* Dependencies are **only supported for price triggers**, not TWAP orders
* Dependency orders can be regular orders or other trigger orders
* Circular dependencies are not allowed
* If a dependency order is cancelled, the dependent trigger order is also cancelled
**Use Cases:**
* **Take profit after stop loss**: Set a take profit order that only triggers after a stop loss executes
* **Scaling strategies**: Execute multiple orders in sequence based on fills
* **Complex exit strategies**: Chain multiple conditional exits together
## Constructing Order Appendix
{% hint style="warning" %}
**CRITICAL**: The order <mark style="color:red;">`appendix`</mark> field must be correctly configured for trigger orders. The appendix is a 128-bit integer sent as a string.
{% endhint %}
### Using Python SDK (Recommended)
```python
from nado_protocol.utils.appendix import build_appendix
from nado_protocol.utils.appendix import OrderAppendixTriggerType
# Price trigger order
appendix = build_appendix(
order_type=0, # DEFAULT
trigger_type=OrderAppendixTriggerType.PRICE
)
# Result: "4096"
# TWAP order: 5 executions, 1% slippage (must use IOC)
appendix = build_appendix(
order_type=1, # IOC (required for TWAP)
trigger_type=OrderAppendixTriggerType.TWAP,
twap_times=5,
twap_slippage_frac=0.01
)
# Result: "21474841600"
```
### Manual Bit Manipulation
```python
def build_trigger_appendix(trigger_type, order_type=0, twap_times=0, twap_slippage_frac=0.0):
appendix = 0
# Version (bits 0-7): Always 0
appendix |= 0
# Order type (bits 9-10): 0=DEFAULT, 1=IOC (required for TWAP)
appendix |= (order_type & 0b11) << 9
# Trigger type (bits 12-13): 1=PRICE, 2=TWAP, 3=TWAP_CUSTOM_AMOUNTS
appendix |= (trigger_type & 0b11) << 12
# TWAP configuration in value field (bits 32-127)
if trigger_type == 2 or trigger_type == 3: # TWAP or TWAP_CUSTOM_AMOUNTS
slippage_x6 = int(twap_slippage_frac * 1_000_000)
value = (twap_times & ((1 << 32) - 1)) | ((slippage_x6 & ((1 << 32) - 1)) << 32)
appendix |= (value & ((1 << 96) - 1)) << 32
return str(appendix)
# Examples:
price_appendix = build_trigger_appendix(1) # Price trigger
# Result: "4096"
twap_appendix = build_trigger_appendix(2, 1, 5, 0.01) # TWAP: IOC, 5 times, 1% slippage
# Result: "21474841600"
twap_custom = build_trigger_appendix(3, 1, 10, 0.005) # TWAP_CUSTOM_AMOUNTS: IOC, 10 times, 0.5% slippage
# Result: "42949678080"
```
{% hint style="info" %}
**Important constraints:**
* TWAP orders **must** use IOC (order\_type=1) execution
* TWAP orders **cannot** be combined with isolated margin
* For complete appendix encoding specification, see [Order Appendix](https://docs.nado.xyz/developer-resources/api/order-appendix) documentation
{% endhint %}
## Response
#### Success
```json
{
"status": "success",
"signature": {signature},
"data": {
"digest": {order digest}
},
"request_type": "execute_place_order"
"id": 100
}
```
#### Failure
```json
{
"status": "failure",
"signature": {signature},
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "execute_place_order"
}
```
@@ -0,0 +1,179 @@
# Place Orders
Place multiple trigger orders in a single request. This is more efficient than placing orders individually and allows for better control over batch trigger order placement.
## Rate limits
* A max of 25 pending trigger orders per product per subaccount
{% hint style="info" %}
See more details in [Trigger Service Limits](https://docs.nado.xyz/developer-resources/rate-limits#trigger-service-limits).
{% endhint %}
{% hint style="warning" %}
**Important**: All orders in a batch must belong to the same subaccount. Orders with different senders will be rejected.
{% endhint %}
## Request
<mark style="color:orange;">`POST [TRIGGER_ENDPOINT]/execute`</mark>
### Body
```json
{
"place_orders": {
"orders": [
{
"product_id": 2,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "100000000000000000000000",
"amount": "1000000000000000000",
"expiration": "4294967295",
"nonce": "1757062078359666688",
"appendix": "4096"
},
"trigger": {
"price_trigger": {
"price_requirement": {
"oracle_price_below": "100000000000000000000000"
}
}
},
"signature": "0x...",
"id": 100
},
{
"product_id": 3,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "3800000000000000000000",
"amount": "2000000000000000000",
"expiration": "4294967295",
"nonce": "1757062078359666689",
"appendix": "4096"
},
"trigger": {
"price_trigger": {
"price_requirement": {
"oracle_price_above": "3800000000000000000000"
}
}
},
"signature": "0x...",
"id": 101
}
],
"stop_on_failure": false
}
}
```
## Request Parameters
<table><thead><tr><th width="200" align="center">Parameter</th><th width="94" align="center">Type</th><th width="112" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">orders</td><td align="center">array</td><td align="center">Yes</td><td>Array of trigger order objects to place. Each order follows the same structure as <a href="place-order">Place Order</a>. <strong>All orders must have the same sender</strong>.</td></tr><tr><td align="center">orders[].product_id</td><td align="center">number</td><td align="center">Yes</td><td>Id of spot / perp product for which to place order.</td></tr><tr><td align="center">orders[].order</td><td align="center">object</td><td align="center">Yes</td><td>Order object (same structure as single order placement).</td></tr><tr><td align="center">orders[].trigger</td><td align="center">object</td><td align="center">Yes</td><td>Trigger criteria - either price_trigger or time_trigger. See <a href="place-order">Place Order</a> for details.</td></tr><tr><td align="center">orders[].signature</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing hash of the <strong>signed</strong> order.</td></tr><tr><td align="center">orders[].digest</td><td align="center">string</td><td align="center">No</td><td>Hex string representing a hash of the order.</td></tr><tr><td align="center">orders[].spot_leverage</td><td align="center">boolean</td><td align="center">No</td><td>Indicates whether leverage should be used for this order. Defaults to <mark style="color:red;"><code>true</code></mark>.</td></tr><tr><td align="center">orders[].id</td><td align="center">number</td><td align="center">No</td><td>An optional id returned in <mark style="color:red;"><code>Fill</code></mark> and <mark style="color:red;"><code>OrderUpdate</code></mark> events.</td></tr><tr><td align="center">stop_on_failure</td><td align="center">boolean</td><td align="center">No</td><td>If <mark style="color:red;"><code>true</code></mark>, stops processing remaining orders when the first order fails. Already successfully placed orders are NOT cancelled. Defaults to <mark style="color:red;"><code>false</code></mark>.</td></tr></tbody></table>
## Response
```json
{
"status": "success",
"data": {
"place_orders": [
{
"digest": "0x1234...",
"error": null
},
{
"digest": null,
"error": "Max trigger orders limit reached"
}
]
}
}
```
### Response Fields
<table><thead><tr><th width="200">Field</th><th>Description</th></tr></thead><tbody><tr><td>digest</td><td>Order digest (32-byte hash) if successfully placed, <mark style="color:red;"><code>null</code></mark> if failed.</td></tr><tr><td>error</td><td>Error message if order failed, <mark style="color:red;"><code>null</code></mark> if successful.</td></tr></tbody></table>
## Behavior
* **Partial Success**: By default, orders are processed independently. Some orders may succeed while others fail.
* **Stop on Failure**: Set `stop_on_failure: true` to stop processing remaining orders when the first order fails. Already successfully placed orders remain active.
* **Same Sender Required**: All orders in a batch must have the same sender. Mixed sender batches will be rejected with `BatchSenderMismatch` error.
* **Order Signing**: Each order must be individually signed using EIP712 (see [Signing](https://github.com/nadohq/nado-docs/blob/main/docs/developer-resources/api/gateway/executes/signing/README.md) for details).
* **Per-Order Limits**: The 25 pending trigger orders per product per subaccount limit applies to each order individually.
## Use Cases
* **Multi-Market Stop Losses**: Set stop loss triggers across multiple products simultaneously
* **Bracket Orders**: Place both take profit and stop loss triggers together
* **Conditional Exits**: Create multiple exit strategies across different products
## Example
Placing stop loss triggers for BTC and ETH perps:
```javascript
const placeTriggerOrdersParams = {
orders: [
{
product_id: 2, // BTC-PERP
order: {
sender: subaccount,
priceX18: toX18(95000), // Stop at $95k
amount: toX18(-0.1), // Sell 0.1 BTC
expiration: getExpiration(OrderType.DEFAULT),
nonce: genOrderNonce(),
appendix: buildAppendix({
order_type: 0,
trigger_type: OrderAppendixTriggerType.PRICE
})
},
trigger: {
price_trigger: {
price_requirement: {
oracle_price_below: toX18(95000)
}
}
},
signature: await signOrder(btcOrder),
id: 1
},
{
product_id: 3, // ETH-PERP
order: {
sender: subaccount, // Must be same sender
priceX18: toX18(3600), // Stop at $3.6k
amount: toX18(-1), // Sell 1 ETH
expiration: getExpiration(OrderType.DEFAULT),
nonce: genOrderNonce(),
appendix: buildAppendix({
order_type: 0,
trigger_type: OrderAppendixTriggerType.PRICE
})
},
trigger: {
price_trigger: {
price_requirement: {
oracle_price_below: toX18(3600)
}
}
},
signature: await signOrder(ethOrder),
id: 2
}
],
stop_on_failure: false
};
const response = await triggerClient.execute({ place_orders: placeTriggerOrdersParams });
```
## See Also
* [Place Order](https://docs.nado.xyz/developer-resources/api/trigger/executes/place-order) - Single trigger order placement
* [Cancel Orders](https://docs.nado.xyz/developer-resources/api/trigger/executes/cancel-orders) - Cancel multiple trigger orders
* [List Trigger Orders](https://docs.nado.xyz/developer-resources/api/trigger/queries/list-trigger-orders) - Query active trigger orders
@@ -0,0 +1,29 @@
# Queries
All queries go through the following endpoint; the exact details of the query are specified by the JSON payload.
* **REST**: <mark style="color:orange;">`POST [TRIGGER_ENDPOINT]/query`</mark>
## API Response
All `queries` return in the format:
```json
{
"status": "success" | "failure",
"data"?: {data},
"error"?: "{error_msg}",
"error_code"?: {error_code},
"request_type": "{request_type}"
}
```
## Available Queries:
{% content-ref url="queries/list-trigger-orders" %}
[list-trigger-orders](https://docs.nado.xyz/developer-resources/api/trigger/queries/list-trigger-orders)
{% endcontent-ref %}
{% content-ref url="queries/list-twap-executions" %}
[list-twap-executions](https://docs.nado.xyz/developer-resources/api/trigger/queries/list-twap-executions)
{% endcontent-ref %}
@@ -0,0 +1,181 @@
# List Trigger Orders
## Request
{% tabs %}
{% tab title="Basic query" %} <mark style="color:orange;">`POST [TRIGGER_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "list_trigger_orders",
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"recvTime": "1688768157050"
},
"signature": "0x",
"product_ids": [1, 2],
"max_update_time": 1688768157,
"limit": 20
}
```
{% endtab %}
{% tab title="Fetch by digest" %} <mark style="color:orange;">`POST [TRIGGER_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "list_trigger_orders",
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"recvTime": "1688768157050"
},
"signature": "0x",
"digests": ["0x5886d5eee7dc4879c7f8ed1222fdbbc0e3681a14c1e55d7859515898c7bd2038"],
"limit": 20
}
```
{% endtab %}
{% tab title="Filter by type and status" %} <mark style="color:orange;">`POST [TRIGGER_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "list_trigger_orders",
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"recvTime": "1688768157050"
},
"signature": "0x",
"trigger_types": ["time_trigger"],
"status_types": ["twap_executing", "waiting_price"],
"product_ids": [1, 2, 3],
"limit": 50
}
```
{% endtab %}
{% tab title="Filter by reduce-only" %} <mark style="color:orange;">`POST [TRIGGER_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "list_trigger_orders",
"tx": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"recvTime": "1688768157050"
},
"signature": "0x",
"reduce_only": true,
"product_ids": [1, 2],
"limit": 20
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
{% hint style="info" %}
**Note**: `max_update_time` It's the time that the trigger order last changed state. For example, if a trigger order is placed & pending, the update time = time of placement. If the trigger order is cancelled, then the update time = time of cancellation.
{% endhint %}
<table><thead><tr><th width="201" align="center">Parameter</th><th width="128" align="center">Type</th><th width="129" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">tx</td><td align="center">object</td><td align="center">Yes</td><td>List trigger orders transaction object. See <a href="#signing">Signing</a> section for details on the transaction fields.</td></tr><tr><td align="center">tx.sender</td><td align="center">string</td><td align="center">Yes</td><td>Hex string representing the subaccount's 32 bytes (address + subaccount name) of the tx sender.</td></tr><tr><td align="center">tx.recvTime</td><td align="center">string</td><td align="center">Yes</td><td>Encoded time in milliseconds after which the list trigger orders transaction will be ignored. cannot be more than 100 seconds from the time it is received by the server.</td></tr><tr><td align="center">signature</td><td align="center">string</td><td align="center">Yes</td><td>Signed transaction. See <a href="#signing">Signing</a> section for more details.</td></tr><tr><td align="center">product_ids</td><td align="center">number[]</td><td align="center">No</td><td>If provided, returns trigger orders for the specified products; otherwise, returns trigger orders for all products.</td></tr><tr><td align="center">trigger_types</td><td align="center">string[]</td><td align="center">No</td><td>If provided, filters by trigger type. Values: <mark style="color:red;"><code>price_trigger</code></mark>, <mark style="color:red;"><code>time_trigger</code></mark>.</td></tr><tr><td align="center">status_types</td><td align="center">string[]</td><td align="center">No</td><td>If provided, filters by order status. Values: <mark style="color:red;"><code>cancelled</code></mark>, <mark style="color:red;"><code>triggered</code></mark>, <mark style="color:red;"><code>internal_error</code></mark>, <mark style="color:red;"><code>triggering</code></mark>, <mark style="color:red;"><code>waiting_price</code></mark>, <mark style="color:red;"><code>waiting_dependency</code></mark>, <mark style="color:red;"><code>twap_executing</code></mark>, <mark style="color:red;"><code>twap_completed</code></mark>.</td></tr><tr><td align="center">max_update_time</td><td align="center">number</td><td align="center">No</td><td>If provided, returns all trigger orders that were last updated up to <mark style="color:red;"><code>max_update_time</code></mark>. must be a unix epoch in seconds.</td></tr><tr><td align="center">max_digest</td><td align="center">string</td><td align="center">No</td><td>If provided, returns all trigger orders up to the given order digest (exclusive). This can be used for pagination.</td></tr><tr><td align="center">digests</td><td align="center">string[]</td><td align="center">No</td><td>If provided, only returns the trigger orders for the associated digests. <strong>Note</strong>: all other filters are ignored when <mark style="color:red;"><code>digests</code></mark> is provided.</td></tr><tr><td align="center">reduce_only</td><td align="center">boolean</td><td align="center">No</td><td>If provided, filters trigger orders by reduce-only flag. <mark style="color:red;"><code>true</code></mark> returns only orders that can only decrease existing positions. If omitted, returns all orders regardless of reduce-only status.</td></tr><tr><td align="center">limit</td><td align="center">number</td><td align="center">No</td><td>If provided, returns the most recently updated trigger orders up to <mark style="color:red;"><code>limit</code></mark>. defaults to 100. max limit is 500.</td></tr></tbody></table>
## Signing
{% hint style="info" %}
See more details and and examples in our [signing](https://docs.nado.xyz/developer-resources/api/gateway/signing) page.
{% endhint %}
The solidity typed data struct that needs to be signed is:
```solidity
struct ListTriggerOrders {
bytes32 sender;
uint64 recvTime;
}
```
<mark style="color:red;">`sender`</mark>: a <mark style="color:red;">`bytes32`</mark> sent as a hex string; includes the address and the subaccount identifier
<mark style="color:red;">`recvTime`</mark>: the time in milliseconds (a `recv_time`) after which the transaction should be ignored by the trigger service. cannot be more than 100 seconds from the time it is received by the server.
{% hint style="warning" %}
**Note**: for signing you should always use the data type specified in the solidity struct which might be different from the type sent in the request e.g: <mark style="color:red;">`recvTime`</mark> should be an <mark style="color:red;">`uint64`</mark> for **Signing** but should be sent as a <mark style="color:red;">`string`</mark> in the final payload.
{% endhint %}
## Response
#### Success
```json
{
"status": "success",
"data": {
"orders": [
{
"order": {
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
"priceX18": "1000000000000000000",
"amount": "1000000000000000000",
"expiration": "2000000000",
"nonce": "1",
},
"signature": "0x...",
"product_id": 1,
"spot_leverage": true,
"trigger": {
"price_above": "1000000000000000000"
},
"digest": "0x..."
},
"status": "pending",
"placed_at": 1688768157000,
"updated_at": 1688768157050
}
]
},
"request_type": "query_list_trigger_orders"
}
```
{% hint style="info" %}
**Note**: trigger orders can have the following statuses:
* **cancelled**: trigger order was cancelled due to user request, order expiration, or account health issues.
* **triggered**: trigger criteria was met, and order was submitted for execution.
* **internal\_error**: an internal error occurred while processing the trigger order.
* **triggering**: trigger order is currently being processed for execution.
* **waiting\_price**: trigger order is waiting for price criteria to be met.
* **waiting\_dependency**: trigger order is waiting for a dependency order to be filled.
* **twap\_executing**: TWAP order is currently executing individual orders over time.
* **twap\_completed**: TWAP order has completed all scheduled executions.
{% endhint %}
#### Failure
```json
{
"status": "failure",
"signature": {signature}
"error": "{error_msg}"
"error_code": {error_code}
"request_type": "query_list_trigger_orders"
}
```
@@ -0,0 +1,98 @@
# List TWAP Executions
## Request
{% tabs %}
{% tab title="Get TWAP executions" %} <mark style="color:orange;">`POST [TRIGGER_ENDPOINT]/query`</mark>
**Body**
```json
{
"type": "list_twap_executions",
"digest": "0x5886d5eee7dc4879c7f8ed1222fdbbc0e3681a14c1e55d7859515898c7bd2038"
}
```
{% endtab %}
{% endtabs %}
## Request Parameters
<table><thead><tr><th width="201" align="center">Parameter</th><th width="128" align="center">Type</th><th width="129" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td align="center">digest</td><td align="center">string</td><td align="center">Yes</td><td>The digest of the TWAP trigger order to get execution details for.</td></tr></tbody></table>
## Response
#### Success
```json
{
"status": "success",
"data": {
"executions": [
{
"execution_id": 1,
"scheduled_time": 1688768157,
"status": "pending",
"updated_at": 1688768157050
},
{
"execution_id": 2,
"scheduled_time": 1688768187,
"status": {
"executed": {
"executed_time": 1688768187050,
"execute_response": {
"status": "success",
"data": {
"digest": "0x..."
},
"id": 12345,
"request_type": "place_order"
}
}
},
"updated_at": 1688768187050
},
{
"execution_id": 3,
"scheduled_time": 1688768217,
"status": {
"failed": "Insufficient balance"
},
"updated_at": 1688768217050
},
{
"execution_id": 4,
"scheduled_time": 1688768247,
"status": {
"cancelled": "user_requested"
},
"updated_at": 1688768247050
}
]
},
"request_type": "query_list_twap_executions"
}
```
{% hint style="info" %}
**Note**: TWAP executions can have the following statuses:
* **pending**: execution is scheduled but has not yet been attempted.
* **executed**: execution was successful, includes execution time and response details from the engine.
* **failed**: execution failed, includes error message.
* **cancelled**: execution was cancelled, includes cancellation reason (e.g., "user\_requested", "linked\_signer\_changed", "expired", "account\_health", "isolated\_subaccount\_closed", "dependent\_order\_cancelled").
{% endhint %}
#### Failure
```json
{
"status": "failure",
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "query_list_twap_executions"
}
```
+41
View File
@@ -0,0 +1,41 @@
# V2
Nado V2 API offers REST-based endpoints focused on two key functionalities:
1. **Gateway Queries**: Access real-time market data, including trading pairs and book liquidity.
2. **Archive (indexer) Queries**: Query historical market data, including 24-hour statistics for all products and recent trades.
## Endpoints
### Testnet
* **Gateway**: <mark style="color:red;">`https://gateway.test.nado.xyz/v2`</mark>
* **Archive (indexer)**: <mark style="color:red;">`https://archive.test.nado.xyz/v2`</mark>
## Gateway
{% content-ref url="v2/assets" %}
[assets](https://docs.nado.xyz/developer-resources/api/v2/assets)
{% endcontent-ref %}
{% content-ref url="v2/pairs" %}
[pairs](https://docs.nado.xyz/developer-resources/api/v2/pairs)
{% endcontent-ref %}
{% content-ref url="v2/orderbook" %}
[orderbook](https://docs.nado.xyz/developer-resources/api/v2/orderbook)
{% endcontent-ref %}
## Archive (indexer)
{% content-ref url="v2/tickers" %}
[tickers](https://docs.nado.xyz/developer-resources/api/v2/tickers)
{% endcontent-ref %}
{% content-ref url="v2/contracts" %}
[contracts](https://docs.nado.xyz/developer-resources/api/v2/contracts)
{% endcontent-ref %}
{% content-ref url="v2/trades" %}
[trades](https://docs.nado.xyz/developer-resources/api/v2/trades)
{% endcontent-ref %}

Some files were not shown because too many files have changed in this diff Show More