NAV
shell javascript go java

Introduction

Hashkey Custody provides a simple and robust RESTful API and client SDK to integrate digital currency wallets with your application. Feel free to check out our NodeJs SDK, Go SDK, Java SDK.We have 2 level API, management API and wallet API.

The management API enables the following:

The wallet API enables the following:

Environments

HashKey Custody has two separate environments available for development and production. For security reasons, all API requests are made using TLS over HTTPS.

Production Environment

The production endpoint is live and used by partners.

Test Environment

The test environment is entirely separate from the production environment and there is no overlap in either data or accounts.

This environment is connected to the TestNet networks of various digital currencies we support. Tokens on these networks can be obtained from faucets and do not represent real money.

Coin / Digital Currency Support

For production environment, please refer the document.

https://XXXXX

For test Environment, please refer the list:

Coin Blockchain Description
ETH Ethereum Sepolia Testnet
USDT Ethereum Sepolia Testnet, ERC20
TRX Tron Tron Testnet
BTC Bitcoin public Testnet

API Authentication

General Structure

This is the general request structure for verifing the request by server.

Parameters

Name Located in Description Required Type
timestamp query/body unix timestamp, seconds Yes string
nonce query/body nonce, random string, not repeated in 10 minutes Yes string
sign query/body hex string, sign parameters with HMACSHA256 Yes string

The parameters timestamp, nonce and sign are located in query for GET requests, but located in the body for POST requests.

if POST request, the body looks like this:

{ "timestamp": 1583376284, "nonce": "15833762841261615239762485", "mode": "auto", "sign":"7042a9fd6deea017be7ad76dfb48e4c36feca279819630c870a628f5352c9044" }

if GET request, the url looks like this:

/api/v1/app/balance/ETH?timestamp=1583374390&nonce=1583374390314165815853245&sign=7c482cf15d9d25772eee2c43bd146c8136472a055b4587b9fb22d02720037875

The signature method is similar to OAuth.

Wallet API

$ git clone https://github.com/HKDAG/hashkey-custody-sdk-go && cd hashkey-custody-sdk-golang
const key = 'TyTLvCnHINbWZQag88hhmMz1'
const secret = 'uf0rPlTluGnIllGqx0X1os4hQ6rOdXDxStiN4qGd79lS6yeHZaOK4ldvRv1TBqr6'
const apiAddr = 'http://127.0.0.1:8092'

const api = new API(key, secret, apiAddr)
app := sdk.NewAppWithAddr(apiAddr, key, secret)
String endpoint = "http://127.0.0.1:8092";
String appKey = "TyTLvCnHINbWZQag88hhmMz1";
String appSecret = "uf0rPlTluGnIllGqx0X1os4hQ6rOdXDxStiN4qGd79lS6yeHZaOK4ldvRv1TBqr6";

APIContext appContext = new APIContext(endpoint, appKey, appSecret);
App appTest = new App(appContext);

The wallet key and secret can be generated in the wallet settings.

For security purpose, it is strongly recommended that you bind an IP address or IP segment to the API Key.

Warning: API Key/Secret is closely related to the security of your account and should not be disclosed to anyone at any time. API Key/Secret disclosure may result in the loss of your assets (even if you do not enable access to withdrawals). Please delete the API Key/Secret as soon as you discover it has been compromised.

Address

get the latest address

$ go run cmd/ctl/main.go "appkey" "appsecret" "GetAddress" "ETH"
code: 0
message: success
data:
{
  "address": "0x9bf65CDF5729b9588F6bAEBb2Aa2926472D4a035",
  "mode": "deposit"
}
    try {
        const result = await api.getAddress("ETH")
        console.log(result)
    } catch(e) {
        // do something
        console.log(e.response)
    }
    result, _ := app.GetAddress("ETH")
  APIResult result = appTest.getAddress("ETH");

Summary: get the latest address, create if not exist

HTTP Request

GET /api/v1/address/{coinName}

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
coinName path coinName Yes string

Response Result

Value Type Description
address string the new address
mode string address mode

create a new address

$ go run cmd/ctl/main.go "appkey" "appsecret" "CreateAddress" "ETH"
code: 0
message: success
data:
{
  "address": "0x9bf65CDF5729b9588F6bAEBb2Aa2926472D4a035",
  "mode": "deposit"
}
    try {
        const result = await api.createAddress("ETH")
        console.log(result)
    } catch(e) {
        // do something
        console.log(e.response)
    }
    result, _ := app.CreateAddress("ETH")
  APIResult result = appTest.createAddress("ETH");

Summary: create a new address

HTTP Request

POST /api/v1/address/{coinName}/new

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
coinName path coinName Yes string
mode body mode No string

Response Result

Value Type Description
address string the new address
mode string address mode

verify a address

$ go run cmd/ctl/main.go "appkey" "appsecret" "VerifyAddress" "ETH" "0x9bf65CDF5729b9588F6bAEBb2Aa2926472D4a035"
code: 0
message: success
data:
{
  "address": "0x9bf65CDF5729b9588F6bAEBb2Aa2926472D4a035",
  "valid": true
}
    try {
        result = await api.verifyAddress("ETH", address) 
        console.log(result)
    } catch(e) {
        // do something
        console.log(e)
    }
    result, _ = app.VerifyAddress("ETH", "0x9bf65CDF5729b9588F6bAEBb2Aa2926472D4a035")
  APIResult result = appTest.verifyAddress("ETH", "0x9bf65CDF5729b9588F6bAEBb2Aa2926472D4a035");

