diff --git a/packages/api-derive/src/balances/fees.ts b/packages/api-derive/src/balances/fees.ts index e477622c32..b664420617 100644 --- a/packages/api-derive/src/balances/fees.ts +++ b/packages/api-derive/src/balances/fees.ts @@ -19,9 +19,9 @@ function queryV2 (api: ApiInterfaceRx): Observable { return of([ // get values from api.const for substrate versions post spec_version: 101 // https://github.com/paritytech/substrate/pull/2883/files#diff-5e5e1c3aec9ddfde0a9054d062ab3db9R131 - api.consts.balances.creationFee as Balance, - api.consts.balances.existentialDeposit as Balance, - api.consts.balances.transferFee as Balance, + api.consts.balances.creationFee, + api.consts.balances.existentialDeposit, + api.consts.balances.transferFee, paymentBase.transactionBaseFee as Balance, paymentBase.transactionByteFee as Balance ]); diff --git a/packages/api-derive/src/elections/voterPositions.ts b/packages/api-derive/src/elections/voterPositions.ts index 01e283d817..4ce1e40350 100644 --- a/packages/api-derive/src/elections/voterPositions.ts +++ b/packages/api-derive/src/elections/voterPositions.ts @@ -4,7 +4,7 @@ import { AccountId, SetIndex } from '@polkadot/types/interfaces'; import { ApiInterfaceRx } from '@polkadot/api/types'; -import { Vec, Option, createType } from '@polkadot/types'; +import { Vec, Option, createType, u32 } from '@polkadot/types'; import { DerivedVoterPositions } from '../types'; import BN from 'bn.js'; @@ -15,11 +15,11 @@ import { memo } from '../util'; function queryElections (api: ApiInterfaceRx): Observable { return api.query.elections.nextVoterSet().pipe( - switchMap((nextVoterSet: SetIndex): Observable<[BN, Vec>[]]> => combineLatest( - of(api.consts.elections.voterSetSize) as any as Observable, - api.query.elections.voters.multi([...Array(+nextVoterSet + 1).keys()].map((_, i): [number] => [i])) as any as Observable>[]> + switchMap((nextVoterSet: SetIndex): Observable<[u32, Vec>[]]> => combineLatest( + of(api.consts.elections.voterSetSize), + api.query.elections.voters.multi>>([...Array(+nextVoterSet + 1).keys()].map((_, i): [number] => [i])) )), - map((result: [BN, Vec>[]]): DerivedVoterPositions => { + map((result: [u32, Vec>[]]): DerivedVoterPositions => { const [setSize, voters] = result; return voters.reduce((result: DerivedVoterPositions, vec, setIndex): DerivedVoterPositions => { diff --git a/packages/api-derive/src/session/info.ts b/packages/api-derive/src/session/info.ts index 82815bbf38..f2a4a2779c 100644 --- a/packages/api-derive/src/session/info.ts +++ b/packages/api-derive/src/session/info.ts @@ -87,7 +87,7 @@ function infoLatestAura (api: ApiInterfaceRx): Observable { return api.derive.session.indexes().pipe( map((indexes): DerivedSessionInfo => createDerivedLatest([ - [false, createType('u64', 1), api.consts.staking.sessionsPerEra as SessionIndex], + [false, createType('u64', 1), api.consts.staking.sessionsPerEra], indexes, [createType('u64', 1), createType('u64', 1), createType('u64', 1), createType('SessionIndex', 1)] ]) @@ -107,7 +107,7 @@ function infoLatestBabe (api: ApiInterfaceRx): Observable { ]).pipe( map(([indexes, slots]: [DeriveSessionIndexes, ResultSlots]): DerivedSessionInfo => createDerivedLatest([ - [true, api.consts.babe.epochDuration as u64, api.consts.staking.sessionsPerEra as SessionIndex], + [true, api.consts.babe.epochDuration, api.consts.staking.sessionsPerEra], indexes, slots ]) diff --git a/packages/api/src/checkTypes.manual.ts b/packages/api/src/checkTypes.manual.ts index 9c2fc6e98c..b7466d52d3 100644 --- a/packages/api/src/checkTypes.manual.ts +++ b/packages/api/src/checkTypes.manual.ts @@ -4,7 +4,6 @@ // Simple non-runnable checks to test type definitions in the editor itself -import { ConstantCodec } from '@polkadot/metadata/Decorated/types'; import { Balance, Header, Index } from '@polkadot/types/interfaces'; import { IExtrinsic, IMethod } from '@polkadot/types/types'; @@ -18,8 +17,9 @@ import { SubmittableResult } from './'; function consts (api: ApiPromise): void { // constants has actual value & metadata console.log( - api.consts.balances.creationFee.toHex(), - (api.consts.balances.creationFee as ConstantCodec).meta.documentation.map((s): string => s.toString()).join('') + api.consts.foo.bar, + api.consts.balances.creationFee.toNumber(), + api.consts.balances.creationFee.meta.documentation.map((s): string => s.toString()).join('') ); } diff --git a/packages/api/src/consts.types.ts b/packages/api/src/consts.types.ts new file mode 100644 index 0000000000..ee3398ec41 --- /dev/null +++ b/packages/api/src/consts.types.ts @@ -0,0 +1,95 @@ +// Auto-generated via `yarn build:interfaces`, do not edit +/* eslint-disable @typescript-eslint/no-empty-interface */ + +import { Bytes, u32, u64 } from '@polkadot/types'; +import { Balance, BalanceOf, BlockNumber, Moment, Permill } from '@polkadot/types/interfaces/runtime'; +import { Gas } from '@polkadot/types/interfaces/contracts'; +import { VoteIndex } from '@polkadot/types/interfaces/elections'; +import { SessionIndex } from '@polkadot/types/interfaces/session'; +import { EraIndex } from '@polkadot/types/interfaces/staking'; +import { Codec } from '@polkadot/types/types'; + +declare module '@polkadot/metadata/Decorated/types' { + export interface Constants { + babe: { + [index: string]: Codec; + epochDuration: u64 & ConstantCodec; + expectedBlockTime: Moment & ConstantCodec; + }; + timestamp: { + [index: string]: Codec; + minimumPeriod: Moment & ConstantCodec; + }; + balances: { + [index: string]: Codec; + existentialDeposit: Balance & ConstantCodec; + transferFee: Balance & ConstantCodec; + creationFee: Balance & ConstantCodec; + transactionBaseFee: Balance & ConstantCodec; + transactionByteFee: Balance & ConstantCodec; + }; + staking: { + [index: string]: Codec; + sessionsPerEra: SessionIndex & ConstantCodec; + bondingDuration: EraIndex & ConstantCodec; + }; + session: { + [index: string]: Codec; + dedupKeyPrefix: Bytes & ConstantCodec; + }; + democracy: { + [index: string]: Codec; + enactmentPeriod: BlockNumber & ConstantCodec; + launchPeriod: BlockNumber & ConstantCodec; + votingPeriod: BlockNumber & ConstantCodec; + minimumDeposit: BalanceOf & ConstantCodec; + emergencyVotingPeriod: BlockNumber & ConstantCodec; + cooloffPeriod: BlockNumber & ConstantCodec; + }; + elections: { + [index: string]: Codec; + candidacyBond: BalanceOf & ConstantCodec; + votingBond: BalanceOf & ConstantCodec; + votingFee: BalanceOf & ConstantCodec; + presentSlashPerVoter: BalanceOf & ConstantCodec; + carryCount: u32 & ConstantCodec; + inactiveGracePeriod: VoteIndex & ConstantCodec; + votingPeriod: BlockNumber & ConstantCodec; + minimumVotingLock: BalanceOf & ConstantCodec; + decayRatio: u32 & ConstantCodec; + voterSetSize: u32 & ConstantCodec; + approvalSetSize: u32 & ConstantCodec; + }; + finalityTracker: { + [index: string]: Codec; + windowSize: BlockNumber & ConstantCodec; + reportLatency: BlockNumber & ConstantCodec; + }; + treasury: { + [index: string]: Codec; + proposalBond: Permill & ConstantCodec; + proposalBondMinimum: BalanceOf & ConstantCodec; + spendPeriod: BlockNumber & ConstantCodec; + burn: Permill & ConstantCodec; + }; + contracts: { + [index: string]: Codec; + signedClaimHandicap: BlockNumber & ConstantCodec; + tombstoneDeposit: BalanceOf & ConstantCodec; + storageSizeOffset: u32 & ConstantCodec; + rentByteFee: BalanceOf & ConstantCodec; + rentDepositOffset: BalanceOf & ConstantCodec; + surchargeReward: BalanceOf & ConstantCodec; + transferFee: BalanceOf & ConstantCodec; + creationFee: BalanceOf & ConstantCodec; + transactionBaseFee: BalanceOf & ConstantCodec; + transactionByteFee: BalanceOf & ConstantCodec; + contractFee: BalanceOf & ConstantCodec; + callBaseFee: Gas & ConstantCodec; + instantiateBaseFee: Gas & ConstantCodec; + maxDepth: u32 & ConstantCodec; + maxValueSize: u32 & ConstantCodec; + blockGasLimit: Gas & ConstantCodec; + }; + } +} diff --git a/packages/api/src/types.ts b/packages/api/src/types.ts index 1dcdca9255..e8016caaec 100644 --- a/packages/api/src/types.ts +++ b/packages/api/src/types.ts @@ -2,8 +2,9 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -// `query.types` adds module augmentation so that `api.query.*.*` gets typed. -// Import that file to make these types effective. +// These two files add module augmentation so that `api.{query,consts}.*.*` +// get typed. Import them to make these types effective. +import './consts.types'; import './query.types'; import { Constants } from '@polkadot/metadata/Decorated/types'; diff --git a/packages/metadata/src/Decorated/consts/fromMetadata/index.ts b/packages/metadata/src/Decorated/consts/fromMetadata/index.ts index 3cee38299e..81054e7d5c 100644 --- a/packages/metadata/src/Decorated/consts/fromMetadata/index.ts +++ b/packages/metadata/src/Decorated/consts/fromMetadata/index.ts @@ -34,8 +34,8 @@ export default function fromMetadata (metadata: Metadata): Constants { newModule[stringCamelCase(meta.name.toString())] = codec; return newModule; - }, {}); + }, {} as ModuleConstants); return result; - }, {}); + }, {} as Constants); } diff --git a/packages/metadata/src/Decorated/types.ts b/packages/metadata/src/Decorated/types.ts index 9a6f5eede8..c4996f0d65 100644 --- a/packages/metadata/src/Decorated/types.ts +++ b/packages/metadata/src/Decorated/types.ts @@ -12,7 +12,9 @@ export interface ConstantCodec extends Codec { export type ModuleConstants = Record; -export type Constants = Record; +export interface Constants { + [index: string]: ModuleConstants; +} export interface ModuleStorage { [key: string]: StorageEntry; diff --git a/packages/types/src/scripts/generateTypes/consts.ts b/packages/types/src/scripts/generateTypes/consts.ts new file mode 100644 index 0000000000..1a6c324004 --- /dev/null +++ b/packages/types/src/scripts/generateTypes/consts.ts @@ -0,0 +1,90 @@ +// Copyright 2017-2019 @polkadot/types authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import fs from 'fs'; +import { ModuleMetadataV8 } from '@polkadot/metadata/Metadata/v8/Metadata'; +import staticData from '@polkadot/metadata/Metadata/static'; +import { stringCamelCase } from '@polkadot/util'; + +import { Metadata } from '../..'; +import { createImportCode, createImports, FOOTER, HEADER, indent, setImports, TypeImports } from '../util'; + +// Generate types for one module +function generateModule (modul: ModuleMetadataV8, imports: TypeImports): string[] { + if (!modul.constants.length) { + return []; + } + + setImports(imports, ['Codec']); + + return [indent(4)(`${stringCamelCase(modul.name.toString())}: {`)] + .concat(indent(6)('[index: string]: Codec;')) + .concat( + modul.constants + .map((constant): string => { + setImports(imports, [constant.type.toString()]); + + return indent(6)(`${stringCamelCase(constant.name.toString())}: ${constant.type} & ConstantCodec;`); + }) + ) + .concat([indent(4)('};')]); +} + +// Generate `packages/types-jsonrpc/src/jsonrpc.types.ts` for a particular +// metadata +function generateForMeta (meta: Metadata): void { + console.log('Writing packages/api/src/consts.types.ts'); + + // Inject all types so that metadata can use them + require('../../injector'); + + const imports = createImports(); // Will hold all needed imports + + const body = meta.asLatest.modules.reduce((acc, modul): string[] => { + const storageEntries = generateModule(modul, imports); + + return acc.concat(storageEntries); + }, [] as string[]); + + const header = createImportCode(HEADER, [ + { + file: '@polkadot/types/codec', + types: Object.keys(imports.codecTypes).filter((name): boolean => name !== 'Tuple') + }, + { + file: '@polkadot/types', + types: Object.keys(imports.primitiveTypes) + }, + ...Object.keys(imports.localTypes).map((moduleName): { file: string; types: string[] } => ({ + file: `@polkadot/types/interfaces/${moduleName}`, + types: Object.keys(imports.localTypes[moduleName]) + })), + { + file: '@polkadot/types/types', + types: Object.keys(imports.typesTypes) + } + ]); + + const interfaceStart = + [ + "declare module '@polkadot/metadata/Decorated/types' {", + indent(2)('export interface Constants {\n') + ].join('\n'); + const interfaceEnd = `\n${indent(2)('}')}\n}`; + + fs.writeFileSync( + 'packages/api/src/consts.types.ts', + header + .concat(interfaceStart) + .concat(body.join('\n')) + .concat(interfaceEnd) + .concat(FOOTER) + , { flag: 'w' } + ); +} + +// Call `generateForMeta()` with current static metadata +export default function generateConsts (): void { + return generateForMeta(new Metadata(staticData)); +} diff --git a/packages/types/src/scripts/generateTypes/query.ts b/packages/types/src/scripts/generateTypes/query.ts index 690bf564eb..1e802b6f2c 100644 --- a/packages/types/src/scripts/generateTypes/query.ts +++ b/packages/types/src/scripts/generateTypes/query.ts @@ -59,7 +59,6 @@ function generateEntry (storageEntry: StorageEntryMetadata, imports: TypeImports return [ `${stringLowerFirst(storageEntry.name.toString())}: StorageEntryExact Observable<${returnType}>> & QueryableStorageEntry;` - // `${stringLowerFirst(storageEntry.name.toString())}: QueryableStorageEntry;` ]; } diff --git a/packages/types/src/scripts/interfacesTs.ts b/packages/types/src/scripts/interfacesTs.ts index 5145692afb..ad0e19a9df 100644 --- a/packages/types/src/scripts/interfacesTs.ts +++ b/packages/types/src/scripts/interfacesTs.ts @@ -2,12 +2,14 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. +import generateConstsTypes from './generateTypes/consts'; import generateInterfaceRegistry from './generateTypes/interfaceRegistry'; import generateQueryTypes from './generateTypes/query'; import generateRpcTypes from './generateTypes/rpc'; import generateTsDef from './generateTypes/tsDef'; function main (): void { + generateConstsTypes(); generateInterfaceRegistry(); generateQueryTypes(); generateRpcTypes();