@dedot/codegen 0.12.1-next.c7fd0a6c.2 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -82,33 +82,124 @@ export declare abstract class ApiGen {
82
82
  };
83
83
  default: `0x${string}`;
84
84
  docs: string[];
85
+ deprecationInfo: {
86
+ type: "NotDeprecated";
87
+ } | {
88
+ type: "DeprecatedWithoutNote";
89
+ } | {
90
+ type: "Deprecated";
91
+ value: {
92
+ note: string;
93
+ since: string | undefined;
94
+ };
95
+ };
85
96
  }[];
86
97
  } | undefined;
87
- calls: number | undefined;
88
- event: number | undefined;
98
+ calls: {
99
+ typeId: number;
100
+ deprecationInfo: readonly [ReadonlyMap<number, {
101
+ type: "DeprecatedWithoutNote";
102
+ } | {
103
+ type: "Deprecated";
104
+ value: {
105
+ note: string;
106
+ since: string | undefined;
107
+ };
108
+ }>];
109
+ } | undefined;
110
+ event: {
111
+ typeId: number;
112
+ deprecationInfo: readonly [ReadonlyMap<number, {
113
+ type: "DeprecatedWithoutNote";
114
+ } | {
115
+ type: "Deprecated";
116
+ value: {
117
+ note: string;
118
+ since: string | undefined;
119
+ };
120
+ }>];
121
+ } | undefined;
89
122
  constants: {
90
123
  name: string;
91
124
  typeId: number;
92
125
  value: `0x${string}`;
93
126
  docs: string[];
127
+ deprecationInfo: {
128
+ type: "NotDeprecated";
129
+ } | {
130
+ type: "DeprecatedWithoutNote";
131
+ } | {
132
+ type: "Deprecated";
133
+ value: {
134
+ note: string;
135
+ since: string | undefined;
136
+ };
137
+ };
138
+ }[];
139
+ error: {
140
+ typeId: number;
141
+ deprecationInfo: readonly [ReadonlyMap<number, {
142
+ type: "DeprecatedWithoutNote";
143
+ } | {
144
+ type: "Deprecated";
145
+ value: {
146
+ note: string;
147
+ since: string | undefined;
148
+ };
149
+ }>];
150
+ } | undefined;
151
+ associatedTypes: {
152
+ name: string;
153
+ typeId: number;
154
+ docs: string[];
155
+ }[];
156
+ viewFunctions: {
157
+ id: readonly [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number];
158
+ name: string;
159
+ inputs: {
160
+ name: string;
161
+ typeId: number;
162
+ }[];
163
+ output: number;
164
+ docs: string[];
165
+ deprecationInfo: {
166
+ type: "NotDeprecated";
167
+ } | {
168
+ type: "DeprecatedWithoutNote";
169
+ } | {
170
+ type: "Deprecated";
171
+ value: {
172
+ note: string;
173
+ since: string | undefined;
174
+ };
175
+ };
94
176
  }[];
95
- error: number | undefined;
96
177
  index: number;
97
178
  docs: string[];
179
+ deprecationInfo: {
180
+ type: "NotDeprecated";
181
+ } | {
182
+ type: "DeprecatedWithoutNote";
183
+ } | {
184
+ type: "Deprecated";
185
+ value: {
186
+ note: string;
187
+ since: string | undefined;
188
+ };
189
+ };
98
190
  }[];
99
191
  extrinsic: {
100
- version: number;
192
+ versions: number[];
101
193
  addressTypeId: number;
102
- callTypeId: number;
103
194
  signatureTypeId: number;
104
- extraTypeId: number;
195
+ callTypeId: number;
196
+ signedExtensionsByVersion: ReadonlyMap<number, number[]>;
105
197
  signedExtensions: {
106
198
  ident: string;
107
199
  typeId: number;
108
200
  additionalSigned: number;
109
201
  }[];
110
202
  };