Summary: verify a address

HTTP Request

POST /api/v1/address/{coinName}/verify

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
coinName path coinName Yes string
address body address Yes string

Response Result

Value Type Description
address string the address to validate
valid boolean the address is valid or not

anti-money laundering check

$ go run cmd/ctl/main.go "appkey" "appsecret" "CheckAddress" "ETH" "0x9bf65CDF5729b9588F6bAEBb2Aa2926472D4a035"
code: 0
message: success
data:
{
  "hitRule": false
}
    result, _ = app.CheckAddress("ETH", "0x9bf65CDF5729b9588F6bAEBb2Aa2926472D4a035")

Summary: anti-money laundering check

HTTP Request

POST /api/v1/address/{coinName}/check

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
coinName path coinName Yes string
address body address Yes string

Response Result

Value Type Description
hitRule boolean the address hit the anti-money rule or not

Wallet

get all available assets

$ go run cmd/ctl/main.go "appkey" "appsecret" "GetAllAssets"
code: 0
message: success
data:
{
  "assets": [
    "ETH"
  ]
}
    try {
        result = await api.getAllAssets()
        console.log(result)
    } catch(e) {
        // do something
        console.log(e)
    }
    result, _ = app.GetAllAssets()
  APIResult result = appTest.getAllAssets();

Summary: get all available assets

HTTP Request

GET /api/v1/app/allAssets

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string

Response Result

Value Type Description
assets array the wallet coin list

get wallet balances

$ go run cmd/ctl/main.go "appkey" "appsecret" "GetBalances"
code: 0
message: success
data:
{
  "balances": [
    {
      "balance": "10001.225",
      "money": "98175466.911631525",
      "name": "BTC",
      "price": "9816.344189",
      "outLocked": "11.2",
      "inLocked": "11.2"
    },
    {
      "balance": "1.0",
      "money": "246.565827",
      "name": "ETH",
      "price": "246.565827",
      "outLocked": "11.2",
      "inLocked": "11.2"
    }
  ],
  "total": "98175713.477458525"
}
    try {
        result = await api.getBalances()
        console.log(result)
    } catch(e) {
        // do something
        console.log(e)
    }
    result, _ = app.GetBalances()
  APIResult result = appTest.getBalances();

Summary: get all asset balances, include the amount by USD and the price by USD

HTTP Request

GET /api/v1/app/balances

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string

Response Result

Value Type Description
total string total money(USD)
balances array the wallet balance list

balance:

Value Type Description
balance string the coin balance
money string the amount(USD) equal to the balance
name string the coin name
price string the coin price(USD)
outLocked string the coin transfer out amount under locked
inLocked string the coin transfer in amount under locked

add wallet asset

$ go run cmd/ctl/main.go "appkey" "appsecret" "AddAsset" "BTC"
code: 0
message: success
data:
{}
    try {
        result = await api.addAppAsset("BTC")
        console.log(result)
    } catch(e) {
        // do something
        console.log(e)
    }
    result, _ = app.AddAsset("BTC")
  APIResult result = appTest.addAppAsset("BTC");

Summary: add wallet asset

HTTP Request

POST /api/v1/app/assets

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
coinName body asset name Yes array

Response Result

Value Type Description

get wallet signle asset balance

$ go run cmd/ctl/main.go "appkey" "appsecret" "GetBalance" "ETH"
code: 0
message: success
data:
{
  "balance": "0.450000000000000000",
  "inLocked": "0.000000000000000000",
  "inLockedFee": "0.000000000000000000",
  "outLocked": "0.000000000000000000",
  "outLockedFee": "0.000000000000000000",
  "delegateAmount": "0.000000000000000000",
  "delegateInLocked": "0.000000000000000000",
  "delegateOutLocked": "0.000000000000000000",
  "undelegateAmount": "0.000000000000000000",
  "undelegateInLocked": "0.000000000000000000",
  "undelegateOutLocked": "0.000000000000000000"
}
    try {
        result = await api.getBalance("ETH")
        console.log(result)
    } catch(e) {
        // do something
        console.log(e)
    }
    result, _ = app.GetBalance("ETH")
  APIResult result = appTest.getBalance("ETH");

Summary: get wallet signle asset balance

HTTP Request

GET /api/v1/app/balance/{coinName}

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
coinName path coin type Yes string

Response Result

Value Type Description
balance string the coin balance
inLocked string the coin transfer in amount under locked
inLockedFee string the coin transfer in fee under locked
outLocked string the coin transfer out amount under locked
outLockedFee string the coin transfer out fee under locked
delegateAmount string the coin delegate amount
delegateInLocked string the coin delegate transfer in amount under locked
delegateOutLocked string the coin delegate transfer out amount under locked
undelegateAmount string the undelegate coin amount
undelegateInLocked string the undelegate coin transfer in amount under locked
undelegateOutLocked string the undelegate coin transfer out amount under locked

get wallet assets

$ go run cmd/ctl/main.go "appkey" "appsecret" "GetAssets"
code: 0
message: success
data:
{
  "assets": [
    "ETH"
  ]
}
    try {
        result = await api.getAssets()
        console.log(result)
    } catch(e) {
        // do something
        console.log(e)
    }
    result, _ = app.GetAssets()
  APIResult result = appTest.getAssets();

