介绍
Tokenlon-MMSK 是一个启动 node http 服务的工具,该服务部署在做市商一侧,是一个连接 imToken Server 和 做市商服务的 中转工具,mmsk 全称为 Market Maker Service Kit,用于降低两端接口对接成本。
安装
需要做市商团队手动下载 Release 最新版
考虑到安全因素,做市商需要检查下载的 zip 文件 sha256 是否与 Release 版本一致。例如:shasum -a 256 /path/to/file
检查完成,解压后,进入 tokenlon-mmsk 根目录,执行:
yarn
或者 npm install
准备工作
- 做市商需要准备一个用于 签名的钱包 marketMakerSigner
- 联系 imToken,将 marketMakerSigner 钱包地址提供给 imToken,此时 imToken 会部署一个 marketMakerProxyContract 并将该合约地址提供给做市商
- 联系 imToken,imToken 提供相应环境的
EXCHANGE_URL
、WEBSOCKET_URL
地址 - 给 marketMakerProxyContract 地址充值可交易的 Token 代币
做市商接口提供
做市商需要实现以下 5 个接口,用于 Tokenlon-MMSK 的运行
- pairs 接口用于
tokenlon-mmsk
向做市商获取支持的交易关系 - indicativePrice 接口用于
tokenlon-mmsk
向做市商获取两个支持的 Token 相应数量对应的 参考 价格 - price 接口用于
tokenlon-mmsk
向做市商获取两个支持的 Token 相应数量对应的 真实成交 价格 - deal 接口:当做市商的报价被用户确认后,imToken Server 会通过 发送一个 order 到
tokenlon-mmsk
,tokenlon-mmsk
再通过 deal 接口 通知做市商 - exception 接口:当做市商被成交的订单,存在一些异常情况时,imToken Server 会通过 发送这个异常的 order 到
tokenlon-mmsk
,tokenlon-mmsk
再通过 exception 接口 通知做市商
通过 zerorpc 方式提供接口
示例
import * as zerorpc from 'zerorpc'
const server = new zerorpc.Server({
pairs(params, reply) {
reply(null, {
result: true,
pairs: ['SNT/ETH', 'KNC/ETH', 'ETH/DAI'],
})
},
indicativePrice(params, reply) {
reply(null, {
result: true,
exchangeable: true,
minAmount: 0.002,
maxAmount: 100,
price: 0.00032,
})
},
price(params, reply) {
reply(null, {
result: true,
exchangeable: true,
minAmount: 0.002,
maxAmount: 100,
quoteId: '234dsfasd-sdfasdf-sdfasf'
})
},
deal(params, replay) {
reply(null, {
result: true
})
},
exception(params, replay) {
reply(null, {
result: true
})
},
})
server.bind('tcp://0.0.0.0:4242')
详见:zerorpc
pairs 接口
Invoke
import * as zerorpc from 'zerorpc'
const client = new zerorpc.Client()
client.connect('tcp://127.0.0.1:4242')
client.invoke('pairs', undefined, (error, res, more) => {
console.log(res)
})
Response
{
"result": true,
"pairs": [
"SNT/ETH",
"OMG/ETH",
"ETH/DAI"
]
}
// 其他情况返回
{
"result": false,
"message": "异常错误"
}
Params 参数
无
返回
正确情况
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
pairs | Array | pair string array |
其他情况返回
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
message | String | 可能的错误信息 |
indicativePrice 接口
Invoke
import * as zerorpc from 'zerorpc'
const client = new zerorpc.Client()
client.connect('tcp://127.0.0.1:4242')
client.invoke('indicativePrice', {
base: 'SNT',
quote: 'ETH',
side: 'SELL',
amount: 50,
}, (error, res, more) => {
console.log(res)
})
client.invoke('indicativePrice', {
base: 'SNT',
quote: 'ETH',
side: 'SELL',
amount: 1000,
}, (error, res, more) => {
console.log(res)
})
Response
// 正确情况
{
"result": true,
"exchangeable": true,
"price": 0.00017508,
"minAmount": 0.002,
"maxAmount": 100,
}
// 其他情况
{
"result": false,
"exchangeable": false,
"minAmount": 0.002,
"maxAmount": 100,
"message": "余额不足"
}
Params 参数
Name | Type | Mandatory | Description |
---|---|---|---|
base | String | YES | base symbol |
quote | String | YES | quote symbol |
side | String | YES | 'BUY' or 'SELL' |
amount | Number | NO | BUY or SELL base amount |
返回
正确情况
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
exchangeable | Boolean | 是否可交易 |
minAmount | Number | 可交易的最小 base token 数量 |
maxAmount | Number | 可交易的最大 base token 数量 |
price | Number |
其他情况返回
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
exchangeable | Boolean | 是否可交易 |
minAmount | Number | 可交易的最小 base token 数量 |
maxAmount | Number | 可交易的最大 base token 数量 |
message | String | 可能的错误信息 |
price 接口
Invoke
import * as zerorpc from 'zerorpc'
const client = new zerorpc.Client()
client.connect('tcp://127.0.0.1:4242')
client.invoke('price', {
base: 'SNT',
quote: 'ETH',
side: 'SELL',
amount: 50,
uniqId: 'dfasfsdf',
}, (error, res, more) => {
console.log(res)
})
client.invoke('price', {
base: 'SNT',
quote: 'ETH',
side: 'SELL',
amount: 1000,
uniqId: 'dfasfsdf',
}, (error, res, more) => {
console.log(res)
})
Response
// 正确情况
{
"result": true,
"exchangeable": true,
"price": 0.00017508,
"minAmount": 0.0002,
"maxAmount": 100,
"quoteId": "asfadsf-dsfsdf-ggsd-qwe-rgjty",
}
// 其他情况
{
"result": false,
"exchangeable": false,
"minAmount": 0.0002,
"maxAmount": 100,
"message": "余额不足"
}
Params 参数
Name | Type | Mandatory | Description |
---|---|---|---|
base | String | YES | base symbol |
quote | String | YES | quote symbol |
side | String | YES | 'BUY' or 'SELL' |
amount | Number | YES | BUY or SELL base amount |
uniqId | String | YES | 代表用户的唯一Id |
返回
正确情况
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
exchangeable | Boolean | 是否可交易 |
minAmount | Number | 可交易的最小 base token 数量 |
maxAmount | Number | 可交易的最大 base token 数量 |
price | Number | |
quoteId | String | 一个唯一值,用于跟踪该报价最终的订单、以及成交情况 |
其他情况返回
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
exchangeable | Boolean | 是否可交易 |
minAmount | Number | 可交易的最小 base token 数量 |
maxAmount | Number | 可交易的最大 base token 数量 |
message | String | 可能的错误信息 |
deal 接口
Invoke
import * as zerorpc from 'zerorpc'
const client = new zerorpc.Client()
client.connect('tcp://127.0.0.1:4242')
client.invoke('deal', {
makerToken: 'SNT',
takerToken: 'ETH',
makerTokenAmount: 1000,
takerTokenAmount: 1,
quoteId: '234dsfasd-sdfasdf-sdfasf',
timestamp: 1231234324,
}, (error, res, more) => {
console.log(res)
})
Response
{
"result": true
}
Params 参数
Name | Type | Mandatory | Description |
---|---|---|---|
makerToken | String | YES | token symbol |
takerToken | String | YES | token symbol |
makerTokenAmount | Number | YES | maker token's amount |
takerTokenAmount | Number | YES | taker token's amount |
quoteId | String | YES | quoteId from price interface |
timestamp | Number | YES |
返回
Name | Type | Description |
---|---|---|
result | Boolean | 是否接收 exception 通知,建议直接返回 true ;如果返回 false ,imToken 会持续不断发送此通知,做市商可能会有重复对冲风险 |
exception 接口
Invoke
import * as zerorpc from 'zerorpc'
const client = new zerorpc.Client()
client.connect('tcp://127.0.0.1:4242')
client.invoke('exception', {
makerToken: 'SNT',
takerToken: 'ETH',
makerTokenAmount: 1000,
takerTokenAmount: 1,
quoteId: '234dsfasd-sdfasdf-sdfasf',
timestamp: 1231234324,
type: 'FAILED',
}, (error, res, more) => {
console.log(res)
})
Response
{
"result": true
}
Params 参数
Name | Type | Mandatory | Description |
---|---|---|---|
makerToken | String | YES | token symbol |
takerToken | String | YES | token symbol |
makerTokenAmount | Number | YES | maker token's amount |
takerTokenAmount | Number | YES | taker token's amount |
quoteId | String | YES | quoteId from price interface |
type | String | YES | 'FAILED' 代表这笔订单失败;'TIMEOUT' 代表这笔订单超时失败;'DELAY' 代表这笔订单成交了,但是没有通过 deal 通知做市商,此种情况也属于异常情况 |
timestamp | Number | YES |
返回
Name | Type | Description |
---|---|---|
result | Boolean | 是否接收 exception 通知,建议直接返回 true ;如果返回 false ,imToken 会持续不断发送此通知,做市商可能会有重复处理风险 |
通过 http 方式提供接口
pairs 接口
Request
curl 'HTTP_SERVER_ENDPOINT/pairs'
Response
// 正确情况
{
"result": true,
"pairs": [
"SNT/ETH",
"OMG/ETH",
"DAI/ETH"
]
}
// 其他情况返回
{
"result": false,
"message": "异常错误"
}
请求地址:HTTP_SERVER_ENDPOINT/pairs
请求方式
GET
请求参数
无
请求返回
正确情况
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
pairs | Array | pair string array |
其他情况返回
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
message | String | 可能的错误信息 |
indicativePrice 接口
Request
curl 'HTTP_SERVER_ENDPOINT/indicativePrice?base=SNT"e=OMG&amount=30&side=BUY'
Response
// 正确情况
{
"result": true,
"exchangeable": true,
"price": 0.00017508,
"minAmount": 0.0002,
"maxAmount": 100
}
// 其他情况
{
"result": false,
"exchangeable": false,
"minAmount": 0.0002,
"maxAmount": 100,
"message": "余额不足"
}
请求地址:HTTP_SERVER_ENDPOINT/indicativePrice
请求方式
GET
请求参数
Name | Type | Mandatory | Description |
---|---|---|---|
base | String | YES | base symbol |
quote | String | YES | quote symbol |
side | String | YES | 'BUY' or 'SELL' |
amount | Number | NO | BUY or SELL base amount |
请求返回
正确情况
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
exchangeable | Boolean | 是否可交易 |
minAmount | Number | 可交易的最小 base token 数量 |
maxAmount | Number | 可交易的最大 base token 数量 |
price | Number |
其他情况返回
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
exchangeable | Boolean | 是否可交易 |
minAmount | Number | 可交易的最小 base token 数量 |
maxAmount | Number | 可交易的最大 base token 数量 |
message | String | 可能的错误信息 |
price 接口
Request
curl 'HTTP_SERVER_ENDPOINT/price?base=SNT"e=OMG&amount=30&side=BUY&uniqId=dfdsfjsidf'
Response
// 正确情况
{
"result": true,
"exchangeable": true,
"price": 0.00017508,
"minAmount": 0.0002,
"maxAmount": 100,
"quoteId": "asfadsf-dsfsdf-ggsd-qwe-rgjty"
}
// 其他情况
{
"result": false,
"exchangeable": false,
"minAmount": 0.0002,
"maxAmount": 100,
"message": "余额不足"
}
请求地址:HTTP_SERVER_ENDPOINT/price
请求方式
GET
请求参数
Name | Type | Mandatory | Description |
---|---|---|---|
base | String | YES | base symbol |
quote | String | YES | quote symbol |
side | String | YES | 'BUY' or 'SELL' |
amount | Number | YES | BUY or SELL base amount |
uniqId | String | YES | 代表用户的唯一Id |
请求返回
正确情况
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
exchangeable | Boolean | 是否可交易 |
minAmount | Number | 可交易的最小 base token 数量 |
maxAmount | Number | 可交易的最大 base token 数量 |
price | Number | |
quoteId | String | 一个唯一值,用于跟踪该报价最终的订单、以及成交情况 |
其他情况返回
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
exchangeable | Boolean | 是否可交易 |
minAmount | Number | 可交易的最小 base token 数量 |
maxAmount | Number | 可交易的最大 base token 数量 |
message | String | 可能的错误信息 |
deal 接口
Request
curl -X POST \
HTTP_SERVER_ENDPOINT/deal \
-H 'Content-Type: application/json' \
-H 'cache-control: no-cache' \
-d '{"makerToken": "SNT","takerToken":"OMG","makerTokenAmount":30,"takerTokenAmount":0.1,"quoteId":"234dsfasd-sdfasdf-sdfasf","timestamp":1231234324}'
Response
{
"result": true
}
请求地址:HTTP_SERVER_ENDPOINT/deal
请求方式
POST
请求参数
Name | Type | Mandatory | Description |
---|---|---|---|
makerToken | String | YES | token symbol |
takerToken | String | YES | token symbol |
makerTokenAmount | Number | YES | maker token's amount |
takerTokenAmount | Number | YES | taker token's amount |
quoteId | String | YES | quoteId from price interface |
timestamp | Number | YES |
请求返回
Name | Type | Description |
---|---|---|
result | Boolean | 是否接收 exception 通知,建议直接返回 true ;如果返回 false ,imToken 会持续不断发送此通知,做市商可能会有重复对冲风险 |
exception 接口
Request
curl -X POST \
HTTP_SERVER_ENDPOINT/exception \
-H 'Content-Type: application/json' \
-H 'cache-control: no-cache' \
-d '{"makerToken": "SNT","takerToken":"OMG","makerTokenAmount":30,"takerTokenAmount":0.1,"quoteId":"234dsfasd-sdfasdf-sdfasf","timestamp":1231234324,"type":"FAILED"}'
Response
{
"result": true
}
Params 参数
Name | Type | Mandatory | Description |
---|---|---|---|
makerToken | String | YES | token symbol |
takerToken | String | YES | token symbol |
makerTokenAmount | Number | YES | maker token's amount |
takerTokenAmount | Number | YES | taker token's amount |
quoteId | String | YES | quoteId from price interface |
type | String | YES | 'FAILED' 代表这笔订单失败;'TIMEOUT' 代表这笔订单超时失败;'DELAY' 代表这笔订单成交了,但是没有通过 deal 通知做市商,此种情况也属于异常情况 |
timestamp | Number | YES |
返回
Name | Type | Description |
---|---|---|
result | Boolean | 是否接收 exception 通知,建议直接返回 true ;如果返回 false ,imToken 会持续不断发送此通知,做市商可能会有重复处理风险 |
配置
需要做市商根据自身情况,更改 tokenlon-mmsk 项目 app
目录下 mmConf.js
配置信息
EXCHANGE_URL
WEBSOCKET_URL
PROVIDER_URL
// kovan
const PROVIDER_URL = 'https://kovan.infura.io/v3/xxxxxx'
const PROVIDER_URL = ['https://kovan.infura.io/v3/xxxxxx1', 'https://kovan.infura.io/v3/xxxxxx2', 'https://kovan.infura.io/v3/xxxxxx3']
// mainnet
const PROVIDER_URL = 'https://mainnet.infura.io/v3/xxxxxx'
const PROVIDER_URL = ['https://mainnet.infura.io/v3/xxxxxx1', 'https://mainnet.infura.io/v3/xxxxxx2', 'https://mainnet.infura.io/v3/xxxxxx3']
PROVIDER_URL
支持 string
, array
数组形式配置
做市商可以在 infura 上注册账号获取
MMSK_SERVER_PORT
TOKENLON-MMSK 的服务端口,默认值为80
WALLET_ADDRESS
marketMakerSigner 地址 (用于签名的钱包地址)
wallet 私钥配置
marketMakerSigner 私钥
钱包私钥的引入方式目前有两个:纯私钥方式、keystore 方式。
keystore 方式
keystore 方式
// 运维配置的环境变量 - keystore 存储位置
const keystorePath = process.env.KEYSTORE_PATH
// 读取 keystore
const keystoreStr = fs.readFileSync(keystorePath).toString()
const keystore = JSON.parse(keystoreStr)
const USE_KEYSTORE = true
const WALLET_KEYSTORE = keystore
此方式仅将钱包 keystore 存储在服务器上,而需要管理人员输入密码来得到对应的私钥。具体处理为,将 USE_KEYSTORE
参数设置为 true
,使用 WALLET_KEYSTORE
,WALLET_PRIVATE_KEY
可不传递。
此时 Tokenlon-MMSK 在运行时,会在命令行提示输入该 keystore 的密码。
纯私钥方式
纯私钥方式
const WALLET_PRIVATE_KEY = 'your marketMakerSigner private key'
将 USE_KEYSTORE
参数设置为 false
或不传递,使用 WALLET_PRIVATE_KEY
,WALLET_KEYSTORE
可不传递
做市商接口地址配置
zerorpc 方式
const USE_ZERORPC = true
const ZERORPC_SERVER_ENDPOINT = 'your zerorpc addr and port' // like tcp:127.0.0.1:4242
http 方式
const USE_ZERORPC = false
const HTTP_SERVER_ENDPOINT = 'your http server endpoint' // like https://xxx.xxx.com
做市商接口可通过 zerorpc
或 http
方式提供。
- 如果使用 HTTP 服务提供
pairs
、indicativePrice
、price
、deal
、exception
接口,USE_ZERORPC
设置为false
,ZERORPC_SERVER_ENDPOINT
可不传递 - 如果使用 zerorpc 提供
pairs
、indicativePrice
、price
、deal
、exception
接口,USE_ZERORPC
设置为true
,HTTP_SERVER_ENDPOINT
可不传递
做市商接口实现检查
私钥方式 与 http提供接口 的 mmConf.js 配置
module.exports = {
EXCHANGE_URL,
WEBSOCKET_URL,
PROVIDER_URL, // like ['https://mainnet.infura.io']
MMSK_SERVER_PORT: 80, // default is 80,
WALLET_ADDRESS,
WALLET_PRIVATE_KEY,
USE_ZERORPC: false,
HTTP_SERVER_ENDPOINT: 'https://xxx.xxx.com',
})
keystore 方式 与 zerorpc 提供接口 的 mmConf.js 配置
import * as fs from 'fs'
// 运维配置的环境变量 - keystore 存储位置
const keystorePath = process.env.KEYSTORE_PATH
// 读取 keystore
const keystoreStr = fs.readFileSync(keystorePath).toString()
const keystore = JSON.parse(keystoreStr)
module.exports = {
EXCHANGE_URL,
WEBSOCKET_URL,
PROVIDER_URL, // like ['https://mainnet.infura.io']
MMSK_SERVER_PORT: 80, // default is 80,
WALLET_ADDRESS,
USE_KEYSTORE: true,
WALLET_KEYSTORE: keystore,
USE_ZERORPC: true,
ZERORPC_SERVER_ENDPOINT: 'tcp:127.0.0.1:4242',
}
接口检查使用方式: yarn run check
或 npm run check
做市商可通过此方法检测接口实现情况,排查是否存在相关问题,例如:
- 接口返回不符合约定
- 接口返回错误
等情况。
初始化
私钥方式 与 zerorpc 提供接口 的 mmConf.js 配置
module.exports = {
EXCHANGE_URL,
WEBSOCKET_URL,
PROVIDER_URL, // like ['https://mainnet.infura.io']
MMSK_SERVER_PORT: 80, // default is 80,
WALLET_ADDRESS,
WALLET_PRIVATE_KEY,
USE_ZERORPC: true,
ZERORPC_SERVER_ENDPOINT: 'tcp:127.0.0.1:4242',
})
keystore 方式 与 http提供接口 的 mmConf.js 配置
import * as fs from 'fs'
// 运维配置的环境变量 - keystore 存储位置
const keystorePath = process.env.KEYSTORE_PATH
// 读取 keystore
const keystoreStr = fs.readFileSync(keystorePath).toString()
const keystore = JSON.parse(keystoreStr)
module.exports = {
EXCHANGE_URL,
WEBSOCKET_URL,
PROVIDER_URL, // like ['https://mainnet.infura.io']
MMSK_SERVER_PORT: 80, // default is 80,
WALLET_ADDRESS,
USE_KEYSTORE: true,
WALLET_KEYSTORE: keystore,
USE_ZERORPC: false,
HTTP_SERVER_ENDPOINT: 'https://xxx.xxx.com',
}
运行方式: yarn start
或 npm run start
做市商运行正常后,需要部署至服务器上,提供外网访问 (IP 或 域名方式),并将外网访问地址(IP 或 域名)提供给 imToken。
数据流
MMSK 对外提供的API
tokenlon-mmsk 对外提供的接口,方便数据间的通讯与交互。
getSupportedTokenList
示例
{
"result": true,
"tokens": [
{
"symbol": "ETH",
"opposites": [
"MANA",
"SNT",
]
},
{
"symbol": "MANA",
"opposites": [
"ETH"
]
},
{
"symbol": "SNT",
"opposites": [
"ETH"
]
}
]
}
imToken 会通过做市商 的 pairs 接口、以及 imToken Server 的 getTokenList
接口,将做市商 支持交易的Token、imToken 支持交易的Token 做一个交集通过这个接口返回。
请求方式
GET
请求参数
无
请求返回
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
tokens | Array | token item array |
getRate
示例
{
"result": true,
"exchangeable": true,
"minAmount": 0.0002,
"maxAmount": 100,
"rate": 124.28
}
imToken Server 会不断轮询请求做市商 mmsk Server 的 getRate
接口,提供最优报价展示给用户。此接口仅为 做市商 indicativePrice 接口 的一个简单衍生。
请求方式
GET
请求参数
Name | Type | Mandatory | description |
---|---|---|---|
base | String | YES | base symbol |
quote | String | YES | quote symbol |
side | String | YES | 'BUY' or 'SELL' |
amount | Number | NO | BUY or SELL base amount |
请求返回
正常返回
Name | Type | description |
---|---|---|
result | Boolean | 是否正常返回 |
exchangeable | Boolean | 是否可交易 |
minAmount | Number | 可交易的最小 base token 数量 |
maxAmount | Number | 可交易的最大 base token 数量 |
rate | Number |
其他情况返回
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
exchangeable | Boolean | 是否可交易 |
minAmount | Number | 可交易的最小 base token 数量 |
maxAmount | Number | 可交易的最大 base token 数量 |
message | String | 可能的错误信息 |
newOrder
示例
{
"result": true,
"rate": 0.00002,
"exchangeable": true,
"minAmount": 0.0002,
"maxAmount": 100,
"order": {
"makerAddress": "0xb6025914f4e631d458f4668cc232d1e38ddbd569",
"makerAssetAmount": "1000000000000000000000",
"makerAssetData": "0xf47261b0000000000000000000000000744d70fdbe2ba4cf95131626614a1763df805b9e",
"makerFee": "0",
"takerAddress": "0x08053129c3967f4a496958aac5a1e8e6df6c7652",
"takerAssetAmount": "23324453240000000000",
"takerAssetData": "0xf47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"takerFee": "0",
"senderAddress": "0x8f19bf4b5dfae80c1e3f91bd33f3bbc37326d5e7",
"feeRecipientAddress": "0x0000000000000000000000000000000000000000",
"expirationTimeSeconds": "1539498614",
"exchangeAddress": "0x2002d3812f58e35f0ea1ffbf80a75a38c32175fa",
"salt": "59572482685924225672407231424301404205239289582722616080644908172098386763718",
"makerWalletSignature": "0x1b66353b9b6cff19d5acbdf275d55e988c2a077c6c6074bcf49705e09b7efd3a61212821ff244b96623fa5181507da0b796a6693b1d511e9355a83c4c06ac88a66fba2ff8436171ddd3653cd2ca1c5595046144d7f04",
"quoteId": "TD-190109-173025-NqGaWun",
"feeFactor": 10
}
}
在 imToken APP 中,当用户点击按钮后,需要获取对应价格的订单。此部分由 imToken 服务器轮询各位做市商 mmsk Server 的 newOrder 接口,提供最优报价的订单给用户
请求方式
GET
请求参数
Name | Type | Mandatory | description |
---|---|---|---|
base | String | YES | base symbol |
quote | String | YES | quote symbol |
side | String | YES | 'BUY' or 'SELL' |
userAddr | String | YES | user's address |
amount | Number | YES | BUY or SELL base amount |
uniqId | String | YES | 代表用户的唯一Id |
请求返回
正常返回
Name | Type | description |
---|---|---|
result | Boolean | 是否正常返回 |
exchangeable | Boolean | 是否可交易 |
minAmount | Number | 可交易的最小 base token 数量 |
maxAmount | Number | 可交易的最大 base token 数量 |
rate | Number | This order's rate |
order | Object | 0x's maker signed order |
其他情况返回
Name | Type | Description |
---|---|---|
result | Boolean | 是否正常返回 |
exchangeable | Boolean | 是否可交易 |
minAmount | Number | 可交易的最小 base token 数量 |
maxAmount | Number | 可交易的最大 base token 数量 |
message | String | 可能的错误信息 |
dealOrder
示例
{
makerToken: 'SNT',
takerToken: 'ETH',
makerTokenAmount: 1000,
takerTokenAmount: 1,
quoteId: '234dsfasd-sdfasdf-sdfasf',
timestamp: 1231234324,
}
请求方式
POST
请求参数
Name | Type | Mandatory | Description |
---|---|---|---|
makerToken | String | YES | token symbol |
takerToken | String | YES | token symbol |
makerTokenAmount | Number | YES | maker token's amount |
takerTokenAmount | Number | YES | taker token's amount |
quoteId | String | YES | quoteId from price interface |
timestamp | Number | YES |
请求返回
正常返回
Name | Type | description |
---|---|---|
result | true |
其他情况返回
Name | Type | Description |
---|---|---|
result | false | |
message | String | 可能的错误信息 |
exceptionOrder
示例
{
makerToken: 'SNT',
takerToken: 'ETH',
makerTokenAmount: 1000,
takerTokenAmount: 1,
quoteId: '234dsfasd-sdfasdf-sdfasf',
timestamp: 1231234324,
type: 'FAILED',
}
请求方式
POST
请求参数
Name | Type | Mandatory | Description |
---|---|---|---|
makerToken | String | YES | token symbol |
takerToken | String | YES | token symbol |
makerTokenAmount | Number | YES | maker token's amount |
takerTokenAmount | Number | YES | taker token's amount |
quoteId | String | YES | quoteId from price interface |
type | String | YES | 'FAILED' 代表这笔订单失败;'TIMEOUT' 代表这笔订单超时失败;'DELAY' 代表这笔订单成交了,但是没有通过 deal 通知做市商,此种情况也属于异常情况 |
timestamp | Number | YES |
请求返回
正常返回
Name | Type | description |
---|---|---|
result | true |
其他情况返回
Name | Type | Description |
---|---|---|
result | false | |
message | String | 可能的错误信息 |
version
请求方式
GET
请求返回
Name | Type | description |
---|---|---|
result | true | |
version | String | MMSK 的版本号 |
getBalance
示例
{
"result": true,
"balance": 0.13371396
}
做市商可通过此接口获取 marketMakerProxyContract
合约相应代币余额
请求方式
GET
请求参数
Name | Type | Mandatory | description |
---|---|---|---|
token | String | YES | token symbol |
请求返回
Name | Type | description |
---|---|---|
result | Boolean | 是否正常返回 |
balance | Number | the token's balance |
getBalances
示例
{
"result": true,
"balances": [
{
"symbol": "ETH",
"balance": 0.13371396
},
{
"symbol": "ZRX",
"balance": 0
},
{
"symbol": "DAI",
"balance": 5.78464455
},
{
"symbol": "KNC",
"balance": 49.99451026
},
{
"symbol": "MKR",
"balance": 0
},
{
"symbol": "OMG",
"balance": 0
},
{
"symbol": "SNT",
"balance": 0
},
{
"symbol": "MANA",
"balance": 0
}
]
}
做市商可通过此接口获取 marketMakerProxyContract
合约代币余额
请求方式
GET
请求参数
无
请求返回
Name | Type | description |
---|---|---|
result | Boolean | 是否正常返回 |
balances | Array | balance item array |
getOrdersHistory
示例
{
"result": true,
"orders": [
{
"makerToken": "SNT",
"takerToken": "ETH",
"makerTokenAmount": 1000,
"takerTokenAmount": 1,
"quoteId": "234dsfasd-sdfasdf-sdfasf",
"status": "success",
"txHash": "0x953e9641811865e2a5da0bcfbee1c0da2f88e252efb9e782e60730ac0e730807",
"timestamp": 1549349662
}
]
}
做市商可通过此接口获取所有成交的订单情况
请求方式
GET
请求参数
Name | Type | Mandatory | description |
---|---|---|---|
page | Number | YES | |
perpage | Number | YES | 每页数量 |
请求返回
Name | Type | description |
---|---|---|
result | Boolean | 是否正常返回 |
orders | Array | 具体见示例 |
getOrderState
示例
{
"result": true,
"order": {
"makerToken": "SNT",
"takerToken": "ETH",
"makerTokenAmount": 1000,
"takerTokenAmount": 1,
"quoteId": "234dsfasd-sdfasdf-sdfasf",
"status": "success",
"txHash": "0x953e9641811865e2a5da0bcfbee1c0da2f88e252efb9e782e60730ac0e730807",
"timestamp": 1549349662
}
}
做市商可通过此接口获取对应quoteId的订单信息与成交状态情况
请求方式
GET
请求参数
Name | Type | Mandatory | description |
---|---|---|---|
quoteId | String | YES | 一个唯一值,用于跟踪该报价最终的订单、以及成交情况 |
请求返回
Name | Type | description |
---|---|---|
result | Boolean | 是否正常返回 |
order | Object | 具体见示例 |
附:订单状态 status
order
相应的 status
存在情况:
status | description |
---|---|
unbroadcast | 该笔订单尚未经 机器人 进行上链 |
pending | 该笔交易正在打包中 |
success | 上链交易成功 |
failed | 上链交易失败 |
timeout | 上链交易超时 |
invalid | 该笔订单无效 |
abandoned | 该笔订单未被采用 |