111
- runtimeType: number;
112
203
  apis: {
113
204
  name: string;
114
205
  methods: {
@@ -119,8 +210,31 @@ export declare abstract class ApiGen {
119
210
  }[];
120
211
  output: number;
121
212
  docs: string[];
213
+ deprecationInfo: {
214
+ type: "NotDeprecated";
215
+ } | {
216
+ type: "DeprecatedWithoutNote";
217
+ } | {
218
+ type: "Deprecated";
219
+ value: {
220
+ note: string;
221
+ since: string | undefined;
222
+ };
223
+ };
122
224
  }[];
123
225
  docs: string[];
226
+ version: number;
227
+ deprecationInfo: {
228
+ type: "NotDeprecated";
229
+ } | {
230
+ type: "DeprecatedWithoutNote";
231
+ } | {
232
+ type: "Deprecated";
233
+ value: {
234
+ note: string;
235
+ since: string | undefined;
236
+ };
237
+ };
124
238
  }[];
125
239
  outerEnums: {
126
240
  callEnumTypeId: number;
@@ -12,7 +12,7 @@ export class ErrorsGen extends ApiGen {
12
12
  if (!errorTypeId) {
13
13
  continue;
14
14
  }
15
- const errorDefs = this.#getErrorDefs(errorTypeId);
15
+ const errorDefs = this.#getErrorDefs(errorTypeId.typeId);
16
16
  defTypeOut += commentBlock(`Pallet \`${pallet.name}\`'s errors`);
17
17
  defTypeOut += `${stringCamelCase(pallet.name)}: {
18
18
  ${errorDefs
@@ -12,7 +12,7 @@ export class EventsGen extends ApiGen {
12
12
  if (!eventTypeId) {
13
13
  continue;
14
14
  }
15
- const eventDefs = this.#getEventDefs(eventTypeId);
15
+ const eventDefs = this.#getEventDefs(eventTypeId.typeId);
16
16
  const flatMembers = eventDefs.every((d) => d.fields.length === 0);
17
17
  defTypeOut += commentBlock(`Pallet \`${pallet.name}\`'s events`);
18
18
  defTypeOut += `${stringCamelCase(pallet.name)}: {
@@ -17,7 +17,7 @@ export class TxGen extends ApiGen {
17
17
  for (let pallet of pallets) {
18
18
  if (pallet.calls === undefined)
19
19
  continue;
20
- const { typeDef } = types[pallet.calls];
20
+ const { typeDef } = types[pallet.calls.typeId];
21
21
  if (typeDef.type !== 'Enum')
22
22
  continue;
23
23
  const isFlatEnum = typeDef.value.members.every((m) => m.fields.length === 0);
@@ -15,7 +15,7 @@ class ErrorsGen extends ApiGen_js_1.ApiGen {
15
15
  if (!errorTypeId) {
16
16
  continue;
17
17
  }
18
- const errorDefs = this.#getErrorDefs(errorTypeId);
18
+ const errorDefs = this.#getErrorDefs(errorTypeId.typeId);
19
19
  defTypeOut += (0, utils_js_1.commentBlock)(`Pallet \`${pallet.name}\`'s errors`);
20
20
  defTypeOut += `${(0, utils_1.stringCamelCase)(pallet.name)}: {
21
21
  ${errorDefs
@@ -15,7 +15,7 @@ class EventsGen extends ApiGen_js_1.ApiGen {
15
15
  if (!eventTypeId) {
16
16
  continue;
17
17
  }
18
- const eventDefs = this.#getEventDefs(eventTypeId);
18
+ const eventDefs = this.#getEventDefs(eventTypeId.typeId);
19
19
  const flatMembers = eventDefs.every((d) => d.fields.length === 0);
20
20
  defTypeOut += (0, utils_js_1.commentBlock)(`Pallet \`${pallet.name}\`'s events`);