Summary: get wallet assets

HTTP Request

GET /api/v1/app/assets

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string

Response Result

Value Type Description
assets array the wallet coin list

get wallet assets detail

$ go run cmd/ctl/main.go "appkey" "appsecret" "GetAssets"
code: 0
message: success
data:
{
  "assets": [
    {
      "id": 1,
      "name": "ETH",
      "absFee": "0.005",
      "canDeposit": true,
      "canWithdraw": true,
      "decimal": 18,
      "description": "ETH",
      "feeCoin": "ETH",
      "priorityAverage": {
        "fee": "0.02",
        "priority": "4.0"
      },
      "priorityFast": {
        "fee": "0.025",
        "priority": "5.0"
      },
      "prioritySlow": {
        "fee": "0.01",
        "priority": "2.0"
      },
      "priorityVeryFast": {
        "fee": "0.03",
        "priority": "6.0"
      },
      "priorityVerySlow": {
        "fee": "0.015",
        "priority": "3.0"
      },
      "withdrawMinAmount": "0.0001"
    }
  ]
}

Summary: get wallet assets detail

HTTP Request

GET /api/v1/app/assetsWithID

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string

Response Result

Value Type Description
assets array the wallet coin list

asset:

Value Type Description
id number the asset id
name string the asset name
absFee string withdraw fee
canDeposit boolean whether or not the asset can be deposited
canWithdraw boolean whether or not the asset can be withdrawn
decimal number the asset decimal
description string the asset description
feeCoin string withdraw fee coin
priorityAverage object withdraw fee with average priority
priorityFast object withdraw fee with fast priority
prioritySlow object withdraw fee with slow priority
priorityVeryFast object withdraw fee with very fast priority
priorityVerySlow object withdraw fee with very slow priority
withdrawMinAmount string min withdraw amount

priority:

Value Type Description
fee string fee with the priority
priority string the priority, set into the withdraw request

get wallet attributes

$ go run cmd/ctl/main.go "appkey" "appsecret" "GetAppInfo"
code: 0
message: success
data:
{
  "bizType": "NORMAL",
  "description": "string",
  "id": "L6RayqPn4jXExW0",
  "name": "test",
  "status": "NORMAL"
}
    result, _ = app.GetAppInfo()

Summary: get wallet attributes

HTTP Request

GET /api/v1/app/info

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string

Response Result

Value Type Description
id string the wallet id
name string the wallet name
description string the wallet description
status string the wallet status, NORMAL/ABNORMAL
bizType string the wallet type, NORMAL

get wallet orders

$ go run cmd/ctl/main.go "appkey" "appsecret" "GetOrders" 1 10
code: 0
message: success
data:
{
  "totalAmount": 1,
  "orders": [{
    "bizType": "WITHDRAW",
    "block": 12970670,
    "coinName": "ETH",
    "confirmations": 21,
    "fee": "0.005000000000000000",
    "from": "0xdedc1eca923cc1227c20571030146d8a01b70774",
    "id": "rNXBQGJlw09apVyg4nDo",
    "memo": "",
    "n": 0,
    "state": "DONE",
    "to": "0xF0706B7Cab38EA42538f4D8C279B6F57ad1d4072",
    "txid": "0xcfc4cb925c77c2ea10be3c233029fc1f05d0ddffe7396920ddd493544e52933d",
    "type": "ETH",
    "value": "0.045000000000000000"
  }]
}
    try {
        result = await api.getOrders(1, 10)
        console.log(result)
    } catch(e) {
        // do something
        console.log(e)
    }
    result, _ = app.GetOrders(1, 10)
  APIResult result = appTest.getOrders(1, 10);

Summary: get wallet orders

HTTP Request

GET /api/v1/app/orders

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
page query page, e.g. 1 Yes string
amount query item count on this page, e.g. 10 Yes string
coins query coin list, can be empty string No string
state query order state, can be empty string No string
bizType query order type, TRANSFER_IN/TRANSFER_OUT/WITHDRAW/DEPOSIT No string

Response Result

Value Type Description
orders array order list
totalAmount number the total count of orders

order:

Value Type Description
bizType string order type
block number the block transaction mined in
coinName string unique token name
confirmations number number of transaction confirmations
fee string fee burnt for the transaction
from string transaction input
id string order id
memo string order memo
n number order index
state string order state
to string transaction output
txid string transaction hash
type string token type
value string transaction value
note string order note
message string message to recipient of transfer
createdAt number unix timestamp, seconds
finalizedAt number unix timestamp, seconds
relatedOrderId string related order id

get wallet signle order

$ go run cmd/ctl/main.go "appkey" "appsecret" "GetOrder" "rNXBQGJlw09apVyg4nDo"
code: 0
message: success
data:
{
  "bizType": "WITHDRAW",
  "block": 12970670,
  "coinName": "ETH",
  "confirmations": 21,
  "fee": "0.005000000000000000",
  "from": "0xdedc1eca923cc1227c20571030146d8a01b70774",
  "id": "rNXBQGJlw09apVyg4nDo",
  "memo": "",
  "n": 0,
  "state": "DONE",
  "to": "0xF0706B7Cab38EA42538f4D8C279B6F57ad1d4072",
  "txid": "0xcfc4cb925c77c2ea10be3c233029fc1f05d0ddffe7396920ddd493544e52933d",
  "type": "ETH",
  "value": "0.045000000000000000",
  "note": "note",
  "message": "",
  "createdAt": 1569306519,
  "finalizedAt": 1569306519,
  "relatedOrderId": "orderrNXBQGJlw09apVyg4nDo"
}
    try {
        result = await api.getOrder("rNXBQGJlw09apVyg4nDo")
        console.log(result)
    } catch(e) {
        // do something
        console.log(e)
    }
    result, _ = app.GetOrder("rNXBQGJlw09apVyg4nDo")
  APIResult result = appTest.getOrder("rNXBQGJlw09apVyg4nDo");

