Skip to content
Public API for the exchange integration
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.gitignore
README.md

README.md

USDX Wallet Exchange API Specification

USDX Wallet Exchange API allows exchanges to interact with USDX Wallet backend for the following purposes:

  1. Transfer USDX/LHT assets from exchange account to user account.
  2. Receive notifications when user transfers assets from his account to exchange account.
  3. Get transactions history for exchange account.
  4. Get exchange account balance.

Exchange Registration

To register your exchange, please send request to api@usdx.cash, providing information specified below:

  1. Exchange name.
  2. Callback URL. USDX Wallet backend will send notifications about transfer transactions to this URL (see Callback endpoint description).
  3. (Optional). The list of exchange IP addresses. If specified, USDX Wallet backend will accept requests coming only from these whitelisted IP addresses.

After registration you will be able to receive USDX/LHT assets on the provided account from users of USDX Wallet as well as send assets from this account to users via USDX Wallet Exchange API.

As the result of the registration, you will receive the following information:

  1. Exchange ID. Unique identifier of your exchange used by USDX Wallet backend. Should be kept in secret.
  2. API key. Unique key for your exchange used to sign requests. Should be kept in secret.
  3. Account name. Name of your exchange account in USDX Wallet blockchain. Let your exchange users know this account name, so they will be able to send USDX/LHT assets to it (via USDX Wallet mobile application).

General API information

API is implemented as HTTP REST endpoints. Endpoints are described in API Endpoints Reference section. URLs of all endpoints start with ${BASE_URL}, which should be requested from USDX Wallet team.

POST requests should contain body in JSON format, UTF-8 encoded.

All HTTP requests must be signed as specified in Authentication section.

Authentication

All API HTTP requests must contain X-Usdx-Signature header with request signature. The signature is generated using the following steps:

  1. Take body of your prepared HTTP request. Body should be UTF-8 encoded. In case of empty body or GET-request, body is considered as empty string.
  2. Get current timestamp (in milliseconds).
  3. Take apiKey, API key received during registration, see Exchange Registration.
  4. Concatenate body + apiKey + timestamp.
  5. Calculate SHA-256 hash of the resulted string and take hex representation of it.
  6. Set the value of X-Usdx-Signature header in the following format:
X-Usdx-Signature: t=1549022587251, v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

where t value is timestamp used in the calculation, v1 value is SHA-256 hash (v stands for current signature schema, actual version is 1).

Please pay attention that each next API call should have timestamp value larger that the value used in the previous call. In case if it is smaller or equal to timestamp value used in the previous call, request will be rejected.

Example of request signature calculation:

  1. For example, body of HTTP request is the following:
{
    "transferId" : "abcdef0123456789abcdef0123456789",
    "accountName": "someAccountName",
    "amount": 1000.23,
    "currency": "USDX",
    "type": "OUTGOING",
    "createdAt": "2019-01-02T08:02:13",
    "status": "PENDING",
    "memo": "memo text",
    "customData": "1cad7e77a0e56ff536d0c",
}
  1. Current timestamp (in milliseconds) is 1546416133123.
  2. apiKey is a1b2c3d4e5f6g7h8.
  3. Result of body + timestamp + apiKey concatenation:
{
    "transferId" : "abcdef0123456789abcdef0123456789",
    "accountName": "someAccountName",
    "amount": 1000.23,
    "currency": "USDX",
    "type": "OUTGOING",
    "createdAt": "2019-01-02T08:02:13",
    "status": "PENDING",
    "memo": "memo text",
    "customData": "1cad7e77a0e56ff536d0c",
}1546416133123a1b2c3d4e5f6g7h8
  1. Result of SHA-256 hash (hex representation):
9ee36fa6b574f6a6afb6525aa9857d5b083ccb5a5c0cfbc1341c135ee764956a
  1. Value of X-Usdx-Signature header:
X-Usdx-Signature: t=1546416133123, v1=9ee36fa6b574f6a6afb6525aa9857d5b083ccb5a5c0cfbc1341c135ee764956a

API Endpoints Reference

Response structure

Response structure of all endpoints corresponds to JSend format (see specification).

In case of success, the structure of response is the following:

{
    "data": {...},
    "message": null,
    "status": "success"
}
  • data contains JSON object specific for this request;
  • message is null;
  • status is success;

In case of errors caught and handled by server (for example, signature is incorrect, there are not enough assets to transfer etc.), the structure of response is the following:

{
    "data": {
        "errorCode": "INCORRECT_SIGNATURE",
        "failReason": "Signature is incorrect"
    },
    "message": null,
    "status": "fail"
}
  • errorCode contains code of the error;
  • failReason contains error description;
  • message is null;
  • status is fail;

In case of critical errors of the backend itself (for example, internal server error), the structure of response is the following:

{
    "message": "Internal server error",
    "status": "error",
}
  • message contains error description;
  • status is error;

