@talismn/sapi 1.0.0 → 2.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.
package/dist/index.js CHANGED
@@ -1,743 +1,628 @@
1
- "use strict";
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
7
  var __getProtoOf = Object.getPrototypeOf;
7
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
9
  var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- MAX_SUPPORTED_METADATA_VERSION: () => MAX_SUPPORTED_METADATA_VERSION,
34
- fetchBestMetadata: () => fetchBestMetadata,
35
- getScaleApi: () => getScaleApi
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let _polkadot_api_tx_utils = require("@polkadot-api/tx-utils");
25
+ let _polkadot_api_substrate_bindings = require("@polkadot-api/substrate-bindings");
26
+ let _polkadot_api_utils = require("@polkadot-api/utils");
27
+ let scale_ts = require("scale-ts");
28
+ let _talismn_scale = require("@talismn/scale");
29
+ let anylogger = require("anylogger");
30
+ anylogger = __toESM(anylogger);
31
+ let _polkadot_api_metadata_builders = require("@polkadot-api/metadata-builders");
32
+ let _polkadot_api_signers_common = require("@polkadot-api/signers-common");
33
+ let _polkadot_api_merkleize_metadata = require("@polkadot-api/merkleize-metadata");
34
+ //#region src/customSignedExtensions.ts
35
+ const EMPTY = /* @__PURE__ */ new Uint8Array();
36
+ /**
37
+ * Encoders for chain-specific signed extensions that `@polkadot-api/tx-utils` doesn't know about.
38
+ */
39
+ const CUSTOM_SIGNED_EXTENSIONS = { CheckAppId: ({ pjsPayload }) => {
40
+ const appId = Number(pjsPayload.appId ?? 0);
41
+ return {
42
+ value: _polkadot_api_substrate_bindings.compactNumber.enc(Number.isFinite(appId) ? appId : 0),
43
+ additionalSigned: EMPTY
44
+ };
45
+ } };
46
+ //#endregion
47
+ //#region src/fetchBestMetadata.ts
48
+ const MAGIC_NUMBER = 1635018093;
49
+ const MAX_SUPPORTED_METADATA_VERSION = 15;
50
+ /**
51
+ * Fetches the highest supported version of metadata from the chain.
52
+ *
53
+ * @param rpcSend
54
+ * @returns hex-encoded metadata starting with the magic number
55
+ */
56
+ const fetchBestMetadata = async (rpcSend, allowLegacyFallback) => {
57
+ try {
58
+ const metadataVersions = await rpcSend("state_call", ["Metadata_metadata_versions", "0x"], true);
59
+ const availableVersions = (0, scale_ts.Vector)(scale_ts.u32).dec(metadataVersions);
60
+ const bestVersion = Math.max(...availableVersions.filter((v) => v <= 15));
61
+ const metadata = await rpcSend("state_call", ["Metadata_metadata_at_version", (0, _polkadot_api_utils.toHex)(scale_ts.u32.enc(bestVersion))], true);
62
+ return normalizeMetadata(metadata);
63
+ } catch (cause) {
64
+ const message = cause?.message;
65
+ if (allowLegacyFallback || message?.includes("is not found") || message?.includes("Module doesn't have export Metadata_metadata_versions") || message?.includes("Exported method Metadata_metadata_versions is not found") || message?.includes("Execution, MethodNotFound, Metadata_metadata_versions")) return await rpcSend("state_getMetadata", [], true);
66
+ throw new Error("Failed to fetch metadata", { cause });
67
+ }
68
+ };
69
+ /**
70
+ * Removes everything before the magic number in the metadata.
71
+ * This ensures Opaque metadata is usable by pjs
72
+ */
73
+ const normalizeMetadata = (metadata) => {
74
+ const hexMagicNumber = (0, _polkadot_api_utils.toHex)(scale_ts.u32.enc(MAGIC_NUMBER)).slice(2);
75
+ const magicNumberIndex = metadata.indexOf(hexMagicNumber);
76
+ if (magicNumberIndex === -1) throw new Error("Invalid metadata format: magic number not found");
77
+ return `0x${metadata.slice(magicNumberIndex)}`;
78
+ };
79
+ //#endregion
80
+ //#region src/helpers/papi.ts
81
+ const toPjsHex = (value, minByteLen) => {
82
+ let inner = value.toString(16);
83
+ inner = (inner.length % 2 ? "0" : "") + inner;
84
+ const nPaddedBytes = Math.max(0, (minByteLen || 0) - inner.length / 2);
85
+ return `0x${"00".repeat(nPaddedBytes)}${inner}`;
86
+ };
87
+ const mortal = (0, _polkadot_api_substrate_bindings.enhanceEncoder)((0, _polkadot_api_substrate_bindings.Bytes)(2).enc, (value) => {
88
+ const factor = Math.max(value.period >> 12, 1);
89
+ const left = Math.min(Math.max(trailingZeroes(value.period) - 1, 1), 15);
90
+ const right = value.phase / factor << 4;
91
+ return _polkadot_api_substrate_bindings.u16.enc(left | right);
36
92
  });