Summary: get wallet signle order

HTTP Request

GET /api/v1/app/order/{id}

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
id path order id Yes string

Response Result

Value Type Description
bizType string order type
block number the block transaction mined in
coinName string unique token name
confirmations number number of transaction confirmations
fee string fee burnt for the transaction
from string transaction input
id string order id
memo string order memo
n number order index
state string order state
to string transaction output
txid string transaction hash
type string token type
value string transaction value
note string order note
message string message to recipient of transfer
createdAt number unix timestamp, seconds
finalizedAt number unix timestamp, seconds
relatedOrderId string related order id

update wallet order

$ go run cmd/ctl/main.go "appkey" "appsecret" "UpdateOrder" "rNXBQGJlw09apVyg4nDo" "123"
code: 0
message: success
data:
{}
    result, _ = app.UpdateOrder("rNXBQGJlw09apVyg4nDo", "123")

Summary: update wallet order

HTTP Request

PUT /api/v1/app/order/{id}

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
id path order id Yes string
note body note No string

Response Result

Value Type Description

withdraw

$ go run cmd/ctl/main.go "appkey" "appsecret" "Withdraw" "$(date +%s)" "ETH" "0xF0706B7Cab38EA42538f4D8C279B6F57ad1d4072" "0.05"
code: 0
message: success
data:
{
  "bizType": "WITHDRAW",
  "block": -1,
  "coinName": "ETH",
  "confirmations": 0,
  "fee": "0.0050000000",
  "from": "",
  "id": "Jd7qbDRa1qM1lxK5Qe2M",
  "memo": "",
  "n": 0,
  "state": "INIT",
  "to": "0xF0706B7Cab38EA42538f4D8C279B6F57ad1d4072",
  "txid": "",
  "type": "ETH",
  "value": "0.0450000000"
}
    try {
        let id = ''+new Date().valueOf()
        let coinType = 'ETH'
        let to = '0x56204b988844b20160035273fD98Dbb2A54C85F5'
        let value = '0.01'
        let memo = ''
        result = await api.withdraw(id, coinType, to, value, memo)
        console.log(result)
    } catch(e) {
        // do something
        console.log(e)
    }
    result, _ = app.Withdraw("1569225735", "ETH", "0xF0706B7Cab38EA42538f4D8C279B6F57ad1d4072", "0.05")
  APIResult result = appTest.withdraw(id, "ETH", "0xF0706B7Cab38EA42538f4D8C279B6F57ad1d4072", "0.05");

Summary: withdraw

HTTP Request

POST /api/v1/app/{coinName}/withdraw

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
coinName path coin type Yes string
id body withdraw id Yes string
to body receive address Yes string
value body withdraw amount Yes string
memo body address memo No string
note body note No string
priority body priority No string

Response Result

Value Type Description
bizType string order type
block number the block transaction mined in
coinName string unique token name
confirmations number number of transaction confirmations
fee string fee burnt for the transaction
from string transaction input
id string order id
memo string address memo
n number order index
state string order state
to string transaction output
txid string transaction hash
type string token type
value string transaction value
note string order note

transfer

$ go run cmd/ctl/main.go "appkey" "appsecret" Transfer "e5dJyVp8R3B1m4o" "ETH" "0.01"
code: 0
message: success
data:
{
  "bizType": "TRANSFER_OUT",
  "coinName": "ETH",
  "confirmations": 0,
  "fee": "0",
  "from": "L6RayqPn4jXExW0",
  "id": "orders4eq8kz1235jz2yj0n9rvpwl7",
  "memo": "",
  "message": "",
  "n": 0,
  "note": "",
  "state": "DONE",
  "to": "e5dJyVp8R3B1m4o",
  "txid": "",
  "type": "ETH",
  "value": "0.01"
}
    result, _ = app.Transfer("e5dJyVp8R3B1m4o", "ETH", "0.01")

Summary: transfer

HTTP Request

POST /api/v1/app/{coinName}/transfer

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
coinName path coin type Yes string
to body receive wallet id Yes string
value body transfer amount Yes string
note body transfer note, can be empty string Yes string
message body transfer message, can be empty string Yes string

Response Result

Value Type Description
bizType string order type
block number the block transaction mined in
coinName string unique token name
confirmations number number of transaction confirmations
fee string fee burnt for the transaction
from string transaction input
id string order id
memo string order note
n number order index
state string order state
to string transaction output
txid string transaction hash
type string token type
value string transaction value
note string transfer note
message string transfer message

refund



Summary: refund

HTTP Request

POST /api/v1/app/refund

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
depositOrderId body deposit order id Yes string
id body refund order id Yes string
to body refund address Yes string
memo body address memo No string
note body refund note No string

Response Result

