@dedot/api 0.18.8 → 1.0.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.
Files changed (102) hide show
  1. package/chaintypes/substrate/consts.d.ts +2 -2
  2. package/chaintypes/substrate/consts.js +1 -0
  3. package/chaintypes/substrate/errors.d.ts +909 -909
  4. package/chaintypes/substrate/errors.js +1 -0
  5. package/chaintypes/substrate/events.d.ts +664 -664
  6. package/chaintypes/substrate/events.js +1 -0
  7. package/chaintypes/substrate/index.d.ts +13 -16
  8. package/chaintypes/substrate/index.js +1 -0
  9. package/chaintypes/substrate/json-rpc.d.ts +2 -2
  10. package/chaintypes/substrate/json-rpc.js +1 -0
  11. package/chaintypes/substrate/query.d.ts +509 -527
  12. package/chaintypes/substrate/query.js +1 -0
  13. package/chaintypes/substrate/runtime.d.ts +123 -123
  14. package/chaintypes/substrate/runtime.js +1 -0
  15. package/chaintypes/substrate/tx.d.ts +1311 -1311
  16. package/chaintypes/substrate/tx.js +1 -0
  17. package/chaintypes/substrate/types.js +1 -0
  18. package/chaintypes/substrate/view-functions.d.ts +2 -2
  19. package/chaintypes/substrate/view-functions.js +1 -0
  20. package/cjs/chaintypes/substrate/consts.js +1 -0
  21. package/cjs/chaintypes/substrate/errors.js +1 -0
  22. package/cjs/chaintypes/substrate/events.js +1 -0
  23. package/cjs/chaintypes/substrate/index.js +1 -0
  24. package/cjs/chaintypes/substrate/json-rpc.js +1 -0
  25. package/cjs/chaintypes/substrate/query.js +1 -0
  26. package/cjs/chaintypes/substrate/runtime.js +1 -0
  27. package/cjs/chaintypes/substrate/tx.js +1 -0
  28. package/cjs/chaintypes/substrate/types.js +1 -0
  29. package/cjs/chaintypes/substrate/view-functions.js +1 -0
  30. package/cjs/client/BaseSubstrateClient.js +45 -2
  31. package/cjs/client/DedotClient.js +356 -224
  32. package/cjs/client/LegacyClient.js +99 -23
  33. package/cjs/client/V2Client.js +316 -0
  34. package/cjs/client/explorer/LegacyBlockExplorer.js +263 -0
  35. package/cjs/client/explorer/V2BlockExplorer.js +74 -0
  36. package/cjs/client/explorer/index.js +18 -0
  37. package/cjs/client/utils.js +57 -0
  38. package/cjs/executor/EventExecutor.js +1 -0
  39. package/cjs/executor/RuntimeApiExecutor.js +49 -2
  40. package/cjs/executor/StorageQueryExecutor.js +114 -2
  41. package/cjs/executor/ViewFunctionExecutor.js +21 -2
  42. package/cjs/executor/v2/StorageQueryExecutorV2.js +7 -1
  43. package/cjs/executor/validation-helpers.js +181 -0
  44. package/cjs/extrinsic/submittable/BaseSubmittableExtrinsic.js +86 -2
  45. package/cjs/extrinsic/submittable/SubmittableExtrinsic.js +38 -16
  46. package/cjs/extrinsic/submittable/SubmittableExtrinsicV2.js +12 -2
  47. package/cjs/json-rpc/group/ChainHead/ChainHead.js +226 -21
  48. package/cjs/storage/QueryableStorage.js +1 -0
  49. package/client/BaseSubstrateClient.d.ts +34 -18
  50. package/client/BaseSubstrateClient.js +47 -4
  51. package/client/DedotClient.d.ts +346 -49
  52. package/client/DedotClient.js +356 -224
  53. package/client/LegacyClient.d.ts +22 -17
  54. package/client/LegacyClient.js +101 -25
  55. package/client/V2Client.d.ts +75 -0
  56. package/client/V2Client.js +312 -0
  57. package/client/explorer/LegacyBlockExplorer.d.ts +68 -0
  58. package/client/explorer/LegacyBlockExplorer.js +259 -0
  59. package/client/explorer/V2BlockExplorer.d.ts +40 -0
  60. package/client/explorer/V2BlockExplorer.js +70 -0
  61. package/client/explorer/index.d.ts +2 -0
  62. package/client/explorer/index.js +2 -0
  63. package/client/utils.d.ts +18 -0
  64. package/client/utils.js +52 -0
  65. package/executor/ConstantExecutor.d.ts +1 -2
  66. package/executor/ErrorExecutor.d.ts +2 -2
  67. package/executor/EventExecutor.d.ts +2 -2
  68. package/executor/EventExecutor.js +1 -0
  69. package/executor/Executor.d.ts +4 -5
  70. package/executor/RuntimeApiExecutor.d.ts +2 -2
  71. package/executor/RuntimeApiExecutor.js +27 -3
  72. package/executor/StorageQueryExecutor.d.ts +3 -2
  73. package/executor/StorageQueryExecutor.js +92 -3
  74. package/executor/TxExecutor.d.ts +2 -2
  75. package/executor/ViewFunctionExecutor.d.ts +2 -2
  76. package/executor/ViewFunctionExecutor.js +22 -3
  77. package/executor/v2/RuntimeApiExecutorV2.d.ts +2 -3
  78. package/executor/v2/StorageQueryExecutorV2.d.ts +3 -3
  79. package/executor/v2/StorageQueryExecutorV2.js +8 -2
  80. package/executor/v2/TxExecutorV2.d.ts +5 -5
  81. package/executor/v2/ViewFunctionExecutorV2.d.ts +2 -3
  82. package/executor/validation-helpers.d.ts +36 -0
  83. package/executor/validation-helpers.js +174 -0
  84. package/extrinsic/extensions/SignedExtension.d.ts +1 -1
  85. package/extrinsic/submittable/BaseSubmittableExtrinsic.d.ts +7 -3
  86. package/extrinsic/submittable/BaseSubmittableExtrinsic.js +64 -3
  87. package/extrinsic/submittable/SubmittableExtrinsic.d.ts +4 -1
  88. package/extrinsic/submittable/SubmittableExtrinsic.js +39 -17
  89. package/extrinsic/submittable/SubmittableExtrinsicV2.d.ts +6 -3
  90. package/extrinsic/submittable/SubmittableExtrinsicV2.js +13 -3
  91. package/json-rpc/JsonRpcClient.d.ts +6 -6
  92. package/json-rpc/group/Archive.d.ts +1 -1
  93. package/json-rpc/group/ChainHead/ChainHead.d.ts +18 -2
  94. package/json-rpc/group/ChainHead/ChainHead.js +226 -21
  95. package/json-rpc/group/ChainSpec.d.ts +3 -3
  96. package/json-rpc/group/Transaction.d.ts +1 -1
  97. package/json-rpc/group/TransactionWatch.d.ts +1 -1
  98. package/package.json +9 -9
  99. package/proxychain.d.ts +3 -4
  100. package/storage/NewStorageQuery.d.ts +3 -3
  101. package/storage/QueryableStorage.js +1 -0
  102. package/types.d.ts +94 -6
