@talismn/scale 0.1.0 → 0.1.1
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.
|
@@ -14,7 +14,11 @@ export type V15StorageItem = NonNullable<V15Pallet["storage"]>["items"][0];
|
|
|
14
14
|
* E.g. if `palletsAndItems` is `{ pallet: "System", items: ["Account"] }`, then only the
|
|
15
15
|
* types used in the `System.Account` storage query will remain inside of metadata.lookups.
|
|
16
16
|
*/
|
|
17
|
-
export declare const compactMetadata: (metadata: V15 | V14, palletsAndItems
|
|
17
|
+
export declare const compactMetadata: (metadata: V15 | V14, palletsAndItems?: Array<{
|
|
18
18
|
pallet: string;
|
|
19
|
+
constants?: string[];
|
|
19
20
|
items: string[];
|
|
21
|
+
}>, runtimeApisAndMethods?: Array<{
|
|
22
|
+
runtimeApi: string;
|
|
23
|
+
methods: string[];
|
|
20
24
|
}>, extraKeepTypes?: number[]) => void;
|
|
@@ -26,4 +26,5 @@
|
|
|
26
26
|
* Output: `Enum("Stellar", { code: Binary.fromText("TZS"), issuer: Binary.fromHex("0x34c94b2a4ba9e8b57b22547dcbb30f443c4cb02da3829a89aa1bd4780e4466ba") })`
|
|
27
27
|
*/
|
|
28
28
|
export declare const papiParse: <T = unknown>(text: string | T) => T;
|
|
29
|
-
export declare const papiStringify: (value: any,
|
|
29
|
+
export declare const papiStringify: (value: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
30
|
+
space?: string | number) => string;
|
|
@@ -14,55 +14,7 @@ var anylogger__default = /*#__PURE__*/_interopDefault(anylogger);
|
|
|
14
14
|
const magicNumber = 1635018093;
|
|
15
15
|
|
|
16
16
|
var packageJson = {
|
|
17
|
-
name: "@talismn/scale"
|
|
18
|
-
version: "0.1.0",
|
|
19
|
-
author: "Talisman",
|
|
20
|
-
homepage: "https://talisman.xyz",
|
|
21
|
-
license: "GPL-3.0-or-later",
|
|
22
|
-
publishConfig: {
|
|
23
|
-
access: "public"
|
|
24
|
-
},
|
|
25
|
-
repository: {
|
|
26
|
-
directory: "packages/scale",
|
|
27
|
-
type: "git",
|
|
28
|
-
url: "https://github.com/talismansociety/talisman.git"
|
|
29
|
-
},
|
|
30
|
-
main: "dist/talismn-scale.cjs.js",
|
|
31
|
-
module: "dist/talismn-scale.esm.js",
|
|
32
|
-
files: [
|
|
33
|
-
"/dist"
|
|
34
|
-
],
|
|
35
|
-
engines: {
|
|
36
|
-
node: ">=18"
|
|
37
|
-
},
|
|
38
|
-
scripts: {
|
|
39
|
-
test: "jest",
|
|
40
|
-
lint: "eslint src --max-warnings 0",
|
|
41
|
-
clean: "rm -rf dist .turbo node_modules"
|
|
42
|
-
},
|
|
43
|
-
dependencies: {
|
|
44
|
-
"@polkadot-api/metadata-builders": "0.9.1",
|
|
45
|
-
"@polkadot-api/substrate-bindings": "0.9.3",
|
|
46
|
-
"@polkadot-api/utils": "0.1.2",
|
|
47
|
-
anylogger: "^1.0.11",
|
|
48
|
-
"scale-ts": "^1.6.1"
|
|
49
|
-
},
|
|
50
|
-
devDependencies: {
|
|
51
|
-
"@talismn/eslint-config": "workspace:*",
|
|
52
|
-
"@talismn/tsconfig": "workspace:*",
|
|
53
|
-
"@types/jest": "^29.5.14",
|
|
54
|
-
eslint: "^8.57.1",
|
|
55
|
-
jest: "^29.7",
|
|
56
|
-
"ts-jest": "^29.2.5",
|
|
57
|
-
typescript: "^5.6.3"
|
|
58
|
-
},
|
|
59
|
-
eslintConfig: {
|
|
60
|
-
root: true,
|
|
61
|
-
"extends": [
|
|
62
|
-
"@talismn/eslint-config/base"
|
|
63
|
-
]
|
|
64
|
-
}
|
|
65
|
-
};
|
|
17
|
+
name: "@talismn/scale"};
|
|
66
18
|
|
|
67
19
|
var log = anylogger__default.default(packageJson.name);
|
|
68
20
|
|
|
@@ -75,7 +27,7 @@ var log = anylogger__default.default(packageJson.name);
|
|
|
75
27
|
* E.g. if `palletsAndItems` is `{ pallet: "System", items: ["Account"] }`, then only the
|
|
76
28
|
* types used in the `System.Account` storage query will remain inside of metadata.lookups.
|
|
77
29
|
*/
|
|
78
|
-
const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
30
|
+
const compactMetadata = (metadata, palletsAndItems = [], runtimeApisAndMethods = [], extraKeepTypes = []) => {
|
|
79
31
|
// remove pallets we don't care about
|
|
80
32
|
metadata.pallets = metadata.pallets.filter(pallet =>
|
|
81
33
|
// keep this pallet if it's listed in `palletsAndItems`
|
|
@@ -84,8 +36,9 @@ const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
|
84
36
|
}) => pallet.name === palletName));
|
|
85
37
|
|
|
86
38
|
// remove fields we don't care about from each pallet, and extract types for each storage item we care about
|
|
87
|
-
const
|
|
39
|
+
const palletsKeepTypes = palletsAndItems.flatMap(({
|
|
88
40
|
pallet: palletName,
|
|
41
|
+
constants: constantNames,
|
|
89
42
|
items: itemNames
|
|
90
43
|
}) => {
|
|
91
44
|
const pallet = metadata.pallets.find(pallet => pallet.name === palletName);
|
|
@@ -96,7 +49,7 @@ const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
|
96
49
|
|
|
97
50
|
// remove pallet fields we don't care about
|
|
98
51
|
pallet.calls = undefined;
|
|
99
|
-
pallet.constants = [];
|
|
52
|
+
pallet.constants = constantNames ? pallet.constants.filter(constant => constantNames.includes(constant.name)) : [];
|
|
100
53
|
// v15 (NOT v14) has docs
|
|
101
54
|
if ("docs" in pallet) pallet.docs = [];
|
|
102
55
|
pallet.errors = undefined;
|
|
@@ -105,19 +58,54 @@ const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
|
105
58
|
|
|
106
59
|
// filter and extract storage items we care about
|
|
107
60
|
pallet.storage.items = pallet.storage.items.filter(item => itemNames.some(itemName => item.name === itemName));
|
|
108
|
-
return pallet.storage.items
|
|
61
|
+
return [...pallet.storage.items.flatMap(item => [
|
|
62
|
+
// each type can be either "Plain" or "Map"
|
|
63
|
+
// if it's "Plain" we only need to get the value type
|
|
64
|
+
// if it's a "Map" we want to keep both the key AND the value types
|
|
65
|
+
item.type.tag === "plain" && item.type.value, item.type.tag === "map" && item.type.value.key, item.type.tag === "map" && item.type.value.value]).filter(type => typeof type === "number"), ...pallet.constants.flatMap(constant => constant.type)];
|
|
109
66
|
});
|
|
110
67
|
|
|
68
|
+
// remove runtime apis we don't care about
|
|
69
|
+
let runtimeApisKeepTypes = [];
|
|
70
|
+
if ("apis" in metadata) {
|
|
71
|
+
// metadata is v15 (NOT v14)
|
|
72
|
+
|
|
73
|
+
// keep this api if it's listed in `runtimeApisAndMethods`
|
|
74
|
+
metadata.apis = metadata.apis.filter(runtimeApi => runtimeApisAndMethods.some(({
|
|
75
|
+
runtimeApi: runtimeApiName
|
|
76
|
+
}) => runtimeApi.name === runtimeApiName));
|
|
77
|
+
|
|
78
|
+
// remove methods we don't care about from each runtime api, and extract types for each call's params and result
|
|
79
|
+
runtimeApisKeepTypes = runtimeApisAndMethods.flatMap(({
|
|
80
|
+
runtimeApi: runtimeApiName,
|
|
81
|
+
methods: methodNames
|
|
82
|
+
}) => {
|
|
83
|
+
const runtimeApi = metadata.apis.find(runtimeApi => runtimeApi.name === runtimeApiName);
|
|
84
|
+
if (!runtimeApi) {
|
|
85
|
+
log.debug("Failed to find runtimeApi", runtimeApiName);
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// remove runtime fields we don't care about
|
|
90
|
+
runtimeApi.docs = [];
|
|
91
|
+
if (!runtimeApi.methods) return [];
|
|
92
|
+
|
|
93
|
+
// filter and extract methods we care about
|
|
94
|
+
runtimeApi.methods = runtimeApi.methods.filter(method => methodNames.some(methodName => method.name === methodName));
|
|
95
|
+
return runtimeApi.methods.flatMap(method => [
|
|
96
|
+
// each method has an array of input types (for the params)
|
|
97
|
+
...method.inputs.map(input => input.type),
|
|
98
|
+
// and one output type (for the result)
|
|
99
|
+
method.output]);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
111
103
|
// this is a set of type ids which we plan to keep in our compacted metadata
|
|
112
104
|
// anything not in this set will be deleted
|
|
113
105
|
// we start off with just the types of the state calls we plan to make,
|
|
114
106
|
// then we run those types through a function (addDependentTypes) which will also include
|
|
115
107
|
// all of the types which those types depend on - recursively
|
|
116
|
-
const keepTypes = new Set(
|
|
117
|
-
// each type can be either "Plain" or "Map"
|
|
118
|
-
// if it's "Plain" we only need to get the value type
|
|
119
|
-
// if it's a "Map" we want to keep both the key AND the value types
|
|
120
|
-
item.type.tag === "plain" && item.type.value, item.type.tag === "map" && item.type.value.key, item.type.tag === "map" && item.type.value.value]).filter(type => typeof type === "number"));
|
|
108
|
+
const keepTypes = new Set([...palletsKeepTypes, ...runtimeApisKeepTypes]);
|
|
121
109
|
extraKeepTypes?.forEach(type => keepTypes.add(type));
|
|
122
110
|
|
|
123
111
|
// recursively find all the types which our keepTypes depend on and add them to the keepTypes set
|
|
@@ -136,12 +124,6 @@ const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
|
136
124
|
return newTypeId ?? 0;
|
|
137
125
|
};
|
|
138
126
|
remapTypeIds(metadata, getNewTypeId);
|
|
139
|
-
|
|
140
|
-
// ditch the remaining data we don't need to keep in a miniMetata
|
|
141
|
-
if ("apis" in metadata) {
|
|
142
|
-
// metadata is v15 (NOT v14)
|
|
143
|
-
metadata.apis = [];
|
|
144
|
-
}
|
|
145
127
|
if ("address" in metadata.extrinsic) {
|
|
146
128
|
// metadata is v15 (NOT v14)
|
|
147
129
|
metadata.extrinsic.address = 0;
|
|
@@ -208,6 +190,7 @@ addedTypes = new Set()) => {
|
|
|
208
190
|
const remapTypeIds = (metadata, getNewTypeId) => {
|
|
209
191
|
remapLookupTypeIds(metadata, getNewTypeId);
|
|
210
192
|
remapStorageTypeIds(metadata, getNewTypeId);
|
|
193
|
+
remapRuntimeApisTypeIds(metadata, getNewTypeId);
|
|
211
194
|
};
|
|
212
195
|
const remapLookupTypeIds = (metadata, getNewTypeId) => {
|
|
213
196
|
for (const type of metadata.lookup) {
|
|
@@ -270,6 +253,19 @@ const remapStorageTypeIds = (metadata, getNewTypeId) => {
|
|
|
270
253
|
item.type.value.value = getNewTypeId(item.type.value.value);
|
|
271
254
|
}
|
|
272
255
|
}
|
|
256
|
+
for (const constant of pallet.constants ?? []) {
|
|
257
|
+
constant.type = getNewTypeId(constant.type);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
const remapRuntimeApisTypeIds = (metadata, getNewTypeId) => {
|
|
262
|
+
for (const runtimeApi of metadata.apis) {
|
|
263
|
+
for (const method of runtimeApi.methods ?? []) {
|
|
264
|
+
for (const input of method.inputs) {
|
|
265
|
+
input.type = getNewTypeId(input.type);
|
|
266
|
+
}
|
|
267
|
+
method.output = getNewTypeId(method.output);
|
|
268
|
+
}
|
|
273
269
|
}
|
|
274
270
|
};
|
|
275
271
|
|
|
@@ -313,7 +309,7 @@ const decodeMetadata = metadataRpc => {
|
|
|
313
309
|
const decodeScale = (scaleCoder, change, error) => {
|
|
314
310
|
if (change === null) return null;
|
|
315
311
|
try {
|
|
316
|
-
return scaleCoder?.dec(change) ?? null;
|
|
312
|
+
return scaleCoder?.value?.dec(change) ?? null;
|
|
317
313
|
} catch (cause) {
|
|
318
314
|
log.warn(error ?? `Failed to decode ${change}`, cause);
|
|
319
315
|
return null;
|
|
@@ -336,7 +332,7 @@ const encodeMetadata = ({
|
|
|
336
332
|
|
|
337
333
|
const encodeStateKey = (scaleCoder, error, ...args) => {
|
|
338
334
|
try {
|
|
339
|
-
return scaleCoder?.enc(...args);
|
|
335
|
+
return scaleCoder?.keys?.enc(...args);
|
|
340
336
|
} catch (cause) {
|
|
341
337
|
log.warn(error ?? `Failed to encode stateKey ${JSON.stringify(args)}`, cause);
|
|
342
338
|
return;
|
|
@@ -14,55 +14,7 @@ var anylogger__default = /*#__PURE__*/_interopDefault(anylogger);
|
|
|
14
14
|
const magicNumber = 1635018093;
|
|
15
15
|
|
|
16
16
|
var packageJson = {
|
|
17
|
-
name: "@talismn/scale"
|
|
18
|
-
version: "0.1.0",
|
|
19
|
-
author: "Talisman",
|
|
20
|
-
homepage: "https://talisman.xyz",
|
|
21
|
-
license: "GPL-3.0-or-later",
|
|
22
|
-
publishConfig: {
|
|
23
|
-
access: "public"
|
|
24
|
-
},
|
|
25
|
-
repository: {
|
|
26
|
-
directory: "packages/scale",
|
|
27
|
-
type: "git",
|
|
28
|
-
url: "https://github.com/talismansociety/talisman.git"
|
|
29
|
-
},
|
|
30
|
-
main: "dist/talismn-scale.cjs.js",
|
|
31
|
-
module: "dist/talismn-scale.esm.js",
|
|
32
|
-
files: [
|
|
33
|
-
"/dist"
|
|
34
|
-
],
|
|
35
|
-
engines: {
|
|
36
|
-
node: ">=18"
|
|
37
|
-
},
|
|
38
|
-
scripts: {
|
|
39
|
-
test: "jest",
|
|
40
|
-
lint: "eslint src --max-warnings 0",
|
|
41
|
-
clean: "rm -rf dist .turbo node_modules"
|
|
42
|
-
},
|
|
43
|
-
dependencies: {
|
|
44
|
-
"@polkadot-api/metadata-builders": "0.9.1",
|
|
45
|
-
"@polkadot-api/substrate-bindings": "0.9.3",
|
|
46
|
-
"@polkadot-api/utils": "0.1.2",
|
|
47
|
-
anylogger: "^1.0.11",
|
|
48
|
-
"scale-ts": "^1.6.1"
|
|
49
|
-
},
|
|
50
|
-
devDependencies: {
|
|
51
|
-
"@talismn/eslint-config": "workspace:*",
|
|
52
|
-
"@talismn/tsconfig": "workspace:*",
|
|
53
|
-
"@types/jest": "^29.5.14",
|
|
54
|
-
eslint: "^8.57.1",
|
|
55
|
-
jest: "^29.7",
|
|
56
|
-
"ts-jest": "^29.2.5",
|
|
57
|
-
typescript: "^5.6.3"
|
|
58
|
-
},
|
|
59
|
-
eslintConfig: {
|
|
60
|
-
root: true,
|
|
61
|
-
"extends": [
|
|
62
|
-
"@talismn/eslint-config/base"
|
|
63
|
-
]
|
|
64
|
-
}
|
|
65
|
-
};
|
|
17
|
+
name: "@talismn/scale"};
|
|
66
18
|
|
|
67
19
|
var log = anylogger__default.default(packageJson.name);
|
|
68
20
|
|
|
@@ -75,7 +27,7 @@ var log = anylogger__default.default(packageJson.name);
|
|
|
75
27
|
* E.g. if `palletsAndItems` is `{ pallet: "System", items: ["Account"] }`, then only the
|
|
76
28
|
* types used in the `System.Account` storage query will remain inside of metadata.lookups.
|
|
77
29
|
*/
|
|
78
|
-
const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
30
|
+
const compactMetadata = (metadata, palletsAndItems = [], runtimeApisAndMethods = [], extraKeepTypes = []) => {
|
|
79
31
|
// remove pallets we don't care about
|
|
80
32
|
metadata.pallets = metadata.pallets.filter(pallet =>
|
|
81
33
|
// keep this pallet if it's listed in `palletsAndItems`
|
|
@@ -84,8 +36,9 @@ const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
|
84
36
|
}) => pallet.name === palletName));
|
|
85
37
|
|
|
86
38
|
// remove fields we don't care about from each pallet, and extract types for each storage item we care about
|
|
87
|
-
const
|
|
39
|
+
const palletsKeepTypes = palletsAndItems.flatMap(({
|
|
88
40
|
pallet: palletName,
|
|
41
|
+
constants: constantNames,
|
|
89
42
|
items: itemNames
|
|
90
43
|
}) => {
|
|
91
44
|
const pallet = metadata.pallets.find(pallet => pallet.name === palletName);
|
|
@@ -96,7 +49,7 @@ const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
|
96
49
|
|
|
97
50
|
// remove pallet fields we don't care about
|
|
98
51
|
pallet.calls = undefined;
|
|
99
|
-
pallet.constants = [];
|
|
52
|
+
pallet.constants = constantNames ? pallet.constants.filter(constant => constantNames.includes(constant.name)) : [];
|
|
100
53
|
// v15 (NOT v14) has docs
|
|
101
54
|
if ("docs" in pallet) pallet.docs = [];
|
|
102
55
|
pallet.errors = undefined;
|
|
@@ -105,19 +58,54 @@ const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
|
105
58
|
|
|
106
59
|
// filter and extract storage items we care about
|
|
107
60
|
pallet.storage.items = pallet.storage.items.filter(item => itemNames.some(itemName => item.name === itemName));
|
|
108
|
-
return pallet.storage.items
|
|
61
|
+
return [...pallet.storage.items.flatMap(item => [
|
|
62
|
+
// each type can be either "Plain" or "Map"
|
|
63
|
+
// if it's "Plain" we only need to get the value type
|
|
64
|
+
// if it's a "Map" we want to keep both the key AND the value types
|
|
65
|
+
item.type.tag === "plain" && item.type.value, item.type.tag === "map" && item.type.value.key, item.type.tag === "map" && item.type.value.value]).filter(type => typeof type === "number"), ...pallet.constants.flatMap(constant => constant.type)];
|
|
109
66
|
});
|
|
110
67
|
|
|
68
|
+
// remove runtime apis we don't care about
|
|
69
|
+
let runtimeApisKeepTypes = [];
|
|
70
|
+
if ("apis" in metadata) {
|
|
71
|
+
// metadata is v15 (NOT v14)
|
|
72
|
+
|
|
73
|
+
// keep this api if it's listed in `runtimeApisAndMethods`
|
|
74
|
+
metadata.apis = metadata.apis.filter(runtimeApi => runtimeApisAndMethods.some(({
|
|
75
|
+
runtimeApi: runtimeApiName
|
|
76
|
+
}) => runtimeApi.name === runtimeApiName));
|
|
77
|
+
|
|
78
|
+
// remove methods we don't care about from each runtime api, and extract types for each call's params and result
|
|
79
|
+
runtimeApisKeepTypes = runtimeApisAndMethods.flatMap(({
|
|
80
|
+
runtimeApi: runtimeApiName,
|
|
81
|
+
methods: methodNames
|
|
82
|
+
}) => {
|
|
83
|
+
const runtimeApi = metadata.apis.find(runtimeApi => runtimeApi.name === runtimeApiName);
|
|
84
|
+
if (!runtimeApi) {
|
|
85
|
+
log.debug("Failed to find runtimeApi", runtimeApiName);
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// remove runtime fields we don't care about
|
|
90
|
+
runtimeApi.docs = [];
|
|
91
|
+
if (!runtimeApi.methods) return [];
|
|
92
|
+
|
|
93
|
+
// filter and extract methods we care about
|
|
94
|
+
runtimeApi.methods = runtimeApi.methods.filter(method => methodNames.some(methodName => method.name === methodName));
|
|
95
|
+
return runtimeApi.methods.flatMap(method => [
|
|
96
|
+
// each method has an array of input types (for the params)
|
|
97
|
+
...method.inputs.map(input => input.type),
|
|
98
|
+
// and one output type (for the result)
|
|
99
|
+
method.output]);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
111
103
|
// this is a set of type ids which we plan to keep in our compacted metadata
|
|
112
104
|
// anything not in this set will be deleted
|
|
113
105
|
// we start off with just the types of the state calls we plan to make,
|
|
114
106
|
// then we run those types through a function (addDependentTypes) which will also include
|
|
115
107
|
// all of the types which those types depend on - recursively
|
|
116
|
-
const keepTypes = new Set(
|
|
117
|
-
// each type can be either "Plain" or "Map"
|
|
118
|
-
// if it's "Plain" we only need to get the value type
|
|
119
|
-
// if it's a "Map" we want to keep both the key AND the value types
|
|
120
|
-
item.type.tag === "plain" && item.type.value, item.type.tag === "map" && item.type.value.key, item.type.tag === "map" && item.type.value.value]).filter(type => typeof type === "number"));
|
|
108
|
+
const keepTypes = new Set([...palletsKeepTypes, ...runtimeApisKeepTypes]);
|
|
121
109
|
extraKeepTypes?.forEach(type => keepTypes.add(type));
|
|
122
110
|
|
|
123
111
|
// recursively find all the types which our keepTypes depend on and add them to the keepTypes set
|
|
@@ -136,12 +124,6 @@ const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
|
136
124
|
return newTypeId ?? 0;
|
|
137
125
|
};
|
|
138
126
|
remapTypeIds(metadata, getNewTypeId);
|
|
139
|
-
|
|
140
|
-
// ditch the remaining data we don't need to keep in a miniMetata
|
|
141
|
-
if ("apis" in metadata) {
|
|
142
|
-
// metadata is v15 (NOT v14)
|
|
143
|
-
metadata.apis = [];
|
|
144
|
-
}
|
|
145
127
|
if ("address" in metadata.extrinsic) {
|
|
146
128
|
// metadata is v15 (NOT v14)
|
|
147
129
|
metadata.extrinsic.address = 0;
|
|
@@ -208,6 +190,7 @@ addedTypes = new Set()) => {
|
|
|
208
190
|
const remapTypeIds = (metadata, getNewTypeId) => {
|
|
209
191
|
remapLookupTypeIds(metadata, getNewTypeId);
|
|
210
192
|
remapStorageTypeIds(metadata, getNewTypeId);
|
|
193
|
+
remapRuntimeApisTypeIds(metadata, getNewTypeId);
|
|
211
194
|
};
|
|
212
195
|
const remapLookupTypeIds = (metadata, getNewTypeId) => {
|
|
213
196
|
for (const type of metadata.lookup) {
|
|
@@ -270,6 +253,19 @@ const remapStorageTypeIds = (metadata, getNewTypeId) => {
|
|
|
270
253
|
item.type.value.value = getNewTypeId(item.type.value.value);
|
|
271
254
|
}
|
|
272
255
|
}
|
|
256
|
+
for (const constant of pallet.constants ?? []) {
|
|
257
|
+
constant.type = getNewTypeId(constant.type);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
const remapRuntimeApisTypeIds = (metadata, getNewTypeId) => {
|
|
262
|
+
for (const runtimeApi of metadata.apis) {
|
|
263
|
+
for (const method of runtimeApi.methods ?? []) {
|
|
264
|
+
for (const input of method.inputs) {
|
|
265
|
+
input.type = getNewTypeId(input.type);
|
|
266
|
+
}
|
|
267
|
+
method.output = getNewTypeId(method.output);
|
|
268
|
+
}
|
|
273
269
|
}
|
|
274
270
|
};
|
|
275
271
|
|
|
@@ -313,7 +309,7 @@ const decodeMetadata = metadataRpc => {
|
|
|
313
309
|
const decodeScale = (scaleCoder, change, error) => {
|
|
314
310
|
if (change === null) return null;
|
|
315
311
|
try {
|
|
316
|
-
return scaleCoder?.dec(change) ?? null;
|
|
312
|
+
return scaleCoder?.value?.dec(change) ?? null;
|
|
317
313
|
} catch (cause) {
|
|
318
314
|
log.warn(error ?? `Failed to decode ${change}`, cause);
|
|
319
315
|
return null;
|
|
@@ -336,7 +332,7 @@ const encodeMetadata = ({
|
|
|
336
332
|
|
|
337
333
|
const encodeStateKey = (scaleCoder, error, ...args) => {
|
|
338
334
|
try {
|
|
339
|
-
return scaleCoder?.enc(...args);
|
|
335
|
+
return scaleCoder?.keys?.enc(...args);
|
|
340
336
|
} catch (cause) {
|
|
341
337
|
log.warn(error ?? `Failed to encode stateKey ${JSON.stringify(args)}`, cause);
|
|
342
338
|
return;
|
|
@@ -4,61 +4,13 @@ export { fromHex, toHex } from '@polkadot-api/utils';
|
|
|
4
4
|
import { metadata, Binary } from '@polkadot-api/substrate-bindings';
|
|
5
5
|
export { metadata, v14, v15 } from '@polkadot-api/substrate-bindings';
|
|
6
6
|
import anylogger from 'anylogger';
|
|
7
|
-
import { Struct,
|
|
7
|
+
import { Struct, u8, u32 } from 'scale-ts';
|
|
8
8
|
|
|
9
9
|
/** Constant: https://docs.substrate.io/build/application-development/#metadata-format */
|
|
10
10
|
const magicNumber = 1635018093;
|
|
11
11
|
|
|
12
12
|
var packageJson = {
|
|
13
|
-
name: "@talismn/scale"
|
|
14
|
-
version: "0.1.0",
|
|
15
|
-
author: "Talisman",
|
|
16
|
-
homepage: "https://talisman.xyz",
|
|
17
|
-
license: "GPL-3.0-or-later",
|
|
18
|
-
publishConfig: {
|
|
19
|
-
access: "public"
|
|
20
|
-
},
|
|
21
|
-
repository: {
|
|
22
|
-
directory: "packages/scale",
|
|
23
|
-
type: "git",
|
|
24
|
-
url: "https://github.com/talismansociety/talisman.git"
|
|
25
|
-
},
|
|
26
|
-
main: "dist/talismn-scale.cjs.js",
|
|
27
|
-
module: "dist/talismn-scale.esm.js",
|
|
28
|
-
files: [
|
|
29
|
-
"/dist"
|
|
30
|
-
],
|
|
31
|
-
engines: {
|
|
32
|
-
node: ">=18"
|
|
33
|
-
},
|
|
34
|
-
scripts: {
|
|
35
|
-
test: "jest",
|
|
36
|
-
lint: "eslint src --max-warnings 0",
|
|
37
|
-
clean: "rm -rf dist .turbo node_modules"
|
|
38
|
-
},
|
|
39
|
-
dependencies: {
|
|
40
|
-
"@polkadot-api/metadata-builders": "0.9.1",
|
|
41
|
-
"@polkadot-api/substrate-bindings": "0.9.3",
|
|
42
|
-
"@polkadot-api/utils": "0.1.2",
|
|
43
|
-
anylogger: "^1.0.11",
|
|
44
|
-
"scale-ts": "^1.6.1"
|
|
45
|
-
},
|
|
46
|
-
devDependencies: {
|
|
47
|
-
"@talismn/eslint-config": "workspace:*",
|
|
48
|
-
"@talismn/tsconfig": "workspace:*",
|
|
49
|
-
"@types/jest": "^29.5.14",
|
|
50
|
-
eslint: "^8.57.1",
|
|
51
|
-
jest: "^29.7",
|
|
52
|
-
"ts-jest": "^29.2.5",
|
|
53
|
-
typescript: "^5.6.3"
|
|
54
|
-
},
|
|
55
|
-
eslintConfig: {
|
|
56
|
-
root: true,
|
|
57
|
-
"extends": [
|
|
58
|
-
"@talismn/eslint-config/base"
|
|
59
|
-
]
|
|
60
|
-
}
|
|
61
|
-
};
|
|
13
|
+
name: "@talismn/scale"};
|
|
62
14
|
|
|
63
15
|
var log = anylogger(packageJson.name);
|
|
64
16
|
|
|
@@ -71,7 +23,7 @@ var log = anylogger(packageJson.name);
|
|
|
71
23
|
* E.g. if `palletsAndItems` is `{ pallet: "System", items: ["Account"] }`, then only the
|
|
72
24
|
* types used in the `System.Account` storage query will remain inside of metadata.lookups.
|
|
73
25
|
*/
|
|
74
|
-
const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
26
|
+
const compactMetadata = (metadata, palletsAndItems = [], runtimeApisAndMethods = [], extraKeepTypes = []) => {
|
|
75
27
|
// remove pallets we don't care about
|
|
76
28
|
metadata.pallets = metadata.pallets.filter(pallet =>
|
|
77
29
|
// keep this pallet if it's listed in `palletsAndItems`
|
|
@@ -80,8 +32,9 @@ const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
|
80
32
|
}) => pallet.name === palletName));
|
|
81
33
|
|
|
82
34
|
// remove fields we don't care about from each pallet, and extract types for each storage item we care about
|
|
83
|
-
const
|
|
35
|
+
const palletsKeepTypes = palletsAndItems.flatMap(({
|
|
84
36
|
pallet: palletName,
|
|
37
|
+
constants: constantNames,
|
|
85
38
|
items: itemNames
|
|
86
39
|
}) => {
|
|
87
40
|
const pallet = metadata.pallets.find(pallet => pallet.name === palletName);
|
|
@@ -92,7 +45,7 @@ const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
|
92
45
|
|
|
93
46
|
// remove pallet fields we don't care about
|
|
94
47
|
pallet.calls = undefined;
|
|
95
|
-
pallet.constants = [];
|
|
48
|
+
pallet.constants = constantNames ? pallet.constants.filter(constant => constantNames.includes(constant.name)) : [];
|
|
96
49
|
// v15 (NOT v14) has docs
|
|
97
50
|
if ("docs" in pallet) pallet.docs = [];
|
|
98
51
|
pallet.errors = undefined;
|
|
@@ -101,19 +54,54 @@ const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
|
101
54
|
|
|
102
55
|
// filter and extract storage items we care about
|
|
103
56
|
pallet.storage.items = pallet.storage.items.filter(item => itemNames.some(itemName => item.name === itemName));
|
|
104
|
-
return pallet.storage.items
|
|
57
|
+
return [...pallet.storage.items.flatMap(item => [
|
|
58
|
+
// each type can be either "Plain" or "Map"
|
|
59
|
+
// if it's "Plain" we only need to get the value type
|
|
60
|
+
// if it's a "Map" we want to keep both the key AND the value types
|
|
61
|
+
item.type.tag === "plain" && item.type.value, item.type.tag === "map" && item.type.value.key, item.type.tag === "map" && item.type.value.value]).filter(type => typeof type === "number"), ...pallet.constants.flatMap(constant => constant.type)];
|
|
105
62
|
});
|
|
106
63
|
|
|
64
|
+
// remove runtime apis we don't care about
|
|
65
|
+
let runtimeApisKeepTypes = [];
|
|
66
|
+
if ("apis" in metadata) {
|
|
67
|
+
// metadata is v15 (NOT v14)
|
|
68
|
+
|
|
69
|
+
// keep this api if it's listed in `runtimeApisAndMethods`
|
|
70
|
+
metadata.apis = metadata.apis.filter(runtimeApi => runtimeApisAndMethods.some(({
|
|
71
|
+
runtimeApi: runtimeApiName
|
|
72
|
+
}) => runtimeApi.name === runtimeApiName));
|
|
73
|
+
|
|
74
|
+
// remove methods we don't care about from each runtime api, and extract types for each call's params and result
|
|
75
|
+
runtimeApisKeepTypes = runtimeApisAndMethods.flatMap(({
|
|
76
|
+
runtimeApi: runtimeApiName,
|
|
77
|
+
methods: methodNames
|
|
78
|
+
}) => {
|
|
79
|
+
const runtimeApi = metadata.apis.find(runtimeApi => runtimeApi.name === runtimeApiName);
|
|
80
|
+
if (!runtimeApi) {
|
|
81
|
+
log.debug("Failed to find runtimeApi", runtimeApiName);
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// remove runtime fields we don't care about
|
|
86
|
+
runtimeApi.docs = [];
|
|
87
|
+
if (!runtimeApi.methods) return [];
|
|
88
|
+
|
|
89
|
+
// filter and extract methods we care about
|
|
90
|
+
runtimeApi.methods = runtimeApi.methods.filter(method => methodNames.some(methodName => method.name === methodName));
|
|
91
|
+
return runtimeApi.methods.flatMap(method => [
|
|
92
|
+
// each method has an array of input types (for the params)
|
|
93
|
+
...method.inputs.map(input => input.type),
|
|
94
|
+
// and one output type (for the result)
|
|
95
|
+
method.output]);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
107
99
|
// this is a set of type ids which we plan to keep in our compacted metadata
|
|
108
100
|
// anything not in this set will be deleted
|
|
109
101
|
// we start off with just the types of the state calls we plan to make,
|
|
110
102
|
// then we run those types through a function (addDependentTypes) which will also include
|
|
111
103
|
// all of the types which those types depend on - recursively
|
|
112
|
-
const keepTypes = new Set(
|
|
113
|
-
// each type can be either "Plain" or "Map"
|
|
114
|
-
// if it's "Plain" we only need to get the value type
|
|
115
|
-
// if it's a "Map" we want to keep both the key AND the value types
|
|
116
|
-
item.type.tag === "plain" && item.type.value, item.type.tag === "map" && item.type.value.key, item.type.tag === "map" && item.type.value.value]).filter(type => typeof type === "number"));
|
|
104
|
+
const keepTypes = new Set([...palletsKeepTypes, ...runtimeApisKeepTypes]);
|
|
117
105
|
extraKeepTypes?.forEach(type => keepTypes.add(type));
|
|
118
106
|
|
|
119
107
|
// recursively find all the types which our keepTypes depend on and add them to the keepTypes set
|
|
@@ -132,12 +120,6 @@ const compactMetadata = (metadata, palletsAndItems, extraKeepTypes) => {
|
|
|
132
120
|
return newTypeId ?? 0;
|
|
133
121
|
};
|
|
134
122
|
remapTypeIds(metadata, getNewTypeId);
|
|
135
|
-
|
|
136
|
-
// ditch the remaining data we don't need to keep in a miniMetata
|
|
137
|
-
if ("apis" in metadata) {
|
|
138
|
-
// metadata is v15 (NOT v14)
|
|
139
|
-
metadata.apis = [];
|
|
140
|
-
}
|
|
141
123
|
if ("address" in metadata.extrinsic) {
|
|
142
124
|
// metadata is v15 (NOT v14)
|
|
143
125
|
metadata.extrinsic.address = 0;
|
|
@@ -204,6 +186,7 @@ addedTypes = new Set()) => {
|
|
|
204
186
|
const remapTypeIds = (metadata, getNewTypeId) => {
|
|
205
187
|
remapLookupTypeIds(metadata, getNewTypeId);
|
|
206
188
|
remapStorageTypeIds(metadata, getNewTypeId);
|
|
189
|
+
remapRuntimeApisTypeIds(metadata, getNewTypeId);
|
|
207
190
|
};
|
|
208
191
|
const remapLookupTypeIds = (metadata, getNewTypeId) => {
|
|
209
192
|
for (const type of metadata.lookup) {
|
|
@@ -266,6 +249,19 @@ const remapStorageTypeIds = (metadata, getNewTypeId) => {
|
|
|
266
249
|
item.type.value.value = getNewTypeId(item.type.value.value);
|
|
267
250
|
}
|
|
268
251
|
}
|
|
252
|
+
for (const constant of pallet.constants ?? []) {
|
|
253
|
+
constant.type = getNewTypeId(constant.type);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
const remapRuntimeApisTypeIds = (metadata, getNewTypeId) => {
|
|
258
|
+
for (const runtimeApi of metadata.apis) {
|
|
259
|
+
for (const method of runtimeApi.methods ?? []) {
|
|
260
|
+
for (const input of method.inputs) {
|
|
261
|
+
input.type = getNewTypeId(input.type);
|
|
262
|
+
}
|
|
263
|
+
method.output = getNewTypeId(method.output);
|
|
264
|
+
}
|
|
269
265
|
}
|
|
270
266
|
};
|
|
271
267
|
|
|
@@ -309,7 +305,7 @@ const decodeMetadata = metadataRpc => {
|
|
|
309
305
|
const decodeScale = (scaleCoder, change, error) => {
|
|
310
306
|
if (change === null) return null;
|
|
311
307
|
try {
|
|
312
|
-
return scaleCoder?.dec(change) ?? null;
|
|
308
|
+
return scaleCoder?.value?.dec(change) ?? null;
|
|
313
309
|
} catch (cause) {
|
|
314
310
|
log.warn(error ?? `Failed to decode ${change}`, cause);
|
|
315
311
|
return null;
|
|
@@ -332,7 +328,7 @@ const encodeMetadata = ({
|
|
|
332
328
|
|
|
333
329
|
const encodeStateKey = (scaleCoder, error, ...args) => {
|
|
334
330
|
try {
|
|
335
|
-
return scaleCoder?.enc(...args);
|
|
331
|
+
return scaleCoder?.keys?.enc(...args);
|
|
336
332
|
} catch (cause) {
|
|
337
333
|
log.warn(error ?? `Failed to encode stateKey ${JSON.stringify(args)}`, cause);
|
|
338
334
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@talismn/scale",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"author": "Talisman",
|
|
5
5
|
"homepage": "https://talisman.xyz",
|
|
6
6
|
"license": "GPL-3.0-or-later",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"node": ">=18"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@polkadot-api/metadata-builders": "0.
|
|
25
|
-
"@polkadot-api/substrate-bindings": "0.
|
|
24
|
+
"@polkadot-api/metadata-builders": "0.10.2",
|
|
25
|
+
"@polkadot-api/substrate-bindings": "0.11.1",
|
|
26
26
|
"@polkadot-api/utils": "0.1.2",
|
|
27
27
|
"anylogger": "^1.0.11",
|
|
28
28
|
"scale-ts": "^1.6.1"
|