Value Type Description
hashID string refund order hashID
appID number app id
companyID number company id
appkeyID number appkey id
accountID number account id
sourceOrderId number deposit order id
sourceOrderHash string deposit order hash
refundOrderId number refund order id
refundOrderHash string refund order hash
to string refund address
memo string address memo
amount string refund amount
fee string refund fee
status string refund status
opsType string refund type
note string refund note
reason string refund reason

White list

add white address

    result, _ = app.AddWhiteAddress("ETH", "address")

add withdraw/deposite white address

HTTP Request

POST /api/v1/address/whitelist/add

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
coinName body coin type Yes string
address body receive wallet address Yes string

Response Result

Value Type Description
code int the result status
0: success
10006:internal error
10005: bad params
20003: duplicate request
message string transfer message

Market

current price

$ go run cmd/ctl/main.go "appkey" "appsecret" "GetMarket" "BTC"
code: 0
message: success
data:
{
  "price": "10000"
}
  APIResult result = appTest.getMarket("ETH");

Summary: get the asset price by USD

HTTP Request

GET /api/v1/market/{coinName}

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string
coinName path asset name Yes string

Response Result

Value Type Description
price string current price

System

current timestamp

$ go run cmd/ctl/main.go "appkey" "appsecret" "SystemGetTime"
code: 0
message: success
data:
{
  "timestamp": 1590391287
}

Summary: get system current timestamp

HTTP Request

GET /api/v1/system/time

Parameters

Name Located in Description Required Type
X-App-Key header app key Yes string

Response Result

Value Type Description
timestamp number current timestamp

Management API

$ git clone https://github.com/HKDAG/hashkey-custody-sdk-go && cd hashkey-custody-sdk-golang
const teamKey = 'TyTLvCnHINbWZQag88hhmMz1'
const teamSecret = 'uf0rPlTluGnIllGqx0X1os4hQ6rOdXDxStiN4qGd79lS6yeHZaOK4ldvRv1TBqr6'
const apiAddr = 'http://127.0.0.1:8092'

const api = new API(teamKey, teamSecret, apiAddr)
company := sdk.NewCompanyWithAddr(apiAddr, key, secret)
String endpoint = "http://127.0.0.1:8092";
String appKey = "TyTLvCnHINbWZQag88hhmMz1";
String appSecret = "uf0rPlTluGnIllGqx0X1os4hQ6rOdXDxStiN4qGd79lS6yeHZaOK4ldvRv1TBqr6";
APIContext companyContext = new APIContext(endpoint, appKey, appSecret);
Company companyTest = new Company(companyContext);

The management key and secret can be generated in the team settings.

For security purpose, it is strongly recommended that you bind an IP address or IP segment to the API Key.

Warning: API Key/Secret is closely related to the security of your account and should not be disclosed to anyone at any time. Please delete the API Key/Secret as soon as you discover it has been compromised.

Wallet

create

$ go run cmd/ctl/main.go "teamkey" "teamsecret" "CreateWallet" "name" "password" "https://noti.domain/callback"
code: 0
message: success
data:
{
  "id": "ylr07eg5p862mkpw",
  "appKey": "52u036rjmnd5qtwc74vohpj3",
  "appSecret": "4d6718b405cb55e5544ba0b343472acba8a5a1eb0c5777e4040b38f9edd96a60",
  "encryptedAppSecret": "7p128MoVWgSFI7AYAUXO9Px72qCNYSvtM5PCAGD3f6de+HjYJbJBEJcTswMH1qdLcKIriuy1RoP6P0YmNeEDlAfSSyJiHrX98Oid5/fuCEs="
}
    result, _ = company.CreateWallet("name", "password", "https://noti.domain/callback")
  APIResult result = companyTest.createWallet("name", "password", "https://noti.domain/callback", "description");

Summary: create a general wallet

HTTP Request

POST /api/v1/app

Parameters

Name Located in Description Required Type
X-Company-Key header team api key Yes string
name body the wallet name Yes string
password body the wallet password, should encrypted by AES encryption and base64 encoded Yes string
description body the wallet description Yes string
webHook body the url will be called when send a notification Yes string
aesIV body base64 encoded AES encryption iv, must be 16 bytes, used by encrypting app password and secret Yes string

Response Result

Value Type Description
id string wallet id
appKey string the appkey placed in the header of Wallet API
encryptedAppSecret string the base64 encoded AES encrypted appsecret, the appsecret used for the signature of Wallet API

get appkeys

$ go run cmd/ctl/main.go "teamkey" "teamsecret" "GetWalletKeys" "appID"
code: 0
message: success
data:
{
  "keys": [
    {
      "appKey": "nq73yzkovqo44fsek2nq37nw",
      "appSecret": "nn2oh58iuc1sg2adya1golz35cowjbz7r0hfjt2ey6b4fc4xyq6kdopp9tlp0ko3",
      "enable": true,
      "encryptedAppSecret": "+XowuN5bDYKKoDXvci19uoOiYAR+esV762cnBFCd2oX5pfRvOsCsRCyS0eopj9TdziDCm2N8YIBk+/Gj0JGwwKjtXA829ivYdiiVHEe6jvE="
    }
  ]
}
    result, _ = company.GetWalletKeys("appID")
  APIResult result = companyTest.getWalletKeys("appID");

Summary: get appkeys(include appsecret)

HTTP Request

GET /api/v1/app/{appID}/keys

Parameters

