Public REST API
Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.
This is a readonly REST API which can be used to fetch data about the DerivaDEX exchange. Realtime equivalents for most of these endpoints can be found in the Realtime API section.
Trader
These APIs provide data for a particular trader. Use the 'Full table views' APIs to find the unscoped variants.
Trader
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}
Returns a specific trader
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Trader data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": {
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"availDdx": "1000",
"lockedDdx": "200",
"payFeesInDdx": true
},
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Trader API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | object | true | none | Entity which represents the current trader state. |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant. |
»» availDdx | string | true | none | The amount of DDX that the trader holds. |
»» lockedDdx | string | true | none | The amount of DDX that the trader has initiated for withdrawal. |
»» payFeesInDdx | boolean | true | none | A flag which indicates whether the trader wants to attempt to pay trading fees using their DDX balance. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Trader order updates
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}/order_updates',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}/order_updates', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}/order_updates',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}/order_updates
Returns the order update timeseries data for a particular trader
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
ordinal | query | integer | false | The ordinal boundary used when fetching the next timeseries page. Must be passed along with epoch and txOrdinal. |
order | query | string | false | The ordering of the results. |
symbol | query | string | false | The symbol |
orderHash | query | string | false | the order hash of the order intent. Multiple order hash values can be provided. |
fillReason | query | integer | false | The reason for the creation of this row. 0-Trade; 1-Liquidation; 2-Cancel. Multiple reason values can be provided. |
since | query | integer | false | The earliest time in seconds to fetch rows for. This param cannot be used together with param order = 'desc' |
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Order update timeseries data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"ordinal": 0,
"makerOrderHash": "0xe49584ff9d5a154d2075ff658ccb4c7af844bb9fad5055ad72",
"makerOrderTrader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"makerOrderStrategyIdHash": "0x2576ebd1",
"amount": "1.5",
"symbol": "ETHP",
"price": "595.8",
"makerFeeUSDC": "0",
"makerFeeDDX": "0",
"makerRealizedPnl": "0",
"reason": 0,
"takerOrderHash": "0x93ee93e9e90db7f3f8ae2815cb54610c6e072fe3cf9a475be2",
"takerOrderTrader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"takerOrderStrategyIdHash": "0x2576ebd1",
"takerFeeUSDC": "1.7874",
"takerFeeDDX": "1.7874",
"takerRealizedPnl": "0",
"liquidatedTrader": null,
"liquidatedStrategyIdHash": null,
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for fills API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» ordinal | string | true | none | The ordinal within this particular transaction. |
»» makerOrderHash | string | true | none | The order hash for the maker side of this fill. |
»» makerOrderTrader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader which owns the maker order. |
»» makerOrderStrategyIdHash | string | true | none | The hashed strategy id of the strategy which owns the maker order. |
»» amount | string | true | none | The amount that was filled. |
»» symbol | string | true | none | The symbol of the asset that was filled. |
»» price | string,null | true | none | The fill price. |
»» makerFeeUSDC | string,null | true | none | The USDC fee that was incurred to the maker side of the fill if the maker receives fees in USDC. |
»» makerFeeDDX | string,null | true | none | The fee that was incurred to the maker side of the fill if the maker elected to receive fees in DDX. Null otherwise. |
»» makerRealizedPnl | string,null | true | none | The realized profit and loss (not inclusive of fees) incurred to the maker due to this fill. Null otherwise. |
»» reason | number | true | none | The type of fill. Values include: 0: trade, 1: liquidation, 2: cancel |
»» takerOrderHash | string,null | true | none | The order hash for the taker side of this fill. |
»» takerOrderTrader | string,null | true | none | The trader address prefixed with the blockchain discriminant of the trader which owns the taker order. |
»» takerOrderStrategyIdHash | string,null | true | none | The hashed strategy id of the strategy which owns the taker order. |
»» takerFeeUSDC | string,null | true | none | The fee that was incurred to the taker side of the fill if taker receives fees in USDC. Null otherwise |
»» takerFeeDDX | string,null | true | none | The fee that was incurred to the taker side of the fill if taker receives fees in DDX. Null otherwise |
»» takerRealizedPnl | string,null | true | none | The realized profit and loss (not inclusive of fees) incurred to the taker due to this fill. |
»» liquidatedTrader | string,null | true | none | In the case that this was a liquidation fill, the trader address prefixed with the blockchain discriminant of the trader that was liquidated. |
»» liquidatedStrategyIdHash | string,null | true | none | The liquidated strategy id hash |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
All strategies of a trader
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}/strategies',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}/strategies', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}/strategies',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}/strategies
Returns information about a particular trader's updates
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
limit | query | integer | false | The number of rows to return |
offset | query | integer | false | The offset of returned rows |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Strategy data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyIdHash": "0x2576ebd1",
"strategyId": "main",
"maxLeverage": 3,
"availCollateral": "10000",
"lockedCollateral": "1000",
"frozen": false
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Strategies API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who owns this strategy. |
»» strategyIdHash | string | true | none | The hashed version of this strategy ID. |
»» strategyId | string | true | none | An identifier for this strategy. |
»» maxLeverage | number | true | none | The maximum leverage this strategy is allowed to take on. |
»» availCollateral | string | true | none | The amount of collateral that this strategy holds. |
»» lockedCollateral | string | true | none | The amount of collateral which has been initiated for withdrawal. |
»» frozen | boolean | true | none | Whether this strategy is frozen. Not currently in use. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Trader updates
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}/trader_updates',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}/trader_updates', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}/trader_updates',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}/trader_updates
Returns information about a particular trader's updates
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
kind | query | integer | false | The type of trader update. Multiple trader update values can be provided. Values include: |
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
ordinal | query | integer | false | The ordinal boundary used when fetching the next timeseries page. Must be passed along with epoch and txOrdinal. |
order | query | string | false | The ordering of the results. |
Detailed descriptions
kind: The type of trader update. Multiple trader update values can be provided. Values include: 0: Deposit 1: WithdrawDDX 2: ClaimDDXWithdraw 3: TradeMiningReward
Enumerated Values
Parameter | Value |
---|---|
kind | 0 |
kind | 1 |
kind | 2 |
kind | 3 |
kind | 4 |
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Trader updates data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"ordinal": 0,
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"amount": "1000",
"newDdxBalance": "1200",
"kind": 0,
"payFeesInDdx": true,
"blockNumber": "344100",
"txHash": "0xfcdae2edac7063ae3a3fb0e74b48816a0593644a3b2f5d701c8e5fafec70828e",
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Trader Updates API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» ordinal | string | true | none | The ordinal within this particular transaction. |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader. |
»» amount | string,null | true | none | The amount of DDX was modified in this trader. |
»» newDdxBalance | string,null | true | none | The new DDX balance after updating this trader. |
»» kind | number | true | none | The type of trader update. Values include: 0: Deposit 1: WithdrawDDX 2: ClaimDDXWithdraw 3: TradeMiningReward |
»» payFeesInDdx | boolean,null | true | none | A flag which when set will attempt to pay trading fees using the DDX held in this trader. |
»» blockNumber | string,null | true | none | The block number in which this strategy update was processed. |
»» txHash | string,null | true | none | The on-chain transaction hash corresponding to this trader update (for Deposit and ClaimDDXWithdraw kinds) |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Strategy
These APIs provide access to tables under the context of a particular trader address and strategy ID pair. Use the 'Full table views' APIs to find the unscoped variants.
Strategy ADLs
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}/strategy/{strategyId}/adls',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}/strategy/{strategyId}/adls', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}/strategy/{strategyId}/adls',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}/strategy/{strategyId}/adls
Returns the ADL events for traders who were either on the liquidation side or de-leveraging side
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
strategyId | path | string | true | The strategy ID. |
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
ordinal | query | integer | false | The ordinal boundary used when fetching the next timeseries page. Must be passed along with epoch and txOrdinal. |
order | query | string | false | The ordering of the results. |
symbol | query | string | false | The symbol |
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | ADL timeseries data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"ordinal": 0,
"amount": "1.0",
"symbol": "ETHP",
"adlTrader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"adlStrategyIdHash": "0x2576ebd1",
"liquidatedTrader": "0x006bb7d07901a1aade4ead7b68167224a0512985cf",
"liquidatedStrategyIdHash": "0x2576ebd1",
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for ADLs API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» ordinal | string | true | none | The ordinal within this particular transaction. |
»» amount | string | true | none | The amount that was auto de-leveraged. |
»» symbol | string | true | none | The symbol of the asset that was auto de-leveraged. |
»» adlTrader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who was de-leveraged. |
»» adlStrategyIdHash | string | true | none | The strategy ID from the trader who was de-leveraged. |
»» liquidatedTrader | string | true | none | The trader address of the trader who was liquidated, leading to this adl. |
»» liquidatedStrategyIdHash | string | true | none | The strategy ID from the trader who was liquidated, leading to this adl. |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Strategy Fees
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}/strategy/{strategyId}/fees',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}/strategy/{strategyId}/fees', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}/strategy/{strategyId}/fees',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}/strategy/{strategyId}/fees
Returns the fees from the trades for a specific strategy
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
strategyId | path | string | true | The strategy ID. |
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
ordinal | query | integer | false | The ordinal boundary used when fetching the next timeseries page. Must be passed along with epoch and txOrdinal. |
symbol | query | string | false | The symbol |
order | query | string | false | The ordering of the results. |
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Fees timeseries data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": {
"epochId": 100,
"txOrdinal": 3432,
"ordinal": 0,
"amount": "1.0",
"feeSymbol": "USDC",
"symbol": "ETHP",
"createdAt": "2023-01-06T16:37:27.929Z"
},
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Fee API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | object | true | none | Fee Response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» ordinal | string | true | none | The ordinal within this particular transaction. |
»» amount | string | true | none | The amount of fee paid |
»» feeSymbol | string | true | none | The symbol of the fee paid (USDC or DDX) |
»» symbol | string | true | none | The symbol of the asset for which the fee was paid. |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Strategy
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}/strategy/{strategyId}',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}/strategy/{strategyId}', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}/strategy/{strategyId}',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}/strategy/{strategyId}
Returns information about a particular strategy
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
strategyId | path | string | true | The strategy ID. |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Strategy data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": {
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyIdHash": "0x2576ebd1",
"strategyId": "main",
"maxLeverage": 3,
"availCollateral": "10000",
"lockedCollateral": "1000",
"frozen": false
},
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Strategy API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | object | true | none | Current state of a trader's strategy. |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who owns this strategy. |
»» strategyIdHash | string | true | none | The hashed version of this strategy ID. |
»» strategyId | string | true | none | An identifier for this strategy. |
»» maxLeverage | number | true | none | The maximum leverage this strategy is allowed to take on. |
»» availCollateral | string | true | none | The amount of collateral that this strategy holds. |
»» lockedCollateral | string | true | none | The amount of collateral which has been initiated for withdrawal. |
»» frozen | boolean | true | none | Whether this strategy is frozen. Not currently in use. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Strategy liquidations
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}/strategy/{strategyId}/liquidations',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}/strategy/{strategyId}/liquidations', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}/strategy/{strategyId}/liquidations',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}/strategy/{strategyId}/liquidations
Returns the liquidations timeseries data for a particular trader and strategy
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
strategyId | path | string | true | The strategy ID. |
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
ordinal | query | integer | false | The ordinal boundary used when fetching the next timeseries page. Must be passed along with epoch and txOrdinal. |
order | query | string | false | The ordering of the results. |
symbol | query | string | false | The symbol |
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Liquidations timeseries data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"ordinal": 0,
"symbol": "ETHP",
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyIdHash": "0x2576ebd1",
"triggerPriceHash": "0x7fedd251937b6240d46f989f21d06ea0d8929cd42cf627cee6",
"markPrice": "51899.698653",
"insuranceFundCapitalization": "string",
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Liquidation API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» ordinal | string | true | none | The ordinal within this particular transaction. |
»» symbol | string | true | none | The symbol of the asset in which the liquidation occured. |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who was liquidated. |
»» strategyIdHash | string | true | none | The strategy id of the trader who was liquidated. |
»» triggerPriceHash | string,null | true | none | The hash of the price update that caused the liquidation. |
»» markPrice | string | true | none | The mark price of the asset at the time of liquidation. |
»» insuranceFundCapitalization | string | true | none | The insurance fund capitalization after this liquidation transaction. |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Strategy metrics
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}/strategy/{strategyId}/metrics',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}/strategy/{strategyId}/metrics', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}/strategy/{strategyId}/metrics',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}/strategy/{strategyId}/metrics
Returns the metrics for a particular trader and strategy, like margin fraction, maintenance margin ratio, leverage, strategy available collateral and strategy value.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
strategyId | path | string | true | The strategy ID. |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Strategy metrics data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": {
"marginFraction": "999999999999",
"mmr": "0.05",
"leverage": "3",
"strategyMargin": "6147.5",
"strategyValue": "9233.3"
},
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Strategy Metrics API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | object | true | none | Strategy metrics |
»» marginFraction | string | true | none | The current margin fraction of the strategy. |
»» mmr | string | true | none | The maintenance margin ratio. The margin fraction of the strategy should be greater than this number, or it may be subject to liquidation. |
»» leverage | string | true | none | The current leverage of the strategy. |
»» strategyMargin | string | true | none | The amount of unsettled margin and unutilized collateral available for new trades, or as a buffer against losses. |
»» strategyValue | string | true | none | The total value of all positions owned by this strategy. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Strategy open orders
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}/strategy/{strategyId}/order_book',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}/strategy/{strategyId}/order_book', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}/strategy/{strategyId}/order_book',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}/strategy/{strategyId}/order_book
Returns the open orders on the book for a particular trader and strategy
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
strategyId | path | string | true | The strategy ID. |
depth | query | integer | false | The best N bids and asks to return, where N = depth |
symbol | query | string | false | The symbol |
side | query | integer | false | The side of the order. Values include: |
Detailed descriptions
side: The side of the order. Values include: 0: Bid, 1: Ask
Enumerated Values
Parameter | Value |
---|---|
side | 0 |
side | 1 |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Order book data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"orderHash": "0xc8ab0f901fc3968dfae99b6efb34b0bdd81d69aefb21effcf5",
"symbol": "ETHP",
"side": 0,
"originalAmount": "1.0",
"amount": "0.9",
"price": "595.8",
"traderAddress": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyId": "main",
"bookOrdinal": "54"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the OrderBook API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» orderHash | string | true | none | A hash of the order details. |
»» symbol | string | true | none | The symbol of the asset for this order. |
»» side | number | true | none | The side of the order. Values include: 0: Bid, 1: Ask |
»» originalAmount | string | true | none | The original order amount (before any fills). |
»» amount | string | true | none | The order amount currently left on this order. |
»» price | string | true | none | The order price. |
»» traderAddress | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who owns this order. |
»» strategyId | string | true | none | The strategy of the trader which owns this order. |
»» bookOrdinal | string | true | none | The ordinal of when this order arrived on the book. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Strategy order intents
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}/strategy/{strategyId}/order_intents',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}/strategy/{strategyId}/order_intents', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}/strategy/{strategyId}/order_intents',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}/strategy/{strategyId}/order_intents
Returns all orders that were opened for a particular trader and strategy
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
strategyId | path | string | true | The strategy ID. |
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
order | query | string | false | The ordering of the results. |
symbol | query | string | false | The symbol |
orderHash | query | string | false | the order hash of the order intent. Multiple order hash values can be provided. |
side | query | integer | false | The side of the order. Values include: |
since | query | integer | false | The earliest time in seconds to fetch rows for. This param cannot be used together with param order = 'desc' |
filterByStatus | query | integer | false | The status of the order intents. 0-Fully Filled; 1-Partially Filled; 2-Not Filled. Multiple values can be provided. |
Detailed descriptions
side: The side of the order. Values include: 0: Bid, 1: Ask
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
side | 0 |
side | 1 |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Order history data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"orderHash": [
"0xa3c4c1c18c6e72c4aea8cfa0a1868ac4bc0f9b6463e8c9687f"
],
"symbol": [
"ETHP"
],
"side": 0,
"amount": "1.0",
"remainingAmount": "0.5",
"price": "1500.0",
"traderAddress": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyId": "main",
"orderType": 0,
"stopPrice": "0",
"nonce": "0x3136373332393531393331383537373332363800000000000000000000000000",
"signature": "0xf9b19b088e3d0ad2c6330231899e03e50b45a8c7a1f52082aa0e9a61391fd5a35d3aece9dd2d42132a25b0aef5ac1bda7aee87c0c0c25ab9525d5eeeff9787d81b",
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Order Intents Stats API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» orderHash | string | true | none | A hash of this order contents. |
»» symbol | string | true | none | The symbol of the asset for this order. |
»» side | number | true | none | The side of the order. Values include: 0: Bid, 1: Ask |
»» amount | string | true | none | The amount of the order. |
»» remainingAmount | string | true | none | The order amount currently left on this order. |
»» price | string | true | none | The price of the order. |
»» traderAddress | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who issues this order. |
»» strategyId | string | true | none | The strategy of the trader which owns this order. |
»» orderType | number | true | none | The type of order. Values include: 0: Limit, 1: Market 2: Stop |
»» stopPrice | string | true | none | The stop price for this order. Not currently an active field. |
»» nonce | string | true | none | The nonce sent by the trader when placing this order. |
»» signature | string | true | none | A signature which was used to verify the authenticity of the order, when it was sent by the trader. Encrypted using the public key exposed by the leader Operator. |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Strategy order updates
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}/strategy/{strategyId}/order_updates',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}/strategy/{strategyId}/order_updates', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}/strategy/{strategyId}/order_updates',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}/strategy/{strategyId}/order_updates
Returns the order update timeseries data for a particular trader and strategy
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
strategyId | path | string | true | The strategy ID. |
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
ordinal | query | integer | false | The ordinal boundary used when fetching the next timeseries page. Must be passed along with epoch and txOrdinal. |
order | query | string | false | The ordering of the results. |
symbol | query | string | false | The symbol |
orderHash | query | string | false | the order hash of the order intent. Multiple order hash values can be provided. |
fillReason | query | integer | false | The reason for the creation of this row. 0-Trade; 1-Liquidation; 2-Cancel. Multiple reason values can be provided. |
since | query | integer | false | The earliest time in seconds to fetch rows for. This param cannot be used together with param order = 'desc' |
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Order update timeseries data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"ordinal": 0,
"makerOrderHash": "0xe49584ff9d5a154d2075ff658ccb4c7af844bb9fad5055ad72",
"makerOrderTrader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"makerOrderStrategyIdHash": "0x2576ebd1",
"amount": "1.5",
"symbol": "ETHP",
"price": "595.8",
"makerFeeUSDC": "0",
"makerFeeDDX": "0",
"makerRealizedPnl": "0",
"reason": 0,
"takerOrderHash": "0x93ee93e9e90db7f3f8ae2815cb54610c6e072fe3cf9a475be2",
"takerOrderTrader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"takerOrderStrategyIdHash": "0x2576ebd1",
"takerFeeUSDC": "1.7874",
"takerFeeDDX": "1.7874",
"takerRealizedPnl": "0",
"liquidatedTrader": null,
"liquidatedStrategyIdHash": null,
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for fills API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» ordinal | string | true | none | The ordinal within this particular transaction. |
»» makerOrderHash | string | true | none | The order hash for the maker side of this fill. |
»» makerOrderTrader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader which owns the maker order. |
»» makerOrderStrategyIdHash | string | true | none | The hashed strategy id of the strategy which owns the maker order. |
»» amount | string | true | none | The amount that was filled. |
»» symbol | string | true | none | The symbol of the asset that was filled. |
»» price | string,null | true | none | The fill price. |
»» makerFeeUSDC | string,null | true | none | The USDC fee that was incurred to the maker side of the fill if the maker receives fees in USDC. |
»» makerFeeDDX | string,null | true | none | The fee that was incurred to the maker side of the fill if the maker elected to receive fees in DDX. Null otherwise. |
»» makerRealizedPnl | string,null | true | none | The realized profit and loss (not inclusive of fees) incurred to the maker due to this fill. Null otherwise. |
»» reason | number | true | none | The type of fill. Values include: 0: trade, 1: liquidation, 2: cancel |
»» takerOrderHash | string,null | true | none | The order hash for the taker side of this fill. |
»» takerOrderTrader | string,null | true | none | The trader address prefixed with the blockchain discriminant of the trader which owns the taker order. |
»» takerOrderStrategyIdHash | string,null | true | none | The hashed strategy id of the strategy which owns the taker order. |
»» takerFeeUSDC | string,null | true | none | The fee that was incurred to the taker side of the fill if taker receives fees in USDC. Null otherwise |
»» takerFeeDDX | string,null | true | none | The fee that was incurred to the taker side of the fill if taker receives fees in DDX. Null otherwise |
»» takerRealizedPnl | string,null | true | none | The realized profit and loss (not inclusive of fees) incurred to the taker due to this fill. |
»» liquidatedTrader | string,null | true | none | In the case that this was a liquidation fill, the trader address prefixed with the blockchain discriminant of the trader that was liquidated. |
»» liquidatedStrategyIdHash | string,null | true | none | The liquidated strategy id hash |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Strategy positions
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}/strategy/{strategyId}/positions',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}/strategy/{strategyId}/positions', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}/strategy/{strategyId}/positions',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}/strategy/{strategyId}/positions
Returns the open positions for a particular trader and strategy
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
strategyId | path | string | true | The strategy ID. |
symbol | query | string | false | The symbol |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Positions data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"symbol": "ETHP",
"strategyIdHash": "0x2576ebd1",
"side": 0,
"balance": "1.0",
"avgEntryPrice": "1500",
"lastModifiedInEpoch": 35
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for positions API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who owns this position. |
»» symbol | string | true | none | The symbol of the asset for this position. |
»» strategyIdHash | string | true | none | The hash of the strategy which owns this position. |
»» side | number | true | none | The side of the position. Values include: 0: None, 1: Long, 2: Short |
»» balance | string | true | none | The current balance of this position. |
»» avgEntryPrice | string | true | none | The average entry price of this position. |
»» lastModifiedInEpoch | number,null | true | none | The epoch in which this position's balance was last modified. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Strategy updates
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/account/{trader}/strategy/{strategyId}/strategy_updates',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/account/{trader}/strategy/{strategyId}/strategy_updates', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/account/{trader}/strategy/{strategyId}/strategy_updates',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/account/{trader}/strategy/{strategyId}/strategy_updates
Returns information about a particular strategy's updates
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
strategyId | path | string | true | The strategy ID. |
kind | query | integer | false | The type of strategy update. Multiple strategy update values can be provided. Values include: |
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
ordinal | query | integer | false | The ordinal boundary used when fetching the next timeseries page. Must be passed along with epoch and txOrdinal. |
order | query | string | false | The ordering of the results. |
Detailed descriptions
kind: The type of strategy update. Multiple strategy update values can be provided. Values include: 0: Deposit, 1: Withdraw, 2: WithdrawIntent, 3: FundingPayment, 4: RealizedPnl
Enumerated Values
Parameter | Value |
---|---|
kind | 0 |
kind | 1 |
kind | 2 |
kind | 3 |
kind | 4 |
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Strategy updates data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"ordinal": 0,
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyIdHash": "0x2576ebd1",
"collateralAddress": "0x8ea76477cfaca8f7ea06477fd3c09a740ac6012a",
"amount": "1000",
"newAvailCollateral": "10000",
"newLockedCollateral": "10000",
"kind": 0,
"blockNumber": "344100",
"txHash": "0xfcdae2edac7063ae3a3fb0e74b48816a0593644a3b2f5d701c8e5fafec70828e",
"newAvgEntryPrices": {
"BTCP": "51591.628081",
"ETHP": "4786.43076"
},
"fundingPayments": {
"BTCP": "17.918454670996998719225076469",
"ETHP": "-2.1938698405321453631273234871"
},
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Strategy Updates API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» ordinal | string | true | none | The ordinal within this particular transaction. |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who owns this strategy. |
»» strategyIdHash | string | true | none | The hashed version of this strategy ID. |
»» collateralAddress | string,null | true | none | The collateral address on which this strategy update took place. |
»» amount | string | true | none | The amount that was modified in the strategy. |
»» newAvailCollateral | string,null | true | none | If affected, the updated available collateral amount after this strategy update. |
»» newLockedCollateral | string,null | true | none | If affected, the updated locked collateral amount after this strategy update. |
»» kind | number | true | none | The type of strategy update. Values include: 0: Deposit, 1: Withdraw, 2: WithdrawIntent, 3: FundingPayment, 4: RealizedPnl |
»» blockNumber | string,null | true | none | The block number in which this strategy update was processed. |
»» txHash | string,null | true | none | The on-chain transaction hash corresponding to this strategy update (for Deposit and Withdraw kinds) |
»» newAvgEntryPrices | any | true | none | After a RealizedPnl strategy update, what the new average entry prices are for this strategies' open positions. |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»»» anonymous | any | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»»» anonymous | null | false | none | none |
continued
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» fundingPayments | any | true | none | Payment distribution broken down by symbol due to the position's notional value and funding rate at the time of the funding event. |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»»» anonymous | any | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»»» anonymous | null | false | none | none |
continued
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Markets
These APIs return key high level metrics for markets.
Markets
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/markets',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/markets', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/markets',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/markets
Returns keys metrics for markets
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
symbol | query | string | false | The symbol |
aggregationPeriod | query | string | false | The period for the aggregation. |
lookbackCount | query | integer | false | The number of periods to look back from present. |
Enumerated Values
Parameter | Value |
---|---|
aggregationPeriod | week |
aggregationPeriod | day |
aggregationPeriod | hour |
aggregationPeriod | minute |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Market data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"market": "BTCP",
"volume": "569664.89",
"price": "21969.23",
"fundingRate": "0.005",
"openInterest": "15000000"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Markets API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» market | string | true | none | The symbol of the market. |
»» volume | string | true | none | The total volume for the market over the time period. |
»» price | string | true | none | The most recent mark price. |
»» fundingRate | string | true | none | The funding rate estimate over the time period. |
»» openInterest | string | true | none | The current open interest for the market. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Order Book L2
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/markets/order_book/L2',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/markets/order_book/L2', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/markets/order_book/L2',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/markets/order_book/L2
Returns L2 orderbooks
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
symbol | query | string | false | The symbol |
depth | query | integer | false | The best N bids and asks to return, where N = depth |
side | query | integer | false | The side of the order. Values include: |
Detailed descriptions
side: The side of the order. Values include: 0: Bid, 1: Ask
Enumerated Values
Parameter | Value |
---|---|
side | 0 |
side | 1 |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Order Book L2 data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"symbol": "ETHP",
"amount": "0.1",
"price": 1000,
"side": 0
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Order Book L2 API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» symbol | string | true | none | The symbol of the asset for this order aggregation. |
»» side | number | true | none | The side of the order aggregation. Values include: 0: Bid, 1: Ask |
»» amount | string | true | none | The order amount currently left on this aggregation level. |
»» price | string | true | none | The price level of the aggregation. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Ticker
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/markets/tickers',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/markets/tickers', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/markets/tickers',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/markets/tickers
Returns all Ticker data
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
symbol | query | string | false | The symbol |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Ticker data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"symbol": "ETHP",
"high": "2000",
"low": "1000",
"volumeWeightedAveragePrice": "1600",
"open": "1100",
"close": "1700",
"previousClose": "1000",
"change": "600",
"percentage": "54.54",
"baseVolume": "150",
"notionalVolume": "18026.42"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for Ticker API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» symbol | string | true | none | The symbol of the asset for this ticker. |
»» high | string,null | true | none | The highest index price for the current 24 hour period. |
»» low | string,null | true | none | The lowest index price for the current 24 hour period. |
»» volumeWeightedAveragePrice | string,null | true | none | The volume weighted average price for the current 24 period. |
»» open | string,null | true | none | The opening index price for the current 24 hour period. |
»» close | string,null | true | none | The closing index price for the current 24 hour period. |
»» previousClose | string,null | true | none | The closing index price in the previous 24 hour period. |
»» change | string,null | true | none | The absolute change of the index price in the current 24 hour period, close - open. |
»» percentage | string,null | true | none | The relative change of the index price in the current 24 hour period, (change / open) * 100. |
»» baseVolume | string,null | true | none | The sum of the underlying asset traded in the current 24 hour period |
»» notionalVolume | string,null | true | none | The notional sum of the asset traded in the current 24 hour period |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Full table views
These APIs provide access to all the rows from the DerivaDEX database.
Order rejections
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/order_rejections',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/order_rejections', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/order_rejections',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/order_rejections
Returns all orders that were rejected
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
offset | query | integer | false | The offset of returned rows |
symbol | query | string | false | The symbol |
orderHash | query | string | false | the order hash of the order intent. Multiple order hash values can be provided. |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Order rejection data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"epochId": 100,
"requestIndex": 3432,
"orderHash": [
"0xa3c4c1c18c6e72c4aea8cfa0a1868ac4bc0f9b6463e8c9687f"
],
"symbol": [
"ETHP"
],
"amount": "1.0",
"reason": 0,
"traderAddress": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyId": "main"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Order Rejections API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» requestIndex | string | true | none | The request index. |
»» orderHash | string | true | none | A hash of this order's contents. |
»» symbol | string | true | none | The symbol of the asset for this order. |
»» amount | string | true | none | The amount of the order that got rejected. |
»» reason | number | true | none | The reason the order was rejected. Values include: 0: Self match 1: Solvency 2: Market order not fully filled |
»» traderAddress | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who issues this order. |
»» strategyId | string | true | none | The strategy of the trader which owns this order. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Enumerated Values
Property | Value |
---|---|
reason | 0 |
reason | 1 |
reason | 2 |
reason | 3 |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
ADLs
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/adls',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/adls', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/adls',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/adls
Returns all ADL timeseries data
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
ordinal | query | integer | false | The ordinal boundary used when fetching the next timeseries page. Must be passed along with epoch and txOrdinal. |
order | query | string | false | The ordering of the results. |
symbol | query | string | false | The symbol |
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | ADLs timeseries data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"ordinal": 0,
"amount": "1.0",
"symbol": "ETHP",
"adlTrader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"adlStrategyIdHash": "0x2576ebd1",
"liquidatedTrader": "0x006bb7d07901a1aade4ead7b68167224a0512985cf",
"liquidatedStrategyIdHash": "0x2576ebd1",
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for ADLs API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» ordinal | string | true | none | The ordinal within this particular transaction. |
»» amount | string | true | none | The amount that was auto de-leveraged. |
»» symbol | string | true | none | The symbol of the asset that was auto de-leveraged. |
»» adlTrader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who was de-leveraged. |
»» adlStrategyIdHash | string | true | none | The strategy ID from the trader who was de-leveraged. |
»» liquidatedTrader | string | true | none | The trader address of the trader who was liquidated, leading to this adl. |
»» liquidatedStrategyIdHash | string | true | none | The strategy ID from the trader who was liquidated, leading to this adl. |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
DDX fee pool
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/ddx_fee_pool',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/ddx_fee_pool', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/ddx_fee_pool',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/ddx_fee_pool
Returns total capitalization of the DDX fee pool as timeseries
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
order | query | string | false | The ordering of the results. |
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | DDX fee pool timeseries data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"totalCapitalization": "1.929969",
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for DDX fee pool API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» totalCapitalization | string,null | true | none | The total capitalization of the DDX fee pool after this transaction occured. |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Epochs
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/epochs',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/epochs', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/epochs',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/epochs
Returns all epoch start and end time data
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
limit | query | integer | false | The number of rows to return |
offset | query | integer | false | The offset of returned rows |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Epoch start and end time data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"epochId": 100,
"startTime": "2023-01-06T16:37:27.929Z",
"endTime": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for Epochs API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch number. |
»» startTime | string(date-time) | true | none | The timestamp at which this epoch started. |
»» endTime | string | true | none | The timestamp at which this epoch ended. This will be null if the epoch is still ongoing. |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»»» anonymous | object(date-time) | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»»» anonymous | null | false | none | none |
continued
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Funding Rate History
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/funding_rate_history',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/funding_rate_history', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/funding_rate_history',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/funding_rate_history
Returns all funding rate data
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
order | query | string | false | The ordering of the results. |
symbol | query | string | false | The symbol |
since | query | integer | false | The earliest time in seconds to fetch rows for. This param cannot be used together with param order = 'desc' |
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Funding Rate History Data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"symbol": "BTCP",
"fundingRate": "0.005",
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Funding Rate History API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this funding rate update occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» symbol | string | true | none | The symbol of the market. |
»» fundingRate | string | true | none | The funding rate for the given market. |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Insurance fund
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/insurance_fund',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/insurance_fund', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/insurance_fund',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/insurance_fund
Returns the total capitalization of the insurance fund with per transaction granularity
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
order | query | string | false | The ordering of the results. |
symbol | query | string | false | The symbol |
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Insurance fund capitalization timeseries data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"symbol": "USDC",
"totalCapitalization": "1000000",
"kind": 0,
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for Insurance Fund API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» symbol | string | true | none | The symbol of the insurance fund asset. |
»» totalCapitalization | string,null | true | none | The total capitalization of the insurance fund after this transaction occured. |
»» kind | number | true | none | The type of insurance fund capitalization change. Values include: 0: fill, 1: liquidation, 2: deposit, 3: withdrawal |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Liquidations
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/liquidations',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/liquidations', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/liquidations',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/liquidations
Returns all liquidations timeseries data
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
ordinal | query | integer | false | The ordinal boundary used when fetching the next timeseries page. Must be passed along with epoch and txOrdinal. |
order | query | string | false | The ordering of the results. |
symbol | query | string | false | The symbol |
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Liquidations timeseries data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"ordinal": 0,
"symbol": "ETHP",
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyIdHash": "0x2576ebd1",
"triggerPriceHash": "0x7fedd251937b6240d46f989f21d06ea0d8929cd42cf627cee6",
"markPrice": "51899.698653",
"insuranceFundCapitalization": "string",
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Liquidation API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» ordinal | string | true | none | The ordinal within this particular transaction. |
»» symbol | string | true | none | The symbol of the asset in which the liquidation occured. |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who was liquidated. |
»» strategyIdHash | string | true | none | The strategy id of the trader who was liquidated. |
»» triggerPriceHash | string,null | true | none | The hash of the price update that caused the liquidation. |
»» markPrice | string | true | none | The mark price of the asset at the time of liquidation. |
»» insuranceFundCapitalization | string | true | none | The insurance fund capitalization after this liquidation transaction. |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Mark prices
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/mark_prices',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/mark_prices', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/mark_prices',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/mark_prices
Returns all mark prices
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
symbol | query | string | false | The symbol |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Mark price data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"requestIndex": 981,
"symbol": "ETHP",
"price": 3428.44,
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Mark Price API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which the mark price belongs. |
»» requestIndex | string | true | none | The request index associated with the mark price. |
»» symbol | string | true | none | The symbol of the asset. |
»» price | string | true | none | The mark price value. |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Open Interest History
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/open_interest_history',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/open_interest_history', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/open_interest_history',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/open_interest_history
Returns open interest history
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
order | query | string | false | The ordering of the results. |
symbol | query | string | false | The symbol |
interval | query | string | false | The interval for open interest history. |
since | query | integer | false | The earliest time in seconds to fetch rows for. This param cannot be used together with param order = 'desc' |
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
interval | 5m |
interval | 1h |
interval | 1d |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Open Interest History Data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"symbol": "BTCP",
"amount": "1000",
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Open Interest History API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» symbol | string | true | none | The symbol of the market. |
»» amount | string | true | none | The amount of open interest for the given market. |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Order book
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/order_book',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/order_book', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/order_book',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/order_book
Returns all open orders on the book
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
depth | query | integer | false | The best N bids and asks to return, where N = depth |
symbol | query | string | false | The symbol |
side | query | integer | false | The side of the order. Values include: |
Detailed descriptions
side: The side of the order. Values include: 0: Bid, 1: Ask
Enumerated Values
Parameter | Value |
---|---|
side | 0 |
side | 1 |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Order book data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"orderHash": "0xc8ab0f901fc3968dfae99b6efb34b0bdd81d69aefb21effcf5",
"symbol": "ETHP",
"side": 0,
"originalAmount": "1.0",
"amount": "0.9",
"price": "595.8",
"traderAddress": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyId": "main",
"bookOrdinal": "54"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the OrderBook API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» orderHash | string | true | none | A hash of the order details. |
»» symbol | string | true | none | The symbol of the asset for this order. |
»» side | number | true | none | The side of the order. Values include: 0: Bid, 1: Ask |
»» originalAmount | string | true | none | The original order amount (before any fills). |
»» amount | string | true | none | The order amount currently left on this order. |
»» price | string | true | none | The order price. |
»» traderAddress | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who owns this order. |
»» strategyId | string | true | none | The strategy of the trader which owns this order. |
»» bookOrdinal | string | true | none | The ordinal of when this order arrived on the book. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Order intents
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/order_intents',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/order_intents', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/order_intents',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/order_intents
Returns all orders that were opened
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
order | query | string | false | The ordering of the results. |
symbol | query | string | false | The symbol |
orderHash | query | string | false | the order hash of the order intent. Multiple order hash values can be provided. |
side | query | integer | false | The side of the order. Values include: |
since | query | integer | false | The earliest time in seconds to fetch rows for. This param cannot be used together with param order = 'desc' |
filterByStatus | query | integer | false | The status of the order intents. 0-Fully Filled; 1-Partially Filled; 2-Not Filled. Multiple values can be provided. |
Detailed descriptions
side: The side of the order. Values include: 0: Bid, 1: Ask
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
side | 0 |
side | 1 |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Order history data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"orderHash": [
"0xa3c4c1c18c6e72c4aea8cfa0a1868ac4bc0f9b6463e8c9687f"
],
"symbol": [
"ETHP"
],
"side": 0,
"amount": "1.0",
"remainingAmount": "0.5",
"price": "1500.0",
"traderAddress": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyId": "main",
"orderType": 0,
"stopPrice": "0",
"nonce": "0x3136373332393531393331383537373332363800000000000000000000000000",
"signature": "0xf9b19b088e3d0ad2c6330231899e03e50b45a8c7a1f52082aa0e9a61391fd5a35d3aece9dd2d42132a25b0aef5ac1bda7aee87c0c0c25ab9525d5eeeff9787d81b",
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Order Intents Stats API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» orderHash | string | true | none | A hash of this order contents. |
»» symbol | string | true | none | The symbol of the asset for this order. |
»» side | number | true | none | The side of the order. Values include: 0: Bid, 1: Ask |
»» amount | string | true | none | The amount of the order. |
»» remainingAmount | string | true | none | The order amount currently left on this order. |
»» price | string | true | none | The price of the order. |
»» traderAddress | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who issues this order. |
»» strategyId | string | true | none | The strategy of the trader which owns this order. |
»» orderType | number | true | none | The type of order. Values include: 0: Limit, 1: Market 2: Stop |
»» stopPrice | string | true | none | The stop price for this order. Not currently an active field. |
»» nonce | string | true | none | The nonce sent by the trader when placing this order. |
»» signature | string | true | none | A signature which was used to verify the authenticity of the order, when it was sent by the trader. Encrypted using the public key exposed by the leader Operator. |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Order updates
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/order_updates',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/order_updates', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/order_updates',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/order_updates
Returns all order update timeseries data
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
ordinal | query | integer | false | The ordinal boundary used when fetching the next timeseries page. Must be passed along with epoch and txOrdinal. |
order | query | string | false | The ordering of the results. |
symbol | query | string | false | The symbol |
orderHash | query | string | false | the order hash of the order intent. Multiple order hash values can be provided. |
fillReason | query | integer | false | The reason for the creation of this row. 0-Trade; 1-Liquidation; 2-Cancel. Multiple reason values can be provided. |
since | query | integer | false | The earliest time in seconds to fetch rows for. This param cannot be used together with param order = 'desc' |
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Order Update timeseries data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"ordinal": 0,
"makerOrderHash": "0xe49584ff9d5a154d2075ff658ccb4c7af844bb9fad5055ad72",
"makerOrderTrader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"makerOrderStrategyIdHash": "0x2576ebd1",
"amount": "1.5",
"symbol": "ETHP",
"price": "595.8",
"makerFeeUSDC": "0",
"makerFeeDDX": "0",
"makerRealizedPnl": "0",
"reason": 0,
"takerOrderHash": "0x93ee93e9e90db7f3f8ae2815cb54610c6e072fe3cf9a475be2",
"takerOrderTrader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"takerOrderStrategyIdHash": "0x2576ebd1",
"takerFeeUSDC": "1.7874",
"takerFeeDDX": "1.7874",
"takerRealizedPnl": "0",
"liquidatedTrader": null,
"liquidatedStrategyIdHash": null,
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for fills API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» ordinal | string | true | none | The ordinal within this particular transaction. |
»» makerOrderHash | string | true | none | The order hash for the maker side of this fill. |
»» makerOrderTrader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader which owns the maker order. |
»» makerOrderStrategyIdHash | string | true | none | The hashed strategy id of the strategy which owns the maker order. |
»» amount | string | true | none | The amount that was filled. |
»» symbol | string | true | none | The symbol of the asset that was filled. |
»» price | string,null | true | none | The fill price. |
»» makerFeeUSDC | string,null | true | none | The USDC fee that was incurred to the maker side of the fill if the maker receives fees in USDC. |
»» makerFeeDDX | string,null | true | none | The fee that was incurred to the maker side of the fill if the maker elected to receive fees in DDX. Null otherwise. |
»» makerRealizedPnl | string,null | true | none | The realized profit and loss (not inclusive of fees) incurred to the maker due to this fill. Null otherwise. |
»» reason | number | true | none | The type of fill. Values include: 0: trade, 1: liquidation, 2: cancel |
»» takerOrderHash | string,null | true | none | The order hash for the taker side of this fill. |
»» takerOrderTrader | string,null | true | none | The trader address prefixed with the blockchain discriminant of the trader which owns the taker order. |
»» takerOrderStrategyIdHash | string,null | true | none | The hashed strategy id of the strategy which owns the taker order. |
»» takerFeeUSDC | string,null | true | none | The fee that was incurred to the taker side of the fill if taker receives fees in USDC. Null otherwise |
»» takerFeeDDX | string,null | true | none | The fee that was incurred to the taker side of the fill if taker receives fees in DDX. Null otherwise |
»» takerRealizedPnl | string,null | true | none | The realized profit and loss (not inclusive of fees) incurred to the taker due to this fill. |
»» liquidatedTrader | string,null | true | none | In the case that this was a liquidation fill, the trader address prefixed with the blockchain discriminant of the trader that was liquidated. |
»» liquidatedStrategyIdHash | string,null | true | none | The liquidated strategy id hash |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Positions
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/positions',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/positions', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/positions',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/positions
Returns all currently open positions
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
offset | query | integer | false | The offset of returned rows |
symbol | query | string | false | The symbol |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Positions data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"symbol": "ETHP",
"strategyIdHash": "0x2576ebd1",
"side": 0,
"balance": "1.0",
"avgEntryPrice": "1500",
"lastModifiedInEpoch": 35
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for positions API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who owns this position. |
»» symbol | string | true | none | The symbol of the asset for this position. |
»» strategyIdHash | string | true | none | The hash of the strategy which owns this position. |
»» side | number | true | none | The side of the position. Values include: 0: None, 1: Long, 2: Short |
»» balance | string | true | none | The current balance of this position. |
»» avgEntryPrice | string | true | none | The average entry price of this position. |
»» lastModifiedInEpoch | number,null | true | none | The epoch in which this position's balance was last modified. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Price Checkpoints
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/price_checkpoints',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/price_checkpoints', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/price_checkpoints',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/price_checkpoints
Returns all price checkpoints
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
order | query | string | false | The ordering of the results. |
symbol | query | string | false | The symbol |
priceHash | query | string | false | the index price hash of the mark price. Multiple price hash values can be provided. |
Enumerated Values
Parameter | Value |
---|---|
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Price checkpoint data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"indexPriceHash": "0x607b9303d1da6aa842c4f7af2ae18d8616e5af63b692a05151",
"symbol": "ETHP",
"indexPrice": "5311.571505",
"markPrice": "5311.203",
"time": "100",
"ema": "-2.67",
"priceOrdinal": "100",
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Price Checkpoints API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» indexPriceHash | string | true | none | The hash of the index price. |
»» symbol | string | true | none | The symbol of the asset. |
»» indexPrice | string | true | none | The exponential weighted average of prices from the price feed by source. |
»» markPrice | string | true | none | The index price + ema clamped to 50bps above/below the index price at all times. |
»» time | string | true | none | The monotonic clock tick associated with this price checkpoint. |
»» ema | string | true | none | Exponential moving average which tracks the spread between the DerivaDEX Petual swap price and the underlying index price it is tracking. |
»» priceOrdinal | string | true | none | The ordinal of this price update. |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Specs
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/specs',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/specs', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/specs',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/specs
Returns Operator configuration settings data
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
kind | query | integer | false | The type of spec update. Values include: |
limit | query | integer | false | The number of rows to return |
offset | query | integer | false | The offset of returned rows |
Detailed descriptions
kind: The type of spec update. Values include: 0: Market 1: MarketGateway
Enumerated Values
Parameter | Value |
---|---|
kind | 0 |
kind | 1 |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Specs data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"kind": 0,
"name": "ETHP",
"expr": "(Market :name \"ETHP\":tick-size 0.1:max-order-notional 1000000:max-taker-price-deviation 0.02:min-order-size 0.0001)",
"value": {
"tickSize": "0.1",
"minOrderSize": "0.0001",
"maxOrderNotional": "1000000",
"maxTakerPriceDeviation": "0.02"
}
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Specs API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» kind | number | true | none | The type of setting. Values include: 0: Market, 1: MarketGateway - a group of settings for a particular price feed source, |
»» name | string | true | none | The name of the setting. |
»» expr | string | true | none | A colon seperated set of key value pairs describing the setting |
»» value | any | true | none | The value of the setting . |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Strategies
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/strategies',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/strategies', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/strategies',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/strategies
Returns all strategies
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
offset | query | integer | false | The offset of returned rows |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Strategy data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyIdHash": "0x2576ebd1",
"strategyId": "main",
"maxLeverage": 3,
"availCollateral": "10000",
"lockedCollateral": "1000",
"frozen": false
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Strategies API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who owns this strategy. |
»» strategyIdHash | string | true | none | The hashed version of this strategy ID. |
»» strategyId | string | true | none | An identifier for this strategy. |
»» maxLeverage | number | true | none | The maximum leverage this strategy is allowed to take on. |
»» availCollateral | string | true | none | The amount of collateral that this strategy holds. |
»» lockedCollateral | string | true | none | The amount of collateral which has been initiated for withdrawal. |
»» frozen | boolean | true | none | Whether this strategy is frozen. Not currently in use. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Strategy updates
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/strategy_updates',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/strategy_updates', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/strategy_updates',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/strategy_updates
Returns all strategy updates
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
kind | query | integer | false | The type of strategy update. Multiple strategy update values can be provided. Values include: |
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
ordinal | query | integer | false | The ordinal boundary used when fetching the next timeseries page. Must be passed along with epoch and txOrdinal. |
order | query | string | false | The ordering of the results. |
Detailed descriptions
kind: The type of strategy update. Multiple strategy update values can be provided. Values include: 0: Deposit, 1: Withdraw, 2: WithdrawIntent, 3: FundingPayment, 4: RealizedPnl
Enumerated Values
Parameter | Value |
---|---|
kind | 0 |
kind | 1 |
kind | 2 |
kind | 3 |
kind | 4 |
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Strategy updates data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"ordinal": 0,
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyIdHash": "0x2576ebd1",
"collateralAddress": "0x8ea76477cfaca8f7ea06477fd3c09a740ac6012a",
"amount": "1000",
"newAvailCollateral": "10000",
"newLockedCollateral": "10000",
"kind": 0,
"blockNumber": "344100",
"txHash": "0xfcdae2edac7063ae3a3fb0e74b48816a0593644a3b2f5d701c8e5fafec70828e",
"newAvgEntryPrices": {
"BTCP": "51591.628081",
"ETHP": "4786.43076"
},
"fundingPayments": {
"BTCP": "17.918454670996998719225076469",
"ETHP": "-2.1938698405321453631273234871"
},
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Strategy Updates API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» ordinal | string | true | none | The ordinal within this particular transaction. |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader who owns this strategy. |
»» strategyIdHash | string | true | none | The hashed version of this strategy ID. |
»» collateralAddress | string,null | true | none | The collateral address on which this strategy update took place. |
»» amount | string | true | none | The amount that was modified in the strategy. |
»» newAvailCollateral | string,null | true | none | If affected, the updated available collateral amount after this strategy update. |
»» newLockedCollateral | string,null | true | none | If affected, the updated locked collateral amount after this strategy update. |
»» kind | number | true | none | The type of strategy update. Values include: 0: Deposit, 1: Withdraw, 2: WithdrawIntent, 3: FundingPayment, 4: RealizedPnl |
»» blockNumber | string,null | true | none | The block number in which this strategy update was processed. |
»» txHash | string,null | true | none | The on-chain transaction hash corresponding to this strategy update (for Deposit and Withdraw kinds) |
»» newAvgEntryPrices | any | true | none | After a RealizedPnl strategy update, what the new average entry prices are for this strategies' open positions. |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»»» anonymous | any | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»»» anonymous | null | false | none | none |
continued
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» fundingPayments | any | true | none | Payment distribution broken down by symbol due to the position's notional value and funding rate at the time of the funding event. |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»»» anonymous | any | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»»» anonymous | null | false | none | none |
continued
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Trader updates
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/trader_updates',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/trader_updates', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/trader_updates',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/trader_updates
Returns all trader updates
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
kind | query | integer | false | The type of trader update. Multiple trader update values can be provided. Values include: |
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
ordinal | query | integer | false | The ordinal boundary used when fetching the next timeseries page. Must be passed along with epoch and txOrdinal. |
order | query | string | false | The ordering of the results. |
Detailed descriptions
kind: The type of trader update. Multiple trader update values can be provided. Values include: 0: Deposit 1: WithdrawDDX 2: ClaimDDXWithdraw 3: TradeMiningReward
Enumerated Values
Parameter | Value |
---|---|
kind | 0 |
kind | 1 |
kind | 2 |
kind | 3 |
kind | 4 |
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Trader updates data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"ordinal": 0,
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"amount": "1000",
"newDdxBalance": "1200",
"kind": 0,
"payFeesInDdx": true,
"blockNumber": "344100",
"txHash": "0xfcdae2edac7063ae3a3fb0e74b48816a0593644a3b2f5d701c8e5fafec70828e",
"createdAt": "2023-01-06T16:37:27.929Z"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Trader Updates API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» ordinal | string | true | none | The ordinal within this particular transaction. |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant of the trader. |
»» amount | string,null | true | none | The amount of DDX was modified in this trader. |
»» newDdxBalance | string,null | true | none | The new DDX balance after updating this trader. |
»» kind | number | true | none | The type of trader update. Values include: 0: Deposit 1: WithdrawDDX 2: ClaimDDXWithdraw 3: TradeMiningReward |
»» payFeesInDdx | boolean,null | true | none | A flag which when set will attempt to pay trading fees using the DDX held in this trader. |
»» blockNumber | string,null | true | none | The block number in which this strategy update was processed. |
»» txHash | string,null | true | none | The on-chain transaction hash corresponding to this trader update (for Deposit and ClaimDDXWithdraw kinds) |
»» createdAt | string(date-time) | true | none | The time when this row was added to the database. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Traders
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/traders',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/traders', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/traders',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/traders
Returns all traders
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
offset | query | integer | false | The offset of returned rows |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Traders data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"availDdx": "1000",
"lockedDdx": "200",
"payFeesInDdx": true
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Traders API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant. |
»» availDdx | string | true | none | The amount of DDX that the trader holds. |
»» lockedDdx | string | true | none | The amount of DDX that the trader has initiated for withdrawal. |
»» payFeesInDdx | boolean | true | none | A flag which indicates whether the trader wants to attempt to pay trading fees using their DDX balance. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Transaction Logs
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/tx_logs',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/tx_logs', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/tx_logs',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/tx_logs
Returns all transaction logs
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
eventKind | query | integer | false | The type of transaction log event. Values include: |
limit | query | integer | false | The number of rows to return |
epoch | query | integer | false | The epoch boundary used when fetching the next timeseries page. |
txOrdinal | query | integer | false | The txOrdinal boundary used when fetching the next timeseries page. Must be passed along with epoch. |
order | query | string | false | The ordering of the results. |
Detailed descriptions
eventKind: The type of transaction log event. Values include: 0: Partial fill, 1: Complete fill, 2: Post, 3: Cancel, 4: Liquidation, 5: Strategy update, 6: Trader update, 7: Withdraw, 8: Withdraw DDX, 9: Price Checkpoint, 10: PnL Realization, 11: Funding, 12: Trade mining, 13: Specs update, 14: Insurance fund update, 15: Insurance fund withdraw, 16: Disaster recovery, 30: Cancel all, 60: Signer registered, 70: Fee distribution, 100: Epoch marker, 999: No transition
Enumerated Values
Parameter | Value |
---|---|
eventKind | 0 |
eventKind | 1 |
eventKind | 2 |
eventKind | 3 |
eventKind | 4 |
eventKind | 5 |
eventKind | 6 |
eventKind | 7 |
eventKind | 8 |
eventKind | 9 |
eventKind | 10 |
eventKind | 11 |
eventKind | 12 |
eventKind | 13 |
eventKind | 14 |
eventKind | 15 |
eventKind | 16 |
eventKind | 30 |
eventKind | 60 |
eventKind | 70 |
eventKind | 100 |
eventKind | 999 |
order | asc |
order | desc |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Transaction log data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextEpoch": 100,
"nextTxOrdinal": 3432,
"nextOrdinal": 100,
"value": [
{
"epochId": 100,
"txOrdinal": 3432,
"requestIndex": "24032",
"batchId": "string",
"timeValue": "2343",
"timeStamp": "1673294861956",
"stateRootHash": "0x070c27fdf7e15363044fe3384a50febfa5d4c9e4990a1ed3df6c4c4f41b51bbb",
"eventKind": 0,
"event": {
"c": {
"amount": "10000",
"trader": "0x006ffdc68e0e6709c11938d59b3a50b11a25957377",
"txHash": "0x0740398fe79ac316aeeaa430f651f5ba085fede0513aa9e1bf40c17b8aee9c77",
"strategyId": "main",
"updateKind": "Deposit",
"blockNumber": 610,
"collateralAddress": "0x8ea76477cfaca8f7ea06477fd3c09a740ac6012a"
},
"t": "StrategyUpdate"
}
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the TxLog API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextEpoch | number,null | true | none | Pointer for the epoch boundary of the next page. Will return null when there is no more data left to fetch. |
» nextTxOrdinal | number,null | true | none | Pointer for the txOrdinal boundary of the next page. Will return null when there is no more data left to fetch. |
» nextOrdinal | number,null | true | none | Pointer for the ordinal boundary of the next page. Will return null when there is no more data left to fetch. |
» value | [object] | true | none | The value of the response |
»» epochId | string | true | none | The epoch in which this transaction occured. |
»» txOrdinal | string | true | none | The transaction ordinal, within the epoch. |
»» requestIndex | string | true | none | The index of the sequenced request from which this transaction originated. |
»» batchId | string | true | none | Numerical identifier for a batch of transactions. |
»» timeValue | string | true | none | The monotonic clock tick associated with this transaction log. |
»» timeStamp | string | true | none | The unix timestamp associated with this transaction log. |
»» stateRootHash | string | true | none | A hash representing the full state of the exchange, before processing this transaction log. |
»» eventKind | number | true | none | The type of transaction log event. Values include: 0: Partial fill, 1: Complete fill, 2: Post, 3: Cancel, 4: Liquidation, 5: Strategy update, 6: Trader update, 7: Withdraw, 8: Withdraw DDX, 9: Price Checkpoint, 10: PnL Realization, 11: Funding, 12: Trade mining, 13: Specs update, 14: Insurance fund update, 15: Insurance fund withdraw, 16: Disaster recovery, 30: Cancel all, 60: Signer registered, 70: Fee distribution, 100: Epoch marker, 999: No transition |
»» event | any | true | none | The transaction event in JSON format. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status
These APIs return key status metrics.
Exchange status
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/status/exchange',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/status/exchange', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/status/exchange',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/status/exchange
Returns high level information about the exchange status.
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Exchange status data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": {
"currentEpoch": "9958",
"latestOnChainCheckpoint": {
"latestOnChainCheckpoint": 9920,
"latestCheckpointTransactionLink": "https://goerli.etherscan.io/tx/0x05f4e74a64b2626af2edc555249484781732508f2096aed0aa52be2d09a51a73"
},
"activeAddresses": "20"
},
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Exchange Status API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | object | true | none | High level status information about the exchange |
»» latestOnChainCheckpoint | any | true | none | Information about the latest on-chain checkpoint. Returns null if there haven't been any on-chain checkpoints. |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»»» anonymous | object | false | none | Data about the latest on-chain checkpoint. |
»»»» latestOnChainCheckpoint | number | true | none | The latest on-chain checkpoint number. |
»»»» latestCheckpointTransactionLink | string,null | true | none | An etherscan link to the latest on-chain checkpoint transaction. |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»»» anonymous | null | false | none | none |
continued
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» activeAddresses | number | true | none | The number of active addresses on the exchange. Active addresses are defined as addresses that have deposited, withdrawn, or traded within the last 24 hours or have currently open positions. |
»» currentEpoch | string | true | none | The latest epoch on the Operator network. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Supply
This APIs returns DDX circulating supply metrics.
Circulating supply
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/supply',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/supply', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/supply',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/supply
Returns the current DDX circulating supply
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | DDX Circulating Supply | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": {
"circulatingSupply": "26094663"
},
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Exchange Supply API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | object | true | none | The current circulating supply of DDX tokens |
»» circulatingSupply | string | true | none | The current circulating supply of DDX tokens. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Aggregations
Balance aggregation
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/aggregations/account/{trader}/strategy/{strategyId}/balance',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/aggregations/account/{trader}/strategy/{strategyId}/balance', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/aggregations/account/{trader}/strategy/{strategyId}/balance',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/aggregations/account/{trader}/strategy/{strategyId}/balance
Returns the change of trader's balance for a specific strategy over a specific time period, looking back from the present
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
strategyId | path | string | true | The strategy ID. |
aggregationPeriod | query | string | false | The period for the aggregation. |
lookbackCount | query | integer | false | The number of periods to look back from present. |
Enumerated Values
Parameter | Value |
---|---|
aggregationPeriod | week |
aggregationPeriod | day |
aggregationPeriod | hour |
aggregationPeriod | minute |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Balance aggregation data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyIdHash": "0x2576ebd1",
"amount": "0.9",
"timestamp": 1673308800
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Balance API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant. |
»» strategyIdHash | string | true | none | The strategy id hash of the trader. |
»» amount | string | true | none | The amount. |
»» timestamp | number | true | none | The unix timestamp at the start of the aggregation period. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Funding rate payments aggregation
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/aggregations/account/{trader}/strategy/{strategyId}/funding_rate_payments',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/aggregations/account/{trader}/strategy/{strategyId}/funding_rate_payments', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/aggregations/account/{trader}/strategy/{strategyId}/funding_rate_payments',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/aggregations/account/{trader}/strategy/{strategyId}/funding_rate_payments
Returns the change of trader's funding rate payments for a specific strategy over a specific time period, looking back from the present
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
strategyId | path | string | true | The strategy ID. |
aggregationPeriod | query | string | false | The period for the aggregation. |
lookbackCount | query | integer | false | The number of periods to look back from present. |
Enumerated Values
Parameter | Value |
---|---|
aggregationPeriod | week |
aggregationPeriod | day |
aggregationPeriod | hour |
aggregationPeriod | minute |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Funding rate payments aggregation data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyIdHash": "0x2576ebd1",
"amount": "0.9",
"timestamp": 1673308800
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Funding Rate Payments API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant. |
»» strategyIdHash | string | true | none | The strategy id hash of the trader. |
»» amount | string | true | none | The amount. |
»» timestamp | number | true | none | The unix timestamp at the start of the aggregation period. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Realized pnl aggregation
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/aggregations/account/{trader}/strategy/{strategyId}/realized_pnl',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/aggregations/account/{trader}/strategy/{strategyId}/realized_pnl', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/aggregations/account/{trader}/strategy/{strategyId}/realized_pnl',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/aggregations/account/{trader}/strategy/{strategyId}/realized_pnl
Returns the change of trader's realized pnl, per time period looking back from the present
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
strategyId | path | string | true | The strategy ID. |
aggregationPeriod | query | string | false | The period for the aggregation. |
lookbackCount | query | integer | false | The number of periods to look back from present. |
Enumerated Values
Parameter | Value |
---|---|
aggregationPeriod | week |
aggregationPeriod | day |
aggregationPeriod | hour |
aggregationPeriod | minute |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Realized Pnl aggregation data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"strategyIdHash": "0x2576ebd1",
"amount": "0.9",
"timestamp": 1673308800
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Realized Pnl API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant. |
»» strategyIdHash | string | true | none | The strategy id hash of the trader. |
»» amount | string | true | none | The amount. |
»» timestamp | number | true | none | The unix timestamp at the start of the aggregation period. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Volume aggregation
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/aggregations/volume',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/aggregations/volume', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/aggregations/volume',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/aggregations/volume
Returns volume per time period looking back from the present
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
group | query | string | false | The grouping for the aggregation. |
symbol | query | string | false | The symbol |
aggregationPeriod | query | string | false | The period for the aggregation. |
lookbackCount | query | integer | false | The number of periods to look back from present. |
lookbackTimestamp | query | number | false | The timestamp of the when to begin the lookback from. Each lookback query will return nextLookbackTimestamp in the response, which can be passed as a query parameter here to get the next page of results. |
Detailed descriptions
lookbackTimestamp: The timestamp of the when to begin the lookback from. Each lookback query will return nextLookbackTimestamp in the response, which can be passed as a query parameter here to get the next page of results.
Enumerated Values
Parameter | Value |
---|---|
group | symbol |
aggregationPeriod | week |
aggregationPeriod | day |
aggregationPeriod | hour |
aggregationPeriod | minute |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Volume aggregation data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextLookbackTimestamp": 1673384400,
"value": [
{
"timestamp": 1673308800,
"volume_overall": "164113411.21248"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Volume aggregation API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextLookbackTimestamp | number,null | true | none | Time pointer for where the next lookback should begin. Pass this value as lookbackTimestamp to get the next page of data. Will also skip over gaps in the data to return the next non-null. aggregation period. When this value is null, it indicates there is no more data to fetch. |
» value | [object] | true | none | The value of the response |
»» additionalProperties | string | false | none | none |
»» timestamp | number | true | none | The unix timestamp at the start of the aggregation period. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Trade Mining Rewards for the trader
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/aggregations/account/{trader}/trade_mining_rewards',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/aggregations/account/{trader}/trade_mining_rewards', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/aggregations/account/{trader}/trade_mining_rewards',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/aggregations/account/{trader}/trade_mining_rewards
Returns the aggregation of a trader's trade mining rewards
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trader | path | string | true | The trader address. |
aggregationPeriod | query | string | false | The period for the aggregation. |
lookbackCount | query | integer | false | The number of periods to look back from present. |
Enumerated Values
Parameter | Value |
---|---|
aggregationPeriod | week |
aggregationPeriod | day |
aggregationPeriod | hour |
aggregationPeriod | minute |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Trade mining rewards aggregation data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"value": [
{
"trader": "0x00b993e587c15a9e0a0fe4f111de98fd6b5ce7067d",
"amount": "0.9",
"timestamp": 1673308800
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Trade Mining Rewards API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» value | [object] | true | none | The value of the response |
»» trader | string | true | none | The trader address prefixed with the blockchain discriminant. |
»» amount | string | true | none | The amount. |
»» timestamp | number | true | none | The unix timestamp at the start of the aggregation period. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Collateral aggregation
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/aggregations/collateral',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/aggregations/collateral', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/aggregations/collateral',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/aggregations/collateral
Returns a rolling sum of collateral per time period grouped by the inflow and outflow types.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
aggregationPeriod | query | string | false | The period for the aggregation. |
startingValue | query | number | false | The partial total of this aggregation, used for rolling aggregation paging. |
fromEpoch | query | integer | false | The from epoch |
toEpoch | query | integer | false | The to epoch |
Enumerated Values
Parameter | Value |
---|---|
aggregationPeriod | week |
aggregationPeriod | day |
aggregationPeriod | hour |
aggregationPeriod | minute |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Collateral aggregation data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextStartingValue": "34000",
"value": [
{
"timestamp": 1673222400,
"collateral_deposits": "765000000",
"collateral_withdrawals": "-4125604.939779",
"collateral_fees": "-122277.669972",
"collateral_liquidations": "-339878.8954",
"collateral_overall": "760412238.494849"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Collateral aggregation API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextStartingValue | string,null | true | none | The partial total for this aggregation, which can be passed as startingValue to get the next page for rolling aggregation type APIs. |
» value | [object] | true | none | The value of the response |
»» additionalProperties | string | false | none | none |
»» timestamp | number | true | none | The unix timestamp at the start of the aggregation period. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
DDX aggregation
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/aggregations/ddx',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/aggregations/ddx', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/aggregations/ddx',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/aggregations/ddx
Returns a rolling sum of DDX per time period grouped by the inflow and outflow types.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
aggregationPeriod | query | string | false | The period for the aggregation. |
startingValue | query | number | false | The partial total of this aggregation, used for rolling aggregation paging. |
fromEpoch | query | integer | false | The from epoch |
toEpoch | query | integer | false | The to epoch |
Enumerated Values
Parameter | Value |
---|---|
aggregationPeriod | week |
aggregationPeriod | day |
aggregationPeriod | hour |
aggregationPeriod | minute |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | DDX aggregation data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextStartingValue": "34000",
"value": [
{
"timestamp": 1669680000,
"ddx_deposits": "2000000",
"ddx_withdrawals": "0",
"ddx_trade-mining-rewards": "0",
"ddx_fees": "0",
"ddx_overall": "2000000"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the DDX aggregaton API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextStartingValue | string,null | true | none | The partial total for this aggregation, which can be passed as startingValue to get the next page for rolling aggregation type APIs. |
» value | [object] | true | none | The value of the response |
»» additionalProperties | string | false | none | none |
»» timestamp | number | true | none | The unix timestamp at the start of the aggregation period. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Fees aggregation
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/aggregations/fees',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/aggregations/fees', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/aggregations/fees',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/aggregations/fees
Returns fees per time period looking back from the present
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
group | query | string | false | The grouping for the aggregation. |
symbol | query | string | false | The symbol |
feeSymbol | query | string | false | The fee symbol |
aggregationPeriod | query | string | false | The period for the aggregation. |
lookbackCount | query | integer | false | The number of periods to look back from present. |
lookbackTimestamp | query | number | false | The timestamp of the when to begin the lookback from. Each lookback query will return nextLookbackTimestamp in the response, which can be passed as a query parameter here to get the next page of results. |
Detailed descriptions
lookbackTimestamp: The timestamp of the when to begin the lookback from. Each lookback query will return nextLookbackTimestamp in the response, which can be passed as a query parameter here to get the next page of results.
Enumerated Values
Parameter | Value |
---|---|
group | symbol |
group | feeSymbol |
feeSymbol | USDC |
feeSymbol | DDX |
aggregationPeriod | week |
aggregationPeriod | day |
aggregationPeriod | hour |
aggregationPeriod | minute |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Fees aggregation data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextLookbackTimestamp": 1673384400,
"value": [
{
"timestamp": 1671062400,
"fees_DDX": "5.823239",
"fees_USDC": "7.8"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Fees aggregation API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextLookbackTimestamp | number,null | true | none | Time pointer for where the next lookback should begin. Pass this value as lookbackTimestamp to get the next page of data. Will also skip over gaps in the data to return the next non-null. aggregation period. When this value is null, it indicates there is no more data to fetch. |
» value | [object] | true | none | The value of the response |
»» additionalProperties | string | false | none | none |
»» timestamp | number | true | none | The unix timestamp at the start of the aggregation period. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Insurance Fund aggregation
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/aggregations/insurance_fund',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/aggregations/insurance_fund', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/aggregations/insurance_fund',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/aggregations/insurance_fund
Returns a rolling sum of insurance fund value per time period grouped by the inflow and outflow types.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
aggregationPeriod | query | string | false | The period for the aggregation. |
startingValue | query | number | false | The partial total of this aggregation, used for rolling aggregation paging. |
fromEpoch | query | integer | false | The from epoch |
toEpoch | query | integer | false | The to epoch |
Enumerated Values
Parameter | Value |
---|---|
aggregationPeriod | week |
aggregationPeriod | day |
aggregationPeriod | hour |
aggregationPeriod | minute |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Insurance Fund aggregation data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
{
"nextStartingValue": "34000",
"value": [
{
"timestamp": 1669766400,
"insurance-fund_fees": "99.99534",
"insurance-fund_positive-liquidations": "0",
"insurance-fund_negative-liquidations": "0",
"insurance-fund_deposits": "0",
"insurance-fund_withdrawals": "0",
"insurance-fund_overall": "99.99534"
}
],
"success": true,
"timestamp": 1673031089
}
Status Code 200
Successful response for the Insurance Fund aggregation API
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» nextStartingValue | string,null | true | none | The partial total for this aggregation, which can be passed as startingValue to get the next page for rolling aggregation type APIs. |
» value | [object] | true | none | The value of the response |
»» additionalProperties | string | false | none | none |
»» timestamp | number | true | none | The unix timestamp at the start of the aggregation period. |
» success | boolean | true | none | Whether the request was successful |
» timestamp | number | true | none | The timestamp of the response |
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Top Traders
Code samples
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json'
}
result = RestClient.get '/stats/api/v1/aggregations/traders',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json'
}
r = requests.get('/stats/api/v1/aggregations/traders', headers = headers)
print(r.json())
const headers = {
'Accept':'application/json'
};
fetch('/stats/api/v1/aggregations/traders',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
GET /stats/api/v1/aggregations/traders
Returns the top N traders by volume
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
limit | query | integer | false | The number of rows to return |
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Top Traders data | Inline |
400 | Bad Request | Bad request | Inline |
500 | Internal Server Error | Unexpected error | Inline |
Response Schema
Example responses
200 Response
null
Status Code 400
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Status Code 500
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
» success | boolean | true | none | none |
» errorMsg | any | false | none | none |
anyOf
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | string | false | none | none |
or
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
»» anonymous | [object] | false | none | none |
Authenticated REST API
Users may send requests, including placing orders, canceling orders, and withdrawing funds.
Since requests modify system state, these requests must include an EIP-712 signature.
Please keep in mind, all sample requests displayed below are NOT encrypted. The reason for this is to more clearly display the formats of the various requests you may send. You MUST encrypt these messages prior to sending them to the exchange.
Place order
Request
Request format (JSON)
{
"t": "Order",
"c": {
"symbol": "ETHP",
"strategy": "main",
"side": "Bid",
"orderType": "Limit",
"nonce": "0x3136313839303336353634383833373230303000000000000000000000000000",
"amount": 10,
"price": 487.5,
"stopPrice": 0,
"signature": "0xd5a1ca6d40a030368710ab86d391e5d16164ea16d2c809894eefddd1658bb08c6898177aa492d4d45272ee41cb40f252327a23e8d1fc2af6904e8860d3f72b3b1b"
}
}
Request (Python)
from web3 import Web3
from eth_account.signers.local import (
LocalAccount,
)
import requests
import simplejson as json
from ddx_python.decimal import Decimal
from decimal import Decimal as PyDecimal
class OutputEncoder(json.JSONEncoder):
"""
Custom JSON-encoder for serializing objects
"""
def __init__(self, **kwargs):
super(OutputEncoder, self).__init__(**kwargs)
def default(self, o):
if type(o) == Decimal:
return PyDecimal(str(o))
return json.JSONEncoder.default(self, o)
def place_order(
web3_account: LocalAccount,
symbol: str,
strategy: str,
side: str,
order_type: str,
nonce: str,
amount: Decimal,
price: Decimal,
stop_price: Decimal,
verifying_contract_address: str,
chain_id: int,
):
# Refer to #derivadex-requests-signatures-and-hashing for
# these helper implementations.
eip712_domain_struct_hash = compute_eip712_domain_struct_hash(
chain_id, verifying_contract_address
)
eip712_message_struct_hash = compute_eip712_message_struct_hash(
symbol, strategy, side, order_type, nonce, amount, price, stop_price
)
eip712_hash = compute_eip712_hash(
eip191_header, eip712_domain_struct_hash, eip712_message_struct_hash
)
contents = {
"t": "Order",
"c": {
"symbol": symbol,
"strategy": strategy,
"side": side,
"orderType": order_type,
"nonce": nonce,
"amount": amount,
"price": price,
"stopPrice": stop_price,
"signature": web3_account.signHash(
bytes.fromhex(eip712_hash)
).signature.hex(),
},
}
# Encrypt request contents, please refer to
# #derivadex-requests-encryption.
encryption_key = requests.get(
f"https://testnet.derivadex.io/v2/encryption-key"
).json()
encrypted_contents = encrypt_with_nonce(
encryption_key, OutputEncoder().encode(contents)
)
# Submit request.
requests.post(f"https://testnet.derivadex.io/v2/request", data=encrypted_contents)
rpc_url = '<your_rpc_url>'
private_key = '<your_private_key>'
verifying_contract_address = '0xd9239543d15fb9479f2cc9951b45432ba4221bfa'
chain_id = 11155111
w3 = Web3(Web3.HTTPProvider(rpc_url, request_kwargs={"timeout": 60}))
web3_account = w3.eth.account.from_key(private_key)
place_order(
web3_account,
'ETHP',
'main',
'Bid',
'Limit',
'0x3136343630373732323434323935363430303000000000000000000000000000',
Decimal('12.3'),
Decimal('2031.4'),
Decimal('0'),
verifying_contract_address,
chain_id
)
You can place new orders by specifying specific attributes in the Order
request payload. These requests are subject to a set of validations.
type | field | description |
---|---|---|
string | t | Request type, which in this case will be Order |
dict | c | Request contents containing the order being placed |
string | c.symbol | Name of the market to trade. Currently, this is limited to ETHP or BTCP , but new symbols are coming soon! |
string | c.strategy | Name of the cross-margined strategy this trade belongs to. Currently, this is limited to the default main strategy, but support for multiple strategies is coming soon! |
string | c.side | Side of trade, either Bid (buy/long) or an Ask (sell/short) |
string | c.orderType | Order type, either Limit or Market . Other order types coming soon! |
bytes32_s | c.nonce | An incrementing numeric identifier for this request that is unique per user for all time |
decimal | c.amount | The order amount/size requested |
decimal | c.price | The order price (If orderType is Market , this must be set to 0 ) |
decimal | c.stopPrice | Currently, always set to 0 as stops are not implemented. |
bytes_s | c.signature | EIP-712 signature of the order placement intent |
To be more explicit, all of these fields must be passed in, even if not all of the fields apply due to certain functionalities not currently implemented (i.e. stops) or the fact that prices aren't applicable in the case of market orders. Please follow the guidelines specified in the table above around these conditions.
Response
Receipt (success) format (JSON)
{
"t": "Sequenced",
"c": {
"nonce": "0x3136323631383732373739373732303230303000000000000000000000000000",
"requestHash": "0xdfcdd015a63119477e456e48ab16a6324cb4820b99c47d8a0520f1d43834d7ef",
"requestIndex": 54913,
"sender": "0xe36ea790bc9d7ab70c55260c66d52b1eca985f84",
"enclaveSignature": "0x69865fca4901d21c84e1fd9b12b0e6ba4d7f7a885594fa8a1aa4dfdaf0dc7b6f433069b38c7822d215e55b3d46118ed012c874bf524fe73cb6aafe9adb42d3e81c"
}
}
A place order request returns a response receipt, which confirms that an Operator has received the request and has sequenced it for processing. The receipt type
will be either Sequenced
or Error
.
A successful request returns a Sequenced
receipt from the Operator. DerivaDEX Operators execute code within a trusted execution environment. The enclaveSignature affirms that this environment has the security guarantees associated with Intel SGX TEEs.
type | field | description |
---|---|---|
string | t | Message type, which in this case will be Sequenced |
dict | c | Message contents |
bytes32_s | c.nonce | The same nonce that was passed in the initial request, which can be used to correlate your initial requests with receipts |
bytes32_s | c.requestHash | Hash of the request |
int | c.requestIndex | A ticket number which guarantees fair sequencing. All tickets are processed and handled by the exchange in order of this requestIndex . |
address_s | c.sender | The request sender's Ethereum address |
bytes_s | c.enclaveSignature | An Operator's signature which proves secure handling of the request |
Receipt (error) format (JSON)
{
"t": "Error",
"c": {
"message": "Error: timeout of 2000ms exceeded"
}
}
An erroneous request returns an Error
receipt from the Operator.
type | field | description |
---|---|---|
string | msg | Error message |
Cancel order
Request
Request format (JSON)
{
"t": "CancelOrder",
"c": {
"symbol": "ETHP",
"orderHash": "0xedee9c27b4fc64a481bd45c145eaf35806d6ad49ca0c68890a00000000000000",
"nonce": "0x3136323635353034303835323735383330303000000000000000000000000000",
"signature": "0xee6c271fc010e25fb28556b39f8999d832485b03335c9c4a5ceca84455ce6bb205483995f5240e62adeb50bda12ed8db67a990c0930e5512709b3bcff4a98ca01b"
}
}
Request (Python)
from web3 import Web3
from eth_account.signers.local import (
LocalAccount,
)
from eth_abi.utils.padding import zpad32_right
import requests
import simplejson as json
from ddx_python.decimal import Decimal
from decimal import Decimal as PyDecimal
class OutputEncoder(json.JSONEncoder):
"""
Custom JSON-encoder for serializing objects
"""
def __init__(self, **kwargs):
super(OutputEncoder, self).__init__(**kwargs)
def default(self, o):
if type(o) == Decimal:
return PyDecimal(str(o))
return json.JSONEncoder.default(self, o)
def cancel_order(
web3_account: LocalAccount,
symbol: str,
order_hash: str,
nonce: str,
verifying_contract_address: str,
chain_id: int,
):
# Refer to #derivadex-requests-signatures-and-hashing for
# these helper implementations.
eip712_domain_struct_hash = compute_eip712_domain_struct_hash(
chain_id, verifying_contract_address
)
eip712_message_struct_hash = compute_eip712_message_struct_hash(
symbol,
order_hash,
nonce,
)
eip712_hash = compute_eip712_hash(
eip191_header, eip712_domain_struct_hash, eip712_message_struct_hash
)
contents = {
"t": "CancelOrder",
"c": {
"symbol": symbol,
"orderHash": f"0x{zpad32_right(bytes.fromhex(order_hash[2:])).hex()}",
"nonce": nonce,
"signature": web3_account.signHash(
bytes.fromhex(eip712_hash)
).signature.hex(),
},
}
# Encrypt request contents, please refer to
# #derivadex-requests-encryption.
encryption_key = requests.get(
f"https://testnet.derivadex.io/v2/encryption-key"
).json()
encrypted_contents = encrypt_with_nonce(
encryption_key, OutputEncoder().encode(contents)
)
# Submit request.
requests.post(f"https://testnet.derivadex.io/v2/request", data=encrypted_contents)
rpc_url = '<your_rpc_url>'
private_key = '<your_private_key>'
verifying_contract_address = '0xd9239543d15fb9479f2cc9951b45432ba4221bfa'
chain_id = 11155111
w3 = Web3(Web3.HTTPProvider(rpc_url, request_kwargs={"timeout": 60}))
web3_account = w3.eth.account.from_key(private_key)
cancel_order(
web3_account,
'ETHP',
'0xdc15c175ed2cf4613362f81d9c2fd50c3444af2b33af2c5bd6',
'0x3136393832323333303030393036383930303000000000000000000000000000',
verifying_contract_address,
chain_id
)
You can cancel existing orders by specifying specific attributes in the CancelOrder
request's payload.
type | field | description |
---|---|---|
string | t | Request type, which in this case will be CancelOrder |
dict | c | Request contents containing the order being canceled |
string | c.symbol | Currently always ETHP or BTCP . New symbols coming soon! |
bytes32_s | c.orderHash | The first 25 bytes of the order's unique hash that is being canceled. |
bytes32_s | c.nonce | An incrementing numeric identifier for this request that is unique per user for all time |
bytes_s | c.signature | EIP-712 signature of the order cancellation request |
As described in the Signatures & hashing
section, the orderHash
is something that you construct client-side prior to submitting the order to the exchange. In this regard, you have the orderHash
for each order you submit irrespective of acknowledgement from the exchange. However, you likely will fire order cancellations after you have already had acknowledgement of placement receipt from the exchange. You can obtain the order hashes of your open orders using appropriately defined REST requests or WebSocket subscriptions.
Response
Receipt (success) format (JSON)
{
"t": "Sequenced",
"c": {
"nonce": "0x3136323635353034303835323735383330303000000000000000000000000000",
"requestHash": "0xdab45fe8ddac0cf1231f79bf4fcbfa847606f45341b446d143b0b0688aa7eed0",
"requestIndex": 108095,
"sender": "0xe36ea790bc9d7ab70c55260c66d52b1eca985f84",
"enclaveSignature": "0x040d24750b994b3603cabb4097093bc310fbfcbe88246501fac4f1d9a441798b20a09eedfdbe52a576cba17ed3986984ba0bfe4a8a3141a525759e7c39f49a441b"
}
}
A cancel order request returns a response receipt, which confirms that an Operator has received the request and has sequenced it for processing. The receipt type
will be either Sequenced
or Error
.
A successful request returns a Received
receipt from the Operator. DerivaDEX Operators execute code within a trusted execution environment. The enclaveSignature affirms that this environment has the security guarantees associated with Intel SGX TEEs.
type | field | description |
---|---|---|
string | t | Message type, which in this case will be Sequenced |
dict | c | Message contents |
bytes32_s | c.nonce | The same nonce that was passed in the initial request, which can be used to correlate your initial requests with receipts |
bytes32_s | c.requestHash | Hash of the request |
int | c.requestIndex | A ticket number which guarantees fair sequencing. All tickets are processed and handled by the exchange in order of this requestIndex . |
address_s | c.sender | The request sender's Ethereum address |
bytes_s | c.enclaveSignature | An Operator's signature which proves secure handling of the request |
Receipt (error) format (JSON)
{
"t": "Error",
"c": {
"message": "Error: timeout of 2000ms exceeded"
}
}
An erroneous request returns an Error
receipt from the Operator.
type | field | description |
---|---|---|
string | msg | Error message |
Cancel all
Request
Request format (JSON)
{
"t": "CancelAll",
"c": {
"symbol": "ETHP",
"strategyId": "main",
"nonce": "0x3136323635353034303835323735383330303000000000000000000000000000",
"signature": "0xee6c271fc010e25fb28556b39f8999d832485b03335c9c4a5ceca84455ce6bb205483995f5240e62adeb50bda12ed8db67a990c0930e5512709b3bcff4a98ca01b"
}
}
Request (Python)
from web3 import Web3
from eth_account.signers.local import (
LocalAccount,
)
from eth_abi.utils.padding import zpad32_right
import requests
import simplejson as json
from ddx_python.decimal import Decimal
from decimal import Decimal as PyDecimal
class OutputEncoder(json.JSONEncoder):
"""
Custom JSON-encoder for serializing objects
"""
def __init__(self, **kwargs):
super(OutputEncoder, self).__init__(**kwargs)
def default(self, o):
if type(o) == Decimal:
return PyDecimal(str(o))
return json.JSONEncoder.default(self, o)
def cancel_all(
web3_account: LocalAccount,
strategy: str,
symbol: str,
nonce: str,
verifying_contract_address: str,
chain_id: int,
):
# Refer to #derivadex-requests-signatures-and-hashing for
# these helper implementations.
eip712_domain_struct_hash = compute_eip712_domain_struct_hash(
chain_id,
verifying_contract_address
)
eip712_message_struct_hash = compute_eip712_message_struct_hash(
strategy,
nonce,
)
eip712_hash = compute_eip712_hash(
eip191_header,
eip712_domain_struct_hash,
eip712_message_struct_hash
)
contents = {
"t": "CancelAll",
"c": {
"symbol": symbol,
"strategyId": strategy,
"nonce": nonce,
"signature": web3_account.signHash(
bytes.fromhex(eip712_hash)
).signature.hex(),
},
}
# Encrypt request contents, please refer to
# #derivadex-requests-encryption.
encryption_key = requests.get(
f"https://testnet.derivadex.io/v2/encryption-key"
).json()
encrypted_contents = encrypt_with_nonce(
encryption_key, OutputEncoder().encode(contents)
)
# Submit request.
requests.post(
f"https://testnet.derivadex.io/v2/request",
data=encrypted_contents
)
rpc_url = '<your_rpc_url>'
private_key = '<your_private_key>'
verifying_contract_address = '0xd9239543d15fb9479f2cc9951b45432ba4221bfa'
chain_id = 11155111
w3 = Web3(Web3.HTTPProvider(rpc_url, request_kwargs={"timeout": 60}))
web3_account = w3.eth.account.from_key(private_key)
cancel_all(
web3_account,
'main',
'ETHP'
'0x3136393832323431363235313430323730303000000000000000000000000000',
verifying_contract_address,
chain_id
)
You can cancel all existing orders by specifying specific attributes in the CancelAll
request's payload.
type | field | description |
---|---|---|
string | t | Request type, which in this case will be CancelOrder |
dict | c | Request contents containing the order being canceled |
string | c.symbol | Name of the market to trade. Currently, this is limited to ETHP or BTCP , but new symbols are coming soon! |
string | c.strategyId | Name of the cross-margined strategy this trade belongs to. Currently, this is limited to the default main strategy, but support for multiple strategies is coming soon! |
bytes32_s | c.nonce | An incrementing numeric identifier for this request that is unique per user for all time |
bytes_s | c.signature | EIP-712 signature of the order cancellation request |
Response
Receipt (success) format (JSON)
{
"t": "Sequenced",
"c": {
"nonce": "0x3136323635353034303835323735383330303000000000000000000000000000",
"requestHash": "0xdab45fe8ddac0cf1231f79bf4fcbfa847606f45341b446d143b0b0688aa7eed0",
"requestIndex": 108095,
"sender": "0xe36ea790bc9d7ab70c55260c66d52b1eca985f84",
"enclaveSignature": "0x040d24750b994b3603cabb4097093bc310fbfcbe88246501fac4f1d9a441798b20a09eedfdbe52a576cba17ed3986984ba0bfe4a8a3141a525759e7c39f49a441b"
}
}
A cancel all request
returns a response receipt, which confirms that an Operator has received the request and has sequenced it for processing. The receipt type
will be either Sequenced
or Error
.
A successful request
returns a Received
receipt from the Operator. DerivaDEX Operators execute code within a trusted execution environment. The enclaveSignature affirms that this environment has the security guarantees associated with Intel SGX TEEs.
type | field | description |
---|---|---|
string | t | Message type, which in this case will be Sequenced |
dict | c | Message contents |
bytes32_s | c.nonce | The same nonce that was passed in the initial request, which can be used to correlate your initial requests with receipts |
bytes32_s | c.requestHash | Hash of the request |
int | c.requestIndex | A ticket number which guarantees fair sequencing. All tickets are processed and handled by the exchange in order of this requestIndex . |
address_s | c.sender | The request sender's Ethereum address |
bytes_s | c.enclaveSignature | An Operator's signature which proves secure handling of the request |
Receipt (error) format (JSON)
{
"t": "Error",
"c": {
"message": "Error: timeout of 2000ms exceeded"
}
}
An erroneous request returns an Error
receipt from the Operator.
type | field | description |
---|---|---|
string | msg | Error message |
Withdraw
Request
Request format (JSON)
{
"t": "Withdraw",
"c": {
"strategyId": "main",
"currency": "0x41082c820342539de44c1b404fead3b4b39e15d6",
"amount": 440.32,
"nonce": "0x3136313839303336353634383833373230303000000000000000000000000000",
"signature": "0xd5a1ca6d40a030368710ab86d391e5d16164ea16d2c809894eefddd1658bb08c6898177aa492d4d45272ee41cb40f252327a23e8d1fc2af6904e8860d3f72b3b1b"
}
}
Request (Python)
from web3 import Web3
from eth_account.signers.local import (
LocalAccount,
)
from eth_abi.utils.padding import zpad32_right
import requests
import simplejson as json
from ddx_python.decimal import Decimal
from decimal import Decimal as PyDecimal
class OutputEncoder(json.JSONEncoder):
"""
Custom JSON-encoder for serializing objects
"""
def __init__(self, **kwargs):
super(OutputEncoder, self).__init__(**kwargs)
def default(self, o):
if type(o) == Decimal:
return PyDecimal(str(o))
return json.JSONEncoder.default(self, o)
def withdraw(
web3_account: LocalAccount,
strategy: str,
currency: str,
amount: Decimal,
nonce: str,
verifying_contract_address: str,
chain_id: int,
):
# Refer to #derivadex-requests-signatures-and-hashing for
# these helper implementations.
eip712_domain_struct_hash = compute_eip712_domain_struct_hash(
chain_id,
verifying_contract_address
)
eip712_message_struct_hash = compute_eip712_message_struct_hash(
strategy,
nonce,
)
eip712_hash = compute_eip712_hash(
eip191_header,
eip712_domain_struct_hash,
eip712_message_struct_hash
)
contents = {
"t": "Withdraw",
"c": {
"strategyId": strategy,
"currency": currency,
"amount": amount,
"nonce": nonce,
"signature": web3_account.signHash(
bytes.fromhex(eip712_hash)
).signature.hex(),
},
}
# Encrypt request contents, please refer to
# #derivadex-requests-encryption.
encryption_key = requests.get(
f"https://testnet.derivadex.io/v2/encryption-key"
).json()
encrypted_contents = encrypt_with_nonce(
encryption_key, OutputEncoder().encode(contents)
)
# Submit request.
requests.post(
f"https://testnet.derivadex.io/v2/request",
data=encrypted_contents
)
rpc_url = '<your_rpc_url>'
private_key = '<your_private_key>'
verifying_contract_address = '0xd9239543d15fb9479f2cc9951b45432ba4221bfa'
chain_id = 5
w3 = Web3(Web3.HTTPProvider(rpc_url, request_kwargs={"timeout": 60}))
web3_account = w3.eth.account.from_key(private_key)
withdraw(
web3_account,
'0xe36ea790bc9d7ab70c55260c66d52b1eca985f84',
'main',
'0x0998ba4bd2ffbfaa894d8b616ae412813a79bcf9',
Decimal('4.2'),
'0x3136323737363235343138383430383030303000000000000000000000000000',
verifying_contract_address,
chain_id
)
You can signal withdrawal intents to the Operators by specifying specific attributes in the Withdraw
request's payload. Withdrawal is a 2-step process: submitting a withdrawal intent, and performing a smart contract withdrawal. Once a withdrawal intent is initiated, you won"t be able to trade with the collateral you are attempting to withdraw. You will only be able to formally initiate a smart contract withdrawal/token transfer once the epoch in which you signal your withdrawal desire has concluded.
type | field | description |
---|---|---|
string | t | Request type, which in this case will be Withdraw |
dict | c | Request contents containing the withdrawal data |
string | c.strategyId | Name of the cross-margined strategy this withdrawal belongs to. Currently, this is limited to the default main strategy, but support for multiple strategies is coming soon! |
address_s | c.currency | ERC-20 token address being withdrawn |
decimal | c.amount | Amount withdrawn (be sure to use the grains format specific to the collateral token being used (e.g. if you wanted to withdraw 1 USDC, you would enter 1000000 since the USDC token contract has 6 decimal places) |
bytes32_s | c.nonce | An incrementing numeric identifier for this request that is unique per user for all time |
bytes_s | c.signature | EIP-712 signature for the withdrawal request |
Response
Receipt (success) format (JSON)
{
"t": "Sequenced",
"c": {
"nonce": "0x3136323631383732373739373732303230303000000000000000000000000000",
"requestHash": "0xdfcdd015a63119477e456e48ab16a6324cb4820b99c47d8a0520f1d43834d7ef",
"requestIndex": 54913,
"sender": "0xe36ea790bc9d7ab70c55260c66d52b1eca985f84",
"enclaveSignature": "0x69865fca4901d21c84e1fd9b12b0e6ba4d7f7a885594fa8a1aa4dfdaf0dc7b6f433069b38c7822d215e55b3d46118ed012c874bf524fe73cb6aafe9adb42d3e81c"
}
}
A withdraw request
returns a response receipt, which confirms that an Operator has received the request and has sequenced it for processing. The receipt type
will be either Received
or Error
.
A successful request
returns a Received
receipt from the Operator. DerivaDEX Operators execute code within a trusted execution environment. The enclaveSignature affirms that this environment has the security guarantees associated with Intel SGX TEEs.
type | field | description |
---|---|---|
string | t | Message type, which in this case will be Sequenced |
dict | c | Message contents |
bytes32_s | c.nonce | The same nonce that was passed in the initial request, which can be used to correlate your initial requests with receipts |
bytes32_s | c.requestHash | Hash of the request |
int | c.requestIndex | A ticket number which guarantees fair sequencing. All tickets are processed and handled by the exchange in order of this requestIndex . |
address_s | c.sender | The request sender's Ethereum address |
bytes_s | c.enclaveSignature | An Operator's signature which proves secure handling of the request |
Receipt (error) format (JSON)
{
"t": "Error",
"c": {
"message": "Error: timeout of 2000ms exceeded"
}
}
An erroneous request returns an Error
receipt from the Operator.
type | field | description |
---|---|---|
string | msg | Error message |
Signatures and hashing
All [requests
] on the API must be signed. The payload you will sign using an Ethereum wallet client of your choice (e.g. ethers, web3.js, web3.py, etc.) will need to be hashed as per the EIP-712 standard. We highly recommend referring to the original proposal for full context, but in short, this standard introduced a framework by which users can securely sign typed structured data. This greatly improves the crypto UX as users can now sign data they see and understand as opposed to unreadable byte-strings. While these benefits may not be readily apparent for programmatic traders, you will need to conform to this standard regardless.
EIP-712 hashing consists of three critical components - a header
, domain
struct hash, and message
struct hash.
Header
Sample EIP-191 header definition
bytes2 eip191_header = 0x1901;
eip191_header = b"\x19\x01"
The header
is simply the byte-string \x19\x01
. You are welcome to do this however you like, but it must adhere to the standard eventually, otherwise the signature will not ultimately successfully recover. Example Solidity and Python reference implementations are displayed on the right, but feel free to utilize whichever language, tooling, and abstractions you see fit.
Domain
Domain separator for sepolia. DO NOT modify these parameters.
{
"name": "DerivaDEX",
"version": "1",
"chainId": 11155111,
"verifyingContract": "0xd9239543d15fb9479f2cc9951b45432ba4221bfa"
}
Sample computation of domain struct hash
function compute_eip712_domain_struct_hash(
string memory _name,
string memory _version,
uint256 _chainId,
address _verifyingContract
) public view returns (bytes32) {
// keccak-256 hash of the encoded schema for the domain separator
bytes32 domainSchemaHash =
keccak256(
abi.encodePacked(
'EIP712Domain(',
'string name,',
'string version,',
'uint256 chainId,',
'address verifyingContract',
')'
)
);
bytes32 domainStructHash =
keccak256(
abi.encodePacked(
domainSchemaHash,
keccak256(bytes(_name)),
keccak256(bytes(_version)),
_chainId,
uint256(_verifyingContract)
)
);
return domainStructHash;
}
from eth_abi import encode
from eth_utils.crypto import keccak
def compute_eip712_domain_struct_hash(chain_id: int, verifying_contract: str) -> bytes:
return keccak(
keccak(
b"EIP712Domain("
+ b"string name,"
+ b"string version,"
+ b"uint256 chainId,"
+ b"address verifyingContract"
+ b")"
)
+ keccak(b"DerivaDEX")
+ keccak(b"1")
+ encode(["uint256"], [chain_id])
+ encode(["address"], [verifying_contract])
)
The domain
is a mandatory field that allows for signature/hashing schemes on one dApp to be unique to itself from other dApps. All requests use the same domain
specification. The parameters that comprise the domain are as follows:
type | field | description |
---|---|---|
string | name | Name of the dApp or protocol |
string | version | Current version of the signing domain |
uint256 | chainId | EIP-155 chain ID |
address | verifyingContract | DerivaDEX smart contract's Ethereum address |
To generate the domain
struct hash, you must perform a series of encodings and hashings of the schema and contents of the domain
specfication. You are welcome to do this however you like, but it must adhere to the standard eventually, otherwise the signature will not ultimately successfully recover. Example Solidity and Python reference implementations are displayed on the right, but feel free to utilize whichever language, tooling, and abstractions you see fit.
Message
The message
field varies depending on the typed data you are signing, and is illustrated on a case-by-case basis below.
Place order
Sample computation of place order message struct hash
function compute_eip712_message_struct_hash(
bytes32 _symbol,
bytes32 _strategy,
uint256 _side,
uint256 _orderType,
bytes32 _nonce,
uint256 _amount,
uint256 _price,
uint256 _stopPrice
) public view returns (bytes32) {
// keccak-256 hash of the encoded schema for the order params struct
bytes32 eip712SchemaHash =
keccak256(
abi.encodePacked(
'OrderParams(',
'bytes32 symbol,',
'bytes32 strategy,',
'uint256 side,',
'uint256 orderType,',
'bytes32 nonce,',
'uint256 amount,',
'uint256 price,',
'uint256 stopPrice',
')'
)
);
bytes32 messageStructHash =
keccak256(
abi.encodePacked(
eip712SchemaHash,
_symbol,
_strategy,
_side,
_orderType,
_nonce,
_amount,
_price,
_stopPrice
)
);
return messageStructHash;
}
from eth_utils.crypto import keccak
from eth_abi import encode
from eth_abi.utils.padding import zpad32_right
from ddx_python.decimal import Decimal
def compute_eip712_message_struct_hash(
symbol: str,
strategy: str,
side: str,
order_type: str,
nonce: str,
amount: Decimal,
price: Decimal,
stop_price: Decimal,
) -> bytes:
# keccak-256 hash of the encoded schema for the place order request
eip712_schema_hash = keccak(
b"OrderParams("
+ b"bytes32 symbol,"
+ b"bytes32 strategy,"
+ b"uint256 side,"
+ b"uint256 orderType,"
+ b"bytes32 nonce,"
+ b"uint256 amount,"
+ b"uint256 price,"
+ b"uint256 stopPrice"
+ b")"
)
# Ensure decimal value has no more than 6 decimals of precision
def round_to_unit(val: Decimal) -> Decimal:
return val.quantize(6)
# Scale up to DDX grains format (i.e. multiply by 1e18)
def to_base_unit_amount(val: Decimal, decimals: int) -> int:
return int(round_to_unit(val) * 10**decimals)
# Convert order side string to int representation
def order_side_to_int(order_side: str) -> int:
if order_side == "Bid":
return 0
elif order_side == "Ask":
return 1
return 2
# Convert order type string to int representation
def order_type_to_int(order_type: str) -> int:
if order_type == "Limit":
return 0
elif order_type == "Market":
return 1
return 2
return keccak(
eip712_schema_hash
+ zpad32_right(
len(symbol).to_bytes(1, byteorder="little") + symbol.encode("utf8")
)
+ zpad32_right(
len(strategy).to_bytes(1, byteorder="little") + strategy.encode("utf8")
)
+ encode(["uint256"], [order_side_to_int(side)])
+ encode(["uint256"], [order_type_to_int(order_type)])
+ encode(["bytes32"], [bytes.fromhex(nonce[2:])])
+ encode(["uint256"], [to_base_unit_amount(amount, 6)])
+ encode(["uint256"], [to_base_unit_amount(price, 6)])
+ encode(["uint256"], [to_base_unit_amount(stop_price, 6)])
)
The parameters that comprise the message
for the request to place an order are as follows:
type | field | description |
---|---|---|
bytes32 | symbol | 32-byte encoding of the symbol length and symbol this order is for. The symbol of the order you send to the API is a string, however for signing purposes, you must bytes-encode and pad accordingly. |
bytes32 | strategy | 32-byte encoding of the strategy length and strategy this order belongs to. The strategy of the order you send to the API is a string, however for signing purposes, you must bytes-encode and pad accordingly. The strategy refers to the cross-margined bucket this trade belongs to. Currently, there is only the default main strategy, but support for multiple strategies is coming soon! |
uint256 | side | An integer value either 0 (Bid) or 1 (Ask) |
uint256 | orderType | An integer value either 0 (Limit) or 1 (Market) |
bytes32 | nonce | 32-byte value (an incrementing numeric identifier that is unique per user for all time) resulting in uniqueness of order |
uint256 | amount | Order amount (scaled up by 6 decimals; e.g. 2.5 => 2500000). The amount of the order you send to the API is a decimal, however for signing purposes, you must scale up by 6 decimals and convert to an integer. |
uint256 | price | Order price (scaled up by 6 decimals; e.g. 2001.37 => 2001370000). The price of the order you send to the API is a decimal, however for signing purposes, you must scale up by 6 decimals and convert to an integer. |
uint256 | stopPrice | Stop price (scaled up by 6 decimals). The stopPrice of the order you send to the API is a decimal, however for signing purposes, you must scale up by 6 decimals and convert to an integer. |
Take special note of the transformations done on several fields as described in the table above. In other words, the order intent you submit to the API will have different representations for some fields than the order intent you hash. You are welcome to do this however you like, but it must adhere to the standard eventually, otherwise the signature will not ultimately successfully recover. Example Solidity and Python reference implementations are displayed on the right, but feel free to utilize whichever language, tooling, and abstractions you see fit.
Cancel order
Sample computation of cancel order message struct hash
function compute_eip712_message_struct_hash(bytes32 _symbol, bytes32 _orderHash, bytes32 _nonce) public view returns (bytes32) {
// keccak-256 hash of the encoded schema for the cancel order params struct
bytes32 eip712SchemaHash = keccak256(abi.encodePacked(
"CancelOrderParams(",
"bytes32 symbol,",
"bytes32 orderHash,",
"bytes32 nonce",
")"
));
bytes32 messageStructHash = keccak256(abi.encodePacked(
eip712SchemaHash,
_symbol,
_orderHash,
_nonce,
));
return messageStructHash;
}
from eth_abi import encode
from eth_abi.utils.padding import zpad32_right
from eth_utils.crypto import keccak
def compute_eip712_message_struct_hash(
symbol: str, order_hash: str, nonce: str
) -> bytes:
# keccak-256 hash of the encoded schema for the cancel order request
eip712_schema_hash = keccak(
b"CancelOrderParams("
+ b"bytes32 symbol,"
+ b"bytes32 orderHash,"
+ b"bytes32 nonce"
+ b")"
)
return keccak(
eip712_schema_hash
+ zpad32_right(
len(symbol).to_bytes(1, byteorder="little") + symbol.encode("utf8")
)
+ encode(["bytes32"], [bytes.fromhex(order_hash[2:])])
+ encode(["bytes32"], [bytes.fromhex(nonce[2:])])
)
The parameters that comprise the message
for the request to cancel an order are as follows:
type | field | description |
---|---|---|
bytes32 | symbol | 32-byte encoding of the symbol length and symbol this order is for. The symbol of the order you send to the API is a string, however for signing purposes, you must bytes-encode and pad accordingly. |
bytes32 | orderHash | 32-byte EIP-712 hash of the order at the time of placement |
bytes32 | nonce | 32-byte value (an incrementing numeric identifier that is unique per user for all time) resulting in uniqueness of order cancellation |
Cancel all
Sample computation of cancel all message struct hash
function compute_eip712_message_struct_hash(bytes32 _strategy, bytes32 _nonce) public view returns (bytes32) {
// keccak-256 hash of the encoded schema for the cancel all params struct
bytes32 eip712SchemaHash = keccak256(abi.encodePacked(
"CancelAllParams(",
"bytes32 symbol,",
"bytes32 strategy,",
"bytes32 nonce",
")"
));
bytes32 messageStructHash = keccak256(abi.encodePacked(
eip712SchemaHash,
_strategy,
_nonce,
));
return messageStructHash;
}
from eth_abi import encode
from eth_abi.utils.padding import zpad32_right
from eth_utils.crypto import keccak
def compute_eip712_message_struct_hash(strategy: str, nonce: str) -> bytes:
# keccak-256 hash of the encoded schema for the cancel all request
eip712_schema_hash = keccak(
b"CancelAllParams(" + b"bytes32 symbol" + b"bytes32 strategy," + b"bytes32 nonce" + b")"
)
return keccak(
eip712_schema_hash
+ zpad32_right(
len(strategy).to_bytes(1, byteorder="little") + strategy.encode("utf8")
)
+ encode(["bytes32"], [bytes.fromhex(nonce[2:])])
)
The parameters that comprise the message
for the request to cancel an order are as follows:
type | field | description |
---|---|---|
bytes32 | strategy | 32-byte encoding of the strategy length and strategy this order belongs to. The strategy of the order you send to the API is a string, however for signing purposes, you must bytes-encode and pad accordingly. The strategy refers to the cross-margined bucket this trade belongs to. Currently, there is only the default main strategy, but support for multiple strategies is coming soon! |
bytes32 | nonce | 32-byte value (an incrementing numeric identifier that is unique per user for all time) resulting in uniqueness of order cancellation |
Tying it all together
Computing the final EIP-712 hash
function compute_eip712_hash(
bytes2 _eip191_header,
bytes32 _domainStructHash,
bytes32 _messageStructHash
) public view returns (bytes32) {
return keccak256(abi.encodePacked(_eip191_header, _domainStructHash, _messageStructHash));
}
from eth_utils.crypto import keccak
def compute_eip712_hash(eip191_header: bytes, eip712_domain_struct_hash: bytes, eip712_message_struct_hash: bytes) -> str:
# Converting bytes result to a hexadecimal string
return keccak(
eip191_header
+ eip712_domain_struct_hash
+ eip712_message_struct_hash
).hex()
To derive the final EIP-712 hash of the typed data you will sign, you will need to keccak256
hash the header
, eip712_domain_struct_hash
, and eip712_message_struct_hash
(will vary depending on which request specifically you are sending). You are welcome to do this however you like, but it must adhere to the standard eventually, otherwise the signature will not ultimately successfully recover. Example Solidity and Python reference implementations are displayed on the right, but feel free to utilize whichever language, tooling, and abstractions you see fit.
Samples
Please feel free to use these ground truth samples to validate your EIP-712 hashing implementation for correctness. For the following samples, assume a chainId = 11155111
and verifyingContract = 0xd9239543d15fb9479f2cc9951b45432ba4221bfa
.
Place order
The following sample order placement data results in an EIP-712 hash of: 0x1755cce1ec303da618937c7a1654e43b80bd6106fd88563457dc20f2bd979dd1
.
field | value |
---|---|
symbol | "ETHP" |
strategy | "main" |
side | "Bid" |
orderType | "Limit" |
nonce | "0x3136393832323235373738313438313430303000000000000000000000000000" |
amount | 51.5 |
price | 1762.4 |
stopPrice | 0 |
Cancel order
The following sample cancellation data results in an EIP-712 hash of: 0xaeaccd96f66406d1dcfbdf4e94cb77ead89fb0e369eca88cc9e14c3007e4a1f7
.
field | value |
---|---|
symbol | "ETHP" |
orderHash | "0xdc15c175ed2cf4613362f81d9c2fd50c3444af2b33af2c5bd6" |
nonce | "0x3136393832323333303030393036383930303000000000000000000000000000" |
Cancel all
The following sample cancellation data results in an EIP-712 hash of: 0x9c6adbbbb7c15e33e1e1d69eae3ca5031432068fb35cdffcd6a771ac95818970
.
field | value |
---|---|
strategy | "main" |
nonce | "0x3136393832323431363235313430323730303000000000000000000000000000" |
Encryption
Sample encryption (JSON)
// Sample unencrypted order placement request
{
"t": "Order",
"c": {
"symbol": "ETHP",
"strategy": "main",
"side": "Ask",
"orderType": "Limit",
"nonce": "0x3136323737363235343138383430383030303000000000000000000000000000",
"amount": 10.6,
"price": 2472.1,
"stopPrice": 0,
"signature": "0x1b1f419961c742861a41396f14892ea4a665b7b89086637d37d53ec20364a7ef3aaf1e1472867f5a18fa3f27a2748ed16c603eccd13472cfd61d43df1c3ed22a1b"
}
}
// Sample encrypted order placement request
"0x3bb4fec9257fb81c846c075fb3944151838c32ce41dadb585049fa7788ae591bb970ea295993d42b238e95595fde09d80d675aa960112533cf61ed4b91b9d77dd3f97d6ecf1cf809800854a11b43d27c5da51d69f550463bddeb471be94fb6a17de3e54cf99665be081ec7f8c24b7eebaef691baa27de167e448ed3a0facf6af0c4fec0e856f56515590c40479cf95f6e25918a42a60b4c15b4362614f91bfbd67eba6a6aad6de9edd45ba5fa7fc33e4473fb9e94a14f492c65bfecc08ff97d7c3126d6ce697aa955234e98ebb027fb042500122c299826267deb278b44a7dfc7f06fad6174f448f4fb41ce13e1003c2013b6de2e9a0bf3d9871658c84644fc41d7e5482bd4efad8370172e64b7220d2a2e596c9a5b3ce38997bae79200b3b62839e47bc6aa876128cb6d4430e18b1f51588d7741161e1a9734d0e203d725c9f4d7dae174a0e75fcdb3882c23590437fbc3330046b150bc90818e7b1c3a42571b62363343f2e46bc7cf6fcd0dfd2550ec83d453641d7a236a3a6677e806125b0c50246d5f26c2db3f61ebc78b955d5095d8b0cd7f4929f5bc2adf53c455b2170f546a09d2e11b463db6cc582a771c6aaad96c3c56123d5010643e584849e6f7cf998495e28b018b4c00bcb64a3aa2b7b7e0cb3faea33c7034887c86a15d5c0a01db2c8bc27a4b6ec2acc2e06ccabde4a64962ab3aec63f36"
Sample encryption implementation (Python)
from coincurve import PublicKey, PrivateKey
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Hash import keccak
def encrypt_with_nonce(encryption_key: str, msg: str) -> bytes:
"""
Encrypt the JSON-stringified request contents
Parameters
----------
encryption_key: str
Encryption key
msg : str
JSON-stringified request contents
"""
network_public_key = PublicKey(bytes.fromhex(encryption_key[2:]))
my_secret_key = PrivateKey(get_random_bytes(32))
my_public_key = my_secret_key.public_key
shared_pub = network_public_key.multiply(my_secret_key.secret)
keccak_256 = keccak.new(digest_bits=256)
keccak_256.update(shared_pub.format())
derived_key = keccak_256.digest()[:16]
nonce = get_random_bytes(12)
cipher = AES.new(derived_key, AES.MODE_GCM, nonce=nonce)
encoded_message = msg.encode("utf8")
ciphertext, tag = cipher.encrypt_and_digest(
len(encoded_message).to_bytes(4, byteorder="big") + encoded_message
)
return ciphertext + tag + nonce + my_public_key.format()
DerivaDEX is a front-running resistant decentralized exchange, achieved with sending encrypted data that can only be decrypted from inside the Operator's trusted hardware. All requests must be encrypted using an AES-GCM128 scheme. The encryption steps are as follows:
-
Generate n 16-byte (128-bit) ECDH shared key using the operator's public key (
0x03bc06b4271530d20b4ddb03e0069b00b2c0d03baf45d0ab60582448b6d70c2737
, which can be obtained from this endpoint) and a 32-byte private key of your choosing (you can randomly generate this each time you are sending a request). Make sure you are using akeccak256
ECDH key generation scheme, but since you need a 16-byte shared key, make sure you take only the first 16 bytes of the 32-byte key generated. -
Generate a 12-byte random nonce
-
Setup the payload you want to encrypt, which is the bytes-encoded request's contents prefixed with a 4-byte value indicating the length of this bytes-encoded request's contents
-
Generate the ciphertext and MAC tag using AES-GCM128
-
Return the encrypted bytes in the format of [ciphertext][tag][nonce][client_public_key_compressed_format]
To validate your encryption implementation for correctness (assuming you are not using the DerivaDEX Python client library), please reference what follows and the display on the right:
- Step 1: Assuming a random client secret key of
0xa178baab5a727c5d08c4ed1118179348d8d43e68c0d5e620757f852cdbc79dfd
, you may arrive at a ECDH shared key of0x9e9f36797212e683f971a140086a3e74
- Step 2: Assume a random nonce of
0x4eaac2e15c60705ec631d9c8
- Step 3: Assuming a stringified unencrypted order placement message content of the following form
{"t": "Order", "c": {"symbol": "ETHP", "strategy": "main", "side": "Ask", "orderType": "Limit", "nonce": "0x3136323737363235343138383430383030303000000000000000000000000000", "amount": 10.6, "price": 2472.1, "stopPrice": 0, "signature": "0x1b1f419961c742861a41396f14892ea4a665b7b89086637d37d53ec20364a7ef3aaf1e1472867f5a18fa3f27a2748ed16c603eccd13472cfd61d43df1c3ed22a1b"}}
, you may arrive at a bytes-encoded payload (prefixed with the length) to encrypt of:0x000001787b2274223a20224f72646572222c202263223a207b2273796d626f6c223a202245544850455250222c20227374726174656779223a20226d61696e222c202273696465223a202241736b222c20226f7264657254797065223a20224c696d6974222c20226e6f6e6365223a2022307833313336333233373337333633323335333433313338333833343330333833303330333033303030303030303030303030303030303030303030303030303030222c2022616d6f756e74223a2031302e362c20227072696365223a20323437322e312c202273746f705072696365223a20302c20227369676e6174757265223a2022307831623166343139393631633734323836316134313339366631343839326561346136363562376238393038363633376433376435336563323033363461376566336161663165313437323836376635613138666133663237613237343865643136633630336563636431333437326366643631643433646631633365643232613162227d7d
- Step 4: The above may generate a ciphertext of
0xcf9aa16f18136a21ae1c750e0d44662e8fb04d720c2ea22bd51f87bcfa87d8826fdf85be4235e945d22693eea08be73bcd18b897293efea7114d05ffbd0079bd2d2903079f79464fb3f510cae5f4009d10dc9f3025699927c0ac384dc7187905efff2c0d7113608df8cff1f60f96611721fac05be2fe7b69d48d00505aa2feb008ea39719ceb4f5ca881713be5bcbdbbf2112eb0fa9eed7b844cb81dee15ef02c8289eacffe7eebb15d62bc1cb03aea6c838f4aa8115693abb9fb05ddf2240c4c9583fe601e3e5815c892aaa3365639fd82138c5df70383ba11eb82244d14a439bb1dc755ff8f35f3ea0cd7d7abb1b1ef7bfbe220779bad5e5889389523b81b49d74e1695812b662ca380e17a61042eb48265cff02249e36481fda42ff124fd7b8af2d0ce3f5f6aa17c8c6196e6dab6de892c191c14b300265d69c5313bb123950dc9b497127d4ef5365a193f68049dd72fc57adde308df4ae3cdb1139119877655de16e4defccb3a9df5d4fd7ecf77c64b55b27ad6dac68e2c3041a
and a tag of0x41d734fdbd8873fe16702ce5cf5a9f72
- Step 5: After deriving the public key from the secret key from Step 1 (
0x0200d58d635f4ae70e6aab4cb15bdd318c0de2c2949d9a019775345f4c79e3ce56
), you may arrive at the final encrypted message of:0xcf9aa16f18136a21ae1c750e0d44662e8fb04d720c2ea22bd51f87bcfa87d8826fdf85be4235e945d22693eea08be73bcd18b897293efea7114d05ffbd0079bd2d2903079f79464fb3f510cae5f4009d10dc9f3025699927c0ac384dc7187905efff2c0d7113608df8cff1f60f96611721fac05be2fe7b69d48d00505aa2feb008ea39719ceb4f5ca881713be5bcbdbbf2112eb0fa9eed7b844cb81dee15ef02c8289eacffe7eebb15d62bc1cb03aea6c838f4aa8115693abb9fb05ddf2240c4c9583fe601e3e5815c892aaa3365639fd82138c5df70383ba11eb82244d14a439bb1dc755ff8f35f3ea0cd7d7abb1b1ef7bfbe220779bad5e5889389523b81b49d74e1695812b662ca380e17a61042eb48265cff02249e36481fda42ff124fd7b8af2d0ce3f5f6aa17c8c6196e6dab6de892c191c14b300265d69c5313bb123950dc9b497127d4ef5365a193f68049dd72fc57adde308df4ae3cdb1139119877655de16e4defccb3a9df5d4fd7ecf77c64b55b27ad6dac68e2c3041a41d734fdbd8873fe16702ce5cf5a9f724eaac2e15c60705ec631d9c80200d58d635f4ae70e6aab4cb15bdd318c0de2c2949d9a019775345f4c79e3ce56
Realtime API
Connect to the realtime-api websocket through the /realtime-api
route.
Outgoing Messages
Once a websocket connection is established, clients can send one of the following messages as stringified JSON to the socket.
Subscribe
Example subscribe message
{
"action": "subscribe",
"feeds": [
{
"feed": "ORDER_BOOK_L2",
"params": {
"aggregation": "1",
"symbol": "ETHP"
}
}
]
}
Name | Type | Description |
---|---|---|
action | string | The type of action to take |
feeds | array | A list of feed subscription objects |
» feed | string | The name of the feed |
» params | object | The parameters for the specific feed subscription |
Unsubscribe
Example unsubscribe message
{
"action": "unsubscribe",
"feeds": ["ORDER_BOOK_L2"]
}
Name | Type | Description |
---|---|---|
action | string | The type of action to take |
feeds | array | A list of feed subscription names to unsubscribe from |
Order Book L3
Subscription Message
Example Order Book L3 subscription object
{
"feed": "ORDER_BOOK_L3",
"params": {
"symbol": "ETHP"
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» symbol | string | false | The symbols to filter by |
Feed Message
Example Order Book L3 feed message
{
"feed": "ORDER_BOOK_L3",
"params": {
"symbol": "ETHP"
},
"contents": {
"messageType": "partial",
"data": [
{
"orderHash": "0xcd9fffde000459dc5eda283aaf33cbbb1ab4ff37b030b38c76",
"symbol": "ETHP",
"side": 1,
"originalAmount": "3.6",
"amount": "3.6",
"price": "7202.5",
"traderAddress": "0x00535f09feea416b70a05d9dcb57257e2c24197249",
"strategyId": "main",
"bookOrdinal": "0"
},
{
"orderHash": "0x4cb74a8659981905b40af61ff7ec7b244ba4a15963c2675cba",
"symbol": "ETHP",
"side": 1,
"originalAmount": "2.4",
"amount": "2.4",
"price": "9341.8",
"traderAddress": "0x00611c721f4cf33ce857bf8b3c519c82a6f64356e2",
"strategyId": "main",
"bookOrdinal": "1"
},
{
"orderHash": "0xebf50a16b5c58a9cc85da3ee51c8bb8de77465e0ffa5f7b53c",
"symbol": "ETHP",
"side": 1,
"originalAmount": "2.4",
"amount": "2.4",
"price": "7997.2",
"traderAddress": "0x00ed039448c830083fb01577c8b36db412f289be82",
"strategyId": "main",
"bookOrdinal": "2"
},
{
"orderHash": "0x20645d113e0039075a1f1fbe15e61942245ff011ccaad03d1f",
"symbol": "ETHP",
"side": 0,
"originalAmount": "1.1",
"amount": "1.1",
"price": "3992.1",
"traderAddress": "0x00bd80de4f89a5c141ba3b5f8c7a76b25c164ab702",
"strategyId": "main",
"bookOrdinal": "29"
},
{
"orderHash": "0xc203e6ea2225dfc75b8b2ab62818285e77761ee52d5303be87",
"symbol": "ETHP",
"side": 0,
"originalAmount": "3.8",
"amount": "3.8",
"price": "1668.5",
"traderAddress": "0x0022af1cadca90c6b8097f19f40e0d0a442b9a75d8",
"strategyId": "main",
"bookOrdinal": "30"
}
],
"ordinal": 0
}
}
{
"feed": "ORDER_BOOK_L3",
"params": {
"symbol": "ETHP"
},
"contents": {
"messageType": "update",
"data": [
{
"orderHash": "0x7190696d03dbc9ad9a8bff3adda69155e5a54c92c04d8a78e6",
"symbol": "ETHP",
"side": 0,
"originalAmount": "3.8",
"amount": "3.8",
"price": "468.5",
"traderAddress": "0x00a0e5c79803c14d61cc1c33e497aaafed509e29c6",
"strategyId": "main",
"bookOrdinal": "43"
}
],
"ordinal": 1
}
}
Upon subscribing, the Order Book L3 Feed will first return a message reflecting the current state of the Order Book (called a partial). Subsequent messages will contain updates to that initial state. An amount of "0" is sent in an update to reflect that the order book row is no longer present.
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» aggregation | string | true | The order book aggregation |
» symbol | string | false | The symbols to filter by |
contents | object | true | The contents of the message |
» messageType | string | true | The message type. Values include: 'partial', 'update' |
» ordinal | number | true | The sequence number of this message relative to the feed subscription |
» data | array | true | The data returned by the feed |
»» orderHash | string | true | A hash of the order details. |
»» symbol | string | true | The symbol of the asset for this order. |
»» side | string | true | The side of the order. Values include: 0: Bid, 1: Ask |
»» originalAmount | string | true | The original order amount (before any fills). |
»» amount | string | true | The order amount currently left on this order. |
»» price | string | true | The order price. |
»» traderAddress | string | true | The trader address prefixed with the blockchain discriminant of the trader who owns this order. |
»» strategyId | string | true | The strategy of the trader which owns this order. |
»» bookOrdinal | string | true | The ordinal of when this order arrived on the book. |
Order Book L2
Subscription Message
Example Order Book L2 subscription object
{
"feed": "ORDER_BOOK_L2",
"params": {
"symbol": "ETHP",
"aggregation": "10"
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» aggregation | string | true | The order book aggregation |
» symbol | string | false | The symbols to filter by |
ETHP L2 aggregation choices
["0.1", "1", "10"]
BTCP L2 aggregation choices
["1", "10", "100"]
Note: Clients can subscribe to all symbols by omiting the symbol parameter in the subcription object, but the aggregation supplied must be one that both symbols support.
Feed Message
Example Order Book L2 feed message
{
"feed": "ORDER_BOOK_L2",
"params": {
"symbol": "ETHP",
"aggregation": "10"
},
"contents": {
"messageType": "partial",
"data": [
{
"symbol": "ETHP",
"side": 0,
"amount": "0.8",
"price": "4900"
},
{
"symbol": "ETHP",
"side": 0,
"amount": "33.6",
"price": "4860"
},
{
"symbol": "ETHP",
"side": 0,
"amount": "69.3",
"price": "4830"
},
{
"symbol": "ETHP",
"side": 1,
"amount": "1.3",
"price": "5330"
},
{
"symbol": "ETHP",
"side": 1,
"amount": "3.6",
"price": "5430"
},
{
"symbol": "ETHP",
"side": 1,
"amount": "1.5",
"price": "5590"
},
{
"symbol": "ETHP",
"side": 1,
"amount": "1.8",
"price": "5660"
}
],
"ordinal": 0
}
}
Upon subscribing, the Order Book L2 Feed will first return a message reflecting the current state of the Order Book (called a partial). Subsequent messages will contain updates to that initial state. An amount of "0" is sent in an update to reflect that the order book row is no longer present.
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» aggregation | string | true | The order book aggregation |
» symbol | string | false | The symbols to filter by |
contents | object | true | The contents of the message |
» messageType | string | true | The message type. Values include: 'partial', 'update' |
» ordinal | number | true | The sequence number of this message relative to the feed subscription |
» data | array | true | The data returned by the feed |
»» symbol | string | true | The symbol of the aggregated orderbook row |
»» side | number | true | The side of the order. Values include: 0: Bid, 1: Ask |
»» amount | string | true | The aggregated amount for this level in the orderbook |
»» price | string | true | The aggregated price level |
Mark Price
Subscription Message
Example Mark Price subscription object
{
"feed": "MARK_PRICE",
"params": {
"symbol": "ETHP"
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» symbol | string | false | The symbols to filter by |
Feed Message
Example Mark Price feed messages
{
"feed": "MARK_PRICE",
"params": {
"symbol": "ETHP"
},
"contents": {
"messageType": "partial",
"data": [
{
"epochId": "1",
"indexPriceHash": "0xc19d1444b6b2d936e8a03b1b52b1a127405303f458b85eae7d",
"txOrdinal": "129",
"symbol": "ETHP",
"indexPrice": "5066.585409",
"markPrice": "5066.585409",
"time": "210",
"ema": "0",
"priceOrdinal": "7",
"createdAt": "2023-01-27T23:25:02.609Z"
}
],
"ordinal": 0
}
}
{
"feed": "MARK_PRICE",
"params": {
"symbol": "ETHP"
},
"contents": {
"messageType": "update",
"data": [
{
"epochId": "1",
"indexPriceHash": "0x8cf9916f564a2e44d8f4a5017a77f290641a25766b2278d952",
"txOrdinal": "132",
"symbol": "ETHP",
"indexPrice": "5122.040416",
"markPrice": "5122.040416",
"time": "240",
"ema": "0",
"priceOrdinal": "8",
"createdAt": "2023-01-27T23:25:32.609Z"
}
],
"ordinal": 1
}
}
Upon subscribing, the Mark Price Feed will first return a message (a partial) reflecting the most recent mark prices. Subsequent messages will contain updates.
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» symbol | string | false | The symbols to filter by |
contents | object | true | The contents of the message |
» messageType | string | true | The message type. Values include: 'partial', 'update' |
» ordinal | number | true | The sequence number of this message relative to the feed subscription |
» data | array | true | The data returned by the feed |
»» epochId | string | true | The epoch in which this transaction occured. |
»» txOrdinal | string | true | The transaction ordinal, within the epoch. |
»» indexPriceHash | string | true | The hash of the index price. |
»» markPrice | string | true | The index price + ema clamped to 50bps above/below the index price at all times. |
»» symbol | string | true | The symbol of the asset. |
»» indexPrice | string | true | The exponential weighted average of prices from the price feed by source. |
»» time | string | true | The monotonic clock tick associated with this price checkpoint. |
»» ema | string | true | Exponential moving average which tracks the spread between the DerivaDEX Petual swap price and the underlying index price it is tracking. |
»» priceOrdinal | string | true | The ordinal of this price update. |
»» createdAt | string(date-time) | true | The time when this row was added to the database. |
Transaction Log
Subscription Message
Example Transaction Log subscription object
{
"feed": "TX_LOG",
"params": {
"eventKind": 4
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» eventKind | number | false | The event kind to filter by |
Feed Message
Example Transaction Log feed messages
{
"feed": "TX_LOG",
"params": {},
"contents": {
"messageType": "partial",
"data": null,
"ordinal": 0
}
}
{
"feed": "TX_LOG",
"params": {},
"contents": {
"messageType": "update",
"data": [
{
"epochId": "16",
"txOrdinal": "0",
"requestIndex": "6118",
"batchId": "6118",
"timeValue": "4530",
"timeStamp": "1677644197378",
"stateRootHash": "0xb8d4a19dbe18e57e7fa123d6294c32ecb76d8322d1a1371d30d747753f20a53f",
"eventKind": 70,
"event": {
"c": {
"bonds": [
"100000",
"100000",
"100000"
],
"epochId": 15,
"submitter": "0x0091c987bf62d25945db517bdaa840a6c661374402",
"custodians": [
"0x005409ed021d9299bf6814279a6a1411a7e866a631",
"0x006ecbe1db9ef729cbe972c83fb886247691fb6beb",
"0x00e36ea790bc9d7ab70c55260c66d52b1eca985f84"
]
},
"t": "FeeDistribution"
}
}
],
"ordinal": 1
}
}
{
"feed": "TX_LOG",
"params": {},
"contents": {
"messageType": "update",
"data": [
{
"epochId": "16",
"txOrdinal": "1",
"requestIndex": "6120",
"batchId": "6120",
"timeValue": "4531",
"timeStamp": "1677644198314",
"stateRootHash": "0xb8d4a19dbe18e57e7fa123d6294c32ecb76d8322d1a1371d30d747753f20a53f",
"eventKind": 9,
"event": {
"c": {
"BTCP": {
"ema": "0",
"ordinal": 89,
"timeValue": 4527,
"indexPrice": "23438.023023",
"indexPriceHash": "0xbf2d01d6c9be0a9d4f71e604490a2f9be24fa4482c041ce552"
}
},
"t": "PriceCheckpoint"
}
}
],
"ordinal": 2
}
}
Upon subscribing, the Transaction Log Feed will first return an empty partial. Subsequent messages will contain transaction log updates.
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» eventKind | number | false | The type of transaction log event |
contents | object | true | The contents of the message |
» messageType | string | true | The message type. Values include: 'partial', 'update' |
» ordinal | number | true | The sequence number of this message relative to the feed subscription |
» data | array | true | The data returned by the feed |
»» epochId | string | true | The epoch in which this transaction occured. |
»» txOrdinal | string | true | The transaction ordinal, within the epoch. |
»» requestIndex | string | true | The index of the sequenced request from which this transaction originated. |
»» batchId | string | true | Numerical identifier for a batch of transactions. |
»» timeValue | string | true | The monotonic clock tick associated with this transaction log. |
»» timeStamp | string | true | The unix timestamp associated with this transaction log. |
»» stateRootHash | string | true | A hash representing the full state of the exchange, before processing this transaction log. |
»» eventKind | number | true | The type of transaction log event. Values include: 0: Partial fill, 1: Complete fill, 2: Post, 3: Cancel, 4: Liquidation, 5: Strategy update, 6: Trader update, 7: Withdraw, 8: Withdraw DDX, 9: Price Checkpoint, 10: PnL Realization, 11: Funding, 12: Trade mining, 13: Specs update, 14: Insurance fund update, 15: Insurance fund withdraw, 16: Disaster recovery, 30: Cancel all, 60: Signer registered, 70: Fee distribution, 100: Epoch marker, 998: Drain prices, 999: No transition |
»» event | any | true | The transaction event in JSON format. |
Order Intent
Subscription Message
Example Order Intent subscription object
{
"feed": "ORDER_INTENT",
"params": {
"symbol": "ETHP",
"traderAddress": "0x00a0e5c79803c14d61cc1c33e497aaafed509e29c6",
"strategyId": "main"
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» symbol | string | false | The symbol to filter by |
» traderAddress | string | false | The trader address prefixed with the blockchain discriminant of the trader who owns this order. |
» strategyId | string | false | The strategy of the trader which owns this order. |
Feed Message
Example Order Intent feed messages
{
"feed": "ORDER_INTENT",
"params": {},
"contents": {
"messageType": "partial",
"data": null,
"ordinal": 0
}
}
{
"feed": "ORDER_INTENT",
"params": {},
"contents": {
"messageType": "update",
"data": [
{
"epochId": "26",
"orderHash": "0x92aaeac66831b00d0db66517debb3eac7370105d854420ed82",
"txOrdinal": "0",
"symbol": "ETHP",
"side": 1,
"amount": "0.1",
"price": "0",
"traderAddress": "0x0091c987bf62d25945db517bdaa840a6c661374402",
"strategyId": "main",
"orderType": 1,
"stopPrice": "0",
"nonce": "0x000000000000000000000000000000000000000000000000000001869b904348",
"signature": "0xdc2380203f7e290c274ebb65e03b6377959c193a5364a6d77b6d6b981e9b5a027331deafd1e75db542dff2972c11300f9ab71693fe607ff838d5d404e9942f7b1c",
"createdAt": "2023-03-01T05:06:14.313Z"
}
],
"ordinal": 1
}
}
{
"feed": "ORDER_INTENT",
"params": {},
"contents": {
"messageType": "rejected",
"data": [
{
"epochId": "1147",
"orderHash": "0xd66e54ebb4651900cc94979c5166d040fd1ebda8f49fd1e17a",
"requestIndex": "465606",
"symbol": "ETHP",
"amount": 0.9,
"traderAddress": "0x00e36ea790bc9d7ab70c55260c66d52b1eca985f84",
"strategyId": "main",
"reason": 0
}
],
"ordinal": 3
}
}
Upon subscribing, the Order Intent Feed will first return an empty partial. Subsequent messages will contain order intent updates. The order intent feed will also contain messages for rejected orders.
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» symbol | string | false | The symbols to filter by |
» traderAddress | string | false | The trader address which placed the order |
» strategyId | string | false | The strategyId which placed the order |
contents | object | true | The contents of the message |
» messageType | string | true | The message type. Values include: 'partial', 'update' |
» ordinal | number | true | The sequence number of this message relative to the feed subscription |
» data | array | true | The data returned by the feed |
»» epochId | string | true | The epoch in which this transaction occured. |
»» txOrdinal | string | true | The transaction ordinal, within the epoch. |
»» orderHash | string | true | A hash of this order contents. |
»» symbol | string | true | The symbol of the asset for this order. |
»» side | number | true | The side of the order. Values include: 0: Bid, 1: Ask |
»» amount | string | true | The amount of the order. |
»» price | string | true | The price of the order. |
»» traderAddress | string | true | The trader address prefixed with the blockchain discriminant of the trader who issues this order. |
»» strategyId | string | true | The strategy of the trader which owns this order. |
»» orderType | number | true | The type of order. Values include: 0: Limit, 1: Market 2: Stop |
»» stopPrice | string | true | The stop price for this order. Not currently an active field. |
»» nonce | string | true | The nonce sent by the trader when placing this order. |
»» reason | string | false | The reason this order was rejected. Values include: 0: SelfMatch, 1: Solvency, 2: MarketOrderNotFullyFilled. |
»» requestIndex | string | false | The index of the sequenced request from which this transaction originated, only included for rejected orders. |
»» signature | string | true | A signature which was used to verify the authenticity of the order, when it was sent by the trader. Encrypted using the public key exposed by the leader Operator. |
»» createdAt | string(date-time) | true | The time when this row was added to the database. |
Order Update
Subscription Message
Example Order Update subscription object
{
"feed": "ORDER_UPDATE",
"params": {
"symbol": "ETHP",
"trader": "0x00a0e5c79803c14d61cc1c33e497aaafed509e29c6",
"strategyIdHash": "0x2576ebd1"
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» symbol | string | false | The symbol to filter by |
» trader | string | false | The trader address prefixed with the blockchain discriminant on either the maker or taker side of the fill. |
» strategyIdHash | string | false | The hashed strategy of the trader on either the maker or taker side of the fill. |
Feed Message
Example Order Update feed messages
{
"feed": "ORDER_UPDATE",
"params": {},
"contents": {
"messageType": "partial",
"data": null,
"ordinal": 0
}
}
{
"feed": "ORDER_UPDATE",
"params": {},
"contents": {
"messageType": "update",
"data": [
{
"epochId": "27",
"txOrdinal": "8",
"ordinal": "0",
"makerOrderHash": "0xaf0ca8835e26a598d357aabc160497b1aa74b8f9796eb336c1",
"makerOrderTrader": "0x00accf7803c88b05846c46946d7b46418a9adad578",
"makerOrderStrategyIdHash": "0x2576ebd1",
"amount": "0.1",
"symbol": "ETHP",
"price": "1626.1",
"makerFeeUSDC": "0",
"makerFeeDDX": "0",
"makerRealizedPnl": "0",
"takerOrderHash": "0x5b3789e16930b7429dc1bde229306cdc1c1a709c83d1e16d5d",
"takerOrderTrader": "0x0091c987bf62d25945db517bdaa840a6c661374402",
"takerOrderStrategyIdHash": "0x2576ebd1",
"takerFeeUSDC": "1.7874",
"takerFeeDDX": "1.7874",
"takerRealizedPnl": "0",
"reason": 0,
"createdAt": "2023-03-01T05:14:56.313Z",
"liquidatedTrader": null,
"liquidatedStrategyIdHash": null
}
],
"ordinal": 1
}
}
Upon subscribing, the Order Update Feed will first return an empty partial. Subsequent messages will contain new order updates.
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» symbol | string | false | The symbol to filter by |
» trader | string | false | The trader address prefixed with the blockchain discriminant on either the maker or taker side of the fill. |
» strategyId | string | false | The hashed strategy of the trader on either the maker or taker side of the fill. |
contents | object | true | The contents of the message |
» messageType | string | true | The message type. Values include: 'partial', 'update' |
» ordinal | number | true | The sequence number of this message relative to the feed subscription |
» data | array | true | The data returned by the feed |
»» epochId | string | true | The epoch in which this transaction occured. |
»» txOrdinal | string | true | The transaction ordinal, within the epoch. |
»» ordinal | string | true | The ordinal within this particular transaction. |
»» makerOrderHash | string | true | The order hash for the maker side of this order update. |
»» makerOrderTrader | string | true | The trader address prefixed with the blockchain discriminant of the trader which owns the maker order. |
»» makerOrderStrategyIdHash | string | true | The hashed strategy id of the strategy which owns the maker order. |
»» amount | string | true | The amount that was filled. |
»» symbol | string | true | The symbol of the asset that was filled. |
»» price | string,null | true | The fill price. |
»» makerFeeUSDC | string,null | true | The USDC fee that was incurred to the maker side of the fill if the maker receives fees in USDC. |
»» makerFeeDDX | string,null | true | The fee that was incurred to the maker side of the fill if the maker elected to receive fees in DDX. Null otherwise. |
»» makerRealizedPnl | string,null | true | The realized profit and loss (not inclusive of fees) incurred to the maker due to this fill. Null otherwise. |
»» reason | number | true | The type of order update. Values include: 0: trade, 1: liquidation, 2: cancel |
»» takerOrderHash | string,null | true | The order hash for the taker side of this order update. |
»» takerOrderTrader | string,null | true | The trader address prefixed with the blockchain discriminant of the trader which owns the taker order. |
»» takerOrderStrategyIdHash | string,null | true | The hashed strategy id of the strategy which owns the taker order. |
»» takerFeeUSDC | string,null | true | The fee that was incurred to the taker side of the fill if taker receives fees in USDC. Null otherwise |
»» takerFeeDDX | string,null | true | The fee that was incurred to the taker side of the fill if taker receives fees in DDX. Null otherwise |
»» takerRealizedPnl | string,null | true | The realized profit and loss (not inclusive of fees) incurred to the taker due to this fill. |
»» liquidatedTrader | string,null | true | In the case that this was a liquidation fill, the trader address prefixed with the blockchain discriminant of the trader that was liquidated. |
»» liquidatedStrategyIdHash | string,null | true | The liquidated strategy id hash |
»» createdAt | string(date-time) | true | The time when this row was added to the database. |
Strategy Update
Subscription Message
Example Strategy Update subscription object
{
"feed": "STRATEGY_UPDATE",
"params": {
"traderAddress": "0x00a0e5c79803c14d61cc1c33e497aaafed509e29c6",
"strategyIdHash": "0x2576ebd1"
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» traderAddress | string | false | The trader address prefixed with the blockchain discriminant. |
» strategyIdHash | string | false | The hashed strategy of the trader which owns this order. |
Feed Message
Example Strategy Update feed messages
{
"feed": "STRATEGY_UPDATE",
"params": {},
"contents": {
"messageType": "partial",
"data": null,
"ordinal": 0
}
}
{
"feed": "STRATEGY_UPDATE",
"params": {},
"contents": {
"messageType": "update",
"data": [
{
"epochId": "28",
"txOrdinal": "4",
"ordinal": "0",
"amount": "-10",
"createdAt": "2023-03-01T05:17:42.314Z",
"collateralAddress": null,
"newAvailCollateral": "10",
"newLockedCollateral": "0",
"kind": 2,
"blockNumber": null,
"txHash": null,
"newAvgEntryPrices": null,
"fundingPayments": null,
"trader": "0x0091c987bf62d25945db517bdaa840a6c661374402",
"strategyIdHash": "0x2576ebd1"
}
],
"ordinal": 1
}
}
Upon subscribing, the Strategy Update Feed will first return an empty partial. Subsequent messages will contain strategy updates.
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» symbol | string | false | The symbol to filter by |
» traderAddress | string | false | The trader address which placed the order |
» strategyIdHash | string | false | The hashed strategyId |
contents | object | true | The contents of the message |
» messageType | string | true | The message type. Values include: 'partial', 'update' |
» ordinal | number | true | The sequence number of this message relative to the feed subscription |
» data | array | true | The data returned by the feed |
»» epochId | string | true | The epoch in which this transaction occured. |
»» txOrdinal | string | true | The transaction ordinal, within the epoch. |
»» ordinal | string | true | The ordinal within this particular transaction. |
»» trader | string | true | The trader address prefixed with the blockchain discriminant of the trader who owns this strategy. |
»» strategyIdHash | string | true | The hashed version of this strategy ID. |
»» collateralAddress | string,null | true | The collateral address on which this strategy update took place. |
»» amount | string | true | The amount that was modified in the strategy. |
»» newAvailCollateral | string,null | true | If affected, the updated available collateral amount after this strategy update. |
»» newLockedCollateral | string,null | true | If affected, the updated locked collateral amount after this strategy update. |
»» kind | number | true | The type of strategy update. Values include: 0: Deposit, 1: Withdraw, 2: WithdrawIntent, 3: FundingPayment, 4: RealizedPnl |
»» blockNumber | string,null | true | The block number in which this strategy update was processed. |
»» txHash | string,null | true | The on-chain transaction hash corresponding to this strategy update (for Deposit and Withdraw kinds) |
»» newAvgEntryPrices | any | true | After a RealizedPnl strategy update, what the new average entry prices are for this strategies' open positions. |
Trader Update
Subscription Message
Example Trader Update subscription object
{
"feed": "TRADER_UPDATE",
"params": {
"trader": "0x00a0e5c79803c14d61cc1c33e497aaafed509e29c6"
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» trader | string | false | The trader address prefixed with the blockchain discriminant. |
Feed Message
Example Trader Update feed messages
{
"feed": "TRADER_UPDATE",
"params": {},
"contents": {
"messageType": "partial",
"data": null,
"ordinal": 0
}
}
{
"feed": "TRADER_UPDATE",
"params": {},
"contents": {
"messageType": "update",
"data": [
{
"epochId": "28",
"txOrdinal": "9",
"ordinal": "0",
"amount": "2557.077624",
"createdAt": "2023-03-01T05:19:52.314Z",
"newDdxBalance": "0",
"kind": 4,
"blockNumber": "2088",
"txHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"payFeesInDdx": true,
"trader": "0x0091c987bf62d25945db517bdaa840a6c661374402"
}
],
"ordinal": 1
}
}
Upon subscribing, the Trader Update Feed will first return an empty partial. Subsequent messages will contain trader updates.
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» trader | string | false | The trader address |
contents | object | true | The contents of the message |
» messageType | string | true | The message type. Values include: 'partial', 'update' |
» ordinal | number | true | The sequence number of this message relative to the feed subscription |
» data | array | true | The data returned by the feed |
»» epochId | string | true | The epoch in which this transaction occured. |
»» txOrdinal | string | true | The transaction ordinal, within the epoch. |
»» ordinal | string | true | The ordinal within this particular transaction. |
»» trader | string | true | The trader address prefixed with the blockchain discriminant of the trader. |
»» amount | string | true | The amount of DDX was modified in this trader. |
»» newDdxBalance | string | true | The new DDX balance after updating this trader. |
»» kind | number | true | The type of trader update. Values include: 0: Deposit 1: WithdrawDDX 2: ClaimDDXWithdraw 3: TradeMiningReward |
»» payFeesInDdx | boolean | true | A flag which when set will attempt to pay trading fees using the DDX held in this trader. |
»» blockNumber | string,null | true | The block number in which this strategy update was processed. |
»» txHash | string,null | true | The on-chain transaction hash corresponding to this trader update (for Deposit and ClaimDDXWithdraw kinds) |
»» createdAt | string(date-time) | true | The time when this row was added to the database. |
Liquidation
Subscription Message
Example Liquidation subscription object
{
"feed": "LIQUIDATION",
"params": {
"symbol": "ETHP",
"trader": "0x00a0e5c79803c14d61cc1c33e497aaafed509e29c6",
"strategyIdHash": "0x2576ebd1"
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» symbol | string | false | The symbol to filter by |
» trader | string | false | The trader address prefixed with the blockchain discriminant of the trader who owned the liquidated order. |
» strategyIdHash | string | false | The hashed strategy of the trader who owned the liquidated order. |
Feed Message
Example Liquidation feed messages
{
"feed": "LIQUIDATION",
"params": {},
"contents": {
"messageType": "partial",
"data": null,
"ordinal": 0
}
}
{
"feed": "LIQUIDATION",
"params": {},
"contents": {
"messageType": "update",
"data": [
{
"epochId": "28",
"txOrdinal": "9",
"ordinal": "0",
"symbol": "ETHP",
"trader": "0x00a0e5c79803c14d61cc1c33e497aaafed509e29c6",
"strategyIdHash": "0x2576ebd1",
"triggerPriceHash": "0x8cf9916f564a2e44d8f4a5017a77f290641a25766b2278d952",
"markPrice": "5122.040416",
"insuranceFundCapitalization": "10340.40",
"createdAt": "2023-03-01T05:19:52.314Z"
}
],
"ordinal": 1
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» symbol | string | false | The symbol to filter by |
» trader | string | false | The trader address |
» strategyIdHash | string | false | The hashed strategy id |
contents | object | true | The contents of the message |
» messageType | string | true | The message type. Values include: 'partial', 'update' |
» ordinal | number | true | The sequence number of this message relative to the feed subscription |
» data | array | true | The data returned by the feed |
»» epochId | string | true | The epoch in which this transaction occured. |
»» txOrdinal | string | true | The transaction ordinal, within the epoch. |
»» ordinal | string | true | The ordinal within this particular transaction. |
»» symbol | string | true | The symbol of the asset in which the liquidation occured. |
»» trader | string | true | The trader address prefixed with the blockchain discriminant of the trader who was liquidated. |
»» strategyIdHash | string | true | The strategy id of the trader who was liquidated. |
»» triggerPriceHash | string,null | true | The hash of the price update that caused the liquidation. |
»» markPrice | string | true | The mark price of the asset at the time of liquidation. |
»» insuranceFundCapitalization | string | true | The insurance fund capitalization after this liquidation transaction. |
»» createdAt | string(date-time) | true | The time when this row was added to the database. |
ADL
Subscription Message
Example ADL subscription object
{
"feed": "ADL",
"params": {
"symbol": "ETHP",
"adlTrader": "0x00a0e5c79803c14d61cc1c33e497aaafed509e29c6",
"adlStrategyIdHash": "0x2576ebd1"
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» symbol | string | false | The symbol to filter by |
» adlTrader | string | false | The trader address prefixed with the blockchain discriminant of the trader who was ADL'd. |
» adlStrategyIdHash | string | false | The hashed strategy of the trader who was ADL'd. |
Feed Message
Example ADL feed messages
{
"feed": "ADL",
"params": {},
"contents": {
"messageType": "partial",
"data": null,
"ordinal": 0
}
}
{
"feed": "ADL",
"params": {},
"contents": {
"messageType": "update",
"data": [
{
"epochId": "28",
"txOrdinal": "9",
"ordinal": "0",
"amount": "3.6",
"symbol": "ETHP",
"adlTrader": "0x00a0e5c79803c14d61cc1c33e497aaafed509e29c6",
"adlStrategyIdHash": "0x2576ebd1",
"liquidatedTrader": "0x0091c987bf62d25945db517bdaa840a6c661374402",
"liquidatedStrategyIdHash": "0x2576ebd1",
"createdAt": "2023-03-01T05:19:52.314Z"
}
],
"ordinal": 1
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» symbol | string | false | The symbol to filter by |
» adlTrader | string | false | The trader address of the trader that has been ADL'd |
» strategyIdHash | string | false | The hashed strategy id of the strategy that has been ADL'd |
contents | object | true | The contents of the message |
» messageType | string | true | The message type. Values include: 'partial', 'update' |
» ordinal | number | true | The sequence number of this message relative to the feed subscription |
» data | array | true | The data returned by the feed |
»» epochId | string | true | The epoch in which this transaction occured. |
»» txOrdinal | string | true | The transaction ordinal, within the epoch. |
»» ordinal | string | true | The ordinal within this particular transaction. |
»» amount | string | true | The amount that was auto de-leveraged. |
»» symbol | string | true | The symbol of the asset that was auto de-leveraged. |
»» adlTrader | string | true | The trader address prefixed with the blockchain discriminant of the trader who was de-leveraged. |
»» adlStrategyIdHash | string | true | The strategy ID from the trader who was de-leveraged. |
»» liquidatedTrader | string | true | The trader address of the trader who was liquidated, leading to this adl. |
»» liquidatedStrategyIdHash | string | true | The strategy ID from the trader who was liquidated, leading to this adl. |
»» createdAt | string(date-time) | true | The time when this row was added to the database. |
Strategy
If a trader and strategyId are provided upon subscribing, the Strategy Feed will first return a partial reflecting the current state of that Strategy, otherwise it will return an empty partial. Subsequently, the Strategy Feed will send the full Strategy object upon each update.
Subscription Message
Example Strategy subscription object
{
"feed": "STRATEGY",
"params": {
"trader": "0x00a0e5c79803c14d61cc1c33e497aaafed509e29c6",
"strategyId": "main"
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» trader | string | false | The trader address prefixed with the blockchain discriminant of the trader who owns this strategy |
» strategyId | string | false | The strategy id |
Feed Message
Example Strategy feed messages
{
"feed": "STRATEGY",
"params": {
"trader": "0x0091c987bf62d25945db517bdaa840a6c661374402",
"strategyId": "main"
},
"contents": {
"messageType": "partial",
"data": [
{
"trader": "0x0091c987bf62d25945db517bdaa840a6c661374402",
"strategyId": "main",
"strategyIdHash": "0x2576ebd1",
"maxLeverage": 3,
"availCollateral": "9676.755555",
"lockedCollateral": "19.1",
"frozen": false
}
],
"ordinal": 0
}
}
{
"feed": "STRATEGY",
"params": {
"trader": "0x0091c987bf62d25945db517bdaa840a6c661374402",
"strategyId": "main"
},
"contents": {
"messageType": "update",
"data": [
{
"trader": "0x0091c987bf62d25945db517bdaa840a6c661374402",
"strategyId": "main",
"strategyIdHash": "0x2576ebd1",
"maxLeverage": 3,
"availCollateral": "9675.755555",
"lockedCollateral": "20.1",
"frozen": false
}
],
"ordinal": 1
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» trader | string | false | The trader address |
» strategyId | string | false | The strategy id |
contents | object | true | The contents of the message |
» messageType | string | true | The message type. Values include: 'partial', 'update' |
» ordinal | number | true | The sequence number of this message relative to the feed subscription |
» data | array | true | The data returned by the feed |
»» trader | string | true | The trader address prefixed with the blockchain discriminant of the trader who owns this strategy. |
»» strategyIdHash | string | true | The hashed version of this strategy ID. |
»» strategyId | string | true | An identifier for this strategy. |
»» maxLeverage | number | true | The maximum leverage this strategy is allowed to take on. |
»» availCollateral | string | true | The amount of collateral that this strategy holds. |
»» lockedCollateral | string | true | The amount of collateral which has been initiated for withdrawal. |
»» frozen | boolean | true | Whether this strategy is frozen. Not currently in use. |
Trader
If a trader is provided upon subscribing, the Trader Feed will first return a partial reflecting the current state of that Trader, otherwise it will return an empty partial. Subsequently, the Trader Feed will send the full Trader object upon each update.
Subscription Message
Example Trader subscription object
{
"feed": "TRADER",
"params": {
"trader": "0x00a0e5c79803c14d61cc1c33e497aaafed509e29c6"
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» trader | string | false | The trader address prefixed with the blockchain discriminant |
Feed Message
Example Trader feed messages
{
"feed": "TRADER",
"params": {
"trader": "0x0091c987bf62d25945db517bdaa840a6c661374402"
},
"contents": {
"messageType": "partial",
"data": [
{
"trader": "0x0091c987bf62d25945db517bdaa840a6c661374402",
"availDdx": "5114.155248",
"lockedDdx": "0",
"payFeesInDdx": false
}
],
"ordinal": 0
}
}
{
"feed": "TRADER",
"params": {
"trader": "0x0091c987bf62d25945db517bdaa840a6c661374402"
},
"contents": {
"messageType": "update",
"data": [
{
"trader": "0x0091c987bf62d25945db517bdaa840a6c661374402",
"availDdx": "5114.155248",
"lockedDdx": "0",
"payFeesInDdx": false
}
],
"ordinal": 1
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» trader | string | false | The trader address |
contents | object | true | The contents of the message |
» messageType | string | true | The message type. Values include: 'partial', 'update' |
» ordinal | number | true | The sequence number of this message relative to the feed subscription |
» data | array | true | The data returned by the feed |
»» trader | string | true | The trader address prefixed with the blockchain discriminant. |
»» availDdx | string | true | The amount of DDX that the trader holds. |
»» lockedDdx | string | true | The amount of DDX that the trader has initiated for withdrawal. |
»» payFeesInDdx | boolean | true | A flag which indicates whether the trader wants to attempt to pay trading fees using their DDX balance. |
Position
If a trader and strategyIdHash are provided upon subscribing, the Position Feed will first return a partial reflecting the current state of that Position.
Subscription Message
Example Position subscription object
{
"feed": "POSITION",
"params": {
"trader": "0x00a0e5c79803c14d61cc1c33e497aaafed509e29c6",
"strategyIdHash": "0x2576ebd1",
"symbol": "ETHP"
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» trader | string | false | The trader address prefixed with the blockchain discriminant of the trader that owns this position |
» strategyIdHash | string | false | The hashed strategy of the trader who owns this position |
» symbol | string | false | The position symbol to filter by |
Feed Message
Example Position feed messages
{
"feed": "POSITION",
"params": {
"trader": "0x00accf7803c88b05846c46946d7b46418a9adad578",
"strategyIdHash": "0x2576ebd1"
},
"contents": {
"messageType": "partial",
"data": [
{
"trader": "0x00accf7803c88b05846c46946d7b46418a9adad578",
"symbol": "ETHP",
"strategyIdHash": "0x2576ebd1",
"side": 1,
"balance": "2.3",
"avgEntryPrice": "1638.012892",
"lastModifiedInEpoch": null
}
],
"ordinal": 0
}
}
{
"feed": "POSITION",
"params": {
"trader": "0x00accf7803c88b05846c46946d7b46418a9adad578",
"strategyIdHash": "0x2576ebd1"
},
"contents": {
"messageType": "update",
"data": [
{
"trader": "0x00accf7803c88b05846c46946d7b46418a9adad578",
"symbol": "ETHP",
"strategyIdHash": "0x2576ebd1",
"side": 1,
"balance": "2.4",
"avgEntryPrice": "1637.516521",
"lastModifiedInEpoch": null
}
],
"ordinal": 1
}
}
Name | Type | Required | Description |
---|---|---|---|
feed | string | true | The name of the Feed |
params | object | true | The parameters that the feed can take |
» symbol | string | false | The symbols to filter by |
» trader | string | false | The trader address which owns the position |
» strategyIdHash | string | false | The hashed strategyId |
contents | object | true | The contents of the message |
» messageType | string | true | The message type. Values include: 'partial', 'update' |
» ordinal | number | true | The sequence number of this message relative to the feed subscription |
» data | array | true | The data returned by the feed |
»» trader | string | true | The trader address prefixed with the blockchain discriminant of the trader who owns this position. |
»» symbol | string | true | The symbol of the asset for this position. |
»» strategyIdHash | string | true | The hash of the strategy which owns this position. |
»» side | number | true | The side of the position. Values include: 0: None, 1: Long, 2: Short |
»» balance | string | true | The current balance of this position. |
»» avgEntryPrice | string | true | The average entry price of this position. |
»» lastModifiedInEpoch | number,null | true | The epoch in which this position's balance was last modified. |
Auditor
The Auditor is a Pythonic application that connects to the DerivaDEX Operators' WebSocket API upon initialization and allows anyone to validate the honesty and integrity of the exchange's operations.
Running the Auditor is not required to trade on the exchange, however can certainly be run in-band or out-of-band with respect to programmatic strategies to ensure you are verifiably up-to-date with the latest exchange data.
DerivaDEX's data model is powered by a Sparse Merkle Tree data store and a transaction log of state-modifying transitions. These are emitted in raw formats by the DerivaDEX Operators API, and the Auditor efficiently processes them to perform validation.
Setup
To run the Auditor from source, follow these steps from the DerivaDEX ddx_client
repository (< 5 minutes):
-
If you don't already have it, it is recommended you set up Anaconda/Python(>3) on your machine
-
Initialize and activate a Conda environment (located at the root level of the repo) from which you will run the Auditor:
conda env create -f environment.yml && conda activate derivadex
-
Set your PYTHONPATH:
export PYTHONPATH="${PYTHONPATH}:/your/full/path/upto/but/not/including/ddx_client"
-
Navigate to the
auditor
subdirectory and create an.auditor.conf.json
file using the template:cp .auditor.conf.json.template .auditor.conf.json
-
Run the Auditor with:
PYTHON_LOG=info python auditor_driver.py --config ".auditor.conf.json"
You will almost immediately see logging messages (should be lots of green) with state initialized and transactions streaming through successfully.
Voila! You now have the Auditor running locally validating the entire DerivaDEX exchange!
Sparse Merkle Tree
DerivaDEX utilizes a Sparse Merkle Tree (SMT) in order to efficiently maintain the state of the exchange at all times. Storing data on-chain (such as user's balances and positions), something most decentralized exchanges do, is very costly and one that is usually passed on to the user, making exchange use prohibitively expensive to most. An SMT, however, allows the system to only store a single root hash (the root of the tree) on-chain, while still allowing for anyone to verify the integrity of the data (leaves) through inclusion (or non-inclusion) proofs.
So what kind of data is stored and where in the SMT? The short answer is - everything. This means any data pertaining to a trader (their account-level data, strategy-level data, positions, and volume statistics), to a given market (the various open orders and the price feed information), and to the system (the insurance fund capitalization) is stored as individual leaf entries in the SMT. The DerivaDEX SMT consists of 2^256 possible leaves, each uniquely located at a specific leaf location (as indicated by its key
, which is a 32-byte value). As you might surmise, the vast majority of the SMT will be empty (2^256 is very, very, very large number), but the data that does exist can exist at a location anywhere within these large bounds. For efficient querying and data management (while maintaining practical collision-resistance), the various types of leaf items are prefixed to reside in the same general vicinity as one another. Each leaf item type is described in detail below. The full set of leaf types can be seen in the following table, along with their corresponding numeric discriminants.
Item | Discriminant |
---|---|
Empty | 0 |
Trader | 1 |
Strategy | 2 |
Position | 3 |
BookOrder | 4 |
Price | 5 |
InsuranceFund | 6 |
Stats | 7 |
Signer | 8 |
Specs | 9 |
InsuranceFundContribution | 10 |
FeePool | 11 |
EpochMetadata | 12 |
Each leaf type is described in detail below.
Trader
A Trader
leaf contains information pertaining to a trader's available and locked DDX balances, referral address, and fee payment mechanism.
Key encoding / decoding
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right
def encode_key(trader_address: str):
# ItemType.TRADER == 1
return zpad32_right(
ItemType.TRADER.to_bytes(1, byteorder="little")
+ bytes.fromhex(trader_address[2:])
)
def decode_key(trader_key: bytes):
# trader_address
return f"0x{trader_key[1:22].hex()}"
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right
def encode_key(trader_address: str):
# ItemType.TRADER == 1
return zpad32_right(
ItemType.TRADER.to_bytes(1, byteorder="little")
+ bytes.fromhex(trader_address[2:])
)
def decode_key(trader_key: bytes):
# trader_address
return f"0x{trader_key[1:22].hex()}"
The location of a Trader
leaf is determined by its key, which is encoded as follows:
Bytes | Value |
---|---|
0 | Trader discriminant |
[1, 21] | Trader's Ethereum address prefixed with the chain discriminant |
[22, 31] | Zero-padding |
The following sample Trader
materials generates the following encoded key: 0x0100603699848c84529987e14ba32c8a66def67e9ece00000000000000000000
.
field | value |
---|---|
trader_address | "0x00603699848c84529987E14Ba32C8a66DEF67E9eCE" |
Value definition
Value encoding / decoding (Python)
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_unit_amount(val, decimals):
return Decimal(str(val)) / 10 ** decimals
def abi_encoded_value(self, avail_ddx_balance: Decimal, locked_ddx_balance: Decimal, referral_address: str):
# Trader item discriminant
item_type = 1
# Scale collateral amounts to grains
return encode_single(
"(uint8,(uint128,uint128,address,bool))",
[
item_type,
[
to_base_unit_amount(avail_ddx_balance, 6),
to_base_unit_amount(locked_ddx_balance, 6),
referral_address,
],
],
)
def abi_decoded_value(abi_encoded_value: str):
(
item_type,
(avail_ddx_balance, locked_ddx_balance, referral_address),
) = decode_single(
"(uint8,(uint128,uint128,address,bool))", w3.toBytes(hexstr=abi_encoded_value),
)
# Scale collateral amounts from grains
return (
to_unit_amount(avail_ddx_balance, 6),
to_unit_amount(locked_ddx_balance, 6),
referral_address,
)
Value encoding / decoding (Python)
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_unit_amount(val, decimals):
return Decimal(str(val)) / 10 ** decimals
def abi_encoded_value(self, avail_ddx_balance: Decimal, locked_ddx_balance: Decimal, referral_address: str):
# Trader item discriminant
item_type = 1
# Scale collateral amounts to grains
return encode_single(
"(uint8,(uint128,uint128,address,bool))",
[
item_type,
[
to_base_unit_amount(avail_ddx_balance, 6),
to_base_unit_amount(locked_ddx_balance, 6),
referral_address,
],
],
)
def abi_decoded_value(abi_encoded_value: str):
(
item_type,
(avail_ddx_balance, locked_ddx_balance, referral_address),
) = decode_single(
"(uint8,(uint128,uint128,address,bool))", w3.toBytes(hexstr=abi_encoded_value),
)
# Scale collateral amounts from grains
return (
to_unit_amount(avail_ddx_balance, 6),
to_unit_amount(locked_ddx_balance, 6),
referral_address,
)
A Trader
leaf holds the following data:
type | field | description |
---|---|---|
decimal | avail_ddx_balance | DDX collateral available for staking/fees |
decimal | locked_ddx_balance | DDX collateral available for on-chain withdrawal |
address_s | referral_address | Referral address pertaining to the Ethereum address who referred this trader (if applicable) |
bool | pay_fees_in_ddx | Whether trader has opted to pay fees in DDX by default or not |
These contents are always stored in the tree in ABI-encoded form: (uint8,(uint128,uint128,address,bool))
. Meaning, you will want to decode the contents into a more suitable form for your purposes as necessary (for example loading data from a snapshot of the state), and will need to encode it back again if you are saving it back into the tree. A sample of Python code that derives this ABI-encoding, including the grains conversion for certain variables, is shown on the right.
The following sample Trader
materials generates the following ABI-encoded value: 0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a8dda8d7f5310e4a9e24f8eba77e091ac264f8720000000000000000000000000000000000000000000000000000000000000000
.
field | value |
---|---|
avail_ddx_balance | 1000 |
locked_ddx_balance | 0 |
referral_address | "0xA8dDa8d7F5310E4A9E24F8eBA77E091Ac264f872" |
pay_fees_in_ddx | True |
Strategy
A Strategy
leaf contains information pertaining to a trader's cross-margined strategy, such as their available and locked collaterals and max leverage.
Key encoding / decoding
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right, encode_single, decode_single
from web3.auto import w3
def generate_strategy_id_hash(strategy_id: str) -> bytes:
# Get the first 4 bytes of the hash of the strategy id
return w3.keccak(
len(strategy_id).to_bytes(1, byteorder="little")
+ encode_single("bytes32", strategy_id.encode("utf8"))[:-1]
)[:4]
def encode_key(trader_address: str, strategy_id: str, chain_discriminant: int):
# ItemType.STRATEGY == 2
return zpad32_right(
ItemType.STRATEGY.to_bytes(1, byteorder="little")
+ bytes.fromhex(trader_address[2:])
+ generate_strategy_id_hash(strategy_id)
)
def decode_key(strategy_key: bytes):
# trader_address, strategy_id_hash
return (
f"0x{strategy_key[1:22].hex()}",
f"0x{strategy_key[22:26].hex()}",
)
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right, encode_single, decode_single
from web3.auto import w3
def generate_strategy_id_hash(strategy_id: str) -> bytes:
# Get the first 4 bytes of the hash of the strategy id
return w3.keccak(
len(strategy_id).to_bytes(1, byteorder="little")
+ encode_single("bytes32", strategy_id.encode("utf8"))[:-1]
)[:4]
def encode_key(trader_address: str, strategy_id: str, chain_discriminant: int):
# ItemType.STRATEGY == 2
return zpad32_right(
ItemType.STRATEGY.to_bytes(1, byteorder="little")
+ bytes.fromhex(trader_address[2:])
+ generate_strategy_id_hash(strategy_id)
)
def decode_key(strategy_key: bytes):
# trader_address, strategy_id_hash
return (
f"0x{strategy_key[1:22].hex()}",
f"0x{strategy_key[22:26].hex()}",
)
The location of a Strategy
leaf is determined by its key, which is encoded as follows:
Bytes | Value |
---|---|
0 | Strategy discriminant |
[1, 21] | Trader's Ethereum address prefixed with the chain discriminant |
[22, 25] | Abbreviated hash of strategy ID |
[26, 25] | Zero-padding |
The following sample Strategy
materials generates the following encoded key: 0x0200603699848c84529987e14ba32c8a66def67e9ece2576ebd1000000000000
.
field | value |
---|---|
trader_address | "0x00603699848c84529987E14Ba32C8a66DEF67E9eCE" |
strategy_id | "main" |
Value definition
Value encoding / decoding (Python)
from typing import Dict
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_base_unit_amount_list(vals, decimals):
return [to_base_unit_amount(val, decimals) for val in vals]
def to_unit_amount(val: int, decimals: int) -> Decimal:
return Decimal(str(val)) / 10 ** decimals
def to_unit_amount_list(vals: List[int], decimals: int):
return [to_unit_amount(val, decimals) for val in vals]
def to_adjusted_encoding_for_negative_val(val: int):
return 16 ** 32 + abs(val) if val < 0 else val
def to_adjusted_encoding_for_negative_val_list(vals: List[int]):
return [to_adjusted_encoding_for_negative_val(val) for val in vals]
def from_adjusted_encoding_for_negative_val(val: int):
return val if val < 16 ** 32 else -(val - 16 ** 32)
def abi_encoded_value(self, strategy_id: str, avail_collateral: Dict[str, Decimal], locked_collateral: Dict[str, Decimal], max_leverage: int, frozen: bool):
# Strategy item discriminant
item_type = 2
# Scale collateral amounts to grains
return encode_single(
"((uint8,(bytes32,(address[],uint256[]),(address[],uint128[]),uint64,bool)))",
[
[
item_type,
[
len(strategy_id).to_bytes(1, byteorder="little")
+ encode_single("bytes32", strategy_id.encode("utf8"))[
:-1
],
[
list(avail_collateral.keys()),
to_adjusted_encoding_for_negative_val_list(
to_base_unit_amount_list(
list(avail_collateral.values()), 6
)
),
],
[
list(locked_collateral.keys()),
to_base_unit_amount_list(
list(locked_collateral.values()), 6
),
],
max_leverage,
frozen,
],
]
],
)
def abi_decoded_value(abi_encoded_value: str):
(
(
item_type,
(
strategy_id,
(avail_collateral_tokens, avail_collateral_amounts),
(locked_collateral_tokens, locked_collateral_amounts),
max_leverage,
frozen,
),
),
) = decode_single(
"((uint8,(bytes32,(address[],uint256[]),(address[],uint128[]),uint64,bool)))",
w3.toBytes(hexstr=abi_encoded_value),
)
# Scale collateral amounts from grains
return (
strategy_id[1 : 1 + strategy_id[0]].decode("utf8"),
{
k: to_unit_amount(from_adjusted_encoding_for_negative_val(v), 6)
for k, v in zip(
list(avail_collateral_tokens), list(avail_collateral_amounts)
)
},
{
k: to_unit_amount(v, 6)
for k, v in zip(
list(locked_collateral_tokens), list(locked_collateral_amounts)
)
},
max_leverage,
frozen,
)
Value encoding / decoding (Python)
from typing import Dict
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_base_unit_amount_list(vals, decimals):
return [to_base_unit_amount(val, decimals) for val in vals]
def to_unit_amount(val: int, decimals: int) -> Decimal:
return Decimal(str(val)) / 10 ** decimals
def to_unit_amount_list(vals: List[int], decimals: int):
return [to_unit_amount(val, decimals) for val in vals]
def to_adjusted_encoding_for_negative_val(val: int):
return 16 ** 32 + abs(val) if val < 0 else val
def to_adjusted_encoding_for_negative_val_list(vals: List[int]):
return [to_adjusted_encoding_for_negative_val(val) for val in vals]
def from_adjusted_encoding_for_negative_val(val: int):
return val if val < 16 ** 32 else -(val - 16 ** 32)
def abi_encoded_value(self, strategy_id: str, avail_collateral: Dict[str, Decimal], locked_collateral: Dict[str, Decimal], max_leverage: int, frozen: bool):
# Strategy item discriminant
item_type = 2
# Scale collateral amounts to grains
return encode_single(
"((uint8,(bytes32,(address[],uint256[]),(address[],uint128[]),uint64,bool)))",
[
[
item_type,
[
len(strategy_id).to_bytes(1, byteorder="little")
+ encode_single("bytes32", strategy_id.encode("utf8"))[
:-1
],
[
list(avail_collateral.keys()),
to_adjusted_encoding_for_negative_val_list(
to_base_unit_amount_list(
list(avail_collateral.values()), 6
)
),
],
[
list(locked_collateral.keys()),
to_base_unit_amount_list(
list(locked_collateral.values()), 6
),
],
max_leverage,
frozen,
],
]
],
)
def abi_decoded_value(abi_encoded_value: str):
(
(
item_type,
(
strategy_id,
(avail_collateral_tokens, avail_collateral_amounts),
(locked_collateral_tokens, locked_collateral_amounts),
max_leverage,
frozen,
),
),
) = decode_single(
"((uint8,(bytes32,(address[],uint256[]),(address[],uint128[]),uint64,bool)))",
w3.toBytes(hexstr=abi_encoded_value),
)
# Scale collateral amounts from grains
return (
strategy_id[1 : 1 + strategy_id[0]].decode("utf8"),
{
k: to_unit_amount(from_adjusted_encoding_for_negative_val(v), 6)
for k, v in zip(
list(avail_collateral_tokens), list(avail_collateral_amounts)
)
},
{
k: to_unit_amount(v, 6)
for k, v in zip(
list(locked_collateral_tokens), list(locked_collateral_amounts)
)
},
max_leverage,
frozen,
)
A Strategy
leaf holds the following data:
type | field | description |
---|---|---|
string | strategy_id | Identifier for strategy (e.g. "main") |
dict<address_s, decimal> | avail_collateral | Mapping of collateral address to available collateral amount |
dict<address_s, decimal> | locked_collateral | Mapping of collateral address to locked collateral amount |
int | max_leverage | Maximum leverage strategy can take |
bool | frozen | Whether the strategy is frozen or not (relevant for tokenization) |
These contents are always stored in the tree in ABI-encoded form: ((uint8,(bytes32,(address[],uint128[]),(address[],uint128[]),uint64,bool)))
. Meaning, you will want to decode the contents into a more suitable form for your purposes as necessary (for example loading data from a snapshot of the state), and will need to encode it back again if you are saving it back into the tree. A sample of Python code that derives this ABI-encoding, including the grains conversion for certain variables, is shown on the right.
The following sample Strategy
materials generates the following ABI-encoded value: 0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040046d61696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000b69e673309512a9d726f87304c6984054f87a93b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000002e8f3487400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
.
field | value |
---|---|
strategy_id | "main" |
avail_collateral | {"0xb69e673309512a9d726f87304c6984054f87a93b": 199971.08} |
locked_collateral | {} |
max_leverage | 3 |
frozen | False |
Position
A Position
leaf contains information pertaining to an open position.
Key encoding / decoding
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right, encode_single, decode_single
from web3.auto import w3
def generate_strategy_id_hash(strategy_id: str) -> bytes:
# Get the first 4 bytes of the hash of the strategy id
return w3.keccak(
len(strategy_id).to_bytes(1, byteorder="little")
+ encode_single("bytes32", strategy_id.encode("utf8"))[:-1]
)[:4]
def pack_bytes(text: str):
charset = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"
symbol_bits = ""
for letter in text:
for i, char in enumerate(charset):
if char == letter:
bits = format(i, "08b")[::-1]
symbol_bits += bits[:5]
symbol_bytes = int(symbol_bits[::-1], 2).to_bytes(
(len(symbol_bits) + 7) // 8, byteorder="little"
)
return zpad_right(symbol_bytes, 6)
def unpack_bytes(packed_text: bytes):
charset = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"
symbol_bits = format(int.from_bytes(packed_text, "little"), "030b")[::-1]
symbol_char_bit_chunks = [
symbol_bits[i : i + 5] for i in range(0, len(symbol_bits), 5)
]
symbol = ""
for symbol_char_bit_chunk in symbol_char_bit_chunks:
reversed_bit_chunk = symbol_char_bit_chunk[::-1]
char_index = int(reversed_bit_chunk, 2)
symbol += charset[char_index]
return symbol
def encode_key(trader_address: str, strategy_id: str, symbol: str, chain_discriminant: int):
# ItemType.POSITION == 3
return (
ItemType.POSITION.to_bytes(1, byteorder="little")
+ pack_bytes(symbol)
+ bytes.fromhex(trader_address[2:])
+ generate_strategy_id_hash(strategy_id)
)
def decode_key(position_key: bytes):
# symbol, trader_address, strategy_id_hash
return (
unpack_bytes(position_key[1:7]),
f"0x{position_key[7:28].hex()}",
f"0x{position_key[28:].hex()}",
)
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right, encode_single, decode_single
from web3.auto import w3
def generate_strategy_id_hash(strategy_id: str) -> bytes:
# Get the first 4 bytes of the hash of the strategy id
return w3.keccak(
len(strategy_id).to_bytes(1, byteorder="little")
+ encode_single("bytes32", strategy_id.encode("utf8"))[:-1]
)[:4]
def pack_bytes(text: str):
charset = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"
symbol_bits = ""
for letter in text:
for i, char in enumerate(charset):
if char == letter:
bits = format(i, "08b")[::-1]
symbol_bits += bits[:5]
symbol_bytes = int(symbol_bits[::-1], 2).to_bytes(
(len(symbol_bits) + 7) // 8, byteorder="little"
)
return zpad_right(symbol_bytes, 6)
def unpack_bytes(packed_text: bytes):
charset = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"
symbol_bits = format(int.from_bytes(packed_text, "little"), "030b")[::-1]
symbol_char_bit_chunks = [
symbol_bits[i : i + 5] for i in range(0, len(symbol_bits), 5)
]
symbol = ""
for symbol_char_bit_chunk in symbol_char_bit_chunks:
reversed_bit_chunk = symbol_char_bit_chunk[::-1]
char_index = int(reversed_bit_chunk, 2)
symbol += charset[char_index]
return symbol
def encode_key(trader_address: str, strategy_id: str, symbol: str, chain_discriminant: int):
# ItemType.POSITION == 3
return (
ItemType.POSITION.to_bytes(1, byteorder="little")
+ pack_bytes(symbol)
+ bytes.fromhex(trader_address[2:])
+ generate_strategy_id_hash(strategy_id)
)
def decode_key(position_key: bytes):
# symbol, trader_address, strategy_id_hash
return (
unpack_bytes(position_key[1:7]),
f"0x{position_key[7:28].hex()}",
f"0x{position_key[28:].hex()}",
)
The location of a Position
leaf is determined by its key, which is encoded as follows:
Bytes | Value |
---|---|
0 | Position discriminant |
[1, 6] | Symbol (5-bit encoded/packed) |
[7, 27] | Trader's Ethereum address prefixed with the chain discriminant |
[28, 31] | Abbreviated hash of strategy ID |
The following sample Position
materials generates the following encoded key: 0x0385225824040000603699848c84529987e14ba32c8a66def67e9ece2576ebd1
.
field | value |
---|---|
trader_address | "0x603699848c84529987E14Ba32C8a66DEF67E9eCE" |
strategy_id | "main" |
symbol | "ETHP" |
Value definition
Value encoding / decoding (Python)
from typing import Dict
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_unit_amount(val, decimals):
return Decimal(str(val)) / 10 ** decimals
def abi_encoded_value(side: int, balance: Decimal, avg_entry_price: Decimal):
# Position item discriminant
item_type = 3
# Scale balance and average entry price grains
return encode_single(
"(uint8,(uint8,uint128,uint128))",
[
item_type,
[
side,
to_base_unit_amount(balance, 6),
to_base_unit_amount(avg_entry_price, 6),
],
],
)
def abi_decoded_value(abi_encoded_value: str):
(item_type, (side, balance, avg_entry_price)) = decode_single(
"(uint8,(uint8,uint128,uint128))", w3.toBytes(hexstr=abi_encoded_value),
)
# Scale balance and average entry price from DDX grains
return (
side, to_unit_amount(balance, 6), to_unit_amount(avg_entry_price, 6)
)
Value encoding / decoding (Python)
from typing import Dict
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_unit_amount(val, decimals):
return Decimal(str(val)) / 10 ** decimals
def abi_encoded_value(side: int, balance: Decimal, avg_entry_price: Decimal):
# Position item discriminant
item_type = 3
# Scale balance and average entry price grains
return encode_single(
"(uint8,(uint8,uint128,uint128))",
[
item_type,
[
side,
to_base_unit_amount(balance, 6),
to_base_unit_amount(avg_entry_price, 6),
],
],
)
def abi_decoded_value(abi_encoded_value: str):
(item_type, (side, balance, avg_entry_price)) = decode_single(
"(uint8,(uint8,uint128,uint128))", w3.toBytes(hexstr=abi_encoded_value),
)
# Scale balance and average entry price from DDX grains
return (
side, to_unit_amount(balance, 6), to_unit_amount(avg_entry_price, 6)
)
A Position
leaf holds the following data:
type | field | description |
---|---|---|
int | side | Side of position (Long=1 , Short=2 ) |
decimal | balance | Size of the position |
decimal | average_entry_price | Average entry price of the position |
These contents are always stored in the tree in ABI-encoded form: (uint8,(uint8,uint128,uint128))
. Meaning, you will want to decode the contents into a more suitable form for your purposes as necessary (for example loading data from a snapshot of the state), and will need to encode it back again if you are saving it back into the tree. A sample of Python code that derives this ABI-encoding, including the grains conversion for certain variables, is shown on the right.
The following sample Position
materials generates the following ABI-encoded value: 0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000068155a43676e0000000000000000000000000000000000000000000000000000d4eff354906660000
.
field | value |
---|---|
side | 1 |
balance | 120 |
avg_entry_price | 245.5 |
Book Order
A BookOrder
leaf contains information pertaining to a maker order in the order book.
Key encoding / decoding
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right, encode_single, decode_single
from web3.auto import w3
def generate_strategy_id_hash(strategy_id: str) -> bytes:
# Get the first 4 bytes of the hash of the strategy id
return w3.keccak(
len(strategy_id).to_bytes(1, byteorder="little")
+ encode_single("bytes32", strategy_id.encode("utf8"))[:-1]
)[:4]
def pack_bytes(text: str):
charset = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"
symbol_bits = ""
for letter in text:
for i, char in enumerate(charset):
if char == letter:
bits = format(i, "08b")[::-1]
symbol_bits += bits[:5]
symbol_bytes = int(symbol_bits[::-1], 2).to_bytes(
(len(symbol_bits) + 7) // 8, byteorder="little"
)
return zpad_right(symbol_bytes, 6)
def unpack_bytes(packed_text: bytes):
charset = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"
symbol_bits = format(int.from_bytes(packed_text, "little"), "030b")[::-1]
symbol_char_bit_chunks = [
symbol_bits[i : i + 5] for i in range(0, len(symbol_bits), 5)
]
symbol = ""
for symbol_char_bit_chunk in symbol_char_bit_chunks:
reversed_bit_chunk = symbol_char_bit_chunk[::-1]
char_index = int(reversed_bit_chunk, 2)
symbol += charset[char_index]
return symbol
def encode_key(symbol: str, order_hash: str):
# ItemType.BOOK_ORDER == 3
return (
ItemType.BOOK_ORDER.to_bytes(1, byteorder="little")
+ pack_bytes(symbol)
+ bytes.fromhex(order_hash[2:52])
)
def decode_key(book_order_key: bytes):
# symbol, first 25 bytes of order_hash
return (
unpack_bytes(book_order_key[1:7]),
f"0x{book_order_key[7:].hex()}",
)
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right, encode_single, decode_single
from web3.auto import w3
def generate_strategy_id_hash(strategy_id: str) -> bytes:
# Get the first 4 bytes of the hash of the strategy id
return w3.keccak(
len(strategy_id).to_bytes(1, byteorder="little")
+ encode_single("bytes32", strategy_id.encode("utf8"))[:-1]
)[:4]
def pack_bytes(text: str):
charset = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"
symbol_bits = ""
for letter in text:
for i, char in enumerate(charset):
if char == letter:
bits = format(i, "08b")[::-1]
symbol_bits += bits[:5]
symbol_bytes = int(symbol_bits[::-1], 2).to_bytes(
(len(symbol_bits) + 7) // 8, byteorder="little"
)
return zpad_right(symbol_bytes, 6)
def unpack_bytes(packed_text: bytes):
charset = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"
symbol_bits = format(int.from_bytes(packed_text, "little"), "030b")[::-1]
symbol_char_bit_chunks = [
symbol_bits[i : i + 5] for i in range(0, len(symbol_bits), 5)
]
symbol = ""
for symbol_char_bit_chunk in symbol_char_bit_chunks:
reversed_bit_chunk = symbol_char_bit_chunk[::-1]
char_index = int(reversed_bit_chunk, 2)
symbol += charset[char_index]
return symbol
def encode_key(symbol: str, order_hash: str):
# ItemType.BOOK_ORDER == 3
return (
ItemType.BOOK_ORDER.to_bytes(1, byteorder="little")
+ pack_bytes(symbol)
+ bytes.fromhex(order_hash[2:52])
)
def decode_key(book_order_key: bytes):
# symbol, first 25 bytes of order_hash
return (
unpack_bytes(book_order_key[1:7]),
f"0x{book_order_key[7:].hex()}",
)
The location of a BookOrder
leaf is determined by its key, which is encoded as follows:
Bytes | Value |
---|---|
0 | Book order discriminant |
[1, 6] | Symbol (5-bit encoded/packed) |
[7, 31] | First 25 bytes of order's unique hash |
The following sample BookOrder
materials generates the following encoded key: 0x048522582404009fcf480aa9606f5bbb64ab36e642566bd893f715b346df244e
.
field | value |
---|---|
symbol | "ETHP" |
order_hash | "0x9fcf480aa9606f5bbb64ab36e642566bd893f715b346df244eABABABABABABAB" |
Value definition
Value encoding / decoding (Python)
from typing import Dict
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_unit_amount(val, decimals):
return Decimal(str(val)) / 10 ** decimals
def abi_encoded_value(self, side: int, amount: Decimal, price: Decimal, trader_address: str, strategy_id_hash: str, book_ordinal: int, time_value: int):
# BookOrder item discriminant
item_type = 4
# Scale amount and price to grains
return encode_single(
"(uint8,(uint8,uint128,uint128,bytes21,bytes32,uint64,uint64))",
[
item_type,
[
side,
to_base_unit_amount(amount, 6),
to_base_unit_amount(price, 6),
bytes.fromhex(trader_address[2:]),
bytes.fromhex(strategy_id_hash[2:]),
book_ordinal,
time_value,
],
],
)
def abi_decoded_value(abi_encoded_value: str):
(
item_type,
(side, amount, price, trader_address, strategy_id_hash, book_ordinal, time_value),
) = decode_single(
"(uint8,(uint8,uint128,uint128,bytes21,bytes32,uint64,uint64))",
w3.toBytes(hexstr=abi_encoded_value),
)
# Scale amount and price from grains
return (
side,
to_unit_amount(amount, 6),
to_unit_amount(price, 6),
f"0x{trader_address.hex()}",
f"0x{strategy_id_hash[:4].hex()}",
book_ordinal,
time_value,
)
Value encoding / decoding (Python)
from typing import Dict
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_unit_amount(val, decimals):
return Decimal(str(val)) / 10 ** decimals
def abi_encoded_value(self, side: int, amount: Decimal, price: Decimal, trader_address: str, strategy_id_hash: str, book_ordinal: int, time_value: int):
# BookOrder item discriminant
item_type = 4
# Scale amount and price to grains
return encode_single(
"(uint8,(uint8,uint128,uint128,bytes21,bytes32,uint64,uint64))",
[
item_type,
[
side,
to_base_unit_amount(amount, 6),
to_base_unit_amount(price, 6),
bytes.fromhex(trader_address[2:]),
bytes.fromhex(strategy_id_hash[2:]),
book_ordinal,
time_value,
],
],
)
def abi_decoded_value(abi_encoded_value: str):
(
item_type,
(side, amount, price, trader_address, strategy_id_hash, book_ordinal, time_value),
) = decode_single(
"(uint8,(uint8,uint128,uint128,bytes21,bytes32,uint64,uint64))",
w3.toBytes(hexstr=abi_encoded_value),
)
# Scale amount and price from grains
return (
side,
to_unit_amount(amount, 6),
to_unit_amount(price, 6),
f"0x{trader_address.hex()}",
f"0x{strategy_id_hash[:4].hex()}",
book_ordinal,
time_value,
)
A BookOrder
leaf holds the following data:
type | field | description |
---|---|---|
str | side | Side of order (Bid , Ask ) |
decimal | amount | Amount/size of order |
decimal | price | Price the order has been placed at |
str | trader_address | The order creator's Ethereum address prefixed with the chain discriminant |
str | strategy_id_hash | First 4 bytes of strategy ID hash this order belongs to |
int | book_ordinal | Numerical sequencing identifier for a BookOrder, which can be used to sort orders at any given price level |
int | time_value | Time value of order placement since genesis (s) |
These contents are always stored in the tree in ABI-encoded form: (uint8,(uint8,uint128,uint128,address,bytes32,uint64))
. Meaning, you will want to decode the contents into a more suitable form for your purposes as necessary (for example loading data from a snapshot of the state), and will need to encode it back again if you are saving it back into the tree. A sample of Python code that derives this ABI-encoding, including the grains conversion for certain variables, is shown on the right.
The following sample BookOrder
materials generates the following ABI-encoded value: 00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001158e460913d0000000000000000000000000000000000000000000000000000d8d726b7177a80000603699848c84529987e14ba32c8a66def67e9ece0000000000000000000000002576ebd100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000003e8
field | value |
---|---|
side | "Bid" |
amount | 20 |
price | 250 |
trader_address | "0x603699848c84529987E14Ba32C8a66DEF67E9eCE" |
strategy_id_hash | "0x2576ebd1" |
book_ordinal | 3 |
book_ordinal | 1000 |
Price
A Price
contains information pertaining to a market's price checkpoint.
Key encoding / decoding
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right, encode_single, decode_single
from web3.auto import w3
def pack_bytes(text: str):
charset = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"
symbol_bits = ""
for letter in text:
for i, char in enumerate(charset):
if char == letter:
bits = format(i, "08b")[::-1]
symbol_bits += bits[:5]
symbol_bytes = int(symbol_bits[::-1], 2).to_bytes(
(len(symbol_bits) + 7) // 8, byteorder="little"
)
return zpad_right(symbol_bytes, 6)
def unpack_bytes(packed_text: bytes):
charset = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"
symbol_bits = format(int.from_bytes(packed_text, "little"), "030b")[::-1]
symbol_char_bit_chunks = [
symbol_bits[i : i + 5] for i in range(0, len(symbol_bits), 5)
]
symbol = ""
for symbol_char_bit_chunk in symbol_char_bit_chunks:
reversed_bit_chunk = symbol_char_bit_chunk[::-1]
char_index = int(reversed_bit_chunk, 2)
symbol += charset[char_index]
return symbol
def encode_key(symbol: str, index_price_hash: str):
# ItemType.PRICE == 5
return zpad32_right(
ItemType.PRICE.to_bytes(1, byteorder="little")
+ pack_bytes(symbol)
+ bytes.fromhex(index_price_hash[2:])
)
def decode_key(price_key: bytes):
# symbol, index price hash
return (
unpack_bytes(price_key[1:7]),
f"0x{leaf_key[7:].hex()}",
)
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right, encode_single, decode_single
from web3.auto import w3
def pack_bytes(text: str):
charset = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"
symbol_bits = ""
for letter in text:
for i, char in enumerate(charset):
if char == letter:
bits = format(i, "08b")[::-1]
symbol_bits += bits[:5]
symbol_bytes = int(symbol_bits[::-1], 2).to_bytes(
(len(symbol_bits) + 7) // 8, byteorder="little"
)
return zpad_right(symbol_bytes, 6)
def unpack_bytes(packed_text: bytes):
charset = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"
symbol_bits = format(int.from_bytes(packed_text, "little"), "030b")[::-1]
symbol_char_bit_chunks = [
symbol_bits[i : i + 5] for i in range(0, len(symbol_bits), 5)
]
symbol = ""
for symbol_char_bit_chunk in symbol_char_bit_chunks:
reversed_bit_chunk = symbol_char_bit_chunk[::-1]
char_index = int(reversed_bit_chunk, 2)
symbol += charset[char_index]
return symbol
def encode_key(symbol: str, index_price_hash: str):
# ItemType.PRICE == 5
return zpad32_right(
ItemType.PRICE.to_bytes(1, byteorder="little")
+ pack_bytes(symbol)
+ bytes.fromhex(index_price_hash[2:])
)
def decode_key(price_key: bytes):
# symbol, index price hash
return (
unpack_bytes(price_key[1:7]),
f"0x{leaf_key[7:].hex()}",
)
The location of a Price
leaf is determined by its key, which is encoded as follows:
Bytes | Value |
---|---|
0 | Price discriminant |
[1, 6] | Symbol (5-bit encoded/packed) |
[7, 31] | 25 bytes of index price's unique hash |
The following sample Price
materials generates the following encoded key: 0x0585225824040023c2b28e94b9dfcb8630a369fed134cdb6689dcb2528578779
.
field | value |
---|---|
symbol | "ETHP" |
index_price_hash | "0x23c2b28e94b9dfcb8630a369fed134cdb6689dcb2528578779ABABABABABABAB" |
Value definition
Value encoding / decoding (Python)
from typing import Dict
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_unit_amount(val, decimals):
return Decimal(str(val)) / 10 ** decimals
def abi_encoded_value(self, index_price: Decimal, ema: Decimal, ordinal: int):
# Price item discriminant
item_type = 5
# Scale index price and ema to grains
price_encoding = encode_single(
"(uint8,(uint128,uint256,uint64))",
[
item_type,
[
to_base_unit_amount(index_price, 6),
to_base_unit_amount(abs(ema), 6),
ordinal,
],
],
)
if self.ema < 0:
price_encoding_byte_array = bytearray(price_encoding)
price_encoding_byte_array[-49] = 1
price_encoding = bytes(price_encoding_byte_array)
return price_encoding
def abi_decoded_value(abi_encoded_value: str):
price_encoding_byte_array = bytearray(bytes.fromhex(abi_encoded_value[2:]))
multiplier = -1 if price_encoding_byte_array[-49] == 1 else 1
price_encoding_byte_array[-49] = 0
abi_encoded_value = bytes(price_encoding_byte_array).hex()
(item_type, (index_price, ema, ordinal)) = decode_single(
"(uint8,(uint128,uint256,uint64))", w3.toBytes(hexstr=abi_encoded_value),
)
# Scale index price and ema from grains
return (
to_unit_amount(index_price, 6),
to_unit_amount(ema * multiplier, 6),
ordinal,
)
Value encoding / decoding (Python)
from typing import Dict
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_unit_amount(val, decimals):
return Decimal(str(val)) / 10 ** decimals
def abi_encoded_value(self, index_price: Decimal, ema: Decimal, ordinal: int):
# Price item discriminant
item_type = 5
# Scale index price and ema to grains
price_encoding = encode_single(
"(uint8,(uint128,uint256,uint64))",
[
item_type,
[
to_base_unit_amount(index_price, 6),
to_base_unit_amount(abs(ema), 6),
ordinal,
],
],
)
if self.ema < 0:
price_encoding_byte_array = bytearray(price_encoding)
price_encoding_byte_array[-49] = 1
price_encoding = bytes(price_encoding_byte_array)
return price_encoding
def abi_decoded_value(abi_encoded_value: str):
price_encoding_byte_array = bytearray(bytes.fromhex(abi_encoded_value[2:]))
multiplier = -1 if price_encoding_byte_array[-49] == 1 else 1
price_encoding_byte_array[-49] = 0
abi_encoded_value = bytes(price_encoding_byte_array).hex()
(item_type, (index_price, ema, ordinal)) = decode_single(
"(uint8,(uint128,uint256,uint64))", w3.toBytes(hexstr=abi_encoded_value),
)
# Scale index price and ema from grains
return (
to_unit_amount(index_price, 6),
to_unit_amount(ema * multiplier, 6),
ordinal,
)
A Price
leaf holds the following data:
type | field | description |
---|---|---|
decimal | index_price | Composite index price Petual is tracking |
decimal | ema | EMA component of price, tracking the difference between the DerivaDEX order book price and the underlying |
int | ordinal | Numerical sequencing identifier for PriceCheckpoint that created this Price state leaf, can be used to arrange Price leaves in order of entry |
These contents are always stored in the tree in ABI-encoded form: (uint8,(uint128,uint256,uint64))
. Meaning, you will want to decode the contents into a more suitable form for your purposes as necessary (for example loading data from a snapshot of the state), and will need to encode it back again if you are saving it back into the tree. A sample of Python code that derives this ABI-encoding, including the grains conversion for certain variables, is shown on the right. It's demonstrated in the code sample, but it's worth highlighting that the ema
component, which can be a negative value, is ABI-encoded to a 32-byte value where the first 16 bytes will either be 0x00000000000000000000000000000000
(positive) or 0x00000000000000000000000000000001
(negative), and the next 16 bytes is the absolute value of the ema
.
The following sample Price
materials generates the following ABI-encoded value: 0x00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000ff439f867f838f4000000000000000000000000000000000000000000000000004d94aaad5556854d300000000000000000000000000000000000000000000000000000000000020e2
.
field | value |
---|---|
index_price | 4708.7925 |
ema | 89.444491182582813907 |
ordinal | 8418 |
Insurance Fund
An InsuranceFund
leaf contains information pertaining to the insurance fund' capitalization.
Key encoding / decoding
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right
def encode_key():
# ItemType.INSURANCE_FUND == 6
return zpad32_right(
ItemType.INSURANCE_FUND.to_bytes(1, byteorder="little")
+ "OrganicInsuranceFund".encode("utf8")
)
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right
def encode_key():
# ItemType.INSURANCE_FUND == 6
return zpad32_right(
ItemType.INSURANCE_FUND.to_bytes(1, byteorder="little")
+ "OrganicInsuranceFund".encode("utf8")
)
The location of an InsuranceFund
leaf is determined by its key, which is encoded as follows:
Bytes | Value |
---|---|
0 | Insurance fund discriminant |
[1, 20] | "OrganicInsuranceFund" bytes-encoded |
[21, 31] | Zero-padding |
The InsuranceFund
leaf is located at the encoded key: 0x064f7267616e6963496e737572616e636546756e640000000000000000000000
.
Value definition
Value encoding / decoding (Python)
from typing import Dict
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_unit_amount(val, decimals):
return Decimal(str(val)) / 10 ** decimals
def abi_encoded_value(self, capitalization: Dict[str, Decimal]):
# InsuranceFund item discriminant
item_type = 6
# Scale collateral amounts to grains
return encode_single(
"((uint8,(address[],uint128[])))",
[
[
self.item_type,
[
list(capitalization.keys()),
to_base_unit_amount_list(
list(capitalization.values()), 6
),
],
]
],
)
def abi_decoded_value(abi_encoded_value: str):
(
(item_type, (capitalization_tokens, capitalization_amounts,),),
) = decode_single(
"((uint8,(address[],uint128[])))", w3.toBytes(hexstr=abi_encoded_value),
)
# Scale collateral amounts from grains
return cls(
{
k: to_unit_amount(v, 6)
for k, v in zip(
list(capitalization_tokens), list(capitalization_amounts)
)
},
)
Value encoding / decoding (Python)
from typing import Dict
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_unit_amount(val, decimals):
return Decimal(str(val)) / 10 ** decimals
def abi_encoded_value(self, capitalization: Dict[str, Decimal]):
# InsuranceFund item discriminant
item_type = 6
# Scale collateral amounts to grains
return encode_single(
"((uint8,(address[],uint128[])))",
[
[
self.item_type,
[
list(capitalization.keys()),
to_base_unit_amount_list(
list(capitalization.values()), 6
),
],
]
],
)
def abi_decoded_value(abi_encoded_value: str):
(
(item_type, (capitalization_tokens, capitalization_amounts,),),
) = decode_single(
"((uint8,(address[],uint128[])))", w3.toBytes(hexstr=abi_encoded_value),
)
# Scale collateral amounts from grains
return cls(
{
k: to_unit_amount(v, 6)
for k, v in zip(
list(capitalization_tokens), list(capitalization_amounts)
)
},
)
An InsuranceFund
leaf holds the following data:
type | field | description |
---|---|---|
dict<address_s, decimal> | capitalization | Mapping of collateral address to organic insurance fund capitalization |
These contents are always stored in the tree in ABI-encoded form: ((uint8,(address[],uint128[])))
. Meaning, you will want to decode the contents into a more suitable form for your purposes as necessary (for example loading data from a snapshot of the state), and will need to encode it back again if you are saving it back into the tree. A sample of Python code that derives this ABI-encoding, including the grains conversion for certain variables, is shown on the right.
The following sample InsuranceFund
materials generates the following ABI-encoded value: 0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cfc18cec799fbd1793b5c43e773c98d4d61cc2db000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000532d4737cf8c716f0000
.
field | value |
---|---|
capitalization | {"0xcfc18cec799fbd1793b5c43e773c98d4d61cc2db": 392791.65336} |
Stats
A Stats
leaf contains data such as volume info for trade mining for any given trader.
Key encoding / decoding
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right
def encode_key(trader_address: str):
# ItemType.STATS == 7
return zpad32_right(
ItemType.STATS.to_bytes(1, byteorder="little")
+ bytes.fromhex(trader_address[2:])
)
def decode_key(stats_key: bytes):
# chain_discriminant, trader_address
return f"0x{stats_key[1:22].hex()}"
Key encoding / decoding (Python)
from eth_abi.utils.padding import zpad32_right
def encode_key(trader_address: str):
# ItemType.STATS == 7
return zpad32_right(
ItemType.STATS.to_bytes(1, byteorder="little")
+ bytes.fromhex(trader_address[2:])
)
def decode_key(stats_key: bytes):
# chain_discriminant, trader_address
return f"0x{stats_key[1:22].hex()}"
The location of a Stats
leaf is determined by its key, which is encoded as follows:
Bytes | Value |
---|---|
0 | Stats discriminant |
[1, 21] | Trader' Ethereum address prefixed with the chain discriminant |
[22, 31] | Zero-padding |
The following sample Stats
materials generates the following encoded key: 0x0700603699848c84529987e14ba32c8a66def67e9ece00000000000000000000
.
field | value |
---|---|
trader_address | "0x00603699848c84529987E14Ba32C8a66DEF67E9eCE" |
Value definition
Value encoding / decoding (Python)
from typing import Dict
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_unit_amount(val, decimals):
return Decimal(str(val)) / 10 ** decimals
def abi_encoded_value(self, maker_volume: Decimal, taker_volume: Decimal):
# Stats item discriminant
item_type = 6
# Scale volume amounts to grains
return encode_single(
"(uint8,(uint128,uint128))",
[
item_type,
[
to_base_unit_amount(maker_volume, 6),
to_base_unit_amount(taker_volume, 6),
],
],
)
def abi_decoded_value(abi_encoded_value: str):
(item_type, (maker_volume, taker_volume)) = decode_single(
"(uint8,(uint128,uint128))", w3.toBytes(hexstr=abi_encoded_value),
)
# Scale volumes from DDX grains
return (to_unit_amount(maker_volume, 6), to_unit_amount(taker_volume, 6))
Value encoding / decoding (Python)
from typing import Dict
from ddx_python.decimal import Decimal
from eth_abi import encode_single, decode_single
from web3.auto import w3
def round_to_unit(val):
return val.quantize(6)
def to_base_unit_amount(val, decimals):
return int(round_to_unit(val) * 10 ** decimals)
def to_unit_amount(val, decimals):
return Decimal(str(val)) / 10 ** decimals
def abi_encoded_value(self, maker_volume: Decimal, taker_volume: Decimal):
# Stats item discriminant
item_type = 6
# Scale volume amounts to grains
return encode_single(
"(uint8,(uint128,uint128))",
[
item_type,
[
to_base_unit_amount(maker_volume, 6),
to_base_unit_amount(taker_volume, 6),
],
],
)
def abi_decoded_value(abi_encoded_value: str):
(item_type, (maker_volume, taker_volume)) = decode_single(
"(uint8,(uint128,uint128))", w3.toBytes(hexstr=abi_encoded_value),
)
# Scale volumes from DDX grains
return (to_unit_amount(maker_volume, 6), to_unit_amount(taker_volume, 6))
A Stats
leaf holds the following data:
type | field | description |
---|---|---|
decimal | maker_volume | Maker volume of trader during this trade mining epoch |
decimal | taker_volume | Taker volume of trader during this trade mining epoch |
These contents are always stored in the tree in ABI-encoded form: (uint8,(uint128,uint128))
. Meaning, you will want to decode the contents into a more suitable form for your purposes as necessary (for example loading data from a snapshot of the state), and will need to encode it back again if you are saving it back into the tree. A sample of Python code that derives this ABI-encoding, including the grains conversion for certain variables, is shown on the right.
The following sample Stats
materials generates the following ABI-encoded value: 0x000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000032d26d12e980b60000000000000000000000000000000000000000000000000030fe0cfcba2f4700000
.
field | value |
---|---|
maker_volume | 15000 |
taker_volume | 14460 |
Transactions
Transactions refer to the state-changing events that modify the SMT and its leaves (thus the root hash) described above.
There are several types of transactions on DerivaDEX. The full set of transactions along with their corresponding numeric discrimants can be seen in the table below:
Event | Discriminant |
---|---|
PartialFill | 0 |
CompleteFill | 1 |
PostOrder | 2 |
Cancel | 3 |
CancelAll | 30 |
Liquidation | 4 |
StrategyUpdate | 5 |
TraderUpdate | 6 |
Withdraw | 7 |
WithdrawDDX | 8 |
PriceCheckpoint | 9 |
PnlRealization | 10 |
Funding | 11 |
TradeMining | 12 |
SpecsUpdate | 13 |
InsuranceFundUpdate | 14 |
InsuranceFundWithdraw | 15 |
DisasterRecovery | 16 |
SignerRegistered | 60 |
EpochMarker | 100 |
DrainPrices | 998 |
NoTransition | 999 |
Each of these transaction types as received from the Operator WebSocket API are described at length below.
Partial fill
Sample PartialFill (JSON)
{
"event": [
{
"side": "Ask",
"price": "53008",
"amount": "7.8",
"symbol": "BTCP",
"orderHash": "0xcd69dd0341444be5bc46c0a7e9b305bc4a3a322fae3eedd70e",
"strategyId": "main",
"bookOrdinal": 41,
"traderAddress": "0x00aa6676733e2e259d879127519d973ac71135f797"
},
{},
[
{
"Fill": {
"price": "53163",
"amount": "0.1",
"reason": "Trade",
"symbol": "BTCP",
"takerSide": "Ask",
"makerOutcome": {
"fee": "0",
"trader": "0x000e646446bfd163dc1cb3010754a7e1a5dd73a6de",
"strategy": "main",
"ddxFeeElection": false
},
"takerOutcome": {
"fee": "10.6326",
"trader": "0x00aa6676733e2e259d879127519d973ac71135f797",
"strategy": "main",
"ddxFeeElection": false
},
"makerOrderHash": "0xc7aa4937f79ee9fbc3f8c5f00f46157ac0c0ab6a485227e920",
"takerOrderHash": "0xcd69dd0341444be5bc46c0a7e9b305bc4a3a322fae3eedd70e",
"makerOrderRemainingAmount": "0"
}
}
]
]
}
A PartialFill
transaction is a scenario where the taker order has been partially filled across 1 or more maker orders and thus has a remaining order that enters the order book. The event portion of the transaction response consists of a 3-item array. The first item is the remaining Post
event, the second item is a dictionary of any relevant price updates, and the third item is a list of trade outcomes, which can either be TradeFill
or Cancel
events pertaining to maker orders that may have been canceled.
Complete fill
Sample CompleteFill (JSON)
{
"event": [
{},
[
{
"Fill": {
"price": "53163",
"amount": "0.1",
"reason": "Trade",
"symbol": "BTCP",
"takerSide": "Ask",
"makerOutcome": {
"fee": "0",
"trader": "0x000e646446bfd163dc1cb3010754a7e1a5dd73a6de",
"strategy": "main",
"ddxFeeElection": false
},
"takerOutcome": {
"fee": "10.6326",
"trader": "0x00aa6676733e2e259d879127519d973ac71135f797",
"strategy": "main",
"ddxFeeElection": false
},
"makerOrderHash": "0xc7aa4937f79ee9fbc3f8c5f00f46157ac0c0ab6a485227e920",
"takerOrderHash": "0xcd69dd0341444be5bc46c0a7e9b305bc4a3a322fae3eedd70e",
"makerOrderRemainingAmount": "0"
}
}
]
]
}
A CompleteFill
is a scenario where the taker order has been completely filled across 1 or more maker orders. The event portion of the transaction response consists of a consists of a trade outcomes, which can either be TradeFill
or Cancel
events pertaining to maker orders that may have been canceled.
Post order
Sample PostOrder (JSON)
{
"event": [
{
"side": "Bid",
"price": "1870.25",
"amount": "1.39",
"symbol": "ETHP",
"orderHash": "0x860b1065b629df495de7a0d97432a48b098cadcbb37a1fdbd9",
"strategyId": "main",
"bookOrdinal": 0,
"traderAddress": "0x00e36ea790bc9d7ab70c55260c66d52b1eca985f84",
"timeValue": 1024
},
{},
[]
]
}
A PostOrder
is a 3-item array where the first item is a Post
order that enters the order book, the second item is price checkpoints that may have taken place, and the third item is a list of Cancel
events pertaining to maker orders that may have been canceled.
Cancel
Sample Cancel (JSON)
{
"event": {
"amount": "1.39",
"symbol": "ETHP",
"orderHash": "0x860b1065b629df495de7a0d97432a48b098cadcbb37a1fdbd9"
}
}
A Cancel
is when an existing order is canceled and removed from the order book. The event portion of the transaction has attributes defined as follows:
type | field | description |
---|---|---|
dict | event | The contents of the transaction event |
decimal_s | event.amount | Size of order canceled from the order book |
string | event.symbol | Symbol for the market this order has been canceled (e.g. ETHP ) |
bytes32_s | event.orderHash | Hexstr representation of the first 25 bytes of the unique EIP-712 hash of the order being canceled |
Liquidation
Sample Liquidation (JSON)
{
"event": [
{
"positions": [
[
"ETHP",
{
"price": {
"ema": "-212.602242612626064356",
"ordinal": 157,
"indexPrice": "2718.2459",
"indexPriceHash": "0x16f0d2a4abfd17f788c900a392cf4297439bae04d0f5a13cd1"
},
"amount": "6.1",
"adlOutcomes": [],
"tradeOutcomes": [
{
"Fill": {
"price": "2322",
"amount": "6.1",
"reason": "Liquidation",
"symbol": "ETHP",
"takerSide": "Ask",
"makerOutcome": {
"fee": "0",
"trader": "0x00e834ec434daba538cd1b9fe1582052b880bd7e63",
"strategy": "main",
"realizedPnl": "595.832921348314606732",
"positionSide": "Short",
"newCollateral": "942709.042921348314605958",
"ddxFeeElection": false,
"newPositionBalance": "2.8",
"newPositionAvgEntryPrice": "2419.677528089887640448"
},
"indexPriceHash": "0x16f0d2a4abfd17f788c900a392cf4297439bae04d0f5a13cd1",
"makerOrderHash": "0x63d8e48a6536760deaf29e5f2f2e0039356fc77a437ccc47f7",
"makerOrderRemainingAmount": "4.7"
}
}
],
"newInsuranceFundCap": "734.512240000000000005"
}
]
],
"strategyId": "main",
"traderAddress": "0x00d9a605a32d920d90d8119ffd5fe1fd247c500479",
"canceledOrders": []
}
]
}
A Liquidation
is when a set of strategies are under-collateralized and closed out forcibly closed out:
type | field | description |
---|---|---|
list | event | The contents of the transaction event |
dict | event[n] | Liquidation entry |
address_s | event[n].traderAddress | Liquidated trader'prefixed Ethereum address |
string | event[n].strategyId | Liquidated trader's strategy id |
dict | event[n].strategyId | Liquidated trader's strategy id |
list | event[n].canceledOrders | Cancel events pertaining to canceled orders for the liquidated trader |
list | event[n].positions | List of tuples pertaining to liquidated positions |
string | event[n].positions[n][0] | Liquidated position symbol |
dict | event[n].positions[n][1] | Liquidated position details |
dict | event[n].positions[n][1].price | Latest PriceCheckpoint corresponding to this position being liquidated |
decimal_s | event[n].positions[n][1].amount | Amount of position being liquidated |
list | event[n].positions[n][1].adlOutcomes | ADL outcomes as a result of liquidation |
list | event[n].positions[n][1].tradeOutcomes | Trade outcomes as a result of liquidation |
decimal_s | event[n].positions[n][1].newInsuranceFundCap | New insurance fund capitalization after position has been liquidated |
Strategy update
Sample StrategyUpdate (JSON)
{
"event": {
"amount": "1000000",
"trader": "0x00e36ea790bc9d7ab70c55260c66d52b1eca985f84",
"txHash": "0x239a452c6abc453e153c8c53e4bdb995c558619b3aa1980c8977cbc4c283618f",
"strategyId": "main",
"updateType": "Deposit",
"collateralAddress": "0xb69e673309512a9d726f87304c6984054f87a93b"
}
}
A StrategyUpdate
is an update to a trader's strategy (such as depositing or withdrawing collateral). The event portion of the transaction has attributes defined as follows:
type | field | description |
---|---|---|
dict | event | The contents of the transaction event |
decimal_s | event.amount | Amount deposited or withdrawn |
address_pre_s | event.trader | Trader's Ethereum address prefixed with the chain discriminant |
bytes32_s | event.txHash | Ethereum transaction hash for the on-chain deposit / withdrawal |
string | event.strategyId | Strategy ID deposited to or withdrawn from (e.g. "main") |
string | event.updateType | Action corresponding to either "Deposit" or "Withdraw" |
address_s | event.collateralAddress | Deposited / withdrawn collateral token'Ethereum address |
Trader update
Sample TraderUpdate (JSON)
{
"event": {
"amount": "1000000",
"trader": "0x00e36ea790bc9d7ab70c55260c66d52b1eca985f84",
"txHash": "0x239a452c6abc453e153c8c53e4bdb995c558619b3aa1980c8977cbc4c283618f",
"updateType": "Deposit"
}
}
A TraderUpdate
is an update to a trader'DDX account (such as depositing or withdrawing DDX). The event portion of the transaction has attributes defined as follows:
type | field | description |
---|---|---|
dict | event | The contents of the transaction event |
decimal_s | event.amount | Amount of DDX deposited or withdrawn |
address_pre_s | event.trader | Trader's Ethereum address prefixed with the chain discriminant |
bytes32_s | event.txHash | Ethereum transaction hash for the on-chain deposit / withdrawal |
string | event.updateType | Action corresponding to either "Deposit" or "Withdraw" |
Withdraw
Sample Withdraw (JSON)
{
"event": {
"amount": "1000",
"currency": "0xb69e673309512a9d726f87304c6984054f87a93b",
"strategy": "main",
"signerAddress": "0x6ecbe1db9ef729cbe972c83fb886247691fb6beb",
"traderAddress": "0x006ecbe1db9ef729cbe972c83fb886247691fb6beb"
}
}
A Withdraw
is when a withdrawal of a collateral token is signaled. The event portion of the transaction has attributes defined as follows:
type | field | description |
---|---|---|
dict | event | The contents of the transaction event |
decimal_s | event.amount | Amount of collateral token withdrawal has been signaled for |
address_s | event.currency | Collateral ERC-20 token address |
string | event.strategy | Strategy ID the withdrawal applies to |
address_s | event.signerAddress | Signer'Ethereum address withdrawal is taking place from |
address_pre_s | event.traderAddress | Trader's Ethereum address prefixed with the chain discriminant collateral is being withdrawn to |
Withdraw DDX
Sample WithdrawDDX (JSON)
{
"event": {
"amount": "100",
"signerAddress": "0xa8dda8d7f5310e4a9e24f8eba77e091ac264f872",
"traderAddress": "0x00603699848c84529987e14ba32c8a66def67e9ece"
}
}
A WithdrawDDX
is when a withdrawal of DDX is signaled. The event portion of the transaction has attributes defined as follows:
type | field | description |
---|---|---|
dict | event | The contents of the transaction event |
decimal_s | event.amount | Amount of DDX withdrawal has been signaled for |
address_s | event.signerAddress | Signer'Ethereum address withdrawal is taking place from |
address_pre_s | event.traderAddress | Trader's Ethereum address prefixed with the chain discriminant DDX is being withdrawn to |
Price checkpoint
Sample PriceCheckpoint (JSON)
{
"event": {
"ETHP": {
"ema": "0",
"indexPrice": "1874.075454545454545454",
"indexPriceHash": "0xa35d3dac391cc18671daacab1c393554aac1546a2cbfe630da1e4e86fb44f542"
}
}
}
A PriceCheckpoint
is when a market registers an update to the composite index price a Petual is tracking along with the ema component. The event portion of the transaction essentially emits the latest Price
leaf contents, and is defined as follows:
type | field | description |
---|---|---|
dict | event | The contents of the transaction event |
string | event.symbol | The market name for which this PriceCheckpoint transaction applies |
decimal_s | event.symbol.ema | Captures a smoothed average of the spread between the underlying index price and the DerivaDEX order book for the market |
decimal_s | event.symbol.indexPrice | Composite index price (a weighted average across several price feed sources) |
bytes32_s | event.symbol.indexPriceHash | Index price hash |
PNL Realization
Sample PnlRealization (JSON)
{
"event": {
"settlementEpochId": 19
}
}
A PnlRealization
is when a there is a PNL realization event. This event realizes the PNL of all open positions and adjusts the average entry price to the current mark price. The event portion of the transaction has attributes defined as follows:
type | field | description |
---|---|---|
dict | event | The contents of the transaction event |
int | event.settlementEpochId | The epoch id for the PNL realization event |
Funding
Sample Funding (JSON)
{
"event": [
{
"settlementEpochId": 9
},
[]
]
}
A Funding
is when a there is a funding rate distribution. At this time, all strategies are either credited or debited an amount based on the current funding rate and their position notional values and side. The event portion of the transaction has attributes defined as follows:
type | field | description |
---|---|---|
list | event | The contents of the transaction event |
int_s | event[0].settlementEpochId | The epoch id for the funding event |
list | event[1] | Liquidation events that have taken place as a result of funding distributions |
Trade mining
Sample TradeMining (JSON)
{
"event": {
"totalVolume": {
"makerVolume": "41249.393239489105059823",
"takerVolume": "40101.194995030184814398"
},
"ddxDistributed": "3192.388588391993848193",
"tradeMiningEpochId": 15
}
}
A TradeMining
is when there is a trade mining distribution. Traders will receive a portion of the overall DDX distributed proportional to their volume traded that interval. Makers will receive 20% of the DDX allocation and takers will receive 80% of the allocation. The event portion of the transaction has attributes defined as follows:
type | field | description |
---|---|---|
dict | event | The contents of the transaction event |
dict | event.totalVolume | Holds the total volume information for this trade mining interval |
decimal_s | event.totalVolume.makerVolume | Maker volume total for this trade mining interval |
decimal_s | event.totalVolume.takerVolume | Taker volume total for this trade mining interval. Note that this number may be <= the makerTotalVolume , and any discrepancy is due to liquidations only counting towards maker allocation (i.e. the liquidation engine does not receive any DDX per trade mining) |
decimal_s | event.ddxDistributed | Total DDX distributed for trade mining for this interval |
int | event.tradeMiningEpochId | Interval counter for when trade mining occurred |
Post
Sample Post (JSON)
{
"event": {
"side": "Bid",
"price": "1870.25",
"amount": "1.39",
"symbol": "ETHP",
"orderHash": "0x860b1065b629df495de7a0d97432a48b098cadcbb37a1fdbd9",
"strategyId": "main",
"bookOrdinal": 0,
"traderAddress": "0x00e36ea790bc9d7ab70c55260c66d52b1eca985f84",
"timeValue": 1024
}
}
A Post
is an order that enters the order book. The transaction has attributes defined as follows:
type | field | description |
---|---|---|
dict | event | The contents of the transaction event |
decimal_s | event.amount | Size of order posted to the order book |
bytes32_s | event.orderHash | Hexstr representation of the first 25 bytes of the unique EIP-712 hash of the order being placed |
decimal_s | event.price | Price the order has been placed at |
string | event.side | Side of order (Bid or Ask ) |
string | event.strategyId | Strategy ID this order belongs to (e.g. "main") |
string | event.symbol | Symbol for the market this order has been placed (e.g. ETHP ) |
int | event.bookOrdinal | Numerical value signifying sequence of order placement, which can be used to arrange multiple orders at the same price level to achieve FIFO priority in a local order book |
address_pre_s | event.traderAddress | Trader's Ethereum address prefixed with the chain discriminant |
timeValue | event.timeValue | Time value |
Trade fill
Sample TradeFill (JSON)
{
"event": {
"price": "1860",
"amount": "1.23",
"reason": "Trade",
"symbol": "ETHP",
"takerSide": "Ask",
"makerOutcome": {
"fee": "0",
"trader": "0x006ecbe1db9ef729cbe972c83fb886247691fb6beb",
"strategy": "main",
"ddxFeeElection": false
},
"takerOutcome": {
"fee": "4.5756",
"trader": "0x00e36ea790bc9d7ab70c55260c66d52b1eca985f84",
"strategy": "main",
"newPositionBalance": "2.46"
},
"makerOrderHash": "0x542ad7f2640447d3e93723253099fd45ae721925e0df64702e",
"takerOrderHash": "0x100d1edd45edede9eedc0e3aac28e7df17168fbef9b459ffc8",
"makerOrderRemainingAmount": "2.54"
}
}
A TradeFill
is when there is a fill / match that has taken place. Technically, a TradeFill
is not a transaction in it of itself, but rather a part of CompleteFill
and PartialFill
transactions. We often look to these individual TradeFill
events as their own dedicated transaction type, however, for Traders to subscribe to and follow as they would other transactions. The event portion of the transaction has attributes defined as follows:
type | field | description |
---|---|---|
dict | event | The contents of the transaction event |
decimal | event.price | Price the fill took place |
decimal | event.amount | Size of the fill |
string | event.reason | Reason for fill (Trade , Liquidation ) |
string | event.symbol | Market symbol for which this fill took place |
string | event.takerSide | Taker / aggressor side (Bid , Ask ) |
dict | event.makerOutcome | Data containing the some relevant information pertaining to the maker in the trade |
address_pre_s | event.makerOutcome.traderAddress | Maker trader's Ethereum address prefixed with the chain discrimimant |
string | event.makerOutcome.strategyId | Cross-margined strategy identifier for the maker trader |
decimal_s | event.makerOutcome.fee | Fees paid by the maker as a result of the trade |
bool | event.makerOutcome.ddxFeeElection | Whether maker fees are being paid in DDX (true ) or USDC (false ) |
dict | event.takerOutcome | Data containing the some relevant information pertaining to the taker in the trade |
address_pre_s | event.takerOutcome.traderAddress | Taker trader's Ethereum address prefixed with the chain discrimimant |
string | event.takerOutcome.strategyId | Cross-margined strategy identifier for the taker trader |
decimal_s | event.takerOutcome.fee | Fees paid by the taker as a result of the trade |
bool | event.takerOutcome.ddxFeeElection | Whether taker fees are being paid in DDX (true ) or USDC (false ) |
Types
The types labeled throughout this document in the request and response parameters may be familiar to those who have a background in Ethereum. In any case, please refer to the table below for additional information on the terminology used here. This reference in conjunction with the JSON samples should provide enough clarity:
type | description | example |
---|---|---|
string | Literal of a sequence of characters surrounded by quotes | "ETHP" |
address_s | 20-byte "0x"-prefixed hexadecimal string literal (i.e. 40 digits long) corresponding to an address ETH type |
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" |
address_pre_s | 21-byte "0x"-prefixed hexadecimal string literal (i.e. 42 digits long) corresponding to an address ETH type prefixed with a single byte for the chain discriminant |
"0x00A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" |
decimal | Numerical value with up to, but no more than 18 decimals of precision | 10.031500000000000000 |
decimal_s | String representation of decimal |
"10.031500000000000000" |
bool | Boolean value, either true or false |
True |
bytes_s | "0x"-prefixed hexadecimal string literal corresponding to a bytes ETH type |
"0x00000001" |
bytes32_s | 32-byte "0x"-prefixed hexadecimal string literal (i.e. 64 digits long) corresponding to an bytes32 ETH type |
"0x0000000000000000000000000000000000000000000000000000000000000001" |
timestamp_s_i | String representation of numerical UNIX timestamp representing the number of seconds since 1/1/1970 | "1616667513875" |
timestamp_s | String representation representing the ISO 8601 UTC timestamp | "2021-03-25T10:38:09.503654" |