Perpetual Account
Each user wallet that interacts with the Foundation has a unique id called account_id
and that id is 32 bytes with:
First 20 bytes is wallet address
The next 4 bytes is BROKER_ID (default: 1)
The next 5 bytes is reserve (0)
Next byte is product type
Final 2 bytes is account index
One wallet have max 15 perpetual accounts (start from 1)
Account format
export const getAccountId = (address: Address, productType: PRODUCT_TYPE, accountIndex: number) => {
return bytesToHex(
Uint8Array.from([
...hexToBytes(address, {
size: 20,
}),
...numberToBytes(BROKER_ID, {
size: 4,
}),
...numberToBytes(0, {
size: 5,
}),
...numberToBytes(productType, {
size: 1,
}),
...numberToBytes(accountIndex, {
size: 2,
}),
]),
);
};
Perpetual Order
Supported order types
Strategy (Place order with TP/SL)
Order structure
Get market_id
from Market Info API
set to default
, immediate_or_cancel
, fill_or_kill
, post_only
as GTD (good til date) not yet implemented, leave this field with default value 0
if order is market
or stop_market
set to true
, otherwise set to false
set to cancel_provide
(default), decrease_take
, expire_both
Order nonce
Generated from expired_time << 20 | random_number
expired_time = now + gap (gap should set to equal or above 30s)
Order signature
Place or cancel order require sign order by user wallet or linked signer wallet
Time in Force Option
GTC (default): Order will continue to work until filled or canceled.
IOC (immediate_or_cancel): Order will execute all or partial immediately and cancel any unfilled portion of the order.
FOK (fill_or_kill): Order must be filled immediately in its entirety or not executed at all.
Post Only (post_only): orders will be added to the order book and not execute with a pre-existing order.
Reduce-Only Option
Order serves to strictly reduce your open position
Only supported on FOK or IOC
Close Position will cancel all Trigger Order with Reduce-Only = True
Self Trading Prevention
none:
This mode exempts the order from self-trade prevention. Accounts will not be compared, no orders will be revoked, and the trade will occur.
cancel_provide:
This mode prevents a trade by immediately revoking the potential maker order's remaining quantity
decrease_take:
This mode prevents a trade by immediately revoking the taker order's remaining quantity
expire_both:
This mode prevents a trade by immediately revoking both the taker and the potential maker orders' remaining quantities
Place market order
Market order is immediately matched to the best available market price
Time in Force: IOC (default), FOK
Request & Response
Request
Params: [order_object, order_signature]
curl --location 'https://testnet-rpc.foundation.network/perpetual' \
--header 'Content-Type: application/json' \
--data '[
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.010",
"price": "98556.3",
"time_in_force": "fill_or_kill",
"reduce_only": false,
"expires_at": null,
"is_market_order": true,
"nonce": "1820392312872633083",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": null
},
"0xf24c7c878421f64387cb04b1c1b0e02b9e2c310c0c4bf2aed5847ca437a05872621d189d355595fdd3ee84e9bb3788ce5b84c9e388a305e93906ae47073744641c"
]
}
]'
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
const raw = JSON.stringify([
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.010",
"price": "98556.3",
"time_in_force": "fill_or_kill",
"reduce_only": false,
"expires_at": null,
"is_market_order": true,
"nonce": "1820392312872633083",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": null
},
"0xf24c7c878421f64387cb04b1c1b0e02b9e2c310c0c4bf2aed5847ca437a05872621d189d355595fdd3ee84e9bb3788ce5b84c9e388a305e93906ae47073744641c"
]
}
]);
const requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
redirect: "follow"
};
fetch("https://testnet-rpc.foundation.network/perpetual", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
import requests
import json
url = "https://testnet-rpc.foundation.network/perpetual"
payload = json.dumps([
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.010",
"price": "98556.3",
"time_in_force": "fill_or_kill",
"reduce_only": False,
"expires_at": None,
"is_market_order": True,
"nonce": "1820392312872633083",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": None
},
"0xf24c7c878421f64387cb04b1c1b0e02b9e2c310c0c4bf2aed5847ca437a05872621d189d355595fdd3ee84e9bb3788ce5b84c9e388a305e93906ae47073744641c"
]
}
])
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::builder()
.build()?;
let mut headers = reqwest::header::HeaderMap::new();
headers.insert("Content-Type", "application/json".parse()?);
let data = r#"[
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.010",
"price": "98556.3",
"time_in_force": "fill_or_kill",
"reduce_only": false,
"expires_at": null,
"is_market_order": true,
"nonce": "1820392312872633083",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": null
},
"0xf24c7c878421f64387cb04b1c1b0e02b9e2c310c0c4bf2aed5847ca437a05872621d189d355595fdd3ee84e9bb3788ce5b84c9e388a305e93906ae47073744641c"
]
}
]"#;
let json: serde_json::Value = serde_json::from_str(&data)?;
let request = client.request(reqwest::Method::POST, "https://testnet-rpc.foundation.network/perpetual")
.headers(headers)
.json(&json);
let response = request.send().await?;
let body = response.text().await?;
println!("{}", body);
Ok(())
}
[
{
"jsonrpc": "2.0",
"id": "1",
"result": 841787
}
]
Place limit order
A limit order is an order to buy or sell at a specific price or better. Limit orders are not guaranteed to execute
Time in Force: GTC (default), IOC, FOK
Reduce Only: Only supported on FOK or IOC
Request & Response
Request
Params: [order_object, order_signature]
curl --location 'https://testnet-rpc.foundation.network/perpetual' \
--header 'Content-Type: application/json' \
--data '[
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.051",
"price": "98000",
"time_in_force": "default",
"reduce_only": false,
"expires_at": null,
"is_market_order": false,
"nonce": "1820392919896425329",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": null
},
"0x16787c587b1e336372600a2cc09a29a51b504462a47210918a648efc8629b34520ff3898786e3c40ab84a24289d8578be44f9c06961c650ee8214f3401d9c6351b"
]
}
]'
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
const raw = JSON.stringify([
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.051",
"price": "98000",
"time_in_force": "default",
"reduce_only": false,
"expires_at": null,
"is_market_order": false,
"nonce": "1820392919896425329",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": null
},
"0x16787c587b1e336372600a2cc09a29a51b504462a47210918a648efc8629b34520ff3898786e3c40ab84a24289d8578be44f9c06961c650ee8214f3401d9c6351b"
]
}
]);
const requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
redirect: "follow"
};
fetch("https://testnet-rpc.foundation.network/perpetual", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
import requests
import json
url = "https://testnet-rpc.foundation.network/perpetual"
payload = json.dumps([
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.051",
"price": "98000",
"time_in_force": "default",
"reduce_only": False,
"expires_at": None,
"is_market_order": False,
"nonce": "1820392919896425329",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": None
},
"0x16787c587b1e336372600a2cc09a29a51b504462a47210918a648efc8629b34520ff3898786e3c40ab84a24289d8578be44f9c06961c650ee8214f3401d9c6351b"
]
}
])
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::builder()
.build()?;
let mut headers = reqwest::header::HeaderMap::new();
headers.insert("Content-Type", "application/json".parse()?);
let data = r#"[
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.051",
"price": "98000",
"time_in_force": "default",
"reduce_only": false,
"expires_at": null,
"is_market_order": false,
"nonce": "1820392919896425329",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": null
},
"0x16787c587b1e336372600a2cc09a29a51b504462a47210918a648efc8629b34520ff3898786e3c40ab84a24289d8578be44f9c06961c650ee8214f3401d9c6351b"
]
}
]"#;
let json: serde_json::Value = serde_json::from_str(&data)?;
let request = client.request(reqwest::Method::POST, "https://testnet-rpc.foundation.network/perpetual")
.headers(headers)
.json(&json);
let response = request.send().await?;
let body = response.text().await?;
println!("{}", body);
Ok(())
}
[
{
"jsonrpc": "2.0",
"id": "1",
"result": 842648
}
]
Place stop market order
Stop Market Orders become market orders when a specified price is reached. Specify a trigger price to activate the order
Trigger price can be Mark Price or Last Price
Time in Force: IOC (default), FOK
Request & Response
Request
Params: [order_object, order_signature]
curl --location 'https://testnet-rpc.foundation.network/perpetual' \
--header 'Content-Type: application/json' \
--data '[
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.050",
"price": "98196",
"time_in_force": "fill_or_kill",
"reduce_only": false,
"expires_at": null,
"is_market_order": true,
"nonce": "1820393289179726727",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": {
"mark_price": {
"below": "98000"
}
}
},
"0x3ded0f6deb9318fc267ffe0b5f25e76fd945b5d86ce9e4a316b63346c507add005f1892b4e5eb6e5584e65194e70415844789f872abb7852fa455851408c8a561b"
]
}
]'
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
const raw = JSON.stringify([
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.050",
"price": "98196",
"time_in_force": "fill_or_kill",
"reduce_only": false,
"expires_at": null,
"is_market_order": true,
"nonce": "1820393289179726727",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": {
"mark_price": {
"below": "98000"
}
}
},
"0x3ded0f6deb9318fc267ffe0b5f25e76fd945b5d86ce9e4a316b63346c507add005f1892b4e5eb6e5584e65194e70415844789f872abb7852fa455851408c8a561b"
]
}
]);
const requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
redirect: "follow"
};
fetch("https://testnet-rpc.foundation.network/perpetual", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
import requests
import json
url = "https://testnet-rpc.foundation.network/perpetual"
payload = json.dumps([
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.050",
"price": "98196",
"time_in_force": "fill_or_kill",
"reduce_only": False,
"expires_at": None,
"is_market_order": True,
"nonce": "1820393289179726727",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": {
"mark_price": {
"below": "98000"
}
}
},
"0x3ded0f6deb9318fc267ffe0b5f25e76fd945b5d86ce9e4a316b63346c507add005f1892b4e5eb6e5584e65194e70415844789f872abb7852fa455851408c8a561b"
]
}
])
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::builder()
.build()?;
let mut headers = reqwest::header::HeaderMap::new();
headers.insert("Content-Type", "application/json".parse()?);
let data = r#"[
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.050",
"price": "98196",
"time_in_force": "fill_or_kill",
"reduce_only": false,
"expires_at": null,
"is_market_order": true,
"nonce": "1820393289179726727",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": {
"mark_price": {
"below": "98000"
}
}
},
"0x3ded0f6deb9318fc267ffe0b5f25e76fd945b5d86ce9e4a316b63346c507add005f1892b4e5eb6e5584e65194e70415844789f872abb7852fa455851408c8a561b"
]
}
]"#;
let json: serde_json::Value = serde_json::from_str(&data)?;
let request = client.request(reqwest::Method::POST, "https://testnet-rpc.foundation.network/perpetual")
.headers(headers)
.json(&json);
let response = request.send().await?;
let body = response.text().await?;
println!("{}", body);
Ok(())
}
[
{
"jsonrpc": "2.0",
"id": "1",
"result": 843252
}
]
Place stop limit order
Stop Limit Orders become limit orders when a specified stop price is reached. Specify a trigger price to activate the order
Trigger price can be Mark Price or Last Price
Time in Force: GTC (default), IOC, FOK
Reduce Only: Only supported on FOK or IOC
Request & Response
Request
Params: [order_object, order_signature]
curl --location 'https://testnet-rpc.foundation.network/perpetual' \
--header 'Content-Type: application/json' \
--data '[
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.051",
"price": "97500",
"time_in_force": "default",
"reduce_only": false,
"expires_at": null,
"is_market_order": false,
"nonce": "1820393522228888309",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": {
"mark_price": {
"below": "98000"
}
}
},
"0xb2e284d112cbbed092a9cb64b35cd21434d92b181bc848f2383dd7e6621dc36b5c402b6a3b2f66212f07392e25b3ed58afe12fc6a6221e1adecba251df86a65f1b"
]
}
]'
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
const raw = JSON.stringify([
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.051",
"price": "97500",
"time_in_force": "default",
"reduce_only": false,
"expires_at": null,
"is_market_order": false,
"nonce": "1820393522228888309",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": {
"mark_price": {
"below": "98000"
}
}
},
"0xb2e284d112cbbed092a9cb64b35cd21434d92b181bc848f2383dd7e6621dc36b5c402b6a3b2f66212f07392e25b3ed58afe12fc6a6221e1adecba251df86a65f1b"
]
}
]);
const requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
redirect: "follow"
};
fetch("https://testnet-rpc.foundation.network/perpetual", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
import requests
import json
url = "https://testnet-rpc.foundation.network/perpetual"
payload = json.dumps([
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.051",
"price": "97500",
"time_in_force": "default",
"reduce_only": False,
"expires_at": None,
"is_market_order": False,
"nonce": "1820393522228888309",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": {
"mark_price": {
"below": "98000"
}
}
},
"0xb2e284d112cbbed092a9cb64b35cd21434d92b181bc848f2383dd7e6621dc36b5c402b6a3b2f66212f07392e25b3ed58afe12fc6a6221e1adecba251df86a65f1b"
]
}
])
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::builder()
.build()?;
let mut headers = reqwest::header::HeaderMap::new();
headers.insert("Content-Type", "application/json".parse()?);
let data = r#"[
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.051",
"price": "97500",
"time_in_force": "default",
"reduce_only": false,
"expires_at": null,
"is_market_order": false,
"nonce": "1820393522228888309",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": {
"mark_price": {
"below": "98000"
}
}
},
"0xb2e284d112cbbed092a9cb64b35cd21434d92b181bc848f2383dd7e6621dc36b5c402b6a3b2f66212f07392e25b3ed58afe12fc6a6221e1adecba251df86a65f1b"
]
}
]"#;
let json: serde_json::Value = serde_json::from_str(&data)?;
let request = client.request(reqwest::Method::POST, "https://testnet-rpc.foundation.network/perpetual")
.headers(headers)
.json(&json);
let response = request.send().await?;
let body = response.text().await?;
println!("{}", body);
Ok(())
}
[
{
"jsonrpc": "2.0",
"id": "1",
"result": 843573
}
]
Place post-only order
Post Only orders will be added to the order book and not execute with a pre-existing order.
Reduce Only: not supported
Request & Response
Request
Params: [order_object, order_signature]
curl --location 'https://testnet-rpc.foundation.network/perpetual' \
--header 'Content-Type: application/json' \
--data '[
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.051",
"price": "98000",
"time_in_force": "post_only",
"reduce_only": false,
"expires_at": null,
"is_market_order": false,
"nonce": "1820393736968864321",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": null
},
"0x1fba81235330776eefa23104d44a929093667b5e99e46853b78cfed4757249046d324db887f70ecce7c8154ed4efd002a6e2c22f7038cb7c40d34bb9c2ba355e1c"
]
}
]'
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
const raw = JSON.stringify([
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.051",
"price": "98000",
"time_in_force": "post_only",
"reduce_only": false,
"expires_at": null,
"is_market_order": false,
"nonce": "1820393736968864321",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": null
},
"0x1fba81235330776eefa23104d44a929093667b5e99e46853b78cfed4757249046d324db887f70ecce7c8154ed4efd002a6e2c22f7038cb7c40d34bb9c2ba355e1c"
]
}
]);
const requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
redirect: "follow"
};
fetch("https://testnet-rpc.foundation.network/perpetual", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
import requests
import json
url = "https://testnet-rpc.foundation.network/perpetual"
payload = json.dumps([
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.051",
"price": "98000",
"time_in_force": "post_only",
"reduce_only": False,
"expires_at": None,
"is_market_order": False,
"nonce": "1820393736968864321",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": None
},
"0x1fba81235330776eefa23104d44a929093667b5e99e46853b78cfed4757249046d324db887f70ecce7c8154ed4efd002a6e2c22f7038cb7c40d34bb9c2ba355e1c"
]
}
])
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::builder()
.build()?;
let mut headers = reqwest::header::HeaderMap::new();
headers.insert("Content-Type", "application/json".parse()?);
let data = r#"[
{
"id": "1",
"jsonrpc": "2.0",
"method": "ob_place_limit",
"params": [
{
"market_id": 1,
"amount": "0.051",
"price": "98000",
"time_in_force": "post_only",
"reduce_only": false,
"expires_at": null,
"is_market_order": false,
"nonce": "1820393736968864321",
"account_id": "0xb0477aa910d2a70647782afb91ba3477b8963a2e000000010000000000010000",
"side": "bid",
"self_trade_behavior": "cancel_provide",
"trigger_condition": null
},
"0x1fba81235330776eefa23104d44a929093667b5e99e46853b78cfed4757249046d324db887f70ecce7c8154ed4efd002a6e2c22f7038cb7c40d34bb9c2ba355e1c"
]
}
]"#;
let json: serde_json::Value = serde_json::from_str(&data)?;
let request = client.request(reqwest::Method::POST, "https://testnet-rpc.foundation.network/perpetual")
.headers(headers)
.json(&json);
let response = request.send().await?;
let body = response.text().await?;
println!("{}", body);
Ok(())
}
[
{
"jsonrpc": "2.0",
"id": "1",
"result": 843902
}
]
Place reduce-only order
Request
Params: [order_object, order_signature]
curl --location 'https://testnet-rpc.foundation.network/perpetual' \