Name Located in Description Required Type
X-Company-Key header team api key Yes string
appID path wallet id Yes string
aesIV query base64 encoded AES encryption iv, must be 16 bytes, used by encrypting app secret in the response Yes string

Response Result

Value Type Description
keys array the appkey list

key:

Value Type Description
appKey string the appkey placed in the header of Wallet API
enable boolean enable flag, the appkey will been forbidden if set false
encryptedAppSecret string the base64 encoded AES encrypted appsecret, the appsecret used for the signature of Wallet API

update appkey

$ go run cmd/ctl/main.go "teamkey" "teamsecret" UpdateWalletKey "appKey" true
code: 0
message: success
data:
{}
    result, _ = company.UpdateWalletKey("appKey", true)
  APIResult result = companyTest.updateWalletKey("appKey", true);

Summary: update appkey attributes

HTTP Request

PUT /api/v1/appKey/{appKey}

Parameters

Name Located in Description Required Type
X-Company-Key header team api key Yes string
appKey path wallet appkey Yes string
enable body enable flag, the appkey will been forbidden if set false Yes boolean

Response Result

Value Type Description

Finance

Income and Expenditure

$ go run cmd/ctl/main.go "companykey" "companysecret" "GetFinanceOrders" "1" "10" "https://stg-xpert.hashkeydev.com/saas-api"
code: 0
message: success
data:
{
  "orders": [
    {
      "amount": "0.100000000000000000",
      "fee": "0.000000000000000000",
      "balance": "2.000000000000000000",
      "bizOrderID": "ordersxv3z41mwyglorr0gnl2keop5",
      "bizType": "DEPOSIT",
      "coinName": "USDT",
      "createdAt": 1737014596,
      "exchangeID": "",
      "exchangeName": "",
      "from": "0x53f1F06D87683c7443B316DFD994ff1562313888",
      "fromType": "ADDRESS",
      "id": "finorderkewm30o8568p8l9j79qp12zn",
      "note": "",
      "operator": "",
      "opsType": "ADMIN",
      "subType": "DEPOSIT",
      "to": "0xf128c288b92009CED44D654cDfc111Dc5248cBEE",
      "toType": "ADDRESS",
      "txid": "0x3610d05727fa0ff997653e54c69df8c3065b15dd9744130b9887151d58f29507",
      "updatedAt": 1737014709,
      "walletID": "walletylr07eg5r4j2mkpw",
      "walletName": "wallet2"
    }
  ],
  "total": 1
}
    result, _ = company.GetFinanceOrders(map[string]interface{}{
        "page":1,
    "pageSize":10
    })

HTTP Request

GET /api/v1/finance/orders

Download Excel file: GET /api/v1/finance/orders/download

Params

Name Located in Description Required Type
X-Company-Key header company key Yes string
wallets query wallet id list, multiple values separated by commas No string
bizTypes query Type:
DEPOSIT
WITHDRAW
BATCH_WITHDRAW
BATCH_TRANSFER
WALLET_TRANSFER
No string
subType query Subtype:
IN
OUT
No string
coins query token list (multiple values separated by commas) No string
start query Start timestamp (seconds) Yes number
end query End timestamp (seconds) Yes number
page query Page (starting value is 1) No number
pageSize query Page size No number

Response Result

{
  "code": 0,
  "data": {
    "orders": [
      {
        "amount": "0.106000000000000000",
        "fee": "0.000000000000000000",
        "balance": "10.430999300000000000",
        "bizOrderID": "ordersmq41ndkz1232323232r",
        "bizType": "WITHDRAW",
        "coinName": "BTC",
        "createdAt": 1733971691,
        "exchangeID": "",
        "exchangeName": "",
        "from": "0x510F4a8CC103E0F17915A7630F1524Bb9AF01aB6",
        "fromType": "ADDRESS",
        "id": "finorder40ymrp87zgywpw4jlqd95e2w",
        "note": "34343",
        "operator": "0x4511@gmail.com",
        "opsType": "ADMIN",
        "subType": "WITHDRAW",
        "to": "0x035221cF1bDcCd8100531B6B6132323232323",
        "toType": "ADDRESS",
        "fee": "0.000000000000000000",
        "txid": "0x01921175f4986bf3bafd2a16a61b886cf12323232323232323",
        "updatedAt": 1733971965,
        "walletID": "walletw5l729323232323",
        "walletName": "BTC_WALLET"
      }
    ],
    "total": 1
  },
  "message": "success"
}

Status Code 200

Name Type Required Constraints Description
» code integer true none none
» message string true none none
» data object true none none
»» orders [object] true none Order list
»»» amount string true none Amount
»»» fee string true none Fee
»»» balance string true none Balance
»»» bizOrderID string true none Business order id
»»» bizType string true none Type:
DEPOSIT-Deposit
WITHDRAW-Withdraw
BATCH_WITHDRAW-Batch withdraw
BATCH_TRANSFER-Batch transfer
WALLET_TRANSFER-Wallet transfer
»»» coinName string true none Coin name
»»» createdAt integer true none Created at
»»» exchangeID string true none Exchange id
»»» exchangeName string true none Exchange name
»»» from string true none From
»»» fromType string true none From type
»»» id string true none Order id
»»» note string true none Note
»»» operator string true none Operator
»»» opsType string true none Ops type: ADMIN-Admin operation, API-System operation
»»» subType string true none Subtype:
WITHDRAW-Withdraw
DEPOSIT-Deposit
TRANSFER_OUT-Transfer out
TRANSFER_IN-Transfer in
»»» to string true none Target address or wallet name
»»» toType string true none Target type: ADDRESS-Address, WALLET-Wallet
»»» txid string true none Transaction hash
»»» updatedAt integer true none Updated at
»»» walletID string true none Wallet id
»»» walletName string true none Wallet name
»» total integer true none Total

