turing-wallet-provider 1.5.2 → 1.5.4
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/README.md +251 -21
- package/dist/types/providerTypes.d.ts +11 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,6 +65,71 @@ const {name,platform,version} = await wallet.getInfo();
|
|
|
65
65
|
{Turing,android,1.0.0}//示例的返回值
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
+
## getNetwork
|
|
69
|
+
|
|
70
|
+
获取已连接账户当前激活的网络。
|
|
71
|
+
|
|
72
|
+
### 用法
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const wallet = useTuringWallet();
|
|
76
|
+
const network = await wallet.getNetwork();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 参数
|
|
80
|
+
|
|
81
|
+
该方法不接受任何参数。
|
|
82
|
+
|
|
83
|
+
### 返回值
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
interface GetNetworkResponse {
|
|
87
|
+
network: "tbc" | "btc" | "eth" | "bnb" | "all";
|
|
88
|
+
type: "mainnet" | "testnet";
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
| 字段 | 类型 | 说明 |
|
|
93
|
+
| --- | --- | --- |
|
|
94
|
+
| `network` | `"tbc" \| "btc" \| "eth" \| "bnb" \| "all"` | 当前激活的链。`"all"` 表示用户处于钱包的"所有网络"视图,未选择具体的链。 |
|
|
95
|
+
| `type` | `"mainnet" \| "testnet"` | 主网 / 测试网。仅 `tbc` 可能为 `"testnet"`,其余链恒为 `"mainnet"`。 |
|
|
96
|
+
|
|
97
|
+
### 错误处理
|
|
98
|
+
|
|
99
|
+
| 错误 | 原因 |
|
|
100
|
+
| --- | --- |
|
|
101
|
+
| `User not connected` | 尚未调用 `wallet.connect()`,或用户已断开连接。 |
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
const wallet = useTuringWallet();
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const info = await wallet.getNetwork();
|
|
108
|
+
console.log(info);
|
|
109
|
+
} catch (error) {
|
|
110
|
+
console.error("Failed to get network:", error);
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 订阅变化
|
|
115
|
+
|
|
116
|
+
钱包内切换网络时,dapp 会收到 `TuringNetworkChanged` 事件并附带新的网络信息,无需轮询 `getNetwork()`。
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
window.addEventListener("TuringNetworkChanged", (event) => {
|
|
120
|
+
const { network } = event.detail;
|
|
121
|
+
// `network` 与 wallet.getNetwork() 的返回值同结构
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
interface TuringNetworkChangedDetail {
|
|
127
|
+
network: GetNetworkResponse;
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
仅在 dapp 已连接期间触发,且只推送 `connect()` 之后的变化(初始网络可通过 `wallet.getNetwork()` 获取)。
|
|
132
|
+
|
|
68
133
|
## signMessage
|
|
69
134
|
|
|
70
135
|
```ts
|
|
@@ -176,33 +241,93 @@ broadcastTXsraw(txs.map((tx) => ({ txraw: tx.uncheckedSerialize() })));
|
|
|
176
241
|
|
|
177
242
|
## signAssociatedTransaction
|
|
178
243
|
|
|
244
|
+
使用钱包签名父子(关联)交易。钱包根据源交易构建子交易并统一签名。
|
|
245
|
+
|
|
246
|
+
### 用法
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
const { txraws } = await Turing.signAssociatedTransaction({
|
|
250
|
+
sourceTxraw,
|
|
251
|
+
sourceUtxos,
|
|
252
|
+
inputs,
|
|
253
|
+
outputs,
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### 参数
|
|
258
|
+
|
|
179
259
|
```ts
|
|
180
|
-
//使用示例
|
|
181
260
|
interface Input {
|
|
182
|
-
txId?: string;
|
|
183
|
-
script?: string;
|
|
184
|
-
satoshis?: number;
|
|
185
|
-
outputIndex: number;
|
|
186
|
-
scriptSigType:
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
261
|
+
txId?: string; // 交易 ID(源交易输入需提供)
|
|
262
|
+
script?: string; // 锁定脚本,仅支持 hex 格式
|
|
263
|
+
satoshis?: number; // satoshi 值
|
|
264
|
+
outputIndex: number; // 输出索引
|
|
265
|
+
scriptSigType:
|
|
266
|
+
| "p2pkh"
|
|
267
|
+
| "tbc20" // 普通 FT 转账解锁
|
|
268
|
+
| "tbc20_contract" // 普通 FT 在合约/swap 场景下的解锁
|
|
269
|
+
| "tbc20_coin" // 稳定币转账解锁(FT.getFTunlock + isCoin)
|
|
270
|
+
| "tbc20_coin_contract" // 稳定币在合约/swap 场景下的解锁(FT.getFTunlockSwap + isCoin)
|
|
271
|
+
| "other"; // 脚本签名类型
|
|
272
|
+
unfinishedScriptSig?: string; // "other" 类型的自定义脚本模板(hex 格式),签名部分用 097369676e6174757265 替代
|
|
273
|
+
ftVersion?: 1 | 2; // "tbc20_contract"/"tbc20_coin_contract" 类型的 FT 版本
|
|
274
|
+
contractTxId?: string; // "tbc20_contract"/"tbc20_coin_contract" 类型的合约交易 ID
|
|
190
275
|
}
|
|
191
276
|
|
|
192
277
|
interface Output {
|
|
193
|
-
script: string;
|
|
194
|
-
satoshis: number;
|
|
278
|
+
script: string; // 输出锁定脚本,仅支持 hex 格式
|
|
279
|
+
satoshis: number; // 输出的 satoshi 值
|
|
195
280
|
}
|
|
196
281
|
|
|
197
282
|
interface SignAssociatedTransactionRequestData {
|
|
198
|
-
sourceTxraw: string;
|
|
199
|
-
sourceUtxos: Input[];
|
|
200
|
-
inputs?: Input[][];
|
|
201
|
-
outputs?: Output[][];
|
|
283
|
+
sourceTxraw: string; // 源头交易的原始 hex 字符串
|
|
284
|
+
sourceUtxos: Input[]; // 源头交易的 UTXO 数组
|
|
285
|
+
inputs?: Input[][]; // 子交易输入的二维数组
|
|
286
|
+
outputs?: Output[][]; // 子交易输出的二维数组
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
291
|
+
| --- | --- | --- | --- |
|
|
292
|
+
| `sourceTxraw` | `string` | 是 | 源头交易的原始 hex 字符串 |
|
|
293
|
+
| `sourceUtxos` | `Input[]` | 是 | 源头交易的 UTXO 数组 |
|
|
294
|
+
| `inputs` | `Input[][]` | 否 | 二维数组 — 每个子数组代表一个子交易的输入 |
|
|
295
|
+
| `outputs` | `Output[][]` | 否 | 二维数组 — 每个子数组代表一个子交易的输出 |
|
|
296
|
+
|
|
297
|
+
### 返回值
|
|
298
|
+
|
|
299
|
+
```ts
|
|
300
|
+
interface SignAssociatedTransactionResponse {
|
|
301
|
+
txraws: string[]; // 已组装的待广播交易 hex 字符串数组(包含父子交易)
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
| 字段 | 类型 | 说明 |
|
|
306
|
+
| --- | --- | --- |
|
|
307
|
+
| `txraws` | `string[]` | 包含父子交易的已组装待广播交易数组 |
|
|
308
|
+
|
|
309
|
+
### 错误处理
|
|
310
|
+
|
|
311
|
+
```ts
|
|
312
|
+
try {
|
|
313
|
+
const { txraws } = await Turing.signAssociatedTransaction({
|
|
314
|
+
sourceTxraw,
|
|
315
|
+
sourceUtxos,
|
|
316
|
+
inputs,
|
|
317
|
+
outputs,
|
|
318
|
+
});
|
|
319
|
+
console.log("交易:", txraws);
|
|
320
|
+
} catch (error) {
|
|
321
|
+
console.error("签名失败:", error);
|
|
202
322
|
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### 示例
|
|
203
326
|
|
|
204
|
-
|
|
205
|
-
|
|
327
|
+
FT 转移示例:
|
|
328
|
+
|
|
329
|
+
```ts
|
|
330
|
+
const sourceUtxos: Input[] = [
|
|
206
331
|
{
|
|
207
332
|
txId: "",
|
|
208
333
|
outputIndex: 0,
|
|
@@ -219,7 +344,7 @@ const sourceUtxos: intput[] = [
|
|
|
219
344
|
},
|
|
220
345
|
];
|
|
221
346
|
|
|
222
|
-
const inputs:
|
|
347
|
+
const inputs: Input[][] = [
|
|
223
348
|
[
|
|
224
349
|
{ outputIndex: 0, scriptSigType: "tbc20" },
|
|
225
350
|
{ outputIndex: 2, scriptSigType: "p2pkh" },
|
|
@@ -230,7 +355,7 @@ const inputs: intput[][] = [
|
|
|
230
355
|
],
|
|
231
356
|
];
|
|
232
357
|
|
|
233
|
-
const outputs:
|
|
358
|
+
const outputs: Output[][] = [
|
|
234
359
|
[
|
|
235
360
|
{
|
|
236
361
|
script: ftcode,
|
|
@@ -261,8 +386,113 @@ const outputs: output[][] = [
|
|
|
261
386
|
],
|
|
262
387
|
];
|
|
263
388
|
|
|
264
|
-
const
|
|
265
|
-
|
|
389
|
+
const { txraws } = await Turing.signAssociatedTransaction({
|
|
390
|
+
sourceTxraw,
|
|
391
|
+
sourceUtxos,
|
|
392
|
+
inputs,
|
|
393
|
+
outputs,
|
|
394
|
+
});
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### 稳定币 (tbc20_coin / tbc20_coin_contract)
|
|
398
|
+
|
|
399
|
+
稳定币是一种特殊的 FT,解锁脚本与普通 FT 不同,所以提供了专用的 `scriptSigType`:
|
|
400
|
+
|
|
401
|
+
- `"tbc20_coin"`:稳定币普通转账解锁
|
|
402
|
+
- `"tbc20_coin_contract"`:稳定币参与合约 / swap 场景的解锁(同时需要 `contractTxId` 与 `ftVersion`)
|
|
403
|
+
|
|
404
|
+
#### 子交易 (`inputs` / `outputs`)
|
|
405
|
+
|
|
406
|
+
只要把对应输入的 `scriptSigType` 标成 `"tbc20_coin"` 或 `"tbc20_coin_contract"` 即可,**其它字段与普通 FT 写法完全一致**,无需关心 sequence / nLockTime。
|
|
407
|
+
|
|
408
|
+
#### 源交易 (`sourceTxraw`)
|
|
409
|
+
|
|
410
|
+
`sourceTxraw` 是调用方自己组装好的原始交易,**如果里面包含稳定币输入**,必须在构建时自行满足以下两个条件:
|
|
411
|
+
|
|
412
|
+
1. 每个稳定币输入的 `sequence` 设为 `0xFFFFFFFE`
|
|
413
|
+
2. 整笔交易的 `nLockTime` 设为所有被花费稳定币 UTXO tape 中 `lockTime` 的最大值
|
|
414
|
+
|
|
415
|
+
参考写法:
|
|
416
|
+
|
|
417
|
+
```ts
|
|
418
|
+
import { Transaction } from "tbc-lib-js";
|
|
419
|
+
import { stableCoin } from "tbc-contract";
|
|
420
|
+
|
|
421
|
+
const tx = new Transaction().from(coinUtxos).from(payUtxo);
|
|
422
|
+
// ...addOutput(...)
|
|
423
|
+
|
|
424
|
+
for (let i = 0; i < coinUtxos.length; i++) {
|
|
425
|
+
tx.setInputSequence(i, 0xFFFFFFFE);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
let lockTimeMax = 0;
|
|
429
|
+
for (let i = 0; i < coinUtxos.length; i++) {
|
|
430
|
+
const lt = stableCoin.getLockTimeFromTape(
|
|
431
|
+
preTXs[i].outputs[coinUtxos[i].outputIndex + 1].script
|
|
432
|
+
);
|
|
433
|
+
lockTimeMax = Math.max(lockTimeMax, lt);
|
|
434
|
+
}
|
|
435
|
+
tx.setLockTime(lockTimeMax);
|
|
436
|
+
|
|
437
|
+
const sourceTxraw = tx.uncheckedSerialize();
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
> 对应的 `sourceUtxos` 条目仍要填 `"tbc20_coin"` 或 `"tbc20_coin_contract"`。
|
|
441
|
+
|
|
442
|
+
#### 稳定币示例
|
|
443
|
+
|
|
444
|
+
父交易花掉 1 个稳定币 UTXO + 1 个 P2PKH UTXO,产生新的稳定币 UTXO(output 0/1 为 code/tape,output 2 为 P2PKH 找零);子交易再次花掉这个新稳定币 UTXO:
|
|
445
|
+
|
|
446
|
+
```ts
|
|
447
|
+
const sourceUtxos: Input[] = [
|
|
448
|
+
{
|
|
449
|
+
txId: coinUtxo.txId,
|
|
450
|
+
outputIndex: coinUtxo.outputIndex,
|
|
451
|
+
satoshis: 500,
|
|
452
|
+
script: coinCodeHex,
|
|
453
|
+
scriptSigType: "tbc20_coin",
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
txId: payUtxo.txId,
|
|
457
|
+
outputIndex: payUtxo.outputIndex,
|
|
458
|
+
satoshis: 10000,
|
|
459
|
+
script: p2pkhHex,
|
|
460
|
+
scriptSigType: "p2pkh",
|
|
461
|
+
},
|
|
462
|
+
];
|
|
463
|
+
|
|
464
|
+
const inputs: Input[][] = [
|
|
465
|
+
[
|
|
466
|
+
{ outputIndex: 0, scriptSigType: "tbc20_coin" },
|
|
467
|
+
{ outputIndex: 2, scriptSigType: "p2pkh" },
|
|
468
|
+
],
|
|
469
|
+
];
|
|
470
|
+
|
|
471
|
+
const outputs: Output[][] = [
|
|
472
|
+
[
|
|
473
|
+
{ script: newCoinCodeHex, satoshis: 500 },
|
|
474
|
+
{ script: newCoinTapeHex, satoshis: 0 },
|
|
475
|
+
{ script: p2pkhChangeHex, satoshis: 8000 },
|
|
476
|
+
],
|
|
477
|
+
];
|
|
478
|
+
|
|
479
|
+
const { txraws } = await Turing.signAssociatedTransaction({
|
|
480
|
+
sourceTxraw,
|
|
481
|
+
sourceUtxos,
|
|
482
|
+
inputs,
|
|
483
|
+
outputs,
|
|
484
|
+
});
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
如果稳定币要走合约 / swap 路径,把 `scriptSigType` 改成 `"tbc20_coin_contract"`,并附上 `contractTxId` 与 `ftVersion`:
|
|
488
|
+
|
|
489
|
+
```ts
|
|
490
|
+
{
|
|
491
|
+
outputIndex: 0,
|
|
492
|
+
scriptSigType: "tbc20_coin_contract",
|
|
493
|
+
contractTxId: "<合约交易 ID>",
|
|
494
|
+
ftVersion: 2,
|
|
495
|
+
}
|
|
266
496
|
```
|
|
267
497
|
|
|
268
498
|
## sendTransaction
|
|
@@ -17,6 +17,15 @@ export type Info = {
|
|
|
17
17
|
version: string;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
+
export type GetNetworkResponse = {
|
|
21
|
+
network: "tbc" | "btc" | "eth" | "bnb" | "all";
|
|
22
|
+
type: "mainnet" | "testnet";
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type TuringNetworkChangedDetail = {
|
|
26
|
+
network: GetNetworkResponse;
|
|
27
|
+
};
|
|
28
|
+
|
|
20
29
|
export type TransactionFlag =
|
|
21
30
|
| "P2PKH"
|
|
22
31
|
| "COLLECTION_CREATE"
|
|
@@ -125,7 +134,7 @@ export type Input = {
|
|
|
125
134
|
script?: string;
|
|
126
135
|
satoshis?: number;
|
|
127
136
|
outputIndex: number;
|
|
128
|
-
scriptSigType: "p2pkh" | "tbc20" | "tbc20_contract" | "other";
|
|
137
|
+
scriptSigType: "p2pkh" | "tbc20" | "tbc20_contract" | "tbc20_coin" | "tbc20_coin_contract" | "other";
|
|
129
138
|
unfinishedScriptSig?: string;
|
|
130
139
|
ftVersion?: 1 | 2;
|
|
131
140
|
contractTxId?: string;
|
|
@@ -241,6 +250,7 @@ export type TuringProviderType = {
|
|
|
241
250
|
getPubKey: () => Promise<PubKey | undefined>;
|
|
242
251
|
getAddress: () => Promise<Address | undefined>;
|
|
243
252
|
getInfo: () => Promise<Info | undefined>;
|
|
253
|
+
getNetwork: () => Promise<GetNetworkResponse | undefined>;
|
|
244
254
|
sendTransaction: (
|
|
245
255
|
params: SendTransaction[]
|
|
246
256
|
) => Promise<SendTransactionResponse | undefined>;
|