List of error codes

The following is the list of possible errorCode values in case when response status value is fail.

Code Description
SIGNATURE_NOT_SPECIFIED X-Usdx-Signature request header is absent
SIGNATURE_FORMAT_INVALID X-Usdx-Signature request header is specified, but has incorrect format
TIMESTAMP_INVALID Timestamp specified in X-Usdx-Signature request header is invalid (previous API call contained larger value of timestamp)
SIGNATURE_INVALID Signature specified in X-Usdx-Signature request header is invalid
IP_ADDRESS_INVALID IP address the request is coming from is not whitelisted for this exchange (only in case if exchange provided IP addresses white list, see Exchange Registration)
EXCHANGE_ID_INVALID Specified exchangeId parameter doesn't correspond to any registered exchange
USER_ACCOUNT_INVALID User account with specified name doesn't exist
ASSETS_NOT_ENOUGH Attempt to transfer more assets than exchange account has
TRANSACTION_NOT_FOUND Transaction with specified ID was not found

Object reference

Transfer transaction object

Transfer transaction JSON object is used in different API endpoints. It contains all information about the transfer:

{
    "transferId" : "jdk5823kdywi57kar35dkryqr354mvlf",
    "accountName": "someAccountName",
    "amount": 1000.23,
    "currency": "USDX",
    "type": "OUTGOING",
    "createdAt": "2019-01-02T08:02:13",
    "status": "PENDING",
    "memo": "memo text",
    "customData": "1cad7e77a0e56ff536d0c",
}
  • transferId - ID of the transfer transaction, which can be used, for example, to track transaction status;
  • accountName - name of account; if type is OUTGOING, this is the name of user account, which receives assets from the exchange; if type is INCOMING, this is the name of user account, which transfers assets to the exchange account;
  • amount - amount of assets transferred by this transaction;
  • currency - name of assets transferred by this transaction (for the list of possible values, see Asset name)
  • type - type of the transfer transaction (for the list of possible values, see see Transaction type)
  • createdAt - date/time in UTC timezone when transaction was created; format is ISO-8601 YYYY-MM-DDTHH:mm:SS;
  • status - current status of the transaction (for the list of possible values, see see Transaction status)
  • memo (optional) - arbitrary text, description of transfer;
  • customData (optional) - can be present in case if type is OUTGOING only; arbitrary string with any additional information provided by the exchange;

Asset name

There are only two possible values of asset name (currency field):

  1. LHT
  2. USDX

Any another value is considered as incorrect one.

Transaction type

Possible types of transaction are:

  1. INCOMING - transfer transaction from user account to exchange account.
  2. OUTGOING - transfer transaction from exchange account to user account.

Transaction status