Financial Statement

$ go run cmd/ctl/main.go "companykey" "companysecret" "GetFinanceReport" "1" "10" "https://stg-xpert.hashkeydev.com/saas-api"
code: 0
message: success
data:
{
  "reports": [
      {
          "coin": "USDT-ERC20",
          "deposit": "0.000000000000000000",
          "depositCount": 0,
          "endingBalance": "0.000000000000000000",
          "loanPurchase": "0.000000000000000000",
          "loanPurchaseCount": 0,
          "loanSettle": "0.000000000000000000",
          "loanSettleCount": 0,
          "openingBalance": "0.000000000000000000",
          "price": 1.0002579083,
          "priceDeposit": 0,
          "priceEndingBalance": 0,
          "priceLoanPurchase": 0,
          "priceLoanSettle": 0,
          "priceOpeningBalance": 0,
          "priceTransferIn": 0,
          "priceWithdraw": 0,
          "time": "2024/10/18",
          "transferIn": "0.000000000000000000",
          "wallet": {
              "id": "walletw5l729jn4mgy0843",
              "name": "HBLHSK"
          },
          "withdraw": "0.000000000000000000",
          "withdrawCount": 0
      }
  ],
  "total": 1
}
    result, _ = company.GetFinanceReport(map[string]interface{}{
        "page":1,
    "pageSize":10
    })

HTTP请求

GET /api/v1/finance/reports

Download Excel file: GET /api/v1/finance/reports/download

Params

Name Located in Description Required Type
X-Company-Key header company key Yes string
wallets query wallet id list, multiple values separated by commas No string
type query DAILY-Daily
MONTHLY-Monthly
ANNUAL-Annual
string
coins query token list (multiple values separated by commas) string
startDate query Start date (yyyy-MM-dd) Yes string
endDate query End date (yyyy-MM-dd) Yes string
page query Page (starting value is 1) No number
pageSize query Page size No number

Response Result

{
    "code": 0,
    "data": {
        "reports": [
            {
                "coin": "ETH",
                "deposit": "167.000000000000000000",
                "depositCount": 5,
                "endingBalance": "10.430999300000000000",
                "loanPurchase": "0.000000000000000000",
                "loanPurchaseCount": 0,
                "loanSettle": "0.000000000000000000",
                "loanSettleCount": 0,
                "openingBalance": "0.000000000000000000",
                "priceDeposit": 297166.4704650682,
                "priceEndingBalance": 18561.336798829732,
                "priceLoanPurchase": 0,
                "priceLoanSettle": 0,
                "priceOpeningBalance": 0,
                "priceTransferIn": 0,
                "priceWithdraw": 278605.1336662383,
                "time": "2024",
                "transferIn": "0.000000000000000000",
                "wallet": {
                    "id": "walletw5l729jn4mgy0843",
                    "name": "HBLHSK"
                },
                "withdraw": "156.569000700000000000",
                "withdrawCount": 37
            }
        ],
        "total": 20
    },
    "message": "success"
}

Status Code 200

Name Type Required Constraints Description
» code integer true none none
» message string true none none
» data object true none none
»» reports [object] true none Report list
»»» coin string true none Coin
»»» deposit string true none Deposit amount
»»» depositCount integer true none Deposit count
»»» endingBalance string true none Ending balance
»»» loanPurchase string true none Loan purchase amount
»»» loanPurchaseCount integer true none Loan purchase count
»»» loanSettle string true none Loan settle amount
»»» loanSettleCount integer true none Loan settle count
»»» openingBalance string true none Opening balance
»»» priceDeposit number true none Deposit price
»»» priceEndingBalance number true none Ending balance price
»»» priceLoanPurchase number true none Loan purchase price
»»» priceLoanSettle number true none Loan settle price
»»» priceOpeningBalance number true none Opening balance price
»»» priceTransferIn number true none Transfer in price
»»» priceWithdraw number true none Withdraw price
»»» time string true none Time
»»» transferIn string true none Transfer in amount
»»» wallet object true none Wallet
»»»» id string true none Wallet id
»»»» name string true none Wallet name
»»» withdraw string true none Withdraw amount
»»» withdrawCount integer true none Withdraw count
»» total integer true none Total

Callback

Order

Order notification sends JSON structured like this:

{
  "id": "2XB0eKAvj7KvjZDk59zl",
  "withdrawID": "7Cab38EA42538f4D8C2",
  "bizType": "DEPOSIT",
  "coinName": "ETH",
  "type": "ETH",
  "state": "DONE",
  "memo": "",
  "value": "1.000000000000000000",
  "fee": "0.000000000000000000",
  "from": "0xF0706B7Cab38EA42538f4D8C279B6F57ad1d4072",
  "to": "0x29152c850456899A78178622B6543BBFfC224495",
  "txid": "0x8487e23bbf71f1763e015598283ae891cc5ea8d444f87a0a60a0b5eb7e1a4d59",
  "n": 0,
  "block": 13721091,
  "affirmativeConfirmation": 20,
  "confirmations": 27,
  "sign": "fb0f53f33bba4cfa4bcb2c81e976bbe817633ba87a9904b6c3de293da3805cb3",
  "relatedOrderID": "orderrNXBQGJlw09apVyg4nDo"
}

