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