@ckb-ccc/core 0.0.13-alpha.6 → 0.0.13-alpha.8
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/CHANGELOG.md +22 -0
- package/dist/ckb/transaction.d.ts +91 -1
- package/dist/ckb/transaction.d.ts.map +1 -1
- package/dist/ckb/transaction.js +118 -24
- package/dist/client/cache/cache.d.ts +29 -9
- package/dist/client/cache/cache.d.ts.map +1 -1
- package/dist/client/cache/cache.js +43 -1
- package/dist/client/cache/memory.d.ts +10 -6
- package/dist/client/cache/memory.d.ts.map +1 -1
- package/dist/client/cache/memory.js +49 -39
- package/dist/client/client.d.ts +10 -4
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +6 -5
- package/dist/client/clientPublicMainnet.advanced.d.ts.map +1 -1
- package/dist/client/clientPublicMainnet.advanced.js +15 -0
- package/dist/client/clientPublicTestnet.advanced.d.ts.map +1 -1
- package/dist/client/clientPublicTestnet.advanced.js +15 -0
- package/dist/client/clientTypes.d.ts +47 -4
- package/dist/client/clientTypes.d.ts.map +1 -1
- package/dist/client/clientTypes.js +26 -1
- package/dist/client/jsonRpc/index.d.ts +39 -1
- package/dist/client/jsonRpc/index.d.ts.map +1 -1
- package/dist/client/jsonRpc/index.js +63 -2
- package/dist/client/jsonRpc/transformers.d.ts.map +1 -1
- package/dist/client/jsonRpc/transformers.js +11 -4
- package/dist/fixedPoint/index.d.ts +3 -3
- package/dist/fixedPoint/index.js +3 -3
- package/dist/signer/signer/index.d.ts +3 -1
- package/dist/signer/signer/index.d.ts.map +1 -1
- package/dist/signer/signer/index.js +14 -0
- package/dist.commonjs/ckb/transaction.d.ts +91 -1
- package/dist.commonjs/ckb/transaction.d.ts.map +1 -1
- package/dist.commonjs/ckb/transaction.js +121 -23
- package/dist.commonjs/client/cache/cache.d.ts +29 -9
- package/dist.commonjs/client/cache/cache.d.ts.map +1 -1
- package/dist.commonjs/client/cache/cache.js +45 -0
- package/dist.commonjs/client/cache/memory.d.ts +10 -6
- package/dist.commonjs/client/cache/memory.d.ts.map +1 -1
- package/dist.commonjs/client/cache/memory.js +49 -39
- package/dist.commonjs/client/client.d.ts +10 -4
- package/dist.commonjs/client/client.d.ts.map +1 -1
- package/dist.commonjs/client/client.js +6 -5
- package/dist.commonjs/client/clientPublicMainnet.advanced.d.ts.map +1 -1
- package/dist.commonjs/client/clientPublicMainnet.advanced.js +15 -0
- package/dist.commonjs/client/clientPublicTestnet.advanced.d.ts.map +1 -1
- package/dist.commonjs/client/clientPublicTestnet.advanced.js +15 -0
- package/dist.commonjs/client/clientTypes.d.ts +47 -4
- package/dist.commonjs/client/clientTypes.d.ts.map +1 -1
- package/dist.commonjs/client/clientTypes.js +33 -5
- package/dist.commonjs/client/jsonRpc/index.d.ts +39 -1
- package/dist.commonjs/client/jsonRpc/index.d.ts.map +1 -1
- package/dist.commonjs/client/jsonRpc/index.js +74 -13
- package/dist.commonjs/client/jsonRpc/transformers.d.ts.map +1 -1
- package/dist.commonjs/client/jsonRpc/transformers.js +55 -48
- package/dist.commonjs/fixedPoint/index.d.ts +3 -3
- package/dist.commonjs/fixedPoint/index.js +3 -3
- package/dist.commonjs/signer/signer/index.d.ts +3 -1
- package/dist.commonjs/signer/signer/index.d.ts.map +1 -1
- package/dist.commonjs/signer/signer/index.js +14 -0
- package/package.json +1 -1
- package/src/ckb/transaction.ts +170 -30
- package/src/client/cache/cache.ts +58 -13
- package/src/client/cache/memory.ts +60 -52
- package/src/client/client.ts +22 -5
- package/src/client/clientPublicMainnet.advanced.ts +17 -0
- package/src/client/clientPublicTestnet.advanced.ts +17 -0
- package/src/client/clientTypes.ts +76 -5
- package/src/client/jsonRpc/index.ts +105 -3
- package/src/client/jsonRpc/transformers.ts +11 -3
- package/src/fixedPoint/index.ts +3 -3
- package/src/signer/signer/index.ts +20 -1
|
@@ -8,23 +8,68 @@ import {
|
|
|
8
8
|
import { HexLike } from "../../hex/index.js";
|
|
9
9
|
import { ClientCollectableSearchKeyLike } from "../clientTypes.advanced.js";
|
|
10
10
|
|
|
11
|
-
export
|
|
12
|
-
markUsable(...cellLikes: (CellLike | CellLike[])[]): Promise<void>;
|
|
13
|
-
markUnusable(
|
|
11
|
+
export abstract class ClientCache {
|
|
12
|
+
abstract markUsable(...cellLikes: (CellLike | CellLike[])[]): Promise<void>;
|
|
13
|
+
abstract markUnusable(
|
|
14
14
|
...outPointLike: (OutPointLike | OutPointLike[])[]
|
|
15
15
|
): Promise<void>;
|
|
16
|
-
markTransactions(
|
|
16
|
+
async markTransactions(
|
|
17
17
|
...transactionLike: (TransactionLike | TransactionLike[])[]
|
|
18
|
-
): Promise<void
|
|
18
|
+
): Promise<void> {
|
|
19
|
+
await Promise.all([
|
|
20
|
+
this.recordTransactions(...transactionLike),
|
|
21
|
+
...transactionLike.flat().map((transactionLike) => {
|
|
22
|
+
const tx = Transaction.from(transactionLike);
|
|
23
|
+
const txHash = tx.hash();
|
|
19
24
|
|
|
20
|
-
|
|
25
|
+
return Promise.all([
|
|
26
|
+
...tx.inputs.map((i) => this.markUnusable(i.previousOutput)),
|
|
27
|
+
...tx.outputs.map((o, i) =>
|
|
28
|
+
this.markUsable({
|
|
29
|
+
cellOutput: o,
|
|
30
|
+
outputData: tx.outputsData[i],
|
|
31
|
+
outPoint: {
|
|
32
|
+
txHash,
|
|
33
|
+
index: i,
|
|
34
|
+
},
|
|
35
|
+
}),
|
|
36
|
+
),
|
|
37
|
+
]);
|
|
38
|
+
}),
|
|
39
|
+
]);
|
|
40
|
+
}
|
|
41
|
+
abstract clear(): Promise<void>;
|
|
42
|
+
abstract findCells(
|
|
43
|
+
filter: ClientCollectableSearchKeyLike,
|
|
44
|
+
): AsyncGenerator<Cell>;
|
|
45
|
+
/**
|
|
46
|
+
* Get a known cell by out point
|
|
47
|
+
* @param _outPoint
|
|
48
|
+
*/
|
|
49
|
+
abstract getCell(_outPoint: OutPointLike): Promise<Cell | undefined>;
|
|
50
|
+
abstract isUnusable(outPointLike: OutPointLike): Promise<boolean>;
|
|
21
51
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Record known transactions
|
|
54
|
+
* Implement this method to enable transactions query caching
|
|
55
|
+
* @param _transactions
|
|
56
|
+
*/
|
|
57
|
+
async recordTransactions(
|
|
58
|
+
..._transactions: (TransactionLike | TransactionLike[])[]
|
|
59
|
+
): Promise<void> {}
|
|
60
|
+
/**
|
|
61
|
+
* Get a known transaction by hash
|
|
62
|
+
* Implement this method to enable transactions query caching
|
|
63
|
+
* @param _txHash
|
|
64
|
+
*/
|
|
65
|
+
async getTransaction(_txHash: HexLike): Promise<Transaction | undefined> {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
26
68
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Record known cells
|
|
71
|
+
* Implement this method to enable cells query caching
|
|
72
|
+
* @param _cells
|
|
73
|
+
*/
|
|
74
|
+
async recordCells(..._cells: (CellLike | CellLike[])[]): Promise<void> {}
|
|
30
75
|
}
|
|
@@ -11,24 +11,32 @@ import { ClientCollectableSearchKeyLike } from "../clientTypes.advanced.js";
|
|
|
11
11
|
import { ClientCache } from "./cache.js";
|
|
12
12
|
import { filterCell } from "./memory.advanced.js";
|
|
13
13
|
|
|
14
|
-
export class ClientCacheMemory
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
private readonly
|
|
14
|
+
export class ClientCacheMemory extends ClientCache {
|
|
15
|
+
/**
|
|
16
|
+
* OutPoint => [isLive, Cell | OutPoint]
|
|
17
|
+
*/
|
|
18
|
+
private readonly cells: Map<
|
|
19
|
+
string,
|
|
20
|
+
| [
|
|
21
|
+
false,
|
|
22
|
+
Pick<Cell, "outPoint"> &
|
|
23
|
+
Partial<Pick<Cell, "cellOutput" | "outputData">>,
|
|
24
|
+
]
|
|
25
|
+
| [true, Cell]
|
|
26
|
+
| [undefined, Cell]
|
|
27
|
+
> = new Map();
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* TX Hash => Transaction
|
|
31
|
+
*/
|
|
32
|
+
private readonly knownTransactions: Map<string, Transaction> = new Map();
|
|
19
33
|
|
|
20
34
|
async markUsable(...cellLikes: (CellLike | CellLike[])[]): Promise<void> {
|
|
21
35
|
cellLikes.flat().forEach((cellLike) => {
|
|
22
36
|
const cell = Cell.from(cellLike).clone();
|
|
23
|
-
|
|
24
|
-
this.knownCells.push(cell);
|
|
37
|
+
const outPointStr = hexFrom(cell.outPoint.toBytes());
|
|
25
38
|
|
|
26
|
-
|
|
27
|
-
cell.outPoint.eq(o),
|
|
28
|
-
);
|
|
29
|
-
if (index !== -1) {
|
|
30
|
-
this.unusableOutPoints.splice(index, 1);
|
|
31
|
-
}
|
|
39
|
+
this.cells.set(outPointStr, [true, cell]);
|
|
32
40
|
});
|
|
33
41
|
}
|
|
34
42
|
|
|
@@ -37,74 +45,74 @@ export class ClientCacheMemory implements ClientCache {
|
|
|
37
45
|
): Promise<void> {
|
|
38
46
|
outPointLikes.flat().forEach((outPointLike) => {
|
|
39
47
|
const outPoint = OutPoint.from(outPointLike);
|
|
40
|
-
|
|
48
|
+
const outPointStr = hexFrom(outPoint.toBytes());
|
|
41
49
|
|
|
42
|
-
const
|
|
43
|
-
if (
|
|
44
|
-
|
|
50
|
+
const existed = this.cells.get(outPointStr);
|
|
51
|
+
if (existed) {
|
|
52
|
+
existed[0] = false;
|
|
53
|
+
return;
|
|
45
54
|
}
|
|
55
|
+
this.cells.set(outPointStr, [false, { outPoint }]);
|
|
46
56
|
});
|
|
47
57
|
}
|
|
48
58
|
|
|
49
|
-
async
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
transactionLike.flat().map(async (transactionLike) => {
|
|
54
|
-
const tx = Transaction.from(transactionLike);
|
|
55
|
-
const txHash = tx.hash();
|
|
56
|
-
|
|
57
|
-
await Promise.all(
|
|
58
|
-
tx.inputs.map((i) => this.markUnusable(i.previousOutput)),
|
|
59
|
-
);
|
|
60
|
-
await Promise.all(
|
|
61
|
-
tx.outputs.map((o, i) =>
|
|
62
|
-
this.markUsable({
|
|
63
|
-
cellOutput: o,
|
|
64
|
-
outputData: tx.outputsData[i],
|
|
65
|
-
outPoint: {
|
|
66
|
-
txHash,
|
|
67
|
-
index: i,
|
|
68
|
-
},
|
|
69
|
-
}),
|
|
70
|
-
),
|
|
71
|
-
);
|
|
72
|
-
}),
|
|
73
|
-
);
|
|
59
|
+
async clear(): Promise<void> {
|
|
60
|
+
for (const val of this.cells.values()) {
|
|
61
|
+
val[0] = undefined;
|
|
62
|
+
}
|
|
74
63
|
}
|
|
75
64
|
|
|
76
65
|
async *findCells(
|
|
77
66
|
keyLike: ClientCollectableSearchKeyLike,
|
|
78
67
|
): AsyncGenerator<Cell> {
|
|
79
|
-
for (const cell of this.
|
|
68
|
+
for (const [isLive, cell] of this.cells.values()) {
|
|
69
|
+
if (!isLive) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
80
72
|
if (!filterCell(keyLike, cell)) {
|
|
81
73
|
continue;
|
|
82
74
|
}
|
|
83
75
|
|
|
84
|
-
yield cell;
|
|
76
|
+
yield cell.clone();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async getCell(outPointLike: OutPointLike): Promise<Cell | undefined> {
|
|
80
|
+
const outPoint = OutPoint.from(outPointLike);
|
|
81
|
+
|
|
82
|
+
const cell = this.cells.get(hexFrom(outPoint.toBytes()))?.[1];
|
|
83
|
+
if (cell && cell.cellOutput && cell.outputData) {
|
|
84
|
+
return Cell.from((cell as Cell).clone());
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
async isUnusable(outPointLike: OutPointLike): Promise<boolean> {
|
|
89
89
|
const outPoint = OutPoint.from(outPointLike);
|
|
90
|
-
|
|
90
|
+
|
|
91
|
+
return !(this.cells.get(hexFrom(outPoint.toBytes()))?.[0] ?? true);
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
async recordTransactions(
|
|
94
95
|
...transactions: (TransactionLike | TransactionLike[])[]
|
|
95
96
|
): Promise<void> {
|
|
96
|
-
|
|
97
|
+
transactions.flat().map((txLike) => {
|
|
98
|
+
const tx = Transaction.from(txLike);
|
|
99
|
+
this.knownTransactions.set(tx.hash(), tx);
|
|
100
|
+
});
|
|
97
101
|
}
|
|
98
102
|
async getTransaction(txHashLike: HexLike): Promise<Transaction | undefined> {
|
|
99
103
|
const txHash = hexFrom(txHashLike);
|
|
100
|
-
return this.knownTransactions.
|
|
104
|
+
return this.knownTransactions.get(txHash)?.clone();
|
|
101
105
|
}
|
|
102
106
|
|
|
103
107
|
async recordCells(...cells: (CellLike | CellLike[])[]): Promise<void> {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
cells.flat().map((cellLike) => {
|
|
109
|
+
const cell = Cell.from(cellLike);
|
|
110
|
+
const outPointStr = hexFrom(cell.outPoint.toBytes());
|
|
111
|
+
|
|
112
|
+
if (this.cells.get(outPointStr)) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this.cells.set(outPointStr, [undefined, cell]);
|
|
116
|
+
});
|
|
109
117
|
}
|
|
110
118
|
}
|
package/src/client/client.ts
CHANGED
|
@@ -18,6 +18,7 @@ import { ClientCacheMemory } from "./cache/memory.js";
|
|
|
18
18
|
import { ClientCollectableSearchKeyLike } from "./clientTypes.advanced.js";
|
|
19
19
|
import {
|
|
20
20
|
ClientBlock,
|
|
21
|
+
ClientBlockHeader,
|
|
21
22
|
ClientFindCellsResponse,
|
|
22
23
|
ClientFindTransactionsGroupedResponse,
|
|
23
24
|
ClientFindTransactionsResponse,
|
|
@@ -45,6 +46,7 @@ export enum KnownScript {
|
|
|
45
46
|
UniqueType = "UniqueType",
|
|
46
47
|
SingleUseLock = "SingleUseLock",
|
|
47
48
|
OutputTypeProxyLock = "OutputTypeProxyLock",
|
|
49
|
+
NervosDao = "NervosDao",
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
/**
|
|
@@ -92,6 +94,7 @@ export abstract class Client {
|
|
|
92
94
|
>;
|
|
93
95
|
|
|
94
96
|
abstract getTip(): Promise<Num>;
|
|
97
|
+
abstract getTipHeader(verbosity?: number | null): Promise<ClientBlockHeader>;
|
|
95
98
|
abstract getBlockByNumber(
|
|
96
99
|
blockNumber: NumLike,
|
|
97
100
|
verbosity?: number | null,
|
|
@@ -102,6 +105,20 @@ export abstract class Client {
|
|
|
102
105
|
verbosity?: number | null,
|
|
103
106
|
withCycles?: boolean | null,
|
|
104
107
|
): Promise<ClientBlock | undefined>;
|
|
108
|
+
abstract getHeaderByNumber(
|
|
109
|
+
blockNumber: NumLike,
|
|
110
|
+
verbosity?: number | null,
|
|
111
|
+
): Promise<ClientBlockHeader | undefined>;
|
|
112
|
+
abstract getHeaderByHash(
|
|
113
|
+
blockHash: HexLike,
|
|
114
|
+
verbosity?: number | null,
|
|
115
|
+
): Promise<ClientBlockHeader | undefined>;
|
|
116
|
+
|
|
117
|
+
abstract estimateCycles(transaction: TransactionLike): Promise<Num>;
|
|
118
|
+
abstract sendTransactionDry(
|
|
119
|
+
transaction: TransactionLike,
|
|
120
|
+
validator?: OutputsValidator,
|
|
121
|
+
): Promise<Num>;
|
|
105
122
|
|
|
106
123
|
abstract sendTransactionNoCache(
|
|
107
124
|
transaction: TransactionLike,
|
|
@@ -155,7 +172,7 @@ export abstract class Client {
|
|
|
155
172
|
return res;
|
|
156
173
|
}
|
|
157
174
|
|
|
158
|
-
async *
|
|
175
|
+
async *findCellsOnChin(
|
|
159
176
|
key: ClientIndexerSearchKeyLike,
|
|
160
177
|
order?: "asc" | "desc",
|
|
161
178
|
limit = 10,
|
|
@@ -185,7 +202,7 @@ export abstract class Client {
|
|
|
185
202
|
* @param keyLike - The search key.
|
|
186
203
|
* @returns A async generator for yielding cells.
|
|
187
204
|
*/
|
|
188
|
-
async *
|
|
205
|
+
async *findCells(
|
|
189
206
|
keyLike: ClientCollectableSearchKeyLike,
|
|
190
207
|
order?: "asc" | "desc",
|
|
191
208
|
limit = 10,
|
|
@@ -198,7 +215,7 @@ export abstract class Client {
|
|
|
198
215
|
yield cell;
|
|
199
216
|
}
|
|
200
217
|
|
|
201
|
-
for await (const cell of this.
|
|
218
|
+
for await (const cell of this.findCellsOnChin(key, order, limit)) {
|
|
202
219
|
if (
|
|
203
220
|
(await this.cache.isUnusable(cell.outPoint)) ||
|
|
204
221
|
foundedOutPoints.some((founded) => founded.eq(cell.outPoint))
|
|
@@ -217,7 +234,7 @@ export abstract class Client {
|
|
|
217
234
|
order?: "asc" | "desc",
|
|
218
235
|
limit = 10,
|
|
219
236
|
): AsyncGenerator<Cell> {
|
|
220
|
-
return this.
|
|
237
|
+
return this.findCells(
|
|
221
238
|
{
|
|
222
239
|
script: lock,
|
|
223
240
|
scriptType: "lock",
|
|
@@ -238,7 +255,7 @@ export abstract class Client {
|
|
|
238
255
|
order?: "asc" | "desc",
|
|
239
256
|
limit = 10,
|
|
240
257
|
): AsyncGenerator<Cell> {
|
|
241
|
-
return this.
|
|
258
|
+
return this.findCells(
|
|
242
259
|
{
|
|
243
260
|
script: type,
|
|
244
261
|
scriptType: "type",
|
|
@@ -254,4 +254,21 @@ export const MAINNET_SCRIPTS: Record<
|
|
|
254
254
|
},
|
|
255
255
|
],
|
|
256
256
|
},
|
|
257
|
+
[KnownScript.NervosDao]: {
|
|
258
|
+
codeHash:
|
|
259
|
+
"0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e",
|
|
260
|
+
hashType: "type",
|
|
261
|
+
cellDeps: [
|
|
262
|
+
{
|
|
263
|
+
cellDep: {
|
|
264
|
+
outPoint: {
|
|
265
|
+
txHash:
|
|
266
|
+
"0xe2fb199810d49a4d8beec56718ba2593b665db9d52299a0f9e6e75416d73ff5c",
|
|
267
|
+
index: 2,
|
|
268
|
+
},
|
|
269
|
+
depType: "code",
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
],
|
|
273
|
+
},
|
|
257
274
|
});
|
|
@@ -265,4 +265,21 @@ export const TESTNET_SCRIPTS: Record<
|
|
|
265
265
|
},
|
|
266
266
|
],
|
|
267
267
|
},
|
|
268
|
+
[KnownScript.NervosDao]: {
|
|
269
|
+
codeHash:
|
|
270
|
+
"0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e",
|
|
271
|
+
hashType: "type",
|
|
272
|
+
cellDeps: [
|
|
273
|
+
{
|
|
274
|
+
cellDep: {
|
|
275
|
+
outPoint: {
|
|
276
|
+
txHash:
|
|
277
|
+
"0x8f8c79eb6671709633fe6a46de93c0fedc9c1b8a6527a18d3983879542635c9f",
|
|
278
|
+
index: 2,
|
|
279
|
+
},
|
|
280
|
+
depType: "code",
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
],
|
|
284
|
+
},
|
|
268
285
|
});
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
Cell,
|
|
3
|
+
Epoch,
|
|
4
|
+
OutPoint,
|
|
5
|
+
OutPointLike,
|
|
6
|
+
Script,
|
|
7
|
+
Transaction,
|
|
8
|
+
} from "../ckb/index.js";
|
|
9
|
+
import { Hex, HexLike, hexFrom } from "../hex/index.js";
|
|
10
|
+
import { Num, NumLike, numFrom } from "../num/index.js";
|
|
4
11
|
import { apply } from "../utils/index.js";
|
|
5
12
|
import {
|
|
6
13
|
ClientCollectableSearchKeyFilterLike,
|
|
@@ -181,8 +188,28 @@ export type ClientFindTransactionsGroupedResponse = {
|
|
|
181
188
|
*/
|
|
182
189
|
export type ClientBlockHeader = {
|
|
183
190
|
compactTarget: Num;
|
|
184
|
-
dao:
|
|
185
|
-
|
|
191
|
+
dao: {
|
|
192
|
+
/**
|
|
193
|
+
* C_i: the total issuance up to and including block i.
|
|
194
|
+
*/
|
|
195
|
+
c: Num;
|
|
196
|
+
/**
|
|
197
|
+
* AR_i: the current accumulated rate at block i.
|
|
198
|
+
* AR_j / AR_i reflects the CKByte amount if one deposit 1 CKB to Nervos DAO at block i, and withdraw at block j.
|
|
199
|
+
*/
|
|
200
|
+
ar: Num;
|
|
201
|
+
/**
|
|
202
|
+
* S_i: the total unissued secondary issuance up to and including block i,
|
|
203
|
+
* including unclaimed Nervos DAO compensation and treasury funds.
|
|
204
|
+
*/
|
|
205
|
+
s: Num;
|
|
206
|
+
/**
|
|
207
|
+
* U_i: the total occupied capacities currently in the blockchain up to and including block i.
|
|
208
|
+
* Occupied capacity is the sum of capacities used to store all cells.
|
|
209
|
+
*/
|
|
210
|
+
u: Num;
|
|
211
|
+
};
|
|
212
|
+
epoch: Epoch;
|
|
186
213
|
extraHash: Hex;
|
|
187
214
|
hash: Hex;
|
|
188
215
|
nonce: Num;
|
|
@@ -211,3 +238,47 @@ export type ClientBlock = {
|
|
|
211
238
|
transactions: Transaction[];
|
|
212
239
|
uncles: ClientBlockUncle[];
|
|
213
240
|
};
|
|
241
|
+
|
|
242
|
+
export interface ErrorClientBaseLike {
|
|
243
|
+
message: string;
|
|
244
|
+
code: number;
|
|
245
|
+
data: string;
|
|
246
|
+
}
|
|
247
|
+
export class ErrorClientBase extends Error {
|
|
248
|
+
public readonly message: string;
|
|
249
|
+
public readonly code: number;
|
|
250
|
+
public readonly data: string;
|
|
251
|
+
|
|
252
|
+
constructor(origin: ErrorClientBaseLike) {
|
|
253
|
+
super(origin.message);
|
|
254
|
+
this.message = origin.message;
|
|
255
|
+
this.code = origin.code;
|
|
256
|
+
this.data = origin.data;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export class ErrorClientResolveUnknown extends ErrorClientBase {
|
|
261
|
+
public readonly outPoint: OutPoint;
|
|
262
|
+
constructor(origin: ErrorClientBaseLike, outPointLike: OutPointLike) {
|
|
263
|
+
super(origin);
|
|
264
|
+
this.outPoint = OutPoint.from(outPointLike);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export class ErrorClientVerification extends ErrorClientBase {
|
|
269
|
+
public readonly sourceIndex: Num;
|
|
270
|
+
public readonly scriptCodeHash: Hex;
|
|
271
|
+
|
|
272
|
+
constructor(
|
|
273
|
+
origin: ErrorClientBaseLike,
|
|
274
|
+
public readonly source: "lock" | "inputType" | "outputType",
|
|
275
|
+
sourceIndex: NumLike,
|
|
276
|
+
public readonly errorCode: number,
|
|
277
|
+
public readonly scriptHashType: "data" | "type",
|
|
278
|
+
scriptCodeHash: HexLike,
|
|
279
|
+
) {
|
|
280
|
+
super(origin);
|
|
281
|
+
this.sourceIndex = numFrom(sourceIndex);
|
|
282
|
+
this.scriptCodeHash = hexFrom(scriptCodeHash);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TransactionLike } from "../../ckb/index.js";
|
|
1
|
+
import { OutPoint, TransactionLike } from "../../ckb/index.js";
|
|
2
2
|
import { Hex, HexLike, hexFrom } from "../../hex/index.js";
|
|
3
3
|
import { Num, NumLike, numFrom, numToHex } from "../../num/index.js";
|
|
4
4
|
import { apply } from "../../utils/index.js";
|
|
@@ -8,6 +8,10 @@ import {
|
|
|
8
8
|
ClientFindCellsResponse,
|
|
9
9
|
ClientIndexerSearchKeyLike,
|
|
10
10
|
ClientTransactionResponse,
|
|
11
|
+
ErrorClientBase,
|
|
12
|
+
ErrorClientBaseLike,
|
|
13
|
+
ErrorClientResolveUnknown,
|
|
14
|
+
ErrorClientVerification,
|
|
11
15
|
OutputsValidator,
|
|
12
16
|
} from "../clientTypes.js";
|
|
13
17
|
import {
|
|
@@ -88,7 +92,17 @@ export abstract class ClientJsonRpc extends Client {
|
|
|
88
92
|
) as () => Promise<Num>;
|
|
89
93
|
|
|
90
94
|
/**
|
|
91
|
-
* Get
|
|
95
|
+
* Get tip block header
|
|
96
|
+
*
|
|
97
|
+
* @param verbosity - result format which allows 0 and 1. (Optional, the default is 1.)
|
|
98
|
+
* @returns BlockHeader
|
|
99
|
+
*/
|
|
100
|
+
getTipHeader = this.buildSender("get_tip_header", [], (b) =>
|
|
101
|
+
apply(JsonRpcTransformers.blockHeaderTo, b),
|
|
102
|
+
) as Client["getTipHeader"];
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Get block by block number
|
|
92
106
|
*
|
|
93
107
|
* @param blockNumber - The block number.
|
|
94
108
|
* @param verbosity - result format which allows 0 and 2. (Optional, the default is 2.)
|
|
@@ -113,6 +127,56 @@ export abstract class ClientJsonRpc extends Client {
|
|
|
113
127
|
apply(JsonRpcTransformers.blockTo, b),
|
|
114
128
|
) as Client["getBlockByHash"];
|
|
115
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Get header by block number
|
|
132
|
+
*
|
|
133
|
+
* @param blockNumber - The block number.
|
|
134
|
+
* @param verbosity - result format which allows 0 and 1. (Optional, the default is 1.)
|
|
135
|
+
* @returns BlockHeader
|
|
136
|
+
*/
|
|
137
|
+
getHeaderByNumber = this.buildSender(
|
|
138
|
+
"get_header_by_number",
|
|
139
|
+
[(v: NumLike) => numToHex(numFrom(v))],
|
|
140
|
+
(b) => apply(JsonRpcTransformers.blockHeaderTo, b),
|
|
141
|
+
) as Client["getHeaderByNumber"];
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Get header by block hash
|
|
145
|
+
*
|
|
146
|
+
* @param blockHash - The block hash.
|
|
147
|
+
* @param verbosity - result format which allows 0 and 1. (Optional, the default is 1.)
|
|
148
|
+
* @returns BlockHeader
|
|
149
|
+
*/
|
|
150
|
+
getHeaderByHash = this.buildSender("get_header", [hexFrom], (b) =>
|
|
151
|
+
apply(JsonRpcTransformers.blockHeaderTo, b),
|
|
152
|
+
) as Client["getHeaderByHash"];
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Estimate cycles of a transaction.
|
|
156
|
+
*
|
|
157
|
+
* @param transaction - The transaction to estimate.
|
|
158
|
+
* @returns Consumed cycles
|
|
159
|
+
*/
|
|
160
|
+
estimateCycles = this.buildSender(
|
|
161
|
+
"estimate_cycles",
|
|
162
|
+
[JsonRpcTransformers.transactionFrom],
|
|
163
|
+
({ cycles }: { cycles: NumLike }) => numFrom(cycles),
|
|
164
|
+
) as Client["estimateCycles"];
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Test a transaction.
|
|
168
|
+
*
|
|
169
|
+
* @param transaction - The transaction to test.
|
|
170
|
+
* @param validator - "passthrough": Disable validation. "well_known_scripts_only": Only accept well known scripts in the transaction.
|
|
171
|
+
* @returns Consumed cycles
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
sendTransactionDry = this.buildSender(
|
|
175
|
+
"test_tx_pool_accept",
|
|
176
|
+
[JsonRpcTransformers.transactionFrom],
|
|
177
|
+
({ cycles }: { cycles: NumLike }) => numFrom(cycles),
|
|
178
|
+
) as Client["sendTransactionDry"];
|
|
179
|
+
|
|
116
180
|
/**
|
|
117
181
|
* Send a transaction to node.
|
|
118
182
|
*
|
|
@@ -229,7 +293,45 @@ export abstract class ClientJsonRpc extends Client {
|
|
|
229
293
|
),
|
|
230
294
|
);
|
|
231
295
|
|
|
232
|
-
|
|
296
|
+
try {
|
|
297
|
+
return transform(await this.send(payload), outTransformer);
|
|
298
|
+
} catch (errAny: unknown) {
|
|
299
|
+
if (typeof errAny !== "object" || errAny === null) {
|
|
300
|
+
throw errAny;
|
|
301
|
+
}
|
|
302
|
+
const err = errAny as ErrorClientBaseLike;
|
|
303
|
+
|
|
304
|
+
const unknownOutPointMatch = err.data.match(
|
|
305
|
+
new RegExp("Resolve\\(Unknown\\(OutPoint\\((0x.*)\\)\\)\\)"),
|
|
306
|
+
)?.[1];
|
|
307
|
+
if (unknownOutPointMatch) {
|
|
308
|
+
throw new ErrorClientResolveUnknown(
|
|
309
|
+
err,
|
|
310
|
+
OutPoint.fromBytes(unknownOutPointMatch),
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
const verificationFailedMatch = err.data.match(
|
|
314
|
+
new RegExp(
|
|
315
|
+
"Verification\\(Error { kind: Script, inner: TransactionScriptError { source: (Inputs|Outputs)\\[([0-9]*)\\].(Lock|Type), cause: ValidationFailure: see error code (-?[0-9])* on page https://nervosnetwork\\.github\\.io/ckb-script-error-codes/by-(type|data)-hash/(.*)\\.html",
|
|
316
|
+
),
|
|
317
|
+
);
|
|
318
|
+
if (verificationFailedMatch) {
|
|
319
|
+
throw new ErrorClientVerification(
|
|
320
|
+
err,
|
|
321
|
+
verificationFailedMatch[3] === "Lock"
|
|
322
|
+
? "lock"
|
|
323
|
+
: verificationFailedMatch[1] === "Inputs"
|
|
324
|
+
? "inputType"
|
|
325
|
+
: "outputType",
|
|
326
|
+
verificationFailedMatch[2],
|
|
327
|
+
Number(verificationFailedMatch[4]),
|
|
328
|
+
verificationFailedMatch[5] === "data" ? "data" : "type",
|
|
329
|
+
verificationFailedMatch[6],
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
throw new ErrorClientBase(err);
|
|
334
|
+
}
|
|
233
335
|
};
|
|
234
336
|
}
|
|
235
337
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { bytesFrom } from "../../bytes/index.js";
|
|
1
2
|
import {
|
|
2
3
|
Cell,
|
|
3
4
|
CellDep,
|
|
@@ -17,10 +18,11 @@ import {
|
|
|
17
18
|
Transaction,
|
|
18
19
|
TransactionLike,
|
|
19
20
|
depTypeFrom,
|
|
21
|
+
epochFromHex,
|
|
20
22
|
hashTypeFrom,
|
|
21
23
|
} from "../../ckb/index.js";
|
|
22
24
|
import { Hex, HexLike, hexFrom } from "../../hex/index.js";
|
|
23
|
-
import { NumLike, numFrom, numToHex } from "../../num/index.js";
|
|
25
|
+
import { NumLike, numFrom, numLeFromBytes, numToHex } from "../../num/index.js";
|
|
24
26
|
import { apply } from "../../utils/index.js";
|
|
25
27
|
import {
|
|
26
28
|
ClientBlock,
|
|
@@ -201,10 +203,16 @@ export class JsonRpcTransformers {
|
|
|
201
203
|
};
|
|
202
204
|
}
|
|
203
205
|
static blockHeaderTo(header: JsonRpcBlockHeader): ClientBlockHeader {
|
|
206
|
+
const dao = bytesFrom(header.dao);
|
|
204
207
|
return {
|
|
205
208
|
compactTarget: numFrom(header.compact_target),
|
|
206
|
-
dao:
|
|
207
|
-
|
|
209
|
+
dao: {
|
|
210
|
+
c: numLeFromBytes(dao.slice(0, 8)),
|
|
211
|
+
ar: numLeFromBytes(dao.slice(8, 16)),
|
|
212
|
+
s: numLeFromBytes(dao.slice(16, 24)),
|
|
213
|
+
u: numLeFromBytes(dao.slice(24, 32)),
|
|
214
|
+
},
|
|
215
|
+
epoch: epochFromHex(header.epoch),
|
|
208
216
|
extraHash: header.extra_hash,
|
|
209
217
|
hash: header.hash,
|
|
210
218
|
nonce: numFrom(header.nonce),
|
package/src/fixedPoint/index.ts
CHANGED
|
@@ -24,8 +24,8 @@ export type FixedPointLike = bigint | string | number;
|
|
|
24
24
|
* @example
|
|
25
25
|
* ```typescript
|
|
26
26
|
* const str = fixedPointToString(123456789n, 8); // Outputs "1.23456789"
|
|
27
|
-
* const strFromString = fixedPointToString("
|
|
28
|
-
* const strFromNumber = fixedPointToString(
|
|
27
|
+
* const strFromString = fixedPointToString("1.23456789", 8); // Outputs "1.23456789"
|
|
28
|
+
* const strFromNumber = fixedPointToString(1.23456789, 8); // Outputs "1.23456789"
|
|
29
29
|
* ```
|
|
30
30
|
*/
|
|
31
31
|
|
|
@@ -54,7 +54,7 @@ export function fixedPointToString(val: FixedPointLike, decimals = 8): string {
|
|
|
54
54
|
*
|
|
55
55
|
* @example
|
|
56
56
|
* ```typescript
|
|
57
|
-
* const fixedPoint = fixedPointFrom(
|
|
57
|
+
* const fixedPoint = fixedPointFrom(123456789n, 8); // Outputs 123456789n
|
|
58
58
|
* const fixedPointFromString = fixedPointFrom("1.23456789", 8); // Outputs 123456789n
|
|
59
59
|
* const fixedPointFromNumber = fixedPointFrom(1.23456789, 8); // Outputs 123456789n
|
|
60
60
|
* ```
|