mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-09 16:28:06 +00:00
Add Nado documentation and examples, including new API endpoints, FAQs, and guides for using the TypeScript SDK. Update .env.example with additional configuration options.
This commit is contained in:
@@ -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"
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user