Overview
Introduction
This documentation is intended for developers who want to write applications to interact with the Switcheo Exchange programatically.
Switcheo Exchange offers both a fully featured REST API and a WebSocket API. Language bindings are provided in Javascript. Authentications are not made using API keys but are done instead by signing the request payload or transaction using your private key.
You may wish to visit Awesome Switcheo which contains everything awesome about Switcheo.
Information on API wrappers can also be found on Awesome Switcheo.
Sandbox
TestNet URLs (Sandbox)
Type | Base URL |
---|---|
UI | https://beta.switcheo.exchange/ |
API | https://test-api.switcheo.network |
WS | wss://test-ws.switcheo.io |
MainNet URLs (Actual Exchange)
Type | Base URL |
---|---|
UI | https://switcheo.exchange/ |
API | https://api.switcheo.network |
WS | wss://ws.switcheo.io |
REST
Introduction
The REST APIs are feature complete, allowing developers to build their own applications on top of Switcheo Exchange.
All API requests and responses use the JSON format.
There are two types of REST API endpoints available:
Public
These public endpoints include:
- GET Announcements
- GET Candlesticks
- GET Contract Balances
- GET Contracts
- GET Fees
- GET Last 24 Hours
- GET Last Price
- GET Offer Book
- GET Order
- GET Order Book
- GET Orders
- GET Pairs
- GET Recent Trades
- GET Timestamp
- GET Tokens
- GET Trades
Private
All private endpoints must be authenticated.
These private endpoints include:
- POST Create Cancellation
- POST Create Deposit
- POST Create Order
- POST Create Withdrawal
- POST Execute Cancellation
- POST Execute ETH Deposit
- POST Execute NEO Deposit
- POST Execute Order
- POST Execute Withdrawal
The base URLs for the REST API are:
Type | Base URL |
---|---|
Sandbox / TestNet | https://test-api.switcheo.network/ |
Production / MainNet | https://api.switcheo.network |
Rate Limits
All endpoints are rate-limited. We use a dynamic algorithm for determining these limits. The HTTP error code 429
will be returned if this limit is exceeded. You should implement an exponential backoff strategy when encountering this error code.
Exchange Information
This section consists of endpoints that allows retrieval of Switcheo Exchange information.
Authentication is not required for these endpoints.
GET Timestamp
Retrieve the current epoch timestamp in the exchange.
HTTP Request
GET /v2/exchange/timestamp
Example response
{
"timestamp": 1534392760908
}
Notes
This value should be fetched and used when a timestamp parameter is required for API requests.
If the timestamp used for your API request is not within an acceptable range of the exchange's timestamp then an invalid signature error will be returned. The acceptable range might vary, but it should be less than one minute.
GET Contracts
HTTP Request
GET /v2/exchange/contracts
Example response
{
"NEO": {
"V1": "<contract hash NEO 1>",
"V1_5": "<contract hash NEO 1.5>",
"V2": "<contract hash NEO 2>"
},
"ETH": {
"V1": "<contract address ETH V1>"
}
}
Returns the current deployed contract hashes by Switcheo Exchange.
Please note that a different set of contract hashes should be used depending on the network you intend to interact with.
Network | URL |
---|---|
TestNet | Retrieve contract hashes from [TestNet_URL]/v2/exchange/contracts |
MainNet | Retrieve contract hashes from [MainNet_URL]/v2/exchange/contracts |
ETH contract hashes should always include a 0x
prefix, while NEO contract hashes should never
includes a 0x
prefix.
GET Pairs
Retrieve available trading pairs on Switcheo Exchange filtered by the base
parameter. Defaults to all pairs.
HTTP Request
GET /v2/exchange/pairs
Example response without details
// GET /v2/exchange/pairs?bases=["NEO"]&show_details=0
[
"GAS_NEO",
"SWTH_NEO",
...
]
Example response with details
// GET /v2/exchange/pairs?bases=["NEO"]&show_details=1
[
{
"name": "GAS_NEO",
"price_precision": 3
},
{
"name": "SWTH_NEO",
"price_precision": 6,
},
...
]
Request parameters
Parameter | Type | Required | Description |
---|---|---|---|
bases | Array<string> | no | Provides pairs for these base symbols. |
show_details | Boolean | no | Show further details for token. Defaults to 0 |
Response parameters for show_details=0
Parameter | Description |
---|---|
Array | List of token pairings (ticker) <QUOTE>_<BASE> where <QUOTE> is the trading token symbol (e.g. SWTH ), while <BASE> is the base token symbol (e.g. NEO ) |
Response parameters for show_details=1
Parameter | Description |
---|---|
name | The ticker name as <QUOTE>_<BASE> where <QUOTE> is the trading token symbol (e.g. SWTH ), while <BASE> is the base token symbol (e.g. NEO ) |
precision | The maximum price precision that can be submitted (e.g. if precision is 2 , an order on this pair for 1.99 or 1.90000000 price is valid, but 1.999 is not) |
GET Tokens
Retrieve a list of supported tokens on Switcheo.
HTTP Request
GET /v2/exchange/tokens
Example response
// GET /v2/exchange/tokens?show_listing_details=1&show_inactive=1
{
"NEO": {
"hash": "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b",
"decimals": 8,
"precision": 3,
"trading_active": true
"active": true,
"listing_info": {
"deposits": {
"start": 1514764800,
"end": 7983792000,
"paused": false
},
"trading": {
"start": 1514764800,
"end": 7983792000,
"paused": false
},
"cancellations": {
"start": 1514764800,
"end": 7983792000,
"paused": false
},
"withdrawals": {
"start": 1514764800,
"end": 7983792000,
"paused": false
}
}
},
...
"SWC": {
"hash": "0x00bb907302e508707108cd835621dfd2b44ca7cf",
"decimals": 18,
"precision": 1,
"trading_active": true
"active": true,
"listing_info": {
"deposits": {
"start": 1514764800,
"end": 7983792000,
"paused": false
},
"trading": {
"start": 1514764800,
"end": 7983792000,
"paused": false
},
"cancellations": {
"start": 1514764800,
"end": 7983792000,
"paused": false
},
"withdrawals": {
"start": 1514764800,
"end": 7983792000,
"paused": false
}
}
}
...
}
Request parameters
Parameter | Type | Required | Description |
---|---|---|---|
show_listing_details | Boolean | no | Show all details for each token. If false , only hash & decimals are returned, otherwise all parameters below are returned. Defaults to false |
show_inactive | Boolean | no | Show inactive tokens. Default to false ) |
Response parameters
Parameter | Description |
---|---|
hash | Contract hash of the token |
decimals | Number of decimal places to use when submitting order amounts (e.g. if a token has 8 decimals , then an order for 1.2 tokens should be submitted as 120000000 ) |
precision | The maximum amount precision that can be submitted in orders (e.g. if a token has 8 decimals and 2 precision, 123000000 would be a valid order amount to submit, but not 12340000 ) |
minimum_quantity | The minimum order amount for any orders submitted involving this token. Note that this applies to both the order want_amount and offer_amount (or quantity , if using new format). |
trading_active | Whether this token is currently actively trading |
active | Whether this token is currently visible on the Switcheo Exchange UI |
listing_info | Status of the token for trading activities ["deposits", "trading", "cancellations", "withdrawals"] (only returned if show_listing_details is truthy) |
start | Starting time for the activity (in epoch seconds) |
end | Ending time for the activity (in epoch seconds) |
paused | Whether the trading of the token is temporarily paused |
GET Fees
Example response
[
{
"maker": {
"default": 0
},
"taker": {
"default": 0.002
},
"network_fee_subsidy_threshold": {
"neo": 0.1,
"eth": 0.1
},
"max_taker_fee_ratio": {
"neo": 0.005,
"eth": 0.1
},
"native_fee_discount": 0.75,
"native_fee_asset_id": "ab38352559b8b203bde5fddfa0b07d8b2525e132",
"enforce_native_fees": [
"RHT",
"RHTC"
],
"native_fee_exchange_rates": {
"NEO": "952.38095238",
"GAS": "297.14285714",
...
"ETH": "0",
"JRC": "0",
"SWC": "0"
},
"network_fees": {
"eth": "2466000000000000",
"neo": "200000"
},
"network_fees_for_wdl": {
"eth": "873000000000000",
"neo": "0"
}
}
]
Returns fee data for various blockchains and pairs
HTTP Request
GET /v2/fees
Response parameters
Parameter | Description |
---|---|
maker / default | Default trading fee rate for maker orders, before any discount and network fees |
taker / default | Default trading rate for taker orders, before any discount and network fees |
network_fee_subsidy_threshold | The rate used against your trade proceeds at which network fees will be capped at. (E.g. Assuming network_fee_subsidy_threshold is 0.1 and the your total trade proceeds is 0.2 ETH, the payable network fee will not exceed 0.02 ETH.) |
native_fee_discount | Discount applied to fee for use of native token (as a multiplier). Discount Rate is 1 - native_fee_discount |
native_fee_asset_id | NEO contract hash of the Native Token (i.e. SWTH ) |
enforce_native_fee | List of asset tickers where fee must be paid in Native Tokens |
native_fee_exchange_rates | List of token:value tuples, containing the exchange rate in Native Token |
network_fees | Network Trading fee in the smallest denomination of the native network token |
network_fees_for_wdl | Network Withdrawal fee in the smallest denomination of the native network token |
GET Announcements
Retrieve the currently active Switcheo Exchange Announcement
HTTP Request
GET /v2/exchange/announcement_message
Example response
{
"messages": [
{
"message": "<span>Welcome onboard to <a href=\"https://medium.com/switcheo/callisto-is-now-live-de940a62f1a4\" target=\\\"blank\\\">Switcheo</a>, the first decentralized exchange on Ethereum and NEO.</span>",
"message_type": "alert"
},
{
"message": "<span>To access the legacy UI, please visit: <a href=\"https://legacy.switcheo.exchange\" target=\\\"blank\\\">https://legacy.switcheo.exchange/</a></span>",
"message_type": "info"
}
],
"updated_at": "20181203"
}
Response parameters
Parameter | Description |
---|---|
messages | A list of messages |
updated_at | Last updated date in YYYYMMDD format |
Tickers
Ticker endpoints allow retrieval of aggregated market data.
Authentication is not required for these endpoints.
GET Candlesticks
Returns candlestick chart data filtered by url parameters.
HTTP Request
GET /v2/tickers/candlesticks
Example request
{
"pair": "SWTH_NEO",
"interval": 1,
"start_time": 1531213200,
"end_time": 1531220400
}
Example response
[
{
"time": "1531215240",
"open": "0.00049408",
"close": "0.00049238",
"high": "0.000497",
"low": "0.00048919",
"volume": "110169445.0",
"quote_volume": "222900002152.0"
},
{
"time": "1531219800",
"open": "0.00050366",
"close": "0.00049408",
"high": "0.00050366",
"low": "0.00049408",
"volume": "102398958.0",
"quote_volume": "205800003323.0"
},
...
]
Request parameters
Parameter | Type | Required | Description |
---|---|---|---|
pair | string | yes | Only show chart data of this trading pair |
start_time | integer | yes | Start of time range for data in epoch seconds |
end_time | integer | yes | End of time range for data in epoch seconds |
interval | integer | yes | Candlestick period in minutes Possible values are: 1, 5, 30, 60, 360, 1440 |
Response parameters
Parameter | Description |
---|---|
time | Epoch time for the beginning of the interval (in seconds). |
open | Opening price at the start of the interval. |
close | Closing price at the end of the interval. |
high | Highest price during the interval. |
low | Lowest price during the interval. |
volume | Volume in base token traded during the interval. |
quote_volume | Volume in quoted token traded during the interval. |
GET Last 24 Hours
Returns 24-hour data for all pairs and markets.
HTTP Request
GET /v2/tickers/last_24_hours
Example response
[
{
"pair": "SWTH_NEO",
"open": "0.00047221",
"close": "0.00049769",
"high": "1.2",
"low": "0.0004563",
"volume": "11897236125.0",
"quote_volume": "19927606119564.0"
},
{
"pair": "GAS_NEO",
"open": "0.0",
"close": "0.0",
"high": "0.0",
"low": "0.0",
"volume": "0.0",
"quote_volume": "0.0"
}
]
Response parameters
Parameter | Description |
---|---|
time | Epoch time for the beginning of the interval (in seconds). |
open | Opening price at the start of the interval. |
close | Closing price at the end of the interval. |
high | Highest price during the interval. |
low | Lowest price during the interval. |
volume | Volume in base token traded during the interval. |
quote_volume | Volume in quoted token traded during the interval. |
GET Last Price
Returns last price of the requested symbol(s) / base(s). Defaults to all symbols & bases.
HTTP Request
GET v2/tickers/last_price
Example request
{
"symbols": ["SWTH","GAS"]
}
Example response
{
"GAS": {
"NEO": "0.31200000"
},
"SWTH": {
"GAS": "0.00410000",
"NEO": "0.00106600"
}
}
Request parameters
Parameter | Type | Required | Description |
---|---|---|---|
symbols | array | no | Return the price for only these symbols. |
bases | array | no | Return the price for only these bases. |
Response parameters
Parameter | Description |
---|---|
symbol | JSON Object containing a list of base:price tuples |
base | Base token symbol |
price | Price of symbol in base units with 8 decimal precision |
Authentication
As a non-custodian exchange, Switcheo does not use passwords or API keys as we do not have custody of user funds. Instead, authentication is done by signing the request payload or blockchain transaction using the blockchain-specific digital signature with the user's private key.
Overview
Currently, all supported blockchains uses the ellipitic curve digital signature algorithim (ECDSA). However, the curves and hashing algorithim used for each blockchain differs slightly.
Blockchain | Signature Algo | Curve | Hash Function |
---|---|---|---|
NEO | ECDSA | NIST P-256 | SHA-256 |
ETH | ECDSA | secp256k1 | SHA-3 (Keccak) |
In the first step:
- Sign the parameters of the request using the user's private key
- Send both the raw parameters and the result of signing the parameters to the first API endpoint
- A response with either a message or transaction will be returned
In the second step:
- Sign the returned message or transaction with the user's private key
- Send the signed message or transaction to the second API endpoint
Signing Messages for ETH
Signing a message for ETH
const Web3 = require('web3')
const web3 = new Web3()
function signMessage(message, privateKey) {
return web3.eth.accounts.sign(message, privateKey).signature
}
signMessage('Hello', '<private key>')
To sign a message for ETH, the message should be hex encoded, and enveloped as
"\x19Ethereum Signed Message:\n" + message.length + message
before being signed.
web3.js can be used to sign messages for ETH.
Signing Request Parameters
Signing parameters for API requests
// 1. Serialize parameters into a string
// Note that parameters must be ordered alphanumerically
const rawParams = { blockchain: 'neo', timestamp: 1529380859, apple: 'Z', }
const stableStringify = require('json-stable-stringify')
const parameterString = stableStringify(rawParams)
// parameterString: '{"apple":"Z","blockchain":"neo","timestamp":1529380859}'
// 2. Sign the parameterString with the user's privateKey
const signature = signMessage(parameterString, '<private key>')
// 3. Combine the raw parameters with the signature
// to get the final parameters to send
const parametersToSend = { ...rawParams, signature }
To perform an action, request parameters have to be signed to generate a signature parameter. This signature parameter should then be sent together with the other parameters in the request.
- Convert the API parameters into a string, with parameters ordered alphanumerically
- Sign the result of (1) with the user's private key
- Send the result of (2) together with the raw parameters to the API endpoint
Example
Using the following parameters as an example:
{ blockchain: 'eth', timestamp: 1529380859, apple: 'Z' }
- Convert the parameters into a string with parameters ordered alphanumerically:
{"apple":"Z","blockchain":"eth","timestamp":1529380859}
- Let the user's private key be
0x98c193239bff9eb53a83e708b63b9c08d6e47900b775402aca2acc3daad06f24
- Sign the result from (1) with the private key in (2) to get
0xbcff177dba964027085b5653a5732a68677a66c581f9c85a18e1dc23892c72d86c0b65336e8a17637fd1fe1def7fa8cbac43bf9a8b98ad9c1e21d00e304e32911c
Signing Transactions for ETH
Signing a transaction for ETH
// Send the parameters for the first step of an action
// and retrieve the response
const response = ...
const { transaction } = response
// verify the transaction data to ensure that it matches the user's intention
...
const Web3 = require('web3')
const web3 = new Web3()
function signTransaction(transaction, privateKey) {
return web3.eth.accounts.signMessage(transaction.message, user.privateKey)
}
// send the result to the second API endpoint
const signatureToSend = signTransaction(transaction, '<private key>')
The second step of an action usually requires the returned transaction to be signed. This is done by:
- Checking the returned transaction data to ensure it matches the user's intention
- Signing the
message
in the transaction with the user's private key - An exception to this is the deposit endpoint, which requires the client to sign and broadcast the transaction, this is covered in more detail in the Deposits section.
Signing Messages for NEO
Signing a message for NEO
const { wallet } = require('@cityofzion/neon-js')
function signMessage(message, privateKey) {
return wallet.generateSignature(message, privateKey)
}
signMessage('Hello', '<private key>')
neon-js can be used to sign messages for NEO.
Signing Request Parameters
Signing parameters for API requests
// 1. Serialize parameters into a string
// Note that parameters must be ordered alphanumerically
const rawParams = { blockchain: 'neo', timestamp: 1529380859, apple: 'Z', }
const stableStringify = require('json-stable-stringify')
const parameterString = stableStringify(rawParams)
// parameterString: '{"apple":"Z","blockchain":"neo","timestamp":1529380859}'
// 2. Serialize the parameter string into a hex string
const Neon = require('@cityofzion/neon-js')
const parameterHexString = Neon.u.str2hexstring(parameterString)
// 3. Zero pad (parameterHexString.length / 2) into a two digit hex string
const lengthHex = (parameterHexString.length / 2).toString(16).padStart(2, '0')
// lengthHex: 37
// 4. Concat lengthHex and parameterHexString
const concatenatedString = lengthHex + parameterHexString
// 5. Wrap concatenatedString in an empty neo transaction and serialize it
const serializedTransaction = '010001f0' + concatenatedString + '0000'
// 6. Sign serializedTransaction with the user's privateKey
const signature = signMessage(serializedTransaction, '<private key>')
// 7. Combine the raw parameters with the signature
// to get the final parameters to send
const parametersToSend = { ...rawParams, signature }
To perform an action, request parameters have to be signed to generate a signature parameter. This signature parameter should then be sent together with the other parameters in the request.
- Convert the API parameters into a string, with parameters ordered alphanumerically
- Serialize the parameter string into a hex string
- Zero pad the length / 2 of the result from (2) into a two digit hex string
- Concat the result of (3) and (2)
- Wrap the result of (4) in a neo transaction
- Sign the result of (5) with the user's private key
- Send the result of (6) together with the raw parameters to the API endpoint
Example
Using the following parameters as an example:
{ blockchain: 'neo', timestamp: 1529380859, apple: 'Z' }
- Convert the parameters into a string with parameters ordered alphanumerically:
{"apple":"Z","blockchain":"neo","timestamp":1529380859}
- Serialize the parameter into a hex string to get:
7b226170706c65223a225a222c22626c6f636b636861696e223a226e656f222c2274696d657374616d70223a313532393338303835397d
- The length of this string is
110
, divide this by 2 to get55
- Convert
55
to hexadecimal to get37
- Zero pad
37
into a two digit string if needed. In this case37
is already two digits so no padding is needed, but if the value was something like8
then it should be padded to become08
- Form a string by concatenating
37
, and the result of (2) to get:377b226170706c65223a225a222c22626c6f636b636861696e223a226e656f222c2274696d657374616d70223a313532393338303835397d
- Prepend
010001f0
and append0000
to (6) to get:010001f0377b226170706c65223a225a222c22626c6f636b636861696e223a226e656f222c2274696d657374616d70223a313532393338303835397d0000
- Let the user's private key be
cd7b887c29a110e0ce53e81d6dd02805fc7b912718ff8b6659d8da42887342bd
- Sign the result from (7) with the private key in (8) to get
f3831797cbd4244d1ccffafc42739e662e8b06c7a6f98efe5155d0eab1cf5c50fbac6d2a4c4487cbf71498b81e1e9478f06bef02d32da5d8f8bb7fdfc449879a
View a full example implementation
Signing Transactions for NEO
Signing a transaction for NEO
// Send the parameters for the first step of an action
// and retrieve the response
const response = ...
const { transaction } = response
// verify the transaction data to ensure that it matches the user's intention
...
const { tx, wallet } = require('@cityofzion/neon-js')
function signTransaction(transaction, privateKey) {
const serializedTxn = tx.serializeTransaction(transaction, false)
return wallet.generateSignature(serializedTxn, privateKey)
}
// send the result to the second API endpoint
const signatureToSend = signTransaction(transaction, '<private key>')
The second step of an action usually requires the returned transaction to be signed, this is done by:
- Checking the returned transaction data to ensure it matches the user's intention
- Serializing the transaction, this can be done with neon-js (View implementation details)
- Signing the serialized transaction with the user's private key
Offers
An offer represents an open order on the Switcheo Exchange order book.
Funds that are used to make an offer are locked in the contract until the order is cancelled or filled.
GET Order Book
Example request
{
"pair": "SWTH_NEO",
"contract_hash": "eed0d2e14b0027f5f30ade45f2b23dc57dd54ad2"
}
Example response
{
asks: [
{
"price": "0.00046103",
"quantity": "9378.0"
},
{
"price": "0.00046759",
"quantity": "1084.30496802"
}
],
bids: [
{
"price": "0.00045645",
"quantity": "6678.0"
},
{
"price": "0.0004534",
"quantity": "12279.38328187"
},
]
}
Retrieves the order book with formatted price and quantity.
HTTP Request
GET /v2/offers/book
Request Parameters
Parameter | Type | Required | Description |
---|---|---|---|
pair | string | yes | Only return offers from this pair. |
contract_hash | string | no | Only return offers for this contract hash. |
Response parameters
Parameter | Description |
---|---|
price | Bid or Ask price. |
quantity | If bids side, returns amount of tokens being bought. If asks side, returns amount of tokens that is being sold. |
GET Offer Book
Example request - ETH Pair
{
"pair": "JRC_ETH",
"contract_hash": "0x607af5164d95bd293dbe2b994c7d8aef6bec03bf"
}
Example response
[
{
"id": "e4a76e85-53dc-4a25-ab44-4eed504ce0e0",
"address": "0x0fc8f7bab5feb402ed624b5f5fc88a0648a7f3ae",
"available_amount": 2.4043723e+24,
"offer_amount": 1e+25,
"want_amount": 1500000000000000000,
"offer_asset": "JRC",
"want_asset": "ETH"
},
....
]
Retrieves the raw data for 70 best offers (per side) of the offer book.
HTTP Request
GET /v2/offers
Request Parameters
Parameter | Type | Required | Description |
---|---|---|---|
pair | string | yes | Only return offers from this pair. |
contract_hash | string | no | Only return offers for this contract hash. |
Response parameters
Parameter | Description |
---|---|
id | Unique identifier for the offer object. |
address | Address of the offer maker |
available_amount | Remaining amount of the offer_asset that has not been taken by other orders. |
offer_amount | Total amount of the offer_asset . |
want_amount | Total amount of the want_asset . |
offer_asset | Symbol of the token that the offer maker is offering. |
want_asset | Symbol of the token that the offer maker wants . |
Example
Trades
A trade represents a fill of an offer.
This happens when an incoming order matches an offer on the opposite side of the order book in price.
Trades can be seen on the Trade History column on Switcheo Exchange.
GET Trades
Example request
{
"blockchain": "neo",
"pair": "SWTH_NEO",
"limit": 3,
"contract_hash": "<contract hash>"
}
Example response
[
{
"id": "712a5019-3a23-463e-b0e1-80e9f0ad4f91",
"fill_amount": 9122032316,
"take_amount": 20921746,
"event_time": "2018-06-08T11:32:03.219Z",
"is_buy": false
},
{
"id": "5d7e42a2-a8f3-40a9-bce5-7304921ff691",
"fill_amount": 280477933,
"take_amount": 4207169,
"event_time": "2018-06-08T11:31:42.200Z",
"is_buy": false
},
...
]
Retrieves raw trades that occurred on Switcheo Exchange, filtered by the request parameters.
HTTP Request
GET /v2/trades
Request Parameters
Parameter | Type | Required | Description |
---|---|---|---|
contract_hash | string | yes | Only return trades for this contract hash. |
pair | string | yes | Only return trades for this pair. |
from | integer | no | Only return trades after this time in epoch seconds. |
to | integer | no | Only return trades before this time in epoch seconds. |
limit | integer | no | Only return this number of trades (min: 1 , max: 10000 , default: 5000 ). |
Response parameters
Parameter | Description |
---|---|
id | Unique identifier for the trade object. |
fill_amount | Amount of tokens that is given by the trade to the offer that it is filling. |
take_amount | Amount of tokens that the trade takes from the offer's available_amount that it is filling. |
event_time | Datetime that the trade occurs in Zulu Time (UDT+0) |
is_buy | Whether the side of the trade is a buy. |
Example
GET Recent Trades
Returns 20
most recent formatted trades on the selected pair sorted by executed time in descending order (most recent first).
HTTP Request
GET /v2/trades/recent
Request Parameters
Parameter | Type | Required | Description |
---|---|---|---|
pair | string | yes | Only return trades for this pair. |
Response parameters
Example response
[
{
"id": "dc1c8926-dda1-4f39-afae-0872da950340",
"pair": "SWTH_NEO",
"side": "sell",
"price": "0.00046835",
"quantity": "84.0",
"total": "0.0393414",
"timestamp": 1537924944
},
...
]
Parameter | Description |
---|---|
id | Unique identifier for the trade object. |
pair | The pair on which the trade occurred. |
side | Whether the trade was a buy or sell on this pair. Possible values are: buy , sell . If the pair is SWTH_NEO and the side is buy then the trade bought SWTH using NEO . If the side is sell then the trade sold SWTH for NEO . |
price | Buy or sell price to 8 decimal places precision. |
quantity | If buy side, returns amount of tokens that the trade takes from the offer's available_amount that it is filling. If sell side, returns amount of tokens that the trade gives the offer that it is filling |
total | If buy side, returns amount of tokens that the trade gives the offer that it is filling. If sell side, returns amount of tokens that the trade takes from the offer's available_amount that it is filling |
timestamp | Time that trade was broadcasted in epoch seconds |
Deposits
Deposits are a transfer of tokens from your wallet into the Switcheo smart contract.
Overview
Trading on Switcheo Exchange can only be done using funds that have been successfully deposited into the smart contract.
Deposits are not instantaneous. Once a deposit has been executed, funds in your wallet balance would be deducted by the amount of tokens you chose to deposit.
Funds deducted from your wallet balance will be added to your contract balance but put on hold until Switcheo has determined that it has been successfully broadcasted to the blockchain.
Testing with TestNet Faucet
For the convenience of testing API endpoints, tokens can be received through our TestNet faucet. To use the faucet:
- Go to https://legacy.switcheo.exchange/
- Click on the TestNet/MainNet selector at the bottom of the page
- Select TestNet V2
- Click on WALLET LOGIN to login
- Click on the FAUCET button to receive tokens for testing
POST Create Deposit
Create a deposit
function createDeposit ({ blockchain, address, assetID, amount, privateKey }) {
const signableParams = { blockchain, assetID, amount, timestamp: getTimestamp(),
contractHash: CONTRACT_HASH }
const signature = signParams(signableParams, privateKey)
const apiParams = { ...signableParams, address, signature }
return api.post(API_URL + '/deposits', apiParams)
}
// NOTE: in this example, the parameters can be in camel case because
// the `signParams` and `api.post` method automatically convert param keys
// to snake case
createDeposit({
blockchain: 'neo',
address: user.address,
assetID: 'SWTH',
amount: toNeoAssetAmount(7),
privateKey: user.privateKey
})
Example request
{
"blockchain": "neo",
"asset_id": "SWTH",
"amount": "100000000",
"timestamp": 1531543361074,
"contract_hash": "<contract hash>",
"address": "87cf67daa0c1e9b6caa1443cf5555b09cb3f8e5f",
"signature": "<signature>"
}
Example response
{
"id": "ad5a6e05-d992-47c0-9f52-79ca173dccd1",
"transaction": {
"hash": "a53f26b21f2ede25909e8ac3bf094ac3318e31d5cd654bde4ba734478f1368b2",
"sha256": "caa6727a795ef2dba75c7ea143b6020ffc0d2d4164d7be9639ebb9a1bbd7a6d1",
"type": 209,
"version": 1,
"attributes": [
[
null
]
],
"inputs": [
[
null
]
],
"outputs": [
[
null
]
],
"scripts": [],
"script": "0800e1f505000000001432e125258b7db0a0dffde5bd03b2b859253538ab145f8e3fcb095b55f53c44a1cab6e9c1a0da67cf8753c1076465706f73697467d24ad57dc53db2f245de0af3f527004be1d2d0ee",
"gas": 0
},
"script_params": {
"scriptHash": "eed0d2e14b0027f5f30ade45f2b23dc57dd54ad2",
"operation": "deposit",
"args": [
"5f8e3fcb095b55f53c44a1cab6e9c1a0da67cf87",
"32e125258b7db0a0dffde5bd03b2b859253538ab",
100000000
]
}
}
This endpoint creates a deposit which can be executed through Execute Deposit. To be able to make a deposit, sufficient funds are required in the depositing wallet.
HTTP Request
POST /v2/deposits
Request Parameters
Parameter | Type | Required | Description |
---|---|---|---|
blockchain | string | yes | Blockchain that the token to deposit is on. Possible values are: neo . |
asset_id | string | yes | The asset symbol or ID to deposit. |
amount | amount | yes | Amount of tokens to deposit. |
contract_hash | string | yes | Switcheo Exchange contract hash to execute the deposit on. |
timestamp | timestamp | yes | The exchange's timestamp to be used as a nonce. |
signature | string | yes | Signature of the request payload. See Authentication for more details. |
address | address | yes | The depositer's address. Do not include this in the parameters to be signed. |
Example
POST Execute ETH Deposit
Execute a deposit
const Web3 = require('web3')
const provider = new Web3.providers.HttpProvider('https://mainnet.infura.io')
const web3 = new Web3(provider)
function executeDeposit ({ deposit, privateKey }) {
const { rawTransaction } = await web3.eth.accounts.signTransaction(deposit.transaction, privateKey)
const transactionHash = web3.utils.keccak256(rawTransaction)
web3.eth.sendSignedTransaction(rawTransaction)
const url = `${API_URL}/deposits/${deposit.id}/broadcast`
return api.post(url, { transactionHash })
}
Example request
{
"transaction_hash": "<transaction_hash>"
}
This is the second endpoint required to execute a deposit.
After using the Create Deposit endpoint,
you will receive a response which contains a transaction
.
The transaction
in the response should be signed and directly broadcasted by the client,
the transaction hash of the broadcasted transaction should then be sent to the broadcast endpoint.
HTTP Request
POST /v2/deposits/:id/broadcast
Request Parameters
Parameter | Type | Description |
---|---|---|
transaction_hash | string | The transaction hash of the broadcasted transaction |
POST Execute NEO Deposit
Execute a deposit
function executeDeposit ({ deposit, privateKey }) {
const signature = signTransaction(deposit.transaction, privateKey)
const url = `${API_URL}/deposits/${deposit.id}/broadcast`
return api.post(url, { signature })
}
Example request
{
"signature": "<signature>"
}
This is the second endpoint required to execute a deposit. After using the Create Deposit endpoint, you will receive a response which requires additional signing.
The signature should then be attached as the signature
parameter in the request payload.
Note that a sha256
parameter is provided for convenience to be used directly as part of the ECDSA signature process.
In production mode, this should be recalculated for additional security.
HTTP Request
POST /v2/deposits/:id/broadcast
Request Parameters
Parameter | Type | Description |
---|---|---|
signature | string | Signed response from create deposit endpoint. (See how and what to sign for different blockchains above) |
Withdrawals
Withdrawals are a transfer of tokens from the Switcheo smart contract into your wallet.
Overview
Once a withdrawal has been executed, tokens in your contract balance would be deducted. Tokens that are put on hold by orders cannot be withdrawn.
Withdrawals are not instantaneous. Tokens deducted from your contract balance will be added to your wallet balance but put on hold until the withdrawal has been fully executed.
POST Create Withdrawal
Create a withdrawal
function createWithdrawal ({ blockchain, address, assetID, amount, privateKey }) {
const signableParams = { blockchain, assetID, amount,
contractHash: CONTRACT_HASH, timestamp: getTimestamp() }
const signature = signParams(signableParams, privateKey,)
const apiParams = { ...signableParams, address, signature }
return api.post(API_URL + '/withdrawals', apiParams)
}
// NOTE: in this example, the parameters can be in camel case because
// the `signParams` and `api.post` method automatically convert param keys
// to snake case
createWithdrawal({
blockchain: 'neo',
address: user.address,
assetID: 'SWTH',
amount: (toNeoAssetAmount(1)),
privateKey: user.privateKey
})
Example request
{
"blockchain": "neo",
"asset_id": "SWTH",
"amount": "100000000",
"timestamp": 1531544358560,
"contract_hash": "<contract hash>",
"signature": "<signature>",
"address": "87cf67daa0c1e9b6caa1443cf5555b09cb3f8e5f"
}
Example response
{
"id": "e0f56e23-2e11-4848-b749-a147c872cbe6"
}
This endpoint creates a withdrawal which can be executed through Execute Withdrawal. To be able to make a withdrawal, sufficient funds are required in the contract balance.
A signature of the request payload has to be provided for this API call.
HTTP Request
POST /v2/withdrawals
Request Parameters
Parameter | Type | Required | Description |
---|---|---|---|
blockchain | string | yes | Blockchain that the token to withdraw is on. Possible values are: neo . |
asset_id | string | yes | The asset symbol or ID to withdraw. |
amount | amount | yes | Amount of tokens to withdraw. |
timestamp | timestamp | yes | The exchange's timestamp to be used as a nonce. |
contract_hash | string | yes | Switcheo Exchange contract hash to execute the withdraw on. |
signature | string | yes | Signature of the request payload. See Authentication for more details. |
address | address | yes | The withdrawer's address. Do not include this in the parameters to be signed. |
Example
Full create withdrawal example
POST Execute Withdrawal
Executing a withdrawal
function executeWithdrawal ({ withdrawal, privateKey }) {
const signableParams = { id: withdrawal.id, timestamp: getTimestamp() }
const signature = signParams(signableParams, privateKey)
const url = `${API_URL}/withdrawals/${withdrawal.id}/broadcast`
return api.post(url, { ...signableParams, signature })
}
Example request
{
"id": "998f1bdc-f26f-44f2-b204-403e24d5777f",
"timestamp": 1531545149715,
"signature": "<signature>"
}
Example response
{
"event_type": "withdrawal",
"amount": -100000000,
"asset_id": "ab38352559b8b203bde5fddfa0b07d8b2525e132",
"status": "confirming",
"id": "998f1bdc-f26f-44f2-b204-403e24d5777f",
"blockchain": "neo",
"reason_code": 9,
"address": "87cf67daa0c1e9b6caa1443cf5555b09cb3f8e5f",
"transaction_hash": null,
"created_at": "2018-07-14T05:12:29.699Z",
"updated_at": "2018-07-14T05:12:29.765Z",
"contract_hash": "<contract hash>"
}
This is the second endpoint required to execute a withdrawal. After using the Create Withdrawal endpoint, you will receive a response which requires additional signing.
HTTP Request
POST /v2/withdrawals/:id/broadcast
Request Parameters
Parameter | Type | Required | Description |
---|---|---|---|
id | string | yes | id parameter in the response from create withdrawal endpoint. |
timestamp | timestamp | yes | The exchange's timestamp to be used as a nonce. |
signature | string | yes | Signature of the request payload. See Authentication for more details. |
Example
Full execute withdrawal example
Orders
Orders are instructions to trade tokens on Switcheo Exchange.
Overview
limit
, market
and otc
type orders are available. Fill-Or-Cancel, Make-Or-Cancel, etc. strategies are not yet available.
As such, orders will contain a combination of zero or one make and/or zero or more fills.
Once an order is placed, the funds required to fulfill the order is debited from the user's contract balance and locked up until the order is filled or cancelled.
The Order Model
A breakdown of attributes in an order object returned from our API is described below.
Order Object
Example order
[
{
"id": "c415f943-bea8-4dbf-82e3-8460c559d8b7",
"blockchain": "neo",
"contract_hash": "c41d8b0c30252ce7e8b6d95e9ce13fdd68d2a5a8",
"address": "20abeefe84e4059f6681bf96d5dcb5ddeffcc377",
"side": "buy",
"offer_asset_id": "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b",
"want_asset_id": "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7",
"offer_amount": "100000000",
"want_amount": "20000000",
"transfer_amount": "0",
"priority_gas_amount": "0",
"use_native_token": false,
"native_fee_transfer_amount": 0,
"deposit_txn": null,
"created_at": "2018-05-15T10:54:20.054Z",
"status": "processed",
"order_status": "completed",
"fills": [...],
"fill_groups": [...],
"makes": [...]
}
]
Attribute | Description |
---|---|
id | Unique identifier for the order object. |
blockchain | The blockchain that the order exists on. |
contract_hash | Switcheo Exchange contract hash that the order is on. |
address | Wallet Address of the order maker. |
side | Whether the order maker is buying or selling. |
offer_asset_id | Asset ID of the token that the order maker is offering. |
want_asset_id | Asset ID of the token that the order maker wants. |
offer_amount | Total amount of the token that the order maker is offering. |
want_amount | Total amount of the token that the order maker wants. |
transfer_amount | Amount (out of the offer_amount ) that was deposited into the contract in order to create the order. |
priority_gas_amount | Amount of gas paid by the order maker as priority. |
use_native_token | Whether SWTH tokens was used by the order maker to pay taker fees. |
native_fee_transfer_amount | Amount of SWTH that was deposited into the contract in order to pay the taker fees of the order. |
deposit_txn | Transaction that was used for deposits related to the order creation. |
created_at | Time when the order was created. |
status | Status of the order in the context of the blockchain. Possible values are pending (after creation), processed (after broadcast), expired (created but not broadcasted for a long time) |
order_status | Status of the order in the context of the exchange. Possible values are open (on orderbook waiting to be filled),cancelled (cancelled open order), completed (maker order that is entirely filled or broadcasted filler order) |
fills | Refer to the fills section for more details. |
fill groups | Refer to the fills groups section for more details. |
makes | Refer to the makes section for more details. |
Fill Object
Example fill
{
"id": "6531a67c-6b2e-49b6-8a33-20dfb32b5d8e",
"offer_hash": "fcc8ef7fa17cd540b2e0cbbed9e231db9994279b08618208a4dee292370b38b9",
"offer_asset_id": "ab38352559b8b203bde5fddfa0b07d8b2525e132",
"want_asset_id": "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b",
"fill_amount": "100000000",
"want_amount": "1000000",
"filled_amount": "100000000",
"fee_asset_id": "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b",
"fee_amount": "1500",
"price": "0.01",
"txn": [Object],
"status": "success",
"created_at": "2018-06-08T07:23:32.299Z",
"transaction_hash": "c51232abf42935a52d6c27122e5de5f92b33ffc43f9a85c5ee6353009c81f80c"
}
When an order is created, the order matching engine will match the order against existing offers.
If any matching offers are found, then fills
are created.
These fills
represent the filling of the order by the matching offers.
Attribute | Description |
---|---|
id | Unique identifier for the fill object. |
offer_hash | The hash of the corresponding offer for this fill object. |
offer_asset_id | Asset ID of the token that the order maker is offering. |
want_asset_id | Asset ID of the token that the order maker wants. |
fill_amount | Amount of tokens that the target offer wants. |
want_amount | Amount of tokens that is being taken from the target offer. |
filled_amount | Amount of tokens that is given to the target offer. |
fee_asset_id | Asset id of the token used for fees. |
fee_amount | Amount of fees paid for the fill. |
price | The buy or sell price of order. |
txn | The transaction representing this fill. |
status | Status of the fill. Possible values are pending (after order creation), confirming (after order broadcast), success (after broadcast success), expired (after order creation but not broadcasted for a long while) |
created_at | Time when the fill was created. |
transaction_hash | Transaction hash of the transaction representing this fill. |
Fill Group Object
Example fill group
{
"id": "7193c1e3-c9ab-429c-881c-429169880cfc",
"address": "0x0f936dce97a9a5c50becc3f58a4842b4c607e722",
"fill_ids": [
"dd08787b-242c-4eb5-8c53-3e9d2f4be4cd"
],
"txn": [Object],
"fee_amount": "4242000000000000",
"fee_asset_id": "0x0000000000000000000000000000000000000000"
}
Fills are grouped into sets for ETH.
This reduces the number of signature requests needed for an order, instead of signing multiple fills individually, a group of fills can be signed with one signature request.
This feature also minimizes ETH network gas costs.
Attribute | Description |
---|---|
id | Unique identifier for the fill group object. |
address | Address of the filler. |
fill_ids | The IDs grouped under this fill group. |
txn | The transaction representing this fill group. |
fee_amount | Amount of fees paid for this fill group. |
fee_asset_id | Asset id of the token used for the fee. |
Make Object
Example make
{
"id": "dc8a36dd-c405-4999-875a-ce619aecbb5c",
"offer_hash": "3423bd82c6e2ec36ccba7a949d5732905e5c6b179517c8aebd9caf72977d817d",
"available_amount": "1000",
"offer_asset_id": "ab38352559b8b203bde5fddfa0b07d8b2525e132",
"offer_amount": "1234567800",
"want_asset_id": "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b",
"want_amount": "111111102",
"filled_amount": "1234567800",
"txn": [Object],
"cancel_txn": [Object],
"price": "0.09",
"status": "success",
"created_at": "2018-06-08T07:21:19.988Z",
"transaction_hash": "ff6e73805aed42d445ec0e8d47375e024a7d8c99cd5b8c375d607fec61b80567"
}
When an order is created, the order matching engine will match the order against existing offers.
If the order is not fully filled by existing offers, a make
is created.
This make
represents the unfilled amount of the order.
Attribute | Description |
---|---|
id | Unique identifier for the make object. |
offer_hash | The hash of the corresponding offer for this make object. |
available_amount | Remaining amount of the offered tokens in the make that has not been filled by other offers. |
offer_asset_id | Asset ID of the token that the make is offering. |
offer_amount | Amount of tokens that the make is offering. |
want_asset_id | Asset ID of the token that the make wants. |
want_amount | Amount of tokens that the make wants. |
filled_amount | Amount of tokens out of the make's offer_amount that has been taken by other orders. |
txn | The transaction representing this make. |
cancel_txn | If this make was cancelled, this parameter would be the transaction that represents the cancellation. |
price | Buy or sell price of order. |
status | Status of the make. Possible values are pending (after order creation), confirming (after order broadcast), success (after broadcast success), cancelling (after cancellation broadcasted), cancelled (after cancellation broadcast success), expired (after order creation but not broadcasted for a long while) |
created_at | Time when the make was created. |
transaction_hash | Transaction hash of the transaction representing this make. |
GET Order
Example request
{
"order": "995cfc34-8fb8-41e6-bccd-1695086267d1",
}
Example Response
{
"id": "995cfc34-8fb8-41e6-bccd-1695086267d1",
"blockchain": "eth",
"contract_hash": "0xba3ed686cc32ffa8664628b1e96d8022e40543de",
"address": "0x7c819b61b3a35ab718f66508d31e2cf3c25eb624",
"pair": "DAI_ETH",
"side": "buy",
"price": "0.00662",
"quantity": "62000000000000000000",
"use_native_token": false,
"created_at": "2018-11-20T03:43:48.035Z",
"order_status": "cancelled",
"offer_asset_id": "0x0000000000000000000000000000000000000000",
"want_asset_id": "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359",
"offer_amount": "410440000000000000",
"want_amount": "62000000000000000000",
"status": "processed",
"deposit_txn": null,
"transfer_amount": "0",
"priority_gas_amount": "0",
"native_fee_transfer_amount": 0,
"fill_groups": [...],
"fills": [...],
"makes": [...]
}
Retrieves a specific order
HTTP Request
GET /v2/orders/:order_id
Request Parameters
Parameter | Type | Required | Description |
---|---|---|---|
order_id | string | yes | Return order details for a specific order id |
GET Orders
Example request
{
"address": "87cf67daa0c1e9b6caa1443cf5555b09cb3f8e5f",
"contract_hash": "<contract hash>"
}
Example Response
[
{
"id": "c415f943-bea8-4dbf-82e3-8460c559d8b7",
"blockchain": "neo",
"contract_hash": "c41d8b0c30252ce7e8b6d95e9ce13fdd68d2a5a8",
"address": "20abeefe84e4059f6681bf96d5dcb5ddeffcc377",
"side": "buy",
"offer_asset_id": "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b",
"want_asset_id": "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7",
"offer_amount": "100000000",
"want_amount": "20000000",
"transfer_amount": "0",
"priority_gas_amount": "0",
"use_native_token": false,
"native_fee_transfer_amount": 0,
"deposit_txn": null,
"created_at": "2018-05-15T10:54:20.054Z",
"status": "processed",
"order_status": "processed",
"fills": [...],
"makes": [...]
}
]
Retrieves orders from a specific address filtered by the given parameters.
HTTP Request
GET /v2/orders
Request Parameters
Parameter | Type | Required | Description |
---|---|---|---|
address | address | yes | Only return orders made by this address. |
pair | string | no | Only return orders from this pair. |
contract_hash | string | yes | Only return orders from this contract hash. |
from | integer | no | Only return orders that are last updated at or after this time in UNIX timestamp format |
order_status | string | no | Only return orders have this status. Possible values are open , cancelled , completed |
before_id | string | no | Only return orders that are created before the order with this id |
limit | integer | no | Only return up to this number of orders (min: 1 , max: 200 , default: 50 ). |
Example
POST Create Order
This endpoint creates an order which can be executed through Broadcast Order. Orders can only be created after sufficient funds have been deposited into the user's contract balance. A successful order will have zero or one make and/or zero or more fills.
HTTP Request
POST /v2/orders
Request Parameters
For the below descriptions, the order maker
refers to your API user.
Create an order
function createOrder({ pair, blockchain, side, price,
quantity, useNativeTokens, orderType,
privateKey, address }) {
const signableParams = { pair, blockchain, side, price, quantity,
useNativeTokens, orderType, timestamp: getTimestamp(),
contractHash: CONTRACT_HASH }
const signature = signParams(signableParams, privateKey)
const apiParams = { ...signableParams, address, signature }
return api.post(API_URL + '/orders', apiParams)
}
// NOTE: in this example, the parameters can be in camel case because
// the `signParams` and `api.post` method automatically convert param keys
// to snake case
createOrder({
pair: 'SWTH_NEO',
blockchain: 'neo',
address: user.address,
side: 'buy',
price: (0.001).toFixed(8),
quantity: toAssetAmount(1000, 'SWTH'),
useNativeTokens: true,
orderType: 'limit',
privateKey: user.privateKey
})
Example request
{
"pair": "SWTH_NEO",
"blockchain": "neo",
"side": "buy",
"price": "0.00100000",
"quantity": "100000000000",
"use_native_tokens": true,
"order_type": "limit",
"timestamp": 1531541888559,
"contract_hash": "<contract hash>",
"address": "87cf67daa0c1e9b6caa1443cf5555b09cb3f8e5f",
"signature": "<signature>"
}
Example response
{
"id": "cfd3805c-50e1-4786-a81f-a60ffba33434",
"blockchain": "neo",
"contract_hash": "eed0d2e14b0027f5f30ade45f2b23dc57dd54ad2",
"address": "87cf67daa0c1e9b6caa1443cf5555b09cb3f8e5f",
"side": "buy",
"price": "0.00100000",
"quantity": "100000000000",
"offer_asset_id": "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b",
"want_asset_id": "ab38352559b8b203bde5fddfa0b07d8b2525e132",
"offer_amount": "100000000",
"want_amount": "100000000000",
"transfer_amount": "0",
"priority_gas_amount": "0",
"use_native_token": true,
"native_fee_transfer_amount": 0,
"deposit_txn": null,
"created_at": "2018-07-13T07:58:11.340Z",
"status": "pending",
"order_status": "nil",
"fills": [
{
"id": "2eaa3621-0e7e-4b3d-9c8c-454427f20949",
"offer_hash": "bb70a40e8465596bf63dbddf9862a009246e3ca27a4cf5140d70f01bdd107277",
"offer_asset_id": "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b",
"want_asset_id": "ab38352559b8b203bde5fddfa0b07d8b2525e132",
"fill_amount": "1031498",
"want_amount": "2050000000",
"filled_amount": "",
"fee_asset_id": "ab38352559b8b203bde5fddfa0b07d8b2525e132",
"fee_amount": "1537500",
"price": "0.00050317",
"txn": [Object],
"status": "pending",
"created_at": "2018-07-13T07:58:11.353Z",
"transaction_hash": "97ad8c0af68d22304e7f2d09d04f3beed29a845fe57de53444fff1507b752b99"
}
],
"makes": []
}
Parameter | Type | Required | Description |
---|---|---|---|
blockchain | string | yes | Blockchain that the pair is on. Possible values are: neo , eth . |
contract_hash | string | yes | Switcheo Exchange contract hash to execute the order on. |
pair | string | yes | Pair to trade, e.g. SWTH_NEO . |
side | string | yes | Whether to buy or sell on this pair. Possible values are: buy , sell . If the pair is SWTH_NEO and the side is buy then the order is to buy SWTH using NEO . If the side is sell then the order is to sell SWTH for NEO . |
price | string | yes | Buy or sell price rounded to the pair's price precision, found on Get Pairs. Set value to null for market type order. |
quantity | amount | yes | The amount of tokens you wish to trade. |
use_native_tokens | boolean | yes | true if you wish to pay fees in SWTH. Use only false for orders on the Ethereum network. |
order_type | string | yes | Order type, possible values are: limit , market , otc |
otc_address | address | no | Address of the counterparty in OTC trades. Must be provided if and only if order_type is otc . |
timestamp | timestamp | yes | The exchange's timestamp to be used as a nonce. |
signature | string | yes | Signature of the request payload. See Authentication for more details. |
address | address | yes | Address of the order maker. Do not include this in the parameters to be signed. |
Example
POST Execute Order
This is the second endpoint required to execute an order. After using the Create Order endpoint, you will receive a response which needs to be signed.
Format of signatures parameter
{
makes: {
<make_id>: <signature>
},
fills: {
<fill_id_1>: <signature_1>,
<fill_id_2>: <signature_2>
},
fill_groups: {
<fill_group_id_1>: <signature_3>,
<fill_group_id_2>: <signature_4>
}
}
Every txn
of the fills
, fill_groups
and makes
in the Create Order response should be signed,
and structured in the signatures
format shown on the right.
Note that the txn
of fills
for ETH will be empty, only the txn
of the fill_groups
need to be signed for ETH.
HTTP Request
POST /v2/orders/:id/broadcast
Request Parameters
Broadcast an order
function signArray(array, privateKey) {
return array.reduce((map, item) => {
if (item.txn) {
map[item.id] = signTransaction(item.txn, privateKey)
}
return map
}, {})
}
function broadcastOrder({ order, privateKey }) {
const { fills, makes } = order
const signatures = {
fills: signArray(order.fills, privateKey),
makes: signArray(order.makes, privateKey),
fill_groups: signArray(order.fill_groups, privateKey)
}
const url = `${API_URL}/orders/${order.id}/broadcast`
return api.post(url, { signatures })
}
Example request
{
"signatures": {
"fills": {
"c821c814-d4a3-475b-b461-e909d8c8a59a": "<signature_1>"
},
"makes": {
"d034djb1-9sd8-5b6k-1f9g-40fd9jntk86k": "<signature_2>",
"ufdh03kt-23jg-h6k5-45fd-56dfy7ks0g9a": "<signature_3>"
},
"fill_groups": {
"6f9afaeb-1866-47d5-b7d8-061eab1b5fbc": "<signature_4>",
"94a282ed-bf89-40e2-b0ea-7d3a0dac3c68": "<signature_5>"
}
}
}
Parameter | Type | Required | Description |
---|---|---|---|
signatures | hash | yes | See the section description and example for the format. |
Example
POST Create Cancellation
Create a cancellation
function createCancellation({ order, address, privateKey }) {
const signableParams = { orderId: order.id, timestamp: getTimestamp() }
const signature = signParams(signableParams, privateKey)
const apiParams = { ...signableParams, signature, address }
return api.post(API_URL + '/cancellations', apiParams)
}
This is the first API call required to cancel an order.
Only orders with makes and with an available_amount
of more than 0 can be cancelled.
HTTP Request
POST /v2/cancellations
URL Parameters
Example request
{
"order_id": "69c60da5-5832-4705-8390-de4bb4ed62c5",
"timestamp": 1531471743957,
"signature": "<signature>",
"address": "87cf67daa0c1e9b6caa1443cf5555b09cb3f8e5f"
}
Example response
{
"id": "e4cf0472-59e3-4887-b2d3-720b98da0de6",
"transaction": {
"hash": "b4013bdfde6370198f043f2a5fb235242d20280361241d85ee0774c63856f65b",
"sha256": "f760aaa9efe99059af46a2a9640e91527119e78f18322729ab620e20116b3cf8",
"type": 209,
"version": 1,
"attributes": [
[
null
]
],
"inputs": [
[
null
]
],
"outputs": [
[
null
]
],
"scripts": [],
"script": "206e62f9555edc1f791d36f6f081d44b249e8696ab73f41cc809db73316eff6e65349b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc532e125258b7db0a0dffde5bd03b2b859253538ab52c10b63616e63656c4f6666657267d24ad57dc53db2f245de0af3f527004be1d2d0ee",
"gas": 0
},
"script_params": {
"scriptHash": "eed0d2e14b0027f5f30ade45f2b23dc57dd54ad2",
"operation": "cancelOffer",
"args": [
"9b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc532e125258b7db0a0dffde5bd03b2b859253538ab",
"6e62f9555edc1f791d36f6f081d44b249e8696ab73f41cc809db73316eff6e65"
]
}
}
Parameter | Type | Required | Description |
---|---|---|---|
order_id | string | yes | The ID of the order to cancel. |
timestamp | timestamp | yes | The exchange's timestamp to be used as a nonce. |
signature | string | yes | Signature of the request payload. See Authentication for more details. |
address | address | yes | Address of the order maker. Do not include this in the parameters to be signed. |
Example
Full create cancellation example
POST Execute Cancellation
Execute a cancellation
function executeCancellation({ cancellation, privateKey }) {
const signature = signTransaction(cancellation.transaction, privateKey)
const url = `${API_URL}/cancellations/${cancellation.id}/broadcast`
return api.post(url, { signature })
}
This is the second endpoint that must be called to cancel an order. After calling the Create Cancellation endpoint, you will receive a transaction in the response which must be signed.
Note that a sha256
parameter is provided for convenience to be used directly as part of the ECDSA signature process.
In production mode, this should be recalculated for additional security.
Example request
{
"signature": "<signature>"
}
HTTP Request
POST /v2/cancellations/:id/broadcast
URL Parameters
Parameter | Type | Required | Description |
---|---|---|---|
signature | string | yes | Signature of the transaction. See Authentication for more details. |
Example
Full execute cancellation example
Computing Offer Hash (NEO)
Computing the offer_hash
const invoke = {
scriptHash: contractHash,
operation: 'makeOffer',
args: [
u.reverseHex(userHash),
u.reverseHex(offerAssetID), new BigNumber(offerAmount).toNumber(),
u.reverseHex(wantAssetID), new BigNumber(wantAmount).toNumber(),
u.str2hexstring(uuid),
],
}
const offerKeyBytes = invoke.args[0] + invoke.args[1] + invoke.args[3] +
numToHex(invoke.args[2]) + numToHex(invoke.args[4]) + invoke.args[5]
const offerHash = u.reverseHex(u.hash256(offerKeyBytes))
const numToHex = (num) => {
if (typeof num !== 'number') throw new Error('numToHex received a non-number')
if (num < 0) throw Error.new(`numToHex received a negative number (${num})!`)
if (num <= 16) {
return u.num2hexstring(num)
}
return u.num2hexstring(num, 8, true)
}
In the previous sections, you may have noticed that offer_hashes are generated for fills and makes right after creation.
To compute the offer_hash, please take reference from the sample code snippet that is shown on the right.
You can find the u
library from neon-js.
Balances
Description
There are two types of balances.
Balance | Description |
---|---|
Wallet balance | Number of tokens present in your wallet. |
Contract balance | Number of tokens present in the Switcheo smart contract. |
Trading on Switcheo Exchange can only be done using your contract balance.
GET Contract Balances
List contract balances of the given address and contract.
The purpose of this endpoint is to allow convenient querying of a user's balance across multiple blockchains, for example, if you want to retrieve a user's NEO and ethereum balances.
As such, when using this endpoint, balances for the specified addresses and contract hashes will be merged and summed.
HTTP Request
Example request:
{
"addresses": [
"<address 1>"
],
"contract_hashes": [
"<contract hash 1>",
"<contract hash 2>"
]
}
// The URL should be:
// /v2/balances?addresses[]=address_1&contract_hashes[]=contract_hash_1&contract_hashes[]=contract_hash_2
/v2/balances
URL parameters
Parameter | Type | Required | Description |
---|---|---|---|
addresses | array | yes | Only return balances for these addresses |
contract_hashes | array | yes | Only return balances from these contract hashes. |
Example
Example response:
{
"confirming": {
"GAS": [
{
"event_type": "withdrawal",
"asset_id": "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7",
"amount": -100000000,
"transaction_hash": null,
"created_at": "2018-07-12T10:48:48.866Z"
}
]
},
"confirmed": {
"GAS": "47320000000.0",
"SWTH": "421549852102.0",
"NEO": "50269113921.0"
},
"locked": {
"GAS": "500000000.0",
"NEO": "1564605000.0"
}
}
Errors
The Switcheo REST API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- Your request is badly formed. |
401 | Unauthorized -- You did not provide a valid signature. |
404 | Not Found -- The specified endpoint or resource could not be found. |
406 | Not Acceptable -- You requested a format that isn't json. |
422 | Unprocessible Entity -- Your request had validation errors. |
429 | Too Many Requests -- Slow down requests using an exponential backoff strategy. |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |
Websocket
Introduction
Switcheo offers 3 APIs for streaming data:
- a public Offer Book API
- a public Trade Events API
- a private Order Events API
Advantages include:
- receive notifications in real time
- reduce the amount of data you have to transfer over the network
- reduce latency introduced by polling interval
For example, to maintain an order book on your client and react to changes on it, you may be polling the Get Offer Book endpoint every three seconds:
- request
/v2/offers
- bring back HTTP header data and a response body
- parse the JSON in the response body
- compare the latest response against the previous response to see what has changed
Using the public Offer Book API, you can instead subscribe once and receive real time notifications of all offer book changes.
The Switcheo Streaming API uses the Socket.IO protocol. It is recommended to use a Socket.IO client for connecting the API.
For more information on how the Socket.IO protocol works in general, refer to:
Connection Endpoints
Example
const client = io('wss://test-ws.switcheo.io/<namespace>');
The connection endpoints are:
Type | Base URL |
---|---|
Sandbox / TestNet | wss://test-ws.switcheo.io/ |
Production / MainNet | wss://ws.switcheo.io |
Event Types
Below are the event types that may be emitted by WebSocket server. In addition, all standard Socket.IO events are also emitted.
Name | Type | Description |
---|---|---|
all |
Server | Emitted when initially joining a room |
more |
Server | Emitted in response to additional data requested by client |
updates |
Server | Emitted when a new event occurs |
Below are the event types that can be emitted by the client and are processed by the WebSocket server.
Name | Type | Description |
---|---|---|
join |
Client | Emit to join a room (i.e. subscribe to a channel) |
leave |
Client | Emit to leave a room (i.e. unsubscribe from a channel) |
more |
Client | Emit to fetch more data |
Rooms
Example
io.on('connection', function(socket){
socket.join({ ... });
});
After connecting to the Switcheo API, clients need to join the appropriate room in order to send or receive data.
Note that the room to join is always an object. The namespace and room parameters are described in each API section below. To learn more about Room and Namespaces, see the Socket.io docs.
Offer Book
The Offer Book API allows clients to maintain an offer book, with diff-ing support to ensure data integrity.
Socket Connection
Example
const client = io('wss://test-ws.switcheo.io/books');
io.on('connection', function(socket){
socket.join({
contractHash: "91b83e96f2a7c4fdf0c1688441ec61986c7cae26",
pair: "SWTH_NEO"
});
});
To subscribe to the offer book API, connect to the offers
namespace and join the room with the following parameters:
Parameter | Description |
---|---|
contractHash | Contract hash of the exchange |
pair | Pair of the offer book to subscribe |
All Event
Example Event
{
book: {
buys: [ // i.e. bids
{ price: '0.01000000', amount: '100' }, // amount refers to the quote quantity
{ price: '0.09000000', amount: '50' },
...
],
sells: [ // i.e. asks
...
]
}
digest: '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12',
}
Upon joining the appropriate room, you will receieve an all
event on your socket, which will contain the full data of the offer book for the subscribed pair, as well as a SHA-1 digest.
The SHA-1 digest can be used to maintain offer book integrity after future updates are applied.
Response Fields
Parameter | Description |
---|---|
book | The offer book data |
digest | A SHA-1 digest of the stringified JSON book |
Updates Event
Example Event
{
events: [
{ price: '0.01000000', side: 'buy', delta: '-1' },
...
],
digest: '62d7beb325a49df2c323c45fd27e119d524468e0',
}
Example Handling
socket.on('all', ({ events, digest }) => {
events.forEach(event => {
const index = book[event.side].findIndex(o => o.price === event.price)
oldBook[event.side].amount += event.delta
})
const computedDigest = computeDigest(book)
if (computedDigest !== digest) {
throw new Error('offer book desynchronized!') // handle by rejoining room
}
});
Whenever there is a change to the offer book, an updates
event will be emitted, containing the update events and a SHA-1 digest.
Response Fields
Field | Description |
---|---|
events | An array of event s to apply against the existing offer book. |
digest | A SHA-1 digest of the stringified JSON book after events have been applied. |
event
Fields
Field | Description |
---|---|
delta | The difference in quantity, which may be negative. |
price | The offer book price point that is being updated. |
side | The side of the offer book that has changed, either buy or sell . |
If the SHA-1 digest of the offer book does not match after applying updates, the room should be rejoined in order to refetch the full offer book.
The digest should be computed by constructing a sorted JSON string and applying the SHA-1 hash algorithm.
Keys in any JSON object should be sorted alphanumerically. Arrays should be sorted from highest price to lowest price.
Take note that when changing numeric values, and recomputing the offer book digest, amounts should be stringified, and exponentiated when the exponent is less than -6
or more than 19
.
Number to string formatting
Number | String | Info |
---|---|---|
12345678 |
'12345678' |
// e is only 8 |
0.000000123 |
'1.23e-7' |
// e is < -6 |
Trade Events
The Trade Events API allows clients to subscribe and listen to trade events that happen on Switcheo Exchange. There is diff-ing support to ensure that no trade events are missed.
Socket Connection
Example
const client = io('wss://test-ws.switcheo.io/trades');
io.on('connection', function(socket){
socket.join({
contractHash: "91b83e96f2a7c4fdf0c1688441ec61986c7cae26",
pair: "SWTH_NEO"
});
});
To subscribe to the trade events API, connect to the trades
namespace and join the room with the following parameters:
Parameter | Description |
---|---|
contractHash | Contract hash of the exchange |
pair | Pair to listen to trade events for |
All Event
Example Event
{
trades: [
{ price: '0.01000000', side: 'buy', timestamp: '-1', amount: '100' },
...
]
digest: '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12',
}
Upon joining the appropriate room, you will receieve an all
event on your socket, which will contain the last 50 trade events for the subscribed pair, as well as a SHA-1 digest.
The SHA-1 digest can be used to ensure that trade events were not missed.
Response Fields
Field | Description |
---|---|
trades | The trade events |
digest | A SHA-1 digest of the stringified JSON trades |
trade
Fields
Field | Description |
---|---|
amount | The amount of tokens traded (in quote quantity) |
price | The price of the trade |
side | The taker side of the trade, either buy or sell |
timestamp | The trade execution time |
Updates Event
Example Event
{
events: [...],
digest: '62d7beb325a49df2c323c45fd27e119d524468e0',
limit: 50,
}
Whenever there is a new trade event, an updates
event will be emitted.
The digest should be computed by stringifying the last limit
trades of JSON data, and applying the SHA-1 hash algorithm.
The data array should be sorted from the largest to smallest timestamp
. Keys in each object should be sorted alphanumerically.
Take note that to compute the digest, only the last limit
trades should be used. Earlier trades events should be trimmed, before stringifying and hashing the data.
Event Fields
Field | Description |
---|---|
events | An array of event s, in the same format as trade |
digest | A SHA-1 digest of the stringified JSON trades after events have been applied. |
limit | The number of trades to hash in order to compute the SHA-1 digest. If this is less than the number of trades given in the all event and updates event, all trades should be used. |
Order Events
The Order Events API allows clients to subscribe and listen to order events that happen on Switcheo Exchange.
Socket Connection
Example
const client = io('wss://test-ws.switcheo.io/orders');
io.on('connection', function(socket){
socket.join({
contractHash: "91b83e96f2a7c4fdf0c1688441ec61986c7cae26",
pair: "SWTH_NEO",
address: "20abeefe84e4059f6681bf96d5dcb5ddeffcc377"
});
});
To subscribe to the order events API, connect to the orders
namespace and join the room with the following parameters:
Parameter | Description |
---|---|
address | Address to listen to order events for |
contractHash | Contract hash of the exchange |
All Event
Example Event
{
orders: [
{
baseAmount: "6147810",
baseAsset: "NEO",
blockchain: "neo",
fee: "0",
feeAsset: "NEO",
filledAmount: "12345000000",
fills: [
{
amount: "2345000000",
fee: "1758750",
id: "353e8e0e-581c-4207-9cdb-718144d0ce0e",
price: "0.000498",
timestamp: 1541582687
},
...
],
id: "06105c4c-9ed1-43fb-be79-d65c9e40c7fa",
makeFills: [
amount: "12345000000",
fee: "78791",
id: "2e8da960-10f6-439f-9ec2-36f5eeb1f179",
price: "0.00034",
timestamp: 1540528856,
...
],
price: "0.000498",
side: "sell",
status: "completed",
timestamp: 1541582603,
tradeAmount: "12345000000",
tradeAsset: "SWTH",
type: "limit"
},
...
]
}
Clients can emit an all
event to receive the last 50 orders. To receive more orders, emit a more
event.
Request Fields
Field | Type | Required | Description |
---|---|---|---|
address | Array<string> | yes | Addresses to listen to order events for |
contractHash | Array<string> | yes | Contract hashes of the exchange |
pair | string | no | Pair to listen to order events for |
status | string | no | The status of the order, either cancelled , completed , or open |
Response Fields
Field | Description |
---|---|
orders | The order events |
order
Fields
Field | Description |
---|---|
baseAmount | The quoted quantity of base asset |
baseAsset | The base asset |
blockchain | The blockchain, either neo or eth |
fee | The fee incurred |
feeAsset | The fee asset |
filledAmount | The filled amount of the order |
fills | The orders fill ed by this order |
id | The order id |
makeFills | The orders that fill s this order |
price | The quoted price if it's a limit order or null if it's a market order |
side | The side of the order, either buy or sell |
status | The status of the order, either cancelled , completed , or open |
timestamp | The order time |
tradeAmount | The quoted quantity of trade asset |
tradeAsset: | The trade asset |
type | The type of order, either limit or market |
fill
Fields
Field | Description |
---|---|
amount | The filled amount |
fee | The fee incurred by the taker |
id | The fill id |
price | The executed price |
timestamp | The executed time |
More Event
The more event is exactly the same as the all
event with the exception of an additional request parameter, beforeId
.
Request Fields
Field | Type | Required | Description |
---|---|---|---|
address | Array<string> | yes | Addresses to listen to order events for |
contractHash | Array<string> | yes | Contract hashes of the exchange |
pair | string | no | Pair to listen to order events for |
status | string | no | The status of the order, either cancelled , completed , or open |
beforeId | string | no | The id of the last order in the order history |
Updates Event
Example Event
{
events: [...],
}
Whenever there is a new order event, an updates
event will be emitted.
Event Fields
Field | Description |
---|---|
events | An array of event s, in the same format as order |
Troubleshooting
The following steps can be used to troubleshoot potential issues:
Check the Data Types section and ensure your parameters have the correct formatting. Possible issues include the address format, amount format, parameter casing, private key format, wrong parameters included to be signed, wrong timestamp.
Trace each step of signing parameters using the example in Signing Request Parameters, this example has the expected inputs and outputs at each step of generating a signature.
If you have further technical questions, please join our slack channel where you can field your questions to Switcheo developers or the Switcheo dev community.
Data Types
There are some data types and attributes which Switcheo Exchange uses that have specific meanings and formats.
Here is a list of important data types:
Data Type |
---|
Addresses |
Amounts |
Contract Hashes |
Private Keys |
Signature |
Timestamp |
Addresses
An address
in Switcheo is always represented by a hex string, and is prefixed by a 0x
only if it is
an Ethereum address. Addresses should always be in a lowercase hex string representation.
NEO Addresses
Getting the user's address
const { wallet } = require('@cityofzion/neon-js')
wallet.getScriptHashFromPublicKey('031c37f6cce9627dc635d026deddd1200013c1b78dac767cdb507339a831183fd9')
// Result: 87cf67daa0c1e9b6caa1443cf5555b09cb3f8e5f
// you can also retrieve the script hash from a wallet address directly with:
wallet.getScriptHashFromAddress('AQV8FNNi2o7EtMNn4etWBYx1cqBREAifgE')
// Result: 87cf67daa0c1e9b6caa1443cf5555b09cb3f8e5f
For NEO, an address
refers to the RIPEMD160 hash of the the user's ECDSA public key.
An example implemention to derive an address
from a user's public key can be found in the
neon-js javascript library.
Please note the difference in terminology between Switcheo and neon-js. Switcheo's address
is equivalent to neon-js's scriptHash
.
Ethereum Addresses
For Ethereum, an addresses
refers to the Keccak hash of the right-most 160-bits of the user's ECDSA public key, as specified in the Ethereum Yellow Paper.
Ethereum addresses are sometimes displayed with uppercase letters for verification purposes. When submitting addresses through the Switcheo API however, the address should always be fully lowercased.
Amounts
When specifying amounts as request parameters, the amounts should first be converted by following these steps:
- Multiply the original amount by 10 to the power of the precision allowed by the given token.
- Drop any decimals, and convert the resulting integer to a string
For example, if the token's precision is 8
, and the original amount is 9.12345678
:
- Following the above steps:
9.12345678 * (10 ^ 8)
=912345678.00
- Drop any decimals to get:
912345678
- Convert the result to a string to get
"912345678"
The list of supported assets and their corresponding precisions can be found in the Tokens section.
Private Keys
Please check the documentation of the respective blockchains for signing with private keys.
For NEO, there is both a WIF and a private key.
Example WIF:
L479CJz4ZyxHiumy2viAjBFk8nixKeMY45DCQa5p4n4AT6M6WsWq
Example private key:
cd7b887c29a110e0ce53e81d6dd02805fc7b912718ff8b6659d8da42887342bd
The private key should be used for signing, not the WIF.
Contract Hashes
Use Get Contracts to get the correct blockchain smart contract you are referring to. There may be more than one version for a given blockchain, due to upgrades, as smart contracts are immutable. The correct contract hash must be used depending on whether you are using the TestNet or MainNet endpoints.
Signatures
Take note that not all parameters should be included to generate the signature, excluded parameters are specified in their respective endpoint's documentation. See signing request parameters for more information on how to sign each request based on the required blcokchain.
Timestamps
If a timestamp parameter is required, then it should first be fetched from the server using Get Timestamp. If the timestamp is not within an acceptable range of the exchange's timestamp then an invalid signature error will be returned.