DApp同钱包交互

接入ChainBow

渠道、开发商等可以按照下面流程接入ChainBow钱包支付API.

目前所有等api都是基于WalletConnect 2.0在新窗口打开

接入项目需要导入WalletConnect 2.0版本的依赖

示例项目DAppDemo在新窗口打开

准备

流程图

WalletConnect API

初始化

await WalletConnectClient.init(
        Object.assign(
          {
            relayUrl: wss://domain,(根据自己指定服务器,也可以指定WalletConnect官方的服务器)
          } as ClientOptions,
          opts ?? {}
        )
      );
1
2
3
4
5
6
7
8

连接

DApp通过WalletConnect库中的connect() 连接WalletConnect Server。

断开

DApp通过WalletConnect库中的disconnect() 断开WalletConnect Server。

接入钱包

建立连接

DAPP 数据结构

字段说明
nameDApp名称
descriptionDApp功能描述
urlDApp官网
iconsDApp icon
  const wc = useWallet();
  await wc.connect(DAPP);
1
2

返回数据结构

字段说明
bsv:livenet是使用bsv对主网还是测试网络
aliaspaymail地址
domaindomain
address钱包地址
signature对session中随机对publicKey签名
const account = session.state.accounts[0];

"bsv:livenet:test_account 
 | chainbow.io 
 | 1BikvsWbVmLC9R9inrtRLQ7j2qBpMJVUfT
 | Hxj8kJ7ZdDC8zgtCAZopEQ01VUPI4Gl+L8L26IYKcsh/Mp1nhlxniTGFuPYTCPZMNA3ovlHdVED43r+QLiaYwmw="
 
 
 说明:

1.namespace, network 使用 ':'分割

2.账号字段使用 '|' 分割

bsv:livenet:alias|domain|address|signature

如果没有alias 返回结构

bsv:livenet:address| |address|signature

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

签名

为了保证DApp和钱包配对。调用方法 signMessage

1.DApp把需要签名的数据通过signMessage发送给钱包

2.钱包使用私钥签名之后通过signMessage返回给DApp

3.DApp使用钱包的address验证signMessage返回的签名数据

输入结构

字段说明
address地址
message签名信息
  await wc.signMessage({address: data.address,message: data.message})
1

返回

字段说明
signaturemessage经过签名的数据

验证签名


// 验证签名数据合法
const result = Message.verify(data.message, data.address, data.sig);

1
2
3
4

发送单笔交易

调用方法 sendTransaction 创建一个交易,发送Satoshi或者Token给指定的地址

输入结构

输入outputs数组,output数据结构如下

字段说明
to目标地址(根据 format 填写)
format'address':to 需要满足比特币地址规范, 'paymail':to 需要注册paymail地址, 'script':脚本
amount发送金额
  await wc.sendTransaction({
            outputs: [
              {
                to: data.toAddress,
                format: data.format
                  ? (data.format as any).value.toString()
                  : undefined,
                amount: data.amount.toString(),
              },
            ],
          })
1
2
3
4
5
6
7
8
9
10
11

返回

字段说明
txId交易id
time交易时间
fee手续费
amount转账金额
{
    txId: '91256db99f8756d757fa72f2bf57b6c2bb45e9ce2d6e4a5d78ff70d89b6d53c9', 
    time: 1645501589365, 
    fee: 200,
    amount: 600
}
1
2
3
4
5
6

发送多笔交易

调用方法 sendRawTransaction。 发送已签名交易,通过钱包广播到区块链。

const res = await wc.sendRawTransaction([rawHex])
1

1.输入数据结构