37
- module.exports = __toCommonJS(index_exports);
38
-
39
- // src/fetchBestMetadata.ts
40
- var import_utils = require("@polkadot-api/utils");
41
- var import_scale_ts = require("scale-ts");
42
- var MAGIC_NUMBER = 1635018093;
43
- var MAX_SUPPORTED_METADATA_VERSION = 15;
44
- var fetchBestMetadata = async (rpcSend, allowLegacyFallback) => {
45
- try {
46
- const metadataVersions = await rpcSend(
47
- "state_call",
48
- ["Metadata_metadata_versions", "0x"],
49
- true
50
- );
51
- const availableVersions = (0, import_scale_ts.Vector)(import_scale_ts.u32).dec(metadataVersions);
52
- const bestVersion = Math.max(
53
- ...availableVersions.filter((v) => v <= MAX_SUPPORTED_METADATA_VERSION)
54
- );
55
- const metadata = await rpcSend(
56
- "state_call",
57
- ["Metadata_metadata_at_version", (0, import_utils.toHex)(import_scale_ts.u32.enc(bestVersion))],
58
- true
59
- );
60
- return normalizeMetadata(metadata);
61
- } catch (cause) {
62
- const message = cause?.message;
63
- if (allowLegacyFallback || message?.includes("is not found") || // ex: crust standalone
64
- message?.includes("Module doesn't have export Metadata_metadata_versions") || // ex: 3DPass
65
- message?.includes("Exported method Metadata_metadata_versions is not found") || // ex: sora-polkadot & sora-standalone
66
- message?.includes("Execution, MethodNotFound, Metadata_metadata_versions")) {
67
- return await rpcSend("state_getMetadata", [], true);
68
- }
69
- throw new Error("Failed to fetch metadata", { cause });
70
- }
71
- };
72
- var normalizeMetadata = (metadata) => {
73
- const hexMagicNumber = (0, import_utils.toHex)(import_scale_ts.u32.enc(MAGIC_NUMBER)).slice(2);
74
- const magicNumberIndex = metadata.indexOf(hexMagicNumber);
75
- if (magicNumberIndex === -1) throw new Error("Invalid metadata format: magic number not found");
76
- return `0x${metadata.slice(magicNumberIndex)}`;
77
- };
78
-
79
- // src/sapi.ts
80
- var import_scale2 = require("@talismn/scale");
81
-
82
- // src/log.ts
83
- var import_anylogger = __toESM(require("anylogger"));
84
-
85
- // package.json
86
- var package_default = {
87
- name: "@talismn/sapi",
88
- version: "1.0.0",
89
- author: "Talisman",
90
- homepage: "https://talisman.xyz",
91
- license: "GPL-3.0-or-later",
92
- publishConfig: {
93
- access: "public"
94
- },
95
- repository: {
96
- directory: "packages/sapi",
97
- type: "git",
98
- url: "https://github.com/TalismanSociety/talisman.git"
99
- },
100
- main: "./dist/index.js",
101
- module: "./dist/index.mjs",
102
- files: [
103
- "dist"
104
- ],
105
- engines: {
106
- node: ">=20"
107
- },
108
- scripts: {
109
- test: "vitest run",
110
- clean: "rm -rf dist .turbo node_modules",
111
- build: "tsup --silent",
112
- typecheck: "tsc --noEmit"
113
- },
114
- dependencies: {
115
- "@polkadot-api/merkleize-metadata": "1.2.3",
116
- "@polkadot-api/metadata-builders": "0.14.3",
117
- "@polkadot-api/substrate-bindings": "0.20.3",
118
- "@polkadot-api/utils": "0.4.0",
119
- "@polkadot/types": "16.5.6",
120
- "@polkadot/types-codec": "16.5.6",
121
- "@talismn/scale": "workspace:*",
122
- anylogger: "^1.0.11",
123
- "polkadot-api": "2.1.6",
124
- "scale-ts": "^1.6.1"
125
- },
126
- devDependencies: {
127
- "@talismn/tsconfig": "workspace:*",
128
- typescript: "^6.0.3"
129
- },
130
- types: "./dist/index.d.ts",
131
- exports: {
132
- ".": {
133
- "@talismn/source": "./src/index.ts",
134
- import: {
135
- types: "./dist/index.d.mts",
136
- default: "./dist/index.mjs"
137
- },
138
- require: {
139
- types: "./dist/index.d.ts",
140
- default: "./dist/index.js"
141
- }
142
- }
143
- }
144
- };
145
-
146
- // src/log.ts
147
- var log_default = (0, import_anylogger.default)(package_default.name);
148
-
149
- // src/helpers/getCallDocs.ts
150
- var getCallDocs = (chain, pallet, method) => {
151
- try {
152
- const typeIdCalls = chain.metadata.pallets.find(({ name }) => name === pallet)?.calls?.type;
153
- if (!typeIdCalls) return null;
154
- let palletCalls = chain.metadata.lookup[typeIdCalls];
155
- if (!palletCalls || palletCalls.id !== typeIdCalls)
156
- palletCalls = chain.metadata.lookup.find((v) => v.id === typeIdCalls);
157
- if (!palletCalls) return null;
158
- const call = palletCalls.def.value.find(
159
- (c) => c.name === method
160
- );
161
- return call?.docs?.join("\n") ?? null;
162
- } catch {
163
- log_default.error("Failed to find call docs", { pallet, method, chain });
164
- return null;
165
- }
166
- };
167
-
168
- // src/helpers/getConstantValue.ts
169
- var import_scale = require("@talismn/scale");
170
- var getConstantValue = (chain, pallet, constant) => {
171
- return (0, import_scale.getConstantValueFromMetadata)(
172
- {
173
- builder: chain.builder,
174
- unifiedMetadata: chain.metadata
175
- },
176
- pallet,
177
- constant
178
- );
179
- };
180
-
181
- // src/helpers/getChainInfo.ts
182
- var getChainInfo = (chain) => {
183
- const {
184
- spec_name: specName,
185
- spec_version: specVersion,
186
- transaction_version: transactionVersion
187
- } = getConstantValue(chain, "System", "Version");
188
- const base58Prefix = getConstantValue(chain, "System", "SS58Prefix");
189
- return {
190
- specName,
191
- specVersion,
192
- transactionVersion,
193
- base58Prefix
194
- };
195
- };
196
-
197
- // src/helpers/getDecodedCall.ts
198
- var getDecodedCall = (palletName, methodName, args) => ({
199
- type: palletName,
200
- value: { type: methodName, value: args }
93
+ function trailingZeroes(n) {
94
+ let i = 0;
95
+ while (!(n & 1)) {
96
+ i++;
97
+ n >>= 1;
98
+ }
99
+ return i;
100
+ }
101
+ const isEthereumAddress = (address) => /^0x[0-9a-fA-F]{40}$/.test(address);
102
+ /** decodes an ss58 or ethereum address into its raw account bytes */
103
+ const getAddressBytes = (address) => {
104
+ if (isEthereumAddress(address)) return (0, _polkadot_api_utils.fromHex)(address);
105
+ const info = (0, _polkadot_api_substrate_bindings.getSs58AddressInfo)(address);
106
+ if (!info.isValid) throw new Error(`Invalid address: ${address}`);
107
+ return info.publicKey;
108
+ };
109
+ //#endregion
110
+ //#region src/log.ts
111
+ var log_default = (0, anylogger.default)("@talismn/sapi");
112
+ //#endregion
113
+ //#region src/helpers/getCallDocs.ts
114
+ const getCallDocs = (chain, pallet, method) => {
115
+ try {
116
+ const typeIdCalls = chain.metadata.pallets.find(({ name }) => name === pallet)?.calls?.type;
117
+ if (!typeIdCalls) return null;
118
+ let palletCalls = chain.metadata.lookup[typeIdCalls];
119
+ if (!palletCalls || palletCalls.id !== typeIdCalls) palletCalls = chain.metadata.lookup.find((v) => v.id === typeIdCalls);
120
+ if (!palletCalls) return null;
121
+ return palletCalls.def.value.find((c) => c.name === method)?.docs?.join("\n") ?? null;
122
+ } catch {
123
+ log_default.error("Failed to find call docs", {
124
+ pallet,
125
+ method,
126
+ chain
127
+ });
128
+ return null;
129
+ }
130
+ };
131
+ //#endregion
132
+ //#region src/helpers/getConstantValue.ts
133
+ const getConstantValue = (chain, pallet, constant) => {
134
+ return (0, _talismn_scale.getConstantValueFromMetadata)({
135
+ builder: chain.builder,
136
+ unifiedMetadata: chain.metadata
137
+ }, pallet, constant);
138
+ };
139
+ //#endregion
140
+ //#region src/helpers/getChainInfo.ts
141
+ const getChainInfo = (chain) => {
142
+ const { spec_name: specName, spec_version: specVersion, transaction_version: transactionVersion } = getConstantValue(chain, "System", "Version");
143
+ return {
144
+ specName,
145
+ specVersion,
146
+ transactionVersion,
147
+ base58Prefix: getConstantValue(chain, "System", "SS58Prefix")
148
+ };
149
+ };
150
+ //#endregion
151
+ //#region src/helpers/getDecodedCall.ts
152
+ const getDecodedCall = (palletName, methodName, args) => ({
153
+ type: palletName,
154
+ value: {
155
+ type: methodName,
156
+ value: args
157
+ }
201
158
  });
202
- var getDecodedCallFromPayload = (chain, payload) => {
203
- const def = chain.builder.buildDefinition(chain.lookup.call);
204
- const decoded = def.dec(payload.method);
205
- return {
206
- pallet: decoded.type,
207
- method: decoded.value.type,
208
- args: decoded.value.value
209
- };
210
- };
211
-
212
- // src/helpers/getDecodedCallFromExtrinsic.ts
213
- var import_substrate_bindings = require("@polkadot-api/substrate-bindings");
214
- var allBytesDec = (0, import_substrate_bindings.Bytes)(Infinity).dec;
215
- var getDecodedCallFromExtrinsic = (chain, extrinsicHex) => {
216
- try {
217
- const { metadata, builder } = chain;
218
- const extensionsArray = metadata.extrinsic.signedExtensions[0] ?? [];
219
- const extraDec = import_substrate_bindings.Struct.dec(
220
- Object.fromEntries(
221
- extensionsArray.map((x) => [x.identifier, builder.buildDefinition(x.type)[1]])
222
- )
223
- );
224
- let callDec;
225
- const { extrinsic } = metadata;
226
- if ("address" in extrinsic) {
227
- callDec = builder.buildDefinition(extrinsic.call)[1];
228
- } else {
229
- const params = metadata.lookup[extrinsic.type]?.params;
230
- const callType = params?.find((v) => v.name === "Call")?.type;
231
- if (callType == null) throw new Error("Call type not found in metadata");
232
- callDec = builder.buildDefinition(callType)[1];
233
- }
234
- let addressDec;
235
- let signatureDec;
236
- if ("address" in extrinsic) {
237
- addressDec = builder.buildDefinition(extrinsic.address)[1];
238
- signatureDec = builder.buildDefinition(extrinsic.signature)[1];
239
- } else {
240
- const params = metadata.lookup[extrinsic.type]?.params;
241
- const addrType = params?.find((v) => v.name === "Address")?.type;
242
- const sigType = params?.find((v) => v.name === "Signature")?.type;
243
- if (addrType == null || sigType == null)
244
- throw new Error("Address or Signature type not found");
245
- addressDec = builder.buildDefinition(addrType)[1];
246
- signatureDec = builder.buildDefinition(sigType)[1];
247
- }
248
- const v4Body = import_substrate_bindings.Struct.dec({
249
- address: addressDec,
250
- signature: signatureDec,
251
- extra: extraDec,
252
- callData: allBytesDec
253
- });
254
- const extrinsicDecoder = (0, import_substrate_bindings.enhanceDecoder)(
255
- (0, import_substrate_bindings.createDecoder)((data) => {
256
- const len = import_substrate_bindings.compactNumber.dec(data);
257
- const { type, version } = import_substrate_bindings.extrinsicFormat[1](data);
258
- if (type === "bare") {
259
- return { len, version, type, callData: allBytesDec(data) };
260
- }
261
- if (type === "signed") {
262
- return { len, version, type, ...v4Body(data) };
263
- }
264
- const extensionVersion = import_substrate_bindings.u8.dec(data);
265
- const extra = extraDec(data);
266
- return {
267
- len,
268
- type,
269
- version,
270
- extensionVersion,
271
- extra,
272
- callData: allBytesDec(data)
273
- };
274
- }),
275
- (v) => ({
276
- ...v,
277
- call: callDec(v.callData)
278
- })
279
- );
280
- const decoded = extrinsicDecoder(extrinsicHex);
281
- return {
282
- pallet: decoded.call.type,
283
- method: decoded.call.value.type,
284
- args: decoded.call.value.value
285
- };
286
- } catch (err) {
287
- console.error("[SAPI] Failed to decode extrinsic:", err);
288
- return null;
289
- }
290
- };
291
-
292
- // src/helpers/getDryRunCall.ts
293
- var import_polkadot_api = require("polkadot-api");
294
-
295
- // src/helpers/errors.ts
296
- var import_metadata_builders = require("@polkadot-api/metadata-builders");
297
- var getDispatchErrorMessage = (chain, err) => {
298
- try {
299
- if (!err) return null;
300
- const error = err;
301
- if (!error.type) throw new Error("Unknown dispatch error");
302
- const lv1 = DISPATCH_ERROR[error.type];
303
- if (!lv1) throw new Error("Unknown dispatch error");
304
- if (lv1 === ERROR_METADATA_LOOKUP)
305
- return getModuleErrorMessage(chain, error.value);
306
- if (typeof lv1 === "string") return lv1;
307
- const lv2 = lv1[error.value?.type];
308
- if (!lv2) throw new Error("Unknown dispatch error");
309
- if (typeof lv2 === "string") return lv2;
310
- throw new Error("Unknown dispatch error");
311
- } catch (cause) {
312
- log_default.error("Failed to parse runtime error", { chainId: chain.connector.chainId, cause, err });
313
- return tryFormatError(err);
314
- }
315
- };
316
- var ERROR_METADATA_LOOKUP = "METADATA_LOOKUP";
317
- var ERRORS_TRANSACTIONAL = {
318
- LimitReached: "Too many transactional layers have been spawned",
319
- NoLayer: "A transactional layer was expected, but does not exist"
320
- };
321
- var ERRORS_TOKEN = {
322
- FundsUnavailable: "Funds are unavailable",
323
- OnlyProvider: "Account that must exist would die",
324
- BelowMinimum: "Account cannot exist with the funds that would be given",
325
- CannotCreate: "Account cannot be created",
326
- UnknownAsset: "The asset in question is unknown",
327
- Frozen: "Funds exist but are frozen",
328
- Unsupported: "Operation is not supported by the asset",
329
- CannotCreateHold: "Account cannot be created for recording amount on hold",
330
- NotExpendable: "Account that is desired to remain would die",
331
- Blocked: "Account cannot receive the assets"
332
- };
333
- var ERRORS_ARITHMETIC = {
334
- Overflow: "An underflow would occur",
335
- Underflow: "An overflow would occur",
336
- DivisionByZero: "Division by zero"
337
- };
338
- var DISPATCH_ERROR = {
339
- CannotLookup: "Cannot lookup",
340
- BadOrigin: "Bad origin",
341
- Module: ERROR_METADATA_LOOKUP,
342
- ConsumerRemaining: "Consumer remaining",
343
- NoProviders: "No providers",
344
- TooManyConsumers: "Too many consumers",
345
- Token: ERRORS_TOKEN,
346
- Arithmetic: ERRORS_ARITHMETIC,
347
- Transactional: ERRORS_TRANSACTIONAL,
348
- Exhausted: "Resources exhausted",
349
- Corruption: "State corrupt",
350
- Unavailable: "Resource unavailable",
351
- RootNotAllowed: "Root not allowed",
352
- Trie: "Unknown error",
353
- // unsupported,
354
- Other: "Unknown error"
355
- // unsupported,
356
- };
357
- var getModuleErrorMessage = (chain, error) => {
358
- try {
359
- if (!chain.metadata) throw new Error("Could not fetch metadata");
360
- const pallet = chain.metadata.pallets.find((p) => p.name === error.type);
361
- if (typeof pallet?.errors !== "number") throw new Error("Unknown pallet");
362
- const lookup = (0, import_metadata_builders.getLookupFn)(chain.metadata);
363
- const palletErrors = lookup(pallet.errors);
364
- if (palletErrors.type !== "enum" || !palletErrors.innerDocs[error.value.type]?.length)
365
- throw new Error("Unknown error type");
366
- return palletErrors.innerDocs[error.value.type].join(" ");
367
- } catch (err) {
368
- log_default.error("Failed to parse module error", { chainId: chain.connector.chainId, error, err });
369
- return [error.type, error.value.type].join(": ");
370
- }
371
- };
372
- var tryFormatError = (err) => {
373
- try {
374
- const unsafeErr = err;
375
- if (unsafeErr.type && unsafeErr.value?.type)
376
- return [unsafeErr.type, unsafeErr.value.type].join(": ");
377
- } catch {
378
- }
379
- return "Unknown error";
380
- };
381
-
382
- // src/helpers/getRuntimeCallResult.ts
383
- var import_utils2 = require("@polkadot-api/utils");
384
-
385
- // src/helpers/getSendRequestResult.ts
386
- var getSendRequestResult = (chain, method, params, isCacheable) => {
387
- return chain.connector.send(method, params, isCacheable);
388
- };
389
-
390
- // src/helpers/getRuntimeCallResult.ts
391
- var getRuntimeCallResult = async (chain, apiName, method, args) => {
392
- const call = chain.builder.buildRuntimeCall(apiName, method);
393
- const hex = await getSendRequestResult(chain, "state_call", [
394
- `${apiName}_${method}`,
395
- (0, import_utils2.toHex)(call.args.enc(args))
396
- ]);
397
- return call.value.dec(hex);
398
- };
399
-
400
- // src/helpers/isApiAvailable.ts
401
- var isApiAvailable = (chain, name, method) => {
402
- return chain.metadata.apis.some(
403
- (a) => a.name === name && a.methods.some((m) => m.name === method)
404
- );
405
- };
406
-
407
- // src/helpers/getDryRunCall.ts
408
- var getDryRunCall = async (chain, from, decodedCall) => {
409
- try {
410
- if (!isApiAvailable(chain, "DryRunApi", "dry_run_call"))
411
- return {
412
- available: false,
413
- data: null
414
- };
415
- const origin = (0, import_polkadot_api.Enum)("system", (0, import_polkadot_api.Enum)("Signed", from));
416
- const { pallet, method, args } = decodedCall;
417
- const call = { type: pallet, value: { type: method, value: args } };
418
- const data = await getRuntimeCallResult(chain, "DryRunApi", "dry_run_call", [
419
- origin,
420
- call
421
- ]);
422
- const ok = data.success && data.value.execution_result.success;
423
- const errorMessage = data.success && !data.value.execution_result.success ? getDispatchErrorMessage(chain, data.value.execution_result.value.error) : null;
424
- return {
425
- available: true,
426
- // NOTE: we can't re-export `@polkadot-api/descriptors` from this package.
427
- // So, the caller of this function must pass in their own instance of `type DryRunResult` as the generic argument `T`.
428
- data,
429
- ok,
430
- errorMessage
431
- };
432
- } catch (err) {
433
- log_default.error("Failed to dry run", { chainId: chain.connector.chainId, err });
434
- return {
435
- available: false,
436
- data: null
437
- };
438
- }
439
- };
440
-
441
- // src/helpers/getExtrinsicDispatchInfo.ts
442
- var import_utils3 = require("@polkadot-api/utils");
443
- var getExtrinsicDispatchInfo = async (chain, signedExtrinsic) => {
444
- if (!signedExtrinsic.isSigned)
445
- throw new Error("Extrinsic must be signed (or fakeSigned) in order to query fee");
446
- const len = signedExtrinsic.registry.createType("u32", signedExtrinsic.encodedLength);
447
- const dispatchInfo = await stateCall(
448
- chain.connector.send,
449
- "TransactionPaymentApi_query_info",
450
- "RuntimeDispatchInfo",
451
- [signedExtrinsic, len],
452
- void 0,
453
- true
454
- );
455
- return {
456
- partialFee: dispatchInfo.partialFee.toString()
457
- };
458
- };
459
- var stateCall = async (request, method, resultType, args, blockHash, isCacheable) => {
460
- const registry = args[0].registry;
461
- const bytes = registry.createType("Raw", (0, import_utils3.mergeUint8)(args.map((arg) => arg.toU8a())));
462
- const result = await request("state_call", [method, bytes.toHex(), blockHash], isCacheable);
463
- return registry.createType(resultType, result);
464
- };
465
-
466
- // src/helpers/getTypeRegistry.ts
467
- var import_types = require("@polkadot/types");
468
- var getTypeRegistry = (chain, payload) => {
469
- log_default.debug(`[sapi] getTypeRegistry for payload (${chain.token.symbol})`);
470
- const registry = new import_types.TypeRegistry();
471
- if (chain.registryTypes) registry.register(chain.registryTypes);
472
- const meta = new import_types.Metadata(registry, chain.hexMetadata);
473
- registry.setMetadata(meta, payload.signedExtensions, chain.signedExtensions);
474
- return registry;
475
- };
476
-
477
- // src/helpers/getFeeEstimate.ts
478
- var getFeeEstimate = async (chain, payload, chainInfo) => {
479
- const registry = getTypeRegistry(chain, payload);
480
- const extrinsic = registry.createType("Extrinsic", payload);
481
- extrinsic.signFake(payload.address, {
482
- appId: 0,
483
- nonce: payload.nonce,
484
- blockHash: payload.blockHash,
485
- genesisHash: payload.genesisHash,
486
- runtimeVersion: {
487
- specVersion: chainInfo.specVersion,
488
- transactionVersion: chainInfo.transactionVersion
489
- // other fields aren't necessary for signing
490
- }
491
- });
492
- const bytes = extrinsic.toU8a(true);
493
- try {
494
- const result = await getRuntimeCallResult(
495
- chain,
496
- "TransactionPaymentApi",
497
- "query_info",
498
- [bytes, bytes.length]
499
- );
500
- if (!result?.partial_fee && result.partial_fee !== 0n) {
501
- throw new Error("partialFee is not found");
502
- }
503
- return result.partial_fee;
504
- } catch (err) {
505
- log_default.error("Failed to get fee estimate using getRuntimeCallValue", { err });
506
- }
507
- const { partialFee } = await getExtrinsicDispatchInfo(chain, extrinsic);
508
- return BigInt(partialFee);
509
- };
510
-
511
- // src/helpers/getSapiConnector.ts
512
- var getSapiConnector = ({
513
- chainId,
514
- send,
515
- submit: submit2,
516
- submitWithBittensorMevShield
517
- }) => ({
518
- chainId,
519
- send,
520
- submit: (...args) => {
521
- if (submit2) return submit2(...args);
522
- throw new Error("submit handler not provided");
523
- },
524
- submitWithBittensorMevShield: (...args) => {
525
- if (submitWithBittensorMevShield) return submitWithBittensorMevShield(...args);
526
- throw new Error("submitWithBittensorMevShield handler not provided");
527
- }
159
+ const getDecodedCallFromPayload = (chain, payload) => {
160
+ const decoded = chain.builder.buildDefinition(chain.lookup.call).dec(payload.method);
161
+ return {
162
+ pallet: decoded.type,
163
+ method: decoded.value.type,
164
+ args: decoded.value.value
165
+ };
166
+ };
167
+ //#endregion
168
+ //#region src/helpers/getDecodedCallFromExtrinsic.ts
169
+ const allBytesDec = (0, _polkadot_api_substrate_bindings.Bytes)(Infinity).dec;
170
+ /**
171
+ * Decodes a signed extrinsic and extracts the call data.
172
+ * Handles different metadata versions (v14, v15, v16) and extrinsic formats.
173
+ *
174
+ * @param chain - The chain context with metadata and builder
175
+ * @param extrinsicHex - The hex-encoded extrinsic (with 0x prefix)
176
+ * @returns The decoded call with pallet, method, and args, or null if decoding fails
177
+ */
178
+ const getDecodedCallFromExtrinsic = (chain, extrinsicHex) => {
179
+ try {
180
+ const { metadata, builder } = chain;
181
+ const extensionsArray = metadata.extrinsic.signedExtensions[0] ?? [];
182
+ const extraDec = _polkadot_api_substrate_bindings.Struct.dec(Object.fromEntries(extensionsArray.map((x) => [x.identifier, builder.buildDefinition(x.type)[1]])));
183
+ let callDec;
184
+ const { extrinsic } = metadata;
185
+ if ("address" in extrinsic) callDec = builder.buildDefinition(extrinsic.call)[1];
186
+ else {
187
+ const callType = (metadata.lookup[extrinsic.type]?.params)?.find((v) => v.name === "Call")?.type;
188
+ if (callType == null) throw new Error("Call type not found in metadata");
189
+ callDec = builder.buildDefinition(callType)[1];
190
+ }
191
+ let addressDec;
192
+ let signatureDec;
193
+ if ("address" in extrinsic) {
194
+ addressDec = builder.buildDefinition(extrinsic.address)[1];
195
+ signatureDec = builder.buildDefinition(extrinsic.signature)[1];
196
+ } else {
197
+ const params = metadata.lookup[extrinsic.type]?.params;
198
+ const addrType = params?.find((v) => v.name === "Address")?.type;
199
+ const sigType = params?.find((v) => v.name === "Signature")?.type;
200
+ if (addrType == null || sigType == null) throw new Error("Address or Signature type not found");
201
+ addressDec = builder.buildDefinition(addrType)[1];
202
+ signatureDec = builder.buildDefinition(sigType)[1];
203
+ }
204
+ const v4Body = _polkadot_api_substrate_bindings.Struct.dec({
205
+ address: addressDec,
206
+ signature: signatureDec,
207
+ extra: extraDec,
208
+ callData: allBytesDec
209
+ });
210
+ const decoded = (0, _polkadot_api_substrate_bindings.enhanceDecoder)((0, _polkadot_api_substrate_bindings.createDecoder)((data) => {
211
+ const len = _polkadot_api_substrate_bindings.compactNumber.dec(data);
212
+ const { type, version } = _polkadot_api_substrate_bindings.extrinsicFormat[1](data);
213
+ if (type === "bare") return {
214
+ len,
215
+ version,
216
+ type,
217
+ callData: allBytesDec(data)
218
+ };
219
+ if (type === "signed") return {
220
+ len,
221
+ version,
222
+ type,
223
+ ...v4Body(data)
224
+ };
225
+ return {
226
+ len,
227
+ type,
228
+ version,
229
+ extensionVersion: _polkadot_api_substrate_bindings.u8.dec(data),
230
+ extra: extraDec(data),
231
+ callData: allBytesDec(data)
232
+ };
233
+ }), (v) => ({
234
+ ...v,
235
+ call: callDec(v.callData)
236
+ }))(extrinsicHex);
237
+ return {
238
+ pallet: decoded.call.type,
239
+ method: decoded.call.value.type,
240
+ args: decoded.call.value.value
241
+ };
242
+ } catch (err) {
243
+ console.error("[SAPI] Failed to decode extrinsic:", err);
244
+ return null;
245
+ }
246
+ };
247
+ //#endregion
248
+ //#region src/helpers/errors.ts
249
+ const getDispatchErrorMessage = (chain, err) => {
250
+ try {
251
+ if (!err) return null;
252
+ const error = err;
253
+ if (!error.type) throw new Error("Unknown dispatch error");
254
+ const lv1 = DISPATCH_ERROR[error.type];
255
+ if (!lv1) throw new Error("Unknown dispatch error");
256
+ if (lv1 === ERROR_METADATA_LOOKUP) return getModuleErrorMessage(chain, error.value);
257
+ if (typeof lv1 === "string") return lv1;
258
+ const lv2 = lv1[error.value?.type];
259
+ if (!lv2) throw new Error("Unknown dispatch error");
260
+ if (typeof lv2 === "string") return lv2;
261
+ throw new Error("Unknown dispatch error");
262
+ } catch (cause) {
263
+ log_default.error("Failed to parse runtime error", {
264
+ chainId: chain.connector.chainId,
265
+ cause,
266
+ err
267
+ });
268
+ return tryFormatError(err);
269
+ }
270
+ };
271
+ const ERROR_METADATA_LOOKUP = "METADATA_LOOKUP";
272
+ const DISPATCH_ERROR = {
273
+ CannotLookup: "Cannot lookup",
274
+ BadOrigin: "Bad origin",
275
+ Module: ERROR_METADATA_LOOKUP,
276
+ ConsumerRemaining: "Consumer remaining",
277
+ NoProviders: "No providers",
278
+ TooManyConsumers: "Too many consumers",
279
+ Token: {
280
+ FundsUnavailable: "Funds are unavailable",
281
+ OnlyProvider: "Account that must exist would die",
282
+ BelowMinimum: "Account cannot exist with the funds that would be given",
283
+ CannotCreate: "Account cannot be created",
284
+ UnknownAsset: "The asset in question is unknown",
285
+ Frozen: "Funds exist but are frozen",
286
+ Unsupported: "Operation is not supported by the asset",
287
+ CannotCreateHold: "Account cannot be created for recording amount on hold",
288
+ NotExpendable: "Account that is desired to remain would die",
289
+ Blocked: "Account cannot receive the assets"
290
+ },
291
+ Arithmetic: {
292
+ Overflow: "An underflow would occur",
293
+ Underflow: "An overflow would occur",
294
+ DivisionByZero: "Division by zero"
295
+ },
296
+ Transactional: {
297
+ LimitReached: "Too many transactional layers have been spawned",
298
+ NoLayer: "A transactional layer was expected, but does not exist"
299
+ },
300
+ Exhausted: "Resources exhausted",
301
+ Corruption: "State corrupt",
302
+ Unavailable: "Resource unavailable",
303
+ RootNotAllowed: "Root not allowed",
304
+ Trie: "Unknown error",
305
+ Other: "Unknown error"
306
+ };
307
+ const getModuleErrorMessage = (chain, error) => {
308
+ try {
309
+ if (!chain.metadata) throw new Error("Could not fetch metadata");
310
+ const pallet = chain.metadata.pallets.find((p) => p.name === error.type);
311
+ if (typeof pallet?.errors !== "number") throw new Error("Unknown pallet");
312
+ const palletErrors = (0, _polkadot_api_metadata_builders.getLookupFn)(chain.metadata)(pallet.errors);
313
+ if (palletErrors.type !== "enum" || !palletErrors.innerDocs[error.value.type]?.length) throw new Error("Unknown error type");
314
+ return palletErrors.innerDocs[error.value.type].join(" ");
315
+ } catch (err) {
316
+ log_default.error("Failed to parse module error", {
317
+ chainId: chain.connector.chainId,
318
+ error,
319
+ err
320
+ });
321
+ return [error.type, error.value.type].join(": ");
322
+ }
323
+ };
324
+ const tryFormatError = (err) => {
325
+ try {
326
+ const unsafeErr = err;
327
+ if (unsafeErr.type && unsafeErr.value?.type) return [unsafeErr.type, unsafeErr.value.type].join(": ");
328
+ } catch {}
329
+ return "Unknown error";
330
+ };
331
+ //#endregion
332
+ //#region src/helpers/getSendRequestResult.ts
333
+ const getSendRequestResult = (chain, method, params, isCacheable) => {
334
+ return chain.connector.send(method, params, isCacheable);
335
+ };
336
+ //#endregion
337
+ //#region src/helpers/getRuntimeCallResult.ts
338
+ const getRuntimeCallResult = async (chain, apiName, method, args) => {
339
+ const call = chain.builder.buildRuntimeCall(apiName, method);
340
+ const hex = await getSendRequestResult(chain, "state_call", [`${apiName}_${method}`, (0, _polkadot_api_utils.toHex)(call.args.enc(args))]);
341
+ return call.value.dec(hex);
342
+ };
343
+ //#endregion
344
+ //#region src/helpers/isApiAvailable.ts
345
+ const isApiAvailable = (chain, name, method) => {
346
+ return chain.metadata.apis.some((a) => a.name === name && a.methods.some((m) => m.name === method));
347
+ };
348
+ //#endregion
349
+ //#region src/helpers/getDryRunCall.ts
350
+ const getDryRunCall = async (chain, from, decodedCall) => {
351
+ try {
352
+ if (!isApiAvailable(chain, "DryRunApi", "dry_run_call")) return {
353
+ available: false,
354
+ data: null
355
+ };
356
+ const origin = (0, _polkadot_api_substrate_bindings.Enum)("system", (0, _polkadot_api_substrate_bindings.Enum)("Signed", from));
357
+ const { pallet, method, args } = decodedCall;
358
+ const data = await getRuntimeCallResult(chain, "DryRunApi", "dry_run_call", [origin, {
359
+ type: pallet,
360
+ value: {
361
+ type: method,
362
+ value: args
363
+ }
364
+ }]);
365
+ return {
366
+ available: true,
367
+ data,
368
+ ok: data.success && data.value.execution_result.success,
369
+ errorMessage: data.success && !data.value.execution_result.success ? getDispatchErrorMessage(chain, data.value.execution_result.value.error) : null
370
+ };
371
+ } catch (err) {
372
+ log_default.error("Failed to dry run", {
373
+ chainId: chain.connector.chainId,
374
+ err
375
+ });
376
+ return {
377
+ available: false,
378
+ data: null
379
+ };
380
+ }
381
+ };
382
+ //#endregion
383
+ //#region src/helpers/getExtrinsicDispatchInfo.ts
384
+ const getExtrinsicDispatchInfo = async (chain, signedTxBytes) => {
385
+ const args = (0, _polkadot_api_utils.mergeUint8)([signedTxBytes, _polkadot_api_substrate_bindings.u32.enc(signedTxBytes.length)]);
386
+ const bytes = (0, _polkadot_api_utils.fromHex)(await chain.connector.send("state_call", ["TransactionPaymentApi_query_info", (0, _polkadot_api_utils.toHex)(args)], true));
387
+ if (bytes.length < 16) throw new Error("Invalid RuntimeDispatchInfo");
388
+ return { partialFee: _polkadot_api_substrate_bindings.u128.dec(bytes.slice(bytes.length - 16)).toString() };
389
+ };
390
+ //#endregion
391
+ //#region src/helpers/getFeeEstimate.ts
392
+ /** strips the leading compact length prefix from an encoded extrinsic */
393
+ const stripLengthPrefix = (tx) => {
394
+ const mode = tx[0] & 3;
395
+ const prefixLen = mode === 0 ? 1 : mode === 1 ? 2 : mode === 2 ? 4 : 1 + (tx[0] >> 2) + 4;
396
+ return tx.subarray(prefixLen);
397
+ };
398
+ const getFeeEstimate = async (chain, payload) => {
399
+ const { callData, extra } = (0, _polkadot_api_tx_utils.getPjsTxHelper)(chain.hexMetadata, CUSTOM_SIGNED_EXTENSIONS)(payload);
400
+ const fakeSignature = isEthereumAddress(payload.address) ? /* @__PURE__ */ new Uint8Array(65) : (/* @__PURE__ */ new Uint8Array(66)).fill(2, 0, 1);
401
+ const signedTx = (0, _polkadot_api_signers_common.createV4Tx)(chain.metadata, getAddressBytes(payload.address), fakeSignature, [extra], callData);
402
+ const bytes = stripLengthPrefix(signedTx);
403
+ try {
404
+ const result = await getRuntimeCallResult(chain, "TransactionPaymentApi", "query_info", [bytes, bytes.length]);
405
+ if (!result?.partial_fee && result.partial_fee !== 0n) throw new Error("partialFee is not found");
406
+ return result.partial_fee;
407
+ } catch (err) {
408
+ log_default.error("Failed to get fee estimate using getRuntimeCallValue", { err });
409
+ }
410
+ const { partialFee } = await getExtrinsicDispatchInfo(chain, signedTx);
411
+ return BigInt(partialFee);
412
+ };
413
+ //#endregion
414
+ //#region src/helpers/getSapiConnector.ts
415
+ const getSapiConnector = ({ chainId, send, submit, submitWithBittensorMevShield }) => ({
416
+ chainId,
417
+ send,
418
+ submit: (...args) => {
419
+ if (submit) return submit(...args);
420
+ throw new Error("submit handler not provided");
421
+ },
422
+ submitWithBittensorMevShield: (...args) => {
423
+ if (submitWithBittensorMevShield) return submitWithBittensorMevShield(...args);
424
+ throw new Error("submitWithBittensorMevShield handler not provided");
425
+ }
528
426
  });
529
-
530
- // src/helpers/getSignerPayloadJSON.ts
531
- var import_utils5 = require("@polkadot-api/utils");
532
- var import_polkadot_api2 = require("polkadot-api");
533
-
534
- // src/helpers/getPayloadWithMetadataHash.ts
535
- var import_merkleize_metadata = require("@polkadot-api/merkleize-metadata");
536
- var import_utils4 = require("@polkadot-api/utils");
537
- var getPayloadWithMetadataHash = (chain, chainInfo, payload) => {
538
- if (!chain.hasCheckMetadataHash || !payload.signedExtensions.includes("CheckMetadataHash"))
539
- return {
540
- payload,
541
- txMetadata: void 0
542
- };
543
- try {
544
- const { decimals, symbol: tokenSymbol } = chain.token;
545
- const { base58Prefix, specName, specVersion } = chainInfo;
546
- const metadataHashInputs = { tokenSymbol, decimals, base58Prefix, specName, specVersion };
547
- const merkleizedMetadata = (0, import_merkleize_metadata.merkleizeMetadata)(chain.hexMetadata, metadataHashInputs);
548
- const metadataHash = (0, import_utils4.toHex)(merkleizedMetadata.digest());
549
- log_default.log("metadataHash", metadataHash, metadataHashInputs);
550
- const payloadWithMetadataHash = {
551
- ...payload,
552
- mode: 1,
553
- metadataHash,
554
- withSignedTransaction: true
555
- };
556
- const registry = getTypeRegistry(chain, payload);
557
- const extPayload = registry.createType("ExtrinsicPayload", payloadWithMetadataHash);
558
- const barePayload = extPayload.toU8a(true);
559
- const txMetadata = merkleizedMetadata.getProofForExtrinsicPayload(barePayload);
560
- return {
561
- payload: payloadWithMetadataHash,
562
- txMetadata
563
- };
564
- } catch (err) {
565
- log_default.error("Failed to get shortened metadata", { error: err });
566
- return {
567
- payload,
568
- txMetadata: void 0
569
- };
570
- }
571
- };
572
-
573
- // src/helpers/getStorageValue.ts
574
- var getStorageValue = async (chain, pallet, entry, keys, at) => {
575
- const storageCodec = chain.builder.buildStorage(pallet, entry);
576
- const stateKey = storageCodec.keys.enc(...keys);
577
- const hexValue = await getSendRequestResult(chain, "state_getStorage", [
578
- stateKey,
579
- at
580
- ]);
581
- if (!hexValue) return null;
582
- return storageCodec.value.dec(hexValue);
583
- };
584
-
585
- // src/helpers/papi.ts
586
- var import_substrate_bindings2 = require("@polkadot-api/substrate-bindings");
587
- var toPjsHex = (value, minByteLen) => {
588
- let inner = value.toString(16);
589
- inner = (inner.length % 2 ? "0" : "") + inner;
590
- const nPaddedBytes = Math.max(0, (minByteLen || 0) - inner.length / 2);
591
- return `0x${"00".repeat(nPaddedBytes)}${inner}`;
592
- };
593
- var mortal = (0, import_substrate_bindings2.enhanceEncoder)((0, import_substrate_bindings2.Bytes)(2).enc, (value) => {
594
- const factor = Math.max(value.period >> 12, 1);
595
- const left = Math.min(Math.max(trailingZeroes(value.period) - 1, 1), 15);
596
- const right = value.phase / factor << 4;
597
- return import_substrate_bindings2.u16.enc(left | right);
427
+ //#endregion
428
+ //#region src/helpers/getPayloadWithMetadataHash.ts
429
+ const getPayloadWithMetadataHash = (chain, chainInfo, payload) => {
430
+ if (!chain.hasCheckMetadataHash || !payload.signedExtensions.includes("CheckMetadataHash")) return {
431
+ payload,
432
+ txMetadata: void 0
433
+ };
434
+ try {
435
+ const { decimals, symbol: tokenSymbol } = chain.token;
436
+ const { base58Prefix, specName, specVersion } = chainInfo;
437
+ const metadataHashInputs = {
438
+ tokenSymbol,
439
+ decimals,
440
+ base58Prefix,
441
+ specName,
442
+ specVersion
443
+ };
444
+ const merkleizedMetadata = (0, _polkadot_api_merkleize_metadata.merkleizeMetadata)(chain.hexMetadata, metadataHashInputs);
445
+ const metadataHash = (0, _polkadot_api_utils.toHex)(merkleizedMetadata.digest());
446
+ log_default.log("metadataHash", metadataHash, metadataHashInputs);
447
+ const payloadWithMetadataHash = {
448
+ ...payload,
449
+ mode: 1,
450
+ metadataHash,
451
+ withSignedTransaction: true
452
+ };
453
+ const { callData, extra, additionalSigned } = (0, _polkadot_api_tx_utils.getPjsTxHelper)(chain.hexMetadata, CUSTOM_SIGNED_EXTENSIONS)(payloadWithMetadataHash);
454
+ const barePayload = (0, _polkadot_api_utils.mergeUint8)([
455
+ callData,
456
+ extra,
457
+ additionalSigned
458
+ ]);
459
+ return {
460
+ payload: payloadWithMetadataHash,
461
+ txMetadata: merkleizedMetadata.getProofForExtrinsicPayload(barePayload)
462
+ };
463
+ } catch (err) {
464
+ log_default.error("Failed to get shortened metadata", { error: err });
465
+ return {
466
+ payload,
467
+ txMetadata: void 0
468
+ };
469
+ }
470
+ };
471
+ //#endregion
472
+ //#region src/helpers/getStorageValue.ts
473
+ const getStorageValue = async (chain, pallet, entry, keys, at) => {
474
+ const storageCodec = chain.builder.buildStorage(pallet, entry);
475
+ const hexValue = await getSendRequestResult(chain, "state_getStorage", [storageCodec.keys.enc(...keys), at]);
476
+ if (!hexValue) return null;
477
+ return storageCodec.value.dec(hexValue);
478
+ };
479
+ //#endregion
480
+ //#region src/helpers/getSignerPayloadJSON.ts
481
+ const ERA_PERIOD = 64;
482
+ const getSignerPayloadJSON = async (chain, palletName, methodName, args, signerConfig, chainInfo) => {
483
+ const { codec, location } = chain.builder.buildCall(palletName, methodName);
484
+ const method = (0, _polkadot_api_utils.mergeUint8)([new Uint8Array(location), codec.enc(args)]);
485
+ let blockHash = await getSendRequestResult(chain, "chain_getFinalizedHead", [], false);
486
+ const [nonce, genesisHash, blockNumberFinalized, blockNumberCurrent] = await Promise.all([
487
+ getSendRequestResult(chain, "system_accountNextIndex", [signerConfig.address], false),
488
+ getStorageValue(chain, "System", "BlockHash", [0]),
489
+ getStorageValue(chain, "System", "Number", [], blockHash),
490
+ getStorageValue(chain, "System", "Number", [])
491
+ ]);
492
+ if (!genesisHash) throw new Error("Genesis hash not found");
493
+ if (!blockHash) throw new Error("Block hash not found");
494
+ let blockNumber = blockNumberFinalized;
495
+ if (blockNumberCurrent - blockNumberFinalized > 32) {
496
+ blockNumber = blockNumberCurrent - 16;
497
+ blockHash = await getStorageValue(chain, "System", "BlockHash", [blockNumber]);
498
+ }
499
+ const era = mortal({
500
+ period: ERA_PERIOD,
501
+ phase: blockNumber % ERA_PERIOD
502
+ });
503
+ const signedExtensions = (chain.metadata.extrinsic.signedExtensions[0] ?? []).map((ext) => ext.identifier);
504
+ const { payload, txMetadata } = getPayloadWithMetadataHash(chain, chainInfo, {
505
+ address: signerConfig.address,
506
+ genesisHash,
507
+ blockHash,
508
+ method: _polkadot_api_substrate_bindings.Binary.toHex(method),
509
+ signedExtensions,
510
+ nonce: toPjsHex(nonce, 4),
511
+ specVersion: toPjsHex(chainInfo.specVersion, 4),
512
+ transactionVersion: toPjsHex(chainInfo.transactionVersion, 4),
513
+ blockNumber: toPjsHex(blockNumber, 4),
514
+ era: (0, _polkadot_api_utils.toHex)(era),
515
+ tip: toPjsHex(0, 16),
516
+ assetId: void 0,
517
+ version: 4
518
+ });
519
+ const shortMetadata = txMetadata ? (0, _polkadot_api_utils.toHex)(txMetadata) : void 0;
520
+ if (payload.signedExtensions.includes("CheckAppId")) payload.appId = 0;
521
+ log_default.log("[sapi] payload", {
522
+ newPayload: payload,
523
+ txMetadata
524
+ });
525
+ return {
526
+ payload,
527
+ txMetadata,
528
+ shortMetadata
529
+ };
530
+ };
531
+ //#endregion
532
+ //#region src/helpers/hasConstant.ts
533
+ const hasConstant = (chain, pallet, constant) => {
534
+ return !!chain.metadata.pallets.find((p) => p.name === pallet)?.constants.some((c) => c.name === constant);
535
+ };
536
+ //#endregion
537
+ //#region src/helpers/hasEvent.ts
538
+ const hasEvent = (chain, pallet, event) => {
539
+ try {
540
+ const palletDef = chain.metadata.pallets.find((p) => p.name === pallet);
541
+ if (typeof palletDef?.events !== "number") return false;
542
+ const palletEvents = (0, _polkadot_api_metadata_builders.getLookupFn)(chain.metadata)(palletDef.events);
543
+ return palletEvents.type === "enum" && event in palletEvents.innerDocs;
544
+ } catch (err) {
545
+ log_default.error("Failed to check event existence", {
546
+ pallet,
547
+ event,
548
+ err
549
+ });
550
+ return false;
551
+ }
552
+ };
553
+ //#endregion
554
+ //#region src/helpers/submit.ts
555
+ const submit = async (chain, payload, signature, txInfo, mode) => {
556
+ switch (mode) {
557
+ case "bittensor-mev-shield":
558
+ if (signature) throw new Error("Signature should not be provided when using bittensor-mev-shield mode");
559
+ return chain.connector.submitWithBittensorMevShield(payload, txInfo);
560
+ default: return chain.connector.submit(payload, signature, txInfo);
561
+ }
562
+ };
563
+ //#endregion
564
+ //#region src/sapi.ts
565
+ const getScaleApi = (connector, hexMetadata, token, hasCheckMetadataHash, signedExtensions, registryTypes) => {
566
+ const { unifiedMetadata: metadata, lookupFn: lookup, builder } = (0, _talismn_scale.parseMetadataRpc)(hexMetadata);
567
+ const chain = {
568
+ connector: getSapiConnector(connector),
569
+ hexMetadata,
570
+ token,
571
+ hasCheckMetadataHash,
572
+ signedExtensions,
573
+ registryTypes,
574
+ metadata,
575
+ lookup,
576
+ builder,
577
+ metadataRpc: hexMetadata
578
+ };
579
+ const chainInfo = getChainInfo(chain);
580
+ const { specName, specVersion, base58Prefix } = chainInfo;
581
+ return {
582
+ id: `${connector.chainId}::${specName}::${specVersion}`,
583
+ chainId: connector.chainId,
584
+ specName,
585
+ specVersion,
586
+ hasCheckMetadataHash,
587
+ base58Prefix,
588
+ token: chain.token,
589
+ chain,
590
+ getConstant: (pallet, constant) => getConstantValue(chain, pallet, constant),
591
+ getStorage: (pallet, entry, keys, at) => getStorageValue(chain, pallet, entry, keys, at),
592
+ getDecodedCall: (pallet, method, args) => getDecodedCall(pallet, method, args),
593
+ getDecodedCallFromPayload: (payload) => getDecodedCallFromPayload(chain, payload),
594
+ getDecodedCallFromExtrinsic: (extrinsicHex) => getDecodedCallFromExtrinsic(chain, extrinsicHex),
595
+ getExtrinsicPayload: (pallet, method, args, config) => getSignerPayloadJSON(chain, pallet, method, args, config, chainInfo),
596
+ getFeeEstimate: (payload) => getFeeEstimate(chain, payload),
597
+ getRuntimeCallValue: (apiName, method, args) => getRuntimeCallResult(chain, apiName, method, args),
598
+ submit: (payload, signature, txInfo, mode) => submit(chain, payload, signature, txInfo, mode),
599
+ getCallDocs: (pallet, method) => getCallDocs(chain, pallet, method),
600
+ getDryRunCall: (from, decodedCall) => getDryRunCall(chain, from, decodedCall),
601
+ isApiAvailable: (name, method) => isApiAvailable(chain, name, method),
602
+ hasEvent: (pallet, event) => hasEvent(chain, pallet, event),
603
+ hasConstant: (pallet, constant) => hasConstant(chain, pallet, constant)
604
+ };
605
+ };
606
+ //#endregion
607
+ exports.CUSTOM_SIGNED_EXTENSIONS = CUSTOM_SIGNED_EXTENSIONS;
608
+ exports.MAX_SUPPORTED_METADATA_VERSION = MAX_SUPPORTED_METADATA_VERSION;
609
+ exports.fetchBestMetadata = fetchBestMetadata;
610
+ exports.getAddressBytes = getAddressBytes;
611
+ Object.defineProperty(exports, "getPjsTxHelper", {
612
+ enumerable: true,
613
+ get: function() {
614
+ return _polkadot_api_tx_utils.getPjsTxHelper;
615
+ }
598
616
  });
599
- function trailingZeroes(n) {
600
- let i = 0;
601
- while (!(n & 1)) {
602
- i++;
603
- n >>= 1;
604
- }
605
- return i;
606
- }
607
-
608
- // src/helpers/getSignerPayloadJSON.ts
609
- var ERA_PERIOD = 64;
610
- var getSignerPayloadJSON = async (chain, palletName, methodName, args, signerConfig, chainInfo) => {
611
- const { codec, location } = chain.builder.buildCall(palletName, methodName);
612
- const method = (0, import_utils5.mergeUint8)([new Uint8Array(location), codec.enc(args)]);
613
- let blockHash = await getSendRequestResult(
614
- chain,
615
- "chain_getFinalizedHead",
616
- [],
617
- false
618
- );
619
- const [nonce, genesisHash, blockNumberFinalized, blockNumberCurrent] = await Promise.all([
620
- getSendRequestResult(chain, "system_accountNextIndex", [signerConfig.address], false),
621
- getStorageValue(chain, "System", "BlockHash", [0]),
622
- getStorageValue(chain, "System", "Number", [], blockHash),
623
- getStorageValue(chain, "System", "Number", [])
624
- ]);
625
- if (!genesisHash) throw new Error("Genesis hash not found");
626
- if (!blockHash) throw new Error("Block hash not found");
627
- let blockNumber = blockNumberFinalized;
628
- if (blockNumberCurrent - blockNumberFinalized > 32) {
629
- blockNumber = blockNumberCurrent - 16;
630
- const binBlockHash = await getStorageValue(chain, "System", "BlockHash", [
631
- blockNumber
632
- ]);
633
- blockHash = binBlockHash;
634
- }
635
- const era = mortal({ period: ERA_PERIOD, phase: blockNumber % ERA_PERIOD });
636
- const signedExtensions = (chain.metadata.extrinsic.signedExtensions[0] ?? []).map(
637
- (ext) => ext.identifier
638
- );
639
- const basePayload = {
640
- address: signerConfig.address,
641
- genesisHash,
642
- blockHash,
643
- method: import_polkadot_api2.Binary.toHex(method),
644
- signedExtensions,
645
- nonce: toPjsHex(nonce, 4),
646
- specVersion: toPjsHex(chainInfo.specVersion, 4),
647
- transactionVersion: toPjsHex(chainInfo.transactionVersion, 4),
648
- blockNumber: toPjsHex(blockNumber, 4),
649
- era: (0, import_utils5.toHex)(era),
650
- tip: toPjsHex(0, 16),
651
- // TODO gas station (required for Astar)
652
- assetId: void 0,
653
- version: 4
654
- };
655
- const { payload, txMetadata } = getPayloadWithMetadataHash(chain, chainInfo, basePayload);
656
- const shortMetadata = txMetadata ? (0, import_utils5.toHex)(txMetadata) : void 0;
657
- if (payload.signedExtensions.includes("CheckAppId"))
658
- payload.appId = 0;
659
- log_default.log("[sapi] payload", { newPayload: payload, txMetadata });
660
- return {
661
- payload,
662
- txMetadata,
663
- // TODO remove
664
- shortMetadata
665
- };
666
- };
667
-
668
- // src/helpers/hasEvent.ts
669
- var import_metadata_builders2 = require("@polkadot-api/metadata-builders");
670
- var hasEvent = (chain, pallet, event) => {
671
- try {
672
- const palletDef = chain.metadata.pallets.find((p) => p.name === pallet);
673
- if (typeof palletDef?.events !== "number") return false;
674
- const lookup = (0, import_metadata_builders2.getLookupFn)(chain.metadata);
675
- const palletEvents = lookup(palletDef.events);
676
- return palletEvents.type === "enum" && event in palletEvents.innerDocs;
677
- } catch (err) {
678
- log_default.error("Failed to check event existence", { pallet, event, err });
679
- return false;
680
- }
681
- };
682
-
683
- // src/helpers/submit.ts
684
- var submit = async (chain, payload, signature, txInfo, mode) => {
685
- switch (mode) {
686
- case "bittensor-mev-shield":
687
- if (signature)
688
- throw new Error("Signature should not be provided when using bittensor-mev-shield mode");
689
- return chain.connector.submitWithBittensorMevShield(payload, txInfo);
690
- default:
691
- return chain.connector.submit(payload, signature, txInfo);
692
- }
693
- };
694
-
695
- // src/sapi.ts
696
- var getScaleApi = (connector, hexMetadata, token, hasCheckMetadataHash, signedExtensions, registryTypes) => {
697
- const { unifiedMetadata: metadata, lookupFn: lookup, builder } = (0, import_scale2.parseMetadataRpc)(hexMetadata);
698
- const chain = {
699
- connector: getSapiConnector(connector),
700
- hexMetadata,
701
- token,
702
- hasCheckMetadataHash,
703
- signedExtensions,
704
- registryTypes,
705
- metadata,
706
- lookup,
707
- builder,
708
- metadataRpc: hexMetadata
709
- };
710
- const chainInfo = getChainInfo(chain);
711
- const { specName, specVersion, base58Prefix } = chainInfo;
712
- return {
713
- id: `${connector.chainId}::${specName}::${specVersion}`,
714
- chainId: connector.chainId,
715
- specName,
716
- specVersion,
717
- hasCheckMetadataHash,
718
- base58Prefix,
719
- token: chain.token,
720
- chain,
721
- getConstant: (pallet, constant) => getConstantValue(chain, pallet, constant),
722
- getStorage: (pallet, entry, keys, at) => getStorageValue(chain, pallet, entry, keys, at),
723
- getDecodedCall: (pallet, method, args) => getDecodedCall(pallet, method, args),
724
- getDecodedCallFromPayload: (payload) => getDecodedCallFromPayload(chain, payload),
725
- getDecodedCallFromExtrinsic: (extrinsicHex) => getDecodedCallFromExtrinsic(chain, extrinsicHex),
726
- getExtrinsicPayload: (pallet, method, args, config) => getSignerPayloadJSON(chain, pallet, method, args, config, chainInfo),
727
- getFeeEstimate: (payload) => getFeeEstimate(chain, payload, chainInfo),
728
- getRuntimeCallValue: (apiName, method, args) => getRuntimeCallResult(chain, apiName, method, args),
729
- getTypeRegistry: (payload) => getTypeRegistry(chain, payload),
730
- submit: (payload, signature, txInfo, mode) => submit(chain, payload, signature, txInfo, mode),
731
- getCallDocs: (pallet, method) => getCallDocs(chain, pallet, method),
732
- getDryRunCall: (from, decodedCall) => getDryRunCall(chain, from, decodedCall),
733
- isApiAvailable: (name, method) => isApiAvailable(chain, name, method),
734
- hasEvent: (pallet, event) => hasEvent(chain, pallet, event)
735
- };
736
- };
737
- // Annotate the CommonJS export names for ESM import in node:
738
- 0 && (module.exports = {
739
- MAX_SUPPORTED_METADATA_VERSION,
740
- fetchBestMetadata,
741
- getScaleApi
617
+ exports.getScaleApi = getScaleApi;
618
+ Object.defineProperty(exports, "getTxHelper", {
619
+ enumerable: true,
620
+ get: function() {
621
+ return _polkadot_api_tx_utils.getTxHelper;
622
+ }
742
623
  });
624
+ exports.isEthereumAddress = isEthereumAddress;
625
+ exports.mortal = mortal;
626
+ exports.toPjsHex = toPjsHex;
627
+
743
628
  //# sourceMappingURL=index.js.map