NAV navbar
ruby solidity python javascript

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",
    "freeDdx": "1000",
    "frozenDdx": "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.
»» freeDdx string true none The amount of DDX that the trader holds.
»» frozenDdx 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,
      "freeCollateral": "10000",
      "frozenCollateral": "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.
»» freeCollateral string true none The amount of collateral that this strategy holds.
»» frozenCollateral 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. 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. 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

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,
    "freeCollateral": "10000",
    "frozenCollateral": "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.
»» freeCollateral string true none The amount of collateral that this strategy holds.
»» frozenCollateral 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 free 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",
    "strategyFreeCollateral": "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.
»» strategyFreeCollateral string true none The amount of 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",
      "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 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.
»» 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. 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. 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",
      "newCollateral": "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.
»» newCollateral string,null true none The updated total 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

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 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 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 Mark 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 Mark Prices 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

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",
      "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 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.
»» 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

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,
      "freeCollateral": "10000",
      "frozenCollateral": "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.
»» freeCollateral string true none The amount of collateral that this strategy holds.
»» frozenCollateral 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. 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. 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",
      "newCollateral": "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.
»» newCollateral string,null true none The updated total 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. 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. 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",
      "freeDdx": "1000",
      "frozenDdx": "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.
»» freeDdx string true none The amount of DDX that the trader holds.
»» frozenDdx 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

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

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

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": {
        "recipientAddress": "0x603699848c84529987E14Ba32C8a66DEF67E9eCE",
        "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,
        recipient_address: str,
        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": {
                "recipientAddress": recipient_address,
                "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
address_s c.recipientAddress Trader's Ethereum address (same as the one that facilitated the deposit)
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:

  1. 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 a keccak256 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.

  2. Generate a 12-byte random nonce

  3. 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

  4. Generate the ciphertext and MAC tag using AES-GCM128

  5. 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:

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,
                "newCollateral": "10",
                "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.
»» newCollateral string,null true The updated total 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,
                "freeCollateral": "9676.755555",
                "frozenCollateral": "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,
                "freeCollateral": "9675.755555",
                "frozenCollateral": "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.
»» freeCollateral string true The amount of collateral that this strategy holds.
»» frozenCollateral 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",
                "freeDdx": "5114.155248",
                "frozenDdx": "0",
                "payFeesInDdx": false
            }
        ],
        "ordinal": 0
    }
}

{
    "feed": "TRADER",
    "params": {
        "trader": "0x0091c987bf62d25945db517bdaa840a6c661374402"
    },
    "contents": {
        "messageType": "update",
        "data": [
            {
                "trader": "0x0091c987bf62d25945db517bdaa840a6c661374402",
                "freeDdx": "5114.155248",
                "frozenDdx": "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.
»» freeDdx string true The amount of DDX that the trader holds.
»» frozenDdx 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):

  1. If you don't already have it, it is recommended you set up Anaconda/Python(>3) on your machine

  2. 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

  3. Set your PYTHONPATH: export PYTHONPATH="${PYTHONPATH}:/your/full/path/upto/but/not/including/ddx_client"

  4. Navigate to the auditor subdirectory and create an .auditor.conf.json file using the template: cp .auditor.conf.json.template .auditor.conf.json

  5. 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 free and frozen 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()}"

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, free_ddx_balance: Decimal, frozen_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(free_ddx_balance, 6),
                to_base_unit_amount(frozen_ddx_balance, 6),
                referral_address,
            ],
        ],
    )

def abi_decoded_value(abi_encoded_value: str):
    (
        item_type,
        (free_ddx_balance, frozen_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(free_ddx_balance, 6),
        to_unit_amount(frozen_ddx_balance, 6),
        referral_address,
    )

A Trader leaf holds the following data:

type field description
decimal free_ddx_balance DDX collateral available for staking/fees
decimal frozen_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
free_ddx_balance 1000
frozen_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 free and frozen 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()}",
        )

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, free_collateral: Dict[str, Decimal], frozen_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(free_collateral.keys()),
                        to_adjusted_encoding_for_negative_val_list(
                            to_base_unit_amount_list(
                                list(free_collateral.values()), 6
                            )
                        ),
                    ],
                    [
                        list(frozen_collateral.keys()),
                        to_base_unit_amount_list(
                            list(frozen_collateral.values()), 6
                        ),
                    ],
                    max_leverage,
                    frozen,
                ],
            ]
        ],
    )

def abi_decoded_value(abi_encoded_value: str):
    (
        (
            item_type,
            (
                strategy_id,
                (free_collateral_tokens, free_collateral_amounts),
                (frozen_collateral_tokens, frozen_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(free_collateral_tokens), list(free_collateral_amounts)
            )
        },
        {
            k: to_unit_amount(v, 6)
            for k, v in zip(
                list(frozen_collateral_tokens), list(frozen_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> free_collateral Mapping of collateral address to free collateral amount
dict<address_s, decimal> frozen_collateral Mapping of collateral address to frozen 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"
free_collateral {"0xb69e673309512a9d726f87304c6984054f87a93b": 199971.08}
frozen_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()}",
        )

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)
    )

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()}",
        )

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,
    )

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()}",
        )

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,
    )

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")
    )

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)
            )
        },
    )

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()}"

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))

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"