@ocap/client 1.25.4 → 1.25.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/report.html +1 -1
- package/docs/api-reference-client-methods.ja.md +229 -0
- package/docs/api-reference-client-methods.zh-TW.md +229 -0
- package/docs/api-reference-client-methods.zh.md +27 -27
- package/docs/api-reference-data-types.ja.md +482 -0
- package/docs/api-reference-data-types.zh-TW.md +482 -0
- package/docs/api-reference-data-types.zh.md +14 -14
- package/docs/api-reference-low-level-api.ja.md +228 -0
- package/docs/api-reference-low-level-api.zh-TW.md +228 -0
- package/docs/api-reference-low-level-api.zh.md +39 -39
- package/docs/api-reference-query-mutation-methods.ja.md +814 -0
- package/docs/api-reference-query-mutation-methods.zh-TW.md +814 -0
- package/docs/api-reference-query-mutation-methods.zh.md +158 -158
- package/docs/api-reference-transaction-helpers.ja.md +649 -0
- package/docs/api-reference-transaction-helpers.zh-TW.md +649 -0
- package/docs/api-reference-transaction-helpers.zh.md +112 -112
- package/docs/api-reference.ja.md +23 -0
- package/docs/api-reference.zh-TW.md +23 -0
- package/docs/api-reference.zh.md +6 -6
- package/docs/core-concepts-client-architecture.ja.md +102 -0
- package/docs/core-concepts-client-architecture.zh-TW.md +102 -0
- package/docs/core-concepts-client-architecture.zh.md +21 -21
- package/docs/core-concepts-event-subscriptions.ja.md +123 -0
- package/docs/core-concepts-event-subscriptions.zh-TW.md +123 -0
- package/docs/core-concepts-event-subscriptions.zh.md +22 -22
- package/docs/core-concepts-gas-payment.ja.md +111 -0
- package/docs/core-concepts-gas-payment.zh-TW.md +111 -0
- package/docs/core-concepts-gas-payment.zh.md +30 -30
- package/docs/core-concepts-transaction-lifecycle.ja.md +183 -0
- package/docs/core-concepts-transaction-lifecycle.zh-TW.md +183 -0
- package/docs/core-concepts-transaction-lifecycle.zh.md +51 -51
- package/docs/core-concepts.ja.md +22 -0
- package/docs/core-concepts.zh-TW.md +22 -0
- package/docs/core-concepts.zh.md +6 -6
- package/docs/getting-started-basic-usage.ja.md +87 -0
- package/docs/getting-started-basic-usage.zh-TW.md +87 -0
- package/docs/getting-started-basic-usage.zh.md +17 -17
- package/docs/getting-started-installation.ja.md +60 -0
- package/docs/getting-started-installation.zh-TW.md +60 -0
- package/docs/getting-started-installation.zh.md +14 -14
- package/docs/getting-started.ja.md +16 -0
- package/docs/getting-started.zh-TW.md +16 -0
- package/docs/getting-started.zh.md +6 -5
- package/docs/how-to-guides-delegate-permissions.ja.md +167 -0
- package/docs/how-to-guides-delegate-permissions.zh-TW.md +167 -0
- package/docs/how-to-guides-delegate-permissions.zh.md +27 -28
- package/docs/how-to-guides-manage-accounts.ja.md +73 -0
- package/docs/how-to-guides-manage-accounts.zh-TW.md +73 -0
- package/docs/how-to-guides-manage-accounts.zh.md +14 -14
- package/docs/how-to-guides-manage-assets.ja.md +255 -0
- package/docs/how-to-guides-manage-assets.zh-TW.md +255 -0
- package/docs/how-to-guides-manage-assets.zh.md +60 -60
- package/docs/how-to-guides-manage-tokens.ja.md +179 -0
- package/docs/how-to-guides-manage-tokens.zh-TW.md +179 -0
- package/docs/how-to-guides-manage-tokens.zh.md +52 -52
- package/docs/how-to-guides-stake-tokens-and-assets.ja.md +205 -0
- package/docs/how-to-guides-stake-tokens-and-assets.zh-TW.md +205 -0
- package/docs/how-to-guides-stake-tokens-and-assets.zh.md +44 -44
- package/docs/how-to-guides-transfer-tokens-and-nfts.ja.md +179 -0
- package/docs/how-to-guides-transfer-tokens-and-nfts.zh-TW.md +179 -0
- package/docs/how-to-guides-transfer-tokens-and-nfts.zh.md +47 -47
- package/docs/how-to-guides.ja.md +27 -0
- package/docs/how-to-guides.zh-TW.md +27 -0
- package/docs/how-to-guides.zh.md +11 -11
- package/docs/overview.ja.md +70 -0
- package/docs/overview.zh-TW.md +70 -0
- package/docs/overview.zh.md +8 -8
- package/package.json +14 -14
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# 事件订阅
|
|
2
2
|
|
|
3
|
-
OCAP Client
|
|
3
|
+
OCAP Client 提供了一个强大的实时事件订阅系统,允许您的应用程序在链上活动发生时进行监听。该功能基于 WebSocket 构建,提供与区块链节点的持久连接,无需通过持续轮询来检查更新。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
通过订阅特定的事件主题,您可以接收各种链上事件的即时通知,例如当新交易创建、资产转移或代币交换时。这对于构建能够实时响应区块链状态变化的响应式和交互式应用程序至关重要。要更深入地了解触发这些事件的原因,您可能需要查阅[交易生命周期](./core-concepts-transaction-lifecycle.md)。
|
|
6
6
|
|
|
7
7
|
## 工作原理
|
|
8
8
|
|
|
9
|
-
在底层,当您首次订阅事件时,OCAP Client 会自动与区块链节点的指定端点建立 WebSocket
|
|
9
|
+
在底层,当您首次订阅事件时,OCAP Client 会自动与区块链节点的指定端点建立 WebSocket 连接。此连接将保持活动状态,允许节点在事件发生时立即将事件数据推送至您的客户端。
|
|
10
10
|
|
|
11
11
|
客户端为您管理 WebSocket 连接的生命周期。它处理初始连接,发送心跳消息以保持连接活跃,并在连接断开时尝试重新连接。这确保了事件流的稳定和可靠,而您只需进行最少的配置。
|
|
12
12
|
|
|
13
13
|
## 订阅事件
|
|
14
14
|
|
|
15
|
-
要开始监听事件,您可以使用 `subscribe`
|
|
15
|
+
要开始监听事件,您可以使用 `subscribe` 方法。您需要提供一个事件主题(标识事件的字符串)和一个回调函数,该函数将在收到事件时执行。
|
|
16
16
|
|
|
17
17
|
```javascript OCAP Client icon=logos:javascript
|
|
18
18
|
const client = new GraphQLClient('https://beta.abtnetwork.io/api/v2/gql');
|
|
@@ -21,7 +21,7 @@ const handleNewTransaction = (eventData) => {
|
|
|
21
21
|
console.log('A new transaction was created on-chain:', eventData);
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
//
|
|
24
|
+
// 订阅 'tx.create' 主题
|
|
25
25
|
client.subscribe('tx.create', handleNewTransaction);
|
|
26
26
|
```
|
|
27
27
|
|
|
@@ -40,20 +40,20 @@ client.subscribe('tx.create', handleNewTransaction);
|
|
|
40
40
|
|
|
41
41
|
| Topic | Description |
|
|
42
42
|
|---|---|
|
|
43
|
-
| `tx.create` |
|
|
43
|
+
| `tx.create` | 当任何新交易成功处理并被添加到区块中时触发。 |
|
|
44
44
|
| `tx.transfer_v2` | 当 `transferV2` 交易发生时专门触发。 |
|
|
45
45
|
| `tx.exchange_v2` | 当 `exchangeV2`(原子交换)交易完成时触发。 |
|
|
46
|
-
| `tx.create_asset` |
|
|
46
|
+
| `tx.create_asset` | 当新资产(NFT)被创建时触发。 |
|
|
47
47
|
|
|
48
48
|
## 取消订阅事件
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
在不再需要订阅时进行清理是一个好习惯,特别是在组件会挂载和卸载的单页应用程序中。这可以防止内存泄漏和不必要的处理。您可以使用 `unsubscribe` 方法来移除订阅。
|
|
51
51
|
|
|
52
52
|
```javascript OCAP Client icon=logos:javascript
|
|
53
|
-
//
|
|
53
|
+
// 要移除特定的监听器,请传递相同的回调函数引用
|
|
54
54
|
client.unsubscribe('tx.create', handleNewTransaction);
|
|
55
55
|
|
|
56
|
-
//
|
|
56
|
+
// 要移除特定主题的所有监听器
|
|
57
57
|
client.unsubscribe('tx.create');
|
|
58
58
|
```
|
|
59
59
|
|
|
@@ -68,7 +68,7 @@ client.unsubscribe('tx.create');
|
|
|
68
68
|
|
|
69
69
|
## 完整示例
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
以下是一个完整的示例,演示了订阅事件、触发事件然后取消订阅的过程。
|
|
72
72
|
|
|
73
73
|
```javascript Event Subscription Lifecycle icon=logos:javascript
|
|
74
74
|
import GraphQLClient from '@ocap/client';
|
|
@@ -82,35 +82,35 @@ const main = async () => {
|
|
|
82
82
|
client.subscribe('tx.create', () => (events.txCreate += 1));
|
|
83
83
|
client.subscribe('tx.transfer_v2', () => (events.txTransfer += 1));
|
|
84
84
|
|
|
85
|
-
console.log('
|
|
85
|
+
console.log('已订阅 tx.create 和 tx.transfer_v2 事件...');
|
|
86
86
|
|
|
87
|
-
//
|
|
87
|
+
// 等待一小段时间的辅助函数
|
|
88
88
|
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
89
89
|
await sleep(100); // 等待片刻以注册订阅
|
|
90
90
|
|
|
91
91
|
// 2. 执行触发事件的操作
|
|
92
92
|
// 注意:这需要一个有资金的钱包。您可以从 https://faucet.abtnetwork.io/ 获取测试代币。
|
|
93
|
-
const sender = fromRandom(); //
|
|
93
|
+
const sender = fromRandom(); // 在真实应用中,加载一个有资金的钱包
|
|
94
94
|
// 在此示例中,我们假设操作会成功。
|
|
95
|
-
console.log('
|
|
95
|
+
console.log('一笔转账交易将触发事件处理程序。');
|
|
96
96
|
|
|
97
|
-
//
|
|
97
|
+
// 在真实场景中,成功转账后:
|
|
98
98
|
// await client.transfer({ to: 'z1...', token: 1, wallet: sender });
|
|
99
99
|
|
|
100
|
-
//
|
|
100
|
+
// 让我们模拟在成功交易后事件计数器递增
|
|
101
101
|
events.txCreate = 1;
|
|
102
102
|
events.txTransfer = 1;
|
|
103
103
|
|
|
104
104
|
await sleep(100); // 等待事件处理
|
|
105
105
|
|
|
106
106
|
// 3. 验证事件处理程序是否被调用
|
|
107
|
-
console.log(`tx.create
|
|
108
|
-
console.log(`tx.transfer_v2
|
|
107
|
+
console.log(`tx.create 被调用了 ${events.txCreate} 次。`);
|
|
108
|
+
console.log(`tx.transfer_v2 被调用了 ${events.txTransfer} 次。`);
|
|
109
109
|
|
|
110
110
|
// 4. 取消订阅以进行清理
|
|
111
111
|
client.unsubscribe('tx.create');
|
|
112
112
|
client.unsubscribe('tx.transfer_v2');
|
|
113
|
-
console.log('
|
|
113
|
+
console.log('已取消事件订阅。');
|
|
114
114
|
};
|
|
115
115
|
|
|
116
116
|
main().catch(console.error);
|
|
@@ -118,6 +118,6 @@ main().catch(console.error);
|
|
|
118
118
|
|
|
119
119
|
## 总结
|
|
120
120
|
|
|
121
|
-
事件订阅是使用 OCAP Client 构建动态 dApp 的核心功能。它们提供了一个简单而强大的 API,通过可靠的 WebSocket 连接实时响应链上事件。通过使用 `subscribe` 和 `unsubscribe`
|
|
121
|
+
事件订阅是使用 OCAP Client 构建动态 dApp 的核心功能。它们提供了一个简单而强大的 API,通过可靠的 WebSocket 连接实时响应链上事件。通过使用 `subscribe` 和 `unsubscribe` 方法,您可以有效地管理应用程序中的实时数据流。
|
|
122
122
|
|
|
123
|
-
有关如何构建和发送交易(这些交易会生成这些事件)的更多详细信息,请参阅[交易生命周期](./core-concepts-transaction-lifecycle.md)
|
|
123
|
+
有关如何构建和发送交易(这些交易会生成这些事件)的更多详细信息,请参阅[交易生命周期](./core-concepts-transaction-lifecycle.md)文档。要了解如何为您的用户赞助交易费用(这在与事件监听器结合使用时非常有用),请阅读[燃料费支付](./core-concepts-gas-payment.md)。
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Gas支払い
|
|
2
|
+
|
|
3
|
+
ほとんどのブロックチェーンシステムでは、すべてのトランザクションには、一般的に「ガス」として知られる手数料が必要であり、これは発信者が支払う必要があります。これは、これらの手数料を支払うためのネイティブ通貨を持っていない新規ユーザーにとっては、大きな障壁となり得ます。OCAP Clientは、アプリケーション開発者がこれらの手数料をスポンサーできるGas支払い機能を導入し、ユーザーにシームレスな「ガスレス」体験を提供します。
|
|
4
|
+
|
|
5
|
+
この強力な機能により、dAppsはガスの複雑さを抽象化し、ユーザーのオンボーディングとアプリケーション全体のユーザビリティを向上させることができます。
|
|
6
|
+
|
|
7
|
+
## 仕組み
|
|
8
|
+
|
|
9
|
+
ガス支払いメカニズムは、標準のHTTPヘッダーを介して実装されます。クライアントインスタンスにガス支払いウォレットを設定すると、クライアントはブロックチェーンノードに送信するすべての `sendTx` ミューテーションに、2つの特別なヘッダーを自動的に添付します:
|
|
10
|
+
|
|
11
|
+
- `x-gas-payer-pk`: ガス料金を支払うウォレットの公開鍵。
|
|
12
|
+
- `x-gas-payer-sig`: ガス支払い者の秘密鍵で署名されたJSON Web Token (JWT)。このトークンにはトランザクションのハッシュが含まれており、その特定のトランザクションの手数料を支払うためのスポンサーからの検証可能な承認として機能します。
|
|
13
|
+
|
|
14
|
+
ブロックチェーンノードがトランザクションを受信すると、2つの重要な検証を実行します:
|
|
15
|
+
|
|
16
|
+
1. トランザクション自体のユーザーの署名を検証します。
|
|
17
|
+
2. ヘッダー内のガス支払い者の署名をトランザクションハッシュと照合して検証します。
|
|
18
|
+
|
|
19
|
+
両方の署名が有効な場合、トランザクションはユーザーの権限で実行されますが、対応するガス料金はガス支払い者のアカウント残高から差し引かれます。
|
|
20
|
+
|
|
21
|
+
### ワークフロー図
|
|
22
|
+
|
|
23
|
+
以下の図は、トランザクションの開始から実行までのガス支払いフロー全体を示しています:
|
|
24
|
+
|
|
25
|
+
```d2 ガス支払いのワークフロー icon=mdi:gas-station
|
|
26
|
+
direction: down
|
|
27
|
+
|
|
28
|
+
User-App: {
|
|
29
|
+
label: "ユーザーのアプリケーション"
|
|
30
|
+
shape: rectangle
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
Gas-Payer-Wallet: {
|
|
34
|
+
label: "ガス支払いウォレット\n(アプリバックエンドのウォレット)"
|
|
35
|
+
shape: cylinder
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
OCAP-Client: {
|
|
39
|
+
label: "OCAPクライアントインスタンス"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
Blockchain-Node: {
|
|
43
|
+
label: "ブロックチェーンノード"
|
|
44
|
+
shape: rectangle
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
User-App -> OCAP-Client: "1. ユーザーがトランザクションを開始"
|
|
48
|
+
OCAP-Client -> OCAP-Client: "2. ユーザーのウォレットで\nTxを準備・署名"
|
|
49
|
+
Gas-Payer-Wallet -> OCAP-Client: "3. ガスのためにTxハッシュに署名"
|
|
50
|
+
OCAP-Client -> Blockchain-Node: "4. Tx + ガス支払いヘッダーを送信"
|
|
51
|
+
Blockchain-Node -> Blockchain-Node: "5. 両方の署名を検証"
|
|
52
|
+
Blockchain-Node: "6. トランザクションを実行"
|
|
53
|
+
Blockchain-Node -> Gas-Payer-Wallet: "7. ガス料金を差し引く"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 使用例
|
|
57
|
+
|
|
58
|
+
ガスレストランザクションを有効にするには、スポンサーアカウント用のウォレットインスタンスを作成し、`setGasPayer` メソッドを使用してクライアントに設定するだけです。
|
|
59
|
+
|
|
60
|
+
```javascript Gas Payer Setup and Usage icon=logos:javascript
|
|
61
|
+
import Client from '@ocap/client';
|
|
62
|
+
import Wallet, { fromRandom } from '@ocap/wallet';
|
|
63
|
+
|
|
64
|
+
// 1. Betaチェーンに接続するためにクライアントを初期化します
|
|
65
|
+
const client = new Client('https://beta.abtnetwork.io/api');
|
|
66
|
+
|
|
67
|
+
// 2. ガス支払い者(アプリケーションのウォレット)用のウォレットを作成します
|
|
68
|
+
// このウォレットには、トランザクション手数料をカバーするのに十分なネイティブトークン(TBA)が必要です。
|
|
69
|
+
// テストトークンはフォーセットから入手できます: https://faucet.abtnetwork.io/
|
|
70
|
+
const gasPayerWallet = Wallet.fromJSON({
|
|
71
|
+
sk: '...your_sponsor_secret_key...',
|
|
72
|
+
pk: '...your_sponsor_public_key...',
|
|
73
|
+
address: '...your_sponsor_address...',
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// 3. クライアントインスタンスにガス支払い者を設定します
|
|
77
|
+
client.setGasPayer(gasPayerWallet);
|
|
78
|
+
|
|
79
|
+
// 4. エンドユーザー用のウォレットを作成します。
|
|
80
|
+
const userWallet = fromRandom();
|
|
81
|
+
|
|
82
|
+
// 5. ユーザーのウォレットを使用してトランザクションを送信します。
|
|
83
|
+
// トランザクションはユーザーによって署名されますが、ガス料金はgasPayerWalletによって支払われます。
|
|
84
|
+
async function performGaslessTransaction() {
|
|
85
|
+
try {
|
|
86
|
+
// 注:新しいアカウントは最初の受信トランザクションでオンチェーンに作成されますが、
|
|
87
|
+
// トランザクションを *送信* する前にオンチェーンに存在している必要があります。
|
|
88
|
+
// フォーセットから少量のトークンを送信することで初期化できます。
|
|
89
|
+
|
|
90
|
+
const receiverAddress = 'z1...'; // 有効な受信者アドレス
|
|
91
|
+
const hash = await client.transfer({
|
|
92
|
+
to: receiverAddress,
|
|
93
|
+
tokens: [{ value: '0.1' }], // 0.1 TBAを送信
|
|
94
|
+
wallet: userWallet,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
console.log('ガスレストランザクション成功。ハッシュ:', hash);
|
|
98
|
+
console.log(`エクスプローラーで確認: https://beta.abtnetwork.io/explorer/txs/${hash}`);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error('トランザクション失敗:', error);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
performGaslessTransaction();
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
この例では、`gasPayerWallet`がコストを負担するため、`userWallet`はネイティブトークンの残高がゼロであってもトランザクションを正常に送信できます。これにより、特にアプリケーションに参加する新規ユーザーにとって、摩擦のない体験が生まれます。
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
トランザクションの作成から確定までの全行程を理解するには、[トランザクションライフサイクル](./core-concepts-transaction-lifecycle.md)のドキュメントを参照してください。
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Gas 支付
|
|
2
|
+
|
|
3
|
+
在大多數區塊鏈系統中,每筆交易都需要發起人支付一筆費用,通常稱為「gas」。對於可能沒有原生貨幣來支付這些費用的新使用者來說,這可能是一個重大的障礙。OCAP Client 引入了 Gas 支付功能,允許應用程式開發者贊助這些費用,為其使用者創造無縫的「無 gas」體驗。
|
|
4
|
+
|
|
5
|
+
這個強大的功能使 dApps 能夠將 gas 的複雜性抽離,從而改善使用者引導流程和應用程式的整體可用性。
|
|
6
|
+
|
|
7
|
+
## 運作原理
|
|
8
|
+
|
|
9
|
+
Gas 支付機制是透過標準的 HTTP 標頭實現的。當您在您的客戶端實例上配置一個 gas 支付者錢包時,客戶端會自動將兩個特殊的標頭附加到它發送到區塊鏈節點的每個 `sendTx` 變異中:
|
|
10
|
+
|
|
11
|
+
- `x-gas-payer-pk`:將支付 gas 費用的錢包的公鑰。
|
|
12
|
+
- `x-gas-payer-sig`:由 gas 支付者的私鑰簽署的 JSON Web Token (JWT)。此權杖包含交易的雜湊值,作為贊助商為該特定交易支付費用的可驗證授權。
|
|
13
|
+
|
|
14
|
+
當區塊鏈節點收到交易時,它會執行兩項關鍵的驗證:
|
|
15
|
+
|
|
16
|
+
1. 它會驗證使用者在交易本身上的簽名。
|
|
17
|
+
2. 它會根據交易雜湊值,驗證標頭中 gas 支付者的簽名。
|
|
18
|
+
|
|
19
|
+
如果兩個簽名都有效,交易將以使用者的權限執行,但相應的 gas 費用會從 gas 支付者的帳戶餘額中扣除。
|
|
20
|
+
|
|
21
|
+
### 工作流程圖
|
|
22
|
+
|
|
23
|
+
下圖說明了從交易發起到執行的整個 gas 支付流程:
|
|
24
|
+
|
|
25
|
+
```d2 Gas 支付工作流程 icon=mdi:gas-station
|
|
26
|
+
direction: down
|
|
27
|
+
|
|
28
|
+
User-App: {
|
|
29
|
+
label: "使用者應用程式"
|
|
30
|
+
shape: rectangle
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
Gas-Payer-Wallet: {
|
|
34
|
+
label: "Gas 支付者錢包\n(應用程式後端錢包)"
|
|
35
|
+
shape: cylinder
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
OCAP-Client: {
|
|
39
|
+
label: "OCAP Client 實例"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
Blockchain-Node: {
|
|
43
|
+
label: "區塊鏈節點"
|
|
44
|
+
shape: rectangle
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
User-App -> OCAP-Client: "1. 使用者發起交易"
|
|
48
|
+
OCAP-Client -> OCAP-Client: "2. 使用使用者錢包\n準備並簽署交易"
|
|
49
|
+
Gas-Payer-Wallet -> OCAP-Client: "3. 為 gas 簽署交易雜湊"
|
|
50
|
+
OCAP-Client -> Blockchain-Node: "4. 發送交易 + Gas 支付者標頭"
|
|
51
|
+
Blockchain-Node -> Blockchain-Node: "5. 驗證雙方簽名"
|
|
52
|
+
Blockchain-Node: "6. 執行交易"
|
|
53
|
+
Blockchain-Node -> Gas-Payer-Wallet: "7. 扣除 gas 費用"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 使用範例
|
|
57
|
+
|
|
58
|
+
要啟用無 gas 交易,您只需為贊助帳戶創建一個錢包實例,並使用 `setGasPayer` 方法在客戶端上設定它。
|
|
59
|
+
|
|
60
|
+
```javascript Gas 支付者設定與使用 icon=logos:javascript
|
|
61
|
+
import Client from '@ocap/client';
|
|
62
|
+
import Wallet, { fromRandom } from '@ocap/wallet';
|
|
63
|
+
|
|
64
|
+
// 1. 初始化客戶端以連接到 Beta 鏈
|
|
65
|
+
const client = new Client('https://beta.abtnetwork.io/api');
|
|
66
|
+
|
|
67
|
+
// 2. 為 gas 支付者(您的應用程式錢包)創建一個錢包
|
|
68
|
+
// 此錢包必須有足夠的原生代幣(TBA)來支付交易費用。
|
|
69
|
+
// 您可以從水龍頭獲取測試代幣:https://faucet.abtnetwork.io/
|
|
70
|
+
const gasPayerWallet = Wallet.fromJSON({
|
|
71
|
+
sk: '...your_sponsor_secret_key...',
|
|
72
|
+
pk: '...your_sponsor_public_key...',
|
|
73
|
+
address: '...your_sponsor_address...',
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// 3. 在客戶端實例上設定 gas 支付者
|
|
77
|
+
client.setGasPayer(gasPayerWallet);
|
|
78
|
+
|
|
79
|
+
// 4. 為終端使用者創建一個錢包。
|
|
80
|
+
const userWallet = fromRandom();
|
|
81
|
+
|
|
82
|
+
// 5. 使用使用者的錢包發送一筆交易。
|
|
83
|
+
// 該交易由使用者簽署,但 gas 費用由 gasPayerWallet 支付。
|
|
84
|
+
async function performGaslessTransaction() {
|
|
85
|
+
try {
|
|
86
|
+
// 注意:雖然新帳戶在收到第一筆傳入交易時會在鏈上創建,
|
|
87
|
+
// 但它必須先存在於鏈上,才能*發送*交易。
|
|
88
|
+
// 您可以透過從水龍頭向其發送少量代幣來進行初始化。
|
|
89
|
+
|
|
90
|
+
const receiverAddress = 'z1...'; // 一個有效的收款人地址
|
|
91
|
+
const hash = await client.transfer({
|
|
92
|
+
to: receiverAddress,
|
|
93
|
+
tokens: [{ value: '0.1' }], // 發送 0.1 TBA
|
|
94
|
+
wallet: userWallet,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
console.log('無 gas 交易成功。雜湊值:', hash);
|
|
98
|
+
console.log(`在區塊鏈瀏覽器上查看:https://beta.abtnetwork.io/explorer/txs/${hash}`);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error('交易失敗:', error);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
performGaslessTransaction();
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
在此範例中,`userWallet` 即使原生代幣餘額為零,也可以成功發送交易,因為 `gasPayerWallet` 支付了費用。這創造了一種順暢的體驗,特別是對於加入您應用程式的新使用者。
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
要了解交易從創建到最終確定的完整過程,請參閱 [交易生命週期](./core-concepts-transaction-lifecycle.md) 文件。
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
# Gas
|
|
1
|
+
# Gas 支付
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
在大多数区块链系统中,每笔交易都需要发起者支付一笔费用,通常称为“gas”。对于没有原生货币来支付这些费用的新用户来说,这可能是一个巨大的障碍。OCAP Client 引入了 Gas 支付功能,允许应用程序开发者代付这些费用,从而为用户创造无缝的、“无 gas”体验。
|
|
4
4
|
|
|
5
|
-
这一强大功能使 dApp
|
|
5
|
+
这一强大功能使 dApp 能够屏蔽 gas 的复杂性,从而改善用户引导流程和应用的整体易用性。
|
|
6
6
|
|
|
7
7
|
## 工作原理
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
gas 支付机制通过标准的 HTTP 标头实现。当您在客户端实例上配置 gas 代付方钱包时,客户端会自动将两个特殊的标头附加到它发送给区块链节点的每个 `sendTx` mutation 请求中:
|
|
10
10
|
|
|
11
|
-
- `x-gas-payer-pk`:将支付
|
|
12
|
-
- `x-gas-payer-sig`:由
|
|
11
|
+
- `x-gas-payer-pk`:将支付 gas 费用的钱包的公钥。
|
|
12
|
+
- `x-gas-payer-sig`:由 gas 代付方私钥签名的 JSON Web Token (JWT)。此令牌包含交易的哈希值,作为代付方为该特定交易支付费用的可验证授权。
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
当区块链节点收到交易时,它会执行两项关键验证:
|
|
15
15
|
|
|
16
16
|
1. 验证用户在交易本身的签名。
|
|
17
|
-
2. 根据交易哈希验证标头中
|
|
17
|
+
2. 根据交易哈希验证标头中 gas 代付方的签名。
|
|
18
18
|
|
|
19
|
-
如果两个签名都有效,交易将在用户的授权下执行,但相应的
|
|
19
|
+
如果两个签名都有效,交易将在用户的授权下执行,但相应的 gas 费用将从 gas 代付方的账户余额中扣除。
|
|
20
20
|
|
|
21
|
-
###
|
|
21
|
+
### 工作流程图
|
|
22
22
|
|
|
23
|
-
下图说明了从交易发起 Gas
|
|
23
|
+
下图说明了从交易发起 Gas 支付到执行的整个流程:
|
|
24
24
|
|
|
25
|
-
```d2 Gas
|
|
25
|
+
```d2 Gas 支付工作流 icon=mdi:gas-station
|
|
26
26
|
direction: down
|
|
27
27
|
|
|
28
28
|
User-App: {
|
|
@@ -31,7 +31,7 @@ User-App: {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
Gas-Payer-Wallet: {
|
|
34
|
-
label: "Gas
|
|
34
|
+
label: "Gas 代付方钱包\n(应用后端的钱包)"
|
|
35
35
|
shape: cylinder
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -45,27 +45,27 @@ Blockchain-Node: {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
User-App -> OCAP-Client: "1. 用户发起交易"
|
|
48
|
-
OCAP-Client -> OCAP-Client: "2.
|
|
49
|
-
Gas-Payer-Wallet -> OCAP-Client: "3. 为
|
|
50
|
-
OCAP-Client -> Blockchain-Node: "4. 发送交易 + Gas
|
|
48
|
+
OCAP-Client -> OCAP-Client: "2. 使用用户钱包\n准备并签署交易"
|
|
49
|
+
Gas-Payer-Wallet -> OCAP-Client: "3. 为 gas 签署交易哈希"
|
|
50
|
+
OCAP-Client -> Blockchain-Node: "4. 发送交易 + Gas 代付方标头"
|
|
51
51
|
Blockchain-Node -> Blockchain-Node: "5. 验证双方签名"
|
|
52
52
|
Blockchain-Node: "6. 执行交易"
|
|
53
|
-
Blockchain-Node -> Gas-Payer-Wallet: "7. 扣除
|
|
53
|
+
Blockchain-Node -> Gas-Payer-Wallet: "7. 扣除 gas 费用"
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
##
|
|
56
|
+
## 用法示例
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
要启用无 gas 交易,您只需为代付账户创建一个钱包实例,并使用 `setGasPayer` 方法在客户端上进行设置。
|
|
59
59
|
|
|
60
|
-
```javascript Gas
|
|
60
|
+
```javascript Gas Payer 设置与使用 icon=logos:javascript
|
|
61
61
|
import Client from '@ocap/client';
|
|
62
62
|
import Wallet, { fromRandom } from '@ocap/wallet';
|
|
63
63
|
|
|
64
64
|
// 1. 初始化客户端以连接到 Beta 链
|
|
65
65
|
const client = new Client('https://beta.abtnetwork.io/api');
|
|
66
66
|
|
|
67
|
-
// 2. 为
|
|
68
|
-
//
|
|
67
|
+
// 2. 为 gas 代付方(您的应用程序的钱包)创建一个钱包
|
|
68
|
+
// 此钱包必须有足够的原生代币(TBA)来支付交易费用。
|
|
69
69
|
// 您可以从水龙头获取测试代币:https://faucet.abtnetwork.io/
|
|
70
70
|
const gasPayerWallet = Wallet.fromJSON({
|
|
71
71
|
sk: '...your_sponsor_secret_key...',
|
|
@@ -73,39 +73,39 @@ const gasPayerWallet = Wallet.fromJSON({
|
|
|
73
73
|
address: '...your_sponsor_address...',
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
-
// 3. 在客户端实例上设置
|
|
76
|
+
// 3. 在客户端实例上设置 gas 代付方
|
|
77
77
|
client.setGasPayer(gasPayerWallet);
|
|
78
78
|
|
|
79
79
|
// 4. 为最终用户创建一个钱包。
|
|
80
80
|
const userWallet = fromRandom();
|
|
81
81
|
|
|
82
82
|
// 5. 使用用户的钱包发送一笔交易。
|
|
83
|
-
//
|
|
83
|
+
// 交易由用户签名,但 gas 费用由 gasPayerWallet 支付。
|
|
84
84
|
async function performGaslessTransaction() {
|
|
85
85
|
try {
|
|
86
86
|
// 注意:虽然新账户在收到第一笔入账交易时会在链上创建,
|
|
87
87
|
// 但它必须在链上存在才能 *发送* 交易。
|
|
88
88
|
// 您可以通过从水龙头向其发送少量代币来初始化它。
|
|
89
89
|
|
|
90
|
-
const receiverAddress = 'z1...'; //
|
|
90
|
+
const receiverAddress = 'z1...'; // 一个有效的接收者地址
|
|
91
91
|
const hash = await client.transfer({
|
|
92
92
|
to: receiverAddress,
|
|
93
93
|
tokens: [{ value: '0.1' }], // 发送 0.1 TBA
|
|
94
94
|
wallet: userWallet,
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
-
console.log('
|
|
98
|
-
console.log(
|
|
97
|
+
console.log('无 gas 交易成功。哈希:', hash);
|
|
98
|
+
console.log(`在浏览器上查看: https://beta.abtnetwork.io/explorer/txs/${hash}`);
|
|
99
99
|
} catch (error) {
|
|
100
|
-
console.error('
|
|
100
|
+
console.error('交易失败:', error);
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
performGaslessTransaction();
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
在此示例中,`userWallet` 即使原生代币余额为零也能成功发送交易,因为 `gasPayerWallet` 承担了费用。这创造了无摩擦的体验,特别是对于加入您应用程序的新用户而言。
|
|
108
108
|
|
|
109
109
|
---
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
要了解从创建到最终确认的完整交易过程,请参阅[交易生命周期](./core-concepts-transaction-lifecycle.md)文档。
|