@dedot/api 0.0.1-next.d9aff57d.57 → 0.1.0
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/chaintypes/substrate/consts.js +1 -1
- package/chaintypes/substrate/errors.js +1 -1
- package/chaintypes/substrate/events.js +1 -1
- package/chaintypes/substrate/index.js +1 -1
- package/chaintypes/substrate/json-rpc.d.ts +1 -1
- package/chaintypes/substrate/json-rpc.js +1 -1
- package/chaintypes/substrate/query.js +1 -1
- package/chaintypes/substrate/runtime.js +1 -1
- package/chaintypes/substrate/tx.d.ts +2 -2
- package/chaintypes/substrate/tx.js +1 -1
- package/chaintypes/substrate/types.d.ts +377 -377
- package/chaintypes/substrate/types.js +1 -1
- package/cjs/chaintypes/substrate/consts.js +1 -1
- package/cjs/chaintypes/substrate/errors.js +1 -1
- package/cjs/chaintypes/substrate/events.js +1 -1
- package/cjs/chaintypes/substrate/index.js +1 -1
- package/cjs/chaintypes/substrate/json-rpc.js +1 -1
- package/cjs/chaintypes/substrate/query.js +1 -1
- package/cjs/chaintypes/substrate/runtime.js +1 -1
- package/cjs/chaintypes/substrate/tx.js +1 -1
- package/cjs/chaintypes/substrate/types.js +1 -1
- package/cjs/client/BaseSubstrateClient.js +21 -0
- package/cjs/client/DedotClient.js +5 -4
- package/cjs/client/{Dedot.js → LegacyClient.js} +13 -9
- package/cjs/client/index.js +1 -1
- package/cjs/executor/ErrorExecutor.js +3 -3
- package/cjs/executor/EventExecutor.js +2 -2
- package/cjs/executor/StorageQueryExecutor.js +1 -1
- package/cjs/executor/TxExecutor.js +3 -3
- package/cjs/executor/v2/StorageQueryExecutorV2.js +7 -7
- package/cjs/extrinsic/extensions/known/ChargeAssetTxPayment.js +2 -2
- package/cjs/extrinsic/extensions/known/CheckMetadataHash.js +31 -0
- package/cjs/extrinsic/extensions/known/StorageWeightReclaim.js +10 -0
- package/cjs/extrinsic/extensions/known/index.js +4 -0
- package/cjs/extrinsic/submittable/BaseSubmittableExtrinsic.js +31 -1
- package/cjs/extrinsic/submittable/SubmittableExtrinsic.js +7 -4
- package/cjs/extrinsic/submittable/SubmittableExtrinsicV2.js +11 -11
- package/cjs/extrinsic/submittable/utils.js +66 -1
- package/cjs/storage/QueryableStorage.js +17 -17
- package/client/BaseSubstrateClient.d.ts +15 -9
- package/client/BaseSubstrateClient.js +22 -1
- package/client/DedotClient.d.ts +2 -2
- package/client/DedotClient.js +5 -4
- package/client/{Dedot.d.ts → LegacyClient.d.ts} +8 -7
- package/client/{Dedot.js → LegacyClient.js} +11 -7
- package/client/index.d.ts +1 -1
- package/client/index.js +1 -1
- package/executor/ErrorExecutor.js +3 -3
- package/executor/EventExecutor.js +2 -2
- package/executor/Executor.d.ts +12 -12
- package/executor/StorageQueryExecutor.js +1 -1
- package/executor/TxExecutor.js +3 -3
- package/executor/v2/StorageQueryExecutorV2.js +7 -7
- package/extrinsic/extensions/known/ChargeAssetTxPayment.js +2 -2
- package/extrinsic/extensions/known/CheckMetadataHash.d.ts +13 -0
- package/extrinsic/extensions/known/CheckMetadataHash.js +27 -0
- package/extrinsic/extensions/known/StorageWeightReclaim.d.ts +6 -0
- package/extrinsic/extensions/known/StorageWeightReclaim.js +6 -0
- package/extrinsic/extensions/known/index.js +4 -0
- package/extrinsic/submittable/BaseSubmittableExtrinsic.d.ts +2 -0
- package/extrinsic/submittable/BaseSubmittableExtrinsic.js +32 -2
- package/extrinsic/submittable/SubmittableExtrinsic.js +7 -4
- package/extrinsic/submittable/SubmittableExtrinsicV2.js +11 -11
- package/extrinsic/submittable/SubmittableResult.d.ts +4 -4
- package/extrinsic/submittable/utils.d.ts +10 -1
- package/extrinsic/submittable/utils.js +65 -1
- package/json-rpc/JsonRpcClient.d.ts +6 -5
- package/package.json +11 -11
- package/storage/QueryableStorage.js +17 -17
- package/types.d.ts +9 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Generated by
|
|
1
|
+
// Generated by dedot cli
|
|
2
2
|
export {};
|
|
@@ -26,6 +26,7 @@ class BaseSubstrateClient extends index_js_2.JsonRpcClient {
|
|
|
26
26
|
_genesisHash;
|
|
27
27
|
_runtimeVersion;
|
|
28
28
|
_localCache;
|
|
29
|
+
_runtimeUpgrading;
|
|
29
30
|
constructor(rpcVersion, options) {
|
|
30
31
|
super(options);
|
|
31
32
|
this.rpcVersion = rpcVersion;
|
|
@@ -197,6 +198,22 @@ class BaseSubstrateClient extends index_js_2.JsonRpcClient {
|
|
|
197
198
|
}, {}),
|
|
198
199
|
};
|
|
199
200
|
}
|
|
201
|
+
startRuntimeUpgrade() {
|
|
202
|
+
this._runtimeUpgrading = (0, utils_1.deferred)();
|
|
203
|
+
}
|
|
204
|
+
doneRuntimeUpgrade() {
|
|
205
|
+
if (!this._runtimeUpgrading)
|
|
206
|
+
return;
|
|
207
|
+
this._runtimeUpgrading.resolve();
|
|
208
|
+
setTimeout(() => {
|
|
209
|
+
this._runtimeUpgrading = undefined;
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
async ensureRuntimeUpgraded() {
|
|
213
|
+
if (!this._runtimeUpgrading)
|
|
214
|
+
return;
|
|
215
|
+
await this._runtimeUpgrading.promise;
|
|
216
|
+
}
|
|
200
217
|
/// --- Public APIs ---
|
|
201
218
|
/**
|
|
202
219
|
* @description Connect to blockchain node
|
|
@@ -228,6 +245,10 @@ class BaseSubstrateClient extends index_js_2.JsonRpcClient {
|
|
|
228
245
|
get runtimeVersion() {
|
|
229
246
|
return ensurePresence(this._runtimeVersion);
|
|
230
247
|
}
|
|
248
|
+
async getRuntimeVersion() {
|
|
249
|
+
await this.ensureRuntimeUpgraded();
|
|
250
|
+
return this.runtimeVersion;
|
|
251
|
+
}
|
|
231
252
|
get consts() {
|
|
232
253
|
return (0, proxychain_js_1.newProxyChain)({ executor: new index_js_1.ConstantExecutor(this) });
|
|
233
254
|
}
|
|
@@ -14,7 +14,8 @@ const BaseSubstrateClient_js_1 = require("./BaseSubstrateClient.js");
|
|
|
14
14
|
*
|
|
15
15
|
* __Unstable, use with caution.__
|
|
16
16
|
*/
|
|
17
|
-
class DedotClient
|
|
17
|
+
class DedotClient// prettier-end-here
|
|
18
|
+
extends BaseSubstrateClient_js_1.BaseSubstrateClient {
|
|
18
19
|
_chainHead;
|
|
19
20
|
_chainSpec;
|
|
20
21
|
_txBroadcaster;
|
|
@@ -102,16 +103,16 @@ class DedotClient extends BaseSubstrateClient_js_1.BaseSubstrateClient {
|
|
|
102
103
|
subscribeRuntimeUpgrades() {
|
|
103
104
|
this.chainHead.on('bestBlock', this.onRuntimeUpgrade);
|
|
104
105
|
}
|
|
105
|
-
unsubscribeRuntimeUpgrades() {
|
|
106
|
-
this.chainHead.off('bestBlock', this.onRuntimeUpgrade);
|
|
107
|
-
}
|
|
108
106
|
onRuntimeUpgrade = async (block) => {
|
|
109
107
|
const runtimeUpgraded = block.runtime && block.runtime.specVersion !== this._runtimeVersion?.specVersion;
|
|
110
108
|
if (!runtimeUpgraded)
|
|
111
109
|
return;
|
|
110
|
+
this.startRuntimeUpgrade();
|
|
112
111
|
this._runtimeVersion = block.runtime;
|
|
113
112
|
const newMetadata = await this.fetchMetadata(undefined, this._runtimeVersion);
|
|
114
113
|
await this.setupMetadata(newMetadata);
|
|
114
|
+
this.emit('runtimeUpgraded', this._runtimeVersion);
|
|
115
|
+
this.doneRuntimeUpgrade();
|
|
115
116
|
};
|
|
116
117
|
async beforeDisconnect() {
|
|
117
118
|
await this.chainHead.unfollow();
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.LegacyClient = void 0;
|
|
4
4
|
const codecs_1 = require("@dedot/codecs");
|
|
5
5
|
const index_js_1 = require("../executor/index.js");
|
|
6
6
|
const proxychain_js_1 = require("../proxychain.js");
|
|
7
7
|
const BaseSubstrateClient_js_1 = require("./BaseSubstrateClient.js");
|
|
8
8
|
const KEEP_ALIVE_INTERVAL = 10_000; // in ms
|
|
9
9
|
/**
|
|
10
|
-
* @name
|
|
10
|
+
* @name LegacyClient
|
|
11
11
|
* @description Promised-based API Client for Polkadot & Substrate
|
|
12
12
|
*
|
|
13
13
|
* Initialize API instance and interact with substrate-based network
|
|
@@ -16,7 +16,7 @@ const KEEP_ALIVE_INTERVAL = 10_000; // in ms
|
|
|
16
16
|
* import type { PolkadotApi } from '@dedot/chaintypes/polkadot';
|
|
17
17
|
*
|
|
18
18
|
* const run = async () => {
|
|
19
|
-
* const api = await
|
|
19
|
+
* const api = await LegacyClient.new<PolkadotApi>('wss://rpc.polkadot.io');
|
|
20
20
|
*
|
|
21
21
|
* // Call rpc `state_getMetadata` to fetch raw scale-encoded metadata and decode it.
|
|
22
22
|
* const metadata = await api.rpc.state.getMetadata();
|
|
@@ -44,7 +44,8 @@ const KEEP_ALIVE_INTERVAL = 10_000; // in ms
|
|
|
44
44
|
* run().catch(console.error);
|
|
45
45
|
* ```
|
|
46
46
|
*/
|
|
47
|
-
class
|
|
47
|
+
class LegacyClient// prettier-end-here
|
|
48
|
+
extends BaseSubstrateClient_js_1.BaseSubstrateClient {
|
|
48
49
|
#runtimeSubscriptionUnsub;
|
|
49
50
|
#healthTimer;
|
|
50
51
|
#apiAtCache = {};
|
|
@@ -62,15 +63,15 @@ class Dedot extends BaseSubstrateClient_js_1.BaseSubstrateClient {
|
|
|
62
63
|
* @param options
|
|
63
64
|
*/
|
|
64
65
|
static async create(options) {
|
|
65
|
-
return new
|
|
66
|
+
return new LegacyClient(options).connect();
|
|
66
67
|
}
|
|
67
68
|
/**
|
|
68
|
-
* Alias for
|
|
69
|
+
* Alias for __LegacyClient.create__
|
|
69
70
|
*
|
|
70
71
|
* @param options
|
|
71
72
|
*/
|
|
72
73
|
static async new(options) {
|
|
73
|
-
return
|
|
74
|
+
return LegacyClient.create(options);
|
|
74
75
|
}
|
|
75
76
|
onDisconnected = async () => {
|
|
76
77
|
await this.#unsubscribeUpdates();
|
|
@@ -104,9 +105,12 @@ class Dedot extends BaseSubstrateClient_js_1.BaseSubstrateClient {
|
|
|
104
105
|
this.rpc
|
|
105
106
|
.state_subscribeRuntimeVersion(async (runtimeVersion) => {
|
|
106
107
|
if (runtimeVersion.specVersion !== this.runtimeVersion?.specVersion) {
|
|
108
|
+
this.startRuntimeUpgrade();
|
|
107
109
|
this._runtimeVersion = this.toSubstrateRuntimeVersion(runtimeVersion);
|
|
108
110
|
const newMetadata = await this.fetchMetadata(undefined, this._runtimeVersion);
|
|
109
111
|
await this.setupMetadata(newMetadata);
|
|
112
|
+
this.emit('runtimeUpgraded', this._runtimeVersion);
|
|
113
|
+
this.doneRuntimeUpgrade();
|
|
110
114
|
}
|
|
111
115
|
})
|
|
112
116
|
.then((unsub) => {
|
|
@@ -205,7 +209,7 @@ class Dedot extends BaseSubstrateClient_js_1.BaseSubstrateClient {
|
|
|
205
209
|
* // Make a transfer balance transaction
|
|
206
210
|
* api.tx.balances.transferKeepAlive(<address>, <amount>)
|
|
207
211
|
* .signAndSend(<keyPair|address>, { signer }, ({ status }) => {
|
|
208
|
-
* console.log('Transaction status', status.
|
|
212
|
+
* console.log('Transaction status', status.type);
|
|
209
213
|
* });
|
|
210
214
|
* ```
|
|
211
215
|
*/
|
|
@@ -247,4 +251,4 @@ class Dedot extends BaseSubstrateClient_js_1.BaseSubstrateClient {
|
|
|
247
251
|
return api;
|
|
248
252
|
}
|
|
249
253
|
}
|
|
250
|
-
exports.
|
|
254
|
+
exports.LegacyClient = LegacyClient;
|
package/cjs/client/index.js
CHANGED
|
@@ -14,5 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./
|
|
17
|
+
__exportStar(require("./LegacyClient.js"), exports);
|
|
18
18
|
__exportStar(require("./DedotClient.js"), exports);
|
|
@@ -20,7 +20,7 @@ class ErrorExecutor extends Executor_js_1.Executor {
|
|
|
20
20
|
palletIndex: targetPallet.index,
|
|
21
21
|
},
|
|
22
22
|
is: (errorInfo) => {
|
|
23
|
-
if ((0, utils_1.isObject)(errorInfo) && errorInfo.
|
|
23
|
+
if ((0, utils_1.isObject)(errorInfo) && errorInfo.type === 'Module') {
|
|
24
24
|
errorInfo = errorInfo.value;
|
|
25
25
|
}
|
|
26
26
|
if ((0, utils_1.isObject)(errorInfo) && (0, utils_1.isNumber)(errorInfo.index) && (0, utils_1.isHex)(errorInfo.error)) {
|
|
@@ -33,8 +33,8 @@ class ErrorExecutor extends Executor_js_1.Executor {
|
|
|
33
33
|
#getErrorDef(errorTypeId, errorName) {
|
|
34
34
|
const def = this.metadata.types[errorTypeId];
|
|
35
35
|
(0, utils_1.assert)(def, new utils_1.UnknownApiError(`Error def not found for id ${errorTypeId}`));
|
|
36
|
-
const {
|
|
37
|
-
(0, utils_1.assert)(
|
|
36
|
+
const { type, value } = def.typeDef;
|
|
37
|
+
(0, utils_1.assert)(type === 'Enum', new utils_1.UnknownApiError(`Error type should be an enum, found: ${type}`));
|
|
38
38
|
const errorDef = value.members.find(({ name }) => (0, utils_1.stringPascalCase)(name) === errorName);
|
|
39
39
|
(0, utils_1.assert)(errorDef, new utils_1.UnknownApiError(`Error def not found for ${errorName}`));
|
|
40
40
|
return {
|
|
@@ -39,8 +39,8 @@ class EventExecutor extends Executor_js_1.Executor {
|
|
|
39
39
|
#getEventDef(eventTypeId, errorName) {
|
|
40
40
|
const def = this.metadata.types[eventTypeId];
|
|
41
41
|
(0, utils_1.assert)(def, new utils_1.UnknownApiError(`Event def not found for id ${eventTypeId}`));
|
|
42
|
-
const {
|
|
43
|
-
(0, utils_1.assert)(
|
|
42
|
+
const { type, value } = def.typeDef;
|
|
43
|
+
(0, utils_1.assert)(type === 'Enum', new utils_1.UnknownApiError(`Event type should be an enum, found: ${type}`));
|
|
44
44
|
const eventDef = value.members.find(({ name }) => (0, utils_1.stringPascalCase)(name) === errorName);
|
|
45
45
|
(0, utils_1.assert)(eventDef, new utils_1.UnknownApiError(`Event def not found for ${errorName}`));
|
|
46
46
|
return {
|
|
@@ -52,7 +52,7 @@ class StorageQueryExecutor extends Executor_js_1.Executor {
|
|
|
52
52
|
palletIndex: entry.pallet.index,
|
|
53
53
|
...entry.storageEntry,
|
|
54
54
|
};
|
|
55
|
-
const isMap = entry.storageEntry.type
|
|
55
|
+
const isMap = entry.storageEntry.storageType.type === 'Map';
|
|
56
56
|
if (isMap) {
|
|
57
57
|
const queryMultiFn = async (...args) => {
|
|
58
58
|
const [inArgs, callback] = extractArgs(args);
|
|
@@ -13,9 +13,9 @@ class TxExecutor extends Executor_js_1.Executor {
|
|
|
13
13
|
const targetPallet = this.getPallet(pallet);
|
|
14
14
|
(0, utils_1.assert)(targetPallet.calls, new utils_1.UnknownApiError(`Tx calls are not available for pallet ${targetPallet.name}`));
|
|
15
15
|
const txType = this.metadata.types[targetPallet.calls];
|
|
16
|
-
(0, utils_1.assert)(txType.type
|
|
17
|
-
const isFlatEnum = txType.
|
|
18
|
-
const txCallDef = txType.
|
|
16
|
+
(0, utils_1.assert)(txType.typeDef.type === 'Enum', new utils_1.UnknownApiError('Tx type defs should be enum'));
|
|
17
|
+
const isFlatEnum = txType.typeDef.value.members.every((m) => m.fields.length === 0);
|
|
18
|
+
const txCallDef = txType.typeDef.value.members.find((m) => (0, utils_1.stringCamelCase)(m.name) === functionName);
|
|
19
19
|
(0, utils_1.assert)(txCallDef, new utils_1.UnknownApiError(`Tx call spec not found for ${pallet}.${functionName}`));
|
|
20
20
|
const txCallFn = (...args) => {
|
|
21
21
|
let call;
|
|
@@ -35,27 +35,27 @@ class StorageQueryExecutorV2 extends StorageQueryExecutor_js_1.StorageQueryExecu
|
|
|
35
35
|
}, {});
|
|
36
36
|
}
|
|
37
37
|
async subscribeStorage(keys, callback) {
|
|
38
|
-
let
|
|
38
|
+
let best = await this.chainHead.bestBlock();
|
|
39
39
|
let eventToListen = 'bestBlock';
|
|
40
40
|
// TODO subscribe to finalized data source
|
|
41
41
|
// initialHash = this.chainHead.finalizedHash;
|
|
42
42
|
// eventToListen = 'finalizedBlock';
|
|
43
|
-
const latestChanges =
|
|
44
|
-
const pull = async (hash) => {
|
|
43
|
+
const latestChanges = new Map();
|
|
44
|
+
const pull = async ({ hash }) => {
|
|
45
45
|
const results = await this.queryStorage(keys, hash);
|
|
46
46
|
let changed = false;
|
|
47
47
|
keys.forEach((key) => {
|
|
48
48
|
const newValue = results[key];
|
|
49
|
-
if (latestChanges
|
|
49
|
+
if (latestChanges.size > 0 && latestChanges.get(key) === newValue)
|
|
50
50
|
return;
|
|
51
51
|
changed = true;
|
|
52
|
-
latestChanges
|
|
52
|
+
latestChanges.set(key, newValue);
|
|
53
53
|
});
|
|
54
54
|
if (!changed)
|
|
55
55
|
return;
|
|
56
|
-
callback(keys.map((key) => latestChanges
|
|
56
|
+
callback(keys.map((key) => latestChanges.get(key)));
|
|
57
57
|
};
|
|
58
|
-
await pull(
|
|
58
|
+
await pull(best);
|
|
59
59
|
const unsub = this.chainHead.on(eventToListen, pull);
|
|
60
60
|
return async () => {
|
|
61
61
|
unsub();
|
|
@@ -30,8 +30,8 @@ class ChargeAssetTxPayment extends SignedExtension_js_1.SignedExtension {
|
|
|
30
30
|
}
|
|
31
31
|
$AssetId() {
|
|
32
32
|
const extensionTypeDef = this.registry.findType(this.signedExtensionDef.typeId);
|
|
33
|
-
(0, utils_1.assert)(extensionTypeDef.type
|
|
34
|
-
const assetIdTypeDef = extensionTypeDef.
|
|
33
|
+
(0, utils_1.assert)(extensionTypeDef.typeDef.type === 'Struct');
|
|
34
|
+
const assetIdTypeDef = extensionTypeDef.typeDef.value.fields.find((f) => f.name === 'asset_id');
|
|
35
35
|
const $codec = this.registry.findCodec(assetIdTypeDef.typeId);
|
|
36
36
|
const codecMetadata = $codec.metadata[0];
|
|
37
37
|
if (codecMetadata.name === '$.option') {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CheckMetadataHash = void 0;
|
|
4
|
+
const utils_1 = require("@dedot/utils");
|
|
5
|
+
const SignedExtension_js_1 = require("../SignedExtension.js");
|
|
6
|
+
/**
|
|
7
|
+
* @description Genesis hash check to provide replay protection between different networks.
|
|
8
|
+
*/
|
|
9
|
+
class CheckMetadataHash extends SignedExtension_js_1.SignedExtension {
|
|
10
|
+
async init() {
|
|
11
|
+
let metadataHash = this.payloadOptions.metadataHash;
|
|
12
|
+
if (metadataHash) {
|
|
13
|
+
(0, utils_1.assert)((0, utils_1.isHex)(metadataHash), 'Metadata hash is not a valid hex string');
|
|
14
|
+
this.data = { mode: 'Enabled' };
|
|
15
|
+
this.additionalSigned = metadataHash;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
this.data = { mode: 'Disabled' };
|
|
19
|
+
this.additionalSigned = undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
toPayload() {
|
|
23
|
+
// Ref: https://github.com/paritytech/polkadot-sdk/blob/8dbe4ee80734bba6644c7e5f879a363ce7c0a19f/substrate/frame/metadata-hash-extension/src/lib.rs#L55-L58
|
|
24
|
+
let enabled = this.data.mode === 'Enabled';
|
|
25
|
+
return {
|
|
26
|
+
mode: enabled ? 1 : 0, // 0 -> disabled, 1 -> enabled
|
|
27
|
+
metadataHash: this.additionalSigned,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.CheckMetadataHash = CheckMetadataHash;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StorageWeightReclaim = void 0;
|
|
4
|
+
const SignedExtension_js_1 = require("../SignedExtension.js");
|
|
5
|
+
/**
|
|
6
|
+
* @description Storage weight reclaim mechanism.
|
|
7
|
+
*/
|
|
8
|
+
class StorageWeightReclaim extends SignedExtension_js_1.SignedExtension {
|
|
9
|
+
}
|
|
10
|
+
exports.StorageWeightReclaim = StorageWeightReclaim;
|
|
@@ -4,6 +4,7 @@ exports.knownSignedExtensions = void 0;
|
|
|
4
4
|
const ChargeAssetTxPayment_js_1 = require("./ChargeAssetTxPayment.js");
|
|
5
5
|
const ChargeTransactionPayment_js_1 = require("./ChargeTransactionPayment.js");
|
|
6
6
|
const CheckGenesis_js_1 = require("./CheckGenesis.js");
|
|
7
|
+
const CheckMetadataHash_js_1 = require("./CheckMetadataHash.js");
|
|
7
8
|
const CheckMortality_js_1 = require("./CheckMortality.js");
|
|
8
9
|
const CheckNonZeroSender_js_1 = require("./CheckNonZeroSender.js");
|
|
9
10
|
const CheckNonce_js_1 = require("./CheckNonce.js");
|
|
@@ -11,6 +12,7 @@ const CheckSpecVersion_js_1 = require("./CheckSpecVersion.js");
|
|
|
11
12
|
const CheckTxVersion_js_1 = require("./CheckTxVersion.js");
|
|
12
13
|
const CheckWeight_js_1 = require("./CheckWeight.js");
|
|
13
14
|
const PrevalidateAttests_js_1 = require("./PrevalidateAttests.js");
|
|
15
|
+
const StorageWeightReclaim_js_1 = require("./StorageWeightReclaim.js");
|
|
14
16
|
exports.knownSignedExtensions = {
|
|
15
17
|
CheckNonZeroSender: CheckNonZeroSender_js_1.CheckNonZeroSender,
|
|
16
18
|
CheckSpecVersion: CheckSpecVersion_js_1.CheckSpecVersion,
|
|
@@ -22,4 +24,6 @@ exports.knownSignedExtensions = {
|
|
|
22
24
|
ChargeTransactionPayment: ChargeTransactionPayment_js_1.ChargeTransactionPayment,
|
|
23
25
|
PrevalidateAttests: PrevalidateAttests_js_1.PrevalidateAttests,
|
|
24
26
|
ChargeAssetTxPayment: ChargeAssetTxPayment_js_1.ChargeAssetTxPayment,
|
|
27
|
+
CheckMetadataHash: CheckMetadataHash_js_1.CheckMetadataHash,
|
|
28
|
+
StorageWeightReclaim: StorageWeightReclaim_js_1.StorageWeightReclaim,
|
|
25
29
|
};
|
|
@@ -8,6 +8,7 @@ const fakeSigner_js_1 = require("./fakeSigner.js");
|
|
|
8
8
|
const utils_js_1 = require("./utils.js");
|
|
9
9
|
class BaseSubmittableExtrinsic extends codecs_1.Extrinsic {
|
|
10
10
|
api;
|
|
11
|
+
#alterTx;
|
|
11
12
|
constructor(api, call) {
|
|
12
13
|
super(api.registry, call);
|
|
13
14
|
this.api = api;
|
|
@@ -26,13 +27,14 @@ class BaseSubmittableExtrinsic extends codecs_1.Extrinsic {
|
|
|
26
27
|
});
|
|
27
28
|
await extra.init();
|
|
28
29
|
const { signer } = options || {};
|
|
29
|
-
let signature;
|
|
30
|
+
let signature, alteredTx;
|
|
30
31
|
if ((0, utils_js_1.isKeyringPair)(fromAccount)) {
|
|
31
32
|
signature = (0, utils_1.u8aToHex)((0, utils_js_1.signRaw)(fromAccount, extra.toRawPayload(this.callHex).data));
|
|
32
33
|
}
|
|
33
34
|
else if (signer?.signPayload) {
|
|
34
35
|
const result = await signer.signPayload(extra.toPayload(this.callHex));
|
|
35
36
|
signature = result.signature;
|
|
37
|
+
alteredTx = result.signedTransaction;
|
|
36
38
|
}
|
|
37
39
|
else {
|
|
38
40
|
throw new Error('Signer not found. Cannot sign the extrinsic!');
|
|
@@ -44,6 +46,13 @@ class BaseSubmittableExtrinsic extends codecs_1.Extrinsic {
|
|
|
44
46
|
signature: $Signature.tryDecode(signature),
|
|
45
47
|
extra: extra.data,
|
|
46
48
|
});
|
|
49
|
+
// If the tx payload are altered from signer
|
|
50
|
+
// We'll need to validate the altered tx
|
|
51
|
+
// and broadcast it instead of the original tx
|
|
52
|
+
if (alteredTx) {
|
|
53
|
+
this.#validateSignedTx(alteredTx);
|
|
54
|
+
this.#alterTx = (0, utils_1.toHex)(alteredTx);
|
|
55
|
+
}
|
|
47
56
|
return this;
|
|
48
57
|
}
|
|
49
58
|
async signAndSend(fromAccount, partialOptions, maybeCallback) {
|
|
@@ -66,5 +75,26 @@ class BaseSubmittableExtrinsic extends codecs_1.Extrinsic {
|
|
|
66
75
|
const atApi = (await this.api.at(hash));
|
|
67
76
|
return await atApi.query.system.events();
|
|
68
77
|
}
|
|
78
|
+
toHex() {
|
|
79
|
+
return this.#alterTx || super.toHex();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Validate a raw signed transaction coming from signer
|
|
83
|
+
* We need to make sure the tx is signed and call-data is intact/not-changing
|
|
84
|
+
*
|
|
85
|
+
* @param tx
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
#validateSignedTx(tx) {
|
|
89
|
+
const alteredTx = this.$Codec.tryDecode(tx);
|
|
90
|
+
// The alter tx should be signed
|
|
91
|
+
if (!alteredTx.signed) {
|
|
92
|
+
throw new utils_1.DedotError('Altered transaction from signer is not signed');
|
|
93
|
+
}
|
|
94
|
+
// Signer's not allow the change the call data
|
|
95
|
+
if (alteredTx.callHex !== this.callHex) {
|
|
96
|
+
throw new utils_1.DedotError('Call data does not match, signer is not allowed to change tx call data.');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
69
99
|
}
|
|
70
100
|
exports.BaseSubmittableExtrinsic = BaseSubmittableExtrinsic;
|
|
@@ -4,6 +4,7 @@ exports.SubmittableExtrinsic = void 0;
|
|
|
4
4
|
const utils_1 = require("@dedot/utils");
|
|
5
5
|
const BaseSubmittableExtrinsic_js_1 = require("./BaseSubmittableExtrinsic.js");
|
|
6
6
|
const SubmittableResult_js_1 = require("./SubmittableResult.js");
|
|
7
|
+
const utils_js_1 = require("./utils.js");
|
|
7
8
|
/**
|
|
8
9
|
* @name SubmittableExtrinsic
|
|
9
10
|
* @description A wrapper around an Extrinsic that exposes methods to sign, send, and other utility around Extrinsic.
|
|
@@ -22,19 +23,21 @@ class SubmittableExtrinsic extends BaseSubmittableExtrinsic_js_1.BaseSubmittable
|
|
|
22
23
|
const txHex = this.toHex();
|
|
23
24
|
const txHash = this.hash;
|
|
24
25
|
if (isSubscription) {
|
|
25
|
-
return this.api.rpc.author_submitAndWatchExtrinsic(txHex, async (
|
|
26
|
-
if (
|
|
27
|
-
const blockHash =
|
|
26
|
+
return this.api.rpc.author_submitAndWatchExtrinsic(txHex, async (txStatus) => {
|
|
27
|
+
if (txStatus.type === 'InBlock' || txStatus.type === 'Finalized') {
|
|
28
|
+
const blockHash = txStatus.value;
|
|
28
29
|
const [signedBlock, blockEvents] = await Promise.all([
|
|
29
30
|
this.api.rpc.chain_getBlock(blockHash),
|
|
30
31
|
this.getSystemEventsAt(blockHash),
|
|
31
32
|
]);
|
|
32
33
|
const txIndex = signedBlock.block.extrinsics.indexOf(txHex);
|
|
33
34
|
(0, utils_1.assert)(txIndex >= 0, 'Extrinsic not found!');
|
|
34
|
-
const events = blockEvents.filter(({ phase }) => phase.
|
|
35
|
+
const events = blockEvents.filter(({ phase }) => phase.type === 'ApplyExtrinsic' && phase.value === txIndex);
|
|
36
|
+
const status = (0, utils_js_1.toTxStatus)(txStatus, txIndex);
|
|
35
37
|
return callback(new SubmittableResult_js_1.SubmittableResult({ status, txHash, events, txIndex }));
|
|
36
38
|
}
|
|
37
39
|
else {
|
|
40
|
+
const status = (0, utils_js_1.toTxStatus)(txStatus);
|
|
38
41
|
return callback(new SubmittableResult_js_1.SubmittableResult({ status, txHash }));
|
|
39
42
|
}
|
|
40
43
|
});
|
|
@@ -28,10 +28,10 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
|
|
|
28
28
|
};
|
|
29
29
|
const validation = await validateTx(finalizedHash);
|
|
30
30
|
if (validation.isOk) {
|
|
31
|
-
callback(new SubmittableResult_js_1.SubmittableResult({ status: {
|
|
31
|
+
callback(new SubmittableResult_js_1.SubmittableResult({ status: { type: 'Validated' }, txHash }));
|
|
32
32
|
}
|
|
33
33
|
else if (validation.isErr) {
|
|
34
|
-
throw new errors_js_1.InvalidTxError(`Invalid Tx: ${validation.err.
|
|
34
|
+
throw new errors_js_1.InvalidTxError(`Invalid Tx: ${validation.err.type} - ${validation.err.value.type}`, validation);
|
|
35
35
|
}
|
|
36
36
|
const checkTxIsOnChain = async (blockHash) => {
|
|
37
37
|
if (blockHash === finalizedHash)
|
|
@@ -42,7 +42,7 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
|
|
|
42
42
|
return checkTxIsOnChain(api.chainHead.findBlock(blockHash).parent);
|
|
43
43
|
}
|
|
44
44
|
const events = await this.getSystemEventsAt(blockHash);
|
|
45
|
-
const txEvents = events.filter(({ phase }) => phase.
|
|
45
|
+
const txEvents = events.filter(({ phase }) => phase.type == 'ApplyExtrinsic' && phase.value === txIndex);
|
|
46
46
|
return {
|
|
47
47
|
blockHash,
|
|
48
48
|
index: txIndex,
|
|
@@ -88,7 +88,7 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
|
|
|
88
88
|
if (txFound && bestChainChanged) {
|
|
89
89
|
txFound = undefined;
|
|
90
90
|
callback(new SubmittableResult_js_1.SubmittableResult({
|
|
91
|
-
status: {
|
|
91
|
+
status: { type: 'NoLongerInBestChain' },
|
|
92
92
|
txHash,
|
|
93
93
|
}));
|
|
94
94
|
}
|
|
@@ -101,7 +101,7 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
|
|
|
101
101
|
txFound = inBlock;
|
|
102
102
|
const { index: txIndex, events, blockHash } = inBlock;
|
|
103
103
|
callback(new SubmittableResult_js_1.SubmittableResult({
|
|
104
|
-
status: {
|
|
104
|
+
status: { type: 'BestChainBlockIncluded', value: { blockHash, txIndex } },
|
|
105
105
|
txHash,
|
|
106
106
|
events,
|
|
107
107
|
txIndex,
|
|
@@ -134,7 +134,7 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
|
|
|
134
134
|
if (inBlock) {
|
|
135
135
|
const { index: txIndex, events, blockHash } = inBlock;
|
|
136
136
|
callback(new SubmittableResult_js_1.SubmittableResult({
|
|
137
|
-
status: {
|
|
137
|
+
status: { type: 'Finalized', value: { blockHash, txIndex } },
|
|
138
138
|
txHash,
|
|
139
139
|
events,
|
|
140
140
|
txIndex,
|
|
@@ -148,8 +148,8 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
|
|
|
148
148
|
return;
|
|
149
149
|
callback(new SubmittableResult_js_1.SubmittableResult({
|
|
150
150
|
status: {
|
|
151
|
-
|
|
152
|
-
value: { error: `Invalid Tx: ${validation.err.
|
|
151
|
+
type: 'Invalid',
|
|
152
|
+
value: { error: `Invalid Tx: ${validation.err.type} - ${validation.err.value.type}` },
|
|
153
153
|
},
|
|
154
154
|
txHash,
|
|
155
155
|
}));
|
|
@@ -158,7 +158,7 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
|
|
|
158
158
|
};
|
|
159
159
|
stopBroadcastFn = await api.txBroadcaster.broadcastTx(txHex);
|
|
160
160
|
callback(new SubmittableResult_js_1.SubmittableResult({
|
|
161
|
-
status: {
|
|
161
|
+
status: { type: 'Broadcasting' },
|
|
162
162
|
txHash,
|
|
163
163
|
}));
|
|
164
164
|
const stopBestBlockTrackingFn = api.chainHead.on('bestBlock', checkBestBlockIncluded);
|
|
@@ -184,11 +184,11 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
|
|
|
184
184
|
try {
|
|
185
185
|
// TODO handle timeout for this with the Drop status, just in-case we somehow can't find the tx in any block
|
|
186
186
|
const unsub = await this.#send(({ status, txHash }) => {
|
|
187
|
-
if (status.
|
|
187
|
+
if (status.type === 'BestChainBlockIncluded' || status.type === 'Finalized') {
|
|
188
188
|
defer.resolve(txHash);
|
|
189
189
|
unsub().catch(utils_1.noop);
|
|
190
190
|
}
|
|
191
|
-
else if (status.
|
|
191
|
+
else if (status.type === 'Invalid' || status.type === 'Drop') {
|
|
192
192
|
defer.reject(new Error(status.value.error));
|
|
193
193
|
unsub().catch(utils_1.noop);
|
|
194
194
|
}
|