Callbck Result

Value Type Description
id string the order ID
withdrawID string withdraw id
coinName string unique token name
txid string transaction hash
state string order state
bizType string order type
type string token type
from string transaction input
to string transaction output
value string transaction value
affirmativeConfirmation number affirmative confirmation of the blockchain
confirmations number number of transaction confirmations
fee string fee burnt for the transaction
block number the block transaction mined in
memo string order note, editable on admin
n number the order index
sign string hex string, sign parameters with HMACSHA256
relatedOrderId string related order id

Signature

In order to prove the message sender's identity, it should be verified by the following steps:

  1. Form a String message (sorted) that contains data prarams(exclude the sign param).

    if body params is:
    { "id": "2XB0eKAvj7KvjZDk59zl", "withdrawID": "7Cab38EA42538f4D8C2", "bizType": "DEPOSIT", "coinName": "ETH", "type": "ETH", "state": "DONE", "memo": "", "value": "1.000000000000000000", "fee": "0.000000000000000000", "from": "0xF0706B7Cab38EA42538f4D8C279B6F57ad1d4072", "to": "0x29152c850456899A78178622B6543BBFfC224495", "txid": "0x8487e23bbf71f1763e015598283ae891cc5ea8d444f87a0a60a0b5eb7e1a4d59", "n": 0, "block": 13721091, "affirmativeConfirmation": 20, "confirmations": 27 }

    The message string looks like this:
    affirmativeConfirmation=20&bizType=DEPOSIT&block=13721091&coinName=ETH&confirmations=27&fee=0.000000000000000000&from=0xF0706B7Cab38EA42538f4D8C279B6F57ad1d4072&id=2XB0eKAvj7KvjZDk59zl&memo=&n=0&state=DONE&to=0x29152c850456899A78178622B6543BBFfC224495&txid=0x8487e23bbf71f1763e015598283ae891cc5ea8d444f87a0a60a0b5eb7e1a4d59&type=ETH&value=1.000000000000000000&withdrawID=7Cab38EA42538f4D8C2

  2. Sign the message using HMAC-SHA256. If the AppSecret is exzYZT8IubM9Jxq1PWU5QjZ0JFP81bvCmlf1fFjW0b87Zr6eAMdofeYlhAMZxPzo, the sign param would be like this:
    fb0f53f33bba4cfa4bcb2c81e976bbe817633ba87a9904b6c3de293da3805cb3

Signature

  1. Get the current timestamp (seconds) and the nonce (random string). Please make sure the timestamp error not exceed 5 minutes and the nonce not repeated in 10 minutes.

  2. Form a String message (sorted) that contains data prarams, the timestamp and nonce above.

    if body params is:
    { "mode": "auto" }

    The message string looks like this:
    mode=auto&nonce=15833762841261615239762485&timestamp=1583376284

  3. Sign the message using HMAC-SHA256. If the AppSecret is yeTJ3EnOkyQQEjhTMVqn165Dqjp43bhTwXLIv25Ycdu8qwDOyqpa0WV54C6sO4HW, the sign param would be like this:
    7042a9fd6deea017be7ad76dfb48e4c36feca279819630c870a628f5352c9044

  4. Send request as the same format as described in General Structure.

AES Encryption

The encryption has two parts: key and iv. The key is sha256(TeamSecret). The iv is a random bytes that length is 16. An example of encrypting appSecret written by python.

import base64
import hashlib
from Crypto.Cipher import AES

def _pad(s):
    return s + (AES.block_size - len(s) % AES.block_size) * chr(AES.block_size - len(s) % AES.block_size)

def _unpad(s):
    return s[:-ord(s[len(s)-1:])]

teamSecret = b'kfTKfuSV5oiuFZENI6tv1OwfiJ1tEv70HnmJsVxNGCu2YEKqEq2QHpBGgqwRa29R'
appSecret = 'nn2oh58iuc1sg2adya1golz35cowjbz7r0hfjt2ey6b4fc4xyq6kdopp9tlp0ko3'

aeskey = bytes.fromhex(hashlib.sha256(teamSecret).hexdigest())
iv = base64.b64decode('MTIzNDU2Nzg5MDEyMzQ1Ng==')

decipher = AES.new(aeskey, AES.MODE_CBC, IV=iv)
encryptedAppSecret = decipher.encrypt(_pad(appSecret))
base64EncryptedAppSecret = base64.b64encode(encryptedAppSecret)
print(base64EncryptedAppSecret)

decipher = AES.new(aeskey, AES.MODE_CBC, IV=iv)
plaintext = _unpad(decipher.decrypt(base64.b64decode(base64EncryptedAppSecret)))
print(plaintext)

Change Log

Release Time API New / Update Description
2020-09-04 14:00 - - update the documentation

Errors

The Kittn API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
403 Forbidden -- The kitten requested is hidden for administrators only.
404 Not Found -- The specified kitten could not be found.
405 Method Not Allowed -- You tried to access a kitten with an invalid method.
406 Not Acceptable -- You requested a format that isn't json.
410 Gone -- The kitten requested has been removed from our servers.
418 I'm a teapot.
429 Too Many Requests -- You're requesting too many kittens! Slow down!
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.