21
21
  defTypeOut += `${(0, utils_1.stringCamelCase)(pallet.name)}: {
@@ -20,7 +20,7 @@ class TxGen extends index_js_1.ApiGen {
20
20
  for (let pallet of pallets) {
21
21
  if (pallet.calls === undefined)
22
22
  continue;
23
- const { typeDef } = types[pallet.calls];
23
+ const { typeDef } = types[pallet.calls.typeId];
24
24
  if (typeDef.type !== 'Enum')
25
25
  continue;
26
26
  const isFlatEnum = typeDef.value.members.every((m) => m.fields.length === 0);
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.IndexGen = void 0;
4
+ const contracts_1 = require("@dedot/contracts");
4
5
  const index_js_1 = require("../../shared/index.js");
5
6
  const utils_js_1 = require("../../utils.js");
6
7
  class IndexGen {
@@ -18,9 +19,10 @@ class IndexGen {
18
19
  const langErrorName = this.typesGen.cleanPath(this.contractMetadata.types[langErrorId].type.path);
19
20
  const typeImports = new index_js_1.TypeImports();
20
21
  typeImports.addKnownType('VersionedGenericSubstrateApi', 'RpcVersion', 'RpcV2');
21
- typeImports.addContractType('GenericContractApi');
22
+ typeImports.addContractType('GenericContractApi', 'WithLazyStorage');
22
23
  typeImports.addChainType('SubstrateApi');
23
24
  typeImports.addPortableType(langErrorName);
25
+ const [rootStorageName, lazyStorageName] = this.#extractRootStorageNames(typeImports);
24
26
  const { contract: { name = '', version = '', authors = [] }, source: { language = '' }, } = this.contractMetadata;
25
27
  const interfaceDocs = (0, utils_js_1.commentBlock)([
26
28
  `@name: ${interfaceName}`, // prettier-end-here
@@ -31,7 +33,28 @@ class IndexGen {
31
33
  ]);
32
34
  const importTypes = typeImports.toImports({ useSubPaths });
33
35
  const template = (0, utils_js_1.compileTemplate)('typink/templates/index.hbs');
34
- return (0, utils_js_1.beautifySourceCode)(template({ interfaceName, interfaceDocs, langErrorName, importTypes }));
36
+ return (0, utils_js_1.beautifySourceCode)(template({
37
+ interfaceName,
38
+ interfaceDocs,
39
+ langErrorName,
40
+ importTypes,
41
+ rootStorageName,
42
+ lazyStorageName,
43
+ }));
44
+ }
45
+ #extractRootStorageNames(typeImports) {
46
+ try {
47
+ (0, contracts_1.ensureStorageApiSupports)(this.contractMetadata.version);
48
+ const { ty: rootStorageId } = this.contractMetadata.storage.root;
49
+ const rootStorageName = this.typesGen.cleanPath(this.contractMetadata.types[rootStorageId].type.path);
50
+ typeImports.addPortableType(rootStorageName);
51
+ return [rootStorageName, `WithLazyStorage<${rootStorageName}>`];
52
+ }
53
+ catch {
54
+ const names = ['GenericRootStorage', 'GenericLazyStorage'];
55
+ typeImports.addContractType(...names);
56
+ return names;
57
+ }
35
58
  }
36
59
  }
37
60
  exports.IndexGen = IndexGen;
@@ -26,6 +26,33 @@ class TypesGen extends index_js_1.BaseTypesGen {
26
26
  const template = (0, utils_js_1.compileTemplate)('typink/templates/types.hbs');
27
27
  return (0, utils_js_1.beautifySourceCode)(template({ importTypes, defTypeOut }));
28
28
  }
29
+ generateType(typeId, nestedLevel = 0, typeOut = false) {
30
+ const generatedType = super.generateType(typeId, nestedLevel, typeOut);
31
+ // Lazy types should be inside a wrapper structure/object
32
+ // So we only check for lazy type when nestedLevel > 0
33
+ if (nestedLevel > 0) {
34
+ const types = this.contractMetadata.types;
35
+ const typeDef = types.find(({ id }) => id == typeId);
36
+ const lazyType = (0, contracts_1.isLazyType)(typeDef.type.path);
37
+ if (!lazyType)
38
+ return generatedType;
39
+ const [p1, p2] = typeDef.type.params;
40
+ if (lazyType === contracts_1.KnownLazyType.LAZY) {
41
+ const ValueType = super.generateType(p1.type, 1, true);
42
+ return `{ get(): Promise<${ValueType} | undefined> }`;
43
+ }
44
+ else if (lazyType === contracts_1.KnownLazyType.MAPPING) {
45
+ const KeyType = super.generateType(p1.type, 1);
46
+ const ValueType = super.generateType(p2.type, 1, true);
47
+ return `{ get(arg: ${KeyType}): Promise<${ValueType} | undefined> }`;
48
+ }
49
+ else if (lazyType === contracts_1.KnownLazyType.STORAGE_VEC) {
50
+ const ValueType = super.generateType(p1.type, 1, true);
51
+ return `{ len(): Promise<number>; get(index: number): Promise<${ValueType} | undefined> }`;
52
+ }
53
+ }
54
+ return generatedType;
55
+ }
29
56
  shouldGenerateTypeIn(id) {
30
57
  const { messages, constructors } = this.contractMetadata.spec;
31
58
  return ((this.#idInParameters(id, messages) || this.#idInParameters(id, constructors)) && this.#includeKnownTypes(id));
@@ -10,7 +10,8 @@ const fs_1 = __importDefault(require("fs"));
10
10
  const path_1 = __importDefault(require("path"));
11
11
  const index_js_1 = require("./generator/index.js");
12
12
  async function generateContractTypes(metadata, contract, outDir = '.', extension = 'd.ts', useSubPaths = false) {
13
- let contractMetadata = typeof metadata === 'string' ? (0, contracts_1.parseRawMetadata)(metadata) : metadata;
13
+ let contractMetadata = typeof metadata === 'string' ? JSON.parse(metadata) : metadata;
14
+ (0, contracts_1.ensureSupportedContractMetadataVersion)(contractMetadata);
14
15
  const contractName = contract || contractMetadata.contract.name;
15
16
  const dirPath = path_1.default.resolve(outDir, (0, utils_1.stringDashCase)(contractName));
16
17
  const typesFileName = path_1.default.join(dirPath, `types.${extension}`);
@@ -15,8 +15,14 @@ export * from './types.js';
15
15
  constructorQuery: ConstructorQuery<ChainApi[Rv]>;
16
16
  constructorTx: ConstructorTx<ChainApi[Rv]>;
17
17
  events: ContractEvents<ChainApi[Rv]>;
18
+ storage: {
19
+ root(): Promise<{{{rootStorageName}}}>;
20
+ lazy(): {{{lazyStorageName}}};
21
+ };
18
22
 
19
23
  types: {
24
+ RootStorage: {{{rootStorageName}}};
25
+ LazyStorage: {{{lazyStorageName}}};
20
26
  LangError: {{{langErrorName}}};
21
27
  ChainApi: ChainApi[Rv];
22
28
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dedot/codegen",
3
- "version": "0.12.1-next.c7fd0a6c.2+c7fd0a6c",
3
+ "version": "0.13.0",
4
4
  "description": "Generate types",
5
5
  "author": "Thang X. Vu <thang@dedot.dev>",
6
6
  "homepage": "https://dedot.dev",
@@ -18,16 +18,16 @@
18
18
  "copy": "cp -R ./src/chaintypes/templates ./dist/chaintypes && cp -R ./src/chaintypes/templates ./dist/cjs/chaintypes && cp -R ./src/typink/templates ./dist/typink && cp -R ./src/typink/templates ./dist/cjs/typink"
19
19
  },
20
20
  "dependencies": {
21
- "@dedot/api": "0.12.1-next.c7fd0a6c.2+c7fd0a6c",
22
- "@dedot/codecs": "0.12.1-next.c7fd0a6c.2+c7fd0a6c",
23
- "@dedot/contracts": "0.12.1-next.c7fd0a6c.2+c7fd0a6c",
24
- "@dedot/providers": "0.12.1-next.c7fd0a6c.2+c7fd0a6c",
25
- "@dedot/runtime-specs": "0.12.1-next.c7fd0a6c.2+c7fd0a6c",
26
- "@dedot/shape": "0.12.1-next.c7fd0a6c.2+c7fd0a6c",
27
- "@dedot/types": "0.12.1-next.c7fd0a6c.2+c7fd0a6c",
28
- "@dedot/utils": "0.12.1-next.c7fd0a6c.2+c7fd0a6c",
21
+ "@dedot/api": "0.13.0",
22
+ "@dedot/codecs": "0.13.0",
23
+ "@dedot/contracts": "0.13.0",
24
+ "@dedot/providers": "0.13.0",
25
+ "@dedot/runtime-specs": "0.13.0",
26
+ "@dedot/shape": "0.13.0",
27
+ "@dedot/types": "0.13.0",
28
+ "@dedot/utils": "0.13.0",
29
29
  "handlebars": "^4.7.8",
30
- "prettier": "^3.4.2"
30
+ "prettier": "^3.5.3"
31
31
  },
32
32
  "publishConfig": {
33
33
  "access": "public",
@@ -37,7 +37,7 @@
37
37
  "node": ">=18"
38
38
  },
39
39
  "license": "Apache-2.0",
40
- "gitHead": "c7fd0a6c35b80d78cbf6dead68b12b2820f16f0b",
40
+ "gitHead": "b9193d170fc63ebd64b75f37f8276a7159e2af55",
41
41
  "module": "./index.js",
42
42
  "types": "./index.d.ts",
43
43
  "exports": {
@@ -1,6 +1,7 @@
1
1
  import { ContractMetadata } from '@dedot/contracts';
2
2
  import { TypesGen } from './TypesGen.js';
3
3
  export declare class IndexGen {
4
+ #private;
4
5
  interfaceName: string;
5
6
  contractMetadata: ContractMetadata;
6
7
  typesGen: TypesGen;
@@ -1,3 +1,4 @@
1
+ import { ensureStorageApiSupports } from '@dedot/contracts';
1
2
  import { TypeImports } from '../../shared/index.js';
2
3
  import { beautifySourceCode, commentBlock, compileTemplate } from '../../utils.js';
3
4
  export class IndexGen {
@@ -15,9 +16,10 @@ export class IndexGen {
15
16
  const langErrorName = this.typesGen.cleanPath(this.contractMetadata.types[langErrorId].type.path);
16
17
  const typeImports = new TypeImports();
17
18
  typeImports.addKnownType('VersionedGenericSubstrateApi', 'RpcVersion', 'RpcV2');
18
- typeImports.addContractType('GenericContractApi');
19
+ typeImports.addContractType('GenericContractApi', 'WithLazyStorage');
19
20
  typeImports.addChainType('SubstrateApi');
20
21
  typeImports.addPortableType(langErrorName);
22
+ const [rootStorageName, lazyStorageName] = this.#extractRootStorageNames(typeImports);
21
23
  const { contract: { name = '', version = '', authors = [] }, source: { language = '' }, } = this.contractMetadata;
22
24
  const interfaceDocs = commentBlock([
23
25
  `@name: ${interfaceName}`, // prettier-end-here
@@ -28,6 +30,27 @@ export class IndexGen {
28
30
  ]);
29
31
  const importTypes = typeImports.toImports({ useSubPaths });
30
32
  const template = compileTemplate('typink/templates/index.hbs');
31
- return beautifySourceCode(template({ interfaceName, interfaceDocs, langErrorName, importTypes }));
33
+ return beautifySourceCode(template({
34
+ interfaceName,
35
+ interfaceDocs,
36
+ langErrorName,
37
+ importTypes,
38
+ rootStorageName,
39
+ lazyStorageName,
40
+ }));
41
+ }
42
+ #extractRootStorageNames(typeImports) {
43
+ try {
44
+ ensureStorageApiSupports(this.contractMetadata.version);
45
+ const { ty: rootStorageId } = this.contractMetadata.storage.root;
46
+ const rootStorageName = this.typesGen.cleanPath(this.contractMetadata.types[rootStorageId].type.path);
47
+ typeImports.addPortableType(rootStorageName);
48
+ return [rootStorageName, `WithLazyStorage<${rootStorageName}>`];
49
+ }
50
+ catch {
51
+ const names = ['GenericRootStorage', 'GenericLazyStorage'];
52
+ typeImports.addContractType(...names);
53
+ return names;
54
+ }
32
55
  }
33
56
  }
@@ -6,5 +6,6 @@ export declare class TypesGen extends BaseTypesGen {
6
6
  contractMetadata: ContractMetadata;
7
7
  constructor(contractMetadata: ContractMetadata);
8
8
  generate(useSubPaths?: boolean): Promise<string>;
9
+ generateType(typeId: TypeId, nestedLevel?: number, typeOut?: boolean): string;
9
10
  shouldGenerateTypeIn(id: TypeId): boolean;
10
11
  }
@@ -1,4 +1,4 @@
1
- import { extractContractTypes, normalizeContractTypeDef } from '@dedot/contracts';
1
+ import { extractContractTypes, isLazyType, KnownLazyType, normalizeContractTypeDef, } from '@dedot/contracts';
2
2
  import { BaseTypesGen } from '../../shared/index.js';
3
3
  import { beautifySourceCode, compileTemplate } from '../../utils.js';
4
4
  const SKIP_TYPES = ['Result', 'Option'];
@@ -23,6 +23,33 @@ export class TypesGen extends BaseTypesGen {
23
23
  const template = compileTemplate('typink/templates/types.hbs');
24
24
  return beautifySourceCode(template({ importTypes, defTypeOut }));
25
25
  }
26
+ generateType(typeId, nestedLevel = 0, typeOut = false) {
27
+ const generatedType = super.generateType(typeId, nestedLevel, typeOut);
28
+ // Lazy types should be inside a wrapper structure/object
29
+ // So we only check for lazy type when nestedLevel > 0
30
+ if (nestedLevel > 0) {
31
+ const types = this.contractMetadata.types;
32
+ const typeDef = types.find(({ id }) => id == typeId);
33
+ const lazyType = isLazyType(typeDef.type.path);
34
+ if (!lazyType)
35
+ return generatedType;
36
+ const [p1, p2] = typeDef.type.params;
37
+ if (lazyType === KnownLazyType.LAZY) {
38
+ const ValueType = super.generateType(p1.type, 1, true);
39
+ return `{ get(): Promise<${ValueType} | undefined> }`;
40
+ }
41
+ else if (lazyType === KnownLazyType.MAPPING) {
42
+ const KeyType = super.generateType(p1.type, 1);
43
+ const ValueType = super.generateType(p2.type, 1, true);
44
+ return `{ get(arg: ${KeyType}): Promise<${ValueType} | undefined> }`;
45
+ }
46
+ else if (lazyType === KnownLazyType.STORAGE_VEC) {
47
+ const ValueType = super.generateType(p1.type, 1, true);
48
+ return `{ len(): Promise<number>; get(index: number): Promise<${ValueType} | undefined> }`;
49
+ }
50
+ }
51
+ return generatedType;
52
+ }
26
53
  shouldGenerateTypeIn(id) {
27
54
  const { messages, constructors } = this.contractMetadata.spec;
28
55
  return ((this.#idInParameters(id, messages) || this.#idInParameters(id, constructors)) && this.#includeKnownTypes(id));
package/typink/index.js CHANGED
@@ -1,10 +1,11 @@
1
- import { parseRawMetadata } from '@dedot/contracts';
1
+ import { ensureSupportedContractMetadataVersion } from '@dedot/contracts';
2
2
  import { stringDashCase, stringPascalCase } from '@dedot/utils';
3
3
  import fs from 'fs';
4
4
  import path from 'path';
5
- import { IndexGen, QueryGen, EventsGen, TxGen, TypesGen, ConstructorTxGen, ConstructorQueryGen, } from './generator/index.js';
5
+ import { ConstructorQueryGen, ConstructorTxGen, EventsGen, IndexGen, QueryGen, TxGen, TypesGen, } from './generator/index.js';
6
6
  export async function generateContractTypes(metadata, contract, outDir = '.', extension = 'd.ts', useSubPaths = false) {
7
- let contractMetadata = typeof metadata === 'string' ? parseRawMetadata(metadata) : metadata;
7
+ let contractMetadata = typeof metadata === 'string' ? JSON.parse(metadata) : metadata;
8
+ ensureSupportedContractMetadataVersion(contractMetadata);
8
9
  const contractName = contract || contractMetadata.contract.name;
9
10
  const dirPath = path.resolve(outDir, stringDashCase(contractName));
10
11
  const typesFileName = path.join(dirPath, `types.${extension}`);
@@ -15,8 +15,14 @@ export * from './types.js';
15
15
  constructorQuery: ConstructorQuery<ChainApi[Rv]>;
16
16
  constructorTx: ConstructorTx<ChainApi[Rv]>;
17
17
  events: ContractEvents<ChainApi[Rv]>;
18
+ storage: {
19
+ root(): Promise<{{{rootStorageName}}}>;
20
+ lazy(): {{{lazyStorageName}}};
21
+ };
18
22
 
19
23
  types: {
24
+ RootStorage: {{{rootStorageName}}};
25
+ LazyStorage: {{{lazyStorageName}}};
20
26
  LangError: {{{langErrorName}}};
21
27
  ChainApi: ChainApi[Rv];
22
28
  };