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