RFC 提议:CKB Provider JavaScript API

摘要

这个 RFC 定义了 CKB Provider JavaScript API,让不同的应用使用同样的 API 通过 Provider 与 CKB 节点进行交互。

名词解释

Wallet

用来管理用户的公钥和私钥,为交易签名。

Provider

Provider 可以看做是一组 API,用来方便应用与区块链进行交互。一方面可以代替应用向 CKB 节点发送 RPC 请求,就好像互联网服务提供商(Provider)一样,为应用提供了访问互联网的能力,而区块链的 Provider 为应用提供了访问区块链的能力。另一方面,除了访问区块链,Provider 本身还可以提供额外的功能,比如返回用户的钱包地址、签名等。通常 Provider 会内置在 Wallet 中,也可以是一个单独的库。

CKB 节点

CKB 节点是实现了 CKB 协议的客户端,也称为区块链节点,接收来自 Provider 或者用户 的 Remote Procedure Call (RPC),并返回结果。

应用(Application)

面向用户的程序,通常具有用户界面,允许用户与其交互,并返回特定的结果。

动机

不同的 Provider 会定义不同的 API 名称,这样会导致定义和交互方式的碎片化,而通过定义一个统一的接口可以避免这类问题,给应用开发者更好的开发体验。例如,对于一个浏览器插件钱包,钱包会提供 API 给 DApp 开发者使用,如:

getAddresses: any[];    // 获取可用的地址列表

而另外一个桌面端钱包也提供了类似的 API:

methodCall({ method: "getAddressList", pubKey: string }): { message: string, result: any[] };    // 获取可用的地址列表

虽然这两个 API 的功能类似,但却使用了不同的调用方式和返回的数据结构。

通过使用 JSON RPC 的方式可以将不同的 API 调用方式统一起来:

// getAddresses
--> {"jsonrpc": "2.0", "method": "getAddresses", "params": [], "id": 1}
<-- {"jsonrpc": "2.0", "result": [], "id": 1}

// getAddressList
--> {"jsonrpc": "2.0", "method": "getAddressList", "params": ["0x11"], "id": 2}
<-- {"jsonrpc": "2.0", "result": [], "id": 2}

这样就提供了几个优点:

  • 提供统一的调用方式。无论是对于 CKB 节点的直接 RPC 调用,还是调用 Provider 提供的 RPC 方法,调用方法都是一样的,应用开发者不需要进行区分。
  • 兼顾了接口统一和灵活扩展。开发者在使用统一接口的基础上,通过添加自定义的方法来进行扩展。

但是 JSON RPC 的调用方式构造起来有点复杂,为了简化调用方式,我们提议使用一个统一的 API 名称: request

规范

API

request: 封装了 JSON RPC 调用,方便用户与区块链进行交互。

interface Request {
  method: string;
  params?: Array<any>;
}

interface Result {
  result: any;
  error: Error;
}

interface Error {
  message: string;
  code: number;
  data?: any;
}

Provider.request(args: Request): Promise<Result>;

请求

请求的参数需要符合下面的结构:

interface Request {
  method: string;
  params?: Array<any>;
}

Provider.request(args: Request)

返回值

interface Result {
  result: any;
  error: Error;
}
  • 成功: 返回result 由具体的方法指定。
  • 失败: 返回 error 符合下面 Error 的定义。

Error

如果发生错误,返回的数据结构需要符合下面的定义:

interface Error {
  message: string;
  code: number;
  data?: any;
}
  • message: 人类可读的字符串。
  • code: 错误码,正整数。参考下面的 Error Code 的定义。
  • data: 任何其它的信息。

Error Code

Code Name Explanation
1001 Rejected Request is rejected by user
1004 UnknownError Other error
1100 Unauthorized Method or account is not authorized by user
1200 Unsupported Method is not supported by provider

Example:

import Provider from "ckb-provider";

const provider = new Provider(["http://127.0.0.1:8114"]);
const tx = {
  version: "0x0",
  cellDeps: [{
      outPoint: {
          // a fixed value for testnet
          txHash: "0xf8de3bb47d055cdf460d93a2a6e1b05f7432f9777c8c474abf4eec1d4aee5d37",
          index: "0x0"
      },
      depType: "depGroup",
  }],
  headerDeps: [],
  inputs: [],
  outputs: [],
  witnesses: [],
  outputsData: []
};

const result: Result = await provider.request({
  method: "send_transaction",
  params: [tx]
});

References

2 Likes