@ckb-ccc/core 0.0.13-alpha.7 → 0.0.13
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 +58 -0
- 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 +2 -0
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +7 -0
- package/dist/client/clientTypes.d.ts +24 -2
- package/dist/client/clientTypes.d.ts.map +1 -1
- package/dist/client/clientTypes.js +25 -1
- package/dist/client/jsonRpc/index.d.ts +10 -1
- package/dist/client/jsonRpc/index.d.ts.map +1 -1
- package/dist/client/jsonRpc/index.js +42 -1
- package/dist/fixedPoint/index.d.ts +3 -3
- package/dist/fixedPoint/index.js +3 -3
- 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 +2 -0
- package/dist.commonjs/client/client.d.ts.map +1 -1
- package/dist.commonjs/client/client.js +7 -0
- package/dist.commonjs/client/clientTypes.d.ts +24 -2
- package/dist.commonjs/client/clientTypes.d.ts.map +1 -1
- package/dist.commonjs/client/clientTypes.js +32 -5
- package/dist.commonjs/client/jsonRpc/index.d.ts +10 -1
- package/dist.commonjs/client/jsonRpc/index.d.ts.map +1 -1
- package/dist.commonjs/client/jsonRpc/index.js +58 -17
- package/dist.commonjs/fixedPoint/index.d.ts +3 -3
- package/dist.commonjs/fixedPoint/index.js +3 -3
- package/package.json +1 -1
- package/src/client/cache/cache.ts +58 -13
- package/src/client/cache/memory.ts +60 -52
- package/src/client/client.ts +21 -0
- package/src/client/clientTypes.ts +52 -3
- package/src/client/jsonRpc/index.ts +97 -3
- package/src/fixedPoint/index.ts +3 -3
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ClientJsonRpc = void 0;
|
|
4
|
-
const index_js_1 = require("../../
|
|
5
|
-
const index_js_2 = require("../../
|
|
6
|
-
const index_js_3 = require("../../
|
|
4
|
+
const index_js_1 = require("../../ckb/index.js");
|
|
5
|
+
const index_js_2 = require("../../hex/index.js");
|
|
6
|
+
const index_js_3 = require("../../num/index.js");
|
|
7
|
+
const index_js_4 = require("../../utils/index.js");
|
|
7
8
|
const client_js_1 = require("../client.js");
|
|
9
|
+
const clientTypes_js_1 = require("../clientTypes.js");
|
|
8
10
|
const advanced_js_1 = require("../transports/advanced.js");
|
|
9
11
|
const advanced_js_2 = require("./advanced.js");
|
|
10
12
|
/**
|
|
@@ -45,14 +47,14 @@ class ClientJsonRpc extends client_js_1.Client {
|
|
|
45
47
|
*
|
|
46
48
|
* @returns Tip block number
|
|
47
49
|
*/
|
|
48
|
-
this.getTip = this.buildSender("get_tip_block_number", [],
|
|
50
|
+
this.getTip = this.buildSender("get_tip_block_number", [], index_js_3.numFrom);
|
|
49
51
|
/**
|
|
50
52
|
* Get tip block header
|
|
51
53
|
*
|
|
52
54
|
* @param verbosity - result format which allows 0 and 1. (Optional, the default is 1.)
|
|
53
55
|
* @returns BlockHeader
|
|
54
56
|
*/
|
|
55
|
-
this.getTipHeader = this.buildSender("get_tip_header", [], (b) => (0,
|
|
57
|
+
this.getTipHeader = this.buildSender("get_tip_header", [], (b) => (0, index_js_4.apply)(advanced_js_2.JsonRpcTransformers.blockHeaderTo, b));
|
|
56
58
|
/**
|
|
57
59
|
* Get block by block number
|
|
58
60
|
*
|
|
@@ -61,7 +63,7 @@ class ClientJsonRpc extends client_js_1.Client {
|
|
|
61
63
|
* @param withCycles - whether the return cycles of block transactions. (Optional, default false.)
|
|
62
64
|
* @returns Block
|
|
63
65
|
*/
|
|
64
|
-
this.getBlockByNumber = this.buildSender("get_block_by_number", [(v) => (0,
|
|
66
|
+
this.getBlockByNumber = this.buildSender("get_block_by_number", [(v) => (0, index_js_3.numToHex)((0, index_js_3.numFrom)(v))], (b) => (0, index_js_4.apply)(advanced_js_2.JsonRpcTransformers.blockTo, b));
|
|
65
67
|
/**
|
|
66
68
|
* Get block by block hash
|
|
67
69
|
*
|
|
@@ -70,7 +72,7 @@ class ClientJsonRpc extends client_js_1.Client {
|
|
|
70
72
|
* @param withCycles - whether the return cycles of block transactions. (Optional, default false.)
|
|
71
73
|
* @returns Block
|
|
72
74
|
*/
|
|
73
|
-
this.getBlockByHash = this.buildSender("get_block", [
|
|
75
|
+
this.getBlockByHash = this.buildSender("get_block", [index_js_2.hexFrom], (b) => (0, index_js_4.apply)(advanced_js_2.JsonRpcTransformers.blockTo, b));
|
|
74
76
|
/**
|
|
75
77
|
* Get header by block number
|
|
76
78
|
*
|
|
@@ -78,7 +80,7 @@ class ClientJsonRpc extends client_js_1.Client {
|
|
|
78
80
|
* @param verbosity - result format which allows 0 and 1. (Optional, the default is 1.)
|
|
79
81
|
* @returns BlockHeader
|
|
80
82
|
*/
|
|
81
|
-
this.getHeaderByNumber = this.buildSender("get_header_by_number", [(v) => (0,
|
|
83
|
+
this.getHeaderByNumber = this.buildSender("get_header_by_number", [(v) => (0, index_js_3.numToHex)((0, index_js_3.numFrom)(v))], (b) => (0, index_js_4.apply)(advanced_js_2.JsonRpcTransformers.blockHeaderTo, b));
|
|
82
84
|
/**
|
|
83
85
|
* Get header by block hash
|
|
84
86
|
*
|
|
@@ -86,14 +88,14 @@ class ClientJsonRpc extends client_js_1.Client {
|
|
|
86
88
|
* @param verbosity - result format which allows 0 and 1. (Optional, the default is 1.)
|
|
87
89
|
* @returns BlockHeader
|
|
88
90
|
*/
|
|
89
|
-
this.getHeaderByHash = this.buildSender("get_header", [
|
|
91
|
+
this.getHeaderByHash = this.buildSender("get_header", [index_js_2.hexFrom], (b) => (0, index_js_4.apply)(advanced_js_2.JsonRpcTransformers.blockHeaderTo, b));
|
|
90
92
|
/**
|
|
91
93
|
* Estimate cycles of a transaction.
|
|
92
94
|
*
|
|
93
95
|
* @param transaction - The transaction to estimate.
|
|
94
96
|
* @returns Consumed cycles
|
|
95
97
|
*/
|
|
96
|
-
this.estimateCycles = this.buildSender("estimate_cycles", [advanced_js_2.JsonRpcTransformers.transactionFrom], ({ cycles }) => (0,
|
|
98
|
+
this.estimateCycles = this.buildSender("estimate_cycles", [advanced_js_2.JsonRpcTransformers.transactionFrom], ({ cycles }) => (0, index_js_3.numFrom)(cycles));
|
|
97
99
|
/**
|
|
98
100
|
* Test a transaction.
|
|
99
101
|
*
|
|
@@ -101,7 +103,7 @@ class ClientJsonRpc extends client_js_1.Client {
|
|
|
101
103
|
* @param validator - "passthrough": Disable validation. "well_known_scripts_only": Only accept well known scripts in the transaction.
|
|
102
104
|
* @returns Consumed cycles
|
|
103
105
|
*/
|
|
104
|
-
this.sendTransactionDry = this.buildSender("test_tx_pool_accept", [advanced_js_2.JsonRpcTransformers.transactionFrom], ({ cycles }) => (0,
|
|
106
|
+
this.sendTransactionDry = this.buildSender("test_tx_pool_accept", [advanced_js_2.JsonRpcTransformers.transactionFrom], ({ cycles }) => (0, index_js_3.numFrom)(cycles));
|
|
105
107
|
/**
|
|
106
108
|
* Send a transaction to node.
|
|
107
109
|
*
|
|
@@ -109,14 +111,14 @@ class ClientJsonRpc extends client_js_1.Client {
|
|
|
109
111
|
* @param validator - "passthrough": Disable validation. "well_known_scripts_only": Only accept well known scripts in the transaction.
|
|
110
112
|
* @returns Transaction hash.
|
|
111
113
|
*/
|
|
112
|
-
this.sendTransactionNoCache = this.buildSender("send_transaction", [advanced_js_2.JsonRpcTransformers.transactionFrom],
|
|
114
|
+
this.sendTransactionNoCache = this.buildSender("send_transaction", [advanced_js_2.JsonRpcTransformers.transactionFrom], index_js_2.hexFrom);
|
|
113
115
|
/**
|
|
114
116
|
* Get a transaction from node.
|
|
115
117
|
*
|
|
116
118
|
* @param txHash - The hash of the transaction.
|
|
117
119
|
* @returns The transaction with status.
|
|
118
120
|
*/
|
|
119
|
-
this.getTransactionNoCache = this.buildSender("get_transaction", [
|
|
121
|
+
this.getTransactionNoCache = this.buildSender("get_transaction", [index_js_2.hexFrom], advanced_js_2.JsonRpcTransformers.transactionResponseTo);
|
|
120
122
|
/**
|
|
121
123
|
* find cells from node.
|
|
122
124
|
*
|
|
@@ -129,7 +131,7 @@ class ClientJsonRpc extends client_js_1.Client {
|
|
|
129
131
|
this.findCellsPagedNoCache = this.buildSender("get_cells", [
|
|
130
132
|
advanced_js_2.JsonRpcTransformers.indexerSearchKeyFrom,
|
|
131
133
|
(order) => order ?? "asc",
|
|
132
|
-
(limit) => (0,
|
|
134
|
+
(limit) => (0, index_js_3.numToHex)(limit ?? 10),
|
|
133
135
|
], advanced_js_2.JsonRpcTransformers.findCellsResponseTo);
|
|
134
136
|
/**
|
|
135
137
|
* find transactions from node.
|
|
@@ -143,7 +145,7 @@ class ClientJsonRpc extends client_js_1.Client {
|
|
|
143
145
|
this.findTransactionsPaged = this.buildSender("get_transactions", [
|
|
144
146
|
advanced_js_2.JsonRpcTransformers.indexerSearchKeyTransactionFrom,
|
|
145
147
|
(order) => order ?? "asc",
|
|
146
|
-
(limit) => (0,
|
|
148
|
+
(limit) => (0, index_js_3.numToHex)(limit ?? 10),
|
|
147
149
|
], advanced_js_2.JsonRpcTransformers.findTransactionsResponseTo);
|
|
148
150
|
/**
|
|
149
151
|
* get cells capacity from node.
|
|
@@ -151,7 +153,7 @@ class ClientJsonRpc extends client_js_1.Client {
|
|
|
151
153
|
* @param key - The search key of cells.
|
|
152
154
|
* @returns The sum of cells capacity.
|
|
153
155
|
*/
|
|
154
|
-
this.getCellsCapacity = this.buildSender("get_cells_capacity", [advanced_js_2.JsonRpcTransformers.indexerSearchKeyFrom], ({ capacity }) => (0,
|
|
156
|
+
this.getCellsCapacity = this.buildSender("get_cells_capacity", [advanced_js_2.JsonRpcTransformers.indexerSearchKeyFrom], ({ capacity }) => (0, index_js_3.numFrom)(capacity));
|
|
155
157
|
this.transport = (0, advanced_js_1.transportFromUri)(url_, config);
|
|
156
158
|
}
|
|
157
159
|
/**
|
|
@@ -162,6 +164,21 @@ class ClientJsonRpc extends client_js_1.Client {
|
|
|
162
164
|
get url() {
|
|
163
165
|
return this.url_;
|
|
164
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Get a live cell from node.
|
|
169
|
+
*
|
|
170
|
+
* @param outPoint - The out point of the cell.
|
|
171
|
+
* @param withData - Include data in the response.
|
|
172
|
+
* @param includeTxPool - Include cells in the tx pool.
|
|
173
|
+
* @returns The cell
|
|
174
|
+
*/
|
|
175
|
+
getCellLiveNoCache(outPoint, withData, includeTxPool) {
|
|
176
|
+
return this.buildSender("get_live_cell", [advanced_js_2.JsonRpcTransformers.outPointFrom], ({ cell, }) => (0, index_js_4.apply)(({ output, data, }) => index_js_1.Cell.from({
|
|
177
|
+
cellOutput: advanced_js_2.JsonRpcTransformers.cellOutputTo(output),
|
|
178
|
+
outputData: data?.content ?? "0x",
|
|
179
|
+
outPoint,
|
|
180
|
+
}), cell))(outPoint, withData ?? true, includeTxPool);
|
|
181
|
+
}
|
|
165
182
|
/**
|
|
166
183
|
* Builds a sender function for a JSON-RPC method.
|
|
167
184
|
*
|
|
@@ -175,7 +192,31 @@ class ClientJsonRpc extends client_js_1.Client {
|
|
|
175
192
|
const payload = ClientJsonRpc.buildPayload(rpcMethod, await Promise.all(req
|
|
176
193
|
.concat(Array.from(new Array(Math.max(inTransformers.length - req.length, 0))))
|
|
177
194
|
.map((v, i) => transform(v, inTransformers[i]))));
|
|
178
|
-
|
|
195
|
+
try {
|
|
196
|
+
return transform(await this.send(payload), outTransformer);
|
|
197
|
+
}
|
|
198
|
+
catch (errAny) {
|
|
199
|
+
if (typeof errAny !== "object" ||
|
|
200
|
+
errAny === null ||
|
|
201
|
+
!("data" in errAny) ||
|
|
202
|
+
typeof errAny.data !== "string") {
|
|
203
|
+
throw errAny;
|
|
204
|
+
}
|
|
205
|
+
const err = errAny;
|
|
206
|
+
const unknownOutPointMatch = err.data.match(new RegExp("Resolve\\(Unknown\\(OutPoint\\((0x.*)\\)\\)\\)"))?.[1];
|
|
207
|
+
if (unknownOutPointMatch) {
|
|
208
|
+
throw new clientTypes_js_1.ErrorClientResolveUnknown(err, index_js_1.OutPoint.fromBytes(unknownOutPointMatch));
|
|
209
|
+
}
|
|
210
|
+
const verificationFailedMatch = err.data.match(new RegExp("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"));
|
|
211
|
+
if (verificationFailedMatch) {
|
|
212
|
+
throw new clientTypes_js_1.ErrorClientVerification(err, verificationFailedMatch[3] === "Lock"
|
|
213
|
+
? "lock"
|
|
214
|
+
: verificationFailedMatch[1] === "Inputs"
|
|
215
|
+
? "inputType"
|
|
216
|
+
: "outputType", verificationFailedMatch[2], Number(verificationFailedMatch[4]), verificationFailedMatch[5] === "data" ? "data" : "type", verificationFailedMatch[6]);
|
|
217
|
+
}
|
|
218
|
+
throw new clientTypes_js_1.ErrorClientBase(err);
|
|
219
|
+
}
|
|
179
220
|
};
|
|
180
221
|
}
|
|
181
222
|
/**
|
|
@@ -20,8 +20,8 @@ export type FixedPointLike = bigint | string | number;
|
|
|
20
20
|
* @example
|
|
21
21
|
* ```typescript
|
|
22
22
|
* const str = fixedPointToString(123456789n, 8); // Outputs "1.23456789"
|
|
23
|
-
* const strFromString = fixedPointToString("
|
|
24
|
-
* const strFromNumber = fixedPointToString(
|
|
23
|
+
* const strFromString = fixedPointToString("1.23456789", 8); // Outputs "1.23456789"
|
|
24
|
+
* const strFromNumber = fixedPointToString(1.23456789, 8); // Outputs "1.23456789"
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
27
|
export declare function fixedPointToString(val: FixedPointLike, decimals?: number): string;
|
|
@@ -35,7 +35,7 @@ export declare function fixedPointToString(val: FixedPointLike, decimals?: numbe
|
|
|
35
35
|
*
|
|
36
36
|
* @example
|
|
37
37
|
* ```typescript
|
|
38
|
-
* const fixedPoint = fixedPointFrom(
|
|
38
|
+
* const fixedPoint = fixedPointFrom(123456789n, 8); // Outputs 123456789n
|
|
39
39
|
* const fixedPointFromString = fixedPointFrom("1.23456789", 8); // Outputs 123456789n
|
|
40
40
|
* const fixedPointFromNumber = fixedPointFrom(1.23456789, 8); // Outputs 123456789n
|
|
41
41
|
* ```
|
|
@@ -16,8 +16,8 @@ exports.One = exports.Zero = exports.fixedPointFrom = exports.fixedPointToString
|
|
|
16
16
|
* @example
|
|
17
17
|
* ```typescript
|
|
18
18
|
* const str = fixedPointToString(123456789n, 8); // Outputs "1.23456789"
|
|
19
|
-
* const strFromString = fixedPointToString("
|
|
20
|
-
* const strFromNumber = fixedPointToString(
|
|
19
|
+
* const strFromString = fixedPointToString("1.23456789", 8); // Outputs "1.23456789"
|
|
20
|
+
* const strFromNumber = fixedPointToString(1.23456789, 8); // Outputs "1.23456789"
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
23
|
function fixedPointToString(val, decimals = 8) {
|
|
@@ -43,7 +43,7 @@ exports.fixedPointToString = fixedPointToString;
|
|
|
43
43
|
*
|
|
44
44
|
* @example
|
|
45
45
|
* ```typescript
|
|
46
|
-
* const fixedPoint = fixedPointFrom(
|
|
46
|
+
* const fixedPoint = fixedPointFrom(123456789n, 8); // Outputs 123456789n
|
|
47
47
|
* const fixedPointFromString = fixedPointFrom("1.23456789", 8); // Outputs 123456789n
|
|
48
48
|
* const fixedPointFromNumber = fixedPointFrom(1.23456789, 8); // Outputs 123456789n
|
|
49
49
|
* ```
|
package/package.json
CHANGED
|
@@ -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
|
@@ -155,6 +155,27 @@ export abstract class Client {
|
|
|
155
155
|
return cell;
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
abstract getCellLiveNoCache(
|
|
159
|
+
outPointLike: OutPointLike,
|
|
160
|
+
withData?: boolean | null,
|
|
161
|
+
includeTxPool?: boolean | null,
|
|
162
|
+
): Promise<Cell | undefined>;
|
|
163
|
+
async getCellLive(
|
|
164
|
+
outPointLike: OutPointLike,
|
|
165
|
+
withData?: boolean | null,
|
|
166
|
+
includeTxPool?: boolean | null,
|
|
167
|
+
): Promise<Cell | undefined> {
|
|
168
|
+
const cell = await this.getCellLiveNoCache(
|
|
169
|
+
outPointLike,
|
|
170
|
+
withData,
|
|
171
|
+
includeTxPool,
|
|
172
|
+
);
|
|
173
|
+
if (withData && cell) {
|
|
174
|
+
await this.cache.recordCells(cell);
|
|
175
|
+
}
|
|
176
|
+
return cell;
|
|
177
|
+
}
|
|
178
|
+
|
|
158
179
|
abstract findCellsPagedNoCache(
|
|
159
180
|
key: ClientIndexerSearchKeyLike,
|
|
160
181
|
order?: "asc" | "desc",
|
|
@@ -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,
|
|
@@ -231,3 +238,45 @@ export type ClientBlock = {
|
|
|
231
238
|
transactions: Transaction[];
|
|
232
239
|
uncles: ClientBlockUncle[];
|
|
233
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 code?: number;
|
|
249
|
+
public readonly data: string;
|
|
250
|
+
|
|
251
|
+
constructor(origin: ErrorClientBaseLike) {
|
|
252
|
+
super(origin.message);
|
|
253
|
+
this.code = origin.code;
|
|
254
|
+
this.data = origin.data;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export class ErrorClientResolveUnknown extends ErrorClientBase {
|
|
259
|
+
public readonly outPoint: OutPoint;
|
|
260
|
+
constructor(origin: ErrorClientBaseLike, outPointLike: OutPointLike) {
|
|
261
|
+
super(origin);
|
|
262
|
+
this.outPoint = OutPoint.from(outPointLike);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export class ErrorClientVerification extends ErrorClientBase {
|
|
267
|
+
public readonly sourceIndex: Num;
|
|
268
|
+
public readonly scriptCodeHash: Hex;
|
|
269
|
+
|
|
270
|
+
constructor(
|
|
271
|
+
origin: ErrorClientBaseLike,
|
|
272
|
+
public readonly source: "lock" | "inputType" | "outputType",
|
|
273
|
+
sourceIndex: NumLike,
|
|
274
|
+
public readonly errorCode: number,
|
|
275
|
+
public readonly scriptHashType: "data" | "type",
|
|
276
|
+
scriptCodeHash: HexLike,
|
|
277
|
+
) {
|
|
278
|
+
super(origin);
|
|
279
|
+
this.sourceIndex = numFrom(sourceIndex);
|
|
280
|
+
this.scriptCodeHash = hexFrom(scriptCodeHash);
|
|
281
|
+
}
|
|
282
|
+
}
|