diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000..b6f5271476 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +**/build/* +**/coverage/* +**/node_modules/* diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000000..3c4ceb716d --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,12 @@ +const base = require('@polkadot/dev/config/eslint'); + +module.exports = { + ...base, + rules: { + ...base.rules, + // add override for any (a metric ton of them, initial conversion) + '@typescript-eslint/no-explicit-any': 'off', + // these should be removed, there are 8 of them as errors + '@typescript-eslint/no-non-null-assertion': 'off' + } +}; diff --git a/docs/examples/promise/01_simple_connect/index.js b/docs/examples/promise/01_simple_connect/index.js index 1dfd3d9bc5..4dff56ac9c 100755 --- a/docs/examples/promise/01_simple_connect/index.js +++ b/docs/examples/promise/01_simple_connect/index.js @@ -1,4 +1,4 @@ -// @ts-check +/* eslint-disable @typescript-eslint/no-var-requires */ // Required imports const { ApiPromise, WsProvider } = require('@polkadot/api'); diff --git a/docs/examples/promise/02_listen_to_blocks/index.js b/docs/examples/promise/02_listen_to_blocks/index.js index 5ac10320ac..f4b3a9244e 100755 --- a/docs/examples/promise/02_listen_to_blocks/index.js +++ b/docs/examples/promise/02_listen_to_blocks/index.js @@ -1,4 +1,4 @@ -// @ts-check +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API const { ApiPromise } = require('@polkadot/api'); @@ -8,11 +8,19 @@ async function main () { // the API has connected to the node and completed the initialisation process const api = await ApiPromise.create(); + // we only display a couple, then unsubscribe + let count = 0; + // Subscribe to the new headers on-chain. The callback is fired when new headers // are found, the call itself returns a promise with a subscription that can be // used to unsubscribe from the newHead subscription const unsubscribe = await api.rpc.chain.subscribeNewHead((header) => { console.log(`Chain is at block: #${header.blockNumber}`); + + if (++count === 256) { + unsubscribe(); + process.exit(0); + } }); } diff --git a/docs/examples/promise/03_listen_to_balance_change/index.js b/docs/examples/promise/03_listen_to_balance_change/index.js index 0b09b35542..ac5c493674 100755 --- a/docs/examples/promise/03_listen_to_balance_change/index.js +++ b/docs/examples/promise/03_listen_to_balance_change/index.js @@ -1,4 +1,4 @@ -// @ts-check +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API const { ApiPromise } = require('@polkadot/api'); diff --git a/docs/examples/promise/03_listen_to_multiple_balances_change/index.js b/docs/examples/promise/03_listen_to_multiple_balances_change/index.js index 22539005f5..5726a22629 100755 --- a/docs/examples/promise/03_listen_to_multiple_balances_change/index.js +++ b/docs/examples/promise/03_listen_to_multiple_balances_change/index.js @@ -1,23 +1,20 @@ -// @ts-check +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API const { ApiPromise } = require('@polkadot/api'); // Known account we want to use (available on dev chain, with funds) -const Alice = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; -const Bob = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; +const ALICE = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; +const BOB = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; async function main () { // Create an await for the API const api = await ApiPromise.create(); - const ALICE = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; - const BOB = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; - - console.log('Tracking balances for:', [ALICE, BOB]) + console.log('Tracking balances for:', [ALICE, BOB]); // Subscribe and listen to several balance changes api.query.balances.freeBalance.multi([ALICE, BOB], (balances) => { - console.log('Change detected, new balances: ', balances) + console.log('Change detected, new balances: ', balances); }); } diff --git a/docs/examples/promise/04_unsubscribe/index.js b/docs/examples/promise/04_unsubscribe/index.js index 497b6ded48..7a2143914c 100644 --- a/docs/examples/promise/04_unsubscribe/index.js +++ b/docs/examples/promise/04_unsubscribe/index.js @@ -1,9 +1,8 @@ -// @ts-check +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API const { ApiPromise } = require('@polkadot/api'); async function main () { - // Create a new instance of the api const api = await ApiPromise.create(); @@ -16,7 +15,7 @@ async function main () { // returned by the api call function after 20s. setTimeout(() => { unsubscribe(); - console.log('Unsubscribed') + console.log('Unsubscribed'); }, 20000); } diff --git a/docs/examples/promise/05_read_storage/index.js b/docs/examples/promise/05_read_storage/index.js index cef8535e2e..c7752397ef 100755 --- a/docs/examples/promise/05_read_storage/index.js +++ b/docs/examples/promise/05_read_storage/index.js @@ -1,4 +1,4 @@ -// @ts-check +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API const { ApiPromise } = require('@polkadot/api'); @@ -11,7 +11,7 @@ async function main () { // Make our basic chain state/storage queries, all in one go const [accountNonce, blockPeriod, validators] = await Promise.all([ - api.query.system.accountNonce(Alice), + api.query.system.accountNonce(ALICE), api.query.timestamp.blockPeriod(), api.query.session.validators() ]); @@ -35,4 +35,4 @@ async function main () { } } -main().catch(console.error).finally(_ => process.exit()); +main().catch(console.error).finally(() => process.exit()); diff --git a/docs/examples/promise/05_read_storage_at/index.js b/docs/examples/promise/05_read_storage_at/index.js index ceebaaea77..d923763014 100755 --- a/docs/examples/promise/05_read_storage_at/index.js +++ b/docs/examples/promise/05_read_storage_at/index.js @@ -1,4 +1,4 @@ -// @ts-check +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API const { ApiPromise } = require('@polkadot/api'); @@ -27,4 +27,4 @@ async function main () { console.log(`Current balances for Alice and Bob are ${balances[0]} and ${balances[1]}`); } -main().catch(console.error).finally(_ => process.exit()); +main().catch(console.error).finally(() => process.exit()); diff --git a/docs/examples/promise/06_make_transfer/index.js b/docs/examples/promise/06_make_transfer/index.js index bf527ee4a1..a7ae0c269c 100755 --- a/docs/examples/promise/06_make_transfer/index.js +++ b/docs/examples/promise/06_make_transfer/index.js @@ -1,4 +1,4 @@ -// @ts-check +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API, Keyring and some utility functions const { ApiPromise } = require('@polkadot/api'); const { Keyring } = require('@polkadot/keyring'); diff --git a/docs/examples/promise/07_make_transfer_with_allowed_block_permissions_only/index.js b/docs/examples/promise/07_make_transfer_with_allowed_block_permissions_only/index.js index 776e295ccd..9e8b53619e 100644 --- a/docs/examples/promise/07_make_transfer_with_allowed_block_permissions_only/index.js +++ b/docs/examples/promise/07_make_transfer_with_allowed_block_permissions_only/index.js @@ -1,4 +1,4 @@ -// @ts-check +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API, Keyring and some utility functions const { ApiPromise } = require('@polkadot/api'); const { Keyring } = require('@polkadot/keyring'); @@ -8,7 +8,7 @@ const BOB = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; async function main () { // Instantiate the API - const api = await ApiPromise.create(); //remove provider + const api = await ApiPromise.create(); // default provider // Constuct the keying after the API (crypto has an async init) const keyring = new Keyring({ type: 'sr25519' }); diff --git a/docs/examples/promise/08_system_events/index.js b/docs/examples/promise/08_system_events/index.js index 89052eb50e..d0b7bfcbd2 100755 --- a/docs/examples/promise/08_system_events/index.js +++ b/docs/examples/promise/08_system_events/index.js @@ -1,4 +1,4 @@ -// @ts-check +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API const { ApiPromise } = require('@polkadot/api'); diff --git a/docs/examples/promise/09_transfer_events/index.js b/docs/examples/promise/09_transfer_events/index.js index 0b84df9894..9f5a1117c4 100755 --- a/docs/examples/promise/09_transfer_events/index.js +++ b/docs/examples/promise/09_transfer_events/index.js @@ -1,4 +1,4 @@ -// @ts-check +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API & Provider and some utility functions const { ApiPromise } = require('@polkadot/api'); diff --git a/docs/examples/promise/10_upgrade_chain/index.js b/docs/examples/promise/10_upgrade_chain/index.js index c0048dffb8..b75864bb35 100755 --- a/docs/examples/promise/10_upgrade_chain/index.js +++ b/docs/examples/promise/10_upgrade_chain/index.js @@ -1,4 +1,4 @@ -// @ts-check +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API & Provider and some utility functions const { ApiPromise, WsProvider } = require('@polkadot/api'); diff --git a/docs/examples/rx/01_simple_connect/index.js b/docs/examples/rx/01_simple_connect/index.js index c20c79cf1a..4110d40f27 100644 --- a/docs/examples/rx/01_simple_connect/index.js +++ b/docs/examples/rx/01_simple_connect/index.js @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ // Required imports const { zip } = require('rxjs'); const { ApiRx } = require('@polkadot/api'); @@ -16,9 +17,7 @@ function main () { api.rpc.system.chain(), api.rpc.system.name(), api.rpc.system.version() - ) - // Then we subscribe to the result - .subscribe(([chain, nodeName, nodeVersion]) => { + ).subscribe(([chain, nodeName, nodeVersion]) => { console.log(`You are connected to chain ${chain} using ${nodeName} v${nodeVersion}`); }); } diff --git a/docs/examples/rx/02_listen_to_blocks/index.js b/docs/examples/rx/02_listen_to_blocks/index.js index 1ed46259be..a20ef70c60 100644 --- a/docs/examples/rx/02_listen_to_blocks/index.js +++ b/docs/examples/rx/02_listen_to_blocks/index.js @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API const { ApiRx } = require('@polkadot/api'); const { switchMap } = require('rxjs/operators'); diff --git a/docs/examples/rx/03_listen_to_balance_change/index.js b/docs/examples/rx/03_listen_to_balance_change/index.js index 234b0d54c5..b5ba4ecc8d 100644 --- a/docs/examples/rx/03_listen_to_balance_change/index.js +++ b/docs/examples/rx/03_listen_to_balance_change/index.js @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API and operators from RxJs const { ApiRx } = require('@polkadot/api'); const { pairwise, startWith } = require('rxjs/operators'); diff --git a/docs/examples/rx/04_unsubscribe/index.js b/docs/examples/rx/04_unsubscribe/index.js index 4286164c8a..7c4d9580be 100644 --- a/docs/examples/rx/04_unsubscribe/index.js +++ b/docs/examples/rx/04_unsubscribe/index.js @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API const { ApiRx } = require('@polkadot/api'); const { switchMap } = require('rxjs/operators'); diff --git a/docs/examples/rx/05_read_storage/index.js b/docs/examples/rx/05_read_storage/index.js index 8ad9d89f20..5aeed582dd 100644 --- a/docs/examples/rx/05_read_storage/index.js +++ b/docs/examples/rx/05_read_storage/index.js @@ -1,6 +1,6 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API const { ApiRx } = require('@polkadot/api'); -// Import dependencies from RxJs const { combineLatest, of } = require('rxjs'); const { first, switchMap } = require('rxjs/operators'); @@ -9,7 +9,7 @@ const Alice = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; function main () { // Create our API with a default connection to the local node - new ApiRx(provider).isReady + new ApiRx().isReady .pipe( // Here we ake our basic chain state/storage queries switchMap((api) => combineLatest( @@ -48,4 +48,4 @@ function main () { }); } -main().catch(console.error).finally(_ => process.exit()); +main().catch(console.error).finally(() => process.exit()); diff --git a/docs/examples/rx/06_make_transfer/index.js b/docs/examples/rx/06_make_transfer/index.js index 300e0b3659..ced5b53fdb 100644 --- a/docs/examples/rx/06_make_transfer/index.js +++ b/docs/examples/rx/06_make_transfer/index.js @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API, Keyring and some utility functions const { ApiRx } = require('@polkadot/api'); const { Keyring } = require('@polkadot/keyring'); @@ -17,7 +18,7 @@ async function main () { // Create a extrinsic, transferring 12345 units to Bob. api.tx.balances // create transfer - .transfer(BOB, randomAmount) + .transfer(BOB, 12345) // Sign and send the transcation .signAndSend(alice) // Subscribe to the status updates of the transfer @@ -30,4 +31,4 @@ async function main () { }); } -main().catch(console.error).finally(_ => process.exit()); +main().catch(console.error).finally(() => process.exit()); diff --git a/docs/examples/rx/08_system_events/index.js b/docs/examples/rx/08_system_events/index.js index 54d75847bf..ab3e592dad 100644 --- a/docs/examples/rx/08_system_events/index.js +++ b/docs/examples/rx/08_system_events/index.js @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API and selected RxJs operators const { switchMap } = require('rxjs/operators'); const { ApiRx } = require('@polkadot/api'); @@ -9,8 +10,9 @@ async function main () { switchMap((api) => // subscribe to system events via storage api.query.system.events() - )) - // Then we're subscribing to the emitted results + ) + ) + // Then we're subscribing to the emitted results .subscribe((events) => { console.log(`\nReceived ${events.length} events:`); // loop through the Vec @@ -29,7 +31,7 @@ async function main () { }); }); }); -}; +} main().catch((error) => { console.error(error); diff --git a/docs/examples/rx/09_transfer_events/index.js b/docs/examples/rx/09_transfer_events/index.js index 9291995f4b..6fe0ebe281 100644 --- a/docs/examples/rx/09_transfer_events/index.js +++ b/docs/examples/rx/09_transfer_events/index.js @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API and some utility functions const { ApiRx } = require('@polkadot/api'); diff --git a/docs/examples/rx/10_upgrade_chain/index.js b/docs/examples/rx/10_upgrade_chain/index.js index 5883467a81..ab10ee720d 100644 --- a/docs/examples/rx/10_upgrade_chain/index.js +++ b/docs/examples/rx/10_upgrade_chain/index.js @@ -1,5 +1,6 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ // Import the API & Provider and some utility functions -const { ApiRx, WsPovider } = require('@polkadot/api'); +const { ApiRx, WsProvider } = require('@polkadot/api'); // import the test keyring (already has dev keys for Alice, Bob, Charlie, Eve & Ferdie) const testKeyring = require('@polkadot/keyring/testing'); const fs = require('fs'); diff --git a/jest.config.js b/jest.config.js index 9d5152efb7..47355101f1 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/camelcase */ +/* eslint-disable @typescript-eslint/no-var-requires */ const config = require('@polkadot/dev/config/jest'); module.exports = Object.assign({}, config, { @@ -21,13 +23,13 @@ module.exports = Object.assign({}, config, { '/packages/types/build' ], globals: { - 'ws_local': 'ws://127.0.0.1:9944/', - 'ws_local_substrate_master': 'ws://127.0.0.1:9945/', - 'ws_local_substrate_1': 'ws://127.0.0.1:9946/', - 'ws_local_substrate_2': 'ws://127.0.0.1:9947/', - 'ws_local_polkadot_master': 'ws://127.0.0.1:9948/', - 'ws_local_polkadot_alex': 'ws://127.0.0.1:9949/', - 'ws_substrate_1': 'wss://substrate-rpc.parity.io/', - 'ws_polkadot_alex': 'wss://poc3-rpc.polkadot.io/' + ws_local: 'ws://127.0.0.1:9944/', + ws_local_substrate_master: 'ws://127.0.0.1:9945/', + ws_local_substrate_1: 'ws://127.0.0.1:9946/', + ws_local_substrate_2: 'ws://127.0.0.1:9947/', + ws_local_polkadot_master: 'ws://127.0.0.1:9948/', + ws_local_polkadot_alex: 'ws://127.0.0.1:9949/', + ws_substrate_1: 'wss://substrate-rpc.parity.io/', + ws_polkadot_alex: 'wss://poc3-rpc.polkadot.io/' } }); diff --git a/package.json b/package.json index d61f8b53d0..cc087a2974 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "build:methodsdoc": "node packages/types/src/scripts/MetadataMdWrapper.js", "build:srmlTs": "node packages/types/src/scripts/srmlTSWrapper.js", "check": "yarn lint", - "lint": "tslint --project . && tsc --noEmit --pretty", + "lint": "eslint --ext .js,.jsx,.ts,.tsx . && tsc --noEmit --pretty", "clean": "polkadot-dev-clean-build", "postinstall": "polkadot-dev-yarn-only", "test": "jest --coverage --testPathIgnorePatterns e2e", diff --git a/packages/api-contract/src/Abi.spec.ts b/packages/api-contract/src/Abi.spec.ts index 63a896bdf5..4e362c5a8c 100644 --- a/packages/api-contract/src/Abi.spec.ts +++ b/packages/api-contract/src/Abi.spec.ts @@ -2,29 +2,29 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { ContractABIFn$Arg } from './types'; +import { ContractABIArg } from './types'; import typesAbi from '../test/abi/types.json'; import erc20Abi from '../test/contracts/erc20.json'; import { Abi } from '.'; -describe('Abi', () => { - describe('types encoding', () => { +describe('Abi', (): void => { + describe('types encoding', (): void => { let abi: Abi; - beforeAll(() => { + beforeAll((): void => { abi = new Abi(typesAbi); }); - function check (method: string, args: Array, type: string | null): void { + function check (method: string, args: ContractABIArg[], type: string | null): void { const fn = abi.messages[method]; expect(fn.args).toEqual(args); expect(fn.type).toEqual(type); } - it('has the primitive method with args & return', () => { + it('has the primitive method with args & return', (): void => { check( 'primitive', [ @@ -35,7 +35,7 @@ describe('Abi', () => { ); }); - it('has the vector method with args & return', () => { + it('has the vector method with args & return', (): void => { check( 'vector', [ @@ -46,7 +46,7 @@ describe('Abi', () => { ); }); - it('has the vector_fixed method with args & return', () => { + it('has the vector_fixed method with args & return', (): void => { check( 'vectorFixed', [ @@ -56,7 +56,7 @@ describe('Abi', () => { ); }); - it('has the option method with args & return', () => { + it('has the option method with args & return', (): void => { check( 'option', [ @@ -66,7 +66,7 @@ describe('Abi', () => { ); }); - it('has the result method with return (empty)', () => { + it('has the result method with return (empty)', (): void => { check( 'result', [], @@ -74,7 +74,7 @@ describe('Abi', () => { ); }); - it('allows for nested args', () => { + it('allows for nested args', (): void => { check( 'nested', [ @@ -84,14 +84,14 @@ describe('Abi', () => { ); }); - describe('messages', () => { - it('fails when invalid args are supplied', () => { + describe('messages', (): void => { + it('fails when invalid args are supplied', (): void => { expect( - () => abi.messages.primitive(false) + (): Uint8Array => abi.messages.primitive(false) ).toThrow(/Expected 2 arguments to contract messages.primitive, found 1/); }); - it('encodes primitives correctly', () => { + it('encodes primitives correctly', (): void => { expect( abi.messages.primitive(true, 0x12345678) ).toEqual(new Uint8Array([ @@ -104,14 +104,14 @@ describe('Abi', () => { }); }); - describe('erc20', () => { + describe('erc20', (): void => { let abi: Abi; - beforeEach(() => { + beforeEach((): void => { abi = new Abi(erc20Abi); }); - it('has the attached methods', () => { + it('has the attached methods', (): void => { expect(Object.keys(abi.messages)).toEqual( ['totalSupply', 'balanceOf', 'allowance', 'transfer', 'approve', 'transferFrom'] ); diff --git a/packages/api-contract/src/Abi.ts b/packages/api-contract/src/Abi.ts index 1c57b410b5..9c7ac5b10b 100644 --- a/packages/api-contract/src/Abi.ts +++ b/packages/api-contract/src/Abi.ts @@ -2,25 +2,27 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { ContractABI, ContractABIFn, IAbi, IAbi$Messages } from './types'; +import { ContractABI, ContractABIFn, InterfaceAbi, AbiMessages } from './types'; import { stringCamelCase } from '@polkadot/util'; import { createMethod } from './method'; import { validateAbi } from './validation'; -export default class ContractAbi implements IAbi { - readonly abi: ContractABI; - readonly deploy: ContractABIFn; - readonly messages: IAbi$Messages = {}; +export default class ContractAbi implements InterfaceAbi { + public readonly abi: ContractABI; - constructor (abi: ContractABI) { + public readonly deploy: ContractABIFn; + + public readonly messages: AbiMessages = {}; + + public constructor (abi: ContractABI) { validateAbi(abi); this.abi = abi; this.deploy = createMethod('deploy', abi.deploy); - abi.messages.forEach((method) => { + abi.messages.forEach((method): void => { const name = stringCamelCase(method.name); this.messages[name] = createMethod(`messages.${name}`, method); diff --git a/packages/api-contract/src/RxBase.ts b/packages/api-contract/src/RxBase.ts index 7a8d1ea3d5..9eacd8b329 100644 --- a/packages/api-contract/src/RxBase.ts +++ b/packages/api-contract/src/RxBase.ts @@ -3,19 +3,21 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { SubmittableModuleExtrinsics } from '@polkadot/api/types'; -import { ApiObject, ContractABI, IContractBase } from './types'; +import { ApiObject, ContractABI, ContractBase } from './types'; import { assert } from '@polkadot/util'; import Abi from './Abi'; // NOTE Experimental, POC, bound to change -export default abstract class RxBase implements IContractBase<'rxjs'> { - readonly abi: Abi; - readonly api: ApiObject<'rxjs'>; - readonly apiContracts: SubmittableModuleExtrinsics<'rxjs'>; +export default abstract class RxBase implements ContractBase<'rxjs'> { + public readonly abi: Abi; - constructor (api: ApiObject<'rxjs'>, abi: ContractABI | Abi) { + public readonly api: ApiObject<'rxjs'>; + + public readonly apiContracts: SubmittableModuleExtrinsics<'rxjs'>; + + public constructor (api: ApiObject<'rxjs'>, abi: ContractABI | Abi) { this.abi = abi instanceof Abi ? abi : new Abi(abi); diff --git a/packages/api-contract/src/RxBlueprint.ts b/packages/api-contract/src/RxBlueprint.ts index 2073d2ea77..1945ac025d 100644 --- a/packages/api-contract/src/RxBlueprint.ts +++ b/packages/api-contract/src/RxBlueprint.ts @@ -16,16 +16,16 @@ import Abi from './Abi'; import RxBase from './RxBase'; import RxContract from './RxContract'; -type IBlueprintCreateResultSubscription = Observable; +type BlueprintCreateResultSubscription = Observable; -export interface IBlueprintCreate { - signAndSend (account: IKeyringPair | string | AccountId | Address): IBlueprintCreateResultSubscription; +export interface BlueprintCreate { + signAndSend (account: IKeyringPair | string | AccountId | Address): BlueprintCreateResultSubscription; } class BlueprintCreateResult extends SubmittableResult { - readonly contract?: RxContract; + public readonly contract?: RxContract; - constructor (result: ISubmittableResult, contract?: RxContract) { + public constructor (result: ISubmittableResult, contract?: RxContract) { super(result); this.contract = contract; @@ -34,21 +34,21 @@ class BlueprintCreateResult extends SubmittableResult { // NOTE Experimental, POC, bound to change export default class Blueprint extends RxBase { - readonly codeHash: Hash; + public readonly codeHash: Hash; - constructor (api: ApiRx, abi: ContractABI | Abi, codeHash: string | Hash) { + public constructor (api: ApiRx, abi: ContractABI | Abi, codeHash: string | Hash) { super(api, abi); this.codeHash = new Hash(codeHash); } - public deployContract (endowment: number | BN, maxGas: number | BN, ...params: Array): IBlueprintCreate { - const signAndSend = (account: IKeyringPair | string | AccountId | Address): IBlueprintCreateResultSubscription => { + public deployContract (endowment: number | BN, maxGas: number | BN, ...params: any[]): BlueprintCreate { + const signAndSend = (account: IKeyringPair | string | AccountId | Address): BlueprintCreateResultSubscription => { return this.apiContracts .create(endowment, maxGas, this.codeHash, this.abi.deploy(...params)) .signAndSend(account) .pipe( - map((result: SubmittableResult) => { + map((result: SubmittableResult): BlueprintCreateResult => { let contract: RxContract | undefined; if (result.isFinalized) { diff --git a/packages/api-contract/src/RxCode.ts b/packages/api-contract/src/RxCode.ts index 98c75ff27f..69773bfe87 100644 --- a/packages/api-contract/src/RxCode.ts +++ b/packages/api-contract/src/RxCode.ts @@ -20,7 +20,7 @@ import RxBlueprint from './RxBlueprint'; // Ok, tried, failed, eventually ... well, we are only trying with RxJs as a // start, so take a big fat shortcut with this version, real intended version // follows this and is commented out -type ICodePutCodeResultSubscription = Observable; +type CodePutCodeResultSubscription = Observable; // type ICodePutCodeResultSubscription = // ApiType extends 'rxjs' // ? Observable @@ -31,14 +31,15 @@ type ICodePutCodeResultSubscription = Observable; // is hanging where, with the bare-mainimum from a simplicity perspective // Very obvious is that it supports only 1 version of signAndSend // (we need to revisit this, but probably ok for initial?) -export interface ICodePutCode { - signAndSend (account: IKeyringPair | string | AccountId | Address): ICodePutCodeResultSubscription; +// eslint-disable-next-line @typescript-eslint/interface-name-prefix +export interface CodePutCode { + signAndSend (account: IKeyringPair | string | AccountId | Address): CodePutCodeResultSubscription; } class CodePutCodeResult extends SubmittableResult { - readonly blueprint?: RxBlueprint; + public readonly blueprint?: RxBlueprint; - constructor (result: ISubmittableResult, blueprint?: RxBlueprint) { + public constructor (result: ISubmittableResult, blueprint?: RxBlueprint) { super(result); this.blueprint = blueprint; @@ -47,21 +48,21 @@ class CodePutCodeResult extends SubmittableResult { // NOTE Experimental, POC, bound to change export default class RxCode extends RxBase { - readonly code: Uint8Array; + public readonly code: Uint8Array; - constructor (api: ApiRx, abi: ContractABI | Abi, wasm: string | Uint8Array) { + public constructor (api: ApiRx, abi: ContractABI | Abi, wasm: string | Uint8Array) { super(api, abi); this.code = u8aToU8a(wasm); } - public createBlueprint (maxGas: number | BN): ICodePutCode { - const signAndSend = (account: IKeyringPair | string | AccountId | Address): ICodePutCodeResultSubscription => { + public createBlueprint (maxGas: number | BN): CodePutCode { + const signAndSend = (account: IKeyringPair | string | AccountId | Address): CodePutCodeResultSubscription => { return this.apiContracts .putCode(maxGas, compactAddLength(this.code)) .signAndSend(account) .pipe( - map((result: ISubmittableResult) => { + map((result: ISubmittableResult): CodePutCodeResult => { let blueprint: RxBlueprint | undefined; if (result.isFinalized) { diff --git a/packages/api-contract/src/RxContract.ts b/packages/api-contract/src/RxContract.ts index 686f935caf..208f445105 100644 --- a/packages/api-contract/src/RxContract.ts +++ b/packages/api-contract/src/RxContract.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { ContractABI, ContractABIFn, IContract, IContract$Calls } from './types'; +import { ContractABI, ContractABIFn, InterfaceContract, InterfaceContractCalls } from './types'; import { IKeyringPair } from '@polkadot/types/types'; import BN from 'bn.js'; @@ -14,25 +14,28 @@ import { AccountId, Address } from '@polkadot/types'; import Abi from './Abi'; import RxBase from './RxBase'; -export type IContractCallResultSubscription = Observable; +export type ContractCallResultSubscription = Observable; -export interface IContractCall { - signAndSend (account: IKeyringPair | string | AccountId | Address): IContractCallResultSubscription; +export interface ContractCall { + signAndSend (account: IKeyringPair | string | AccountId | Address): ContractCallResultSubscription; } -// NOTE Experimental, POC, bound to change -export default class RxContract extends RxBase implements IContract { - readonly address: Address; - readonly calls: IContract$Calls = {}; +type CallResult = (value: BN | number, maxGas: BN | number, ...params: any[]) => ContractCall; - constructor (api: ApiRx, abi: ContractABI | Abi, address: string | AccountId | Address) { +// NOTE Experimental, POC, bound to change +export default class RxContract extends RxBase implements InterfaceContract { + public readonly address: Address; + + public readonly calls: InterfaceContractCalls = {}; + + public constructor (api: ApiRx, abi: ContractABI | Abi, address: string | AccountId | Address) { super(api, abi); this.address = new Address(address); - Object.entries(abi.messages).forEach(([name, fn]) => { - this.calls[name] = (fn: ContractABIFn) => - (value: BN | number, maxGas: BN | number, ...params: Array): IContractCall => + Object.entries(abi.messages).forEach(([name]): void => { + this.calls[name] = (fn: ContractABIFn): CallResult => + (value: BN | number, maxGas: BN | number, ...params: any[]): ContractCall => this.apiContracts.call(this.address, value, maxGas, fn(...params)); }); } diff --git a/packages/api-contract/src/method.ts b/packages/api-contract/src/method.ts index 9fccdab03d..997a050264 100644 --- a/packages/api-contract/src/method.ts +++ b/packages/api-contract/src/method.ts @@ -3,7 +3,7 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { CodecArg, Constructor } from '@polkadot/types/types'; -import { ContractABIFn, ContractABIFn$Arg, ContractABIMethod, ContractABIMethodBase, ContractABITypes } from './types'; +import { ContractABIFn, ContractABIArg, ContractABIMethod, ContractABIMethodBase, ContractABITypes } from './types'; import { Compact, createClass } from '@polkadot/types'; import { assert, isString, isUndefined, stringCamelCase } from '@polkadot/util'; @@ -12,7 +12,7 @@ export function typeToString (type: ContractABITypes): string { if (isString(type)) { return type; } else if (Array.isArray(type)) { - return `(${type.map((type) => typeToString(type)).join(',')})`; + return `(${type.map((type): string => typeToString(type)).join(',')})`; } else if (type['Option']) { return `Option<${typeToString(type['Option'].T)}>`; } else if (type['Result']) { @@ -26,10 +26,10 @@ export function typeToString (type: ContractABITypes): string { throw new Error(`Unknown type specified ${JSON.stringify(type)}`); } -export function createArgClass (args: Array, baseDef: { [index: string]: string }): Constructor { +export function createArgClass (args: ContractABIArg[], baseDef: Record): Constructor { return createClass( JSON.stringify( - args.reduce((base: { [index: string]: string }, { name, type }) => { + args.reduce((base: Record, { name, type }): Record => { base[name] = type; return base; @@ -39,17 +39,17 @@ export function createArgClass (args: Array, baseDef: { [inde } export function createMethod (name: string, method: Partial & ContractABIMethodBase): ContractABIFn { - const args: Array = method.args.map(({ name, type }) => ({ + const args: ContractABIArg[] = method.args.map(({ name, type }): ContractABIArg => ({ name: stringCamelCase(name), type: typeToString(type) })); const Clazz = createArgClass(args, isUndefined(method.selector) ? {} : { __selector: 'u32' }); const baseStruct: { [index: string]: any } = { __selector: method.selector }; - const encoder = (...params: Array): Uint8Array => { + const encoder = (...params: CodecArg[]): Uint8Array => { assert(params.length === args.length, `Expected ${args.length} arguments to contract ${name}, found ${params.length}`); const u8a = new Clazz( - args.reduce((mapped, { name }, index) => { + args.reduce((mapped, { name }, index): Record => { mapped[name] = params[index]; return mapped; diff --git a/packages/api-contract/src/types.ts b/packages/api-contract/src/types.ts index 39f29f6ebe..b3c2787b41 100644 --- a/packages/api-contract/src/types.ts +++ b/packages/api-contract/src/types.ts @@ -12,83 +12,81 @@ export type ApiObject = ApiType extends 'rxjs' ? ApiRx : ApiPromise; -export type ContractABITypes$Struct = { +export interface ContractABITypesStruct { 'Option'?: { - T: ContractABITypes - }, + T: ContractABITypes; + }; 'Result'?: { - T: ContractABITypes, - E: ContractABITypes - }, + T: ContractABITypes; + E: ContractABITypes; + }; 'Vec'?: { - T: ContractABITypes - }, + T: ContractABITypes; + }; '[T;n]'?: { - T: ContractABITypes, - n: number - } -}; + T: ContractABITypes; + n: number; + }; +} -export type ContractABITypes = string | ContractABITypes$Struct | Array; +export type ContractABITypes = string | ContractABITypesStruct | (string | ContractABITypesStruct)[]; -export type ContractABIArg = { - name: string, - type: ContractABITypes -}; +export interface ContractABIArg { + name: string; + type: ContractABITypes; +} -export type ContractABIMethodBase = { - args: Array -}; +export interface ContractABIMethodBase { + args: ContractABIArg[]; +} -export type ContractABIMethod = ContractABIMethodBase & { - mutates?: boolean, - name: string, - selector: number, - return_type: ContractABITypes | null -}; +export interface ContractABIMethod extends ContractABIMethodBase { + mutates?: boolean; + name: string; + selector: number; + return_type: ContractABITypes | null; +} -export type ContractABI = { - deploy: ContractABIMethodBase, - messages: Array, - name: string -}; +export interface ContractABI { + deploy: ContractABIMethodBase; + messages: ContractABIMethod[]; + name: string; +} -export interface ContractABIFn$Arg { +export interface ContractABIMetaArg { name: string; type: string; } -export interface ContractABIFn$Meta { - args: Array; +export interface ContractABIMeta { + args: ContractABIArg[]; isConstant: boolean; type: string | null; } -export interface ContractABIFn extends ContractABIFn$Meta { - (...args: Array): Uint8Array; +export interface ContractABIFn extends ContractABIMeta { + (...args: CodecArg[]): Uint8Array; } -export interface IAbi$Messages { - [index: string]: ContractABIFn; -} +export type AbiMessages = Record; -export interface IAbi { +export interface InterfaceAbi { readonly abi: ContractABI; readonly deploy: ContractABIFn; - readonly messages: IAbi$Messages; + readonly messages: AbiMessages; } -export interface IContractBase { - readonly abi: IAbi; +export interface ContractBase { + readonly abi: InterfaceAbi; readonly api: ApiObject; readonly apiContracts: SubmittableModuleExtrinsics; } -export interface IContract$Calls { +export interface InterfaceContractCalls { [index: string]: Function; } -export interface IContract { +export interface InterfaceContract { readonly address: Address; - readonly calls: IContract$Calls; + readonly calls: InterfaceContractCalls; } diff --git a/packages/api-contract/src/validation.ts b/packages/api-contract/src/validation.ts index 74fe50446a..db928c5d6b 100644 --- a/packages/api-contract/src/validation.ts +++ b/packages/api-contract/src/validation.ts @@ -6,11 +6,11 @@ import { ContractABI, ContractABIArg } from './types'; import { assert, isNumber, isNull, isString, isObject } from '@polkadot/util'; -export function validateArgs (name: string, args: Array): void { +export function validateArgs (name: string, args: ContractABIArg[]): void { assert(Array.isArray(args), `Expected 'args' to exist on ${name}`); - args.forEach((arg) => { - const unknownKeys = Object.keys(arg).filter((key) => !['name', 'type'].includes(key)); + args.forEach((arg): void => { + const unknownKeys = Object.keys(arg).filter((key): boolean => !['name', 'type'].includes(key)); assert(unknownKeys.length === 0, `Unknown keys ${unknownKeys.join(', ')} found in ABI args for ${name}`); assert(isString(arg.name), `${name} args should have valid name `); @@ -19,7 +19,7 @@ export function validateArgs (name: string, args: Array): void { } export function validateDeploy ({ deploy }: ContractABI): void { - const unknownKeys = Object.keys(deploy).filter((key) => !['args'].includes(key)); + const unknownKeys = Object.keys(deploy).filter((key): boolean => !['args'].includes(key)); assert(unknownKeys.length === 0, `Unknown keys ${unknownKeys.join(', ')} found in ABI deploy`); @@ -27,8 +27,8 @@ export function validateDeploy ({ deploy }: ContractABI): void { } export function validateMethods ({ messages }: ContractABI): void { - messages.forEach((method) => { - const unknownKeys = Object.keys(method).filter((key) => !['args', 'mutates', 'name', 'selector', 'return_type'].includes(key)); + messages.forEach((method): void => { + const unknownKeys = Object.keys(method).filter((key): boolean => !['args', 'mutates', 'name', 'selector', 'return_type'].includes(key)); assert(unknownKeys.length === 0, `Unknown keys ${unknownKeys.join(', ')} found in ABI args for messages.${method.name}`); assert(isString(method.name), `Expected name for messages.${method.name}`); @@ -40,7 +40,7 @@ export function validateMethods ({ messages }: ContractABI): void { } export function validateAbi (abi: ContractABI): void { - const unknownKeys = Object.keys(abi).filter((key) => !['deploy', 'messages', 'name'].includes(key)); + const unknownKeys = Object.keys(abi).filter((key): boolean => !['deploy', 'messages', 'name'].includes(key)); assert(unknownKeys.length === 0, `Unknown fields ${unknownKeys.join(', ')} found in ABI`); assert(abi.deploy && abi.messages && isString(abi.name), 'ABI should have deploy, messages & name sections'); diff --git a/packages/api-derive/src/accounts/idAndIndex.ts b/packages/api-derive/src/accounts/idAndIndex.ts index c4a8e32d59..10b5aad8cc 100644 --- a/packages/api-derive/src/accounts/idAndIndex.ts +++ b/packages/api-derive/src/accounts/idAndIndex.ts @@ -4,7 +4,7 @@ import { Observable, of } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { AccountId, AccountIndex, Address } from '@polkadot/types'; import { isU8a } from '@polkadot/util'; import { decodeAddress } from '@polkadot/util-crypto'; @@ -28,7 +28,7 @@ export type AccountIdAndIndex = [AccountId?, AccountIndex?]; * }); * ``` */ -export function idAndIndex (api: ApiInterface$Rx) { +export function idAndIndex (api: ApiInterfaceRx): (address?: Address | AccountId | AccountIndex | string | null) => Observable { return (address?: Address | AccountId | AccountIndex | string | null): Observable => { try { // yes, this can fail, don't care too much, catch will catch it @@ -41,7 +41,7 @@ export function idAndIndex (api: ApiInterface$Rx) { return idToIndex(api)(accountId).pipe( startWith(undefined), - map((accountIndex) => [accountId, accountIndex] as AccountIdAndIndex), + map((accountIndex): AccountIdAndIndex => [accountId, accountIndex] as AccountIdAndIndex), drr() ); } @@ -50,7 +50,7 @@ export function idAndIndex (api: ApiInterface$Rx) { return indexToId(api)(accountIndex).pipe( startWith(undefined), - map((accountId) => [accountId, accountIndex] as AccountIdAndIndex), + map((accountId): AccountIdAndIndex => [accountId, accountIndex] as AccountIdAndIndex), drr() ); } catch (error) { diff --git a/packages/api-derive/src/accounts/idToIndex.ts b/packages/api-derive/src/accounts/idToIndex.ts index 5eff8c46b1..907b860378 100644 --- a/packages/api-derive/src/accounts/idToIndex.ts +++ b/packages/api-derive/src/accounts/idToIndex.ts @@ -4,7 +4,7 @@ import { Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { AccountId, AccountIndex } from '@polkadot/types'; import { indexes, AccountIndexes } from './indexes'; @@ -24,12 +24,14 @@ import { drr } from '../util/drr'; * }); * ``` */ -export function idToIndex (api: ApiInterface$Rx) { +export function idToIndex (api: ApiInterfaceRx): (accountId: AccountId | string) => Observable { return (accountId: AccountId | string): Observable => indexes(api)() .pipe( startWith({}), - map((indexes: AccountIndexes) => (indexes || {})[accountId.toString()]), + map((indexes: AccountIndexes): AccountIndex | undefined => + (indexes || {})[accountId.toString()] + ), drr() ); } diff --git a/packages/api-derive/src/accounts/indexToId.ts b/packages/api-derive/src/accounts/indexToId.ts index 663a755e1b..2e288ec679 100644 --- a/packages/api-derive/src/accounts/indexToId.ts +++ b/packages/api-derive/src/accounts/indexToId.ts @@ -4,7 +4,7 @@ import { Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { ENUMSET_SIZE } from '@polkadot/types/primitive/AccountIndex'; import { AccountId, AccountIndex, Vector } from '@polkadot/types'; @@ -23,8 +23,8 @@ import { drr } from '../util/drr'; * }); * ``` */ -export function indexToId (api: ApiInterface$Rx) { - return (_accountIndex: AccountIndex | string): Observable => { +export function indexToId (api: ApiInterfaceRx): (accountIndex: AccountIndex | string) => Observable { + return (_accountIndex: AccountIndex | string): Observable => { const querySection = api.query.indices || api.query.balances; const accountIndex = _accountIndex instanceof AccountIndex ? _accountIndex @@ -33,11 +33,10 @@ export function indexToId (api: ApiInterface$Rx) { return (querySection.enumSet>(accountIndex.div(ENUMSET_SIZE))) .pipe( startWith([]), - map((accounts) => + map((accounts): AccountId | undefined => (accounts || [])[accountIndex.mod(ENUMSET_SIZE).toNumber()] ), drr() ); }; - } diff --git a/packages/api-derive/src/accounts/indexes.ts b/packages/api-derive/src/accounts/indexes.ts index 5c88a5768c..aa0d4134df 100644 --- a/packages/api-derive/src/accounts/indexes.ts +++ b/packages/api-derive/src/accounts/indexes.ts @@ -4,13 +4,13 @@ import { Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { ENUMSET_SIZE } from '@polkadot/types/primitive/AccountIndex'; import { AccountId, AccountIndex } from '@polkadot/types'; import { drr } from '../util/drr'; -export type AccountIndexes = { [index: string]: AccountIndex }; +export type AccountIndexes = Record; const enumsetSize = ENUMSET_SIZE.toNumber(); @@ -29,7 +29,7 @@ const enumsetSize = ENUMSET_SIZE.toNumber(); * }); * ``` */ -export function indexes (api: ApiInterface$Rx) { +export function indexes (api: ApiInterfaceRx): () => Observable { return (): Observable => { return (api.query.indices.nextEnumSet()) .pipe( @@ -37,12 +37,12 @@ export function indexes (api: ApiInterface$Rx) { // a range of values to query [0, 1, 2, ...]. Retrieve the full enum set for the // specific index - each query can return up to ENUMSET_SIZE (64) records, each // containing an AccountId - switchMap((next: AccountIndex) => + switchMap((next: AccountIndex): Observable => api.query.indices.enumSet.multi([...Array(next.toNumber() + 1).keys()]) as Observable ), - map((all: Array | undefined>) => - (all || []).reduce((result, list, outerIndex) => { - (list || []).forEach((accountId, innerIndex) => { + map((all: (AccountId[] | undefined)[]): AccountIndexes => + (all || []).reduce((result, list, outerIndex): AccountIndexes => { + (list || []).forEach((accountId, innerIndex): void => { // re-create the index based on position 0 is [0][0] and likewise // 64 (0..63 in first) is [1][0] (the first index value in set 2) const index = (outerIndex * enumsetSize) + innerIndex; @@ -51,7 +51,7 @@ export function indexes (api: ApiInterface$Rx) { }); return result; - }, {} as AccountIndexes)), + }, {} as unknown as AccountIndexes)), drr() ); }; diff --git a/packages/api-derive/src/balances/all.ts b/packages/api-derive/src/balances/all.ts index 2e3009afef..88c327ef0e 100644 --- a/packages/api-derive/src/balances/all.ts +++ b/packages/api-derive/src/balances/all.ts @@ -5,7 +5,7 @@ import BN from 'bn.js'; import { combineLatest, of, Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { AccountId, AccountIndex, Address, Balance, BalanceLock, BlockNumber, Index, Option, VestingSchedule } from '@polkadot/types'; import { bnMax } from '@polkadot/util'; @@ -14,7 +14,7 @@ import { bestNumber } from '../chain/bestNumber'; import { DerivedBalances } from '../types'; import { drr } from '../util/drr'; -type Result = [AccountId | undefined, BlockNumber | undefined, [Balance?, Balance?, Array?, Option?, Index?]]; +type Result = [AccountId | undefined, BlockNumber | undefined, [Balance?, Balance?, BalanceLock[]?, Option?, Index?]]; const EMPTY_ACCOUNT = new AccountId(); const ZERO = new Balance(0); @@ -24,10 +24,10 @@ function calcBalances ([accountId = EMPTY_ACCOUNT, bestNumber = ZERO, [freeBalan if (Array.isArray(locks)) { // only get the locks that are valid until passed the current block - const totals = locks.filter((value) => bestNumber && value.until.gt(bestNumber)); + const totals = locks.filter((value): boolean => bestNumber && value.until.gt(bestNumber)); // get the maximum of the locks according to https://github.com/paritytech/substrate/blob/master/srml/balances/src/lib.rs#L699 lockedBalance = totals[0] - ? bnMax(...totals.map(({ amount }) => amount)) as Balance + ? bnMax(...totals.map(({ amount }): Balance => amount)) as Balance : ZERO; } @@ -54,7 +54,7 @@ function calcBalances ([accountId = EMPTY_ACCOUNT, bestNumber = ZERO, [freeBalan reservedBalance, vestedBalance, votingBalance: freeBalance.add(reservedBalance) - } as DerivedBalances; + } as unknown as DerivedBalances; } /** @@ -73,10 +73,10 @@ function calcBalances ([accountId = EMPTY_ACCOUNT, bestNumber = ZERO, [freeBalan * }); * ``` */ -export function all (api: ApiInterface$Rx) { +export function all (api: ApiInterfaceRx): (address: AccountIndex | AccountId | Address | string) => Observable { return (address: AccountIndex | AccountId | Address | string): Observable => { return idAndIndex(api)(address).pipe( - switchMap(([accountId]) => + switchMap(([accountId]): Observable => (accountId ? combineLatest([ of(accountId), diff --git a/packages/api-derive/src/balances/fees.ts b/packages/api-derive/src/balances/fees.ts index afbdf56848..2b866a3208 100644 --- a/packages/api-derive/src/balances/fees.ts +++ b/packages/api-derive/src/balances/fees.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { DerivedFees } from '../types'; import BN from 'bn.js'; @@ -24,7 +24,7 @@ import { drr } from '../util/drr'; * }); * ``` */ -export function fees (api: ApiInterface$Rx) { +export function fees (api: ApiInterfaceRx): () => Observable { return (): Observable => { return ( api.consts.balances @@ -45,13 +45,14 @@ export function fees (api: ApiInterface$Rx) { api.query.balances.transactionByteFee, api.query.balances.transferFee ]) as any as Observable<[BN, BN, BN, BN, BN]> - ).pipe(map(([creationFee, existentialDeposit, transactionBaseFee, transactionByteFee, transferFee]) => ({ + ).pipe( + map(([creationFee, existentialDeposit, transactionBaseFee, transactionByteFee, transferFee]): DerivedFees => ({ creationFee, existentialDeposit, transactionBaseFee, transactionByteFee, transferFee - } as DerivedFees)), + } as unknown as DerivedFees)), drr() ); }; diff --git a/packages/api-derive/src/balances/votingBalances.ts b/packages/api-derive/src/balances/votingBalances.ts index e296c31764..dd9fbe5cf7 100644 --- a/packages/api-derive/src/balances/votingBalances.ts +++ b/packages/api-derive/src/balances/votingBalances.ts @@ -3,18 +3,18 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { combineLatest, Observable, of } from 'rxjs'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { AccountId, AccountIndex, Address } from '@polkadot/types'; import { DerivedBalances } from '../types'; import { drr } from '../util/drr'; import { all } from './all'; -export function votingBalances (api: ApiInterface$Rx) { - return (addresses?: Array): Observable> => { +export function votingBalances (api: ApiInterfaceRx): (addresses?: (AccountId | AccountIndex | Address | string)[]) => Observable { + return (addresses?: (AccountId | AccountIndex | Address | string)[]): Observable => { return ( !addresses || !addresses.length - ? of([] as Array) + ? of([] as DerivedBalances[]) : combineLatest(addresses.map(all(api))) ).pipe( drr() diff --git a/packages/api-derive/src/balances/votingBalancesNominatorsFor.ts b/packages/api-derive/src/balances/votingBalancesNominatorsFor.ts index 53ead1072a..9cde50607d 100644 --- a/packages/api-derive/src/balances/votingBalancesNominatorsFor.ts +++ b/packages/api-derive/src/balances/votingBalancesNominatorsFor.ts @@ -4,7 +4,7 @@ import { Observable, of } from 'rxjs'; import { switchMap } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { AccountId, AccountIndex, Address, Vector } from '@polkadot/types'; import { idAndIndex } from '../accounts/idAndIndex'; @@ -12,13 +12,13 @@ import { DerivedBalances } from '../types'; import { drr } from '../util/drr'; import { votingBalances } from './votingBalances'; -export function votingBalancesNominatorsFor (api: ApiInterface$Rx) { - return (address: AccountId | AccountIndex | Address | string): Observable> => { +export function votingBalancesNominatorsFor (api: ApiInterfaceRx): (address: AccountId | AccountIndex | Address | string) => Observable { + return (address: AccountId | AccountIndex | Address | string): Observable => { return idAndIndex(api)(address).pipe( - switchMap(([accountId]) => + switchMap(([accountId]): Observable => accountId ? (api.query.staking.nominatorsFor>(accountId)) - : of([] as Array) + : of([] as AccountId[]) ), switchMap(votingBalances(api)), drr() diff --git a/packages/api-derive/src/chain/bestNumber.ts b/packages/api-derive/src/chain/bestNumber.ts index 8216e25ebd..1ee6dbbaff 100644 --- a/packages/api-derive/src/chain/bestNumber.ts +++ b/packages/api-derive/src/chain/bestNumber.ts @@ -4,7 +4,7 @@ import { Observable } from 'rxjs'; import { filter, map } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { BlockNumber, Header } from '@polkadot/types'; import { drr } from '../util/drr'; @@ -21,12 +21,12 @@ import { drr } from '../util/drr'; * }); * ``` */ -export function bestNumber (api: ApiInterface$Rx) { +export function bestNumber (api: ApiInterfaceRx): () => Observable { return (): Observable => (api.rpc.chain.subscribeNewHead() as Observable
) .pipe( - filter((header: Header) => header && !!header.blockNumber), - map(({ blockNumber }: Header) => blockNumber), + filter((header: Header): boolean => !!header && !!header.blockNumber), + map(({ blockNumber }: Header): BlockNumber => blockNumber), drr() ); } diff --git a/packages/api-derive/src/chain/bestNumberFinalized.ts b/packages/api-derive/src/chain/bestNumberFinalized.ts index eaad5ae1ae..a602bac54e 100644 --- a/packages/api-derive/src/chain/bestNumberFinalized.ts +++ b/packages/api-derive/src/chain/bestNumberFinalized.ts @@ -4,7 +4,7 @@ import { Observable } from 'rxjs'; import { filter, map } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { BlockNumber, Header } from '@polkadot/types'; import { drr } from '../util/drr'; @@ -22,12 +22,12 @@ import { drr } from '../util/drr'; * }); * ``` */ -export function bestNumberFinalized (api: ApiInterface$Rx) { +export function bestNumberFinalized (api: ApiInterfaceRx): () => Observable { return (): Observable => (api.rpc.chain.subscribeFinalizedHeads() as Observable
) .pipe( - filter((header: Header) => header && !!header.blockNumber), - map(({ blockNumber }: Header) => blockNumber), + filter((header: Header): boolean => !!header && !!header.blockNumber), + map(({ blockNumber }: Header): BlockNumber => blockNumber), drr() ); } diff --git a/packages/api-derive/src/chain/bestNumberLag.ts b/packages/api-derive/src/chain/bestNumberLag.ts index 36f2f63881..610d8d17cc 100644 --- a/packages/api-derive/src/chain/bestNumberLag.ts +++ b/packages/api-derive/src/chain/bestNumberLag.ts @@ -4,7 +4,7 @@ import { Observable, combineLatest } from 'rxjs'; import { map } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { BlockNumber } from '@polkadot/types'; import { drr } from '../util/drr'; @@ -24,13 +24,13 @@ import { bestNumberFinalized } from './bestNumberFinalized'; * }); * ``` */ -export function bestNumberLag (api: ApiInterface$Rx) { +export function bestNumberLag (api: ApiInterfaceRx): () => Observable { return (): Observable => combineLatest([ bestNumber(api)(), bestNumberFinalized(api)() ]).pipe( - map(([bestNumber, bestNumberFinalized]) => + map(([bestNumber, bestNumberFinalized]): BlockNumber => new BlockNumber(bestNumber.sub(bestNumberFinalized)) ), drr() diff --git a/packages/api-derive/src/chain/getHeader.ts b/packages/api-derive/src/chain/getHeader.ts index 654cad1dcc..8344cb15c2 100644 --- a/packages/api-derive/src/chain/getHeader.ts +++ b/packages/api-derive/src/chain/getHeader.ts @@ -4,7 +4,7 @@ import { Observable, combineLatest, of } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { Header } from '@polkadot/types'; import { HeaderExtended } from '../type'; @@ -25,7 +25,7 @@ import { HeaderAndValidators } from './subscribeNewHead'; * console.log(`block #${blockNumber} was authored by ${author}`); * ``` */ -export function getHeader (api: ApiInterface$Rx) { +export function getHeader (api: ApiInterfaceRx): (hash: Uint8Array | string) => Observable { return (hash: Uint8Array | string): Observable => // tslint:disable-next-line (combineLatest([ @@ -34,10 +34,10 @@ export function getHeader (api: ApiInterface$Rx) { ? api.query.session.validators.at(hash) : of([]) ]) as Observable).pipe( - map(([header, validators]) => + map(([header, validators]): HeaderExtended => new HeaderExtended(header, validators) ), - catchError(() => + catchError((): Observable => // where rpc.chain.getHeader throws, we will land here - it can happen that // we supplied an invalid hash. (Due to defaults, storeage will have an // empty value, so only the RPC is affected). So return undefined diff --git a/packages/api-derive/src/chain/subscribeNewHead.ts b/packages/api-derive/src/chain/subscribeNewHead.ts index 356dc87f22..7364b63a52 100644 --- a/packages/api-derive/src/chain/subscribeNewHead.ts +++ b/packages/api-derive/src/chain/subscribeNewHead.ts @@ -4,13 +4,13 @@ import { Observable, combineLatest, of } from 'rxjs'; import { filter, map, switchMap } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { AccountId, Header } from '@polkadot/types'; import { HeaderExtended } from '../type'; import { drr } from '../util/drr'; -export type HeaderAndValidators = [Header, Array]; +export type HeaderAndValidators = [Header, AccountId[]]; /** * @name subscribeNewHead @@ -25,13 +25,11 @@ export type HeaderAndValidators = [Header, Array]; * }); * ``` */ -export function subscribeNewHead (api: ApiInterface$Rx) { +export function subscribeNewHead (api: ApiInterfaceRx): () => Observable { return (): Observable => (api.rpc.chain.subscribeNewHead() as Observable
) .pipe( - filter((header: Header) => - header && !!header.blockNumber - ), + filter((header: Header): boolean => !!header && !!header.blockNumber), switchMap((header: Header): Observable => (combineLatest([ of(header), @@ -43,7 +41,7 @@ export function subscribeNewHead (api: ApiInterface$Rx) { : of([]) ]) as Observable) ), - map(([header, validators]) => + map(([header, validators]): HeaderExtended => new HeaderExtended(header, validators) ), drr() diff --git a/packages/api-derive/src/contracts/fees.ts b/packages/api-derive/src/contracts/fees.ts index 46bab5ac66..f35aa09255 100644 --- a/packages/api-derive/src/contracts/fees.ts +++ b/packages/api-derive/src/contracts/fees.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { DerivedContractFees } from '../types'; import BN from 'bn.js'; @@ -26,7 +26,7 @@ const ZERO = new BN(0); * }); * ``` */ -export function fees (api: ApiInterface$Rx) { +export function fees (api: ApiInterfaceRx): () => Observable { return (): Observable => { const queryBase = api.query.contracts || api.query.contract; @@ -44,11 +44,11 @@ export function fees (api: ApiInterface$Rx) { queryBase.transactionByteFee, queryBase.transferFee ]) - ]) as any as Observable>>).pipe( + ]) as unknown as Observable).pipe( map(([ [rentByteFee, rentDepositOffset, tombstoneDeposit], [callBaseFee, contractFee, createBaseFee, creationFee, transactionBaseFee, transactionByteFee, transferFee] - ]) => ({ + ]): DerivedContractFees => ({ callBaseFee, contractFee, createBaseFee, @@ -59,7 +59,7 @@ export function fees (api: ApiInterface$Rx) { transactionBaseFee, transactionByteFee, transferFee - } as DerivedContractFees)), + } as unknown as DerivedContractFees)), drr() ); } @@ -79,7 +79,7 @@ export function fees (api: ApiInterface$Rx) { api.consts.contracts.transactionBaseFee, api.consts.contracts.transactionByteFee, api.consts.contracts.transferFee - ]) as any as Observable> + ]) as unknown as Observable // Support versions pre spec_version 101 and get values from storage : api.queryMulti([ queryBase.callBaseFee, @@ -92,9 +92,10 @@ export function fees (api: ApiInterface$Rx) { queryBase.transactionBaseFee, queryBase.transactionByteFee, queryBase.transferFee - ]) as any as Observable> - ).pipe(map( - ([callBaseFee, contractFee, createBaseFee, creationFee, rentByteFee, rentDepositOffset, tombstoneDeposit, transactionBaseFee, transactionByteFee, transferFee]) => ({ + ]) as unknown as Observable + ).pipe( + map( + ([callBaseFee, contractFee, createBaseFee, creationFee, rentByteFee, rentDepositOffset, tombstoneDeposit, transactionBaseFee, transactionByteFee, transferFee]): DerivedContractFees => ({ callBaseFee, contractFee, createBaseFee, @@ -105,7 +106,7 @@ export function fees (api: ApiInterface$Rx) { transactionBaseFee, transactionByteFee, transferFee - } as DerivedContractFees) + } as unknown as DerivedContractFees) ), drr() ); diff --git a/packages/api-derive/src/democracy/referendumInfo.ts b/packages/api-derive/src/democracy/referendumInfo.ts index 2e97564c42..2a8564b083 100644 --- a/packages/api-derive/src/democracy/referendumInfo.ts +++ b/packages/api-derive/src/democracy/referendumInfo.ts @@ -5,7 +5,7 @@ import BN from 'bn.js'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { Option, ReferendumInfo } from '@polkadot/types'; import { isNull } from '@polkadot/util'; @@ -25,15 +25,14 @@ export function constructInfo (index: BN | number, optionInfo?: Option Observable> { return (index: BN | number): Observable> => { return (api.query.democracy.referendumInfoOf>(index)) .pipe( - map((optionInfo) => + map((optionInfo): Option => constructInfo(index, optionInfo) ), drr() ); }; - } diff --git a/packages/api-derive/src/democracy/referendumInfos.ts b/packages/api-derive/src/democracy/referendumInfos.ts index 069ffcb271..5799f5be80 100644 --- a/packages/api-derive/src/democracy/referendumInfos.ts +++ b/packages/api-derive/src/democracy/referendumInfos.ts @@ -5,27 +5,26 @@ import BN from 'bn.js'; import { Observable, of } from 'rxjs'; import { map } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { Option, ReferendumInfo, Vector } from '@polkadot/types'; import { ReferendumInfoExtended } from '../type'; import { drr } from '../util/drr'; import { constructInfo } from './referendumInfo'; -export function referendumInfos (api: ApiInterface$Rx) { - return (ids: Array = []): Observable>> => { +export function referendumInfos (api: ApiInterfaceRx): (ids?: (BN | number)[]) => Observable[]> { + return (ids: (BN | number)[] = []): Observable[]> => { return ( !ids || !ids.length - ? of([] as Array>) + ? of([] as Option[]) : api.query.democracy.referendumInfoOf.multi(ids) as Observable>> ).pipe( - map((infos) => - ids.map((id, index) => - constructInfo(id, infos[index]) - ) - ), - drr() - ); + map((infos): Option[] => + ids.map((id, index): Option => + constructInfo(id, infos[index]) + ) + ), + drr() + ); }; - } diff --git a/packages/api-derive/src/democracy/referendumVotesFor.ts b/packages/api-derive/src/democracy/referendumVotesFor.ts index 66b8cb9bbe..090a442433 100644 --- a/packages/api-derive/src/democracy/referendumVotesFor.ts +++ b/packages/api-derive/src/democracy/referendumVotesFor.ts @@ -5,30 +5,30 @@ import BN from 'bn.js'; import { combineLatest, Observable, of } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { AccountId, Balance, Vector, Vote } from '@polkadot/types'; -import { DerivedReferendumVote } from '../types'; +import { DerivedBalances, DerivedReferendumVote } from '../types'; import { drr } from '../util/drr'; import { votes } from './votes'; import { votingBalances } from '../balances/votingBalances'; -export function referendumVotesFor (api: ApiInterface$Rx) { - return (referendumId: BN | number): Observable> => +export function referendumVotesFor (api: ApiInterfaceRx): (referendumId: BN | number) => Observable { + return (referendumId: BN | number): Observable => (api.query.democracy.votersFor>(referendumId)).pipe( - switchMap((votersFor) => + switchMap((votersFor): Observable<[Vector, Vote[], DerivedBalances[]]> => combineLatest([ of(votersFor), votes(api)(referendumId as BN, votersFor), votingBalances(api)(votersFor) ]) ), - map(([votersFor, votes, balances]) => + map(([votersFor, votes, balances]): DerivedReferendumVote[] => votersFor.map((accountId, index): DerivedReferendumVote => ({ accountId, balance: balances[index].votingBalance || new Balance(0), vote: votes[index] || new Vote(0) - } as DerivedReferendumVote)) + } as unknown as DerivedReferendumVote)) ), drr() ); diff --git a/packages/api-derive/src/democracy/referendums.ts b/packages/api-derive/src/democracy/referendums.ts index 4d190efb94..20e8330950 100644 --- a/packages/api-derive/src/democracy/referendums.ts +++ b/packages/api-derive/src/democracy/referendums.ts @@ -2,25 +2,26 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. +import BN from 'bn.js'; import { Observable, of } from 'rxjs'; import { switchMap } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { Option, ReferendumIndex } from '@polkadot/types'; import { ReferendumInfoExtended } from '../type'; import { drr } from '../util/drr'; import { referendumInfos } from './referendumInfos'; -export function referendums (api: ApiInterface$Rx) { - return (): Observable>> => +export function referendums (api: ApiInterfaceRx): () => Observable[]> { + return (): Observable[]> => (api.queryMulti([ api.query.democracy.nextTally, api.query.democracy.referendumCount ]) as any as Observable<[ReferendumIndex?, ReferendumIndex?]>).pipe( - switchMap(([nextTally, referendumCount]) => + switchMap(([nextTally, referendumCount]): Observable[]> => referendumCount && nextTally && referendumCount.gt(nextTally) && referendumCount.gtn(0) ? referendumInfos(api)( - [...Array(referendumCount.sub(nextTally).toNumber())].map((_, i) => + [...Array(referendumCount.sub(nextTally).toNumber())].map((_, i): BN => nextTally.addn(i) ) ) diff --git a/packages/api-derive/src/democracy/votes.ts b/packages/api-derive/src/democracy/votes.ts index 5c7286f52d..225811a78d 100644 --- a/packages/api-derive/src/democracy/votes.ts +++ b/packages/api-derive/src/democracy/votes.ts @@ -4,19 +4,21 @@ import BN from 'bn.js'; import { Observable, of } from 'rxjs'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { AccountId, Vector, Vote } from '@polkadot/types'; import { drr } from '../util/drr'; -export function votes (api: ApiInterface$Rx) { - return (referendumId: BN, accountIds: Array = []): Observable> => { +export function votes (api: ApiInterfaceRx): (referendumId: BN, accountIds?: AccountId[]) => Observable { + return (referendumId: BN, accountIds: AccountId[] = []): Observable => { return (( !accountIds || !accountIds.length ? of([]) : api.query.democracy.voteOf.multi( - accountIds.map((accountId) => [referendumId, accountId]) + accountIds.map((accountId): [BN, AccountId] => + [referendumId, accountId] ) - ) as Observable>).pipe(drr()); + ) + ) as Observable>).pipe(drr()); }; } diff --git a/packages/api-derive/src/index.spec.ts b/packages/api-derive/src/index.spec.ts index 3c001b0512..b029b2cfd8 100644 --- a/packages/api-derive/src/index.spec.ts +++ b/packages/api-derive/src/index.spec.ts @@ -8,17 +8,17 @@ import MockProvider from '@polkadot/rpc-provider/mock'; import { Derive } from '.'; -const testFunction = (api: ApiRx) => { +const testFunction = (api: ApiRx): any => { return < Section extends keyof Derive, Method extends keyof (typeof api.derive[Section]) - >(section: Section, method: Method, inputs: any[]) => { - describe(`derive.${section}.${method}`, () => { - it('should be a function', () => { + >(section: Section, method: Method, inputs: any[]): void => { + describe(`derive.${section}.${method}`, (): void => { + it('should be a function', (): void => { expect(typeof api.derive[section][method]).toBe('function'); }); - it('should return an Observable', () => { + it('should return an Observable', (): void => { expect((api.derive[section][method] as any)(...inputs)).toBeInstanceOf(Observable); }); }); @@ -27,12 +27,12 @@ const testFunction = (api: ApiRx) => { // https://github.com/polkadot-js/api/pull/1066#issuecomment-509142048 // https://github.com/polkadot-js/api/issues/1064 -describe.skip('derive', () => { - describe('builtin', () => { +describe.skip('derive', (): void => { + describe('builtin', (): void => { const api = new ApiRx(new MockProvider()); - beforeAll((done) => { - api.isReady.subscribe(() => done()); + beforeAll((done): void => { + api.isReady.subscribe((): void => done()); }); testFunction(api)('accounts', 'idAndIndex', []); @@ -59,21 +59,21 @@ describe.skip('derive', () => { testFunction(api)('session', 'sessionProgress', []); }); - describe('custom', () => { + describe('custom', (): void => { const api = new ApiRx({ derives: { balances: { - fees: () => () => from(['a', 'b']) + fees: (): any => (): Observable => from(['a', 'b']) }, custom: { - test: () => () => from([1, 2, 3]) + test: (): any => (): Observable => from([1, 2, 3]) } }, provider: new MockProvider() }); - beforeAll((done) => { - api.isReady.subscribe(() => done()); + beforeAll((done): void => { + api.isReady.subscribe((): void => done()); }); // override diff --git a/packages/api-derive/src/index.ts b/packages/api-derive/src/index.ts index bfcf4c73c9..49f6d4044d 100644 --- a/packages/api-derive/src/index.ts +++ b/packages/api-derive/src/index.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { AnyFunction } from '@polkadot/types/types'; import { Observable } from 'rxjs'; @@ -19,33 +19,29 @@ export * from './type'; export type ReturnTypes
= { [Method in keyof Section]: Section[Method] extends AnyFunction - ? ReturnType // ReturnType will be the inner function, i.e. without (api) argument - : never; + ? ReturnType // ReturnType will be the inner function, i.e. without (api) argument + : never; }; export type DeriveSections = { [Section in keyof AllSections]: ReturnTypes }; -export interface DeriveCustom { - [index: string]: { - [index: string]: (api: ApiInterface$Rx) => (...args: Array) => Observable - }; -} +export type DeriveCustom = Record (...args: any[]) => Observable>>; /** * Returns an object that will inject `api` into all the functions inside * `allSections`, and keep the object architecture of `allSections`. */ -function injectFunctions (api: ApiInterface$Rx, allSections: AllSections) { +function injectFunctions (api: ApiInterfaceRx, allSections: AllSections): DeriveSections { return Object .keys(allSections) - .reduce((deriveAcc, sectionName) => { + .reduce((deriveAcc, sectionName): DeriveSections => { const section = allSections[sectionName as keyof AllSections]; deriveAcc[sectionName as keyof AllSections] = Object .keys(section) - .reduce((sectionAcc, _methodName) => { + .reduce((sectionAcc, _methodName): ReturnTypes => { const methodName = _methodName as keyof typeof section; // Not sure what to do here, casting as any. Though the final types are good const method = (section[methodName] as any)(api); @@ -53,16 +49,18 @@ function injectFunctions (api: ApiInterface$Rx, allSections: AllSec (sectionAcc as any)[methodName] = method; return sectionAcc; - }, {} as ReturnTypes); + }, {} as unknown as ReturnTypes); return deriveAcc; - }, {} as DeriveSections); + }, {} as unknown as DeriveSections); } export const derive = { accounts, balances, chain, contracts, democracy, session, staking }; export type Derive = typeof derive; -export default function decorateDerive (api: ApiInterface$Rx, custom: DeriveCustom = {}) { +// FIXME I have no idea how to get this done +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export default function decorateDerive (api: ApiInterfaceRx, custom: DeriveCustom = {}) { return { ...injectFunctions(api, derive), ...injectFunctions(api, custom) diff --git a/packages/api-derive/src/session/eraLength.ts b/packages/api-derive/src/session/eraLength.ts index bba3edb9b7..5ef8d68150 100644 --- a/packages/api-derive/src/session/eraLength.ts +++ b/packages/api-derive/src/session/eraLength.ts @@ -5,15 +5,15 @@ import BN from 'bn.js'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { drr } from '../util/drr'; import { info } from './info'; -export function eraLength (api: ApiInterface$Rx) { +export function eraLength (api: ApiInterfaceRx): () => Observable { return (): Observable => info(api)().pipe( - map(({ eraLength }) => eraLength), + map(({ eraLength }): BN => eraLength), drr() ); } diff --git a/packages/api-derive/src/session/eraProgress.ts b/packages/api-derive/src/session/eraProgress.ts index 93e467c1bd..7ddd070daf 100644 --- a/packages/api-derive/src/session/eraProgress.ts +++ b/packages/api-derive/src/session/eraProgress.ts @@ -5,15 +5,15 @@ import BN from 'bn.js'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { drr } from '../util/drr'; import { info } from './info'; -export function eraProgress (api: ApiInterface$Rx) { +export function eraProgress (api: ApiInterfaceRx): () => Observable { return (): Observable => info(api)().pipe( - map(({ eraProgress }) => eraProgress), + map(({ eraProgress }): BN => eraProgress), drr() ); } diff --git a/packages/api-derive/src/session/info.ts b/packages/api-derive/src/session/info.ts index ab39959924..9fd25f9c19 100644 --- a/packages/api-derive/src/session/info.ts +++ b/packages/api-derive/src/session/info.ts @@ -7,19 +7,19 @@ import { DerivedSessionInfo } from '../types'; import BN from 'bn.js'; import { Observable, combineLatest, of } from 'rxjs'; import { map } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { BlockNumber, Option } from '@polkadot/types'; import { drr } from '../util/drr'; import { bestNumber } from '../chain'; -type Result_0_94 = [BN, [BN, Option, BN, BN, BN]]; +type Result0to94 = [BN, [BN, Option, BN, BN, BN]]; type Result = [BN, [BN, BN]]; const ZERO = new BN(0); // internal helper to just split the logic - take all inputs, do the calculations and combine -function createDerived_0_94 ([bestNumber, [currentIndex, _lastLengthChange, sessionLength, lastEraLengthChange, sessionsPerEra]]: Result_0_94): DerivedSessionInfo { +function createDerived0to94 ([bestNumber, [currentIndex, _lastLengthChange, sessionLength, lastEraLengthChange, sessionsPerEra]]: Result0to94): DerivedSessionInfo { const eraLength = sessionLength.mul(sessionsPerEra); const lastLengthChange = _lastLengthChange ? _lastLengthChange.unwrapOr(ZERO) @@ -45,7 +45,7 @@ function createDerived_0_94 ([bestNumber, [currentIndex, _lastLengthChange, sess sessionLength, sessionsPerEra, sessionProgress - } as DerivedSessionInfo; + } as unknown as DerivedSessionInfo; } function createDerived ([sessionsPerEra, [currentIndex, currentEra]]: Result): DerivedSessionInfo { @@ -61,43 +61,47 @@ function createDerived ([sessionsPerEra, [currentIndex, currentEra]]: Result): D sessionLength: ZERO, sessionsPerEra, sessionProgress: ZERO - } as DerivedSessionInfo; + } as unknown as DerivedSessionInfo; } /** * @description Retrieves all the session and era info and calculates specific values on it as the length of the session and eras */ -export function info (api: ApiInterface$Rx) { +export function info (api: ApiInterfaceRx): () => Observable { return (): Observable => { // With substrate `spec_version 94`, the era and session has been explicitly exposed as `parameter_types`. // pre-94 we had more info and needed to calculate (handle old/Alex first) // https://github.com/paritytech/substrate/commit/dbf322620948935d2bbae214504e6c668c3073ed#diff-c29f42d6b931fa93ba038dbbbfec3055 return api.query.session.lastLengthChange - ? (combineLatest([ - bestNumber(api)(), - api.queryMulti([ - api.query.session.currentIndex, - api.query.session.lastLengthChange, - api.query.session.sessionLength, - api.query.staking.lastEraLengthChange, - api.query.staking.sessionsPerEra - ]) - ]) as any as Observable).pipe( - map(createDerived_0_94), + ? ( + combineLatest([ + bestNumber(api)(), + api.queryMulti([ + api.query.session.currentIndex, + api.query.session.lastLengthChange, + api.query.session.sessionLength, + api.query.staking.lastEraLengthChange, + api.query.staking.sessionsPerEra + ]) + ]) as any as Observable + ).pipe( + map(createDerived0to94), drr() ) - : (combineLatest([ - // sessionsPerEra: - // substrate spec_version >= 94 : get from parameter_types exposed as api.consts - // https://github.com/paritytech/substrate/pull/2802/files#diff-5e5e1c3aec9ddfde0a9054d062ab3db9R156 - of(api.consts.staking.sessionsPerEra), - api.queryMulti([ - api.query.session.currentIndex, - api.query.staking.currentEra - ]) - ]) as any as Observable).pipe( - map(createDerived), - drr() - ); + : ( + combineLatest([ + // sessionsPerEra: + // substrate spec_version >= 94 : get from parameter_types exposed as api.consts + // https://github.com/paritytech/substrate/pull/2802/files#diff-5e5e1c3aec9ddfde0a9054d062ab3db9R156 + of(api.consts.staking.sessionsPerEra), + api.queryMulti([ + api.query.session.currentIndex, + api.query.staking.currentEra + ]) + ]) as unknown as Observable + ).pipe( + map(createDerived), + drr() + ); }; } diff --git a/packages/api-derive/src/session/sessionProgress.ts b/packages/api-derive/src/session/sessionProgress.ts index f486c7241c..6568062b4c 100644 --- a/packages/api-derive/src/session/sessionProgress.ts +++ b/packages/api-derive/src/session/sessionProgress.ts @@ -5,15 +5,15 @@ import BN from 'bn.js'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { drr } from '../util/drr'; import { info } from './info'; -export function sessionProgress (api: ApiInterface$Rx) { +export function sessionProgress (api: ApiInterfaceRx): () => Observable { return (): Observable => info(api)().pipe( - map(({ sessionProgress }) => sessionProgress), + map(({ sessionProgress }): BN => sessionProgress), drr() ); } diff --git a/packages/api-derive/src/staking/controllers.ts b/packages/api-derive/src/staking/controllers.ts index 1d25b44af2..488ac1fcea 100644 --- a/packages/api-derive/src/staking/controllers.ts +++ b/packages/api-derive/src/staking/controllers.ts @@ -4,7 +4,7 @@ import { Observable, combineLatest, of } from 'rxjs'; import { switchMap } from 'rxjs/operators'; -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { AccountId, Option } from '@polkadot/types'; import { drr } from '../util/drr'; @@ -12,14 +12,14 @@ import { drr } from '../util/drr'; /** * @description From the list of stash accounts, retrieve the list of controllers */ -export function controllers (api: ApiInterface$Rx) { - return (): Observable<[Array, Array>]> => - (api.query.staking.validators() as any as Observable<[Array, any]>) +export function controllers (api: ApiInterfaceRx): () => Observable<[AccountId[], Option[]]> { + return (): Observable<[AccountId[], Option[]]> => + (api.query.staking.validators() as any as Observable<[AccountId[], any]>) .pipe( - switchMap(([stashIds]) => + switchMap(([stashIds]): Observable<[AccountId[], Option[]]> => combineLatest([ of(stashIds), - api.query.staking.bonded.multi(stashIds) as any as Observable>> + api.query.staking.bonded.multi(stashIds) as any as Observable[]> ]) ), drr() diff --git a/packages/api-derive/src/staking/info.ts b/packages/api-derive/src/staking/info.ts index 9774860bf9..8b742d7ffa 100644 --- a/packages/api-derive/src/staking/info.ts +++ b/packages/api-derive/src/staking/info.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { ApiInterface$Rx } from '@polkadot/api/types'; +import { ApiInterfaceRx } from '@polkadot/api/types'; import { DerivedStaking, DerivedUnlocking } from '../types'; import BN from 'bn.js'; @@ -16,30 +16,8 @@ import { bestNumber } from '../chain/bestNumber'; import { eraLength } from '../session/eraLength'; import { drr } from '../util/drr'; -function calculateUnlocking (stakingLedger: StakingLedger | undefined, eraLength: BN, bestNumber: BlockNumber): DerivedUnlocking | undefined { - if (isUndefined(stakingLedger)) { - return undefined; - } - - // select the Unlockchunks that can't be redeemed yet. - const unlockingChunks = stakingLedger.unlocking.filter((chunk) => remainingBlocks(chunk.era, eraLength, bestNumber).gtn(0)); - - if (!unlockingChunks.length) { - return undefined; - } - - // group the Unlockchunks that have the same era and sum their values - const groupedResult = groupByEra(unlockingChunks); - const results = Object.entries(groupedResult).map(([eraString, value]) => ({ - value, - remainingBlocks: remainingBlocks(new BlockNumber(eraString), eraLength, bestNumber) - })); - - return results.length ? results : undefined; -} - -function groupByEra (list: UnlockChunk[]) { - return list.reduce((map, { era, value }) => { +function groupByEra (list: UnlockChunk[]): Record { + return list.reduce((map, { era, value }): Record => { const key = era.toString(); if (!map[key]) { @@ -49,27 +27,51 @@ function groupByEra (list: UnlockChunk[]) { } return map; - }, {} as { [index: string]: BN }); + }, {} as unknown as Record); } -function redeemableSum (stakingLedger: StakingLedger | undefined, eraLength: BN, bestNumber: BlockNumber) { +function remainingBlocks (era: BN, eraLength: BN, bestNumber: BlockNumber): BN { + const remaining = eraLength.mul(era).sub(bestNumber); + + return remaining.lten(0) ? new BN(0) : remaining; +} + +function calculateUnlocking (stakingLedger: StakingLedger | undefined, eraLength: BN, bestNumber: BlockNumber): DerivedUnlocking | undefined { + if (isUndefined(stakingLedger)) { + return undefined; + } + + // select the Unlockchunks that can't be redeemed yet. + const unlockingChunks = stakingLedger.unlocking.filter((chunk): boolean => + remainingBlocks(chunk.era, eraLength, bestNumber).gtn(0) + ); + + if (!unlockingChunks.length) { + return undefined; + } + + // group the Unlockchunks that have the same era and sum their values + const groupedResult = groupByEra(unlockingChunks); + const results = Object.entries(groupedResult).map(([eraString, value]): { value: BN; remainingBlocks: BN } => ({ + value, + remainingBlocks: remainingBlocks(new BlockNumber(eraString), eraLength, bestNumber) + })); + + return results.length ? results : undefined; +} + +function redeemableSum (stakingLedger: StakingLedger | undefined, eraLength: BN, bestNumber: BlockNumber): BN { if (isUndefined(stakingLedger)) { return new BN(0); } return stakingLedger.unlocking - .filter((chunk) => remainingBlocks(chunk.era, eraLength, bestNumber).eqn(0)) - .reduce((curr, prev) => { + .filter((chunk): boolean => remainingBlocks(chunk.era, eraLength, bestNumber).eqn(0)) + .reduce((curr, prev): BN => { return curr.add(prev.value); }, new BN(0)); } -function remainingBlocks (era: BN, eraLength: BN, bestNumber: BlockNumber) { - const remaining = eraLength.mul(era).sub(bestNumber); - - return remaining.lten(0) ? new BN(0) : remaining; -} - function nextSessionId (_nextKeyFor: Option): AccountId | undefined { const nextKeyFor: SessionKeys | SessionKey | null = _nextKeyFor.unwrapOr(null); @@ -79,7 +81,7 @@ function nextSessionId (_nextKeyFor: Option): AccountId | und : undefined; } -function withStashController (api: ApiInterface$Rx, accountId: AccountId, controllerId: AccountId): Observable { +function withStashController (api: ApiInterfaceRx, accountId: AccountId, controllerId: AccountId): Observable { const stashId = accountId; return ( @@ -94,9 +96,9 @@ function withStashController (api: ApiInterface$Rx, accountId: AccountId, contro [api.query.staking.stakers, stashId], [api.query.staking.validators, stashId] ]) - ]) as any as Observable<[BN, BlockNumber, [Option, Option, [Array], RewardDestination, Exposure, [ValidatorPrefs]]]> + ]) as any as Observable<[BN, BlockNumber, [Option, Option, [AccountId[]], RewardDestination, Exposure, [ValidatorPrefs]]]> ).pipe( - map(([eraLength, bestNumber, [nextKeyFor, _stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs]]]) => { + map(([eraLength, bestNumber, [nextKeyFor, _stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs]]]): DerivedStaking => { const stakingLedger = _stakingLedger.unwrapOr(null) || undefined; return { @@ -111,13 +113,13 @@ function withStashController (api: ApiInterface$Rx, accountId: AccountId, contro stashId, unlocking: calculateUnlocking(stakingLedger, eraLength, bestNumber), validatorPrefs - } as DerivedStaking; + } as unknown as DerivedStaking; }), drr() ); } -function withControllerLedger (api: ApiInterface$Rx, accountId: AccountId, stakingLedger: StakingLedger): Observable { +function withControllerLedger (api: ApiInterfaceRx, accountId: AccountId, stakingLedger: StakingLedger): Observable { const controllerId = accountId; const stashId = stakingLedger.stash; @@ -128,9 +130,9 @@ function withControllerLedger (api: ApiInterface$Rx, accountId: AccountId, staki [api.query.staking.payee, stashId], [api.query.staking.stakers, stashId], [api.query.staking.validators, stashId] - ]) as any as Observable<[Option, [Array], RewardDestination, Exposure, [ValidatorPrefs]]> + ]) as any as Observable<[Option, [AccountId[]], RewardDestination, Exposure, [ValidatorPrefs]]> ).pipe( - map(([nextKeyFor, [nominators], rewardDestination, stakers, [validatorPrefs]]) => ({ + map(([nextKeyFor, [nominators], rewardDestination, stakers, [validatorPrefs]]): DerivedStaking => ({ accountId, controllerId, nextSessionId: nextSessionId(nextKeyFor), @@ -140,7 +142,7 @@ function withControllerLedger (api: ApiInterface$Rx, accountId: AccountId, staki stakingLedger, stashId, validatorPrefs - } as DerivedStaking)), + } as unknown as DerivedStaking)), drr() ); } @@ -148,7 +150,7 @@ function withControllerLedger (api: ApiInterface$Rx, accountId: AccountId, staki /** * @description From either a stash or controller id, retrieve the controllerId, stashId, nextSessionId, stakingLedger and preferences */ -export function info (api: ApiInterface$Rx) { +export function info (api: ApiInterfaceRx): (_accountId: Uint8Array | string) => Observable { return (_accountId: Uint8Array | string): Observable => { const accountId = new AccountId(_accountId); @@ -158,7 +160,7 @@ export function info (api: ApiInterface$Rx) { [api.query.staking.ledger, accountId] // try to map to stash ]) as any as Observable<[Option, Option]> ).pipe( - switchMap(([controllerId, stakingLedger]) => + switchMap(([controllerId, stakingLedger]): Observable => controllerId.isSome // we have a controller, so input was a stash, great ? withStashController(api, accountId, controllerId.unwrap()) @@ -166,7 +168,7 @@ export function info (api: ApiInterface$Rx) { stakingLedger.isSome ? withControllerLedger(api, accountId, stakingLedger.unwrap()) // dangit, this is something else, ok, we are done - : of({ accountId } as DerivedStaking) + : of({ accountId } as unknown as DerivedStaking) ) ), drr() diff --git a/packages/api-derive/src/type/HeaderExtended.ts b/packages/api-derive/src/type/HeaderExtended.ts index 1da5e98242..5d91f591c2 100644 --- a/packages/api-derive/src/type/HeaderExtended.ts +++ b/packages/api-derive/src/type/HeaderExtended.ts @@ -13,7 +13,7 @@ import { AnyJsonObject } from '@polkadot/types/types'; export default class HeaderExtended extends Header { private _author?: AccountId; - constructor (header: Header | null = null, sessionValidators: Array = []) { + public constructor (header: Header | null = null, sessionValidators: AccountId[] = []) { super(header); if (!header || !header.digest || !sessionValidators.length) { @@ -59,14 +59,14 @@ export default class HeaderExtended extends Header { /** * @description Convenience method, returns the author for the block */ - get author (): AccountId | undefined { + public get author (): AccountId | undefined { return this._author; } /** * @description Creates the JSON representation */ - toJSON (): AnyJsonObject { + public toJSON (): AnyJsonObject { return { ...super.toJSON() as AnyJsonObject, author: this.author diff --git a/packages/api-derive/src/type/ReferendumInfoExtended.ts b/packages/api-derive/src/type/ReferendumInfoExtended.ts index 07260149e7..299494d6e0 100644 --- a/packages/api-derive/src/type/ReferendumInfoExtended.ts +++ b/packages/api-derive/src/type/ReferendumInfoExtended.ts @@ -14,7 +14,7 @@ import { AnyJsonObject } from '@polkadot/types/types'; export default class ReferendumInfoExtended extends ReferendumInfo { private _index: ReferendumIndex; - constructor (value: ReferendumInfo | ReferendumInfoExtended, index?: BN | number) { + public constructor (value: ReferendumInfo | ReferendumInfoExtended, index?: BN | number) { super(value); this._index = value instanceof ReferendumInfoExtended @@ -25,14 +25,14 @@ export default class ReferendumInfoExtended extends ReferendumInfo { /** * @description Convenience getter, returns the referendumIndex */ - get index (): ReferendumIndex { + public get index (): ReferendumIndex { return this._index; } /** * @description Creates the JSON representation */ - toJSON (): AnyJsonObject { + public toJSON (): AnyJsonObject { return { ...super.toJSON() as AnyJsonObject, index: this.index.toJSON() diff --git a/packages/api-derive/src/types.ts b/packages/api-derive/src/types.ts index 22630ebe41..69b107ca99 100644 --- a/packages/api-derive/src/types.ts +++ b/packages/api-derive/src/types.ts @@ -16,9 +16,7 @@ export interface DerivedBalances { vestedBalance: BN; } -export type DerivedBalancesMap = { - [index: string]: DerivedBalances -}; +export type DerivedBalancesMap = Record; export interface DerivedContractFees { callBaseFee: BN; @@ -63,7 +61,7 @@ export interface DerivedStaking { accountId: AccountId; controllerId?: AccountId; nextSessionId?: AccountId; - nominators?: Array; + nominators?: AccountId[]; redeemable?: BN; rewardDestination?: RewardDestination; stakers?: Exposure; @@ -73,4 +71,4 @@ export interface DerivedStaking { validatorPrefs?: ValidatorPrefs; } -export type DerivedUnlocking = Array<{remainingBlocks: BN, value: BN}>; +export type DerivedUnlocking = { remainingBlocks: BN; value: BN }[]; diff --git a/packages/api-derive/src/util/drr.spec.ts b/packages/api-derive/src/util/drr.spec.ts index 240c52603e..225e059ffa 100644 --- a/packages/api-derive/src/util/drr.spec.ts +++ b/packages/api-derive/src/util/drr.spec.ts @@ -6,24 +6,24 @@ import { of, timer } from 'rxjs'; import { drr } from './drr'; -describe('drr', () => { - it('should not fire twice the same value', (done) => { +describe('drr', (): void => { + it('should not fire twice the same value', (done): void => { let count = 0; - of(1, 1).pipe(drr()).subscribe(() => { ++count; }); + of(1, 1).pipe(drr()).subscribe((): void => { ++count; }); - setTimeout(() => { + setTimeout((): void => { expect(count).toBe(1); done(); }, 50); }); - it('should be a ReplaySubject(1)', (done) => { + it('should be a ReplaySubject(1)', (done): void => { const obs = timer(0, 100).pipe(drr()); // Starts at 0, increments every 100ms obs.subscribe(); // Fire the observable // Subscribe another time after some time, i.e. after the observable has fired - setTimeout(() => { - obs.subscribe((value) => { + setTimeout((): void => { + obs.subscribe((value): void => { expect(value > 1).toBe(true); done(); }); diff --git a/packages/api-derive/src/util/drr.ts b/packages/api-derive/src/util/drr.ts index 7f03077814..028a0585df 100644 --- a/packages/api-derive/src/util/drr.ts +++ b/packages/api-derive/src/util/drr.ts @@ -6,6 +6,8 @@ import { catchError, distinctUntilChanged, publishReplay, refCount } from 'rxjs/ import { Observable } from 'rxjs'; import { logger } from '@polkadot/util'; +type DrrResult = (source$: Observable) => Observable; + const l = logger('drr'); /** @@ -13,12 +15,12 @@ const l = logger('drr'); * * @ignore */ -export const drr = () => (source$: Observable): Observable => +export const drr = (): DrrResult => (source$: Observable): Observable => source$.pipe( - catchError(err => { - l.error(err); + catchError((error): Observable => { + l.error(error); - throw err; + throw error; }), distinctUntilChanged(), publishReplay(1), diff --git a/packages/api-derive/test/e2e/promise.spec.ts b/packages/api-derive/test/e2e/promise.spec.ts index 16b48659bf..00e2b50d9a 100644 --- a/packages/api-derive/test/e2e/promise.spec.ts +++ b/packages/api-derive/test/e2e/promise.spec.ts @@ -15,29 +15,33 @@ const ALICE_STASH = testingPairs().alice_stash.address; const WS = 'ws://127.0.0.1:9944/'; // const WS = 'wss://poc3-rpc.polkadot.io/'; -describe.skip('derive e2e', () => { +describe.skip('derive e2e', (): void => { let api: ApiPromise; - beforeAll(() => { + beforeAll((): void => { jest.setTimeout(30000); }); - beforeEach(async (done) => { + beforeEach(async (done): Promise => { api = await ApiPromise.create(new WsProvider(WS)); done(); }); - it('returns correct results', async () => { + it('returns correct results', async (): Promise => { // https://github.com/polkadot-js/api/issues/777 const block1 = await api.derive.chain.bestNumber(); - await new Promise((resolve) => setTimeout(resolve, 15000)); + + await new Promise((resolve): void => { + setTimeout(resolve, 15000); + }); + const block2 = await api.derive.chain.bestNumber(); expect(block1.eq(block2)).toBe(false); }); - it('subscribes to newHead, retrieving the actual validator', (done) => { - return api.derive.chain.subscribeNewHead(({ author }: HeaderExtended) => { + it('subscribes to newHead, retrieving the actual validator', (done): Promise<() => void> => { + return api.derive.chain.subscribeNewHead(({ author }: HeaderExtended): void => { console.log('author', author && author.toString()); if (author) { @@ -46,16 +50,16 @@ describe.skip('derive e2e', () => { }); }); - it('retrieves the fees (api.queryMulti)', (done) => { - return api.derive.balances.fees((fees: DerivedFees) => { + it('retrieves the fees (api.queryMulti)', (done): Promise<() => void> => { + return api.derive.balances.fees((fees: DerivedFees): void => { console.error('fees', JSON.stringify(fees)); done(); }); }); - it('retrieves the balances', (done) => { - return api.derive.balances.all('5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y', (balance: DerivedBalances) => { + it('retrieves the balances', (done): Promise<() => void> => { + return api.derive.balances.all('5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y', (balance: DerivedBalances): void => { console.error(JSON.stringify(balance)); if (balance.freeBalance.gtn(1)) { @@ -64,8 +68,8 @@ describe.skip('derive e2e', () => { }); }); - it('retrieves balances for a problematic account', (done) => { - return api.derive.balances.all('5F7BJL6Z4m8RLtK7nXEqqpEqhBbd535Z3CZeYF6ccvaQAY6N', (balance: DerivedBalances) => { + it('retrieves balances for a problematic account', (done): Promise<() => void> => { + return api.derive.balances.all('5F7BJL6Z4m8RLtK7nXEqqpEqhBbd535Z3CZeYF6ccvaQAY6N', (balance: DerivedBalances): void => { console.error(JSON.stringify(balance)); if (balance.availableBalance.eqn(0)) { @@ -74,10 +78,10 @@ describe.skip('derive e2e', () => { }); }); - it('retrieves all session info', (done) => { + it('retrieves all session info', (done): Promise<() => void> => { let count = 0; - return api.derive.session.info((info: DerivedSessionInfo) => { + return api.derive.session.info((info: DerivedSessionInfo): void => { console.error(JSON.stringify(info)); // 5 blocks only, then go our merry way @@ -87,10 +91,10 @@ describe.skip('derive e2e', () => { }); }); - it('retrieves all staking info (for controller)', (done) => { + it('retrieves all staking info (for controller)', (done): Promise<() => void> => { const accountId = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; - return api.derive.staking.info(accountId, (info: DerivedStaking) => { + return api.derive.staking.info(accountId, (info: DerivedStaking): void => { console.error(JSON.stringify(info)); expect(info.accountId.eq(accountId)).toBe(true); @@ -102,14 +106,15 @@ describe.skip('derive e2e', () => { }); }); - it('retrieves all staking info (for stash)', (done) => { + it('retrieves all staking info (for stash)', (done): Promise<() => void> => { const accountId = '5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY'; - return api.derive.staking.info(accountId, (info: DerivedStaking) => { + return api.derive.staking.info(accountId, (info: DerivedStaking): void => { console.error(JSON.stringify(info)); if (!info.stashId || !info.controllerId || !info.stakingLedger) { - return done.fail(new Error('At leat one of info.stashId, info.controllerId or info.stakingLedger is undefined.')); + done.fail(new Error('At leat one of info.stashId, info.controllerId or info.stakingLedger is undefined.')); + return; } expect(info.accountId.eq(accountId)).toBe(true); @@ -121,43 +126,42 @@ describe.skip('derive e2e', () => { }); }); - describe('verifies derive.staking.unlocking', () => { + describe('verifies derive.staking.unlocking', (): void => { const UNBOND_VALUE = 1; const alicePair = testingPairs().alice; - it('unbonds dots for Alice (from Alice Stash)', (done) => { + it('unbonds dots for Alice (from Alice Stash)', (done): Promise<() => void> => { return api.tx.staking.unbond(UNBOND_VALUE) - .signAndSend(alicePair, (result: SubmittableResult) => { + .signAndSend(alicePair, (result: SubmittableResult): void => { if (result.status.isFinalized) { - done(); } }); }); - it('verifies that derive.staking.unlocking isn\'t empty/undefined', () => { - return api.derive.staking.info(ALICE_STASH, (info: DerivedStaking) => { + it('verifies that derive.staking.unlocking isn\'t empty/undefined', (): Promise<() => void> => { + return api.derive.staking.info(ALICE_STASH, (info: DerivedStaking): void => { expect(info.unlocking).toBeDefined(); }); }); }); - describe('verifies derive.staking.rewardDestination', () => { + describe('verifies derive.staking.rewardDestination', (): void => { const PAYEE = 2; const alicePair = testingPairs().alice; - it('Set payee for ALICE to 2', (done) => { - return api.tx.staking.setPayee(PAYEE) - .signAndSend(alicePair, (result: SubmittableResult) => { + it('Set payee for ALICE to 2', (done): Promise<() => void> => { + return api.tx.staking + .setPayee(PAYEE) + .signAndSend(alicePair, (result: SubmittableResult): void => { if (result.status.isFinalized) { - done(); } }); }); - it('verifies payee for ALICE_STASH', (done) => { - return api.derive.staking.info(ALICE_STASH, (info: DerivedStaking) => { + it('verifies payee for ALICE_STASH', (done): Promise<() => void> => { + return api.derive.staking.info(ALICE_STASH, (info: DerivedStaking): void => { if (!info.rewardDestination) { return done.fail(new Error('rewardDestination is undefined.')); } else { @@ -168,13 +172,13 @@ describe.skip('derive e2e', () => { }); }); - it('staking.info updates itself after changing reward destination', async (done) => { + it('staking.info updates itself after changing reward destination', async (done): Promise => { const stashId = testingPairs().alice_stash.address; // start by setting the reqred to Staked, so we have a common starting point await api.tx.staking .setPayee(new RewardDestination('Staked')) - .signAndSend(testingPairs().alice, ({ status }) => { + .signAndSend(testingPairs().alice, ({ status }): void => { if (status.isFinalized) { console.error('setPayee(Staked) isFinalized'); } @@ -183,7 +187,7 @@ describe.skip('derive e2e', () => { let count = 0; // The # of times we got a callback response from api.derive.staking.info // Subscribe to staking.info - api.derive.staking.info(stashId, (result) => { + api.derive.staking.info(stashId, (result): void => { ++count; console.error('***', count, JSON.stringify(result)); @@ -194,10 +198,10 @@ describe.skip('derive e2e', () => { }).catch(console.error); // Wait a bit, and change reward destination - setTimeout(async () => { + setTimeout(async (): Promise => { await api.tx.staking .setPayee(new RewardDestination('Stash')) - .signAndSend(testingPairs().alice, ({ status }) => { + .signAndSend(testingPairs().alice, ({ status }): void => { if (status.isFinalized) { console.error('setPayee(Stash) isFinalized'); } diff --git a/packages/api-derive/test/e2e/rx.spec.ts b/packages/api-derive/test/e2e/rx.spec.ts index 74be10210e..7f19bd3e8c 100644 --- a/packages/api-derive/test/e2e/rx.spec.ts +++ b/packages/api-derive/test/e2e/rx.spec.ts @@ -19,25 +19,30 @@ const WS = 'ws://127.0.0.1:9944/'; const ID = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; const IX = 'F7Hs'; -describe.skip('Api-RX derive e2e', () => { +describe.skip('Api-RX derive e2e', (): void => { let api: ApiRx; - beforeAll(() => { + beforeAll((): void => { jest.setTimeout(10000); }); - beforeEach(async (done) => { + beforeEach(async (done): Promise => { api = await ApiRx.create(new WsProvider(WS)).toPromise(); + done(); }); + afterAll((): void => { + jest.setTimeout(10000); + }); + // These derive.accounts tests only work on localhost, not the poc-3 URL // (and it is assuming it sent at least 1 tx) - describe('derive.accounts', () => { - describe('idAndIndex', () => { - it('looks up AccountId & AccountIndex from AccountId', async (done) => { + describe('derive.accounts', (): void => { + describe('idAndIndex', (): void => { + it('looks up AccountId & AccountIndex from AccountId', async (done): Promise => { // @ts-ignore silence warning until we have static types here - api.derive.accounts.idAndIndex(ID).subscribe(([accountId, accountIndex]) => { + api.derive.accounts.idAndIndex(ID).subscribe(([accountId, accountIndex]): void => { expect(accountId!.toString()).toEqual(ID); // The first emitted value for ix is undefined when passing the ID if (accountIndex) { @@ -49,9 +54,9 @@ describe.skip('Api-RX derive e2e', () => { }); }); - it('looks up AccountId & AccountIndex from AccountIndex', async (done) => { + it('looks up AccountId & AccountIndex from AccountIndex', async (done): Promise => { // @ts-ignore silence warning until we have static types here - api.derive.accounts.idAndIndex(IX).subscribe(([accountId, accountIndex]) => { + api.derive.accounts.idAndIndex(IX).subscribe(([accountId, accountIndex]): void => { // The first emitted value for id is undefined when passing the IX if (accountId) { expect(accountId.toString()).toEqual(ID); @@ -64,10 +69,10 @@ describe.skip('Api-RX derive e2e', () => { }); }); - describe('indexToId', () => { - it('looks up AccountId from AccountIndex', async (done) => { + describe('indexToId', (): void => { + it('looks up AccountId from AccountIndex', async (done): Promise => { // @ts-ignore silence warning until we have static types here - api.derive.accounts.indexToId(IX).subscribe((accountId) => { + api.derive.accounts.indexToId(IX).subscribe((accountId): void => { // The first emitted value for accountId is undefined when passing the IX if (accountId) { expect(accountId instanceof AccountId).toBe(true); @@ -80,10 +85,10 @@ describe.skip('Api-RX derive e2e', () => { }); }); - describe('idToIndex', () => { - it('looks up AccountIndex from AccountId', async (done) => { + describe('idToIndex', (): void => { + it('looks up AccountIndex from AccountId', async (done): Promise => { // @ts-ignore silence warning until we have static types here - api.derive.accounts.idToIndex(ID).subscribe((accountIndex) => { + api.derive.accounts.idToIndex(ID).subscribe((accountIndex): void => { // The first emitted value for AccountIndex is undefined when passing the ID if (accountIndex) { expect(accountIndex instanceof AccountIndex).toBe(true); @@ -96,10 +101,10 @@ describe.skip('Api-RX derive e2e', () => { }); }); - describe('indexes', () => { - it('looks up all AccountIndexes', async (done) => { + describe('indexes', (): void => { + it('looks up all AccountIndexes', async (done): Promise => { // @ts-ignore silence warning until we have static types here - api.derive.accounts.indexes().subscribe((accountIndexes) => { + api.derive.accounts.indexes().subscribe((accountIndexes): void => { // A local dev chain should have the AccountIndex of Alice expect(accountIndexes).toHaveProperty( ID, @@ -113,10 +118,10 @@ describe.skip('Api-RX derive e2e', () => { // these only work on localhost, not the poc-3 URL // (and it is assuming it sent at least 1 tx) - describe('derive.balances', () => { - describe('all', () => { - it('It returns an object with all relevant balance information of an account', async (done) => { - api.derive.balances.all(ID).subscribe((balances: DerivedBalances) => { + describe('derive.balances', (): void => { + describe('all', (): void => { + it('It returns an object with all relevant balance information of an account', async (done): Promise => { + api.derive.balances.all(ID).subscribe((balances: DerivedBalances): void => { expect(balances).toEqual(expect.objectContaining({ accountId: expect.any(AccountId), accountNonce: expect.any(Index), @@ -132,9 +137,9 @@ describe.skip('Api-RX derive e2e', () => { }); }); - describe('fees', () => { - it('fees: It returns an object with all relevant fees of type BN', async (done) => { - api.derive.balances.fees().subscribe((fees: DerivedFees) => { + describe('fees', (): void => { + it('fees: It returns an object with all relevant fees of type BN', async (done): Promise => { + api.derive.balances.fees().subscribe((fees: DerivedFees): void => { expect(fees).toEqual(expect.objectContaining({ creationFee: expect.any(BN), existentialDeposit: expect.any(BN), @@ -148,10 +153,10 @@ describe.skip('Api-RX derive e2e', () => { }); }); - describe('derive.chain', () => { - describe('bestNumber', () => { - it('Get the latest block number', async (done) => { - api.derive.chain.bestNumber().subscribe((blockNumber: BlockNumber) => { + describe('derive.chain', (): void => { + describe('bestNumber', (): void => { + it('Get the latest block number', async (done): Promise => { + api.derive.chain.bestNumber().subscribe((blockNumber: BlockNumber): void => { expect(blockNumber instanceof BlockNumber).toBe(true); expect(blockNumber.gten(0)).toBe(true); done(); @@ -159,9 +164,9 @@ describe.skip('Api-RX derive e2e', () => { }); }); - describe('bestNumberFinalized', () => { - it('Get the latest finalised block number', async (done) => { - api.derive.chain.bestNumberFinalized().subscribe((blockNumber: BlockNumber) => { + describe('bestNumberFinalized', (): void => { + it('Get the latest finalised block number', async (done): Promise => { + api.derive.chain.bestNumberFinalized().subscribe((blockNumber: BlockNumber): void => { expect(blockNumber instanceof BlockNumber).toBe(true); expect(blockNumber.gten(0)).toBe(true); done(); @@ -169,9 +174,9 @@ describe.skip('Api-RX derive e2e', () => { }); }); - describe('bestNumberLag', () => { - it('lag between finalised head and best head', async (done) => { - api.derive.chain.bestNumberLag().subscribe((numberLag: BlockNumber) => { + describe('bestNumberLag', (): void => { + it('lag between finalised head and best head', async (done): Promise => { + api.derive.chain.bestNumberLag().subscribe((numberLag: BlockNumber): void => { expect(numberLag instanceof BlockNumber).toBe(true); expect(numberLag.gten(0)).toBe(true); done(); @@ -180,9 +185,9 @@ describe.skip('Api-RX derive e2e', () => { }); // FIXME https://github.com/polkadot-js/api/issues/868 - describe.skip('getHeader', () => { - it('gets a specific block header and extended with it\`s author', async (done) => { - api.derive.chain.getHeader('TODO').subscribe((headerExtended: HeaderExtended | undefined) => { + describe.skip('getHeader', (): void => { + it('gets a specific block header and extended with it`s author', async (done): Promise => { + api.derive.chain.getHeader('TODO').subscribe((headerExtended: HeaderExtended | undefined): void => { // WIP expect(headerExtended).toEqual(expect.arrayContaining([])); done(); @@ -190,9 +195,10 @@ describe.skip('Api-RX derive e2e', () => { }); }); - describe('subscribeNewHead', () => { - it('gets an observable of the current block header and it\'s author', async (done) => { - api.derive.chain.subscribeNewHead().subscribe((headerExtended: HeaderExtended) => { + describe('subscribeNewHead', (): void => { + it('gets an observable of the current block header and it\'s author', async (done): Promise => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + api.derive.chain.subscribeNewHead().subscribe((headerExtended: HeaderExtended): void => { // WIP https://github.com/polkadot-js/api/issues/868 done(); }); @@ -200,10 +206,10 @@ describe.skip('Api-RX derive e2e', () => { }); }); - describe('derive.contracts', () => { - describe('fees', () => { - it('fees: It returns an object with all relevant constract fees of type Balance', async (done) => { - api.derive.contracts.fees().subscribe((fees: DerivedContractFees) => { + describe('derive.contracts', (): void => { + describe('fees', (): void => { + it('fees: It returns an object with all relevant constract fees of type Balance', async (done): Promise => { + api.derive.contracts.fees().subscribe((fees: DerivedContractFees): void => { expect(fees).toEqual(expect.objectContaining({ callBaseFee: expect.any(BN), contractFee: expect.any(BN), @@ -222,19 +228,19 @@ describe.skip('Api-RX derive e2e', () => { }); }); - describe('derive.session', () => { - describe('sessionProgress', () => { - it('derive.session.sessionProgress', async (done) => { - api.derive.session.sessionProgress().subscribe((progress: BN) => { + describe('derive.session', (): void => { + describe('sessionProgress', (): void => { + it('derive.session.sessionProgress', async (done): Promise => { + api.derive.session.sessionProgress().subscribe((progress: BN): void => { expect(progress instanceof BN).toBe(true); done(); }); }); }); - describe('session.info', () => { - it('retrieves all session info', async (done) => { - api.derive.session.info().subscribe((info: DerivedSessionInfo) => { + describe('session.info', (): void => { + it('retrieves all session info', async (done): Promise => { + api.derive.session.info().subscribe((info: DerivedSessionInfo): void => { expect(info).toEqual(expect.objectContaining({ currentEra: expect.anything(), currentIndex: expect.anything(), @@ -251,18 +257,18 @@ describe.skip('Api-RX derive e2e', () => { }); }); - describe('session.eraLength', () => { - it('derive.session.eraLength', async (done) => { - api.derive.session.eraLength().subscribe((length: BN) => { + describe('session.eraLength', (): void => { + it('derive.session.eraLength', async (done): Promise => { + api.derive.session.eraLength().subscribe((length: BN): void => { expect(length instanceof BN).toBe(true); done(); }); }); }); - describe('session.eraProgress', () => { - it('derive.session.eraProgress', async (done) => { - api.derive.session.eraProgress().subscribe((progress: BN) => { + describe('session.eraProgress', (): void => { + it('derive.session.eraProgress', async (done): Promise => { + api.derive.session.eraProgress().subscribe((progress: BN): void => { expect(progress instanceof BN).toBe(true); done(); }); @@ -270,13 +276,9 @@ describe.skip('Api-RX derive e2e', () => { }); }); - describe('derive.staking', () => { - describe('controllers', () => { + describe('derive.staking', (): void => { + describe('controllers', (): void => { // @TODO https://github.com/polkadot-js/api/issues/868 }); }); - - afterAll(() => { - jest.setTimeout(10000); - }); }); diff --git a/packages/api-metadata/src/consts/fromMetadata/fromMetadata.spec.ts b/packages/api-metadata/src/consts/fromMetadata/fromMetadata.spec.ts index 1934488cf2..5039086cd9 100644 --- a/packages/api-metadata/src/consts/fromMetadata/fromMetadata.spec.ts +++ b/packages/api-metadata/src/consts/fromMetadata/fromMetadata.spec.ts @@ -11,8 +11,8 @@ import fromMetadata from '../fromMetadata'; const metadata = new Metadata(json); const consts = fromMetadata(metadata); -describe('fromMetadata', () => { - it('should return constants with the correct type and value', () => { +describe('fromMetadata', (): void => { + it('should return constants with the correct type and value', (): void => { expect(consts.democracy.cooloffPeriod).toBeInstanceOf(BlockNumber); expect(consts.democracy.cooloffPeriod.eq(432000)).toBeTruthy(); }); diff --git a/packages/api-metadata/src/consts/fromMetadata/index.ts b/packages/api-metadata/src/consts/fromMetadata/index.ts index d90442c89c..e00647b1e2 100644 --- a/packages/api-metadata/src/consts/fromMetadata/index.ts +++ b/packages/api-metadata/src/consts/fromMetadata/index.ts @@ -14,7 +14,7 @@ import { Constants, ModuleConstants } from './types'; * @param metadata - The metadata */ export default function fromMetadata (metadata: Metadata): Constants { - return metadata.asV6.modules.reduce((result, moduleMetadata) => { + return metadata.asV6.modules.reduce((result, moduleMetadata): Constants => { if (moduleMetadata.constants.isEmpty) { return result; } @@ -22,11 +22,11 @@ export default function fromMetadata (metadata: Metadata): Constants { const { name } = moduleMetadata; // For access, we change the index names, i.e. Democracy.EnactmentPeriod -> democracy.enactmentPeriod - result[stringCamelCase(name.toString())] = moduleMetadata.constants.reduce((newModule, constantMeta) => { + result[stringCamelCase(name.toString())] = moduleMetadata.constants.reduce((newModule, constantMeta): ModuleConstants => { newModule[stringCamelCase(constantMeta.name.toString())] = createType(constantMeta.type, constantMeta.value); return newModule; - }, {} as ModuleConstants); + }, {} as unknown as ModuleConstants); return result; - }, { } as Constants); + }, {} as unknown as Constants); } diff --git a/packages/api-metadata/src/extrinsics/fromMetadata/fromMetadata.spec.ts b/packages/api-metadata/src/extrinsics/fromMetadata/fromMetadata.spec.ts index df7a7bdddd..3f892dc4a1 100644 --- a/packages/api-metadata/src/extrinsics/fromMetadata/fromMetadata.spec.ts +++ b/packages/api-metadata/src/extrinsics/fromMetadata/fromMetadata.spec.ts @@ -11,16 +11,16 @@ import fromV6 from '.'; const metadata = new Metadata(json); const newExtrinsics = fromV6(metadata); -describe('fromMetadata', () => { - it('should throw if an incorrect number of args is supplied', () => { - expect(() => newExtrinsics.balances.setBalance()).toThrowError(/expects 3 arguments/); +describe('fromMetadata', (): void => { + it('should throw if an incorrect number of args is supplied', (): void => { + expect((): any => newExtrinsics.balances.setBalance()).toThrowError(/expects 3 arguments/); }); - it('should return a value if the storage function does not expect an argument', () => { - expect(() => newExtrinsics.balances.setBalance('5C62W7ELLAAfix9LYrcx5smtcffbhvThkM5x7xfMeYXCtGwF', 2, 3)).not.toThrow(); + it('should return a value if the storage function does not expect an argument', (): void => { + expect((): any => newExtrinsics.balances.setBalance('5C62W7ELLAAfix9LYrcx5smtcffbhvThkM5x7xfMeYXCtGwF', 2, 3)).not.toThrow(); }); - it('should return properly-encoded transactions', () => { + it('should return properly-encoded transactions', (): void => { expect( new Extrinsic(newExtrinsics.timestamp.set([10101])).toU8a() ).toEqual( diff --git a/packages/api-metadata/src/extrinsics/fromMetadata/index.ts b/packages/api-metadata/src/extrinsics/fromMetadata/index.ts index 4045706f44..7356f0feed 100644 --- a/packages/api-metadata/src/extrinsics/fromMetadata/index.ts +++ b/packages/api-metadata/src/extrinsics/fromMetadata/index.ts @@ -17,17 +17,17 @@ import createUnchecked from './createUnchecked'; */ export default function fromMetadata (metadata: Metadata): ModulesWithMethods { return metadata.asV6.modules - .filter((modul) => modul.calls.isSome) - .reduce((result, modul: ModuleMetadata, sectionIndex) => { + .filter((modul): boolean => modul.calls.isSome) + .reduce((result, modul: ModuleMetadata, sectionIndex): ModulesWithMethods => { const section = stringCamelCase(modul.name.toString()); - result[section] = modul.calls.unwrap().reduce((newModule, callMetadata, methodIndex) => { + result[section] = modul.calls.unwrap().reduce((newModule, callMetadata, methodIndex): Methods => { const method = stringCamelCase(callMetadata.name.toString()); newModule[method] = createUnchecked(section, sectionIndex, methodIndex, callMetadata); return newModule; - }, {} as Methods); + }, {} as unknown as Methods); return result; }, { ...extrinsics }); diff --git a/packages/api-metadata/src/extrinsics/index.spec.ts b/packages/api-metadata/src/extrinsics/index.spec.ts index f6c49602b5..4a1d80b89b 100644 --- a/packages/api-metadata/src/extrinsics/index.spec.ts +++ b/packages/api-metadata/src/extrinsics/index.spec.ts @@ -9,8 +9,8 @@ import extrinsics from './static'; const keyring = testingPairs({ type: 'ed25519' }, false); -describe('extrinsics', () => { - it('encodes extrinsic correctly (nobody)', () => { +describe('extrinsics', (): void => { + it('encodes extrinsic correctly (nobody)', (): void => { expect( new Extrinsic( extrinsics.timestamp.set(10101) @@ -26,7 +26,7 @@ describe('extrinsics', () => { ])); }); - it('encodes an actual transfer (actual data)', () => { + it('encodes an actual transfer (actual data)', (): void => { expect( new Extrinsic( extrinsics.balances.transfer(keyring.bob.publicKey, 6969) diff --git a/packages/api-metadata/src/extrinsics/test/e2e/transfer.spec.ts b/packages/api-metadata/src/extrinsics/test/e2e/transfer.spec.ts index 1c5b9db509..286c8169f2 100644 --- a/packages/api-metadata/src/extrinsics/test/e2e/transfer.spec.ts +++ b/packages/api-metadata/src/extrinsics/test/e2e/transfer.spec.ts @@ -14,28 +14,28 @@ const keyring = testingPairs({ type: 'ed25519' }); // @TODO 1: All three tests below are broken, fix or find better way to test transfers. // @TODO 2: Move tests out of ./type-metadata to ./api folder -describe.skip('e2e transfer', () => { +describe.skip('e2e transfer', (): void => { let api: RpcInterface; - beforeAll(() => { + beforeAll((): void => { api = new Rpc(new WsProvider('ws://127.0.0.1:9944')); }); - beforeEach(() => { + beforeEach((): void => { jest.setTimeout(30000); }); // Error: [1002]: Inherent transactions cannot be queued. - it('inherent test', (done) => { + it('inherent test', (done): void => { const inherent = extrinsics.timestamp.set(Math.round(Date.now() / 1000)); api.author.submitExtrinsic(inherent.toU8a()).subscribe(done); }); - it('makes a transfer for a transaction', (done) => { + it('makes a transfer for a transaction', (done): void => { api.chain .getBlockHash(0) - .subscribe((genesisHash) => { + .subscribe((genesisHash): void => { const extrinsic = extrinsics.balances.transfer(keyring.bob.publicKey, 6969) as any; extrinsic.sign(keyring.alice, { blockHash: genesisHash, nonce: 0 }); @@ -43,14 +43,14 @@ describe.skip('e2e transfer', () => { }); }); - it('makes a transfer via watch', (done) => { + it('makes a transfer via watch', (done): void => { api.chain .getBlockHash(0) - .subscribe((genesisHash) => { + .subscribe((genesisHash): void => { const extrinsic = extrinsics.balances.transfer(keyring.bob.publicKey, 6969) as any; extrinsic.sign(keyring.alice, { blockHash: genesisHash, nonce: 0 }); - api.author.submitAndWatchExtrinsic(extrinsic).subscribe((result: SubmittableResult) => { + api.author.submitAndWatchExtrinsic(extrinsic).subscribe((result: SubmittableResult): void => { if (result.status.isFinalized) { done(); } diff --git a/packages/api-metadata/src/storage/fromMetadata/createFunction.spec.ts b/packages/api-metadata/src/storage/fromMetadata/createFunction.spec.ts index 5eab6c81ed..c37f2faaac 100644 --- a/packages/api-metadata/src/storage/fromMetadata/createFunction.spec.ts +++ b/packages/api-metadata/src/storage/fromMetadata/createFunction.spec.ts @@ -8,8 +8,8 @@ import { stringToU8a, u8aConcat, u8aToHex } from '@polkadot/util'; import createFunction from './createFunction'; -describe('createFunction', () => { - it('should create timestamp.now correctly', () => { +describe('createFunction', (): void => { + it('should create timestamp.now correctly', (): void => { expect( createFunction({ prefix: 'Timestamp', @@ -22,7 +22,7 @@ describe('createFunction', () => { ); }); - it('allows overrides on key (keeping name)', () => { + it('allows overrides on key (keeping name)', (): void => { expect( createFunction( { @@ -39,7 +39,7 @@ describe('createFunction', () => { ).toEqual('authorityCount'); }); - it('allows overrides on key (unhashed)', () => { + it('allows overrides on key (unhashed)', (): void => { const key = ':auth:len'; expect( @@ -63,9 +63,10 @@ describe('createFunction', () => { ); }); - describe('the created double map function', () => { + describe('the created double map function', (): void => { let storageFn: StorageEntry; - beforeAll(() => { + + beforeAll((): void => { storageFn = createFunction({ prefix: 'GenericAsset', section: 'genericAsset', @@ -86,19 +87,19 @@ describe('createFunction', () => { }); }); - it('should return correct key', () => { + it('should return correct key', (): void => { const result = storageFn(['5DXUeE5N5LtkW97F2PzqYPyqNkxqSWESdGSPTX6AvkUAhwKP', '5DXUeE5N5LtkW97F2PzqYPyqNkxqSWESdGSPTX6AvkUAhwKP']); expect(u8aToHex(result)).toEqual('0xc000fa40e72d7173e69ee54b980345ea01cb81e64258502e0247af4303dee91ec0aec2ecd3a60ab080cff7b52a8f6d543b'); }); - it('needs two arguments', () => { + it('needs two arguments', (): void => { expect( - () => storageFn(['5DXUeE5N5LtkW97F2PzqYPyqNkxqSWESdGSPTX6AvkUAhwKP']) + (): Uint8Array => storageFn(['5DXUeE5N5LtkW97F2PzqYPyqNkxqSWESdGSPTX6AvkUAhwKP']) ).toThrow(/metaName expects two arguments/); }); }); - it('allows creates double map function with a Null type key', () => { + it('allows creates double map function with a Null type key', (): void => { const storageFn = createFunction({ prefix: 'System', section: 'system', diff --git a/packages/api-metadata/src/storage/fromMetadata/createFunction.ts b/packages/api-metadata/src/storage/fromMetadata/createFunction.ts index 228c6cbd9a..bc8d5d6e46 100644 --- a/packages/api-metadata/src/storage/fromMetadata/createFunction.ts +++ b/packages/api-metadata/src/storage/fromMetadata/createFunction.ts @@ -89,7 +89,7 @@ export default function createFunction ({ meta, method, prefix, section }: Creat if (meta.type.isMap && meta.type.asMap.isLinked) { const keyHash = new U8a(hasher(`head of ${stringKey}`)); - const keyFn: any = () => keyHash; + const keyFn: any = (): U8a => keyHash; keyFn.meta = new StorageEntryMetadata({ name: meta.name, modifier: new StorageEntryModifier('Required'), diff --git a/packages/api-metadata/src/storage/fromMetadata/fromMetadata.spec.ts b/packages/api-metadata/src/storage/fromMetadata/fromMetadata.spec.ts index fb66bb04d6..d6ab998a70 100644 --- a/packages/api-metadata/src/storage/fromMetadata/fromMetadata.spec.ts +++ b/packages/api-metadata/src/storage/fromMetadata/fromMetadata.spec.ts @@ -14,16 +14,16 @@ const keyring = testingPairs({ type: 'ed25519' }); const metadata = new Metadata(json); const storage = fromMetadata(metadata); -describe('fromMetadata', () => { - it('should throw if the storage function expects an argument', () => { - expect(() => storage.balances.freeBalance()).toThrowError(/expects one argument/); +describe('fromMetadata', (): void => { + it('should throw if the storage function expects an argument', (): void => { + expect((): any => storage.balances.freeBalance()).toThrowError(/expects one argument/); }); - it('should return a value if the storage function does not expect an argument', () => { - expect(() => storage.timestamp.now()).not.toThrow(); + it('should return a value if the storage function does not expect an argument', (): void => { + expect((): any => storage.timestamp.now()).not.toThrow(); }); - it('should return the correct length-prefixed storage key', () => { + it('should return the correct length-prefixed storage key', (): void => { expect( u8aToHex( storage.balances.freeBalance(keyring.alice.address) diff --git a/packages/api-metadata/src/storage/fromMetadata/getHasher.ts b/packages/api-metadata/src/storage/fromMetadata/getHasher.ts index 07901ba460..d24a502b44 100644 --- a/packages/api-metadata/src/storage/fromMetadata/getHasher.ts +++ b/packages/api-metadata/src/storage/fromMetadata/getHasher.ts @@ -12,28 +12,28 @@ export type HasherFunction = (data: HasherInput) => Uint8Array; export default function getHasher (hasher?: StorageHasher): HasherFunction { // This one is the default for PlainType storage keys if (!hasher) { - return (data: HasherInput) => xxhashAsU8a(data, 128); + return (data: HasherInput): Uint8Array => xxhashAsU8a(data, 128); } if (hasher.isBlake2128) { - return (data: HasherInput) => blake2AsU8a(data, 128); + return (data: HasherInput): Uint8Array => blake2AsU8a(data, 128); } if (hasher.isBlake2256) { - return (data: HasherInput) => blake2AsU8a(data, 256); + return (data: HasherInput): Uint8Array => blake2AsU8a(data, 256); } if (hasher.isTwox128) { - return (data: HasherInput) => xxhashAsU8a(data, 128); + return (data: HasherInput): Uint8Array => xxhashAsU8a(data, 128); } if (hasher.isTwox256) { - return (data: HasherInput) => xxhashAsU8a(data, 256); + return (data: HasherInput): Uint8Array => xxhashAsU8a(data, 256); } // FIXME Add Twox128Concat // All cases should be handled above, but if not, return Twox128 for // backwards-compatbility - return (data: HasherInput) => xxhashAsU8a(data, 128); + return (data: HasherInput): Uint8Array => xxhashAsU8a(data, 128); } diff --git a/packages/api-metadata/src/storage/fromMetadata/index.ts b/packages/api-metadata/src/storage/fromMetadata/index.ts index 5bb320fb33..a2b1454741 100644 --- a/packages/api-metadata/src/storage/fromMetadata/index.ts +++ b/packages/api-metadata/src/storage/fromMetadata/index.ts @@ -16,7 +16,7 @@ import { storage } from './storage'; * @param metadata - The metadata */ export default function fromMetadata (metadata: Metadata): Storage { - return metadata.asV6.modules.reduce((result, moduleMetadata) => { + return metadata.asV6.modules.reduce((result, moduleMetadata): Storage => { if (moduleMetadata.storage.isNone) { return result; } @@ -25,7 +25,7 @@ export default function fromMetadata (metadata: Metadata): Storage { const section = stringCamelCase(name.toString()); // For access, we change the index names, i.e. Balances.FreeBalance -> balances.freeBalance - result[section] = moduleMetadata.storage.unwrap().reduce((newModule, meta) => { + result[section] = moduleMetadata.storage.unwrap().reduce((newModule, meta): ModuleStorage => { const method = meta.name.toString(); newModule[stringLowerFirst(method)] = createFunction({ @@ -36,7 +36,7 @@ export default function fromMetadata (metadata: Metadata): Storage { }); return newModule; - }, {} as ModuleStorage); + }, {} as unknown as ModuleStorage); return result; }, { ...storage }); diff --git a/packages/api-metadata/src/storage/fromMetadata/storage.spec.ts b/packages/api-metadata/src/storage/fromMetadata/storage.spec.ts index af7971c285..ce097303f1 100644 --- a/packages/api-metadata/src/storage/fromMetadata/storage.spec.ts +++ b/packages/api-metadata/src/storage/fromMetadata/storage.spec.ts @@ -4,8 +4,8 @@ import { storage } from './storage'; -describe('storage', () => { - it('should return well known keys', () => { +describe('storage', (): void => { + it('should return well known keys', (): void => { expect(typeof storage.substrate).toBe('object'); // @deprecated: The ':auth:' (authorityPrefix) and ':auth:len' (authorityCount) storage keys diff --git a/packages/api-metadata/src/storage/fromMetadata/substrate.spec.ts b/packages/api-metadata/src/storage/fromMetadata/substrate.spec.ts index 5b219ec63f..b90b15ba33 100644 --- a/packages/api-metadata/src/storage/fromMetadata/substrate.spec.ts +++ b/packages/api-metadata/src/storage/fromMetadata/substrate.spec.ts @@ -4,37 +4,36 @@ import { authorityCount, authorityPrefix, changesTrieConfig, childStorageKeyPrefix, code, extrinsicIndex, heapPages } from './substrate'; -describe('substrate', () => { - +describe('substrate', (): void => { // @deprecated: The ':auth:' (authorityPrefix) and ':auth:len' (authorityCount) storage keys // have been removed in https://github.com/paritytech/substrate/pull/2802 - it('authorityCount should return the correct storage key', () => { + it('authorityCount should return the correct storage key', (): void => { expect(authorityCount()).toEqual(Uint8Array.from([36, 58, 97, 117, 116, 104, 58, 108, 101, 110])); // Length-prefixed }); - it('authorityPrefix should return the correct storage key', () => { + it('authorityPrefix should return the correct storage key', (): void => { expect(authorityPrefix()).toEqual(Uint8Array.from([24, 58, 97, 117, 116, 104, 58])); // Length-prefixed }); - it('changesTrieConfig should return the correct storage key', () => { + it('changesTrieConfig should return the correct storage key', (): void => { expect(changesTrieConfig()).toEqual(Uint8Array.from([52, 58, 99, 104, 97, 110, 103, 101, 115, 95, 116, 114, 105, 101])); // Length-prefixed }); - it('childStorageKeyPrefix should return the correct storage key', () => { - expect(childStorageKeyPrefix()).toEqual(Uint8Array.from([ 60, 58, 99, 104, 105, 108, 100, 95, 115, 116, 111, 114, 97, 103, 101, 58])); // Length-prefixed + it('childStorageKeyPrefix should return the correct storage key', (): void => { + expect(childStorageKeyPrefix()).toEqual(Uint8Array.from([60, 58, 99, 104, 105, 108, 100, 95, 115, 116, 111, 114, 97, 103, 101, 58])); // Length-prefixed }); - it('code should return the correct storage key', () => { + it('code should return the correct storage key', (): void => { expect(code()).toEqual(Uint8Array.from([20, 58, 99, 111, 100, 101])); // Length-prefixed }); - it('extrinsicIndex should return the correct storage key', () => { + it('extrinsicIndex should return the correct storage key', (): void => { expect(extrinsicIndex()).toEqual( Uint8Array.from([64, 58, 101, 120, 116, 114, 105, 110, 115, 105, 99, 95, 105, 110, 100, 101, 120]) // Length-prefixed ); }); - it('heapPages should return the correct storage key', () => { + it('heapPages should return the correct storage key', (): void => { expect(heapPages()).toEqual(Uint8Array.from([40, 58, 104, 101, 97, 112, 112, 97, 103, 101, 115])); // Length-prefixed }); }); diff --git a/packages/api-metadata/src/storage/fromMetadata/substrate.ts b/packages/api-metadata/src/storage/fromMetadata/substrate.ts index fef97d629c..9f35c759f5 100644 --- a/packages/api-metadata/src/storage/fromMetadata/substrate.ts +++ b/packages/api-metadata/src/storage/fromMetadata/substrate.ts @@ -22,7 +22,7 @@ const createRuntimeFunction = (method: string, key: string, { documentation, typ modifier: new StorageEntryModifier(1), // default type: new StorageEntryType(type, 0), toJSON: (): any => key - } as StorageEntryMetadata, + } as unknown as StorageEntryMetadata, method, prefix: 'Substrate', section: 'substrate' diff --git a/packages/api/src/Base.ts b/packages/api/src/Base.ts index d9edcf108e..2806e9ccbf 100644 --- a/packages/api/src/Base.ts +++ b/packages/api/src/Base.ts @@ -5,8 +5,8 @@ import { ProviderInterface } from '@polkadot/rpc-provider/types'; import { AnyFunction, Codec, CodecArg, RegistryTypes } from '@polkadot/types/types'; import { - ApiInterface$Rx, ApiInterface$Events, ApiOptions, ApiTypes, DecorateMethodOptions, - DecoratedRpc, DecoratedRpc$Section, + ApiInterfaceRx, ApiInterfaceEvents, ApiOptions, ApiTypes, DecorateMethodOptions, + DecoratedRpc, DecoratedRpcSection, QueryableModuleStorage, QueryableStorage, QueryableStorageEntry, QueryableStorageMulti, QueryableStorageMultiArg, QueryableStorageMultiArgs, SubmittableExtrinsicFunction, SubmittableExtrinsics, SubmittableModuleExtrinsics, Signer } from './types'; @@ -22,7 +22,7 @@ import { Storage } from '@polkadot/api-metadata/storage/types'; import storageFromMeta from '@polkadot/api-metadata/storage/fromMetadata'; import RpcCore from '@polkadot/rpc-core'; import { WsProvider } from '@polkadot/rpc-provider'; -import { Event, getTypeRegistry, Hash, Metadata, Method, RuntimeVersion, Null } from '@polkadot/types'; +import { Event, getTypeRegistry, Hash, Metadata, Method, RuntimeVersion, Null, U64 } from '@polkadot/types'; import Linkage, { LinkageResult } from '@polkadot/types/codec/Linkage'; import { MethodFunction, ModulesWithMethods } from '@polkadot/types/primitive/Method'; import * as srmlTypes from '@polkadot/types/srml/definitions'; @@ -34,20 +34,20 @@ import injectNodeCompat from './nodeCompat'; import createSubmittable, { SubmittableExtrinsic } from './SubmittableExtrinsic'; import { decorateSections } from './util/decorate'; -type MetaDecoration = { - callIndex?: Uint8Array, - meta: any, - method: string, - section: string, - toJSON: () => any -}; +interface MetaDecoration { + callIndex?: Uint8Array; + meta: any; + method: string; + section: string; + toJSON: () => any; +} const INIT_ERROR = `Api needs to be initialised before using, listen on 'ready'`; const KEEPALIVE_INTERVAL = 15000; const l = logger('api/decorator'); -let pkgJson: { name: string, version: string }; +let pkgJson: { name: string; version: string }; try { pkgJson = require('./package.json'); @@ -66,20 +66,35 @@ function rxDecorateMethod (method: Method): Method { export default abstract class ApiBase { private _consts?: Constants; + private _derive?: ReturnType['decorateDerive']>; + private _eventemitter: EventEmitter; + private _extrinsics?: SubmittableExtrinsics; + private _genesisHash?: Hash; + protected _isConnected: BehaviorSubject; + private _isReady: boolean = false; + protected readonly _options: ApiOptions; + private _query?: QueryableStorage; + private _queryMulti: QueryableStorageMulti; + private _rpc: DecoratedRpc; + protected _rpcCore: RpcCore; + private _runtimeMetadata?: Metadata; + private _runtimeVersion?: RuntimeVersion; - private _rx: Partial = {}; + + private _rx: Partial = {}; + private _type: ApiTypes; /** @@ -100,9 +115,9 @@ export default abstract class ApiBase { * }); * ``` */ - constructor (provider: ApiOptions | ProviderInterface = {}, type: ApiTypes) { + public constructor (provider: ApiOptions | ProviderInterface = {}, type: ApiTypes) { const options = isObject(provider) && isFunction((provider as ProviderInterface).send) - ? { provider } as ApiOptions + ? { provider } as unknown as ApiOptions : provider as ApiOptions; const thisProvider = options.source ? options.source._rpcCore.provider.clone() @@ -125,7 +140,7 @@ export default abstract class ApiBase { // we only re-register the types (global) if this is not a cloned instance if (!options.source) { // first register the definitions we have, i.e. those where there are no type classes - Object.values(srmlTypes).forEach(({ types }) => + Object.values(srmlTypes).forEach(({ types }): void => this.registerTypes(types) ); @@ -139,7 +154,7 @@ export default abstract class ApiBase { /** * @description Contains the genesis Hash of the attached chain. Apart from being useful to determine the actual chain, it can also be used to sign immortal transactions. */ - get genesisHash (): Hash { + public get genesisHash (): Hash { assert(!isUndefined(this._genesisHash), INIT_ERROR); return this._genesisHash as Hash; @@ -148,21 +163,21 @@ export default abstract class ApiBase { /** * @description `true` when subscriptions are supported */ - get hasSubscriptions (): boolean { + public get hasSubscriptions (): boolean { return this._rpcCore.provider.hasSubscriptions; } /** * @description The library information name & version (from package.json) */ - get libraryInfo (): string { + public get libraryInfo (): string { return `${pkgJson.name} v${pkgJson.version}`; } /** * @description Yields the current attached runtime metadata. Generally this is only used to construct extrinsics & storage, but is useful for current runtime inspection. */ - get runtimeMetadata (): Metadata { + public get runtimeMetadata (): Metadata { assert(!isUndefined(this._runtimeMetadata), INIT_ERROR); return this._runtimeMetadata as Metadata; @@ -171,7 +186,7 @@ export default abstract class ApiBase { /** * @description Contains the version information for the current runtime. */ - get runtimeVersion (): RuntimeVersion { + public get runtimeVersion (): RuntimeVersion { assert(!isUndefined(this._runtimeVersion), INIT_ERROR); return this._runtimeVersion as RuntimeVersion; @@ -180,14 +195,14 @@ export default abstract class ApiBase { /** * @description The type of this API instance, either 'rxjs' or 'promise' */ - get type (): ApiTypes { + public get type (): ApiTypes { return this._type; } /** * @description Set an external signer which will be used to sign extrinsic when account passed in is not KeyringPair */ - setSigner (signer: Signer) { + public setSigner (signer: Signer): void { this._rx.signer = signer; } @@ -203,7 +218,7 @@ export default abstract class ApiBase { * }); * ``` */ - get derive (): ReturnType['decorateDerive']> { + public get derive (): ReturnType['decorateDerive']> { assert(!isUndefined(this._derive), INIT_ERROR); return this._derive as ReturnType['decorateDerive']>; @@ -221,7 +236,7 @@ export default abstract class ApiBase { * console.log(api.consts.democracy.enactmentPeriod.toString()) * ``` */ - get consts (): Constants { + public get consts (): Constants { assert(!isUndefined(this._consts), INIT_ERROR); return this._consts as Constants; @@ -241,7 +256,7 @@ export default abstract class ApiBase { * }); * ``` */ - get query (): QueryableStorage { + public get query (): QueryableStorage { assert(!isUndefined(this._query), INIT_ERROR); return this._query as QueryableStorage; @@ -269,7 +284,7 @@ export default abstract class ApiBase { * ); * ``` */ - get queryMulti (): QueryableStorageMulti { + public get queryMulti (): QueryableStorageMulti { return this._queryMulti; } @@ -287,7 +302,7 @@ export default abstract class ApiBase { * }); * ``` */ - get rpc (): DecoratedRpc { + public get rpc (): DecoratedRpc { return this._rpc; } @@ -305,7 +320,7 @@ export default abstract class ApiBase { * }); * ``` */ - get tx (): SubmittableExtrinsics { + public get tx (): SubmittableExtrinsics { assert(!isUndefined(this._extrinsics), INIT_ERROR); return this._extrinsics as SubmittableExtrinsics; @@ -314,7 +329,7 @@ export default abstract class ApiBase { /** * @description Disconnect from the underlying provider, halting all comms */ - disconnect (): void { + public disconnect (): void { this._rpcCore.disconnect(); } @@ -328,16 +343,16 @@ export default abstract class ApiBase { *
* * ```javascript - * api.on('connected', () => { + * api.on('connected', (): void => { * console.log('API has been connected to the endpoint'); * }); * - * api.on('disconnected', () => { + * api.on('disconnected', (): void => { * console.log('API has been disconnected from the endpoint'); * }); * ``` */ - on (type: ApiInterface$Events, handler: (...args: Array) => any): this { + public on (type: ApiInterfaceEvents, handler: (...args: any[]) => any): this { this._eventemitter.on(type, handler); return this; @@ -353,7 +368,7 @@ export default abstract class ApiBase { *
* * ```javascript - * const handler = () => { + * const handler = (): void => { * console.log('Connected !); * }; * @@ -364,7 +379,7 @@ export default abstract class ApiBase { * api.off('connected', handler); * ``` */ - off (type: ApiInterface$Events, handler: (...args: Array) => any): this { + public off (type: ApiInterfaceEvents, handler: (...args: any[]) => any): this { this._eventemitter.removeListener(type, handler); return this; @@ -380,16 +395,16 @@ export default abstract class ApiBase { *
* * ```javascript - * api.once('connected', () => { + * api.once('connected', (): void => { * console.log('API has been connected to the endpoint'); * }); * - * api.once('disconnected', () => { + * api.once('disconnected', (): void => { * console.log('API has been disconnected from the endpoint'); * }); * ``` */ - once (type: ApiInterface$Events, handler: (...args: Array) => any): this { + public once (type: ApiInterfaceEvents, handler: (...args: any[]) => any): this { this._eventemitter.once(type, handler); return this; @@ -398,7 +413,7 @@ export default abstract class ApiBase { /** * @description Register additional user-defined of chain-specific types in the type registry */ - registerTypes (types?: RegistryTypes): void { + public registerTypes (types?: RegistryTypes): void { if (types) { getTypeRegistry().register(types); } @@ -420,16 +435,16 @@ export default abstract class ApiBase { * implemented by transforming the Observable to Stream/Iterator/Kefir/Bacon * via `deocrateMethod`. */ - protected abstract decorateMethod (method: (...args: Array) => Observable, options?: DecorateMethodOptions): any; + protected abstract decorateMethod (method: (...args: any[]) => Observable, options?: DecorateMethodOptions): any; - private emit (type: ApiInterface$Events, ...args: Array): void { + private emit (type: ApiInterfaceEvents, ...args: any[]): void { this._eventemitter.emit(type, ...args); } private init (): void { let healthTimer: NodeJS.Timeout | null = null; - this._rpcCore.provider.on('disconnected', () => { + this._rpcCore.provider.on('disconnected', (): void => { this.emit('disconnected'); this._isConnected.next(false); @@ -439,11 +454,11 @@ export default abstract class ApiBase { } }); - this._rpcCore.provider.on('error', (error) => { + this._rpcCore.provider.on('error', (error): void => { this.emit('error', error); }); - this._rpcCore.provider.on('connected', async () => { + this._rpcCore.provider.on('connected', async (): Promise => { this.emit('connected'); this._isConnected.next(true); @@ -459,8 +474,8 @@ export default abstract class ApiBase { this.emit('ready', this); } - healthTimer = setInterval(() => { - this._rpcCore.system.health().toPromise().catch(() => { + healthTimer = setInterval((): void => { + this._rpcCore.system.health().toPromise().catch((): void => { // ignore }); }, KEEPALIVE_INTERVAL); @@ -514,7 +529,7 @@ export default abstract class ApiBase { this._rx.tx = this.decorateExtrinsics(extrinsics, rxDecorateMethod); this._rx.query = this.decorateStorage(storage, rxDecorateMethod); this._rx.consts = constants; - this._derive = this.decorateDerive(this._rx as ApiInterface$Rx, this.decorateMethod); + this._derive = this.decorateDerive(this._rx as ApiInterfaceRx, this.decorateMethod); // only inject if we are not a clone (global init) if (!this._options.source) { @@ -539,24 +554,24 @@ export default abstract class ApiBase { } private decorateRpc (rpc: RpcCore, decorateMethod: ApiBase['decorateMethod']): DecoratedRpc { - return ['author', 'chain', 'state', 'system'].reduce((result, _sectionName) => { + return ['author', 'chain', 'state', 'system'].reduce((result, _sectionName): DecoratedRpc => { const sectionName = _sectionName as keyof DecoratedRpc; - result[sectionName] = Object.keys(rpc[sectionName]).reduce((section, methodName) => { + result[sectionName] = Object.keys(rpc[sectionName]).reduce((section, methodName): DecoratedRpcSection => { const method = rpc[sectionName][methodName]; section[methodName] = decorateMethod(method, { methodName }); return section; - }, {} as DecoratedRpc$Section); + }, {} as unknown as DecoratedRpcSection); return result; - }, {} as DecoratedRpc); + }, {} as unknown as DecoratedRpc); } private decorateMulti (decorateMethod: ApiBase['decorateMethod']): QueryableStorageMulti { return decorateMethod( - (calls: QueryableStorageMultiArgs) => { - const mapped = calls.map((arg: QueryableStorageMultiArg): [QueryableStorageEntry, ...Array] => + (calls: QueryableStorageMultiArgs): Observable => { + const mapped = calls.map((arg: QueryableStorageMultiArg): [QueryableStorageEntry, ...CodecArg[]] => // the input is a QueryableStorageEntry, convert to StorageEntry Array.isArray(arg) ? [arg[0].creator, ...arg.slice(1)] @@ -569,49 +584,48 @@ export default abstract class ApiBase { private decorateExtrinsics (extrinsics: ModulesWithMethods, decorateMethod: ApiBase['decorateMethod']): SubmittableExtrinsics { const creator = (value: Uint8Array | string): SubmittableExtrinsic => - createSubmittable(this.type, this._rx as ApiInterface$Rx, decorateMethod, value); + createSubmittable(this.type, this._rx as ApiInterfaceRx, decorateMethod, value); - return Object.keys(extrinsics).reduce((result, sectionName) => { + return Object.keys(extrinsics).reduce((result, sectionName): SubmittableExtrinsics => { const section = extrinsics[sectionName]; - result[sectionName] = Object.keys(section).reduce((result, methodName) => { + result[sectionName] = Object.keys(section).reduce((result, methodName): SubmittableModuleExtrinsics => { result[methodName] = this.decorateExtrinsicEntry(section[methodName], decorateMethod); return result; - }, {} as SubmittableModuleExtrinsics); + }, {} as unknown as SubmittableModuleExtrinsics); return result; - }, creator as SubmittableExtrinsics); + }, creator as unknown as SubmittableExtrinsics); } private decorateExtrinsicEntry (method: MethodFunction, decorateMethod: ApiBase['decorateMethod']): SubmittableExtrinsicFunction { const decorated = - (...params: Array): SubmittableExtrinsic => - createSubmittable(this.type, this._rx as ApiInterface$Rx, decorateMethod, method(...params)); + (...params: CodecArg[]): SubmittableExtrinsic => + createSubmittable(this.type, this._rx as ApiInterfaceRx, decorateMethod, method(...params)); return this.decorateFunctionMeta(method, decorated as any) as SubmittableExtrinsicFunction; } private decorateStorage (storage: Storage, decorateMethod: ApiBase['decorateMethod']): QueryableStorage { - return Object.keys(storage).reduce((result, sectionName) => { + return Object.keys(storage).reduce((result, sectionName): QueryableStorage => { const section = storage[sectionName]; - result[sectionName] = Object.keys(section).reduce((result, methodName) => { + result[sectionName] = Object.keys(section).reduce((result, methodName): QueryableModuleStorage => { result[methodName] = this.decorateStorageEntry(section[methodName], decorateMethod); return result; - }, {} as QueryableModuleStorage); + }, {} as unknown as QueryableModuleStorage); return result; - }, {} as QueryableStorage); + }, {} as unknown as QueryableStorage); } private decorateStorageEntry (creator: StorageEntry, decorateMethod: ApiBase['decorateMethod']): QueryableStorageEntry { const decorated = creator.headKey ? this.decorateStorageEntryLinked(creator, decorateMethod) : decorateMethod( - (...args: Array) => { - + (...args: any[]): Observable => { return this._rpcCore.state // Unfortunately for one-shot calls we also use .subscribeStorage here .subscribeStorage([ @@ -621,7 +635,7 @@ export default abstract class ApiBase { .pipe( // state_storage returns an array of values, since we have just subscribed to // a single entry, we pull that from the array and return it as-is - map((result: Array): Codec => + map((result: Codec[]): Codec => result[0] ) ); @@ -632,18 +646,22 @@ export default abstract class ApiBase { decorated.creator = creator; decorated.at = decorateMethod( - (hash: Hash, arg1?: CodecArg, arg2?: CodecArg) => this._rpcCore.state.getStorage( - creator.meta.type.isDoubleMap - ? [creator, [arg1, arg2]] - : [creator, arg1], - hash) + (hash: Hash, arg1?: CodecArg, arg2?: CodecArg): Observable => + this._rpcCore.state.getStorage( + creator.meta.type.isDoubleMap + ? [creator, [arg1, arg2]] + : [creator, arg1], + hash + ) ); decorated.hash = decorateMethod( - (arg1?: CodecArg, arg2?: CodecArg) => this._rpcCore.state.getStorageHash( - creator.meta.type.isDoubleMap - ? [creator, [arg1, arg2]] - : [creator, arg1]) + (arg1?: CodecArg, arg2?: CodecArg): Observable => + this._rpcCore.state.getStorageHash( + creator.meta.type.isDoubleMap + ? [creator, [arg1, arg2]] + : [creator, arg1] + ) ); decorated.key = (arg1?: CodecArg, arg2?: CodecArg): string => @@ -651,16 +669,21 @@ export default abstract class ApiBase { // When using double map storage function, user need to path double map key as an array decorated.multi = decorateMethod( - (args: Array) => + (args: (CodecArg | CodecArg[])[]): Observable => this._rpcCore.state - .subscribeStorage(args.map((arg: CodecArg[] | CodecArg) => [creator, arg])) + .subscribeStorage( + args.map((arg: CodecArg[] | CodecArg): [StorageEntry, CodecArg | CodecArg[]] => + [creator, arg] + ) + ) ); decorated.size = decorateMethod( - (arg1?: CodecArg, arg2?: CodecArg) => this._rpcCore.state.getStorageSize( - creator.meta.type.isDoubleMap - ? [creator, [arg1, arg2]] - : [creator, arg1]) + (arg1?: CodecArg, arg2?: CodecArg): Observable => + this._rpcCore.state.getStorageSize( + creator.meta.type.isDoubleMap + ? [creator, [arg1, arg2]] + : [creator, arg1]) ); return this.decorateFunctionMeta(creator, decorated) as unknown as QueryableStorageEntry; @@ -677,7 +700,7 @@ export default abstract class ApiBase { const getNext = (key: Codec): Observable => { return this._rpcCore.state.subscribeStorage([[method, key]]) .pipe( - switchMap(([data]: [[Codec, Linkage]]) => { + switchMap(([data]: [[Codec, Linkage]]): Observable => { const linkage = data[1]; result.set(key, data); @@ -736,19 +759,22 @@ export default abstract class ApiBase { // this handles the case where the head changes effectively, i.e. a new entry // appears at the top of the list, the new getNext gets kicked off return decorateMethod( - () => this._rpcCore.state - .subscribeStorage([method.headKey]) - .pipe( - switchMap(([key]: Array) => { - head = key; + (): Observable => + this._rpcCore.state + .subscribeStorage([method.headKey]) + .pipe( + switchMap(([key]: Codec[]): Observable => { + head = key; - return getNext(key); - }) - ) + return getNext(key); + }) + ) ); } - private decorateDerive (apiRx: ApiInterface$Rx, decorateMethod: ApiBase['decorateMethod']) { + // FIXME I have no idea how to get this done + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + private decorateDerive (apiRx: ApiInterfaceRx, decorateMethod: ApiBase['decorateMethod']) { // Pull in derive from api-derive const derive = decorateDerive(apiRx, this._options.derives); diff --git a/packages/api/src/SubmittableExtrinsic.ts b/packages/api/src/SubmittableExtrinsic.ts index a6afad362a..e89680ac52 100644 --- a/packages/api/src/SubmittableExtrinsic.ts +++ b/packages/api/src/SubmittableExtrinsic.ts @@ -4,7 +4,7 @@ import { AccountId, Address, ExtrinsicStatus, EventRecord, getTypeRegistry, Hash, Header, Index, Method, SignedBlock, Vector, ExtrinsicEra } from '@polkadot/types'; import { AnyNumber, AnyU8a, Callback, Codec, IExtrinsic, IExtrinsicEra, IKeyringPair, SignatureOptions } from '@polkadot/types/types'; -import { ApiInterface$Rx, ApiTypes } from './types'; +import { ApiInterfaceRx, ApiTypes } from './types'; import BN from 'bn.js'; import { Observable, combineLatest, of } from 'rxjs'; @@ -14,8 +14,9 @@ import { isBn, isFunction, isNumber, isUndefined } from '@polkadot/util'; import ApiBase from './Base'; import filterEvents from './util/filterEvents'; +// eslint-disable-next-line @typescript-eslint/interface-name-prefix export interface ISubmittableResult { - readonly events: Array; + readonly events: EventRecord[]; readonly status: ExtrinsicStatus; readonly isCompleted: boolean; readonly isError: boolean; @@ -34,10 +35,10 @@ export type SumbitableResultSubscription = ? Observable : Promise<() => void>; -type SubmittableResultValue = { - events?: Array; +interface SubmittableResultValue { + events?: EventRecord[]; status: ExtrinsicStatus; -}; +} interface SignerOptions { blockHash: AnyU8a; @@ -50,31 +51,32 @@ const ONE_MINUTE = 15; const DEFAULT_MORTAL_LENGTH = 5 * ONE_MINUTE; export class SubmittableResult implements ISubmittableResult { - readonly events: Array; - readonly status: ExtrinsicStatus; + public readonly events: EventRecord[]; - constructor ({ events, status }: SubmittableResultValue) { + public readonly status: ExtrinsicStatus; + + public constructor ({ events, status }: SubmittableResultValue) { this.events = events || []; this.status = status; } - get isCompleted (): boolean { + public get isCompleted (): boolean { return this.isError || this.isFinalized; } - get isError (): boolean { + public get isError (): boolean { return this.status.isDropped || this.status.isInvalid || this.status.isUsurped; } - get isFinalized (): boolean { + public get isFinalized (): boolean { return this.status.isFinalized; } /** * @description Finds an EventRecord for the specified method & section */ - findRecord (section: string, method: string): EventRecord | undefined { - return this.events.find(({ event }) => + public findRecord (section: string, method: string): EventRecord | undefined { + return this.events.find(({ event }): boolean => event.section === section && event.method === method ); } @@ -96,7 +98,7 @@ export interface SubmittableExtrinsic extends IExtrinsic { export default function createSubmittableExtrinsic ( type: ApiTypes, - api: ApiInterface$Rx, + api: ApiInterfaceRx, decorateMethod: ApiBase['decorateMethod'], extrinsic: Method | Uint8Array | string, trackingCb?: Callback @@ -125,7 +127,7 @@ export default function createSubmittableExtrinsic ( api.rpc.chain.getBlock(blockHash) as Observable, api.query.system.events.at(blockHash) as Observable> ]).pipe( - map(([signedBlock, allEvents]) => { + map(([signedBlock, allEvents]): SubmittableResult => { const result = new SubmittableResult({ events: filterEvents(_extrinsic.hash, signedBlock, allEvents), status @@ -142,7 +144,7 @@ export default function createSubmittableExtrinsic ( return (api.rpc.author .submitExtrinsic(_extrinsic) as Observable) .pipe( - tap((hash) => { + tap((hash): void => { updateSigner(updateId, hash); }) ); @@ -152,21 +154,21 @@ export default function createSubmittableExtrinsic ( return (api.rpc.author .submitAndWatchExtrinsic(_extrinsic) as Observable) .pipe( - switchMap((status) => + switchMap((status): Observable => statusObservable(status) ), - tap((status) => { + tap((status): void => { updateSigner(updateId, status); }) ); } function expandOptions (options: Partial): SignatureOptions { - return options = { + return { blockHash: api.genesisHash, version: api.runtimeVersion, ...options - } as SignatureOptions; + } as unknown as SignatureOptions; } function setupEraOptions (header: Header | null, options: Partial): Partial { @@ -233,7 +235,7 @@ export default function createSubmittableExtrinsic ( let updateId: number | undefined; return decorateMethod( - () => (( + (): Observable => (( combineLatest([ // if we have a nonce already, don't retrieve the latest, use what is there isUndefined(options.nonce) @@ -247,7 +249,7 @@ export default function createSubmittableExtrinsic ( ]) ).pipe( first(), - mergeMap(async ([nonce, header]) => { + mergeMap(async ([nonce, header]): Promise => { const eraOptions = setupEraOptions(header, options); if (isKeyringPair) { @@ -262,7 +264,7 @@ export default function createSubmittableExtrinsic ( throw new Error('no signer exists'); } }), - switchMap(() => { + switchMap((): Observable | Observable => { return isSubscription ? subscribeObservable(updateId) : sendObservable(updateId) as any; // ??? diff --git a/packages/api/src/checkTypes.manual.ts b/packages/api/src/checkTypes.manual.ts index 84d956f897..1ec2f9d695 100644 --- a/packages/api/src/checkTypes.manual.ts +++ b/packages/api/src/checkTypes.manual.ts @@ -12,7 +12,7 @@ import { Header, Nonce } from '@polkadot/types'; import { SubmittableResult } from './'; -export default async function test () { +export default async function test (): Promise { const api = await ApiPromise.create(); const keyring = testKeyring(); @@ -23,29 +23,29 @@ export default async function test () { const multiUnsub = await api.queryMulti([ [api.query.system.accountNonce, keyring.eve.address], [api.query.system.accountNonce, keyring.bob.address] - ], (balances) => { + ], (balances): void => { console.log('balances', balances); multiUnsub(); }); - await api.query.staking.intentions((intentions) => { + await api.query.staking.intentions((intentions): void => { console.log('intentions:', intentions); }); - await api.rpc.chain.subscribeNewHead
((header) => { + await api.rpc.chain.subscribeNewHead
((header): void => { console.log('current blockNumber:', header.blockNumber); }); - await api.rpc.chain.subscribeNewHead((header: Header) => { + await api.rpc.chain.subscribeNewHead((header: Header): void => { console.log('current blockNumber:', header.blockNumber); }); - await api.derive.chain.subscribeNewHead((header: HeaderExtended) => { + await api.derive.chain.subscribeNewHead((header: HeaderExtended): void => { console.log('current author:', header.author); }); - await api.derive.chain.subscribeNewHead((header: HeaderExtended) => { + await api.derive.chain.subscribeNewHead((header: HeaderExtended): void => { console.log('current author:', header.author); }); @@ -68,7 +68,7 @@ export default async function test () { // just with the callback const unsub = await api.tx.balances .transfer(keyring.bob.address, 12345) - .signAndSend(keyring.alice, ({ status }: SubmittableResult) => { + .signAndSend(keyring.alice, ({ status }: SubmittableResult): void => { console.log('transfer status:', status.type); unsub(); @@ -78,7 +78,7 @@ export default async function test () { const nonce2 = await api.query.system.accountNonce(keyring.alice.address); const unsub2 = await api.tx.balances .transfer(keyring.bob.address, 12345) - .signAndSend(keyring.alice, { nonce: nonce2 }, ({ status }: SubmittableResult) => { + .signAndSend(keyring.alice, { nonce: nonce2 }, ({ status }: SubmittableResult): void => { console.log('transfer status:', status.type); unsub2(); diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index 54dd9e61e4..182b0f1dd6 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -2,11 +2,12 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -export { WsProvider } from '@polkadot/rpc-provider'; import { assertSingletonPackage } from '@polkadot/util'; assertSingletonPackage('@polkadot/api'); +export { WsProvider } from '@polkadot/rpc-provider'; + export { default as ApiPromise } from './promise'; export { default as ApiRx } from './rx'; export { default as SubmittableExtrinsic, SubmittableResult } from './SubmittableExtrinsic'; diff --git a/packages/api/src/nodeCompat.ts b/packages/api/src/nodeCompat.ts index e9b8c538c3..f9c4e69125 100644 --- a/packages/api/src/nodeCompat.ts +++ b/packages/api/src/nodeCompat.ts @@ -1,24 +1,25 @@ +/* eslint-disable @typescript-eslint/camelcase */ // Copyright 2017-2019 @polkadot/api 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 { Constructor } from '@polkadot/types/types'; -import { EventRecord_0_76, RuntimeVersion, getTypeRegistry } from '@polkadot/types'; +import { EventRecord0to76, RuntimeVersion, getTypeRegistry } from '@polkadot/types'; -type Compat = { +interface Compat { // an array of the spec-name and spec_version that denotes the first version that // does not support this feature. i.e. for EventRecord between 0-76, the new version // went live at 77 - hence the version here denotes 77 - nodeSpecs: Array<[string, number]>, + nodeSpecs: [string, number][]; types: { - [index: string]: Constructor - } -}; + [index: string]: Constructor; + }; +} const ANY_VERSION = 0xffffff; -const types: Array = [ +const types: Compat[] = [ { nodeSpecs: [ ['node', 77], @@ -26,20 +27,20 @@ const types: Array = [ ['node-template', ANY_VERSION] ], types: { - 'EventRecord': EventRecord_0_76 + EventRecord: EventRecord0to76 } } ]; export default function injectNodeCompat ({ specName, specVersion }: RuntimeVersion): void { types - .filter(({ nodeSpecs }) => - nodeSpecs.some(([name, version]) => + .filter(({ nodeSpecs }): boolean => + nodeSpecs.some(([name, version]): boolean => specName.eq(name) && specVersion.ltn(version) ) ) - .forEach(({ types }) => { + .forEach(({ types }): void => { getTypeRegistry().register(types); }); } diff --git a/packages/api/src/promise/Api.spec.ts b/packages/api/src/promise/Api.spec.ts index 77604694fa..abfeb54404 100644 --- a/packages/api/src/promise/Api.spec.ts +++ b/packages/api/src/promise/Api.spec.ts @@ -8,22 +8,22 @@ import Mock from '@polkadot/rpc-provider/mock/index'; import { ApiPromise } from './..'; import { ApiOptions } from './../types'; -describe.skip('Metadata queries', () => { +describe.skip('Metadata queries', (): void => { let mock: Mock; - beforeEach(() => { + beforeEach((): void => { jest.setTimeout(3000000); mock = new Mock(); }); - it('Create API instance with metadata map and makes the runtime, rpc, state & extrinsics available', async () => { - const rpcData = await mock.send('state_getMetadata',[]); - const genesisHash = new Hash(await mock.send('chain_getBlockHash',[])).toHex(); + it('Create API instance with metadata map and makes the runtime, rpc, state & extrinsics available', async (): Promise => { + const rpcData = await mock.send('state_getMetadata', []); + const genesisHash = new Hash(await mock.send('chain_getBlockHash', [])).toHex(); const specVersion = 0; const metadata: any = {}; const key = `${genesisHash}-${specVersion}`; metadata[key] = rpcData; - const api = await ApiPromise.create({ provider: mock, metadata } as ApiOptions); + const api = await ApiPromise.create({ provider: mock, metadata } as unknown as ApiOptions); expect(api.genesisHash).toBeDefined(); expect(api.runtimeMetadata.toJSON()).toEqual(new Metadata(rpcData).toJSON()); @@ -34,7 +34,7 @@ describe.skip('Metadata queries', () => { expect(api.derive).toBeDefined(); }); - it('Create API instance without metadata and makes the runtime, rpc, state & extrinsics available', async () => { + it('Create API instance without metadata and makes the runtime, rpc, state & extrinsics available', async (): Promise => { const metadata = {}; const api = await ApiPromise.create({ provider: mock, metadata @@ -48,5 +48,4 @@ describe.skip('Metadata queries', () => { expect(api.tx).toBeDefined(); expect(api.derive).toBeDefined(); }); - }); diff --git a/packages/api/src/promise/Api.ts b/packages/api/src/promise/Api.ts index 41bf832c00..acee881574 100644 --- a/packages/api/src/promise/Api.ts +++ b/packages/api/src/promise/Api.ts @@ -6,7 +6,7 @@ import { ProviderInterface } from '@polkadot/rpc-provider/types'; import { AnyFunction, Callback, Codec } from '@polkadot/types/types'; import { ApiOptions, DecorateMethodOptions, ObsInnerType, StorageEntryPromiseOverloads, UnsubscribePromise } from '../types'; -import { EMPTY } from 'rxjs'; +import { Observable, EMPTY } from 'rxjs'; import { catchError, first, tap } from 'rxjs/operators'; import { isFunction, assert } from '@polkadot/util'; @@ -120,7 +120,7 @@ export default class ApiPromise extends ApiBase<'promise'> { * }); * ``` */ - static create (options: ApiOptions | ProviderInterface = {}): Promise { + public static create (options: ApiOptions | ProviderInterface = {}): Promise { return new ApiPromise(options).isReady; } @@ -143,27 +143,27 @@ export default class ApiPromise extends ApiBase<'promise'> { * }); * ``` */ - constructor (options?: ApiOptions | ProviderInterface) { + public constructor (options?: ApiOptions | ProviderInterface) { super(options, 'promise'); - this._isReadyPromise = new Promise((resolveReady) => - super.once('ready', () => - resolveReady(this) - ) - ); + this._isReadyPromise = new Promise((resolve): void => { + super.once('ready', (): void => { + resolve(this); + }); + }); } /** * @description Promise that returns the first time we are connected and loaded */ - get isReady (): Promise { + public get isReady (): Promise { return this._isReadyPromise; } /** * @description Returns a clone of this ApiPromise instance (new underlying provider connection) */ - clone (): ApiPromise { + public clone (): ApiPromise { return new ApiPromise({ ...this._options, source: this @@ -190,7 +190,7 @@ export default class ApiPromise extends ApiBase<'promise'> { * }); * ``` */ - async combineLatest (fns: Array]>, callback: CombinatorCallback): UnsubscribePromise { + public async combineLatest (fns: (CombinatorFunction | [CombinatorFunction, ...any[]])[], callback: CombinatorCallback): UnsubscribePromise { const combinator = new Combinator(fns, callback); return (): void => { @@ -201,9 +201,9 @@ export default class ApiPromise extends ApiBase<'promise'> { protected decorateMethod (method: Method, options?: DecorateMethodOptions): StorageEntryPromiseOverloads { const needsCallback = options && options.methodName && options.methodName.includes('subscribe'); - return function (...args: any[]) { + return function (...args: any[]): Promise>> | UnsubscribePromise { let callback: Callback | undefined; - let actualArgs = args.slice(); + const actualArgs = args.slice(); // If the last arg is a function, we pop it, put it into callback. // actualArgs will then hold the actual arguments to be passed to `method` @@ -221,12 +221,12 @@ export default class ApiPromise extends ApiBase<'promise'> { // FIXME TSLint shouts that type assertion is unnecessary, but tsc shouts // when I remove it... // tslint:disable-next-line - return new Promise((resolve, reject) => { + return new Promise((resolve, reject): void => { let isCompleted = false; const subscription = method(...actualArgs) .pipe( // if we find an error (invalid params, etc), reject the promise - catchError((error) => { + catchError((error): Observable => { if (!isCompleted) { isCompleted = true; @@ -237,11 +237,11 @@ export default class ApiPromise extends ApiBase<'promise'> { return EMPTY; }), // upon the first result, resolve the with the unsub function - tap(() => { + tap((): void => { if (!isCompleted) { isCompleted = true; - resolve(() => subscription.unsubscribe()); + resolve((): void => subscription.unsubscribe()); } }) ) diff --git a/packages/api/src/promise/Combinator.ts b/packages/api/src/promise/Combinator.ts index ed11d38b0f..0d14a98f89 100644 --- a/packages/api/src/promise/Combinator.ts +++ b/packages/api/src/promise/Combinator.ts @@ -7,23 +7,29 @@ import { UnsubscribePromise } from '../types'; import { isFunction } from '@polkadot/util'; -export type CombinatorCallback = Callback>; -export type CombinatorFunction = { - (cb: Callback): UnsubscribePromise -}; +export type CombinatorCallback = Callback; +export interface CombinatorFunction { + (cb: Callback): UnsubscribePromise; +} export default class Combinator { protected _allHasFired: boolean = false; - protected _callback: CombinatorCallback; - protected _fired: Array = []; - protected _fns: Array = []; - protected _isActive: boolean = true; - protected _results: Array = []; - protected _subscriptions: Array = []; - constructor (fns: Array]>, callback: CombinatorCallback) { + protected _callback: CombinatorCallback; + + protected _fired: boolean[] = []; + + protected _fns: CombinatorFunction[] = []; + + protected _isActive: boolean = true; + + protected _results: any[] = []; + + protected _subscriptions: UnsubscribePromise[] = []; + + public constructor (fns: (CombinatorFunction | [CombinatorFunction, ...any[]])[], callback: CombinatorCallback) { this._callback = callback; - this._subscriptions = fns.map(async (input, index) => { + this._subscriptions = fns.map(async (input, index): UnsubscribePromise => { const [fn, ...args] = Array.isArray(input) ? input : [input]; @@ -38,13 +44,13 @@ export default class Combinator { protected allHasFired (): boolean { if (!this._allHasFired) { - this._allHasFired = this._fired.filter((hasFired) => !hasFired).length === 0; + this._allHasFired = this._fired.filter((hasFired): boolean => !hasFired).length === 0; } return this._allHasFired; } - protected createCallback (index: number) { + protected createCallback (index: number): (value: any) => void { return (value: any): void => { this._fired[index] = true; this._results[index] = value; @@ -65,14 +71,14 @@ export default class Combinator { } } - unsubscribe (): void { + public unsubscribe (): void { if (!this._isActive) { return; } this._isActive = false; - this._subscriptions.forEach(async (subscription) => { + this._subscriptions.forEach(async (subscription): Promise => { try { const unsubscribe = await subscription; diff --git a/packages/api/src/promise/Combinators.spec.ts b/packages/api/src/promise/Combinators.spec.ts index 10a9200d70..6b4619cdc2 100644 --- a/packages/api/src/promise/Combinators.spec.ts +++ b/packages/api/src/promise/Combinators.spec.ts @@ -5,23 +5,23 @@ import { UnsubscribePromise } from '../types'; import Combinator from './Combinator'; -describe('Combinator', () => { - let fns: Array<(value: any) => void> = []; +describe('Combinator', (): void => { + let fns: ((value: any) => void)[] = []; const storeFn = async (cb: (value: any) => void): UnsubscribePromise => { fns.push(cb); - return () => undefined; + return (): void => undefined; }; - beforeEach(() => { + beforeEach((): void => { fns = []; }); - it('it triggers on all values', (done) => { + it('it triggers on all values', (done): void => { let count = 0; const combinator = new Combinator( [storeFn], - (value: Array) => { + (value: any[]): void => { expect(value[0]).toEqual(`test${count}`); count++; @@ -39,10 +39,10 @@ describe('Combinator', () => { expect(combinator).toBeDefined(); }); - it('combines values from 2 sources, firing when it has all results', (done) => { + it('combines values from 2 sources, firing when it has all results', (done): void => { const combinator = new Combinator( [storeFn, storeFn], - (value: Array) => { + (value: any[]): void => { expect(value).toEqual(['test0', 'test1']); done(); @@ -55,11 +55,11 @@ describe('Combinator', () => { expect(combinator).toBeDefined(); }); - it('combines values from 2 sources, allowing multiple updates', (done) => { + it('combines values from 2 sources, allowing multiple updates', (done): void => { let count = 0; const combinator = new Combinator( [storeFn, storeFn], - (value: Array) => { + (value: any[]): void => { expect(value).toEqual( count === 0 ? ['test0', 'test1'] @@ -80,12 +80,13 @@ describe('Combinator', () => { expect(combinator).toBeDefined(); }); - it('unsubscribes as required', (done) => { - const mocker = async () => done; + it('unsubscribes as required', (done): void => { + const mocker = async (): Promise => done; const combinator = new Combinator([ mocker, - async () => () => void 0 - ], (value: Array) => { + async (): UnsubscribePromise => (): void => void 0 + // eslint-disable-next-line @typescript-eslint/no-unused-vars + ], (value: any[]): void => { // ignore }); diff --git a/packages/api/src/promise/index.ts b/packages/api/src/promise/index.ts index e0fb61d6c5..3e3d208c7e 100644 --- a/packages/api/src/promise/index.ts +++ b/packages/api/src/promise/index.ts @@ -2,6 +2,6 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { default as ApiPromise } from './Api'; +import ApiPromise from './Api'; export default ApiPromise; diff --git a/packages/api/src/rx/Api.spec.ts b/packages/api/src/rx/Api.spec.ts index dad3506dc1..85b734699a 100644 --- a/packages/api/src/rx/Api.spec.ts +++ b/packages/api/src/rx/Api.spec.ts @@ -6,8 +6,8 @@ import { isObservable } from '@polkadot/util'; import ApiRx from './Api'; -describe('ApiRx', () => { - it('has isConnected', () => { +describe('ApiRx', (): void => { + it('has isConnected', (): void => { const api = new ApiRx(); expect( diff --git a/packages/api/src/rx/Api.ts b/packages/api/src/rx/Api.ts index f7aded9151..ea465be6ff 100644 --- a/packages/api/src/rx/Api.ts +++ b/packages/api/src/rx/Api.ts @@ -135,7 +135,7 @@ export default class ApiRx extends ApiBase<'rxjs'> { * }); * ``` */ - static create (options?: ApiOptions | ProviderInterface): Observable { + public static create (options?: ApiOptions | ProviderInterface): Observable { return new ApiRx(options).isReady; } @@ -161,37 +161,37 @@ export default class ApiRx extends ApiBase<'rxjs'> { * }); * ``` */ - constructor (provider?: ApiOptions | ProviderInterface) { + public constructor (provider?: ApiOptions | ProviderInterface) { super(provider, 'rxjs'); this._isReadyRx = from( // convinced you can observable from an event, however my mind groks this form better - new Promise((resolveReady) => - super.on('ready', () => - resolveReady(this) - ) - ) + new Promise((resolve): void => { + super.on('ready', (): void => { + resolve(this); + }); + }) ) as Observable; } /** * @description Observable that carries the connected state for the provider. Results in a boolean flag that is true/false based on the connectivity. */ - get isConnected (): Observable { + public get isConnected (): Observable { return this._isConnected; } /** * @description Observable that returns the first time we are connected and loaded */ - get isReady (): Observable { + public get isReady (): Observable { return this._isReadyRx; } /** * @description Returns a clone of this ApiRx instance (new underlying provider connection) */ - clone (): ApiRx { + public clone (): ApiRx { return new ApiRx({ ...this._options, source: this diff --git a/packages/api/src/rx/index.ts b/packages/api/src/rx/index.ts index 936c2e61ce..edd5756c99 100644 --- a/packages/api/src/rx/index.ts +++ b/packages/api/src/rx/index.ts @@ -2,6 +2,6 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { default as ApiRx } from './Api'; +import ApiRx from './Api'; export default ApiRx; diff --git a/packages/api/src/types.ts b/packages/api/src/types.ts index ae9282847e..59f2f045e9 100644 --- a/packages/api/src/types.ts +++ b/packages/api/src/types.ts @@ -6,7 +6,7 @@ import BN from 'bn.js'; import { Observable } from 'rxjs'; import { DeriveCustom } from '@polkadot/api-derive'; import { Constants } from '@polkadot/api-metadata/consts/fromMetadata/types'; -import { ProviderInterface, ProviderInterface$Emitted } from '@polkadot/rpc-provider/types'; +import { ProviderInterface, ProviderInterfaceEmitted } from '@polkadot/rpc-provider/types'; import { Hash, RuntimeVersion, u64 as U64 } from '@polkadot/types'; import { AnyFunction, Callback, Codec, CodecArg, IExtrinsic, RegistryTypes, SignatureOptions } from '@polkadot/types/types'; import { MethodFunction } from '@polkadot/types/primitive/Method'; @@ -20,15 +20,20 @@ import { ISubmittableResult, SubmittableExtrinsic } from './SubmittableExtrinsic type Cons = ((v: V, ...t: T) => void) extends ((...r: infer R) => void) ? R : never; + // Append an element V onto the end of a tuple T // Push<[1,2,3],4> is [1,2,3,4] // note that this DOES NOT PRESERVE optionality/readonly in tuples. // So unfortunately Push<[1, 2?, 3?], 4> is [1,2|undefined,3|undefined,4] -type Push = (Cons> extends infer R - ? { [K in keyof R]: K extends keyof T ? T[K] : V } - : never) extends infer P +type Push = ( + ( + Cons> extends infer R + ? { [K in keyof R]: K extends keyof T ? T[K] : V } + : never + ) extends infer P ? P extends any[] ? P : never - : never; + : never +); // Returns the inner type of an Observable export type ObsInnerType> = O extends Observable ? U : never; @@ -37,9 +42,9 @@ export type UnsubscribePromise = Promise<() => void>; // In the abstract `decorateMethod` in Base.ts, we can also pass in some meta- // information. This describes it. -export type DecorateMethodOptions = { - methodName?: string -}; +export interface DecorateMethodOptions { + methodName?: string; +} // Here are the return types of these parts of the api: // - api.query.*.*: no exact typings @@ -50,19 +55,22 @@ export type DecorateMethodOptions = { // These are the types that don't lose type information (used for api.derive.*) // Also use these for api.rpc.* https://github.com/polkadot-js/api/issues/1009 export type RxResult = (...args: Parameters) => Observable>>; + +// eslint-disable-next-line @typescript-eslint/prefer-interface export type PromiseResult = { - (...args: Parameters): Promise>>, - (...args: Push, Callback>>>): UnsubscribePromise + (...args: Parameters): Promise>>; + (...args: Push, Callback>>>): UnsubscribePromise; }; + // FIXME The day TS has higher-kinded types, we can remove this hardcoded stuff export type MethodResult = ApiType extends 'rxjs' ? RxResult : PromiseResult; -type DecoratedRpc$Method = ApiType extends 'rxjs' +type DecoratedRpcMethod = ApiType extends 'rxjs' ? { - (arg1?: CodecArg, arg2?: CodecArg, arg3?: CodecArg): Observable - (arg1?: CodecArg, arg2?: CodecArg, arg3?: CodecArg): Observable + (arg1?: CodecArg, arg2?: CodecArg, arg3?: CodecArg): Observable; + (arg1?: CodecArg, arg2?: CodecArg, arg3?: CodecArg): Observable; } : { // These signatures are allowed and exposed here (bit or a stoopid way, but checked @@ -77,16 +85,16 @@ type DecoratedRpc$Method = ApiType extends 'rxjs' }; // FIXME https://github.com/polkadot-js/api/issues/1009 -export interface DecoratedRpc$Section { - [index: string]: DecoratedRpc$Method; +export interface DecoratedRpcSection { + [index: string]: DecoratedRpcMethod; } // FIXME https://github.com/polkadot-js/api/issues/1009 export interface DecoratedRpc { - author: DecoratedRpc$Section; - chain: DecoratedRpc$Section; - state: DecoratedRpc$Section; - system: DecoratedRpc$Section; + author: DecoratedRpcSection; + chain: DecoratedRpcSection; + state: DecoratedRpcSection; + system: DecoratedRpcSection; } export interface StorageEntryObservable { @@ -96,7 +104,7 @@ export interface StorageEntryObservable { creator: StorageEntry; hash: (arg1?: CodecArg, arg2?: CodecArg) => Observable; key: (arg1?: CodecArg, arg2?: CodecArg) => string; - multi: (args: Array) => Observable>; + multi: (args: (CodecArg[] | CodecArg)[]) => Observable; size: (arg1?: CodecArg, arg2?: CodecArg) => Observable; } @@ -109,8 +117,8 @@ export interface StorageEntryPromiseOverloads { } export interface StorageEntryPromiseMulti { - (args: Array): Promise>; - (args: Array, callback: Callback>): UnsubscribePromise; + (args: (CodecArg[] | CodecArg)[]): Promise; + (args: (CodecArg[] | CodecArg)[], callback: Callback): UnsubscribePromise; } export interface StorageEntryPromise extends StorageEntryPromiseOverloads { @@ -133,16 +141,16 @@ export interface QueryableModuleStorage { export type QueryableStorageMultiArg = QueryableStorageEntry | - [QueryableStorageEntry, ...Array]; + [QueryableStorageEntry, ...CodecArg[]]; -export type QueryableStorageMultiArgs = Array>; +export type QueryableStorageMultiArgs = QueryableStorageMultiArg[]; export interface QueryableStorageMultiBase { - (calls: QueryableStorageMultiArgs): Observable>; + (calls: QueryableStorageMultiArgs): Observable; } export interface QueryableStorageMultiPromise { - (calls: QueryableStorageMultiArgs, callback: Callback>): UnsubscribePromise; + (calls: QueryableStorageMultiArgs, callback: Callback): UnsubscribePromise; } export type QueryableStorageMulti = @@ -155,7 +163,7 @@ export interface QueryableStorage { } export interface SubmittableExtrinsicFunction extends MethodFunction { - (...params: Array): SubmittableExtrinsic; + (...params: CodecArg[]): SubmittableExtrinsic; } export interface SubmittableModuleExtrinsics { @@ -176,9 +184,7 @@ export interface ApiOptions { * @description prebundles is a map of 'genesis hash and runtime spec version' as key to metadata's hex string * if genesis hash and runtime spec version matches, then use metadata, else fetch it from chain */ - metadata?: { - [key: string]: string - }; + metadata?: Record; /** * @description Transport Provider from rpc-provider. If not specified, it will default to * connecting to a WsProvider connecting localhost with the default port, i.e. `ws://127.0.0.1:9944` @@ -200,7 +206,7 @@ export interface ApiOptions { } // A smaller interface of ApiRx, used in derive and in SubmittableExtrinsic -export interface ApiInterface$Rx { +export interface ApiInterfaceRx { consts: Constants; genesisHash: Hash; hasSubscriptions: boolean; @@ -213,7 +219,7 @@ export interface ApiInterface$Rx { signer?: Signer; } -export type ApiInterface$Events = ProviderInterface$Emitted | 'ready'; +export type ApiInterfaceEvents = ProviderInterfaceEmitted | 'ready'; export type ApiTypes = 'promise' | 'rxjs'; diff --git a/packages/api/src/util/decorate.ts b/packages/api/src/util/decorate.ts index 7b8041ee81..c1311c74a3 100644 --- a/packages/api/src/util/decorate.ts +++ b/packages/api/src/util/decorate.ts @@ -7,47 +7,49 @@ import { MethodResult } from '../types'; // A technically unsafe version of Object.keys(obj) that assumes that // obj only has known properties of T -function keys (obj: T) { - return Object.keys(obj) as Array; +function keys (obj: T): (keyof T)[] { + return Object.keys(obj) as (keyof T)[]; } -function decorateMethods) => any>> ( +// FIXME the return value typings here is horrible and not DRY +function decorateMethods any>> ( section: Section, decorateMethod: (method: Method) => MethodResult -) { +): { [MethodName in keyof Section]: MethodResult } { return keys(section).reduce( ( acc: { [MethodName in keyof Section]: MethodResult }, methodName: MethodName - ) => { + ): { [MethodName in keyof Section]: MethodResult } => { const method = section[methodName]; acc[methodName] = decorateMethod(method) as any; return acc; }, - {} as { [MethodName in keyof Section]: MethodResult } + {} as unknown as { [MethodName in keyof Section]: MethodResult } ); } /** * This is a section decorator which keeps all type information. */ +// FIXME the return value typings here is horrible and not DRY export function decorateSections any> }> ( allSections: AllSections, decorateMethod: (method: Method) => MethodResult -) { +): { [SectionName in keyof AllSections]: { [MethodName in keyof AllSections[SectionName]]: MethodResult } } { return keys(allSections).reduce( ( acc: { [SectionName in keyof AllSections]: { [MethodName in keyof AllSections[SectionName]]: MethodResult } }, sectionName: MethodName - ) => { + ): { [SectionName in keyof AllSections]: { [MethodName in keyof AllSections[SectionName]]: MethodResult } } => { acc[sectionName] = decorateMethods(allSections[sectionName], decorateMethod); return acc; }, - {} as { [SectionName in keyof AllSections]: { [MethodName in keyof AllSections[SectionName]]: MethodResult } } + {} as unknown as { [SectionName in keyof AllSections]: { [MethodName in keyof AllSections[SectionName]]: MethodResult } } ); } diff --git a/packages/api/src/util/filterEvents.ts b/packages/api/src/util/filterEvents.ts index 0f2963157a..a7ab760d14 100644 --- a/packages/api/src/util/filterEvents.ts +++ b/packages/api/src/util/filterEvents.ts @@ -6,10 +6,10 @@ import { EventRecord, SignedBlock, U8a } from '@polkadot/types'; import l from './logging'; -export default function filterEvents (extHash: U8a, { block: { extrinsics, header } }: SignedBlock, allEvents: Array): Array | undefined { +export default function filterEvents (extHash: U8a, { block: { extrinsics, header } }: SignedBlock, allEvents: EventRecord[]): EventRecord[] | undefined { // extrinsics to hashes const myHash = extHash.toHex(); - const allHashes = extrinsics.map((ext) => ext.hash.toHex()); + const allHashes = extrinsics.map((ext): string => ext.hash.toHex()); // find the index of our extrinsic in the block const index = allHashes.indexOf(myHash); @@ -20,7 +20,7 @@ export default function filterEvents (extHash: U8a, { block: { extrinsics, heade return; } - return allEvents.filter(({ phase }) => + return allEvents.filter(({ phase }): boolean => // only ApplyExtrinsic has the extrinsic index phase.isApplyExtrinsic && phase.asApplyExtrinsic.eqn(index) ); diff --git a/packages/api/test/e2e/promise-alex-archive.spec.ts b/packages/api/test/e2e/promise-alex-archive.spec.ts index 5d5fd79df2..f731d6e98d 100644 --- a/packages/api/test/e2e/promise-alex-archive.spec.ts +++ b/packages/api/test/e2e/promise-alex-archive.spec.ts @@ -7,21 +7,21 @@ import { Extrinsic, SignedBlock } from '@polkadot/types'; import Api from './../../src/promise'; // To run these tests locally you need to run a Alexander full archive node locally -describe.skip('alex archive queries (local)', () => { +describe.skip('alex archive queries (local)', (): void => { let api: Api; - beforeEach(() => { + beforeEach((): void => { jest.setTimeout(30000); }); - beforeEach(async () => { + beforeEach(async (): Promise => { api = await Api.create(); return api; }); // https://github.com/polkadot-js/api/issues/845 - it('retrieves block with no issues', async () => { + it('retrieves block with no issues', async (): Promise => { const metadata = await api.rpc.state.getMetadata('0x6f6f9bba0eed8e3ae9446c37eee763f93118b52a315a7b46090453ba6288da1f'); console.error(JSON.stringify(metadata, null, 2)); @@ -36,10 +36,10 @@ describe.skip('alex archive queries (local)', () => { }); // https://github.com/polkadot-js/api/issues/846 - it('handles toJSON with no issues', async (done) => { + it('handles toJSON with no issues', async (done): Promise<() => void> => { return ( - api.rpc.chain.getBlock('0x85c62b581f38cb81c3e443d34392672beb1fb877017fd7237cc87704113259dc', (result: SignedBlock) => { - const failed: Array = result.block.extrinsics.filter((extrinsic: Extrinsic) => { + api.rpc.chain.getBlock('0x85c62b581f38cb81c3e443d34392672beb1fb877017fd7237cc87704113259dc', (result: SignedBlock): void => { + const failed: Extrinsic[] = result.block.extrinsics.filter((extrinsic: Extrinsic): boolean => { try { const json = extrinsic.method.toJSON(); diff --git a/packages/api/test/e2e/promise-alex.spec.ts b/packages/api/test/e2e/promise-alex.spec.ts index 2eb0ba8f5c..4946e79d7f 100644 --- a/packages/api/test/e2e/promise-alex.spec.ts +++ b/packages/api/test/e2e/promise-alex.spec.ts @@ -10,14 +10,14 @@ import Api from './../../src/promise'; const WS_URL = 'wss://poc3-rpc.polkadot.io/'; // const WS_URL = 'wss://substrate-rpc.parity.io/'; -describe.skip('alex queries', () => { +describe.skip('alex queries', (): void => { let api: Api; - beforeEach(() => { + beforeEach((): void => { jest.setTimeout(30000); }); - beforeEach(async () => { + beforeEach(async (): Promise => { api = await Api.create({ provider: new WsProvider(WS_URL) }); @@ -25,9 +25,9 @@ describe.skip('alex queries', () => { return api; }); - it('retrieves the list of validators', (done) => { + it('retrieves the list of validators', (done): Promise<() => void> => { return ( - api.query.staking.validators((res) => { + api.query.staking.validators((res): void => { console.error(res); console.log('api.query.staking.validators():', res.toJSON()); @@ -36,10 +36,10 @@ describe.skip('alex queries', () => { ); }); - describe('retrieves a single value', () => { - it('retrieves the list of stash validators', (done) => { + describe('retrieves a single value', (): void => { + it('retrieves the list of stash validators', (done): Promise<() => void> => { return ( - api.query.staking.validators('5DuiZFa184E9iCwbh4WjXYvJ88NHvWJbS8SARY8Ev1YEqrri', (res) => { + api.query.staking.validators('5DuiZFa184E9iCwbh4WjXYvJ88NHvWJbS8SARY8Ev1YEqrri', (res): void => { console.error(res); console.log('api.query.staking.validators(id):', res.toJSON()); done(); @@ -47,18 +47,18 @@ describe.skip('alex queries', () => { ); }); - it('Gets the hash of the last finalized header', async (done) => { + it('Gets the hash of the last finalized header', async (done): Promise<() => void> => { return ( - api.rpc.chain.getFinalizedHead((head) => { + api.rpc.chain.getFinalizedHead((head): void => { expect(head instanceof Hash).toBe(true); done(); }) ); }); - it('Subscribes to the best finalized header on ALEX', async (done) => { + it('Subscribes to the best finalized header on ALEX', async (done): Promise<() => void> => { return ( - api.rpc.chain.subscribeFinalizedHeads((head) => { + api.rpc.chain.subscribeFinalizedHeads((head): void => { expect(head instanceof Header).toBe(true); done(); }) @@ -66,9 +66,9 @@ describe.skip('alex queries', () => { }); }); - it('derives a list of the controllers', (done) => { + it('derives a list of the controllers', (done): Promise<() => void> => { return ( - api.derive.staking.controllers((res: [Array, Array>]) => { + api.derive.staking.controllers((res: [AccountId[], Option[]]): void => { console.log('api.derive.staking.controllers:', JSON.stringify(res)); done(); @@ -76,15 +76,15 @@ describe.skip('alex queries', () => { ); }); - it('makes a query at a latest block (specified)', async () => { + it('makes a query at a latest block (specified)', async (): Promise => { const header = await api.rpc.chain.getHeader() as Header; const events = await api.query.system.events.at(header.hash) as Vector; expect(events.length).not.toEqual(0); }); - it('subscribes to events', (done) => { - return api.query.system.events((events: Vector) => { + it('subscribes to events', (done): Promise<() => void> => { + return api.query.system.events((events: Vector): void => { expect(events).not.toHaveLength(0); done(); }); diff --git a/packages/api/test/e2e/promise-consts.spec.ts b/packages/api/test/e2e/promise-consts.spec.ts index 184f025c3d..b815afa158 100644 --- a/packages/api/test/e2e/promise-consts.spec.ts +++ b/packages/api/test/e2e/promise-consts.spec.ts @@ -6,20 +6,20 @@ import WsProvider from '@polkadot/rpc-provider/ws'; import { ApiPromise } from '@polkadot/api'; import { BlockNumber } from '@polkadot/types'; -describe.skip('e2e consts', () => { +describe.skip('e2e consts', (): void => { let api: ApiPromise; - beforeEach(() => { + beforeEach((): Promise => { api = new ApiPromise(new WsProvider('ws://127.0.0.1:9944')); return api.isReady; }); - beforeEach(() => { + beforeEach((): void => { jest.setTimeout(30000); }); - it('democracy.cooloffPeriod parameter type', () => { + it('democracy.cooloffPeriod parameter type', (): void => { expect(api.consts.democracy.cooloffPeriod).toBeInstanceOf(BlockNumber); expect(api.consts.democracy.cooloffPeriod.eq(432000)).toBeTruthy(); }); diff --git a/packages/api/test/e2e/promise-contract.spec.ts b/packages/api/test/e2e/promise-contract.spec.ts index a5cad8d2f3..95636b9b6a 100644 --- a/packages/api/test/e2e/promise-contract.spec.ts +++ b/packages/api/test/e2e/promise-contract.spec.ts @@ -17,15 +17,15 @@ import { ApiPromise, SubmittableResult } from '../../src'; const flipperCode = fs.readFileSync(path.join(__dirname, '../../../api-contract/test/contracts/flipper-pruned.wasm')).toString('hex'); -describe.skip('Promise e2e contracts', () => { +describe.skip('Promise e2e contracts', (): void => { let address: Address; let codeHash: Hash; let keyring: { - [index: string]: KeyringPair + [index: string]: KeyringPair; }; let api: ApiPromise; - beforeEach(async (done) => { + beforeEach(async (done): Promise => { if (!api) { api = await ApiPromise.create(); @@ -36,19 +36,19 @@ describe.skip('Promise e2e contracts', () => { done(); }); - describe('flipper', () => { + describe('flipper', (): void => { const MAX_GAS = 500000; let abi: Abi; - beforeEach(() => { + beforeEach((): void => { abi = new Abi(flipperAbi); }); - it('allows putCode', (done) => { + it('allows putCode', (done): Promise<() => void> => { return ( api.tx.contracts .putCode(MAX_GAS, `0x${flipperCode}`) - .signAndSend(keyring.eve, (result: SubmittableResult) => { + .signAndSend(keyring.eve, (result: SubmittableResult): void => { if (result.status.isFinalized) { const record = result.findRecord('contract', 'CodeStored'); if (record) { @@ -61,13 +61,13 @@ describe.skip('Promise e2e contracts', () => { ); }); - it('allows contract create', (done) => { + it('allows contract create', (done): Promise<() => void> => { expect(codeHash).toBeDefined(); return ( api.tx.contracts .create(12345, MAX_GAS, codeHash, abi.deploy()) - .signAndSend(keyring.bob, (result: SubmittableResult) => { + .signAndSend(keyring.bob, (result: SubmittableResult): void => { console.error('create', JSON.stringify(result)); if (result.status.isFinalized) { @@ -83,13 +83,13 @@ describe.skip('Promise e2e contracts', () => { ); }); - it('allows contract call', (done) => { + it('allows contract call', (done): Promise<() => void> => { expect(address).toBeDefined(); return ( api.tx.contracts .call(address, 12345, MAX_GAS, abi.messages.flip()) - .signAndSend(keyring.bob, (result: SubmittableResult) => { + .signAndSend(keyring.bob, (result: SubmittableResult): void => { console.error('call', JSON.stringify(result)); if (result.status.isFinalized && result.findRecord('system', 'ExtrinsicSuccess')) { diff --git a/packages/api/test/e2e/promise-queries.spec.ts b/packages/api/test/e2e/promise-queries.spec.ts index 63079f8f54..9a9e134fc6 100644 --- a/packages/api/test/e2e/promise-queries.spec.ts +++ b/packages/api/test/e2e/promise-queries.spec.ts @@ -17,11 +17,11 @@ const ZERO = new BN(0); const WS_URL = 'ws://127.0.0.1:9944'; // const WS_URL = 'wss://poc3-rpc.polkadot.io/'; -describe.skip('Promise e2e queries', () => { +describe.skip('Promise e2e queries', (): void => { const keyring = testingPairs({ type: 'ed25519' }); let api: Api; - beforeEach(async (done) => { + beforeEach(async (done): Promise => { if (!api) { api = await Api.create({ provider: new WsProvider(WS_URL) @@ -32,7 +32,7 @@ describe.skip('Promise e2e queries', () => { done(); }); - it('makes the runtime, rpc, state & extrinsics available', () => { + it('makes the runtime, rpc, state & extrinsics available', (): void => { expect(api.genesisHash).toBeDefined(); expect(api.runtimeMetadata).toBeDefined(); expect(api.runtimeVersion).toBeDefined(); @@ -42,31 +42,29 @@ describe.skip('Promise e2e queries', () => { expect(api.derive).toBeDefined(); }); - it('allows retrieval of an fallback entry (once-off query)', async () => { + it('allows retrieval of an fallback entry (once-off query)', async (): Promise => { const nonce = await api.query.system.accountNonce('5DSo5RVtfrtgHoz2c7jK7Tca7FgJgpCzFnxoRVDeYUQcKPng'); expect(nonce.toHex()).toEqual('0x0000000000000000'); }); - it('allows retrieval of fallback when at query is made', async () => { + it('allows retrieval of fallback when at query is made', async (): Promise => { const header = await api.rpc.chain.getHeader() as Header; const nonce = await api.query.system.accountNonce.at(header.hash, '5DSo5RVtfrtgHoz2c7jK7Tca7FgJgpCzFnxoRVDeYUQcKPng'); expect(nonce.toHex()).toEqual('0x0000000000000000'); }); - it('queries state for a balance', async () => { - return ( - api.query.balances.freeBalance(keyring.alice.address, (balance: Balance) => { - expect(balance).toBeInstanceOf(BN); - expect(balance.isZero()).toBe(false); - }) - ); + it('queries state for a balance', async (): Promise<() => void> => { + return api.query.balances.freeBalance(keyring.alice.address, (balance: Balance): void => { + expect(balance).toBeInstanceOf(BN); + expect(balance.isZero()).toBe(false); + }); }); - it('subscribes to rpc', (done) => { + it('subscribes to rpc', (done): Promise<() => void> => { return ( - api.rpc.chain.subscribeNewHead((header: Header) => { + api.rpc.chain.subscribeNewHead((header: Header): void => { expect(header.blockNumber.isZero()).toBe(false); done(); @@ -74,9 +72,9 @@ describe.skip('Promise e2e queries', () => { ); }); - it('subscribes to finalized', (done) => { + it('subscribes to finalized', (done): Promise<() => void> => { return ( - api.rpc.chain.subscribeFinalizedHeads((header: Header) => { + api.rpc.chain.subscribeFinalizedHeads((header: Header): void => { expect(header.blockNumber.isZero()).toBe(false); done(); @@ -84,9 +82,9 @@ describe.skip('Promise e2e queries', () => { ); }); - it('subscribes to derive', (done) => { + it('subscribes to derive', (done): Promise<() => void> => { return ( - api.derive.chain.subscribeNewHead((header: HeaderExtended) => { + api.derive.chain.subscribeNewHead((header: HeaderExtended): void => { expect(header.blockNumber.isZero()).toBe(false); done(); @@ -94,9 +92,9 @@ describe.skip('Promise e2e queries', () => { ); }); - it('subscribes to queries', (done) => { + it('subscribes to queries', (done): Promise<() => void> => { return ( - api.query.system.accountNonce(keyring.ferdie.address, (nonce: Index) => { + api.query.system.accountNonce(keyring.ferdie.address, (nonce: Index): void => { expect(nonce instanceof BN).toBe(true); done(); @@ -104,9 +102,9 @@ describe.skip('Promise e2e queries', () => { ); }); - it.skip('subscribes to queries (default)', (done) => { + it.skip('subscribes to queries (default)', (done): Promise<() => void> => { return ( - api.query.staking.validators(keyring.ferdie.address, (prefs: ValidatorPrefs) => { + api.query.staking.validators(keyring.ferdie.address, (prefs: ValidatorPrefs): void => { expect(prefs.unstakeThreshold.toNumber()).toBe(3); done(); @@ -114,9 +112,9 @@ describe.skip('Promise e2e queries', () => { ); }); - it('subscribes to a linked map (staking.validators)', (done) => { + it('subscribes to a linked map (staking.validators)', (done): Promise<() => void> => { return ( - api.query.staking.validators((prefs: LinkageResult) => { + api.query.staking.validators((prefs: LinkageResult): void => { expect(prefs instanceof LinkageResult).toBe(true); done(); @@ -124,14 +122,14 @@ describe.skip('Promise e2e queries', () => { ); }); - it('subscribes to multiple results (freeBalance.multi)', (done) => { + it('subscribes to multiple results (freeBalance.multi)', (done): Promise<() => void> => { return ( api.query.balances.freeBalance.multi([ keyring.alice.address, keyring.bob.address, '5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y', keyring.ferdie.address - ], (balances) => { + ], (balances): void => { expect(balances).toHaveLength(4); done(); @@ -139,24 +137,24 @@ describe.skip('Promise e2e queries', () => { ); }); - it('subscribes to multiple results (api.queryMulti)', (done) => { + it('subscribes to multiple results (api.queryMulti)', (done): Promise<() => void> => { return api.queryMulti([ [api.query.balances.freeBalance, keyring.alice.address], [api.query.balances.freeBalance, keyring.bob.address], [api.query.balances.freeBalance, '5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y'], [api.query.balances.freeBalance, keyring.ferdie.address] - ], (balances: Array) => { + ], (balances: Balance[]): void => { expect(balances).toHaveLength(4); done(); }); }); - it('subscribes to derived balances (balances.all)', (done) => { + it('subscribes to derived balances (balances.all)', (done): Promise<() => void> => { return ( api.derive.balances.all( keyring.alice.address, - (all: DerivedBalances) => { + (all: DerivedBalances): void => { expect(all.accountId.toString()).toEqual(keyring.alice.address); expect(all.freeBalance).toBeDefined(); @@ -172,61 +170,61 @@ describe.skip('Promise e2e queries', () => { ); }); - it('can retrive header by hash', async () => { + it('can retrive header by hash', async (): Promise => { const latest = await api.rpc.chain.getHeader() as Header; const specific = await api.rpc.chain.getHeader(latest.hash) as Header; expect(latest.hash).toEqual(specific.hash); }); - it('makes a query at a latest block (specified)', async () => { + it('makes a query at a latest block (specified)', async (): Promise => { const header = await api.rpc.chain.getHeader() as Header; const events = await api.query.system.events.at(header.hash) as Vector; expect(events.length).not.toEqual(0); - events.forEach(({ event: { data, method, section }, phase, topics }: EventRecord) => { + events.forEach(({ event: { data, method, section }, phase, topics }: EventRecord): void => { console.error(phase.toString(), `: ${section}.${method}`, data.toString(), topics.toString()); }); }); - it('subscribes to events', (done) => { + it('subscribes to events', (done): Promise<() => void> => { return ( - api.query.system.events((events) => { + api.query.system.events((events): void => { expect(events).not.toHaveLength(0); done(); }) ); }); - describe('with plain type', () => { - it('queries a correct value', async () => { + describe('with plain type', (): void => { + it('queries a correct value', async (): Promise => { const sessionIndex = await api.query.session.currentIndex() as SessionIndex; expect(sessionIndex.toNumber()).toBeGreaterThanOrEqual(0); }); - it('queries correct value at a specified block', async () => { + it('queries correct value at a specified block', async (): Promise => { const header = await api.rpc.chain.getHeader() as Header; const sessionIndex = await api.query.session.currentIndex.at(header.hash) as SessionIndex; expect(sessionIndex.toNumber()).toBeGreaterThanOrEqual(0); }); - it('subscribes to query and get correct result', (done) => { - return api.query.session.currentIndex((sessionIndex: SessionIndex) => { + it('subscribes to query and get correct result', (done): Promise<() => void> => { + return api.query.session.currentIndex((sessionIndex: SessionIndex): void => { expect(sessionIndex.toNumber()).toBeGreaterThanOrEqual(0); done(); }); }); - it('queries correct hash', async () => { + it('queries correct hash', async (): Promise => { const hash: Hash = await api.query.session.currentIndex.hash(); expect(hash).toBeDefined(); }); - it('gets correct key', async () => { + it('gets correct key', async (): Promise => { const key = api.query.session.currentIndex.key(); const sessionIndexData = await api.rpc.state.getStorage(key) as Option; const sessionIndexRPC = new SessionIndex(sessionIndexData.unwrapOr(undefined)); @@ -234,7 +232,7 @@ describe.skip('Promise e2e queries', () => { expect(sessionIndexRPC.toNumber()).toBeGreaterThanOrEqual(0); }); - it('queries correct size', async () => { + it('queries correct size', async (): Promise => { const size = await api.query.session.currentIndex.size(); expect(size).not.toHaveLength(0); @@ -242,14 +240,14 @@ describe.skip('Promise e2e queries', () => { }); }); - describe('with map type', () => { - it('queries correct value', async () => { + describe('with map type', (): void => { + it('queries correct value', async (): Promise => { const balance = await api.query.balances.freeBalance(keyring.alice.address) as Balance; expect(balance.isZero()).toBe(false); }); - it('queries correct value at a specified block', async () => { + it('queries correct value at a specified block', async (): Promise => { // assume the account Alice is only used in test(the balance of Alice does not change in this test case) const balance = await api.query.balances.freeBalance(keyring.alice.address); const header = await api.rpc.chain.getHeader() as Header; @@ -259,24 +257,24 @@ describe.skip('Promise e2e queries', () => { expect(balanceAt.toString()).toEqual(balance.toString()); }); - it('subscribes to query and get correct result', async (done) => { + it('subscribes to query and get correct result', async (done): Promise<() => void> => { // assume the account Alice is only used in test(the balance of Alice does not change in this test case) const balance = await api.query.balances.freeBalance(keyring.alice.address); - return api.query.balances.freeBalance(keyring.alice.address, (balanceSubscribed: Balance) => { + return api.query.balances.freeBalance(keyring.alice.address, (balanceSubscribed: Balance): void => { expect(balanceSubscribed.isZero()).toBe(false); expect(balanceSubscribed.toString()).toEqual(balance.toString()); done(); }); }); - it('queries correct hash', async () => { + it('queries correct hash', async (): Promise => { const hash = await api.query.balances.freeBalance.hash(keyring.alice.address); expect(hash).toBeDefined(); }); - it('gets correct key', async () => { + it('gets correct key', async (): Promise => { // assume the account Alice is only used in test(the balance of Alice does not change in this test case) const key = api.query.balances.freeBalance.key(keyring.alice.address); const balanceData = await api.rpc.state.getStorage(key) as Option; @@ -288,7 +286,7 @@ describe.skip('Promise e2e queries', () => { expect(balanceRPC.toString()).toEqual(balance.toString()); }); - it('queries multiple results', async () => { + it('queries multiple results', async (): Promise => { // assume the account Alice and Bob are only used in test(the balance of them do not change in this test case) const balanceAlice = await api.query.balances.freeBalance(keyring.alice.address); const balanceBob = await api.query.balances.freeBalance(keyring.bob.address); @@ -303,7 +301,7 @@ describe.skip('Promise e2e queries', () => { expect((balances as any)[1].toString()).toEqual(balanceBob.toString()); }); - it('subscribes to multiple queries and get correct results', async (done) => { + it('subscribes to multiple queries and get correct results', async (done): Promise<() => void> => { // assume the account Alice and Bob are only used in test(the balance of them do not change in this test case) const balanceAlice = await api.query.balances.freeBalance(keyring.alice.address); const balanceBob = await api.query.balances.freeBalance(keyring.bob.address); @@ -311,7 +309,7 @@ describe.skip('Promise e2e queries', () => { return api.query.balances.freeBalance.multi([ keyring.alice.address, keyring.bob.address - ], (balances) => { + ], (balances): void => { expect(balances).toHaveLength(2); expect(balances[0].toString()).toEqual(balanceAlice.toString()); expect(balances[1].toString()).toEqual(balanceBob.toString()); @@ -319,7 +317,7 @@ describe.skip('Promise e2e queries', () => { }); }); - it('queries correct size', async () => { + it('queries correct size', async (): Promise => { const size = await api.query.balances.freeBalance.size(keyring.alice.address); expect(size.toNumber()).not.toEqual(0); @@ -327,16 +325,16 @@ describe.skip('Promise e2e queries', () => { }); // TODO Update ['any', '0x1234'] to the key of a known event topic and update EXPECTED_VALUE to the expected value - describe('with double map type', () => { + describe('with double map type', (): void => { const KEY1 = 'any'; const KEY2 = '0x1234'; - it('queries correct value', async () => { + it('queries correct value', async (): Promise => { const eventTopics = await api.query.system.eventTopics(KEY1, KEY2); expect(eventTopics.toJSON()).toEqual([]); }); - it('queries correct value at a specified block', async () => { + it('queries correct value at a specified block', async (): Promise => { const header = await api.rpc.chain.getHeader() as Header; // TODO check & fix: this will throw the error: Encoding for input doesn't match output, created 0x00 from 0x @@ -347,27 +345,27 @@ describe.skip('Promise e2e queries', () => { // expect(eventTopicsAt.toJSON()).toEqual([]); }); - it('subscribes to query and get correct result', async (done) => { - return api.query.system.eventTopics(KEY1, KEY2, (eventTopicsAt) => { + it('subscribes to query and get correct result', async (done): Promise<() => void> => { + return api.query.system.eventTopics(KEY1, KEY2, (eventTopicsAt): void => { expect(eventTopicsAt.toJSON()).toEqual([]); done(); }); }); - it('queries correct hash', async () => { + it('queries correct hash', async (): Promise => { const hash = await api.query.system.eventTopics(KEY1, KEY2); expect(hash).toBeDefined(); }); - it('gets correct key', async () => { + it('gets correct key', async (): Promise => { const key = api.query.system.eventTopics.key(KEY1, KEY2); const eventTopicsData = await api.rpc.state.getStorage(key) as Option; expect(eventTopicsData.unwrapOr(undefined)).toEqual(undefined); }); - it('queries multiple results', async () => { + it('queries multiple results', async (): Promise => { const eventTopicsList = await api.query.system.eventTopics.multi([ [KEY1, KEY2] ]); @@ -376,17 +374,17 @@ describe.skip('Promise e2e queries', () => { expect((eventTopicsList as any)[0].toJSON()).toEqual([]); }); - it('subscribes to multiple queries and get correct results', async (done) => { + it('subscribes to multiple queries and get correct results', async (done): Promise<() => void> => { return api.query.system.eventTopics.multi([ [KEY1, KEY2] - ], (eventTopicsList) => { + ], (eventTopicsList): void => { expect(eventTopicsList).toHaveLength(1); expect(eventTopicsList[0].toJSON()).toEqual([]); done(); }); }); - it('queries correct size', async () => { + it('queries correct size', async (): Promise => { const size = await api.query.system.eventTopics.size(KEY1, KEY2); expect(size.toNumber()).toEqual(0); diff --git a/packages/api/test/e2e/promise-tx.spec.ts b/packages/api/test/e2e/promise-tx.spec.ts index 3431206c47..b9efae8837 100644 --- a/packages/api/test/e2e/promise-tx.spec.ts +++ b/packages/api/test/e2e/promise-tx.spec.ts @@ -14,15 +14,15 @@ import { Signer } from './../../src/types'; import Api from './../../src/promise'; // log all events for the transfare, calling done() when finalized -const logEvents = (done: () => {}) => - ({ events, status }: SubmittableResult) => { +const logEvents = (done: () => {}): (r: SubmittableResult) => void => + ({ events, status }: SubmittableResult): void => { console.log('Transaction status:', status.type); if (status.isFinalized) { console.log('Completed at block hash', status.value.toHex()); console.log('Events:'); - events.forEach(({ phase, event: { data, method, section } }: EventRecord) => { + events.forEach(({ phase, event: { data, method, section } }: EventRecord): void => { console.log('\t', phase.toString(), `: ${section}.${method}`, data.toString()); }); @@ -32,11 +32,11 @@ const logEvents = (done: () => {}) => } }; -describe.skip('Promise e2e transactions', () => { +describe.skip('Promise e2e transactions', (): void => { const keyring = testingPairs({ type: 'ed25519' }); let api: Api; - beforeEach(async (done) => { + beforeEach(async (done): Promise => { if (!api) { api = await Api.create({ provider: new WsProvider('ws://127.0.0.1:9944') @@ -47,11 +47,11 @@ describe.skip('Promise e2e transactions', () => { done(); }); - afterEach(() => { + afterEach((): void => { jest.setTimeout(5000); }); - it('can submit an extrinsic from hex', async (done) => { + it('can submit an extrinsic from hex', async (done): Promise<() => void> => { const nonce = await api.query.system.accountNonce(keyring.dave.address) as Index; const hex = api.tx.balances .transfer(keyring.eve.address, 12345) @@ -61,7 +61,7 @@ describe.skip('Promise e2e transactions', () => { return api.tx(hex).send(logEvents(done)); }); - it('makes a transfer (sign, then send)', async (done) => { + it('makes a transfer (sign, then send)', async (done): Promise<() => void> => { const nonce = await api.query.system.accountNonce(keyring.dave.address) as Index; return api.tx.balances @@ -70,7 +70,7 @@ describe.skip('Promise e2e transactions', () => { .send(logEvents(done)); }); - it('makes a transfer (sign, then send - compat version)', async (done) => { + it('makes a transfer (sign, then send - compat version)', async (done): Promise<() => void> => { const nonce = await api.query.system.accountNonce(keyring.dave.address) as Index; return api.tx.balances @@ -79,13 +79,13 @@ describe.skip('Promise e2e transactions', () => { .send(logEvents(done)); }); - it('makes a transfer (signAndSend, immortal)', async (done) => { + it('makes a transfer (signAndSend, immortal)', async (done): Promise<() => void> => { return api.tx.balances .transfer(keyring.eve.address, 12345) .signAndSend(keyring.charlie, { era: 0 }, logEvents(done)); }); - it('makes a transfer (signAndSend via Signer)', async (done) => { + it('makes a transfer (signAndSend via Signer)', async (done): Promise<() => void> => { const signer = new SingleAccountSigner(keyring.charlie) as Signer; api.setSigner(signer); @@ -95,7 +95,7 @@ describe.skip('Promise e2e transactions', () => { .signAndSend(keyring.charlie.address, logEvents(done)); }); - it('makes a transfer (signAndSend via Signer) with undefined Signer', async () => { + it('makes a transfer (signAndSend via Signer) with undefined Signer', async (): Promise => { const signer: any = undefined; // no signer api.setSigner(signer); @@ -105,7 +105,7 @@ describe.skip('Promise e2e transactions', () => { .signAndSend(keyring.alice.address)).rejects.toThrow('no signer exists'); }); - it('makes a transfer (signAndSend via Signer) with the wrong keyring pair', async () => { + it('makes a transfer (signAndSend via Signer) with the wrong keyring pair', async (): Promise => { const signer: Signer = new SingleAccountSigner(keyring.dave); api.setSigner(signer); @@ -116,14 +116,15 @@ describe.skip('Promise e2e transactions', () => { .signAndSend(keyring.alice.address)).rejects.toThrow('does not have the keyringPair'); }); - it('makes a transfer (signAndSend via Signer) with the wrong keyring pair with a callback', async () => { + it('makes a transfer (signAndSend via Signer) with the wrong keyring pair with a callback', async (): Promise => { // with callback await expect(api.tx.balances .transfer(keyring.eve.address, 12345) - .signAndSend(keyring.alice.address, (cb: any) => { /*do nothing */ })).rejects.toThrow('does not have the keyringPair'); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + .signAndSend(keyring.alice.address, (cb: any): void => { /* do nothing */ })).rejects.toThrow('does not have the keyringPair'); }); - it('makes a transfer (no callback)', async () => { + it('makes a transfer (no callback)', async (): Promise => { const hash = await api.tx.balances .transfer(keyring.eve.address, 12345) .signAndSend(keyring.dave); @@ -131,7 +132,7 @@ describe.skip('Promise e2e transactions', () => { expect(hash.toHex()).toHaveLength(66); }); - it('makes a proposal', async () => { + it('makes a proposal', async (): Promise => { // don't wait for status, just get hash. Here we generate a large-ish payload // to ensure that we can sign with the hashed version as well (and have it accepted) const hash: Hash = await api.tx.democracy @@ -142,29 +143,29 @@ describe.skip('Promise e2e transactions', () => { }); // this one is slightly difficult with the current testnet config - CantPay - it.skip('makes a transfer, and uses new balance to transfers to new', async (done) => { + it.skip('makes a transfer, and uses new balance to transfers to new', async (done): Promise<() => void> => { const pair = new Keyring().addFromUri('testing123', {}, 'ed25519'); - function doOne (cb: any) { + function doOne (cb: any): Promise<() => void> { return api.tx.balances .transfer(pair.address, 1234567) .signAndSend(keyring.dave, logEvents(cb)); } - function doTwo (cb: any) { + function doTwo (cb: any): Promise<() => void> { return api.tx.balances .transfer(keyring.alice.address, 1111111) .signAndSend(pair, logEvents(cb)); } // return doTwo(done); - return doOne(() => { + return doOne((): Promise<() => void> => { return doTwo(done); }); }); - describe('eras', () => { - it('makes a transfer (specified era)', async (done) => { + describe('eras', (): void => { + it('makes a transfer (specified era)', async (done): Promise => { const signedBlock = await api.rpc.chain.getBlock() as SignedBlock; const currentHeight = signedBlock.block.header.number; const exERA = new ExtrinsicEra({ current: currentHeight, period: 10 }); @@ -178,7 +179,7 @@ describe.skip('Promise e2e transactions', () => { done(); }); - it('makes a transfer with invalid time', async (done) => { + it('makes a transfer with invalid time', async (done): Promise<() => void> => { const nonce = await api.query.system.accountNonce(keyring.alice.address) as Index; const signedBlock = await api.rpc.chain.getBlock() as SignedBlock; const currentHeight = signedBlock.block.header.number; @@ -188,7 +189,7 @@ describe.skip('Promise e2e transactions', () => { const ex = api.tx.balances.transfer(keyring.eve.address, 12345); return ( - api.rpc.chain.subscribeNewHead(async (header: Header) => { + api.rpc.chain.subscribeNewHead(async (header: Header): Promise => { if (header.blockNumber.toNumber() === eraDeath - 1) { try { await ex.signAndSend(keyring.alice, { blockHash, era: exERA, nonce } as any); @@ -201,7 +202,7 @@ describe.skip('Promise e2e transactions', () => { ); }); - it('makes a transfer with custom numeric era', async (done) => { + it('makes a transfer with custom numeric era', async (done): Promise => { const hash = await api.tx.balances .transfer(keyring.eve.address, 12345) .signAndSend(keyring.charlie, { era: 2 }); diff --git a/packages/api/test/e2e/rx-queries.spec.ts b/packages/api/test/e2e/rx-queries.spec.ts index df4a1df74d..1c0e0524a1 100644 --- a/packages/api/test/e2e/rx-queries.spec.ts +++ b/packages/api/test/e2e/rx-queries.spec.ts @@ -11,17 +11,17 @@ import testingPairs from '@polkadot/keyring/testingPairs'; import Api from '../../src/rx'; -describe.skip('Rx e2e queries', () => { +describe.skip('Rx e2e queries', (): void => { const keyring = testingPairs({ type: 'ed25519' }); let api: Api; - beforeEach(async (done) => { + beforeEach(async (done): Promise => { api = await Api.create().toPromise(); jest.setTimeout(3000000); done(); }); - it('makes the runtime, rpc, state & extrinsics available', () => { + it('makes the runtime, rpc, state & extrinsics available', (): void => { expect(api.genesisHash).toBeDefined(); expect(api.runtimeMetadata).toBeDefined(); expect(api.runtimeVersion).toBeDefined(); @@ -31,22 +31,22 @@ describe.skip('Rx e2e queries', () => { expect(api.derive).toBeDefined(); }); - it('queries state for a balance', (done) => { - api.query.balances.freeBalance(keyring.alice.address).subscribe((balance) => { + it('queries state for a balance', (done): void => { + api.query.balances.freeBalance(keyring.alice.address).subscribe((balance): void => { expect(balance).toBeInstanceOf(BN); expect((balance as Balance).isZero()).toBe(false); done(); }); }); - it('makes a query at a specific block', (done) => { + it('makes a query at a specific block', (done): void => { (api.rpc.chain.getHeader() as Observable
) .pipe( - switchMap(({ hash }: Header) => + switchMap(({ hash }: Header): Observable => api.query.system.events.at(hash) ) ) - .subscribe((events: any) => { + .subscribe((events: any): void => { expect(events.length).not.toEqual(0); done(); }); diff --git a/packages/api/test/e2e/rx-tx.spec.ts b/packages/api/test/e2e/rx-tx.spec.ts index c3837d573c..f047821d25 100644 --- a/packages/api/test/e2e/rx-tx.spec.ts +++ b/packages/api/test/e2e/rx-tx.spec.ts @@ -11,50 +11,50 @@ import testingPairs from '@polkadot/keyring/testingPairs'; import Api from './../../src/rx'; import { SubmittableResult } from './../../src'; -describe.skip('Rx e2e transactions', () => { +describe.skip('Rx e2e transactions', (): void => { const keyring = testingPairs({ type: 'ed25519' }); let api: Api; - beforeEach(async (done) => { + beforeEach(async (done): Promise => { api = await Api.create().toPromise(); jest.setTimeout(30000); done(); }); - afterEach(() => { + afterEach((): void => { jest.setTimeout(5000); }); - it('makes a transfer', (done) => { + it('makes a transfer', (done): void => { (api.query.system.accountNonce(keyring.alice.address) as Observable) .pipe( first(), - switchMap((nonce: Index) => + switchMap((nonce: Index): Observable => api.tx.balances .transfer(keyring.bob.address, 12345) .sign(keyring.alice, { nonce }) .send() ) ) - .subscribe(({ status }: SubmittableResult) => { + .subscribe(({ status }: SubmittableResult): void => { if (status.isFinalized) { done(); } }); }); - it('makes a proposal', (done) => { + it('makes a proposal', (done): void => { (api.query.system.accountNonce(keyring.alice.address) as Observable) .pipe( first(), - switchMap((nonce: Index) => + switchMap((nonce: Index): Observable => api.tx.democracy .propose(api.tx.system.setCode('0xdeadbeef'), 10000) .sign(keyring.alice, { nonce }) .send() ) ) - .subscribe(({ status }: SubmittableResult) => { + .subscribe(({ status }: SubmittableResult): void => { if (status.isFinalized) { done(); } diff --git a/packages/api/test/util/SingleAccountSigner.ts b/packages/api/test/util/SingleAccountSigner.ts index a7ba79ec1d..bc529a49aa 100644 --- a/packages/api/test/util/SingleAccountSigner.ts +++ b/packages/api/test/util/SingleAccountSigner.ts @@ -12,11 +12,11 @@ let id = 0; export default class SingleAccountSigner { private keyringPair: KeyringPair; - constructor (keyringPair: KeyringPair) { + public constructor (keyringPair: KeyringPair) { this.keyringPair = keyringPair; } - async sign (extrinsic: Extrinsic, address: string, options: SignatureOptions) { + public async sign (extrinsic: Extrinsic, address: string, options: SignatureOptions): Promise { if (!this.keyringPair || String(address) !== this.keyringPair.address) { throw new Error('does not have the keyringPair'); } diff --git a/packages/rpc-core/src/cached.spec.ts b/packages/rpc-core/src/cached.spec.ts index a6d0ce564e..0418af92e0 100644 --- a/packages/rpc-core/src/cached.spec.ts +++ b/packages/rpc-core/src/cached.spec.ts @@ -8,43 +8,43 @@ import { AccountId } from '@polkadot/types'; import Rpc from '.'; -describe('Cached Observables', () => { +describe('Cached Observables', (): void => { let rpc: Rpc; const keyring = testingPairs(); - beforeEach(() => { + beforeEach((): void => { rpc = new Rpc(new MockProvider()); }); - it('creates a single observable for subscriptions (multiple calls)', () => { + it('creates a single observable for subscriptions (multiple calls)', (): void => { const observable1 = rpc.chain.subscribeNewHead(123); const observable2 = rpc.chain.subscribeNewHead(123); expect(observable2).toBe(observable1); }); - it('creates a single observable for subscriptions (multiple calls, no arguments)', () => { + it('creates a single observable for subscriptions (multiple calls, no arguments)', (): void => { const observable1 = rpc.chain.subscribeNewHead(); const observable2 = rpc.chain.subscribeNewHead(); expect(observable2).toBe(observable1); }); - it('creates a single observable (multiple calls, different arguments that should be cached together)', () => { + it('creates a single observable (multiple calls, different arguments that should be cached together)', (): void => { const observable1 = rpc.chain.subscribeNewHead(keyring.alice.address); const observable2 = rpc.chain.subscribeNewHead(new AccountId(keyring.alice.address)); expect(observable2).toBe(observable1); }); - it('creates multiple observables for different values', () => { + it('creates multiple observables for different values', (): void => { const observable1 = rpc.chain.subscribeNewHead(123); const observable2 = rpc.chain.subscribeNewHead(456); expect(observable2).not.toBe(observable1); }); - it('clears cache if there are no more subscribers', () => { + it('clears cache if there are no more subscribers', (): void => { const observable1 = rpc.chain.subscribeNewHead(); const observable2 = rpc.chain.subscribeNewHead(); @@ -62,14 +62,14 @@ describe('Cached Observables', () => { expect(observable3).not.toBe(observable1); }); - it('creates different observables for different methods but same arguments', () => { + it('creates different observables for different methods but same arguments', (): void => { const observable1 = rpc.chain.subscribeNewHead(123); const observable2 = rpc.state.subscribeStorage(123); expect(observable2).not.toBe(observable1); }); - it('creates multiple observables for one-shots', () => { + it('creates multiple observables for one-shots', (): void => { const observable1 = rpc.system.chain(123); const observable2 = rpc.system.chain(123); diff --git a/packages/rpc-core/src/formatting.spec.ts b/packages/rpc-core/src/formatting.spec.ts index 3f2df631bd..5c1d3364fd 100644 --- a/packages/rpc-core/src/formatting.spec.ts +++ b/packages/rpc-core/src/formatting.spec.ts @@ -22,23 +22,23 @@ const BALANCE_KEYS = [ ]; const OPTION_BYTES_HEX = '0x210100000000000000000000000000000000000000000000000000000000000000000000000000000000011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce'; -function formattingTests (version: string, storage: Storage, encodedValues: [string, string, string]) { +function formattingTests (version: string, storage: Storage, encodedValues: [string, string, string]): void { const [ENC_ONE, ENC_TWO, CONTRACT_KEY] = encodedValues; - describe(`formatting with Metadata ${version}`, () => { + describe(`formatting with Metadata ${version}`, (): void => { let api: Api; let provider: any; - beforeEach(() => { + beforeEach((): void => { provider = { - send: jest.fn((method, [key]) => + send: jest.fn((method, [key]): Promise => Promise.resolve( BALANCE_KEYS.includes(key) ? '0x01020000000000000000000000000000' : null ) ), - subscribe: jest.fn((type, method, params, cb) => { + subscribe: jest.fn((type, method, params, cb): void => { // this emulates https://github.com/polkadot-js/api/issues/1051 params[0][0] === CONTRACT_KEY ? cb(null, { @@ -60,10 +60,10 @@ function formattingTests (version: string, storage: Storage, encodedValues: [str api = new Api(provider); }); - it('encodes key (with params), decoding response', (done) => { + it('encodes key (with params), decoding response', (done): void => { api.state .getStorage([storage.balances.freeBalance, ADDR_ONE]) - .subscribe((value) => { + .subscribe((value): void => { expect( provider.send ).toHaveBeenCalledWith( @@ -75,22 +75,22 @@ function formattingTests (version: string, storage: Storage, encodedValues: [str }); }); - it('returns the fallback result on not-found values', (done) => { + it('returns the fallback result on not-found values', (done): void => { api.state .getStorage([storage.system.accountNonce, ADDR_ONE]) - .subscribe((value) => { + .subscribe((value): void => { expect(value.toHex()).toEqual('0x0000000000000000'); done(); }); }); - it('encodes multiple keys, decoding multiple results', (done) => { + it('encodes multiple keys, decoding multiple results', (done): void => { api.state.subscribeStorage( [ [storage.balances.freeBalance, ADDR_ONE], [storage.balances.freeBalance, ADDR_TWO] ] - ).subscribe((value: any) => { + ).subscribe((value: any): void => { console.error(value); expect( @@ -102,7 +102,7 @@ function formattingTests (version: string, storage: Storage, encodedValues: [str expect.anything() ); expect( - value.map((balance: BN) => + value.map((balance: BN): number => balance.toNumber() ) ).toEqual([0x0201, 0x0102]); @@ -111,11 +111,15 @@ function formattingTests (version: string, storage: Storage, encodedValues: [str }); }); - it('handles the case where Option are retrieved', (done) => { - let call = Number(version.slice(1)) <= 5 ? storage.contract.pristineCode : storage.contracts.pristineCode; + it('handles the case where Option are retrieved', (done): void => { + const call = Number(version.slice(1)) <= 5 + ? storage.contract.pristineCode + : storage.contracts.pristineCode; + api.state .subscribeStorage([[call, '0x00']]) - .subscribe((value: any) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + .subscribe((value: any): void => { // console.error(value); // expect(value.toHex()).toBe(OPTION_BYTES_HEX); diff --git a/packages/rpc-core/src/index.spec.ts b/packages/rpc-core/src/index.spec.ts index c866bc1de8..462ffe5360 100644 --- a/packages/rpc-core/src/index.spec.ts +++ b/packages/rpc-core/src/index.spec.ts @@ -6,18 +6,18 @@ import MockProvider from '@polkadot/rpc-provider/mock'; import Rpc from '.'; -describe('Api', () => { - it('requires a provider with a send method', () => { +describe('Api', (): void => { + it('requires a provider with a send method', (): void => { expect( - () => new Rpc({} as any) + (): Rpc => new Rpc({} as any) ).toThrow(/Expected Provider/); }); - it('creates an instance with all sections', () => { + it('creates an instance with all sections', (): void => { const rpc = new Rpc(new MockProvider()); expect( - Object.keys(rpc).filter((key) => !key.startsWith('_')) + Object.keys(rpc).filter((key): boolean => !key.startsWith('_')) ).toEqual([ 'provider', 'author', 'chain', 'state', 'system' diff --git a/packages/rpc-core/src/index.ts b/packages/rpc-core/src/index.ts index d308094b50..d4cbf65f4b 100644 --- a/packages/rpc-core/src/index.ts +++ b/packages/rpc-core/src/index.ts @@ -4,13 +4,13 @@ import { ProviderInterface } from '@polkadot/rpc-provider/types'; import { RpcSection, RpcMethod } from '@polkadot/jsonrpc/types'; -import { RpcInterface, RpcInterface$Method, RpcInterface$Section } from './types'; +import { AnyJson, Codec } from '@polkadot/types/types'; +import { RpcInterface, RpcInterfaceMethod, RpcInterfaceSection } from './types'; import memoize from 'memoizee'; import { combineLatest, from, Observable, Observer, of, throwError } from 'rxjs'; import { catchError, map, publishReplay, refCount, switchMap } from 'rxjs/operators'; import interfaces from '@polkadot/jsonrpc'; -import { Codec } from '@polkadot/types/types'; import { Option, StorageChangeSet, StorageData, StorageKey, Vector, createClass, createType } from '@polkadot/types'; import { ExtError, assert, isFunction, isNull, logger } from '@polkadot/util'; @@ -50,18 +50,23 @@ const EMPTY_META = { */ export default class Rpc implements RpcInterface { private _storageCache = new Map>(); - readonly provider: ProviderInterface; - readonly author: RpcInterface$Section; - readonly chain: RpcInterface$Section; - readonly state: RpcInterface$Section; - readonly system: RpcInterface$Section; + + public readonly provider: ProviderInterface; + + public readonly author: RpcInterfaceSection; + + public readonly chain: RpcInterfaceSection; + + public readonly state: RpcInterfaceSection; + + public readonly system: RpcInterfaceSection; /** * @constructor * Default constructor for the Api Object * @param {ProviderInterface} provider An API provider using HTTP or WebSocket */ - constructor (provider: ProviderInterface) { + public constructor (provider: ProviderInterface) { assert(provider && isFunction(provider.send), 'Expected Provider to API create'); this.provider = provider; @@ -87,8 +92,8 @@ export default class Rpc implements RpcInterface { * Api.signature({ name: 'test_method', params: [ { name: 'dest', type: 'Address' } ], type: 'Address' }); // => test_method (dest: Address): Address * ``` */ - static signature ({ method, params, type }: RpcMethod): string { - const inputs = params.map(({ name, type }) => + public static signature ({ method, params, type }: RpcMethod): string { + const inputs = params.map(({ name, type }): string => `${name}: ${type}` ).join(', '); @@ -98,19 +103,18 @@ export default class Rpc implements RpcInterface { /** * @description Manually disconnect from the attached provider */ - disconnect (): void { + public disconnect (): void { this.provider.disconnect(); } - private createErrorMessage (method: RpcMethod, error: Error) { + private createErrorMessage (method: RpcMethod, error: Error): string { return `${Rpc.signature(method)}:: ${error.message}`; } - private createInterface ({ methods }: RpcSection): RpcInterface$Section { + private createInterface ({ methods }: RpcSection): RpcInterfaceSection { return Object .keys(methods) - .reduce((exposed, methodName) => { - + .reduce((exposed, methodName): RpcInterfaceSection => { const def = methods[methodName]; exposed[methodName] = def.isSubscription @@ -118,13 +122,13 @@ export default class Rpc implements RpcInterface { : this.createMethodSend(def); return exposed; - }, {} as RpcInterface$Section); + }, {} as unknown as RpcInterfaceSection); } - private createMethodSend (method: RpcMethod): RpcInterface$Method { + private createMethodSend (method: RpcMethod): RpcInterfaceMethod { const rpcName = `${method.section}_${method.method}`; - const call = (...values: Array): Observable => { + const call = (...values: any[]): Observable => { // TODO Warn on deprecated methods // Here, logically, it should be `of(this.formatInputs(method, values))`. @@ -135,15 +139,15 @@ export default class Rpc implements RpcInterface { // - then do `map(()=>this.formatInputs)` - might throw, but inside Observable. return of(1) .pipe( - map(() => this.formatInputs(method, values)), - switchMap((params) => + map((): Codec[] => this.formatInputs(method, values)), + switchMap((params): Observable<[Codec[], any]> => combineLatest([ of(params), - from(this.provider.send(rpcName, params.map((param) => param.toJSON()))) + from(this.provider.send(rpcName, params.map((param): AnyJson => param.toJSON()))) ]) ), - map(([params, result]) => this.formatOutput(method, params, result)), - catchError((error) => { + map(([params, result]): any => this.formatOutput(method, params, result)), + catchError((error): any => { const message = this.createErrorMessage(method, error); l.error(message); @@ -158,23 +162,23 @@ export default class Rpc implements RpcInterface { // We voluntarily don't cache the "one-shot" RPC calls. For example, // `getStorage('123')` returns the current value, but this value can change // over time, so we wouldn't want to cache the Observable. - return call as RpcInterface$Method; + return call as RpcInterfaceMethod; } - private createMethodSubscribe (method: RpcMethod): RpcInterface$Method { + private createMethodSubscribe (method: RpcMethod): RpcInterfaceMethod { const [updateType, subMethod, unsubMethod] = method.pubsub; const subName = `${method.section}_${subMethod}`; const unsubName = `${method.section}_${unsubMethod}`; const subType = `${method.section}_${updateType}`; - const call = (...values: Array): Observable => { - return new Observable((observer: Observer) => { + const call = (...values: any[]): Observable => { + return new Observable((observer: Observer): VoidCallback => { let subscriptionPromise: Promise; try { const params = this.formatInputs(method, values); - const paramsJson = params.map((param) => param.toJSON()); - const update = (error?: Error, result?: any) => { + const paramsJson = params.map((param): AnyJson => param.toJSON()); + const update = (error?: Error, result?: any): void => { if (error) { l.error(this.createErrorMessage(method, error)); return; @@ -193,7 +197,7 @@ export default class Rpc implements RpcInterface { } // Teardown logic - return () => { + return (): void => { // Delete from cache // Reason: // ``` @@ -203,11 +207,14 @@ export default class Rpc implements RpcInterface { // api.query.system.accountNonce(addr1).subscribe(); // will output 6 instead of 7 if we don't clear cache // // that's because all our observables are replay(1) // ``` + // eslint-disable-next-line @typescript-eslint/no-use-before-define memoized.delete(...values); // Unsubscribe from provider subscriptionPromise - .then((subscriptionId) => this.provider.unsubscribe(subType, unsubName, subscriptionId)) - .catch((error: Error) => { + .then((subscriptionId): Promise => + this.provider.unsubscribe(subType, unsubName, subscriptionId) + ) + .catch((error: Error): void => { const message = this.createErrorMessage(method, error); l.error(message); @@ -231,20 +238,20 @@ export default class Rpc implements RpcInterface { return memoized; } - private formatInputs (method: RpcMethod, inputs: Array): Array { - const reqArgCount = method.params.filter(({ isOptional }) => !isOptional).length; + private formatInputs (method: RpcMethod, inputs: any[]): Codec[] { + const reqArgCount = method.params.filter(({ isOptional }): boolean => !isOptional).length; const optText = reqArgCount === method.params.length ? '' : ` (${method.params.length - reqArgCount} optional)`; assert(inputs.length >= reqArgCount && inputs.length <= method.params.length, `Expected ${method.params.length} parameters${optText}, ${inputs.length} found instead`); - return inputs.map((input, index) => + return inputs.map((input, index): Codec => createType(method.params[index].type, input) ); } - private formatOutput (method: RpcMethod, params: Array, result?: any): Codec | Array { + private formatOutput (method: RpcMethod, params: Codec[], result?: any): Codec | (Codec | null | undefined)[] { const base = createType(method.type as string, result); if (method.type === 'StorageData') { @@ -263,7 +270,7 @@ export default class Rpc implements RpcInterface { // - Base - There is a valid value, non-empty // - null - The storage key is empty (but in the resultset) // - undefined - The storage value is not in the resultset - return (params[0] as Vector).reduce((results, key: StorageKey) => { + return (params[0] as Vector).reduce((results, key: StorageKey): (Codec | undefined)[] => { try { results.push(this.formatStorageSet(key, base as StorageChangeSet)); } catch (error) { @@ -273,7 +280,7 @@ export default class Rpc implements RpcInterface { } return results; - }, [] as Array); + }, [] as (Codec | undefined)[]); } return base; @@ -305,7 +312,7 @@ export default class Rpc implements RpcInterface { // see if we have a result value for this specific key, fallback to the cache value // when the value in the set is not available, or is null/empty. - const { value } = base.changes.find(({ key, value }) => + const { value } = base.changes.find(({ key, value }): boolean => value.isSome && key.toHex() === hexKey ) || { value: this._storageCache.get(hexKey) || new Option(StorageData, null) }; diff --git a/packages/rpc-core/src/methodSend.spec.ts b/packages/rpc-core/src/methodSend.spec.ts index 15af2be7f4..375b50708f 100644 --- a/packages/rpc-core/src/methodSend.spec.ts +++ b/packages/rpc-core/src/methodSend.spec.ts @@ -4,12 +4,12 @@ import Rpc from '.'; -describe('methodSend', () => { +describe('methodSend', (): void => { let rpc: Rpc; let methods: any; let provider: any; - beforeEach(() => { + beforeEach((): void => { methods = { blah: { method: 'blah', @@ -28,7 +28,7 @@ describe('methodSend', () => { }; provider = { - send: jest.fn((method, params) => { + send: jest.fn((method, params): Promise => { return Promise.resolve(params[0]); }) }; @@ -36,37 +36,37 @@ describe('methodSend', () => { rpc = new Rpc(provider); }); - it('wraps errors with the call signature', (done) => { + it('wraps errors with the call signature', (done): void => { // @ts-ignore private method const method = rpc.createMethodSend(methods.blah); method().subscribe( - () => { /* noop */ }, - (error) => { + (): void => { /* noop */ }, + (error): void => { expect(error.message).toMatch(/blah \(foo: Bytes\): Bytes/); done(); } ); }); - it('checks for mismatched parameters', (done) => { + it('checks for mismatched parameters', (done): void => { // @ts-ignore private method const method = rpc.createMethodSend(methods.bleh); method(1).subscribe( - () => { /* noop */ }, - (error) => { + (): void => { /* noop */ }, + (error): void => { expect(error.message).toMatch(/parameters, 1 found instead/); done(); }); }); - it('calls the provider with the correct parameters', (done) => { + it('calls the provider with the correct parameters', (done): void => { // @ts-ignore private method const method = rpc.createMethodSend(methods.blah); // Args are length-prefixed, because it's a Bytes - method(new Uint8Array([2 << 2, 0x12, 0x34])).subscribe(() => { + method(new Uint8Array([2 << 2, 0x12, 0x34])).subscribe((): void => { expect(provider.send).toHaveBeenCalledWith('test_blah', ['0x1234']); done(); }); diff --git a/packages/rpc-core/src/replay.spec.ts b/packages/rpc-core/src/replay.spec.ts index 4640f7911b..0524d197c6 100644 --- a/packages/rpc-core/src/replay.spec.ts +++ b/packages/rpc-core/src/replay.spec.ts @@ -2,22 +2,22 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { of } from 'rxjs'; +import { Observable, of } from 'rxjs'; import MockProvider from '@polkadot/rpc-provider/mock'; import Rpc from '.'; -describe('replay', () => { +describe('replay', (): void => { let rpc: Rpc; - beforeEach(() => { + beforeEach((): void => { rpc = new Rpc(new MockProvider()); }); - it('subscribes via the rpc section', (done) => { - rpc.chain.getBlockHash = jest.fn(() => of(1)); + it('subscribes via the rpc section', (done): void => { + rpc.chain.getBlockHash = jest.fn((): Observable => of(1)); - rpc.chain.getBlockHash(123, false).subscribe(() => { + rpc.chain.getBlockHash(123, false).subscribe((): void => { expect( rpc.chain.getBlockHash ).toHaveBeenCalledWith(123, false); @@ -26,8 +26,8 @@ describe('replay', () => { }); }); - it('returns the observable value', (done) => { - rpc.system.chain().subscribe((value) => { + it('returns the observable value', (done): void => { + rpc.system.chain().subscribe((value: any): void => { if (value) { expect(value).toEqual('mockChain'); // Defined in MockProvider done(); @@ -35,27 +35,28 @@ describe('replay', () => { }); }); - it('replay(1) works as expected', (done) => { + it('replay(1) works as expected', (done): void => { const observable = rpc.system.chain(); let a: string | undefined; - observable.subscribe((value) => { a = value; }); + observable.subscribe((value: any): void => { a = value; }); - setTimeout(() => { + setTimeout((): void => { // Subscribe again to the same observable, it should fire value immediately - observable.subscribe((value) => { + observable.subscribe((value: any): void => { expect(value).toEqual(a); done(); }); }, 1000); }); - it('unsubscribes as required', (done) => { + it('unsubscribes as required', (done): void => { rpc.provider.unsubscribe = jest.fn(); - const subscription = rpc.chain.subscribeNewHead().subscribe(() => { + const subscription = rpc.chain.subscribeNewHead().subscribe((): void => { subscription.unsubscribe(); + // There's a promise inside .unsubscribe(), wait a bit - setTimeout(() => { + setTimeout((): void => { expect(rpc.provider.unsubscribe).toHaveBeenCalled(); done(); }, 200); diff --git a/packages/rpc-core/src/types.ts b/packages/rpc-core/src/types.ts index 1b5fd9f87a..295ae036e7 100644 --- a/packages/rpc-core/src/types.ts +++ b/packages/rpc-core/src/types.ts @@ -4,17 +4,15 @@ import { Observable } from 'rxjs'; -export interface RpcInterface$Method { - (...params: Array): Observable; +export interface RpcInterfaceMethod { + (...params: any[]): Observable; } -export type RpcInterface$Section = { - [index: string]: RpcInterface$Method -}; +export type RpcInterfaceSection = Record; export interface RpcInterface { - readonly author: RpcInterface$Section; - readonly chain: RpcInterface$Section; - readonly state: RpcInterface$Section; - readonly system: RpcInterface$Section; + readonly author: RpcInterfaceSection; + readonly chain: RpcInterfaceSection; + readonly state: RpcInterfaceSection; + readonly system: RpcInterfaceSection; } diff --git a/packages/rpc-core/test/e2e/alexander.spec.ts b/packages/rpc-core/test/e2e/alexander.spec.ts index d1acd7f67c..729d10f177 100644 --- a/packages/rpc-core/test/e2e/alexander.spec.ts +++ b/packages/rpc-core/test/e2e/alexander.spec.ts @@ -10,21 +10,21 @@ import Rpc from '../../src'; const randomAccount = '5HTqyWJHAVUieZnpb1V8gK4T1E4mnhkrUVSSzWBQd6kYgsVJ'; -describe.skip('e2e Alexander - Polkadot', () => { +describe.skip('e2e Alexander - Polkadot', (): void => { let rpc: Rpc; - beforeEach(() => { + beforeEach((): void => { jest.setTimeout(30000); rpc = new Rpc(new WsProvider('wss://poc3-rpc.polkadot.io/')); }); - it('subscribes to storage', (done) => { + it('subscribes to storage', (done): void => { rpc.state .subscribeStorage([ [storage.system.accountNonce, randomAccount], [storage.session.currentIndex] ]) - .subscribe((data: StorageChangeSet) => { + .subscribe((data: StorageChangeSet): void => { expect(data).toHaveLength(2); expect(data).toEqual( expect.arrayContaining([ @@ -37,20 +37,20 @@ describe.skip('e2e Alexander - Polkadot', () => { }); }); - it('retrieves a block by hash (krumme lanke #1)', (done) => { + it('retrieves a block by hash (krumme lanke #1)', (done): void => { rpc.chain .getBlock('0x627847bffdf5f3e01ac440d057dec6a37a12a6f329db7ef8367665574b76b5df') - .subscribe((block: SignedBlock) => { + .subscribe((block: SignedBlock): void => { expect(block).toBeDefined(); expect(block).toBeInstanceOf(SignedBlock); done(); }); }); - it('retrieves a block by hash (krumme lanke #2)', (done) => { + it('retrieves a block by hash (krumme lanke #2)', (done): void => { rpc.chain .getBlock('0x53416d53a4b1dfcae9165a89d193608e4aa770414f02267f5b2c4015a2e66091') - .subscribe((block: SignedBlock) => { + .subscribe((block: SignedBlock): void => { expect(block).toBeDefined(); expect(block).toBeInstanceOf(SignedBlock); done(); diff --git a/packages/rpc-core/test/e2e/basics.spec.ts b/packages/rpc-core/test/e2e/basics.spec.ts index 19a84ed014..a98e8cae53 100644 --- a/packages/rpc-core/test/e2e/basics.spec.ts +++ b/packages/rpc-core/test/e2e/basics.spec.ts @@ -7,27 +7,27 @@ import WsProvider from '@polkadot/rpc-provider/ws'; import Rpc from '../../src'; -describe.skip('e2e basics', () => { +describe.skip('e2e basics', (): void => { let rpc: Rpc; - beforeEach(() => { + beforeEach((): void => { jest.setTimeout(30000); rpc = new Rpc(new WsProvider('ws://127.0.0.1:9944')); }); - it('retrieves the pending extrinsics', (done) => { + it('retrieves the pending extrinsics', (done): void => { rpc.author .pendingExtrinsics() - .subscribe((extrinsics: PendingExtrinsics) => { + .subscribe((extrinsics: PendingExtrinsics): void => { expect(extrinsics).toBeInstanceOf(PendingExtrinsics); done(); }); }); - it('retrieves the system properties', (done) => { + it('retrieves the system properties', (done): void => { rpc.system .properties() - .subscribe((properties: ChainProperties) => { + .subscribe((properties: ChainProperties): void => { expect(properties).toBeInstanceOf(ChainProperties); console.log('properties', properties); done(); diff --git a/packages/rpc-core/test/e2e/chain.spec.ts b/packages/rpc-core/test/e2e/chain.spec.ts index 7f1e7f4651..b4d41522be 100644 --- a/packages/rpc-core/test/e2e/chain.spec.ts +++ b/packages/rpc-core/test/e2e/chain.spec.ts @@ -7,20 +7,20 @@ import WsProvider from '@polkadot/rpc-provider/ws'; import Rpc from '../../src'; -describe.skip('e2e chain', () => { +describe.skip('e2e chain', (): void => { let rpc: Rpc; - beforeEach(() => { + beforeEach((): void => { jest.setTimeout(30000); rpc = new Rpc(new WsProvider('ws://127.0.0.1:9944')); }); - it('subscribes via subscribeNewHead', (done) => { - let count: number = 0; + it('subscribes via subscribeNewHead', (done): void => { + let count = 0; rpc.chain .subscribeNewHead() - .subscribe((header: Header) => { + .subscribe((header: Header): void => { expect(header).toBeInstanceOf(Header); if (++count === 3) { @@ -29,10 +29,10 @@ describe.skip('e2e chain', () => { }); }); - it('retrieves the runtime version', (done) => { + it('retrieves the runtime version', (done): void => { rpc.chain .getRuntimeVersion() - .subscribe((version: RuntimeVersion) => { + .subscribe((version: RuntimeVersion): void => { expect(version).toBeInstanceOf(RuntimeVersion); done(); }); diff --git a/packages/rpc-core/test/e2e/state.spec.ts b/packages/rpc-core/test/e2e/state.spec.ts index 8663393a84..8ebdbcba4c 100644 --- a/packages/rpc-core/test/e2e/state.spec.ts +++ b/packages/rpc-core/test/e2e/state.spec.ts @@ -21,50 +21,50 @@ const ALICE = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; const CODE = '0x3a636f6465'; // :code const CHILD_STORAGE = '0x3a6368696c645f73746f726167653a'; // :child_storage: -describe.skip('e2e state', () => { +describe.skip('e2e state', (): void => { let rpc: Rpc; - beforeEach(() => { + beforeEach((): void => { jest.setTimeout(30000); rpc = new Rpc(new WsProvider('ws://127.0.0.1:9944')); }); - it('getMetadata(): retrieves the wasm metadata', (done) => { + it('getMetadata(): retrieves the wasm metadata', (done): void => { rpc.state .getMetadata() - .subscribe((meta: Metadata) => { + .subscribe((meta: Metadata): void => { console.error(JSON.stringify(meta.toJSON())); done(); }); }); - it('getKeys(): retrieves storage keys for ":code"', (done) => { + it('getKeys(): retrieves storage keys for ":code"', (done): void => { rpc.state .getKeys(CODE) - .subscribe((keys: Array) => { + .subscribe((keys: StorageKey[]): void => { expect(keys.length).toEqual(1); done(); }); }); - describe('test-suite getStorage()', () => { - it('retrieves code', (done) => { + describe('test-suite getStorage()', (): void => { + it('retrieves code', (done): void => { rpc.state .getStorage([ storage.substrate.code ]) - .subscribe((code: Bytes) => { + .subscribe((code: Bytes): void => { console.error(code.toHex().substr(0, 256), '...'); done(); }); }); - it('retrieves balances', (done) => { + it('retrieves balances', (done): void => { rpc.state .getStorage([ storage.balances.freeBalance, ALICE ]) - .subscribe((balance: Balance) => { + .subscribe((balance: Balance): void => { console.error(balance); expect(balance.isZero()).not.toEqual(true); @@ -72,12 +72,12 @@ describe.skip('e2e state', () => { }); }); - it('retrieves timestamp', (done) => { + it('retrieves timestamp', (done): void => { rpc.state .getStorage([ storage.timestamp.now ]) - .subscribe((moment: Moment) => { + .subscribe((moment: Moment): void => { console.error(moment); expect(moment.toNumber()).not.toEqual(0); @@ -86,22 +86,20 @@ describe.skip('e2e state', () => { }); }); - describe('e2e state child methods', () => { + describe('e2e state child methods', (): void => { // `child_storage` is currently not used anywhere in substrate, that's why we need to // add a Smart Contract that is using `child_storage` before being able to test it. let codeHash: Hash; - beforeAll(async (done) => { + beforeAll(async (done): Promise => { const code: string = fs.readFileSync(path.join(__dirname, '../../../api-contract/test/contracts/flipper-pruned.wasm')).toString('hex'); const abi = new Abi(flipperAbi); const apiPromise: ApiPromise = await ApiPromise.create(new WsProvider('ws://127.0.0.1:9944')); - const keyring: { - [index: string]: KeyringPair - } = testingPairs({ type: 'sr25519' }); + const keyring: Record = testingPairs({ type: 'sr25519' }); const putCode = apiPromise.tx.contract .putCode(50000, `0x${code}`) - .signAndSend(keyring.eve, (result: SubmittableResult) => { + .signAndSend(keyring.eve, (result: SubmittableResult): void => { if (result.status.isFinalized) { const record = result.findRecord('contract', 'CodeStored'); @@ -109,58 +107,60 @@ describe.skip('e2e state', () => { codeHash = record.event.data[0] as Hash; } } + done(); }); - return putCode.then(() => { + return putCode.then((): Promise => { return apiPromise.tx.contract .create(12345, 50000, codeHash, abi.deploy()) .signAndSend(keyring.bob); }); }); - it('getChildKeys(): retrieves :child_storage: keys for one deployed flipper contract', async (done) => { + it('getChildKeys(): retrieves :child_storage: keys for one deployed flipper contract', async (done): + Promise => { const storageKeys = await rpc.state.getKeys(CHILD_STORAGE).toPromise(); rpc.state .getChildKeys(storageKeys[0], '0x') - .subscribe((keys: Array) => { + .subscribe((keys: StorageKey[]): void => { expect(keys.length).toBeGreaterThanOrEqual(1); done(); }); }); - it('getChildStorage(): retrieves the default value of the flipper smart contract', async (done) => { + it('getChildStorage(): retrieves the default value of the flipper smart contract', async (done): Promise => { const storageKeys = await rpc.state.getKeys(CHILD_STORAGE).toPromise(); const childStorageKeys = await rpc.state.getChildKeys(storageKeys[0], '0x').toPromise(); rpc.state .getChildStorage(storageKeys[0], childStorageKeys[0]) - .subscribe((storage: StorageData) => { + .subscribe((storage: StorageData): void => { expect(storage.toString()).toBe('0x00'); done(); }); }); - it('getChildStorageHash(): retrieves the Hash of the flipper smart contract', async (done) => { + it('getChildStorageHash(): retrieves the Hash of the flipper smart contract', async (done): Promise => { const storageKeys = await rpc.state.getKeys(CHILD_STORAGE).toPromise(); const childStorageKeys = await rpc.state.getChildKeys(storageKeys[0], '0x').toPromise(); rpc.state .getChildStorageHash(storageKeys[0], childStorageKeys[0]) - .subscribe((storage: StorageData) => { + .subscribe((storage: StorageData): void => { expect(storage.toString()).toBe('0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314'); done(); }); }); - it('getChildStorageSize(): retrieves the size of the flipper smart contract', async (done) => { + it('getChildStorageSize(): retrieves the size of the flipper smart contract', async (done): Promise => { const storageKeys = await rpc.state.getKeys(CHILD_STORAGE).toPromise(); const childStorageKeys = await rpc.state.getChildKeys(storageKeys[0], '0x').toPromise(); rpc.state .getChildStorageSize(storageKeys[0], childStorageKeys[0]) - .subscribe((storage: StorageData) => { + .subscribe((storage: StorageData): void => { expect(storage.toString()).toBe('1'); done(); }); diff --git a/packages/rpc-core/test/e2e/subscribe.spec.ts b/packages/rpc-core/test/e2e/subscribe.spec.ts index 82a88faa97..494d7ee5b9 100644 --- a/packages/rpc-core/test/e2e/subscribe.spec.ts +++ b/packages/rpc-core/test/e2e/subscribe.spec.ts @@ -8,20 +8,20 @@ import storage from '@polkadot/api-metadata/storage/static'; import Rpc from '../../src'; -describe.skip('e2e subscriptions', () => { +describe.skip('e2e subscriptions', (): void => { let rpc: Rpc; - beforeEach(() => { + beforeEach((): void => { jest.setTimeout(30000); rpc = new Rpc(new WsProvider('ws://127.0.0.1:9944')); }); - it('retrieves current timestamp', (done) => { - let count: number = 0; + it('retrieves current timestamp', (done): void => { + let count = 0; rpc.state .subscribeStorage([[storage.timestamp.now]]) - .subscribe((data: StorageChangeSet) => { + .subscribe((data: StorageChangeSet): void => { expect(data).toBeDefined(); if (++count === 3) { diff --git a/packages/rpc-provider/src/coder/decodeResponse.spec.ts b/packages/rpc-provider/src/coder/decodeResponse.spec.ts index 30e7d09b48..d4fe1e6fcf 100644 --- a/packages/rpc-provider/src/coder/decodeResponse.spec.ts +++ b/packages/rpc-provider/src/coder/decodeResponse.spec.ts @@ -5,46 +5,46 @@ import { JsonRpcResponse } from '../types'; import Coder from './'; -describe('decodeResponse', () => { +describe('decodeResponse', (): void => { let coder: Coder; - beforeEach(() => { + beforeEach((): void => { coder = new Coder(); }); - it('expects a non-empty input object', () => { + it('expects a non-empty input object', (): void => { expect( - () => coder.decodeResponse((undefined as any) as JsonRpcResponse) + (): any => coder.decodeResponse((undefined as any) as JsonRpcResponse) ).toThrow(/Empty response/); }); - it('expects a valid jsonrpc field', () => { + it('expects a valid jsonrpc field', (): void => { expect( - () => coder.decodeResponse({} as JsonRpcResponse) + (): any => coder.decodeResponse({} as unknown as JsonRpcResponse) ).toThrow(/Invalid jsonrpc/); }); - it('expects a valid id field', () => { + it('expects a valid id field', (): void => { expect( - () => coder.decodeResponse({ jsonrpc: '2.0' } as JsonRpcResponse) + (): any => coder.decodeResponse({ jsonrpc: '2.0' } as unknown as JsonRpcResponse) ).toThrow(/Invalid id/); }); - it('expects a valid result field', () => { + it('expects a valid result field', (): void => { expect( - () => coder.decodeResponse({ id: 1, jsonrpc: '2.0' } as JsonRpcResponse) + (): any => coder.decodeResponse({ id: 1, jsonrpc: '2.0' } as unknown as JsonRpcResponse) ).toThrow(/No result/); }); - it('throws any error found', () => { + it('throws any error found', (): void => { expect( - () => coder.decodeResponse({ id: 1, jsonrpc: '2.0', error: { code: 123, message: 'test error' } } as JsonRpcResponse) + (): any => coder.decodeResponse({ id: 1, jsonrpc: '2.0', error: { code: 123, message: 'test error' } } as unknown as JsonRpcResponse) ).toThrow(/123: test error/); }); - it('returns the result', () => { + it('returns the result', (): void => { expect( - coder.decodeResponse({ id: 1, jsonrpc: '2.0', result: 'some result' } as JsonRpcResponse) + coder.decodeResponse({ id: 1, jsonrpc: '2.0', result: 'some result' } as unknown as JsonRpcResponse) ).toEqual('some result'); }); }); diff --git a/packages/rpc-provider/src/coder/encodeJson.spec.ts b/packages/rpc-provider/src/coder/encodeJson.spec.ts index ffdc5e76ff..b513025e4c 100644 --- a/packages/rpc-provider/src/coder/encodeJson.spec.ts +++ b/packages/rpc-provider/src/coder/encodeJson.spec.ts @@ -4,14 +4,14 @@ import Coder from './'; -describe('encodeJson', () => { +describe('encodeJson', (): void => { let coder: Coder; - beforeEach(() => { + beforeEach((): void => { coder = new Coder(); }); - it('encodes a valid JsonRPC JSON string', () => { + it('encodes a valid JsonRPC JSON string', (): void => { expect( coder.encodeJson('method', 'params') ).toEqual('{"id":1,"jsonrpc":"2.0","method":"method","params":"params"}'); diff --git a/packages/rpc-provider/src/coder/encodeObject.spec.ts b/packages/rpc-provider/src/coder/encodeObject.spec.ts index 5d3b425560..e52f4170bd 100644 --- a/packages/rpc-provider/src/coder/encodeObject.spec.ts +++ b/packages/rpc-provider/src/coder/encodeObject.spec.ts @@ -4,18 +4,18 @@ import Coder from './'; -describe('encodeObject', () => { +describe('encodeObject', (): void => { let coder: Coder; - beforeEach(() => { + beforeEach((): void => { coder = new Coder(); }); - it('starts with id === 0 (nothing sent)', () => { + it('starts with id === 0 (nothing sent)', (): void => { expect(coder.getId()).toEqual(0); }); - it('encodes a valid JsonRPC object', () => { + it('encodes a valid JsonRPC object', (): void => { expect( coder.encodeObject('method', 'params') ).toEqual({ diff --git a/packages/rpc-provider/src/coder/index.ts b/packages/rpc-provider/src/coder/index.ts index 1a00b9caf7..7e7f6544c1 100644 --- a/packages/rpc-provider/src/coder/index.ts +++ b/packages/rpc-provider/src/coder/index.ts @@ -2,14 +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 { JsonRpcRequest, JsonRpcResponse, JsonRpcResponseBase$Error } from '../types'; +import { JsonRpcRequest, JsonRpcResponse, JsonRpcResponseBaseError } from '../types'; import { assert, isUndefined, isNumber } from '@polkadot/util'; export default class RpcCoder { private id: number = 0; - decodeResponse (response: JsonRpcResponse): any { + public decodeResponse (response: JsonRpcResponse): any { assert(response, 'Empty response object received'); assert(response.jsonrpc === '2.0', 'Invalid jsonrpc field in decoded object'); @@ -30,13 +30,13 @@ export default class RpcCoder { return response.result; } - encodeJson (method: string, params: any | Array): string { + public encodeJson (method: string, params: any | any[]): string { return JSON.stringify( this.encodeObject(method, params) ); } - encodeObject (method: string, params: any | Array): JsonRpcRequest { + public encodeObject (method: string, params: any | any[]): JsonRpcRequest { return { id: ++this.id, jsonrpc: '2.0', @@ -45,16 +45,16 @@ export default class RpcCoder { }; } - getId (): number { + public getId (): number { return this.id; } - private checkError (error?: JsonRpcResponseBase$Error): void { + private checkError (error?: JsonRpcResponseBaseError): void { if (error) { const { code, data, message } = error; const _data = isUndefined(data) ? '' - : ' (' + `${data}`.substr(0, 10) + ')' ; + : ' (' + `${data}`.substr(0, 10) + ')'; console.error(`${code}: ${message}${_data}`); diff --git a/packages/rpc-provider/src/http/index.spec.ts b/packages/rpc-provider/src/http/index.spec.ts index 78fd4bb090..5085e1caf1 100644 --- a/packages/rpc-provider/src/http/index.spec.ts +++ b/packages/rpc-provider/src/http/index.spec.ts @@ -5,37 +5,39 @@ import { TEST_HTTP_URL } from '../../test/mockHttp'; import Http from './'; -describe('Http', () => { +describe('Http', (): void => { let http: Http; - beforeEach(() => { + beforeEach((): void => { http = new Http(TEST_HTTP_URL); }); - it('requires an http:// prefixed endpoint', () => { + it('requires an http:// prefixed endpoint', (): void => { expect( - () => new Http('ws://') + (): Http => new Http('ws://') ).toThrow(/with 'http/); }); - it('allows https:// endpoints', () => { + it('allows https:// endpoints', (): void => { expect( - () => new Http('https://') + (): Http => new Http('https://') ).not.toThrow(); }); - it('always returns isConnected true', () => { + it('always returns isConnected true', (): void => { expect(http.isConnected()).toEqual(true); }); - it('does not (yet) support subscribe', () => { - return http.subscribe('', '', [], (cb) => { expect(cb).toEqual(expect.anything()); }).catch((error) => { + it('does not (yet) support subscribe', (): Promise => { + return http.subscribe('', '', [], (cb): void => { + expect(cb).toEqual(expect.anything()); + }).catch((error): void => { expect(error.message).toMatch(/does not have subscriptions/); }); }); - it('does not (yet) support unsubscribe', () => { - return http.unsubscribe('', '', 0).catch((error) => { + it('does not (yet) support unsubscribe', (): Promise => { + return http.unsubscribe('', '', 0).catch((error): void => { expect(error.message).toMatch(/does not have subscriptions/); }); }); diff --git a/packages/rpc-provider/src/http/index.ts b/packages/rpc-provider/src/http/index.ts index 2b9d35c3e2..60466dbff4 100644 --- a/packages/rpc-provider/src/http/index.ts +++ b/packages/rpc-provider/src/http/index.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { ProviderInterface, ProviderInterface$Callback, ProviderInterface$Emitted, ProviderInterface$EmitCb } from '../types'; +import { ProviderInterface, ProviderInterfaceCallback, ProviderInterfaceEmitted, ProviderInterfaceEmitCb } from '../types'; import './polyfill'; @@ -37,12 +37,13 @@ const l = logger('api-http'); */ export default class HttpProvider implements ProviderInterface { private coder: Coder; + private endpoint: string; /** * @param {string} endpoint The endpoint url starting with http:// */ - constructor (endpoint: string = defaults.HTTP_URL) { + public constructor (endpoint: string = defaults.HTTP_URL) { assert(/^(https|http):\/\//.test(endpoint), `Endpoint should start with 'http://', received '${endpoint}'`); this.coder = new Coder(); @@ -52,21 +53,21 @@ export default class HttpProvider implements ProviderInterface { /** * @summary `true` when this provider supports subscriptions */ - get hasSubscriptions (): boolean { + public get hasSubscriptions (): boolean { return false; } /** * @description Returns a clone of the object */ - clone (): HttpProvider { + public clone (): HttpProvider { throw new Error('Unimplemented'); } /** * @description Manually disconnect from the connection */ - disconnect (): void { + public disconnect (): void { // noop } @@ -74,7 +75,7 @@ export default class HttpProvider implements ProviderInterface { * @summary Whether the node is connected or not. * @return {boolean} true if connected */ - isConnected (): boolean { + public isConnected (): boolean { return true; } @@ -82,19 +83,20 @@ export default class HttpProvider implements ProviderInterface { * @summary Events are not supported with the HttpProvider, see [[WsProvider]]. * @description HTTP Provider does not have 'on' emitters. WebSockets should be used instead. */ - on (type: ProviderInterface$Emitted, sub: ProviderInterface$EmitCb): void { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public on (type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): void { l.error(`HTTP Provider does not have 'on' emitters, use WebSockets instead`); } /** * @summary Send HTTP POST Request with Body to configured HTTP Endpoint. */ - async send (method: string, params: Array): Promise { + public async send (method: string, params: any[]): Promise { const body = this.coder.encodeJson(method, params); const response = await fetch(this.endpoint, { body, headers: { - 'Accept': 'application/json', + Accept: 'application/json', 'Content-Length': `${body.length}`, 'Content-Type': 'application/json' }, @@ -111,7 +113,8 @@ export default class HttpProvider implements ProviderInterface { /** * @summary Subscriptions are not supported with the HttpProvider, see [[WsProvider]]. */ - async subscribe (types: string, method: string, params: Array, cb: ProviderInterface$Callback): Promise { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public async subscribe (types: string, method: string, params: any[], cb: ProviderInterfaceCallback): Promise { l.error(ERROR_SUBSCRIBE); throw new Error(ERROR_SUBSCRIBE); @@ -120,7 +123,8 @@ export default class HttpProvider implements ProviderInterface { /** * @summary Subscriptions are not supported with the HttpProvider, see [[WsProvider]]. */ - async unsubscribe (type: string, method: string, id: number): Promise { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public async unsubscribe (type: string, method: string, id: number): Promise { l.error(ERROR_SUBSCRIBE); throw new Error(ERROR_SUBSCRIBE); diff --git a/packages/rpc-provider/src/http/polyfill.spec.ts b/packages/rpc-provider/src/http/polyfill.spec.ts index da4c254cfc..71261225eb 100644 --- a/packages/rpc-provider/src/http/polyfill.spec.ts +++ b/packages/rpc-provider/src/http/polyfill.spec.ts @@ -6,26 +6,26 @@ import { Global } from './../mock/types'; declare const global: Global; -describe('http/polyfill', () => { +describe('http/polyfill', (): void => { let origFetch: GlobalFetch; - beforeEach(() => { + beforeEach((): void => { origFetch = global.fetch; }); - afterEach(() => { + afterEach((): void => { global.fetch = origFetch; }); - it('polyfills with no exceptions (without fetch)', () => { + it('polyfills with no exceptions (without fetch)', (): void => { (global as any).fetch = undefined; require('./polyfill'); expect(global.fetch).toBeDefined(); }); - it('polyfills with no exceptions (with fetch)', () => { - (global as any).fetch = () => true; + it('polyfills with no exceptions (with fetch)', (): void => { + (global as any).fetch = (): boolean => true; require('./polyfill'); expect(global.fetch).toBeDefined(); diff --git a/packages/rpc-provider/src/http/send.spec.ts b/packages/rpc-provider/src/http/send.spec.ts index 985b955e55..7528bec8b4 100644 --- a/packages/rpc-provider/src/http/send.spec.ts +++ b/packages/rpc-provider/src/http/send.spec.ts @@ -6,21 +6,21 @@ import Http from './'; import { Mock } from './../mock/types'; import { mockHttp, TEST_HTTP_URL } from '../../test/mockHttp'; -describe('send', () => { +describe('send', (): void => { let http: Http; let mock: Mock; - beforeEach(() => { + beforeEach((): void => { http = new Http(TEST_HTTP_URL); }); - afterEach(() => { + afterEach((): void => { if (mock) { mock.done(); } }); - it('passes the body through correctly', () => { + it('passes the body through correctly', (): Promise => { mock = mockHttp([{ method: 'test_body', reply: { @@ -30,7 +30,7 @@ describe('send', () => { return http .send('test_body', ['param']) - .then((result) => { + .then((): void => { expect((mock.body as any)['test_body']).toEqual({ id: 1, jsonrpc: '2.0', @@ -40,7 +40,7 @@ describe('send', () => { }); }); - it('throws error when !response.ok', () => { + it('throws error when !response.ok', (): Promise => { mock = mockHttp([{ code: 500, method: 'test_error' @@ -48,7 +48,7 @@ describe('send', () => { return http .send('test_error', []) - .catch((error) => { + .catch((error): void => { expect(error.message).toMatch(/\[500\]: Internal Server/); }); }); diff --git a/packages/rpc-provider/src/http/types.ts b/packages/rpc-provider/src/http/types.ts index 36d468be57..11b20b1bf8 100644 --- a/packages/rpc-provider/src/http/types.ts +++ b/packages/rpc-provider/src/http/types.ts @@ -6,8 +6,8 @@ import { Logger } from '@polkadot/util/types'; import Coder from '../coder'; -export type HttpState = { - coder: Coder, - endpoint: string, - l: Logger -}; +export interface HttpState { + coder: Coder; + endpoint: string; + l: Logger; +} diff --git a/packages/rpc-provider/src/mock/index.ts b/packages/rpc-provider/src/mock/index.ts index fd60096e58..7428d3ab6d 100644 --- a/packages/rpc-provider/src/mock/index.ts +++ b/packages/rpc-provider/src/mock/index.ts @@ -1,9 +1,10 @@ +/* eslint-disable @typescript-eslint/camelcase */ // Copyright 2017-2019 @polkadot/rpc-provider 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 { ProviderInterface, ProviderInterface$Emitted, ProviderInterface$EmitCb } from '../types'; -import { MockState$Subscriptions, MockState$Subscription$Callback, MockState$Db } from './types'; +import { ProviderInterface, ProviderInterfaceEmitted, ProviderInterfaceEmitCb } from '../types'; +import { MockStateSubscriptions, MockStateSubscriptionCallback, MockStateDb } from './types'; import BN from 'bn.js'; import EventEmitter from 'eventemitter3'; @@ -18,13 +19,13 @@ import { randomAsU8a } from '@polkadot/util-crypto'; const INTERVAL = 1000; const SUBSCRIPTIONS: string[] = Array.prototype.concat.apply( - [], Object.values(interfaces).map((area) => + [], Object.values(interfaces).map((area): string[] => Object .values(area.methods) - .filter((method) => + .filter((method): boolean => method.isSubscription ) - .map(({ method, section }) => + .map(({ method, section }): string => `${section}_${method}` ) ) @@ -38,60 +39,65 @@ const l = logger('api-mock'); * @return {ProviderInterface} The mock provider */ export default class Mock implements ProviderInterface { - private db: MockState$Db = {}; + private db: MockStateDb = {}; + private emitter = new EventEmitter(); + public isUpdating: boolean = true; - private requests: { [index: string]: (...params: any[]) => string } = { - 'chain_getBlockHash': (blockNumber: number): string => '0x1234', - 'chain_getRuntimeVersion': (): string => new RuntimeVersion().toHex(), - 'state_getStorage': (storage: MockState$Db, params: Array): string => { + + private requests: Record string> = { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + chain_getBlockHash: (blockNumber: number): string => '0x1234', + chain_getRuntimeVersion: (): string => new RuntimeVersion().toHex(), + state_getStorage: (storage: MockStateDb, params: any[]): string => { return u8aToHex( storage[(params[0] as string)] ); }, - 'system_chain': (): string => 'mockChain', - 'state_getMetadata': (): string => rpcMetadataV6, - 'system_name': (): string => 'mockClient', - 'system_version': (): string => '9.8.7' + system_chain: (): string => 'mockChain', + state_getMetadata: (): string => rpcMetadataV6, + system_name: (): string => 'mockClient', + system_version: (): string => '9.8.7' }; - public subscriptions: MockState$Subscriptions = SUBSCRIPTIONS.reduce((subs, name) => { + + public subscriptions: MockStateSubscriptions = SUBSCRIPTIONS.reduce((subs, name): MockStateSubscriptions => { subs[name] = { callbacks: {}, lastValue: null }; return subs; - }, ({} as MockState$Subscriptions)); - private subscriptionId: number = 0; - private subscriptionMap: { - [index: number]: string - } = {}; + }, ({} as unknown as MockStateSubscriptions)); - constructor () { + private subscriptionId: number = 0; + + private subscriptionMap: Record = {}; + + public constructor () { this.init(); } - get hasSubscriptions (): boolean { + public get hasSubscriptions (): boolean { return true; } - clone (): Mock { + public clone (): Mock { throw new Error('Unimplemented'); } - disconnect (): void { + public disconnect (): void { // noop } - isConnected (): boolean { + public isConnected (): boolean { return true; } - on (type: ProviderInterface$Emitted, sub: ProviderInterface$EmitCb): void { + public on (type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): void { this.emitter.on(type, sub); } - async send (method: string, params: Array): Promise { + public async send (method: string, params: any[]): Promise { if (!this.requests[method]) { throw new Error(`provider.send: Invalid method '${method}'`); } @@ -99,11 +105,11 @@ export default class Mock implements ProviderInterface { return this.requests[method](this.db, params); } - async subscribe (type: string, method: string, ...params: Array): Promise { - l.debug(() => ['subscribe', method, params]); + public async subscribe (type: string, method: string, ...params: any[]): Promise { + l.debug((): any => ['subscribe', method, params]); if (this.subscriptions[method]) { - const callback: MockState$Subscription$Callback = params.pop(); + const callback: MockStateSubscriptionCallback = params.pop(); const id = ++this.subscriptionId; this.subscriptions[method].callbacks[id] = callback; @@ -119,10 +125,10 @@ export default class Mock implements ProviderInterface { throw new Error(`provider.subscribe: Invalid method '${method}'`); } - async unsubscribe (type: string, method: string, id: number): Promise { + public async unsubscribe (type: string, method: string, id: number): Promise { const sub = this.subscriptionMap[id]; - l.debug(() => ['unsubscribe', id, sub]); + l.debug((): any => ['unsubscribe', id, sub]); if (!sub) { throw new Error(`Unable to find subscription for ${id}`); @@ -134,14 +140,14 @@ export default class Mock implements ProviderInterface { return true; } - private init () { - const emitEvents: Array = ['connected', 'disconnected']; + private init (): void { + const emitEvents: ProviderInterfaceEmitted[] = ['connected', 'disconnected']; let emitIndex = 0; let newHead = this.makeBlockHeader(new BN(-1)); let counter = -1; // Do something every 1 seconds - setInterval(() => { + setInterval((): void => { if (!this.isUpdating) { return; } @@ -150,7 +156,7 @@ export default class Mock implements ProviderInterface { newHead = this.makeBlockHeader(newHead.blockNumber.toBn()); // increment the balances and nonce for each account - keyring.getPairs().forEach(({ publicKey }, index) => { + keyring.getPairs().forEach(({ publicKey }, index): void => { this.setStateBn(storage.balances.freeBalance(publicKey), newHead.blockNumber.muln(3).iaddn(index)); this.setStateBn(storage.system.accountNonce(publicKey), newHead.blockNumber.addn(index)); }); @@ -190,12 +196,12 @@ export default class Mock implements ProviderInterface { this.db[u8aToHex(key)] = bnToU8a(value, 64, true); } - private updateSubs (method: string, value: Codec) { + private updateSubs (method: string, value: Codec): void { this.subscriptions[method].lastValue = value; Object .values(this.subscriptions[method].callbacks) - .forEach((cb) => { + .forEach((cb): void => { try { cb(null, value.toJSON()); } catch (error) { diff --git a/packages/rpc-provider/src/mock/on.spec.ts b/packages/rpc-provider/src/mock/on.spec.ts index c33ef5d1e9..e071e5aa91 100644 --- a/packages/rpc-provider/src/mock/on.spec.ts +++ b/packages/rpc-provider/src/mock/on.spec.ts @@ -2,24 +2,24 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { ProviderInterface$Emitted } from '../types'; +import { ProviderInterfaceEmitted } from '../types'; import Mock from './'; -describe('on', () => { +describe('on', (): void => { let mock: Mock; - beforeEach(() => { + beforeEach((): void => { mock = new Mock(); }); - it('it emits both connected and disconnected events', (done) => { - const events: { [index: string]: boolean } = { connected: false, disconnected: false }; - const handler = (type: ProviderInterface$Emitted) => { - mock.on(type, () => { + it('it emits both connected and disconnected events', (done): void => { + const events: Record = { connected: false, disconnected: false }; + const handler = (type: ProviderInterfaceEmitted): void => { + mock.on(type, (): void => { events[type] = true; - if (Object.values(events).filter((value) => value).length === 2) { + if (Object.values(events).filter((value): boolean => value).length === 2) { done(); } }); diff --git a/packages/rpc-provider/src/mock/send.spec.ts b/packages/rpc-provider/src/mock/send.spec.ts index e720cb2ab8..5afa2e373b 100644 --- a/packages/rpc-provider/src/mock/send.spec.ts +++ b/packages/rpc-provider/src/mock/send.spec.ts @@ -4,25 +4,25 @@ import Mock from './'; -describe('send', () => { +describe('send', (): void => { let mock: Mock; - beforeEach(() => { + beforeEach((): void => { mock = new Mock(); }); - it('fails on non-supported methods', () => { + it('fails on non-supported methods', (): Promise => { return mock .send('something_invalid', []) - .catch((error) => { + .catch((error): void => { expect(error.message).toMatch(/Invalid method/); }); }); - it('returns values for mocked requests', () => { + it('returns values for mocked requests', (): Promise => { return mock .send('system_name', []) - .then((result) => { + .then((result): void => { expect(result).toBe('mockClient'); }); }); diff --git a/packages/rpc-provider/src/mock/subscribe.spec.ts b/packages/rpc-provider/src/mock/subscribe.spec.ts index dce16250da..f9246906bc 100644 --- a/packages/rpc-provider/src/mock/subscribe.spec.ts +++ b/packages/rpc-provider/src/mock/subscribe.spec.ts @@ -4,51 +4,51 @@ import Mock from './'; -describe('subscribe', () => { +describe('subscribe', (): void => { let mock: Mock; - beforeEach(() => { + beforeEach((): void => { mock = new Mock(); }); - it('fails on unknown methods', () => { + it('fails on unknown methods', (): Promise => { return mock .subscribe('test', 'test_notFound') - .catch((error) => { + .catch((error): void => { expect(error.message).toMatch(/Invalid method 'test_notFound'/); }); }); - it('returns a subscription id', () => { + it('returns a subscription id', (): Promise => { return mock - .subscribe('chain_newHead', 'chain_subscribeNewHead', () => void 0) - .then((id) => { + .subscribe('chain_newHead', 'chain_subscribeNewHead', (): void => void 0) + .then((id): void => { expect(id).toEqual(1); }); }); - it('calls back with the last known value', (done) => { + it('calls back with the last known value', (done): Promise => { mock.isUpdating = false; mock.subscriptions['chain_subscribeNewHead'].lastValue = 'testValue'; - return mock.subscribe('chain_newHead', 'chain_subscribeNewHead', (_: any, value: string) => { + return mock.subscribe('chain_newHead', 'chain_subscribeNewHead', (_: any, value: string): void => { expect(value).toEqual('testValue'); done(); }); }); - it('calls back with new headers', (done) => { - return mock.subscribe('chain_newHead', 'chain_subscribeNewHead', (_: any, header: any) => { + it('calls back with new headers', (done): Promise => { + return mock.subscribe('chain_newHead', 'chain_subscribeNewHead', (_: any, header: any): void => { if (header.number === 4) { done(); } }); }); - it('handles errors withing callbacks gracefully', (done) => { - let hasThrown: boolean = false; + it('handles errors withing callbacks gracefully', (done): Promise => { + let hasThrown = false; - return mock.subscribe('chain_newHead', 'chain_subscribeNewHead', (_: any, header: any) => { + return mock.subscribe('chain_newHead', 'chain_subscribeNewHead', (_: any, header: any): void => { if (!hasThrown) { hasThrown = true; diff --git a/packages/rpc-provider/src/mock/types.ts b/packages/rpc-provider/src/mock/types.ts index ff8ba7d9fb..9732b5d311 100644 --- a/packages/rpc-provider/src/mock/types.ts +++ b/packages/rpc-provider/src/mock/types.ts @@ -10,28 +10,20 @@ export interface Global extends NodeJS.Global { fetch: GlobalFetch; } -export type Mock = { - body: Object, - requests: Number, - server: Server - done: () => {} -}; +export interface Mock { + body: Record; + requests: number; + server: Server; + done: () => {}; +} -export type MockState$Subscription$Callback = (error: Error | null, value: any) => void; +export type MockStateSubscriptionCallback = (error: Error | null, value: any) => void; -export type MockState$Subscriptions = { - [index: string]: { - callbacks: { - [index: number]: MockState$Subscription$Callback - }, - lastValue: any - } -}; +export type MockStateSubscriptions = Record; + lastValue: any; +}>; -export type MockState$Db = { - [index: string]: Uint8Array -}; +export type MockStateDb = Record; -export type MockState$Requests = { - [index: string]: (db: MockState$Db, params: Array) => string -}; +export type MockStateRequests = Record string>; diff --git a/packages/rpc-provider/src/mock/unsubscribe.spec.ts b/packages/rpc-provider/src/mock/unsubscribe.spec.ts index e38091da1f..55a776ccad 100644 --- a/packages/rpc-provider/src/mock/unsubscribe.spec.ts +++ b/packages/rpc-provider/src/mock/unsubscribe.spec.ts @@ -4,37 +4,43 @@ import Mock from './'; -describe('unsubscribe', () => { +describe('unsubscribe', (): void => { let mock: Mock; let id: number; - beforeEach(() => { + beforeEach((): Promise => { mock = new Mock(); return mock - .subscribe('chain_newHead', 'chain_subscribeNewHead', () => void 0) - .then((_id) => { + .subscribe('chain_newHead', 'chain_subscribeNewHead', (): void => void 0) + .then((_id): void => { id = _id; }); }); - it('fails on unknown ids', () => { + it('fails on unknown ids', (): Promise => { return mock .unsubscribe('chain_newHead', 'chain_subscribeNewHead', 5) - .catch((error) => { + .catch((error): boolean => { expect(error.message).toMatch(/Unable to find/); + + return false; }); }); - it('unsubscribes successfully', () => { + it('unsubscribes successfully', (): Promise => { return mock.unsubscribe('chain_newHead', 'chain_subscribeNewHead', id); }); - it('fails on double unsubscribe', () => { + it('fails on double unsubscribe', (): Promise => { return mock.unsubscribe('chain_newHead', 'chain_subscribeNewHead', id) - .then(() => mock.unsubscribe('chain_newHead', 'chain_subscribeNewHead', id)) - .catch((error) => { + .then((): Promise => + mock.unsubscribe('chain_newHead', 'chain_subscribeNewHead', id) + ) + .catch((error): boolean => { expect(error.message).toMatch(/Unable to find/); + + return false; }); }); }); diff --git a/packages/rpc-provider/src/types.ts b/packages/rpc-provider/src/types.ts index 9515afa540..bb488d9f4c 100644 --- a/packages/rpc-provider/src/types.ts +++ b/packages/rpc-provider/src/types.ts @@ -2,53 +2,53 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -export type JsonRpcObject = { +export interface JsonRpcObject { id: number; jsonrpc: '2.0'; -}; +} -export type JsonRpcRequest = JsonRpcObject & { +export interface JsonRpcRequest extends JsonRpcObject { method: string; - params: Array; -}; + params: any[]; +} -export type JsonRpcResponseBase$Error = { - code: number, - data?: number | string, - message: string -}; +export interface JsonRpcResponseBaseError { + code: number; + data?: number | string; + message: string; +} -type JsonRpcResponse$Single = { - error?: JsonRpcResponseBase$Error; +interface JsonRpcResponseSingle { + error?: JsonRpcResponseBaseError; result?: any; -}; +} -type JsonRpcResponse$Subscription = { +interface JsonRpcResponseSubscription { method?: string; params: { - error?: JsonRpcResponseBase$Error; + error?: JsonRpcResponseBaseError; result: any; subscription: number; - } -}; + }; +} -export type JsonRpcResponseBase = JsonRpcResponse$Single & JsonRpcResponse$Subscription; +export type JsonRpcResponseBase = JsonRpcResponseSingle & JsonRpcResponseSubscription; export type JsonRpcResponse = JsonRpcObject & JsonRpcResponseBase; -export type ProviderInterface$Callback = (result: any) => void; +export type ProviderInterfaceCallback = (result: any) => void; -export type ProviderInterface$Emitted = 'connected' | 'disconnected' | 'error'; +export type ProviderInterfaceEmitted = 'connected' | 'disconnected' | 'error'; -export type ProviderInterface$EmitCb = (value?: any) => any; +export type ProviderInterfaceEmitCb = (value?: any) => any; export interface ProviderInterface { readonly hasSubscriptions: boolean; clone (): ProviderInterface; disconnect (): void; isConnected (): boolean; - on (type: ProviderInterface$Emitted, sub: ProviderInterface$EmitCb): void; - send (method: string, params: Array): Promise; - subscribe (type: string, method: string, params: Array, cb: ProviderInterface$Callback): Promise; + on (type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): void; + send (method: string, params: any[]): Promise; + subscribe (type: string, method: string, params: any[], cb: ProviderInterfaceCallback): Promise; unsubscribe (type: string, method: string, id: number): Promise; } diff --git a/packages/rpc-provider/src/ws/Provider.ts b/packages/rpc-provider/src/ws/Provider.ts index b11fa91bfd..f9af744040 100644 --- a/packages/rpc-provider/src/ws/Provider.ts +++ b/packages/rpc-provider/src/ws/Provider.ts @@ -1,8 +1,9 @@ +/* eslint-disable @typescript-eslint/camelcase */ // Copyright 2017-2019 @polkadot/rpc-provider 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 { JsonRpcResponse, ProviderInterface, ProviderInterface$Callback, ProviderInterface$Emitted, ProviderInterface$EmitCb } from '../types'; +import { JsonRpcResponse, ProviderInterface, ProviderInterfaceCallback, ProviderInterfaceEmitted, ProviderInterfaceEmitCb } from '../types'; import './polyfill'; @@ -14,31 +15,31 @@ import defaults from '../defaults'; type CallbackHandler = (error?: null | Error, value?: any) => void; -type SubscriptionHandler = { - callback: CallbackHandler, - type: string -}; +interface SubscriptionHandler { + callback: CallbackHandler; + type: string; +} -type WsState$Awaiting = { - callback: CallbackHandler, - method: string, - params: Array, - subscription?: SubscriptionHandler -}; +interface WsStateAwaiting { + callback: CallbackHandler; + method: string; + params: any[]; + subscription?: SubscriptionHandler; +} -type WsState$Subscription = SubscriptionHandler & { - method: string, - params: Array -}; +interface WsStateSubscription extends SubscriptionHandler { + method: string; + params: any[]; +} interface WSProviderInterface extends ProviderInterface { connect (): void; } const ALIASSES: { [index: string]: string } = { - 'chain_finalisedHead': 'chain_finalizedHead', - 'chain_subscribeFinalisedHeads': 'chain_subscribeFinalizedHeads', - 'chain_unsubscribeFinalisedHeads': 'chain_unsubscribeFinalizedHeads' + chain_finalisedHead: 'chain_finalizedHead', + chain_subscribeFinalisedHeads: 'chain_subscribeFinalizedHeads', + chain_unsubscribeFinalisedHeads: 'chain_unsubscribeFinalizedHeads' }; const l = logger('api-ws'); @@ -65,29 +66,30 @@ const l = logger('api-ws'); */ export default class WsProvider implements WSProviderInterface { private _eventemitter: EventEmitter; + private _isConnected: boolean = false; + private autoConnect: boolean; + private coder: Coder; + private endpoint: string; - private handlers: { - [index: string]: WsState$Awaiting - }; - private queued: { - [index: string]: string - }; - private subscriptions: { - [index: string]: WsState$Subscription - }; - private waitingForId: { - [index: string]: JsonRpcResponse - }; + + private handlers: Record; + + private queued: Record; + + private subscriptions: Record; + + private waitingForId: Record; + private websocket: WebSocket | null; /** * @param {string} endpoint The endpoint url. Usually `ws://ip:9944` or `wss://ip:9944` * @param {boolean} autoConnect Whether to connect automatically or not. */ - constructor (endpoint: string = defaults.WS_URL, autoConnect: boolean = true) { + public constructor (endpoint: string = defaults.WS_URL, autoConnect: boolean = true) { assert(/^(wss|ws):\/\//.test(endpoint), `Endpoint should start with 'ws://', received '${endpoint}'`); this._eventemitter = new EventEmitter(); @@ -108,14 +110,14 @@ export default class WsProvider implements WSProviderInterface { /** * @summary `true` when this provider supports subscriptions */ - get hasSubscriptions (): boolean { + public get hasSubscriptions (): boolean { return true; } /** * @description Returns a clone of the object */ - clone (): WsProvider { + public clone (): WsProvider { return new WsProvider(this.endpoint); } @@ -124,7 +126,7 @@ export default class WsProvider implements WSProviderInterface { * @description The [[WsProvider]] connects automatically by default, however if you decided otherwise, you may * connect manually using this method. */ - connect (): void { + public connect (): void { try { this.websocket = new WebSocket(this.endpoint); @@ -140,7 +142,7 @@ export default class WsProvider implements WSProviderInterface { /** * @description Manually disconnect from the connection, clearing autoconnect logic */ - disconnect (): void { + public disconnect (): void { if (isNull(this.websocket)) { throw new Error('Cannot disconnect on a non-open websocket'); } @@ -157,16 +159,16 @@ export default class WsProvider implements WSProviderInterface { * @summary Whether the node is connected or not. * @return {boolean} true if connected */ - isConnected (): boolean { + public isConnected (): boolean { return this._isConnected; } /** * @summary Listens on events after having subscribed using the [[subscribe]] function. - * @param {ProviderInterface$Emitted} type Event - * @param {ProviderInterface$EmitCb} sub Callback + * @param {ProviderInterfaceEmitted} type Event + * @param {ProviderInterfaceEmitCb} sub Callback */ - on (type: ProviderInterface$Emitted, sub: ProviderInterface$EmitCb): void { + public on (type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): void { this._eventemitter.on(type, sub); } @@ -176,18 +178,18 @@ export default class WsProvider implements WSProviderInterface { * @param params Encoded paramaters as appliucable for the method * @param subscription Subscription details (internally used) */ - send (method: string, params: Array, subscription?: SubscriptionHandler): Promise { + public send (method: string, params: any[], subscription?: SubscriptionHandler): Promise { return new Promise((resolve, reject): void => { try { const json = this.coder.encodeJson(method, params); const id = this.coder.getId(); - const callback = (error?: Error | null, result?: any) => { + const callback = (error?: Error | null, result?: any): void => { error ? reject(error) : resolve(result); }; - l.debug(() => ['calling', method, params, json, !!subscription]); + l.debug((): any[] => ['calling', method, params, json, !!subscription]); this.handlers[id] = { callback, @@ -212,8 +214,8 @@ export default class WsProvider implements WSProviderInterface { * @summary Allows subscribing to a specific event. * @param {string} type Subscription type * @param {string} method Subscription method - * @param {Array} params Parameters - * @param {ProviderInterface$Callback} callback Callback + * @param {any[]} params Parameters + * @param {ProviderInterfaceCallback} callback Callback * @return {Promise} Promise resolving to the dd of the subscription you can use with [[unsubscribe]]. * * @example @@ -230,7 +232,7 @@ export default class WsProvider implements WSProviderInterface { * }) * ``` */ - async subscribe (type: string, method: string, params: Array, callback: ProviderInterface$Callback): Promise { + public async subscribe (type: string, method: string, params: any[], callback: ProviderInterfaceCallback): Promise { const id = await this.send(method, params, { callback, type }); return id as number; @@ -239,7 +241,7 @@ export default class WsProvider implements WSProviderInterface { /** * @summary Allows unsubscribing to subscriptions made with [[subscribe]]. */ - async unsubscribe (type: string, method: string, id: number): Promise { + public async unsubscribe (type: string, method: string, id: number): Promise { const subscription = `${type}::${id}`; // FIXME This now could happen with re-subscriptions. The issue is that with a re-sub @@ -247,7 +249,7 @@ export default class WsProvider implements WSProviderInterface { // a slight complication in solving - since we cannot rely on the send id, but rather // need to find the actual subscription id to map it if (isUndefined(this.subscriptions[subscription])) { - l.debug(() => `Unable to find active subscription=${subscription}`); + l.debug((): any => `Unable to find active subscription=${subscription}`); return false; } @@ -259,7 +261,7 @@ export default class WsProvider implements WSProviderInterface { return result as boolean; } - private emit (type: ProviderInterface$Emitted, ...args: Array): void { + private emit (type: ProviderInterfaceEmitted, ...args: any[]): void { this._eventemitter.emit(type, ...args); } @@ -272,19 +274,19 @@ export default class WsProvider implements WSProviderInterface { this.emit('disconnected'); if (this.autoConnect) { - setTimeout(() => { + setTimeout((): void => { this.connect(); }, 1000); } } private onSocketError = (error: Event): void => { - l.debug(() => ['socket error', error]); + l.debug((): any => ['socket error', error]); this.emit('error', error); } private onSocketMessage = (message: MessageEvent): void => { - l.debug(() => ['received', message.data]); + l.debug((): any => ['received', message.data]); const response: JsonRpcResponse = JSON.parse(message.data as string); @@ -297,7 +299,7 @@ export default class WsProvider implements WSProviderInterface { const handler = this.handlers[response.id]; if (!handler) { - l.debug(() => `Unable to find handler for id=${response.id}`); + l.debug((): string => `Unable to find handler for id=${response.id}`); return; } @@ -339,7 +341,7 @@ export default class WsProvider implements WSProviderInterface { // store the JSON, we could have out-of-order subid coming in this.waitingForId[subId] = response; - l.debug(() => `Unable to find handler for subscription=${subId}`); + l.debug((): string => `Unable to find handler for subscription=${subId}`); return; } @@ -358,7 +360,7 @@ export default class WsProvider implements WSProviderInterface { private onSocketOpen = (): boolean => { assert(!isNull(this.websocket), 'WebSocket cannot be null in onOpen'); - l.debug(() => ['connected to', this.endpoint]); + l.debug((): any[] => ['connected to', this.endpoint]); this._isConnected = true; this.emit('connected'); @@ -374,7 +376,7 @@ export default class WsProvider implements WSProviderInterface { this.subscriptions = {}; - Object.keys(subscriptions).forEach(async (id) => { + Object.keys(subscriptions).forEach(async (id): Promise => { const { callback, method, params, type } = subscriptions[id]; // only re-create subscriptions which are not in author (only area where @@ -393,7 +395,7 @@ export default class WsProvider implements WSProviderInterface { } private sendQueue (): void { - Object.keys(this.queued).forEach((id) => { + Object.keys(this.queued).forEach((id): void => { try { // @ts-ignore we have done the websocket check in onSocketOpen, if an issue, will catch it this.websocket.send( diff --git a/packages/rpc-provider/src/ws/connect.spec.ts b/packages/rpc-provider/src/ws/connect.spec.ts index cb475b7026..3bac4a0d84 100644 --- a/packages/rpc-provider/src/ws/connect.spec.ts +++ b/packages/rpc-provider/src/ws/connect.spec.ts @@ -6,33 +6,33 @@ import WsProvider from './'; import { Mock } from './../mock/types'; import { mockWs, TEST_WS_URL } from '../../test/mockWs'; -describe('onConnect', () => { +describe('onConnect', (): void => { let mock: Mock; - beforeEach(() => { + beforeEach((): void => { mock = mockWs([]); }); - afterEach(() => { + afterEach((): void => { if (mock) { mock.done(); } }); - it('Does not connect when autoConnect is false', () => { + it('Does not connect when autoConnect is false', (): void => { const provider: WsProvider = new WsProvider(TEST_WS_URL, false); // We need to access the private WsProvider property 'websocket' here which would otherwise trigger a tslint error. // @ts-ignore expect(provider.websocket).toBeNull(); }); - it('Does connect when autoConnect is true', () => { + it('Does connect when autoConnect is true', (): void => { const provider: WsProvider = new WsProvider(TEST_WS_URL, true); // @ts-ignore expect(provider.websocket).not.toBeNull(); }); - it('Creates a new WebSocket instance by calling the connect() method', () => { + it('Creates a new WebSocket instance by calling the connect() method', (): void => { const provider: WsProvider = new WsProvider(TEST_WS_URL, false); // @ts-ignore expect(provider.websocket).toBeNull(); @@ -45,7 +45,7 @@ describe('onConnect', () => { expect(provider.websocket instanceof WebSocket).toBe(true); }); - it('Creates the on handlers', () => { + it('Creates the on handlers', (): void => { const provider: WsProvider = new WsProvider(TEST_WS_URL); // @ts-ignore diff --git a/packages/rpc-provider/src/ws/index.spec.ts b/packages/rpc-provider/src/ws/index.spec.ts index bbce3058f1..58429a1dc4 100644 --- a/packages/rpc-provider/src/ws/index.spec.ts +++ b/packages/rpc-provider/src/ws/index.spec.ts @@ -9,22 +9,23 @@ import { mockWs, TEST_WS_URL } from '../../test/mockWs'; let ws: WsProvider; let mock: Mock; -function createWs (requests: Array, autoConnect: boolean | undefined) { +function createWs (requests: any[], autoConnect: boolean | undefined): WsProvider { mock = mockWs(requests); ws = new WsProvider(TEST_WS_URL, autoConnect); + return ws; } -describe('Ws', () => { - afterEach(() => { +describe('Ws', (): void => { + afterEach((): void => { if (mock) { mock.done(); } }); - it('returns the connected state', () => { + it('returns the connected state', (): void => { expect( - createWs([],true).isConnected() + createWs([], true).isConnected() ).toEqual(false); }); }); diff --git a/packages/rpc-provider/src/ws/index.ts b/packages/rpc-provider/src/ws/index.ts index 2e62a42dd7..6f1fcc647e 100644 --- a/packages/rpc-provider/src/ws/index.ts +++ b/packages/rpc-provider/src/ws/index.ts @@ -2,6 +2,6 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { default as WsProvider } from './Provider'; +import WsProvider from './Provider'; export default WsProvider; diff --git a/packages/rpc-provider/src/ws/onMessageResult.spec.ts b/packages/rpc-provider/src/ws/onMessageResult.spec.ts index ecf7bc7be3..32536e1dff 100644 --- a/packages/rpc-provider/src/ws/onMessageResult.spec.ts +++ b/packages/rpc-provider/src/ws/onMessageResult.spec.ts @@ -4,18 +4,18 @@ import WsProvider from './'; -describe('WsProvider', () => { +describe('WsProvider', (): void => { let provider: WsProvider; - beforeEach(() => { + beforeEach((): void => { provider = new WsProvider('ws://127.0.0.1:1234', false); }); - it('calls the handler when found', (done) => { + it('calls the handler when found', (done): void => { // We need to access the private WsProvider property 'handlers' here which otherwise trigger a tslint error.. // @ts-ignore provider.handlers[5] = { - callback: (_: any, result: any) => { + callback: (_: any, result: any): void => { expect(result).toEqual('test'); done(); }, @@ -25,6 +25,8 @@ describe('WsProvider', () => { // We need to access the private WsProvider property 'onSocketMessage' here which would otherwise trigger a tslint error. // @ts-ignore - provider.onSocketMessage(new MessageEvent('test', { data: '{"jsonrpc":"2.0","id":5,"result":"test"}' })); + provider.onSocketMessage( + new MessageEvent('test', { data: '{"jsonrpc":"2.0","id":5,"result":"test"}' }) + ); }); }); diff --git a/packages/rpc-provider/src/ws/onMessageSubscribe.spec.ts b/packages/rpc-provider/src/ws/onMessageSubscribe.spec.ts index 1c9ecb45e8..3d540ebcc1 100644 --- a/packages/rpc-provider/src/ws/onMessageSubscribe.spec.ts +++ b/packages/rpc-provider/src/ws/onMessageSubscribe.spec.ts @@ -4,24 +4,24 @@ import WsProvider from './'; -describe('onMessageSubscribe', () => { +describe('onMessageSubscribe', (): void => { let provider: WsProvider; - beforeEach(() => { + beforeEach((): void => { provider = new WsProvider('ws://127.0.0.1:1234', false); }); - it('calls the subscriber with data', (done) => { + it('calls the subscriber with data', (done): void => { // We need to access the private WsProvider property 'handlers' here which otherwise triggers a tslint error.. // @ts-ignore provider.handlers[11] = { - callback: (_: any, id: number) => { + callback: (_: any, id: number): void => { expect(typeof id).toBe('number'); }, method: 'test', params: [], subscription: { - callback: (_: any, result: any) => { + callback: (_: any, result: any): void => { expect(result).toEqual('test'); done(); }, @@ -36,17 +36,17 @@ describe('onMessageSubscribe', () => { provider.onSocketMessage(new MessageEvent('test', { data: '{"jsonrpc":"2.0","method":"test","params":{"subscription":22,"result":"test"}}' })); }); - it('calls the subscriber with error', (done) => { + it('calls the subscriber with error', (done): void => { // We need to access the private WsProvider property 'handlers' here which otherwise trigger a tslint error.. // @ts-ignore provider.handlers[11] = { - callback: (_: any, id: number) => { + callback: (_: any, id: number): void => { expect(typeof id).toBe('number'); }, method: 'test', params: [], subscription: { - callback: (error: any) => { + callback: (error: any): void => { expect(error.message).toMatch(/test/); done(); }, diff --git a/packages/rpc-provider/src/ws/onOpen.spec.ts b/packages/rpc-provider/src/ws/onOpen.spec.ts index f156ece373..d7a7903c5e 100644 --- a/packages/rpc-provider/src/ws/onOpen.spec.ts +++ b/packages/rpc-provider/src/ws/onOpen.spec.ts @@ -9,21 +9,21 @@ import { mockWs, TEST_WS_URL } from '../../test/mockWs'; let ws: WsProvider; let mock: Mock; -function createWs (requests: Array, autoConnect: boolean | undefined) { +function createWs (requests: any[], autoConnect: boolean | undefined): WsProvider { mock = mockWs(requests); ws = new WsProvider(TEST_WS_URL, autoConnect); return ws; } -describe('onOpen', () => { - afterEach(() => { +describe('onOpen', (): void => { + afterEach((): void => { if (mock) { mock.done(); } }); - it('sends messages when connected', () => { + it('sends messages when connected', (): Promise => { const ws = createWs([{ id: 1, method: 'test_queue', @@ -35,7 +35,7 @@ describe('onOpen', () => { ws.connect(); - return sendPromise.then((result) => { + return sendPromise.then((result): void => { expect(result).toEqual('ok'); }); }); diff --git a/packages/rpc-provider/src/ws/polyfill.spec.ts b/packages/rpc-provider/src/ws/polyfill.spec.ts index ac246bdfce..c2fb5d33d4 100644 --- a/packages/rpc-provider/src/ws/polyfill.spec.ts +++ b/packages/rpc-provider/src/ws/polyfill.spec.ts @@ -8,26 +8,26 @@ import { Global } from './../mock/types'; declare let global: Global; -describe('ws/polyfill', () => { +describe('ws/polyfill', (): void => { let origWs: Constructor; - beforeEach(() => { + beforeEach((): void => { origWs = global.WebSocket; }); - afterEach(() => { + afterEach((): void => { global.WebSocket = origWs; }); - it('polyfills with no exceptions (with WebSocket)', () => { + it('polyfills with no exceptions (with WebSocket)', (): void => { (global as any).WebSocket = undefined; require('./polyfill'); expect(global.WebSocket).toBeDefined(); }); - it('polyfills with no exceptions (without WebSocket)', () => { - (global as any).WebSocket = () => true; + it('polyfills with no exceptions (without WebSocket)', (): void => { + (global as any).WebSocket = (): boolean => true; require('./polyfill'); expect(global.WebSocket).toBeDefined(); diff --git a/packages/rpc-provider/src/ws/send.spec.ts b/packages/rpc-provider/src/ws/send.spec.ts index ee18724118..a3a9487f5f 100644 --- a/packages/rpc-provider/src/ws/send.spec.ts +++ b/packages/rpc-provider/src/ws/send.spec.ts @@ -12,24 +12,24 @@ declare const global: Global; let provider: WsProvider; let mock: Mock; -function createMock (requests: Array) { +function createMock (requests: any[]): void { mock = mockWs(requests); } -function createWs (autoConnect: boolean = true) { +function createWs (autoConnect: boolean = true): WsProvider { provider = new WsProvider(TEST_WS_URL, autoConnect); return provider; } -describe('send', () => { +describe('send', (): void => { let globalWs: Constructor; - beforeEach(() => { + beforeEach((): void => { globalWs = global.WebSocket; }); - afterEach(() => { + afterEach((): void => { global.WebSocket = globalWs; if (mock) { @@ -37,11 +37,11 @@ describe('send', () => { } }); - it('handles internal errors', () => { + it('handles internal errors', (): Promise => { createMock([]); (global as any).WebSocket = class { - send () { + public send (): void { throw new Error('send error'); } }; @@ -52,12 +52,12 @@ describe('send', () => { return provider .send('test_encoding', ['param']) - .catch((error) => { + .catch((error): void => { expect(error.message).toEqual('send error'); }); }); - it('passes the body through correctly', () => { + it('passes the body through correctly', (): Promise => { createMock([{ id: 1, method: 'test_body', @@ -68,14 +68,14 @@ describe('send', () => { return createWs(true) .send('test_body', ['param']) - .then((result) => { + .then((): void => { expect( (mock.body as any)['test_body'] ).toEqual('{"id":1,"jsonrpc":"2.0","method":"test_body","params":["param"]}'); }); }); - it('throws error when !response.ok', () => { + it('throws error when !response.ok', (): Promise => { createMock([{ id: 1, error: { @@ -86,12 +86,12 @@ describe('send', () => { return createWs(true) .send('test_error', []) - .catch((error) => { + .catch((error): void => { expect(error.message).toMatch(/666: error/); }); }); - it('adds subscriptions', () => { + it('adds subscriptions', (): Promise => { createMock([{ id: 1, method: 'test_sub', @@ -102,7 +102,7 @@ describe('send', () => { return createWs(true) .send('test_sub', []) - .then((id) => { + .then((id): void => { expect(id).toEqual(1); }); }); diff --git a/packages/rpc-provider/src/ws/state.spec.ts b/packages/rpc-provider/src/ws/state.spec.ts index 3ddf75eea1..097ac06a2a 100644 --- a/packages/rpc-provider/src/ws/state.spec.ts +++ b/packages/rpc-provider/src/ws/state.spec.ts @@ -4,16 +4,16 @@ import WsProvider from './'; -describe('state', () => { - it('requires an ws:// prefixed endpoint', () => { +describe('state', (): void => { + it('requires an ws:// prefixed endpoint', (): void => { expect( - () => new WsProvider('http://', false) + (): WsProvider => new WsProvider('http://', false) ).toThrow(/with 'ws/); }); - it('allows wss:// endpoints', () => { + it('allows wss:// endpoints', (): void => { expect( - () => new WsProvider('wss://', false) + (): WsProvider => new WsProvider('wss://', false) ).not.toThrow(); }); }); diff --git a/packages/rpc-provider/src/ws/subscribe.spec.ts b/packages/rpc-provider/src/ws/subscribe.spec.ts index 846354cae8..002ed01585 100644 --- a/packages/rpc-provider/src/ws/subscribe.spec.ts +++ b/packages/rpc-provider/src/ws/subscribe.spec.ts @@ -12,24 +12,24 @@ declare var global: Global; let ws: WsProvider; let mock: Mock; -function createMock (requests: Array) { +function createMock (requests: any[]): void { mock = mockWs(requests); } -function createWs (autoConnect: boolean = true) { +function createWs (autoConnect: boolean = true): WsProvider { ws = new WsProvider(TEST_WS_URL, autoConnect); return ws; } -describe('subscribe', () => { +describe('subscribe', (): void => { let globalWs: Constructor; - beforeEach(() => { + beforeEach((): void => { globalWs = global.WebSocket; }); - afterEach(() => { + afterEach((): void => { global.WebSocket = globalWs; if (mock) { @@ -37,7 +37,7 @@ describe('subscribe', () => { } }); - it('adds subscriptions', () => { + it('adds subscriptions', (): Promise => { createMock([{ id: 1, method: 'test_sub', @@ -47,8 +47,10 @@ describe('subscribe', () => { }]); return createWs(true) - .subscribe('type', 'test_sub', [], (cb) => { expect(cb).toEqual(expect.anything()); }) - .then((id) => { + .subscribe('type', 'test_sub', [], (cb): void => { + expect(cb).toEqual(expect.anything()); + }) + .then((id): void => { expect(id).toEqual(1); }); }); diff --git a/packages/rpc-provider/src/ws/unsubscribe.spec.ts b/packages/rpc-provider/src/ws/unsubscribe.spec.ts index 997d72682b..eb2c659da3 100644 --- a/packages/rpc-provider/src/ws/unsubscribe.spec.ts +++ b/packages/rpc-provider/src/ws/unsubscribe.spec.ts @@ -12,24 +12,24 @@ declare var global: Global; let ws: WsProvider; let mock: Mock; -function createMock (requests: any) { +function createMock (requests: any): void { mock = mockWs(requests); } -function createWs (autoConnect: boolean = true) { +function createWs (autoConnect: boolean = true): WsProvider { ws = new WsProvider(TEST_WS_URL, autoConnect); return ws; } -describe('subscribe', () => { +describe('subscribe', (): void => { let globalWs: Constructor; - beforeEach(() => { + beforeEach((): void => { globalWs = global.WebSocket; }); - afterEach(() => { + afterEach((): void => { global.WebSocket = globalWs; if (mock) { @@ -37,7 +37,7 @@ describe('subscribe', () => { } }); - it('removes subscriptions', () => { + it('removes subscriptions', (): Promise => { createMock([ { id: 1, @@ -58,13 +58,15 @@ describe('subscribe', () => { const ws = createWs(true); return ws - .subscribe('test', 'subscribe_test', [], (cb) => { expect(cb).toEqual(expect.anything()); }) - .then((id) => { + .subscribe('test', 'subscribe_test', [], (cb): void => { + expect(cb).toEqual(expect.anything()); + }) + .then((id): Promise => { return ws.unsubscribe('test', 'subscribe_test', id); }); }); - it('fails when sub not found', () => { + it('fails when sub not found', (): Promise => { createMock([{ id: 1, method: 'subscribe_test', @@ -76,11 +78,13 @@ describe('subscribe', () => { const ws = createWs(true); return ws - .subscribe('test', 'subscribe_test', [], (cb) => { expect(cb).toEqual(expect.anything()); }) - .then((id) => { + .subscribe('test', 'subscribe_test', [], (cb): void => { + expect(cb).toEqual(expect.anything()); + }) + .then((): Promise => { return ws.unsubscribe('test', 'subscribe_test', 111); }) - .then((result) => { + .then((result): void => { expect(result).toBe(false); }); }); diff --git a/packages/rpc-provider/test/mockHttp.ts b/packages/rpc-provider/test/mockHttp.ts index ce3da900c5..25a3841e5f 100644 --- a/packages/rpc-provider/test/mockHttp.ts +++ b/packages/rpc-provider/test/mockHttp.ts @@ -6,13 +6,13 @@ import nock from 'nock'; const TEST_HTTP_URL = 'http://localhost:9944'; -function mockHttp (requests: any[]) { +function mockHttp (requests: any[]): any { nock.cleanAll(); - return requests.reduce((scope, request: any, index: number) => { + return requests.reduce((scope, request: any): nock.Scope => { return scope .post('/') - .reply(request.code || 200, (uri: string, body: { id: string }) => { + .reply(request.code || 200, (uri: string, body: { id: string }): any => { scope.body = scope.body || {}; scope.body[request.method] = body; diff --git a/packages/rpc-provider/test/mockWs.ts b/packages/rpc-provider/test/mockWs.ts index 3fa5abf84b..8c100056ec 100644 --- a/packages/rpc-provider/test/mockWs.ts +++ b/packages/rpc-provider/test/mockWs.ts @@ -8,22 +8,30 @@ const TEST_WS_URL = 'ws://localhost:9955'; let server: Server; -type ErrorDef = { - id: number, +interface Scope { + body: { [index: string]: {} }; + requests: number; + server: Server; + done: any; +} + +interface ErrorDef { + id: number; error: { - code: number, - message: string - } -}; + code: number; + message: string; + }; +} -type ReplyDef = { - id: number, +interface ReplyDef { + id: number; reply: { - result: any - } -}; + result: any; + }; +} -function createError ({ id, error: { code, message } }: ErrorDef) { +// should be JSONRPC def return +function createError ({ id, error: { code, message } }: ErrorDef): any { return { id, jsonrpc: '2.0', @@ -34,7 +42,8 @@ function createError ({ id, error: { code, message } }: ErrorDef) { }; } -function createReply ({ id, reply: { result } }: ReplyDef) { +// should be JSONRPC def return +function createReply ({ id, reply: { result } }: ReplyDef): any { return { id, jsonrpc: '2.0', @@ -42,24 +51,25 @@ function createReply ({ id, reply: { result } }: ReplyDef) { }; } -function mockWs (requests: Array<{ method: string }>) { +// scope definition returned +function mockWs (requests: { method: string }[]): Scope { server = new Server(TEST_WS_URL); let requestCount = 0; - const scope: { - body: { [index: string]: {} }, - requests: number, - server: Server, - done: any - } = { body: {}, requests: 0, server, done: () => - server.stop(() => { + const scope: Scope = { + body: {}, + done: (): void => { + server.stop((): void => { // ignore - }) + }); + }, + requests: 0, + server }; - server.on('connection', (socket) => { + server.on('connection', (socket): void => { // @ts-ignore definitions are wrong, this is 'on', not 'onmessage' - socket.on('message', (body: { [index: string]: {} }) => { + socket.on('message', (body: { [index: string]: {} }): void => { const request = requests[requestCount]; // @ts-ignore Yes, SHOULD be fixed, this is a mess const response = request.error diff --git a/packages/type-jsonrpc/src/author.ts b/packages/type-jsonrpc/src/author.ts index 54d8a0f645..3706168e4d 100644 --- a/packages/type-jsonrpc/src/author.ts +++ b/packages/type-jsonrpc/src/author.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { RpcMethodOpt, RpcSection } from './types'; +import { RpcMethodOpt } from './types'; import createMethod from './create/method'; import createParam from './create/param'; @@ -51,4 +51,4 @@ export default { submitExtrinsic: createMethod(section, 'submitExtrinsic', submitExtrinsic), submitAndWatchExtrinsic: createMethod(section, 'submitAndWatchExtrinsic', submitAndWatchExtrinsic) } -} as RpcSection; +}; diff --git a/packages/type-jsonrpc/src/chain.ts b/packages/type-jsonrpc/src/chain.ts index 75b817936e..aff84748ea 100644 --- a/packages/type-jsonrpc/src/chain.ts +++ b/packages/type-jsonrpc/src/chain.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { RpcMethodOpt, RpcSection } from './types'; +import { RpcMethodOpt } from './types'; import createMethod from './create/method'; import createParam from './create/param'; @@ -102,4 +102,4 @@ export default { subscribeRuntimeVersion: createMethod(section, 'subscribeRuntimeVersion', subscribeRuntimeVersion), subscribeNewHead: createMethod(section, 'subscribeNewHead', subscribeNewHead) } -} as RpcSection; +}; diff --git a/packages/type-jsonrpc/src/create/param.ts b/packages/type-jsonrpc/src/create/param.ts index ea163883fe..d30b0ed814 100644 --- a/packages/type-jsonrpc/src/create/param.ts +++ b/packages/type-jsonrpc/src/create/param.ts @@ -5,9 +5,9 @@ import { CodecTypes } from '@polkadot/types/classes'; import { RpcParam } from '../types'; -type RpcParamOptions = { - isOptional?: boolean -}; +interface RpcParamOptions { + isOptional?: boolean; +} export default function createParam (name: string, type: CodecTypes, { isOptional = false }: RpcParamOptions = { isOptional: false }): RpcParam { return { diff --git a/packages/type-jsonrpc/src/index.spec.ts b/packages/type-jsonrpc/src/index.spec.ts index ee43e0a9cb..f67a205d2d 100644 --- a/packages/type-jsonrpc/src/index.spec.ts +++ b/packages/type-jsonrpc/src/index.spec.ts @@ -4,8 +4,8 @@ import interfaces from './'; -describe('jsonrpc', () => { - it('exports the available interfaces', () => { +describe('jsonrpc', (): void => { + it('exports the available interfaces', (): void => { expect(interfaces).toBeDefined(); expect(Object.keys(interfaces).length).toBeGreaterThan(0); }); diff --git a/packages/type-jsonrpc/src/index.ts b/packages/type-jsonrpc/src/index.ts index bb9d1ad1a5..d60af6f77d 100644 --- a/packages/type-jsonrpc/src/index.ts +++ b/packages/type-jsonrpc/src/index.ts @@ -9,7 +9,7 @@ import chain from './chain'; import state from './state'; import system from './system'; -const interfaces: { [key: string]: RpcSection } = { +const interfaces: Record = { author, chain, state, diff --git a/packages/type-jsonrpc/src/state.ts b/packages/type-jsonrpc/src/state.ts index ed15e544be..557c393a86 100644 --- a/packages/type-jsonrpc/src/state.ts +++ b/packages/type-jsonrpc/src/state.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { RpcMethodOpt, RpcSection } from './types'; +import { RpcMethodOpt } from './types'; import createMethod from './create/method'; import createParam from './create/param'; @@ -164,4 +164,4 @@ export default { queryStorage: createMethod(section, 'queryStorage', queryStorage), subscribeStorage: createMethod(section, 'subscribeStorage', subscribeStorage) } -} as RpcSection; +}; diff --git a/packages/type-jsonrpc/src/system.ts b/packages/type-jsonrpc/src/system.ts index 8dc73e3f58..09f4704d93 100644 --- a/packages/type-jsonrpc/src/system.ts +++ b/packages/type-jsonrpc/src/system.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { RpcMethodOpt, RpcSection } from './types'; +import { RpcMethodOpt } from './types'; import createMethod from './create/method'; @@ -70,4 +70,4 @@ export default { properties: createMethod(section, 'properties', properties), version: createMethod(section, 'version', version) } -} as RpcSection; +}; diff --git a/packages/type-jsonrpc/src/types.ts b/packages/type-jsonrpc/src/types.ts index 3bf2d041a2..002b74477e 100644 --- a/packages/type-jsonrpc/src/types.ts +++ b/packages/type-jsonrpc/src/types.ts @@ -6,43 +6,41 @@ import { CodecTypes } from '@polkadot/types/classes'; type PubSub = [string, string, string]; -export type RpcParam = { - isOptional: boolean, - name: string, - type: CodecTypes -}; +export interface RpcParam { + isOptional: boolean; + name: string; + type: CodecTypes; +} -export type RpcMethodOpt = { - description: string, - isDeprecated?: boolean, - isHidden?: boolean, - isSigned?: boolean, - isSubscription?: boolean, - params: Array, - pubsub?: PubSub, - type: CodecTypes -}; +export interface RpcMethodOpt { + description: string; + isDeprecated?: boolean; + isHidden?: boolean; + isSigned?: boolean; + isSubscription?: boolean; + params: RpcParam[]; + pubsub?: PubSub; + type: CodecTypes; +} -export type RpcMethod = { - alias?: string, - description: string, - isDeprecated: boolean, - isHidden: boolean, - isSigned: boolean, - isSubscription: boolean, - method: string, - params: Array, - pubsub: PubSub, - section: string, - type: CodecTypes -}; +export interface RpcMethod { + alias?: string; + description: string; + isDeprecated: boolean; + isHidden: boolean; + isSigned: boolean; + isSubscription: boolean; + method: string; + params: RpcParam[]; + pubsub: PubSub; + section: string; + type: CodecTypes; +} -export type RpcSection = { - isDeprecated: boolean, - isHidden: boolean, - description: string, - section: string, - methods: { - [index: string]: RpcMethod - } -}; +export interface RpcSection { + isDeprecated: boolean; + isHidden: boolean; + description: string; + section: string; + methods: Record; +} diff --git a/packages/types/src/Metadata/MagicNumber.spec.ts b/packages/types/src/Metadata/MagicNumber.spec.ts index 15edfbfed8..30d2a13156 100644 --- a/packages/types/src/Metadata/MagicNumber.spec.ts +++ b/packages/types/src/Metadata/MagicNumber.spec.ts @@ -4,12 +4,12 @@ import MagicNumber, { MAGIC_NUMBER } from './MagicNumber'; -describe('MagicNumber', () => { - it('succeeds when the magic number matches', () => { - expect(() => new MagicNumber(MAGIC_NUMBER)).not.toThrow(); +describe('MagicNumber', (): void => { + it('succeeds when the magic number matches', (): void => { + expect((): MagicNumber => new MagicNumber(MAGIC_NUMBER)).not.toThrow(); }); - it('fails when the magic number missmatches', () => { - expect(() => new MagicNumber(0x12345)).toThrow(/MagicNumber/); + it('fails when the magic number missmatches', (): void => { + expect((): MagicNumber => new MagicNumber(0x12345)).toThrow(/MagicNumber/); }); }); diff --git a/packages/types/src/Metadata/MagicNumber.ts b/packages/types/src/Metadata/MagicNumber.ts index 6565b1c032..fb0db1c4f5 100644 --- a/packages/types/src/Metadata/MagicNumber.ts +++ b/packages/types/src/Metadata/MagicNumber.ts @@ -9,7 +9,7 @@ import U32 from '../primitive/U32'; export const MAGIC_NUMBER = new U32(0x6174656d); // `meta`, reversed for Little Endian encoding export default class MagicNumber extends U32 { - constructor (value?: any) { + public constructor (value?: any) { super(value); assert(this.eq(MAGIC_NUMBER), `MagicNumber mismatch: expected ${MAGIC_NUMBER.toHex()}, found ${this.toHex()}`); diff --git a/packages/types/src/Metadata/Metadata.ts b/packages/types/src/Metadata/Metadata.ts index 560db9794d..2acc4eca0f 100644 --- a/packages/types/src/Metadata/Metadata.ts +++ b/packages/types/src/Metadata/Metadata.ts @@ -13,7 +13,7 @@ import MetadataVersioned from './MetadataVersioned'; * The versioned runtime metadata as a decoded structure */ export default class Metadata extends MetadataVersioned { - constructor (value?: Uint8Array | string) { + public constructor (value?: Uint8Array | string) { super(Metadata.decodeMetadata(value)); } diff --git a/packages/types/src/Metadata/MetadataVersioned.ts b/packages/types/src/Metadata/MetadataVersioned.ts index eac28c4438..68b72c078c 100644 --- a/packages/types/src/Metadata/MetadataVersioned.ts +++ b/packages/types/src/Metadata/MetadataVersioned.ts @@ -22,7 +22,7 @@ import v4ToV5 from './v4/toV5'; import v5ToV6 from './v5/toV6'; class MetadataEnum extends Enum { - constructor (value?: any) { + public constructor (value?: any) { super({ MetadataV0, // once rolled-out, can replace this with MetadataDeprecated MetadataV1, // once rolled-out, can replace this with MetadataDeprecated @@ -37,7 +37,7 @@ class MetadataEnum extends Enum { /** * @description Returns the wrapped values as a V0 object */ - get asV0 (): MetadataV0 { + public get asV0 (): MetadataV0 { assert(this.isV0, `Cannot convert '${this.type}' via asV0`); return this.value as MetadataV0; @@ -46,7 +46,7 @@ class MetadataEnum extends Enum { /** * @description Returns the wrapped values as a V1 object */ - get asV1 (): MetadataV1 { + public get asV1 (): MetadataV1 { assert(this.isV1, `Cannot convert '${this.type}' via asV1`); return this.value as MetadataV1; @@ -55,7 +55,7 @@ class MetadataEnum extends Enum { /** * @description Returns the wrapped values as a V2 object */ - get asV2 (): MetadataV2 { + public get asV2 (): MetadataV2 { assert(this.isV2, `Cannot convert '${this.type}' via asV2`); return this.value as MetadataV2; @@ -64,7 +64,7 @@ class MetadataEnum extends Enum { /** * @description Returns the wrapped values as a V3 object */ - get asV3 (): MetadataV3 { + public get asV3 (): MetadataV3 { assert(this.isV3, `Cannot convert '${this.type}' via asV3`); return this.value as MetadataV3; @@ -73,7 +73,7 @@ class MetadataEnum extends Enum { /** * @description Returns the wrapped values as a V4 object */ - get asV4 (): MetadataV4 { + public get asV4 (): MetadataV4 { assert(this.isV4, `Cannot convert '${this.type}' via asV4`); return this.value as MetadataV4; @@ -82,7 +82,7 @@ class MetadataEnum extends Enum { /** * @description Returns the wrapped values as a V5 object */ - get asV5 (): MetadataV5 { + public get asV5 (): MetadataV5 { assert(this.isV5, `Cannot convert '${this.type}' via asV5`); return this.value as MetadataV5; @@ -91,7 +91,7 @@ class MetadataEnum extends Enum { /** * @description Returns the wrapped values as a V6 object */ - get asV6 (): MetadataV6 { + public get asV6 (): MetadataV6 { assert(this.isV6, `Cannot convert '${this.type}' via asV6`); return this.value as MetadataV6; @@ -100,63 +100,63 @@ class MetadataEnum extends Enum { /** * @description `true` if Deprecated */ - get isDeprecated (): boolean { + public get isDeprecated (): boolean { return this.type === 'MetadataDeprectated'; } /** * @description `true` if V0 */ - get isV0 (): boolean { + public get isV0 (): boolean { return this.type === 'MetadataV0'; } /** * @description `true` if V1 */ - get isV1 (): boolean { + public get isV1 (): boolean { return this.type === 'MetadataV1'; } /** * @description `true` if V2 */ - get isV2 (): boolean { + public get isV2 (): boolean { return this.type === 'MetadataV2'; } /** * @description `true` if V3 */ - get isV3 (): boolean { + public get isV3 (): boolean { return this.type === 'MetadataV3'; } /** * @description `true` if V4 */ - get isV4 (): boolean { + public get isV4 (): boolean { return this.type === 'MetadataV4'; } /** * @description `true` if V5 */ - get isV5 (): boolean { + public get isV5 (): boolean { return this.type === 'MetadataV5'; } /** * @description `true` if V6 */ - get isV6 (): boolean { + public get isV6 (): boolean { return this.type === 'MetadataV6'; } /** * @description The version this metadata represents */ - get version (): number { + public get version (): number { return this.index; } } @@ -168,13 +168,18 @@ class MetadataEnum extends Enum { */ export default class MetadataVersioned extends Struct { private _convertedV1?: MetadataV1; + private _convertedV2?: MetadataV2; + private _convertedV3?: MetadataV3; + private _convertedV4?: MetadataV4; + private _convertedV5?: MetadataV5; + private _convertedV6?: MetadataV6; - constructor (value?: any) { + public constructor (value?: any) { super({ magicNumber: MagicNumber, metadata: MetadataEnum @@ -184,7 +189,7 @@ export default class MetadataVersioned extends Struct { /** * @description */ - get magicNumber (): MagicNumber { + public get magicNumber (): MagicNumber { return this.get('magicNumber') as MagicNumber; } @@ -198,14 +203,14 @@ export default class MetadataVersioned extends Struct { /** * @description the metadata version this structure represents */ - get version (): number { + public get version (): number { return this.metadata.index; } /** * @description Returns the wrapped metadata as a V0 object */ - get asV0 (): MetadataV0 { + public get asV0 (): MetadataV0 { assert(this.metadata.version === 0, `Cannot convert metadata from v${this.metadata.version} to v0`); return this.metadata.asV0; @@ -214,7 +219,7 @@ export default class MetadataVersioned extends Struct { /** * @description Returns the wrapped values as a V1 object */ - get asV1 (): MetadataV1 { + public get asV1 (): MetadataV1 { assert(this.metadata.version <= 1, `Cannot convert metadata from v${this.metadata.version} to v1`); if (this.metadata.version === 1) { @@ -231,7 +236,7 @@ export default class MetadataVersioned extends Struct { /** * @description Returns the wrapped values as a V2 object */ - get asV2 (): MetadataV2 { + public get asV2 (): MetadataV2 { assert(this.metadata.version <= 2, `Cannot convert metadata from v${this.metadata.version} to v2`); if (this.metadata.version === 2) { @@ -248,7 +253,7 @@ export default class MetadataVersioned extends Struct { /** * @description Returns the wrapped values as a V3 object */ - get asV3 (): MetadataV3 { + public get asV3 (): MetadataV3 { assert(this.metadata.version <= 3, `Cannot convert metadata from v${this.metadata.version} to v3`); if (this.metadata.version === 3) { @@ -265,7 +270,7 @@ export default class MetadataVersioned extends Struct { /** * @description Returns the wrapped values as a V4 object */ - get asV4 (): MetadataV4 { + public get asV4 (): MetadataV4 { assert(this.metadata.version <= 4, `Cannot convert metadata from v${this.metadata.version} to v4`); if (this.metadata.version === 4) { @@ -282,7 +287,7 @@ export default class MetadataVersioned extends Struct { /** * @description Returns the wrapped values as a V5 object */ - get asV5 (): MetadataV5 { + public get asV5 (): MetadataV5 { assert(this.metadata.version <= 5, `Cannot convert metadata from v${this.metadata.version} to v5`); if (this.metadata.version === 5) { @@ -299,7 +304,7 @@ export default class MetadataVersioned extends Struct { /** * @description Returns the wrapped values as a V6 object */ - get asV6 (): MetadataV6 { + public get asV6 (): MetadataV6 { assert(this.metadata.version <= 6, `Cannot convert metadata from v${this.metadata.version} to v6`); if (this.metadata.version === 6) { @@ -313,7 +318,7 @@ export default class MetadataVersioned extends Struct { return this._convertedV6; } - getUniqTypes (throwError: boolean): Array { + public getUniqTypes (throwError: boolean): string[] { return this.asV6.getUniqTypes(throwError); } } diff --git a/packages/types/src/Metadata/index.ts b/packages/types/src/Metadata/index.ts index 5e105166a4..7f470fabf4 100644 --- a/packages/types/src/Metadata/index.ts +++ b/packages/types/src/Metadata/index.ts @@ -2,6 +2,6 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { default as Metadata } from './Metadata'; +import Metadata from './Metadata'; export default Metadata; diff --git a/packages/types/src/Metadata/types.ts b/packages/types/src/Metadata/types.ts index a0a99b928b..19b074894e 100644 --- a/packages/types/src/Metadata/types.ts +++ b/packages/types/src/Metadata/types.ts @@ -7,5 +7,5 @@ import { Codec } from '../types'; export interface MetadataInterface extends Codec { modules: Vector; - getUniqTypes (throwError: boolean): Array; + getUniqTypes (throwError: boolean): string[]; } diff --git a/packages/types/src/Metadata/util/flattenUniq.ts b/packages/types/src/Metadata/util/flattenUniq.ts index 0c3fbdb244..527824351d 100644 --- a/packages/types/src/Metadata/util/flattenUniq.ts +++ b/packages/types/src/Metadata/util/flattenUniq.ts @@ -3,8 +3,8 @@ // of the Apache-2.0 license. See the LICENSE file for details. // Quick and dirty flatten (.flat() not available) -export default function flattenUniq (list: Array): Array { - const flat = list.reduce((result, entry) => { +export default function flattenUniq (list: any[]): any[] { + const flat = list.reduce((result, entry): any[] => { return result.concat( Array.isArray(entry) ? flattenUniq(entry) @@ -13,6 +13,6 @@ export default function flattenUniq (list: Array): Array { }, []); return [...new Set(flat)] - .filter((value: any) => value) + .filter((value: any): any => value) .sort(); } diff --git a/packages/types/src/Metadata/util/testUtil.ts b/packages/types/src/Metadata/util/testUtil.ts index 1ad1def43b..bfe429fd35 100644 --- a/packages/types/src/Metadata/util/testUtil.ts +++ b/packages/types/src/Metadata/util/testUtil.ts @@ -12,8 +12,8 @@ import Method from '../../primitive/Method'; import { MetadataInterface } from '../types'; import { Codec } from '../../types'; -function injectDefinitions () { - Object.values(srmlTypes).forEach(({ types }) => +function injectDefinitions (): void { + Object.values(srmlTypes).forEach(({ types }): void => getTypeRegistry().register(types) ); } @@ -26,8 +26,8 @@ export function decodeLatestSubstrate ( version: number, rpcData: string, latestSubstrate: object -) { - it('decodes latest substrate properly', () => { +): void { + it('decodes latest substrate properly', (): void => { injectDefinitions(); const metadata = new Metadata(rpcData); @@ -44,8 +44,8 @@ export function decodeLatestSubstrate ( * Given a `version`, MetadataV6 and MetadataV{version} should output the same * unique types. */ -export function toV6 (version: number, rpcData: string) { - it('converts to V6', () => { +export function toV6 (version: number, rpcData: string): void { + it('converts to V6', (): void => { injectDefinitions(); const metadata = new Metadata(rpcData)[`asV${version}` as keyof Metadata]; @@ -60,8 +60,8 @@ export function toV6 (version: number, rpcData: string) { /** * Given a Metadata, no type should throw when given its fallback value. */ -export function defaultValues (rpcData: string) { - describe('storage with default values', () => { +export function defaultValues (rpcData: string): void { + describe('storage with default values', (): void => { injectDefinitions(); const metadata = new Metadata(rpcData); @@ -69,15 +69,15 @@ export function defaultValues (rpcData: string) { Method.injectMethods(extrinsicsFromMeta(metadata)); metadata.asV6.modules - .filter(({ storage }) => storage.isSome) - .map((mod) => - mod.storage.unwrap().forEach(({ fallback, name, type }) => { - it(`creates default types for ${mod.prefix}.${name}, type ${type}`, () => { + .filter(({ storage }): boolean => storage.isSome) + .forEach((mod): void => { + mod.storage.unwrap().forEach(({ fallback, name, type }): void => { + it(`creates default types for ${mod.prefix}.${name}, type ${type}`, (): void => { expect( - () => createType(type.toString(), fallback) + (): Codec => createType(type.toString(), fallback) ).not.toThrow(); }); - }) - ); + }); + }); }); } diff --git a/packages/types/src/Metadata/util/validateTypes.ts b/packages/types/src/Metadata/util/validateTypes.ts index c3407072e9..6f475248d4 100644 --- a/packages/types/src/Metadata/util/validateTypes.ts +++ b/packages/types/src/Metadata/util/validateTypes.ts @@ -8,9 +8,9 @@ import { getTypeDef, TypeDef, TypeDefInfo } from '../../codec/createType'; import flattenUniq from './flattenUniq'; import { getTypeRegistry } from '../../codec'; -export default function validateTypes (types: Array, throwError: boolean): void { - const extractTypes = (types: Array): Array => { - return types.map((type) => { +export default function validateTypes (types: string[], throwError: boolean): void { + const extractTypes = (types: string[]): any[] => { + return types.map((type): any => { const decoded = getTypeDef(type); switch (decoded.info) { @@ -24,7 +24,7 @@ export default function validateTypes (types: Array, throwError: boolean case TypeDefInfo.Tuple: return extractTypes( - (decoded.sub as Array).map((sub) => sub.type) + (decoded.sub as TypeDef[]).map((sub): string => sub.type) ); default: @@ -34,7 +34,7 @@ export default function validateTypes (types: Array, throwError: boolean }; const typeRegistry = getTypeRegistry(); - const missing = flattenUniq(extractTypes(types)).filter((type) => + const missing = flattenUniq(extractTypes(types)).filter((type): boolean => isUndefined(typeRegistry.get(type)) ); diff --git a/packages/types/src/Metadata/v0/Calls.ts b/packages/types/src/Metadata/v0/Calls.ts index 8a447fd295..ec897dd32a 100644 --- a/packages/types/src/Metadata/v0/Calls.ts +++ b/packages/types/src/Metadata/v0/Calls.ts @@ -8,7 +8,7 @@ import Text from '../../primitive/Text'; import U16 from '../../primitive/U16'; export class OuterDispatchCall extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, prefix: Text, @@ -19,27 +19,27 @@ export class OuterDispatchCall extends Struct { /** * @description The [[U16]] index for the call */ - get index (): U16 { + public get index (): U16 { return this.get('index') as U16; } /** * @description The name for the call */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description The call prefix (or section) */ - get prefix (): Text { + public get prefix (): Text { return this.get('prefix') as Text; } } export class OuterDispatchMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, calls: Vector.with(OuterDispatchCall) @@ -49,14 +49,14 @@ export class OuterDispatchMetadata extends Struct { /** * @description The [[OuterDispathCall]] wrapped */ - get calls (): Vector { + public get calls (): Vector { return this.get('calls') as Vector; } /** * @description The name for the dispatch */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } } diff --git a/packages/types/src/Metadata/v0/Events.ts b/packages/types/src/Metadata/v0/Events.ts index 98f492dd07..f218440170 100644 --- a/packages/types/src/Metadata/v0/Events.ts +++ b/packages/types/src/Metadata/v0/Events.ts @@ -9,7 +9,7 @@ import Text from '../../primitive/Text'; import Type from '../../primitive/Type'; export class EventMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, args: Vector.with(Type), @@ -20,7 +20,7 @@ export class EventMetadata extends Struct { /** * @description The arguments of [[Type]] */ - get args (): Vector { + public get args (): Vector { return this.get('args') as Vector; } @@ -28,14 +28,14 @@ export class EventMetadata extends Struct { * @description The arguments of [[Type]] * @deprecated Use `.args` instead */ - get arguments (): Vector { + public get arguments (): Vector { return this.args; } /** * @description The [[Text]] documentation */ - get documentation (): Vector { + public get documentation (): Vector { return this.get('documentation') as Vector; } @@ -43,20 +43,20 @@ export class EventMetadata extends Struct { * @description The [[Text]] documentation * @deprecated Use `.documentation` instead. */ - get docs (): Vector { + public get docs (): Vector { return this.documentation; } /** * @description The name for the event */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } } export class OuterEventEventMetadata extends Tuple { - constructor (value?: any) { + public constructor (value?: any) { super({ Text, 'Vec': Vector.with(EventMetadata) @@ -66,20 +66,20 @@ export class OuterEventEventMetadata extends Tuple { /** * @description The [[EventMetadata]] */ - get events (): Vector { + public get events (): Vector { return this[1] as Vector; } /** * @description The name of the section */ - get name (): Text { + public get name (): Text { return this[0] as Text; } } export class OuterEventMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, events: Vector.with(OuterEventEventMetadata) @@ -89,14 +89,14 @@ export class OuterEventMetadata extends Struct { /** * @description The [[OuterEventEventMetadata]] */ - get events (): Vector { + public get events (): Vector { return this.get('events') as Vector; } /** * @description The name of the event */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } } diff --git a/packages/types/src/Metadata/v0/Metadata.spec.ts b/packages/types/src/Metadata/v0/Metadata.spec.ts index a99b9896ad..656e39ad29 100644 --- a/packages/types/src/Metadata/v0/Metadata.spec.ts +++ b/packages/types/src/Metadata/v0/Metadata.spec.ts @@ -8,15 +8,15 @@ import latestSubstrateV0 from './latest.substrate.v0.json'; import rpcData from './static'; import { defaultValues, toV6 } from '../util/testUtil'; -describe('Metadata', () => { - it('works with fallback', () => { +describe('Metadata', (): void => { + it('works with fallback', (): void => { const metadata = new Metadata(rpcData); const metadataV0 = new MetadataV0(rpcData); expect(metadata.asV0.toString()).toEqual(metadataV0.toString()); }); - it('decodes latest substrate properly', () => { + it('decodes latest substrate properly', (): void => { const metadata = new Metadata(rpcData); const json = metadata.asV0.toJSON(); diff --git a/packages/types/src/Metadata/v0/Metadata.ts b/packages/types/src/Metadata/v0/Metadata.ts index d420f378e2..8b6fed26d7 100644 --- a/packages/types/src/Metadata/v0/Metadata.ts +++ b/packages/types/src/Metadata/v0/Metadata.ts @@ -22,7 +22,7 @@ import { RuntimeModuleMetadata } from './Modules'; * The runtime metadata as a decoded structure */ export default class MetadataV0 extends Struct implements MetadataInterface { - constructor (value?: any) { + public constructor (value?: any) { super({ outerEvent: OuterEventMetadata, modules: Vector.with(RuntimeModuleMetadata), @@ -30,7 +30,7 @@ export default class MetadataV0 extends Struct implements MetadataInterface { + public get calls (): Vector { return (this.get('outerDispatch') as OuterDispatchMetadata).calls; } /** * @description Wrapped [[OuterEventEventMetadata]] */ - get events (): Vector { + public get events (): Vector { return (this.get('outerEvent') as OuterEventMetadata).events; } /** * @description Wrapped [[RuntimeModuleMetadata]] */ - get modules (): Vector { + public get modules (): Vector { return this.get('modules') as Vector; } - private get argNames () { - return this.modules.map((modul) => - modul.module.call.functions.map((fn) => - fn.args.map((argument) => argument.type.toString()) + private get argNames (): string[][][] { + return this.modules.map((modul): string[][] => + modul.module.call.functions.map((fn): string[] => + fn.args.map((argument): string => argument.type.toString()) ) ); } - private get eventNames () { - return this.events.map((modul) => - modul.events.map((event) => - event.args.map((argument) => argument.toString()) + private get eventNames (): string[][][] { + return this.events.map((modul): string[][] => + modul.events.map((event): string[] => + event.args.map((argument): string => argument.toString()) ) ); } - private get storageNames () { - return this.modules.map((modul) => + private get storageNames (): string[][][] { + return this.modules.map((modul): string[][] => modul.storage.isSome - ? modul.storage.unwrap().functions.map((fn) => + ? modul.storage.unwrap().functions.map((fn): string[] => fn.type.isMap ? [fn.type.asMap.key.toString(), fn.type.asMap.value.toString()] : [fn.type.asType.toString()] @@ -104,7 +104,7 @@ export default class MetadataV0 extends Struct implements MetadataInterface { + public getUniqTypes (throwError: boolean): string[] { const types = flattenUniq([this.argNames, this.eventNames, this.storageNames]); validateTypes(types, throwError); diff --git a/packages/types/src/Metadata/v0/Modules.ts b/packages/types/src/Metadata/v0/Modules.ts index 3559605592..8feedef304 100644 --- a/packages/types/src/Metadata/v0/Modules.ts +++ b/packages/types/src/Metadata/v0/Modules.ts @@ -12,7 +12,7 @@ import U16 from '../../primitive/U16'; import { StorageMetadata } from './Storage'; export class FunctionArgumentMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, type: Type @@ -22,20 +22,20 @@ export class FunctionArgumentMetadata extends Struct { /** * @description The argument name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description The [[Type]] */ - get type (): Type { + public get type (): Type { return this.get('type') as Type; } } export class FunctionMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ id: U16, name: Text, @@ -47,7 +47,7 @@ export class FunctionMetadata extends Struct { /** * @description The arguments of [[Type]] */ - get args (): Vector { + public get args (): Vector { return this.get('args') as Vector; } @@ -55,14 +55,14 @@ export class FunctionMetadata extends Struct { * @description The [[FunctionArgumentMetadata]] for arguments * @deprecated Use `.args` instead */ - get arguments (): Vector { + public get arguments (): Vector { return this.get('arguments') as Vector; } /** * @description The [[Text]] documentation */ - get documentation (): Vector { + public get documentation (): Vector { return this.get('documentation') as Vector; } @@ -70,27 +70,27 @@ export class FunctionMetadata extends Struct { * @description The [[Text]] documentation * @deprecated Use `.documentation` instead. */ - get docs (): Vector { + public get docs (): Vector { return this.documentation; } /** * @description The `[sectionIndex, methodIndex]` call id */ - get id (): U16 { + public get id (): U16 { return this.get('id') as U16; } /** * @description The call name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } } export class CallMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, functions: Vector.with(FunctionMetadata) @@ -100,19 +100,19 @@ export class CallMetadata extends Struct { /** * @description The functions available as [[FunctionMetadata]] */ - get functions (): Vector { + public get functions (): Vector { return this.get('functions') as Vector; } /** * @description The section name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } } export class ModuleMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, call: CallMetadata @@ -122,20 +122,20 @@ export class ModuleMetadata extends Struct { /** * @description The calls as [[FunctionMetadata]] */ - get call (): CallMetadata { + public get call (): CallMetadata { return this.get('call') as CallMetadata; } /** * @description The name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } } export class RuntimeModuleMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ prefix: Text, module: ModuleMetadata, @@ -146,21 +146,21 @@ export class RuntimeModuleMetadata extends Struct { /** * @description The [[ModuleMetadata]] */ - get module (): ModuleMetadata { + public get module (): ModuleMetadata { return this.get('module') as ModuleMetadata; } /** * @description The prefix */ - get prefix (): Text { + public get prefix (): Text { return this.get('prefix') as Text; } /** * @description The optional [[StorageMetadata]] */ - get storage (): Option { + public get storage (): Option { return this.get('storage') as Option; } } diff --git a/packages/types/src/Metadata/v0/Storage.ts b/packages/types/src/Metadata/v0/Storage.ts index f5cf44221a..81964a7c13 100644 --- a/packages/types/src/Metadata/v0/Storage.ts +++ b/packages/types/src/Metadata/v0/Storage.ts @@ -14,18 +14,18 @@ import Text from '../../primitive/Text'; import Type from '../../primitive/Type'; export class StorageFunctionModifier extends Enum { - constructor (value?: any) { + public constructor (value?: any) { super(['Optional', 'Default', 'Required'], value); } /** * @description `true` if the storage entry is optional */ - get isOptional (): boolean { + public get isOptional (): boolean { return this.toNumber() === 0; } - toJSON (): string { + public toJSON (): string { // This looks prettier in the generated JSON return this.toString(); } @@ -34,7 +34,7 @@ export class StorageFunctionModifier extends Enum { export class MapType extends Struct { private _isLinked = false; - constructor (value?: any) { + public constructor (value?: any) { super({ key: Type, value: Type @@ -48,21 +48,21 @@ export class MapType extends Struct { /** * @description The mapped key as [[Type]] */ - get key (): Type { + public get key (): Type { return this.get('key') as Type; } /** * @description The mapped value as [[Type]] */ - get value (): Type { + public get value (): Type { return this.get('value') as Type; } /** * @description Is this an enumerable linked map */ - get isLinked (): boolean { + public get isLinked (): boolean { return this._isLinked; } } @@ -71,7 +71,7 @@ export class PlainType extends Type { } export class StorageFunctionType extends Enum { - constructor (value?: any, index?: number) { + public constructor (value?: any, index?: number) { super({ PlainType, MapType @@ -81,7 +81,7 @@ export class StorageFunctionType extends Enum { /** * @description The value as a mapped value */ - get asMap (): MapType { + public get asMap (): MapType { assert(this.isMap, `Cannot convert '${this.type}' via asMap`); return this.value as MapType; @@ -90,7 +90,7 @@ export class StorageFunctionType extends Enum { /** * @description The value as a [[Type]] value */ - get asType (): PlainType { + public get asType (): PlainType { assert(this.isPlainType, `Cannot convert '${this.type}' via asType`); return this.value as PlainType; @@ -99,21 +99,21 @@ export class StorageFunctionType extends Enum { /** * @description `true` if the storage entry is a map */ - get isMap (): boolean { + public get isMap (): boolean { return this.toNumber() === 1; } /** * @description `true` if the storage entry is a plain type */ - get isPlainType (): boolean { + public get isPlainType (): boolean { return this.toNumber() === 0; } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { if (this.isMap) { if (this.asMap.isLinked) { return `(${this.asMap.value.toString()}, Linkage<${this.asMap.key.toString()}>)`; @@ -126,16 +126,16 @@ export class StorageFunctionType extends Enum { } } -export type StorageFunctionMetadataValue = { - name: string | Text, - modifier: StorageFunctionModifier | AnyNumber, - type: StorageFunctionType, - fallback: Bytes, - documentation: Vector | Array -}; +export interface StorageFunctionMetadataValue { + name: string | Text; + modifier: StorageFunctionModifier | AnyNumber; + type: StorageFunctionType; + fallback: Bytes; + documentation: Vector | string[]; +} export class StorageFunctionMetadata extends Struct { - constructor (value?: StorageFunctionMetadataValue | Uint8Array) { + public constructor (value?: StorageFunctionMetadataValue | Uint8Array) { super({ name: Text, modifier: StorageFunctionModifier, @@ -149,21 +149,21 @@ export class StorageFunctionMetadata extends Struct { * @description The default value of the storage function * @deprecated Use `.fallback` instead. */ - get default (): Bytes { + public get default (): Bytes { return this.fallback; } /** * @description The default value of the storage function */ - get fallback (): Bytes { + public get fallback (): Bytes { return this.get('fallback') as Bytes; } /** * @description The [[Text]] documentation */ - get documentation (): Vector { + public get documentation (): Vector { return this.get('documentation') as Vector; } @@ -171,34 +171,34 @@ export class StorageFunctionMetadata extends Struct { * @description The [[Text]] documentation * @deprecated Use `.documentation` instead. */ - get docs (): Vector { + public get docs (): Vector { return this.documentation; } /** * @description The key name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description The modifier */ - get modifier (): StorageFunctionModifier { + public get modifier (): StorageFunctionModifier { return this.get('modifier') as StorageFunctionModifier; } /** * @description The [[StorageFunctionType]] */ - get type (): StorageFunctionType { + public get type (): StorageFunctionType { return this.get('type') as StorageFunctionType; } } export class StorageMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ prefix: Text, functions: Vector.with(StorageFunctionMetadata) @@ -208,14 +208,14 @@ export class StorageMetadata extends Struct { /** * @description The [[StorageFunctionMetadata]] for the section */ - get functions (): Vector { + public get functions (): Vector { return this.get('functions') as Vector; } /** * @description The section prefix */ - get prefix (): Text { + public get prefix (): Text { return this.get('prefix') as Text; } } diff --git a/packages/types/src/Metadata/v0/index.ts b/packages/types/src/Metadata/v0/index.ts index 379c902089..6115ad6320 100644 --- a/packages/types/src/Metadata/v0/index.ts +++ b/packages/types/src/Metadata/v0/index.ts @@ -2,6 +2,6 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { default as MetadataV0 } from './Metadata'; +import MetadataV0 from './Metadata'; export default MetadataV0; diff --git a/packages/types/src/Metadata/v0/toV1.ts b/packages/types/src/Metadata/v0/toV1.ts index 203561407d..592148aa3a 100644 --- a/packages/types/src/Metadata/v0/toV1.ts +++ b/packages/types/src/Metadata/v0/toV1.ts @@ -14,21 +14,21 @@ import { EventMetadata } from '../v1/Events'; import MetadataV1, { ModuleMetadata } from '../v1/Metadata'; import { StorageFunctionMetadata } from '../v1/Storage'; -function toV1Calls (modul: RuntimeModuleMetadata) { +function toV1Calls (modul: RuntimeModuleMetadata): Option { return modul.module.call.functions.length === 0 ? new Option(Vector.with(FunctionMetadata)) : new Option(Vector.with(FunctionMetadata), modul.module.call.functions); } -function toV1Events (metadataV0: MetadataV0, prefix: Text) { - const events = metadataV0.events.find((event) => event.name.eq(prefix)); +function toV1Events (metadataV0: MetadataV0, prefix: Text): Option { + const events = metadataV0.events.find((event): boolean => event.name.eq(prefix)); return events ? new Option(Vector.with(EventMetadata), events.events) : new Option(Vector.with(EventMetadata)); } -function toV1Storage (modul: RuntimeModuleMetadata) { +function toV1Storage (modul: RuntimeModuleMetadata): Option { return modul.storage.isNone ? new Option(Vector.with(StorageFunctionMetadata)) : new Option( @@ -42,7 +42,7 @@ function toV1Storage (modul: RuntimeModuleMetadata) { */ export default function toV1 (metadataV0: MetadataV0): MetadataV1 { return new MetadataV1({ - modules: metadataV0.modules.map((modul) => { + modules: metadataV0.modules.map((modul): ModuleMetadata => { // The prefix of this module (capitalized) const prefix = modul.storage.isSome ? modul.storage.unwrap().prefix.toString() diff --git a/packages/types/src/Metadata/v1/Calls.ts b/packages/types/src/Metadata/v1/Calls.ts index 4cd6cde999..4fbe8b54d7 100644 --- a/packages/types/src/Metadata/v1/Calls.ts +++ b/packages/types/src/Metadata/v1/Calls.ts @@ -8,7 +8,7 @@ import Text from '../../primitive/Text'; import Type from '../../primitive/Type'; export class FunctionArgumentMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, type: Type @@ -18,14 +18,14 @@ export class FunctionArgumentMetadata extends Struct { /** * @description The argument name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description The [[Type]] */ - get type (): Type { + public get type (): Type { return this.get('type') as Type; } } @@ -36,7 +36,7 @@ export class FunctionArgumentMetadata extends Struct { * The definition of a call */ export class FunctionMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, args: Vector.with(FunctionArgumentMetadata), @@ -47,14 +47,14 @@ export class FunctionMetadata extends Struct { /** * @description The [[FunctionArgumentMetadata]] for arguments */ - get args (): Vector { + public get args (): Vector { return this.get('args') as Vector; } /** * @description The [[Text]] documentation */ - get documentation (): Vector { + public get documentation (): Vector { return this.get('documentation') as Vector; } @@ -62,14 +62,14 @@ export class FunctionMetadata extends Struct { * @description The [[Text]] documentation * @deprecated Use `.documentation` instead. */ - get docs (): Vector { + public get docs (): Vector { return this.documentation; } /** * @description The call name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } } diff --git a/packages/types/src/Metadata/v1/Metadata.spec.ts b/packages/types/src/Metadata/v1/Metadata.spec.ts index 1b023ef9f2..2e43f074b3 100644 --- a/packages/types/src/Metadata/v1/Metadata.spec.ts +++ b/packages/types/src/Metadata/v1/Metadata.spec.ts @@ -6,7 +6,7 @@ import latestSubstrate from './latest.substrate.v1.json'; import rpcData from './static'; import { decodeLatestSubstrate, defaultValues, toV6 } from '../util/testUtil'; -describe('MetadataV1', () => { +describe('MetadataV1', (): void => { decodeLatestSubstrate(1, rpcData, latestSubstrate); toV6(1, rpcData); diff --git a/packages/types/src/Metadata/v1/Metadata.ts b/packages/types/src/Metadata/v1/Metadata.ts index c9eb2187c9..0dff7432df 100644 --- a/packages/types/src/Metadata/v1/Metadata.ts +++ b/packages/types/src/Metadata/v1/Metadata.ts @@ -20,7 +20,7 @@ import { StorageFunctionMetadata } from './Storage'; * The definition of a module in the system */ export class ModuleMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, prefix: Text, @@ -33,35 +33,35 @@ export class ModuleMetadata extends Struct { /** * @description the module calls */ - get calls (): Option> { + public get calls (): Option> { return this.get('calls') as Option>; } /** * @description the module events */ - get events (): Option> { + public get events (): Option> { return this.get('events') as Option>; } /** * @description the module name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description the module prefix */ - get prefix (): Text { + public get prefix (): Text { return this.get('prefix') as Text; } /** * @description the associated module storage */ - get storage (): Option> { + public get storage (): Option> { return this.get('storage') as Option>; } } @@ -72,7 +72,7 @@ export class ModuleMetadata extends Struct { * The runtime metadata as a decoded structure */ export default class MetadataV1 extends Struct implements MetadataInterface { - constructor (value?: any) { + public constructor (value?: any) { super({ modules: Vector.with(ModuleMetadata) }, value); @@ -81,35 +81,35 @@ export default class MetadataV1 extends Struct implements MetadataInterface { + public get modules (): Vector { return this.get('modules') as Vector; } - private get callNames () { - return this.modules.map((mod) => + private get callNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.calls.isNone ? [] - : mod.calls.unwrap().map((fn) => - fn.args.map((arg) => arg.type.toString()) + : mod.calls.unwrap().map((fn): string[] => + fn.args.map((arg): string => arg.type.toString()) ) ); } - private get eventNames () { - return this.modules.map((mod) => + private get eventNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.events.isNone ? [] - : mod.events.unwrap().map((event) => - event.args.map((arg) => arg.toString()) + : mod.events.unwrap().map((event): string[] => + event.args.map((arg): string => arg.toString()) ) ); } - private get storageNames () { - return this.modules.map((mod) => + private get storageNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.storage.isNone ? [] - : mod.storage.unwrap().map((fn) => + : mod.storage.unwrap().map((fn): string[] => fn.type.isMap ? [fn.type.asMap.key.toString(), fn.type.asMap.value.toString()] : [fn.type.asType.toString()] @@ -120,7 +120,7 @@ export default class MetadataV1 extends Struct implements MetadataInterface { + public getUniqTypes (throwError: boolean): string[] { const types = flattenUniq([this.callNames, this.eventNames, this.storageNames]); validateTypes(types, throwError); diff --git a/packages/types/src/Metadata/v1/index.ts b/packages/types/src/Metadata/v1/index.ts index b2602b2183..f4133697d0 100644 --- a/packages/types/src/Metadata/v1/index.ts +++ b/packages/types/src/Metadata/v1/index.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { default as MetadataV1, ModuleMetadata as ModuleMetadataV1 } from './Metadata'; +import MetadataV1, { ModuleMetadata as ModuleMetadataV1 } from './Metadata'; export default MetadataV1; diff --git a/packages/types/src/Metadata/v2/Metadata.spec.ts b/packages/types/src/Metadata/v2/Metadata.spec.ts index 0737d31130..a296e40751 100644 --- a/packages/types/src/Metadata/v2/Metadata.spec.ts +++ b/packages/types/src/Metadata/v2/Metadata.spec.ts @@ -6,7 +6,7 @@ import latestSubstrate from './latest.substrate.v2.json'; import rpcData from './static'; import { decodeLatestSubstrate, defaultValues, toV6 } from '../util/testUtil'; -describe('MetadataV2', () => { +describe('MetadataV2', (): void => { decodeLatestSubstrate(2, rpcData, latestSubstrate); toV6(2, rpcData); diff --git a/packages/types/src/Metadata/v2/Metadata.ts b/packages/types/src/Metadata/v2/Metadata.ts index 0a89730ce0..7b4ea05086 100644 --- a/packages/types/src/Metadata/v2/Metadata.ts +++ b/packages/types/src/Metadata/v2/Metadata.ts @@ -20,7 +20,7 @@ import { StorageFunctionMetadata } from './Storage'; * The definition of a module in the system */ export class ModuleMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, prefix: Text, @@ -33,35 +33,35 @@ export class ModuleMetadata extends Struct { /** * @description the module calls */ - get calls (): Option> { + public get calls (): Option> { return this.get('calls') as Option>; } /** * @description the module events */ - get events (): Option> { + public get events (): Option> { return this.get('events') as Option>; } /** * @description the module name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description the module prefix */ - get prefix (): Text { + public get prefix (): Text { return this.get('prefix') as Text; } /** * @description the associated module storage */ - get storage (): Option> { + public get storage (): Option> { return this.get('storage') as Option>; } } @@ -72,7 +72,7 @@ export class ModuleMetadata extends Struct { * The runtime metadata as a decoded structure */ export default class MetadataV2 extends Struct implements MetadataInterface { - constructor (value?: any) { + public constructor (value?: any) { super({ modules: Vector.with(ModuleMetadata) }, value); @@ -81,35 +81,35 @@ export default class MetadataV2 extends Struct implements MetadataInterface { + public get modules (): Vector { return this.get('modules') as Vector; } - private get callNames () { - return this.modules.map((mod) => + private get callNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.calls.isNone ? [] - : mod.calls.unwrap().map((fn) => - fn.args.map((arg) => arg.type.toString()) + : mod.calls.unwrap().map((fn): string[] => + fn.args.map((arg): string => arg.type.toString()) ) ); } - private get eventNames () { - return this.modules.map((mod) => + private get eventNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.events.isNone ? [] - : mod.events.unwrap().map((event) => - event.args.map((arg) => arg.toString()) + : mod.events.unwrap().map((event): string[] => + event.args.map((arg): string => arg.toString()) ) ); } - private get storageNames () { - return this.modules.map((mod) => + private get storageNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.storage.isNone ? [] - : mod.storage.unwrap().map((fn) => + : mod.storage.unwrap().map((fn): string[] => fn.type.isMap ? [fn.type.asMap.key.toString(), fn.type.asMap.value.toString()] : [fn.type.asType.toString()] @@ -120,7 +120,7 @@ export default class MetadataV2 extends Struct implements MetadataInterface { + public getUniqTypes (throwError: boolean): string[] { const types = flattenUniq([this.callNames, this.eventNames, this.storageNames]); validateTypes(types, throwError); diff --git a/packages/types/src/Metadata/v2/Storage.ts b/packages/types/src/Metadata/v2/Storage.ts index 26dbece198..2ef36770e3 100644 --- a/packages/types/src/Metadata/v2/Storage.ts +++ b/packages/types/src/Metadata/v2/Storage.ts @@ -22,7 +22,7 @@ export { }; export class MapType extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ key: Type, value: Type, @@ -33,27 +33,27 @@ export class MapType extends Struct { /** * @description The mapped key as [[Type]] */ - get key (): Type { + public get key (): Type { return this.get('key') as Type; } /** * @description The mapped value as [[Type]] */ - get value (): Type { + public get value (): Type { return this.get('value') as Type; } /** * @description Is this an enumerable linked map */ - get isLinked (): boolean { + public get isLinked (): boolean { return (this.get('isLinked') as Bool).valueOf(); } } export class StorageFunctionType extends Enum { - constructor (value?: any, index?: number) { + public constructor (value?: any, index?: number) { super({ PlainType, MapType @@ -63,7 +63,7 @@ export class StorageFunctionType extends Enum { /** * @description The value as a mapped value */ - get asMap (): MapType { + public get asMap (): MapType { assert(this.isMap, `Cannot convert '${this.type}' via asMap`); return this.value as MapType; @@ -72,7 +72,7 @@ export class StorageFunctionType extends Enum { /** * @description The value as a [[Type]] value */ - get asType (): PlainType { + public get asType (): PlainType { assert(this.isPlainType, `Cannot convert '${this.type}' via asType`); return this.value as PlainType; @@ -81,21 +81,21 @@ export class StorageFunctionType extends Enum { /** * @description `true` if the storage entry is a map */ - get isMap (): boolean { + public get isMap (): boolean { return this.toNumber() === 1; } /** * @description `true` if the storage entry is a plain type */ - get isPlainType (): boolean { + public get isPlainType (): boolean { return this.toNumber() === 0; } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { if (this.isMap) { if (this.asMap.isLinked) { return `(${this.asMap.value.toString()}, Linkage<${this.asMap.key.toString()}>)`; @@ -108,13 +108,13 @@ export class StorageFunctionType extends Enum { } } -export type StorageFunctionMetadataValue = { - name: string | Text, - modifier: StorageFunctionModifier | AnyNumber, - type: StorageFunctionType, - fallback: Bytes, - documentation: Vector | Array -}; +export interface StorageFunctionMetadataValue { + name: string | Text; + modifier: StorageFunctionModifier | AnyNumber; + type: StorageFunctionType; + fallback: Bytes; + documentation: Vector | string[]; +} /** * @name ModuleMetadata @@ -122,7 +122,7 @@ export type StorageFunctionMetadataValue = { * The definition of a storage function */ export class StorageFunctionMetadata extends Struct { - constructor (value?: StorageFunctionMetadataValue | Uint8Array) { + public constructor (value?: StorageFunctionMetadataValue | Uint8Array) { super({ name: Text, modifier: StorageFunctionModifier, @@ -136,14 +136,14 @@ export class StorageFunctionMetadata extends Struct { * @description The default value of the storage function * @deprecated Use `.fallback` instead. */ - get default (): Bytes { + public get default (): Bytes { return this.fallback; } /** * @description The [[Text]] documentation */ - get documentation (): Vector { + public get documentation (): Vector { return this.get('documentation') as Vector; } @@ -151,35 +151,35 @@ export class StorageFunctionMetadata extends Struct { * @description The [[Text]] documentation * @deprecated Use `.documentation` instead. */ - get docs (): Vector { + public get docs (): Vector { return this.documentation; } /** * @description The [[Bytes]] fallback default */ - get fallback (): Bytes { + public get fallback (): Bytes { return this.get('fallback') as Bytes; } /** * @description The [[MetadataArgument]] for arguments */ - get modifier (): StorageFunctionModifier { + public get modifier (): StorageFunctionModifier { return this.get('modifier') as StorageFunctionModifier; } /** * @description The call name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description The [[StorageFunctionType]] */ - get type (): StorageFunctionType { + public get type (): StorageFunctionType { return this.get('type') as StorageFunctionType; } } diff --git a/packages/types/src/Metadata/v2/index.ts b/packages/types/src/Metadata/v2/index.ts index b78df7caba..3ece8cc735 100644 --- a/packages/types/src/Metadata/v2/index.ts +++ b/packages/types/src/Metadata/v2/index.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { default as MetadataV2, ModuleMetadata as ModuleMetadataV2 } from './Metadata'; +import MetadataV2, { ModuleMetadata as ModuleMetadataV2 } from './Metadata'; export default MetadataV2; diff --git a/packages/types/src/Metadata/v3/Metadata.spec.ts b/packages/types/src/Metadata/v3/Metadata.spec.ts index 66a834df2c..f7819498df 100644 --- a/packages/types/src/Metadata/v3/Metadata.spec.ts +++ b/packages/types/src/Metadata/v3/Metadata.spec.ts @@ -6,7 +6,7 @@ import latestSubstrate from './latest.substrate.v3.json'; import rpcData from './static'; import { decodeLatestSubstrate, defaultValues, toV6 } from '../util/testUtil'; -describe('MetadataV3', () => { +describe('MetadataV3', (): void => { decodeLatestSubstrate(3, rpcData, latestSubstrate); toV6(3, rpcData); diff --git a/packages/types/src/Metadata/v3/Metadata.ts b/packages/types/src/Metadata/v3/Metadata.ts index c7f3d9cf7f..81bc649c33 100644 --- a/packages/types/src/Metadata/v3/Metadata.ts +++ b/packages/types/src/Metadata/v3/Metadata.ts @@ -20,7 +20,7 @@ import { StorageFunctionMetadata } from './Storage'; * The definition of a module in the system */ export class ModuleMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, prefix: Text, @@ -33,35 +33,35 @@ export class ModuleMetadata extends Struct { /** * @description the module calls */ - get calls (): Option> { + public get calls (): Option> { return this.get('calls') as Option>; } /** * @description the module events */ - get events (): Option> { + public get events (): Option> { return this.get('events') as Option>; } /** * @description the module name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description the module prefix */ - get prefix (): Text { + public get prefix (): Text { return this.get('prefix') as Text; } /** * @description the associated module storage */ - get storage (): Option> { + public get storage (): Option> { return this.get('storage') as Option>; } } @@ -72,7 +72,7 @@ export class ModuleMetadata extends Struct { * The runtime metadata as a decoded structure */ export default class MetadataV3 extends Struct implements MetadataInterface { - constructor (value?: any) { + public constructor (value?: any) { super({ modules: Vector.with(ModuleMetadata) }, value); @@ -81,35 +81,35 @@ export default class MetadataV3 extends Struct implements MetadataInterface { + public get modules (): Vector { return this.get('modules') as Vector; } - private get callNames () { - return this.modules.map((mod) => + private get callNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.calls.isNone ? [] - : mod.calls.unwrap().map((fn) => - fn.args.map((arg) => arg.type.toString()) + : mod.calls.unwrap().map((fn): string[] => + fn.args.map((arg): string => arg.type.toString()) ) ); } - private get eventNames () { - return this.modules.map((mod) => + private get eventNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.events.isNone ? [] - : mod.events.unwrap().map((event) => - event.args.map((arg) => arg.toString()) + : mod.events.unwrap().map((event): string[] => + event.args.map((arg): string => arg.toString()) ) ); } - private get storageNames () { - return this.modules.map((mod) => + private get storageNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.storage.isNone ? [] - : mod.storage.unwrap().map((fn) => { + : mod.storage.unwrap().map((fn): string[] => { if (fn.type.isMap) { return [fn.type.asMap.key.toString(), fn.type.asMap.value.toString()]; } else if (fn.type.isDoubleMap) { @@ -124,7 +124,7 @@ export default class MetadataV3 extends Struct implements MetadataInterface { + public getUniqTypes (throwError: boolean): string[] { const types = flattenUniq([this.callNames, this.eventNames, this.storageNames]); validateTypes(types, throwError); diff --git a/packages/types/src/Metadata/v3/Storage.ts b/packages/types/src/Metadata/v3/Storage.ts index f78379252d..d628cb68b1 100644 --- a/packages/types/src/Metadata/v3/Storage.ts +++ b/packages/types/src/Metadata/v3/Storage.ts @@ -26,7 +26,7 @@ export { }; export class DoubleMapType extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ key1: Type, key2: Type, @@ -38,34 +38,34 @@ export class DoubleMapType extends Struct { /** * @description The mapped key as [[Type]] */ - get key1 (): Type { + public get key1 (): Type { return this.get('key1') as Type; } /** * @description The mapped key as [[Type]] */ - get key2 (): Type { + public get key2 (): Type { return this.get('key2') as Type; } /** * @description The hashing algorithm used to hash key2, as [[Text]] */ - get key2Hasher (): Text { + public get key2Hasher (): Text { return this.get('key2Hasher') as Text; } /** * @description The mapped key as [[Type]] */ - get value (): Type { + public get value (): Type { return this.get('value') as Type; } } export class StorageFunctionType extends Enum { - constructor (value?: any, index?: number) { + public constructor (value?: any, index?: number) { super({ PlainType, MapType, @@ -76,7 +76,7 @@ export class StorageFunctionType extends Enum { /** * @description The value as a mapped value */ - get asDoubleMap (): DoubleMapType { + public get asDoubleMap (): DoubleMapType { assert(this.isDoubleMap, `Cannot convert '${this.type}' via asDoubleMap`); return this.value as DoubleMapType; @@ -85,7 +85,7 @@ export class StorageFunctionType extends Enum { /** * @description The value as a mapped value */ - get asMap (): MapType { + public get asMap (): MapType { assert(this.isMap, `Cannot convert '${this.type}' via asMap`); return this.value as MapType; @@ -94,7 +94,7 @@ export class StorageFunctionType extends Enum { /** * @description The value as a [[Type]] value */ - get asType (): PlainType { + public get asType (): PlainType { assert(this.isPlainType, `Cannot convert '${this.type}' via asType`); return this.value as PlainType; @@ -103,28 +103,28 @@ export class StorageFunctionType extends Enum { /** * @description `true` if the storage entry is a doublemap */ - get isDoubleMap (): boolean { + public get isDoubleMap (): boolean { return this.toNumber() === 2; } /** * @description `true` if the storage entry is a map */ - get isMap (): boolean { + public get isMap (): boolean { return this.toNumber() === 1; } /** * @description `true` if the storage entry is a plain type */ - get isPlainType (): boolean { + public get isPlainType (): boolean { return this.toNumber() === 0; } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { if (this.isDoubleMap) { return `DoubleMap<${this.asDoubleMap.toString()}>`; } @@ -141,13 +141,13 @@ export class StorageFunctionType extends Enum { } } -export type StorageFunctionMetadataValue = { - name: string | Text, - modifier: StorageFunctionModifier | AnyNumber, - type: StorageFunctionType, - fallback: Bytes, - documentation: Vector | Array -}; +export interface StorageFunctionMetadataValue { + name: string | Text; + modifier: StorageFunctionModifier | AnyNumber; + type: StorageFunctionType; + fallback: Bytes; + documentation: Vector | string[]; +} /** * @name StorageFunctionMetadata @@ -155,7 +155,7 @@ export type StorageFunctionMetadataValue = { * The definition of a storage function */ export class StorageFunctionMetadata extends Struct { - constructor (value?: StorageFunctionMetadataValue | Uint8Array) { + public constructor (value?: StorageFunctionMetadataValue | Uint8Array) { super({ name: Text, modifier: StorageFunctionModifier, @@ -169,14 +169,14 @@ export class StorageFunctionMetadata extends Struct { * @description The default value of the storage function * @deprecated Use `.fallback` instead. */ - get default (): Bytes { + public get default (): Bytes { return this.fallback; } /** * @description The [[Text]] documentation */ - get documentation (): Vector { + public get documentation (): Vector { return this.get('documentation') as Vector; } @@ -184,35 +184,35 @@ export class StorageFunctionMetadata extends Struct { * @description The [[Text]] documentation * @deprecated Use `.documentation` instead. */ - get docs (): Vector { + public get docs (): Vector { return this.documentation; } /** * @description The [[Bytes]] fallback default */ - get fallback (): Bytes { + public get fallback (): Bytes { return this.get('fallback') as Bytes; } /** * @description The [[MetadataArgument]] for arguments */ - get modifier (): StorageFunctionModifier { + public get modifier (): StorageFunctionModifier { return this.get('modifier') as StorageFunctionModifier; } /** * @description The call name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description The [[StorageFunctionType]] */ - get type (): StorageFunctionType { + public get type (): StorageFunctionType { return this.get('type') as StorageFunctionType; } } diff --git a/packages/types/src/Metadata/v3/index.ts b/packages/types/src/Metadata/v3/index.ts index 84d77891ce..eaad960c1c 100644 --- a/packages/types/src/Metadata/v3/index.ts +++ b/packages/types/src/Metadata/v3/index.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { default as MetadataV3, ModuleMetadata as ModuleMetadataV3 } from './Metadata'; +import MetadataV3, { ModuleMetadata as ModuleMetadataV3 } from './Metadata'; export default MetadataV3; diff --git a/packages/types/src/Metadata/v3/toV4.ts b/packages/types/src/Metadata/v3/toV4.ts index 1791555c70..8848df0fff 100644 --- a/packages/types/src/Metadata/v3/toV4.ts +++ b/packages/types/src/Metadata/v3/toV4.ts @@ -50,7 +50,8 @@ function toV4StorageFunction (storageFn: StorageFunctionMetadataV3): StorageFunc */ export default function toV4 (metadataV3: MetadataV3): MetadataV4 { return new MetadataV4({ - modules: metadataV3.modules.map((modul) => { + // FIXME, this needs typing, not any + modules: metadataV3.modules.map((modul): any => { return { name: modul.name, prefix: modul.prefix, diff --git a/packages/types/src/Metadata/v4/Metadata.spec.ts b/packages/types/src/Metadata/v4/Metadata.spec.ts index a2e7eafef4..1b358fb402 100644 --- a/packages/types/src/Metadata/v4/Metadata.spec.ts +++ b/packages/types/src/Metadata/v4/Metadata.spec.ts @@ -6,7 +6,7 @@ import latestSubstrate from './latest.substrate.v4.json'; import rpcData from './static'; import { decodeLatestSubstrate, defaultValues, toV6 } from '../util/testUtil'; -describe('MetadataV4', () => { +describe('MetadataV4', (): void => { decodeLatestSubstrate(4, rpcData, latestSubstrate); toV6(4, rpcData); diff --git a/packages/types/src/Metadata/v4/Metadata.ts b/packages/types/src/Metadata/v4/Metadata.ts index ea8c2ff56d..168f50aac3 100644 --- a/packages/types/src/Metadata/v4/Metadata.ts +++ b/packages/types/src/Metadata/v4/Metadata.ts @@ -20,7 +20,7 @@ import { StorageFunctionMetadata } from './Storage'; * The definition of a module in the system */ export class ModuleMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, prefix: Text, @@ -33,35 +33,35 @@ export class ModuleMetadata extends Struct { /** * @description the module calls */ - get calls (): Option> { + public get calls (): Option> { return this.get('calls') as Option>; } /** * @description the module events */ - get events (): Option> { + public get events (): Option> { return this.get('events') as Option>; } /** * @description the module name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description the module prefix */ - get prefix (): Text { + public get prefix (): Text { return this.get('prefix') as Text; } /** * @description the associated module storage */ - get storage (): Option> { + public get storage (): Option> { return this.get('storage') as Option>; } } @@ -72,7 +72,7 @@ export class ModuleMetadata extends Struct { * The runtime metadata as a decoded structure */ export default class MetadataV4 extends Struct implements MetadataInterface { - constructor (value?: any) { + public constructor (value?: any) { super({ modules: Vector.with(ModuleMetadata) }, value); @@ -81,35 +81,35 @@ export default class MetadataV4 extends Struct implements MetadataInterface { + public get modules (): Vector { return this.get('modules') as Vector; } - private get callNames () { - return this.modules.map((mod) => + private get callNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.calls.isNone ? [] - : mod.calls.unwrap().map((fn) => - fn.args.map((arg) => arg.type.toString()) + : mod.calls.unwrap().map((fn): string[] => + fn.args.map((arg): string => arg.type.toString()) ) ); } - private get eventNames () { - return this.modules.map((mod) => + private get eventNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.events.isNone ? [] - : mod.events.unwrap().map((event) => - event.args.map((arg) => arg.toString()) + : mod.events.unwrap().map((event): string[] => + event.args.map((arg): string => arg.toString()) ) ); } - private get storageNames () { - return this.modules.map((mod) => + private get storageNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.storage.isNone ? [] - : mod.storage.unwrap().map((fn) => { + : mod.storage.unwrap().map((fn): string[] => { if (fn.type.isMap) { return [fn.type.asMap.key.toString(), fn.type.asMap.value.toString()]; } else if (fn.type.isDoubleMap) { @@ -124,7 +124,7 @@ export default class MetadataV4 extends Struct implements MetadataInterface { + public getUniqTypes (throwError: boolean): string[] { const types = flattenUniq([this.callNames, this.eventNames, this.storageNames]); validateTypes(types, throwError); diff --git a/packages/types/src/Metadata/v4/Storage.ts b/packages/types/src/Metadata/v4/Storage.ts index 9e0417cc2b..7ecafda049 100644 --- a/packages/types/src/Metadata/v4/Storage.ts +++ b/packages/types/src/Metadata/v4/Storage.ts @@ -23,7 +23,7 @@ export { }; export class MapType extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ hasher: StorageHasher, key: Type, @@ -35,34 +35,34 @@ export class MapType extends Struct { /** * @description The hash algorithm used to hash keys, as [[StorageHasher]] */ - get hasher (): StorageHasher { + public get hasher (): StorageHasher { return this.get('hasher') as StorageHasher; } /** * @description Is this an enumerable linked map */ - get isLinked (): boolean { + public get isLinked (): boolean { return (this.get('isLinked') as Bool).valueOf(); } /** * @description The mapped key as [[Type]] */ - get key (): Type { + public get key (): Type { return this.get('key') as Type; } /** * @description The mapped value as [[Type]] */ - get value (): Type { + public get value (): Type { return this.get('value') as Type; } } export class DoubleMapType extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ hasher: StorageHasher, key1: Type, @@ -75,41 +75,41 @@ export class DoubleMapType extends Struct { /** * @description The hashing algorithm used to hash keys, as [[StorageHasher]] */ - get hasher (): StorageHasher { + public get hasher (): StorageHasher { return this.get('hasher') as StorageHasher; } /** * @description The mapped key as [[Type]] */ - get key1 (): Type { + public get key1 (): Type { return this.get('key1') as Type; } /** * @description The mapped key as [[Type]] */ - get key2 (): Type { + public get key2 (): Type { return this.get('key2') as Type; } /** * @description The hashing algorithm used to hash key2, as [[Text]] */ - get key2Hasher (): Text { + public get key2Hasher (): Text { return this.get('key2Hasher') as Text; } /** * @description The mapped key as [[Type]] */ - get value (): Type { + public get value (): Type { return this.get('value') as Type; } } export class StorageFunctionType extends Enum { - constructor (value?: any, index?: number) { + public constructor (value?: any, index?: number) { super({ PlainType, MapType, @@ -120,7 +120,7 @@ export class StorageFunctionType extends Enum { /** * @description The value as a mapped value */ - get asDoubleMap (): DoubleMapType { + public get asDoubleMap (): DoubleMapType { assert(this.isDoubleMap, `Cannot convert '${this.type}' via asDoubleMap`); return this.value as DoubleMapType; @@ -129,7 +129,7 @@ export class StorageFunctionType extends Enum { /** * @description The value as a mapped value */ - get asMap (): MapType { + public get asMap (): MapType { assert(this.isMap, `Cannot convert '${this.type}' via asMap`); return this.value as MapType; @@ -138,7 +138,7 @@ export class StorageFunctionType extends Enum { /** * @description The value as a [[Type]] value */ - get asType (): PlainType { + public get asType (): PlainType { assert(this.isPlainType, `Cannot convert '${this.type}' via asType`); return this.value as PlainType; @@ -147,28 +147,28 @@ export class StorageFunctionType extends Enum { /** * @description `true` if the storage entry is a doublemap */ - get isDoubleMap (): boolean { + public get isDoubleMap (): boolean { return this.toNumber() === 2; } /** * @description `true` if the storage entry is a map */ - get isMap (): boolean { + public get isMap (): boolean { return this.toNumber() === 1; } /** * @description `true` if the storage entry is a plain type */ - get isPlainType (): boolean { + public get isPlainType (): boolean { return this.toNumber() === 0; } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { if (this.isDoubleMap) { return `DoubleMap<${this.asDoubleMap.value.toString()}>`; } @@ -185,13 +185,13 @@ export class StorageFunctionType extends Enum { } } -export type StorageFunctionMetadataValue = { - name: string | Text, - modifier: StorageFunctionModifier | AnyNumber, - type: StorageFunctionType, - fallback: Bytes, - documentation: Vector | Array -}; +export interface StorageFunctionMetadataValue { + name: string | Text; + modifier: StorageFunctionModifier | AnyNumber; + type: StorageFunctionType; + fallback: Bytes; + documentation: Vector | string[]; +} /** * @name StorageFunctionMetadata @@ -199,7 +199,7 @@ export type StorageFunctionMetadataValue = { * The definition of a storage function */ export class StorageFunctionMetadata extends Struct { - constructor (value?: StorageFunctionMetadataValue | Uint8Array) { + public constructor (value?: StorageFunctionMetadataValue | Uint8Array) { super({ name: Text, modifier: StorageFunctionModifier, @@ -213,21 +213,21 @@ export class StorageFunctionMetadata extends Struct { * @description The default value of the storage function * @deprecated Use `.fallback` instead. */ - get default (): Bytes { + public get default (): Bytes { return this.fallback; } /** * @description The default value of the storage function */ - get fallback (): Bytes { + public get fallback (): Bytes { return this.get('fallback') as Bytes; } /** * @description The [[Text]] documentation */ - get documentation (): Vector { + public get documentation (): Vector { return this.get('documentation') as Vector; } @@ -235,28 +235,28 @@ export class StorageFunctionMetadata extends Struct { * @description The [[Text]] documentation * @deprecated Use `.documentation` instead. */ - get docs (): Vector { + public get docs (): Vector { return this.documentation; } /** * @description The key name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description The modifier */ - get modifier (): StorageFunctionModifier { + public get modifier (): StorageFunctionModifier { return this.get('modifier') as StorageFunctionModifier; } /** * @description The [[StorageFunctionType]] */ - get type (): StorageFunctionType { + public get type (): StorageFunctionType { return this.get('type') as StorageFunctionType; } } diff --git a/packages/types/src/Metadata/v4/index.ts b/packages/types/src/Metadata/v4/index.ts index 1225541d08..76f851e746 100644 --- a/packages/types/src/Metadata/v4/index.ts +++ b/packages/types/src/Metadata/v4/index.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { default as MetadataV4, ModuleMetadata as ModuleMetadataV4 } from './Metadata'; +import MetadataV4, { ModuleMetadata as ModuleMetadataV4 } from './Metadata'; export default MetadataV4; diff --git a/packages/types/src/Metadata/v4/toV5.ts b/packages/types/src/Metadata/v4/toV5.ts index 515c8d6322..11419d7311 100644 --- a/packages/types/src/Metadata/v4/toV5.ts +++ b/packages/types/src/Metadata/v4/toV5.ts @@ -60,7 +60,8 @@ function toV5StorageFunction (storageFn: StorageFunctionMetadataV4): StorageFunc */ export default function toV5 (metadataV4: MetadataV4): MetadataV5 { return new MetadataV5({ - modules: metadataV4.modules.map((modul) => { + // FIXME, this needs typing, not any + modules: metadataV4.modules.map((modul): any => { return { name: modul.name, prefix: modul.prefix, diff --git a/packages/types/src/Metadata/v5/Metadata.spec.ts b/packages/types/src/Metadata/v5/Metadata.spec.ts index 2706c8bb82..f64351a564 100644 --- a/packages/types/src/Metadata/v5/Metadata.spec.ts +++ b/packages/types/src/Metadata/v5/Metadata.spec.ts @@ -8,7 +8,7 @@ import polkadotData from './static.polkadot'; import substrateData from './static'; import { decodeLatestSubstrate, defaultValues, toV6 } from '../util/testUtil'; -describe('MetadataV5 (substrate)', () => { +describe('MetadataV5 (substrate)', (): void => { decodeLatestSubstrate(5, substrateData, substrateJson); toV6(5, substrateData); @@ -16,7 +16,7 @@ describe('MetadataV5 (substrate)', () => { defaultValues(substrateData); }); -describe('MetadataV5 (polkadot)', () => { +describe('MetadataV5 (polkadot)', (): void => { decodeLatestSubstrate(5, polkadotData, polkadotJson); toV6(5, polkadotData); diff --git a/packages/types/src/Metadata/v5/Metadata.ts b/packages/types/src/Metadata/v5/Metadata.ts index 85492f81c6..be5dea4d15 100644 --- a/packages/types/src/Metadata/v5/Metadata.ts +++ b/packages/types/src/Metadata/v5/Metadata.ts @@ -20,7 +20,7 @@ import { StorageFunctionMetadata } from './Storage'; * The definition of a module in the system */ export class ModuleMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, prefix: Text, @@ -33,35 +33,35 @@ export class ModuleMetadata extends Struct { /** * @description the module calls */ - get calls (): Option> { + public get calls (): Option> { return this.get('calls') as Option>; } /** * @description the module events */ - get events (): Option> { + public get events (): Option> { return this.get('events') as Option>; } /** * @description the module name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description the module prefix */ - get prefix (): Text { + public get prefix (): Text { return this.get('prefix') as Text; } /** * @description the associated module storage */ - get storage (): Option> { + public get storage (): Option> { return this.get('storage') as Option>; } } @@ -72,7 +72,7 @@ export class ModuleMetadata extends Struct { * The runtime metadata as a decoded structure */ export default class MetadataV5 extends Struct implements MetadataInterface { - constructor (value?: any) { + public constructor (value?: any) { super({ modules: Vector.with(ModuleMetadata) }, value); @@ -81,35 +81,35 @@ export default class MetadataV5 extends Struct implements MetadataInterface { + public get modules (): Vector { return this.get('modules') as Vector; } - private get callNames () { - return this.modules.map((mod) => + private get callNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.calls.isNone ? [] - : mod.calls.unwrap().map((fn) => - fn.args.map((arg) => arg.type.toString()) + : mod.calls.unwrap().map((fn): string[] => + fn.args.map((arg): string => arg.type.toString()) ) ); } - private get eventNames () { - return this.modules.map((mod) => + private get eventNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.events.isNone ? [] - : mod.events.unwrap().map((event) => - event.args.map((arg) => arg.toString()) + : mod.events.unwrap().map((event): string[] => + event.args.map((arg): string => arg.toString()) ) ); } - private get storageNames () { - return this.modules.map((mod) => + private get storageNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.storage.isNone ? [] - : mod.storage.unwrap().map((fn) => { + : mod.storage.unwrap().map((fn): string[] => { if (fn.type.isMap) { return [fn.type.asMap.key.toString(), fn.type.asMap.value.toString()]; } else if (fn.type.isDoubleMap) { @@ -124,7 +124,7 @@ export default class MetadataV5 extends Struct implements MetadataInterface { + public getUniqTypes (throwError: boolean): string[] { const types = flattenUniq([this.callNames, this.eventNames, this.storageNames]); validateTypes(types, throwError); diff --git a/packages/types/src/Metadata/v5/Storage.ts b/packages/types/src/Metadata/v5/Storage.ts index d140bae1aa..147aa39420 100644 --- a/packages/types/src/Metadata/v5/Storage.ts +++ b/packages/types/src/Metadata/v5/Storage.ts @@ -23,7 +23,7 @@ export { }; export class DoubleMapType extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ hasher: StorageHasher, key1: Type, @@ -36,41 +36,41 @@ export class DoubleMapType extends Struct { /** * @description The hashing algorithm used to hash keys, as [[StorageHasher]] */ - get hasher (): StorageHasher { + public get hasher (): StorageHasher { return this.get('hasher') as StorageHasher; } /** * @description The mapped key as [[Type]] */ - get key1 (): Type { + public get key1 (): Type { return this.get('key1') as Type; } /** * @description The mapped key as [[Type]] */ - get key2 (): Type { + public get key2 (): Type { return this.get('key2') as Type; } /** * @description The hashing algorithm used to hash key2, as [[StorageHasher]] */ - get key2Hasher (): StorageHasher { + public get key2Hasher (): StorageHasher { return this.get('key2Hasher') as StorageHasher; } /** * @description The mapped key as [[Type]] */ - get value (): Type { + public get value (): Type { return this.get('value') as Type; } } export class StorageFunctionType extends Enum { - constructor (value?: any, index?: number) { + public constructor (value?: any, index?: number) { super({ PlainType, MapType, @@ -81,7 +81,7 @@ export class StorageFunctionType extends Enum { /** * @description The value as a mapped value */ - get asDoubleMap (): DoubleMapType { + public get asDoubleMap (): DoubleMapType { assert(this.isDoubleMap, `Cannot convert '${this.type}' via asDoubleMap`); return this.value as DoubleMapType; @@ -90,7 +90,7 @@ export class StorageFunctionType extends Enum { /** * @description The value as a mapped value */ - get asMap (): MapType { + public get asMap (): MapType { assert(this.isMap, `Cannot convert '${this.type}' via asMap`); return this.value as MapType; @@ -99,7 +99,7 @@ export class StorageFunctionType extends Enum { /** * @description The value as a [[Type]] value */ - get asType (): PlainType { + public get asType (): PlainType { assert(this.isPlainType, `Cannot convert '${this.type}' via asType`); return this.value as PlainType; @@ -108,28 +108,28 @@ export class StorageFunctionType extends Enum { /** * @description `true` if the storage entry is a doublemap */ - get isDoubleMap (): boolean { + public get isDoubleMap (): boolean { return this.toNumber() === 2; } /** * @description `true` if the storage entry is a map */ - get isMap (): boolean { + public get isMap (): boolean { return this.toNumber() === 1; } /** * @description `true` if the storage entry is a plain type */ - get isPlainType (): boolean { + public get isPlainType (): boolean { return this.toNumber() === 0; } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { if (this.isDoubleMap) { return `DoubleMap<${this.asDoubleMap.value.toString()}>`; } @@ -146,13 +146,13 @@ export class StorageFunctionType extends Enum { } } -export type StorageFunctionMetadataValue = { - name: string | Text, - modifier: StorageFunctionModifier | AnyNumber, - type: StorageFunctionType, - fallback: Bytes, - documentation: Vector | Array -}; +export interface StorageFunctionMetadataValue { + name: string | Text; + modifier: StorageFunctionModifier | AnyNumber; + type: StorageFunctionType; + fallback: Bytes; + documentation: Vector | string[]; +} /** * @name StorageFunctionMetadata @@ -160,7 +160,7 @@ export type StorageFunctionMetadataValue = { * The definition of a storage function */ export class StorageFunctionMetadata extends Struct { - constructor (value?: StorageFunctionMetadataValue | Uint8Array) { + public constructor (value?: StorageFunctionMetadataValue | Uint8Array) { super({ name: Text, modifier: StorageFunctionModifier, @@ -174,21 +174,21 @@ export class StorageFunctionMetadata extends Struct { * @description The default value of the storage function * @deprecated Use `.fallback` instead. */ - get default (): Bytes { + public get default (): Bytes { return this.fallback; } /** * @description The default value of the storage function */ - get fallback (): Bytes { + public get fallback (): Bytes { return this.get('fallback') as Bytes; } /** * @description The [[Text]] documentation */ - get documentation (): Vector { + public get documentation (): Vector { return this.get('documentation') as Vector; } @@ -196,28 +196,28 @@ export class StorageFunctionMetadata extends Struct { * @description The [[Text]] documentation * @deprecated Use `.documentation` instead. */ - get docs (): Vector { + public get docs (): Vector { return this.documentation; } /** * @description The key name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description The modifier */ - get modifier (): StorageFunctionModifier { + public get modifier (): StorageFunctionModifier { return this.get('modifier') as StorageFunctionModifier; } /** * @description The [[StorageFunctionType]] */ - get type (): StorageFunctionType { + public get type (): StorageFunctionType { return this.get('type') as StorageFunctionType; } } diff --git a/packages/types/src/Metadata/v5/index.ts b/packages/types/src/Metadata/v5/index.ts index 6ee8a9fab4..4cd1d4a265 100644 --- a/packages/types/src/Metadata/v5/index.ts +++ b/packages/types/src/Metadata/v5/index.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { default as MetadataV5, ModuleMetadata as ModuleMetadataV5 } from './Metadata'; +import MetadataV5, { ModuleMetadata as ModuleMetadataV5 } from './Metadata'; export default MetadataV5; diff --git a/packages/types/src/Metadata/v5/toV6.ts b/packages/types/src/Metadata/v5/toV6.ts index 8ba328f4b5..fc646cc965 100644 --- a/packages/types/src/Metadata/v5/toV6.ts +++ b/packages/types/src/Metadata/v5/toV6.ts @@ -11,7 +11,8 @@ import MetadataV6 from '../v6'; */ export default function toV6 (metadataV5: MetadataV5): MetadataV6 { return new MetadataV6({ - modules: metadataV5.modules.map((modul) => { + // FIXME, this needs typing, not any + modules: metadataV5.modules.map((modul): any => { return { name: modul.name, prefix: modul.prefix, diff --git a/packages/types/src/Metadata/v6/Constants.ts b/packages/types/src/Metadata/v6/Constants.ts index 8b56367ff9..591c286ba5 100644 --- a/packages/types/src/Metadata/v6/Constants.ts +++ b/packages/types/src/Metadata/v6/Constants.ts @@ -9,7 +9,7 @@ import Struct from '../../codec/Struct'; import Vector from '../../codec/Vector'; export class ModuleConstantMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, type: Type, @@ -21,28 +21,28 @@ export class ModuleConstantMetadata extends Struct { /** * @description The argument name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description The [[Type]] */ - get type (): Type { + public get type (): Type { return this.get('type') as Type; } /** * @description The value as [[Bytes]] */ - get value (): Bytes { + public get value (): Bytes { return this.get('value') as Bytes; } /** * @description The documentation */ - get documentation (): Vector { + public get documentation (): Vector { return this.get('documentation') as Vector; } } diff --git a/packages/types/src/Metadata/v6/Metadata.spec.ts b/packages/types/src/Metadata/v6/Metadata.spec.ts index 5c7451636f..24cbbd2012 100644 --- a/packages/types/src/Metadata/v6/Metadata.spec.ts +++ b/packages/types/src/Metadata/v6/Metadata.spec.ts @@ -6,7 +6,7 @@ import substrateJson from './latest.substrate.v6.json'; import substrateData from './static'; import { decodeLatestSubstrate, defaultValues, toV6 } from '../util/testUtil'; -describe('MetadataV6 (substrate)', () => { +describe('MetadataV6 (substrate)', (): void => { decodeLatestSubstrate(6, substrateData, substrateJson); toV6(6, substrateData); diff --git a/packages/types/src/Metadata/v6/Metadata.ts b/packages/types/src/Metadata/v6/Metadata.ts index aa6a51857c..293457c319 100644 --- a/packages/types/src/Metadata/v6/Metadata.ts +++ b/packages/types/src/Metadata/v6/Metadata.ts @@ -21,7 +21,7 @@ import { StorageEntryMetadata } from './Storage'; * The definition of a module in the system */ export class ModuleMetadata extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ name: Text, prefix: Text, @@ -35,42 +35,42 @@ export class ModuleMetadata extends Struct { /** * @description the module calls */ - get calls (): Option> { + public get calls (): Option> { return this.get('calls') as Option>; } /** * @description the module constants */ - get constants (): Vector { + public get constants (): Vector { return this.get('constants') as Vector; } /** * @description the module events */ - get events (): Option> { + public get events (): Option> { return this.get('events') as Option>; } /** * @description the module name */ - get name (): Text { + public get name (): Text { return this.get('name') as Text; } /** * @description the module prefix */ - get prefix (): Text { + public get prefix (): Text { return this.get('prefix') as Text; } /** * @description the associated module storage */ - get storage (): Option> { + public get storage (): Option> { return this.get('storage') as Option>; } } @@ -81,7 +81,7 @@ export class ModuleMetadata extends Struct { * The runtime metadata as a decoded structure */ export default class MetadataV6 extends Struct implements MetadataInterface { - constructor (value?: any) { + public constructor (value?: any) { super({ modules: Vector.with(ModuleMetadata) }, value); @@ -90,43 +90,43 @@ export default class MetadataV6 extends Struct implements MetadataInterface { + public get modules (): Vector { return this.get('modules') as Vector; } - private get callNames () { - return this.modules.map((mod) => + private get callNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.calls.isNone ? [] - : mod.calls.unwrap().map((fn) => - fn.args.map((arg) => arg.type.toString()) + : mod.calls.unwrap().map((fn): string[] => + fn.args.map((arg): string => arg.type.toString()) ) ); } - private get constantNames () { - return this.modules.map((mod) => - mod.constants.map((c) => + private get constantNames (): string[][] { + return this.modules.map((mod): string[] => + mod.constants.map((c): string => c.type.toString() ) ); } - private get eventNames () { - return this.modules.map((mod) => + private get eventNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.events.isNone ? [] - : mod.events.unwrap().map((event) => - event.args.map((arg) => arg.toString()) + : mod.events.unwrap().map((event): string[] => + event.args.map((arg): string => arg.toString()) ) ); } - private get storageNames () { - return this.modules.map((mod) => + private get storageNames (): string[][][] { + return this.modules.map((mod): string[][] => mod.storage.isNone ? [] - : mod.storage.unwrap().map((fn) => { + : mod.storage.unwrap().map((fn): string[] => { if (fn.type.isMap) { return [fn.type.asMap.key.toString(), fn.type.asMap.value.toString()]; } else if (fn.type.isDoubleMap) { @@ -141,7 +141,7 @@ export default class MetadataV6 extends Struct implements MetadataInterface { + public getUniqTypes (throwError: boolean): string[] { const types = flattenUniq([this.callNames, this.constantNames, this.eventNames, this.storageNames]); validateTypes(types, throwError); diff --git a/packages/types/src/Metadata/v6/index.ts b/packages/types/src/Metadata/v6/index.ts index a3900c2d26..c49086d527 100644 --- a/packages/types/src/Metadata/v6/index.ts +++ b/packages/types/src/Metadata/v6/index.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { default as MetadataV6, ModuleMetadata as ModuleMetadataV6 } from './Metadata'; +import MetadataV6, { ModuleMetadata as ModuleMetadataV6 } from './Metadata'; export default MetadataV6; diff --git a/packages/types/src/codec/AbstractArray.ts b/packages/types/src/codec/AbstractArray.ts index a844d492dd..c84339c6d9 100644 --- a/packages/types/src/codec/AbstractArray.ts +++ b/packages/types/src/codec/AbstractArray.ts @@ -5,7 +5,7 @@ import { u8aConcat, u8aToHex } from '@polkadot/util'; import Compact from './Compact'; -import { AnyJsonArray, Codec } from '../types'; +import { AnyJson, AnyJsonArray, Codec } from '../types'; import { compareArray } from './utils'; /** @@ -19,15 +19,15 @@ export default abstract class AbstractArray extends Array im /** * @description Checks if the value is an empty value */ - get isEmpty (): boolean { + public get isEmpty (): boolean { return this.length === 0; } /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { - return this.reduce((total, raw) => { + public get encodedLength (): number { + return this.reduce((total, raw): number => { return total + raw.encodedLength; }, Compact.encodeU8a(this.length).length); } @@ -35,7 +35,7 @@ export default abstract class AbstractArray extends Array im /** * @description The length of the value */ - get length (): number { + public get length (): number { // only included here since we ignore inherited docs return super.length; } @@ -43,29 +43,29 @@ export default abstract class AbstractArray extends Array im /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { return compareArray(this, other); } /** * @description Converts the Object to an standard JavaScript Array */ - toArray (): Array { + public toArray (): T[] { return Array.from(this); } /** * @description Returns a hex string representation of the value */ - toHex (): string { + public toHex (): string { return u8aToHex(this.toU8a()); } /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): AnyJsonArray { - return this.map((entry) => + public toJSON (): AnyJsonArray { + return this.map((entry): AnyJson => entry.toJSON() ); } @@ -78,9 +78,9 @@ export default abstract class AbstractArray extends Array im /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { // Overwrite the default toString representation of Array. - const data = this.map((entry) => + const data = this.map((entry): string => entry.toString() ); @@ -91,8 +91,8 @@ export default abstract class AbstractArray extends Array im * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { - const encoded = this.map((entry) => + public toU8a (isBare?: boolean): Uint8Array { + const encoded = this.map((entry): Uint8Array => entry.toU8a(isBare) ); @@ -113,7 +113,7 @@ export default abstract class AbstractArray extends Array im * @param callbackfn The filter function * @param thisArg The `this` object to apply the result to */ - filter (callbackfn: (value: T, index: number, array: Array) => any, thisArg?: any): Array { + public filter (callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[] { return this.toArray().filter(callbackfn, thisArg); } @@ -122,7 +122,7 @@ export default abstract class AbstractArray extends Array im * @param callbackfn The mapping function * @param thisArg The `this` onject to apply the result to */ - map (callbackfn: (value: T, index: number, array: Array) => U, thisArg?: any): Array { + public map (callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[] { return this.toArray().map(callbackfn, thisArg); } } diff --git a/packages/types/src/codec/AbstractInt.ts b/packages/types/src/codec/AbstractInt.ts index b67f5c50dc..6f07f3a072 100644 --- a/packages/types/src/codec/AbstractInt.ts +++ b/packages/types/src/codec/AbstractInt.ts @@ -20,10 +20,12 @@ export const DEFAULT_UINT_BITS = 64; // - Apart from encoding/decoding we don't actually keep check on the sizes, is this good enough? export default abstract class AbstractInt extends BN implements Codec { protected _bitLength: UIntBitLength; + private _isHexJson: boolean; + private _isNegative: boolean; - constructor ( + public constructor ( isNegative: boolean, value: AnyNumber = 0, bitLength: UIntBitLength = DEFAULT_UINT_BITS, isHexJson: boolean = true) { @@ -36,7 +38,7 @@ export default abstract class AbstractInt extends BN implements Codec { this._isNegative = isNegative; } - static decodeAbstracInt (value: AnyNumber, bitLength: UIntBitLength, isNegative: boolean): string { + public static decodeAbstracInt (value: AnyNumber, bitLength: UIntBitLength, isNegative: boolean): string { // This function returns a string, which will be passed in the BN // constructor. It would be ideal to actually return a BN, but there's a // bug: https://github.com/indutny/bn.js/issues/206. @@ -63,28 +65,29 @@ export default abstract class AbstractInt extends BN implements Codec { /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { return this._bitLength / 8; } /** * @description Checks if the value is a zero value (align elsewhere) */ - get isEmpty (): boolean { + public get isEmpty (): boolean { return this.isZero(); } /** * @description Returns the number of bits in the value */ - bitLength (): UIntBitLength { + public bitLength (): UIntBitLength { return this._bitLength; } /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + public eq (other?: any): boolean { // Here we are actually overriding the built-in .eq to take care of both // number and BN inputs (no `.eqn` needed) - numbers will be converted return super.eq( @@ -97,7 +100,7 @@ export default abstract class AbstractInt extends BN implements Codec { /** * @description Returns the BN representation of the number. (Compatibility) */ - toBn (): BN { + public toBn (): BN { return this; } @@ -109,7 +112,7 @@ export default abstract class AbstractInt extends BN implements Codec { /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): any { + public toJSON (): any { // FIXME this return type should by string | number, but BN's return type // is string. // Maximum allowed integer for JS is 2^53 - 1, set limit at 52 @@ -127,7 +130,7 @@ export default abstract class AbstractInt extends BN implements Codec { * @description Returns the string representation of the value * @param base The base to use for the conversion */ - toString (base?: number): string { + public toString (base?: number): string { // only included here since we do not inherit docs return super.toString(base); } diff --git a/packages/types/src/codec/Base.ts b/packages/types/src/codec/Base.ts index 56dadd87e1..7db0cb3b3f 100644 --- a/packages/types/src/codec/Base.ts +++ b/packages/types/src/codec/Base.ts @@ -9,7 +9,7 @@ export default class Base { protected raw: T; - constructor (value?: any) { + public constructor (value?: any) { this.raw = value; } } diff --git a/packages/types/src/codec/Compact.spec.ts b/packages/types/src/codec/Compact.spec.ts index 2904111feb..a8438c84b8 100644 --- a/packages/types/src/codec/Compact.spec.ts +++ b/packages/types/src/codec/Compact.spec.ts @@ -11,9 +11,9 @@ import BlockNumber from '../type/BlockNumber'; import Compact from './Compact'; import UInt from './UInt'; -describe('Compact', () => { - describe('encodeU8a', () => { - it('encodes short u8', () => { +describe('Compact', (): void => { + describe('encodeU8a', (): void => { + it('encodes short u8', (): void => { expect( Compact.encodeU8a(18) ).toEqual( @@ -21,7 +21,7 @@ describe('Compact', () => { ); }); - it('encodes max u8 values', () => { + it('encodes max u8 values', (): void => { expect( Compact.encodeU8a(new UInt(63)) ).toEqual( @@ -29,7 +29,7 @@ describe('Compact', () => { ); }); - it('encodes basic u16 value', () => { + it('encodes basic u16 value', (): void => { expect( Compact.encodeU8a(511) ).toEqual( @@ -37,7 +37,7 @@ describe('Compact', () => { ); }); - it('encodes basic ua6 (not at edge)', () => { + it('encodes basic ua6 (not at edge)', (): void => { expect( Compact.encodeU8a(111) ).toEqual( @@ -45,7 +45,7 @@ describe('Compact', () => { ); }); - it('encodes basic u32 values (short)', () => { + it('encodes basic u32 values (short)', (): void => { expect( Compact.encodeU8a(0xffff) ).toEqual( @@ -53,7 +53,7 @@ describe('Compact', () => { ); }); - it('encodes basic u32 values (full)', () => { + it('encodes basic u32 values (full)', (): void => { expect( Compact.encodeU8a(0xfffffff9) ).toEqual( @@ -61,7 +61,7 @@ describe('Compact', () => { ); }); - it('encondes a large balance', () => { + it('encondes a large balance', (): void => { expect( Compact.encodeU8a(new Balance('0x5af3107a4000')) ).toEqual( @@ -73,86 +73,86 @@ describe('Compact', () => { }); }); - describe('decodeU8a', () => { - it('decoded u8 value', () => { + describe('decodeU8a', (): void => { + it('decoded u8 value', (): void => { expect( Compact.decodeU8a(new Uint8Array([0b11111100]), 32) ).toEqual([1, new BN(63)]); }); - it('decodes from same u16 encoded value', () => { + it('decodes from same u16 encoded value', (): void => { expect( Compact.decodeU8a(new Uint8Array([0b11111101, 0b00000111]), 32) ).toEqual([2, new BN(511)]); }); - it('decodes from same u32 encoded value (short)', () => { + it('decodes from same u32 encoded value (short)', (): void => { expect( Compact.decodeU8a(new Uint8Array([254, 255, 3, 0]), 32) ).toEqual([4, new BN(0xffff)]); }); - it('decodes from same u32 encoded value (full)', () => { + it('decodes from same u32 encoded value (full)', (): void => { expect( Compact.decodeU8a(new Uint8Array([3, 249, 255, 255, 255]), 32) ).toEqual([5, new BN(0xfffffff9)]); }); - it('decodes from same u32 as u64 encoded value (full, default)', () => { + it('decodes from same u32 as u64 encoded value (full, default)', (): void => { expect( Compact.decodeU8a(new Uint8Array([3, 249, 255, 255, 255]), 64) ).toEqual([5, new BN(0xfffffff9)]); }); }); - describe('constructor', () => { - it('has the correct bitLength for constructor values (BlockNumber)', () => { + describe('constructor', (): void => { + it('has the correct bitLength for constructor values (BlockNumber)', (): void => { expect( new Compact(BlockNumber, 0xfffffff9).bitLength() ).toEqual(64); }); - it('has the correct encodedLength for constructor values (BlockNumber)', () => { + it('has the correct encodedLength for constructor values (BlockNumber)', (): void => { expect( new Compact(BlockNumber, 0xfffffff9).encodedLength ).toEqual(5); }); - it('has the correct encodedLength for constructor values (u32)', () => { + it('has the correct encodedLength for constructor values (u32)', (): void => { expect( new Compact(U32, 0xffff9).encodedLength ).toEqual(4); }); - it('constructs properly via U8a as U32', () => { + it('constructs properly via U8a as U32', (): void => { expect( new Compact(U32, new Uint8Array([254, 255, 3, 0])).toNumber() ).toEqual(new BN(0xffff).toNumber()); }); - it('constructs properly via number as Moment', () => { + it('constructs properly via number as Moment', (): void => { expect( new Compact(Moment, 1537968546).toString().startsWith('Wed Sep 26 2018') // The time depends on the timezone this test is run in ).toBe(true); }); }); - describe('utils', () => { - it('compares against another Compact', () => { + describe('utils', (): void => { + it('compares against another Compact', (): void => { expect(new Compact(U32, 12345).eq(new Compact(U32, 12345))).toBe(true); }); - it('compares against a primitive', () => { + it('compares against a primitive', (): void => { expect(new Compact(U32, 12345).eq(12345)).toBe(true); }); - it('unwraps to the wrapped value', () => { + it('unwraps to the wrapped value', (): void => { expect(new Compact(U32, 12345).unwrap() instanceof U32).toBe(true); }); }); - describe('helpers', () => { - it('correctly adds the length prefix', () => { + describe('helpers', (): void => { + it('correctly adds the length prefix', (): void => { expect( Compact.addLengthPrefix(Uint8Array.from([12, 13])) ).toEqual(Uint8Array.from([2 << 2, 12, 13])); diff --git a/packages/types/src/codec/Compact.ts b/packages/types/src/codec/Compact.ts index 38b629e174..f6852d7d94 100644 --- a/packages/types/src/codec/Compact.ts +++ b/packages/types/src/codec/Compact.ts @@ -21,13 +21,13 @@ import UInt from './UInt'; * a number and making the compact representation thereof */ export default class Compact extends Base implements Codec { - constructor (Type: Constructor, value: Compact | AnyNumber = 0) { + public constructor (Type: Constructor, value: Compact | AnyNumber = 0) { super(Compact.decodeCompact(Type, value)); } - static with (Type: Constructor): Constructor { + public static with (Type: Constructor): Constructor { return class extends Compact { - constructor (value?: any) { + public constructor (value?: any) { super(Type, value); } }; @@ -38,17 +38,19 @@ export default class Compact extends Base implements Codec { * * @param u8a - The Uint8Array to be prefixed */ - static addLengthPrefix = compactAddLength; - static decodeU8a = compactFromU8a; - static encodeU8a = compactToU8a; + public static addLengthPrefix = compactAddLength; - static stripLengthPrefix (u8a: Uint8Array, bitLength: UIntBitLength = DEFAULT_BITLENGTH): Uint8Array { + public static decodeU8a = compactFromU8a; + + public static encodeU8a = compactToU8a; + + public static stripLengthPrefix (u8a: Uint8Array, bitLength: UIntBitLength = DEFAULT_BITLENGTH): Uint8Array { const [, value] = compactStripLength(u8a, bitLength); return value; } - static decodeCompact (Type: Constructor, value: Compact | AnyNumber): Moment | UInt { + public static decodeCompact (Type: Constructor, value: Compact | AnyNumber): Moment | UInt { if (value instanceof Compact) { return new Type(value.raw); } else if (isString(value)) { @@ -69,28 +71,28 @@ export default class Compact extends Base implements Codec { /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { return this.toU8a().length; } /** * @description Checks if the value is an empty value */ - get isEmpty (): boolean { + public get isEmpty (): boolean { return this.raw.isEmpty; } /** * @description Returns the number of bits in the value */ - bitLength (): UIntBitLength { + public bitLength (): UIntBitLength { return this.raw.bitLength(); } /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { return this.raw.eq( other instanceof Compact ? other.raw @@ -101,42 +103,42 @@ export default class Compact extends Base implements Codec { /** * @description Returns the BN representation of the number */ - toBn (): BN { + public toBn (): BN { return this.raw.toBn(); } /** * @description Returns a hex string representation of the value */ - toHex (isLe?: boolean): any { + public toHex (isLe?: boolean): any { return this.raw.toHex(isLe); } /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): string | number { + public toJSON (): string | number { return this.raw.toJSON(); } /** * @description Returns the number representation for the value */ - toNumber (): number { + public toNumber (): number { return this.raw.toNumber(); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return `Compact<${this.raw.toRawType()}>`; } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { return this.raw.toString(); } @@ -144,14 +146,15 @@ export default class Compact extends Base implements Codec { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public toU8a (isBare?: boolean): Uint8Array { return Compact.encodeU8a(this.raw.toBn()); } /** * @description Returns the embedded [[UInt]] or [[Moment]] value */ - unwrap (): UInt | Moment { + public unwrap (): UInt | Moment { return this.raw; } } diff --git a/packages/types/src/codec/EnumType.spec.ts b/packages/types/src/codec/EnumType.spec.ts index a766ad498c..f8e9bccd3e 100644 --- a/packages/types/src/codec/EnumType.spec.ts +++ b/packages/types/src/codec/EnumType.spec.ts @@ -7,9 +7,9 @@ import Null from '../primitive/Null'; import Text from '../primitive/Text'; import U32 from '../primitive/U32'; -describe('Enum', () => { - describe('typed enum (previously EnumType)', () => { - it('provides a clean toString() (value)', () => { +describe('Enum', (): void => { + describe('typed enum (previously EnumType)', (): void => { + it('provides a clean toString() (value)', (): void => { expect( new Enum( { Text, U32 }, @@ -18,7 +18,7 @@ describe('Enum', () => { ).toEqual('12'); }); - it('provides a clean toString() (enum)', () => { + it('provides a clean toString() (enum)', (): void => { expect( new Enum( { Text, U32 }, @@ -27,16 +27,16 @@ describe('Enum', () => { ).toEqual('{"U32":3289352}'); }); - it('decodes from a JSON input (lowercase)', () => { + it('decodes from a JSON input (lowercase)', (): void => { expect( new Enum( { Text, U32 }, - { 'text': 'some text value' } + { text: 'some text value' } ).value.toString() ).toEqual('some text value'); }); - it('decodes from hex', () => { + it('decodes from hex', (): void => { expect( new Enum( { Text, U32 }, @@ -45,16 +45,16 @@ describe('Enum', () => { ).toEqual('4660'); // 0x1234 in decimal }); - it('decodes from a JSON input (mixed case)', () => { + it('decodes from a JSON input (mixed case)', (): void => { expect( new Enum( { Text, U32 }, - { 'U32': 42 } + { U32: 42 } ).value.toString() ).toEqual('42'); }); - it('decodes from JSON string', () => { + it('decodes from JSON string', (): void => { expect( new Enum( { Null, U32 }, @@ -63,20 +63,20 @@ describe('Enum', () => { ).toEqual('Null'); }); - it('has correct isXyz/asXyz (Enum.with)', () => { - const test = new (Enum.with({ First: Text, Second: U32, Third: U32 }))({ 'Second': 42 }) as any as { isSecond: boolean, asSecond: U32, asThird: never }; + it('has correct isXyz/asXyz (Enum.with)', (): void => { + const test = new (Enum.with({ First: Text, Second: U32, Third: U32 }))({ Second: 42 }) as any as { isSecond: boolean; asSecond: U32; asThird: never }; expect(test.isSecond).toEqual(true); expect(test.asSecond.toNumber()).toEqual(42); - expect(() => test.asThird).toThrow(/Cannot convert Second via asThird/); + expect((): never => test.asThird).toThrow(/Cannot convert Second via asThird/); }); - it('stringifies with custom types', () => { + it('stringifies with custom types', (): void => { class A extends Null { } class B extends Null { } class C extends Null { } class Test extends Enum { - constructor (value?: string, index?: number) { + public constructor (value?: string, index?: number) { super({ a: A, b: B, @@ -88,7 +88,7 @@ describe('Enum', () => { expect(new Test().toJSON()).toEqual({ a: null }); }); - it('creates via with', () => { + it('creates via with', (): void => { class A extends Null { } class B extends U32 { } class C extends Null { } @@ -101,7 +101,7 @@ describe('Enum', () => { // We are currently not using this approach, none of the types in Substrate currently // have any overrides. Instead of trying to support it (just-in-case), rather have it // removed to simplify the code - it can be pulled-back if needed - it.skip('allows checking against defined indexes', () => { + it.skip('allows checking against defined indexes', (): void => { expect( new Enum( { 1: Text, 5: U32 }, @@ -110,7 +110,7 @@ describe('Enum', () => { ).toEqual('Text'); }); - it('allows accessing the type and value', () => { + it('allows accessing the type and value', (): void => { const text = new Text('foo'); const enumType = new Enum( { Text, U32 }, @@ -121,19 +121,19 @@ describe('Enum', () => { expect(enumType.value).toEqual(text); }); - describe('utils', () => { + describe('utils', (): void => { const eqtest = new Enum( { U32, Text }, new Uint8Array([1, 3 << 2, 88, 89, 90]) ); - it('compares against index', () => { + it('compares against index', (): void => { expect( eqtest.eq(1) ).toBe(true); }); - it('compares against values', () => { + it('compares against values', (): void => { expect( eqtest.eq('XYZ') ).toBe(true); @@ -141,16 +141,16 @@ describe('Enum', () => { }); }); - describe('string-only construction (old Enum)', () => { - const testDecode = (type: string, input: any, expected: any) => - it(`can decode from ${type}`, () => { + describe('string-only construction (old Enum)', (): void => { + const testDecode = (type: string, input: any, expected: any): void => + it(`can decode from ${type}`, (): void => { const e = new Enum(['foo', 'bar'], input); expect(e.toString()).toBe(expected); }); - const testEncode = (to: 'toJSON' | 'toNumber' | 'toString' | 'toU8a', expected: any) => - it(`can encode ${to}`, () => { + const testEncode = (to: 'toJSON' | 'toNumber' | 'toString' | 'toU8a', expected: any): void => + it(`can encode ${to}`, (): void => { const e = new Enum(['foo', 'bar'], 1); expect(e[to]()).toEqual(expected); @@ -169,56 +169,56 @@ describe('Enum', () => { testEncode('toString', 'bar'); testEncode('toU8a', Uint8Array.from([1])); - it('provides a clean toString()', () => { + it('provides a clean toString()', (): void => { expect( new Enum(['foo', 'bar']).toString() ).toEqual('foo'); }); - it('provides a clean toString() (enum)', () => { + it('provides a clean toString() (enum)', (): void => { expect( new Enum(['foo', 'bar'], new Enum(['foo', 'bar'], 1)).toNumber() ).toEqual(1); }); - it('converts to and from U8a', () => { + it('converts to and from U8a', (): void => { expect( new Enum(['foo', 'bar'], new Uint8Array([1])).toU8a() ).toEqual(new Uint8Array([1])); }); - it('converts from JSON', () => { + it('converts from JSON', (): void => { expect( new Enum(['foo', 'bar', 'baz', 'gaz', 'jaz'], 4).toNumber() ).toEqual(4); }); - it('has correct isXyz getters (Enum.with)', () => { - const test = new (Enum.with(['First', 'Second', 'Third']))('Second') as any as { isSecond: boolean, asSecond: never }; + it('has correct isXyz getters (Enum.with)', (): void => { + const test = new (Enum.with(['First', 'Second', 'Third']))('Second') as any as { isSecond: boolean; asSecond: never }; expect(test.isSecond).toEqual(true); }); - describe('utils', () => { - it('compares agains the index value', () => { + describe('utils', (): void => { + it('compares agains the index value', (): void => { expect( new Enum(['foo', 'bar'], 1).eq(1) ).toBe(true); }); - it('compares agains the index value (false)', () => { + it('compares agains the index value (false)', (): void => { expect( new Enum(['foo', 'bar'], 1).eq(0) ).toBe(false); }); - it('compares agains the string value', () => { + it('compares agains the string value', (): void => { expect( new Enum(['foo', 'bar'], 1).eq('bar') ).toBe(true); }); - it('compares agains the string value (false)', () => { + it('compares agains the string value (false)', (): void => { expect( new Enum(['foo', 'bar'], 1).eq('foo') ).toBe(false); @@ -226,14 +226,14 @@ describe('Enum', () => { }); }); - describe('toRawType', () => { - it('has a sane output for basic enums', () => { + describe('toRawType', (): void => { + it('has a sane output for basic enums', (): void => { expect( new Enum(['foo', 'bar']).toRawType() ).toEqual(JSON.stringify({ _enum: ['foo', 'bar'] })); }); - it('has a sane output for types enums', () => { + it('has a sane output for types enums', (): void => { expect( new Enum({ foo: Text, bar: U32 }).toRawType() ).toEqual(JSON.stringify({ _enum: { foo: 'Text', bar: 'u32' } })); diff --git a/packages/types/src/codec/EnumType.ts b/packages/types/src/codec/EnumType.ts index a906b45c6d..8b1b97a408 100644 --- a/packages/types/src/codec/EnumType.ts +++ b/packages/types/src/codec/EnumType.ts @@ -9,16 +9,16 @@ import { assert, hexToU8a, isHex, isNumber, isObject, isString, isU8a, isUndefin import Null from '../primitive/Null'; import Base from './Base'; -type EnumConstructor = { new(value?: any, index?: number): T }; +interface EnumConstructor { + new(value?: any, index?: number): T; +} -type TypesDef = { - [name: string]: Constructor -}; +type TypesDef = Record; -type Decoded = { - index: number, - value: Codec -}; +interface Decoded { + index: number; + value: Codec; +} /** * @name Enum @@ -31,11 +31,14 @@ type Decoded = { // - It should rather probably extend Enum instead of copying code export default class Enum extends Base implements Codec { private _def: TypesDef; + private _index: number; - private _indexes: Array; + + private _indexes: number[]; + private _isBasic: boolean; - constructor (def: TypesDef | Array, value?: any, index?: number | Enum) { + public constructor (def: TypesDef | string[], value?: any, index?: number | Enum) { const defInfo = Enum.extractDef(def); const decoded = Enum.decodeEnum(defInfo.def, value, index); @@ -43,11 +46,11 @@ export default class Enum extends Base implements Codec { this._def = defInfo.def; this._isBasic = defInfo.isBasic; - this._indexes = Object.keys(defInfo.def).map((_, index) => index); + this._indexes = Object.keys(defInfo.def).map((_, index): number => index); this._index = this._indexes.indexOf(decoded.index) || 0; } - private static extractDef (def: TypesDef | Array): { def: TypesDef, isBasic: boolean } { + private static extractDef (def: TypesDef | string[]): { def: TypesDef; isBasic: boolean } { if (!Array.isArray(def)) { return { def, @@ -56,11 +59,11 @@ export default class Enum extends Base implements Codec { } return { - def: def.reduce((def, key) => { + def: def.reduce((def, key): TypesDef => { def[key] = Null; return def; - }, {} as TypesDef), + }, {} as unknown as TypesDef), isBasic: true }; } @@ -100,10 +103,10 @@ export default class Enum extends Base implements Codec { return Enum.createValue(def, 0); } - private static createViaJSON (def: TypesDef, key: string, value?: any) { + private static createViaJSON (def: TypesDef, key: string, value?: any): Decoded { // JSON comes in the form of { "": "" }, here we // additionally force to lower to ensure forward compat - const keys = Object.keys(def).map((k) => k.toLowerCase()); + const keys = Object.keys(def).map((k): string => k.toLowerCase()); const keyLower = key.toLowerCase(); const index = keys.indexOf(keyLower); @@ -123,12 +126,12 @@ export default class Enum extends Base implements Codec { }; } - static with (Types: TypesDef | Array): EnumConstructor { + public static with (Types: TypesDef | string[]): EnumConstructor { return class extends Enum { - constructor (value?: any, index?: number) { + public constructor (value?: any, index?: number) { super(Types, value, index); - Object.keys(this._def).forEach((_key) => { + Object.keys(this._def).forEach((_key): void => { const askey = `as${_key}`; const iskey = `is${_key}`; @@ -136,14 +139,14 @@ export default class Enum extends Base implements Codec { if (isUndefined((this as any)[iskey])) { Object.defineProperty(this, iskey, { enumerable: true, - get: () => this.type === _key + get: (): boolean => this.type === _key }); } if (isUndefined((this as any)[askey])) { Object.defineProperty(this, askey, { enumerable: true, - get: () => { + get: (): Codec => { assert((this as any)[iskey], `Cannot convert ${this.type} via ${askey}`); return this.value; @@ -158,56 +161,56 @@ export default class Enum extends Base implements Codec { /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { return 1 + this.raw.encodedLength; } /** * @description The index of the metadata value */ - get index (): number { + public get index (): number { return this._index; } /** * @description Checks if the value is an empty value */ - get isEmpty (): boolean { + public get isEmpty (): boolean { return this.isEmpty; } /** * @description Checks if the Enum points to a [[Null]] type */ - get isNone (): boolean { + public get isNone (): boolean { return this.isNull; } /** * @description Checks if the Enum points to a [[Null]] type (deprecated, use isNone) */ - get isNull (): boolean { + public get isNull (): boolean { return this.raw instanceof Null; } /** * @description The name of the type this enum value represents */ - get type (): string { + public get type (): string { return Object.keys(this._def)[this._index]; } /** * @description The value of the enum */ - get value (): Codec { + public get value (): Codec { return this.raw; } /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { // cater for the case where we only pass the enum index if (isNumber(other)) { return this.toNumber() === other; @@ -222,14 +225,14 @@ export default class Enum extends Base implements Codec { /** * @description Returns a hex string representation of the value */ - toHex (): string { + public toHex (): string { return u8aToHex(this.toU8a()); } /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): AnyJson { + public toJSON (): AnyJson { return this._isBasic ? this._index : { [this.type]: this.raw.toJSON() }; @@ -238,21 +241,21 @@ export default class Enum extends Base implements Codec { /** * @description Returns the number representation for the value */ - toNumber (): number { + public toNumber (): number { return this._index; } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { const _enum = this._isBasic ? Object.keys(this._def) - : Object.entries(this._def).reduce((result, [key, Type]) => { + : Object.entries(this._def).reduce((result, [key, Type]): Record => { result[key] = new Type().toRawType(); return result; - }, {} as { [index: string]: string }); + }, {} as unknown as Record); return JSON.stringify({ _enum }); } @@ -260,7 +263,7 @@ export default class Enum extends Base implements Codec { /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { return this.isNull ? this.type : JSON.stringify(this.toJSON()); @@ -270,7 +273,7 @@ export default class Enum extends Base implements Codec { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + public toU8a (isBare?: boolean): Uint8Array { const index = this._indexes[this._index]; return u8aConcat( diff --git a/packages/types/src/codec/Int.spec.ts b/packages/types/src/codec/Int.spec.ts index 6dbe8c8b6a..ba2de054e9 100644 --- a/packages/types/src/codec/Int.spec.ts +++ b/packages/types/src/codec/Int.spec.ts @@ -4,39 +4,39 @@ import Int from './Int'; -describe('Int', () => { - it('provides a toBn interface', () => { +describe('Int', (): void => { + it('provides a toBn interface', (): void => { expect( new Int(-1234).toBn().toNumber() ).toEqual(-1234); }); - it('provides a toNumber interface', () => { + it('provides a toNumber interface', (): void => { expect( new Int(-1234).toNumber() ).toEqual(-1234); }); - it('converts to Little Endian from the provided value', () => { + it('converts to Little Endian from the provided value', (): void => { expect( new Int(-1234).toU8a() ).toEqual(new Uint8Array([46, 251, 255, 255, 255, 255, 255, 255])); }); - it('converts to Little Endian from the provided value (bitLength)', () => { + it('converts to Little Endian from the provided value (bitLength)', (): void => { expect( new Int(-1234, 32).toU8a() ).toEqual(new Uint8Array([46, 251, 255, 255])); }); - it('converts to hex/string', () => { + it('converts to hex/string', (): void => { const i = new Int('0x12', 16); expect(i.toHex()).toEqual('0x0012'); expect(i.toString()).toEqual('18'); }); - it('converts to equivalents', () => { + it('converts to equivalents', (): void => { const a = new Int('-123'); expect( @@ -44,7 +44,7 @@ describe('Int', () => { ).toEqual(-123); }); - it('converts to JSON depending on flags', () => { + it('converts to JSON depending on flags', (): void => { expect(new Int(0x12, 16).toJSON()).toEqual('0x0012'); expect(new Int(0x12, 16, false).toJSON()).toEqual(0x12); }); diff --git a/packages/types/src/codec/Int.ts b/packages/types/src/codec/Int.ts index b3be53752f..3afcd8b9f1 100644 --- a/packages/types/src/codec/Int.ts +++ b/packages/types/src/codec/Int.ts @@ -19,7 +19,7 @@ import AbstractInt, { DEFAULT_UINT_BITS, UIntBitLength } from './AbstractInt'; * @noInheritDoc */ export default class Int extends AbstractInt { - constructor ( + public constructor ( value: AnyNumber = 0, bitLength: UIntBitLength = DEFAULT_UINT_BITS, isHexJson: boolean = true) { super( @@ -33,7 +33,7 @@ export default class Int extends AbstractInt { /** * @description Returns a hex string representation of the value */ - toHex (isLe: boolean = false): string { + public toHex (isLe: boolean = false): string { return bnToHex(this, { bitLength: this._bitLength, isLe, @@ -44,7 +44,7 @@ export default class Int extends AbstractInt { /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return `i${this._bitLength}`; } @@ -52,7 +52,8 @@ export default class Int extends AbstractInt { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public toU8a (isBare?: boolean): Uint8Array { return bnToU8a(this, { bitLength: this._bitLength, isLe: true, diff --git a/packages/types/src/codec/Linkage.ts b/packages/types/src/codec/Linkage.ts index 272362e9c0..1f2a19fb37 100644 --- a/packages/types/src/codec/Linkage.ts +++ b/packages/types/src/codec/Linkage.ts @@ -5,35 +5,35 @@ import { Struct, Option, Tuple, Vector } from '.'; import { Constructor, Codec } from '../types'; -type TypeWithValues = [Constructor, Array]; +type TypeWithValues = [Constructor, any[]]; export default class Linkage extends Struct { - constructor (Type: Constructor, value?: any) { + public constructor (Type: Constructor, value?: any) { super({ previous: Option.with(Type), next: Option.with(Type) }, value); } - static withKey (Type: Constructor): Constructor> { + public static withKey (Type: Constructor): Constructor> { return class extends Linkage { - constructor (value?: any) { + public constructor (value?: any) { super(Type, value); } }; } - get previous (): Option { + public get previous (): Option { return this.get('previous') as Option; } - get next (): Option { + public get next (): Option { return this.get('next') as Option; } } export class LinkageResult extends Tuple { - constructor ([TypeKey, keys]: TypeWithValues, [TypeValue, values]: TypeWithValues) { + public constructor ([TypeKey, keys]: TypeWithValues, [TypeValue, values]: TypeWithValues) { super({ Keys: Vector.with(TypeKey), Values: Vector.with(TypeValue) diff --git a/packages/types/src/codec/Option.spec.ts b/packages/types/src/codec/Option.spec.ts index f2f1d239e9..a95fe22b9a 100644 --- a/packages/types/src/codec/Option.spec.ts +++ b/packages/types/src/codec/Option.spec.ts @@ -7,35 +7,35 @@ import Bytes from '../primitive/Bytes'; import U32 from '../primitive/U32'; import Text from '../primitive/Text'; -const testDecode = (type: string, input: any, expected: any) => - it(`can decode from ${type}`, () => { +const testDecode = (type: string, input: any, expected: any): void => + it(`can decode from ${type}`, (): void => { const o = new Option(Text, input); expect(o.toString()).toBe(expected); expect(o.isNone).toBe(!expected.length); }); -const testEncode = (to: string, expected: any) => - it(`can encode ${to}`, () => { +const testEncode = (to: string, expected: any): void => + it(`can encode ${to}`, (): void => { const e = new Option(Text, 'foo'); expect((e as any)[to]()).toEqual(expected); }); -describe('Option', () => { - it('converts undefined/null to empty', () => { +describe('Option', (): void => { + it('converts undefined/null to empty', (): void => { expect(new Option(Text, undefined).isNone).toBe(true); expect(new Option(Text, null).isNone).toBe(true); expect(new Option(Text, 'test').isNone).toBe(false); }); - it('converts an option to an option', () => { + it('converts an option to an option', (): void => { expect( new Option(Text, new Option(Text, 'hello')).toString() ).toEqual('hello'); }); - it('properly converts correctly toHex (Bytes)', () => { + it('properly converts correctly toHex (Bytes)', (): void => { // Option for a parachain head, however, this is effectively an // Option> (hence the length, since it is from storage) const HEX = '0x210100000000000000000000000000000000000000000000000000000000000000000000000000000000011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce'; @@ -44,7 +44,7 @@ describe('Option', () => { ).toEqual(HEX.substr(6)); }); - it.only('properly converts correctly toHex (U64)', () => { + it.only('properly converts correctly toHex (U64)', (): void => { const HEX = '0x12345678'; expect( (new Option(U32, HEX).unwrap() as U32).toNumber() @@ -60,46 +60,46 @@ describe('Option', () => { testEncode('toString', 'foo'); testEncode('toU8a', Uint8Array.from([1, 12, 102, 111, 111])); - it('has empty toString() (undefined)', () => { + it('has empty toString() (undefined)', (): void => { expect( new Option(Text).toString() ).toEqual(''); }); - it('has value toString() (provided)', () => { + it('has value toString() (provided)', (): void => { expect( new Option(Text, new Uint8Array([1, 4 << 2, 49, 50, 51, 52])).toString() ).toEqual('1234'); }); - it('converts toU8a() with', () => { + it('converts toU8a() with', (): void => { expect( new Option(Text, '1234').toU8a() ).toEqual(new Uint8Array([1, 4 << 2, 49, 50, 51, 52])); }); - it('converts toU8a() without', () => { + it('converts toU8a() without', (): void => { expect( new Option(Text).toU8a() ).toEqual(new Uint8Array([0])); }); - describe('utils', () => { + describe('utils', (): void => { const testeq = new Option(Text, '1234'); - it('compares against other option', () => { + it('compares against other option', (): void => { expect(testeq.eq(new Option(Text, '1234'))).toBe(true); }); - it('compares against raw value', () => { + it('compares against raw value', (): void => { expect(testeq.eq('1234')).toBe(true); }); - it('unwraps to default if empty', () => { + it('unwraps to default if empty', (): void => { expect(new Option(Text).unwrapOr('6789')).toBe('6789'); }); - it('unwraps to value if non-empty', () => { + it('unwraps to value if non-empty', (): void => { expect((new Option(Text, '1234').unwrapOr(null) as Text).toString()).toBe('1234'); }); }); diff --git a/packages/types/src/codec/Option.ts b/packages/types/src/codec/Option.ts index 29c486c9f5..b115d06f44 100644 --- a/packages/types/src/codec/Option.ts +++ b/packages/types/src/codec/Option.ts @@ -19,7 +19,7 @@ import Null from '../primitive/Null'; export default class Option extends Base implements Codec { private _Type: Constructor; - constructor (Type: Constructor, value?: any) { + public constructor (Type: Constructor, value?: any) { super( Option.decodeOption(Type, value) ); @@ -27,7 +27,7 @@ export default class Option extends Base implements Codec { this._Type = Type; } - static decodeOption (Type: Constructor, value?: any): Codec { + public static decodeOption (Type: Constructor, value?: any): Codec { if (isNull(value) || isUndefined(value) || value instanceof Null) { return new Null(); } else if (value instanceof Option) { @@ -46,9 +46,9 @@ export default class Option extends Base implements Codec { return new Type(value); } - static with (Type: Constructor): Constructor> { + public static with (Type: Constructor): Constructor> { return class extends Option { - constructor (value?: any) { + public constructor (value?: any) { super(Type, value); } }; @@ -57,7 +57,7 @@ export default class Option extends Base implements Codec { /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { // boolean byte (has value, doesn't have) along with wrapped length return 1 + this.raw.encodedLength; } @@ -65,35 +65,35 @@ export default class Option extends Base implements Codec { /** * @description Checks if the Option has no value */ - get isEmpty (): boolean { + public get isEmpty (): boolean { return this.isNone; } /** * @description Checks if the Option has no value */ - get isNone (): boolean { + public get isNone (): boolean { return this.raw instanceof Null; } /** * @description Checks if the Option has a value */ - get isSome (): boolean { + public get isSome (): boolean { return !this.isNone; } /** * @description The actual value for the Option */ - get value (): Codec { + public get value (): Codec { return this.raw; } /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { if (other instanceof Option) { return (this.isSome === other.isSome) && this.value.eq(other.value); } @@ -104,7 +104,7 @@ export default class Option extends Base implements Codec { /** * @description Returns a hex string representation of the value */ - toHex (): string { + public toHex (): string { // This attempts to align with the JSON encoding - actually in this case // the isSome value is correct, however the `isNone` may be problematic return this.isNone @@ -115,21 +115,21 @@ export default class Option extends Base implements Codec { /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): AnyJson { + public toJSON (): AnyJson { return this.raw.toJSON(); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return `Option<${new this._Type().toRawType()}>`; } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { return this.raw.toString(); } @@ -137,7 +137,7 @@ export default class Option extends Base implements Codec { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + public toU8a (isBare?: boolean): Uint8Array { if (isBare) { return this.raw.toU8a(true); } @@ -155,7 +155,7 @@ export default class Option extends Base implements Codec { /** * @description Returns the value that the Option represents (if available), throws if null */ - unwrap (): T { + public unwrap (): T { if (this.isNone) { throw new Error('Option: unwrapping a None value'); } @@ -167,7 +167,7 @@ export default class Option extends Base implements Codec { * @description Returns the value that the Option represents (if available) or defaultValue if none * @param defaultValue The value to return if the option isNone */ - unwrapOr (defaultValue: O): T | O { + public unwrapOr (defaultValue: O): T | O { return this.isSome ? this.unwrap() : defaultValue; diff --git a/packages/types/src/codec/Set.spec.ts b/packages/types/src/codec/Set.spec.ts index aa91164634..8e6841e01e 100644 --- a/packages/types/src/codec/Set.spec.ts +++ b/packages/types/src/codec/Set.spec.ts @@ -5,16 +5,16 @@ import Set from './Set'; const SET_FIELDS = { - header: 0b00000001, - body: 0b00000010, - receipt: 0b00000100, - messageQueue: 0b00001000, + header: 0b00000001, + body: 0b00000010, + receipt: 0b00000100, + messageQueue: 0b00001000, justification: 0b00010000 }; const SET_ROLES = { - none: 0b00000000, - full: 0b00000001, - light: 0b00000010, + none: 0b00000000, + full: 0b00000001, + light: 0b00000010, authority: 0b00000100 }; const SET_WITHDRAW = { @@ -24,8 +24,8 @@ const SET_WITHDRAW = { Fee: 0b00001000 }; -describe('Set', () => { - it('constructs via an Array', () => { +describe('Set', (): void => { + it('constructs via an string[]', (): void => { const set = new Set(SET_ROLES, ['full', 'authority']); expect(set.isEmpty).toEqual(false); @@ -34,65 +34,65 @@ describe('Set', () => { ); }); - it('throws with invalid values', () => { + it('throws with invalid values', (): void => { expect( - () => new Set(SET_ROLES, ['full', 'authority', 'invalid']) + (): Set => new Set(SET_ROLES, ['full', 'authority', 'invalid']) ).toThrow(/Invalid key 'invalid'/); }); - it('throws with add on invalid', () => { + it('throws with add on invalid', (): void => { expect( - () => (new Set(SET_ROLES, [])).add('invalid') + (): Set => (new Set(SET_ROLES, [])).add('invalid') ).toThrow(/Invalid key 'invalid'/); }); - it('allows construction via number', () => { + it('allows construction via number', (): void => { expect( (new Set(SET_WITHDRAW, 15)).eq(['TransactionPayment', 'Transfer', 'Reserve', 'Fee']) ).toBe(true); }); - it('does not allow invalid number', () => { + it('does not allow invalid number', (): void => { expect( - () => new Set(SET_WITHDRAW, 31) + (): Set => new Set(SET_WITHDRAW, 31) ).toThrow(/Mismatch decoding '31', computed as '15'/); }); - it('hash a valid encoding', () => { + it('hash a valid encoding', (): void => { const set = new Set(SET_FIELDS, ['header', 'body', 'justification']); expect(set.toU8a()).toEqual(new Uint8Array([19])); }); - describe('utils', () => { + describe('utils', (): void => { const set = new Set(SET_ROLES, ['full', 'authority']); - it('compares against string array', () => { + it('compares against string array', (): void => { expect( set.eq(['authority', 'full']) ).toBe(true); }); - it('compares against number (encoded)', () => { + it('compares against number (encoded)', (): void => { expect( set.eq(SET_ROLES.full | SET_ROLES.authority) ).toBe(true); }); - it('compares against other sets', () => { + it('compares against other sets', (): void => { expect( set.eq(new Set(SET_ROLES, ['authority', 'full'])) ).toBe(true); }); - it('returns false on other values', () => { + it('returns false on other values', (): void => { expect( set.eq('full') ).toBe(false); }); }); - it('has a sane toRawType representation', () => { + it('has a sane toRawType representation', (): void => { expect( new Set({ a: 1, b: 2, c: 345 }).toRawType() ).toEqual(JSON.stringify({ diff --git a/packages/types/src/codec/Set.ts b/packages/types/src/codec/Set.ts index 834f7d360c..8c2ff503a0 100644 --- a/packages/types/src/codec/Set.ts +++ b/packages/types/src/codec/Set.ts @@ -7,9 +7,7 @@ import { assert, isU8a, isNumber, isUndefined, u8aToHex } from '@polkadot/util'; import { Codec } from '../types'; import { compareArray } from './utils'; -type SetValues = { - [index: string]: number -}; +type SetValues = Record; /** * @name Set @@ -21,7 +19,7 @@ type SetValues = { export default class CodecSet extends Set implements Codec { private _setValues: SetValues; - constructor (setValues: SetValues, value?: Array | Set | Uint8Array | number) { + public constructor (setValues: SetValues, value?: string[] | Set | Uint8Array | number) { super( CodecSet.decodeSet(setValues, value) ); @@ -29,7 +27,7 @@ export default class CodecSet extends Set implements Codec { this._setValues = setValues; } - static decodeSet (setValues: SetValues, value: Array | Set | Uint8Array | number = 0): Array { + public static decodeSet (setValues: SetValues, value: string[] | Set | Uint8Array | number = 0): string[] { if (isU8a(value)) { return value.length === 0 ? [] @@ -37,22 +35,22 @@ export default class CodecSet extends Set implements Codec { } else if (value instanceof Set) { return CodecSet.decodeSet(setValues, [...value.values()]); } else if (Array.isArray(value)) { - return value.reduce((result, key) => { + return value.reduce((result, key): string[] => { assert(!isUndefined(setValues[key]), `Set: Invalid key '${key}' passed to Set, allowed ${Object.keys(setValues).join(', ')}`); result.push(key); return result; - }, [] as Array); + }, [] as string[]); } - const result = Object.keys(setValues).reduce((result, key) => { + const result = Object.keys(setValues).reduce((result, key): string[] => { if ((value & setValues[key]) === setValues[key]) { result.push(key); } return result; - }, [] as Array); + }, [] as string[]); const computed = CodecSet.encodeSet(setValues, result); @@ -61,8 +59,8 @@ export default class CodecSet extends Set implements Codec { return result; } - static encodeSet (setValues: SetValues, value: Array): number { - return value.reduce((result, value) => { + public static encodeSet (setValues: SetValues, value: string[]): number { + return value.reduce((result, value): number => { return result | (setValues[value] || 0); }, 0); } @@ -70,35 +68,35 @@ export default class CodecSet extends Set implements Codec { /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { return 1; } /** * @description true is the Set contains no values */ - get isEmpty (): boolean { + public get isEmpty (): boolean { return this.size === 0; } /** - * @description The actual set values as a Array + * @description The actual set values as a string[] */ - get strings (): Array { + public get strings (): string[] { return [...super.values()]; } /** * @description The encoded value for the set members */ - get valueEncoded (): number { + public get valueEncoded (): number { return CodecSet.encodeSet(this._setValues, this.strings); } /** * @description adds a value to the Set (extended to allow for validity checking) */ - add (key: string): this { + public add (key: string): this { // we have the isUndefined(this._setValues) in here as well, add is used internally // in the Set constructor (so it is undefined at this point, and should allow) assert(isUndefined(this._setValues) || !isUndefined(this._setValues[key]), `Set: Invalid key '${key}' on add`); @@ -111,7 +109,7 @@ export default class CodecSet extends Set implements Codec { /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { if (Array.isArray(other)) { // we don't actually care about the order, sort the values return compareArray(this.strings.sort(), other.sort()); @@ -127,28 +125,28 @@ export default class CodecSet extends Set implements Codec { /** * @description Returns a hex string representation of the value */ - toHex (): string { + public toHex (): string { return u8aToHex(this.toU8a()); } /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): string[] { + public toJSON (): string[] { return this.strings; } /** * @description The encoded value for the set members */ - toNumber (): number { + public toNumber (): number { return this.valueEncoded; } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { // FIXME We don't cater for this in createType as of yet return JSON.stringify({ _set: this._setValues }); } @@ -156,7 +154,7 @@ export default class CodecSet extends Set implements Codec { /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { return `[${this.strings.join(', ')}]`; } @@ -164,7 +162,8 @@ export default class CodecSet extends Set implements Codec { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public toU8a (isBare?: boolean): Uint8Array { return new Uint8Array([this.valueEncoded]); } } diff --git a/packages/types/src/codec/Struct.spec.ts b/packages/types/src/codec/Struct.spec.ts index 28ec1db03d..4375123af8 100644 --- a/packages/types/src/codec/Struct.spec.ts +++ b/packages/types/src/codec/Struct.spec.ts @@ -13,17 +13,17 @@ import Option from './Option'; import Struct from './Struct'; import Vector from './Vector'; -describe('Struct', () => { - describe('decoding', () => { - const testDecode = (type: string, input: any) => - it(`can decode from ${type}`, () => { +describe('Struct', (): void => { + describe('decoding', (): void => { + const testDecode = (type: string, input: any): void => + it(`can decode from ${type}`, (): void => { const s = new Struct({ foo: Text, bar: U32 }, input); expect([...s.keys()]).toEqual(['foo', 'bar']); expect( - [...s.values()].map((v) => + [...s.values()].map((v): string => v.toString() ) ).toEqual(['bazzing', '69']); @@ -35,9 +35,9 @@ describe('Struct', () => { testDecode('Uint8Array', Uint8Array.from([28, 98, 97, 122, 122, 105, 110, 103, 69, 0, 0, 0])); }); - describe('encoding', () => { - const testEncode = (to: CodecTo, expected: any) => - it(`can encode ${to}`, () => { + describe('encoding', (): void => { + const testEncode = (to: CodecTo, expected: any): void => + it(`can encode ${to}`, (): void => { const s = new Struct({ foo: Text, bar: U32 @@ -51,7 +51,7 @@ describe('Struct', () => { testEncode('toString', '{"foo":"bazzing","bar":69}'); }); - it('decodes null', () => { + it('decodes null', (): void => { expect( new ( Struct.with({ @@ -62,7 +62,7 @@ describe('Struct', () => { ).toEqual('{}'); }); - it('decodes a more complicated type', () => { + it('decodes a more complicated type', (): void => { const s = new Struct({ foo: Vector.with(Struct.with({ bar: Text @@ -71,7 +71,7 @@ describe('Struct', () => { expect(s.toString()).toBe('{"foo":[{"bar":"1"},{"bar":"2"}]}'); }); - it('decodes from a Map input', () => { + it('decodes from a Map input', (): void => { const input = new Struct({ a: U32, txt: Text @@ -84,9 +84,9 @@ describe('Struct', () => { expect(s.toString()).toEqual('{"txt":"fubar","foo":0,"bar":0}'); }); - it('throws when it cannot decode', () => { + it('throws when it cannot decode', (): void => { expect( - () => new ( + (): Struct => new ( Struct.with({ txt: Text, u32: U32 @@ -95,7 +95,7 @@ describe('Struct', () => { ).toThrowError(/Struct: cannot decode type/); }); - it('provides a clean toString()', () => { + it('provides a clean toString()', (): void => { expect( new ( Struct.with({ @@ -106,7 +106,7 @@ describe('Struct', () => { ).toEqual('{"txt":"foo","u32":1193046}'); }); - it('exposes the properties on the object', () => { + it('exposes the properties on the object', (): void => { const struct = new ( Struct.with({ txt: Text, @@ -118,7 +118,7 @@ describe('Struct', () => { expect((struct as any).u32.toNumber()).toEqual(0x123456); }); - it('correctly encodes length', () => { + it('correctly encodes length', (): void => { expect( new ( Struct.with({ @@ -129,7 +129,7 @@ describe('Struct', () => { ).toEqual(5); }); - it('exposes the types', () => { + it('exposes the types', (): void => { expect( new Struct({ foo: Text, @@ -147,7 +147,7 @@ describe('Struct', () => { }); }); - it('gets the value at a particular index', () => { + it('gets the value at a particular index', (): void => { expect( new ( Struct.with({ @@ -160,8 +160,8 @@ describe('Struct', () => { ).toEqual('1234'); }); - describe('utils', () => { - it('compares against other objects', () => { + describe('utils', (): void => { + it('compares against other objects', (): void => { const test = { foo: 'foo', bar: 'bar', @@ -178,7 +178,7 @@ describe('Struct', () => { }); }); - it('allows toString with large numbers', () => { + it('allows toString with large numbers', (): void => { // replicate https://github.com/polkadot-js/api/issues/640 expect( new Struct({ @@ -187,7 +187,7 @@ describe('Struct', () => { ).toEqual('{"blockNumber":"0x1234567890abcdef"}'); }); - it('generates sane toRawType', () => { + it('generates sane toRawType', (): void => { expect( new Struct({ accountId: AccountId, @@ -209,7 +209,7 @@ describe('Struct', () => { })); }); - it('generates sane toRawType (via with)', () => { + it('generates sane toRawType (via with)', (): void => { const Type = Struct.with({ accountId: AccountId, balance: Balance diff --git a/packages/types/src/codec/Struct.ts b/packages/types/src/codec/Struct.ts index 6ad5fb666d..571fe6b882 100644 --- a/packages/types/src/codec/Struct.ts +++ b/packages/types/src/codec/Struct.ts @@ -25,12 +25,12 @@ export default class Struct< // input values, mapped by key can be anything (construction) V extends { [K in keyof S]: any } = { [K in keyof S]: any }, // type names, mapped by key, name of Class in S - E extends { [K in keyof S]: string } = { [K in keyof S]: string } - > extends Map implements Codec { + E extends { [K in keyof S]: string } = { [K in keyof S]: string }> extends Map implements Codec { protected _jsonMap: Map; + protected _Types: S; - constructor (Types: S, value: V | Map | Array = {} as V, jsonMap: Map = new Map()) { + public constructor (Types: S, value: V | Map | any[] = {} as unknown as V, jsonMap: Map = new Map()) { const decoded = Struct.decodeStruct(Types, value, jsonMap); super( @@ -69,14 +69,14 @@ export default class Struct< const values = decodeU8a(value, Object.values(Types)); // Transform array of values to {key: value} mapping - return Object.keys(Types).reduce((raw: T, key: keyof S, index) => { + return Object.keys(Types).reduce((raw: T, key: keyof S, index): T => { // TS2322: Type 'Codec' is not assignable to type 'T[keyof S]'. (raw as any)[key] = values[index]; return raw; - }, {} as T); + }, {} as unknown as T); } else if (!value) { - return {} as T; + return {} as unknown as T; } // We assume from here that value is a JS object (Array, Map, Object) @@ -88,7 +88,7 @@ export default class Struct< _, T extends { [K in keyof S]: Codec } > (Types: S, value: any, jsonMap: Map): T { - return Object.keys(Types).reduce((raw: T, key: keyof S, index) => { + return Object.keys(Types).reduce((raw: T, key: keyof S, index): T => { // The key in the JSON can be snake_case (or other cases), but in our // Types, result or any other maps, it's camelCase const jsonKey = (jsonMap.get(key as any) && !value[key]) ? jsonMap.get(key as any) : key; @@ -117,17 +117,17 @@ export default class Struct< } return raw; - }, {} as T); + }, {} as unknown as T); } - static with< + public static with< S extends ConstructorDef > (Types: S): Constructor> { return class extends Struct { - constructor (value?: any, jsonMap?: Map) { + public constructor (value?: any, jsonMap?: Map) { super(Types, value, jsonMap); - (Object.keys(Types) as Array).forEach((key) => { + (Object.keys(Types) as (keyof S)[]).forEach((key): void => { // do not clobber existing properties on the object if (!isUndefined((this as any)[key])) { return; @@ -135,7 +135,7 @@ export default class Struct< Object.defineProperty(this, key, { enumerable: true, - get: () => this.get(key) + get: (): Codec | undefined => this.get(key) }); }); } @@ -145,7 +145,7 @@ export default class Struct< /** * @description Checks if the value is an empty value */ - get isEmpty (): boolean { + public get isEmpty (): boolean { const items = this.toArray(); for (let i = 0; i < items.length; i++) { @@ -160,29 +160,31 @@ export default class Struct< /** * @description Returns the Type description to sthe structure */ - get Type (): E { + public get Type (): E { return (Object - .entries(this._Types) as Array<[keyof S, Constructor]>) - .reduce((result: E, [key, Type]) => { + .entries(this._Types) as [keyof S, Constructor][]) + .reduce((result: E, [key, Type]): E => { (result as any)[key] = Type.name; return result; - }, {} as E); + }, {} as unknown as E); } /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { - return this.toArray().reduce((length, entry) => { - return length += entry.encodedLength; + public get encodedLength (): number { + return this.toArray().reduce((length, entry): number => { + length += entry.encodedLength; + + return length; }, 0); } /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { return compareMap(this, other); } @@ -190,38 +192,38 @@ export default class Struct< * @description Returns a specific names entry in the structure * @param name The name of the entry to retrieve */ - get (name: keyof S): Codec | undefined { + public get (name: keyof S): Codec | undefined { return super.get(name); } /** * @description Returns the values of a member at a specific index (Rather use get(name) for performance) */ - getAtIndex (index: number): Codec { + public getAtIndex (index: number): Codec { return this.toArray()[index]; } /** * @description Converts the Object to an standard JavaScript Array */ - toArray (): Array { + public toArray (): Codec[] { return [...this.values()]; } /** * @description Returns a hex string representation of the value */ - toHex () { + public toHex (): string { return u8aToHex(this.toU8a()); } /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): AnyJsonObject | string { + public toJSON (): AnyJsonObject | string { // FIXME the return type string is only used by Extrinsic (extends Struct), // but its toJSON is the hex value - return [...this.keys()].reduce((json, key) => { + return [...this.keys()].reduce((json, key): any => { const jsonKey = this._jsonMap.get(key) || key; const value = this.get(key); @@ -234,20 +236,20 @@ export default class Struct< /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return JSON.stringify( - Object.entries(this._Types).reduce((result, [key, Type]) => { + Object.entries(this._Types).reduce((result, [key, Type]): Record => { result[key] = new Type().toRawType(); return result; - }, {} as { [index: string]: string }) + }, {} as unknown as Record) ); } /** * @description Returns the string representation of the value */ - toString () { + public toString (): string { return JSON.stringify(this.toJSON()); } @@ -255,9 +257,9 @@ export default class Struct< * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + public toU8a (isBare?: boolean): Uint8Array { return u8aConcat( - ...this.toArray().map((entry) => + ...this.toArray().map((entry): Uint8Array => entry.toU8a(isBare) ) ); diff --git a/packages/types/src/codec/StructAny.ts b/packages/types/src/codec/StructAny.ts index f3f5c4955f..b467c4e4b7 100644 --- a/packages/types/src/codec/StructAny.ts +++ b/packages/types/src/codec/StructAny.ts @@ -17,13 +17,13 @@ import { compareMap } from './utils'; * @noInheritDoc */ export default class StructAny extends Map implements Codec { - constructor (value?: { [index: string]: any } | null) { + public constructor (value?: { [index: string]: any } | null) { const decoded = StructAny.decodeJson(value); super(decoded); // like we are doing with structs, add the keys as getters - decoded.forEach(([key]) => { + decoded.forEach(([key]): void => { // do not clobber existing properties on the object if (!isUndefined((this as any)[key])) { return; @@ -31,48 +31,48 @@ export default class StructAny extends Map implements Codec { Object.defineProperty(this, key, { enumerable: true, - get: () => this.get(key) + get: (): Codec | undefined => this.get(key) }); }); } - private static decodeJson (value?: { [index: string]: any } | null): Array<[string, any]> { + private static decodeJson (value?: { [index: string]: any } | null): [string, any][] { return Object.entries(value || {}); } /** * @description Always 0, never encodes as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { return 0; } /** * @description Checks if the value is an empty value */ - get isEmpty (): boolean { + public get isEmpty (): boolean { return [...this.keys()].length === 0; } /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { return compareMap(this, other); } /** * @description Unimplemented, will throw */ - toHex (): string { + public toHex (): string { throw new Error('Unimplemented'); } /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): AnyJsonObject { - return [...this.entries()].reduce((json, [key, value]) => { + public toJSON (): AnyJsonObject { + return [...this.entries()].reduce((json, [key, value]): AnyJsonObject => { json[key] = value; return json; @@ -82,21 +82,22 @@ export default class StructAny extends Map implements Codec { /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'Json'; } /** * @description Returns the string representation of the value */ - toString () { + public toString (): string { return JSON.stringify(this.toJSON()); } /** * @description Unimplemented, will throw */ - toU8a (isBare?: boolean): Uint8Array { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public toU8a (isBare?: boolean): Uint8Array { throw new Error('Unimplemented'); } } diff --git a/packages/types/src/codec/Tuple.spec.ts b/packages/types/src/codec/Tuple.spec.ts index 0d83ccc192..41383f9b88 100644 --- a/packages/types/src/codec/Tuple.spec.ts +++ b/packages/types/src/codec/Tuple.spec.ts @@ -13,19 +13,19 @@ import Proposal from '../type/Proposal'; import VoteThreshold from '../type/VoteThreshold'; import Tuple from './Tuple'; -describe('Tuple', () => { +describe('Tuple', (): void => { let tuple: Tuple; - beforeEach(() => { + beforeEach((): void => { tuple = new Tuple( [Text, U32], ['bazzing', 69] ); }); - describe('decoding', () => { - const testDecode = (type: string, input: any) => - it(`can decode from ${type}`, () => { + describe('decoding', (): void => { + const testDecode = (type: string, input: any): void => + it(`can decode from ${type}`, (): void => { const t = new Tuple([ Text, U32 @@ -40,9 +40,9 @@ describe('Tuple', () => { testDecode('Uint8Array', Uint8Array.from([28, 98, 97, 122, 122, 105, 110, 103, 69, 0, 0, 0])); }); - describe('encoding', () => { - const testEncode = (to: CodecTo | 'toArray', expected: any) => - it(`can encode ${to}`, () => { + describe('encoding', (): void => { + const testEncode = (to: CodecTo | 'toArray', expected: any): void => + it(`can encode ${to}`, (): void => { expect(tuple[to]()).toEqual(expected); }); @@ -52,7 +52,7 @@ describe('Tuple', () => { testEncode('toString', '["bazzing",69]'); }); - it.skip('creates properly via actual hex string', () => { + it.skip('creates properly via actual hex string', (): void => { Method.injectMethods(extrinsics); const test = new (Tuple.with([ @@ -65,11 +65,11 @@ describe('Tuple', () => { expect((test[2] as VoteThreshold).toNumber()).toEqual(1); }); - it('exposes the Types', () => { + it('exposes the Types', (): void => { expect(tuple.Types).toEqual(['Text', 'U32']); }); - it('exposes the Types (object creation)', () => { + it('exposes the Types (object creation)', (): void => { const test = new Tuple({ BlockNumber, VoteThreshold }, []); @@ -77,32 +77,32 @@ describe('Tuple', () => { expect(test.Types).toEqual(['BlockNumber', 'VoteThreshold']); }); - it('exposes filter', () => { - expect(tuple.filter((v) => v.toJSON() === 69)).toEqual([new U32(69)]); + it('exposes filter', (): void => { + expect(tuple.filter((v): boolean => v.toJSON() === 69)).toEqual([new U32(69)]); }); - it('exposes map', () => { - expect(tuple.map(v => v.toString())).toEqual(['bazzing', '69']); + it('exposes map', (): void => { + expect(tuple.map((v): string => v.toString())).toEqual(['bazzing', '69']); }); - describe('utils', () => { - it('compares against inputs', () => { + describe('utils', (): void => { + it('compares against inputs', (): void => { expect(tuple.eq(['bazzing', 69])).toBe(true); }); - it('compares against inputs (mismatch)', () => { + it('compares against inputs (mismatch)', (): void => { expect(tuple.eq(['bazzing', 72])).toBe(false); }); }); - describe('toRawType', () => { - it('generates sane value with array types', () => { + describe('toRawType', (): void => { + it('generates sane value with array types', (): void => { expect( new Tuple([U32, BlockNumber]).toRawType() ).toEqual('(u32,u64)'); }); - it('generates sane value with object types', () => { + it('generates sane value with object types', (): void => { expect( new Tuple({ number: U32, blockNumber: BlockNumber }).toRawType() ).toEqual('(u32,u64)'); diff --git a/packages/types/src/codec/Tuple.ts b/packages/types/src/codec/Tuple.ts index 35d1a4538b..f84c6cfc65 100644 --- a/packages/types/src/codec/Tuple.ts +++ b/packages/types/src/codec/Tuple.ts @@ -8,8 +8,8 @@ import { AnyNumber, AnyU8a, AnyString, Codec, Constructor } from '../types'; import { decodeU8a } from './utils'; import AbstractArray from './AbstractArray'; -type TupleConstructors = Array | { - [index: string]: Constructor +type TupleConstructors = Constructor[] | { + [index: string]: Constructor; }; /** @@ -21,7 +21,7 @@ type TupleConstructors = Array | { export default class Tuple extends AbstractArray { private _Types: TupleConstructors; - constructor (Types: TupleConstructors, value?: any) { + public constructor (Types: TupleConstructors, value?: any) { super( ...Tuple.decodeTuple(Types, value) ); @@ -29,18 +29,18 @@ export default class Tuple extends AbstractArray { this._Types = Types; } - private static decodeTuple (_Types: TupleConstructors, value: AnyU8a | string | Array): Array { + private static decodeTuple (_Types: TupleConstructors, value: AnyU8a | string | (AnyU8a | AnyNumber | AnyString | undefined | null)[]): Codec[] { if (isU8a(value)) { return decodeU8a(value, _Types); } else if (isHex(value)) { return Tuple.decodeTuple(_Types, hexToU8a(value)); } - const Types: Array = Array.isArray(_Types) + const Types: Constructor[] = Array.isArray(_Types) ? _Types : Object.values(_Types); - return Types.map((Type, index) => { + return Types.map((Type, index): Codec => { try { return new Type(value && value[index]); } catch (error) { @@ -49,9 +49,9 @@ export default class Tuple extends AbstractArray { }); } - static with (Types: TupleConstructors): Constructor { + public static with (Types: TupleConstructors): Constructor { return class extends Tuple { - constructor (value?: any) { + public constructor (value?: any) { super(Types, value); } }; @@ -60,30 +60,32 @@ export default class Tuple extends AbstractArray { /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { - return this.reduce((length, entry) => { - return length += entry.encodedLength; + public get encodedLength (): number { + return this.reduce((length: number, entry: Codec): number => { + length += entry.encodedLength; + + return length; }, 0); } /** * @description The types definition of the tuple */ - get Types (): Array { + public get Types (): string[] { return Array.isArray(this._Types) - ? this._Types.map(({ name }) => name) + ? this._Types.map(({ name }): string => name) : Object.keys(this._Types); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { const types = ( Array.isArray(this._Types) ? this._Types : Object.values(this._Types) - ).map((Type) => new Type().toRawType()); + ).map((Type): string => new Type().toRawType()); return `(${types.join(',')})`; } @@ -91,7 +93,7 @@ export default class Tuple extends AbstractArray { /** * @description Returns the string representation of the value */ - toString () { + public toString (): string { // Overwrite the default toString representation of Array. return JSON.stringify(this.toJSON()); } @@ -100,9 +102,9 @@ export default class Tuple extends AbstractArray { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + public toU8a (isBare?: boolean): Uint8Array { return u8aConcat( - ...this.map((entry) => + ...this.map((entry): Uint8Array => entry.toU8a(isBare) ) ); diff --git a/packages/types/src/codec/TypeRegistry.spec.ts b/packages/types/src/codec/TypeRegistry.spec.ts index e264625a77..62b257bd56 100644 --- a/packages/types/src/codec/TypeRegistry.spec.ts +++ b/packages/types/src/codec/TypeRegistry.spec.ts @@ -6,49 +6,49 @@ import { TypeRegistry } from './typeRegistry'; import Text from '../primitive/Text'; import U32 from '../primitive/U32'; -describe('TypeRegistry', () => { +describe('TypeRegistry', (): void => { let registry: TypeRegistry; - beforeEach(() => { + beforeEach((): void => { registry = new TypeRegistry(); }); - it('handles non exist type', () => { + it('handles non exist type', (): void => { expect(registry.get('non-exist')).toBeUndefined(); }); - it('can register single type', () => { + it('can register single type', (): void => { registry.register(Text); expect(registry.get('Text')).toBe(Text); }); - it('can register type with a different name', () => { + it('can register type with a different name', (): void => { registry.register('TextRenamed', Text); expect(registry.get('TextRenamed')).toBe(Text); }); - describe('object registration', () => { - it('can register multiple types', () => { + describe('object registration', (): void => { + it('can register multiple types', (): void => { registry.register({ Text, - 'U32Renamed': U32 + U32Renamed: U32 }); expect(registry.get('Text')).toBe(Text); expect(registry.get('U32Renamed')).toBe(U32); }); - it('can create types from string', () => { + it('can create types from string', (): void => { registry.register({ - 'U32Renamed': 'u32' + U32Renamed: 'u32' }); expect(registry.get('U32Renamed')).toBe(U32); }); - it('can create structs via definition', () => { + it('can create structs via definition', (): void => { registry.register({ - 'SomeStruct': { - 'foo': 'u32', - 'bar': 'Text' + SomeStruct: { + foo: 'u32', + bar: 'Text' } }); diff --git a/packages/types/src/codec/U8a.spec.ts b/packages/types/src/codec/U8a.spec.ts index 4eec497ab6..a1099fccf8 100644 --- a/packages/types/src/codec/U8a.spec.ts +++ b/packages/types/src/codec/U8a.spec.ts @@ -5,22 +5,24 @@ import { CodecTo } from '../types'; import U8a from './U8a'; -const testDecode = (type: string, input: any, expected: string) => - it(`can decode from ${type}`, () => { +const testDecode = (type: string, input: any, expected: string): void => + it(`can decode from ${type}`, (): void => { const e = new U8a(input); + expect(e.toString()).toBe(expected); }); -const testEncode = (to: CodecTo, expected: any) => - it(`can encode ${to}`, () => { +const testEncode = (to: CodecTo, expected: any): void => + it(`can encode ${to}`, (): void => { const e = new U8a([1, 2, 3, 4, 5]); + expect(e[to]()).toEqual(expected); }); -describe('U8a', () => { +describe('U8a', (): void => { let u8a: U8a; - beforeEach(() => { + beforeEach((): void => { u8a = new U8a([1, 2, 3, 4, 5]); }); @@ -34,38 +36,38 @@ describe('U8a', () => { testEncode('toString', '0x0102030405'); testEncode('toU8a', Uint8Array.from([1, 2, 3, 4, 5])); - it('contains the length of the elements', () => { + it('contains the length of the elements', (): void => { expect(u8a.length).toEqual(5); }); - it('correctly encodes length', () => { + it('correctly encodes length', (): void => { expect(u8a.encodedLength).toEqual(5); }); - it('allows wrapping of a pre-existing instance', () => { + it('allows wrapping of a pre-existing instance', (): void => { expect( new U8a(u8a).length ).toEqual(5); }); - it('implements subarray correctly', () => { + it('implements subarray correctly', (): void => { expect(u8a.subarray(1, 3)).toEqual(Uint8Array.from([2, 3])); }); - describe('utils', () => { - it('compares against other U8a', () => { + describe('utils', (): void => { + it('compares against other U8a', (): void => { expect(u8a.eq(new Uint8Array([1, 2, 3, 4, 5]))).toBe(true); }); - it('compares against other U8a (non-length)', () => { + it('compares against other U8a (non-length)', (): void => { expect(u8a.eq(new Uint8Array([1, 2, 3, 4]))).toBe(false); }); - it('compares against other U8a (mismatch)', () => { + it('compares against other U8a (mismatch)', (): void => { expect(u8a.eq(new Uint8Array([1, 2, 3, 4, 6]))).toBe(false); }); - it('compares against hex inputs', () => { + it('compares against hex inputs', (): void => { expect(u8a.eq('0x0102030405')).toBe(true); }); }); diff --git a/packages/types/src/codec/U8a.ts b/packages/types/src/codec/U8a.ts index a638b15fc3..8b791994f8 100644 --- a/packages/types/src/codec/U8a.ts +++ b/packages/types/src/codec/U8a.ts @@ -16,7 +16,7 @@ import { AnyU8a, Codec } from '../types'; * @noInheritDoc */ export default class U8a extends Uint8Array implements Codec { - constructor (value?: AnyU8a) { + public constructor (value?: AnyU8a) { super( U8a.decodeU8a(value) ); @@ -33,21 +33,21 @@ export default class U8a extends Uint8Array implements Codec { /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { return this.length; } /** * @description Returns true if the type wraps an empty/default all-0 value */ - get isEmpty (): boolean { - return !this.length || isUndefined(this.find((value) => !!value)); + public get isEmpty (): boolean { + return !this.length || isUndefined(this.find((value): boolean => !!value)); } /** * @description The length of the value */ - get length (): number { + public get length (): number { // only included here since we ignore inherited docs return super.length; } @@ -55,10 +55,10 @@ export default class U8a extends Uint8Array implements Codec { /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { if (other instanceof Uint8Array) { return (this.length === other.length) && isUndefined( - this.find((value, index) => value !== other[index]) + this.find((value, index): boolean => value !== other[index]) ); } @@ -70,35 +70,35 @@ export default class U8a extends Uint8Array implements Codec { * @param begin The position to start at * @param end The position to end at */ - subarray (begin: number, end?: number): Uint8Array { + public subarray (begin: number, end?: number): Uint8Array { return Uint8Array.from(this).subarray(begin, end); } /** * @description Returns a hex string representation of the value */ - toHex (): string { + public toHex (): string { return u8aToHex(this); } /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): string { + public toJSON (): string { return this.toHex(); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return `Vec`; } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { return this.toHex(); } @@ -106,7 +106,8 @@ export default class U8a extends Uint8Array implements Codec { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public toU8a (isBare?: boolean): Uint8Array { return Uint8Array.from(this); } } diff --git a/packages/types/src/codec/U8aFixed.spec.ts b/packages/types/src/codec/U8aFixed.spec.ts index 0d1ca3c6ce..fb3b99a4da 100644 --- a/packages/types/src/codec/U8aFixed.spec.ts +++ b/packages/types/src/codec/U8aFixed.spec.ts @@ -4,34 +4,34 @@ import U8aFixed from './U8aFixed'; -describe('U8aFixed', () => { +describe('U8aFixed', (): void => { let u8a: U8aFixed; - beforeEach(() => { + beforeEach((): void => { u8a = new U8aFixed([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 32); }); - it('limits the length', () => { + it('limits the length', (): void => { expect(u8a.length).toEqual(4); }); - it('exposes the correct bitLength', () => { + it('exposes the correct bitLength', (): void => { expect(u8a.bitLength()).toEqual(32); }); - it('allows wrapping of a pre-existing instance', () => { + it('allows wrapping of a pre-existing instance', (): void => { expect( u8a.toU8a() ).toEqual(new Uint8Array([1, 2, 3, 4])); }); - it('allows empty values', () => { + it('allows empty values', (): void => { expect( new U8aFixed().toHex() ).toEqual('0x0000000000000000000000000000000000000000000000000000000000000000'); }); - it('allows construction via with', () => { + it('allows construction via with', (): void => { expect( new (U8aFixed.with(64))().bitLength() ).toEqual(64); diff --git a/packages/types/src/codec/U8aFixed.ts b/packages/types/src/codec/U8aFixed.ts index 896fda332c..3eb55381ad 100644 --- a/packages/types/src/codec/U8aFixed.ts +++ b/packages/types/src/codec/U8aFixed.ts @@ -17,7 +17,7 @@ export type BitLength = 8 | 16 | 32 | 64 | 128 | 160 | 256 | 512 | 1024 | 2048; * to be used directly, rather is should be subclassed with the specific lengths. */ export default class U8aFixed extends U8a { - constructor (value: AnyU8a = new Uint8Array(), bitLength: BitLength = 256) { + public constructor (value: AnyU8a = new Uint8Array(), bitLength: BitLength = 256) { super( U8aFixed.decodeU8aFixed(value, bitLength) ); @@ -46,9 +46,9 @@ export default class U8aFixed extends U8a { return value; } - static with (bitLength: BitLength): Constructor { + public static with (bitLength: BitLength): Constructor { return class extends U8aFixed { - constructor (value?: any) { + public constructor (value?: any) { super(value, bitLength); } }; @@ -57,14 +57,14 @@ export default class U8aFixed extends U8a { /** * @description Returns the number of bits in the value */ - bitLength () { + public bitLength (): number { return this.length * 8; } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { // FIEXME We don't cater for this in createType return `[u8;${this.length}]`; } diff --git a/packages/types/src/codec/UInt.spec.ts b/packages/types/src/codec/UInt.spec.ts index 315f338996..fc62b10f51 100644 --- a/packages/types/src/codec/UInt.spec.ts +++ b/packages/types/src/codec/UInt.spec.ts @@ -6,39 +6,39 @@ import BN from 'bn.js'; import UInt from './UInt'; -describe('UInt', () => { - it('provides a toBn interface', () => { +describe('UInt', (): void => { + it('provides a toBn interface', (): void => { expect( new UInt(987).toBn().toNumber() ).toEqual(987); }); - it('provides a toNumber interface', () => { + it('provides a toNumber interface', (): void => { expect( new UInt(4567).toNumber() ).toEqual(4567); }); - it('converts to Little Endian from the provided value', () => { + it('converts to Little Endian from the provided value', (): void => { expect( new UInt(1234567).toU8a() ).toEqual(new Uint8Array([135, 214, 18, 0, 0, 0, 0, 0])); }); - it('converts to Little Endian from the provided value (bitLength)', () => { + it('converts to Little Endian from the provided value (bitLength)', (): void => { expect( new UInt(1234567, 32).toU8a() ).toEqual(new Uint8Array([135, 214, 18, 0])); }); - it('converts to hex/string', () => { + it('converts to hex/string', (): void => { const u = new UInt('0x12', 16); expect(u.toHex()).toEqual('0x0012'); expect(u.toString()).toEqual('18'); }); - it('converts to equivalents', () => { + it('converts to equivalents', (): void => { const a = new UInt('123'); expect( @@ -46,24 +46,24 @@ describe('UInt', () => { ).toEqual(123); }); - it('converts to JSON representation based on flags/size', () => { + it('converts to JSON representation based on flags/size', (): void => { expect(new UInt('0x12345678', 64, true).toJSON()).toEqual('0x0000000012345678'); expect(new UInt('0x1234567890', 64, false).toJSON()).toEqual(0x1234567890); expect(new UInt('0x1234567890abcdef', 64, false).toJSON()).toEqual('0x1234567890abcdef'); }); - describe('eq', () => { + describe('eq', (): void => { const test = new UInt(12345); - it('compares against other BN values', () => { + it('compares against other BN values', (): void => { expect(test.eq(new BN(12345))).toBe(true); }); - it('compares against other number values', () => { + it('compares against other number values', (): void => { expect(test.eq(12345)).toBe(true); }); - it('compares against hex values', () => { + it('compares against hex values', (): void => { expect(test.eq('0x3039')).toBe(true); }); }); diff --git a/packages/types/src/codec/UInt.ts b/packages/types/src/codec/UInt.ts index 58e135a722..d41bd7d8ce 100644 --- a/packages/types/src/codec/UInt.ts +++ b/packages/types/src/codec/UInt.ts @@ -19,7 +19,7 @@ import AbstractInt, { DEFAULT_UINT_BITS, UIntBitLength } from './AbstractInt'; * @noInheritDoc */ export default class UInt extends AbstractInt { - constructor ( + public constructor ( value: AnyNumber = 0, bitLength: UIntBitLength = DEFAULT_UINT_BITS, isHexJson: boolean = false) { super( @@ -33,7 +33,7 @@ export default class UInt extends AbstractInt { /** * @description Returns a hex string representation of the value */ - toHex (isLe: boolean = false): string { + public toHex (isLe: boolean = false): string { // For display/JSON, this is BE, for compare, use isLe return bnToHex(this, { bitLength: this._bitLength, @@ -45,7 +45,7 @@ export default class UInt extends AbstractInt { /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return `u${this._bitLength}`; } @@ -53,7 +53,8 @@ export default class UInt extends AbstractInt { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public toU8a (isBare?: boolean): Uint8Array { return bnToU8a(this, { bitLength: this._bitLength, isLe: true, diff --git a/packages/types/src/codec/Vector.spec.ts b/packages/types/src/codec/Vector.spec.ts index b9c8ba0679..54a159414b 100644 --- a/packages/types/src/codec/Vector.spec.ts +++ b/packages/types/src/codec/Vector.spec.ts @@ -15,24 +15,24 @@ import createType from './createType'; import Vector from './Vector'; import Tuple from './Tuple'; -describe('Vector', () => { +describe('Vector', (): void => { let vector: Vector; - beforeEach(() => { + beforeEach((): void => { vector = new Vector(Text, ['1', '23', '345', '4567', new Text('56789')]); Method.injectMethods(extrinsics); }); - it('wraps a sequence of values', () => { + it('wraps a sequence of values', (): void => { expect(vector.length).toEqual(5); // eslint-disable-line }); - it('has a sane representation for toString', () => { + it('has a sane representation for toString', (): void => { expect(vector.toString()).toEqual('[1, 23, 345, 4567, 56789]'); }); - it('encodes with length prefix', () => { + it('encodes with length prefix', (): void => { expect(vector.toU8a()).toEqual(new Uint8Array([ 5 << 2, 1 << 2, 49, @@ -43,17 +43,17 @@ describe('Vector', () => { ])); }); - it('allows contruction via JSON', () => { + it('allows contruction via JSON', (): void => { expect( new Vector(Text, ['6', '7']).toJSON() ).toEqual(['6', '7']); }); - it('exposes the type', () => { + it('exposes the type', (): void => { expect(vector.Type).toEqual('Text'); }); - it.skip('decodes a complex type via construction', () => { + it.skip('decodes a complex type via construction', (): void => { const test = createType('Vec<(PropIndex, Proposal, AccountId)>', new Uint8Array([ 4, 10, 0, 0, 0, 0, 3, 80, 123, 10, 9, 34, 48, 120, 52, 50, 34, 58, 32, 34, 48, 120, 52, 51, 34, 10, 125, 10, 209, 114, 167, 76, 218, 76, 134, 89, 18, 195, 43, 160, 168, 10, 87, 174, 105, 171, 174, 65, 14, 92, 203, 89, 222, 232, 78, 47, 68, 50, 219, 79 ])); @@ -64,17 +64,17 @@ describe('Vector', () => { expect((first[2] as AccountId).toString()).toEqual('5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaDtZ'); }); - describe('vector-like functions', () => { - it('allows retrieval of a specific item', () => { + describe('vector-like functions', (): void => { + it('allows retrieval of a specific item', (): void => { expect( vector[2].toString() ).toEqual('345'); }); - it('exposes a working forEach', () => { + it('exposes a working forEach', (): void => { const result: { [index: number]: string } = {}; - vector.forEach((e, i) => { + vector.forEach((e, i): void => { result[i] = e.toString(); }); @@ -87,28 +87,28 @@ describe('Vector', () => { }); }); - it('exposes a working filter', () => { + it('exposes a working filter', (): void => { expect( - vector.filter((e, i) => i >= 3).toString() + vector.filter((e, i): boolean => i >= 3).toString() ).toEqual('4567,56789'); }); - it('exposes a working map', () => { + it('exposes a working map', (): void => { expect( - vector.map((e) => e.toString().substr(0, 1)) + vector.map((e): string => e.toString().substr(0, 1)) ).toEqual(['1', '2', '3', '4', '5']); }); - it('exposes a working reduce', () => { + it('exposes a working reduce', (): void => { expect( - vector.reduce((r, e) => `${r}${e}`, '') + vector.reduce((r, e): string => `${r}${e}`, '') ).toEqual('123345456756789'); }); }); - describe('encode', () => { - const testEncode = (to: CodecTo, expected: any) => - it(`can encode ${to}`, () => { + describe('encode', (): void => { + const testEncode = (to: CodecTo, expected: any): void => + it(`can encode ${to}`, (): void => { expect(vector[to]()).toEqual(expected); }); @@ -118,18 +118,18 @@ describe('Vector', () => { testEncode('toU8a', Uint8Array.from([20, 4, 49, 8, 50, 51, 12, 51, 52, 53, 16, 52, 53, 54, 55, 20, 53, 54, 55, 56, 57])); }); - describe('utils', () => { + describe('utils', (): void => { const vec = new Vector(Text, ['123', '456']); - it('compares against codec types', () => { + it('compares against codec types', (): void => { expect(vec.eq([new Text('123'), new Text('456')])).toBe(true); }); - it('compares against codec + primitive types', () => { + it('compares against codec + primitive types', (): void => { expect(vec.eq(['123', new Text('456')])).toBe(true); }); - it('finds the index of an value', () => { + it('finds the index of an value', (): void => { const myId = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; const vec = new Vector(AccountId, [ '5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw', '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty', '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY' diff --git a/packages/types/src/codec/Vector.ts b/packages/types/src/codec/Vector.ts index 5b4e51770a..d0f6848d2d 100644 --- a/packages/types/src/codec/Vector.ts +++ b/packages/types/src/codec/Vector.ts @@ -21,7 +21,7 @@ const MAX_LENGTH = 32768; export default class Vector extends AbstractArray { private _Type: Constructor; - constructor (Type: Constructor, value: Vector | Uint8Array | string | Array = [] as Array) { + public constructor (Type: Constructor, value: Vector | Uint8Array | string | any[] = [] as any[]) { super( ...Vector.decodeVector(Type, value) ); @@ -29,9 +29,9 @@ export default class Vector extends AbstractArray { this._Type = Type; } - static decodeVector (Type: Constructor, value: Vector | Uint8Array | string | Array): Array { + public static decodeVector (Type: Constructor, value: Vector | Uint8Array | string | any[]): T[] { if (Array.isArray(value)) { - return value.map((entry, index) => { + return value.map((entry, index): T => { try { return entry instanceof Type ? entry @@ -52,13 +52,13 @@ export default class Vector extends AbstractArray { return decodeU8a(u8a.subarray(offset), new Array(length.toNumber()).fill(Type)) as T[]; } - static with (Type: Constructor): Constructor> { + public static with (Type: Constructor): Constructor> { return class extends Vector { - constructor (value?: Array) { + public constructor (value?: any[]) { super(Type, value); } - static Fallback = Type.Fallback + public static Fallback = Type.Fallback ? Vector.with(Type.Fallback) : undefined; }; @@ -67,14 +67,14 @@ export default class Vector extends AbstractArray { /** * @description The type for the items */ - get Type (): string { + public get Type (): string { return this._Type.name; } /** * @description Finds the index of the value in the array */ - indexOf (_other?: any): number { + public indexOf (_other?: any): number { // convert type first, this removes overhead from the eq const other = _other instanceof this._Type ? _other @@ -92,7 +92,7 @@ export default class Vector extends AbstractArray { /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return `Vec<${new this._Type().toRawType()}>`; } } diff --git a/packages/types/src/codec/VectorAny.ts b/packages/types/src/codec/VectorAny.ts index 4f3c750d13..cb8294a516 100644 --- a/packages/types/src/codec/VectorAny.ts +++ b/packages/types/src/codec/VectorAny.ts @@ -16,7 +16,7 @@ export default class VectorAny extends AbstractArray { /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { // FIXME This is basically an any type, cannot instantiate via createType return 'Vec'; } diff --git a/packages/types/src/codec/VectorFixed.ts b/packages/types/src/codec/VectorFixed.ts index f129a0c973..e6bcfa81eb 100644 --- a/packages/types/src/codec/VectorFixed.ts +++ b/packages/types/src/codec/VectorFixed.ts @@ -17,7 +17,7 @@ import Vector from './Vector'; export default class VectorFixed extends AbstractArray { private _Type: Constructor; - constructor (Type: Constructor, length: number, value: VectorFixed | Uint8Array | string | Array = [] as Array) { + public constructor (Type: Constructor, length: number, value: VectorFixed | Uint8Array | string | any[] = [] as any[]) { super( ...VectorFixed.decodeVectorFixed(Type, length, value) ); @@ -25,7 +25,7 @@ export default class VectorFixed extends AbstractArray { this._Type = Type; } - static decodeVectorFixed (Type: Constructor, allocLength: number, value: VectorFixed | Uint8Array | string | Array): Array { + public static decodeVectorFixed (Type: Constructor, allocLength: number, value: VectorFixed | Uint8Array | string | any[]): T[] { const values = Vector.decodeVector( Type, isU8a(value) @@ -42,13 +42,13 @@ export default class VectorFixed extends AbstractArray { return values; } - static with (Type: Constructor, length: number): Constructor> { + public static with (Type: Constructor, length: number): Constructor> { return class extends VectorFixed { - constructor (value?: Array) { + public constructor (value?: any[]) { super(Type, length, value); } - static Fallback = Type.Fallback + public static Fallback = Type.Fallback ? VectorFixed.with(Type.Fallback, length) : undefined; }; @@ -57,18 +57,18 @@ export default class VectorFixed extends AbstractArray { /** * @description The type for the items */ - get Type (): string { + public get Type (): string { return this._Type.name; } - toU8a (): Uint8Array { + public toU8a (): Uint8Array { return super.toU8a(true); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return `[${new this._Type().toRawType()};${this.length}`; } } diff --git a/packages/types/src/codec/createType.spec.ts b/packages/types/src/codec/createType.spec.ts index 74d384eb88..d45b46b2be 100644 --- a/packages/types/src/codec/createType.spec.ts +++ b/packages/types/src/codec/createType.spec.ts @@ -2,66 +2,68 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import createType, { TypeDefInfo, getTypeClass, getTypeDef, typeSplit } from './createType'; +import { Codec, Constructor } from '../types'; -describe('typeSplit', () => { - it('splits simple types into an array', () => { +import createType, { TypeDef, TypeDefInfo, getTypeClass, getTypeDef, typeSplit } from './createType'; + +describe('typeSplit', (): void => { + it('splits simple types into an array', (): void => { expect( typeSplit('Text, u32, u64') ).toEqual(['Text', 'u32', 'u64']); }); - it('splits nested combinations', () => { + it('splits nested combinations', (): void => { expect( typeSplit('Text, (u32), Vec') ).toEqual(['Text', '(u32)', 'Vec']); }); - it('keeps nested tuples together', () => { + it('keeps nested tuples together', (): void => { expect( typeSplit('Text, (u32, u128), Vec') ).toEqual(['Text', '(u32, u128)', 'Vec']); }); - it('keeps nested vector tuples together', () => { + it('keeps nested vector tuples together', (): void => { expect( typeSplit('Text, (u32, u128), Vec<(u64, u32)>') ).toEqual(['Text', '(u32, u128)', 'Vec<(u64, u32)>']); }); - it('allows for deep nesting', () => { + it('allows for deep nesting', (): void => { expect( typeSplit('Text, (u32, (u128, u8)), Vec<(u64, (u32, u32))>') ).toEqual(['Text', '(u32, (u128, u8))', 'Vec<(u64, (u32, u32))>']); }); - it('checks for unclosed vec', () => { + it('checks for unclosed vec', (): void => { expect( - () => typeSplit('Text, Vec typeSplit('Text, Vec { + it('checks for unclosed tuple', (): void => { expect( - () => typeSplit('Text, (u64, u32') + (): string[] => typeSplit('Text, (u64, u32') ).toThrow(/Invalid defintion/); }); }); -describe('getTypeValue', () => { - it('does not allow invalid tuples, end )', () => { +describe('getTypeValue', (): void => { + it('does not allow invalid tuples, end )', (): void => { expect( - () => getTypeDef('(u64, u32') + (): TypeDef => getTypeDef('(u64, u32') ).toThrow(/Expected '\(' closing with '\)'/); }); - it('does not allow invalid vectors, end >', () => { + it('does not allow invalid vectors, end >', (): void => { expect( - () => getTypeDef('Vec getTypeDef('Vec'/); }); - it('returns a type structure', () => { + it('returns a type structure', (): void => { expect( getTypeDef('(u32, Compact, Vec, Option, DoubleMap, (Text, Vec<(Bool, u128)>))') ).toEqual({ @@ -136,7 +138,7 @@ describe('getTypeValue', () => { }); }); - it('returns a type structure (actual)', () => { + it('returns a type structure (actual)', (): void => { expect( getTypeDef('Vec<(PropIndex, Proposal, AccountId)>') ).toEqual({ @@ -163,7 +165,7 @@ describe('getTypeValue', () => { }); }); - it('returns an actual Struct', () => { + it('returns an actual Struct', (): void => { expect( getTypeDef('{"balance":"Balance","account_id":"AccountId","log":"(u64, Signature)"}') ).toEqual({ @@ -200,16 +202,16 @@ describe('getTypeValue', () => { }); }); -describe('getTypeClass', () => { - it('does not allow invalid types', () => { +describe('getTypeClass', (): void => { + it('does not allow invalid types', (): void => { expect( - () => getTypeClass('SomethingInvalid' as any) + (): Constructor => getTypeClass('SomethingInvalid' as any) ).toThrow(/determine type/); }); }); -describe('createType', () => { - it('allows creation of a Struct', () => { +describe('createType', (): void => { + it('allows creation of a Struct', (): void => { expect( createType('{"balance":"Balance","index":"u32"}', { balance: 1234, @@ -221,43 +223,43 @@ describe('createType', () => { }); }); - it('allows creation of a Enum (simple)', () => { + it('allows creation of a Enum (simple)', (): void => { expect( createType('{"_enum": ["A", "B", "C"]}', 1).toJSON() ).toEqual({ B: null }); }); - it('allows creation of a Enum (parametrised)', () => { + it('allows creation of a Enum (parametrised)', (): void => { expect( createType('{"_enum": {"A": null, "B": "u32", "C": null} }', 1).toJSON() ).toEqual({ B: 0 }); }); - it('allows creation of a [u8; 8]', () => { + it('allows creation of a [u8; 8]', (): void => { expect( createType('[u8; 8]', [0x12, 0x00, 0x23, 0x00, 0x45, 0x00, 0x67, 0x00]).toHex() ).toEqual('0x1200230045006700'); }); - it('allows creation of a [u16; 4]', () => { + it('allows creation of a [u16; 4]', (): void => { expect( createType('[u16; 4]', [0x1200, 0x2300, 0x4500, 0x6700]).toU8a() ).toEqual(new Uint8Array([0x00, 0x12, 0x00, 0x23, 0x00, 0x45, 0x00, 0x67])); }); - it('throw error when create base is a StorageData with null value and isPedantic is true', () => { + it('throw error when create base is a StorageData with null value and isPedantic is true', (): void => { const base = createType('StorageData', null); expect( - () => createType('DoubleMap>', base, true) + (): Codec => createType('DoubleMap>', base, true) ).toThrow(/ Input doesn't match output, received 0x, created 0x00/); }); - it('throw error when create base is a StorageData with null value and isPedantic is true', () => { + it('throw error when create base is a StorageData with null value and isPedantic is true', (): void => { const base = createType('StorageData', null); expect( - () => createType('Vec<(BlockNumber,EventIndex)>', base, true) + (): Codec => createType('Vec<(BlockNumber,EventIndex)>', base, true) ).toThrow(/Input doesn't match output, received 0x, created 0x00/); }); }); diff --git a/packages/types/src/codec/createType.ts b/packages/types/src/codec/createType.ts index 01ea230de2..08054c991a 100644 --- a/packages/types/src/codec/createType.ts +++ b/packages/types/src/codec/createType.ts @@ -35,21 +35,21 @@ export enum TypeDefInfo { Null } -export type TypeDefExtVecFixed = { - length: number, - type: string -}; +export interface TypeDefExtVecFixed { + length: number; + type: string; +} -export type TypeDef = { - info: TypeDefInfo, - ext?: TypeDefExtVecFixed, // add additional here as required - name?: string, - type: string, - sub?: TypeDef | Array -}; +export interface TypeDef { + info: TypeDefInfo; + ext?: TypeDefExtVecFixed; // add additional here as required + name?: string; + type: string; + sub?: TypeDef | TypeDef[]; +} // safely split a string on ', ' while taking care of any nested occurences -export function typeSplit (type: string): Array { +export function typeSplit (type: string): string[] { let cDepth = 0; // compact/doublemap/linkedmap/option/vector depth let fDepth = 0; // vector (fixed) depth let sDepth = 0; // struct depth @@ -119,7 +119,7 @@ export function getTypeDef (_type: Text | string, name?: string): TypeDef { if (startingWith(type, '(', ')')) { value.info = TypeDefInfo.Tuple; - value.sub = typeSplit(subType).map((inner) => getTypeDef(inner)); + value.sub = typeSplit(subType).map((inner): TypeDef => getTypeDef(inner)); } else if (startingWith(type, '[', ']')) { // this handles e.g. [u8;32] const [vecType, _vecLen] = type.substr(1, type.length - 2).split(';'); @@ -129,7 +129,7 @@ export function getTypeDef (_type: Text | string, name?: string): TypeDef { assert(vecLen <= 256, `Only support for [Type; ], where length <= 256`); value.info = TypeDefInfo.VectorFixed; - value.ext = { length: vecLen, type: vecType } as TypeDefExtVecFixed; + value.ext = { length: vecLen, type: vecType } as unknown as TypeDefExtVecFixed; } else if (startingWith(type, '{', '}')) { const parsed = JSON.parse(type); const keys = Object.keys(parsed); @@ -139,12 +139,12 @@ export function getTypeDef (_type: Text | string, name?: string): TypeDef { // not as pretty, but remain compatible with oo7 for both struct and Array types value.sub = Array.isArray(details) - ? details.map((name) => ({ + ? details.map((name): TypeDef => ({ info: TypeDefInfo.Plain, name, type: 'Null' })) - : Object.keys(details).map((name) => ({ + : Object.keys(details).map((name): TypeDef => ({ info: TypeDefInfo.Plain, name, type: details[name] || 'Null' @@ -152,7 +152,7 @@ export function getTypeDef (_type: Text | string, name?: string): TypeDef { value.info = TypeDefInfo.Enum; } else { value.info = TypeDefInfo.Struct; - value.sub = keys.map((name) => getTypeDef(parsed[name], name)); + value.sub = keys.map((name): TypeDef => getTypeDef(parsed[name], name)); } } else if (startingWith(type, 'Compact<', '>')) { value.info = TypeDefInfo.Compact; @@ -174,13 +174,21 @@ export function getTypeDef (_type: Text | string, name?: string): TypeDef { return value; } +export function createClass (type: Text | string): Constructor { + // eslint-disable-next-line @typescript-eslint/no-use-before-define + return getTypeClass( + getTypeDef(type) + ); +} + // create an array of constructors from the input -export function getTypeClassMap (defs: Array): { [index: string]: Constructor } { - return defs.reduce((result, sub) => { +export function getTypeClassMap (defs: TypeDef[]): { [index: string]: Constructor } { + return defs.reduce((result, sub): Record => { + // eslint-disable-next-line @typescript-eslint/no-use-before-define result[sub.name as string] = getTypeClass(sub); return result; - }, {} as { [index: string]: Constructor }); + }, {} as unknown as Record); } // Returns the type Class for construction @@ -202,7 +210,7 @@ export function getTypeClass (value: TypeDef, Fallback?: Constructor): Construct assert(value.sub && Array.isArray(value.sub), 'Expected subtype for Enum'); return Enum.with( - getTypeClassMap(value.sub as Array) + getTypeClassMap(value.sub as TypeDef[]) ); case TypeDefInfo.Option: assert(value.sub && !Array.isArray(value.sub), 'Expected subtype for Option'); @@ -214,13 +222,13 @@ export function getTypeClass (value: TypeDef, Fallback?: Constructor): Construct assert(Array.isArray(value.sub), 'Expected nested subtypes for Struct'); return Struct.with( - getTypeClassMap(value.sub as Array) + getTypeClassMap(value.sub as TypeDef[]) ); case TypeDefInfo.Tuple: assert(Array.isArray(value.sub), 'Expected nested subtypes for Tuple'); return Tuple.with( - (value.sub as Array).map((Type) => getTypeClass(Type)) + (value.sub as TypeDef[]).map((Type): Constructor => getTypeClass(Type)) ); case TypeDefInfo.Vector: assert(value.sub && !Array.isArray(value.sub), 'Expected subtype for Vector'); @@ -257,12 +265,6 @@ export function getTypeClass (value: TypeDef, Fallback?: Constructor): Construct throw new Error(`Unable to determine type from '${value.type}'`); } -export function createClass (type: Text | string): Constructor { - return getTypeClass( - getTypeDef(type) - ); -} - // alias for createClass export function ClassOf (name: string): Constructor { return createClass(name); diff --git a/packages/types/src/codec/typeRegistry.ts b/packages/types/src/codec/typeRegistry.ts index 477b753b10..3fa4e04a40 100644 --- a/packages/types/src/codec/typeRegistry.ts +++ b/packages/types/src/codec/typeRegistry.ts @@ -8,13 +8,17 @@ import { Constructor, RegistryTypes } from '../types'; import { createClass } from './createType'; export class TypeRegistry { - static readonly defaultRegistry: TypeRegistry = new TypeRegistry(); + public static readonly defaultRegistry: TypeRegistry = new TypeRegistry(); private _registry: Map = new Map(); - register (type: Constructor | RegistryTypes): void; - register (name: string, type: Constructor): void; - register (arg1: string | Constructor | RegistryTypes, arg2?: Constructor): void { + public register (type: Constructor | RegistryTypes): void; + + // eslint-disable-next-line no-dupe-class-members + public register (name: string, type: Constructor): void; + + // eslint-disable-next-line no-dupe-class-members + public register (arg1: string | Constructor | RegistryTypes, arg2?: Constructor): void { if (isString(arg1)) { const name = arg1; const type = arg2!; @@ -30,8 +34,8 @@ export class TypeRegistry { } } - private registerObject (obj: RegistryTypes, overwrite: boolean = true) { - Object.entries(obj).forEach(([name, type]) => { + private registerObject (obj: RegistryTypes, overwrite: boolean = true): void { + Object.entries(obj).forEach(([name, type]): void => { if (overwrite || !this.get(name)) { if (isString(type)) { this._registry.set(name, createClass(type)); @@ -45,11 +49,11 @@ export class TypeRegistry { }); } - get (name: string): Constructor | undefined { + public get (name: string): Constructor | undefined { return this._registry.get(name); } - getOrThrow (name: string, msg?: string): Constructor { + public getOrThrow (name: string, msg?: string): Constructor { const type = this.get(name); if (isUndefined(type)) { @@ -62,8 +66,9 @@ export class TypeRegistry { let defaultRegistry: TypeRegistry; -export default function getDefaultRegistry () { +export default function getDefaultRegistry (): TypeRegistry { if (!defaultRegistry) { + // eslint-disable-next-line @typescript-eslint/no-var-requires const defaultTypes = require('../index.types'); defaultRegistry = new TypeRegistry(); diff --git a/packages/types/src/codec/utils/compareArray.spec.ts b/packages/types/src/codec/utils/compareArray.spec.ts index d6b74ecc75..8dbeb870ad 100644 --- a/packages/types/src/codec/utils/compareArray.spec.ts +++ b/packages/types/src/codec/utils/compareArray.spec.ts @@ -5,28 +5,28 @@ import U32 from '../../primitive/U32'; import compareArray from './compareArray'; -describe('compareArray', () => { +describe('compareArray', (): void => { const a = [new U32(123), new U32(456), new U32(789)]; - it('returns false when second param is a non-array', () => { + it('returns false when second param is a non-array', (): void => { expect( compareArray(a, 123) ).toBe(false); }); - it('compares array of codec agains primitive', () => { + it('compares array of codec agains primitive', (): void => { expect( compareArray(a, [123, 456, 789]) ).toBe(true); }); - it('compares array of codec agains codec', () => { + it('compares array of codec agains codec', (): void => { expect( compareArray(a, [new U32(123), new U32(456), new U32(789)]) ).toBe(true); }); - it('compares primitive against primitive', () => { + it('compares primitive against primitive', (): void => { expect( compareArray( [123, 456], [123, 456] @@ -34,13 +34,13 @@ describe('compareArray', () => { ).toBe(true); }); - it('returns false when lengths are not matching', () => { + it('returns false when lengths are not matching', (): void => { expect( compareArray(a, [123]) ).toBe(false); }); - it('returns false when value mismatches', () => { + it('returns false when value mismatches', (): void => { expect( compareArray(a, [123, 456, 999]) ).toBe(false); diff --git a/packages/types/src/codec/utils/compareArray.ts b/packages/types/src/codec/utils/compareArray.ts index 1ffb8d9974..b85f8acb1f 100644 --- a/packages/types/src/codec/utils/compareArray.ts +++ b/packages/types/src/codec/utils/compareArray.ts @@ -5,11 +5,11 @@ import { isFunction, isUndefined } from '@polkadot/util'; // NOTE These are used internally and when comparing objects, expects that -// when the second is an Array that the first has to be as well -export default function compareArray (a: Array, b?: any): boolean { +// when the second is an Codec[] that the first has to be as well +export default function compareArray (a: any[], b?: any): boolean { if (Array.isArray(b)) { return (a.length === b.length) && isUndefined( - a.find((value, index) => + a.find((value, index): boolean => isFunction(value.eq) ? !value.eq(b[index]) : value !== b[index] diff --git a/packages/types/src/codec/utils/compareMap.spec.ts b/packages/types/src/codec/utils/compareMap.spec.ts index 332b8af0b8..e1741fad19 100644 --- a/packages/types/src/codec/utils/compareMap.spec.ts +++ b/packages/types/src/codec/utils/compareMap.spec.ts @@ -6,7 +6,7 @@ import { Codec } from '../../types'; import U32 from '../../primitive/U32'; import compareMap from './compareMap'; -describe('compareMap', () => { +describe('compareMap', (): void => { const a = new Map([ ['decimals', new U32(15)], ['missing', new U32(10)], @@ -23,7 +23,7 @@ describe('compareMap', () => { ['foobar', new U32(5)] ]); - it('compares Map against Object', () => { + it('compares Map against Object', (): void => { expect( compareMap(a, { decimals: 15, @@ -33,7 +33,7 @@ describe('compareMap', () => { ).toBe(true); }); - it('compares Map against entries array', () => { + it('compares Map against entries array', (): void => { expect( compareMap(b, [ ['missing', 10], ['decimals', 15], ['foobar', 5] @@ -41,39 +41,39 @@ describe('compareMap', () => { ).toBe(true); }); - it('compares between 2 maps', () => { + it('compares between 2 maps', (): void => { expect(compareMap(a, b)).toBe(true); }); - it('compares between 2 maps (both codec)', () => { + it('compares between 2 maps (both codec)', (): void => { expect(compareMap(a, c)).toBe(true); }); - it('returns false when second param is a non-map, non-array, non-object', () => { + it('returns false when second param is a non-map, non-array, non-object', (): void => { expect( compareMap(a, 123) ).toBe(false); }); - it('returns false when second param is a array with non-entries', () => { + it('returns false when second param is a array with non-entries', (): void => { expect( compareMap(a, [123, 456, 789]) ).toBe(false); }); - it('returns false when second param is a array with non-entries (only key)', () => { + it('returns false when second param is a array with non-entries (only key)', (): void => { expect( compareMap(a, [[123], [456], [789]]) ).toBe(false); }); - it('returns false when properties are missing', () => { + it('returns false when properties are missing', (): void => { expect( compareMap(a, [['decimals', 15], ['wrong', 10], ['foobar', 5]]) ).toBe(false); }); - it('returns false when lengths do not match', () => { + it('returns false when lengths do not match', (): void => { expect( compareMap(a, [['decimals', 15]]) ).toBe(false); diff --git a/packages/types/src/codec/utils/compareMap.ts b/packages/types/src/codec/utils/compareMap.ts index 02de2876e8..e0e16663ea 100644 --- a/packages/types/src/codec/utils/compareMap.ts +++ b/packages/types/src/codec/utils/compareMap.ts @@ -9,7 +9,7 @@ import { isFunction, isObject, isUndefined } from '@polkadot/util'; export default function compareMap (a: Map, b?: any): boolean { if (Array.isArray(b)) { return (a.size === b.length) && isUndefined( - b.find((entry) => { + b.find((entry): boolean => { if (!Array.isArray(entry) || entry.length !== 2) { return true; } diff --git a/packages/types/src/index.spec.ts b/packages/types/src/index.spec.ts index 2e234d8c46..5d15a644da 100644 --- a/packages/types/src/index.spec.ts +++ b/packages/types/src/index.spec.ts @@ -4,17 +4,17 @@ import extrinsics from '@polkadot/api-metadata/extrinsics/static'; -import { Constructor } from './types'; +import { Codec, Constructor } from './types'; import * as Classes from './index.types'; const Types = Classes as { [index: string]: Constructor }; const UNCONSTRUCTABLE = ['origin', 'usize', 'vote']; -describe('types', () => { - describe('default creation', () => { - Object.keys(Types).forEach((name) => { - it(`creates an empty ${name}`, () => { - const constructFn = () => +describe('types', (): void => { + describe('default creation', (): void => { + Object.keys(Types).forEach((name): void => { + it(`creates an empty ${name}`, (): void => { + const constructFn = (): Codec => new Types[name](); if (UNCONSTRUCTABLE.includes(name.toLowerCase())) { @@ -26,12 +26,12 @@ describe('types', () => { }); }); - describe('default creation (empty bytes)', () => { + describe('default creation (empty bytes)', (): void => { (Types.Method as any).injectMethods(extrinsics); - Object.keys(Types).forEach((name) => { - it(`creates an empty ${name} (from empty bytes)`, () => { - const constructFn = () => + Object.keys(Types).forEach((name): void => { + it(`creates an empty ${name} (from empty bytes)`, (): void => { + const constructFn = (): Codec => new Types[name](new Types.Bytes()); if (UNCONSTRUCTABLE.includes(name.toLowerCase())) { diff --git a/packages/types/src/primitive/AccountId.spec.ts b/packages/types/src/primitive/AccountId.spec.ts index b05027506e..717c53a161 100644 --- a/packages/types/src/primitive/AccountId.spec.ts +++ b/packages/types/src/primitive/AccountId.spec.ts @@ -10,26 +10,26 @@ import jsonVec from '../json/AccountIdVec.001.json'; import AccountId from './AccountId'; import StorageData from './StorageData'; -describe('AccountId', () => { - describe('defaults', () => { +describe('AccountId', (): void => { + describe('defaults', (): void => { const id = new AccountId(); - it('has a 32-byte length', () => { + it('has a 32-byte length', (): void => { expect(id).toHaveLength(32); }); - it('is empty by default', () => { + it('is empty by default', (): void => { expect(id.isEmpty).toBe(true); }); - it('equals the empty address', () => { + it('equals the empty address', (): void => { expect(id.eq('5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM')).toBe(true); }); }); - describe('decoding', () => { - const testDecode = (type: string, input: Uint8Array | string | AccountId, expected: string) => - it(`can decode from ${type}`, () => { + describe('decoding', (): void => { + const testDecode = (type: string, input: Uint8Array | string | AccountId, expected: string): void => + it(`can decode from ${type}`, (): void => { const a = new AccountId(input); expect(a.toString()).toBe(expected); }); @@ -59,9 +59,9 @@ describe('AccountId', () => { ); }); - describe('encoding', () => { - const testEncode = (to: 'toHex' | 'toJSON' | 'toString' | 'toU8a', expected: Uint8Array | string, input: string = '5C62W7ELLAAfix9LYrcx5smtcffbhvThkM5x7xfMeYXCtGwF') => - it(`can encode ${to}`, () => { + describe('encoding', (): void => { + const testEncode = (to: 'toHex' | 'toJSON' | 'toString' | 'toU8a', expected: Uint8Array | string, input: string = '5C62W7ELLAAfix9LYrcx5smtcffbhvThkM5x7xfMeYXCtGwF'): void => + it(`can encode ${to}`, (): void => { const a = new AccountId(input); expect(a[to]()).toEqual(expected); @@ -76,17 +76,17 @@ describe('AccountId', () => { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 ])); - it('decodes to a non-empty value', () => { + it('decodes to a non-empty value', (): void => { expect(new AccountId('7qT1BvpawNbqb3BZaBTMFMMAKrpJKLPf1LmEHR1JyarWJdMX').isEmpty).toBe(false); }); }); - describe('storage decoding', () => { - it('has the correct entries', () => { + describe('storage decoding', (): void => { + it('has the correct entries', (): void => { setAddressPrefix(68); const data = new StorageData(jsonVec.params.result.changes[0][1]); - const list = new Vector(AccountId, data).map((accountId) => accountId.toString()); + const list = new Vector(AccountId, data).map((accountId): string => accountId.toString()); expect(list).toEqual([ '7qVJujLF3EDbZt5WfQXWvueFedMS4Vfk2Hb4GyR8jwksTLup', diff --git a/packages/types/src/primitive/AccountId.ts b/packages/types/src/primitive/AccountId.ts index 783616b8cc..f173c46996 100644 --- a/packages/types/src/primitive/AccountId.ts +++ b/packages/types/src/primitive/AccountId.ts @@ -17,14 +17,14 @@ import U8aFixed from '../codec/U8aFixed'; * just a Uint8Array wrapper with a fixed length. */ export default class AccountId extends U8aFixed { - constructor (value: AnyU8a = new Uint8Array()) { + public constructor (value: AnyU8a = new Uint8Array()) { super( AccountId.decodeAccountId(value), 256 ); } - static encode (value: Uint8Array): string { + public static encode (value: Uint8Array): string { return encodeAddress(value); } @@ -34,7 +34,7 @@ export default class AccountId extends U8aFixed { } else if (isHex(value)) { return hexToU8a(value.toString()); } else if (isString(value)) { - return decodeAddress((value as String).toString()); + return decodeAddress((value as string).toString()); } return value; @@ -43,28 +43,28 @@ export default class AccountId extends U8aFixed { /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { return super.eq(AccountId.decodeAccountId(other)); } /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): string { + public toJSON (): string { return this.toString(); } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { return AccountId.encode(this); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'AccountId'; } } diff --git a/packages/types/src/primitive/AccountIndex.spec.ts b/packages/types/src/primitive/AccountIndex.spec.ts index fc9f074499..72d8e76227 100644 --- a/packages/types/src/primitive/AccountIndex.spec.ts +++ b/packages/types/src/primitive/AccountIndex.spec.ts @@ -5,56 +5,57 @@ import BN from 'bn.js'; import AccountIndex from './AccountIndex'; -describe('AccountIndex', () => { - it('creates a BN representation', () => { +describe('AccountIndex', (): void => { + it('creates a BN representation', (): void => { expect( new AccountIndex(new Uint8Array([17, 18, 19, 20])).toNumber() ).toEqual(336794129); }); - it('creates a BN representation (from ss-58)', () => { + it('creates a BN representation (from ss-58)', (): void => { expect( new AccountIndex('Mwz15xP2').toNumber() ).toEqual(336794129); }); - it('constructs 2-byte from number', () => { + it('constructs 2-byte from number', (): void => { expect( new AccountIndex(256 * 1).toString() ).toEqual('25GUyv'); }); - it('constructs from number', () => { + it('constructs from number', (): void => { expect( new AccountIndex(new BN(336794129)).toString() ).toEqual('Mwz15xP2'); }); - it('compares ss-58 values', () => { + it('compares ss-58 values', (): void => { expect(new AccountIndex(256 * 1).eq('25GUyv')).toBe(true); }); - it('compares numbers', () => { + it('compares numbers', (): void => { expect(new AccountIndex('2jpAFn').eq(256 * 1)).toBe(true); }); - describe('calcLength', () => { - const testLength = (value: number, length: number) => + describe('calcLength', (): void => { + const testLength = (value: number, length: number): void => { expect(AccountIndex.calcLength(value)).toEqual(length); + }; - it('returns 1 for <= 0xef', () => { + it('returns 1 for <= 0xef', (): void => { testLength(0xef, 1); }); - it('returns 2 for > 0xef', () => { + it('returns 2 for > 0xef', (): void => { testLength(0xf0, 2); }); - it('returns 4 bytes for 32-bit inputs', () => { + it('returns 4 bytes for 32-bit inputs', (): void => { testLength(0xffeeddcc, 4); }); - it('returns 8 bytes for larger inputs', () => { + it('returns 8 bytes for larger inputs', (): void => { testLength(0x122334455, 8); }); }); diff --git a/packages/types/src/primitive/AccountIndex.ts b/packages/types/src/primitive/AccountIndex.ts index 7045c61264..94b884a0b6 100644 --- a/packages/types/src/primitive/AccountIndex.ts +++ b/packages/types/src/primitive/AccountIndex.ts @@ -27,13 +27,13 @@ const MAX_4BYTE = new BN(1).shln(32); * for an Account. We extends from [[U32]] to provide the number-like properties. */ export default class AccountIndex extends U32 { - constructor (value: AnyNumber = new BN(0)) { + public constructor (value: AnyNumber = new BN(0)) { super( AccountIndex.decodeAccountIndex(value) ); } - static decodeAccountIndex (value: AnyNumber): BN | Uint8Array | number | string { + public static decodeAccountIndex (value: AnyNumber): BN | Uint8Array | number | string { if (value instanceof AccountIndex) { // `value.toBn()` on AccountIndex returns a pure BN (i.e. not an // AccountIndex), which has the initial `toString()` implementation. @@ -45,7 +45,7 @@ export default class AccountIndex extends U32 { return AccountIndex.decodeAccountIndex(decodeAddress(value)); } - static calcLength (_value: BN | number): number { + public static calcLength (_value: BN | number): number { const value = bnToBn(_value); if (value.lte(MAX_1BYTE)) { @@ -59,7 +59,7 @@ export default class AccountIndex extends U32 { return 8; } - static readLength (input: Uint8Array): [number, number] { + public static readLength (input: Uint8Array): [number, number] { const first = input[0]; if (first === PREFIX_2BYTE) { @@ -73,7 +73,7 @@ export default class AccountIndex extends U32 { return [0, 1]; } - static writeLength (input: Uint8Array): Uint8Array { + public static writeLength (input: Uint8Array): Uint8Array { switch (input.length) { case 2: return new Uint8Array([PREFIX_2BYTE]); case 4: return new Uint8Array([PREFIX_4BYTE]); @@ -85,7 +85,7 @@ export default class AccountIndex extends U32 { /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { // shortcut for BN or Number, don't create an object if (isBn(other) || isNumber(other)) { return super.eq(other); @@ -98,14 +98,14 @@ export default class AccountIndex extends U32 { /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): string { + public toJSON (): string { return this.toString(); } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { const length = AccountIndex.calcLength(this); return encodeAddress(this.toU8a().subarray(0, length)); @@ -114,7 +114,7 @@ export default class AccountIndex extends U32 { /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'AccountIndex'; } } diff --git a/packages/types/src/primitive/AccountInfo.ts b/packages/types/src/primitive/AccountInfo.ts index 5aa2ca29bc..dabf50a92c 100644 --- a/packages/types/src/primitive/AccountInfo.ts +++ b/packages/types/src/primitive/AccountInfo.ts @@ -12,7 +12,7 @@ import U64 from './U64'; * An Account information structure for contracts */ export default class AccountInfo extends Struct { - constructor (value: any) { + public constructor (value: any) { super({ trieId: Bytes, currentMemStored: U64 @@ -22,14 +22,14 @@ export default class AccountInfo extends Struct { /** * @description The size of stored value in octet */ - get currentMemStored (): U64 { + public get currentMemStored (): U64 { return this.get('currentMemStored') as U64; } /** * @description Unique ID for the subtree encoded as a byte */ - get trieId (): Bytes { + public get trieId (): Bytes { return this.get('trieId') as Bytes; } } diff --git a/packages/types/src/primitive/Address.spec.ts b/packages/types/src/primitive/Address.spec.ts index 18e4f43629..cc55aa117b 100644 --- a/packages/types/src/primitive/Address.spec.ts +++ b/packages/types/src/primitive/Address.spec.ts @@ -6,27 +6,27 @@ import AccountId from './AccountId'; import AccountIndex from './AccountIndex'; import Address from './Address'; -describe('Address', () => { - const testDecode = (type: string, input: Address | AccountId | AccountIndex | Array | Uint8Array, expected: string) => - it(`can decode from ${type}`, () => { +describe('Address', (): void => { + const testDecode = (type: string, input: Address | AccountId | AccountIndex | number[] | Uint8Array, expected: string): void => + it(`can decode from ${type}`, (): void => { const a = new Address(input); expect(a.toString()).toBe(expected); }); - describe('utility', () => { - it('equals on AccountId', () => { + describe('utility', (): void => { + it('equals on AccountId', (): void => { const addr = '5DkQbYAExs3M2sZgT1Ec3mKfZnAQCL4Dt9beTCknkCUn5jzo'; expect(new Address(addr).eq(addr)).toBe(true); }); - it('equals on AccountIndex', () => { + it('equals on AccountIndex', (): void => { // see the test below - these are equivalent (with different prefix encoding) expect(new Address('2jpAFn').eq('25GUyv')).toBe(true); }); }); - describe('decoding', () => { + describe('decoding', (): void => { testDecode( 'Address', new Address('5C62W7ELLAAfix9LYrcx5smtcffbhvThkM5x7xfMeYXCtGwF'), @@ -91,9 +91,9 @@ describe('Address', () => { // ); }); - describe('encoding', () => { - const testEncode = (to: 'toHex' | 'toString' | 'toU8a', expected: string | Uint8Array) => - it(`can encode ${to}`, () => { + describe('encoding', (): void => { + const testEncode = (to: 'toHex' | 'toString' | 'toU8a', expected: string | Uint8Array): void => + it(`can encode ${to}`, (): void => { const a = new Address('5C62W7ELLAAfix9LYrcx5smtcffbhvThkM5x7xfMeYXCtGwF'); expect(a[to]()).toEqual(expected); }); diff --git a/packages/types/src/primitive/Address.ts b/packages/types/src/primitive/Address.ts index b3be4e58e1..33a36919a5 100644 --- a/packages/types/src/primitive/Address.ts +++ b/packages/types/src/primitive/Address.ts @@ -12,7 +12,7 @@ import Base from '../codec/Base'; import AccountId from './AccountId'; import AccountIndex from './AccountIndex'; -type AnyAddress = BN | Address | AccountId | AccountIndex | Array | Uint8Array | number | string; +type AnyAddress = BN | Address | AccountId | AccountIndex | number[] | Uint8Array | number | string; export const ACCOUNT_ID_PREFIX = new Uint8Array([0xff]); @@ -25,13 +25,13 @@ export const ACCOUNT_ID_PREFIX = new Uint8Array([0xff]); * is encoded as `[ , ...publicKey/...bytes ]` as per spec */ export default class Address extends Base implements Codec { - constructor (value: AnyAddress = new Uint8Array()) { + public constructor (value: AnyAddress = new Uint8Array()) { super( Address.decodeAddress(value) ); } - static decodeAddress (value: AnyAddress): AccountId | AccountIndex { + public static decodeAddress (value: AnyAddress): AccountId | AccountIndex { if (value instanceof AccountId || value instanceof AccountIndex) { return value; } else if (isBn(value) || isNumber(value)) { @@ -66,7 +66,7 @@ export default class Address extends Base implements C /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { const rawLength = this.rawLength; return rawLength + ( @@ -80,14 +80,14 @@ export default class Address extends Base implements C /** * @description Checks if the value is an empty value */ - get isEmpty (): boolean { + public get isEmpty (): boolean { return this.raw.isEmpty; } /** * @description The length of the raw value, either AccountIndex or AccountId */ - get rawLength (): number { + public get rawLength (): number { return this.raw instanceof AccountIndex ? AccountIndex.calcLength(this.raw) : this.raw.encodedLength; @@ -96,35 +96,35 @@ export default class Address extends Base implements C /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { return this.raw.eq(other); } /** * @description Returns a hex string representation of the value */ - toHex (): string { + public toHex (): string { return u8aToHex(this.toU8a()); } /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): string { + public toJSON (): string { return this.raw.toJSON(); } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { return this.raw.toString(); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'Address'; } @@ -132,7 +132,7 @@ export default class Address extends Base implements C * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + public toU8a (isBare?: boolean): Uint8Array { const encoded = this.raw.toU8a().subarray(0, this.rawLength); return isBare diff --git a/packages/types/src/primitive/Balance.ts b/packages/types/src/primitive/Balance.ts index c0b1fb090f..9a93613d1a 100644 --- a/packages/types/src/primitive/Balance.ts +++ b/packages/types/src/primitive/Balance.ts @@ -13,7 +13,7 @@ export default class Balance extends U128 { /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { // NOTE Balance we treat as a special case, don't return the base u128 - there // is typically special processing downstream, i.e. different inputs, it gets // treated as a primitive in this case diff --git a/packages/types/src/primitive/Bool.spec.ts b/packages/types/src/primitive/Bool.spec.ts index ad8a381232..e5a6692b79 100644 --- a/packages/types/src/primitive/Bool.spec.ts +++ b/packages/types/src/primitive/Bool.spec.ts @@ -5,10 +5,11 @@ import Bool from './Bool'; import { CodecTo } from '../types'; -describe('Bool', () => { - describe('decode', () => { - const testDecode = (type: string, input: Uint8Array | boolean | Boolean | Bool | number, expected: boolean) => - it(`can decode from ${type}`, () => { +describe('Bool', (): void => { + describe('decode', (): void => { + // eslint-disable-next-line @typescript-eslint/ban-types + const testDecode = (type: string, input: Uint8Array | boolean | Boolean | Bool | number, expected: boolean): void => + it(`can decode from ${type}`, (): void => { expect(new Bool(input).toJSON()).toBe(expected); }); @@ -19,9 +20,9 @@ describe('Bool', () => { testDecode('Uint8Array', Uint8Array.from([1]), true); }); - describe('encode', () => { - const testEncode = (to: CodecTo, expected: string | Uint8Array | boolean, value: boolean) => - it(`can encode ${to}`, () => { + describe('encode', (): void => { + const testEncode = (to: CodecTo, expected: string | Uint8Array | boolean, value: boolean): void => + it(`can encode ${to}`, (): void => { expect(new Bool(value)[to]()).toEqual(expected); }); @@ -32,16 +33,16 @@ describe('Bool', () => { testEncode('toU8a', Uint8Array.from([0]), false); }); - it('correctly encodes length', () => { + it('correctly encodes length', (): void => { expect(new Bool(true).encodedLength).toEqual(1); }); - describe('utils', () => { - it('compares agains a boolean', () => { + describe('utils', (): void => { + it('compares agains a boolean', (): void => { expect(new Bool(true).eq(true)).toBe(true); }); - it('compares agains a Bool', () => { + it('compares agains a Bool', (): void => { expect(new Bool(false).eq(new Bool(false))).toBe(true); }); }); diff --git a/packages/types/src/primitive/Bool.ts b/packages/types/src/primitive/Bool.ts index 5426176f9c..94b1f407de 100644 --- a/packages/types/src/primitive/Bool.ts +++ b/packages/types/src/primitive/Bool.ts @@ -13,7 +13,8 @@ import { Codec } from '../types'; * @noInheritDoc */ export default class Bool extends Boolean implements Codec { - constructor (value: Bool | Boolean | Uint8Array | boolean | number = false) { + // eslint-disable-next-line @typescript-eslint/ban-types + public constructor (value: Bool | Boolean | Uint8Array | boolean | number = false) { super( Bool.decodeBool(value) ); @@ -32,21 +33,21 @@ export default class Bool extends Boolean implements Codec { /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { return 1; } /** * @description Checks if the value is an empty value (always false) */ - get isEmpty (): boolean { + public get isEmpty (): boolean { return false; } /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { return this.valueOf() === ( other instanceof Boolean ? other.valueOf() @@ -57,28 +58,28 @@ export default class Bool extends Boolean implements Codec { /** * @description Returns a hex string representation of the value */ - toHex (): string { + public toHex (): string { return u8aToHex(this.toU8a()); } /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): boolean { + public toJSON (): boolean { return this.valueOf(); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'bool'; } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { return `${this.toJSON()}`; } @@ -86,7 +87,8 @@ export default class Bool extends Boolean implements Codec { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public toU8a (isBare?: boolean): Uint8Array { return new Uint8Array([this.valueOf() ? 1 : 0]); } } diff --git a/packages/types/src/primitive/Bytes.spec.ts b/packages/types/src/primitive/Bytes.spec.ts index a3f978eee2..4b0cb3daac 100644 --- a/packages/types/src/primitive/Bytes.spec.ts +++ b/packages/types/src/primitive/Bytes.spec.ts @@ -5,29 +5,29 @@ import Bytes from './Bytes'; import StorageData from './StorageData'; -describe('Bytes', () => { +describe('Bytes', (): void => { const CODE = new Uint8Array([0x14, 0x3a, 0x63, 0x6f, 0x64, 0x65]); - describe('construction', () => { - it('decodes when input is string', () => { + describe('construction', (): void => { + it('decodes when input is string', (): void => { expect( new Bytes(':code').toU8a() ).toEqual(CODE); }); - it('decodes when hex is not length prefixed', () => { + it('decodes when hex is not length prefixed', (): void => { expect( new Bytes('0x3a636f6465').toU8a() ).toEqual(CODE); }); - it('decodes from Array', () => { + it('decodes from number[]', (): void => { expect( new Bytes([0x3a, 0x63, 0x6f, 0x64, 0x65]).toU8a() ).toEqual(CODE); }); - it('creates via storagedata (no prefix)', () => { + it('creates via storagedata (no prefix)', (): void => { expect( new Bytes( new StorageData('0x3a636f6465') @@ -35,7 +35,7 @@ describe('Bytes', () => { ).toEqual(CODE); }); - it('creates via storagedata (with length prefix)', () => { + it('creates via storagedata (with length prefix)', (): void => { expect( new Bytes( new StorageData('0x143a636f6465') diff --git a/packages/types/src/primitive/Bytes.ts b/packages/types/src/primitive/Bytes.ts index 55831df1fd..a0ba42c96e 100644 --- a/packages/types/src/primitive/Bytes.ts +++ b/packages/types/src/primitive/Bytes.ts @@ -16,7 +16,7 @@ import U8a from '../codec/U8a'; * as what is found in [[Text]] and [[Vector]]) */ export default class Bytes extends U8a { - constructor (value?: AnyU8a) { + public constructor (value?: AnyU8a) { super(Bytes.decodeBytes(value)); } @@ -65,14 +65,14 @@ export default class Bytes extends U8a { /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { return this.length + Compact.encodeU8a(this.length).length; } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'Bytes'; } @@ -80,7 +80,7 @@ export default class Bytes extends U8a { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + public toU8a (isBare?: boolean): Uint8Array { return isBare ? super.toU8a(isBare) : Compact.addLengthPrefix(this); diff --git a/packages/types/src/primitive/Data.ts b/packages/types/src/primitive/Data.ts index e51ec23755..441ea687dc 100644 --- a/packages/types/src/primitive/Data.ts +++ b/packages/types/src/primitive/Data.ts @@ -13,7 +13,7 @@ export default class Data extends U8a { /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'Data'; } } diff --git a/packages/types/src/primitive/Event.ts b/packages/types/src/primitive/Event.ts index 50fbec85a5..b6a055f7cc 100644 --- a/packages/types/src/primitive/Event.ts +++ b/packages/types/src/primitive/Event.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { Constructor } from '../types'; +import { Constructor, Codec } from '../types'; import { assert, isUndefined, stringCamelCase, u8aToHex } from '@polkadot/util'; @@ -16,7 +16,7 @@ import Null from './Null'; import U32 from './U32'; import Unconstructable from './Unconstructable'; -const EventTypes: { [index: string]: Constructor } = {}; +const EventTypes: Record> = {}; /** * @name EventIndex @@ -33,11 +33,14 @@ export class EventIndex extends U32 { */ export class EventData extends Tuple { private _meta: EventMetadataV6; - private _method: string; - private _section: string; - private _typeDef: Array; - constructor (Types: Array, value: Uint8Array, typeDef: Array, meta: EventMetadataV6, section: string, method: string) { + private _method: string; + + private _section: string; + + private _typeDef: TypeDef[]; + + public constructor (Types: Constructor[], value: Uint8Array, typeDef: TypeDef[], meta: EventMetadataV6, section: string, method: string) { super(Types, value); this._meta = meta; @@ -49,28 +52,28 @@ export class EventData extends Tuple { /** * @description The wrapped [[EventMetadata]] */ - get meta (): EventMetadataV6 { + public get meta (): EventMetadataV6 { return this._meta; } /** * @description The method as a string */ - get method (): string { + public get method (): string { return this._method; } /** * @description The section as a string */ - get section (): string { + public get section (): string { return this._section; } /** * @description The [[TypeDef]] for this event */ - get typeDef (): Array { + public get typeDef (): TypeDef[] { return this._typeDef; } } @@ -82,7 +85,7 @@ export class EventData extends Tuple { * that indicates the actual event fired */ export class EventId extends U8aFixed { - constructor (value?: any) { + public constructor (value?: any) { super(value, 16); } } @@ -96,7 +99,7 @@ export class EventId extends U8aFixed { export default class Event extends Struct { // Currently we _only_ decode from Uint8Array, since we expect it to // be used via EventRecord - constructor (_value?: Uint8Array) { + public constructor (_value?: Uint8Array) { const { DataType, value } = Event.decodeEvent(_value); super({ @@ -105,7 +108,7 @@ export default class Event extends Struct { }, value); } - static decodeEvent (value: Uint8Array = new Uint8Array()) { + public static decodeEvent (value: Uint8Array = new Uint8Array()): { DataType: Constructor | Constructor; value?: { index: Uint8Array; data: Uint8Array } } { if (!value.length) { return { DataType: Null @@ -128,20 +131,20 @@ export default class Event extends Struct { // This is called/injected by the API on init, allowing a snapshot of // the available system events to be used in lookups - static injectMetadata (metadata: Metadata): void { + public static injectMetadata (metadata: Metadata): void { metadata.asV6.modules - .filter((section) => section.events.isSome) - .forEach((section, sectionIndex) => { + .filter((section): boolean => section.events.isSome) + .forEach((section, sectionIndex): void => { const sectionName = stringCamelCase(section.name.toString()); - section.events.unwrap().forEach((meta, methodIndex) => { + section.events.unwrap().forEach((meta, methodIndex): void => { const methodName = meta.name.toString(); const eventIndex = new Uint8Array([sectionIndex, methodIndex]); - const typeDef = meta.args.map((arg) => getTypeDef(arg)); - const Types = typeDef.map((typeDef) => getTypeClass(typeDef, Unconstructable.with(typeDef))); + const typeDef = meta.args.map((arg): TypeDef => getTypeDef(arg)); + const Types = typeDef.map((typeDef): Constructor => getTypeClass(typeDef, Unconstructable.with(typeDef))); EventTypes[eventIndex.toString()] = class extends EventData { - constructor (value: Uint8Array) { + public constructor (value: Uint8Array) { super(Types, value, typeDef, meta, sectionName, methodName); } }; @@ -152,42 +155,42 @@ export default class Event extends Struct { /** * @description The wrapped [[EventData]] */ - get data (): EventData { + public get data (): EventData { return this.get('data') as EventData; } /** * @description The [[EventId]], identifying the raw event */ - get index (): EventId { + public get index (): EventId { return this.get('index') as EventId; } /** * @description The [[EventMetadata]] with the documentation */ - get meta (): EventMetadataV6 { + public get meta (): EventMetadataV6 { return this.data.meta; } /** * @description The method string identifying the event */ - get method (): string { + public get method (): string { return this.data.method; } /** * @description The section string identifying the event */ - get section (): string { + public get section (): string { return this.data.section; } /** * @description The [[TypeDef]] for the event */ - get typeDef (): Array { + public get typeDef (): TypeDef[] { return this.data.typeDef; } } diff --git a/packages/types/src/primitive/EventRecord.spec.ts b/packages/types/src/primitive/EventRecord.spec.ts index af82246d4e..5dca839366 100644 --- a/packages/types/src/primitive/EventRecord.spec.ts +++ b/packages/types/src/primitive/EventRecord.spec.ts @@ -12,15 +12,15 @@ import metadata from '../Metadata/static'; import Event from './Event'; import EventRecord from './EventRecord'; -describe('EventRecord', () => { - describe('EventRecord_0_76', () => { - beforeEach(() => { +describe('EventRecord', (): void => { + describe('EventRecord_0_76', (): void => { + beforeEach((): void => { Event.injectMetadata( new Metadata(metadataV0) ); }); - it('decodes correctly', () => { + it('decodes correctly', (): void => { const records: Vector = createType('Vec', json1.params.result.changes[0][1]) as any; const er = records[0]; @@ -28,21 +28,21 @@ describe('EventRecord', () => { }); }); - describe('EventRecord (current)', () => { - beforeEach(() => { + describe('EventRecord (current)', (): void => { + beforeEach((): void => { Event.injectMetadata( new Metadata(metadata) ); }); - it('decodes older eventrecord correctly', () => { + it('decodes older eventrecord correctly', (): void => { const records: Vector = createType('Vec', json1.params.result.changes[0][1], true) as any; const er = records[0]; expect(er.phase.type).toEqual('ApplyExtrinsic'); }); - it('decodes eventrecord with topics correctly', () => { + it('decodes eventrecord with topics correctly', (): void => { const hex = json3.params.result.changes[0][1]; const records: Vector = createType('Vec', hex, true) as any; const er = records[0]; diff --git a/packages/types/src/primitive/EventRecord.ts b/packages/types/src/primitive/EventRecord.ts index 087fcbf61f..71c5654ee1 100644 --- a/packages/types/src/primitive/EventRecord.ts +++ b/packages/types/src/primitive/EventRecord.ts @@ -34,7 +34,7 @@ export class Finalization extends Null { * An [[Enum]] that indicates the specific phase where the [[EventRecord]] was generated */ export class Phase extends Enum { - constructor (value: any, index?: number) { + public constructor (value: any, index?: number) { super({ ApplyExtrinsic, Finalization @@ -44,7 +44,7 @@ export class Phase extends Enum { /** * @description Returns the item as a [[ApplyExtrinsic]] */ - get asApplyExtrinsic (): ApplyExtrinsic { + public get asApplyExtrinsic (): ApplyExtrinsic { assert(this.isApplyExtrinsic, `Cannot convert '${this.type}' via asApplyExtrinsic`); return this.value as ApplyExtrinsic; @@ -53,7 +53,7 @@ export class Phase extends Enum { /** * @description Returns the item as a [[Finalization]] */ - get asFinalization (): Finalization { + public get asFinalization (): Finalization { assert(this.isFinalization, `Cannot convert '${this.type}' via asFinalization`); return this.value as Finalization; @@ -62,14 +62,14 @@ export class Phase extends Enum { /** * @description true when this is a ApplyExtrinsic */ - get isApplyExtrinsic (): boolean { + public get isApplyExtrinsic (): boolean { return this.type === 'ApplyExtrinsic'; } /** * @description true when this is a ApplyExtrinsic */ - get isFinalization (): boolean { + public get isFinalization (): boolean { return this.type === 'Finalization'; } } @@ -80,9 +80,8 @@ export class Phase extends Enum { * A record for an [[Event]] (as specified by [[Metadata]]) with the specific [[Phase]] of * application. */ -// tslint:disable-next-line -export class EventRecord_0_76 extends Struct { - constructor (value: any) { +export class EventRecord0to76 extends Struct { + public constructor (value: any) { super({ phase: Phase, event: Event @@ -92,21 +91,21 @@ export class EventRecord_0_76 extends Struct { /** * @description The [[Event]] this record refers to */ - get event (): Event { + public get event (): Event { return this.get('event') as Event; } /** * @description The [[Phase]] where the event was generated */ - get phase (): Phase { + public get phase (): Phase { return this.get('phase') as Phase; } /** * @description The [[Hash]] topics for this event (empty, compat) */ - get topics (): Vector { + public get topics (): Vector { return new (Vector.with(Hash))(); } } @@ -118,7 +117,7 @@ export class EventRecord_0_76 extends Struct { * application. */ export default class EventRecord extends Struct { - constructor (value: any) { + public constructor (value: any) { super({ phase: Phase, event: Event, @@ -126,26 +125,26 @@ export default class EventRecord extends Struct { }, value); } - static Fallback = EventRecord_0_76; + public static Fallback = EventRecord0to76; /** * @description The [[Event]] this record refers to */ - get event (): Event { + public get event (): Event { return this.get('event') as Event; } /** * @description The [[Phase]] where the event was generated */ - get phase (): Phase { + public get phase (): Phase { return this.get('phase') as Phase; } /** * @description The [[Hash]] topics for this event */ - get topics (): Vector { + public get topics (): Vector { return this.get('topics') as Vector; } } diff --git a/packages/types/src/primitive/H160.ts b/packages/types/src/primitive/H160.ts index 2a06f77a85..bd08a23e8b 100644 --- a/packages/types/src/primitive/H160.ts +++ b/packages/types/src/primitive/H160.ts @@ -13,14 +13,14 @@ import U8aFixed from '../codec/U8aFixed'; * as a sane default for fixed-length hash representations. */ export default class H160 extends U8aFixed { - constructor (value?: AnyU8a) { + public constructor (value?: AnyU8a) { super(value, 160); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'H160'; } } diff --git a/packages/types/src/primitive/H256.ts b/packages/types/src/primitive/H256.ts index 3342678270..b3337d84da 100644 --- a/packages/types/src/primitive/H256.ts +++ b/packages/types/src/primitive/H256.ts @@ -13,14 +13,14 @@ import U8aFixed from '../codec/U8aFixed'; * as a sane default for fixed-length hash representations. */ export default class H256 extends U8aFixed { - constructor (value?: AnyU8a) { + public constructor (value?: AnyU8a) { super(value, 256); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'H256'; } } diff --git a/packages/types/src/primitive/H512.ts b/packages/types/src/primitive/H512.ts index 8e934fd86f..bf1776ca2a 100644 --- a/packages/types/src/primitive/H512.ts +++ b/packages/types/src/primitive/H512.ts @@ -12,14 +12,14 @@ import U8aFixed from '../codec/U8aFixed'; * Hash containing 512 bits (64 bytes), typically used for signatures */ export default class H512 extends U8aFixed { - constructor (value?: AnyU8a) { + public constructor (value?: AnyU8a) { super(value, 512); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'H512'; } } diff --git a/packages/types/src/primitive/I128.ts b/packages/types/src/primitive/I128.ts index 90636f395b..46f8bcbbef 100644 --- a/packages/types/src/primitive/I128.ts +++ b/packages/types/src/primitive/I128.ts @@ -12,7 +12,7 @@ import Int from '../codec/Int'; * A 128-bit signed integer */ export default class I128 extends Int { - constructor (value?: AnyNumber) { + public constructor (value?: AnyNumber) { super(value, 128); } } diff --git a/packages/types/src/primitive/I16.ts b/packages/types/src/primitive/I16.ts index 84333188b5..3d6e189971 100644 --- a/packages/types/src/primitive/I16.ts +++ b/packages/types/src/primitive/I16.ts @@ -12,7 +12,7 @@ import Int from '../codec/Int'; * A 16-bit signed integer */ export default class I16 extends Int { - constructor (value?: AnyNumber) { + public constructor (value?: AnyNumber) { super(value, 16); } } diff --git a/packages/types/src/primitive/I256.ts b/packages/types/src/primitive/I256.ts index d4f2aeeebe..67e96de8b4 100644 --- a/packages/types/src/primitive/I256.ts +++ b/packages/types/src/primitive/I256.ts @@ -12,7 +12,7 @@ import Int from '../codec/Int'; * A 256-bit signed integer */ export default class I256 extends Int { - constructor (value?: AnyNumber) { + public constructor (value?: AnyNumber) { super(value, 256); } } diff --git a/packages/types/src/primitive/I32.ts b/packages/types/src/primitive/I32.ts index e8ca0371fa..b854b15207 100644 --- a/packages/types/src/primitive/I32.ts +++ b/packages/types/src/primitive/I32.ts @@ -12,7 +12,7 @@ import Int from '../codec/Int'; * A 32-bit signed integer */ export default class I32 extends Int { - constructor (value?: AnyNumber) { + public constructor (value?: AnyNumber) { super(value, 32); } } diff --git a/packages/types/src/primitive/I64.ts b/packages/types/src/primitive/I64.ts index 46d79742cd..5362f084c2 100644 --- a/packages/types/src/primitive/I64.ts +++ b/packages/types/src/primitive/I64.ts @@ -12,7 +12,7 @@ import Int from '../codec/Int'; * A 64-bit signed integer */ export default class I64 extends Int { - constructor (value?: AnyNumber) { + public constructor (value?: AnyNumber) { super(value, 64); } } diff --git a/packages/types/src/primitive/I8.ts b/packages/types/src/primitive/I8.ts index 575edfa2d0..856261c302 100644 --- a/packages/types/src/primitive/I8.ts +++ b/packages/types/src/primitive/I8.ts @@ -12,7 +12,7 @@ import Int from '../codec/Int'; * An 8-bit signed integer */ export default class I8 extends Int { - constructor (value?: AnyNumber) { + public constructor (value?: AnyNumber) { super(value, 8); } } diff --git a/packages/types/src/primitive/Method.spec.ts b/packages/types/src/primitive/Method.spec.ts index 2c05f1ed79..f36678129d 100644 --- a/packages/types/src/primitive/Method.spec.ts +++ b/packages/types/src/primitive/Method.spec.ts @@ -6,12 +6,12 @@ import extrinsics from '@polkadot/api-metadata/extrinsics/static'; import Method from './Method'; -describe('Method', () => { - beforeEach(() => { +describe('Method', (): void => { + beforeEach((): void => { Method.injectMethods(extrinsics); }); - it('handles decoding correctly (bare)', () => { + it('handles decoding correctly (bare)', (): void => { expect( new Method({ args: [], @@ -20,31 +20,31 @@ describe('Method', () => { ).toEqual(new Uint8Array([5, 1, 0, 0, 0])); }); - it('handles creation from a hex value properly', () => { + it('handles creation from a hex value properly', (): void => { expect( new Method('0x0501').toU8a() ).toEqual(new Uint8Array([5, 1, 0, 0, 0])); // balances.setBalance }); - describe('hasOrigin', () => { + describe('hasOrigin', (): void => { const test = { args: [], callIndex: [2, 2] // timestamp }; - it('is false with no arguments', () => { + it('is false with no arguments', (): void => { expect( new Method(test, { args: [] } as any).hasOrigin ).toEqual(false); }); - it('is false with first argument as non-Origin', () => { + it('is false with first argument as non-Origin', (): void => { expect( new Method(test, { args: [{ name: 'a', type: 'u32' }] } as any).hasOrigin ).toEqual(false); }); - it('is false with first argument as non-Origin', () => { + it('is false with first argument as non-Origin', (): void => { expect( new Method(test, { args: [{ name: 'a', type: 'Origin' }] } as any).hasOrigin ).toEqual(true); diff --git a/packages/types/src/primitive/Method.ts b/packages/types/src/primitive/Method.ts index 52dafb658a..bf3bd6488c 100644 --- a/packages/types/src/primitive/Method.ts +++ b/packages/types/src/primitive/Method.ts @@ -38,12 +38,12 @@ export interface ModulesWithMethods { [key: string]: Methods; // Will hold modules returned by state_getMetadata } -const FN_UNKNOWN = { +const FN_UNKNOWN: Partial = { method: 'unknown', section: 'unknown' -} as MethodFunction; +}; -const injected: { [index: string]: MethodFunction } = {}; +const injected: Record = {}; /** * @name MethodIndex @@ -51,7 +51,7 @@ const injected: { [index: string]: MethodFunction } = {}; * A wrapper around the `[sectionIndex, methodIndex]` value that uniquely identifies a method */ export class MethodIndex extends U8aFixed { - constructor (value?: AnyU8a) { + public constructor (value?: AnyU8a) { super(value, 16); } } @@ -65,7 +65,7 @@ export class MethodIndex extends U8aFixed { export default class Method extends Struct implements IMethod { protected _meta: FunctionMetadataV6; - constructor (value: any, meta?: FunctionMetadataV6) { + public constructor (value: any, meta?: FunctionMetadataV6) { const decoded = Method.decodeMethod(value, meta); super({ @@ -126,10 +126,10 @@ export default class Method extends Struct implements IMethod { } // If the extrinsic function has an argument of type `Origin`, we ignore it - static filterOrigin (meta?: FunctionMetadataV6): Array { + public static filterOrigin (meta?: FunctionMetadataV6): FunctionArgumentMetadata[] { // FIXME should be `arg.type !== Origin`, but doesn't work... return meta - ? meta.args.filter(({ type }) => + ? meta.args.filter(({ type }): boolean => type.toString() !== 'Origin' ) : []; @@ -142,7 +142,7 @@ export default class Method extends Struct implements IMethod { // // As a convenience helper though, we return the full constructor function, // which includes the meta, name, section & actual interface for calling - static findFunction (callIndex: Uint8Array): MethodFunction { + public static findFunction (callIndex: Uint8Array): MethodFunction { assert(Object.keys(injected).length > 0, 'Calling Method.findFunction before extrinsics have been injected.'); return injected[callIndex.toString()] || FN_UNKNOWN; @@ -155,30 +155,30 @@ export default class Method extends Struct implements IMethod { * @param meta - The function metadata used to get the definition. */ private static getArgsDef (meta: FunctionMetadataV6): ArgsDef { - return Method.filterOrigin(meta).reduce((result, { name, type }) => { + return Method.filterOrigin(meta).reduce((result, { name, type }): ArgsDef => { const Type = getTypeClass( getTypeDef(type) ); result[name.toString()] = Type; return result; - }, {} as ArgsDef); + }, {} as unknown as ArgsDef); } // This is called/injected by the API on init, allowing a snapshot of // the available system extrinsics to be used in lookups - static injectMethods (moduleMethods: ModulesWithMethods): void { - Object.values(moduleMethods).forEach((methods) => - Object.values(methods).forEach((method) => - injected[method.callIndex.toString()] = method - ) + public static injectMethods (moduleMethods: ModulesWithMethods): void { + Object.values(moduleMethods).forEach((methods): void => + Object.values(methods).forEach((method): void => { + injected[method.callIndex.toString()] = method; + }) ); } /** * @description The arguments for the function call */ - get args (): Array { + public get args (): Codec[] { // FIXME This should return a Struct instead of an Array return [...(this.get('args') as Struct).values()]; } @@ -186,28 +186,28 @@ export default class Method extends Struct implements IMethod { /** * @description Thge argument defintions */ - get argsDef (): ArgsDef { + public get argsDef (): ArgsDef { return Method.getArgsDef(this.meta); } /** * @description The encoded `[sectionIndex, methodIndex]` identifier */ - get callIndex (): Uint8Array { + public get callIndex (): Uint8Array { return (this.get('callIndex') as MethodIndex).toU8a(); } /** * @description The encoded data */ - get data (): Uint8Array { + public get data (): Uint8Array { return (this.get('args') as Struct).toU8a(); } /** * @description `true` if the `Origin` type is on the method (extrinsic method) */ - get hasOrigin (): boolean { + public get hasOrigin (): boolean { const firstArg = this.meta.args[0]; return !!firstArg && firstArg.type.toString() === 'Origin'; @@ -216,28 +216,28 @@ export default class Method extends Struct implements IMethod { /** * @description The [[FunctionMetadata]] */ - get meta (): FunctionMetadataV6 { + public get meta (): FunctionMetadataV6 { return this._meta; } /** * @description Returns the name of the method */ - get methodName (): string { + public get methodName (): string { return Method.findFunction(this.callIndex).method; } /** * @description Returns the module containing the method */ - get sectionName (): string { + public get sectionName (): string { return Method.findFunction(this.callIndex).section; } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'Call'; } } diff --git a/packages/types/src/primitive/Moment.spec.ts b/packages/types/src/primitive/Moment.spec.ts index 9cd84b2fc0..b7844df4b6 100644 --- a/packages/types/src/primitive/Moment.spec.ts +++ b/packages/types/src/primitive/Moment.spec.ts @@ -8,10 +8,10 @@ import { CodecTo } from '../types'; import Moment from './Moment'; import U64 from './U64'; -describe('Moment', () => { - describe('decode', () => { - const testDecode = (type: string, input: Date | Moment | U64 | number, expected: string | number, toJSON: boolean = false) => - it(`can decode from ${type}`, () => { +describe('Moment', (): void => { + describe('decode', (): void => { + const testDecode = (type: string, input: Date | Moment | U64 | number, expected: string | number, toJSON: boolean = false): void => + it(`can decode from ${type}`, (): void => { expect(new Moment(input)[toJSON ? 'toJSON' : 'toISOString']()).toBe(expected); }); @@ -21,9 +21,9 @@ describe('Moment', () => { testDecode('U64', new U64(69), 69, true); }); - describe('encode', () => { - const testEncode = (to: 'toBn' | 'toISOString' | 'toNumber' | CodecTo, expected: BN | number | string | Uint8Array) => - it(`can encode ${to}`, () => { + describe('encode', (): void => { + const testEncode = (to: 'toBn' | 'toISOString' | 'toNumber' | CodecTo, expected: BN | number | string | Uint8Array): void => + it(`can encode ${to}`, (): void => { expect(new Moment(421)[to]()).toEqual(expected); }); @@ -34,7 +34,7 @@ describe('Moment', () => { testEncode('toNumber', 421); testEncode('toU8a', Uint8Array.from([165, 1, 0, 0, 0, 0, 0, 0])); - it(`can encode toString`, () => { + it(`can encode toString`, (): void => { expect( new Moment(421) .toString() @@ -42,25 +42,25 @@ describe('Moment', () => { ).toBe(true); }); - it('encodes default BE hex', () => { + it('encodes default BE hex', (): void => { expect( new Moment(3).toHex() ).toEqual('0x0000000000000003'); }); - it('encodes options LE hex', () => { + it('encodes options LE hex', (): void => { expect( new Moment(3).toHex(true) ).toEqual('0x0300000000000000'); }); }); - describe('utils', () => { - it('compares values', () => { + describe('utils', (): void => { + it('compares values', (): void => { expect(new Moment(123).eq(123)).toBe(true); }); - it('compares values (non-match)', () => { + it('compares values (non-match)', (): void => { expect(new Moment(123).eq(456)).toBe(false); }); }); diff --git a/packages/types/src/primitive/Moment.ts b/packages/types/src/primitive/Moment.ts index edf9f19c61..c86ed42f6f 100644 --- a/packages/types/src/primitive/Moment.ts +++ b/packages/types/src/primitive/Moment.ts @@ -23,7 +23,7 @@ const BITLENGTH: UIntBitLength = 64; export default class Moment extends Date implements Codec { protected raw: Date; // FIXME Remove this once we convert all types out of Base - constructor (value: Moment | Date | AnyNumber = 0) { + public constructor (value: Moment | Date | AnyNumber = 0) { super( Moment.decodeMoment(value) ); @@ -31,7 +31,7 @@ export default class Moment extends Date implements Codec { this.raw = this; } - static decodeMoment (value: Moment | Date | AnyNumber): Date { + public static decodeMoment (value: Moment | Date | AnyNumber): Date { if (value instanceof Date) { return value; } else if (isU8a(value)) { @@ -48,42 +48,42 @@ export default class Moment extends Date implements Codec { /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { return BITLENGTH / 8; } /** * @description Checks if the value is an empty value */ - get isEmpty (): boolean { + public get isEmpty (): boolean { return this.getTime() === 0; } /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { return Moment.decodeMoment(other).getTime() === this.getTime(); } /** * @description Returns the number of bits in the value */ - bitLength (): UIntBitLength { + public bitLength (): UIntBitLength { return BITLENGTH; } /** * @description Returns the BN representation of the timestamp */ - toBn (): BN { + public toBn (): BN { return new BN(this.toNumber()); } /** * @description Returns a hex string representation of the value */ - toHex (isLe: boolean = false): string { + public toHex (isLe: boolean = false): string { return bnToHex(this.toBn(), { bitLength: BITLENGTH, isLe, @@ -94,7 +94,7 @@ export default class Moment extends Date implements Codec { /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): any { + public toJSON (): any { // FIXME Return type should be number, but conflicts with Date.toJSON() // which returns string return this.toNumber(); @@ -103,21 +103,21 @@ export default class Moment extends Date implements Codec { /** * @description Returns the number representation for the timestamp */ - toNumber (): number { + public toNumber (): number { return Math.ceil(this.getTime() / 1000); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'Moment'; } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { // only included here since we do not inherit docs return super.toString(); } @@ -126,7 +126,8 @@ export default class Moment extends Date implements Codec { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public toU8a (isBare?: boolean): Uint8Array { return bnToU8a(this.toNumber(), BITLENGTH, true); } } diff --git a/packages/types/src/primitive/Null.spec.ts b/packages/types/src/primitive/Null.spec.ts index 5310bbabb9..dd17ef3f7e 100644 --- a/packages/types/src/primitive/Null.spec.ts +++ b/packages/types/src/primitive/Null.spec.ts @@ -4,16 +4,16 @@ import Null from './Null'; -describe('Null', () => { - it('compares against null', () => { +describe('Null', (): void => { + it('compares against null', (): void => { expect(new Null().eq(null)).toBe(true); }); - it('compares against Null', () => { + it('compares against Null', (): void => { expect(new Null().eq(new Null())).toBe(true); }); - it('compares against other (failed)', () => { + it('compares against other (failed)', (): void => { expect(new Null().eq()).toBe(false); }); }); diff --git a/packages/types/src/primitive/Null.ts b/packages/types/src/primitive/Null.ts index 2c7d6eb506..b9ccceb324 100644 --- a/packages/types/src/primitive/Null.ts +++ b/packages/types/src/primitive/Null.ts @@ -14,49 +14,49 @@ export default class Null implements Codec { /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { return 0; } /** * @description Checks if the value is an empty value (always true) */ - get isEmpty (): boolean { + public get isEmpty (): boolean { return true; } /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { return other instanceof Null || isNull(other); } /** * @description Returns a hex string representation of the value */ - toHex (): string { + public toHex (): string { return '0x'; } /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): null { + public toJSON (): null { return null; } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'Null'; } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { return ''; } @@ -64,7 +64,8 @@ export default class Null implements Codec { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public toU8a (isBare?: boolean): Uint8Array { return new Uint8Array(); } } @@ -75,7 +76,7 @@ export default class Null implements Codec { * Implements a type that does not contain anything (apart from `null`) */ export class Phantom extends Null { - toRawType (): string { + public toRawType (): string { return 'Phantom'; } } diff --git a/packages/types/src/primitive/Origin.spec.ts b/packages/types/src/primitive/Origin.spec.ts index 52ea41f493..2a384a2196 100644 --- a/packages/types/src/primitive/Origin.spec.ts +++ b/packages/types/src/primitive/Origin.spec.ts @@ -4,10 +4,10 @@ import Origin from './Origin'; -describe('Origin', () => { - it('does not allow construction', () => { +describe('Origin', (): void => { + it('does not allow construction', (): void => { expect( - () => new Origin() + (): Origin => new Origin() ).toThrow(/placeholder/); }); }); diff --git a/packages/types/src/primitive/Origin.ts b/packages/types/src/primitive/Origin.ts index 7a25a0f90a..dc28b1376e 100644 --- a/packages/types/src/primitive/Origin.ts +++ b/packages/types/src/primitive/Origin.ts @@ -11,7 +11,7 @@ import Null from './Null'; * never actually be constructed */ export default class Origin extends Null { - constructor () { + public constructor () { super(); throw new Error('Origin should not be constructed, it is only a placeholder for compatibility'); @@ -20,7 +20,7 @@ export default class Origin extends Null { /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'Origin'; // yes, we cannot instantiate, but for consistency } } diff --git a/packages/types/src/primitive/StorageHasher.ts b/packages/types/src/primitive/StorageHasher.ts index e3e099160a..a73e6ede07 100644 --- a/packages/types/src/primitive/StorageHasher.ts +++ b/packages/types/src/primitive/StorageHasher.ts @@ -5,7 +5,7 @@ import Enum from '../codec/Enum'; export default class StorageHasher extends Enum { - constructor (value?: any) { + public constructor (value?: any) { super([ 'Blake2_128', 'Blake2_256', @@ -18,39 +18,39 @@ export default class StorageHasher extends Enum { /** * @description Is the enum Blake2_128? */ - get isBlake2128 (): boolean { + public get isBlake2128 (): boolean { return this.toNumber() === 0; } /** * @description Is the enum Blake2_256? */ - get isBlake2256 (): boolean { + public get isBlake2256 (): boolean { return this.toNumber() === 1; } /** * @description Is the enum Twox128? */ - get isTwox128 (): boolean { + public get isTwox128 (): boolean { return this.toNumber() === 2; } /** * @description Is the enum Twox256? */ - get isTwox256 (): boolean { + public get isTwox256 (): boolean { return this.toNumber() === 3; } /** * @description Is the enum isTwox64Concat? */ - get isTwox64Concat (): boolean { + public get isTwox64Concat (): boolean { return this.toNumber() === 4; } - toJSON (): string { + public toJSON (): string { // This looks prettier in the generated JSON return this.toString(); } diff --git a/packages/types/src/primitive/StorageKey.spec.ts b/packages/types/src/primitive/StorageKey.spec.ts index 42488876b2..0c743e2644 100644 --- a/packages/types/src/primitive/StorageKey.spec.ts +++ b/packages/types/src/primitive/StorageKey.spec.ts @@ -12,11 +12,11 @@ import rpcDataV6 from '@polkadot/types/Metadata/v6/static'; import Metadata from '../Metadata'; import StorageKey from './StorageKey'; -describe('StorageKey', () => { - describe('with MetadataV3 (uses xxHash by default)', () => { +describe('StorageKey', (): void => { + describe('with MetadataV3 (uses xxHash by default)', (): void => { const storage = fromMetadata(new Metadata(rpcDataV3)); - it(`should correctly get Alice's freeBalance storage key (hex)`, () => { + it(`should correctly get Alice's freeBalance storage key (hex)`, (): void => { expect( new StorageKey( storage @@ -27,7 +27,7 @@ describe('StorageKey', () => { ).toBe('0xc99f5446efa57788f39ab529311f4550'); // FIXME OK this should be length-prefixed in reality }); - it(`should correctly get Alice's freeBalance storage key (u8a)`, () => { + it(`should correctly get Alice's freeBalance storage key (u8a)`, (): void => { expect( new StorageKey( storage @@ -42,10 +42,10 @@ describe('StorageKey', () => { }); }); - describe('with MetadataV4 (uses xxHash by default)', () => { + describe('with MetadataV4 (uses xxHash by default)', (): void => { const storage = fromMetadata(new Metadata(rpcDataV4)); - it(`should correctly get Alice's freeBalance storage key (hex)`, () => { + it(`should correctly get Alice's freeBalance storage key (hex)`, (): void => { expect( new StorageKey( storage @@ -56,12 +56,12 @@ describe('StorageKey', () => { ).toBe('0x7f864e18e3dd8b58386310d2fe0919eef27c6e558564b7f67f22d99d20f587bb'); }); - it(`should correctly get Alice's freeBalance storage key (u8a)`, () => { + it(`should correctly get Alice's freeBalance storage key (u8a)`, (): void => { expect( new StorageKey( storage - .balances - .freeBalance('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY') + .balances + .freeBalance('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY') ) .toU8a() ).toEqual( @@ -72,63 +72,7 @@ describe('StorageKey', () => { ); }); - it(`should correctly get the EventTopics double map storage key (hex)`, () => { - expect( - new StorageKey([ - storage - .system - .eventTopics, - ['any', [1, 2, 3]] - ]) - .toHex() - ).toBe('0x3007c9ff7027f65900abcdfca4fdb107ead47e2a9e3558e01b691b0f4a5f8518d487326614f066416308bf6aa4e5041d1949928e4b26ede98e3cebb36a3b1726'); - }); - - it(`should correctly get the EventTopics double map storage key (u8a)`, () => { - expect( - new StorageKey([ - storage - .system - .eventTopics, - ['any', [1, 2, 3]] - ]) - .toU8a() - ).toEqual(Uint8Array.from([1, 1, 48, 7, 201, 255, 112, 39, 246, 89, 0, 171, 205, 252, 164, 253, 177, 7, 234, 212, 126, 42, 158, 53, 88, 224, 27, 105, 27, 15, 74, 95, 133, 24, 212, 135, 50, 102, 20, 240, 102, 65, 99, 8, 191, 106, 164, 229, 4, 29, 25, 73, 146, 142, 75, 38, 237, 233, 142, 60, 235, 179, 106, 59, 23, 38])); - }); - }); - - describe('with MetadataV5', () => { - const storage = fromMetadata(new Metadata(rpcDataV5)); - - it(`should correctly get the EventTopics double map storage key (hex)`, () => { - expect( - new StorageKey([ - storage - .system - .eventTopics, - ['any', [1, 2, 3]] - ]) - .toHex() - ).toBe('0x3007c9ff7027f65900abcdfca4fdb107ead47e2a9e3558e01b691b0f4a5f8518d487326614f066416308bf6aa4e5041d1949928e4b26ede98e3cebb36a3b1726'); - }); - - it(`should correctly get the EventTopics double map storage key (u8a)`, () => { - expect( - new StorageKey([ - storage - .system - .eventTopics, - ['any', [1, 2, 3]] - ]) - .toU8a() - ).toEqual(Uint8Array.from([1, 1, 48, 7, 201, 255, 112, 39, 246, 89, 0, 171, 205, 252, 164, 253, 177, 7, 234, 212, 126, 42, 158, 53, 88, 224, 27, 105, 27, 15, 74, 95, 133, 24, 212, 135, 50, 102, 20, 240, 102, 65, 99, 8, 191, 106, 164, 229, 4, 29, 25, 73, 146, 142, 75, 38, 237, 233, 142, 60, 235, 179, 106, 59, 23, 38])); - }); - }); - - describe('with MetadataV6', () => { - const storage = fromMetadata(new Metadata(rpcDataV6)); - - it(`should correctly get the EventTopics double map storage key (hex)`, () => { + it(`should correctly get the EventTopics double map storage key (hex)`, (): void => { expect( new StorageKey([ storage @@ -140,7 +84,63 @@ describe('StorageKey', () => { ).toBe('0x3007c9ff7027f65900abcdfca4fdb107ead47e2a9e3558e01b691b0f4a5f8518d487326614f066416308bf6aa4e5041d1949928e4b26ede98e3cebb36a3b1726'); }); - it(`should correctly get the EventTopics double map storage key (u8a)`, () => { + it(`should correctly get the EventTopics double map storage key (u8a)`, (): void => { + expect( + new StorageKey([ + storage + .system + .eventTopics, + ['any', [1, 2, 3]] + ]) + .toU8a() + ).toEqual(Uint8Array.from([1, 1, 48, 7, 201, 255, 112, 39, 246, 89, 0, 171, 205, 252, 164, 253, 177, 7, 234, 212, 126, 42, 158, 53, 88, 224, 27, 105, 27, 15, 74, 95, 133, 24, 212, 135, 50, 102, 20, 240, 102, 65, 99, 8, 191, 106, 164, 229, 4, 29, 25, 73, 146, 142, 75, 38, 237, 233, 142, 60, 235, 179, 106, 59, 23, 38])); + }); + }); + + describe('with MetadataV5', (): void => { + const storage = fromMetadata(new Metadata(rpcDataV5)); + + it(`should correctly get the EventTopics double map storage key (hex)`, (): void => { + expect( + new StorageKey([ + storage + .system + .eventTopics, + ['any', [1, 2, 3]] + ]) + .toHex() + ).toBe('0x3007c9ff7027f65900abcdfca4fdb107ead47e2a9e3558e01b691b0f4a5f8518d487326614f066416308bf6aa4e5041d1949928e4b26ede98e3cebb36a3b1726'); + }); + + it(`should correctly get the EventTopics double map storage key (u8a)`, (): void => { + expect( + new StorageKey([ + storage + .system + .eventTopics, + ['any', [1, 2, 3]] + ]) + .toU8a() + ).toEqual(Uint8Array.from([1, 1, 48, 7, 201, 255, 112, 39, 246, 89, 0, 171, 205, 252, 164, 253, 177, 7, 234, 212, 126, 42, 158, 53, 88, 224, 27, 105, 27, 15, 74, 95, 133, 24, 212, 135, 50, 102, 20, 240, 102, 65, 99, 8, 191, 106, 164, 229, 4, 29, 25, 73, 146, 142, 75, 38, 237, 233, 142, 60, 235, 179, 106, 59, 23, 38])); + }); + }); + + describe('with MetadataV6', (): void => { + const storage = fromMetadata(new Metadata(rpcDataV6)); + + it(`should correctly get the EventTopics double map storage key (hex)`, (): void => { + expect( + new StorageKey([ + storage + .system + .eventTopics, + ['any', [1, 2, 3]] + ]) + .toHex() + ).toBe('0x3007c9ff7027f65900abcdfca4fdb107ead47e2a9e3558e01b691b0f4a5f8518d487326614f066416308bf6aa4e5041d1949928e4b26ede98e3cebb36a3b1726'); + }); + + it(`should correctly get the EventTopics double map storage key (u8a)`, (): void => { expect( new StorageKey([ storage diff --git a/packages/types/src/primitive/StorageKey.ts b/packages/types/src/primitive/StorageKey.ts index 899f80b9ad..993436bbbd 100644 --- a/packages/types/src/primitive/StorageKey.ts +++ b/packages/types/src/primitive/StorageKey.ts @@ -32,11 +32,14 @@ interface Decoded { */ export default class StorageKey extends Bytes { private _meta?: MetaV6; + private _method?: string; + private _outputType?: string; + private _section?: string; - constructor (value?: AnyU8a | StorageKey | StorageEntry | [StorageEntry, any]) { + public constructor (value?: AnyU8a | StorageKey | StorageEntry | [StorageEntry, any]) { const { key, method, section } = StorageKey.decodeStorageKey(value); super(key); @@ -47,7 +50,7 @@ export default class StorageKey extends Bytes { this._section = section; } - static decodeStorageKey (value?: AnyU8a | StorageKey | StorageEntry | [StorageEntry, any]): Decoded { + public static decodeStorageKey (value?: AnyU8a | StorageKey | StorageEntry | [StorageEntry, any]): Decoded { if (value instanceof StorageKey) { return { key: value, @@ -66,7 +69,7 @@ export default class StorageKey extends Bytes { section: value.section }; } else if (Array.isArray(value)) { - const [fn, ...arg]: [StorageEntry, ...Array] = value as any; + const [fn, ...arg]: [StorageEntry, ...any[]] = value as any; assert(isFunction(fn), 'Expected function input for key construction'); @@ -80,7 +83,7 @@ export default class StorageKey extends Bytes { throw new Error(`Unable to convert input ${value} to StorageKey`); } - static getMeta (value: StorageKey | StorageEntry | [StorageEntry, any]): MetaV6 | undefined { + public static getMeta (value: StorageKey | StorageEntry | [StorageEntry, any]): MetaV6 | undefined { if (value instanceof StorageKey) { return value.meta; } else if (isFunction(value)) { @@ -94,7 +97,7 @@ export default class StorageKey extends Bytes { return undefined; } - static getType (value: StorageKey | StorageEntry | [StorageEntry, any]): string | undefined { + public static getType (value: StorageKey | StorageEntry | [StorageEntry, any]): string | undefined { if (value instanceof StorageKey) { return value.outputType; } else if (isFunction(value)) { @@ -111,28 +114,28 @@ export default class StorageKey extends Bytes { /** * @description The metadata or `undefined` when not available */ - get meta (): MetaV6 | undefined { + public get meta (): MetaV6 | undefined { return this._meta; } /** * @description The key method or `undefined` when not specified */ - get method (): string | undefined { + public get method (): string | undefined { return this._method; } /** * @description The output type, `null` when not available */ - get outputType (): string | undefined { + public get outputType (): string | undefined { return this._outputType; } /** * @description The key section or `undefined` when not specified */ - get section (): string | undefined { + public get section (): string | undefined { return this._section; } } diff --git a/packages/types/src/primitive/Text.spec.ts b/packages/types/src/primitive/Text.spec.ts index e0f4b2cef6..0a6ea65c79 100644 --- a/packages/types/src/primitive/Text.spec.ts +++ b/packages/types/src/primitive/Text.spec.ts @@ -6,10 +6,10 @@ import { CodecTo } from '../types'; import U8a from '../codec/U8a'; import Text from './Text'; -describe('Text', () => { - describe('decode', () => { - const testDecode = (type: string, input: string | Uint8Array | { toString: () => string }, expected: string, toFn: 'toString' | 'toHex' = 'toString') => - it(`can decode from ${type}`, () => { +describe('Text', (): void => { + describe('decode', (): void => { + const testDecode = (type: string, input: string | Uint8Array | { toString: () => string }, expected: string, toFn: 'toString' | 'toHex' = 'toString'): void => + it(`can decode from ${type}`, (): void => { expect(new Text(input)[toFn]()).toBe(expected); }); @@ -21,9 +21,9 @@ describe('Text', () => { testDecode('hex input value', new Text('0x12345678'), '0x12345678', 'toHex'); }); - describe('encode', () => { - const testEncode = (to: CodecTo, expected: string | Uint8Array) => - it(`can encode ${to}`, () => { + describe('encode', (): void => { + const testEncode = (to: CodecTo, expected: string | Uint8Array): void => + it(`can encode ${to}`, (): void => { expect(new Text('foo')[to]()).toEqual(expected); }); @@ -32,27 +32,27 @@ describe('Text', () => { testEncode('toU8a', Uint8Array.from([12, 102, 111, 111])); }); - describe('utils', () => { - it('compares actual string values', () => { + describe('utils', (): void => { + it('compares actual string values', (): void => { expect(new Text('123').eq('123')).toBe(true); }); - it('compares actual String values', () => { - expect(new Text('XYX').eq(new String('XYX'))).toBe(true); + it('compares actual String values', (): void => { + expect(new Text('XYX').eq(String('XYX'))).toBe(true); }); - it('compares actual non-string values (fails)', () => { + it('compares actual non-string values (fails)', (): void => { expect(new Text('123').eq(123)).toBe(false); }); - it('calulates the length & encoded length correctly for ASCII', () => { + it('calulates the length & encoded length correctly for ASCII', (): void => { const test = new Text('abcde'); expect(test.encodedLength).toEqual(6); expect(test).toHaveLength(5); }); - it('calulates the length & encoded length correctly for non-ASCII', () => { + it('calulates the length & encoded length correctly for non-ASCII', (): void => { const test = new Text('中文'); expect(test.encodedLength).toEqual(7); diff --git a/packages/types/src/primitive/Text.ts b/packages/types/src/primitive/Text.ts index 29856c6ee9..5e542e8528 100644 --- a/packages/types/src/primitive/Text.ts +++ b/packages/types/src/primitive/Text.ts @@ -18,7 +18,7 @@ import Compact from '../codec/Compact'; // TODO // - Strings should probably be trimmed (docs do come through with extra padding) export default class Text extends String implements Codec { - constructor (value: Text | string | AnyU8a | { toString: () => string } = '') { + public constructor (value: Text | string | AnyU8a | { toString: () => string } = '') { super( Text.decodeText(value) ); @@ -46,21 +46,21 @@ export default class Text extends String implements Codec { /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { return this.toU8a().length; } /** * @description Checks if the value is an empty value */ - get isEmpty (): boolean { + public get isEmpty (): boolean { return this.length === 0; } /** * @description The length of the value */ - get length (): number { + public get length (): number { // only included here since we ignore inherited docs return super.length; } @@ -68,7 +68,7 @@ export default class Text extends String implements Codec { /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { return isString(other) ? this.toString() === other.toString() : false; @@ -77,7 +77,7 @@ export default class Text extends String implements Codec { /** * @description Returns a hex string representation of the value */ - toHex (): string { + public toHex (): string { // like with Vec, when we are encoding to hex, we don't actually add // the length prefix (it is already implied by the actual string length) return u8aToHex(this.toU8a(true)); @@ -86,21 +86,21 @@ export default class Text extends String implements Codec { /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): string { + public toJSON (): string { return this.toString(); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'Text'; } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { // only included here since we do not inherit docs return super.toString(); } @@ -109,7 +109,7 @@ export default class Text extends String implements Codec { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + public toU8a (isBare?: boolean): Uint8Array { const encoded = stringToU8a(this.toString()); return isBare diff --git a/packages/types/src/primitive/Type.spec.ts b/packages/types/src/primitive/Type.spec.ts index dc481a8101..bcb87f5225 100644 --- a/packages/types/src/primitive/Type.spec.ts +++ b/packages/types/src/primitive/Type.spec.ts @@ -5,74 +5,74 @@ import Text from './Text'; import Type from './Type'; -describe('Type', () => { - it('fails to cleanup invalid boxes', () => { +describe('Type', (): void => { + it('fails to cleanup invalid boxes', (): void => { expect( - () => new Type('Box new Type('Box { + it('cleans up tuples with a single value', (): void => { expect( new Type('(AccountId)').toString() ).toEqual('AccountId'); }); - it('does not touch tuples with multiple values', () => { + it('does not touch tuples with multiple values', (): void => { expect( new Type('(AccountId, Balance)').toString() ).toEqual('(AccountId,Balance)'); }); - it('handles nested types', () => { + it('handles nested types', (): void => { expect( new Type('Box>').toString() ).toEqual('Vec'); }); - it('handles nested types (embedded)', () => { + it('handles nested types (embedded)', (): void => { expect( new Type('(u32, Box>)').toString() ).toEqual('(u32,Vec)'); }); - it('handles aliasses, multiples per line', () => { + it('handles aliasses, multiples per line', (): void => { expect( new Type('(Vec, AccountId, Vec)').toString() ).toEqual('(Bytes,AccountId,Bytes)'); }); - it('removes whitespaces', () => { + it('removes whitespaces', (): void => { expect( new Type('T :: AccountId').toString() ).toEqual('AccountId'); }); - it('changes PairOf -> (T, T)', () => { + it('changes PairOf -> (T, T)', (): void => { expect( new Type('PairOf').toString() ).toEqual('(Balance,Balance)'); }); - it('changes PairOf (embedded) -> (T, T)', () => { + it('changes PairOf (embedded) -> (T, T)', (): void => { expect( new Type('(Vec, PairOf, Vec)').toString() ).toEqual('(Bytes,(Balance,Balance),Vec)'); }); - it('changes () -> Null', () => { + it('changes () -> Null', (): void => { expect( new Type('()').toString() ).toEqual('Null'); }); - it('does not allow toU8a', () => { + it('does not allow toU8a', (): void => { expect( - () => new Type().toU8a() + (): Uint8Array => new Type().toU8a() ).toThrow(/unimplemented/); }); - it('has a length for the type', () => { + it('has a length for the type', (): void => { expect( new Type( new Text(' Box ') @@ -80,13 +80,13 @@ describe('Type', () => { ).toEqual('Proposal'); // eslint-disable-line }); - it('unwraps compact', () => { + it('unwraps compact', (): void => { expect( new Type('::Type').toString() ).toEqual('Compact'); }); - it('handles InherentOfflineReport', () => { + it('handles InherentOfflineReport', (): void => { expect( new Type('::Inherent').toString() ).toEqual('InherentOfflineReport'); diff --git a/packages/types/src/primitive/Type.ts b/packages/types/src/primitive/Type.ts index 162540182f..43fedfbc00 100644 --- a/packages/types/src/primitive/Type.ts +++ b/packages/types/src/primitive/Type.ts @@ -18,7 +18,7 @@ const ALLOWED_BOXES = ['Compact', 'Option', 'Vec']; export default class Type extends Text { private _originalLength: number; - constructor (value: Text | Uint8Array | string = '') { + public constructor (value: Text | Uint8Array | string = '') { // First decode it with Text const textValue = new Text(value); @@ -34,7 +34,7 @@ export default class Type extends Text { } private static decodeType (value: string): string { - const mappings: Array = [ + const mappings: Mapper[] = [ // alias ::Inherent -> InherentOfflineReport Type._alias('::Inherent', 'InherentOfflineReport'), // alias TreasuryProposal from Proposal> @@ -52,7 +52,7 @@ export default class Type extends Text { // alias String -> Text (compat with jsonrpc methods) Type._alias('String', 'Text'), // alias () -> Null - Type._alias('\\\(\\\)', 'Null'), + Type._alias('\\(\\)', 'Null'), // alias Vec -> Bytes Type._alias('Compact', 'IndexCompact'), // alias Vec -> Bytes @@ -73,7 +73,7 @@ export default class Type extends Text { Type._removeColonPrefix() ]; - return mappings.reduce((result, fn) => { + return mappings.reduce((result, fn): string => { return fn(result); }, value).trim(); } @@ -81,7 +81,7 @@ export default class Type extends Text { /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { // NOTE Length is used in the decoding calculations, so return the original (pre-cleanup) // length of the data. Since toU8a is disabled, this does not affect encoding, but rather // only the decoding leg, allowing the decoders to work with original pointers @@ -92,7 +92,8 @@ export default class Type extends Text { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public toU8a (isBare?: boolean): Uint8Array { // Note Since we are mangling what we get in beyond recognition, we really should // not allow the re-encoding. Additionally, this is probably more of a decoder-only // helper, so treat it as such. @@ -161,7 +162,7 @@ export default class Type extends Text { for (let index = 0; index < value.length; index++) { if (value[index] === '<') { // check against the allowed wrappers, be it Vec<..>, Option<...> ... - const box = ALLOWED_BOXES.find((box) => { + const box = ALLOWED_BOXES.find((box): boolean => { const start = index - box.length; return start >= 0 && value.substr(start, box.length) === box; @@ -249,7 +250,7 @@ export default class Type extends Text { /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'Type'; } } diff --git a/packages/types/src/primitive/U128.ts b/packages/types/src/primitive/U128.ts index ec11a8f0e0..011d499780 100644 --- a/packages/types/src/primitive/U128.ts +++ b/packages/types/src/primitive/U128.ts @@ -12,7 +12,7 @@ import UInt from '../codec/UInt'; * A 128-bit unsigned integer */ export default class U128 extends UInt { - constructor (value?: AnyNumber) { + public constructor (value?: AnyNumber) { super(value, 128); } } diff --git a/packages/types/src/primitive/U16.ts b/packages/types/src/primitive/U16.ts index ac526a1253..196ac25462 100644 --- a/packages/types/src/primitive/U16.ts +++ b/packages/types/src/primitive/U16.ts @@ -12,7 +12,7 @@ import UInt from '../codec/UInt'; * A 16-bit unsigned integer */ export default class U16 extends UInt { - constructor (value?: AnyNumber) { + public constructor (value?: AnyNumber) { super(value, 16); } } diff --git a/packages/types/src/primitive/U256.ts b/packages/types/src/primitive/U256.ts index 88daf066de..5c564cc700 100644 --- a/packages/types/src/primitive/U256.ts +++ b/packages/types/src/primitive/U256.ts @@ -12,7 +12,7 @@ import UInt from '../codec/UInt'; * A 256-bit unsigned integer */ export default class U256 extends UInt { - constructor (value?: AnyNumber) { + public constructor (value?: AnyNumber) { super(value, 256); } } diff --git a/packages/types/src/primitive/U32.ts b/packages/types/src/primitive/U32.ts index 8c8976c2eb..e8bf28526e 100644 --- a/packages/types/src/primitive/U32.ts +++ b/packages/types/src/primitive/U32.ts @@ -12,7 +12,7 @@ import UInt from '../codec/UInt'; * A 32-bit unsigned integer */ export default class U32 extends UInt { - constructor (value?: AnyNumber) { + public constructor (value?: AnyNumber) { super(value, 32); } } diff --git a/packages/types/src/primitive/U64.ts b/packages/types/src/primitive/U64.ts index cece8eb05d..6bb4e33fce 100644 --- a/packages/types/src/primitive/U64.ts +++ b/packages/types/src/primitive/U64.ts @@ -12,7 +12,7 @@ import UInt from '../codec/UInt'; * A 64-bit unsigned integer */ export default class U64 extends UInt { - constructor (value?: AnyNumber) { + public constructor (value?: AnyNumber) { super(value, 64); } } diff --git a/packages/types/src/primitive/U8.ts b/packages/types/src/primitive/U8.ts index 02b9efaaf0..36e6b07c88 100644 --- a/packages/types/src/primitive/U8.ts +++ b/packages/types/src/primitive/U8.ts @@ -12,7 +12,7 @@ import UInt from '../codec/UInt'; * An 8-bit unsigned integer */ export default class U8 extends UInt { - constructor (value?: AnyNumber) { + public constructor (value?: AnyNumber) { super(value, 8); } } diff --git a/packages/types/src/primitive/USize.ts b/packages/types/src/primitive/USize.ts index 1b4acf74e6..60ee2f491a 100644 --- a/packages/types/src/primitive/USize.ts +++ b/packages/types/src/primitive/USize.ts @@ -12,7 +12,7 @@ import U32 from './U32'; * It is not to be used, since it created consensus mismatches. */ export default class USize extends U32 { - constructor (value?: any) { + public constructor (value?: any) { super(value); throw new Error('The `usize` type should not be used. Since it is platform-specific, it creates incompatibilities between native (generally u64) and WASM (always u32) code. Use one of the `u32` or `u64` types explicitly.'); @@ -21,7 +21,7 @@ export default class USize extends U32 { /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'usize'; } } diff --git a/packages/types/src/primitive/Unconstructable.ts b/packages/types/src/primitive/Unconstructable.ts index 28e22199b5..ef96c93b34 100644 --- a/packages/types/src/primitive/Unconstructable.ts +++ b/packages/types/src/primitive/Unconstructable.ts @@ -12,15 +12,15 @@ import Null from './Null'; * A type that should not be constructed */ export default class Unconstructable extends Null { - constructor () { + public constructor () { super(); throw new Error('Unconstructable should not be constructed, it is only a placeholder for compatibility'); } - static with (typeDef: any): Constructor { + public static with (typeDef: any): Constructor { return class extends Null { - constructor () { + public constructor () { super(); throw new Error(`Unabdle to construct ${JSON.stringify(typeDef)}`); diff --git a/packages/types/src/primitive/index.ts b/packages/types/src/primitive/index.ts index 9dedb1b31b..ec697149c4 100644 --- a/packages/types/src/primitive/index.ts +++ b/packages/types/src/primitive/index.ts @@ -18,7 +18,7 @@ export { default as Address } from './Address'; // and actually is problematic/impossible to be overridden, it is included here as well export { default as Balance, BalanceOf } from './Balance'; export { default as Event, EventIndex } from './Event'; -export { default as EventRecord, EventRecord_0_76 } from './EventRecord'; +export { default as EventRecord, EventRecord0to76 } from './EventRecord'; export { default as Bool, default as bool } from './Bool'; export { default as Bytes } from './Bytes'; export { default as Data } from './Data'; diff --git a/packages/types/src/rpc/Block.spec.ts b/packages/types/src/rpc/Block.spec.ts index ea064d0f8c..e94b24b1c2 100644 --- a/packages/types/src/rpc/Block.spec.ts +++ b/packages/types/src/rpc/Block.spec.ts @@ -8,12 +8,12 @@ import block00300 from '../json/SignedBlock.003.00.json'; import Method from '../primitive/Method'; import Block from './Block'; -describe('Block', () => { - beforeEach(() => { +describe('Block', (): void => { + beforeEach((): void => { Method.injectMethods(extrinsics); }); - it('has a valid toRawType', () => { + it('has a valid toRawType', (): void => { expect( new Block().toRawType() ).toEqual( @@ -33,7 +33,7 @@ describe('Block', () => { ); }); - it('re-encodes digest items correctly', () => { + it('re-encodes digest items correctly', (): void => { const digest = new Block(block00300.result.block).header.digest; expect(digest.logs[0].toHex()).toEqual(block00300.result.block.header.digest.logs[0]); diff --git a/packages/types/src/rpc/Block.ts b/packages/types/src/rpc/Block.ts index 88d23a0f96..541fe0e3ac 100644 --- a/packages/types/src/rpc/Block.ts +++ b/packages/types/src/rpc/Block.ts @@ -11,10 +11,10 @@ import Hash from '../primitive/Hash'; import Extrinsics from '../type/Extrinsics'; import Header, { HeaderValue } from './Header'; -export type BlockValue = { - extrinsics?: Array - header?: HeaderValue -}; +export interface BlockValue { + extrinsics?: AnyU8a[]; + header?: HeaderValue; +} /** * @name Block @@ -22,7 +22,7 @@ export type BlockValue = { * A block encoded with header and extrinsics */ export default class Block extends Struct { - constructor (value?: BlockValue | Uint8Array) { + public constructor (value?: BlockValue | Uint8Array) { super({ header: Header, extrinsics: Extrinsics @@ -32,7 +32,7 @@ export default class Block extends Struct { /** * @description Encodes a content [[Hash]] for the block */ - get contentHash (): Hash { + public get contentHash (): Hash { return new Hash( blake2AsU8a(this.toU8a(), 256) ); @@ -41,21 +41,21 @@ export default class Block extends Struct { /** * @description The [[Extrinsics]] contained in the block */ - get extrinsics (): Extrinsics { + public get extrinsics (): Extrinsics { return this.get('extrinsics') as Extrinsics; } /** * @description Block/header [[Hash]] */ - get hash (): Hash { + public get hash (): Hash { return this.header.hash; } /** * @description The [[Header]] of the block */ - get header (): Header { + public get header (): Header { return this.get('header') as Header; } } diff --git a/packages/types/src/rpc/ChainProperties.spec.ts b/packages/types/src/rpc/ChainProperties.spec.ts index 71670362f3..efde7d4f71 100644 --- a/packages/types/src/rpc/ChainProperties.spec.ts +++ b/packages/types/src/rpc/ChainProperties.spec.ts @@ -4,14 +4,14 @@ import ChainProperties from './ChainProperties'; -describe('ChainProperties', () => { - it('decodes from a null value', () => { +describe('ChainProperties', (): void => { + it('decodes from a null value', (): void => { expect( [...new ChainProperties(null).entries()] ).toEqual([]); }); - it('decodes from an actual object', () => { + it('decodes from an actual object', (): void => { expect( [...new ChainProperties({ decimals: 15, @@ -20,7 +20,7 @@ describe('ChainProperties', () => { ).toEqual([['decimals', 15], ['tokenSymbol', 'BBQ']]); }); - it('checks equality', () => { + it('checks equality', (): void => { expect( new ChainProperties({ decimals: 15, diff --git a/packages/types/src/rpc/ChainProperties.ts b/packages/types/src/rpc/ChainProperties.ts index 02a5dae5fc..abc44cc745 100644 --- a/packages/types/src/rpc/ChainProperties.ts +++ b/packages/types/src/rpc/ChainProperties.ts @@ -13,14 +13,14 @@ export default class ChainProperties extends StructAny { /** * @description The token decimals, if defined (de-facto standard only) */ - get tokenDecimals (): number | undefined { + public get tokenDecimals (): number | undefined { return this.get('tokenDecimals'); } /** * @description The token system, if defined (de-facto standard only) */ - get tokenSymbol (): string | undefined { + public get tokenSymbol (): string | undefined { return this.get('tokenSymbol'); } } diff --git a/packages/types/src/rpc/Digest.spec.ts b/packages/types/src/rpc/Digest.spec.ts index 3a4e331241..58dc34652e 100644 --- a/packages/types/src/rpc/Digest.spec.ts +++ b/packages/types/src/rpc/Digest.spec.ts @@ -6,8 +6,8 @@ import json3 from '../json/Header.003.json'; import block1 from '../json/SignedBlock.003.00.json'; import Digest, { ConsensusEngineId, CID_AURA, CID_BABE, CID_GRPA } from './Digest'; -describe('Digest', () => { - it('decodes logs with consensus', () => { +describe('Digest', (): void => { + it('decodes logs with consensus', (): void => { const digest = new Digest(json3.result.digest); expect(digest.logs.length).toEqual(1); @@ -21,27 +21,27 @@ describe('Digest', () => { ]); }); - it('filters logs, excluding items', () => { + it('filters logs, excluding items', (): void => { const logs = new Digest(block1.result.block.header.digest).logsWith('PreRuntime'); expect(logs.length).toEqual(1); expect(logs[0].type).toEqual('PreRuntime'); }); - it('filters logs, including items', () => { + it('filters logs, including items', (): void => { const logs = new Digest(block1.result.block.header.digest).logsWithout('PreRuntime'); expect(logs.length).toEqual(1); expect(logs[0].type).toEqual('Seal'); }); - describe('ConsensusId', () => { - it('creates a valid id for aura', () => { + describe('ConsensusId', (): void => { + it('creates a valid id for aura', (): void => { expect(ConsensusEngineId.stringToId('FRNK')).toEqual(CID_GRPA); expect(ConsensusEngineId.stringToId('aura')).toEqual(CID_AURA); }); - it('reverses an id to string for babe', () => { + it('reverses an id to string for babe', (): void => { expect(ConsensusEngineId.idToString(CID_BABE)).toEqual('babe'); }); }); diff --git a/packages/types/src/rpc/Digest.ts b/packages/types/src/rpc/Digest.ts index 23702c6dec..2b154fd614 100644 --- a/packages/types/src/rpc/Digest.ts +++ b/packages/types/src/rpc/Digest.ts @@ -44,45 +44,45 @@ export class ChangesTrieRoot extends Hash { * A 4-byte identifier (actually a [u8; 4]) identifying the engine, e.g. for Aura it would be [b'a', b'u', b'r', b'a'] */ export class ConsensusEngineId extends U32 { - static idToString (input: number | BN): string { + public static idToString (input: number | BN): string { return bnToBn(input) .toArray('le') - .map((code) => String.fromCharCode(code)) + .map((code): string => String.fromCharCode(code)) .join(''); } - static stringToId (input: string): number { + public static stringToId (input: string): number { return input .split('') .reverse() - .reduce((result, char) => (result * 256) + char.charCodeAt(0), 0); + .reduce((result, char): number => (result * 256) + char.charCodeAt(0), 0); } /** * @description `true` if the engine matches aura */ - get isAura (): boolean { + public get isAura (): boolean { return this.eq(CID_AURA); } /** * @description `true` is the engine matches babe */ - get isBabe (): boolean { + public get isBabe (): boolean { return this.eq(CID_BABE); } /** * @description `true` is the engine matches grandpa */ - get isGrandpa (): boolean { + public get isGrandpa (): boolean { return this.eq(CID_GRPA); } /** * @description From the input bytes, decode into an aura-tuple */ - extractSlot (bytes: Bytes): U64 { + public extractSlot (bytes: Bytes): U64 { assert(this.isAura, 'Invalid engine for asAura conversion'); return new U64( @@ -94,7 +94,7 @@ export class ConsensusEngineId extends U32 { /** * @description Override the default toString to return a 4-byte string */ - toString (): string { + public toString (): string { return ConsensusEngineId.idToString(this as BN); } } @@ -105,7 +105,7 @@ export class ConsensusEngineId extends U32 { * Log item indicating consensus */ export class Consensus extends Tuple { - constructor (value: any) { + public constructor (value: any) { super({ ConsensusEngineId, Bytes @@ -115,21 +115,21 @@ export class Consensus extends Tuple { /** * @description The wrapped engine [[ConsensusEngineId]] */ - get engine (): ConsensusEngineId { + public get engine (): ConsensusEngineId { return this[0] as ConsensusEngineId; } /** * @description The wrapped [[Bytes]] */ - get data (): Bytes { + public get data (): Bytes { return this[1] as Bytes; } /** * @description The slot extracted from the raw data (fails on non-Aura) */ - get slot (): U64 { + public get slot (): U64 { return this.engine.extractSlot(this.data); } } @@ -140,7 +140,7 @@ export class Consensus extends Tuple { * Log item indicating a sealing event. This has been replaced in later versions with a renamed [[Seal]], we however have kept compatibility with the old version */ export class SealV0 extends Tuple { - constructor (value: any) { + public constructor (value: any) { super({ U64, Signature @@ -150,14 +150,14 @@ export class SealV0 extends Tuple { /** * @description The wrapped [[Signature]] */ - get signature (): Signature { + public get signature (): Signature { return this[1] as Signature; } /** * @description The wrapped [[U64]] slot */ - get slot (): U64 { + public get slot (): U64 { return this[0] as U64; } } @@ -168,7 +168,7 @@ export class SealV0 extends Tuple { * Log item indicating a sealing event. */ export class Seal extends Tuple { - constructor (value: any) { + public constructor (value: any) { super({ ConsensusEngineId, Bytes @@ -178,14 +178,14 @@ export class Seal extends Tuple { /** * @description The wrapped [[Bytes]] */ - get data (): Bytes { + public get data (): Bytes { return this[1] as Signature; } /** * @description The wrapped [[U64]] slot */ - get slot (): U64 { + public get slot (): U64 { return this[0] as U64; } } @@ -204,7 +204,7 @@ export class Other extends Bytes { * These are messages from the consensus engine to the runtime, although the consensus engine the consensus engine can (and should) read them itself to avoid ode and state duplication. */ export class PreRuntime extends Tuple { - constructor (value: any) { + public constructor (value: any) { super({ ConsensusEngineId, Bytes @@ -214,21 +214,21 @@ export class PreRuntime extends Tuple { /** * @description The wrapped [[ConsensusEngineId]] */ - get engine (): ConsensusEngineId { + public get engine (): ConsensusEngineId { return this[0] as ConsensusEngineId; } /** * @description The wrapped [[Bytes]] */ - get data (): Bytes { + public get data (): Bytes { return this[1] as Bytes; } /** * @description The slot extracted from the raw data (fails on non-Aura) */ - get slot (): U64 { + public get slot (): U64 { return this.engine.extractSlot(this.data); } } @@ -253,14 +253,14 @@ type DigestItemTypes = keyof typeof DigestItemEnumMap; * A [[Enum]] the specifies the specific item in the logs of a [[Digest]] */ export class DigestItem extends Enum { - constructor (value: any) { + public constructor (value: any) { super(DigestItemEnumMap, value); } /** * @description Returns the item as a [[AuthoritiesChange]] */ - get asAuthoritiesChange (): AuthoritiesChange { + public get asAuthoritiesChange (): AuthoritiesChange { assert(this.isAuthoritiesChange, `Cannot convert '${this.type}' via asAuthoritiesChange`); return this.value as AuthoritiesChange; @@ -269,7 +269,7 @@ export class DigestItem extends Enum { /** * @description Returns the item as a [[ChangesTrieRoot]] */ - get asChangesTrieRoot (): ChangesTrieRoot { + public get asChangesTrieRoot (): ChangesTrieRoot { assert(this.isChangesTrieRoot, `Cannot convert '${this.type}' via asChangesTrieRoot`); return this.value as ChangesTrieRoot; @@ -278,7 +278,7 @@ export class DigestItem extends Enum { /** * @desciption Retuns the item as a [[Consensus]] */ - get asConsensus (): Consensus { + public get asConsensus (): Consensus { assert(this.isConsensus, `Cannot convert '${this.type}' via asConsensus`); return this.value as Consensus; @@ -287,7 +287,7 @@ export class DigestItem extends Enum { /** * @description Returns the item as a [[Other]] */ - get asOther (): Other { + public get asOther (): Other { assert(this.isOther, `Cannot convert '${this.type}' via asOther`); return this.value as Other; @@ -296,7 +296,7 @@ export class DigestItem extends Enum { /** * @description Returns the item as a [[PreRuntime]] */ - get asPreRuntime (): PreRuntime { + public get asPreRuntime (): PreRuntime { assert(this.isPreRuntime, `Cannot convert '${this.type}' via asPreRuntime`); return this.value as PreRuntime; @@ -305,7 +305,7 @@ export class DigestItem extends Enum { /** * @description Returns the item as a [[Seal]] */ - get asSeal (): Seal { + public get asSeal (): Seal { assert(this.isSeal, `Cannot convert '${this.type}' via asSeal`); return this.value as Seal; @@ -314,7 +314,7 @@ export class DigestItem extends Enum { /** * @description Returns the item as a [[SealV0]] */ - get asSealV0 (): SealV0 { + public get asSealV0 (): SealV0 { assert(this.isSealV0, `Cannot convert '${this.type}' via asSealV0`); return this.value as SealV0; @@ -323,63 +323,63 @@ export class DigestItem extends Enum { /** * @description Returns true on [[AuthoritiesChange]] */ - get isAuthoritiesChange (): boolean { + public get isAuthoritiesChange (): boolean { return this.type === 'AuthoritiesChange'; } /** * @description Returns true on [[ChangesTrieRoot]] */ - get isChangesTrieRoot (): boolean { + public get isChangesTrieRoot (): boolean { return this.type === 'ChangesTrieRoot'; } /** * @description Returns true on [[Consensus]] */ - get isConsensus (): boolean { + public get isConsensus (): boolean { return this.type === 'Consensus'; } /** * @description Returns true on [[Other]] */ - get isOther (): boolean { + public get isOther (): boolean { return this.type === 'Other'; } /** * @description Returns true on [[PreRuntime]] */ - get isPreRuntime (): boolean { + public get isPreRuntime (): boolean { return this.type === 'PreRuntime'; } /** * @description Returns true on [[Seal]] */ - get isSeal (): boolean { + public get isSeal (): boolean { return this.type === 'Seal'; } /** * @description Returns true on [[SealV0]] */ - get isSealV0 (): boolean { + public get isSealV0 (): boolean { return this.type === 'SealV0'; } /** * @description Converts the Object to JSON, typically used for RPC transfers. For logs, we overrides to produce the hex version (sligning with substrate gives in actual JSON responses) */ - toJSON (): string { + public toJSON (): string { return this.toHex(); } /** * @description Returns the type of engine, we just override here to get the typings correct */ - get type (): DigestItemTypes { + public get type (): DigestItemTypes { return super.type as DigestItemTypes; } } @@ -390,7 +390,7 @@ export class DigestItem extends Enum { * A [[Header]] Digest */ export default class Digest extends Struct { - constructor (value: any) { + public constructor (value: any) { super({ logs: Vector.with(DigestItem) }, value); @@ -399,22 +399,22 @@ export default class Digest extends Struct { /** * @description The [[DigestItem]] logs */ - get logs (): Vector { + public get logs (): Vector { return this.get('logs') as Vector; } /** * @description The [[DigestItem]] logs, filtered, filter items included. This is useful for derive functionality where only a certain type of log is to be returned. */ - logsWith (...include: Array): Vector { - return this.logs.filter(({ type }) => include.includes(type)) as Vector; + public logsWith (...include: DigestItemTypes[]): Vector { + return this.logs.filter(({ type }): boolean => include.includes(type)) as Vector; } /** * @description The [[DigestItem]] logs, filtered, filter items exluded. This is useful for stripping headers for eg. WASM runtime execution. */ - logsWithout (...exclude: Array): Vector { - return this.logs.filter(({ type }) => !exclude.includes(type)) as Vector; + public logsWithout (...exclude: DigestItemTypes[]): Vector { + return this.logs.filter(({ type }): boolean => !exclude.includes(type)) as Vector; } } diff --git a/packages/types/src/rpc/ExtrinsicStatus.spec.ts b/packages/types/src/rpc/ExtrinsicStatus.spec.ts index b30ac7d4d8..8303a89d02 100644 --- a/packages/types/src/rpc/ExtrinsicStatus.spec.ts +++ b/packages/types/src/rpc/ExtrinsicStatus.spec.ts @@ -5,16 +5,16 @@ import rpc from '../json/ExtrinsicStatus.001.json'; import ExtrinsicStatus from './ExtrinsicStatus'; -describe('ExtrinsicStatus', () => { +describe('ExtrinsicStatus', (): void => { const status = new ExtrinsicStatus(rpc.params.result); - it('has the correct type', () => { + it('has the correct type', (): void => { expect( status.type ).toEqual('Finalized'); }); - it('has the correct hash', () => { + it('has the correct hash', (): void => { expect( status.value.toString() ).toEqual('0xc465b92a72b1d20918d64cd4effa70c2bb58b53a3f8c24c3ac8fd8f465f059b4'); diff --git a/packages/types/src/rpc/ExtrinsicStatus.ts b/packages/types/src/rpc/ExtrinsicStatus.ts index 57ced139ac..3a6052a3aa 100644 --- a/packages/types/src/rpc/ExtrinsicStatus.ts +++ b/packages/types/src/rpc/ExtrinsicStatus.ts @@ -72,7 +72,7 @@ export class Usurped extends Hash { * An [[Enum]] that indicates the status of the [[Extrinsic]] as been submitted */ export default class ExtrinsicStatus extends Enum { - constructor (value: any, index?: number) { + public constructor (value: any, index?: number) { super({ Future, Ready, @@ -87,7 +87,7 @@ export default class ExtrinsicStatus extends Enum { /** * @description Returns the item as a [[Broadcast]] */ - get asBroadcast (): Broadcast { + public get asBroadcast (): Broadcast { assert(this.isBroadcast, `Cannot convert '${this.type}' via asBroadcast`); return this.value as Broadcast; @@ -96,7 +96,7 @@ export default class ExtrinsicStatus extends Enum { /** * @description Returns the item as a [[Dropped]] */ - get asDropped (): Dropped { + public get asDropped (): Dropped { assert(this.isDropped, `Cannot convert '${this.type}' via asDropped`); return this.value as Dropped; @@ -105,7 +105,7 @@ export default class ExtrinsicStatus extends Enum { /** * @description Returns the item as a [[Finalized]] */ - get asFinalized (): Finalized { + public get asFinalized (): Finalized { assert(this.isFinalized, `Cannot convert '${this.type}' via asFinalized`); return this.value as Finalized; @@ -114,7 +114,7 @@ export default class ExtrinsicStatus extends Enum { /** * @description Returns the item as a [[Future]] */ - get asFuture (): Future { + public get asFuture (): Future { assert(this.isFuture, `Cannot convert '${this.type}' via asFuture`); return this.value as Future; @@ -123,7 +123,7 @@ export default class ExtrinsicStatus extends Enum { /** * @description Returns the item as a [[Invalid]] */ - get asInvalid (): Invalid { + public get asInvalid (): Invalid { assert(this.isInvalid, `Cannot convert '${this.type}' via asInvalid`); return this.value as Invalid; @@ -132,7 +132,7 @@ export default class ExtrinsicStatus extends Enum { /** * @description Returns the item as a [[Ready]] */ - get asReady (): Ready { + public get asReady (): Ready { assert(this.isReady, `Cannot convert '${this.type}' via asReady`); return this.value as Ready; @@ -141,7 +141,7 @@ export default class ExtrinsicStatus extends Enum { /** * @description Returns the item as a [[Usurped]] */ - get asUsurped (): Usurped { + public get asUsurped (): Usurped { assert(this.isUsurped, `Cannot convert '${this.type}' via asUsurped`); return this.value as Usurped; @@ -150,49 +150,49 @@ export default class ExtrinsicStatus extends Enum { /** * @description Returns true if the status is boadcast */ - get isBroadcast (): boolean { + public get isBroadcast (): boolean { return this.type === 'Broadcast'; } /** * @description Returns true if the status is dropped */ - get isDropped (): boolean { + public get isDropped (): boolean { return this.type === 'Dropped'; } /** * @description Returns true if the status is finalized */ - get isFinalized (): boolean { + public get isFinalized (): boolean { return this.type === 'Finalized'; } /** * @description Returns true if the status is future */ - get isFuture (): boolean { + public get isFuture (): boolean { return this.type === 'Future'; } /** * @description Returns true if the status is invalid */ - get isInvalid (): boolean { + public get isInvalid (): boolean { return this.type === 'Invalid'; } /** * @description Returns true if the status is eady */ - get isReady (): boolean { + public get isReady (): boolean { return this.type === 'Ready'; } /** * @description Returns true if the status is usurped */ - get isUsurped (): boolean { + public get isUsurped (): boolean { return this.type === 'Usurped'; } } diff --git a/packages/types/src/rpc/Header.spec.ts b/packages/types/src/rpc/Header.spec.ts index 6fdd0710b4..ebea5bff97 100644 --- a/packages/types/src/rpc/Header.spec.ts +++ b/packages/types/src/rpc/Header.spec.ts @@ -11,8 +11,8 @@ import json3 from '../json/Header.003.json'; import block00300 from '../json/SignedBlock.003.00.json'; import block00301 from '../json/SignedBlock.003.01.json'; -describe('Header', () => { - it('decodes an actual JSON response', () => { +describe('Header', (): void => { + it('decodes an actual JSON response', (): void => { const header = new Header(json1.result); expect( @@ -32,7 +32,7 @@ describe('Header', () => { ).toEqual('[]'); }); - it('parses old-style JSON headers (deprecated)', () => { + it('parses old-style JSON headers (deprecated)', (): void => { const header = new Header(json2.result); expect( @@ -40,7 +40,7 @@ describe('Header', () => { ).toHaveLength(1); }); - it('creates a valid hash (incl. digest & compact)', () => { + it('creates a valid hash (incl. digest & compact)', (): void => { const header = new Header(json3.result); expect( @@ -51,7 +51,7 @@ describe('Header', () => { ).toBe(true); }); - it('calculates correct hash, matching with parentHash', () => { + it('calculates correct hash, matching with parentHash', (): void => { const blockHash = new Header(block00300.result.block.header).hash.toHex(); expect(blockHash).toEqual(block00301.result.block.header.parentHash); diff --git a/packages/types/src/rpc/Header.ts b/packages/types/src/rpc/Header.ts index d8577895e0..7fd56dc461 100644 --- a/packages/types/src/rpc/Header.ts +++ b/packages/types/src/rpc/Header.ts @@ -12,13 +12,13 @@ import Hash from '../primitive/Hash'; import BlockNumber from '../type/BlockNumber'; import Digest, { DigestItem } from './Digest'; -export type HeaderValue = { - digest?: Digest | { logs: DigestItem[] }, - extrinsicsRoot?: AnyU8a, - number?: AnyNumber, - parentHash?: AnyU8a, - stateRoot?: AnyU8a -}; +export interface HeaderValue { + digest?: Digest | { logs: DigestItem[] }; + extrinsicsRoot?: AnyU8a; + number?: AnyNumber; + parentHash?: AnyU8a; + stateRoot?: AnyU8a; +} /** * @name Header @@ -26,7 +26,7 @@ export type HeaderValue = { * A [[Block]] header */ export default class Header extends Struct { - constructor (value?: HeaderValue | Uint8Array | null) { + public constructor (value?: HeaderValue | Uint8Array | null) { super({ parentHash: Hash, number: Compact.with(BlockNumber), @@ -39,28 +39,28 @@ export default class Header extends Struct { /** * @description The wrapped [[BlockNumber]] */ - get blockNumber (): BlockNumber { + public get blockNumber (): BlockNumber { return (this.get('number') as Compact).toBn() as BlockNumber; } /** * @description The wrapped [[Digest]] */ - get digest (): Digest { + public get digest (): Digest { return this.get('digest') as Digest; } /** * @description The wrapped extrisics root as a [[Hash]] */ - get extrinsicsRoot (): Hash { + public get extrinsicsRoot (): Hash { return this.get('extrinsicsRoot') as Hash; } /** * @description Convenience method, encodes the header and calculates the [[Hash]] */ - get hash (): Hash { + public get hash (): Hash { return new Hash( blake2AsU8a(this.toU8a(), 256) ); @@ -69,21 +69,21 @@ export default class Header extends Struct { /** * @description Alias for `blockNumber` (this is displayed in JSON) */ - get number (): BlockNumber { + public get number (): BlockNumber { return this.blockNumber; } /** * @description The wrapped parent as a [[Hash]] */ - get parentHash (): Hash { + public get parentHash (): Hash { return this.get('parentHash') as Hash; } /** * @description The wrapped state root as a [[Hash]] */ - get stateRoot (): Hash { + public get stateRoot (): Hash { return this.get('stateRoot') as Hash; } } diff --git a/packages/types/src/rpc/Health.ts b/packages/types/src/rpc/Health.ts index 19aa59db5e..b9739cd9a7 100644 --- a/packages/types/src/rpc/Health.ts +++ b/packages/types/src/rpc/Health.ts @@ -12,7 +12,7 @@ import U64 from '../primitive/U64'; * A system health indicator, reported back over RPC */ export default class Health extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ peers: U64, isSyncing: Bool, @@ -23,21 +23,21 @@ export default class Health extends Struct { /** * @description The sync status */ - get isSyncing (): Bool { + public get isSyncing (): Bool { return this.get('isSyncing') as Bool; } /** * @description The numbers of peers as [[U64]] */ - get peers (): U64 { + public get peers (): U64 { return this.get('peers') as U64; } /** * @description Should this node have peers (not active on --dev) */ - get shouldHavePeers (): Bool { + public get shouldHavePeers (): Bool { return this.get('shouldHavePeers') as Bool; } } diff --git a/packages/types/src/rpc/PeerInfo.ts b/packages/types/src/rpc/PeerInfo.ts index b0ca131b7b..4b7f0f9ff3 100644 --- a/packages/types/src/rpc/PeerInfo.ts +++ b/packages/types/src/rpc/PeerInfo.ts @@ -14,7 +14,7 @@ import BlockNumber from '../type/BlockNumber'; * A system peer info indicator, reported back over RPC */ export default class PeerInfo extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ peerId: Text, roles: Text, @@ -27,35 +27,35 @@ export default class PeerInfo extends Struct { /** * @description The best block hash for the peer */ - get bestHash (): Hash { + public get bestHash (): Hash { return this.get('bestHash') as Hash; } /** * @description The best block hash for the peer */ - get bestNumber (): BlockNumber { + public get bestNumber (): BlockNumber { return this.get('bestNumber') as BlockNumber; } /** * @description The p2p network id for the peer */ - get peerId (): Text { + public get peerId (): Text { return this.get('peerId') as Text; } /** * @description The index of the peer in our list */ - get protocolVersion (): U32 { + public get protocolVersion (): U32 { return this.get('protocolVersion') as U32; } /** * @description The roles of the peer on the network */ - get roles (): Text { + public get roles (): Text { return this.get('roles') as Text; } } diff --git a/packages/types/src/rpc/RuntimeVersion.spec.ts b/packages/types/src/rpc/RuntimeVersion.spec.ts index b65890bbc1..0065f33063 100644 --- a/packages/types/src/rpc/RuntimeVersion.spec.ts +++ b/packages/types/src/rpc/RuntimeVersion.spec.ts @@ -5,26 +5,26 @@ import rpc from '../json/RuntimeVersion.002.json'; import RuntimeVersion from './RuntimeVersion'; -describe('RuntimeVersion', () => { +describe('RuntimeVersion', (): void => { const version = new RuntimeVersion(rpc.result); - it('has the correct authoring', () => { + it('has the correct authoring', (): void => { expect(version.authoringVersion.toNumber()).toEqual(10); }); - it('has the apis', () => { + it('has the apis', (): void => { const api = version.apis[0]; expect(api.id.toHex()).toEqual('0xdf6acb689907609b'); expect(api.version.toNumber()).toEqual(2); }); - it('has the correct implementation', () => { + it('has the correct implementation', (): void => { expect(version.implName.toString()).toEqual('substrate-node'); expect(version.implVersion.toNumber()).toEqual(60); }); - it('has the correct spec', () => { + it('has the correct spec', (): void => { expect(version.specName.toString()).toEqual('node'); expect(version.specVersion.toNumber()).toEqual(60); }); diff --git a/packages/types/src/rpc/RuntimeVersion.ts b/packages/types/src/rpc/RuntimeVersion.ts index c14d1ac0c9..fe602f7979 100644 --- a/packages/types/src/rpc/RuntimeVersion.ts +++ b/packages/types/src/rpc/RuntimeVersion.ts @@ -17,15 +17,15 @@ import U32 from '../primitive/U32'; * An identifier for the runtime API */ export class ApiId extends U8aFixed { - constructor (value?: AnyU8a) { + public constructor (value?: AnyU8a) { super(value, 64); } } -type RuntimeVersionApiValue = { - id?: AnyU8a, - version?: AnyNumber -}; +interface RuntimeVersionApiValue { + id?: AnyU8a; + version?: AnyNumber; +} /** * @name RuntimeVersionApi @@ -33,7 +33,7 @@ type RuntimeVersionApiValue = { * A [[Tuple]] that conatins the [[ApiId]] and [[U32]] version */ export class RuntimeVersionApi extends Tuple { - constructor (value?: RuntimeVersionApiValue | Uint8Array) { + public constructor (value?: RuntimeVersionApiValue | Uint8Array) { super({ ApiId, U32 @@ -43,26 +43,26 @@ export class RuntimeVersionApi extends Tuple { /** * @description The [[ApiId]] */ - get id (): ApiId { + public get id (): ApiId { return this[0] as ApiId; } /** * @description The specific version as [[U32]] */ - get version (): U32 { + public get version (): U32 { return this[1] as U32; } } -type RuntimeVersionValue = { - specName?: string, - implName?: string, - authoringVersion?: AnyNumber, - specVersion?: AnyNumber, - implVersion?: AnyNumber, - apis?: Array -}; +interface RuntimeVersionValue { + specName?: string; + implName?: string; + authoringVersion?: AnyNumber; + specVersion?: AnyNumber; + implVersion?: AnyNumber; + apis?: RuntimeVersionApiValue[]; +} /** * @name RuntimeVersion @@ -70,7 +70,7 @@ type RuntimeVersionValue = { * A defintion of the runtime and the associated versions thereof */ export default class RuntimeVersion extends Struct implements RuntimeVersionInterface { - constructor (value?: RuntimeVersionValue | Uint8Array) { + public constructor (value?: RuntimeVersionValue | Uint8Array) { super({ specName: Text, implName: Text, @@ -84,42 +84,42 @@ export default class RuntimeVersion extends Struct implements RuntimeVersionInte /** * @description The available APIs as [[RuntimeVersionApi]] */ - get apis (): Vector { + public get apis (): Vector { return this.get('apis') as Vector; } /** * @description The authoring version as [[U32]] */ - get authoringVersion (): U32 { + public get authoringVersion (): U32 { return this.get('authoringVersion') as U32; } /** * @description The implementation name */ - get implName (): Text { + public get implName (): Text { return this.get('implName') as Text; } /** * @description The implementation version */ - get implVersion (): U32 { + public get implVersion (): U32 { return this.get('implVersion') as U32; } /** * @description The specification name */ - get specName (): Text { + public get specName (): Text { return this.get('specName') as Text; } /** * @description The specification version */ - get specVersion (): U32 { + public get specVersion (): U32 { return this.get('specVersion') as U32; } } diff --git a/packages/types/src/rpc/SignedBlock.spec.ts b/packages/types/src/rpc/SignedBlock.spec.ts index 306cbd41f8..15ebaa45b0 100644 --- a/packages/types/src/rpc/SignedBlock.spec.ts +++ b/packages/types/src/rpc/SignedBlock.spec.ts @@ -10,12 +10,12 @@ import immortalTxs from '../json/SignedBlock.004.immortal.json'; import mortalTxs from '../json/SignedBlock.004.mortal.json'; import SignedBlock from './SignedBlock'; -describe('SignedBlock', () => { - beforeEach(() => { +describe('SignedBlock', (): void => { + beforeEach((): void => { Method.injectMethods(extrinsics); }); - it('decodes a full block', () => { + it('decodes a full block', (): void => { const s = new SignedBlock(events.result); expect( @@ -34,8 +34,8 @@ describe('SignedBlock', () => { ]); }); - describe('extrinsics', () => { - it('can decode immortals', () => { + describe('extrinsics', (): void => { + it('can decode immortals', (): void => { const s = new SignedBlock(immortalTxs.result); const immortalTx = s.block.extrinsics[2]; @@ -43,7 +43,7 @@ describe('SignedBlock', () => { expect(immortalTx.method.sectionName).toEqual('balances'); }); - it('can decode mortals', () => { + it('can decode mortals', (): void => { const s = new SignedBlock(mortalTxs.result); const mortalTx = s.block.extrinsics[2]; diff --git a/packages/types/src/rpc/SignedBlock.ts b/packages/types/src/rpc/SignedBlock.ts index 7c7ba495e5..852d4bcc53 100644 --- a/packages/types/src/rpc/SignedBlock.ts +++ b/packages/types/src/rpc/SignedBlock.ts @@ -9,10 +9,10 @@ import Hash from '../primitive/Hash'; import Justification from '../type/Justification'; import Block, { BlockValue } from './Block'; -type SignedBlockValue = { - block?: BlockValue, - justification?: AnyU8a -}; +interface SignedBlockValue { + block?: BlockValue; + justification?: AnyU8a; +} /** * @name SignedBlock @@ -20,7 +20,7 @@ type SignedBlockValue = { * A [[Block]] that has been signed and contains a [[Justification]] */ export default class SignedBlock extends Struct { - constructor (value?: SignedBlockValue | Uint8Array) { + public constructor (value?: SignedBlockValue | Uint8Array) { super({ block: Block, justification: Justification @@ -30,21 +30,21 @@ export default class SignedBlock extends Struct { /** * @description The wrapped [[Block]] */ - get block (): Block { + public get block (): Block { return this.get('block') as Block; } /** * @description Block/header [[Hash]] */ - get hash (): Hash { + public get hash (): Hash { return this.block.hash; } /** * @description The wrapped [[Justification]] */ - get justification (): Justification { + public get justification (): Justification { return this.get('justification') as Justification; } } diff --git a/packages/types/src/rpc/StorageChangeSet.spec.ts b/packages/types/src/rpc/StorageChangeSet.spec.ts index fce674afc5..d9e54bfebe 100644 --- a/packages/types/src/rpc/StorageChangeSet.spec.ts +++ b/packages/types/src/rpc/StorageChangeSet.spec.ts @@ -6,8 +6,8 @@ import { createType } from '@polkadot/types'; import json from '../json/StorageChangeSet.001.json'; import StorageChangeSet from './StorageChangeSet'; -describe('StorageChangeSet', () => { - describe('construction', () => { +describe('StorageChangeSet', (): void => { + describe('construction', (): void => { const set = new StorageChangeSet({ block: '0x1234', changes: [ @@ -15,34 +15,34 @@ describe('StorageChangeSet', () => { ] }); - it('wraps blockHash', () => { + it('wraps blockHash', (): void => { expect( set.block.toHex() ).toEqual('0x1234000000000000000000000000000000000000000000000000000000000000'); }); - it('wraps key/value', () => { + it('wraps key/value', (): void => { expect( set.changes[0].value.toString() ).toEqual('0xcd'); }); }); - describe('json', () => { + describe('json', (): void => { const set = new StorageChangeSet(json.params.result); - it('has the correct hash', () => { + it('has the correct hash', (): void => { expect( set.block.toHex() ).toEqual('0x2ad8077937e9a5ceb2e0d57c95b95a6a9edcedc4fb1f14e3bc13245e223a569d'); }); - it('has the changes', () => { + it('has the changes', (): void => { expect(set.changes).toHaveLength(1); expect(set.changes[0].key.toHex()).toEqual('0x54bdbdb5e438d574dd4da05ee6131cee'); }); - it('converts result data to Bytes', () => { + it('converts result data to Bytes', (): void => { const bytes = createType('Bytes', set.changes[0].value.unwrap()); expect(bytes).toHaveLength(4452); diff --git a/packages/types/src/rpc/StorageChangeSet.ts b/packages/types/src/rpc/StorageChangeSet.ts index 61015f2d33..c1f3e0b310 100644 --- a/packages/types/src/rpc/StorageChangeSet.ts +++ b/packages/types/src/rpc/StorageChangeSet.ts @@ -9,10 +9,10 @@ import Vector from '../codec/Vector'; import Hash from '../primitive/Hash'; import { KeyValueOption, KeyValueOptionValue } from '../type/KeyValue'; -type StorageChangeSetValue = { - block?: AnyU8a, - changes?: Array -}; +interface StorageChangeSetValue { + block?: AnyU8a; + changes?: KeyValueOptionValue[]; +} /** * @name StorageChangeSet @@ -22,7 +22,7 @@ type StorageChangeSetValue = { * [[KeyValueOption]] */ export default class StorageChangeSet extends Struct { - constructor (value?: StorageChangeSetValue | Uint8Array) { + public constructor (value?: StorageChangeSetValue | Uint8Array) { super({ block: Hash, changes: Vector.with(KeyValueOption) @@ -32,14 +32,14 @@ export default class StorageChangeSet extends Struct { /** * @description The applicable changes as [[KeyValueOption]] */ - get changes (): Vector { + public get changes (): Vector { return this.get('changes') as Vector; } /** * @description The block [[Hash]] */ - get block (): Hash { + public get block (): Hash { return this.get('block') as Hash; } } diff --git a/packages/types/src/scripts/MetadataMd.ts b/packages/types/src/scripts/MetadataMd.ts index ad3fb966b2..ad72448e7e 100644 --- a/packages/types/src/scripts/MetadataMd.ts +++ b/packages/types/src/scripts/MetadataMd.ts @@ -9,7 +9,7 @@ import interfaces from '../../../type-jsonrpc/src'; import Method from '../primitive/Method'; import Metadata from '../Metadata'; import rpcdata from '../Metadata/static'; -import MetadataV6 from '../Metadata/v6'; +import MetadataV6, { ModuleMetadataV6 } from '../Metadata/v6'; const ANCHOR_TOP = ''; const LINK_BACK_TO_TOP = ''; @@ -19,29 +19,29 @@ const DESC_EVENTS = '\n\nEvents are emitted for certain operations on the runtim const DESC_RPC = '\n\n_The following sections contain RPC methods that are Remote Calls available by default and allow you to interact with the actual node, query, and submit. The RPCs are provided by Substrate itself._'; const DESC_STORAGE = '\n\n_The following sections contain Storage methods are part of the default Substrate runtime._\n'; -function sectionLink (sectionName: string) { +function sectionLink (sectionName: string): string { return `- **[${stringCamelCase(sectionName)}](#${stringCamelCase(sectionName)})**\n\n`; } -function generateSectionHeader (md: string, sectionName: string) { +function generateSectionHeader (md: string, sectionName: string): string { return `${md}\n___\n${LINK_BACK_TO_TOP}\n\n### ${sectionName}\n`; } -function addRpc () { +function addRpc (): string { const renderHeading = `## ${ANCHOR_TOP}JSON-RPC${DESC_RPC}\n`; const orderedSections = Object.keys(interfaces).sort(); - const renderAnchors = Object.keys(interfaces).sort().map((sectionName) => + const renderAnchors = Object.keys(interfaces).sort().map((sectionName): string => sectionLink(sectionName) ).join(''); - return orderedSections.reduce((md, sectionName) => { + return orderedSections.reduce((md, sectionName): string => { const section = interfaces[sectionName]; const renderSection = generateSectionHeader(md, sectionName) + `\n_${section.description}_\n`; const orderedMethods = Object.keys(section.methods).sort(); - return orderedMethods.reduce((md, methodName) => { + return orderedMethods.reduce((md, methodName): string => { const method = section.methods[methodName]; - const args = method.params.map(({ name, isOptional, type }) => { + const args = method.params.map(({ name, isOptional, type }): string => { return name + (isOptional ? '?' : '') + ': `' + type + '`'; }).join(', '); const type = '`' + method.type + '`'; @@ -67,29 +67,27 @@ function sortByName (a: T, b: T): number { return nameA.localeCompare(nameB); } -function addEvents (metadata: MetadataV6) { +function addEvents (metadata: MetadataV6): string { const renderHeading = `## ${ANCHOR_TOP}Events${DESC_EVENTS}`; const orderedSections = metadata.modules.sort(sortByName); let renderAnchors = ''; - const sections = orderedSections.reduce((md, meta) => { + const sections = orderedSections.reduce((md, meta): string => { if (meta.events.isNone || !meta.events.unwrap().length) { return md; } const events = meta.events.unwrap(); - const sectionName = stringCamelCase(meta.name.toString()); renderAnchors += sectionLink(sectionName); const renderSection = generateSectionHeader(md, sectionName); - const orderedMethods = events.sort(sortByName); - return orderedMethods.reduce((md, func) => { + return orderedMethods.reduce((md, func): string => { const methodName = func.name.toString(); - const args = func.args.map((type) => '`' + type + '`').join(', '); - const doc = func.documentation.reduce((md, doc) => `${md} ${doc}`, ''); + const args = func.args.map((type): string => '`' + type + '`').join(', '); + const doc = func.documentation.reduce((md, doc): string => `${md} ${doc}`, ''); const renderSignature = `${md}\n▸ **${methodName}**(${args})`; const renderSummary = `${doc ? `\n- **summary**: ${doc}\n` : '\n'}`; @@ -100,17 +98,16 @@ function addEvents (metadata: MetadataV6) { return renderHeading + renderAnchors + sections; } -function addExtrinsics (metadata: MetadataV6) { +function addExtrinsics (metadata: MetadataV6): string { const renderHeading = `## ${ANCHOR_TOP}Extrinsics${DESC_EXTRINSICS}`; - const orderedSections = metadata.modules.map((i) => i).sort(sortByName); + const orderedSections = metadata.modules.map((i): ModuleMetadataV6 => i).sort(sortByName); let renderAnchors = ''; - const sections = orderedSections.reduce((md, meta) => { + const sections = orderedSections.reduce((md, meta): string => { if (meta.calls.isNone || !meta.calls.unwrap().length) { return md; } const calls = meta.calls.unwrap(); - const sectionName = stringCamelCase(meta.prefix.toString()); renderAnchors += sectionLink(sectionName); @@ -118,10 +115,10 @@ function addExtrinsics (metadata: MetadataV6) { const renderSection = generateSectionHeader(md, sectionName); const orderedMethods = calls.sort(sortByName); - return orderedMethods.reduce((md, func) => { + return orderedMethods.reduce((md, func): string => { const methodName = stringCamelCase(func.name.toString()); - const args = Method.filterOrigin(func).map(({ name, type }) => `${name}: ` + '`' + type + '`').join(', '); - const doc = func.documentation.reduce((md, doc) => `${md} ${doc}`, ''); + const args = Method.filterOrigin(func).map(({ name, type }): string => `${name}: ` + '`' + type + '`').join(', '); + const doc = func.documentation.reduce((md, doc): string => `${md} ${doc}`, ''); const renderSignature = `${md}\n▸ **${methodName}**(${args})`; const renderSummary = `${doc ? `\n- **summary**: ${doc}\n` : '\n'}`; @@ -132,11 +129,11 @@ function addExtrinsics (metadata: MetadataV6) { return renderHeading + renderAnchors + sections; } -function addStorage (metadata: MetadataV6) { +function addStorage (metadata: MetadataV6): string { const renderHeading = `## ${ANCHOR_TOP}Storage${DESC_STORAGE}`; const orderedSections = metadata.modules.sort(sortByName); let renderAnchors = ''; - const sections = orderedSections.reduce((md, moduleMetadata) => { + const sections = orderedSections.reduce((md, moduleMetadata): string => { if (moduleMetadata.storage.isNone) { return md; } @@ -148,10 +145,10 @@ function addStorage (metadata: MetadataV6) { const renderSection = generateSectionHeader(md, sectionName); const orderedMethods = moduleMetadata.storage.unwrap().sort(sortByName); - return orderedMethods.reduce((md, func) => { + return orderedMethods.reduce((md, func): string => { const methodName = stringLowerFirst(func.name.toString()); const arg = func.type.isMap ? ('`' + func.type.asMap.key.toString() + '`') : ''; - const doc = func.documentation.reduce((md, doc) => `${md} ${doc}`, ''); + const doc = func.documentation.reduce((md, doc): string => `${md} ${doc}`, ''); const type = func.modifier.isOptional ? `Option<${func.type}>` : func.type; @@ -165,37 +162,37 @@ function addStorage (metadata: MetadataV6) { return renderHeading + renderAnchors + sectionLink('substrate') + sections; } -function writeFile (name: string, ...chunks: Array) { +function writeFile (name: string, ...chunks: any[]): void { const options = { flags: 'w', encoding: 'utf8' }; const writeStream = fs.createWriteStream(name, options); - writeStream.on('finish', () => { + writeStream.on('finish', (): void => { console.log(`Completed writing ${name}`); }); - chunks.forEach((chunk) => - writeStream.write(chunk) - ); + chunks.forEach((chunk): void => { + writeStream.write(chunk); + }); writeStream.end(); } -function writeToRpcMd () { +function writeToRpcMd (): void { writeFile('docs/METHODS_RPC.md', addRpc()); } -function writeToStorageMd (metadata: MetadataV6) { +function writeToStorageMd (metadata: MetadataV6): void { const options = { flags: 'r', encoding: 'utf8' }; const data = fs.readFileSync('packages/types/src/scripts/METHODS_STORAGE_SUBSTRATE.md', options); writeFile('docs/METHODS_STORAGE.md', addStorage(metadata), data); } -function writeToExtrinsicsMd (metadata: MetadataV6) { +function writeToExtrinsicsMd (metadata: MetadataV6): void { writeFile('docs/METHODS_EXTRINSICS.md', addExtrinsics(metadata)); } -function writeToEventsMd (metadata: MetadataV6) { +function writeToEventsMd (metadata: MetadataV6): void { writeFile('docs/METHODS_EVENTS.md', addEvents(metadata)); } diff --git a/packages/types/src/scripts/srmlTS.ts b/packages/types/src/scripts/srmlTS.ts index ec265d3060..4264b2037f 100644 --- a/packages/types/src/scripts/srmlTS.ts +++ b/packages/types/src/scripts/srmlTS.ts @@ -10,35 +10,18 @@ import * as definitions from '../srml/definitions'; // these map all the codec and primitive types for import, see the TypeImports below. If // we have an unseen type, it is `undefined`/`false`, if we need to import it, it is `true` -type TypeExist = { - [index: string]: boolean -}; -type TypeImports = { - codecTypes: TypeExist, - otherTypes: TypeExist, - ownTypes: Array -}; +interface TypeExist { + [index: string]: boolean; +} +interface TypeImports { + codecTypes: TypeExist; + otherTypes: TypeExist; + ownTypes: string[]; +} -const HEADER = '// Auto-generated, do not edit\n\n'; +const HEADER = '/* eslint-disable @typescript-eslint/no-empty-interface */\n// Auto-generated, do not edit\n\n'; const FOOTER = '\n'; -// handlers are defined externally to use - this means that when we do a -// `generators[typedef.info](...)` TS will show any unhandled types. Rather -// we are being explicit in having no handlers where we do not support (yet) -const generators = { - [TypeDefInfo.Compact]: errorUnhandled, - [TypeDefInfo.DoubleMap]: errorUnhandled, - [TypeDefInfo.Enum]: tsEnum, - [TypeDefInfo.Linkage]: errorUnhandled, - [TypeDefInfo.Null]: errorUnhandled, - [TypeDefInfo.Option]: errorUnhandled, - [TypeDefInfo.Plain]: tsPlain, - [TypeDefInfo.Struct]: tsStruct, - [TypeDefInfo.Tuple]: tsTuple, - [TypeDefInfo.Vector]: tsVector, - [TypeDefInfo.VectorFixed]: tsVector -}; - function setImports ({ codecTypes, otherTypes, ownTypes }: TypeImports, type: string | null, codecType: string | null): void { if (type && !ownTypes.includes(type) && !otherTypes[type]) { otherTypes[type] = true; @@ -49,6 +32,7 @@ function setImports ({ codecTypes, otherTypes, ownTypes }: TypeImports, type: st } } +// eslint-disable-next-line @typescript-eslint/no-unused-vars function errorUnhandled (def: TypeDef, imports: TypeImports): string { throw new Error(`Generate: ${name}: Unhandled type ${TypeDefInfo[def.info]}`); } @@ -56,7 +40,7 @@ function errorUnhandled (def: TypeDef, imports: TypeImports): string { function tsEnum ({ name: enumName, sub }: TypeDef, imports: TypeImports): string { setImports(imports, null, 'Enum'); - const keys = (sub as Array).map(({ info, name, type }, index) => { + const keys = (sub as TypeDef[]).map(({ info, name, type }, index): string => { const [enumType, asGetter] = type === 'Null' ? ['', ''] : [`(${type})`, ` readonly as${name}: ${type};\n`]; @@ -95,7 +79,7 @@ function _tsStructGetterType (structName: string | undefined, { info, sub, type } function tsStruct ({ name: structName, sub }: TypeDef, imports: TypeImports): string { - const keys = (sub as Array).map((typedef) => { + const keys = (sub as TypeDef[]).map((typedef): string => { const [embedType, returnType] = _tsStructGetterType(structName, typedef); setImports(imports, embedType, 'Struct'); @@ -107,7 +91,7 @@ function tsStruct ({ name: structName, sub }: TypeDef, imports: TypeImports): st } function tsTuple ({ name: tupleName, sub }: TypeDef, imports: TypeImports): string { - const types = (sub as Array).map(({ type }) => { + const types = (sub as TypeDef[]).map(({ type }): string => { setImports(imports, type, 'Tuple'); return type; @@ -127,20 +111,37 @@ function tsVector ({ ext, info, name: vectorName, sub }: TypeDef, imports: TypeI return `export interface ${vectorName} extends Vector<${type}> {}`; } -function generateTsDef (srmlName: string, { types }: { types: { [index: string]: any } }): void { +function generateTsDef (srmlName: string, { types }: { types: Record }): void { + // handlers are defined externally to use - this means that when we do a + // `generators[typedef.info](...)` TS will show any unhandled types. Rather + // we are being explicit in having no handlers where we do not support (yet) + const generators = { + [TypeDefInfo.Compact]: errorUnhandled, + [TypeDefInfo.DoubleMap]: errorUnhandled, + [TypeDefInfo.Enum]: tsEnum, + [TypeDefInfo.Linkage]: errorUnhandled, + [TypeDefInfo.Null]: errorUnhandled, + [TypeDefInfo.Option]: errorUnhandled, + [TypeDefInfo.Plain]: tsPlain, + [TypeDefInfo.Struct]: tsStruct, + [TypeDefInfo.Tuple]: tsTuple, + [TypeDefInfo.Vector]: tsVector, + [TypeDefInfo.VectorFixed]: tsVector + }; + const codecTypes: TypeExist = {}; const otherTypes: TypeExist = {}; const ownTypes = Object.keys(types); - const interfaces = Object.entries(types).map(([name, type]) => { + const interfaces = Object.entries(types).map(([name, type]): [string, string] => { const def = getTypeDef(isString(type) ? type.toString() : JSON.stringify(type), name); return [name, generators[def.info](def, { codecTypes, otherTypes, ownTypes })]; }); let header = HEADER; - const codecImports = Object.keys(codecTypes).filter((name) => name !== 'Tuple').sort(); - const primitiveImports = Object.keys(otherTypes).filter((type) => otherTypes[type]).sort(); - const sortedDefs = interfaces.sort((a, b) => a[0].localeCompare(b[0])).map(([, definition]) => definition); + const codecImports = Object.keys(codecTypes).filter((name): boolean => name !== 'Tuple').sort(); + const primitiveImports = Object.keys(otherTypes).filter((type): boolean => otherTypes[type]).sort(); + const sortedDefs = interfaces.sort((a, b): number => a[0].localeCompare(b[0])).map(([, definition]): string => definition); if (codecTypes['Tuple']) { header = header.concat(`import { Codec } from '../../types';\n`); @@ -157,6 +158,6 @@ function generateTsDef (srmlName: string, { types }: { types: { [index: string]: fs.writeFileSync(`packages/types/src/srml/${srmlName}/types.ts`, header.concat('\n').concat(sortedDefs.join('\n\n')).concat(FOOTER), { flag: 'w' }); } -Object.entries(definitions).forEach(([name, obj]) => +Object.entries(definitions).forEach(([name, obj]): void => generateTsDef(name, obj) ); diff --git a/packages/types/src/srml/parachains/types.ts b/packages/types/src/srml/parachains/types.ts index b5b45daeb4..a1569e9fe3 100644 --- a/packages/types/src/srml/parachains/types.ts +++ b/packages/types/src/srml/parachains/types.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-empty-interface */ // Auto-generated, do not edit import { Codec } from '../../types'; diff --git a/packages/types/src/type/BalanceLock.ts b/packages/types/src/type/BalanceLock.ts index fbbfd5445f..8944e55ba5 100644 --- a/packages/types/src/type/BalanceLock.ts +++ b/packages/types/src/type/BalanceLock.ts @@ -14,7 +14,7 @@ import WithdrawReasons from './WithdrawReasons'; * The Substrate BalanceLock for staking */ export default class BalanceLock extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ id: LockIdentifier, amount: Balance, @@ -26,28 +26,28 @@ export default class BalanceLock extends Struct { /** * @description The amount */ - get amount (): Balance { + public get amount (): Balance { return this.get('amount') as Balance; } /** * @description The lock id */ - get id (): LockIdentifier { + public get id (): LockIdentifier { return this.get('id') as LockIdentifier; } /** * @description The reasons */ - get reasons (): WithdrawReasons { + public get reasons (): WithdrawReasons { return this.get('reasons') as WithdrawReasons; } /** * @description Until when this is available */ - get until (): BlockNumber { + public get until (): BlockNumber { return this.get('until') as BlockNumber; } } diff --git a/packages/types/src/type/Bft.spec.ts b/packages/types/src/type/Bft.spec.ts index 8a9936c44c..58992c0786 100644 --- a/packages/types/src/type/Bft.spec.ts +++ b/packages/types/src/type/Bft.spec.ts @@ -4,32 +4,32 @@ import { BftAuthoritySignature, BftHashSignature } from './Bft'; -describe('BftAuthoritySignature', () => { +describe('BftAuthoritySignature', (): void => { const sig = new BftAuthoritySignature([ '0x12344321', '0x567890098765' ]); - it('has the correct authorityId', () => { + it('has the correct authorityId', (): void => { expect(sig.authorityId.toHex()).toEqual('0x1234432100000000000000000000000000000000000000000000000000000000'); }); - it('has the correct signature', () => { + it('has the correct signature', (): void => { expect(sig.signature.toHex()).toEqual('0x56789009876500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); }); }); -describe('BftHashSignature', () => { +describe('BftHashSignature', (): void => { const sig = new BftHashSignature([ '0x12344321', '0x567890098765' ]); - it('has the correct hash', () => { + it('has the correct hash', (): void => { expect(sig.hash.toHex()).toEqual('0x1234432100000000000000000000000000000000000000000000000000000000'); }); - it('has the correct signature', () => { + it('has the correct signature', (): void => { expect(sig.signature.toHex()).toEqual('0x56789009876500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); }); }); diff --git a/packages/types/src/type/Bft.ts b/packages/types/src/type/Bft.ts index 3e35eca815..92bf6d9131 100644 --- a/packages/types/src/type/Bft.ts +++ b/packages/types/src/type/Bft.ts @@ -18,7 +18,7 @@ export type BftAuthoritySignatureValue = [AnyU8a, AnyU8a]; * network behaviour. */ export class BftAuthoritySignature extends Tuple { - constructor (value?: BftAuthoritySignatureValue | Uint8Array) { + public constructor (value?: BftAuthoritySignatureValue | Uint8Array) { super({ AuthorityId, Signature @@ -28,14 +28,14 @@ export class BftAuthoritySignature extends Tuple { /** * @description The wrapped [[AuthoriyId]] */ - get authorityId (): AuthorityId { + public get authorityId (): AuthorityId { return this[0] as AuthorityId; } /** * @description The wrapped [[Signature]] value */ - get signature (): Signature { + public get signature (): Signature { return this[1] as Signature; } } @@ -49,7 +49,7 @@ export type BftHashSignatureValue = [AnyU8a, AnyU8a]; * network behaviour. */ export class BftHashSignature extends Tuple { - constructor (value?: BftHashSignatureValue | Uint8Array) { + public constructor (value?: BftHashSignatureValue | Uint8Array) { super({ Hash, Signature @@ -59,14 +59,14 @@ export class BftHashSignature extends Tuple { /** * @description The wrapped [[Hash]] */ - get hash (): Hash { + public get hash (): Hash { return this[0] as Hash; } /** * @description The wrapped [[Signature]] */ - get signature (): Signature { + public get signature (): Signature { return this[1] as Signature; } } diff --git a/packages/types/src/type/ContractInfo.ts b/packages/types/src/type/ContractInfo.ts index 74682eaba0..d7745c0ec8 100644 --- a/packages/types/src/type/ContractInfo.ts +++ b/packages/types/src/type/ContractInfo.ts @@ -18,7 +18,7 @@ export class TrieId extends Bytes { } export class AliveContractInfo extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ trieId: TrieId, storageSize: U32, @@ -29,27 +29,27 @@ export class AliveContractInfo extends Struct { }, value); } - get codeHash (): CodeHash { + public get codeHash (): CodeHash { return this.get('codeHash') as CodeHash; } - get deductBlock (): BlockNumber { + public get deductBlock (): BlockNumber { return this.get('deductBlock') as BlockNumber; } - get lastWrite (): Option { + public get lastWrite (): Option { return this.get('lastWrite') as Option; } - get rentAllowance (): Balance { + public get rentAllowance (): Balance { return this.get('rentAllowance') as Balance; } - get storageSize (): U32 { + public get storageSize (): U32 { return this.get('storageSize') as U32; } - get trieId (): TrieId { + public get trieId (): TrieId { return this.get('trieId') as TrieId; } } @@ -69,7 +69,7 @@ export class Tombstone extends TombstoneContractInfo { * The contract information for a given contract */ export default class ContractInfo extends Enum { - constructor (value?: any) { + public constructor (value?: any) { super({ Alive, Tombstone @@ -79,7 +79,7 @@ export default class ContractInfo extends Enum { /** * @description Returns the item as an [[Alive]] */ - get asAlive (): Alive { + public get asAlive (): Alive { assert(this.isAlive, `Cannot convert '${this.type}' via asAlive`); return this.value as Alive; @@ -88,7 +88,7 @@ export default class ContractInfo extends Enum { /** * @description Returns the item as an [[Tombstone]] */ - get asTombstone (): Tombstone { + public get asTombstone (): Tombstone { assert(this.isTombstone, `Cannot convert '${this.type}' via asTombstone`); return this.value as Tombstone; @@ -97,14 +97,14 @@ export default class ContractInfo extends Enum { /** * @description value is an [[Alive]] */ - get isAlive (): boolean { + public get isAlive (): boolean { return this.toNumber() === 0; } /** * @description value is an [[Tombstone]] */ - get isTombstone (): boolean { + public get isTombstone (): boolean { return this.toNumber() === 1; } } diff --git a/packages/types/src/type/ContractStorageKey.ts b/packages/types/src/type/ContractStorageKey.ts index 774fe03e19..fcfad9ae58 100644 --- a/packages/types/src/type/ContractStorageKey.ts +++ b/packages/types/src/type/ContractStorageKey.ts @@ -12,14 +12,14 @@ import U8aFixed from '../codec/U8aFixed'; * A [u8; 32] representing a storeage key in contracts */ export default class ContractStorageKey extends U8aFixed { - constructor (value?: AnyU8a) { + public constructor (value?: AnyU8a) { super(value, 256); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return '[u8; 32]'; } } diff --git a/packages/types/src/type/Conviction.ts b/packages/types/src/type/Conviction.ts index 619eb6d23c..564aeeb890 100644 --- a/packages/types/src/type/Conviction.ts +++ b/packages/types/src/type/Conviction.ts @@ -10,7 +10,7 @@ import Enum from '../codec/Enum'; * A value denoting the strength of conviction of a vote. */ export default class Conviction extends Enum { - constructor (value: any) { + public constructor (value: any) { super([ // 0.1x votes, unlocked. 'None', diff --git a/packages/types/src/type/Exposure.ts b/packages/types/src/type/Exposure.ts index 989d7c4da9..e6386f7608 100644 --- a/packages/types/src/type/Exposure.ts +++ b/packages/types/src/type/Exposure.ts @@ -14,7 +14,7 @@ import IndividualExposure from './IndividualExposure'; * A snapshot of the stake backing a single validator in the system */ export default class Exposure extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ total: Compact.with(Balance), own: Compact.with(Balance), @@ -25,21 +25,21 @@ export default class Exposure extends Struct { /** * @description The validator's own stash that is exposed */ - get own (): Balance { + public get own (): Balance { return (this.get('own') as Compact).toBn() as Balance; } /** * @description The total balance backing this validator */ - get total (): Balance { + public get total (): Balance { return (this.get('total') as Compact).toBn() as Balance; } /** * @description The portions of nominators stashes that are exposed */ - get others (): Vector { + public get others (): Vector { return this.get('others') as Vector; } } diff --git a/packages/types/src/type/Extrinsic.spec.ts b/packages/types/src/type/Extrinsic.spec.ts index 3c397a9728..23e99bdf32 100644 --- a/packages/types/src/type/Extrinsic.spec.ts +++ b/packages/types/src/type/Extrinsic.spec.ts @@ -7,12 +7,12 @@ import extrinsics from '@polkadot/api-metadata/extrinsics/static'; import Method from '../primitive/Method'; import Extrinsic from './Extrinsic'; -describe('Extrinsic', () => { - beforeAll(() => { +describe('Extrinsic', (): void => { + beforeAll((): void => { Method.injectMethods(extrinsics); }); - it.skip('decodes a non-signed properly via JSON', () => { + it.skip('decodes a non-signed properly via JSON', (): void => { const extrinsic = new Extrinsic('0x010300ea51b75b00000000'); expect(extrinsic.isSigned).toEqual(false); @@ -20,7 +20,7 @@ describe('Extrinsic', () => { expect(extrinsic.data).toEqual(new Uint8Array([234, 81, 183, 91, 0, 0, 0, 0])); }); - it('decodes an actual transaction (new format)', () => { + it('decodes an actual transaction (new format)', (): void => { const extrinsic = new Extrinsic('0x250281ffbfc823aa75c30058eeec21abe2c2d6b7247418a4af89d67a2084c2ac864da080c0aa4df3b4926c3cd78bbdced31d8bdccb8604b779b71b90e58b2848df4a9ad6b0aa1aae6be7a05c9413a172b0325e4d214e5ff2b25098028b30f1a50be9c90e0c00' + '0500' + // balances.transfer 'ff4a83f1c09be797bc3d9adce29818368b276a84e6b545ced492c25c948978d7f8e5c0'); @@ -35,7 +35,7 @@ describe('Extrinsic', () => { expect(extrinsic.args[0].toString()).toEqual('5DkQbYAExs3M2sZgT1Ec3mKfZnAQCL4Dt9beTCknkCUn5jzo'); }); - it('decodes an actual transaction (old format)', () => { + it('decodes an actual transaction (old format)', (): void => { const extrinsic = new Extrinsic( '0x81ffbfc823aa75c30058eeec21abe2c2d6b7247418a4af89d67a2084c2ac864da080c0aa4df3b4926c3cd78bbdced31d8bdccb8604b779b71b90e58b2848df4a9ad6b0aa1aae6be7a05c9413a172b0325e4d214e5ff2b25098028b30f1a50be9c90e0c00' + '0500' + // balances.transfer diff --git a/packages/types/src/type/Extrinsic.ts b/packages/types/src/type/Extrinsic.ts index 78efcde0c0..11d80d4525 100644 --- a/packages/types/src/type/Extrinsic.ts +++ b/packages/types/src/type/Extrinsic.ts @@ -32,11 +32,11 @@ const UNMASK_VERSION = 0b01111111; * - left as is, to create an inherent */ export default class Extrinsic extends Base implements IExtrinsic, Codec { - constructor (value?: ExtrinsicValue | AnyU8a | Method) { + public constructor (value?: ExtrinsicValue | AnyU8a | Method) { super(Extrinsic.decodeExtrinsic(value)); } - static decodeExtrinsic (value?: ExtrinsicValue | AnyU8a | Method): ExtrinsicV1 { + public static decodeExtrinsic (value?: ExtrinsicValue | AnyU8a | Method): ExtrinsicV1 { if (Array.isArray(value) || isHex(value)) { // Instead of the block below, it should simply be: // return Extrinsic.decodeExtrinsic(hexToU8a(value as string)); @@ -72,7 +72,7 @@ export default class Extrinsic extends Base implements IExtrinsic, return new ExtrinsicV1(value); } - static decodeU8a (value: Uint8Array): ExtrinsicV1 { + public static decodeU8a (value: Uint8Array): ExtrinsicV1 { // decode the actual version string const version = value[0] & UNMASK_VERSION; @@ -88,98 +88,98 @@ export default class Extrinsic extends Base implements IExtrinsic, /** * @description The arguments passed to for the call, exposes args so it is compatible with [[Method]] */ - get args (): Array { + public get args (): Codec[] { return this.method.args; } /** * @description Thge argument defintions, compatible with [[Method]] */ - get argsDef (): ArgsDef { + public get argsDef (): ArgsDef { return this.method.argsDef; } /** * @description The actual `[sectionIndex, methodIndex]` as used in the Method */ - get callIndex (): Uint8Array { + public get callIndex (): Uint8Array { return this.method.callIndex; } /** * @description The actual data for the Method */ - get data (): Uint8Array { + public get data (): Uint8Array { return this.method.data; } /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { return this.raw.encodedLength; } /** * @description Convernience function, encodes the extrinsic and returns the actual hash */ - get hash (): Hash { + public get hash (): Hash { return this.raw.hash; } /** * @description `true` is method has `Origin` argument (compatibility with [[Method]]) */ - get hasOrigin (): boolean { + public get hasOrigin (): boolean { return this.raw.hasOrigin; } /** * @description Checks if the value is an empty value */ - get isEmpty (): boolean { + public get isEmpty (): boolean { return this.raw.isEmpty; } /** * @description `true` id the extrinsic is signed */ - get isSigned (): boolean { + public get isSigned (): boolean { return this.raw.isSigned; } /** * @description The length of the encoded value */ - get length (): number { + public get length (): number { return this.raw.length; } /** * @description The [[FunctionMetadata]] that describes the extrinsic */ - get meta (): FunctionMetadata { + public get meta (): FunctionMetadata { return this.raw.meta; } /** * @description The [[Method]] this extrinsic wraps */ - get method (): Method { + public get method (): Method { return this.raw.method; } /** * @description The [[ExtrinsicSignature]] */ - get signature (): ExtrinsicSignature { + public get signature (): ExtrinsicSignature { return this.raw.signature; } /** * @description Add an [[ExtrinsicSignature]] to the extrinsic (already generated) */ - addSignature (signer: Address | Uint8Array | string, signature: Uint8Array | string, nonce: AnyNumber, era?: Uint8Array): Extrinsic { + public addSignature (signer: Address | Uint8Array | string, signature: Uint8Array | string, nonce: AnyNumber, era?: Uint8Array): Extrinsic { this.raw.addSignature(signer, signature, nonce, era); return this; @@ -188,7 +188,7 @@ export default class Extrinsic extends Base implements IExtrinsic, /** * @description Sign the extrinsic with a specific keypair */ - sign (account: IKeyringPair, options: SignatureOptions): Extrinsic { + public sign (account: IKeyringPair, options: SignatureOptions): Extrinsic { this.raw.sign(account, options); return this; @@ -197,35 +197,35 @@ export default class Extrinsic extends Base implements IExtrinsic, /** * @description Compares the value of the input to see if there is a match */ - eq (other?: any): boolean { + public eq (other?: any): boolean { return this.raw.eq(other); } /** * @description Returns a hex string representation of the value */ - toHex (): string { + public toHex (): string { return this.raw.toHex(); } /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): string { + public toJSON (): string { return this.raw.toJSON(); } /** * @description Returns the string representation of the value */ - toString (): string { + public toString (): string { return this.raw.toString(); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { return 'Extrinsic'; } @@ -233,7 +233,7 @@ export default class Extrinsic extends Base implements IExtrinsic, * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + public toU8a (isBare?: boolean): Uint8Array { return this.raw.toU8a(isBare); } } diff --git a/packages/types/src/type/ExtrinsicEra.spec.ts b/packages/types/src/type/ExtrinsicEra.spec.ts index 663b087439..d4cfc2b43a 100644 --- a/packages/types/src/type/ExtrinsicEra.spec.ts +++ b/packages/types/src/type/ExtrinsicEra.spec.ts @@ -4,29 +4,29 @@ import ExtrinsicEra from './ExtrinsicEra'; -describe('ExtrinsicEra', () => { - it('decodes an Extrinsic Era with immortal', () => { +describe('ExtrinsicEra', (): void => { + it('decodes an Extrinsic Era with immortal', (): void => { const extrinsicEra = new ExtrinsicEra(new Uint8Array([0])); expect(extrinsicEra.asImmortalEra).toBeDefined(); expect(extrinsicEra.toJSON()).toEqual({ ImmortalEra: '0x00' }); }); - it('decodes an Extrinsic Era from u8 as mortal', () => { + it('decodes an Extrinsic Era from u8 as mortal', (): void => { const extrinsicEra = new ExtrinsicEra(new Uint8Array([78, 156])); expect(extrinsicEra.asMortalEra.period.toNumber()).toEqual(32768); expect(extrinsicEra.asMortalEra.phase.toNumber()).toEqual(20000); }); - it('encode an Extrinsic Era from Object with blocknumber & period as mortal instance', () => { + it('encode an Extrinsic Era from Object with blocknumber & period as mortal instance', (): void => { const extrinsicEra = new ExtrinsicEra({ current: 1400, period: 200 }); expect(extrinsicEra.asMortalEra.period.toNumber()).toEqual(256); expect(extrinsicEra.asMortalEra.phase.toNumber()).toEqual(120); }); - it('serializes and de-serializes from JSON', () => { + it('serializes and de-serializes from JSON', (): void => { const extrinsicEra = new ExtrinsicEra(new Uint8Array([78, 156])); const u8a = extrinsicEra.toU8a(); const json = extrinsicEra.toJSON(); diff --git a/packages/types/src/type/ExtrinsicEra.ts b/packages/types/src/type/ExtrinsicEra.ts index 5c38f5ad6b..e44de64571 100644 --- a/packages/types/src/type/ExtrinsicEra.ts +++ b/packages/types/src/type/ExtrinsicEra.ts @@ -29,105 +29,14 @@ interface ImmortalEnumDef { const VALID_IMMORTAL = new U8a([0]); -/** - * @name ExtrinsicEra - * @description - * The era for an extrinsic, indicating either a mortal or immortal extrinsic - */ -export default class ExtrinsicEra extends Enum implements IExtrinsicEra { - constructor (value?: any) { - super({ - ImmortalEra, - MortalEra - }, ExtrinsicEra.decodeExtrinsicEra(value)); - } - - private static decodeExtrinsicEra (value: MortalMethod | MortalEnumDef | ImmortalEnumDef | Uint8Array | string = new Uint8Array()): Uint8Array | Object | undefined { - if (isHex(value)) { - return ExtrinsicEra.decodeExtrinsicEra(hexToU8a(value)); - } else if (isU8a(value)) { - if (!value.length || value[0] === 0) { - return new Uint8Array([0, 0]); - } else { - return new Uint8Array([1, value[0], value[1]]); - } - } else if (isObject(value)) { - // this is to de-serialize from JSON - if ((value as MortalEnumDef).MortalEra) { - return { MortalEra: (value as MortalEnumDef).MortalEra }; - } else if ((value as ImmortalEnumDef).ImmortalEra) { - return { ImmortalEra: (value as ImmortalEnumDef).ImmortalEra }; - } - - return { MortalEra: value }; - } - - throw new Error('Invalid data passed to Era'); - } - - /** - * @description Overide the encoded length method - */ - get encodedLength (): number { - if (this.index === 0) { - return this.asImmortalEra.encodedLength; - } else { - return this.asMortalEra.encodedLength; - } - } - - /** - * @description Returns the item as a [[ImmortalEra]] - */ - get asImmortalEra (): ImmortalEra { - assert(this.isImmortalEra, `Cannot convert '${this.type}' via asImmortalEra`); - - return this.value as ImmortalEra; - } - - /** - * @description Returns the item as a [[MortalEra]] - */ - get asMortalEra (): MortalEra { - assert(this.isMortalEra, `Cannot convert '${this.type}' via asMortalEra`); - - return this.value as MortalEra; - } - - /** - * @description `true` if Immortal - */ - get isImmortalEra (): boolean { - return this.index === 0; - } - - /** - * @description `true` if Mortal - */ - get isMortalEra (): boolean { - return this.index > 0; - } - - /** - * @description Encodes the value as a Uint8Array as per the parity-codec specifications - * @param isBare true when the value has none of the type-specific prefixes (internal) - */ - toU8a (isBare?: boolean): Uint8Array { - if (this.index === 0) { - return this.asImmortalEra.toU8a(isBare); - } else { - return this.asMortalEra.toU8a(isBare); - } - } -} - /** * @name ImmortalEra * @description * The ImmortalEra for an extrinsic */ export class ImmortalEra extends U8a { - constructor (value?: AnyU8a) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public constructor (value?: AnyU8a) { // For immortals, we always provide the known value (i.e. treated as a // constant no matter how it is constructed - it is a fixed structure) super(VALID_IMMORTAL); @@ -140,7 +49,7 @@ export class ImmortalEra extends U8a { * The MortalEra for an extrinsic, indicating period and phase */ export class MortalEra extends Tuple { - constructor (value?: MortalMethod | Uint8Array | number[] | string) { + public constructor (value?: MortalMethod | Uint8Array | number[] | string) { super({ period: U64, phase: U64 @@ -182,28 +91,28 @@ export class MortalEra extends Tuple { /** * @description Encoded length for mortals occupy 2 bytes, different from the actual Tuple since it is encoded. This is a shortcut fro `toU8a().length` */ - get encodedLength (): number { + public get encodedLength (): number { return 2; } /** * @description The period of this Mortal wraps as a [[U64]] */ - get period (): U64 { + public get period (): U64 { return this[0] as U64; } /** * @description The phase of this Mortal wraps as a [[U64]] */ - get phase (): U64 { + public get phase (): U64 { return this[1] as U64; } /** * @description Returns a JSON representation of the actual value */ - toJSON (): any { + public toJSON (): any { return this.toHex(); } @@ -217,7 +126,8 @@ export class MortalEra extends Tuple { * greater than 1 << 12, then it will be a factor of the times greater than 1<<12 that * `period` is. */ - toU8a (isBare?: boolean): Uint8Array { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public toU8a (isBare?: boolean): Uint8Array { const period = this.period.toNumber(); const phase = this.phase.toNumber(); const quantizeFactor = Math.max(period >> 12, 1); @@ -232,7 +142,7 @@ export class MortalEra extends Tuple { /** * @description Get the block number of the start of the era whose properties this object describes that `current` belongs to. */ - birth (current: BN | number) { + public birth (current: BN | number): number { // FIXME No toNumber() here return Math.floor( ( @@ -244,7 +154,7 @@ export class MortalEra extends Tuple { /** * @description Get the block number of the first block at which the era has ended. */ - death (current: BN | number) { + public death (current: BN | number): number { // FIXME No toNumber() here return this.birth(current) + this.period.toNumber(); } @@ -252,7 +162,7 @@ export class MortalEra extends Tuple { /** * @description convert the number to binary and get the trailing zero's. */ - private getTrailingZeros (period: number) { + private getTrailingZeros (period: number): number { const binary = period.toString(2); let index = 0; @@ -263,3 +173,96 @@ export class MortalEra extends Tuple { return index; } } + +/** + * @name ExtrinsicEra + * @description + * The era for an extrinsic, indicating either a mortal or immortal extrinsic + */ +export default class ExtrinsicEra extends Enum implements IExtrinsicEra { + public constructor (value?: any) { + super({ + ImmortalEra, + MortalEra + }, ExtrinsicEra.decodeExtrinsicEra(value)); + } + + // eslint-disable-next-line @typescript-eslint/ban-types + private static decodeExtrinsicEra (value: MortalMethod | MortalEnumDef | ImmortalEnumDef | Uint8Array | string = new Uint8Array()): Uint8Array | Object | undefined { + if (isHex(value)) { + return ExtrinsicEra.decodeExtrinsicEra(hexToU8a(value)); + } else if (isU8a(value)) { + if (!value.length || value[0] === 0) { + return new Uint8Array([0, 0]); + } else { + return new Uint8Array([1, value[0], value[1]]); + } + } else if (isObject(value)) { + // this is to de-serialize from JSON + if ((value as MortalEnumDef).MortalEra) { + return { MortalEra: (value as MortalEnumDef).MortalEra }; + } else if ((value as ImmortalEnumDef).ImmortalEra) { + return { ImmortalEra: (value as ImmortalEnumDef).ImmortalEra }; + } + + return { MortalEra: value }; + } + + throw new Error('Invalid data passed to Era'); + } + + /** + * @description Overide the encoded length method + */ + public get encodedLength (): number { + if (this.index === 0) { + return this.asImmortalEra.encodedLength; + } else { + return this.asMortalEra.encodedLength; + } + } + + /** + * @description Returns the item as a [[ImmortalEra]] + */ + public get asImmortalEra (): ImmortalEra { + assert(this.isImmortalEra, `Cannot convert '${this.type}' via asImmortalEra`); + + return this.value as ImmortalEra; + } + + /** + * @description Returns the item as a [[MortalEra]] + */ + public get asMortalEra (): MortalEra { + assert(this.isMortalEra, `Cannot convert '${this.type}' via asMortalEra`); + + return this.value as MortalEra; + } + + /** + * @description `true` if Immortal + */ + public get isImmortalEra (): boolean { + return this.index === 0; + } + + /** + * @description `true` if Mortal + */ + public get isMortalEra (): boolean { + return this.index > 0; + } + + /** + * @description Encodes the value as a Uint8Array as per the parity-codec specifications + * @param isBare true when the value has none of the type-specific prefixes (internal) + */ + public toU8a (isBare?: boolean): Uint8Array { + if (this.index === 0) { + return this.asImmortalEra.toU8a(isBare); + } else { + return this.asMortalEra.toU8a(isBare); + } + } +} diff --git a/packages/types/src/type/ExtrinsicSignature.ts b/packages/types/src/type/ExtrinsicSignature.ts index d08abacae4..61d0bc94f1 100644 --- a/packages/types/src/type/ExtrinsicSignature.ts +++ b/packages/types/src/type/ExtrinsicSignature.ts @@ -32,7 +32,7 @@ export default class ExtrinsicSignature extends Struct implements IExtrinsicSign // 64 bytes: The sr25519/ed25519 signature of the Signing Payload // 1-8 bytes: The Compact of the signing account // 1/2 bytes: The Transaction Era - constructor (value?: Uint8Array) { + public constructor (value?: Uint8Array) { super({ version: U8, signer: Address, @@ -42,7 +42,7 @@ export default class ExtrinsicSignature extends Struct implements IExtrinsicSign }, ExtrinsicSignature.decodeExtrinsicSignature(value)); } - static decodeExtrinsicSignature (value?: Uint8Array): object | Uint8Array { + public static decodeExtrinsicSignature (value?: Uint8Array): object | Uint8Array { if (!value) { return { // we always explicitly set the unsigned version @@ -62,7 +62,7 @@ export default class ExtrinsicSignature extends Struct implements IExtrinsicSign /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { return this.isSigned ? super.encodedLength : 1; @@ -71,42 +71,49 @@ export default class ExtrinsicSignature extends Struct implements IExtrinsicSign /** * @description `true` if the signature is valid */ - get isSigned (): boolean { + public get isSigned (): boolean { return (this.version & BIT_SIGNED) === BIT_SIGNED; } /** * @description The [[ExtrinsicEra]] (mortal or immortal) this signature applies to */ - get era (): ExtrinsicEra { + public get era (): ExtrinsicEra { return this.get('era') as ExtrinsicEra; } + /** + * @description The [[ExtrinsicEra]] (mortal or immortal) this signature applies to + */ + public set era (era: ExtrinsicEra) { + this.set('era', era); + } + /** * @description The [[Nonce]] for the signature */ - get nonce (): Nonce { + public get nonce (): Nonce { return this.get('nonce') as Nonce; } /** * @description The actuall [[Signature]] hash */ - get signature (): Signature { + public get signature (): Signature { return this.get('signature') as Signature; } /** * @description The [[Address]] that signed */ - get signer (): Address { + public get signer (): Address { return this.get('signer') as Address; } /** * @description The encoded version for the signature */ - get version (): number { + public get version (): number { // Version Information. // 1 byte: version information: // - 7 low bits: version identifier (should be 0b0000001). @@ -114,13 +121,6 @@ export default class ExtrinsicSignature extends Struct implements IExtrinsicSign return (this.get('version') as U8).toNumber(); } - /** - * @description The [[ExtrinsicEra]] (mortal or immortal) this signature applies to - */ - set era (era: ExtrinsicEra) { - this.set('era', era); - } - private injectSignature (signature: Signature, signer: Address, nonce: Nonce, era: ExtrinsicEra): ExtrinsicSignature { this.set('era', era); this.set('nonce', nonce); @@ -134,7 +134,7 @@ export default class ExtrinsicSignature extends Struct implements IExtrinsicSign /** * @description Adds a raw signature */ - addSignature (_signer: Address | Uint8Array | string, _signature: Uint8Array | string, _nonce: AnyNumber, _era: Uint8Array | ExtrinsicEra = IMMORTAL_ERA): ExtrinsicSignature { + public addSignature (_signer: Address | Uint8Array | string, _signature: Uint8Array | string, _nonce: AnyNumber, _era: Uint8Array | ExtrinsicEra = IMMORTAL_ERA): ExtrinsicSignature { const signer = new Address(_signer); const nonce = new Nonce(_nonce); const era = new ExtrinsicEra(_era); @@ -146,7 +146,7 @@ export default class ExtrinsicSignature extends Struct implements IExtrinsicSign /** * @description Generate a payload and pplies the signature from a keypair */ - sign (method: Method, account: IKeyringPair, { blockHash, era, nonce, version }: SignatureOptions): ExtrinsicSignature { + public sign (method: Method, account: IKeyringPair, { blockHash, era, nonce, version }: SignatureOptions): ExtrinsicSignature { const signer = new Address(account.publicKey); const signingPayload = new SignaturePayload({ nonce, @@ -163,7 +163,7 @@ export default class ExtrinsicSignature extends Struct implements IExtrinsicSign * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + public toU8a (isBare?: boolean): Uint8Array { return this.isSigned ? super.toU8a(isBare) : new Uint8Array([this.version]); diff --git a/packages/types/src/type/ExtrinsicV1.ts b/packages/types/src/type/ExtrinsicV1.ts index b074bad702..49c212f62a 100644 --- a/packages/types/src/type/ExtrinsicV1.ts +++ b/packages/types/src/type/ExtrinsicV1.ts @@ -15,10 +15,10 @@ import Address from '../primitive/Address'; import Hash from '../primitive/Hash'; import ExtrinsicSignature from './ExtrinsicSignature'; -export type ExtrinsicValueV1 = { - method?: Method - signature?: ExtrinsicSignature -}; +export interface ExtrinsicValueV1 { + method?: Method; + signature?: ExtrinsicSignature; +} /** * @name ExtrinsicV1 @@ -26,7 +26,7 @@ export type ExtrinsicValueV1 = { * The first generation of compact extrinsics */ export default class ExtrinsicV1 extends Struct implements IExtrinsic { - constructor (value?: Uint8Array | ExtrinsicValueV1) { + public constructor (value?: Uint8Array | ExtrinsicValueV1) { super({ signature: ExtrinsicSignature, method: Method @@ -36,35 +36,35 @@ export default class ExtrinsicV1 extends Struct implements IExtrinsic { /** * @description The arguments passed to for the call, exposes args so it is compatible with [[Method]] */ - get args (): Array { + public get args (): Codec[] { return this.method.args; } /** * @description Thge argument defintions, compatible with [[Method]] */ - get argsDef (): ArgsDef { + public get argsDef (): ArgsDef { return this.method.argsDef; } /** * @description The actual `[sectionIndex, methodIndex]` as used in the Method */ - get callIndex (): Uint8Array { + public get callIndex (): Uint8Array { return this.method.callIndex; } /** * @description The actual data for the Method */ - get data (): Uint8Array { + public get data (): Uint8Array { return this.method.data; } /** * @description The length of the value when encoded as a Uint8Array */ - get encodedLength (): number { + public get encodedLength (): number { const length = this.length; return length + Compact.encodeU8a(length).length; @@ -73,7 +73,7 @@ export default class ExtrinsicV1 extends Struct implements IExtrinsic { /** * @description Convernience function, encodes the extrinsic and returns the actual hash */ - get hash (): Hash { + public get hash (): Hash { return new Hash( blake2AsU8a(this.toU8a(), 256) ); @@ -82,49 +82,49 @@ export default class ExtrinsicV1 extends Struct implements IExtrinsic { /** * @description `true` is method has `Origin` argument (compatibility with [[Method]]) */ - get hasOrigin (): boolean { + public get hasOrigin (): boolean { return this.method.hasOrigin; } /** * @description `true` id the extrinsic is signed */ - get isSigned (): boolean { + public get isSigned (): boolean { return this.signature.isSigned; } /** * @description The length of the encoded value */ - get length (): number { + public get length (): number { return this.toU8a(true).length; } /** * @description The [[FunctionMetadata]] that describes the extrinsic */ - get meta (): FunctionMetadata { + public get meta (): FunctionMetadata { return this.method.meta; } /** * @description The [[Method]] this extrinsic wraps */ - get method (): Method { + public get method (): Method { return this.get('method') as Method; } /** * @description The [[ExtrinsicSignature]] */ - get signature (): ExtrinsicSignature { + public get signature (): ExtrinsicSignature { return this.get('signature') as ExtrinsicSignature; } /** * @description Add an [[ExtrinsicSignature]] to the extrinsic (already generated) */ - addSignature (signer: Address | Uint8Array | string, signature: Uint8Array | string, nonce: AnyNumber, era?: Uint8Array): ExtrinsicV1 { + public addSignature (signer: Address | Uint8Array | string, signature: Uint8Array | string, nonce: AnyNumber, era?: Uint8Array): ExtrinsicV1 { this.signature.addSignature(signer, signature, nonce, era); return this; @@ -133,7 +133,7 @@ export default class ExtrinsicV1 extends Struct implements IExtrinsic { /** * @description Sign the extrinsic with a specific keypair */ - sign (account: IKeyringPair, options: SignatureOptions): ExtrinsicV1 { + public sign (account: IKeyringPair, options: SignatureOptions): ExtrinsicV1 { this.signature.sign(this.method, account, options); return this; @@ -142,21 +142,21 @@ export default class ExtrinsicV1 extends Struct implements IExtrinsic { /** * @description Returns a hex string representation of the value */ - toHex (): string { + public toHex (): string { return u8aToHex(this.toU8a()); } /** * @description Converts the Object to JSON, typically used for RPC transfers */ - toJSON (): string { + public toJSON (): string { return this.toHex(); } /** * @description Returns the base runtime type name for this instance */ - toRawType (): string { + public toRawType (): string { // We are treating this in the same way we do a primitive, this is known return 'Extrinsic'; } @@ -165,7 +165,7 @@ export default class ExtrinsicV1 extends Struct implements IExtrinsic { * @description Encodes the value as a Uint8Array as per the SCALE specifications * @param isBare true when the value has none of the type-specific prefixes (internal) */ - toU8a (isBare?: boolean): Uint8Array { + public toU8a (isBare?: boolean): Uint8Array { const encoded = super.toU8a(); return isBare diff --git a/packages/types/src/type/IndividualExposure.ts b/packages/types/src/type/IndividualExposure.ts index 27572c33ce..6f69be56a1 100644 --- a/packages/types/src/type/IndividualExposure.ts +++ b/packages/types/src/type/IndividualExposure.ts @@ -13,7 +13,7 @@ import Balance from '../primitive/Balance'; * The Substrate IndividualExposure for staking */ export default class IndividualExposure extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ who: AccountId, value: Compact.with(Balance) @@ -23,14 +23,14 @@ export default class IndividualExposure extends Struct { /** * @description The value */ - get value (): Balance { + public get value (): Balance { return (this.get('value') as Compact).toBn() as Balance; } /** * @description The AccountId */ - get who (): AccountId { + public get who (): AccountId { return this.get('who') as AccountId; } } diff --git a/packages/types/src/type/Justification.spec.ts b/packages/types/src/type/Justification.spec.ts index e8414efc24..4f2c485ae0 100644 --- a/packages/types/src/type/Justification.spec.ts +++ b/packages/types/src/type/Justification.spec.ts @@ -5,7 +5,7 @@ import rpc from '../json/SignedBlock.001.json'; import { RhdJustification } from './Justification'; -describe('RhdJustification', () => { +describe('RhdJustification', (): void => { const just = new RhdJustification({ roundNumber: 32, hash: '0xabcd', @@ -15,21 +15,21 @@ describe('RhdJustification', () => { ] }); - it('has the correct hash', () => { + it('has the correct hash', (): void => { expect(just.hash.toHex()).toEqual('0xabcd000000000000000000000000000000000000000000000000000000000000'); }); - it('has the correct round', () => { + it('has the correct round', (): void => { expect(just.roundNumber.toNumber()).toEqual(32); }); - it('has the correct signatures', () => { + it('has the correct signatures', (): void => { const sig = just.signatures[1]; expect(sig.authorityId.toHex()).toEqual('0x9876000000000000000000000000000000000000000000000000000000000000'); }); - it('creates from a JSON strusture', () => { + it('creates from a JSON strusture', (): void => { const viaRpc = new RhdJustification(rpc.result.justification); expect( diff --git a/packages/types/src/type/Justification.ts b/packages/types/src/type/Justification.ts index 906b85c408..acd7afc9e6 100644 --- a/packages/types/src/type/Justification.ts +++ b/packages/types/src/type/Justification.ts @@ -11,11 +11,11 @@ import Hash from '../primitive/Hash'; import U32 from '../primitive/U32'; import { BftAuthoritySignature, BftAuthoritySignatureValue } from './Bft'; -export type RhdJustificationValue = { - roundNumber?: AnyNumber, - hash?: AnyU8a, - signatures?: Array -}; +export interface RhdJustificationValue { + roundNumber?: AnyNumber; + hash?: AnyU8a; + signatures?: BftAuthoritySignatureValue[]; +} /** * @name Justification @@ -31,7 +31,7 @@ export default class Justification extends Bytes { * [[Justification]] for the Rhododendron consensus algorithm */ export class RhdJustification extends Struct { - constructor (value?: RhdJustificationValue | Uint8Array) { + public constructor (value?: RhdJustificationValue | Uint8Array) { super({ roundNumber: U32, hash: Hash, @@ -42,21 +42,21 @@ export class RhdJustification extends Struct { /** * @description The justification [[Hash]] */ - get hash (): Hash { + public get hash (): Hash { return this.get('hash') as Hash; } /** * @description The round this justification wraps as a [[U32]] */ - get roundNumber (): U32 { + public get roundNumber (): U32 { return this.get('roundNumber') as U32; } /** * @description The [[BftAuthoritySignature]] array */ - get signatures (): Vector { + public get signatures (): Vector { return this.get('signatures') as Vector; } } diff --git a/packages/types/src/type/KeyValue.spec.ts b/packages/types/src/type/KeyValue.spec.ts index 123a7b0d65..aae1ed0ea6 100644 --- a/packages/types/src/type/KeyValue.spec.ts +++ b/packages/types/src/type/KeyValue.spec.ts @@ -4,8 +4,8 @@ import KeyValue, { KeyValueOption } from './KeyValue'; -describe('KeyValue', () => { - it('decodes KeyValue from u8a', () => { +describe('KeyValue', (): void => { + it('decodes KeyValue from u8a', (): void => { expect( new KeyValue( Uint8Array.from([ @@ -18,7 +18,7 @@ describe('KeyValue', () => { ).toEqual(['0x11223344', '0x998877665544332211']); }); - it('encodes KeyValue from JSON', () => { + it('encodes KeyValue from JSON', (): void => { expect( new KeyValue(['0x11223344', '0x998877665544332211']).toU8a() ).toEqual( @@ -31,7 +31,7 @@ describe('KeyValue', () => { ); }); - it('exposes the properties for key/value', () => { + it('exposes the properties for key/value', (): void => { const kv = new KeyValue(['0x11223344', '0x998877665544332211']); expect(kv.key.toHex()).toEqual('0x11223344'); @@ -39,8 +39,8 @@ describe('KeyValue', () => { }); }); -describe('KeyValueOption', () => { - it('exposes the properties for key/value', () => { +describe('KeyValueOption', (): void => { + it('exposes the properties for key/value', (): void => { const kv = new KeyValueOption([ '0x11223344' ]); diff --git a/packages/types/src/type/KeyValue.ts b/packages/types/src/type/KeyValue.ts index 50e690917c..5d43bf1c2e 100644 --- a/packages/types/src/type/KeyValue.ts +++ b/packages/types/src/type/KeyValue.ts @@ -20,7 +20,7 @@ type KeyValueValue = [AnyU8a, AnyU8a]; * is actually for Maps, whereas this is a representation of actual storage values) */ export default class KeyValue extends Tuple { - constructor (value?: KeyValueValue | Uint8Array) { + public constructor (value?: KeyValueValue | Uint8Array) { super({ key: StorageKey, value: StorageData @@ -30,14 +30,14 @@ export default class KeyValue extends Tuple { /** * @description The [[StorageKey]] */ - get key (): StorageKey { + public get key (): StorageKey { return this[0] as StorageKey; } /** * @description The [[StorageData]] */ - get value (): StorageData { + public get value (): StorageData { return this[1] as StorageData; } } @@ -52,7 +52,7 @@ export type KeyValueOptionValue = [AnyU8a, AnyU8a?]; * from a [[Tuple]], indicating the use inside areas such as [[StorageChangeSet]] */ export class KeyValueOption extends Tuple { - constructor (value?: KeyValueOptionValue | Uint8Array) { + public constructor (value?: KeyValueOptionValue | Uint8Array) { super({ StorageKey, 'Option': Option.with(StorageData) @@ -62,14 +62,14 @@ export class KeyValueOption extends Tuple { /** * @description The [[StorageKey]] */ - get key (): StorageKey { + public get key (): StorageKey { return this[0] as StorageKey; } /** * @description The [[Option]] [[StorageData]] */ - get value (): Option { + public get value (): Option { return this[1] as Option; } } diff --git a/packages/types/src/type/LockIdentifier.ts b/packages/types/src/type/LockIdentifier.ts index ea7bb62999..2629b56ecc 100644 --- a/packages/types/src/type/LockIdentifier.ts +++ b/packages/types/src/type/LockIdentifier.ts @@ -10,7 +10,7 @@ import U8aFixed from '../codec/U8aFixed'; * The Substrate LockIdentifier for staking */ export default class LockIdentifier extends U8aFixed { - constructor (value?: any) { + public constructor (value?: any) { super(value, 64); // [u8; 8] } } diff --git a/packages/types/src/type/MisbehaviorReport.spec.ts b/packages/types/src/type/MisbehaviorReport.spec.ts index 832352e7a8..32aef81ed1 100644 --- a/packages/types/src/type/MisbehaviorReport.spec.ts +++ b/packages/types/src/type/MisbehaviorReport.spec.ts @@ -4,27 +4,27 @@ import MisbehaviorReport, { BftAtReport } from './MisbehaviorReport'; -describe('BftAtReport', () => { +describe('BftAtReport', (): void => { const report = new BftAtReport({ round: 16, a: ['0x1234', '0x5678'], b: ['0x8765', '0x4321'] }); - it('has the correct round', () => { + it('has the correct round', (): void => { expect(report.round.toNumber()).toEqual(16); }); - it('has the correct hash (a)', () => { + it('has the correct hash (a)', (): void => { expect(report.a.hash.toHex()).toEqual('0x1234000000000000000000000000000000000000000000000000000000000000'); }); - it('has the correct signature (b)', () => { + it('has the correct signature (b)', (): void => { expect(report.b.signature.toHex()).toEqual('0x43210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); }); }); -describe('MisbehaviorReport', () => { +describe('MisbehaviorReport', (): void => { const report = new MisbehaviorReport({ parentHash: '0x01020304', parentNumber: 78, @@ -32,16 +32,16 @@ describe('MisbehaviorReport', () => { misbehavior: 3 }); - it('has the correct misbehavior type', () => { + it('has the correct misbehavior type', (): void => { expect(report.misbehavior.type).toEqual('BftDoubleCommit'); }); - it('has the correct parent block', () => { + it('has the correct parent block', (): void => { expect(report.parentHash.toHex()).toEqual('0x0102030400000000000000000000000000000000000000000000000000000000'); expect(report.parentNumber.toNumber()).toEqual(78); }); - it('identifies the misbehaving authority', () => { + it('identifies the misbehaving authority', (): void => { expect(report.target.toHex()).toEqual('0x1111222200000000000000000000000000000000000000000000000000000000'); }); }); diff --git a/packages/types/src/type/MisbehaviorReport.ts b/packages/types/src/type/MisbehaviorReport.ts index 10d041e4b7..db2d84a9c3 100644 --- a/packages/types/src/type/MisbehaviorReport.ts +++ b/packages/types/src/type/MisbehaviorReport.ts @@ -14,14 +14,14 @@ import AuthorityId from './AuthorityId'; import { BftHashSignature, BftHashSignatureValue } from './Bft'; import BlockNumber from './BlockNumber'; -type BftAtReportValueSingle = { - round?: AnyNumber, - a?: BftHashSignatureValue -}; +interface BftAtReportValueSingle { + round?: AnyNumber; + a?: BftHashSignatureValue; +} -type BftAtReportValue = BftAtReportValueSingle & { - b?: BftHashSignatureValue -}; +interface BftAtReportValue extends BftAtReportValueSingle { + b?: BftHashSignatureValue; +} /** * @name BftAtReport @@ -33,7 +33,7 @@ type BftAtReportValue = BftAtReportValueSingle & { // items in the structure is called, except a & b (one should be expected, the // other actual) export class BftAtReport extends Struct { - constructor (value?: BftAtReportValue | Uint8Array) { + public constructor (value?: BftAtReportValue | Uint8Array) { super({ round: U32, a: BftHashSignature, @@ -44,21 +44,21 @@ export class BftAtReport extends Struct { /** * @description The first report [[BftHashSignature]] */ - get a (): BftHashSignature { + public get a (): BftHashSignature { return this.get('a') as BftHashSignature; } /** * @description The second report [[BftHashSignature]] */ - get b (): BftHashSignature { + public get b (): BftHashSignature { return this.get('b') as BftHashSignature; } /** * @description The round this report applies to as [[U32]] */ - get round (): U32 { + public get round (): U32 { return this.get('round') as U32; } } @@ -69,7 +69,7 @@ export class BftAtReport extends Struct { * A report for out-of-turn proposals */ export class BftProposeOutOfTurn extends Struct { - constructor (value?: BftAtReportValue | Uint8Array) { + public constructor (value?: BftAtReportValue | Uint8Array) { super({ round: U32, a: BftHashSignature @@ -79,14 +79,14 @@ export class BftProposeOutOfTurn extends Struct { /** * @description The [[BftHashSignature]] the report applies to */ - get a (): BftHashSignature { + public get a (): BftHashSignature { return this.get('a') as BftHashSignature; } /** * @description The round as [[u32]] */ - get round (): U32 { + public get round (): U32 { return this.get('round') as U32; } } @@ -121,7 +121,7 @@ export class BftDoubleCommit extends BftAtReport { * An [[Enum]] containing a Bft misbehaviour */ export class MisbehaviorKind extends Enum { - constructor (value?: BftAtReportValue | Uint8Array, index?: number) { + public constructor (value?: BftAtReportValue | Uint8Array, index?: number) { super({ BftProposeOutOfTurn, BftDoublePropose, @@ -133,7 +133,7 @@ export class MisbehaviorKind extends Enum { /** * @description Returns the item as a [[BftDoubleCommit]] */ - get asBftDoubleCommit (): BftDoubleCommit { + public get asBftDoubleCommit (): BftDoubleCommit { assert(this.isBftDoubleCommit, `Cannot convert '${this.type}' via asBftDoubleCommit`); return this.value as BftDoubleCommit; @@ -142,7 +142,7 @@ export class MisbehaviorKind extends Enum { /** * @description Returns the item as a [[BftDoublePrepare]] */ - get asBftDoublePrepare (): BftDoublePrepare { + public get asBftDoublePrepare (): BftDoublePrepare { assert(this.isBftDoublePrepare, `Cannot convert '${this.type}' via asBftDoublePrepare`); return this.value as BftDoublePrepare; @@ -151,7 +151,7 @@ export class MisbehaviorKind extends Enum { /** * @description Returns the item as a [[BftDoublePropose]] */ - get asBftDoublePropose (): BftDoublePropose { + public get asBftDoublePropose (): BftDoublePropose { assert(this.isBftDoublePropose, `Cannot convert '${this.type}' via asBftDoublePropose`); return this.value as BftDoublePropose; @@ -160,7 +160,7 @@ export class MisbehaviorKind extends Enum { /** * @description Returns the item as a [[BftProposeOutOfTurn]] */ - get asBftProposeOutOfTurn (): BftProposeOutOfTurn { + public get asBftProposeOutOfTurn (): BftProposeOutOfTurn { assert(this.isBftProposeOutOfTurn, `Cannot convert '${this.type}' via asBftProposeOutOfTurn`); return this.value as BftProposeOutOfTurn; @@ -169,38 +169,38 @@ export class MisbehaviorKind extends Enum { /** * @description true when this is a BftDoubleCommit */ - get isBftDoubleCommit (): boolean { + public get isBftDoubleCommit (): boolean { return this.type === 'BftDoubleCommit'; } /** * @description true when this is a BftDoublePrepare */ - get isBftDoublePrepare (): boolean { + public get isBftDoublePrepare (): boolean { return this.type === 'BftDoublePrepare'; } /** * @description true when this is a BftDoublePropose */ - get isBftDoublePropose (): boolean { + public get isBftDoublePropose (): boolean { return this.type === 'BftDoublePropose'; } /** * @description true when this is a BftProposeOutOfTurn */ - get isBftProposeOutOfTurn (): boolean { + public get isBftProposeOutOfTurn (): boolean { return this.type === 'BftProposeOutOfTurn'; } } -type MisbehaviorReportValue = { - misbehavior?: MisbehaviorKind | number, - parentHash?: Hash | Uint8Array | string, - parentNumber?: AnyNumber, - target?: AuthorityId | string -}; +interface MisbehaviorReportValue { + misbehavior?: MisbehaviorKind | number; + parentHash?: Hash | Uint8Array | string; + parentNumber?: AnyNumber; + target?: AuthorityId | string; +} /** * @name MisbehaviorReport @@ -208,7 +208,7 @@ type MisbehaviorReportValue = { * A Misbehaviour report of [[MisbehavioirKind]] against a specific [[AuthorityId]] */ export default class MisbehaviorReport extends Struct { - constructor (value?: MisbehaviorReportValue | Uint8Array) { + public constructor (value?: MisbehaviorReportValue | Uint8Array) { super({ parentHash: Hash, parentNumber: BlockNumber, @@ -220,28 +220,28 @@ export default class MisbehaviorReport extends Struct { /** * @description The [[MisbehaviorKind]] */ - get misbehavior (): MisbehaviorKind { + public get misbehavior (): MisbehaviorKind { return this.get('misbehavior') as MisbehaviorKind; } /** * @description The [[Hash]] of the parent block */ - get parentHash (): Hash { + public get parentHash (): Hash { return this.get('parentHash') as Hash; } /** * @description The [[BlockNumber]] of the parent */ - get parentNumber (): BlockNumber { + public get parentNumber (): BlockNumber { return this.get('parentNumber') as BlockNumber; } /** * @description The [[authorityId]] the report applies to */ - get target (): AuthorityId { + public get target (): AuthorityId { return this.get('target') as AuthorityId; } } diff --git a/packages/types/src/type/NewAccountOutcome.spec.ts b/packages/types/src/type/NewAccountOutcome.spec.ts index e8d3a8deb3..c6f4cf399b 100644 --- a/packages/types/src/type/NewAccountOutcome.spec.ts +++ b/packages/types/src/type/NewAccountOutcome.spec.ts @@ -4,8 +4,8 @@ import NewAccountOutcome from './NewAccountOutcome'; -describe('NewAccountOutcome', () => { - it('allows setting value in constructor', () => { +describe('NewAccountOutcome', (): void => { + it('allows setting value in constructor', (): void => { expect( new NewAccountOutcome(2).toNumber() ).toEqual(2); diff --git a/packages/types/src/type/NewAccountOutcome.ts b/packages/types/src/type/NewAccountOutcome.ts index f5400d4944..74bc1eda31 100644 --- a/packages/types/src/type/NewAccountOutcome.ts +++ b/packages/types/src/type/NewAccountOutcome.ts @@ -11,7 +11,7 @@ import U8a from '../codec/U8a'; * Enum to track the outcome for creation of an [[AccountId]] */ export default class NewAccountOutcome extends Enum { - constructor (index?: U8a | Uint8Array | number) { + public constructor (index?: U8a | Uint8Array | number) { super([ 'NoHint', 'GoodHint', diff --git a/packages/types/src/type/PrefabWasmModule.ts b/packages/types/src/type/PrefabWasmModule.ts index 9d6c1994e8..20ef3b8713 100644 --- a/packages/types/src/type/PrefabWasmModule.ts +++ b/packages/types/src/type/PrefabWasmModule.ts @@ -17,7 +17,7 @@ class PrefabWasmModuleReserved extends Option { * @description Struct to encode the vesting schedule of an individual account */ export default class PrefabWasmModule extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ scheduleVersion: Compact.with(U32), initial: Compact.with(U32), @@ -30,28 +30,28 @@ export default class PrefabWasmModule extends Struct { /** * @description The code as [[Bytes]] */ - get code (): Bytes { + public get code (): Bytes { return this.get('code') as Bytes; } /** * @description The initial as [[Compact]] */ - get initial (): Compact { + public get initial (): Compact { return this.get('initial') as Compact; } /** * @description The maximum as [[Compact]] */ - get maximum (): Compact { + public get maximum (): Compact { return this.get('maximum') as Compact; } /** * @description The scheduleVersion value as [[Compact]] */ - get scheduleVersion (): Compact { + public get scheduleVersion (): Compact { return this.get('scheduleVersion') as Compact; } } diff --git a/packages/types/src/type/ReferendumInfo.ts b/packages/types/src/type/ReferendumInfo.ts index efffb6d7b1..019dcce125 100644 --- a/packages/types/src/type/ReferendumInfo.ts +++ b/packages/types/src/type/ReferendumInfo.ts @@ -9,12 +9,12 @@ import BlockNumber from './BlockNumber'; import Proposal from './Proposal'; import VoteThreshold from './VoteThreshold'; -type ReferendumInfoValue = { - end?: BlockNumber, - proposal?: Proposal, - threshold?: VoteThreshold, - delay?: BlockNumber -}; +interface ReferendumInfoValue { + end?: BlockNumber; + proposal?: Proposal; + threshold?: VoteThreshold; + delay?: BlockNumber; +} /** * @name ReferendumInfo @@ -22,7 +22,7 @@ type ReferendumInfoValue = { * Info regarding an ongoing referendum */ export default class ReferendumInfo extends Struct { - constructor (value?: ReferendumInfoValue | Uint8Array | Map) { + public constructor (value?: ReferendumInfoValue | Uint8Array | Map) { super({ end: BlockNumber, proposal: Proposal, @@ -34,28 +34,28 @@ export default class ReferendumInfo extends Struct { /** * @description When voting on this referendum will end */ - get end (): BlockNumber { + public get end (): BlockNumber { return this.get('end') as BlockNumber; } /** * @description The proposal being voted on */ - get proposal (): Proposal { + public get proposal (): Proposal { return this.get('proposal') as Proposal; } /** * @description The thresholding mechanism to determine whether it passed */ - get threshold (): VoteThreshold { + public get threshold (): VoteThreshold { return this.get('threshold') as VoteThreshold; } /** * @description The delay (in blocks) to wait after a successful referendum before deploying */ - get delay (): BlockNumber { + public get delay (): BlockNumber { return this.get('delay') as BlockNumber; } } diff --git a/packages/types/src/type/RewardDestination.ts b/packages/types/src/type/RewardDestination.ts index f5f1ac523c..37138f6a43 100644 --- a/packages/types/src/type/RewardDestination.ts +++ b/packages/types/src/type/RewardDestination.ts @@ -10,7 +10,7 @@ import Enum from '../codec/Enum'; * A destination account for payment */ export default class RewardDestination extends Enum { - constructor (value?: any) { + public constructor (value?: any) { super([ // Pay into the stash account, increasing the amount at stake accordingly. 'Staked', diff --git a/packages/types/src/type/Schedule.ts b/packages/types/src/type/Schedule.ts index b5cfed5e0e..79c9d45995 100644 --- a/packages/types/src/type/Schedule.ts +++ b/packages/types/src/type/Schedule.ts @@ -13,7 +13,7 @@ import Gas from './Gas'; * Definition of the cost schedule and other parameterizations for wasm vm */ export default class Schedule extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ version: U32, putCodePerByteCost: Gas, @@ -36,105 +36,105 @@ export default class Schedule extends Struct { /** * @description Whether the `ext_println` function is allowed to be used contracts. MUST only be enabled for `dev` chains, NOT for production chains */ - get enablePrintln (): Bool { + public get enablePrintln (): Bool { return this.get('enablePrintln') as Bool; } /** * @description Gas cost to deposit an event; the base. */ - get eventBaseCost (): Gas { + public get eventBaseCost (): Gas { return this.get('eventBaseCost') as Gas; } /** * @description Gas cost to deposit an event; the per-byte portion. */ - get eventDataPerByteCost (): Gas { + public get eventDataPerByteCost (): Gas { return this.get('eventDataPerByteCost') as Gas; } /** * @description Gas cost to deposit an event; the cost per topic. */ - get eventPerTopicCost (): Gas { + public get eventPerTopicCost (): Gas { return this.get('eventPerTopicCost') as Gas; } /** * @description Gas cost of a growing memory by single page. */ - get growMemCost (): Gas { + public get growMemCost (): Gas { return this.get('growMemCost') as Gas; } /** * @description The maximum number of topics supported by an event. */ - get maxEventTopics (): U32 { + public get maxEventTopics (): U32 { return this.get('maxEventTopics') as U32; } /** * @description What is the maximal memory pages amount is allowed to have for a contract. */ - get maxMemoryPages (): U32 { + public get maxMemoryPages (): U32 { return this.get('maxMemoryPages') as U32; } /** * @description How tall the stack is allowed to grow? */ - get maxStackHeight (): U32 { + public get maxStackHeight (): U32 { return this.get('maxStackHeight') as U32; } /** * @description The maximum length of a subject used for PRNG generation. */ - get maxSubjectLen (): U32 { + public get maxSubjectLen (): U32 { return this.get('maxSubjectLen') as U32; } /** * @description Cost of putting a byte of code into the storage. */ - get putCodePerByteCost (): Gas { + public get putCodePerByteCost (): Gas { return this.get('putCodePerByteCost') as Gas; } /** * @description Gas cost of a regular operation. */ - get regularOpCost (): Gas { + public get regularOpCost (): Gas { return this.get('regularOpCost') as Gas; } /** * @description Gas cost per one byte returned. */ - get returnDataPerByteCost (): Gas { + public get returnDataPerByteCost (): Gas { return this.get('returnDataPerByteCost') as Gas; } /** * @description Gas cost per one byte read from the sandbox memory. */ - get sandboxDataReadCost (): Gas { + public get sandboxDataReadCost (): Gas { return this.get('sandboxDataReadCost') as Gas; } /** * @description Gas cost per one byte written to the sandbox memory. */ - get sandboxDataWriteCost (): Gas { + public get sandboxDataWriteCost (): Gas { return this.get('sandboxDataWriteCost') as Gas; } /** * @description Version of the schedule. */ - get version (): U32 { + public get version (): U32 { return this.get('version') as U32; } } diff --git a/packages/types/src/type/SessionKeys.ts b/packages/types/src/type/SessionKeys.ts index a3d5da286d..9154cbc464 100644 --- a/packages/types/src/type/SessionKeys.ts +++ b/packages/types/src/type/SessionKeys.ts @@ -11,7 +11,7 @@ import SessionKey from './SessionKey'; * Wrapper for the session and authority ids */ export default class SessionKeys extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ grandpaKey: SessionKey, auraKey: SessionKey @@ -21,14 +21,14 @@ export default class SessionKeys extends Struct { /** * @description The Aura session */ - get auraKey (): SessionKey { + public get auraKey (): SessionKey { return this.get('auraKey') as SessionKey; } /** * @description The Grandpa Authority */ - get grandpaKey (): SessionKey { + public get grandpaKey (): SessionKey { return this.get('grandpaKey') as SessionKey; } } diff --git a/packages/types/src/type/SignaturePayload.ts b/packages/types/src/type/SignaturePayload.ts index f0f0d7e5ef..11cb7afac8 100644 --- a/packages/types/src/type/SignaturePayload.ts +++ b/packages/types/src/type/SignaturePayload.ts @@ -14,12 +14,12 @@ import RuntimeVersion from '../rpc/RuntimeVersion'; import ExtrinsicEra from './ExtrinsicEra'; import Nonce from './NonceCompact'; -type SignaturePayloadValue = { - nonce?: AnyNumber, - method?: Method, - era?: AnyU8a | IExtrinsicEra - blockHash?: AnyU8a -}; +interface SignaturePayloadValue { + nonce?: AnyNumber; + method?: Method; + era?: AnyU8a | IExtrinsicEra; + blockHash?: AnyU8a; +} // a helper function for both types of payloads, Raw and metadata-known function sign (signerPair: IKeyringPair, u8a: Uint8Array): Uint8Array { @@ -102,6 +102,7 @@ export default class SignaturePayload extends Struct { /** * @description Sign the payload with the keypair */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public sign (signerPair: IKeyringPair, version?: RuntimeVersion): Uint8Array { this._signature = sign(signerPair, this.toU8a()); diff --git a/packages/types/src/type/StakingLedger.ts b/packages/types/src/type/StakingLedger.ts index 37a839e1eb..b3b2f5d24e 100644 --- a/packages/types/src/type/StakingLedger.ts +++ b/packages/types/src/type/StakingLedger.ts @@ -16,7 +16,7 @@ import UnlockChunk from './UnlockChunk'; * The ledger of a (bonded) stash */ export default class StakingLedger extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ stash: AccountId, total: Compact.with(Balance), @@ -28,28 +28,28 @@ export default class StakingLedger extends Struct { /** * @description The total amount of the stash's balance that will be at stake in any forthcoming rounds */ - get active (): Balance { + public get active (): Balance { return (this.get('active') as Compact).toBn() as BlockNumber; } /** * @description The stash account whose balance is actually locked and at stake */ - get stash (): AccountId { + public get stash (): AccountId { return this.get('stash') as AccountId; } /** * @description The total amount of the stash's balance that we are currently accounting for. It's just `active` plus all the `unlocking` balances */ - get total (): Balance { + public get total (): Balance { return (this.get('total') as Compact).toBn() as Balance; } /** * @description Any balance that is becoming free, which may eventually be transferred out of the stash (assuming it doesn't get slashed first) */ - get unlocking (): Vector { + public get unlocking (): Vector { return this.get('unlocking') as Vector; } } diff --git a/packages/types/src/type/StoredPendingChange.ts b/packages/types/src/type/StoredPendingChange.ts index 7654bafcc5..ee54e55b59 100644 --- a/packages/types/src/type/StoredPendingChange.ts +++ b/packages/types/src/type/StoredPendingChange.ts @@ -11,16 +11,16 @@ import U64 from '../primitive/U64'; import BlockNumber from './BlockNumber'; import SessionKey from './SessionKey'; -export type NextAuthorityValue = { - index?: AnyNumber, - sessionKey?: AnyU8a -}; +export interface NextAuthorityValue { + index?: AnyNumber; + sessionKey?: AnyU8a; +} -export type StoredPendingChangeValue = { - scheduledAt: AnyNumber, - delay: AnyNumber, - nextAuthorities?: Array -}; +export interface StoredPendingChangeValue { + scheduledAt: AnyNumber; + delay: AnyNumber; + nextAuthorities?: (Uint8Array | NextAuthorityValue)[]; +} /** * @name NextAuthority @@ -28,18 +28,18 @@ export type StoredPendingChangeValue = { * The next authority available as [[SessionKey]] */ export class NextAuthority extends Tuple { - constructor (value?: Uint8Array | NextAuthorityValue) { + public constructor (value?: Uint8Array | NextAuthorityValue) { super({ SessionKey, U64 }, value); } - get index (): U64 { + public get index (): U64 { return this[1] as U64; } - get sessionKey (): SessionKey { + public get sessionKey (): SessionKey { return this[0] as SessionKey; } } @@ -50,7 +50,7 @@ export class NextAuthority extends Tuple { * Stored pending change for a Grandpa events */ export default class StoredPendingChange extends Struct { - constructor (value?: Uint8Array | StoredPendingChangeValue) { + public constructor (value?: Uint8Array | StoredPendingChangeValue) { super({ scheduledAt: BlockNumber, delay: BlockNumber, @@ -58,15 +58,15 @@ export default class StoredPendingChange extends Struct { }, value); } - get delay (): BlockNumber { + public get delay (): BlockNumber { return this.get('delay') as BlockNumber; } - get nextAuthorities (): Vector { + public get nextAuthorities (): Vector { return this.get('nextAuthorities') as Vector; } - get scheduledAt (): BlockNumber { + public get scheduledAt (): BlockNumber { return this.get('scheduledAt') as BlockNumber; } } diff --git a/packages/types/src/type/TreasuryProposal.ts b/packages/types/src/type/TreasuryProposal.ts index 0e8ca3bf94..32989cca5c 100644 --- a/packages/types/src/type/TreasuryProposal.ts +++ b/packages/types/src/type/TreasuryProposal.ts @@ -12,7 +12,7 @@ import Balance from '../primitive/Balance'; * A Proposal made for Treasury */ export default class TreasuryProposal extends Struct { - constructor (value: any) { + public constructor (value: any) { super({ proposer: AccountId, value: Balance, @@ -24,28 +24,28 @@ export default class TreasuryProposal extends Struct { /** * @description The beneficiary */ - get beneficiary (): AccountId { + public get beneficiary (): AccountId { return this.get('beneficiary') as AccountId; } /** * @description The bond */ - get bond (): Balance { + public get bond (): Balance { return this.get('bond') as Balance; } /** * @description The proposer */ - get proposer (): AccountId { + public get proposer (): AccountId { return this.get('proposer') as AccountId; } /** * @description The bond */ - get value (): Balance { + public get value (): Balance { return this.get('value') as Balance; } } diff --git a/packages/types/src/type/UncleEntryItem.ts b/packages/types/src/type/UncleEntryItem.ts index 560a3a888b..03e11e147c 100644 --- a/packages/types/src/type/UncleEntryItem.ts +++ b/packages/types/src/type/UncleEntryItem.ts @@ -19,7 +19,7 @@ export class InclusionHeight extends BlockNumber { * @name Uncle */ export class Uncle extends Tuple { - constructor (value: any) { + public constructor (value: any) { super({ hash: Hash, author: Option.with(AccountId) @@ -33,7 +33,7 @@ export class Uncle extends Tuple { * @description Information about an uncle to include */ export default class UncleEntryItem extends Enum { - constructor (value?: any) { + public constructor (value?: any) { super({ InclusionHeight, Uncle diff --git a/packages/types/src/type/UnlockChunk.ts b/packages/types/src/type/UnlockChunk.ts index e9491ec8a6..5d5c2c604c 100644 --- a/packages/types/src/type/UnlockChunk.ts +++ b/packages/types/src/type/UnlockChunk.ts @@ -13,7 +13,7 @@ import BlockNumber from './BlockNumber'; * Just a Balance/BlockNumber tuple to encode when a chunk of funds will be unlocked */ export default class UnlockChunk extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ value: Compact.with(Balance), era: Compact.with(BlockNumber) @@ -23,14 +23,14 @@ export default class UnlockChunk extends Struct { /** * @description Era number at which point it'll be unlocked */ - get era (): BlockNumber { + public get era (): BlockNumber { return (this.get('era') as Compact).toBn() as BlockNumber; } /** * @description Amount of funds to be unlocked */ - get value (): Balance { + public get value (): Balance { return (this.get('value') as Compact).toBn() as Balance; } } diff --git a/packages/types/src/type/ValidatorPrefs.spec.ts b/packages/types/src/type/ValidatorPrefs.spec.ts index f8a273de3b..73b2f35ac2 100644 --- a/packages/types/src/type/ValidatorPrefs.spec.ts +++ b/packages/types/src/type/ValidatorPrefs.spec.ts @@ -4,14 +4,14 @@ import ValidatorPrefs from './ValidatorPrefs'; -describe('ValidatorPrefs', () => { - it('starts with empty values', () => { +describe('ValidatorPrefs', (): void => { + it('starts with empty values', (): void => { expect( new ValidatorPrefs().validatorPayment.toNumber() ).toEqual(0); }); - it('exposes the internal values via get', () => { + it('exposes the internal values via get', (): void => { const prefs = new ValidatorPrefs({ unstakeThreshold: 3, validatorPayment: 12345 diff --git a/packages/types/src/type/ValidatorPrefs.ts b/packages/types/src/type/ValidatorPrefs.ts index f0c788cdb8..f4ddd0b6b0 100644 --- a/packages/types/src/type/ValidatorPrefs.ts +++ b/packages/types/src/type/ValidatorPrefs.ts @@ -9,10 +9,10 @@ import Struct from '../codec/Struct'; import Balance from '../primitive/Balance'; import U32 from '../primitive/U32'; -type ValidatorPrefsValue = { - unstakeThreshold?: AnyNumber, - validatorPayment?: AnyNumber -}; +interface ValidatorPrefsValue { + unstakeThreshold?: AnyNumber; + validatorPayment?: AnyNumber; +} /** * @name ValidatorPrefs @@ -20,7 +20,7 @@ type ValidatorPrefsValue = { * Validator preferences */ export default class ValidatorPrefs extends Struct { - constructor (value?: ValidatorPrefsValue | Uint8Array) { + public constructor (value?: ValidatorPrefsValue | Uint8Array) { super({ unstakeThreshold: Compact.with(U32), validatorPayment: Compact.with(Balance) @@ -30,14 +30,14 @@ export default class ValidatorPrefs extends Struct { /** * @description The unstake threshold as [[U32]] */ - get unstakeThreshold (): U32 { + public get unstakeThreshold (): U32 { return this.get('unstakeThreshold') as U32; } /** * @description The payment config for the validator as a [[Compact]] [[Balance]] */ - get validatorPayment (): Compact { + public get validatorPayment (): Compact { return this.get('validatorPayment') as Compact; } } diff --git a/packages/types/src/type/VestingSchedule.ts b/packages/types/src/type/VestingSchedule.ts index 8825184cbf..795da5d1eb 100644 --- a/packages/types/src/type/VestingSchedule.ts +++ b/packages/types/src/type/VestingSchedule.ts @@ -10,7 +10,7 @@ import Balance from '../primitive/Balance'; * @description Struct to encode the vesting schedule of an individual account */ export default class VestingSchedule extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ offset: Balance, perBlock: Balance @@ -20,14 +20,14 @@ export default class VestingSchedule extends Struct { /** * @description The offset as [[Balance]] */ - get offset (): Balance { + public get offset (): Balance { return this.get('offset') as Balance; } /** * @description The perBlock value as [[Balance]] */ - get perBlock (): Balance { + public get perBlock (): Balance { return this.get('perBlock') as Balance; } } diff --git a/packages/types/src/type/Vote.spec.ts b/packages/types/src/type/Vote.spec.ts index 7b22b86871..c9b7de7ef0 100644 --- a/packages/types/src/type/Vote.spec.ts +++ b/packages/types/src/type/Vote.spec.ts @@ -2,114 +2,107 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import Boolean from '../primitive/Bool'; +import Bool from '../primitive/Bool'; import Conviction from './Conviction'; import Vote from './Vote'; -describe('Vote', () => { - it('constructs via boolean true', () => { +describe('Vote', (): void => { + it('constructs via boolean true', (): void => { expect(new Vote(true).toU8a()).toEqual(new Uint8Array([128])); expect(new Vote(true).isAye).toBe(true); expect(new Vote(true).isNay).toBe(false); }); - it('constructs via boolean false', () => { + it('constructs via boolean false', (): void => { expect(new Vote(false).toU8a()).toEqual(new Uint8Array([0])); expect(new Vote(false).isNay).toBe(true); expect(new Vote(false).isAye).toBe(false); }); - it('has isYay for positive', () => { - expect(new Vote(new Boolean(true)).isAye).toBe(true); + it('has isYay for positive', (): void => { + // eslint-disable-next-line no-new-wrappers + expect(new Vote(new Bool(true)).isAye).toBe(true); }); - it('has isNay for negative', () => { - expect(new Vote(new Boolean(false)).isNay).toBe(true); + it('has isNay for negative', (): void => { + // eslint-disable-next-line no-new-wrappers + expect(new Vote(new Bool(false)).isNay).toBe(true); }); - it('is Aye for negative numbers', () => { + it('is Aye for negative numbers', (): void => { expect(new Vote(-128).isAye).toBe(true); }); - it('is Nay for positive numbers', () => { + it('is Nay for positive numbers', (): void => { expect(new Vote(127).isNay).toBe(true); }); - it('constructs V2 Vote with raw boolean', () => { + it('constructs V2 Vote with raw boolean', (): void => { expect( new Vote({ aye: true, conviction: new Conviction('Locked1x') - }) - .toU8a() - ) - .toEqual(new Uint8Array([0b10000001])); + }).toU8a() + ).toEqual(new Uint8Array([0b10000001])); }); - it('constructs with V2 Vote aye is false, conviction is None', () => { + it('constructs with V2 Vote aye is false, conviction is None', (): void => { expect( new Vote({ - aye: new Boolean(false), + aye: new Bool(false), conviction: new Conviction('None') - }) - .toU8a() - ) - .toEqual(new Uint8Array([0b00000000])); + }).toU8a() + ).toEqual(new Uint8Array([0b00000000])); }); - it('constructs with Vote aye is true, conviction is Locked4x', () => { + it('constructs with Vote aye is true, conviction is Locked4x', (): void => { expect( new Vote({ - aye: new Boolean(true), + aye: new Bool(true), conviction: new Conviction('Locked4x') - }) - .toU8a() - ) - .toEqual(new Uint8Array([0b10000100])); + }).toU8a() + ).toEqual(new Uint8Array([0b10000100])); }); - it('Conviction getter works', () => { + it('Conviction getter works', (): void => { expect( new Vote({ - aye: new Boolean(true), + aye: new Bool(true), conviction: new Conviction('Locked2x') }).conviction.toString() - ) - .toEqual('Locked2x'); + ).toEqual('Locked2x'); }); - it('Conviction getter works with raw boolean and string conviction', () => { + it('Conviction getter works with raw boolean and string conviction', (): void => { expect( new Vote({ aye: true, conviction: 'Locked2x' }).conviction.toString() - ) - .toEqual('Locked2x'); + ).toEqual('Locked2x'); }); - it('Conviction getter works with raw boolean and conviction index', () => { + it('Conviction getter works with raw boolean and conviction index', (): void => { expect( new Vote({ aye: true, conviction: 2 }).conviction.toString() - ) - .toEqual('Locked2x'); + ).toEqual('Locked2x'); }); - it('isAye getter works', () => { + it('isAye getter works', (): void => { expect( new Vote({ - aye: new Boolean(true), + aye: new Bool(true), conviction: new Conviction('None') }).isAye) .toEqual(true); }); - it('isNay getter works', () => { + it('isNay getter works', (): void => { expect( new Vote({ - aye: new Boolean(true), + aye: new Bool(true), conviction: new Conviction('None') }).isNay) .toEqual(false); diff --git a/packages/types/src/type/Vote.ts b/packages/types/src/type/Vote.ts index 61bf7ebc26..75ccb524c7 100644 --- a/packages/types/src/type/Vote.ts +++ b/packages/types/src/type/Vote.ts @@ -15,9 +15,10 @@ import Bool from '../primitive/Bool'; */ export default class Vote extends U8a { private _aye: Bool; + private _conviction: Conviction; // for V1, default to None - constructor (value?: any) { + public constructor (value?: any) { // decoded is just 1 byte // Aye: Most Significant Bit // Conviction: 0000 - 0101 @@ -35,8 +36,8 @@ export default class Vote extends U8a { private static decodeVote (value?: any): Uint8Array { if (isBoolean(value)) { return value - ? new Uint8Array([0b10000000]) - : new Uint8Array([0b0]); + ? new Uint8Array([0b10000000]) + : new Uint8Array([0b0]); } else if (value instanceof Bool) { return Vote.decodeVote(value.valueOf()); } else if (isNumber(value)) { @@ -60,21 +61,21 @@ export default class Vote extends U8a { /** * @description returns a V2 conviction */ - get conviction (): Conviction { + public get conviction (): Conviction { return this._conviction; } /** * @description true if the wrapped value is a positive vote */ - get isAye (): boolean { + public get isAye (): boolean { return this._aye.eq(true); } /** * @description true if the wrapped value is a negative vote */ - get isNay (): boolean { + public get isNay (): boolean { return !this.isAye; } } diff --git a/packages/types/src/type/VoteThreshold.spec.ts b/packages/types/src/type/VoteThreshold.spec.ts index 743bcea929..b6e577c0d0 100644 --- a/packages/types/src/type/VoteThreshold.spec.ts +++ b/packages/types/src/type/VoteThreshold.spec.ts @@ -4,14 +4,14 @@ import VoteThreshold from './VoteThreshold'; -describe('VoteThreshold', () => { - it('starts with default value', () => { +describe('VoteThreshold', (): void => { + it('starts with default value', (): void => { expect( new VoteThreshold().toString() ).toEqual('Super majority approval'); }); - it('allows setting value in constructor', () => { + it('allows setting value in constructor', (): void => { expect( new VoteThreshold(2).toNumber() ).toEqual(2); diff --git a/packages/types/src/type/VoteThreshold.ts b/packages/types/src/type/VoteThreshold.ts index 5c8324d38d..10e6659c26 100644 --- a/packages/types/src/type/VoteThreshold.ts +++ b/packages/types/src/type/VoteThreshold.ts @@ -10,7 +10,7 @@ import Enum from '../codec/Enum'; * Voting threshold, used inside proposals to set change the voting tally */ export default class VoteThreshold extends Enum { - constructor (index?: number | Uint8Array) { + public constructor (index?: number | Uint8Array) { super([ 'Super majority approval', 'Super majority rejection', diff --git a/packages/types/src/type/VoterInfo.ts b/packages/types/src/type/VoterInfo.ts index 5d11f59980..c976c2e9b0 100644 --- a/packages/types/src/type/VoterInfo.ts +++ b/packages/types/src/type/VoterInfo.ts @@ -13,7 +13,7 @@ import VoteIndex from './VoteIndex'; */ export default class VoterInfo extends Struct { - constructor (value?: any) { + public constructor (value?: any) { super({ lastActive: VoteIndex, lastWin: VoteIndex, @@ -25,7 +25,7 @@ export default class VoterInfo extends Struct { /** * @description Last VoteIndex in which this voter assigned (or initialized) approvals. */ - get lastActive (): VoteIndex { + public get lastActive (): VoteIndex { return this.get('lastActive') as VoteIndex; } @@ -33,21 +33,21 @@ export default class VoterInfo extends Struct { * @description Last VoteIndex in which one of this voter's approvals won. * Note that `last_win = N` indicates a last win at index `N-1`, hence `last_win = 0` means no win ever. */ - get lastWin (): VoteIndex { + public get lastWin (): VoteIndex { return this.get('lastWin') as VoteIndex; } /** * @description The amount of stored weight as a result of not winning but changing approvals. */ - get pot (): Balance { + public get pot (): Balance { return this.get('pot') as Balance; } /** * @description Current staked amount. A lock equal to this value always exists. */ - get stake (): Balance { + public get stake (): Balance { return this.get('stake') as Balance; } } diff --git a/packages/types/src/type/Votes.ts b/packages/types/src/type/Votes.ts index a36c2240e6..6ef05e9694 100644 --- a/packages/types/src/type/Votes.ts +++ b/packages/types/src/type/Votes.ts @@ -9,7 +9,7 @@ import MemberCount from './MemberCount'; import ProposalIndex from './ProposalIndex'; export default class Votes extends Struct { - constructor (value: any) { + public constructor (value: any) { super({ index: ProposalIndex, threshold: MemberCount, @@ -21,28 +21,28 @@ export default class Votes extends Struct { /** * @description The current set of voters that approved it. */ - get ayes (): Vector { + public get ayes (): Vector { return this.get('ayes') as Vector; } /** * @description The proposal's unique index. */ - get index (): ProposalIndex { + public get index (): ProposalIndex { return this.get('index') as ProposalIndex; } /** * @description The current set of voters that rejected it. */ - get nays (): Vector { + public get nays (): Vector { return this.get('nays') as Vector; } /** * @description The number of approval votes that are needed to pass the motion. */ - get threshold (): MemberCount { + public get threshold (): MemberCount { return this.get('threshold') as MemberCount; } } diff --git a/packages/types/src/type/WithdrawReasons.ts b/packages/types/src/type/WithdrawReasons.ts index 78111fc077..d391fb7576 100644 --- a/packages/types/src/type/WithdrawReasons.ts +++ b/packages/types/src/type/WithdrawReasons.ts @@ -10,7 +10,7 @@ import Set from '../codec/Set'; * The Substrate WithdrawReasons for staking */ export default class WithdrawReasons extends Set { - constructor (value: any = []) { + public constructor (value: any = []) { super({ TransactionPayment: 0b00000001, Transfer: 0b00000010, @@ -22,28 +22,28 @@ export default class WithdrawReasons extends Set { /** * @description In order to reserve some funds for a later return or repatriation */ - get isReserve (): boolean { + public get isReserve (): boolean { return this.strings.includes('Reserve'); } /** * @description In order to pay for (system) transaction costs */ - get isTransactionPayment (): boolean { + public get isTransactionPayment (): boolean { return this.strings.includes('TransactionPayment'); } /** * @description In order to transfer ownership */ - get isTransfer (): boolean { + public get isTransfer (): boolean { return this.strings.includes('Transfer'); } /** * @description /// In order to pay some other (higher-level) fees. */ - get isFee (): boolean { + public get isFee (): boolean { return this.strings.includes('Fee'); } } diff --git a/packages/types/src/types.ts b/packages/types/src/types.ts index 62246c65e6..e3a22ef8ae 100644 --- a/packages/types/src/types.ts +++ b/packages/types/src/types.ts @@ -9,14 +9,16 @@ import { FunctionMetadata } from './Metadata/v6/Calls'; import Method from './primitive/Method'; import Address from './primitive/Address'; -export type IKeyringPair = { - address: string, - publicKey: Uint8Array, +// eslint-disable-next-line @typescript-eslint/interface-name-prefix +export interface IKeyringPair { + address: string; + publicKey: Uint8Array; sign: (data: Uint8Array) => Uint8Array; -}; +} -interface CodecArgArray extends Array { } -export type CodecArg = Codec | BN | Boolean | String | Uint8Array | boolean | number | string | undefined | CodecArgArray | CodecArgObject; +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface CodecArgArray extends Array {} +export type CodecArg = Codec | BN | boolean | string | Uint8Array | boolean | number | string | undefined | CodecArgArray | CodecArgObject; export type Callback = (result: T) => void | Promise; @@ -24,16 +26,19 @@ interface CodecArgObject { [index: string]: CodecArg; } +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type AnyFunction = (...args: any[]) => any; export type AnyNumber = BN | Uint8Array | number | string; -export type AnyString = string | String; +export type AnyString = string | string; -export type AnyU8a = Uint8Array | Array | string; +export type AnyU8a = Uint8Array | number[] | string; -export type AnyJsonObject = { [key: string]: AnyJson }; -export interface AnyJsonArray extends Array { } +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface AnyJsonObject extends Record {} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface AnyJsonArray extends Array {} export type AnyJson = string | number | boolean | null | undefined | AnyJsonObject | AnyJsonArray; /** @@ -57,6 +62,7 @@ export interface Codec { /** * @description Compares the value of the input to see if there is a match */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any eq (other?: any): boolean; /** @@ -91,41 +97,45 @@ export type CodecTo = 'toHex' | 'toJSON' | 'toString' | 'toU8a'; export interface Constructor { Fallback?: Constructor; - new(...value: Array): T; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + new(...value: any[]): T; } -export type ConstructorDef = { [index: string]: Constructor }; +export type ConstructorDef = Record>; -export type TypeDef = { [index: string]: Codec }; +export type TypeDef = Record; -export type RegistryTypes = { - [name: string]: Constructor | string | { [name: string]: string } | { _enum: Array | { [index: string]: string } } -}; +export type RegistryTypes = Record | { _enum: string[] | Record }>; export interface RuntimeVersionInterface { - readonly apis: Array; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly apis: any[]; readonly authoringVersion: BN; + // eslint-disable-next-line @typescript-eslint/ban-types readonly implName: String; readonly implVersion: BN; + // eslint-disable-next-line @typescript-eslint/ban-types readonly specName: String; readonly specVersion: BN; } -export type SignatureOptions = { - blockHash: AnyU8a, - era?: IExtrinsicEra, - nonce: AnyNumber, - version?: RuntimeVersionInterface -}; +export interface SignatureOptions { + blockHash: AnyU8a; + era?: IExtrinsicEra; + nonce: AnyNumber; + version?: RuntimeVersionInterface; +} export interface ArgsDef { [index: string]: Constructor; } +// eslint-disable-next-line @typescript-eslint/interface-name-prefix,@typescript-eslint/no-empty-interface export interface IHash extends U8a { } +// eslint-disable-next-line @typescript-eslint/interface-name-prefix export interface IMethod extends Codec { - readonly args: Array; + readonly args: Codec[]; readonly argsDef: ArgsDef; readonly callIndex: Uint8Array; readonly data: Uint8Array; @@ -133,16 +143,19 @@ export interface IMethod extends Codec { readonly meta: FunctionMetadata; } +// eslint-disable-next-line @typescript-eslint/interface-name-prefix export interface IExtrinsicSignature extends Codec { readonly isSigned: boolean; - era: IExtrinsicEra; + readonly era: IExtrinsicEra; } +// eslint-disable-next-line @typescript-eslint/interface-name-prefix export interface IExtrinsicEra { asImmortalEra: Codec; asMortalEra: Codec; } +// eslint-disable-next-line @typescript-eslint/interface-name-prefix export interface IExtrinsic extends IMethod { hash: IHash; isSigned: boolean;