@dedot/api 0.18.6 → 0.18.7
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/cjs/extrinsic/submittable/SubmittableExtrinsicV2.js +53 -33
- package/cjs/json-rpc/group/ChainHead/ChainHead.js +7 -0
- package/extrinsic/submittable/SubmittableExtrinsicV2.js +53 -33
- package/json-rpc/group/ChainHead/ChainHead.d.ts +2 -0
- package/json-rpc/group/ChainHead/ChainHead.js +7 -0
- package/package.json +9 -9
|
@@ -63,23 +63,30 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
|
|
|
63
63
|
};
|
|
64
64
|
let txFound;
|
|
65
65
|
let isSearching = false;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
const searchQueue = new utils_1.AsyncQueue();
|
|
67
|
+
const finalizedQueue = new utils_1.AsyncQueue();
|
|
68
|
+
const trackedHashes = [];
|
|
69
69
|
const cancelPendingSearch = () => {
|
|
70
70
|
searchQueue.clear();
|
|
71
71
|
};
|
|
72
72
|
const cancelBodySearch = () => {
|
|
73
73
|
searchQueue.cancel();
|
|
74
74
|
};
|
|
75
|
-
const startSearching = (block) => {
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
const startSearching = async (block) => {
|
|
76
|
+
const hash = block.hash;
|
|
77
|
+
if (!trackedHashes.includes(hash)) {
|
|
78
|
+
api.chainHead.holdBlock(hash);
|
|
79
|
+
trackedHashes.push(hash);
|
|
80
|
+
}
|
|
81
|
+
return searchQueue
|
|
82
|
+
.enqueue(async () => {
|
|
83
|
+
const found = await checkTxIsOnChain(hash);
|
|
78
84
|
if (found) {
|
|
79
85
|
cancelPendingSearch();
|
|
80
86
|
}
|
|
81
87
|
return found;
|
|
82
|
-
})
|
|
88
|
+
})
|
|
89
|
+
.catch(() => undefined);
|
|
83
90
|
};
|
|
84
91
|
const checkBestBlockIncluded = async (block, bestChainChanged) => {
|
|
85
92
|
if (bestChainChanged) {
|
|
@@ -142,43 +149,56 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
|
|
|
142
149
|
}
|
|
143
150
|
};
|
|
144
151
|
const checkFinalizedBlockIncluded = async (block) => {
|
|
145
|
-
const
|
|
146
|
-
if (
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
status: { type: 'Finalized', value: { blockHash, blockNumber, txIndex } },
|
|
150
|
-
txHash,
|
|
151
|
-
events,
|
|
152
|
-
txIndex,
|
|
153
|
-
}));
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
// Revalidate the tx, just in-case it becomes invalid along the way
|
|
157
|
-
// Context: https://github.com/paritytech/json-rpc-interface-spec/pull/107#issuecomment-1906008814
|
|
158
|
-
const validation = await validateTx(block.hash);
|
|
159
|
-
if (validation.isOk)
|
|
160
|
-
return;
|
|
161
|
-
callback(new SubmittableResult_js_1.SubmittableResult({
|
|
162
|
-
status: {
|
|
163
|
-
type: 'Invalid',
|
|
164
|
-
value: { error: `Invalid Tx: ${validation.err.type} - ${validation.err.value.type}` },
|
|
165
|
-
},
|
|
166
|
-
txHash,
|
|
167
|
-
}));
|
|
152
|
+
const hash = block.hash;
|
|
153
|
+
if (!trackedHashes.includes(hash)) {
|
|
154
|
+
api.chainHead.holdBlock(hash);
|
|
155
|
+
trackedHashes.push(hash);
|
|
168
156
|
}
|
|
169
|
-
|
|
157
|
+
finalizedQueue
|
|
158
|
+
.enqueue(async () => {
|
|
159
|
+
const inBlock = await checkTxIsOnChain(hash);
|
|
160
|
+
if (inBlock) {
|
|
161
|
+
const { index: txIndex, events, blockHash, blockNumber } = inBlock;
|
|
162
|
+
callback(new SubmittableResult_js_1.SubmittableResult({
|
|
163
|
+
status: { type: 'Finalized', value: { blockHash, blockNumber, txIndex } },
|
|
164
|
+
txHash,
|
|
165
|
+
events,
|
|
166
|
+
txIndex,
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
// Revalidate the tx, just in-case it becomes invalid along the way
|
|
171
|
+
// Context: https://github.com/paritytech/json-rpc-interface-spec/pull/107#issuecomment-1906008814
|
|
172
|
+
const validation = await validateTx(hash);
|
|
173
|
+
if (validation.isOk)
|
|
174
|
+
return;
|
|
175
|
+
callback(new SubmittableResult_js_1.SubmittableResult({
|
|
176
|
+
status: {
|
|
177
|
+
type: 'Invalid',
|
|
178
|
+
value: { error: `Invalid Tx: ${validation.err.type} - ${validation.err.value.type}` },
|
|
179
|
+
},
|
|
180
|
+
txHash,
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
183
|
+
txUnsub().catch(utils_1.noop);
|
|
184
|
+
})
|
|
185
|
+
.catch(utils_1.noop);
|
|
170
186
|
};
|
|
187
|
+
const stopBestBlockTrackingFn = api.on('bestBlock', checkBestBlockIncluded);
|
|
188
|
+
const stopFinalizedBlockTrackingFn = api.on('finalizedBlock', checkFinalizedBlockIncluded);
|
|
171
189
|
stopBroadcastFn = await api.txBroadcaster.broadcastTx(txHex);
|
|
172
190
|
callback(new SubmittableResult_js_1.SubmittableResult({
|
|
173
191
|
status: { type: 'Broadcasting' },
|
|
174
192
|
txHash,
|
|
175
193
|
}));
|
|
176
|
-
const stopBestBlockTrackingFn = api.on('bestBlock', checkBestBlockIncluded);
|
|
177
|
-
const stopFinalizedBlockTrackingFn = api.on('finalizedBlock', checkFinalizedBlockIncluded);
|
|
178
194
|
const stopTracking = () => {
|
|
179
195
|
stopBestBlockTrackingFn();
|
|
180
196
|
stopFinalizedBlockTrackingFn();
|
|
181
197
|
cancelBodySearch();
|
|
198
|
+
finalizedQueue.cancel();
|
|
199
|
+
trackedHashes.forEach((h) => {
|
|
200
|
+
api.chainHead.releaseBlock(h);
|
|
201
|
+
});
|
|
182
202
|
};
|
|
183
203
|
txUnsub = async () => {
|
|
184
204
|
stopTracking();
|
|
@@ -765,5 +765,12 @@ class ChainHead extends JsonRpcGroup_js_1.JsonRpcGroup {
|
|
|
765
765
|
this.#cache.clear();
|
|
766
766
|
this.#archive?.clearCache();
|
|
767
767
|
}
|
|
768
|
+
holdBlock(hash) {
|
|
769
|
+
this.#ensurePinnedHash(hash);
|
|
770
|
+
this.#blockUsage.use(hash);
|
|
771
|
+
}
|
|
772
|
+
releaseBlock(hash) {
|
|
773
|
+
this.#blockUsage.release(hash);
|
|
774
|
+
}
|
|
768
775
|
}
|
|
769
776
|
exports.ChainHead = ChainHead;
|
|
@@ -60,23 +60,30 @@ export class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic {
|
|
|
60
60
|
};
|
|
61
61
|
let txFound;
|
|
62
62
|
let isSearching = false;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
const searchQueue = new AsyncQueue();
|
|
64
|
+
const finalizedQueue = new AsyncQueue();
|
|
65
|
+
const trackedHashes = [];
|
|
66
66
|
const cancelPendingSearch = () => {
|
|
67
67
|
searchQueue.clear();
|
|
68
68
|
};
|
|
69
69
|
const cancelBodySearch = () => {
|
|
70
70
|
searchQueue.cancel();
|
|
71
71
|
};
|
|
72
|
-
const startSearching = (block) => {
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
const startSearching = async (block) => {
|
|
73
|
+
const hash = block.hash;
|
|
74
|
+
if (!trackedHashes.includes(hash)) {
|
|
75
|
+
api.chainHead.holdBlock(hash);
|
|
76
|
+
trackedHashes.push(hash);
|
|
77
|
+
}
|
|
78
|
+
return searchQueue
|
|
79
|
+
.enqueue(async () => {
|
|
80
|
+
const found = await checkTxIsOnChain(hash);
|
|
75
81
|
if (found) {
|
|
76
82
|
cancelPendingSearch();
|
|
77
83
|
}
|
|
78
84
|
return found;
|
|
79
|
-
})
|
|
85
|
+
})
|
|
86
|
+
.catch(() => undefined);
|
|
80
87
|
};
|
|
81
88
|
const checkBestBlockIncluded = async (block, bestChainChanged) => {
|
|
82
89
|
if (bestChainChanged) {
|
|
@@ -139,43 +146,56 @@ export class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic {
|
|
|
139
146
|
}
|
|
140
147
|
};
|
|
141
148
|
const checkFinalizedBlockIncluded = async (block) => {
|
|
142
|
-
const
|
|
143
|
-
if (
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
status: { type: 'Finalized', value: { blockHash, blockNumber, txIndex } },
|
|
147
|
-
txHash,
|
|
148
|
-
events,
|
|
149
|
-
txIndex,
|
|
150
|
-
}));
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
// Revalidate the tx, just in-case it becomes invalid along the way
|
|
154
|
-
// Context: https://github.com/paritytech/json-rpc-interface-spec/pull/107#issuecomment-1906008814
|
|
155
|
-
const validation = await validateTx(block.hash);
|
|
156
|
-
if (validation.isOk)
|
|
157
|
-
return;
|
|
158
|
-
callback(new SubmittableResult({
|
|
159
|
-
status: {
|
|
160
|
-
type: 'Invalid',
|
|
161
|
-
value: { error: `Invalid Tx: ${validation.err.type} - ${validation.err.value.type}` },
|
|
162
|
-
},
|
|
163
|
-
txHash,
|
|
164
|
-
}));
|
|
149
|
+
const hash = block.hash;
|
|
150
|
+
if (!trackedHashes.includes(hash)) {
|
|
151
|
+
api.chainHead.holdBlock(hash);
|
|
152
|
+
trackedHashes.push(hash);
|
|
165
153
|
}
|
|
166
|
-
|
|
154
|
+
finalizedQueue
|
|
155
|
+
.enqueue(async () => {
|
|
156
|
+
const inBlock = await checkTxIsOnChain(hash);
|
|
157
|
+
if (inBlock) {
|
|
158
|
+
const { index: txIndex, events, blockHash, blockNumber } = inBlock;
|
|
159
|
+
callback(new SubmittableResult({
|
|
160
|
+
status: { type: 'Finalized', value: { blockHash, blockNumber, txIndex } },
|
|
161
|
+
txHash,
|
|
162
|
+
events,
|
|
163
|
+
txIndex,
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
// Revalidate the tx, just in-case it becomes invalid along the way
|
|
168
|
+
// Context: https://github.com/paritytech/json-rpc-interface-spec/pull/107#issuecomment-1906008814
|
|
169
|
+
const validation = await validateTx(hash);
|
|
170
|
+
if (validation.isOk)
|
|
171
|
+
return;
|
|
172
|
+
callback(new SubmittableResult({
|
|
173
|
+
status: {
|
|
174
|
+
type: 'Invalid',
|
|
175
|
+
value: { error: `Invalid Tx: ${validation.err.type} - ${validation.err.value.type}` },
|
|
176
|
+
},
|
|
177
|
+
txHash,
|
|
178
|
+
}));
|
|
179
|
+
}
|
|
180
|
+
txUnsub().catch(noop);
|
|
181
|
+
})
|
|
182
|
+
.catch(noop);
|
|
167
183
|
};
|
|
184
|
+
const stopBestBlockTrackingFn = api.on('bestBlock', checkBestBlockIncluded);
|
|
185
|
+
const stopFinalizedBlockTrackingFn = api.on('finalizedBlock', checkFinalizedBlockIncluded);
|
|
168
186
|
stopBroadcastFn = await api.txBroadcaster.broadcastTx(txHex);
|
|
169
187
|
callback(new SubmittableResult({
|
|
170
188
|
status: { type: 'Broadcasting' },
|
|
171
189
|
txHash,
|
|
172
190
|
}));
|
|
173
|
-
const stopBestBlockTrackingFn = api.on('bestBlock', checkBestBlockIncluded);
|
|
174
|
-
const stopFinalizedBlockTrackingFn = api.on('finalizedBlock', checkFinalizedBlockIncluded);
|
|
175
191
|
const stopTracking = () => {
|
|
176
192
|
stopBestBlockTrackingFn();
|
|
177
193
|
stopFinalizedBlockTrackingFn();
|
|
178
194
|
cancelBodySearch();
|
|
195
|
+
finalizedQueue.cancel();
|
|
196
|
+
trackedHashes.forEach((h) => {
|
|
197
|
+
api.chainHead.releaseBlock(h);
|
|
198
|
+
});
|
|
179
199
|
};
|
|
180
200
|
txUnsub = async () => {
|
|
181
201
|
stopTracking();
|
|
@@ -762,4 +762,11 @@ export class ChainHead extends JsonRpcGroup {
|
|
|
762
762
|
this.#cache.clear();
|
|
763
763
|
this.#archive?.clearCache();
|
|
764
764
|
}
|
|
765
|
+
holdBlock(hash) {
|
|
766
|
+
this.#ensurePinnedHash(hash);
|
|
767
|
+
this.#blockUsage.use(hash);
|
|
768
|
+
}
|
|
769
|
+
releaseBlock(hash) {
|
|
770
|
+
this.#blockUsage.release(hash);
|
|
771
|
+
}
|
|
765
772
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dedot/api",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.7",
|
|
4
4
|
"description": "A delightful JavaScript/TypeScript client for Polkadot & Substrate",
|
|
5
5
|
"author": "Thang X. Vu <thang@dedot.dev>",
|
|
6
6
|
"homepage": "https://dedot.dev",
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
"type": "module",
|
|
14
14
|
"sideEffects": false,
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@dedot/codecs": "0.18.
|
|
17
|
-
"@dedot/providers": "0.18.
|
|
18
|
-
"@dedot/runtime-specs": "0.18.
|
|
19
|
-
"@dedot/shape": "0.18.
|
|
20
|
-
"@dedot/storage": "0.18.
|
|
21
|
-
"@dedot/types": "0.18.
|
|
22
|
-
"@dedot/utils": "0.18.
|
|
16
|
+
"@dedot/codecs": "0.18.7",
|
|
17
|
+
"@dedot/providers": "0.18.7",
|
|
18
|
+
"@dedot/runtime-specs": "0.18.7",
|
|
19
|
+
"@dedot/shape": "0.18.7",
|
|
20
|
+
"@dedot/storage": "0.18.7",
|
|
21
|
+
"@dedot/types": "0.18.7",
|
|
22
|
+
"@dedot/utils": "0.18.7"
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
25
|
"build": "tsc --project tsconfig.build.json && tsc --project tsconfig.build.cjs.json",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"node": ">=18"
|
|
49
49
|
},
|
|
50
50
|
"license": "Apache-2.0",
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "07f47f75512087407e03f301fc18c2059b3f613a",
|
|
52
52
|
"module": "./index.js",
|
|
53
53
|
"types": "./index.d.ts"
|
|
54
54
|
}
|