@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: Array<{
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, space?: string | number) => string;
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 items = palletsAndItems.flatMap(({
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(items.flatMap(item => [
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 items = palletsAndItems.flatMap(({
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(items.flatMap(item => [
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, u32, u8 } from 'scale-ts';
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 items = palletsAndItems.flatMap(({
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(items.flatMap(item => [
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.0",
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.9.1",
25
- "@polkadot-api/substrate-bindings": "0.9.3",
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"