字段说明
rawHex交易
{
  "rawHex": "01000000018cb9bbfd577afc4811381ac5f6b59c849e85699b31efbc292df812bed71a4635020000006a4730440220676c32d64a9826ecca238427ca84fe11b38a3ec26f89f23b5e73c81ec90e96c302201d5a301febe58e8d42ea2aa2ebdb4b02430c284f1f9504cfdb1def601294464c41210200104c2d3a77bfe8c08a639a561f687197e9e25e94f49018e0a5f87275cf1877ffffffff030000000000000000fd5c01006a223143516150395562486f39675965526d36347864326d6f694251426334456f4471660840899be574ff17004ce54249453103d5f4ba7b8a03de98bdc8d6df2b1e5e61c8eb33a9250b8d178afd8bf06d939d662e7a6fb865ba6f5100b54dfd289061ae902eebf946c5701ecd02b38393590ad484a08c0694e5d201519560d472a9f6c64ecfb0dbe942af17a4d1e877bd6593296bda8f3c39fda07ad5d368517c2124705e44a7b228c5425019c3000ce9d66834eccb10fafdd5c6ad382757454c13fc4b8900fba5f44f8bccd63f289837708775cfd4dade9262956e422b66418289931095956717294bef65f5d453c842743c7511ce88efcdb1f5eb2ef05e80422c324401dcbaabab8e01d5ba122de408ae0521463044022024a25971f83367790b12ace5f58f784a41dcb63fddbd2c3084936e9692b02d2b022036407934c5f661577b9a10b55f509848512154ba3d99fbcb69ab5988d54db67022020000000000001976a9142b3d8b2dae6fedb6f038acf357746d1662b05c4988ac79f13400000000001976a914fbae7a3dae29183e1f37bbd48dff68b4c56476a788ac00000000"
}

1
2
3
4

返回数据结构

字段说明
txId交易id

交易签名

调用方法 signTransaction。 请求钱包对交易签名,获取签名之后,可以使用 sendRawTransaction 广播交易。

输入数据结构

输入ITransaction(包含inputs ,outputs 两个数组),signRequests数组两个字段

ITransaction.inputs

字段说明
prevTxId前面一个txId
outputIndex输出索引
satoshis金额
lockingScript锁定脚本

ITransaction.outputs

字段说明
toconst script = bsv.Script.buildPublicKeyHashOut(data.toAddress);填写 script.toHex()返回
format填写 'script'
amount转账金额

signRequests 数组

字段说明
inputIndex输入索引(0)
address比特币地址
sigtypebsv.crypto.Signature.SIGHASH_ANYONECANPAY
  const transaction: ITransaction = {
        inputs: [
          {
            prevTxId: data.prevTxId,
            outputIndex: data.outputIndex,
            satoshis: data.satoshis,
            lockingScript: data.lockingScriptHex,
          },
        ],
        outputs: [
          {
            to: script.toHex(),
            format: 'script',
            amount: String(data.outputSatoshis),
          },
        ],
      };


 const request: ISignTransaction = {
        transaction,
        signRequests: [
          {
            inputIndex: 0,
            address: data.address,
            sigtype: bsv.crypto.Signature.SIGHASH_ANYONECANPAY | bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID
          },
        ],
      };

 await wc.signTransaction(request)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

返回数据结构

返回 signatures数组,signature结构如下

字段说明
prevTxId前一个交易id
outputIndex输出索引
satoshis交易金额
sequenceNumber交易id
signature签名之后的数据
pubkey公钥
sigtype交易id
inputIndex输入索引

"signatures": [
        {
            "prevTxId": "35a7c737b2e39b7b81219cc1628402a795e7e8a48b6e940207b912123f5e43c1",
            "outputIndex": 0,
            "satoshis": 1280900,
            "sequenceNumber": 4294967295,
            "signature": "304402206738aafa8df6179e2511a08b9646db1c6957d25a48f20134704ef7e84d7c25e10220417fac6e495d006d92519b847874e47519c88e0239ce5cba8e1ffec21d61cd1641",
            "pubkey": "03753e4161e7dab8ca0de4350004af544ced8cdd17494df6597d4f7c12e3e0ed2a",
            "sigtype": 65,
            "inputIndex": 0
        }
 ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14

报错码

错误码说明
Error: User rejected the request在请求钱包授权时,钱包拒绝授权方法
Error: UnknownAddress比特币地址不符合规范
Error: Session not approve钱包拒绝授权登陆
Error: JSON-RPC Request timeout after 300 secondsDapp请求钱包方法,钱包响应超时
上次更新:
贡献者: Ambince, Long Li