NAV
Im token logo imToken API Documentation Tokenlon-SDK DApp-SDK
typescript
  • 介绍
  • 安装
  • 配置
  • 特性
  • Tokenlon
  • 底层暴露方法
  • 其他
  • 中文

    介绍

    Tokenlon-SDK 是 imToken 团队基于 0x protocol 去中心化 Token 兑换合约以及 0x.js 封装,提供给广大开发者运行相关策略,进行自动化挂单、吃单、撤单的工具。

    安装

    yarn add tokenlon-sdk

    or

    npm install tokenlon-sdk

    配置

    server url

    请求的后端服务器地址

    web3 provider url

    wallet 配置

    wallet 配置

    {
      "address": "0x20F0C6e79A763E1Fe83DE1Fbf08279Aa3953FB5f",
      "privateKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    }
    

    包含钱包地址和私钥的 Object 对象。

    钱包地址备注:

    1. 钱包地址需要通过申请与审核才能使用 imToken 服务器相关后端接口服务;
    2. 挂单、吃单、撤单都是基于这个钱包进行,需要确保在运行期间,钱包内有相应可兑换的Token。

    初始化与运行时,私钥会用来处理签名:

    1. 签名时间戳发送到imToken服务器 来获取 JWT Token, 作为每一个请求的请求头。在此过程中,后端会校验签名的地址是否通过审核;
    2. 通过Tokenlon-SDK进行的挂单、吃单、撤单等各类智能合约调用的上链签名参数来进行 web3 广播交易。

    zeroEx 配置

    测试环境(kovan)

    {
      "networkId": 42,
      "gasLimit": 150000,
      "etherTokenContractAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
      "exchangeContractAddress": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364",
      "tokenTransferProxyContractAddress": "0x087Eed4Bc1ee3DE49BeFbd66C662B434B15d49d4"
    }
    

    主网环境

    {
      "networkId": 1,
      "gasLimit": 250000,
      "exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
      "etherTokenContractAddress": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
      "tokenTransferProxyContractAddress": "0x8da0d80f5007ef1e431dd2127178d224e32c2ef4"
    }
    
    1. 其中 networkId 对于测试网络和主网网络是固定的,gasLimit不足调用时,内部会获取该笔交易需要的gasLimit来进行设定,尽量避免 out of gas问题。
    2. etherTokenContractAddress 为 0x 合约设定的,WETH Token合约地址,exchangeContractAddress 则是 0x 合约对应的兑换合约地址,而 tokenTransferProxyContractAddress 则是 0x 合约对应的用于代理转账的合约地址。

    详细文档见 0xproject

    gasPriceAdaptor

    支持 fastsafeLowaverage 三个选项。

    通过请求 ethgasstation 接口 获取对应字段并乘以 100000000 作为 gasPrice,在相关发送上链交易的接口中使用。

    涉及的接口

    tokenlon.deposit
    tokenlon.withdraw
    tokenlon.setAllowance
    tokenlon.setUnlimitedAllowance
    tokenlon.fillOrder
    tokenlon.fillOrKillOrder
    tokenlon.batchFillOrders
    tokenlon.batchFillOrKill
    tokenlon.fillOrdersUpTo
    tokenlon.cancelOrder
    tokenlon.batchCancelOrders
    
    tokenlon.zeroExWrapper.token.setAllowanceAsync
    tokenlon.zeroExWrapper.token.transferAsync
    tokenlon.zeroExWrapper.token.transferFromAsync
    tokenlon.zeroExWrapper.token.setUnlimitedAllowanceAsync
    tokenlon.zeroExWrapper.token.setProxyAllowanceAsync
    tokenlon.zeroExWrapper.token.setUnlimitedProxyAllowanceAsync
    tokenlon.zeroExWrapper.etherToken.depositAsync
    tokenlon.zeroExWrapper.etherToken.withdrawAsync
    tokenlon.zeroExWrapper.exchange.fillOrderAsync
    tokenlon.zeroExWrapper.exchange.cancelOrderAsync
    tokenlon.zeroExWrapper.exchange.fillOrKillOrderAsync
    tokenlon.zeroExWrapper.exchange.batchFillOrdersAsync
    tokenlon.zeroExWrapper.exchange.batchFillOrKillAsync
    tokenlon.zeroExWrapper.exchange.fillOrdersUpToAsync
    tokenlon.zeroExWrapper.exchange.batchCancelOrdersAsync
    

    onChainValidate

    示例

    const baseQuote = { base: 'SNT', quote: 'WETH' }
    const orders = [
      {
        side: 'BUY',
        price: 0.0002,
        amount: 10000,
      },
      {
        side: 'SELL',
        price: 0.00022,
        amount: 10000,
      },
      // ...
    ]
    

    onChainValidate = true

    for (let o of orders) {
      try {
        // 校验不通过会报错
        await tokenlon.placeOrder({
          ...baseQuote,
          ...o,
        })
      } catch (e) {}
    }
    

    onChainValidate = false

    const checkBalanceEnough = (price, side, balanceStack) => {
      const { baseBalance, quoteBalance } = balanceStack
      return side === 'BUY' ? quoteBalance >= price * amount : baseBalance >= amount
    }
    
    const baseBalance = await tokenlon.getTokenBalance(baseQuote.base)
    const quoteBalance = await tokenlon.getTokenBalance(baseQuote.quote)
    
    for (let o of orders) {
      // 提前做好全量授权、保证充足余额(此处只校验了余额)
      // 避免 tokenlon.placeOrder 内部频繁请求余额、授权量
      if (checkBalanceEnough(o.price, o.side, { baseBalance, quoteBalance })) {
        await tokenlon.placeOrder({
          ...baseQuote,
          ...o,
        })
      }
    }
    
    

    默认值: true

    作用为在调用挂单、吃单、撤单接口时,在接口内部使用相关方法进行校验(需要余额、授权量、可吃单量、可撤单量等),来避免无效操作。

    但在校验的过程中,内部需要通过web3请求获取余额、授权量、可吃单量、可撤单量等,涉及到的请求较多。当网络延迟严重、web3 节点不稳定时,会影响挂单、撤单、吃单效率。

    因此 v0.2 以上版本提供 onChainValidate 参数,适用于对 挂单、吃单、撤单 效率要求较高的开发者。

    涉及接口:

    1. tokenlon.utils.getSignedOrderBySimpleOrderAsync (内部调用 tokenlon.zeroExWrapper.exchange.validateOrderFillableOrThrowAsync
    2. tokenlon.placeOrder (内部调用 tokenlon.utils.getSignedOrderBySimpleOrderAsync
    3. tokenlon.fillOrder (内部调用 tokenlon.zeroExWrapper.exchange.validateFillOrderThrowIfInvalidAsync
    4. tokenlon.fillOrKillOrder (内部调用 tokenlon.zeroExWrapper.exchange.validateFillOrKillOrderThrowIfInvalidAsync
    5. tokenlon.batchFillOrders (内部循环调用 tokenlon.zeroExWrapper.exchange.validateFillOrderThrowIfInvalidAsync
    6. tokenlon.batchFillOrKill (内部循环调用 tokenlon.zeroExWrapper.exchange.validateFillOrKillOrderThrowIfInvalidAsync
    7. tokenlon.cancelOrder (内部调用 tokenlon.zeroExWrapper.exchange.validateCancelOrderThrowIfInvalidAsync
    8. tokenlon.batchCancelOrders (内部循环调用 tokenlon.zeroExWrapper.exchange.validateCancelOrderThrowIfInvalidAsync

    初始化

    config 参数格式见 GlobalConfig

    初始化

    import { createTokenlon } from 'tokenlon-sdk'
    
    const config = {
      wallet,
      onChainValidate: true, // default is true
      gasPriceAdaptor: 'average',
      server: {
        url: serverUrl,
      },
      web3: {
        providerUrl,
      },
      zeroEx: zeroExConfig,
    }
    
    const run = async () => {
      const tokenlon = await createTokenlon(config)
      // do something
    }
    
    run()
    

    特性

    无需处理decimal

    示例

    const balance = await tokenlon.getTokenBalance('ZRX')
    console.log(balance) // 10000
    

    在以太坊上,智能合约调用,传递相应数量,最终都会通过对应Token的decimal处理,再上链。

    举例来说,ETH的decimal是18,想要转账1个ETH,在链上传递的参数是 1000000000000000000

    不同的Token,又有不同的decimal。因此,在拿到两个相同数量的不同表现形式后,还需要拿Token的decimal,再进行两边换算,而这增加了相应的复杂度。

    因此,Tokenlon-SDK 提供了简洁的接口,为开发者封装了 decimal的处理。开发者在调用tokenlon相关API时,传递的参数 / 获得的返回,都是所见即所得的数量。

    例如示例中,获得的10000个,即为当前钱包所拥有的ZRX数量,10000个。

    简单的参数

    0x order 形式

    {
      "exchangeContractAddress": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364",
      "maker": "0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36",
      "taker": "0x0000000000000000000000000000000000000000",
      "makerTokenAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
      "takerTokenAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
      "feeRecipient": "0x0000000000000000000000000000000000000000",
      "makerTokenAmount": "20000000000000000000",
      "takerTokenAmount": "22220000000000000",
      "makerFee": "0",
      "takerFee": "0",
      "expirationUnixTimestampSec": "1552032476",
      "salt": "43681724269174499411415138645444720680939661042486674370470466081321366610686",
      "ecSignature": {
          "v": 27,
          "r": "0x85cd3b0768be4a283243de114d12686bd94d560909b7a5da145f4bf9af81d570",
          "s": "0x0dd82fc0aa7b8d90e855e814a18995ec326d35bb3b2c319eff03882139a78a52"
      }
    }
    

    0x 是基于 maker(挂单)、taker(吃单),构建的去中心化兑换协议,详见 0x protocol。但其定义 / 传递的order形式,对于大部分人,特别是新接触者而言,并不友好。

    这个单子里,需要先通过 makerTokenAddresstakerTokenAddress,拿到对应的交易对,再获取该交易对的Token的 decimal,用于处理 makerTokenAmounttakerTokenAmount,再根据交易对的方向,处理出价格price、是买还是卖的side,才能下策略决定这个单子要不要去吃。此外,吃多少的量,又需要从所见即所得的量 通过 decimal处理出对应的数量形式。

    同理,在挂单时候,又是一系列复杂的逆向操作。

    因此,tokenlon API 封装了这部分操作,无论是在挂单、吃单、批量吃单,还是市价单,都只需要通过类似传统化交易所的接口,进行参数传递。

    tokenlon 挂单格式

    {
      "base": "SNT",
      "quote": "WETH",
      "amount": 20,
      "price": 0.001111,
      "side": "SELL"
    }
    

    tokenlon 吃单格式

    {
      "side": "BUY",
      "price": 0.00034,
      "amount": 0.01,
      "expirationUnixTimestampSec": 1551170972,
      "rawOrder": "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0x20f0c6e79a763e1fe83de1fbf08279aa3953fb5f\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"takerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"10000000000000000\",\"takerTokenAmount\":\"3400000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1551170972\",\"salt\":\"15447773907054777000000000000000000000000000000000000000000000000000000000000\",\"ecSignature\":{\"v\":27,\"r\":\"0xc09abbc4b49cdf61c2f0dedf38ed8f618071f70d179280e389e2cb90a500892e\",\"s\":\"0x54a5a7a70253dd7e023ffab04183f8073a50bc8d9683fe37357cd0d89e38a04d\"}}"
    }
    

    其中,rawOrder 字段在 tokenlon 相关封装后的后端交互接口中返回,代表要针对这个单进行处理(买卖、撤单等)。

    从语义化的角度来讲,相信也为广大开发者降低了些许对接的门槛和时间成本。

    私钥发送签名

    可能是为了安全和担心误操作的考虑,类似metamask这类工具,在每次用户发送一笔转账 / 合约调用时,都会要求用户输入密码,用以配对,解开私钥,再进行签名、广播交易。

    而对于一个量化交易机器人 / 自动化交易程序而言,总不可能开发者每进行一步操作,还需要通过命令行提醒一下“您该输入密码了”。

    因而,tokenlon API 对 0x.js 进行了部分封装、覆盖,覆盖了 0x.js 相应签名发送转账交易的接口,不再是输入密码解开私钥,而是直接获取开发者在配置中设置的私钥,进行签名、广播交易

    这让一个基于 0x protocol 的自动化交易程序成为了可能。

    Tokenlon

    支持的交易对与Token

    tokenlon.getPairs

    示例

    await tokenlon.getPairs()
    

    返回数据格式

    [
      {
        "id": 458,
        "market": "Tokenlon",
        "base": {
            "symbol": "SNT",
            "contractAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
            "decimal": 18
        },
        "quote": {
            "symbol": "WETH",
            "contractAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
            "decimal": 18
        },
        "infoUrl": "",
        "tags": [
            "HOT"
        ],
        "relayFee": {
            "relayRecipient": "",
            "makerFee": "",
            "takerFee": ""
        },
        "instantExEnabled": true,
        "marketEnabled": true,
        "tradingEnabled": true,
        "anchored": false,
        "protocol": "0x",
        "rank": 101,
        "precision": 8,
        "quoteMinUnit": 0.0001
      }
      // ...
    ]
    

    获取 tokenlon 所有支持的交易对列表

    Returns

    Result Type Description
    array Promsise<Pair.ExchangePair[]> 交易对数组

    tokenlon.getPairInfo

    示例

    await tokenlon.getPairInfo({ base: 'SNT', quote: 'WETH' })
    

    返回数据格式

    {
      "id": 458,
      "market": "Tokenlon",
      "base": {
          "symbol": "SNT",
          "contractAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
          "decimal": 18
      },
      "quote": {
          "symbol": "WETH",
          "contractAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
          "decimal": 18
      },
      "infoUrl": "",
      "tags": [
          "HOT"
      ],
      "relayFee": {
          "relayRecipient": "",
          "makerFee": "",
          "takerFee": ""
      },
      "instantExEnabled": true,
      "marketEnabled": true,
      "tradingEnabled": true,
      "anchored": false,
      "protocol": "0x",
      "rank": 101,
      "precision": 8,
      "quoteMinUnit": 0.0001
    }
    

    tokenlon.getPairs 接口的一个语法糖,获取指定交易对信息

    Arguments

    Params Type Required Default Description
    baseQuote Tokenlon.BaseQuote true - base, quote 必须为大写字母

    Returns

    Result Type Description
    object Promise<Pair.ExchangePair> 具体的交易对信息

    tokenlon.getTokenInfo

    示例

    await tokenlon.getTokenInfo('SNT')
    

    返回数据格式

    {
      "symbol": "SNT",
      "contractAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
      "decimal": 18
    }
    

    tokenlon.getPairs 接口的一个语法糖,获取指定交易Token的信息

    Arguments

    Params Type Required Default Description
    tokenName string true - tokenName 必须为大写字母

    Returns

    Result Type Description
    object Promise<Pair.ExchangePairToken> 具体的交易对Token信息

    ETH与WETH

    tokenlon.deposit

    // 将2个ETH转换为2个WETH
    await tokenlon.deposit(2)
    

    返回数据格式

    "0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea"
    

    将 ETH 转换为 ERC-20 WETH Token

    Arguments

    Params Type Required Default Description
    amount number true - amount为已经使用decimal处理过的可见数量
    opts Tokenlon.TxOpts fasle - gasPricenumber。 传递的gasPricegasLimit会作为最终参数进行上链操作

    Returns

    Result Type Description
    object Promise<string> string 为 txHash

    示例

    tokenlon.withdraw

    示例

    // 将2个WETH转换为2个ETH
    await tokenlon.withdraw(2)
    

    返回数据格式

    "0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea"
    

    tokenlon.deposit的逆向操作,将 ERC-20 WETH Token 转换为 ETH

    Arguments

    Params Type Required Default Description
    amount number true - amount为已经使用decimal处理过的可见数量
    opts Tokenlon.TxOpts fasle - gasPricenumber。 传递的gasPricegasLimit会作为最终参数进行上链操作

    Returns

    Result Type Description
    object Promise<string> string 为 txHash

    余额与授权

    tokenlon.getTokenBalance

    示例

    // 获取当前配置钱包的 ETH 余额
    await tokenlon.getTokenBalance('ETH')
    
    // 获取当前 0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36 地址的 WETH 余额
    await tokenlon.getTokenBalance('WETH', '0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36')
    

    返回数据格式

    109.98084968041424
    

    获取当前钱包的 ETH / Token 余额

    Arguments

    Params Type Required Default Description
    tokenName string true - tokenName 必须为大写字母
    address string false 当前配置的 config.wallet.address 钱包地址 获取哪个地址的余额情况

    Returns

    Result Type Description
    amount Promise<number> amount为已经使用decimal处理过的可见数量

    tokenlon.getAllowance

    示例

    // 获取当前配置钱包的授权给 0x 代理地址的 WETH 数量
    await tokenlon.getAllowance('WETH')
    
    // 获取 0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36 授权给 0x 代理地址的 SNT 数量
    await tokenlon.getAllowance('SNT', '0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36')
    

    返回的是一个number类型,数量非常大,可以认为这个地址将对应的Token全量授权给了0x 代理地址。

    返回数据格式

    5.78960446186581e+58
    

    获取当前钱包某个 ERC-20 Token 授权给 0x 代理地址 tokenTransferProxyContractAddress 的 token 可操作数量。

    Arguments

    Params Type Required Default Description
    tokenName string true - tokenName 必须为大写字母
    address string false 当前配置的 config.wallet.address 钱包地址 获取具体哪个地址的授权数量情况

    Returns

    Result Type Description
    amount Promise<number> amount为已经使用decimal处理过的可见数量

    tokenlon.setAllowance

    示例

    // 将当前配置钱包 10个WETH 授权给 0x 代理地址,用于智能合约发生兑换时可以正常执行 / 成功
    await tokenlon.setAllowance('WETH', 10)
    

    返回数据格式

    "0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea"
    

    0x的订单在智能合约上进行成交 / 发送兑换,需要0x 代理地址,进行买方、卖方的token转账,因此我们需要授权相应数量的 Token 给 0x 代理地址。

    关于授权:

    1. 代理地址可以调用钱包该Token的 transfer 方法,进行转账。而 0x 代理地址,在没有订单成交 / 合约调用的情况下,是不会“通知” 代理地址进行转账的,除非因为一些不可抗因素,例如 合约Bug。
    2. 即使做了授权,但是钱包内的 Token 在没有订单成交的情况下,不会减少。这就意味着,做了授权之后,钱包内该Token的转账仍旧可以照常进行。
    3. 当做了授权后,该笔订单被对手方吃单,在智能合约上发生调用,0x 代理地址才会对双方钱包地址进行Token的转账。而在发生这部分操作时,如果授权关闭了 / 钱包内该Token余额不足,该笔交易失败。

    Arguments

    Params Type Required Default Description
    tokenName string true - tokenName 必须为大写字母
    amount number true - amount不需要经过 decimal 处理
    opts Tokenlon.TxOpts fasle - gasPricenumber。 传递的gasPricegasLimit会作为最终参数进行上链操作

    Returns

    Result Type Description
    object Promise<string> string 为 txHash

    tokenlon.setUnlimitedAllowance

    示例

    // 将当前配置钱包 WETH 全部授权给 0x 代理地址,用于智能合约发生兑换时可以正常执行 / 成功
    await tokenlon.setUnlimitedAllowance('WETH')
    

    返回数据格式

    "0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea"
    

    为了方便订单成交,而不需要每次管理授权的基于tokenlon.setAllowance的语法糖,功能进行最大授权操作。

    具体授权数量使用 0x 默认的 UNLIMITED_ALLOWANCE_IN_BASE_UNITSnew BigNumber(2).pow(256).minus(1),即 2的256次方减1的数量。

    Arguments

    Params Type Required Default Description
    tokenName string true - tokenName 必须为大写字母
    opts Tokenlon.TxOpts fasle - gasPricenumber。 传递的gasPricegasLimit会作为最终参数进行上链操作

    Returns

    Result Type Description
    object Promise<string> string 为 txHash

    交易信息

    tokenlon.getOrderBook

    示例

    await tokenlon.getOrderBook({
      base: 'SNT',
      quote: 'WETH',
    })
    

    返回数据格式

    {
      "asks": [
        {
          "side": "SELL",
          "price": 0.00034,
          "amount": 0.01,
          "amountTotal": 200,
          "isMaker": true,
          "expirationUnixTimestampSec": 1551170972,
          "rawOrder": "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0x20f0c6e79a763e1fe83de1fbf08279aa3953fb5f\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"takerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"10000000000000000\",\"takerTokenAmount\":\"3400000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1551170972\",\"salt\":\"15447773907054777000000000000000000000000000000000000000000000000000000000000\",\"ecSignature\":{\"v\":27,\"r\":\"0xc09abbc4b49cdf61c2f0dedf38ed8f618071f70d179280e389e2cb90a500892e\",\"s\":\"0x54a5a7a70253dd7e023ffab04183f8073a50bc8d9683fe37357cd0d89e38a04d\"}}"
        }
        // ...
      ],
      "bids": [
        {
          "side": "BUY",
          "price": 0.000255,
          "amount": 100,
          "amountTotal": 200,
          "isMaker": false,
          "expirationUnixTimestampSec": 1551342565,
          "rawOrder": "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0x75eb52e0265b80d5eac78e714b85ea9e199013aa\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"takerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"25500000000000000\",\"takerTokenAmount\":\"100000000000000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1551342565\",\"salt\":\"76669967321507220000000000000000000000000000000000000000000000000000000000000\",\"ecSignature\":{\"v\":27,\"r\":\"0x8afe8a8e4f7d18b65ae8e28ded6dcea22a80b7997b73d75d93b4b04a4dcca3e9\",\"s\":\"0x5abe9f4928b0b9ad1e46083c406adbfd9441897e39ab2eb82869653a39e2d5ab\"}}"
        }
        // ...
      ]
    }
    

    通过传递 basequote 获取 订单列表。

    返回的订单格式是类传统化交易所的订单格式,并且,0x 的订单格式会通过 JSON.stringify 转换为 rawOrder 返回,rawOrder 作为一个统一、单独的字段,用于吃单。其中,amount代表这笔订单剩余可成交的量(伴随链上吃单、链上撤单情况更新),amountTotal代表这笔订单原可成交 base 总量。

    Arguments

    Params Type Required Default Description
    baseQuote Tokenlon.BaseQuote true - base, quote 必须为大写字母

    Returns

    Result Type Description
    object Promise<Tokenlon.OrderBookResult> 订单信息中,isMaker字段,代表这个订单是否是当前钱包config.wallet挂出的单

    tokenlon.getOrders

    示例

    await tokenlon.getOrders({
      base: 'SNT',
      quote: 'WETH',
      page: 1,
      perpage: 20,
    })
    

    返回数据格式

    [
      {
        "side": "BUY",
        "price": 0.001111,
        "amount": 20,
        "amountTotal": 200,
        "expirationUnixTimestampSec": 1552031755,
        "rawOrder": "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"takerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"22220000000000000\",\"takerTokenAmount\":\"20000000000000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1552031755\",\"salt\":\"48847617304836587184218437964024195445423260754840613284444648760400900578804\",\"ecSignature\":{\"v\":28,\"r\":\"0xeafa23489bf35b57bc693fbf590c99dd4239722a2edfcc852653bae858ee987b\",\"s\":\"0x7d04686e0859ac1c6885da811302c863b2fd321dcacc45cda565c7b318865114\"}}"
      },
      {
        "side": "SELL",
        "price": 0.001111,
        "amount": 20,
        "amountTotal": 200,
        "expirationUnixTimestampSec": 1552032476,
        "rawOrder": "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"takerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"20000000000000000000\",\"takerTokenAmount\":\"22220000000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1552032476\",\"salt\":\"43681724269174499411415138645444720680939661042486674370470466081321366610686\",\"ecSignature\":{\"v\":27,\"r\":\"0x85cd3b0768be4a283243de114d12686bd94d560909b7a5da145f4bf9af81d570\",\"s\":\"0x0dd82fc0aa7b8d90e855e814a18995ec326d35bb3b2c319eff03882139a78a52\"}}"
      },
      ...
    ]
    

    通过 basequote 获取当前钱包挂单列表

    Arguments

    Params Type Required Default Description
    Params Tokenlon.GetOrdersParams true - base, quote 必须为大写字母

    Returns

    Result Type Description
    object Promise<Tokenlon.OrderBookItem[]> 挂出的有效单 order 数组

    tokenlon.getOrder

    示例

    await tokenlon.getOrder(rawOrder)
    

    返回数据格式

    {
      "side": "BUY",
      "price": 0.001111,
      "amount": 20,
      "amountTotal": 200,
      "expirationUnixTimestampSec": 1552031755,
      "rawOrder": "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"takerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"22220000000000000\",\"takerTokenAmount\":\"20000000000000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1552031755\",\"salt\":\"48847617304836587184218437964024195445423260754840613284444648760400900578804\",\"ecSignature\":{\"v\":28,\"r\":\"0xeafa23489bf35b57bc693fbf590c99dd4239722a2edfcc852653bae858ee987b\",\"s\":\"0x7d04686e0859ac1c6885da811302c863b2fd321dcacc45cda565c7b318865114\"}}",
      "trades": [{
        "id": 8,
        "price": 0.00016421,
        "amount": 110.12356129346568,
        "timestamp": 1527057048,
        "txHash": "0xae6e54b9006d8f812ac18e804980d84605abf65c36aac7188e133c22db045171"
      }]
    }
    

    通过 rawOrder 获取订单具体信息,包括该笔订单交易记录

    Arguments

    Params Type Required Default Description
    rawOrder string true - 对应的 rawOrder 字符串

    Returns

    Result Type Description
    object Promise<Tokenlon.OrderDetail> tokenlon.getOrders 不同的是,添加了 trades 字段

    tokenlon.getMakerTrades

    示例

    const now = Math.floor(Date.now() / 1000)
    await tokenlon.getMakerTrades({
      base: 'SNT',
      quote: 'WETH',
      page: 1,
      perpage: 20,
      // 获取近一年挂单被成交记录
      timeRange: [now - 365 * 86400, now]
    })
    

    返回数据格式

    [
      {
        "id": 21555,
        "price": 0.00016421,
        "amount": 110.12356129346568,
        "tradeType": "bid",
        "side": "BUY",
        "timestamp": 1527056944,
        "amountRemaining": 70.7103761,
        "expirationUnixTimestampSec": "1527060545",
        "rawOrder": "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0x20f0c6e79a763e1fe83de1fbf08279aa3953fb5f\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"takerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"feeRecipient\":\"0x6f7ae872e995f98fcd2a7d3ba17b7ddfb884305f\",\"makerTokenAmount\":\"40053744052658000\",\"takerTokenAmount\":\"200278734200000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1527076156\",\"salt\":\"14369837435448330357568565681144815538872002803647102464670480132035762359371\",\"ecSignature\":{\"v\":28,\"r\":\"0x1a08f7e01676e039c80895f2265a3e1818cc8a0ab58281e6c5c0ac8d7c8977c2\",\"s\":\"0x746ad6346b4a426ecb623cc3aef8a23ac3335219799781ddeb21f163cd6c2a1d\"}}",
        "trades": [
          {
            "id": 8,
            "price": 0.00016421,
            "amount": 110.12356129346568,
            "timestamp": 1527057048,
            "txHash": "0xae6e54b9006d8f812ac18e804980d84605abf65c36aac7188e133c22db045171"
          }
        ]
      }
    ]
    

    通过 basequote 获取当前钱包的挂单 被成交记录timeRange代表时间区间,为一个数组,第一项为开始时间时间戳,第二项为结束时间时间戳。

    Arguments

    Params Type Required Default Description
    Params Tokenlon.TradesParams true - base, quote 必须为大写字母

    Returns

    Result Type Description
    object Promise<Tokenlon.MakerTradesItem[]> -

    tokenlon.getTakerTrades

    示例

    const now = Math.floor(Date.now() / 1000)
    await tokenlon.getTakerTrades({
      base: 'SNT',
      quote: 'WETH',
      page: 1,
      perpage: 20,
      timeRange: [now - 365 * 86400, now]
    })
    

    返回数据格式

    [
      {
        "id": 38,
        "price": 5000.2500125,
        "amount": 100.1393671,
        "tradeType": "ask",
        "side": "SELL",
        "timestamp": 1527075768,
        "amountRemaining": 0,
        "txHash": "0x2aa141defef4c279db1a03f84dfee077f175e21244d1b1f3388e4c112e700cff",
        "rawOrder": "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0x20f0c6e79a763e1fe83de1fbf08279aa3953fb5f\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"takerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"feeRecipient\":\"0x6f7ae872e995f98fcd2a7d3ba17b7ddfb884305f\",\"makerTokenAmount\":\"40053744052658000\",\"takerTokenAmount\":\"200278734200000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1527076156\",\"salt\":\"14369837435448330357568565681144815538872002803647102464670480132035762359371\",\"ecSignature\":{\"v\":28,\"r\":\"0x1a08f7e01676e039c80895f2265a3e1818cc8a0ab58281e6c5c0ac8d7c8977c2\",\"s\":\"0x746ad6346b4a426ecb623cc3aef8a23ac3335219799781ddeb21f163cd6c2a1d\"}}"
      }
    ]
    

    通过 basequote 获取当前钱包的吃单 成交记录timeRange代表时间区间,为一个数组,第一项为开始时间时间戳,第二项为结束时间时间戳。

    需要注意的是,getTakerTradesgetMakerTrades 参数一致,但是返回的数据结构不同。

    Arguments

    Params Type Required Default Description
    Params Tokenlon.TradesParams true - base, quote 必须为大写字母

    Returns

    Result Type Description
    object Promise<Tokenlon.TakerTradesItem[]> -

    挂单

    tokenlon.placeOrder

    示例

    await tokenlon.placeOrder({
      base: 'SNT',
      quote: 'WETH',
      amount: 20,
      price: 0.001111,
      side: 'BUY',
      expirationUnixTimestampSec: 1552032476,
    })
    

    返回数据格式

    {
      "isMaker": true,
      "base": "SNT",
      "quote": "WETH",
      "amount": 20,
      "price": 0.001111,
      "side": "BUY",
      "expirationUnixTimestampSec": 1552032476,
      "rawOrder": "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"takerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"20000000000000000000\",\"takerTokenAmount\":\"22220000000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1552032476\",\"salt\":\"43681724269174499411415138645444720680939661042486674370470466081321366610686\",\"ecSignature\":{\"v\":27,\"r\":\"0x85cd3b0768be4a283243de114d12686bd94d560909b7a5da145f4bf9af81d570\",\"s\":\"0x0dd82fc0aa7b8d90e855e814a18995ec326d35bb3b2c319eff03882139a78a52\"}}"
    }
    

    通过类传统化交易所订单形式的参数,使用当前配置钱包,生成0x形式订单,并且将其发送到imToken服务器

    Arguments

    Params Type Required Default Description
    Params Tokenlon.SimpleOrderWithBaseQuote true - base, quote 必须为大写字母

    Returns

    Result Type Description
    object Promise<Tokenlon.OrderBookItem> 挂出的订单信息

    吃单

    Tokenlon-SDK吃单 API,在接口内部会发送智能合约调用进行吃单处理,并且将 ordertxHash 发送至imToken服务器,提前标记此部分订单被吃单,暂时不进行该订单的返回,来减少抢单的发生

    txHash 正式确认打包,链上相关订单状态稳定后,再更新具体订单剩余量、订单状态返回。

    tokenlon.fillOrder

    示例

    await tokenlon.fillOrder({
      "side": "BUY",
      "base": "SNT",
      "quote": "WETH",
      "price": 0.001111,
      "amount": 20,
      "expirationUnixTimestampSec": 1552032476,
      "rawOrder": "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"takerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"20000000000000000000\",\"takerTokenAmount\":\"22220000000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1552032476\",\"salt\":\"43681724269174499411415138645444720680939661042486674370470466081321366610686\",\"ecSignature\":{\"v\":27,\"r\":\"0x85cd3b0768be4a283243de114d12686bd94d560909b7a5da145f4bf9af81d570\",\"s\":\"0x0dd82fc0aa7b8d90e855e814a18995ec326d35bb3b2c319eff03882139a78a52\"}}"
    })
    

    返回数据格式

    "0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea"
    

    吃掉一个买单 / 卖单。

    接口内部会校验交易操作(买 / 卖) side、价格pricebasequote 是否与这个 rawOrder 匹配。

    如果 rawOrder 代表的是卖单,而 fillOrder 需要传递 side BUY 来进行买的操作,语义上可以理解为,买这个单子相应数量的Token,来填充这个卖单想要的数量。

    买单同理。

    如果 rawOrder 对应的订单,无法满足数量 amount,最终结果还是会以设定的价格成交,成交的数量是这个单子剩余能被填充的数量

    Arguments

    Params Type Required Default Description
    Params Tokenlon.FillOrderParams true - -
    opts Tokenlon.TxOpts fasle - gasPricenumber。 传递的gasPricegasLimit会作为最终参数进行上链操作

    Returns

    Result Type Description
    object Promise<string> string 为 txHash

    tokenlon.batchFillOrders

    示例

    await tokenlon.batchFillOrders([{
      "side": "BUY",
      "base": "SNT",
      "quote": "WETH",
      "price": 0.001111,
      "amount": 20,
      "expirationUnixTimestampSec": 1552032476,
      "rawOrder": "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"takerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"20000000000000000000\",\"takerTokenAmount\":\"22220000000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1552032476\",\"salt\":\"43681724269174499411415138645444720680939661042486674370470466081321366610686\",\"ecSignature\":{\"v\":27,\"r\":\"0x85cd3b0768be4a283243de114d12686bd94d560909b7a5da145f4bf9af81d570\",\"s\":\"0x0dd82fc0aa7b8d90e855e814a18995ec326d35bb3b2c319eff03882139a78a52\"}}"
    }])
    

    返回数据格式

    "0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea"
    

    批量吃单,tokenlon.fillOrder的批量形式,最终在区块链上只会发生一笔智能合约调用,生成一个 txHash,适用于想要吃掉多个单并且提高时效性、减少矿工费的情况。

    Arguments

    Params Type Required Default Description
    Params Tokenlon.FillOrderParams[] true - -
    opts Tokenlon.TxOpts fasle - gasPricenumber。 传递的gasPricegasLimit会作为最终参数进行上链操作

    Returns

    Result Type Description
    object Promise<string> string 为 txHash

    tokenlon.fillOrKillOrder

    示例

    await tokenlon.fillOrKillOrder({
      "side": "BUY",
      "base": "SNT",
      "quote": "WETH",
      "price": 0.001111,
      "amount": 20,
      "expirationUnixTimestampSec": 1552032476,
      "rawOrder": "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"takerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"20000000000000000000\",\"takerTokenAmount\":\"22220000000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1552032476\",\"salt\":\"43681724269174499411415138645444720680939661042486674370470466081321366610686\",\"ecSignature\":{\"v\":27,\"r\":\"0x85cd3b0768be4a283243de114d12686bd94d560909b7a5da145f4bf9af81d570\",\"s\":\"0x0dd82fc0aa7b8d90e855e814a18995ec326d35bb3b2c319eff03882139a78a52\"}}"
    })
    

    返回数据格式

    "0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea"
    

    参数、功能与tokenlon.fillOrder相同。但不同之处在于,如果设定的买 / 卖数量 amount 这个单子无法满足这个方法会抛出异常,而 tokenlon.fillOrder 如果不满足,会把单子剩余能吃的量吃掉。

    其适用场景举例来说,某个单子只有1000个SNT,但是因为价格优惠,如果使用 tokenlon.fillOrder 不确定最终成交量是多少。而如果最终成交只有100个,其对应赚取的价值,可能不够ETH矿工费价值的消耗。而使用 tokenlon.fillOrKillOrder,就避免了这个问题。如果想要成交1000个SNT无法满足,就不进行后续操作。

    Arguments

    Params Type Required Default Description
    Params Tokenlon.FillOrderParams true - -
    opts Tokenlon.TxOpts fasle - gasPricenumber。 传递的gasPricegasLimit会作为最终参数进行上链操作

    Returns

    Result Type Description
    object Promise<string> string 为 txHash

    tokenlon.batchFillOrKill

    示例

    await tokenlon.batchFillOrKill([{
      "side": "BUY",
      "base": "SNT",
      "quote": "WETH",
      "price": 0.001111,
      "amount": 20,
      "expirationUnixTimestampSec": 1552032476,
      "rawOrder": "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"takerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"20000000000000000000\",\"takerTokenAmount\":\"22220000000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1552032476\",\"salt\":\"43681724269174499411415138645444720680939661042486674370470466081321366610686\",\"ecSignature\":{\"v\":27,\"r\":\"0x85cd3b0768be4a283243de114d12686bd94d560909b7a5da145f4bf9af81d570\",\"s\":\"0x0dd82fc0aa7b8d90e855e814a18995ec326d35bb3b2c319eff03882139a78a52\"}}"
    }])
    

    返回数据格式

    "0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea"
    

    批量吃单,tokenlon.fillOrKillOrder的批量形式,最终在区块链上只会发生一笔智能合约调用,生成一个 txHash,适用于想要吃掉多个单并且提高时效性、减少矿工费的情况。

    Arguments

    Params Type Required Default Description
    Params Tokenlon.FillOrderParams[] true - -
    opts Tokenlon.TxOpts fasle - gasPricenumber。 传递的gasPricegasLimit会作为最终参数进行上链操作

    Returns

    Result Type Description
    object Promise<string> string 为 txHash

    tokenlon.fillOrdersUpTo

    示例

    await tokenlon.fillOrdersUpTo({
      "side": "BUY",
      "base": "SNT",
      "quote": "WETH",
      "amount": 20,
      "rawOrders": [
        "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"takerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"20000000000000000000\",\"takerTokenAmount\":\"22220000000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1552032476\",\"salt\":\"43681724269174499411415138645444720680939661042486674370470466081321366610686\",\"ecSignature\":{\"v\":27,\"r\":\"0x85cd3b0768be4a283243de114d12686bd94d560909b7a5da145f4bf9af81d570\",\"s\":\"0x0dd82fc0aa7b8d90e855e814a18995ec326d35bb3b2c319eff03882139a78a52\"}}",
        // ...
      ]
    })
    

    返回数据格式

    "0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea"
    

    针对一批单子rawOrders,指定一个数量amount,依次开始进行订单成交,直到满足数量 amount为止。类似于传统中心化交易所的市价单功能。

    如果 amount 数量过大,超过了传递的这些单所有的数量,最终成交的就是这些单子所有可成交的数量总和。 如果 amount 数量较小,会进行依次吃单,从订单一、订单二,以此类推,直到 amount 被满足为止。考虑到价格因素,此接口内部会将这些单子做排序(买单价格从高到底、卖单价格从低到高),尽量以更便宜的价格来满足对应的数量。

    部分适用场景举例:

    一批价格相近的订单,不确定其中部分单子的情况,也有可能其中部分单子已经被成交,或者部分单子价格虽低但是数量极少,而使用 tokenlon.fillOrder / tokenlon.batchFillOrders / tokenlon.fillOrKillOrder / tokenlon.batchFillOrKill 需要对每一个单子指定吃单数量,较难考量矿工费情况,以及每笔单子应该设置多少数量,可以考虑使用此方法。

    注意:

    rawOrders 对应的订单,必须是同一个方向side、同一个交易对pair

    Arguments

    Params Type Required Default Description
    Params Tokenlon.FillOrdersUpTo true - -
    opts Tokenlon.TxOpts fasle - gasPricenumber。 传递的gasPricegasLimit会作为最终参数进行上链操作

    Returns

    Result Type Description
    object Promise<string> string 为 txHash

    撤单

    tokenlon.cancelOrder

    示例

    await tokenlon.cancelOrder(
      "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"takerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"20000000000000000000\",\"takerTokenAmount\":\"22220000000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1552032476\",\"salt\":\"43681724269174499411415138645444720680939661042486674370470466081321366610686\",\"ecSignature\":{\"v\":27,\"r\":\"0x85cd3b0768be4a283243de114d12686bd94d560909b7a5da145f4bf9af81d570\",\"s\":\"0x0dd82fc0aa7b8d90e855e814a18995ec326d35bb3b2c319eff03882139a78a52\"}}",
      false
    )
    

    返回数据格式

    // onChain = true
    "0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea"
    
    // onChain = false
    "ok"
    

    撤销一个订单。

    onChain参数代表这个订单撤销的操作是否通过发送智能合约交易来确保该笔订单永远不会被成交。

    onChain 设定为 true 时,会发送撤单的合约调用,而 0x 协议会在链上标记该订单永远不会被成交,而这个操作需要消耗矿工费。并且,接口内部会调用 tokenlon.server.cancelOrdersWithHash 传递 txHash 用于检查,如果该笔撤单上链操作智能合约调用失败,此订单会被认为撤单失败,被正常返回

    onChain 不传递或设定 false 时,不会发送撤单的合约调用,但会发送撤单请求 tokenlon.server.cancelOrdersimToken服务器,来让该笔订单不会再在 getOrderBook 以及token 2.0的订单列表中返回与出现。并且,不再处理 opts 参数

    因为 0x 的机制,是通过私钥签名来生有效、可成交订单,再通过server“广播”来让其他人浏览到该笔订单。可以理解为server“广播”(例如 tokenlon.getOrderBook)只是为了让更多人知道这个单子。

    因此不传递 onChain 参数,只是隐藏了该笔订单的展现,如果该笔订单被人存储过,在未来的某年某月,还是有会被成交(除非关闭了授权、钱包里没有余额)的可能。

    建议: 考虑到撤单上链的矿工费消耗,以及不上链实际上并不是真实撤单而只是做了隐藏(还是有可能会被成交),建议开发者通过 tokenlon.placeOrder 接口挂单时,设置尽量较近的时间戳,来让订单过期自动失效,而尽量少使用撤单API。

    注意: 0x protocol 允许设定具体的撤单数量,比如说10000个SNT的挂单,可以通过API撤销 1000个,剩下9000个仍然可以正常成交。

    tokenlon.cancelOrder 为了方便开发者管理,取消了这个参数设定,撤单的操作,统一进行全部撤销(不包括已成交数量)。

    Arguments

    Params Type Required Default Description
    schema string true - -
    onChain boolean false - -
    opts Tokenlon.TxOpts fasle - gasPricenumber。 传递的gasPricegasLimit会作为最终参数进行上链操作

    Returns

    Result Type Description
    object Promise<string> onChain=true 时string 为 txHash;当 onChain=false 时string 为 'ok'

    tokenlon.batchCancelOrders

    await tokenlon.batchCancelOrders([
      "{\"exchangeContractAddress\":\"0x90fe2af704b34e0224bf2299c838e04d4dcf1364\",\"maker\":\"0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36\",\"taker\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAddress\":\"0xf26085682797370769bbb4391a0ed05510d9029d\",\"takerTokenAddress\":\"0xd0a1e359811322d97991e03f863a0c30c2cf029c\",\"feeRecipient\":\"0x0000000000000000000000000000000000000000\",\"makerTokenAmount\":\"20000000000000000000\",\"takerTokenAmount\":\"22220000000000000\",\"makerFee\":\"0\",\"takerFee\":\"0\",\"expirationUnixTimestampSec\":\"1552032476\",\"salt\":\"43681724269174499411415138645444720680939661042486674370470466081321366610686\",\"ecSignature\":{\"v\":27,\"r\":\"0x85cd3b0768be4a283243de114d12686bd94d560909b7a5da145f4bf9af81d570\",\"s\":\"0x0dd82fc0aa7b8d90e855e814a18995ec326d35bb3b2c319eff03882139a78a52\"}}",
      // ...
    ], false)
    

    返回数据格式

    // onChain = true
    "0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea"
    
    // onChain = false
    "ok"
    

    批量撤单,tokenlon.cancelOrder 的批量形式,最终在区块链上只会发生一笔智能合约调用,生成一个 txHash,适用于想要使用更少量矿工费一次性撤销多笔订单的情况。

    onChain 参数含义同 tokenlon.cancelOrder

    Arguments

    Params Type Required Default Description
    schemas string[] true - -
    onChain boolean false - -
    opts Tokenlon.TxOpts fasle - gasPricenumber。 传递的gasPricegasLimit会作为最终参数进行上链操作

    Returns

    Result Type Description
    object Promise<string> onChain=true 时string 为 txHash;当 onChain=false 时string 为 'ok'

    底层暴露方法

    辅助方法

    此处辅助方法,主要用于一些特殊场景,例如与其他基于 0x 的交易所对接,进行搬砖套利等。而其他大部分交易所的 order 形式大多维持 0x 的订单格式。

    因此此处提供的方法主要用于处理这部分开发者需要在部分情况下想要自行处理数据结构的情况。

    tokenlon.utils.getSimpleOrderWithBaseQuote

    示例

    tokenlon.getSimpleOrderWithBaseQuote({
      exchangeContractAddress: '0x90fe2af704b34e0224bf2299c838e04d4dcf1364',
      maker: '0x20f0c6e79a763e1fe83de1fbf08279aa3953fb5f',
      taker: '0x0000000000000000000000000000000000000000',
      makerTokenAddress: '0xf26085682797370769bbb4391a0ed05510d9029d',
      takerTokenAddress: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
      feeRecipient: '0x0000000000000000000000000000000000000000',
      makerTokenAmount: '10000000000000000',
      takerTokenAmount: '1940000000000',
      makerFee: '0',
      takerFee: '0',
      expirationUnixTimestampSec: '1549361646',
      salt: '42214642756128894000000000000000000000000000000000000000000000000000000000000',
      ecSignature: {
        v: 28,
        r: '0x60dcd418568f7fa56104fb6c9ac66eeb6443994a082eeebf8376ebd400430b78',
        s: '0x06dbdf8b6b92c93e96b79c5fafe70f3caff21b338efc1ad00ec7025120ea4841',
      },
    })
    

    返回数据格式

    {
      side: "SELL",
      base: "SNT",
      quote: "WETH",
      amount: 0.01,
      price: 0.000194,
      expirationUnixTimestampSec: 1549361646,
    }
    

    将 0x order 格式转换为传统中心化交易所的 order 格式,并且补充上 basequote

    当获取其他交易所对应 0x 格式 order 时,可通过此方法将其转化为 更易理解的方法,用来与判断是否进行相关操作。

    Arguments

    Params Type Required Default Description
    order DexOrderBNToString true - -

    Returns

    Result Type Description
    simpleOrderWithBaseQuote Tokenlon.SimpleOrderWithBaseQuote -

    tokenlon.utils.getSignedOrderBySimpleOrderAsync

    示例

    await tokenlon.utils.getSignedOrderBySimpleOrderAsync({
      base: 'SNT',
      quote: 'WETH',
      amount: 20,
      price: 0.001111,
      side: 'BUY',
    })
    

    返回数据格式

    {
      "exchangeContractAddress": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364",
      "maker": "0x20f0c6e79a763e1fe83de1fbf08279aa3953fb5f",
      "taker": "0x0000000000000000000000000000000000000000",
      "makerTokenAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
      "takerTokenAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
      "feeRecipient": "0x0000000000000000000000000000000000000000",
      "makerTokenAmount": "10000000000000000",
      "takerTokenAmount": "1940000000000",
      "makerFee": "0",
      "takerFee": "0",
      "expirationUnixTimestampSec": "1549361646",
      "salt": "42214642756128894000000000000000000000000000000000000000000000000000000000000",
      "ecSignature": {
        "v": 28,
        "r": "0x60dcd418568f7fa56104fb6c9ac66eeb6443994a082eeebf8376ebd400430b78",
        "s": "0x06dbdf8b6b92c93e96b79c5fafe70f3caff21b338efc1ad00ec7025120ea4841"
      }
    }
    

    将 传统中心化交易所的 order 格式 转换为 0x order 格式。接口内部会使用 ZeroEx.generatePseudoRandomSalt 生成 salt,并通过配置的钱包私钥对 处理后的 ordersalt 进行签名,生成 ecSignature,来处理出 0x order 格式。

    tokenlon.placeOrder 内部即调用此方法来进行挂单。

    调用此接口,获得的 0x order 格式订单,可以通过底层 tokenlon.server.placeOrder 发送到imToken服务器(这两步操作的等同于 tokenlon.placeOrder),也可以将订单发送到其他基于 0x 的交易所

    注意:此 utils 方法返回Promise

    Arguments

    Params Type Required Default Description
    Params Tokenlon.SimpleOrderWithBaseQuote true - base, quote 必须为大写字母

    Returns

    Result Type Description
    simpleOrderWithBaseQuote Promise<DexOrderBNToString> -

    tokenlon.utils.orderBNToString

    因 0x 通过 web3.js 发送智能合约上链的 order 相关字段是 BigNumber,参考 Interface SignedOrderimToken服务器接受的相关字段为字符串。

    此方法主要用于此部分转换。

    Arguments

    Params Type Required Default Description
    Params Dex.SignedDexOrder true - base, quote 必须为大写字母

    Returns

    Result Type Description
    DexOrderBNToString DexOrderBNToString -

    tokenlon.utils.orderStringToBN

    tokenlon.utils.orderBNToString 的逆向操作。

    用于处理出 0x.js Interface SignedOrder,其相关字段为 BigNumber,主要用于可能的开发者自发上链操作。

    Arguments

    Params Type Required Default Description
    Params DexOrderBNToString true - base, quote 必须为大写字母

    Returns

    Result Type Description
    Params Dex.SignedDexOrder true

    0x.js 覆盖

    特性-私钥发送签名 中,有提到,为了不需要输入密码,我们封装了 0x.js 相应签名发送转账交易的接口。

    如果开发者对 0x 协议 有比较深的了解,想要进行更高级的自定义,而tokenlon相关接口不满足相应需求,tokenlon 也开放了这部分覆盖了 0x.js 的底层方法。开发者可以视自身情况,有选择的进行调用。

    被覆盖的方法

    tokenlon.zeroExWrapper.token

    tokenlon.zeroExWrapper.token.setAllowanceAsync
    tokenlon.zeroExWrapper.token.transferAsync
    tokenlon.zeroExWrapper.token.transferFromAsync
    
    // 因以下3个方法在其内部调用了this.setAllowanceAsync 等被覆盖的方法,因而同样被覆盖
    tokenlon.zeroExWrapper.token.setUnlimitedAllowanceAsync
    tokenlon.zeroExWrapper.token.setProxyAllowanceAsync
    tokenlon.zeroExWrapper.token.setUnlimitedProxyAllowanceAsync
    

    tokenlon.zeroExWrapper.etherToken

    tokenlon.zeroExWrapper.etherToken.depositAsync
    tokenlon.zeroExWrapper.etherToken.withdrawAsync
    

    tokenlon.zeroExWrapper.exchange

    tokenlon.zeroExWrapper.exchange.fillOrderAsync
    tokenlon.zeroExWrapper.exchange.cancelOrderAsync
    tokenlon.zeroExWrapper.exchange.fillOrKillOrderAsync
    tokenlon.zeroExWrapper.exchange.batchFillOrdersAsync
    tokenlon.zeroExWrapper.exchange.batchFillOrKillAsync
    tokenlon.zeroExWrapper.exchange.fillOrdersUpToAsync
    tokenlon.zeroExWrapper.exchange.batchCancelOrdersAsync
    

    需要注意的区别是,这些方法因为内置了私钥签名广播交易,保留了原有API 参数位置、结构,但将部分非必要的参数做了内部忽略,即不再处理忽略的参数。

    具体为,对应的 shouldValidatetakerAddress 参数位置仍然保留,但传递了此类参数,不进行任何处理。此方面的考虑是,原有0x.js 只是通过这两个参数做一些校验等操作,而 Tokenlon-SDK 在进行初始化配置时,已统一使用设定的 onChainValidate 来作为是否校验的考量;并且吃单时,takerAddress 统一为设定钱包地址。

    除以上签名广播交易外的覆盖是,因为 0x.js 在多处大量调用了其内部的 assert.isSenderAddressAsync 来判断是否是当前钱包签名广播交易,而 Tokenlon-SDK 没有调用其内部的 web3Wrapper 进行初始化的 web3 accounts 创建,因此重写了 assert.isSenderAddressAsync,移除了web3Wrapper.isSenderAddressAvailableAsync(senderAddressHex) 的判断。

    由此可见,覆盖操作所造成的影响可以说微乎其微

    而其他未覆盖的方法,开发者仍然可以使用 0x.js 的形式调用,API 的参数、功能仍然保持一致。

    更详细的 0x.js API 描述详见0x.js API

    后端接口交互

    基于后端 JSONRPC 接口的基本实现,tokenlon 相关API 内部即通过此部分API做的部分封装。资深开发者可以通过 wrapped-0x API 与此部分API,进行其他去中心化交易所交互等更多自定义操作。

    注意: 此部分接口使用 0x order 订单形式进行相关操作。

    详细描述见imToken JSONRPC API(coming soon...)

    其中 获取JWT Token、在请求头中带上JWT Token的操作,已内置进每个接口中,因此开发者无需考虑此部分内容。

    tokenlon.server.getPairList

    示例

    await tokenlon.server.getPairList()
    

    返回数据格式

    [
      {
        "id": 458,
        "market": "Tokenlon",
        "base": {
            "symbol": "SNT",
            "contractAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
            "decimal": 18
        },
        "quote": {
            "symbol": "WETH",
            "contractAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
            "decimal": 18
        },
        "infoUrl": "",
        "tags": [
            "HOT"
        ],
        "relayFee": {
            "relayRecipient": "",
            "makerFee": "",
            "takerFee": ""
        },
        "instantExEnabled": true,
        "marketEnabled": true,
        "tradingEnabled": true,
        "anchored": false,
        "protocol": "0x",
        "rank": 101,
        "precision": 8,
        "quoteMinUnit": 0.0001
      },
      // ...
    ]
    

    功能同 tokenlon.getPairs

    Returns

    Result Type Description
    array Promsise<Pair.ExchangePair[]> 交易对数组

    tokenlon.server.getOrderBook

    示例

    await tokenlon.server.getOrderBook({
      baseTokenAddress: '0xf26085682797370769bbb4391a0ed05510d9029d',
      quoteTokenAddress: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
    })
    

    返回数据格式

    {
      "bids": [
        {
          "orderId": 359828,
          "protocol": "0x",
          "rate": 0.000255,
          "amountRemaining": "0.00000000473965",
          "tradeType": "bid",
          "payload": {
            "exchangeContractAddress": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364",
            "maker": "0x75eb52e0265b80d5eac78e714b85ea9e199013aa",
            "taker": "0x0000000000000000000000000000000000000000",
            "makerTokenAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
            "takerTokenAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
            "feeRecipient": "0x0000000000000000000000000000000000000000",
            "makerTokenAmount": "25500000000000000",
            "takerTokenAmount": "100000000000000000000",
            "makerFee": "0",
            "takerFee": "0",
            "expirationUnixTimestampSec": "1551342565",
            "salt": "76669967321507220000000000000000000000000000000000000000000000000000000000000",
            "ecSignature": {
              "v": 27,
              "r": "0x8afe8a8e4f7d18b65ae8e28ded6dcea22a80b7997b73d75d93b4b04a4dcca3e9",
              "s": "0x5abe9f4928b0b9ad1e46083c406adbfd9441897e39ab2eb82869653a39e2d5ab"
            }
          }
        }
        // ...
      ],
      "asks": [
        {
          "orderId": 557090,
          "protocol": "0x",
          "rate": 0.00024984,
          "amountRemaining": "200.12808197",
          "tradeType": "ask",
          "payload": {
            "exchangeContractAddress": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364",
            "maker": "0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36",
            "taker": "0x0000000000000000000000000000000000000000",
            "makerTokenAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
            "takerTokenAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
            "feeRecipient": "0x0000000000000000000000000000000000000000",
            "makerTokenAmount": "200128081970000000000",
            "takerTokenAmount": "49999999999384800",
            "makerFee": "0",
            "takerFee": "0",
            "expirationUnixTimestampSec": "1522837661",
            "salt": "57928698160066632789044452941960007163066608846099684516946268760498144549884",
            "ecSignature": {
              "v": 28,
              "r": "0x3fff53fb44a1cacd022eb413b8f4534d07bdef80cf18c5049c4224de9970b026",
              "s": "0x2bd054d4b40435ab2ed45d5065d619ce442c7b6a512ce1351c145e63cffb4952"
            }
          }
        }
        // ...
      ]
    }
    

    通过 baseTokenAddressquoteTokenAddress 对应的contractAddress获取订单列表。

    Arguments

    Params Type Required Default Description
    Params Server.GetOrderBookParams true - -

    Returns

    Result Type Description
    object Promsise<Server.OrderBookResult> -

    tokenlon.server.placeOrder

    示例

    await tokenlon.server.placeOrder({
      "exchangeContractAddress": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364",
      "maker": "0x20f0c6e79a763e1fe83de1fbf08279aa3953fb5f",
      "taker": "",
      "makerTokenAddress": "0x739e78d6bebbdf24105a5145fa04436589d1cbd9",
      "takerTokenAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
      "feeRecipient": "0x0000000000000000000000000000000000000000",
      "makerTokenAmount": "1000000000000000",
      "takerTokenAmount": "10000000000000000000",
      "makerFee": "0",
      "takerFee": "0",
      "expirationUnixTimestampSec": "1514539440",
      "salt": "99392977337186991769370078621467871065903823087405146848913118809902183766712",
      "ecSignature": {
        "v": 27,
        "r": "0x9e9e325635110ab6c7cbf44984959028c108f91c21495f5281e2d8a2bd59c658",
        "s": "0x1e3df4c2cd7719ca0a432a172da51be050b84100ecbe1c2686b4f266329a62e8"
      }
    })
    

    返回数据格式

    "ok"
    

    将 0x 格式的订单发送到imToken服务器。

    Arguments

    Params Type Required Default Description
    order DexOrderBNToString true - -

    Returns

    Result Type Description
    object Promsise<string> -

    tokenlon.server.fillOrder

    示例

    await tokenlon.server.fillOrder({
      order: {
        "exchangeContractAddress": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364",
        "maker": "0x20f0c6e79a763e1fe83de1fbf08279aa3953fb5f",
        "taker": "",
        "makerTokenAddress": "0x739e78d6bebbdf24105a5145fa04436589d1cbd9",
        "takerTokenAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
        "feeRecipient": "0x0000000000000000000000000000000000000000",
        "makerTokenAmount": "1000000000000000",
        "takerTokenAmount": "10000000000000000000",
        "makerFee": "0",
        "takerFee": "0",
        "expirationUnixTimestampSec": "1514539440",
        "salt": "99392977337186991769370078621467871065903823087405146848913118809902183766712",
        "ecSignature": {
          "v": 27,
          "r": "0x9e9e325635110ab6c7cbf44984959028c108f91c21495f5281e2d8a2bd59c658",
          "s": "0x1e3df4c2cd7719ca0a432a172da51be050b84100ecbe1c2686b4f266329a62e8"
        }
      },
      txHash: "0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea",
      amount: "1000000000000000",
    })
    

    返回数据格式

    "ok"
    

    发送吃单请求至imToken服务器,告知此订单被吃单,getOrderBook 接口与imToken 2.0 订单列表不要进行返回与展示。

    当后端查询到该 txHash 对应的链上成交情况,会更新最新的订单可吃单数额以及订单状态。

    注意:

    参数内的 amount 需要经过 decimal 处理。

    Arguments

    Params Type Required Default Description
    Params Server.FillOrderParams true - -

    Returns

    Result Type Description
    object Promsise<string> -

    tokenlon.server.batchFillOrders

    示例

    await tokenlon.server.batchFillOrders({
      txHash: "0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea",
      orders: [
        {
          order: {
            "exchangeContractAddress": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364",
            "maker": "0x20f0c6e79a763e1fe83de1fbf08279aa3953fb5f",
            "taker": "",
            "makerTokenAddress": "0x739e78d6bebbdf24105a5145fa04436589d1cbd9",
            "takerTokenAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
            "feeRecipient": "0x0000000000000000000000000000000000000000",
            "makerTokenAmount": "1000000000000000",
            "takerTokenAmount": "10000000000000000000",
            "makerFee": "0",
            "takerFee": "0",
            "expirationUnixTimestampSec": "1514539440",
            "salt": "99392977337186991769370078621467871065903823087405146848913118809902183766712",
            "ecSignature": {
              "v": 27,
              "r": "0x9e9e325635110ab6c7cbf44984959028c108f91c21495f5281e2d8a2bd59c658",
              "s": "0x1e3df4c2cd7719ca0a432a172da51be050b84100ecbe1c2686b4f266329a62e8"
            }
          },
          amount: "1000000000000000",
        }
      ]
      // ...
    })
    

    返回数据格式

    "ok"
    

    发送吃批量单请求至imToken服务器,告知此系列订单被吃单,getOrderBook 接口与imToken 2.0 订单列表不要进行返回与展示。

    当后端查询到该 txHash 对应的链上成交情况,会更新最新的订单可吃单数额以及订单状态。

    注意:

    参数内的 amount 需要经过 decimal 处理。

    Arguments

    Params Type Required Default Description
    Params Server.BatchFillOrdersParams true - -

    Returns

    Result Type Description
    object Promsise<string> -

    tokenlon.server.cancelOrders

    示例

    const orderHashs = rawOrders.map(rawOrder => ZeroEx.getOrderHashHex(tokenlon.utils.orderStringToBN(JSON.parse(rawOrder))))
    await tokenlon.server.cancelOrders(orderHashs)
    

    返回数据格式

    "ok"
    

    发送撤单请求至imToken服务器,告知此订单被撤销。

    注意: 此接口仅为告知imToken服务器,getOrderBook 接口与imToken 2.0 订单列表不要进行返回与展示。

    Arguments

    Params Type Required Default Description
    orderHashs string[] true - -

    Returns

    Result Type Description
    object Promsise<string> -

    tokenlon.server.cancelOrdersWithHash

    示例

    const cancerOrderItems = rawOrders.map(rawOrder => {
      return {
        orderHash: ZeroEx.getOrderHashHex(tokenlon.utils.orderStringToBN(JSON.parse(rawOrder))),
        txHash: '0x702767ddd0da65d58691d7157e12d379d8135d7e670183880d5877610d1aebea',
      }
    })
    await tokenlon.server.cancelOrdersWithHash(cancerOrderItems)
    

    返回数据格式

    "ok"
    

    发送撤单请求至imToken服务器,告知此订单被撤销。与 tokenlon.server.cancelOrders 相同的地方在于 其同样仅为告知imToken服务器,getOrderBook 接口与imToken 2.0 订单列表不要进行返回与展示。

    而不同之处在于,cancelOrdersWith 需要提供撤单智能合约调用的交易记录 txHash并且imToken 服务器会检查该 txHash 是否被真实撤单,否则会将该笔订单作为正常订单重新返回与展示

    Arguments

    Params Type Required Default Description
    orderHashs Server.CancelOrderItem[] true - -

    Returns

    Result Type Description
    object Promsise<string> -

    tokenlon.server.getOrders

    示例

    const baseContractAddress = '0x7606bd550f467546212649a9c25623dfca88dcd7'
    const quoteContractAddress = '0xd0a1e359811322d97991e03f863a0c30c2cf029c'
    
    await tokenlon.server.getOrders({
      maker: '0xd7a0D7889577ef77C11Ab5CC00817D1c9adE6B36',
      tokenPair: [baseContractAddress, quoteContractAddress],
      page: 1,
      perpage: 20,
    })
    

    返回数据格式

    [
      {
        "orderId": 558227,
        "protocol": "0x",
        "rate": 0.022152,
        "amountRemaining": "2.25713254",
        "tradeType": "bid",
        "payload": {
          "exchangeContractAddress": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364",
          "maker": "0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36",
          "taker": "0x0000000000000000000000000000000000000000",
          "makerTokenAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
          "takerTokenAddress": "0x7606bd550f467546212649a9c25623dfca88dcd7",
          "feeRecipient": "0x0000000000000000000000000000000000000000",
          "makerTokenAmount": "50000000026080000",
          "takerTokenAmount": "2257132540000000000",
          "makerFee": "0",
          "takerFee": "0",
          "expirationUnixTimestampSec": "1522846664",
          "salt": "4725486074876887493600134161853933784321096497136367356999342811313686135929",
          "ecSignature": {
            "v": 28,
            "r": "0xa7b9c69a81fcb86ae5e947c76ac76e788ebfe43f407c494f6c05f547a58f6eda",
            "s": "0x777ef39a414ddfe9bae5754c3668f52a64f97b07f0b2e10bc3cb0df524b08b92"
          }
        }
      }
      // ...
    ]
    

    获取当前钱包挂单列表。

    Arguments

    Params Type Required Default Description
    Params Server.GetOrdersParams true - -

    Returns

    Result Type Description
    object Promise<Server.OrderBookItem[]> 挂出的有效单 order 数组

    tokenlon.server.getOrder

    示例

    const orderHash = ZeroEx.getOrderHash(JSON.parse(rawOrder))
    
    await tokenlon.server.getOrder(orderHash)
    

    返回数据格式

    {
      "orderId": 21555,
      "protocol": "0x",
      "rate": 0.00016421,
      "amountRemaining": "70.7103761",
      "tradeType": "bid",
      "onchainType": "expired",
      "payload": {
          "exchangeContractAddress": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364",
          "maker": "0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36",
          "taker": "0x0000000000000000000000000000000000000000",
          "makerTokenAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
          "takerTokenAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
          "feeRecipient": "0x6f7ae872e995f98fcd2a7d3ba17b7ddfb884305f",
          "makerTokenAmount": "180833937390000000000",
          "takerTokenAmount": "29694740858811900",
          "makerFee": "0",
          "takerFee": "0",
          "expirationUnixTimestampSec": "1527060545",
          "salt": "84381538164926307902569989902765324966525654257663591646793613516330182861192",
          "ecSignature": {
              "v": 28,
              "r": "0xb3df635d08f8e7024808aa64c4889f0e366053a4c13ef3467730a8e0efcb8159",
              "s": "0x4dda482ac979cc15f8dcc5deb9f32819af1c0ac8f38c38c28d992d4fa9046989"
          }
      },
      "trades": [
        {
          "id": 8,
          "price": 0.00016421,
          "amount": 110.12356129346568,
          "timestamp": 1527057048,
          "txHash": "0xae6e54b9006d8f812ac18e804980d84605abf65c36aac7188e133c22db045171"
        }
      ]
    }
    

    Get order detail info and its trades(if has) by rawOrder.

    Arguments

    Params Type Required Default Description
    orderHash string true - -

    Returns

    Result Type Description
    object Promise<Server.OrderDetail> tokenlon.server.getOrders返回 order 结构不同的是,添加了 trades 字段

    tokenlon.server.getMakerTrades

    示例

    const now = Math.floor(Date.now() / 1000)
    await tokenlon.getMakerTrades({
      "baseTokenAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
      "quoteTokenAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
      "page": 1,
      "perpage": 20,
      "maker": "0x20f0c6e79a763e1fe83de1fbf08279aa3953fb5f",
      // 获取近一年挂单被成交记录
      timeRange: [now - 365 * 86400, now]
    })
    

    返回数据格式

    [
      {
        "id": 21555,
        "price": 0.00016421,
        "amount": 110.12356129346568,
        "tradeType": "bid",
        "timestamp": 1527056944,
        "amountRemaining": 70.7103761,
        "expirationUnixTimestampSec": "1527060545",
        "payload": {
          "exchangeContractAddress": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364",
          "maker": "0xd7a0d7889577ef77c11ab5cc00817d1c9ade6b36",
          "taker": "0x0000000000000000000000000000000000000000",
          "makerTokenAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
          "takerTokenAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
          "feeRecipient": "0x6f7ae872e995f98fcd2a7d3ba17b7ddfb884305f",
          "makerTokenAmount": "180833937390000000000",
          "takerTokenAmount": "29694740858811900",
          "makerFee": "0",
          "takerFee": "0",
          "expirationUnixTimestampSec": "1527060545",
          "salt": "84381538164926307902569989902765324966525654257663591646793613516330182861192",
          "ecSignature": {
            "v": 28,
            "r": "0xb3df635d08f8e7024808aa64c4889f0e366053a4c13ef3467730a8e0efcb8159",
            "s": "0x4dda482ac979cc15f8dcc5deb9f32819af1c0ac8f38c38c28d992d4fa9046989"
          }
        },
        "trades": [
          {
            "id": 8,
            "price": 0.00016421,
            "amount": 110.12356129346568,
            "timestamp": 1527057048,
            "txHash": "0xae6e54b9006d8f812ac18e804980d84605abf65c36aac7188e133c22db045171"
          }
        ]
      }
    ]
    

    通过 baseTokenAddressquoteTokenAddress 获取maker钱包的挂单 被成交记录timeRange代表时间区间,为一个数组,第一项为开始时间时间戳,第二项为结束时间时间戳。

    tokenlon.getMakerTrades 接口基于此接口做的封装。

    Arguments

    Params Type Required Default Description
    Params Server.MakerTradesParams true - -

    Returns

    Result Type Description
    object Promise<Server.MakerTradesItem[]> -

    tokenlon.server.getTakerTrades

    示例

    const now = Math.floor(Date.now() / 1000)
    await tokenlon.getTakerTrades({
      "baseTokenAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
      "quoteTokenAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
      "page": 1,
      "perpage": 20,
      "taker": "0x20f0c6e79a763e1fe83de1fbf08279aa3953fb5f",
      timeRange: [now - 365 * 86400, now]
    })
    

    返回数据格式

    [
      {
        "id": 38,
        "price": 5000.2500125,
        "amount": 100.1393671,
        "tradeType": "ask",
        "timestamp": 1527075768,
        "amountRemaining": 0,
        "txHash": "0x2aa141defef4c279db1a03f84dfee077f175e21244d1b1f3388e4c112e700cff",
        "payload": {
          "exchangeContractAddress": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364",
          "maker": "0x20f0c6e79a763e1fe83de1fbf08279aa3953fb5f",
          "taker": "0x0000000000000000000000000000000000000000",
          "makerTokenAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
          "takerTokenAddress": "0xf26085682797370769bbb4391a0ed05510d9029d",
          "feeRecipient": "0x6f7ae872e995f98fcd2a7d3ba17b7ddfb884305f",
          "makerTokenAmount": "40053744052658000",
          "takerTokenAmount": "200278734200000000000",
          "makerFee": "0",
          "takerFee": "0",
          "expirationUnixTimestampSec": "1527076156",
          "salt": "14369837435448330357568565681144815538872002803647102464670480132035762359371",
          "ecSignature": {
            "v": 28,
            "r": "0x1a08f7e01676e039c80895f2265a3e1818cc8a0ab58281e6c5c0ac8d7c8977c2",
            "s": "0x746ad6346b4a426ecb623cc3aef8a23ac3335219799781ddeb21f163cd6c2a1d"
          }
        }
      }
    ]
    

    通过 baseTokenAddressquoteTokenAddress 获取taker钱包的吃单 成交记录timeRange代表时间区间,为一个数组,第一项为开始时间时间戳,第二项为结束时间时间戳。

    需要注意的是,tokenlon.server.getTakerTradestokenlon.server.getMakerTrades 参数中,takermaker 参数不一致,并且返回的数据结构也不同。

    Arguments

    Params Type Required Default Description
    Params Server.TakerTradesParams true - -

    Returns

    Result Type Description
    object Promise<Server.TakerTradesItem[]> -

    其他

    类型

    type Side

    type Side = 'BUY' | 'SELL'
    

    type Wallet

    type Wallet = {
      address: string
      privateKey: string;
    }
    

    type GasPriceAdaptor

    type GasPriceAdaptor = 'safeLow' | 'average' | 'fast'
    

    type GlobalConfig

    type GlobalConfig = {
      server: {
        url: string;
      }
      web3: {
        providerUrl: string;
      }
      wallet: Wallet
      onChainValidate?: boolean
      gasPriceAdaptor: GasPriceAdaptor
      zeroEx: {
        gasLimit: number
        networkId: number
        exchangeContractAddress: undefined | string
        etherTokenContractAddress: string
        tokenTransferProxyContractAddress: undefined | string
        zrxContractAddress?: undefined | string
        tokenRegistryContractAddress?: undefined | string
        orderWatcherConfig?: {
          cleanupJobIntervalMs: undefined | number
          eventPollingIntervalMs: undefined | number
          expirationMarginMs: undefined | number
          orderExpirationCheckingIntervalMs: undefined | number;
        };
      };
    }
    

    type SimpleOrder

    type SimpleOrder = {
      side: Side
      price: number
      amount: number
      expirationUnixTimestampSec?: number;
    }
    

    type DexOrderBNToString

    type DexOrderBNToString = {
      maker: string
      taker: string
      makerTokenAddress: string
      takerTokenAddress: string
      exchangeContractAddress: string
      expirationUnixTimestampSec: string
      feeRecipient: string
      makerFee: string
      makerTokenAmount: string
      takerFee: string
      takerTokenAmount: string
      salt: string
      ecSignature: ECSignature;
    }
    

    namespace Pair

    namespace Pair {
      type ExchangePairToken = {
        symbol: string
        logo: string
        contractAddress: string
        decimal: number;
      }
      type ExchangePair = {
        id: number | string
        market: string
        marketLogo?: string
        base: ExchangePairToken
        quote: ExchangePairToken
        tags: string[]
        rate?: number
        protocol: string
        addedTimestamp?: number
        index?: number
        infoUrl?: string
        price?: number
        change?: number
        anchored?: boolean
        precision: number
        rank?: number
        quoteMinUnit?: number
        marketUrl?: string;
      }
    }
    

    namespace Dex

    namespace Dex {
      type ECSignatureBuffer = {
        v: number
        r: Buffer
        s: Buffer;
      }
      type GetSimpleOrderParams = {
        amountRemaining?: string
        order: DexOrderBNToString
        pair: Pair.ExchangePair;
      }
      type GenerateDexOrderWithoutSaltParams = {
        simpleOrder: SimpleOrder
        pair: Pair.ExchangePair
        config: GlobalConfig;
      }
      type DexOrderWithoutSalt = {
        exchangeContractAddress: string,
        expirationUnixTimestampSec: BigNumber.BigNumber
        feeRecipient: string
        maker: string
        makerFee: BigNumber.BigNumber
        makerTokenAddress: string
        makerTokenAmount: BigNumber.BigNumber
        taker: string
        takerFee: BigNumber.BigNumber
        takerTokenAddress: string
        takerTokenAmount: BigNumber.BigNumber;
      }
      interface DexOrder extends DexOrderWithoutSalt {
        salt: BigNumber.BigNumber
      }
      interface SignedDexOrder extends DexOrder {
        ecSignature: ECSignature
      }
    
      interface TranslateOrderBookToSimpleParams {
        orderbookItems: Server.OrderBookItem[]
        pair: Pair.ExchangePair
        wallet?: {
          address: string;
        }
      }
    }
    

    namespace Server

    namespace Server {
      type Transformer = {
        (data: any): any;
      }
    
      type RequestParams = {
        [propName: string]: any;
      }
    
      type RequestConfig = {
        url: string
        method: string
        baseURL?: string
        transformRequest?: Transformer | Transformer[]
        transformResponse?: Transformer | Transformer[]
        headers?: any
        params?: any
        paramsSerializer?: (params: any) => string
        data?: any
        timeout?: number
        withCredentials?: boolean
        responseType?: string
        xsrfCookieName?: string
        xsrfHeaderName?: string
        onUploadProgress?: (progressEvent: any) => void
        onDownloadProgress?: (progressEvent: any) => void
        maxContentLength?: number
        validateStatus?: (status: number) => boolean;
      }
    
      type tradeType = 'ask' | 'bid'
    
      type GetTokenParams = {
        timestamp: number
        signature: string;
      }
    
      type GetOrderBookParams = {
        baseTokenAddress: string
        quoteTokenAddress: string;
      }
    
      type OrderBookItem = {
        rate: number
        tradeType?: tradeType
        amountRemaining: string
        payload: DexOrderBNToString;
      }
    
      type OrderBookResult = {
        bids: OrderBookItem[]
        asks: OrderBookItem[];
      }
    
      type CancelOrderItem = {
        orderHash: string
        txHash: string;
      }
    
      type FillOrderItem = {
        order: DexOrderBNToString
        amount: string;
      }
      interface FillOrderParams extends FillOrderItem {
        txHash: string
      }
    
      type BatchFillOrdersParams = {
        txHash: string
        orders: FillOrderItem[];
      }
    
      type GetOrdersParams = {
        maker: string
        page?: number
        perpage?: number
        tokenPair?: string[];
      }
    
      type GetTradesParams = {
        timeRange: number[]
        baseTokenAddress: string
        quoteTokenAddress: string
        page: number
        perpage: number;
      }
    
      interface MakerTradesParams extends GetTradesParams {
        maker: string
      }
    
      interface TakerTradesParams extends GetTradesParams {
        taker: string
      }
    
      type TradesDetailItem = {
        id: number
        price: number
        amount: number
        timestamp: number;
      }
    
      interface MakerTradesDetailItem extends TradesDetailItem {
        txHash: string
      }
    
      interface MakerTradesItem extends TradesDetailItem {
        tradeType: tradeType
        amountRemaining: number
        expirationUnixTimestampSec: string
        payload: DexOrderBNToString
        trades: MakerTradesDetailItem[]
      }
    
      interface TakerTradesItem extends TradesDetailItem {
        tradeType: tradeType
        payload: DexOrderBNToString
        txHash: string
      }
    
      interface OrderDetail extends OrderBookItem {
        trades: MakerTradesDetailItem[]
      }
    }
    

    namespace Tokenlon

    namespace Tokenlon {
      type makerTaker = {
        maker: string
        taker: string;
      }
    
      type BaseQuote = {
        base: string
        quote: string;
      }
    
      interface GetOrdersParams extends BaseQuote {
        page?: number
        perpage?: number
      }
    
      interface OrderBookItem extends SimpleOrder {
        amountTotal: number
        rawOrder: string
        isMaker: boolean
      }
    
      interface OrderBookResult {
        asks: OrderBookItem[]
        bids: OrderBookItem[]
      }
    
      interface SimpleOrderWithBaseQuote extends SimpleOrder {
        base: string
        quote: string
      }
    
      interface FillOrderParams extends SimpleOrderWithBaseQuote {
        rawOrder: string
        [propName: string]: any
      }
    
      interface TradesParams extends BaseQuote {
        page: number
        perpage: number
        timeRange?: [number, number]
      }
    
      interface MakerTradesItem {
        tradeType: Server.tradeType
        trades: Server.MakerTradesDetailItem[]
        amountRemaining: number
        expirationUnixTimestampSec: string
    
        side: Side
        rawOrder: string
      }
    
      interface TakerTradesItem {
        tradeType: Server.tradeType
        id: number
        price: number
        amount: number
        timestamp: number
        txHash: string
    
        side: Side
        rawOrder: string
      }
    
      interface OrderDetail extends OrderBookItem {
        trades: Server.MakerTradesDetailItem[]
      }
    
      interface FillOrdersUpTo {
        base: string
        quote: string
        side: string
        amount: number
        rawOrders: string[]
      }
    
      interface TxOpts {
        gasPrice?: number
        gasLimit?: number
      }
    }
    

    错误

    注意:

    tokenlon 基于 0x.js 封装,0x.js 内置错误类型见 ZeroExError

    enum TokenlonError {
      InvalidOrders = 'INVALID_ORDERS',
      UnsupportedPair = 'UNSUPPORTED_PAIR',
      UnsupportedToken = 'UNSUPPORTED_TOKEN',
      WalletDoseNotExist = 'WALLET_DOSE_NOT_EXIST',
      InvalidContractName = 'INVALID_CONTRACT_NAME',
      InvalidContractMethod = 'INVALID_CONTRACT_METHOD',
      InvalidSideWithOrder = 'INVALID_SIDE_WITH_ORDER',
      InvalidWalletPrivateKey = 'INVALID_WALLET_PRIVATE_KEY',
      InvalidGasPriceAdaptor = 'INVALID_GAS_PRICE_ADAPTOR',
      EthDoseNotHaveApprovedMethod = 'ETH_DOSE_NOT_HAVE_APPROVED_METHOD',
      InvalidPriceWithToBeFilledOrder = 'INVALID_PRICE_WITH_TO_BE_FILLED_ORDER',
      OrdersMustBeSamePairAndSameSideWithFillOrdersUpTo = 'ORDERS_MUST_BE_SAME_PAIR_AND_SAME_SIDE_WITH_FILLORDERSUPTO',
    }