@dedot/codegen 0.18.7 → 1.0.0-next.a0f8d41e.25
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/chaintypes/generator/ConstsGen.js +1 -1
- package/chaintypes/generator/ErrorsGen.js +3 -3
- package/chaintypes/generator/EventsGen.js +3 -3
- package/chaintypes/generator/IndexGen.d.ts +1 -0
- package/chaintypes/generator/IndexGen.js +34 -2
- package/chaintypes/generator/JsonRpcGen.js +1 -1
- package/chaintypes/generator/QueryGen.js +4 -4
- package/chaintypes/generator/RuntimeApisGen.js +5 -5
- package/chaintypes/generator/TxGen.js +6 -10
- package/chaintypes/generator/ViewFunctionsGen.js +3 -3
- package/chaintypes/index.d.ts +22 -3
- package/chaintypes/index.js +63 -13
- package/chaintypes/templates/consts.hbs +1 -1
- package/chaintypes/templates/errors.hbs +1 -1
- package/chaintypes/templates/events.hbs +1 -1
- package/chaintypes/templates/index.hbs +10 -14
- package/chaintypes/templates/json-rpc.hbs +3 -3
- package/chaintypes/templates/query.hbs +1 -1
- package/chaintypes/templates/runtime.hbs +1 -1
- package/chaintypes/templates/tx.hbs +1 -1
- package/chaintypes/templates/view-functions.hbs +1 -1
- package/cjs/chaintypes/generator/ConstsGen.js +1 -1
- package/cjs/chaintypes/generator/ErrorsGen.js +3 -3
- package/cjs/chaintypes/generator/EventsGen.js +3 -3
- package/cjs/chaintypes/generator/IndexGen.js +34 -2
- package/cjs/chaintypes/generator/JsonRpcGen.js +1 -1
- package/cjs/chaintypes/generator/QueryGen.js +4 -4
- package/cjs/chaintypes/generator/RuntimeApisGen.js +5 -5
- package/cjs/chaintypes/generator/TxGen.js +6 -10
- package/cjs/chaintypes/generator/ViewFunctionsGen.js +3 -3
- package/cjs/chaintypes/index.js +61 -11
- package/cjs/chaintypes/templates/consts.hbs +1 -1
- package/cjs/chaintypes/templates/errors.hbs +1 -1
- package/cjs/chaintypes/templates/events.hbs +1 -1
- package/cjs/chaintypes/templates/index.hbs +10 -14
- package/cjs/chaintypes/templates/json-rpc.hbs +3 -3
- package/cjs/chaintypes/templates/query.hbs +1 -1
- package/cjs/chaintypes/templates/runtime.hbs +1 -1
- package/cjs/chaintypes/templates/tx.hbs +1 -1
- package/cjs/chaintypes/templates/view-functions.hbs +1 -1
- package/cjs/index.js +3 -0
- package/cjs/sol/generator/ConstructorQueryGen.js +1 -1
- package/cjs/sol/generator/IndexGen.js +1 -1
- package/cjs/sol/generator/QueryGen.js +1 -1
- package/cjs/sol/templates/index.hbs +7 -7
- package/cjs/typink/generator/ConstructorQueryGen.js +1 -1
- package/cjs/typink/generator/IndexGen.js +1 -1
- package/cjs/typink/generator/QueryGen.js +1 -1
- package/cjs/typink/templates/index.hbs +7 -7
- package/cjs/utils.js +27 -1
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +11 -11
- package/sol/generator/ConstructorQueryGen.js +1 -1
- package/sol/generator/IndexGen.js +1 -1
- package/sol/generator/QueryGen.js +1 -1
- package/sol/templates/index.hbs +7 -7
- package/typink/generator/ConstructorQueryGen.js +1 -1
- package/typink/generator/IndexGen.js +1 -1
- package/typink/generator/QueryGen.js +1 -1
- package/typink/templates/index.hbs +7 -7
- package/utils.d.ts +9 -0
- package/utils.js +25 -0
|
@@ -6,7 +6,7 @@ export class ConstsGen extends ApiGen {
|
|
|
6
6
|
generate(useSubPaths = false) {
|
|
7
7
|
const { pallets } = this.metadata;
|
|
8
8
|
this.typesGen.clearCache();
|
|
9
|
-
this.typesGen.typeImports.addKnownType('GenericChainConsts'
|
|
9
|
+
this.typesGen.typeImports.addKnownType('GenericChainConsts');
|
|
10
10
|
let defTypeOut = '';
|
|
11
11
|
for (let pallet of pallets) {
|
|
12
12
|
const typedConstants = pallet.constants.map((one) => {
|
|
@@ -6,7 +6,7 @@ export class ErrorsGen extends ApiGen {
|
|
|
6
6
|
generate(useSubPaths = false) {
|
|
7
7
|
const { pallets } = this.metadata;
|
|
8
8
|
this.typesGen.clearCache();
|
|
9
|
-
this.typesGen.typeImports.addKnownType('GenericChainErrors', 'GenericPalletError'
|
|
9
|
+
this.typesGen.typeImports.addKnownType('GenericChainErrors', 'GenericPalletError');
|
|
10
10
|
let defTypeOut = '';
|
|
11
11
|
for (let pallet of pallets) {
|
|
12
12
|
const errorTypeId = pallet.error;
|
|
@@ -25,10 +25,10 @@ export class ErrorsGen extends ApiGen {
|
|
|
25
25
|
}
|
|
26
26
|
return { ...def, docs };
|
|
27
27
|
})
|
|
28
|
-
.map(({ name, docs }) => `${commentBlock(docs)}${stringPascalCase(name)}: GenericPalletError
|
|
28
|
+
.map(({ name, docs }) => `${commentBlock(docs)}${stringPascalCase(name)}: GenericPalletError`)
|
|
29
29
|
.join(',\n')}
|
|
30
30
|
|
|
31
|
-
${commentBlock('Generic pallet error')}[error: string]: GenericPalletError
|
|
31
|
+
${commentBlock('Generic pallet error')}[error: string]: GenericPalletError,
|
|
32
32
|
},`;
|
|
33
33
|
}
|
|
34
34
|
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|
|
@@ -6,7 +6,7 @@ export class EventsGen extends ApiGen {
|
|
|
6
6
|
generate(useSubPaths = false) {
|
|
7
7
|
const { pallets } = this.metadata;
|
|
8
8
|
this.typesGen.clearCache();
|
|
9
|
-
this.typesGen.typeImports.addKnownType('GenericChainEvents', 'GenericPalletEvent'
|
|
9
|
+
this.typesGen.typeImports.addKnownType('GenericChainEvents', 'GenericPalletEvent');
|
|
10
10
|
let defTypeOut = '';
|
|
11
11
|
for (let pallet of pallets) {
|
|
12
12
|
const eventTypeId = pallet.event;
|
|
@@ -34,10 +34,10 @@ export class EventsGen extends ApiGen {
|
|
|
34
34
|
}
|
|
35
35
|
return { ...def, genericParts, docs };
|
|
36
36
|
})
|
|
37
|
-
.map(({ name, docs, genericParts }) => `${commentBlock(docs)}${stringPascalCase(name)}: GenericPalletEvent
|
|
37
|
+
.map(({ name, docs, genericParts }) => `${commentBlock(docs)}${stringPascalCase(name)}: GenericPalletEvent<${genericParts.join(', ')}>`)
|
|
38
38
|
.join(',\n')}
|
|
39
39
|
|
|
40
|
-
${commentBlock('Generic pallet event')}[prop: string]: GenericPalletEvent
|
|
40
|
+
${commentBlock('Generic pallet event')}[prop: string]: GenericPalletEvent,
|
|
41
41
|
},`;
|
|
42
42
|
}
|
|
43
43
|
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|
|
@@ -12,7 +12,7 @@ export class IndexGen {
|
|
|
12
12
|
const interfaceName = this.interfaceName;
|
|
13
13
|
// Clear cache and setup type imports
|
|
14
14
|
this.typesGen.clearCache();
|
|
15
|
-
this.typesGen.typeImports.addKnownType('GenericSubstrateApi', 'GenericChainKnownTypes'
|
|
15
|
+
this.typesGen.typeImports.addKnownType('GenericSubstrateApi', 'GenericChainKnownTypes');
|
|
16
16
|
// Extract type IDs from metadata.extrinsic
|
|
17
17
|
const { callTypeId, addressTypeId, signatureTypeId, signedExtensions } = this.typesGen.metadata.extrinsic;
|
|
18
18
|
// Generate proper TypeScript types using typeOut format (0, true)
|
|
@@ -25,8 +25,10 @@ export class IndexGen {
|
|
|
25
25
|
const signedExtensionTypes = signedExtensions.map(({ typeId }) => this.typesGen.generateType(typeId, 1, true));
|
|
26
26
|
extraType = `[${signedExtensionTypes.join(', ')}]`;
|
|
27
27
|
}
|
|
28
|
+
// Generate AssetId type from ChargeAssetTxPayment extension
|
|
29
|
+
const assetIdType = this.findAssetIdType(signedExtensions) ?? 'undefined';
|
|
28
30
|
// Add generated types to imports
|
|
29
|
-
const generatedTypes = [runtimeCallType, addressType, signatureType, extraType];
|
|
31
|
+
const generatedTypes = [runtimeCallType, addressType, signatureType, extraType, assetIdType];
|
|
30
32
|
this.typesGen.addTypeImport(generatedTypes);
|
|
31
33
|
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|
|
32
34
|
const interfaceDocs = commentBlock([
|
|
@@ -42,6 +44,36 @@ export class IndexGen {
|
|
|
42
44
|
signatureType,
|
|
43
45
|
runtimeCallType,
|
|
44
46
|
extraType,
|
|
47
|
+
assetIdType,
|
|
45
48
|
}));
|
|
46
49
|
}
|
|
50
|
+
findAssetIdType(signedExtensions) {
|
|
51
|
+
// Find ChargeAssetTxPayment extension
|
|
52
|
+
const chargeAssetExt = signedExtensions.find((ext) => ext.ident.endsWith('ChargeAssetTxPayment'));
|
|
53
|
+
if (!chargeAssetExt)
|
|
54
|
+
return undefined;
|
|
55
|
+
try {
|
|
56
|
+
const extensionTypeDef = this.typesGen.registry.findType(chargeAssetExt.typeId);
|
|
57
|
+
if (extensionTypeDef.typeDef.type !== 'Struct')
|
|
58
|
+
return undefined;
|
|
59
|
+
const assetIdField = extensionTypeDef.typeDef.value.fields.find((f) => f.name === 'asset_id');
|
|
60
|
+
if (!assetIdField)
|
|
61
|
+
return undefined;
|
|
62
|
+
// Check if wrapped in Option - need to unwrap to get inner type
|
|
63
|
+
const assetIdTypeDef = this.typesGen.registry.findType(assetIdField.typeId);
|
|
64
|
+
let assetIdTypeId = assetIdField.typeId;
|
|
65
|
+
// Option is an Enum type with path ['Option']
|
|
66
|
+
if (assetIdTypeDef.typeDef.type === 'Enum' && assetIdTypeDef.path.join('::') === 'Option') {
|
|
67
|
+
// Get the inner type from the 'Some' variant
|
|
68
|
+
const someVariant = assetIdTypeDef.typeDef.value.members.find((m) => m.name === 'Some');
|
|
69
|
+
if (someVariant && someVariant.fields.length > 0) {
|
|
70
|
+
assetIdTypeId = someVariant.fields[0].typeId;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return this.typesGen.generateType(assetIdTypeId, 1, true);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
47
79
|
}
|
|
@@ -42,7 +42,7 @@ export class JsonRpcGen extends ApiGen {
|
|
|
42
42
|
}
|
|
43
43
|
generate(useSubPaths = false) {
|
|
44
44
|
this.typesGen.clearCache();
|
|
45
|
-
this.typesGen.typeImports.addKnownType('GenericJsonRpcApis'
|
|
45
|
+
this.typesGen.typeImports.addKnownType('GenericJsonRpcApis');
|
|
46
46
|
this.typesGen.typeImports.addKnownJsonRpcType('JsonRpcApis');
|
|
47
47
|
const toExclude = Object.values(subscriptionsInfo).flat();
|
|
48
48
|
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|
|
@@ -6,7 +6,7 @@ export class QueryGen extends ApiGen {
|
|
|
6
6
|
generate(useSubPaths = false) {
|
|
7
7
|
const { pallets } = this.metadata;
|
|
8
8
|
this.typesGen.clearCache();
|
|
9
|
-
this.typesGen.typeImports.addKnownType('GenericChainStorage', 'GenericStorageQuery', 'Callback'
|
|
9
|
+
this.typesGen.typeImports.addKnownType('GenericChainStorage', 'GenericStorageQuery', 'Callback');
|
|
10
10
|
let defTypeOut = '';
|
|
11
11
|
for (let pallet of pallets) {
|
|
12
12
|
const storage = pallet.storage;
|
|
@@ -15,17 +15,17 @@ export class QueryGen extends ApiGen {
|
|
|
15
15
|
const queries = storage.entries.map((one) => this.#generateEntry(one));
|
|
16
16
|
const queryDefs = queries.map(({ name, valueType, keyType, docs, keyTypeOut }) => {
|
|
17
17
|
if (keyTypeOut) {
|
|
18
|
-
return `${commentBlock(docs)}${name}: GenericStorageQuery<
|
|
18
|
+
return `${commentBlock(docs)}${name}: GenericStorageQuery<(${keyType}) => ${valueType}, ${keyTypeOut}>`;
|
|
19
19
|
}
|
|
20
20
|
else {
|
|
21
|
-
return `${commentBlock(docs)}${name}: GenericStorageQuery<
|
|
21
|
+
return `${commentBlock(docs)}${name}: GenericStorageQuery<(${keyType}) => ${valueType}>`;
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
defTypeOut += commentBlock(`Pallet \`${pallet.name}\`'s storage queries`);
|
|
25
25
|
defTypeOut += `${stringCamelCase(pallet.name)}: {
|
|
26
26
|
${queryDefs.join(',\n')}
|
|
27
27
|
|
|
28
|
-
${commentBlock('Generic pallet storage query')}[storage: string]: GenericStorageQuery
|
|
28
|
+
${commentBlock('Generic pallet storage query')}[storage: string]: GenericStorageQuery;
|
|
29
29
|
},`;
|
|
30
30
|
}
|
|
31
31
|
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|
|
@@ -14,7 +14,7 @@ export class RuntimeApisGen extends ApiGen {
|
|
|
14
14
|
}
|
|
15
15
|
generate(useSubPaths = false) {
|
|
16
16
|
this.typesGen.clearCache();
|
|
17
|
-
this.typesGen.typeImports.addKnownType('GenericRuntimeApis', 'GenericRuntimeApiMethod'
|
|
17
|
+
this.typesGen.typeImports.addKnownType('GenericRuntimeApis', 'GenericRuntimeApiMethod');
|
|
18
18
|
let runtimeCallsOut = '';
|
|
19
19
|
if (this.metadata.apis.length > 0) {
|
|
20
20
|
this.metadata.apis.forEach((runtimeApi) => {
|
|
@@ -23,7 +23,7 @@ export class RuntimeApisGen extends ApiGen {
|
|
|
23
23
|
runtimeCallsOut += `${stringCamelCase(runtimeApiName)}: {
|
|
24
24
|
${methods.map((method) => this.#generateMethodDef(runtimeApiName, method)).join('\n')}
|
|
25
25
|
|
|
26
|
-
${commentBlock('Generic runtime api call')}[method: string]: GenericRuntimeApiMethod
|
|
26
|
+
${commentBlock('Generic runtime api call')}[method: string]: GenericRuntimeApiMethod
|
|
27
27
|
}`;
|
|
28
28
|
});
|
|
29
29
|
}
|
|
@@ -40,7 +40,7 @@ export class RuntimeApisGen extends ApiGen {
|
|
|
40
40
|
}))
|
|
41
41
|
.join('\n')}
|
|
42
42
|
|
|
43
|
-
${commentBlock('Generic runtime api call')}[method: string]: GenericRuntimeApiMethod
|
|
43
|
+
${commentBlock('Generic runtime api call')}[method: string]: GenericRuntimeApiMethod
|
|
44
44
|
}`;
|
|
45
45
|
});
|
|
46
46
|
}
|
|
@@ -69,7 +69,7 @@ export class RuntimeApisGen extends ApiGen {
|
|
|
69
69
|
.map(({ name, isOptional, plainType }) => `${stringCamelCase(name)}${isOptional ? '?' : ''}: ${plainType}`)
|
|
70
70
|
.join(', ');
|
|
71
71
|
const typeOut = this.#getGeneratedTypeName(type, false);
|
|
72
|
-
return `${commentBlock(docs, '\n', defaultDocs, typedParams.map(({ plainType, name }) => `@param {${plainType}} ${name}`))}${methodName}: GenericRuntimeApiMethod<
|
|
72
|
+
return `${commentBlock(docs, '\n', defaultDocs, typedParams.map(({ plainType, name }) => `@param {${plainType}} ${name}`))}${methodName}: GenericRuntimeApiMethod<(${paramsOut}) => Promise<${typeOut}>>`;
|
|
73
73
|
}
|
|
74
74
|
#generateMethodDef(runtimeApiName, methodDef) {
|
|
75
75
|
const { name: methodName, inputs, output, docs, deprecationInfo } = methodDef;
|
|
@@ -94,7 +94,7 @@ export class RuntimeApisGen extends ApiGen {
|
|
|
94
94
|
const paramsOut = typedInputs
|
|
95
95
|
.map(({ name, type, isOptional }) => `${stringCamelCase(name)}${isOptional ? '?' : ''}: ${type}`)
|
|
96
96
|
.join(', ');
|
|
97
|
-
return `${commentBlock(docs, '\n', defaultDocs, typedInputs.map(({ type, name }) => `@param {${type}} ${name}`), deprecationComments)}${stringCamelCase(methodName)}: GenericRuntimeApiMethod<
|
|
97
|
+
return `${commentBlock(docs, '\n', defaultDocs, typedInputs.map(({ type, name }) => `@param {${type}} ${name}`), deprecationComments)}${stringCamelCase(methodName)}: GenericRuntimeApiMethod<(${paramsOut}) => Promise<${typeOut}>>`;
|
|
98
98
|
}
|
|
99
99
|
#targetRuntimeApiSpecs() {
|
|
100
100
|
const specs = Object.entries(this.runtimeApis).map(([runtimeApiHash, version]) => {
|
|
@@ -5,7 +5,7 @@ export class TxGen extends ApiGen {
|
|
|
5
5
|
generate(useSubPaths = false) {
|
|
6
6
|
const { pallets, types } = this.metadata;
|
|
7
7
|
this.typesGen.clearCache();
|
|
8
|
-
this.typesGen.typeImports.addKnownType('GenericChainTx', 'GenericTxCall', '
|
|
8
|
+
this.typesGen.typeImports.addKnownType('GenericChainTx', 'GenericTxCall', 'GenericChainKnownTypes', 'ISubmittableExtrinsic', 'ISubmittableResult', 'IRuntimeTxCall');
|
|
9
9
|
const { callTypeId, addressTypeId, signatureTypeId } = this.metadata.extrinsic;
|
|
10
10
|
const callTypeIn = this.typesGen.generateType(callTypeId, 1);
|
|
11
11
|
const addressTypeIn = this.typesGen.generateType(addressTypeId, 1);
|
|
@@ -47,23 +47,19 @@ export class TxGen extends ApiGen {
|
|
|
47
47
|
if (deprecationComments.length > 0) {
|
|
48
48
|
deprecationComments.unshift('\n');
|
|
49
49
|
}
|
|
50
|
-
return `${commentBlock(docs, '\n', params.map((p) => `@param {${p.type}} ${p.normalizedName} ${p.docs}`), deprecationComments)}${functionName}: GenericTxCall<
|
|
50
|
+
return `${commentBlock(docs, '\n', params.map((p) => `@param {${p.type}} ${p.normalizedName} ${p.docs}`), deprecationComments)}${functionName}: GenericTxCall<(${params.map((p) => `${p.normalizedName}: ${p.type}`).join(', ')}) => ChainSubmittableExtrinsic<${callInput}, ChainKnownTypes>>`;
|
|
51
51
|
})
|
|
52
52
|
.join(',\n')}
|
|
53
53
|
|
|
54
|
-
${commentBlock('Generic pallet tx call')}[callName: string]: GenericTxCall<
|
|
54
|
+
${commentBlock('Generic pallet tx call')}[callName: string]: GenericTxCall<TxCall<ChainKnownTypes>>,
|
|
55
55
|
},`;
|
|
56
56
|
}
|
|
57
57
|
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|
|
58
|
-
// TODO make explicit separate type for Extra
|
|
59
58
|
const defTypes = `
|
|
60
|
-
export type ChainSubmittableExtrinsic<
|
|
61
|
-
Extrinsic<${addressTypeIn}, T, ${signatureTypeIn},
|
|
62
|
-
(Rv extends RpcV2
|
|
63
|
-
? ISubmittableExtrinsic<ISubmittableResult<FrameSystemEventRecord>>
|
|
64
|
-
: ISubmittableExtrinsicLegacy<ISubmittableResult<FrameSystemEventRecord>>)
|
|
59
|
+
export type ChainSubmittableExtrinsic<T extends IRuntimeTxCall = ${callTypeIn}, ChainKnownTypes extends GenericChainKnownTypes = GenericChainKnownTypes> =
|
|
60
|
+
Extrinsic<${addressTypeIn}, T, ${signatureTypeIn}, ChainKnownTypes['Extra']> & ISubmittableExtrinsic<ISubmittableResult<FrameSystemEventRecord>, ChainKnownTypes['AssetId']>
|
|
65
61
|
|
|
66
|
-
export type TxCall<
|
|
62
|
+
export type TxCall<ChainKnownTypes extends GenericChainKnownTypes = GenericChainKnownTypes> = (...args: any[]) => ChainSubmittableExtrinsic<${callTypeIn}, ChainKnownTypes>;
|
|
67
63
|
`;
|
|
68
64
|
const template = compileTemplate('chaintypes/templates/tx.hbs');
|
|
69
65
|
return beautifySourceCode(template({ importTypes, defTypes, txDefsOut }));
|
|
@@ -7,7 +7,7 @@ export class ViewFunctionsGen extends ApiGen {
|
|
|
7
7
|
const { pallets } = this.metadata;
|
|
8
8
|
this.typesGen.clearCache();
|
|
9
9
|
this.typesGen.typeImports.addKnownType('GenericChainViewFunctions', // --
|
|
10
|
-
'GenericViewFunction'
|
|
10
|
+
'GenericViewFunction');
|
|
11
11
|
let defTypeOut = '';
|
|
12
12
|
for (let pallet of pallets) {
|
|
13
13
|
if (!pallet.viewFunctions || pallet.viewFunctions.length === 0)
|
|
@@ -24,13 +24,13 @@ export class ViewFunctionsGen extends ApiGen {
|
|
|
24
24
|
}
|
|
25
25
|
const params = vf.inputs.map((input) => `${stringCamelCase(input.name)}: ${this.typesGen.generateType(input.typeId, 1)}`);
|
|
26
26
|
const outputType = this.typesGen.generateType(vf.output, 1, true);
|
|
27
|
-
return `${commentBlock(docs)}${stringCamelCase(vf.name)}: GenericViewFunction<
|
|
27
|
+
return `${commentBlock(docs)}${stringCamelCase(vf.name)}: GenericViewFunction<(${params.join(', ')}) => Promise<${outputType}>>`;
|
|
28
28
|
});
|
|
29
29
|
defTypeOut += commentBlock(`Pallet \`${pallet.name}\`'s view functions`);
|
|
30
30
|
defTypeOut += `${stringCamelCase(pallet.name)}: {
|
|
31
31
|
${viewFns.join(',\n')}
|
|
32
32
|
|
|
33
|
-
${commentBlock('Generic pallet view function')}[name: string]: GenericViewFunction
|
|
33
|
+
${commentBlock('Generic pallet view function')}[name: string]: GenericViewFunction;
|
|
34
34
|
},`;
|
|
35
35
|
}
|
|
36
36
|
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|
package/chaintypes/index.d.ts
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
|
-
import { SubstrateRuntimeVersion } from '@dedot/api';
|
|
1
|
+
import { DedotClient, SubstrateRuntimeVersion } from '@dedot/api';
|
|
2
2
|
import { MetadataLatest } from '@dedot/codecs';
|
|
3
3
|
import { GeneratedResult } from '../types.js';
|
|
4
|
-
export
|
|
5
|
-
|
|
4
|
+
export interface GenerateTypesFromEndpointOptions {
|
|
5
|
+
chain: string;
|
|
6
|
+
endpoint?: string;
|
|
7
|
+
client?: DedotClient;
|
|
8
|
+
outDir?: string;
|
|
9
|
+
extension?: string;
|
|
10
|
+
useSubPaths?: boolean;
|
|
11
|
+
at?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function generateTypesFromEndpoint(options: GenerateTypesFromEndpointOptions): Promise<GeneratedResult>;
|
|
14
|
+
export interface GenerateTypesOptions {
|
|
15
|
+
chain: string;
|
|
16
|
+
metadata: MetadataLatest;
|
|
17
|
+
rpcMethods: string[];
|
|
18
|
+
runtimeVersion: SubstrateRuntimeVersion;
|
|
19
|
+
outDir?: string;
|
|
20
|
+
extension?: string;
|
|
21
|
+
useSubPaths?: boolean;
|
|
22
|
+
appendSpecVersion?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function generateTypes(options: GenerateTypesOptions): Promise<GeneratedResult>;
|
package/chaintypes/index.js
CHANGED
|
@@ -1,20 +1,68 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DedotClient } from '@dedot/api';
|
|
2
2
|
import { WsProvider } from '@dedot/providers';
|
|
3
|
-
import { stringDashCase, stringPascalCase } from '@dedot/utils';
|
|
3
|
+
import { assert, stringDashCase, stringPascalCase } from '@dedot/utils';
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import * as path from 'path';
|
|
6
|
+
import { resolveBlockHash } from '../utils.js';
|
|
6
7
|
import { ConstsGen, ErrorsGen, EventsGen, IndexGen, JsonRpcGen, QueryGen, RuntimeApisGen, TxGen, ViewFunctionsGen, TypesGen, } from './generator/index.js';
|
|
7
|
-
export async function generateTypesFromEndpoint(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
export async function generateTypesFromEndpoint(options) {
|
|
9
|
+
const { chain, endpoint, client: providedClient, outDir, extension = 'd.ts', useSubPaths = false, at } = options;
|
|
10
|
+
// Validate that either endpoint or client is provided
|
|
11
|
+
if (!endpoint && !providedClient) {
|
|
12
|
+
throw new Error('Either "endpoint" or "client" must be provided');
|
|
13
|
+
}
|
|
14
|
+
if (endpoint && providedClient) {
|
|
15
|
+
throw new Error('Cannot provide both "endpoint" and "client"');
|
|
16
|
+
}
|
|
17
|
+
// Create client if not provided
|
|
18
|
+
const client = providedClient || (await DedotClient.legacy(new WsProvider({ endpoint: endpoint, retryDelayMs: 0, timeout: 0 })));
|
|
19
|
+
const shouldDisconnect = !providedClient;
|
|
20
|
+
try {
|
|
21
|
+
const { methods } = await client.rpc.rpc_methods();
|
|
22
|
+
// Resolve block hash if `at` is provided
|
|
23
|
+
let blockHash;
|
|
24
|
+
if (at) {
|
|
25
|
+
blockHash = await resolveBlockHash(client, at);
|
|
26
|
+
}
|
|
27
|
+
// Get runtime version and metadata at the specified block
|
|
28
|
+
let runtimeVersion;
|
|
29
|
+
let metadata;
|
|
30
|
+
if (blockHash) {
|
|
31
|
+
// Get the header of the target block
|
|
32
|
+
const header = await client.block.header(blockHash);
|
|
33
|
+
assert(`Header not found for block hash: ${blockHash}`);
|
|
34
|
+
const childBlockHash = await client.rpc.chain_getBlockHash(header.number + 1);
|
|
35
|
+
const clientAt = await client.at(childBlockHash);
|
|
36
|
+
runtimeVersion = clientAt.runtimeVersion;
|
|
37
|
+
metadata = clientAt.metadata;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
runtimeVersion = client.runtimeVersion;
|
|
41
|
+
metadata = client.metadata;
|
|
42
|
+
}
|
|
43
|
+
const resolvedChain = chain || runtimeVersion.specName || 'local';
|
|
44
|
+
return await generateTypes({
|
|
45
|
+
chain: resolvedChain,
|
|
46
|
+
metadata: metadata.latest,
|
|
47
|
+
rpcMethods: methods,
|
|
48
|
+
runtimeVersion,
|
|
49
|
+
outDir,
|
|
50
|
+
extension,
|
|
51
|
+
useSubPaths,
|
|
52
|
+
appendSpecVersion: !!blockHash,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
if (shouldDisconnect) {
|
|
57
|
+
await client.disconnect();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
15
60
|
}
|
|
16
|
-
export async function generateTypes(
|
|
17
|
-
const
|
|
61
|
+
export async function generateTypes(options) {
|
|
62
|
+
const { chain, metadata, rpcMethods, runtimeVersion, outDir = '.', extension = 'd.ts', useSubPaths = false, appendSpecVersion = false, } = options;
|
|
63
|
+
// Build folder suffix with spec version if requested
|
|
64
|
+
const folderSuffix = appendSpecVersion ? `-${runtimeVersion.specVersion}` : '';
|
|
65
|
+
const dirPath = path.resolve(outDir, stringDashCase(chain) + folderSuffix);
|
|
18
66
|
const defTypesFileName = path.join(dirPath, `types.${extension}`);
|
|
19
67
|
const constsTypesFileName = path.join(dirPath, `consts.${extension}`);
|
|
20
68
|
const queryTypesFileName = path.join(dirPath, `query.${extension}`);
|
|
@@ -28,7 +76,9 @@ export async function generateTypes(chain, metadata, rpcMethods, runtimeVersion,
|
|
|
28
76
|
if (!fs.existsSync(dirPath)) {
|
|
29
77
|
fs.mkdirSync(dirPath, { recursive: true });
|
|
30
78
|
}
|
|
31
|
-
|
|
79
|
+
// Build interface suffix with spec version if requested
|
|
80
|
+
const interfaceSuffix = appendSpecVersion ? runtimeVersion.specVersion : '';
|
|
81
|
+
const interfaceName = `${stringPascalCase(chain)}Api${interfaceSuffix}`;
|
|
32
82
|
const typesGen = new TypesGen(metadata);
|
|
33
83
|
const constsGen = new ConstsGen(typesGen);
|
|
34
84
|
const queryGen = new QueryGen(typesGen);
|
|
@@ -17,22 +17,18 @@ interface ChainKnownTypes extends GenericChainKnownTypes {
|
|
|
17
17
|
Signature: {{{signatureType}}};
|
|
18
18
|
RuntimeCall: {{{runtimeCallType}}};
|
|
19
19
|
Extra: {{{extraType}}};
|
|
20
|
+
AssetId: {{{assetIdType}}};
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
export interface
|
|
23
|
-
rpc: ChainJsonRpcApis
|
|
24
|
-
consts: ChainConsts
|
|
25
|
-
query: ChainStorage
|
|
26
|
-
errors: ChainErrors
|
|
27
|
-
events: ChainEvents
|
|
28
|
-
call: RuntimeApis
|
|
29
|
-
view: ChainViewFunctions
|
|
30
|
-
tx: ChainTx<
|
|
23
|
+
{{interfaceDocs}}export interface {{{interfaceName}}} extends GenericSubstrateApi {
|
|
24
|
+
rpc: ChainJsonRpcApis;
|
|
25
|
+
consts: ChainConsts;
|
|
26
|
+
query: ChainStorage;
|
|
27
|
+
errors: ChainErrors;
|
|
28
|
+
events: ChainEvents;
|
|
29
|
+
call: RuntimeApis;
|
|
30
|
+
view: ChainViewFunctions;
|
|
31
|
+
tx: ChainTx<ChainKnownTypes>;
|
|
31
32
|
|
|
32
33
|
types: ChainKnownTypes;
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
-
{{interfaceDocs}}export interface {{{interfaceName}}} {
|
|
36
|
-
legacy: Versioned{{{interfaceName}}}<RpcLegacy>;
|
|
37
|
-
v2: Versioned{{{interfaceName}}}<RpcV2>;
|
|
38
|
-
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
{{{ importTypes }}}
|
|
4
4
|
|
|
5
|
-
export type ChainJsonRpcApis
|
|
5
|
+
export type ChainJsonRpcApis =
|
|
6
6
|
{{#if jsonRpcMethods.length}}
|
|
7
|
-
Pick<JsonRpcApis, {{{jsonRpcMethods}}}> & GenericJsonRpcApis
|
|
7
|
+
Pick<JsonRpcApis, {{{jsonRpcMethods}}}> & GenericJsonRpcApis;
|
|
8
8
|
{{else}}
|
|
9
|
-
JsonRpcApis & GenericJsonRpcApis
|
|
9
|
+
JsonRpcApis & GenericJsonRpcApis;
|
|
10
10
|
{{/if}}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
{{{ defTypes }}}
|
|
6
6
|
|
|
7
|
-
export interface ChainTx<
|
|
7
|
+
export interface ChainTx<ChainKnownTypes extends GenericChainKnownTypes = GenericChainKnownTypes> extends GenericChainTx<TxCall<ChainKnownTypes>> {
|
|
8
8
|
{{{ txDefsOut }}}
|
|
9
9
|
}
|
|
@@ -9,7 +9,7 @@ class ConstsGen extends ApiGen_js_1.ApiGen {
|
|
|
9
9
|
generate(useSubPaths = false) {
|
|
10
10
|
const { pallets } = this.metadata;
|
|
11
11
|
this.typesGen.clearCache();
|
|
12
|
-
this.typesGen.typeImports.addKnownType('GenericChainConsts'
|
|
12
|
+
this.typesGen.typeImports.addKnownType('GenericChainConsts');
|
|
13
13
|
let defTypeOut = '';
|
|
14
14
|
for (let pallet of pallets) {
|
|
15
15
|
const typedConstants = pallet.constants.map((one) => {
|
|
@@ -9,7 +9,7 @@ class ErrorsGen extends ApiGen_js_1.ApiGen {
|
|
|
9
9
|
generate(useSubPaths = false) {
|
|
10
10
|
const { pallets } = this.metadata;
|
|
11
11
|
this.typesGen.clearCache();
|
|
12
|
-
this.typesGen.typeImports.addKnownType('GenericChainErrors', 'GenericPalletError'
|
|
12
|
+
this.typesGen.typeImports.addKnownType('GenericChainErrors', 'GenericPalletError');
|
|
13
13
|
let defTypeOut = '';
|
|
14
14
|
for (let pallet of pallets) {
|
|
15
15
|
const errorTypeId = pallet.error;
|
|
@@ -28,10 +28,10 @@ class ErrorsGen extends ApiGen_js_1.ApiGen {
|
|
|
28
28
|
}
|
|
29
29
|
return { ...def, docs };
|
|
30
30
|
})
|
|
31
|
-
.map(({ name, docs }) => `${(0, utils_js_1.commentBlock)(docs)}${(0, utils_1.stringPascalCase)(name)}: GenericPalletError
|
|
31
|
+
.map(({ name, docs }) => `${(0, utils_js_1.commentBlock)(docs)}${(0, utils_1.stringPascalCase)(name)}: GenericPalletError`)
|
|
32
32
|
.join(',\n')}
|
|
33
33
|
|
|
34
|
-
${(0, utils_js_1.commentBlock)('Generic pallet error')}[error: string]: GenericPalletError
|
|
34
|
+
${(0, utils_js_1.commentBlock)('Generic pallet error')}[error: string]: GenericPalletError,
|
|
35
35
|
},`;
|
|
36
36
|
}
|
|
37
37
|
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|
|
@@ -9,7 +9,7 @@ class EventsGen extends ApiGen_js_1.ApiGen {
|
|
|
9
9
|
generate(useSubPaths = false) {
|
|
10
10
|
const { pallets } = this.metadata;
|
|
11
11
|
this.typesGen.clearCache();
|
|
12
|
-
this.typesGen.typeImports.addKnownType('GenericChainEvents', 'GenericPalletEvent'
|
|
12
|
+
this.typesGen.typeImports.addKnownType('GenericChainEvents', 'GenericPalletEvent');
|
|
13
13
|
let defTypeOut = '';
|
|
14
14
|
for (let pallet of pallets) {
|
|
15
15
|
const eventTypeId = pallet.event;
|
|
@@ -37,10 +37,10 @@ class EventsGen extends ApiGen_js_1.ApiGen {
|
|
|
37
37
|
}
|
|
38
38
|
return { ...def, genericParts, docs };
|
|
39
39
|
})
|
|
40
|
-
.map(({ name, docs, genericParts }) => `${(0, utils_js_1.commentBlock)(docs)}${(0, utils_1.stringPascalCase)(name)}: GenericPalletEvent
|
|
40
|
+
.map(({ name, docs, genericParts }) => `${(0, utils_js_1.commentBlock)(docs)}${(0, utils_1.stringPascalCase)(name)}: GenericPalletEvent<${genericParts.join(', ')}>`)
|
|
41
41
|
.join(',\n')}
|
|
42
42
|
|
|
43
|
-
${(0, utils_js_1.commentBlock)('Generic pallet event')}[prop: string]: GenericPalletEvent
|
|
43
|
+
${(0, utils_js_1.commentBlock)('Generic pallet event')}[prop: string]: GenericPalletEvent,
|
|
44
44
|
},`;
|
|
45
45
|
}
|
|
46
46
|
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|
|
@@ -15,7 +15,7 @@ class IndexGen {
|
|
|
15
15
|
const interfaceName = this.interfaceName;
|
|
16
16
|
// Clear cache and setup type imports
|
|
17
17
|
this.typesGen.clearCache();
|
|
18
|
-
this.typesGen.typeImports.addKnownType('GenericSubstrateApi', 'GenericChainKnownTypes'
|
|
18
|
+
this.typesGen.typeImports.addKnownType('GenericSubstrateApi', 'GenericChainKnownTypes');
|
|
19
19
|
// Extract type IDs from metadata.extrinsic
|
|
20
20
|
const { callTypeId, addressTypeId, signatureTypeId, signedExtensions } = this.typesGen.metadata.extrinsic;
|
|
21
21
|
// Generate proper TypeScript types using typeOut format (0, true)
|
|
@@ -28,8 +28,10 @@ class IndexGen {
|
|
|
28
28
|
const signedExtensionTypes = signedExtensions.map(({ typeId }) => this.typesGen.generateType(typeId, 1, true));
|
|
29
29
|
extraType = `[${signedExtensionTypes.join(', ')}]`;
|
|
30
30
|
}
|
|
31
|
+
// Generate AssetId type from ChargeAssetTxPayment extension
|
|
32
|
+
const assetIdType = this.findAssetIdType(signedExtensions) ?? 'undefined';
|
|
31
33
|
// Add generated types to imports
|
|
32
|
-
const generatedTypes = [runtimeCallType, addressType, signatureType, extraType];
|
|
34
|
+
const generatedTypes = [runtimeCallType, addressType, signatureType, extraType, assetIdType];
|
|
33
35
|
this.typesGen.addTypeImport(generatedTypes);
|
|
34
36
|
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|
|
35
37
|
const interfaceDocs = (0, utils_js_1.commentBlock)([
|
|
@@ -45,7 +47,37 @@ class IndexGen {
|
|
|
45
47
|
signatureType,
|
|
46
48
|
runtimeCallType,
|
|
47
49
|
extraType,
|
|
50
|
+
assetIdType,
|
|
48
51
|
}));
|
|
49
52
|
}
|
|
53
|
+
findAssetIdType(signedExtensions) {
|
|
54
|
+
// Find ChargeAssetTxPayment extension
|
|
55
|
+
const chargeAssetExt = signedExtensions.find((ext) => ext.ident.endsWith('ChargeAssetTxPayment'));
|
|
56
|
+
if (!chargeAssetExt)
|
|
57
|
+
return undefined;
|
|
58
|
+
try {
|
|
59
|
+
const extensionTypeDef = this.typesGen.registry.findType(chargeAssetExt.typeId);
|
|
60
|
+
if (extensionTypeDef.typeDef.type !== 'Struct')
|
|
61
|
+
return undefined;
|
|
62
|
+
const assetIdField = extensionTypeDef.typeDef.value.fields.find((f) => f.name === 'asset_id');
|
|
63
|
+
if (!assetIdField)
|
|
64
|
+
return undefined;
|
|
65
|
+
// Check if wrapped in Option - need to unwrap to get inner type
|
|
66
|
+
const assetIdTypeDef = this.typesGen.registry.findType(assetIdField.typeId);
|
|
67
|
+
let assetIdTypeId = assetIdField.typeId;
|
|
68
|
+
// Option is an Enum type with path ['Option']
|
|
69
|
+
if (assetIdTypeDef.typeDef.type === 'Enum' && assetIdTypeDef.path.join('::') === 'Option') {
|
|
70
|
+
// Get the inner type from the 'Some' variant
|
|
71
|
+
const someVariant = assetIdTypeDef.typeDef.value.members.find((m) => m.name === 'Some');
|
|
72
|
+
if (someVariant && someVariant.fields.length > 0) {
|
|
73
|
+
assetIdTypeId = someVariant.fields[0].typeId;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return this.typesGen.generateType(assetIdTypeId, 1, true);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
50
82
|
}
|
|
51
83
|
exports.IndexGen = IndexGen;
|
|
@@ -45,7 +45,7 @@ class JsonRpcGen extends ApiGen_js_1.ApiGen {
|
|
|
45
45
|
}
|
|
46
46
|
generate(useSubPaths = false) {
|
|
47
47
|
this.typesGen.clearCache();
|
|
48
|
-
this.typesGen.typeImports.addKnownType('GenericJsonRpcApis'
|
|
48
|
+
this.typesGen.typeImports.addKnownType('GenericJsonRpcApis');
|
|
49
49
|
this.typesGen.typeImports.addKnownJsonRpcType('JsonRpcApis');
|
|
50
50
|
const toExclude = Object.values(api_1.subscriptionsInfo).flat();
|
|
51
51
|
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|