Keyper agency protocol proposal

Keypering是个新的尝试,定位是一个架设在Keyper之上的桌面型轻量钱包,用于和dApp交互,可以理解成Keyper Scatter的翻版。

关于Keyper Scatter,以及Keyper Scatter与dApp的交互方式,请阅读这篇文章。当前Keypering还在初期开发中,UI初版地址

本文重点描述Keypering和dApp的交互协议,欢迎大家提意见。

Rich node RPC

ckb-rich-node RPC基于 ckb-rpc and ckb-indexer-rpc,它们都是JSON-RPC协议,更多信息请参考ckb-rich-node

术语:

id: 数字或string,符合JSON-RPC的语义。由dApp生成,用来标记和跟踪一组request/response,不能为空。

token: 64 byte string。当Auth请求授权成功后,Keypering返回token,dApp就可用于后续的请求中。

Auth

  • Request
{
    "id": 2,
    "jsonrpc": "2.0",
    "method": "auth",
    "params": {
        "origin": "http://demo.ckb.dapp",
        "description": "a dApp demo"
    }
}
  • Response
{
    "id": 2,
    "jsonrpc": "2.0",
    "result": {
        "token": "xxxxxxxxxxxxxxxxxxxx"
    }
}
  • Errors

    • 当用户拒绝本次请求后,Keypering发回:

      {
          "id": 2,
          "jsonrpc": "2.0",
          "error": {
              "code": 1,
              "message": "declined"
        }
      }
      
    • 当用户关闭Keypering,或不理Keypering UI的提示,这时Keypering不会回应任何内容。dApp应能正常处理这种情况,比如引入超时机制

Query Locks

  • Request
{
    "id": 2,
    "jsonrpc": "2.0",
    "method": "query_locks",
    "params": {
        "token": "xxxxxxxxxxxxxxxxxxxx"
    }
}
  • Response
{
    "id": 2,
    "jsonrpc": "2.0",
    "result": {
        "locks": [
            {
                "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
                "hash_type": "type",
                "args": "0x8211f1b938a107cd53b6302cc752a6fc3965638d"
            }
        ]
    }
}
  • Errors

    • 如果token无效,Keypering返回:

      {
          "id": 2,
          "jsonrpc": "2.0",
          "error": {
              "code": 2,
              "message": "invalid_token"
          }
      }
      

Sign

签名交易。

当dApp组装好交易,通过本接口请求签名,Keypering会在UI上展示交易信息,用户签名后,Keypering会返回包含签名的交易信息。

  • Request

config是可选的,默认值 {"index": 0, "length": -1} 代表全签。

{
    "id": 2,
    "jsonrpc": "2.0",
    "method": "sign",
    "params": {
        "token": "xxxxxxxxxxxxxxxxxxxx",
        "target": "LOCK_HASH",
        "tx": TX_JSON,
        "config": {
            "index": 0,
            "length": -1
        },
        "meta": "transaction meta info"
    }
}
  • Response
{
    "id": 2,
    "jsonrpc": "2.0",
    "result": {
        "tx": TX_JSON_WITH_SIGNATURE
    }
}
  • Errors
    • 参考前面,code=1表示declined,code=2表示invalid_token

Sign and Send

签名并发送交易。

  • Request
{
    "id": 2,
    "jsonrpc": "2.0",
    "method": "sign_and_send",
    "params": {
        "token": "xxxxxxxxxxxxxxxxxxxx",
        "target": "LOCK_HASH",
        "tx": TX_JSON,
        "config": {
            "index": 0,
            "length": -1
        },
        "meta": "transaction meta info"
    }
}
  • Response
{
    "id": 2,
    "jsonrpc": "2.0",
    "result": {
        "tx": TX_JSON_WITH_SIGNATURE,
        "hash": TX_HASH
    }
}
  • Errors
    • 参考前面,code=1表示declined,code=2表示invalid_token
3 Likes

几个问题:

  1. 前面的 connect 和 auth 都没有 requestId,考虑没考虑过网络丢包时怎么处理?
  2. 感觉这种格式严格意义上跟 JSON-RPC 很相似,虽然 JSON-RPC 也不是什么定义良好的格式,但是至少有个规范的存在。有没有考虑调整成 JSON-RPC 或者更舒服的格式(比如 grpc)?

确实协议接口形式是RPC,你说的对,我决定改成JSON-RPC了。

不选grpc是考虑到dapp和keypering的交互既不频繁,数据量也不很大,这样基于纯文本的自描述的JSON-RPC适用范围更广。

基于http/websocket协议就不考虑网络丢包的情况了,协议中同一接口多次调用符合幂等性。
选用JSON-RPC另一个额外好处是,它的id就可以用来代表requestId。

重新edit了正文内容

这个字段是什么意思?

LOCK_HASH = utils.scriptToHash(lockScript)

:grinning:

嗯我知道 lock_hash 是啥,哈哈,我是说签名的时候 target 里填这个的意思是?

通过lockHash定位具体由哪个LockScript plugin来签名交易

OK,这看来是 keyper 的设计了