Possible values of transaction status are:

  1. PENDING - transaction was created, but not executed yet.
  2. SUCCESS - transaction was successfully executed, assets were transferred to the account.
  3. FAIL - transaction failed for some reason (for example, there are not enough assets on the sender's account).

1. Transfer assets to user account

Transfers USDX/LHT assets from exchange account to user account.

URL: ${BASE_URL}/v1/exchange/:exchangeId/transfer

Method: POST

Headers: Content-Type: application/json

X-Usdx-Signature: ... (see Authentication)

Request body:

{
    "accountName": "user-account-name",
    "amount": 10000.23,
    "currency": "USDX",
    "memo": "memo text",
    "customData": "1cad7e77a0e56ff536d0c",
}
  • accountName - name of user account in USDX Wallet blockchain, who will receive assets;
  • amount - amount of assets to be transferred;
  • currency - name of assets to be transferred see Asset name for the list of possible values;
  • memo (optional) - arbitrary text, description of transfer transaction, which receiver could see in transaction details in USDX Wallet mobile application;
  • customData (optional) - arbitrary string with any additional information, that you can attach to the transaction;

Success response body:

{
    "data": (Transfer transaction object),
    "message": null,
    "status": "success"
}

In case of success, data field contains transfer transaction object (see description) with status = PENDING.

2. Transactions history

Endpoint to retrieve transactions history. Transactions are retrieved starting from the specified transaction ID (exclusive) towards previous (older) transactions.

URL: ${BASE_URL}/v1/exchange/:exchangeId/history?fromId=jdk5823kdywi57kar35dkryqr354mvlf&limit=10

  • :exchangeId - ID of your exchange received as a result of exchange registration see Exchange Registration
  • fromId (optional) - ID of the transaction, transaction history should be retrieved from (exclusive); if not specified, transactions will be retrieved starting from the most recent one
  • limit - maximum amount of transactions in the response (maximum possible value is 100)

Method: GET

Headers: X-Usdx-Signature: ... (see Authentication)

Success response body:

{
    "data": {
        "history": [
            (Transfer transaction object),
            (Transfer transaction object),
            ...
        ]
    },
    "message": null,
    "status": "success"
}

In case of success, history field contains array of transfer transaction objects (see description), ordered by createdAt field descending. To get next transactions (older ones) use this endpoint again passing transferId value of the last transaction as fromId parameter.

3. Exchange account balance

Endpoint to get current assets balance of exchange account.

URL: ${BASE_URL}/v1/exchange/:exchangeId/balance

Method: GET

Headers: X-Usdx-Signature: ... (see Authentication)

Success response body:

{
    "status": "success",
    "data": {
        "USDX":1000.23,
        "LHT": 1234.56789
    },
    "message": null
}

In case of success, USDX and LHT fields contains current balance of USDX and LHT assets on exchange account.

4. Transaction status

Endpoint to get current transaction status by its ID.

URL: ${BASE_URL}/v1/exchange/:exchangeId/transfer/:transferId

  • :exchangeId - ID of your exchange received as a result of exchange registration see Exchange Registration
  • :transferId - ID of the transfer transaction the status should be retrieved for

Method: GET

Headers: X-Usdx-Signature: ... (see Authentication)

Success response body:

{
    "data": (Transfer transaction object),
    "message": null,
    "status": "success"
}

In case of success, data field contains transfer transaction object (see description) with current status.

Callback endpoint

You must implement this endpoint on the exchange backend in order to receive notifications from USDX Wallet API backend in the following cases:

  1. User executes successful transfer from user's account to exchange account.
  2. Status of transaction created by exchange, is changed (from PENDING to SUCCESS or FAIL).

This endpoint must respond with HTTP status 200, no response body is expected. If endpoint doesn't respond at all or response status code is not 200, USDX Wallet API backend will try to call it again after some time.

It is not guaranteed that even in case when endpoint responds with HTTP status 200, it will be called only once for one transaction. It is possible that duplicated calls will be executed, so endpoint should implement logic to handle such situations properly.

Request to this endpoint contains X-Usdx-Signature, created by USDX Wallet API backend according to the same algorithm as used for USDX Wallet API requests (see Authentication). You can check this signature to ensure that the request was really created by USDX Wallet API backend. This check is optional, however it is recommended for security reasons.

URL: can be any; it will be requested by USDX Wallet team during exchange registration process see Exchange Registration.

Method: POST

Headers: X-Usdx-Signature: ... (see Authentication)

Request body:

(Transfer transaction object)

Request body contains transfer transaction object with current transaction status.

Identifiying user transaction

When user wants to transfer his tokens from the wallet to the exchange account, he could just make a transaction from his account to the exchange wallet account. The trickier part is to match transfer from the wallet account 'alice1231' with the exchange account 'alice@example.com'. For networks like BitCoin and Ethereum exchanges generate uniq wallet address for each incomming transaction. In the Graphene/Bitshares network each wallet has only one address, so it's not possible to generate 'alias', 'temporary', 'one-off', etc. addresses. Nevertheless there are several ways to match transaction with the user account, that could be used.

Memo-based match (recommended)

Each time user wants to transfer funds to his excange account you should provide him with the QR code containing following URL:

usdx:exchange-address?amount=100&currency=LHT&memo=11223344&ro=true

Where

  • exchange-address -- transaction destination address, should be your exchange wallet address.
  • currency -- required field, could be LHT or USDX.
  • amount -- optional field, if specified provides exact amount to be send.
  • memo -- arbitrary string (up to 100 bytes) that will be passed along with the transaction. You will receive it in the callback, also you could get it from the transaction history (refer to the API reference). Memo should contain transferId, account id hash, or any other token that could be used later to identify user account.

When user will scan provided QR code with USDX Wallet app he will be presented with "Send" screen with all the provided data filled in, and marked as read-only. For example, if URL

usdx:example-exchange?amount=100&currency=LHT&memo=11223344&ro=true

is provided, then user will see a "Send" screen with prefilled fields for destination account, memo, amount and currency, and will only have an option to submit transaction or completely decline it.

If he will be provided with the URL

usdx:example-exchange?currency=LHT&memo=11223344&ro=true

then destination account and memo will be prefilled, but user could enter arbitrary amount of tokens he would like to send.

Exact amount transfer

If you couldn't use previous approach, alternativelly you could ask user to send exact amount of tokens, so you will be able to identify his transaction. For example, if user wants to transfer 1.0 LHT, you could ask him to transfer 1.00077 LHT (LHT has precision of 5, while USDX has 2), and use 00077 as identifier of the transfer. This method is less convenient and reliable for sure.

One-time transfer

You could bind user wallet account to the exchange account by asking user to make a transfer of some small amount of tokens (like 0.00001 LHT). This transaction should contain uniq amount or memo (as was described earlier), that will be used to match transaction with the user account. When transaction will be matched you could refund sum to the user. Each subsequent transfer from this wallet could be made without any additional authentication.

You can’t perform that action at this time.