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
2
3
4
5
6
7
8
连接
DApp通过WalletConnect库中的connect() 连接WalletConnect Server。
断开
DApp通过WalletConnect库中的disconnect() 断开WalletConnect Server。
接入钱包
建立连接
DAPP 数据结构
字段 | 说明 |
---|---|
name | DApp名称 |
description | DApp功能描述 |
url | DApp官网 |
icons | DApp icon |
const wc = useWallet();
await wc.connect(DAPP);
1
2
2
返回数据结构
字段 | 说明 |
---|---|
bsv:livenet | 是使用bsv对主网还是测试网络 |
alias | paymail地址 |
domain | domain |
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
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
返回
字段 | 说明 |
---|---|
signature | message经过签名的数据 |
验证签名
// 验证签名数据合法
const result = Message.verify(data.message, data.address, data.sig);
1
2
3
4
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
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
2
3
4
5
6
发送多笔交易
调用方法 sendRawTransaction。 发送已签名交易,通过钱包广播到区块链。
const res = await wc.sendRawTransaction([rawHex])
1
1.输入数据结构
字段 | 说明 |
---|---|
rawHex | 交易 |
{
"rawHex": "01000000018cb9bbfd577afc4811381ac5f6b59c849e85699b31efbc292df812bed71a4635020000006a4730440220676c32d64a9826ecca238427ca84fe11b38a3ec26f89f23b5e73c81ec90e96c302201d5a301febe58e8d42ea2aa2ebdb4b02430c284f1f9504cfdb1def601294464c41210200104c2d3a77bfe8c08a639a561f687197e9e25e94f49018e0a5f87275cf1877ffffffff030000000000000000fd5c01006a223143516150395562486f39675965526d36347864326d6f694251426334456f4471660840899be574ff17004ce54249453103d5f4ba7b8a03de98bdc8d6df2b1e5e61c8eb33a9250b8d178afd8bf06d939d662e7a6fb865ba6f5100b54dfd289061ae902eebf946c5701ecd02b38393590ad484a08c0694e5d201519560d472a9f6c64ecfb0dbe942af17a4d1e877bd6593296bda8f3c39fda07ad5d368517c2124705e44a7b228c5425019c3000ce9d66834eccb10fafdd5c6ad382757454c13fc4b8900fba5f44f8bccd63f289837708775cfd4dade9262956e422b66418289931095956717294bef65f5d453c842743c7511ce88efcdb1f5eb2ef05e80422c324401dcbaabab8e01d5ba122de408ae0521463044022024a25971f83367790b12ace5f58f784a41dcb63fddbd2c3084936e9692b02d2b022036407934c5f661577b9a10b55f509848512154ba3d99fbcb69ab5988d54db67022020000000000001976a9142b3d8b2dae6fedb6f038acf357746d1662b05c4988ac79f13400000000001976a914fbae7a3dae29183e1f37bbd48dff68b4c56476a788ac00000000"
}
1
2
3
4
2
3
4
返回数据结构
字段 | 说明 |
---|---|
txId | 交易id |
交易签名
调用方法 signTransaction。 请求钱包对交易签名,获取签名之后,可以使用 sendRawTransaction 广播交易。
输入数据结构
输入ITransaction(包含inputs ,outputs 两个数组),signRequests数组两个字段
ITransaction.inputs
字段 | 说明 |
---|---|
prevTxId | 前面一个txId |
outputIndex | 输出索引 |
satoshis | 金额 |
lockingScript | 锁定脚本 |
ITransaction.outputs
字段 | 说明 |
---|---|
to | const script = bsv.Script.buildPublicKeyHashOut(data.toAddress);填写 script.toHex()返回 |
format | 填写 'script' |
amount | 转账金额 |
signRequests 数组
字段 | 说明 |
---|---|
inputIndex | 输入索引(0) |
address | 比特币地址 |
sigtype | bsv.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
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
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 seconds | Dapp请求钱包方法,钱包响应超时 |