@@ -28,7 +28,13 @@ class StorageQueryExecutorV2 extends StorageQueryExecutor_js_1.StorageQueryExecu
28
28
  entry.decodeValue(value),
29
29
  ]);
30
30
  };
31
- return { entries };
31
+ const pagedKeys = () => {
32
+ throw new utils_1.DedotError('The pagedKeys method is not yet available via the new JSON-RPC (v2) specification. Please use the legacy client instead.');
33
+ };
34
+ const pagedEntries = () => {
35
+ throw new utils_1.DedotError('The pagedEntries method is not yet available via the new JSON-RPC (v2) specification. Please use the legacy client instead.');
36
+ };
37
+ return { entries, pagedKeys, pagedEntries };
32
38
  }
33
39
  getStorageQuery() {
34
40
  // @ts-ignore little trick to make querying data client.at instance works here,
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildCompatibilityError = exports.padArgsForOptionalParams = exports.isOptionalParam = exports.isOptionCodec = void 0;
4
+ const utils_1 = require("@dedot/utils");
5
+ /**
6
+ * Check if a codec is an Option type
7
+ */
8
+ function isOptionCodec(codec) {
9
+ try {
10
+ const metadata = codec?.metadata?.[0];
11
+ return metadata?.name === '$.option';
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ }
17
+ exports.isOptionCodec = isOptionCodec;
18
+ /**
19
+ * Check if a parameter is optional (wrapped in Option)
20
+ */
21
+ function isOptionalParam(param, registry) {
22
+ // Check direct codec first
23
+ if (param.codec) {
24
+ return isOptionCodec(param.codec);
25
+ }
26
+ // Check via typeId using registry
27
+ if ((0, utils_1.isNumber)(param.typeId)) {
28
+ try {
29
+ const type = registry.findType(param.typeId);
30
+ return type.typeDef.type === 'Enum' && type.path.join('::') === 'Option';
31
+ }
32
+ catch {
33
+ // ignore
34
+ }
35
+ }
36
+ return false;
37
+ }
38
+ exports.isOptionalParam = isOptionalParam;
39
+ /**
40
+ * Pad args array with undefined for missing trailing optional parameters.
41
+ * This allows users to omit optional parameters at the end of the parameter list.
42
+ */
43
+ function padArgsForOptionalParams(args, params, registry) {
44
+ // If args already match params length, no padding needed
45
+ if (args.length === params.length) {
46
+ return args;
47
+ }
48
+ // If more args than params, validation will fail later
49
+ if (args.length > params.length) {
50
+ return args;
51
+ }
52
+ // Check that all missing parameters are optional
53
+ for (let i = args.length; i < params.length; i++) {
54
+ const param = params[i];
55
+ if (!isOptionalParam(param, registry)) {
56
+ // Required parameter is missing, let the validation fail naturally
57
+ return args;
58
+ }
59
+ }
60
+ // All missing parameters are optional, pad with undefined
61
+ return [...args, ...Array(params.length - args.length).fill(undefined)];
62
+ }
63
+ exports.padArgsForOptionalParams = padArgsForOptionalParams;
64
+ /**
65
+ * Format a value for display in error messages
66
+ * Stringifies and truncates to 20 characters max
67
+ */
68
+ function formatValue(value) {
69
+ try {
70
+ let str;
71
+ if (typeof value === 'string') {
72
+ str = JSON.stringify(value);
73
+ }
74
+ else if (typeof value === 'undefined') {
75
+ str = 'undefined';
76
+ }
77
+ else if (value === null) {
78
+ str = 'null';
79
+ }
80
+ else if (typeof value === 'bigint') {
81
+ str = `${value}n`;
82
+ }
83
+ else if (typeof value === 'object') {
84
+ // For objects/arrays, use JSON.stringify
85
+ str = JSON.stringify(value);
86
+ }
87
+ else {
88
+ str = String(value);
89
+ }
90
+ // Truncate to 20 characters
91
+ if (str.length > 20) {
92
+ return str.slice(0, 20) + '...';
93
+ }
94
+ return str;
95
+ }
96
+ catch {
97
+ return '[complex value]';
98
+ }
99
+ }
100
+ /**
101
+ * Build a comprehensive API compatibility error with detailed information
102
+ */
103
+ function buildCompatibilityError(originalError, params, args, context) {
104
+ const lines = [];
105
+ // Header
106
+ if (context.itemIndex !== undefined) {
107
+ lines.push(`API Compatibility Error: ${context.apiName} (item ${context.itemIndex})`);
108
+ }
109
+ else {
110
+ lines.push(`API Compatibility Error: ${context.apiName}`);
111
+ }
112
+ lines.push('');
113
+ // Check parameter count mismatch
114
+ if (args.length !== params.length) {
115
+ lines.push(`Expected ${params.length} parameter${params.length !== 1 ? 's' : ''} but received ${args.length}`);
116
+ lines.push('');
117
+ }
118
+ // Validate each parameter and report errors
119
+ const paramErrors = [];
120
+ const maxParams = Math.max(args.length, params.length);
121
+ for (let i = 0; i < maxParams; i++) {
122
+ const param = params[i];
123
+ const value = args[i];
124
+ if (!param) {
125
+ // Extra argument provided
126
+ paramErrors.push(` [${i}] (unexpected) - value: ${formatValue(value)}`);
127
+ continue;
128
+ }
129
+ if (value === undefined && i >= args.length) {
130
+ // Missing argument - check if it's actually optional
131
+ const isOptional = isOptionalParam(param, context.registry);
132
+ if (isOptional) {
133
+ paramErrors.push(` [${i}] ${param.name}: omitted (optional)`);
134
+ }
135
+ else {
136
+ paramErrors.push(` [${i}] ${param.name}: ✗ required parameter missing - value: undefined`);
137
+ }
138
+ continue;
139
+ }
140
+ // Try to validate the parameter
141
+ try {
142
+ const $codec = findCodec(param, context.registry);
143
+ if ($codec) {
144
+ $codec.assert?.(value);
145
+ // Valid parameter
146
+ paramErrors.push(` [${i}] ${param.name}: ✓ valid`);
147
+ }
148
+ }
149
+ catch (error) {
150
+ // Invalid parameter
151
+ paramErrors.push(` [${i}] ${param.name}: ✗ invalid input type - value: ${formatValue(value)}`);
152
+ }
153
+ }
154
+ if (paramErrors.length > 0) {
155
+ lines.push('Parameters:');
156
+ lines.push(...paramErrors);
157
+ lines.push('');
158
+ }
159
+ // Add suggestion
160
+ lines.push('This may indicate your chaintypes definitions are outdated.');
161
+ lines.push('Consider regenerating chaintypes with:');
162
+ lines.push(' npx dedot chaintypes -w <your-chain-endpoint>');
163
+ return new utils_1.ApiCompatibilityError(lines.join('\n'));
164
+ }
165
+ exports.buildCompatibilityError = buildCompatibilityError;
166
+ /**
167
+ * Find codec for a parameter (internal helper)
168
+ */
169
+ function findCodec(param, registry) {
170
+ if (param.codec)
171
+ return param.codec;
172
+ if ((0, utils_1.isNumber)(param.typeId)) {
173
+ try {
174
+ return registry.findCodec(param.typeId);
175
+ }
176
+ catch {
177
+ // ignore
178
+ }
179
+ }
180
+ return undefined;
181
+ }
@@ -1,8 +1,33 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.BaseSubmittableExtrinsic = void 0;
4
27
  const codecs_1 = require("@dedot/codecs");
28
+ const $ = __importStar(require("@dedot/shape"));
5
29
  const utils_1 = require("@dedot/utils");
30
+ const validation_helpers_js_1 = require("../../executor/validation-helpers.js");
6
31
  const index_js_1 = require("../extensions/index.js");
7
32
  const fakeSigner_js_1 = require("./fakeSigner.js");
8
33
  const utils_js_1 = require("./utils.js");
@@ -10,8 +35,8 @@ class BaseSubmittableExtrinsic extends codecs_1.Extrinsic {
10
35
  client;
11
36
  #alterTx;
12
37
  #hooks;
13
- constructor(client, call) {
14
- super(client.registry, call);
38
+ constructor(client, call, preamble) {
39
+ super(client.registry, call, preamble);
15
40
  this.client = client;
16
41
  }
17
42
  withHooks(hooks) {
@@ -118,10 +143,69 @@ class BaseSubmittableExtrinsic extends codecs_1.Extrinsic {
118
143
  const atApi = (await this.client.at(hash));
119
144
  return await atApi.query.system.events();
120
145
  }
146
+ /**
147
+ * Override callU8a to add transaction parameter validation before encoding
148
+ */
149
+ get callU8a() {
150
+ // Validate transaction parameters first
151
+ this.#validateTxParams();
152
+ // Then call parent implementation which does $RuntimeCall.assert and encoding
153
+ return super.callU8a;
154
+ }
155
+ /**
156
+ * Validate transaction parameters against their type definitions
157
+ * @private
158
+ */
159
+ #validateTxParams() {
160
+ // Skip if palletCall is a string (flat enum, no params)
161
+ if (typeof this.call.palletCall === 'string')
162
+ return;
163
+ if (!this.call.palletCall?.name)
164
+ return;
165
+ // 1. Find pallet metadata
166
+ const palletName = this.call.pallet;
167
+ const pallet = this.registry.metadata.pallets.find((p) => (0, utils_1.stringCamelCase)(p.name) === (0, utils_1.stringCamelCase)(palletName));
168
+ if (!pallet?.calls)
169
+ return;
170
+ // 2. Get calls enum type definition
171
+ const callsType = this.registry.metadata.types[pallet.calls.typeId];
172
+ if (callsType.typeDef.type !== 'Enum')
173
+ return;
174
+ // 3. Find specific call definition
175
+ const callName = this.call.palletCall.name;
176
+ const callDef = callsType.typeDef.value.members.find((m) => (0, utils_1.stringCamelCase)(m.name) === (0, utils_1.stringCamelCase)(callName));
177
+ if (!callDef)
178
+ return;
179
+ // 4. Build param specs from field definitions
180
+ const paramSpecs = callDef.fields.map((f) => ({
181
+ name: (0, utils_1.stringCamelCase)(f.name || ''),
182
+ typeId: f.typeId,
183
+ }));
184
+ // 5. Extract args in field order from params object
185
+ const params = this.call.palletCall.params || {};
186
+ const args = paramSpecs.map((spec) => params[spec.name]);
187
+ // 6. Validate with tuple codec
188
+ const $ParamsTuple = $.Tuple(...paramSpecs.map((spec) => this.registry.findCodec(spec.typeId)));
189
+ try {
190
+ $ParamsTuple.assert?.(args);
191
+ }
192
+ catch (error) {
193
+ if (error instanceof $.ShapeAssertError) {
194
+ throw (0, validation_helpers_js_1.buildCompatibilityError)(error, // --
195
+ paramSpecs, args, {
196
+ apiName: `${(0, utils_1.stringCamelCase)(pallet.name)}.${(0, utils_1.stringCamelCase)(callDef.name)}`,
197
+ registry: this.registry,
198
+ });
199
+ }
200
+ throw error;
201
+ }
202
+ }
121
203
  toU8a() {
122
204
  if (this.#alterTx) {
123
205
  return (0, utils_1.hexToU8a)(this.#alterTx);
124
206
  }
207
+ // Validate transaction parameters before encoding
208
+ this.#validateTxParams();
125
209
  return super.toU8a();
126
210
  }
127
211
  toHex() {
@@ -10,6 +10,16 @@ const utils_js_1 = require("./utils.js");
10
10
  * @description A wrapper around an Extrinsic that exposes methods to sign, send, and other utility around Extrinsic.
11
11
  */
12
12
  class SubmittableExtrinsic extends BaseSubmittableExtrinsic_js_1.BaseSubmittableExtrinsic {
13
+ static fromTx(client, tx) {
14
+ let extrinsic;
15
+ if ((0, utils_1.isHex)(tx)) {
16
+ extrinsic = client.registry.$Extrinsic.tryDecode(tx);
17
+ }
18
+ else {
19
+ extrinsic = tx;
20
+ }
21
+ return new SubmittableExtrinsic(client, extrinsic.call, extrinsic.preamble);
22
+ }
13
23
  async dryRun(account, optionsOrHash) {
14
24
  const dryRunFn = this.client.rpc.system_dryRun;
15
25
  if ((0, utils_1.isHex)(optionsOrHash)) {
@@ -23,7 +33,11 @@ class SubmittableExtrinsic extends BaseSubmittableExtrinsic_js_1.BaseSubmittable
23
33
  const txHex = this.toHex();
24
34
  const txHash = this.hash;
25
35
  const { deferTx, onTxProgress } = (0, utils_js_1.txDefer)();
26
- const unsub = this.client.rpc.author_submitAndWatchExtrinsic(txHex, async (txStatus) => {
36
+ let unsub;
37
+ this.client.rpc
38
+ .author_submitAndWatchExtrinsic(txHex, async (txStatus) => {
39
+ let status;
40
+ let result;
27
41
  if (txStatus.type === 'InBlock' || txStatus.type === 'Finalized') {
28
42
  const blockHash = txStatus.value;
29
43
  const [signedBlock, blockEvents] = await Promise.all([
@@ -34,25 +48,33 @@ class SubmittableExtrinsic extends BaseSubmittableExtrinsic_js_1.BaseSubmittable
34
48
  (0, utils_1.assert)(txIndex >= 0, 'Extrinsic not found!');
35
49
  const events = blockEvents.filter(({ phase }) => phase.type === 'ApplyExtrinsic' && phase.value === txIndex);
36
50
  const blockNumber = signedBlock.block.header.number;
37
- const status = (0, utils_js_1.toTxStatus)(txStatus, { txIndex, blockNumber });
38
- const result = this.transformTxResult(new SubmittableResult_js_1.SubmittableResult({ status, txHash, events, txIndex }));
39
- onTxProgress(result);
40
- !isSubscription && deferTx.resolve(txHash);
41
- return callback?.(result);
51
+ status = (0, utils_js_1.toTxStatus)(txStatus, { txIndex, blockNumber });
52
+ result = this.transformTxResult(new SubmittableResult_js_1.SubmittableResult({ status, txHash, events, txIndex }));
42
53
  }
43
54
  else {
44
- const status = (0, utils_js_1.toTxStatus)(txStatus);
45
- const result = this.transformTxResult(new SubmittableResult_js_1.SubmittableResult({ status, txHash }));
46
- onTxProgress(result);
47
- !isSubscription && deferTx.resolve(txHash);
48
- return callback?.(result);
55
+ status = (0, utils_js_1.toTxStatus)(txStatus);
56
+ result = this.transformTxResult(new SubmittableResult_js_1.SubmittableResult({ status, txHash }));
49
57
  }
50
- });
51
- if (isSubscription) {
52
- unsub.then((x) => {
58
+ onTxProgress(result);
59
+ if (isSubscription) {
60
+ callback?.(result);
61
+ }
62
+ else {
63
+ deferTx.resolve(txHash);
64
+ }
65
+ if (status.type === 'Finalized' || // --
66
+ status.type === 'Invalid' ||
67
+ status.type === 'Drop') {
68
+ unsub?.().catch(utils_1.noop);
69
+ }
70
+ })
71
+ .then((x) => {
72
+ unsub = x;
73
+ if (isSubscription) {
53
74
  deferTx.resolve(x);
54
- });
55
- }
75
+ }
76
+ })
77
+ .catch(deferTx.reject);
56
78
  return deferTx.promise;
57
79
  }
58
80
  }
@@ -12,10 +12,20 @@ const utils_js_1 = require("./utils.js");
12
12
  */
13
13
  class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittableExtrinsic {
14
14
  client;
15
- constructor(client, call) {
16
- super(client, call);
15
+ constructor(client, call, preamble) {
16
+ super(client, call, preamble);
17
17
  this.client = client;
18
18
  }
19
+ static fromTx(client, tx) {
20
+ let extrinsic;
21
+ if ((0, utils_1.isHex)(tx)) {
22
+ extrinsic = client.registry.$Extrinsic.tryDecode(tx);
23
+ }
24
+ else {
25
+ extrinsic = tx;
26
+ }
27
+ return new SubmittableExtrinsicV2(client, extrinsic.call, extrinsic.preamble);
28
+ }
19
29
  async #send(callback) {
20
30
  const api = this.client;
21
31
  const txHex = this.toHex();