From ae1de13620ff8a2d21f3a29b2db0173f62aa6b34 Mon Sep 17 00:00:00 2001 From: Zeke Mostov <32168567+emostov@users.noreply.github.com> Date: Mon, 23 Nov 2020 16:19:09 -0800 Subject: [PATCH 01/22] feat: chainSpec based controller config; Types from apps-config Clean up --- package.json | 18 +- src/App.ts | 3 + src/{Config.ts => SidecarConfig.ts} | 4 +- src/Specs.ts | 2 +- src/chains-config/defaultControllers.ts | 26 + src/chains-config/index.ts | 48 ++ src/chains-config/kulupuControllers.ts | 22 + src/controllers/AbstractControllers.spec.ts | 4 +- .../accounts/AccountsBalanceInfoController.ts | 4 +- .../accounts/AccountsStakingInfoController.ts | 4 +- .../AccountsStakingPayoutsController.ts | 8 +- .../accounts/AccountsVestingInfoController.ts | 4 +- src/controllers/blocks/BlocksController.ts | 4 +- .../chains/KulupuBlocksController.ts | 121 ++++ src/controllers/chains/index.ts | 6 + src/controllers/index.ts | 47 +- src/controllers/node/NodeNetworkController.ts | 4 +- .../node/NodeTransactionPoolController.ts | 4 +- src/controllers/node/NodeVersionController.ts | 4 +- .../PalletsStakingProgressController.ts | 4 +- .../pallets/PalletsStorageItemController.ts | 4 +- src/controllers/pallets/index.ts | 4 +- .../runtime/RuntimeCodeController.ts | 4 +- .../runtime/RuntimeMetadataController.ts | 4 +- .../runtime/RuntimeSpecController.ts | 4 +- .../TransactionDryRunController.ts | 4 +- .../TransactionFeeEstimateController.ts | 4 +- .../TransactionMaterialController.ts | 4 +- .../TransactionSubmitController.ts | 4 +- src/logging/transports/consoleTransport.ts | 4 +- src/main.ts | 146 +++-- src/services/blocks/BlocksService.ts | 54 +- src/types/chains-config/ControllerConfig.ts | 8 + src/types/chains-config/index.ts | 1 + src/types/polkadot-js/Codec.ts | 6 +- .../{config => sidecar-config}/CONFIG.ts | 0 .../{config => sidecar-config}/MODULES.ts | 0 .../SidecarConfig.ts | 0 src/types/{config => sidecar-config}/index.ts | 0 tsconfig.json | 3 +- yarn.lock | 613 +++++++++++------- 41 files changed, 793 insertions(+), 419 deletions(-) rename src/{Config.ts => SidecarConfig.ts} (94%) create mode 100644 src/chains-config/defaultControllers.ts create mode 100644 src/chains-config/index.ts create mode 100644 src/chains-config/kulupuControllers.ts create mode 100644 src/controllers/chains/KulupuBlocksController.ts create mode 100644 src/controllers/chains/index.ts create mode 100644 src/types/chains-config/ControllerConfig.ts create mode 100644 src/types/chains-config/index.ts rename src/types/{config => sidecar-config}/CONFIG.ts (100%) rename src/types/{config => sidecar-config}/MODULES.ts (100%) rename src/types/{config => sidecar-config}/SidecarConfig.ts (100%) rename src/types/{config => sidecar-config}/index.ts (100%) diff --git a/package.json b/package.json index 043eee3a2..a145e7ea0 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "build:calc": "bash ./calc/build.sh", "build:docker": "docker build -t substrate-api-sidecar .", "build:docs": "(cd docs && yarn && yarn build)", + "clean": "rm -rf node_modules/ yarn.lock build/", "main": "node ./build/src/main.js", "lint": "tsc && eslint . --ext ts", "deploy": "yarn build && standard-version", @@ -36,8 +37,9 @@ "test": "jest --silent" }, "dependencies": { - "@polkadot/api": "^2.7.1", - "@polkadot/util-crypto": "^4.1.1", + "@polkadot/api": "^2.8.1", + "@polkadot/apps-config": "^0.68.1", + "@polkadot/util-crypto": "^4.2.1", "@substrate/calc": "^0.1.2", "confmgr": "^1.0.6", "express": "^4.17.1", @@ -52,19 +54,19 @@ "@types/jest": "^26.0.15", "@types/morgan": "^1.9.2", "@types/triple-beam": "^1.3.2", - "@typescript-eslint/eslint-plugin": "^4.7.0", - "@typescript-eslint/parser": "^4.7.0", - "eslint": "^7.13.0", + "@typescript-eslint/eslint-plugin": "^4.8.2", + "@typescript-eslint/parser": "^4.8.2", + "eslint": "^7.14.0", "eslint-config-prettier": "^6.15.0", "eslint-plugin-prettier": "^3.1.4", - "eslint-plugin-simple-import-sort": "^6.0.0", + "eslint-plugin-simple-import-sort": "^6.0.1", "jest": "^26.6.3", - "prettier": "^2.1.2", + "prettier": "^2.2.0", "rimraf": "^3.0.2", "standard-version": "^9.0.0", "ts-jest": "^26.4.4", "tsc-watch": "^4.2.9", - "typescript": "^4.0.5" + "typescript": "^4.1.2" }, "resolutions": { "node-forge": ">=0.10.0", diff --git a/src/App.ts b/src/App.ts index a6b3d97d2..9633fac4b 100644 --- a/src/App.ts +++ b/src/App.ts @@ -83,6 +83,9 @@ export default class App { listen(): void { this.app.listen(this.port, this.host, () => { console.log(`Listening on http://${this.host}:${this.port}/`); + console.log( + `Check the root endpoint (http://${this.host}:${this.port}/) to see the available endpoints for the current node` + ); }); } diff --git a/src/Config.ts b/src/SidecarConfig.ts similarity index 94% rename from src/Config.ts rename to src/SidecarConfig.ts index b541e1948..fc057bb15 100644 --- a/src/Config.ts +++ b/src/SidecarConfig.ts @@ -2,7 +2,7 @@ import { ConfigManager } from 'confmgr'; import * as configTypes from '../config/types.json'; import { Specs } from './Specs'; -import { CONFIG, ISidecarConfig, MODULES } from './types/config'; +import { CONFIG, ISidecarConfig, MODULES } from './types/sidecar-config'; function hr(): string { return Array(80).fill('━').join(''); @@ -11,7 +11,7 @@ function hr(): string { /** * Access a singleton config object that will be intialized on first use. */ -export class Config { +export class SidecarConfig { private static _config: ISidecarConfig | undefined; /** * Gather env vars for config and make sure they are valid. diff --git a/src/Specs.ts b/src/Specs.ts index 496bc62ef..8a42b8ac8 100644 --- a/src/Specs.ts +++ b/src/Specs.ts @@ -1,6 +1,6 @@ import { ConfigSpecs, SpecsFactory } from 'confmgr'; -import { CONFIG, MODULES } from './types/config'; +import { CONFIG, MODULES } from './types/sidecar-config'; /** * Access a singleton specification for config enviroment variables that will diff --git a/src/chains-config/defaultControllers.ts b/src/chains-config/defaultControllers.ts new file mode 100644 index 000000000..df0d3b045 --- /dev/null +++ b/src/chains-config/defaultControllers.ts @@ -0,0 +1,26 @@ +import { ControllerConfig } from '../types/chains-config'; + +/** + * Controllers that Sidecar will always default to. This likely will always be + * the optimal controller selection for Polkadot and Kusama. + */ +export const defaultControllers: ControllerConfig = { + Blocks: true, + KulupuBlocks: true, + AccountsStakingPayouts: true, + AccountsBalanceInfo: true, + AccountsStakingInfo: true, + AccountsVestingInfo: true, + NodeNetwork: true, + NodeVersion: true, + NodeTransactionPool: true, + RuntimeCode: true, + RuntimeSpec: true, + RuntimeMetadata: true, + TransactionDryRun: true, + TransactionMaterial: true, + TransactionFeeEstimate: true, + TransactionSubmit: true, + PalletsStakingProgress: true, + PalletsStorageItem: true, +}; diff --git a/src/chains-config/index.ts b/src/chains-config/index.ts new file mode 100644 index 000000000..d677310a8 --- /dev/null +++ b/src/chains-config/index.ts @@ -0,0 +1,48 @@ +import { ApiPromise } from '@polkadot/api'; +import AbstractController from 'src/controllers/AbstractController'; +import { AbstractService } from 'src/services/AbstractService'; + +import { controllers } from '../controllers'; +import { ControllerConfig } from '../types/chains-config'; +import { defaultControllers } from './defaultControllers'; +import { kulupuControllers } from './kulupuControllers'; + +/** + * + * @param api ApiPromise to inject into controllers + * @param implName + */ +export function getControllersForSpec( + api: ApiPromise, + specName: string +): AbstractController[] { + switch (specName) { + case 'kulupu': + return getControllersFromConfig(api, kulupuControllers); + default: + return getControllersFromConfig(api, defaultControllers); + } +} + +/** + * Return an array of instantiated controller instances based off of a + * `ControllerConfig`. + * + * @param api ApiPromise to inject into controllers + * @param config controller mount configuration object + */ +function getControllersFromConfig(api: ApiPromise, config: ControllerConfig) { + // If we don't typecast here, tsc thinks its just [string, any][] + const controllersToInclude = Object.entries(config) as [ + keyof typeof controllers, + boolean + ][]; + + return controllersToInclude.reduce((acc, [controllerName, shouldMount]) => { + if (shouldMount) { + return acc.concat(new controllers[controllerName](api)); + } + + return acc; + }, [] as AbstractController[]); +} diff --git a/src/chains-config/kulupuControllers.ts b/src/chains-config/kulupuControllers.ts new file mode 100644 index 000000000..298a3505e --- /dev/null +++ b/src/chains-config/kulupuControllers.ts @@ -0,0 +1,22 @@ +import { ControllerConfig } from '../types/chains-config'; + +export const kulupuControllers: ControllerConfig = { + Blocks: false, + KulupuBlocks: true, + AccountsStakingPayouts: false, + AccountsBalanceInfo: true, + AccountsStakingInfo: false, + AccountsVestingInfo: false, + NodeNetwork: true, + NodeVersion: true, + NodeTransactionPool: true, + RuntimeCode: true, + RuntimeSpec: true, + RuntimeMetadata: true, + TransactionDryRun: true, + TransactionMaterial: true, + TransactionFeeEstimate: true, + TransactionSubmit: true, + PalletsStakingProgress: false, + PalletsStorageItem: true, +}; diff --git a/src/controllers/AbstractControllers.spec.ts b/src/controllers/AbstractControllers.spec.ts index c6d673f2c..e568ff4f4 100644 --- a/src/controllers/AbstractControllers.spec.ts +++ b/src/controllers/AbstractControllers.spec.ts @@ -40,9 +40,7 @@ const api = { }, }; -const MockController = class MockController extends AbstractController< - AbstractService -> { +const MockController = class MockController extends AbstractController { protected initRoutes(): void { throw new Error('Method not implemented.'); } diff --git a/src/controllers/accounts/AccountsBalanceInfoController.ts b/src/controllers/accounts/AccountsBalanceInfoController.ts index 26516be6c..355f4daa6 100644 --- a/src/controllers/accounts/AccountsBalanceInfoController.ts +++ b/src/controllers/accounts/AccountsBalanceInfoController.ts @@ -39,9 +39,7 @@ import AbstractController from '../AbstractController'; * - `AccountData`: https://crates.parity.io/pallet_balances/struct.AccountData.html * - `BalanceLock`: https://crates.parity.io/pallet_balances/struct.BalanceLock.html */ -export default class AccountsBalanceController extends AbstractController< - AccountsBalanceInfoService -> { +export default class AccountsBalanceController extends AbstractController { constructor(api: ApiPromise) { super( api, diff --git a/src/controllers/accounts/AccountsStakingInfoController.ts b/src/controllers/accounts/AccountsStakingInfoController.ts index bb359c84e..d3f5315e5 100644 --- a/src/controllers/accounts/AccountsStakingInfoController.ts +++ b/src/controllers/accounts/AccountsStakingInfoController.ts @@ -47,9 +47,7 @@ import AbstractController from '../AbstractController'; * - `Bonded`: https://crates.parity.io/pallet_staking/struct.Bonded.html * - `StakingLedger`: https://crates.parity.io/pallet_staking/struct.StakingLedger.html */ -export default class AccountsStakingInfoController extends AbstractController< - AccountsStakingInfoService -> { +export default class AccountsStakingInfoController extends AbstractController { constructor(api: ApiPromise) { super( api, diff --git a/src/controllers/accounts/AccountsStakingPayoutsController.ts b/src/controllers/accounts/AccountsStakingPayoutsController.ts index b8fba8359..d4d9ed979 100644 --- a/src/controllers/accounts/AccountsStakingPayoutsController.ts +++ b/src/controllers/accounts/AccountsStakingPayoutsController.ts @@ -60,9 +60,7 @@ import AbstractController from '../AbstractController'; * aformentioned payouts. * */ -export default class AccountsStakingPayoutsController extends AbstractController< - AccountsStakingPayoutsService -> { +export default class AccountsStakingPayoutsController extends AbstractController { constructor(api: ApiPromise) { super( api, @@ -86,9 +84,7 @@ export default class AccountsStakingPayoutsController extends AbstractController * @param req Express Request * @param res Express Response */ - private getStakingPayoutsByAccountId: RequestHandler< - IAddressParam - > = async ( + private getStakingPayoutsByAccountId: RequestHandler = async ( { params: { address }, query: { depth, era, unclaimedOnly } }, res ): Promise => { diff --git a/src/controllers/accounts/AccountsVestingInfoController.ts b/src/controllers/accounts/AccountsVestingInfoController.ts index 754c4ebe7..ba72adc47 100644 --- a/src/controllers/accounts/AccountsVestingInfoController.ts +++ b/src/controllers/accounts/AccountsVestingInfoController.ts @@ -27,9 +27,7 @@ import AbstractController from '../AbstractController'; * - Vesting Pallet: https://crates.parity.io/pallet_vesting/index.html * - `VestingInfo`: https://crates.parity.io/pallet_vesting/struct.VestingInfo.html */ -export default class AccountsVestingInfoController extends AbstractController< - AccountsVestingInfoService -> { +export default class AccountsVestingInfoController extends AbstractController { constructor(api: ApiPromise) { super( api, diff --git a/src/controllers/blocks/BlocksController.ts b/src/controllers/blocks/BlocksController.ts index 19b5a5e2b..c8d002cc3 100644 --- a/src/controllers/blocks/BlocksController.ts +++ b/src/controllers/blocks/BlocksController.ts @@ -62,9 +62,7 @@ import AbstractController from '../AbstractController'; * - `OnInitialize`: https://crates.parity.io/frame_support/traits/trait.OnInitialize.html * - `OnFinalize`: https://crates.parity.io/frame_support/traits/trait.OnFinalize.html */ -export default class BlocksController extends AbstractController< - BlocksService -> { +export default class BlocksController extends AbstractController { constructor(api: ApiPromise) { super(api, '/blocks', new BlocksService(api)); this.initRoutes(); diff --git a/src/controllers/chains/KulupuBlocksController.ts b/src/controllers/chains/KulupuBlocksController.ts new file mode 100644 index 000000000..9010f57c2 --- /dev/null +++ b/src/controllers/chains/KulupuBlocksController.ts @@ -0,0 +1,121 @@ +import { ApiPromise } from '@polkadot/api'; +import { RequestHandler } from 'express'; + +import { BlocksService } from '../../services'; +import { INumberParam } from '../../types/requests'; +import AbstractController from '../AbstractController'; + +/** + * GET a block. + * + * N.B. this controller assumes the chain does not have a finality + * gadget (e.g. PoW in Kulupu)) + * + * Paths: + * - `kulupuBlocks\head`: Get the latest finalized block. + * - (Optional) `kulupuBlocks\number`: Block hash or height at which to query. If not provided, queries + * finalized head. + * + * Query: + * - (Optional) `eventDocs`: When set to `true`, every event will have an extra + * `docs` property with a string of the events documentation. + * - (Optional) `extrinsicDocs`: When set to `true`, every extrinsic will have an extra + * `docs` property with a string of the extrinsics documentation. + * + * + * Returns: + * - `number`: Block height. + * - `hash`: The block's hash. + * - `parentHash`: The hash of the parent block. + * - `stateRoot`: The state root after executing this block. + * - `extrinsicsRoot`: The Merkle root of the extrinsics. + * - `authorId`: The account ID of the block author (may be undefined for some chains). + * - `logs`: Array of `DigestItem`s associated with the block. + * - `onInitialize`: Object with an array of `SanitizedEvent`s that occurred during block + * initialization with the `method` and `data` for each. + * - `extrinsics`: Array of extrinsics (inherents and transactions) within the block. Each + * contains: + * - `method`: Extrinsic method. + * - `signature`: Object with `signature` and `signer`, or `null` if unsigned. + * - `nonce`: Account nonce, if applicable. + * - `args`: Array of arguments. + * - `tip`: Any tip added to the transaction. + * - `hash`: The transaction's hash. + * - `info`: `RuntimeDispatchInfo` for the transaction. Includes the `partialFee`. + * - `events`: An array of `SanitizedEvent`s that occurred during extrinsic execution. + * - `success`: Whether or not the extrinsic succeeded. + * - `paysFee`: Whether the extrinsic requires a fee. Careful! This field relates to whether or + * not the extrinsic requires a fee if called as a transaction. Block authors could insert + * the extrinsic as an inherent in the block and not pay a fee. Always check that `paysFee` + * is `true` and that the extrinsic is signed when reconciling old blocks. + * - `onFinalize`: Object with an array of `SanitizedEvent`s that occurred during block + * finalization with the `method` and `data` for each. + * + * + * Substrate Reference: + * - `DigestItem`: https://crates.parity.io/sp_runtime/enum.DigestItem.html + * - `RawEvent`: https://crates.parity.io/frame_system/enum.RawEvent.html + * - Extrinsics: https://substrate.dev/docs/en/knowledgebase/learn-substrate/extrinsics + * - `Extrinsic`: https://crates.parity.io/sp_runtime/traits/trait.Extrinsic.html + * - `OnInitialize`: https://crates.parity.io/frame_support/traits/trait.OnInitialize.html + * - `OnFinalize`: https://crates.parity.io/frame_support/traits/trait.OnFinalize.html + */ +export default class KulupuBlocksController extends AbstractController { + constructor(api: ApiPromise) { + super(api, '/kulupuBlocks', new BlocksService(api)); + this.initRoutes(); + } + + protected initRoutes(): void { + this.safeMountAsyncGetHandlers([ + ['/head', this.getLatestBlock], + ['/:number', this.getBlockById], + ]); + } + + /** + * Get the latest block. + * + * @param _req Express Request + * @param res Express Response + */ + private getLatestBlock: RequestHandler = async ( + { query: { eventDocs, extrinsicDocs } }, + res + ) => { + const eventDocsArg = eventDocs === 'true'; + const extrsinsicDocsArg = extrinsicDocs === 'true'; + + const hash = (await this.api.rpc.chain.getHeader()).hash; + + KulupuBlocksController.sanitizedSend( + res, + await this.service.fetchBlock(hash, eventDocsArg, extrsinsicDocsArg) + ); + }; + + /** + * Get a block by its hash or number identifier. + * + * @param req Express Request + * @param res Express Response + */ + private getBlockById: RequestHandler = async ( + { params: { number }, query: { eventDocs, extrinsicDocs } }, + res + ): Promise => { + const hash = await this.getHashForBlock(number); + + const eventDocsArg = eventDocs === 'true'; + const extrinsinsicDocsArg = extrinsicDocs === 'true'; + + KulupuBlocksController.sanitizedSend( + res, + await this.service.fetchBlock( + hash, + eventDocsArg, + extrinsinsicDocsArg + ) + ); + }; +} diff --git a/src/controllers/chains/index.ts b/src/controllers/chains/index.ts new file mode 100644 index 000000000..3d3fb68f2 --- /dev/null +++ b/src/controllers/chains/index.ts @@ -0,0 +1,6 @@ +// Chain specific controllers. +// +// These endpoints may be reused for other chains as well, but for now naming them after the chain +// that originally neccesitated it for simplicity. + +export { default as KulupuBlocks } from './KulupuBlocksController'; diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 6ae6c08bf..34d34236c 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -1,6 +1,41 @@ -export * from './accounts'; -export * from './blocks'; -export * from './node'; -export * from './pallets'; -export * from './runtime'; -export * from './transaction'; +import { + AccountsBalanceInfo, + AccountsStakingInfo, + AccountsStakingPayouts, + AccountsVestingInfo, +} from './accounts'; +import { Blocks } from './blocks'; +import { KulupuBlocks } from './chains'; +import { NodeNetwork, NodeTransactionPool, NodeVersion } from './node'; +import { PalletsStakingProgress, PalletsStorageItem } from './pallets'; +import { RuntimeCode, RuntimeMetadata, RuntimeSpec } from './runtime'; +import { + TransactionDryRun, + TransactionFeeEstimate, + TransactionMaterial, + TransactionSubmit, +} from './transaction'; + +/** + * Object containing every controller class definition. + */ +export const controllers = { + Blocks, + AccountsBalanceInfo, + AccountsStakingInfo, + AccountsVestingInfo, + AccountsStakingPayouts, + KulupuBlocks, + PalletsStakingProgress, + PalletsStorageItem, + NodeNetwork, + NodeTransactionPool, + NodeVersion, + RuntimeCode, + RuntimeMetadata, + RuntimeSpec, + TransactionDryRun, + TransactionFeeEstimate, + TransactionMaterial, + TransactionSubmit, +}; diff --git a/src/controllers/node/NodeNetworkController.ts b/src/controllers/node/NodeNetworkController.ts index a9d132462..7682482e2 100644 --- a/src/controllers/node/NodeNetworkController.ts +++ b/src/controllers/node/NodeNetworkController.ts @@ -29,9 +29,7 @@ import AbstractController from '../AbstractController'; * References: * - `NodeRole`: https://github.com/paritytech/substrate/blob/master/client/rpc-api/src/system/helpers.rs#L80 */ -export default class NodeNetworkController extends AbstractController< - NodeNetworkService -> { +export default class NodeNetworkController extends AbstractController { constructor(api: ApiPromise) { super(api, '/node/network', new NodeNetworkService(api)); this.initRoutes(); diff --git a/src/controllers/node/NodeTransactionPoolController.ts b/src/controllers/node/NodeTransactionPoolController.ts index 95c6b7fb3..2c273cc59 100644 --- a/src/controllers/node/NodeTransactionPoolController.ts +++ b/src/controllers/node/NodeTransactionPoolController.ts @@ -12,9 +12,7 @@ import AbstractController from '../AbstractController'; * - `hash`: H256 hash of the extrinsic. * - `encodedExtrinsic`: Scale encoded extrinsic. */ -export default class NodeTransactionPoolController extends AbstractController< - NodeTransactionPoolService -> { +export default class NodeTransactionPoolController extends AbstractController { constructor(api: ApiPromise) { super( api, diff --git a/src/controllers/node/NodeVersionController.ts b/src/controllers/node/NodeVersionController.ts index 143bb5094..be4547f95 100644 --- a/src/controllers/node/NodeVersionController.ts +++ b/src/controllers/node/NodeVersionController.ts @@ -12,9 +12,7 @@ import AbstractController from '../AbstractController'; * - `clientImplName`: Node's implementation name. * - `chain`: Node's chain name. */ -export default class NodeVersionController extends AbstractController< - NodeVersionService -> { +export default class NodeVersionController extends AbstractController { constructor(api: ApiPromise) { super(api, '/node/version', new NodeVersionService(api)); this.initRoutes(); diff --git a/src/controllers/pallets/PalletsStakingProgressController.ts b/src/controllers/pallets/PalletsStakingProgressController.ts index 7ed5a2582..98a38fff5 100644 --- a/src/controllers/pallets/PalletsStakingProgressController.ts +++ b/src/controllers/pallets/PalletsStakingProgressController.ts @@ -64,9 +64,7 @@ import AbstractController from '../AbstractController'; * - `Forcing`: https://crates.parity.io/pallet_staking/enum.Forcing.html * - `ElectionStatus`: https://crates.parity.io/pallet_staking/enum.ElectionStatus.html */ -export default class PalletsStakingProgressController extends AbstractController< - PalletsStakingProgressService -> { +export default class PalletsStakingProgressController extends AbstractController { constructor(api: ApiPromise) { super( api, diff --git a/src/controllers/pallets/PalletsStorageItemController.ts b/src/controllers/pallets/PalletsStorageItemController.ts index 870b57b6f..2cf3b686d 100644 --- a/src/controllers/pallets/PalletsStorageItemController.ts +++ b/src/controllers/pallets/PalletsStorageItemController.ts @@ -14,9 +14,7 @@ import AbstractController from '../AbstractController'; * * See `docs/src/openapi-v1.yaml` for usage information. */ -export default class PalletsStorageItemController extends AbstractController< - PalletsStorageItemService -> { +export default class PalletsStorageItemController extends AbstractController { constructor(api: ApiPromise) { super( api, diff --git a/src/controllers/pallets/index.ts b/src/controllers/pallets/index.ts index 45bbac9c1..f96754617 100644 --- a/src/controllers/pallets/index.ts +++ b/src/controllers/pallets/index.ts @@ -1,2 +1,2 @@ -export { default as palletsStakingProgress } from './PalletsStakingProgressController'; -export { default as palletsStorageItem } from './PalletsStorageItemController'; +export { default as PalletsStakingProgress } from './PalletsStakingProgressController'; +export { default as PalletsStorageItem } from './PalletsStorageItemController'; diff --git a/src/controllers/runtime/RuntimeCodeController.ts b/src/controllers/runtime/RuntimeCodeController.ts index 8b1b52ed9..2b5dd2216 100644 --- a/src/controllers/runtime/RuntimeCodeController.ts +++ b/src/controllers/runtime/RuntimeCodeController.ts @@ -15,9 +15,7 @@ import AbstractController from '../AbstractController'; * - `at`: Block number and hash at which the call was made. * - `code`: Runtime code Wasm blob. */ -export default class RuntimeCodeController extends AbstractController< - RuntimeCodeService -> { +export default class RuntimeCodeController extends AbstractController { constructor(api: ApiPromise) { super(api, '/runtime/code', new RuntimeCodeService(api)); this.initRoutes(); diff --git a/src/controllers/runtime/RuntimeMetadataController.ts b/src/controllers/runtime/RuntimeMetadataController.ts index b7470e6e5..13f6caa90 100644 --- a/src/controllers/runtime/RuntimeMetadataController.ts +++ b/src/controllers/runtime/RuntimeMetadataController.ts @@ -18,9 +18,7 @@ import AbstractController from '../AbstractController'; * - FRAME Support: https://crates.parity.io/frame_support/metadata/index.html * - Knowledge Base: https://substrate.dev/docs/en/knowledgebase/runtime/metadata */ -export default class RuntimeMetadataController extends AbstractController< - RuntimeMetadataService -> { +export default class RuntimeMetadataController extends AbstractController { constructor(api: ApiPromise) { super(api, '/runtime/metadata', new RuntimeMetadataService(api)); this.initRoutes(); diff --git a/src/controllers/runtime/RuntimeSpecController.ts b/src/controllers/runtime/RuntimeSpecController.ts index 9813a6157..ce3da8c97 100644 --- a/src/controllers/runtime/RuntimeSpecController.ts +++ b/src/controllers/runtime/RuntimeSpecController.ts @@ -29,9 +29,7 @@ import AbstractController from '../AbstractController'; * its index. * - `properties`: Arbitrary properties defined in the chain spec. */ -export default class RuntimeSpecController extends AbstractController< - RuntimeSpecService -> { +export default class RuntimeSpecController extends AbstractController { constructor(api: ApiPromise) { super(api, '/runtime/spec', new RuntimeSpecService(api)); this.initRoutes(); diff --git a/src/controllers/transaction/TransactionDryRunController.ts b/src/controllers/transaction/TransactionDryRunController.ts index 2970c6487..d3b145f85 100644 --- a/src/controllers/transaction/TransactionDryRunController.ts +++ b/src/controllers/transaction/TransactionDryRunController.ts @@ -28,9 +28,7 @@ import AbstractController from '../AbstractController'; * is connected to does not expose the `system_dryRun` RPC. One way to resolve this * issue is to pass the `--rpc-external` flag to that node. */ -export default class TransactionDryRunController extends AbstractController< - TransactionDryRunService -> { +export default class TransactionDryRunController extends AbstractController { constructor(api: ApiPromise) { super(api, '/transaction/dry-run', new TransactionDryRunService(api)); this.initRoutes(); diff --git a/src/controllers/transaction/TransactionFeeEstimateController.ts b/src/controllers/transaction/TransactionFeeEstimateController.ts index 6be63917c..646120633 100644 --- a/src/controllers/transaction/TransactionFeeEstimateController.ts +++ b/src/controllers/transaction/TransactionFeeEstimateController.ts @@ -30,9 +30,7 @@ import AbstractController from '../AbstractController'; * - `query_info`: https://crates.parity.io/pallet_transaction_payment/struct.Module.html#method.query_info * - `compute_fee`: https://crates.parity.io/pallet_transaction_payment/struct.Module.html#method.compute_fee */ -export default class TransactionFeeEstimateController extends AbstractController< - TransactionFeeEstimateService -> { +export default class TransactionFeeEstimateController extends AbstractController { constructor(api: ApiPromise) { super( api, diff --git a/src/controllers/transaction/TransactionMaterialController.ts b/src/controllers/transaction/TransactionMaterialController.ts index f616378e4..ee94aabea 100644 --- a/src/controllers/transaction/TransactionMaterialController.ts +++ b/src/controllers/transaction/TransactionMaterialController.ts @@ -34,9 +34,7 @@ import AbstractController from '../AbstractController'; * - `SignedExtension`: https://crates.parity.io/sp_runtime/traits/trait.SignedExtension.html * - FRAME Support: https://crates.parity.io/frame_support/metadata/index.html */ -export default class TransactionMaterialController extends AbstractController< - TransactionMaterialService -> { +export default class TransactionMaterialController extends AbstractController { constructor(api: ApiPromise) { super( api, diff --git a/src/controllers/transaction/TransactionSubmitController.ts b/src/controllers/transaction/TransactionSubmitController.ts index 30a8eadef..072e2de83 100644 --- a/src/controllers/transaction/TransactionSubmitController.ts +++ b/src/controllers/transaction/TransactionSubmitController.ts @@ -21,9 +21,7 @@ import AbstractController from '../AbstractController'; * - `extrinsic`: The hex-encoded extrinsic. Only present if Sidecar fails to parse a transaction. * - `cause`: The error message from parsing or from the client. */ -export default class TransactionSubmitController extends AbstractController< - TransactionSubmitService -> { +export default class TransactionSubmitController extends AbstractController { constructor(api: ApiPromise) { super(api, '/transaction', new TransactionSubmitService(api)); this.initRoutes(); diff --git a/src/logging/transports/consoleTransport.ts b/src/logging/transports/consoleTransport.ts index 1e60e211b..48142795c 100644 --- a/src/logging/transports/consoleTransport.ts +++ b/src/logging/transports/consoleTransport.ts @@ -1,7 +1,7 @@ import { TransformableInfo } from 'logform'; import { format, transports } from 'winston'; -import { Config } from '../../Config'; +import { SidecarConfig } from '../../SidecarConfig'; import { filterApiRpc, nodeUtilFormat, @@ -12,7 +12,7 @@ import { const { config: { LOG }, -} = Config; +} = SidecarConfig; /** * Console transport for winston logger. diff --git a/src/main.ts b/src/main.ts index 37914a60e..7a144d964 100644 --- a/src/main.ts +++ b/src/main.ts @@ -16,25 +16,92 @@ // along with this program. If not, see . import { ApiPromise } from '@polkadot/api'; +import { + typesBundle, + typesChain, + typesRpc, + typesSpec, +} from '@polkadot/apps-config/api'; import { WsProvider } from '@polkadot/rpc-provider'; import { json } from 'express'; import App from './App'; -import { Config } from './Config'; -import * as controllers from './controllers'; +import { getControllersForSpec } from './chains-config'; import { consoleOverride } from './logging/consoleOverride'; import { Log } from './logging/Log'; import * as middleware from './middleware'; +import { SidecarConfig } from './SidecarConfig'; + +const { logger } = Log; +const { config } = SidecarConfig; async function main() { - const { config } = Config; + // Overide console.{log, error, warn, etc} + consoleOverride(logger); + + // Instantiate a web socket connection to the node for basic polkadot-js use + const api = await ApiPromise.create({ + provider: new WsProvider(config.SUBSTRATE.WS_URL), + rpc: typesRpc, + typesBundle, + typesChain, + typesSpec, + types: { + ...config.SUBSTRATE.CUSTOM_TYPES, + }, + }); - const { logger } = Log; + // Gather some basic details about the node so we can display a nice message + const [chainName, { implName, specName }] = await Promise.all([ + api.rpc.system.chain(), + api.rpc.state.getRuntimeVersion(), + ]); + + startUpPrompt( + config.SUBSTRATE.WS_URL, + chainName.toString(), + implName.toString() + ); + + // Create our App + const app = new App({ + preMiddleware: [json(), middleware.httpLoggerCreate(logger)], + controllers: getControllersForSpec(api, specName.toString()), + postMiddleware: [ + middleware.txError, + middleware.httpError, + middleware.error, + middleware.legacyError, + middleware.internalError, + ], + port: config.EXPRESS.PORT, + host: config.EXPRESS.HOST, + }); + + // Start the server + app.listen(); +} + +process.on('SIGINT', function () { + console.log('Caught interrupt signal, exiting...'); + process.exit(0); +}); +main().catch(console.log); +/** + * Prompt the user with some basic info abou the node and the network they have + * connected Sidecar to. + * + * @param wsUrl websocket url of the node Sidecar is connected to + * @param chainName chain name of the network Sidecar is connected to + * @param implName implementation name of the node Sidecar is connected to + */ +function startUpPrompt(wsUrl: string, chainName: string, implName: string) { /** * Best effort list of known public nodes that do not encourage high traffic * sidecar installations connecting to them for non - testing / development purposes. */ + // TODO move this to config folder and update const publicWsUrls: string[] = [ 'wss://rpc.polkadot.io', 'wss://cc1-1.polkadot.network', @@ -51,39 +118,20 @@ async function main() { 'wss://rpc.subsocial.network', ]; - // Overide console.{log, error, warn, etc} - consoleOverride(logger); - - // Instantiate a web socket connection to the node for basic polkadot-js use - const api = await ApiPromise.create({ - provider: new WsProvider(config.SUBSTRATE.WS_URL), - types: { - ...config.SUBSTRATE.CUSTOM_TYPES, - }, - }); - - // Gather some basic details about the node so we can display a nice message - const [chainName, { implName }] = await Promise.all([ - api.rpc.system.chain(), - api.rpc.state.getRuntimeVersion(), - ]); - logger.info( - `Connected to chain ${chainName.toString()} on the ${implName.toString()} client at ${ - config.SUBSTRATE.WS_URL - }` + `Connected to chain ${chainName} on the ${implName} client at ${config.SUBSTRATE.WS_URL}` ); - const isPublicUrl: boolean = publicWsUrls.includes(config.SUBSTRATE.WS_URL); + const isPublicUrl: boolean = publicWsUrls.includes(wsUrl); if (isPublicUrl) { logger.info( - `${config.SUBSTRATE.WS_URL} is a public node. Too many users will overload this public endpoint. Switch to a privately hosted node when possible.` + `${wsUrl} is a public node. Too many users will overload this public endpoint. Switch to a privately hosted node when possible.` ); } // Split the Url to check for 2 things. Secure connection, and if its a local IP. - const splitUrl: string[] = config.SUBSTRATE.WS_URL.split(':'); + const splitUrl: string[] = wsUrl.split(':'); // If its 'ws' its not a secure connection. const isSecure: boolean = splitUrl[0] === 'wss'; // Check if its a local IP. @@ -94,49 +142,7 @@ async function main() { if (!isSecure && !isLocal) { logger.warn( - `Using unencrypted connection to a public node (${config.SUBSTRATE.WS_URL}); All traffic is sent over the internet in cleartext.` + `Using unencrypted connection to a public node (${wsUrl}); All traffic is sent over the internet in cleartext.` ); } - - // Create our App - const app = new App({ - preMiddleware: [json(), middleware.httpLoggerCreate(logger)], - controllers: [ - new controllers.Blocks(api), - new controllers.AccountsStakingPayouts(api), - new controllers.AccountsBalanceInfo(api), - new controllers.AccountsStakingInfo(api), - new controllers.AccountsVestingInfo(api), - new controllers.NodeNetwork(api), - new controllers.NodeVersion(api), - new controllers.NodeTransactionPool(api), - new controllers.RuntimeCode(api), - new controllers.RuntimeSpec(api), - new controllers.RuntimeMetadata(api), - new controllers.TransactionDryRun(api), - new controllers.TransactionMaterial(api), - new controllers.TransactionFeeEstimate(api), - new controllers.TransactionSubmit(api), - new controllers.palletsStakingProgress(api), - new controllers.palletsStorageItem(api), - ], - postMiddleware: [ - middleware.txError, - middleware.httpError, - middleware.error, - middleware.legacyError, - middleware.internalError, - ], - port: config.EXPRESS.PORT, - host: config.EXPRESS.HOST, - }); - - // Start the server - app.listen(); } - -process.on('SIGINT', function () { - console.log('Caught interrupt signal, exiting...'); - process.exit(0); -}); -main().catch(console.log); diff --git a/src/services/blocks/BlocksService.ts b/src/services/blocks/BlocksService.ts index e87f28804..5f7ee8ccb 100644 --- a/src/services/blocks/BlocksService.ts +++ b/src/services/blocks/BlocksService.ts @@ -1,10 +1,9 @@ import { ApiPromise } from '@polkadot/api'; +import { SignedBlockExtended } from '@polkadot/api-derive/type'; import { GenericCall, Struct } from '@polkadot/types'; import { - AccountId, Block, BlockHash, - Digest, DispatchInfo, EventRecord, Hash, @@ -45,11 +44,21 @@ export class BlocksService extends AbstractService { ): Promise { const { api } = this; - const [{ block }, events, validators] = await Promise.all([ - api.rpc.chain.getBlock(hash), - this.fetchEvents(api, hash), - api.query.session.validators.at(hash), - ]); + let block; + let events; + let author; + if (typeof api.query?.session?.validators === 'function') { + [{ author, block }, events] = await Promise.all([ + api.derive.chain.getBlock(hash) as Promise, + this.fetchEvents(api, hash), + ]); + } else { + [{ block }, events] = await Promise.all([ + api.rpc.chain.getBlock(hash), + this.fetchEvents(api, hash), + ]); + } + const authorId = author; const { parentHash, @@ -59,8 +68,6 @@ export class BlocksService extends AbstractService { digest, } = block.header; - const authorId = this.extractAuthor(validators, digest); - const logs = digest.logs.map((log) => { const { type, index, value } = log; @@ -464,33 +471,4 @@ export class BlocksService extends AbstractService { args: newArgs, }; } - - // Almost exact mimic of https://github.com/polkadot-js/api/blob/master/packages/api-derive/src/chain/getHeader.ts#L27 - // but we save a call to `getHeader` by hardcoding the logic here and using the digest from the blocks header. - private extractAuthor( - sessionValidators: AccountId[], - digest: Digest - ): AccountId | undefined { - const [pitem] = digest.logs.filter(({ type }) => type === 'PreRuntime'); - - // extract from the substrate 2.0 PreRuntime digest - if (pitem) { - const [engine, data] = pitem.asPreRuntime; - - return engine.extractAuthor(data, sessionValidators); - } else { - const [citem] = digest.logs.filter( - ({ type }) => type === 'Consensus' - ); - - // extract author from the consensus (substrate 1.0, digest) - if (citem) { - const [engine, data] = citem.asConsensus; - - return engine.extractAuthor(data, sessionValidators); - } - } - - return undefined; - } } diff --git a/src/types/chains-config/ControllerConfig.ts b/src/types/chains-config/ControllerConfig.ts new file mode 100644 index 000000000..7ef94a5f3 --- /dev/null +++ b/src/types/chains-config/ControllerConfig.ts @@ -0,0 +1,8 @@ +import { controllers } from '../../controllers'; + +/** + * Controller mounting configuration as an object where the keys are the + * controller class names and the values are booleans indicating whether or not + * to include the controller. + */ +export type ControllerConfig = Record; diff --git a/src/types/chains-config/index.ts b/src/types/chains-config/index.ts new file mode 100644 index 000000000..3b0112e5c --- /dev/null +++ b/src/types/chains-config/index.ts @@ -0,0 +1 @@ +export * from './ControllerConfig'; diff --git a/src/types/polkadot-js/Codec.ts b/src/types/polkadot-js/Codec.ts index 4ef36ee2e..fd8b7e61a 100644 --- a/src/types/polkadot-js/Codec.ts +++ b/src/types/polkadot-js/Codec.ts @@ -5,8 +5,7 @@ export type { Codec } from '@polkadot/types/types'; export function isCodec(thing: unknown): thing is Codec { // Null errors on .hash access so we do not check for .hash - return ( - thing && + return (thing && (thing as Codec).encodedLength !== undefined && (thing as Codec).registry !== undefined && (thing as Codec).isEmpty !== undefined && @@ -16,6 +15,5 @@ export function isCodec(thing: unknown): thing is Codec { typeof (thing as Codec).toJSON === 'function' && typeof (thing as Codec).toRawType === 'function' && typeof (thing as Codec).toString === 'function' && - typeof (thing as Codec).toU8a === 'function' - ); + typeof (thing as Codec).toU8a === 'function') as boolean; } diff --git a/src/types/config/CONFIG.ts b/src/types/sidecar-config/CONFIG.ts similarity index 100% rename from src/types/config/CONFIG.ts rename to src/types/sidecar-config/CONFIG.ts diff --git a/src/types/config/MODULES.ts b/src/types/sidecar-config/MODULES.ts similarity index 100% rename from src/types/config/MODULES.ts rename to src/types/sidecar-config/MODULES.ts diff --git a/src/types/config/SidecarConfig.ts b/src/types/sidecar-config/SidecarConfig.ts similarity index 100% rename from src/types/config/SidecarConfig.ts rename to src/types/sidecar-config/SidecarConfig.ts diff --git a/src/types/config/index.ts b/src/types/sidecar-config/index.ts similarity index 100% rename from src/types/config/index.ts rename to src/types/sidecar-config/index.ts diff --git a/tsconfig.json b/tsconfig.json index ef5f4b9ad..ba3f3496d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,7 +20,8 @@ "sourceMap": true, "strictNullChecks": true, "suppressImplicitAnyIndexErrors": true, - "target": "es2017" + "target": "es2017", + "skipLibCheck": true }, "typeRoots": [ "./node_modules/@types" diff --git a/yarn.lock b/yarn.lock index 677cc51e2..aed6c184a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,13 @@ # yarn lockfile v1 +"@acala-network/type-definitions@^0.4.0-beta.33": + version "0.4.0-beta.33" + resolved "https://registry.yarnpkg.com/@acala-network/type-definitions/-/type-definitions-0.4.0-beta.33.tgz#6b57fb5c415990ed33806ddf2547f797db125b9c" + integrity sha512-3c5WoUs23d2euM58w55itaiU35+CQrT5v8dOjX+I/Q7bqz0c/Q/qgKsZ22rtzjur18j0unBMbgM6OJSzuOTFQg== + dependencies: + "@open-web3/orml-type-definitions" "^0.6.0-beta.26" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" @@ -10,18 +17,18 @@ "@babel/highlight" "^7.10.4" "@babel/core@^7.1.0", "@babel/core@^7.7.5": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.3.tgz#1b436884e1e3bff6fb1328dc02b208759de92ad8" - integrity sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g== + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.7.tgz#bf55363c08c8352a37691f7216ec30090bf7e3bf" + integrity sha512-tRKx9B53kJe8NCGGIxEQb2Bkr0riUIEuN7Sc1fxhs5H8lKlCWUvQCSNMVIB0Meva7hcbCRJ76de15KoLltdoqw== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.1" + "@babel/generator" "^7.12.5" "@babel/helper-module-transforms" "^7.12.1" - "@babel/helpers" "^7.12.1" - "@babel/parser" "^7.12.3" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" + "@babel/helpers" "^7.12.5" + "@babel/parser" "^7.12.7" + "@babel/template" "^7.12.7" + "@babel/traverse" "^7.12.7" + "@babel/types" "^7.12.7" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" @@ -31,7 +38,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.12.1", "@babel/generator@^7.12.5": +"@babel/generator@^7.12.5": version "7.12.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.5.tgz#a2c50de5c8b6d708ab95be5e6053936c1884a4de" integrity sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A== @@ -57,11 +64,11 @@ "@babel/types" "^7.10.4" "@babel/helper-member-expression-to-functions@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz#fba0f2fcff3fba00e6ecb664bb5e6e26e2d6165c" - integrity sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ== + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz#aa77bd0396ec8114e5e30787efa78599d874a855" + integrity sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw== dependencies: - "@babel/types" "^7.12.1" + "@babel/types" "^7.12.7" "@babel/helper-module-imports@^7.12.1": version "7.12.5" @@ -86,11 +93,11 @@ lodash "^4.17.19" "@babel/helper-optimise-call-expression@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" - integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.7.tgz#7f94ae5e08721a49467346aa04fd22f750033b9c" + integrity sha512-I5xc9oSJ2h59OwyUqjv95HRyzxj53DAubUERgQMrpcCEYQyToeHA+NEcUEsVWB4j53RDeskeBJ0SgRAYHDBckw== dependencies: - "@babel/types" "^7.10.4" + "@babel/types" "^7.12.7" "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0": version "7.10.4" @@ -126,7 +133,7 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== -"@babel/helpers@^7.12.1": +"@babel/helpers@^7.12.5": version "7.12.5" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e" integrity sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA== @@ -144,10 +151,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.12.3", "@babel/parser@^7.12.5": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.5.tgz#b4af32ddd473c0bfa643bd7ff0728b8e71b81ea0" - integrity sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ== +"@babel/parser@^7.1.0", "@babel/parser@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.7.tgz#fee7b39fe809d0e73e5b25eecaf5780ef3d73056" + integrity sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -247,34 +254,34 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.10.4", "@babel/template@^7.3.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" - integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== +"@babel/template@^7.10.4", "@babel/template@^7.12.7", "@babel/template@^7.3.3": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" + integrity sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/parser" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/parser" "^7.12.7" + "@babel/types" "^7.12.7" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.5": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.5.tgz#78a0c68c8e8a35e4cacfd31db8bb303d5606f095" - integrity sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA== +"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.5", "@babel/traverse@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.7.tgz#572a722408681cef17d6b0bef69ef2e728ca69f1" + integrity sha512-nMWaqsQEeSvMNypswUDzjqQ+0rR6pqCtoQpsqGJC4/Khm9cISwPTSpai57F6/jDaOoEGz8yE/WxcO3PV6tKSmQ== dependencies: "@babel/code-frame" "^7.10.4" "@babel/generator" "^7.12.5" "@babel/helper-function-name" "^7.10.4" "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.12.5" - "@babel/types" "^7.12.5" + "@babel/parser" "^7.12.7" + "@babel/types" "^7.12.7" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.19" -"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.12.1", "@babel/types@^7.12.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3": - version "7.12.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.6.tgz#ae0e55ef1cce1fbc881cd26f8234eb3e657edc96" - integrity sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA== +"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.12.1", "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.7.tgz#6039ff1e242640a29452c9ae572162ec9a8f5d13" + integrity sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ== dependencies: "@babel/helper-validator-identifier" "^7.10.4" lodash "^4.17.19" @@ -302,6 +309,11 @@ enabled "2.0.x" kuler "^2.0.0" +"@edgeware/node-types@^3.0.7": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@edgeware/node-types/-/node-types-3.0.10.tgz#1b44af24dd0fdf48c1eedf90a90cda62e8f946aa" + integrity sha512-fQgXhlnNPfRv+xUB/HRqbwt22c+BeofMDQzQ22GwOU8NQBXERhwgA2Hi0z1K3IKMqCtSIQlu1uepuFOQIIqrZQ== + "@eslint/eslintrc@^0.2.1": version "0.2.1" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.2.1.tgz#f72069c330461a06684d119384435e12a5d76e3c" @@ -505,6 +517,13 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@laminar/type-definitions@^0.2.0-beta.141": + version "0.2.0-beta.143" + resolved "https://registry.yarnpkg.com/@laminar/type-definitions/-/type-definitions-0.2.0-beta.143.tgz#a4dd18ac34addfeb451dbd3aea789d0976c34c27" + integrity sha512-9CanpyDiQC+XFpc6K70T7pN5qS2uclIUImuNKDgWdV/dbviQnFz5PgZurYsdSCSvOGStjsoRY84SU/S8eCmTLg== + dependencies: + "@open-web3/orml-type-definitions" "^0.6.0-beta.26" + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -526,132 +545,149 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" -"@polkadot/api-derive@2.7.1": - version "2.7.1" - resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-2.7.1.tgz#d4927e2e9579074466da8613953fd460b1f33466" - integrity sha512-tQboJ7VgbHU2lMGxxbsWVZjzS5735cFQKRB036d7or1m4sgyD8cPWopPOo3jyytPmHfuYF0Ni44ZppQeapDxGg== +"@open-web3/orml-type-definitions@^0.6.0-beta.26": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@open-web3/orml-type-definitions/-/orml-type-definitions-0.6.1.tgz#eb7fadf598f24f5024f5d2a1fd39ccc97c801104" + integrity sha512-6asf2W/sluGQ6LNiGSdCg/Xop54mq/Q2FcV2Z9cBxys6QC4qXfo4JwUL6kJsRh/vcIIbUxoyGgKUrU/6Xdm7wA== + +"@polkadot/api-derive@2.8.1": + version "2.8.1" + resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-2.8.1.tgz#e997625e95dce217087ff14199116d3520c7bf19" + integrity sha512-5oJ7V7yRHHSSnWQ/l3MQQ8+ki/g+v4NbqgI/FTOIUQl7Ja1lPwjKYpqXgP7EGob+pcdFj6VRqywzAOkVA730tw== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/api" "2.7.1" - "@polkadot/rpc-core" "2.7.1" - "@polkadot/types" "2.7.1" - "@polkadot/util" "^4.1.1" - "@polkadot/util-crypto" "^4.1.1" - bn.js "^5.1.3" + "@polkadot/api" "2.8.1" + "@polkadot/rpc-core" "2.8.1" + "@polkadot/types" "2.8.1" + "@polkadot/util" "^4.2.1" + "@polkadot/util-crypto" "^4.2.1" + bn.js "^4.11.9" memoizee "^0.4.14" rxjs "^6.6.3" -"@polkadot/api@2.7.1", "@polkadot/api@^2.7.1": - version "2.7.1" - resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-2.7.1.tgz#3eb0ae7eecd342a68a68ed6cf082d6c73d0b6281" - integrity sha512-xgaLsv/qRTjRfSvFBgm9h9+gXK5pYn2iqlWPndvYSM/IaUZWAQPVWL1uGnrEbEFjHvpi6Fe28wsw+QCM8rBxew== +"@polkadot/api@2.8.1", "@polkadot/api@^2.8.1": + version "2.8.1" + resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-2.8.1.tgz#1259260b54723788fb48a2ea4e1d25cd6b9c4b38" + integrity sha512-IvR8aTUzd3759tJVkHEsnpXqdvv72mTkST3poO2/v30GusqTH6KQDWhQy7MhgYjElk9hLIPZRsmA62WVOlSG2Q== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/api-derive" "2.7.1" - "@polkadot/keyring" "^4.1.1" - "@polkadot/metadata" "2.7.1" - "@polkadot/rpc-core" "2.7.1" - "@polkadot/rpc-provider" "2.7.1" - "@polkadot/types" "2.7.1" - "@polkadot/types-known" "2.7.1" - "@polkadot/util" "^4.1.1" - "@polkadot/util-crypto" "^4.1.1" - bn.js "^5.1.3" + "@polkadot/api-derive" "2.8.1" + "@polkadot/keyring" "^4.2.1" + "@polkadot/metadata" "2.8.1" + "@polkadot/rpc-core" "2.8.1" + "@polkadot/rpc-provider" "2.8.1" + "@polkadot/types" "2.8.1" + "@polkadot/types-known" "2.8.1" + "@polkadot/util" "^4.2.1" + "@polkadot/util-crypto" "^4.2.1" + bn.js "^4.11.9" eventemitter3 "^4.0.7" rxjs "^6.6.3" -"@polkadot/keyring@^4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-4.1.1.tgz#bc5e66a42df4146bb67581665afee637df7fba12" - integrity sha512-qKNdaqaohIFwarJEU9XIium5ObzbFCi4Y5cO4JmVfWf+hwcAkeVOEFcz/cGkpIVUQhEHDlvEEoqesd5c1+LC4A== +"@polkadot/apps-config@^0.68.1": + version "0.68.1" + resolved "https://registry.yarnpkg.com/@polkadot/apps-config/-/apps-config-0.68.1.tgz#ae3ad6cb8b6c34ca7aab8a3bc6923e6fbabe7af3" + integrity sha512-MSWqpVuZxMw3Fnzwakbf7ODAiB9BvjOWJS48sUTnZg1Obbp/vBAEZteBUkgEBSwuBupju9DjXkVXeJw8OU7WHA== dependencies: + "@acala-network/type-definitions" "^0.4.0-beta.33" "@babel/runtime" "^7.12.5" - "@polkadot/util" "4.1.1" - "@polkadot/util-crypto" "4.1.1" + "@edgeware/node-types" "^3.0.7" + "@laminar/type-definitions" "^0.2.0-beta.141" + "@polkadot/networks" "^4.2.1" + "@subsocial/types" "^0.4.7" -"@polkadot/metadata@2.7.1": - version "2.7.1" - resolved "https://registry.yarnpkg.com/@polkadot/metadata/-/metadata-2.7.1.tgz#ad2daf41e2efc21c6c83b2a15469ac40ccb896e7" - integrity sha512-lrBYZApKW9iCrZjrfrcuVjM857YIHdmHwJa/Z6QgS7MTGR+8modEKBKs+4hoyMN+NumYAYrHBwzcE2B3mINDyA== +"@polkadot/keyring@^4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-4.2.1.tgz#34bf18ae8cb5822f2ea522c8db62dd0086725ffa" + integrity sha512-8kH8jXSIA3I2Gn96o7KjGoLBa7fmc2iB/VKOmEEcMCgJR32HyE8YbeXwc/85OQCheQjG4rJA3RxPQ4CsTsjO7w== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/types" "2.7.1" - "@polkadot/types-known" "2.7.1" - "@polkadot/util" "^4.1.1" - "@polkadot/util-crypto" "^4.1.1" - bn.js "^5.1.3" + "@polkadot/util" "4.2.1" + "@polkadot/util-crypto" "4.2.1" -"@polkadot/networks@4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-4.1.1.tgz#26a10d58117a2a9e0e538a040446056e43352424" - integrity sha512-OqV4YCiWmUZIm82TdKDbjAhTF+paxko5k7bw0OGRIizmA00CNNRLR2q9SI9ux1InvYuL+zZsTOJAoJ5FxMHzgA== +"@polkadot/metadata@2.8.1": + version "2.8.1" + resolved "https://registry.yarnpkg.com/@polkadot/metadata/-/metadata-2.8.1.tgz#2cb64aa99d7cc99efebf5c25344c0e5d748af575" + integrity sha512-tJ+hTXsvve1f2pziPGp/nELK+W/xvMsc2xGgoVwccxv1mPFNSny8RPDl7Wgmli0PPztXG6eBnLvWt4FXYnp7vA== + dependencies: + "@babel/runtime" "^7.12.5" + "@polkadot/types" "2.8.1" + "@polkadot/types-known" "2.8.1" + "@polkadot/util" "^4.2.1" + "@polkadot/util-crypto" "^4.2.1" + bn.js "^4.11.9" + +"@polkadot/networks@4.2.1", "@polkadot/networks@^4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-4.2.1.tgz#b0ca69807ed60189f1c958bb27cfeb3cb1c6b12b" + integrity sha512-T1tg0V0uG09Vdce2O4KfEcWO3/fZh4VYt0bmJ6iPwC+x6yv939X2BKvuFTDDVNT3fqBpGzWQlwiTXYQ15o9bGA== dependencies: "@babel/runtime" "^7.12.5" -"@polkadot/rpc-core@2.7.1": - version "2.7.1" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-2.7.1.tgz#4a51f2099019faeaf8d710d02a7855ec58f3f378" - integrity sha512-5TA+EZ1sWDwgrfFoMc4SsEwHo9ivO/wfPZsxNixHw1wL68y+3G4pG1YLztcKF//Qp35nOz4JGyX+lNuU3BPXdw== +"@polkadot/rpc-core@2.8.1": + version "2.8.1" + resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-2.8.1.tgz#f569be6e73bb17cbb61d7b79b12c300095bf2535" + integrity sha512-tMSH2D5wu28UMhLIjWxZ7br0HRC0T7crYu/BSBE8m3GzLJU4mwsygn2VLDVxQOz4DvHvWh+xQzd2QFc/z02SQw== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/metadata" "2.7.1" - "@polkadot/rpc-provider" "2.7.1" - "@polkadot/types" "2.7.1" - "@polkadot/util" "^4.1.1" + "@polkadot/metadata" "2.8.1" + "@polkadot/rpc-provider" "2.8.1" + "@polkadot/types" "2.8.1" + "@polkadot/util" "^4.2.1" memoizee "^0.4.14" rxjs "^6.6.3" -"@polkadot/rpc-provider@2.7.1": - version "2.7.1" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-2.7.1.tgz#dd2515648a70665ecd2b56adcc30e8804ed225d4" - integrity sha512-AOS9RfYm8aFuvYo1Bd/SX9eHQJlWbW9IYwNqHLOfXmLRxbIkfVzsc49tCsr+Zy1Ctt/d5bA86P5cUdH0LI0acg== +"@polkadot/rpc-provider@2.8.1": + version "2.8.1" + resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-2.8.1.tgz#c2be0def70d7850deb077813b3d6790c440706e2" + integrity sha512-PtLZcbNMx6+sN04f4T+j3fqJPYG3qsPX+k1DU5FFDUZ3GVRphfyXmswjbwmH9nkCyr04eBGLb1M1EipsqiP8Ig== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/types" "2.7.1" - "@polkadot/util" "^4.1.1" - "@polkadot/util-crypto" "^4.1.1" - "@polkadot/x-fetch" "^4.1.1" - "@polkadot/x-ws" "^4.1.1" - bn.js "^5.1.3" + "@polkadot/types" "2.8.1" + "@polkadot/util" "^4.2.1" + "@polkadot/util-crypto" "^4.2.1" + "@polkadot/x-fetch" "^4.2.1" + "@polkadot/x-ws" "^4.2.1" + bn.js "^4.11.9" eventemitter3 "^4.0.7" -"@polkadot/types-known@2.7.1": - version "2.7.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-2.7.1.tgz#bb6edef252a6ab83cf4088848d68fa56d004902c" - integrity sha512-cnrRJ7HV/ICWwoxNv0cKZZ5EVmPMOnLrcoC1SQYANkOjpxVdloxPdkr+1i6trPJhXntxwRvdFIYqKiAtsfMrGw== +"@polkadot/types-known@2.8.1": + version "2.8.1" + resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-2.8.1.tgz#e1645154218af19837f9c82c3f0f35730258f555" + integrity sha512-aTriYfu5l8Fz73Ti8rT0q2DfwMIk4eLTqb3VBDR21XcAbjVxZHc24jdhnnnbc6RxvGOg2ertrN9fTz3xhvtPyg== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/types" "2.7.1" - "@polkadot/util" "^4.1.1" - bn.js "^5.1.3" + "@polkadot/types" "2.8.1" + "@polkadot/util" "^4.2.1" + bn.js "^4.11.9" -"@polkadot/types@2.7.1": - version "2.7.1" - resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-2.7.1.tgz#f3cac7bba7fa7d1d3d7bd3e474b4ef776526e82f" - integrity sha512-v7vHozNZxz+pSlQnjogtUwzsNU3E5sZ7+oQipFS/S2zXz2Q8K1QOUE08thZTqR5M4cyPDbbD5sHBaSNOMk5X1Q== +"@polkadot/types@2.8.1": + version "2.8.1" + resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-2.8.1.tgz#8904c757b56b0f85569c11d16fedfa465a39dafd" + integrity sha512-D7K2wG7xytkMJ0s6W/JwzU4LPiQdFThqmRY+kXdbXrYF1UdiUkiS5MMjUUG9CseRITYUigtF6D6B/PiOv9zupQ== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/metadata" "2.7.1" - "@polkadot/util" "^4.1.1" - "@polkadot/util-crypto" "^4.1.1" + "@polkadot/metadata" "2.8.1" + "@polkadot/util" "^4.2.1" + "@polkadot/util-crypto" "^4.2.1" "@types/bn.js" "^4.11.6" - bn.js "^5.1.3" + bn.js "^4.11.9" memoizee "^0.4.14" rxjs "^6.6.3" -"@polkadot/util-crypto@4.1.1", "@polkadot/util-crypto@^4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-4.1.1.tgz#b3f9a03c7ad785e72d7a777cdfd76193635f290a" - integrity sha512-LuA75GZqT1Lpx+RwMljoqNl0lPrfyDt9hUByGhzHQ0OjcaOzrcrzsmDYqFgz0ec8dg9KpNcbZM9CMI7r7mZ9cg== +"@polkadot/util-crypto@4.2.1", "@polkadot/util-crypto@^4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-4.2.1.tgz#a342cd6b400c69ed61cd929917030ed2f43c59d1" + integrity sha512-U1rCdzBQxVTA854HRpt2d4InDnPCfHD15JiWAwIzjBvq7i59EcTbVSqV02fcwet/KpmT3XYa25xoiff+alzCBA== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/networks" "4.1.1" - "@polkadot/util" "4.1.1" + "@polkadot/networks" "4.2.1" + "@polkadot/util" "4.2.1" "@polkadot/wasm-crypto" "^2.0.1" - "@polkadot/x-randomvalues" "4.1.1" + "@polkadot/x-randomvalues" "4.2.1" base-x "^3.0.8" blakejs "^1.1.0" - bn.js "^5.1.3" + bn.js "^4.11.9" create-hash "^1.2.0" elliptic "^6.5.3" hash.js "^1.1.7" @@ -660,16 +696,16 @@ tweetnacl "^1.0.3" xxhashjs "^0.2.2" -"@polkadot/util@4.1.1", "@polkadot/util@^4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-4.1.1.tgz#76668d5f0e00c396d6b6f4ba652348d287ad49c2" - integrity sha512-bmXMXq4WKKkowgzgRzCgkWNzu8tT/F4P+cBBlVReOH1UD1AmUG80coD/uIL+kUhLpQVN3xXtdXHIxFQcfK3qKA== +"@polkadot/util@4.2.1", "@polkadot/util@^4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-4.2.1.tgz#1845d03be7e418a14ec2ef929d6288f326f2145d" + integrity sha512-eO/IFbSDjqVPPWPnARDFydy2Kt992Th+8ByleTkCRqWk0aNYaseO1pGKNdwrYbLfUR3JlyWqvJ60lITeS+qAfQ== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/x-textdecoder" "4.1.1" - "@polkadot/x-textencoder" "4.1.1" + "@polkadot/x-textdecoder" "4.2.1" + "@polkadot/x-textencoder" "4.2.1" "@types/bn.js" "^4.11.6" - bn.js "^5.1.3" + bn.js "^4.11.9" camelcase "^5.3.1" ip-regex "^4.2.0" @@ -678,40 +714,40 @@ resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-2.0.1.tgz#cf7384385f832f6389520cc00e52a87fda6f29b6" integrity sha512-Vb0q4NToCRHXYJwhLWc4NTy77+n1dtJmkiE1tt8j1pmY4IJ4UL25yBxaS8NCS1LGqofdUYK1wwgrHiq5A78PFA== -"@polkadot/x-fetch@^4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-4.1.1.tgz#b03083d926da42596fb01871f17912308a34529e" - integrity sha512-pja/3bVqppEh/c/Dv9fXTeVDpsRPr7Il8ADw8qyHKQzYhE3qfrcnje1XV78xiaeCwBJMXL33KbaI/Vs0hc/eSw== +"@polkadot/x-fetch@^4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-4.2.1.tgz#6cd157da6f98f97395c3f01849ccdd3de23ee44f" + integrity sha512-dfVYvCQQXo2AgoWPi4jQp47eIMjAi6glQQ8Y1OsK4sCqmX7BSkNl9ONUKQuH27oi0BkJ/BL7fwDg55JeB5QrKg== dependencies: "@babel/runtime" "^7.12.5" "@types/node-fetch" "^2.5.7" node-fetch "^2.6.1" -"@polkadot/x-randomvalues@4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-4.1.1.tgz#cbcd5b591a3d5c7dc3853e51edc5e20239bf3b25" - integrity sha512-q1UCOYmYSOIjp97qH+Jw6mtaoaqb65I2R/aKOtd5NDyls0lLq4ctv5YQ8jLTvNrGum8aEKE8ZmYuBuZSQXICPw== +"@polkadot/x-randomvalues@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-4.2.1.tgz#91fd272f8bb79a59b20055a4514f944888a6ee76" + integrity sha512-eOfz/KnHYFVl9l0zlhlwomKMzFASgolaQV6uXSN38np+99/+F38wlbOSXFbfZ5H3vmMCt4y/UUTLtoGV/44yLg== dependencies: "@babel/runtime" "^7.12.5" -"@polkadot/x-textdecoder@4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-4.1.1.tgz#9bdc94ca962b6f7d931c827e8316cd09fc751aff" - integrity sha512-I0u3ymy2wAoi3zaycmBu8HqGudp4nMGKqSGasSB1ko9SKtB++JsWKH99it721rpeSdFXJOpBERQjvapCQXK6sQ== +"@polkadot/x-textdecoder@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-4.2.1.tgz#c2fe9f5da9498d982f8fd9244a52e039c0f0dacc" + integrity sha512-B5t20PryMKr7kdd7q+kmzJPU01l28ZDD06cQ/ZFkybI7avI6PIz/U33ctXxiHOatbBRO6Ez8uzrWd3JmaQ2bGQ== dependencies: "@babel/runtime" "^7.12.5" -"@polkadot/x-textencoder@4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-4.1.1.tgz#828e08895fbb7c29db7ce81d63e2d93ca7750660" - integrity sha512-yhDwo2Dy835+OYk5clNVJ0VGGtu6zC9Uw0tDp9BSDSVrb1gZGrhAEGTtvTG8JM4qPJ/XBTaaN9Ul2rnk0VIiOA== +"@polkadot/x-textencoder@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-4.2.1.tgz#cf6b92d7de0fb2dde8314e0f359dd83dc9f25036" + integrity sha512-EHc6RS9kjdP28q6EYlSgHF2MrJCdOTc5EVlqHL7V1UKLh3vD6QaWGYBwbzXNFPXO3RYPO/DKYCu4RxAVSM1OOg== dependencies: "@babel/runtime" "^7.12.5" -"@polkadot/x-ws@^4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-4.1.1.tgz#b5ba15d5f0cd36d1a8cc03c15d4ce661633c55be" - integrity sha512-SgNOgxOLsxCUC5g/G7j11rJfHuFkHR3LIMniB1GvkS87SWkbhftwPPgWOwdGOxxy2L3Ud7t4/4wnlUV+cmRcDA== +"@polkadot/x-ws@^4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-4.2.1.tgz#f160a0c61227419b1d7da623a72ce21063ef69ee" + integrity sha512-7L1ve2rshBFI/00/0zkX1k0OP/rSD6Tp0Mj/GSg2UvnsmUb2Bb3OpwUJ4aTDr1En6OVGWj9c0fNO0tZR7rtoYA== dependencies: "@babel/runtime" "^7.12.5" "@types/websocket" "^1.0.1" @@ -731,6 +767,27 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@subsocial/types@^0.4.7": + version "0.4.23" + resolved "https://registry.yarnpkg.com/@subsocial/types/-/types-0.4.23.tgz#c1a5a5628e991fd91e74e5f20297cad63b8c5b84" + integrity sha512-O4rZP4rzznnEOtbgpQlTqcN/NJtYGFymPV/0pTladW471nawELuLlzxImP4ytH5/XWOXl4bdWJ1lcuukzkfOVQ== + dependencies: + "@subsocial/utils" latest + cids "^0.7.1" + +"@subsocial/utils@latest": + version "0.4.23" + resolved "https://registry.yarnpkg.com/@subsocial/utils/-/utils-0.4.23.tgz#592714cc3cfb81c7ec38fe0ad15c69ae5b9f1de0" + integrity sha512-53PSVvyjDdP3cxgbXscQ8n85PWMD96V7zel+p3o6Qj1hl7Ad+jxwpJNsR35sat63NnbJWeUwvG+y7NZG6vJOmg== + dependencies: + bn.js "^5.1.1" + chalk "^3.0.0" + dotenv "^8.0.0" + lodash.isempty "^4.4.0" + lodash.truncate "^4.4.2" + loglevel "^1.7.0" + loglevel-plugin-prefix "^0.8.4" + "@substrate/calc@^0.1.2": version "0.1.2" resolved "https://registry.yarnpkg.com/@substrate/calc/-/calc-0.1.2.tgz#7004563c04a268ecacebcba2be78a55fd44e42fa" @@ -880,9 +937,9 @@ form-data "^3.0.0" "@types/node@*": - version "14.14.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.7.tgz#8ea1e8f8eae2430cf440564b98c6dfce1ec5945d" - integrity sha512-Zw1vhUSQZYw+7u5dAwNbIA9TuTotpzY/OF7sJM9FqPOF3SPjKnxrjoTktXDZgUjybf4cWVBP7O8wvKdSaGHweg== + version "14.14.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.9.tgz#04afc9a25c6ff93da14deabd65dc44485b53c8d6" + integrity sha512-JsoLXFppG62tWTklIoO4knA+oDTYsmqWxHRvd4lpmfQRNhX6osheUOWETP2jMoV/2bEHuMra8Pp3Dmo/stBFcw== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -905,9 +962,9 @@ integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== "@types/serve-static@*": - version "1.13.7" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.7.tgz#e51b51a0becda910f9fd04c718044da69d6c492e" - integrity sha512-3diZWucbR+xTmbDlU+FRRxBf+31OhFew7cJXML/zh9NmvSPTNoFecAwHB66BUqFgENJtqMiyl7JAwUE/siqdLw== + version "1.13.8" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.8.tgz#851129d434433c7082148574ffec263d58309c46" + integrity sha512-MoJhSQreaVoL+/hurAZzIm8wafFR6ajiTM1m4A0kv6AGeVBl4r4pOV8bGFrjjq1sGxDTnCoF8i22o0/aE5XCyA== dependencies: "@types/mime" "*" "@types/node" "*" @@ -942,67 +999,67 @@ integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== "@types/yargs@^15.0.0": - version "15.0.9" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.9.tgz#524cd7998fe810cdb02f26101b699cccd156ff19" - integrity sha512-HmU8SeIRhZCWcnRskCs36Q1Q00KBV6Cqh/ora8WN1+22dY07AZdn6Gel8QZ3t26XYPImtcL8WV/eqjhVmMEw4g== + version "15.0.10" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.10.tgz#0fe3c8173a0d5c3e780b389050140c3f5ea6ea74" + integrity sha512-z8PNtlhrj7eJNLmrAivM7rjBESG6JwC5xP3RVk12i/8HVP7Xnx/sEmERnRImyEuUaJfO942X0qMOYsoupaJbZQ== dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^4.7.0": - version "4.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.7.0.tgz#85c9bbda00c0cb604d3c241f7bc7fb171a2d3479" - integrity sha512-li9aiSVBBd7kU5VlQlT1AqP0uWGDK6JYKUQ9cVDnOg34VNnd9t4jr0Yqc/bKxJr/tDCPDaB4KzoSFN9fgVxe/Q== +"@typescript-eslint/eslint-plugin@^4.8.2": + version "4.8.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.8.2.tgz#cf9102ec800391caa574f589ffe0623cca1d9308" + integrity sha512-gQ06QLV5l1DtvYtqOyFLXD9PdcILYqlrJj2l+CGDlPtmgLUzc1GpqciJFIRvyfvgLALpnxYINFuw+n9AZhPBKQ== dependencies: - "@typescript-eslint/experimental-utils" "4.7.0" - "@typescript-eslint/scope-manager" "4.7.0" + "@typescript-eslint/experimental-utils" "4.8.2" + "@typescript-eslint/scope-manager" "4.8.2" debug "^4.1.1" functional-red-black-tree "^1.0.1" regexpp "^3.0.0" semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@4.7.0": - version "4.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.7.0.tgz#8d1058c38bec3d3bbd9c898a1c32318d80faf3c5" - integrity sha512-cymzovXAiD4EF+YoHAB5Oh02MpnXjvyaOb+v+BdpY7lsJXZQN34oIETeUwVT2XfV9rSNpXaIcknDLfupO/tUoA== +"@typescript-eslint/experimental-utils@4.8.2": + version "4.8.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.8.2.tgz#8909a5732f19329cf5ef0c39766170476bff5e50" + integrity sha512-hpTw6o6IhBZEsQsjuw/4RWmceRyESfAiEzAEnXHKG1X7S5DXFaZ4IO1JO7CW1aQ604leQBzjZmuMI9QBCAJX8Q== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.7.0" - "@typescript-eslint/types" "4.7.0" - "@typescript-eslint/typescript-estree" "4.7.0" + "@typescript-eslint/scope-manager" "4.8.2" + "@typescript-eslint/types" "4.8.2" + "@typescript-eslint/typescript-estree" "4.8.2" eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/parser@^4.7.0": - version "4.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.7.0.tgz#44bdab0f788b478178368baa65d3365fdc63da1c" - integrity sha512-+meGV8bMP1sJHBI2AFq1GeTwofcGiur8LoIr6v+rEmD9knyCqDlrQcFHR0KDDfldHIFDU/enZ53fla6ReF4wRw== +"@typescript-eslint/parser@^4.8.2": + version "4.8.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.8.2.tgz#78dccbe5124de2b8dea2d4c363dee9f769151ca8" + integrity sha512-u0leyJqmclYr3KcXOqd2fmx6SDGBO0MUNHHAjr0JS4Crbb3C3d8dwAdlazy133PLCcPn+aOUFiHn72wcuc5wYw== dependencies: - "@typescript-eslint/scope-manager" "4.7.0" - "@typescript-eslint/types" "4.7.0" - "@typescript-eslint/typescript-estree" "4.7.0" + "@typescript-eslint/scope-manager" "4.8.2" + "@typescript-eslint/types" "4.8.2" + "@typescript-eslint/typescript-estree" "4.8.2" debug "^4.1.1" -"@typescript-eslint/scope-manager@4.7.0": - version "4.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.7.0.tgz#2115526085fb72723ccdc1eeae75dec7126220ed" - integrity sha512-ILITvqwDJYbcDCROj6+Ob0oCKNg3SH46iWcNcTIT9B5aiVssoTYkhKjxOMNzR1F7WSJkik4zmuqve5MdnA0DyA== +"@typescript-eslint/scope-manager@4.8.2": + version "4.8.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.8.2.tgz#a18388c63ae9c17adde519384f539392f2c4f0d9" + integrity sha512-qHQ8ODi7mMin4Sq2eh/6eu03uVzsf5TX+J43xRmiq8ujng7ViQSHNPLOHGw/Wr5dFEoxq/ubKhzClIIdQy5q3g== dependencies: - "@typescript-eslint/types" "4.7.0" - "@typescript-eslint/visitor-keys" "4.7.0" + "@typescript-eslint/types" "4.8.2" + "@typescript-eslint/visitor-keys" "4.8.2" -"@typescript-eslint/types@4.7.0": - version "4.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.7.0.tgz#5e95ef5c740f43d942542b35811f87b62fccca69" - integrity sha512-uLszFe0wExJc+I7q0Z/+BnP7wao/kzX0hB5vJn4LIgrfrMLgnB2UXoReV19lkJQS1a1mHWGGODSxnBx6JQC3Sg== +"@typescript-eslint/types@4.8.2": + version "4.8.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.8.2.tgz#c862dd0e569d9478eb82d6aee662ea53f5661a36" + integrity sha512-z1/AVcVF8ju5ObaHe2fOpZYEQrwHyZ7PTOlmjd3EoFeX9sv7UekQhfrCmgUO7PruLNfSHrJGQvrW3Q7xQ8EoAw== -"@typescript-eslint/typescript-estree@4.7.0": - version "4.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.7.0.tgz#539531167f05ba20eb0b6785567076679e29d393" - integrity sha512-5XZRQznD1MfUmxu1t8/j2Af4OxbA7EFU2rbo0No7meb46eHgGkSieFdfV6omiC/DGIBhH9H9gXn7okBbVOm8jw== +"@typescript-eslint/typescript-estree@4.8.2": + version "4.8.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.8.2.tgz#eeec34707d8577600fb21661b5287226cc8b3bed" + integrity sha512-HToGNwI6fekH0dOw3XEVESUm71Onfam0AKin6f26S2FtUmO7o3cLlWgrIaT1q3vjB3wCTdww3Dx2iGq5wtUOCg== dependencies: - "@typescript-eslint/types" "4.7.0" - "@typescript-eslint/visitor-keys" "4.7.0" + "@typescript-eslint/types" "4.8.2" + "@typescript-eslint/visitor-keys" "4.8.2" debug "^4.1.1" globby "^11.0.1" is-glob "^4.0.1" @@ -1010,12 +1067,12 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/visitor-keys@4.7.0": - version "4.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.7.0.tgz#6783824f22acfc49e754970ed21b88ac03b80e6f" - integrity sha512-aDJDWuCRsf1lXOtignlfiPODkzSxxop7D0rZ91L6ZuMlcMCSh0YyK+gAfo5zN/ih6WxMwhoXgJWC3cWQdaKC+A== +"@typescript-eslint/visitor-keys@4.8.2": + version "4.8.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.8.2.tgz#62cd3fbbbf65f8eccfbe6f159eb1b84a243a3f77" + integrity sha512-Vg+/SJTMZJEKKGHW7YC21QxgKJrSbxoYYd3MEUGtW7zuytHuEcksewq0DUmo4eh/CTNrVJGSdIY9AtRb6riWFw== dependencies: - "@typescript-eslint/types" "4.7.0" + "@typescript-eslint/types" "4.8.2" eslint-visitor-keys "^2.0.0" JSONStream@^1.0.4: @@ -1301,6 +1358,11 @@ base-x@^3.0.8: dependencies: safe-buffer "^5.0.1" +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" @@ -1326,12 +1388,12 @@ blakejs@^1.1.0: resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.0.tgz#69df92ef953aa88ca51a32df6ab1c54a155fc7a5" integrity sha1-ad+S75U6qIylGjLfarHFShVfx6U= -bn.js@^4.4.0: +bn.js@^4.11.9, bn.js@^4.4.0: version "4.11.9" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== -bn.js@^5.1.3: +bn.js@^5.1.1: version "5.1.3" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== @@ -1412,6 +1474,14 @@ buffer-from@1.x, buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +buffer@^5.5.0, buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + bufferutil@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.2.tgz#79f68631910f6b993d870fc77dc0a2894eb96cd5" @@ -1519,6 +1589,14 @@ chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + char-regex@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" @@ -1529,6 +1607,17 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +cids@^0.7.1: + version "0.7.5" + resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" + integrity sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA== + dependencies: + buffer "^5.5.0" + class-is "^1.1.0" + multibase "~0.6.0" + multicodec "^1.0.0" + multihashes "~0.4.15" + cipher-base@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -1542,6 +1631,11 @@ cjs-module-lexer@^0.6.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz#4186fcca0eae175970aee870b9fe2d6cf8d5655f" integrity sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw== +class-is@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" + integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -2006,9 +2100,9 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3: ms "2.0.0" debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" - integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" @@ -2130,7 +2224,7 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" -dotenv@8.2.0: +dotenv@8.2.0, dotenv@^8.0.0: version "8.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== @@ -2297,10 +2391,10 @@ eslint-plugin-prettier@^3.1.4: dependencies: prettier-linter-helpers "^1.0.0" -eslint-plugin-simple-import-sort@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-6.0.0.tgz#036346edede70afab8928cc4c4b5ae3bd8db7f01" - integrity sha512-YEx+2Zli3mw4mzLzotZSeor4GqdjFWv6S7LcQeKsoXWD4GzMtP42WCz40kAlB35ehxf7PR5V/4f8g8l9aqWGsg== +eslint-plugin-simple-import-sort@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-6.0.1.tgz#24a3af3b745dcd389c060db28e22d0f5e3edf86e" + integrity sha512-RfFnoi7fQtv7z9sZNJidIcZgWc0ZJe8uOPC3ldmatai4Igr5iDpzTmSUDEZKYm4TnrR01N0X32kfKvax7bivHQ== eslint-scope@^5.0.0, eslint-scope@^5.1.1: version "5.1.1" @@ -2327,10 +2421,10 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint@^7.13.0: - version "7.13.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.13.0.tgz#7f180126c0dcdef327bfb54b211d7802decc08da" - integrity sha512-uCORMuOO8tUzJmsdRtrvcGq5qposf7Rw0LwkTJkoDbOycVQtQjmnhZSuLQnozLE4TmAzlMVV45eCHmQ1OpDKUQ== +eslint@^7.14.0: + version "7.14.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.14.0.tgz#2d2cac1d28174c510a97b377f122a5507958e344" + integrity sha512-5YubdnPXrlrYAFCKybPuHIAH++PINe1pmKNc5wQRB9HSbqIK1ywAnntE3Wwua4giKu0bjligf1gLF6qxMGOYRA== dependencies: "@babel/code-frame" "^7.0.0" "@eslint/eslintrc" "^0.2.1" @@ -3166,6 +3260,11 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -4121,6 +4220,11 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= +lodash.isempty@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" + integrity sha1-b4bL7di+TsmHvpqvM8loTbGzHn4= + lodash.ismatch@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" @@ -4151,6 +4255,11 @@ lodash.templatesettings@^4.0.0: dependencies: lodash._reinterpolate "^3.0.0" +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" @@ -4167,6 +4276,16 @@ logform@^2.2.0: ms "^2.1.1" triple-beam "^1.3.0" +loglevel-plugin-prefix@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz#2fe0e05f1a820317d98d8c123e634c1bd84ff644" + integrity sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g== + +loglevel@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.0.tgz#728166855a740d59d38db01cf46f042caa041bb0" + integrity sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ== + loud-rejection@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" @@ -4486,6 +4605,39 @@ ms@2.1.2, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +multibase@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.7.0.tgz#1adfc1c50abe05eefeb5091ac0c2728d6b84581b" + integrity sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multibase@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" + integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multicodec@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-1.0.4.tgz#46ac064657c40380c28367c90304d8ed175a714f" + integrity sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg== + dependencies: + buffer "^5.6.0" + varint "^5.0.0" + +multihashes@~0.4.15: + version "0.4.21" + resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.21.tgz#dc02d525579f334a7909ade8a122dabb58ccfcb5" + integrity sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw== + dependencies: + buffer "^5.5.0" + multibase "^0.7.0" + varint "^5.0.0" + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -4722,9 +4874,9 @@ optionator@^0.9.1: word-wrap "^1.2.3" p-each-series@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.1.0.tgz#961c8dd3f195ea96c747e636b262b800a6b1af48" - integrity sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" + integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA== p-finally@^1.0.0: version "1.0.0" @@ -4966,10 +5118,10 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.1.2.tgz#3050700dae2e4c8b67c4c3f666cdb8af405e1ce5" - integrity sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg== +prettier@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.0.tgz#8a03c7777883b29b37fb2c4348c66a78e980418b" + integrity sha512-yYerpkvseM4iKD/BXLYUkQV5aKt4tQPqaGW6EsZjzyu0r7sVZZNPJW4Y8MyKmicp6t42XUPcBVA+H6sB3gqndw== pretty-format@^26.0.0, pretty-format@^26.6.2: version "26.6.2" @@ -6216,15 +6368,15 @@ typescript@3.9.6: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.6.tgz#8f3e0198a34c3ae17091b35571d3afd31999365a" integrity sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw== -typescript@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.5.tgz#ae9dddfd1069f1cb5beb3ef3b2170dd7c1332389" - integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ== +typescript@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.2.tgz#6369ef22516fe5e10304aae5a5c4862db55380e9" + integrity sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ== uglify-js@^3.1.4: - version "3.11.6" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.11.6.tgz#144b50d3e05eadd3ad4dd047c60ca541a8cd4e9c" - integrity sha512-oASI1FOJ7BBFkSCNDZ446EgkSuHkOZBuqRFrwXIKWCoXw8ZXQETooTQjkAcBS03Acab7ubCKsXnwuV2svy061g== + version "3.12.0" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.12.0.tgz#b943f129275c41d435eb54b643bbffee71dccf57" + integrity sha512-8lBMSkFZuAK7gGF8LswsXmir8eX8d2AAMOnxSDWjKBx/fBR6MypQjs78m6ML9zQVp1/hD4TBdfeMZMC7nW1TAA== union-value@^1.0.0: version "1.0.1" @@ -6315,6 +6467,11 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +varint@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" + integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" From 5d254dd874d556c086f16f1a946152b64e846973 Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Mon, 23 Nov 2020 16:34:27 -0800 Subject: [PATCH 02/22] Update mock api to include derive getBlock - specs work --- package.json | 1 - src/services/blocks/BlocksService.spec.ts | 4 ++-- src/services/blocks/BlocksService.ts | 2 +- src/services/test-helpers/mock/mockApi.ts | 18 +++++++++++++++++- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a145e7ea0..3d367bb52 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,6 @@ "build:calc": "bash ./calc/build.sh", "build:docker": "docker build -t substrate-api-sidecar .", "build:docs": "(cd docs && yarn && yarn build)", - "clean": "rm -rf node_modules/ yarn.lock build/", "main": "node ./build/src/main.js", "lint": "tsc && eslint . --ext ts", "deploy": "yarn build && standard-version", diff --git a/src/services/blocks/BlocksService.spec.ts b/src/services/blocks/BlocksService.spec.ts index f392c208a..0695d3304 100644 --- a/src/services/blocks/BlocksService.spec.ts +++ b/src/services/blocks/BlocksService.spec.ts @@ -53,7 +53,7 @@ describe('BlocksService', () => { (undefined as unknown) as GenericExtrinsic ); - mockApi.rpc.chain.getBlock = (() => + mockApi.derive.chain.getBlock = (() => Promise.resolve().then(() => { return { block: mockBlock789629BadExt, @@ -68,7 +68,7 @@ describe('BlocksService', () => { ) ); - mockApi.rpc.chain.getBlock = (getBlock as unknown) as GetBlock; + mockApi.derive.chain.getBlock = (getBlock as unknown) as GetBlock; }); }); diff --git a/src/services/blocks/BlocksService.ts b/src/services/blocks/BlocksService.ts index 5f7ee8ccb..66cf8f267 100644 --- a/src/services/blocks/BlocksService.ts +++ b/src/services/blocks/BlocksService.ts @@ -47,7 +47,7 @@ export class BlocksService extends AbstractService { let block; let events; let author; - if (typeof api.query?.session?.validators === 'function') { + if (typeof api.query?.session?.validators?.at === 'function') { [{ author, block }, events] = await Promise.all([ api.derive.chain.getBlock(hash) as Promise, this.fetchEvents(api, hash), diff --git a/src/services/test-helpers/mock/mockApi.ts b/src/services/test-helpers/mock/mockApi.ts index 9cac71214..25dac700f 100644 --- a/src/services/test-helpers/mock/mockApi.ts +++ b/src/services/test-helpers/mock/mockApi.ts @@ -37,7 +37,22 @@ const chain = () => export const getBlock = (_hash: Hash): Promise<{ block: Block }> => Promise.resolve().then(() => { - return { block: mockBlock789629 }; + return { + block: mockBlock789629, + }; + }); + +export const deriveGetBlock = ( + _hash: Hash +): Promise<{ block: Block; author: AccountId }> => + Promise.resolve().then(() => { + return { + author: polkadotRegistry.createType( + 'AccountId', + '1zugcajGg5yDD9TEqKKzGx7iKuGWZMkRbYcyaFnaUaEkwMK' + ), + block: mockBlock789629, + }; }); const getHeader = (_hash: Hash) => @@ -354,6 +369,7 @@ export const mockApi = ({ derive: { chain: { getHeader: deriveGetHeader, + getBlock: deriveGetBlock, }, }, } as unknown) as ApiPromise; From 7072fdc6d6b3daa4cc7fde58f9f93b1cf20014dc Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Mon, 23 Nov 2020 18:31:59 -0800 Subject: [PATCH 03/22] Update to reflect TS 4.1 --- src/types/polkadot-js/Codec.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/types/polkadot-js/Codec.ts b/src/types/polkadot-js/Codec.ts index fd8b7e61a..5b7a05867 100644 --- a/src/types/polkadot-js/Codec.ts +++ b/src/types/polkadot-js/Codec.ts @@ -5,7 +5,8 @@ export type { Codec } from '@polkadot/types/types'; export function isCodec(thing: unknown): thing is Codec { // Null errors on .hash access so we do not check for .hash - return (thing && + return ( + !!thing && (thing as Codec).encodedLength !== undefined && (thing as Codec).registry !== undefined && (thing as Codec).isEmpty !== undefined && @@ -15,5 +16,6 @@ export function isCodec(thing: unknown): thing is Codec { typeof (thing as Codec).toJSON === 'function' && typeof (thing as Codec).toRawType === 'function' && typeof (thing as Codec).toString === 'function' && - typeof (thing as Codec).toU8a === 'function') as boolean; + typeof (thing as Codec).toU8a === 'function' + ); } From c682665d91f7ec30c9dfcd35c14510f3e087c26e Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Mon, 23 Nov 2020 18:42:15 -0800 Subject: [PATCH 04/22] Clean up comments --- src/chains-config/index.ts | 1 + src/main.ts | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chains-config/index.ts b/src/chains-config/index.ts index d677310a8..a114ae9cb 100644 --- a/src/chains-config/index.ts +++ b/src/chains-config/index.ts @@ -8,6 +8,7 @@ import { defaultControllers } from './defaultControllers'; import { kulupuControllers } from './kulupuControllers'; /** + * Return an array of instantiated controller instances based off of a `specName`. * * @param api ApiPromise to inject into controllers * @param implName diff --git a/src/main.ts b/src/main.ts index 7a144d964..acc6107c1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -101,7 +101,6 @@ function startUpPrompt(wsUrl: string, chainName: string, implName: string) { * Best effort list of known public nodes that do not encourage high traffic * sidecar installations connecting to them for non - testing / development purposes. */ - // TODO move this to config folder and update const publicWsUrls: string[] = [ 'wss://rpc.polkadot.io', 'wss://cc1-1.polkadot.network', From 4ab1b2d4c61b8f5a8ea3d96305a01e771a2ba945 Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Tue, 1 Dec 2020 16:22:41 -0800 Subject: [PATCH 05/22] Save --- package.json | 3 +- src/chains-config/defaultControllers.ts | 2 +- src/chains-config/index.ts | 4 +- src/chains-config/mandalaControllers.ts | 25 ++++++ .../accounts/AccountsBalanceInfoController.ts | 7 +- .../AccountsBalanceInfoService.spec.ts | 3 +- .../accounts/AccountsBalanceInfoService.ts | 9 +- src/services/blocks/BlocksService.ts | 88 ++++++++++++------- 8 files changed, 102 insertions(+), 39 deletions(-) create mode 100644 src/chains-config/mandalaControllers.ts diff --git a/package.json b/package.json index 3d367bb52..d3ab364b1 100644 --- a/package.json +++ b/package.json @@ -28,11 +28,12 @@ "build:docker": "docker build -t substrate-api-sidecar .", "build:docs": "(cd docs && yarn && yarn build)", "main": "node ./build/src/main.js", + "main:inspect": "node --inspect ./build/src/main.js", "lint": "tsc && eslint . --ext ts", "deploy": "yarn build && standard-version", "start": "yarn run main", "start:log-rpc": "yarn run build && NODE_ENV=test yarn run main ", - "dev": "tsc-watch --onSuccess \"yarn run main\"", + "dev": "tsc-watch --onSuccess \"yarn run main:inspect\"", "test": "jest --silent" }, "dependencies": { diff --git a/src/chains-config/defaultControllers.ts b/src/chains-config/defaultControllers.ts index df0d3b045..758e8ed1d 100644 --- a/src/chains-config/defaultControllers.ts +++ b/src/chains-config/defaultControllers.ts @@ -6,7 +6,7 @@ import { ControllerConfig } from '../types/chains-config'; */ export const defaultControllers: ControllerConfig = { Blocks: true, - KulupuBlocks: true, + KulupuBlocks: false, AccountsStakingPayouts: true, AccountsBalanceInfo: true, AccountsStakingInfo: true, diff --git a/src/chains-config/index.ts b/src/chains-config/index.ts index a114ae9cb..e71afbd91 100644 --- a/src/chains-config/index.ts +++ b/src/chains-config/index.ts @@ -6,7 +6,7 @@ import { controllers } from '../controllers'; import { ControllerConfig } from '../types/chains-config'; import { defaultControllers } from './defaultControllers'; import { kulupuControllers } from './kulupuControllers'; - +import { mandalaControllers } from './mandalaControllers'; /** * Return an array of instantiated controller instances based off of a `specName`. * @@ -20,6 +20,8 @@ export function getControllersForSpec( switch (specName) { case 'kulupu': return getControllersFromConfig(api, kulupuControllers); + case 'mandala': + return getControllersFromConfig(api, mandalaControllers); default: return getControllersFromConfig(api, defaultControllers); } diff --git a/src/chains-config/mandalaControllers.ts b/src/chains-config/mandalaControllers.ts new file mode 100644 index 000000000..524f7e1ec --- /dev/null +++ b/src/chains-config/mandalaControllers.ts @@ -0,0 +1,25 @@ +import { ControllerConfig } from '../types/chains-config'; + +/** + * Controllers for mandala, acala's test network. + */ +export const mandalaControllers: ControllerConfig = { + Blocks: true, + KulupuBlocks: false, + AccountsStakingPayouts: true, + AccountsBalanceInfo: true, + AccountsStakingInfo: true, + AccountsVestingInfo: true, + NodeNetwork: true, + NodeVersion: true, + NodeTransactionPool: true, + RuntimeCode: true, + RuntimeSpec: true, + RuntimeMetadata: true, + TransactionDryRun: true, + TransactionMaterial: true, + TransactionFeeEstimate: true, + TransactionSubmit: true, + PalletsStakingProgress: true, + PalletsStorageItem: true, +}; diff --git a/src/controllers/accounts/AccountsBalanceInfoController.ts b/src/controllers/accounts/AccountsBalanceInfoController.ts index 355f4daa6..15f278f4e 100644 --- a/src/controllers/accounts/AccountsBalanceInfoController.ts +++ b/src/controllers/accounts/AccountsBalanceInfoController.ts @@ -62,14 +62,17 @@ export default class AccountsBalanceController extends AbstractController = async ( - { params: { address }, query: { at } }, + { params: { address }, query: { at, token } }, res ): Promise => { + const tokenArg = + typeof token === 'string' ? token : this.api.registry.chainToken; + const hash = await this.getHashFromAt(at); AccountsBalanceController.sanitizedSend( res, - await this.service.fetchAccountBalanceInfo(hash, address) + await this.service.fetchAccountBalanceInfo(hash, address, tokenArg) ); }; } diff --git a/src/services/accounts/AccountsBalanceInfoService.spec.ts b/src/services/accounts/AccountsBalanceInfoService.spec.ts index 97e3f17ed..ba136c0da 100644 --- a/src/services/accounts/AccountsBalanceInfoService.spec.ts +++ b/src/services/accounts/AccountsBalanceInfoService.spec.ts @@ -12,7 +12,8 @@ describe('AccountsBalanceInfoService', () => { sanitizeNumbers( await accountsBalanceInfoService.fetchAccountBalanceInfo( blockHash789629, - testAddress + testAddress, + 'DOT' ) ) ).toStrictEqual(accountsBalanceInfo789629); diff --git a/src/services/accounts/AccountsBalanceInfoService.ts b/src/services/accounts/AccountsBalanceInfoService.ts index e4f65b7e3..c40644d39 100644 --- a/src/services/accounts/AccountsBalanceInfoService.ts +++ b/src/services/accounts/AccountsBalanceInfoService.ts @@ -12,16 +12,23 @@ export class AccountsBalanceInfoService extends AbstractService { */ async fetchAccountBalanceInfo( hash: BlockHash, - address: string + address: string, + token: string ): Promise { const { api } = this; + console.log(token); + const [header, locks, sysAccount] = await Promise.all([ api.rpc.chain.getHeader(hash), api.query.balances.locks.at(hash, address), api.query.system.account.at(hash, address), ]); + debugger; + console.log('token ', token); + console.log('sysAccount ', sysAccount.data.free); + const account = sysAccount.data != null ? sysAccount.data diff --git a/src/services/blocks/BlocksService.ts b/src/services/blocks/BlocksService.ts index 66cf8f267..a0a0fe4b8 100644 --- a/src/services/blocks/BlocksService.ts +++ b/src/services/blocks/BlocksService.ts @@ -323,7 +323,7 @@ export class BlocksService extends AbstractService { } /** - * Create calcFee from params. + * Create calcFee from params or return `null` if calcFee cannot be created. * * @param api ApiPromise * @param parentHash Hash of the parent block @@ -334,46 +334,70 @@ export class BlocksService extends AbstractService { parentHash: Hash, block: Block ) { - let parentParentHash: Hash; - if (block.header.number.toNumber() > 1) { - parentParentHash = (await api.rpc.chain.getHeader(parentHash)) - .parentHash; + const perByte = api?.consts?.transactionPayment?.transactionByteFee; + const extrinsicBaseWeight = api?.consts?.system?.extrinsicBaseWeight; + + let calcFee; + let specName; + let specVersion; + if (perByte === undefined || extrinsicBaseWeight === undefined) { + // We do not have the neccesary materials to build calcFee, so we just give a dummy function + // that aligns with the expected API of calcFee. + calcFee = { calc_fee: () => null }; + + const version = await api.rpc.state.getRuntimeVersion(parentHash); + [specVersion, specName] = [ + version.specName.toString(), + version.specVersion.toNumber(), + ]; } else { - parentParentHash = parentHash; - } - - const perByte = api.consts.transactionPayment.transactionByteFee; - const extrinsicBaseWeight = api.consts.system.extrinsicBaseWeight; - const multiplier = await api.query.transactionPayment.nextFeeMultiplier.at( - parentHash - ); - // The block where the runtime is deployed falsely proclaims it would - // be already using the new runtime. This workaround therefore uses the - // parent of the parent in order to determine the correct runtime under which - // this block was produced. - const version = await api.rpc.state.getRuntimeVersion(parentParentHash); - const specName = version.specName.toString(); - const specVersion = version.specVersion.toNumber(); - const coefficients = api.consts.transactionPayment.weightToFee.map( - (c) => { - return { - coeffInteger: c.coeffInteger.toString(), - coeffFrac: c.coeffFrac, - degree: c.degree, - negative: c.negative, - }; + const coefficients = api.consts.transactionPayment.weightToFee.map( + (c) => { + return { + coeffInteger: c.coeffInteger.toString(), + coeffFrac: c.coeffFrac, + degree: c.degree, + negative: c.negative, + }; + } + ); + + // The block where the runtime is deployed falsely proclaims it would + // be already using the new runtime. This workaround therefore uses the + // parent of the parent in order to determine the correct runtime under which + // this block was produced. + let parentParentHash: Hash; + if (block.header.number.toNumber() > 1) { + parentParentHash = (await api.rpc.chain.getHeader(parentHash)) + .parentHash; + } else { + parentParentHash = parentHash; } - ); - return { - calcFee: CalcFee.from_params( + const [version, multiplier] = await Promise.all([ + api.rpc.state.getRuntimeVersion(parentParentHash), + api.query?.transactionPayment?.nextFeeMultiplier?.at( + parentHash + ), + ]); + + [specName, specVersion] = [ + version.specName.toString(), + version.specVersion.toNumber(), + ]; + + calcFee = CalcFee.from_params( coefficients, BigInt(extrinsicBaseWeight.toString()), multiplier.toString(), perByte.toString(), specName, specVersion - ), + ); + } + + return { + calcFee, specName, specVersion, }; From ede17872f3399167101cbabeca193dd9602aefbb Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Tue, 1 Dec 2020 20:24:27 -0800 Subject: [PATCH 06/22] feat: Token query param for non-native token balance-info --- docs/src/openapi-v1.yaml | 13 ++++ src/chains-config/defaultControllers.ts | 2 +- src/chains-config/kulupuControllers.ts | 2 +- src/chains-config/mandalaControllers.ts | 2 +- .../accounts/AccountsBalanceInfoController.ts | 4 +- src/controllers/index.ts | 4 +- src/controllers/pallets/index.ts | 4 +- .../accounts/AccountsBalanceInfoService.ts | 69 ++++++++++++++----- .../responses/accounts/balanceInfo789629.json | 1 + src/types/responses/AccountBalanceInfo.ts | 1 + yarn.lock | 36 +++++++--- 11 files changed, 102 insertions(+), 36 deletions(-) diff --git a/docs/src/openapi-v1.yaml b/docs/src/openapi-v1.yaml index 8ea7515e9..2b0c1afc3 100755 --- a/docs/src/openapi-v1.yaml +++ b/docs/src/openapi-v1.yaml @@ -45,6 +45,15 @@ paths: description: Block height (as a non-negative integer) or hash (as a hex string). format: unsignedInteger or $hex + - name: token + in: query + description: 'Token to query the balance of. If not specified it will query + the chains native token (e.g. DOT for Polkadot). Note: this is only relevant + for chains that support multiple tokens through the ORML tokens pallet.' + required: false + schema: + type: string + description: Token symbol responses: "200": description: successful operation @@ -717,6 +726,10 @@ components: type: string description: Account nonce. format: unsignedInteger + tokenSymbol: + type: string + description: Token symbol of the balances displayed in this response. + format: unsignedInteger free: type: string description: Free balance of the account. Not equivalent to _spendable_ diff --git a/src/chains-config/defaultControllers.ts b/src/chains-config/defaultControllers.ts index 758e8ed1d..21274e1e5 100644 --- a/src/chains-config/defaultControllers.ts +++ b/src/chains-config/defaultControllers.ts @@ -22,5 +22,5 @@ export const defaultControllers: ControllerConfig = { TransactionFeeEstimate: true, TransactionSubmit: true, PalletsStakingProgress: true, - PalletsStorageItem: true, + PalletsStorage: true, }; diff --git a/src/chains-config/kulupuControllers.ts b/src/chains-config/kulupuControllers.ts index 298a3505e..a6aff4979 100644 --- a/src/chains-config/kulupuControllers.ts +++ b/src/chains-config/kulupuControllers.ts @@ -18,5 +18,5 @@ export const kulupuControllers: ControllerConfig = { TransactionFeeEstimate: true, TransactionSubmit: true, PalletsStakingProgress: false, - PalletsStorageItem: true, + PalletsStorage: true, }; diff --git a/src/chains-config/mandalaControllers.ts b/src/chains-config/mandalaControllers.ts index 524f7e1ec..237f98a52 100644 --- a/src/chains-config/mandalaControllers.ts +++ b/src/chains-config/mandalaControllers.ts @@ -21,5 +21,5 @@ export const mandalaControllers: ControllerConfig = { TransactionFeeEstimate: true, TransactionSubmit: true, PalletsStakingProgress: true, - PalletsStorageItem: true, + PalletsStorage: true, }; diff --git a/src/controllers/accounts/AccountsBalanceInfoController.ts b/src/controllers/accounts/AccountsBalanceInfoController.ts index 15f278f4e..17c1ab637 100644 --- a/src/controllers/accounts/AccountsBalanceInfoController.ts +++ b/src/controllers/accounts/AccountsBalanceInfoController.ts @@ -66,7 +66,9 @@ export default class AccountsBalanceController extends AbstractController => { const tokenArg = - typeof token === 'string' ? token : this.api.registry.chainToken; + typeof token === 'string' + ? token.toUpperCase() + : this.api.registry.chainToken; const hash = await this.getHashFromAt(at); diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 34d34236c..4b58e1f76 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -7,7 +7,7 @@ import { import { Blocks } from './blocks'; import { KulupuBlocks } from './chains'; import { NodeNetwork, NodeTransactionPool, NodeVersion } from './node'; -import { PalletsStakingProgress, PalletsStorageItem } from './pallets'; +import { PalletsStakingProgress, PalletsStorage } from './pallets'; import { RuntimeCode, RuntimeMetadata, RuntimeSpec } from './runtime'; import { TransactionDryRun, @@ -27,7 +27,7 @@ export const controllers = { AccountsStakingPayouts, KulupuBlocks, PalletsStakingProgress, - PalletsStorageItem, + PalletsStorage, NodeNetwork, NodeTransactionPool, NodeVersion, diff --git a/src/controllers/pallets/index.ts b/src/controllers/pallets/index.ts index 07c219591..a9e4dd10c 100644 --- a/src/controllers/pallets/index.ts +++ b/src/controllers/pallets/index.ts @@ -1,2 +1,2 @@ -export { default as palletsStakingProgress } from './PalletsStakingProgressController'; -export { default as palletsStorageItem } from './PalletsStorageController'; +export { default as PalletsStakingProgress } from './PalletsStakingProgressController'; +export { default as PalletsStorage } from './PalletsStorageController'; diff --git a/src/services/accounts/AccountsBalanceInfoService.ts b/src/services/accounts/AccountsBalanceInfoService.ts index c40644d39..da4821000 100644 --- a/src/services/accounts/AccountsBalanceInfoService.ts +++ b/src/services/accounts/AccountsBalanceInfoService.ts @@ -1,4 +1,10 @@ -import { BlockHash } from '@polkadot/types/interfaces'; +import { Vec } from '@polkadot/types'; +import { + AccountData, + BalanceLock, + BlockHash, +} from '@polkadot/types/interfaces'; +import { BadRequest } from 'http-errors'; import { IAccountBalanceInfo } from 'src/types/responses'; import { AbstractService } from '../AbstractService'; @@ -6,9 +12,11 @@ import { AbstractService } from '../AbstractService'; export class AccountsBalanceInfoService extends AbstractService { /** * Fetch balance information for an account at a given block. + * N.B. assumes all non native tokens are from ORML tokens pallet. * * @param hash `BlockHash` to make call at * @param address address of the account to get the balance info of + * @param token token to get the balance info of for the user */ async fetchAccountBalanceInfo( hash: BlockHash, @@ -17,35 +25,60 @@ export class AccountsBalanceInfoService extends AbstractService { ): Promise { const { api } = this; - console.log(token); + let locks, header, accountInfo, accountData; + if (token === api.registry.chainToken) { + [header, locks, accountInfo] = await Promise.all([ + api.rpc.chain.getHeader(hash), + api.query.balances.locks.at(hash, address), + api.query.system.account.at(hash, address), + ]); - const [header, locks, sysAccount] = await Promise.all([ - api.rpc.chain.getHeader(hash), - api.query.balances.locks.at(hash, address), - api.query.system.account.at(hash, address), - ]); - - debugger; - console.log('token ', token); - console.log('sysAccount ', sysAccount.data.free); + accountData = + accountInfo.data != null + ? accountInfo.data + : await api.query.balances.account.at(hash, address); + } else { + // Assume we are using ORML token pallet + let locksAny, accountDataAny; + try { + [ + header, + locksAny, + accountDataAny, + accountInfo, + ] = await Promise.all([ + api.rpc.chain.getHeader(hash), + api.query.tokens.locks.at(hash, address, { Token: token }), + api.query.tokens.accounts.at(hash, address, { + Token: token, + }), + api.query.system.account.at(hash, address), + ]); + } catch { + throw new BadRequest( + 'An error occured while attempting to query for a non-native token; ' + + 'the token specified is likely invalid.' + ); + } - const account = - sysAccount.data != null - ? sysAccount.data - : await api.query.balances.account.at(hash, address); + // Coerce the ORML query results from polkadot-js generic Codec to exact type + locks = locksAny as Vec; + accountData = accountDataAny as AccountData; + } const at = { hash, height: header.number.toNumber().toString(10), }; - if (account && locks && sysAccount) { - const { free, reserved, miscFrozen, feeFrozen } = account; - const { nonce } = sysAccount; + if (accountData && locks && accountInfo) { + const { free, reserved, miscFrozen, feeFrozen } = accountData; + const { nonce } = accountInfo; return { at, nonce, + tokenSymbol: token, free, reserved, miscFrozen, diff --git a/src/services/test-helpers/responses/accounts/balanceInfo789629.json b/src/services/test-helpers/responses/accounts/balanceInfo789629.json index 830742aa1..4e6aaa522 100644 --- a/src/services/test-helpers/responses/accounts/balanceInfo789629.json +++ b/src/services/test-helpers/responses/accounts/balanceInfo789629.json @@ -4,6 +4,7 @@ "height": "789629" }, "nonce": "6", + "tokenSymbol": "DOT", "free": "501090793179", "reserved": "0", "miscFrozen": "100000000000", diff --git a/src/types/responses/AccountBalanceInfo.ts b/src/types/responses/AccountBalanceInfo.ts index ab66b5884..4bcfcdb78 100644 --- a/src/types/responses/AccountBalanceInfo.ts +++ b/src/types/responses/AccountBalanceInfo.ts @@ -5,6 +5,7 @@ import { IAt } from '.'; export interface IAccountBalanceInfo { at: IAt; + tokenSymbol: string; nonce: Index; free: Balance; reserved: Balance; diff --git a/yarn.lock b/yarn.lock index 0aa9f6f21..26a0d97f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -545,6 +545,11 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" +"@open-web3/orml-type-definitions@^0.6.0-beta.26": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@open-web3/orml-type-definitions/-/orml-type-definitions-0.6.1.tgz#eb7fadf598f24f5024f5d2a1fd39ccc97c801104" + integrity sha512-6asf2W/sluGQ6LNiGSdCg/Xop54mq/Q2FcV2Z9cBxys6QC4qXfo4JwUL6kJsRh/vcIIbUxoyGgKUrU/6Xdm7wA== + "@polkadot/api-derive@2.9.1": version "2.9.1" resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-2.9.1.tgz#e7f496d1b26f82471b649851e6d913769752ae2a" @@ -579,12 +584,23 @@ eventemitter3 "^4.0.7" rxjs "^6.6.3" +"@polkadot/apps-config@^0.68.1": + version "0.68.1" + resolved "https://registry.yarnpkg.com/@polkadot/apps-config/-/apps-config-0.68.1.tgz#ae3ad6cb8b6c34ca7aab8a3bc6923e6fbabe7af3" + integrity sha512-MSWqpVuZxMw3Fnzwakbf7ODAiB9BvjOWJS48sUTnZg1Obbp/vBAEZteBUkgEBSwuBupju9DjXkVXeJw8OU7WHA== + dependencies: + "@acala-network/type-definitions" "^0.4.0-beta.33" + "@babel/runtime" "^7.12.5" + "@edgeware/node-types" "^3.0.7" + "@laminar/type-definitions" "^0.2.0-beta.141" + "@polkadot/networks" "^4.2.1" + "@subsocial/types" "^0.4.7" + "@polkadot/keyring@^4.2.1": version "4.2.1" resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-4.2.1.tgz#34bf18ae8cb5822f2ea522c8db62dd0086725ffa" integrity sha512-8kH8jXSIA3I2Gn96o7KjGoLBa7fmc2iB/VKOmEEcMCgJR32HyE8YbeXwc/85OQCheQjG4rJA3RxPQ4CsTsjO7w== dependencies: - "@acala-network/type-definitions" "^0.4.0-beta.33" "@babel/runtime" "^7.12.5" "@polkadot/util" "4.2.1" "@polkadot/util-crypto" "4.2.1" @@ -601,17 +617,12 @@ "@polkadot/util-crypto" "^4.2.1" bn.js "^4.11.9" -"@polkadot/networks@4.2.1": +"@polkadot/networks@4.2.1", "@polkadot/networks@^4.2.1": version "4.2.1" resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-4.2.1.tgz#b0ca69807ed60189f1c958bb27cfeb3cb1c6b12b" integrity sha512-T1tg0V0uG09Vdce2O4KfEcWO3/fZh4VYt0bmJ6iPwC+x6yv939X2BKvuFTDDVNT3fqBpGzWQlwiTXYQ15o9bGA== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/types" "2.8.1" - "@polkadot/types-known" "2.8.1" - "@polkadot/util" "^4.2.1" - "@polkadot/util-crypto" "^4.2.1" - bn.js "^4.11.9" "@polkadot/rpc-core@2.9.1": version "2.9.1" @@ -1382,6 +1393,11 @@ bn.js@^4.11.9, bn.js@^4.4.0: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== +bn.js@^5.1.1: + version "5.1.3" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" + integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== + body-parser@1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" @@ -4266,9 +4282,9 @@ loglevel-plugin-prefix@^0.8.4: integrity sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g== loglevel@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.0.tgz#728166855a740d59d38db01cf46f042caa041bb0" - integrity sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ== + version "1.7.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" + integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== loud-rejection@^1.0.0: version "1.6.0" From 39e1a1a668ccb5e5e118c2c1dcbadde5de1a4da5 Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Tue, 1 Dec 2020 20:47:28 -0800 Subject: [PATCH 07/22] Revert package.json --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index b088f1f0c..de436f803 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,11 @@ "build:docker": "docker build -t substrate-api-sidecar .", "build:docs": "(cd docs && yarn && yarn build)", "main": "node ./build/src/main.js", - "main:inspect": "node --inspect ./build/src/main.js", "lint": "tsc && eslint . --ext ts", "deploy": "yarn build && standard-version", "start": "yarn run main", "start:log-rpc": "yarn run build && NODE_ENV=test yarn run main ", - "dev": "tsc-watch --onSuccess \"yarn run main:inspect\"", + "dev": "tsc-watch --onSuccess \"yarn run main\"", "test": "jest --silent" }, "dependencies": { From be66056d3ca28abfae98773cdfc52de5f378f83c Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Wed, 2 Dec 2020 13:51:29 -0800 Subject: [PATCH 08/22] Initial reply david review --- src/chains-config/defaultControllers.ts | 2 +- src/chains-config/index.ts | 3 ++- src/services/accounts/AccountsBalanceInfoService.ts | 6 +++--- src/services/blocks/BlocksService.ts | 4 +--- src/types/sidecar-config/SidecarConfig.ts | 4 +++- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/chains-config/defaultControllers.ts b/src/chains-config/defaultControllers.ts index 21274e1e5..2c073d508 100644 --- a/src/chains-config/defaultControllers.ts +++ b/src/chains-config/defaultControllers.ts @@ -1,7 +1,7 @@ import { ControllerConfig } from '../types/chains-config'; /** - * Controllers that Sidecar will always default to. This likely will always be + * Controllers that Sidecar will always default to. This will always be * the optimal controller selection for Polkadot and Kusama. */ export const defaultControllers: ControllerConfig = { diff --git a/src/chains-config/index.ts b/src/chains-config/index.ts index e71afbd91..ee1b305b1 100644 --- a/src/chains-config/index.ts +++ b/src/chains-config/index.ts @@ -7,6 +7,7 @@ import { ControllerConfig } from '../types/chains-config'; import { defaultControllers } from './defaultControllers'; import { kulupuControllers } from './kulupuControllers'; import { mandalaControllers } from './mandalaControllers'; + /** * Return an array of instantiated controller instances based off of a `specName`. * @@ -43,7 +44,7 @@ function getControllersFromConfig(api: ApiPromise, config: ControllerConfig) { return controllersToInclude.reduce((acc, [controllerName, shouldMount]) => { if (shouldMount) { - return acc.concat(new controllers[controllerName](api)); + acc.push(new controllers[controllerName](api)); } return acc; diff --git a/src/services/accounts/AccountsBalanceInfoService.ts b/src/services/accounts/AccountsBalanceInfoService.ts index da4821000..01e06eb4f 100644 --- a/src/services/accounts/AccountsBalanceInfoService.ts +++ b/src/services/accounts/AccountsBalanceInfoService.ts @@ -14,9 +14,9 @@ export class AccountsBalanceInfoService extends AbstractService { * Fetch balance information for an account at a given block. * N.B. assumes all non native tokens are from ORML tokens pallet. * - * @param hash `BlockHash` to make call at - * @param address address of the account to get the balance info of - * @param token token to get the balance info of for the user + * @param hash `BlockHash` to make call at. + * @param address Address of the account to get the balance info of. + * @param token Token to get the balance info of. */ async fetchAccountBalanceInfo( hash: BlockHash, diff --git a/src/services/blocks/BlocksService.ts b/src/services/blocks/BlocksService.ts index 093366784..196c93a4b 100644 --- a/src/services/blocks/BlocksService.ts +++ b/src/services/blocks/BlocksService.ts @@ -337,9 +337,7 @@ export class BlocksService extends AbstractService { const perByte = api?.consts?.transactionPayment?.transactionByteFee; const extrinsicBaseWeight = api?.consts?.system?.extrinsicBaseWeight; - let calcFee; - let specName; - let specVersion; + let calcFee, specName, specVersion; if (perByte === undefined || extrinsicBaseWeight === undefined) { // We do not have the neccesary materials to build calcFee, so we just give a dummy function // that aligns with the expected API of calcFee. diff --git a/src/types/sidecar-config/SidecarConfig.ts b/src/types/sidecar-config/SidecarConfig.ts index e80ccd662..4cdc468e5 100644 --- a/src/types/sidecar-config/SidecarConfig.ts +++ b/src/types/sidecar-config/SidecarConfig.ts @@ -1,3 +1,5 @@ +import { RegistryTypes } from '@polkadot/types/types'; + /** * Object to house the values of all the configurable components for Sidecar. */ @@ -9,7 +11,7 @@ export interface ISidecarConfig { interface ISidecarConfigSubstrate { WS_URL: string; - CUSTOM_TYPES: Record | undefined; + CUSTOM_TYPES: RegistryTypes | undefined; } interface ISidecarConfigExpress { From e46509242677cb43ebcd2e425d2741acd9e33c6e Mon Sep 17 00:00:00 2001 From: Zeke Mostov <32168567+emostov@users.noreply.github.com> Date: Wed, 2 Dec 2020 14:43:16 -0800 Subject: [PATCH 09/22] Update src/main.ts Co-authored-by: David --- src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index acc6107c1..1707e95e8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -89,7 +89,7 @@ process.on('SIGINT', function () { main().catch(console.log); /** - * Prompt the user with some basic info abou the node and the network they have + * Prompt the user with some basic info about the node and the network they have * connected Sidecar to. * * @param wsUrl websocket url of the node Sidecar is connected to From 19a66e73b3594d2173e76c56e13887e22feac609 Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Wed, 2 Dec 2020 15:30:44 -0800 Subject: [PATCH 10/22] Remove kulupu controller --- src/chains-config/defaultControllers.ts | 40 +++--- src/chains-config/index.ts | 24 ++-- src/chains-config/kulupuControllers.ts | 40 +++--- src/chains-config/mandalaControllers.ts | 40 +++--- src/controllers/blocks/BlocksController.ts | 4 +- .../chains/KulupuBlocksController.ts | 121 ------------------ src/controllers/chains/index.ts | 6 - src/controllers/index.ts | 2 - src/types/chains-config/ControllerConfig.ts | 15 ++- 9 files changed, 97 insertions(+), 195 deletions(-) delete mode 100644 src/controllers/chains/KulupuBlocksController.ts delete mode 100644 src/controllers/chains/index.ts diff --git a/src/chains-config/defaultControllers.ts b/src/chains-config/defaultControllers.ts index 2c073d508..7ff0dd198 100644 --- a/src/chains-config/defaultControllers.ts +++ b/src/chains-config/defaultControllers.ts @@ -5,22 +5,26 @@ import { ControllerConfig } from '../types/chains-config'; * the optimal controller selection for Polkadot and Kusama. */ export const defaultControllers: ControllerConfig = { - Blocks: true, - KulupuBlocks: false, - AccountsStakingPayouts: true, - AccountsBalanceInfo: true, - AccountsStakingInfo: true, - AccountsVestingInfo: true, - NodeNetwork: true, - NodeVersion: true, - NodeTransactionPool: true, - RuntimeCode: true, - RuntimeSpec: true, - RuntimeMetadata: true, - TransactionDryRun: true, - TransactionMaterial: true, - TransactionFeeEstimate: true, - TransactionSubmit: true, - PalletsStakingProgress: true, - PalletsStorage: true, + controllers: { + Blocks: true, + AccountsStakingPayouts: true, + AccountsBalanceInfo: true, + AccountsStakingInfo: true, + AccountsVestingInfo: true, + NodeNetwork: true, + NodeVersion: true, + NodeTransactionPool: true, + RuntimeCode: true, + RuntimeSpec: true, + RuntimeMetadata: true, + TransactionDryRun: true, + TransactionMaterial: true, + TransactionFeeEstimate: true, + TransactionSubmit: true, + PalletsStakingProgress: true, + PalletsStorage: true, + }, + options: { + finalizes: true, + }, }; diff --git a/src/chains-config/index.ts b/src/chains-config/index.ts index ee1b305b1..82ea7183e 100644 --- a/src/chains-config/index.ts +++ b/src/chains-config/index.ts @@ -8,6 +8,11 @@ import { defaultControllers } from './defaultControllers'; import { kulupuControllers } from './kulupuControllers'; import { mandalaControllers } from './mandalaControllers'; +const specToControllerMap = { + kulupu: kulupuControllers, + mandala: mandalaControllers, +}; + /** * Return an array of instantiated controller instances based off of a `specName`. * @@ -18,14 +23,13 @@ export function getControllersForSpec( api: ApiPromise, specName: string ): AbstractController[] { - switch (specName) { - case 'kulupu': - return getControllersFromConfig(api, kulupuControllers); - case 'mandala': - return getControllersFromConfig(api, mandalaControllers); - default: - return getControllersFromConfig(api, defaultControllers); + if (specToControllerMap[specName]) { + return getControllersFromConfig(api, specToControllerMap[specName]); } + + // If we don't have the specName in the specToControllerMap we use the default + // contoller config + return getControllersFromConfig(api, defaultControllers); } /** @@ -37,14 +41,16 @@ export function getControllersForSpec( */ function getControllersFromConfig(api: ApiPromise, config: ControllerConfig) { // If we don't typecast here, tsc thinks its just [string, any][] - const controllersToInclude = Object.entries(config) as [ + const controllersToInclude = Object.entries(config.controllers) as [ keyof typeof controllers, boolean ][]; return controllersToInclude.reduce((acc, [controllerName, shouldMount]) => { if (shouldMount) { - acc.push(new controllers[controllerName](api)); + acc.push( + new controllers[controllerName](api, config.options.finalizes) + ); } return acc; diff --git a/src/chains-config/kulupuControllers.ts b/src/chains-config/kulupuControllers.ts index a6aff4979..b6000ae4a 100644 --- a/src/chains-config/kulupuControllers.ts +++ b/src/chains-config/kulupuControllers.ts @@ -1,22 +1,26 @@ import { ControllerConfig } from '../types/chains-config'; export const kulupuControllers: ControllerConfig = { - Blocks: false, - KulupuBlocks: true, - AccountsStakingPayouts: false, - AccountsBalanceInfo: true, - AccountsStakingInfo: false, - AccountsVestingInfo: false, - NodeNetwork: true, - NodeVersion: true, - NodeTransactionPool: true, - RuntimeCode: true, - RuntimeSpec: true, - RuntimeMetadata: true, - TransactionDryRun: true, - TransactionMaterial: true, - TransactionFeeEstimate: true, - TransactionSubmit: true, - PalletsStakingProgress: false, - PalletsStorage: true, + controllers: { + Blocks: true, + AccountsStakingPayouts: false, + AccountsBalanceInfo: true, + AccountsStakingInfo: false, + AccountsVestingInfo: false, + NodeNetwork: true, + NodeVersion: true, + NodeTransactionPool: true, + RuntimeCode: true, + RuntimeSpec: true, + RuntimeMetadata: true, + TransactionDryRun: true, + TransactionMaterial: true, + TransactionFeeEstimate: true, + TransactionSubmit: true, + PalletsStakingProgress: false, + PalletsStorage: true, + }, + options: { + finalizes: false, + }, }; diff --git a/src/chains-config/mandalaControllers.ts b/src/chains-config/mandalaControllers.ts index 237f98a52..3ec234baf 100644 --- a/src/chains-config/mandalaControllers.ts +++ b/src/chains-config/mandalaControllers.ts @@ -4,22 +4,26 @@ import { ControllerConfig } from '../types/chains-config'; * Controllers for mandala, acala's test network. */ export const mandalaControllers: ControllerConfig = { - Blocks: true, - KulupuBlocks: false, - AccountsStakingPayouts: true, - AccountsBalanceInfo: true, - AccountsStakingInfo: true, - AccountsVestingInfo: true, - NodeNetwork: true, - NodeVersion: true, - NodeTransactionPool: true, - RuntimeCode: true, - RuntimeSpec: true, - RuntimeMetadata: true, - TransactionDryRun: true, - TransactionMaterial: true, - TransactionFeeEstimate: true, - TransactionSubmit: true, - PalletsStakingProgress: true, - PalletsStorage: true, + controllers: { + Blocks: true, + AccountsStakingPayouts: true, + AccountsBalanceInfo: true, + AccountsStakingInfo: true, + AccountsVestingInfo: true, + NodeNetwork: true, + NodeVersion: true, + NodeTransactionPool: true, + RuntimeCode: true, + RuntimeSpec: true, + RuntimeMetadata: true, + TransactionDryRun: true, + TransactionMaterial: true, + TransactionFeeEstimate: true, + TransactionSubmit: true, + PalletsStakingProgress: true, + PalletsStorage: true, + }, + options: { + finalizes: true, + }, }; diff --git a/src/controllers/blocks/BlocksController.ts b/src/controllers/blocks/BlocksController.ts index f007611dd..c5400daed 100644 --- a/src/controllers/blocks/BlocksController.ts +++ b/src/controllers/blocks/BlocksController.ts @@ -65,7 +65,7 @@ import AbstractController from '../AbstractController'; * - `OnFinalize`: https://crates.parity.io/frame_support/traits/trait.OnFinalize.html */ export default class BlocksController extends AbstractController { - constructor(api: ApiPromise) { + constructor(api: ApiPromise, private finalizes = true) { super(api, '/blocks', new BlocksService(api)); this.initRoutes(); } @@ -91,7 +91,7 @@ export default class BlocksController extends AbstractController const extrsinsicDocsArg = extrinsicDocs === 'true'; const hash = - finalized === 'false' + finalized === 'false' || !this.finalizes ? (await this.api.rpc.chain.getHeader()).hash : await this.api.rpc.chain.getFinalizedHead(); diff --git a/src/controllers/chains/KulupuBlocksController.ts b/src/controllers/chains/KulupuBlocksController.ts deleted file mode 100644 index 9010f57c2..000000000 --- a/src/controllers/chains/KulupuBlocksController.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { ApiPromise } from '@polkadot/api'; -import { RequestHandler } from 'express'; - -import { BlocksService } from '../../services'; -import { INumberParam } from '../../types/requests'; -import AbstractController from '../AbstractController'; - -/** - * GET a block. - * - * N.B. this controller assumes the chain does not have a finality - * gadget (e.g. PoW in Kulupu)) - * - * Paths: - * - `kulupuBlocks\head`: Get the latest finalized block. - * - (Optional) `kulupuBlocks\number`: Block hash or height at which to query. If not provided, queries - * finalized head. - * - * Query: - * - (Optional) `eventDocs`: When set to `true`, every event will have an extra - * `docs` property with a string of the events documentation. - * - (Optional) `extrinsicDocs`: When set to `true`, every extrinsic will have an extra - * `docs` property with a string of the extrinsics documentation. - * - * - * Returns: - * - `number`: Block height. - * - `hash`: The block's hash. - * - `parentHash`: The hash of the parent block. - * - `stateRoot`: The state root after executing this block. - * - `extrinsicsRoot`: The Merkle root of the extrinsics. - * - `authorId`: The account ID of the block author (may be undefined for some chains). - * - `logs`: Array of `DigestItem`s associated with the block. - * - `onInitialize`: Object with an array of `SanitizedEvent`s that occurred during block - * initialization with the `method` and `data` for each. - * - `extrinsics`: Array of extrinsics (inherents and transactions) within the block. Each - * contains: - * - `method`: Extrinsic method. - * - `signature`: Object with `signature` and `signer`, or `null` if unsigned. - * - `nonce`: Account nonce, if applicable. - * - `args`: Array of arguments. - * - `tip`: Any tip added to the transaction. - * - `hash`: The transaction's hash. - * - `info`: `RuntimeDispatchInfo` for the transaction. Includes the `partialFee`. - * - `events`: An array of `SanitizedEvent`s that occurred during extrinsic execution. - * - `success`: Whether or not the extrinsic succeeded. - * - `paysFee`: Whether the extrinsic requires a fee. Careful! This field relates to whether or - * not the extrinsic requires a fee if called as a transaction. Block authors could insert - * the extrinsic as an inherent in the block and not pay a fee. Always check that `paysFee` - * is `true` and that the extrinsic is signed when reconciling old blocks. - * - `onFinalize`: Object with an array of `SanitizedEvent`s that occurred during block - * finalization with the `method` and `data` for each. - * - * - * Substrate Reference: - * - `DigestItem`: https://crates.parity.io/sp_runtime/enum.DigestItem.html - * - `RawEvent`: https://crates.parity.io/frame_system/enum.RawEvent.html - * - Extrinsics: https://substrate.dev/docs/en/knowledgebase/learn-substrate/extrinsics - * - `Extrinsic`: https://crates.parity.io/sp_runtime/traits/trait.Extrinsic.html - * - `OnInitialize`: https://crates.parity.io/frame_support/traits/trait.OnInitialize.html - * - `OnFinalize`: https://crates.parity.io/frame_support/traits/trait.OnFinalize.html - */ -export default class KulupuBlocksController extends AbstractController { - constructor(api: ApiPromise) { - super(api, '/kulupuBlocks', new BlocksService(api)); - this.initRoutes(); - } - - protected initRoutes(): void { - this.safeMountAsyncGetHandlers([ - ['/head', this.getLatestBlock], - ['/:number', this.getBlockById], - ]); - } - - /** - * Get the latest block. - * - * @param _req Express Request - * @param res Express Response - */ - private getLatestBlock: RequestHandler = async ( - { query: { eventDocs, extrinsicDocs } }, - res - ) => { - const eventDocsArg = eventDocs === 'true'; - const extrsinsicDocsArg = extrinsicDocs === 'true'; - - const hash = (await this.api.rpc.chain.getHeader()).hash; - - KulupuBlocksController.sanitizedSend( - res, - await this.service.fetchBlock(hash, eventDocsArg, extrsinsicDocsArg) - ); - }; - - /** - * Get a block by its hash or number identifier. - * - * @param req Express Request - * @param res Express Response - */ - private getBlockById: RequestHandler = async ( - { params: { number }, query: { eventDocs, extrinsicDocs } }, - res - ): Promise => { - const hash = await this.getHashForBlock(number); - - const eventDocsArg = eventDocs === 'true'; - const extrinsinsicDocsArg = extrinsicDocs === 'true'; - - KulupuBlocksController.sanitizedSend( - res, - await this.service.fetchBlock( - hash, - eventDocsArg, - extrinsinsicDocsArg - ) - ); - }; -} diff --git a/src/controllers/chains/index.ts b/src/controllers/chains/index.ts deleted file mode 100644 index 3d3fb68f2..000000000 --- a/src/controllers/chains/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -// Chain specific controllers. -// -// These endpoints may be reused for other chains as well, but for now naming them after the chain -// that originally neccesitated it for simplicity. - -export { default as KulupuBlocks } from './KulupuBlocksController'; diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 4b58e1f76..d0def0400 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -5,7 +5,6 @@ import { AccountsVestingInfo, } from './accounts'; import { Blocks } from './blocks'; -import { KulupuBlocks } from './chains'; import { NodeNetwork, NodeTransactionPool, NodeVersion } from './node'; import { PalletsStakingProgress, PalletsStorage } from './pallets'; import { RuntimeCode, RuntimeMetadata, RuntimeSpec } from './runtime'; @@ -25,7 +24,6 @@ export const controllers = { AccountsStakingInfo, AccountsVestingInfo, AccountsStakingPayouts, - KulupuBlocks, PalletsStakingProgress, PalletsStorage, NodeNetwork, diff --git a/src/types/chains-config/ControllerConfig.ts b/src/types/chains-config/ControllerConfig.ts index 7ef94a5f3..b1ef19bcb 100644 --- a/src/types/chains-config/ControllerConfig.ts +++ b/src/types/chains-config/ControllerConfig.ts @@ -4,5 +4,18 @@ import { controllers } from '../../controllers'; * Controller mounting configuration as an object where the keys are the * controller class names and the values are booleans indicating whether or not * to include the controller. + * + * There is an additional `finalizes` field that is used to indicate wether or + * not a chain has finalized blocks. Practically, this only affects if + * `BlocksController` defaults to getFinalizedHead (in the case it finalizes) or + * getHeader (in the case it does not finalize) */ -export type ControllerConfig = Record; +export interface ControllerConfig { + controllers: Record; + /** + * Wether or not the chain finalizes blocks + */ + options: { + finalizes: boolean; + }; +} From c5e9284e264b49cf2bfc1ea94e5004050184343e Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Wed, 2 Dec 2020 19:10:01 -0800 Subject: [PATCH 11/22] Add chain builder integration guide --- CHAIN_INTEGRATION.md | 75 +++++++++++++++++++++ README.md | 12 +--- src/types/chains-config/ControllerConfig.ts | 8 ++- 3 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 CHAIN_INTEGRATION.md diff --git a/CHAIN_INTEGRATION.md b/CHAIN_INTEGRATION.md new file mode 100644 index 000000000..aeac6167e --- /dev/null +++ b/CHAIN_INTEGRATION.md @@ -0,0 +1,75 @@ +# Substrate Api Sidecar chain integration guide + +This guide aims to help chain builders integrate their Substrate FRAME based chain with Substrate API Sidecar. + +## Table of contents + +- [Polkadot-js API type definition support](#polkadot-js-API-type-definition-support) +- [Controller configuration](controller-configuration) + +## Polkadot-js API type definition support + +In order decode the SCALE encoded data from a substrate based node, polkadot-js needs to have a registry of type definitions. Sidecar pulls in chain type definitions from the [@polkadot/apps-config package hosted on NPM](https://www.npmjs.com/package/@polkadot/apps-config). + +If the chains type definitions do not already exist in [@polkadot/apps-config](https://github.com/polkadot-js/apps/tree/master/packages/apps-config) they will need to be added via PR to polkadot-js/apps by following their [instructions for API config](https://github.com/polkadot-js/apps/tree/master/packages/apps-config#api). + +Before taking any other steps to integrate a chain with Sidecar, a chains up-to-date type definitions must be included in a published version of @polkadot/apps-config. + +## Controller configuration + +Sidecar offers the ability to configure which controllers to mount. Sidecar uses a chain's spec name to determine which controller config to use, and if no config is linked to a spec name, then the [default config](/src/chains-config/defaultControllers.ts) is used. + +A chain builder can follow the below steps and submit a chain's controller config via PR, where it will be reviewed and merged once deemed ready by the maintainers. + +#### 1) Create a controller config + + Create a controller config for your chain. The shape of the controller config is specified [here](/src/chains-config/ControllerConfig.ts). The `controller` property has keys from the [controller export](/src/controllers/index.ts), which is an exhaustive collection of the available controller classes. + + The easiest way to start creating a controller config would be to copy [defaultControllers.ts](/src/chains-config/ControllerConfig.ts) and name the file and export `{specName}Controllers`. Ensure to export the controller config from `chains-config` by adding `export * from './{specName}Controllers.ts'` in [/src/chains-config/index.ts](/src/chains-config/index.ts). + + To determine what controllers to include, one must consider the runtime logic, specifically what pallets the chain uses. It is important to keep in mind the assumptions the service logic makes and what exact pallets the service queries. E.g. in order to use [`PalletsStakingProgressController`](/src/controllers/pallets/PalletsStakingProgressController.ts), one would check [`PalletsStakingProgressService.ts`](/src/services/pallets/PalletsStakingProgressService.ts). There one would see it queries `staking`, `sessions`, `babe` pallets and makes certain assumptions about how the pallets are used together in the runtime. + +In some circumstance, a chain may need a new path, modify a path or altered bushiness logic for a path it. Path changes that help a chain support custodial wallets will be given priority. Breaking path changes are strongly not preferred. + +##### Basic balance transfer support + +In order to support traditional balance transfers the chain's Sidecar endpoints should support account balance lookup, transaction submission, transaction material retrieval, and block queries. + +To support those actions the following endpoints are necessary: + +| Path | Controller | Description | +|:----------------------------------------:|:-----------------------------:|:--------------------------------------------------------------------------:| +| GET `/transaction/material` | TransactionMaterialController | Get all the network information needed to construct a transaction offline. | +| POST `/transaction` | TransactionSubmitController | Submit a transaction to the node's transaction pool. | +| GET `/blocks/head` & `/blocks/{number}` | BlocksController | Get a block. | +| GET `accounts/{accountId}/balance-info` | AccountsBalanceInfoController | Get balance information for an account. | + +#### 2) Update `specToControllerMap` + +In order for Sidecar to use your controller config, the `specToControllerMap` in [/src/chains-config/index.ts](/src/chains-config/index.ts) must be updated with the chain's `specName` and controller config by adding them as a property to `specToControllerMap`: + +```javascript +const specToControllerMap = { + kulupu: kulupuControllers, + mandala: mandalaControllers, + {specName}: {specName}Controllers, +}; +``` + +#### 3) Test + +Run it against an archive version of your chains node: + +- Ensure all the correct paths work, including the root path +- Exercise each query param of every path +- Make sure transaction submission works +- Try out historic queries across runtimes where types might change + +#### 4) Submit your PR + +Make sure it passes lint with `yarn lint --fix` and tests with `yarn test`. Then submit a PR for review. + +#### 5) Maintenance + +- Keep types up-to-date in `@polkadot/apps-config` +- If the business logic or storage of a chain's pallet queried by a Sidecar endpoint is changed, ensure Sidecar has service logic has any relevant updates. diff --git a/README.md b/README.md index 990803470..9ee047a18 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ This service requires Node version 12 or higher. - [Configuration](#configuration) - [Debugging fee and payout calculations](#debugging-fee-and-payout-calculations) - [Available endpoints](https://paritytech.github.io/substrate-api-sidecar/dist/) -- [Chain compatibility](#chain-compatibility) +- [Chain integration guide](/CHAIN_INTEGRATION.md) - [Docker](#docker) - [Note for maintainers](#note-for-maintainers) - [Roadmap](#roadmap) @@ -200,15 +200,9 @@ CALC_DEBUG=1 yarn [Click here for full endpoint docs.](https://paritytech.github.io/substrate-api-sidecar/dist/) -## Chain compatibility +## Chain integration guide -Sidecar should be compatible with any [Substrate](https://substrate.dev/) based chain, given -constraints: - -- The chain ought to use FRAME and the `balances` pallet. -- The chain is being finalized (by running `grandpa`). -- If the chain is running on custom Node binaries, the JSON-RPC API should be backwards compatible - with the default Substrate Node. +[Click here for chain integration guide.](/CHAIN_INTEGRATION.md) ## Docker diff --git a/src/types/chains-config/ControllerConfig.ts b/src/types/chains-config/ControllerConfig.ts index b1ef19bcb..92954226b 100644 --- a/src/types/chains-config/ControllerConfig.ts +++ b/src/types/chains-config/ControllerConfig.ts @@ -11,11 +11,17 @@ import { controllers } from '../../controllers'; * getHeader (in the case it does not finalize) */ export interface ControllerConfig { + /** + * Controller class names and wether or not to include them + */ controllers: Record; /** - * Wether or not the chain finalizes blocks + * Options relating to how the controllers are configured. */ options: { + /** + * Wether or not the chain finalizes blocks + */ finalizes: boolean; }; } From 0c57ecdfd4236b83336d3da95ef589ee8963633d Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Wed, 2 Dec 2020 19:25:11 -0800 Subject: [PATCH 12/22] Patch CHAIN_INTEGRATION.md --- CHAIN_INTEGRATION.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHAIN_INTEGRATION.md b/CHAIN_INTEGRATION.md index aeac6167e..ac45ded6f 100644 --- a/CHAIN_INTEGRATION.md +++ b/CHAIN_INTEGRATION.md @@ -23,11 +23,11 @@ A chain builder can follow the below steps and submit a chain's controller confi #### 1) Create a controller config - Create a controller config for your chain. The shape of the controller config is specified [here](/src/chains-config/ControllerConfig.ts). The `controller` property has keys from the [controller export](/src/controllers/index.ts), which is an exhaustive collection of the available controller classes. + Create a controller config for your chain. The shape of the controller config is specified [here](/src/chains-config/ControllerConfig.ts). The `controller` property has keys from the [controller export](/src/controllers/index.ts), which is an exhaustive collection of the available controller classes. In order to see the path(s) associated with a controller one must look in the controller source code. - The easiest way to start creating a controller config would be to copy [defaultControllers.ts](/src/chains-config/ControllerConfig.ts) and name the file and export `{specName}Controllers`. Ensure to export the controller config from `chains-config` by adding `export * from './{specName}Controllers.ts'` in [/src/chains-config/index.ts](/src/chains-config/index.ts). + The easiest way to start creating a controller config would be to copy [defaultControllers.ts](/src/chains-config/ControllerConfig.ts) and name the file and export `{specName}Controllers`. Ensure to export the controller config from `chains-config` by adding `export * from './{specName}Controllers.ts'` in [/src/chains-config/index.ts](/src/chains-config/index.ts). Then change the boolean values to indicate wether or not to mount a controller and its paths. - To determine what controllers to include, one must consider the runtime logic, specifically what pallets the chain uses. It is important to keep in mind the assumptions the service logic makes and what exact pallets the service queries. E.g. in order to use [`PalletsStakingProgressController`](/src/controllers/pallets/PalletsStakingProgressController.ts), one would check [`PalletsStakingProgressService.ts`](/src/services/pallets/PalletsStakingProgressService.ts). There one would see it queries `staking`, `sessions`, `babe` pallets and makes certain assumptions about how the pallets are used together in the runtime. + To determine what controllers to include, one must consider the runtime logic, specifically what pallets the chain uses. It is important to keep in mind the assumptions the service's logic makes and what exact pallets the service queries. E.g. in order to use [`PalletsStakingProgressController`](/src/controllers/pallets/PalletsStakingProgressController.ts), one would check [`PalletsStakingProgressService.ts`](/src/services/pallets/PalletsStakingProgressService.ts). There one would see it queries `staking`, `sessions`, `babe` pallets and makes certain assumptions about how the pallets are used together in the runtime. In some circumstance, a chain may need a new path, modify a path or altered bushiness logic for a path it. Path changes that help a chain support custodial wallets will be given priority. Breaking path changes are strongly not preferred. From 6692e50a8d1a9fdc00021a5edb064de4734a296c Mon Sep 17 00:00:00 2001 From: Zeke Mostov <32168567+emostov@users.noreply.github.com> Date: Fri, 4 Dec 2020 10:02:01 -0800 Subject: [PATCH 13/22] Apply suggestions from code review Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> --- CHAIN_INTEGRATION.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHAIN_INTEGRATION.md b/CHAIN_INTEGRATION.md index ac45ded6f..f7f3c5804 100644 --- a/CHAIN_INTEGRATION.md +++ b/CHAIN_INTEGRATION.md @@ -11,9 +11,9 @@ This guide aims to help chain builders integrate their Substrate FRAME based cha In order decode the SCALE encoded data from a substrate based node, polkadot-js needs to have a registry of type definitions. Sidecar pulls in chain type definitions from the [@polkadot/apps-config package hosted on NPM](https://www.npmjs.com/package/@polkadot/apps-config). -If the chains type definitions do not already exist in [@polkadot/apps-config](https://github.com/polkadot-js/apps/tree/master/packages/apps-config) they will need to be added via PR to polkadot-js/apps by following their [instructions for API config](https://github.com/polkadot-js/apps/tree/master/packages/apps-config#api). +If the chain's type definitions do not already exist in [@polkadot/apps-config](https://github.com/polkadot-js/apps/tree/master/packages/apps-config) they will need to be added via PR to polkadot-js/apps by following their [instructions for API config](https://github.com/polkadot-js/apps/tree/master/packages/apps-config#api). -Before taking any other steps to integrate a chain with Sidecar, a chains up-to-date type definitions must be included in a published version of @polkadot/apps-config. +Before taking any other steps to integrate a chain with Sidecar, a chain's up-to-date type definitions must be included in a published version of @polkadot/apps-config. ## Controller configuration @@ -29,7 +29,7 @@ A chain builder can follow the below steps and submit a chain's controller confi To determine what controllers to include, one must consider the runtime logic, specifically what pallets the chain uses. It is important to keep in mind the assumptions the service's logic makes and what exact pallets the service queries. E.g. in order to use [`PalletsStakingProgressController`](/src/controllers/pallets/PalletsStakingProgressController.ts), one would check [`PalletsStakingProgressService.ts`](/src/services/pallets/PalletsStakingProgressService.ts). There one would see it queries `staking`, `sessions`, `babe` pallets and makes certain assumptions about how the pallets are used together in the runtime. -In some circumstance, a chain may need a new path, modify a path or altered bushiness logic for a path it. Path changes that help a chain support custodial wallets will be given priority. Breaking path changes are strongly not preferred. +In some circumstance, a chain may need a new path, modify a path or altered business logic for a path. Path changes that help a chain support custodial wallets will be given priority. Breaking path changes are strongly not preferred. ##### Basic balance transfer support @@ -58,7 +58,7 @@ const specToControllerMap = { #### 3) Test -Run it against an archive version of your chains node: +Run it against an archive version of your chain's node: - Ensure all the correct paths work, including the root path - Exercise each query param of every path From 4b4d9a21b7229a2b40ca41b981b6453c41332f99 Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Fri, 4 Dec 2020 10:04:46 -0800 Subject: [PATCH 14/22] Update CHAIN_INTEGRATION.md --- CHAIN_INTEGRATION.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHAIN_INTEGRATION.md b/CHAIN_INTEGRATION.md index f7f3c5804..0c795b8a0 100644 --- a/CHAIN_INTEGRATION.md +++ b/CHAIN_INTEGRATION.md @@ -25,11 +25,11 @@ A chain builder can follow the below steps and submit a chain's controller confi Create a controller config for your chain. The shape of the controller config is specified [here](/src/chains-config/ControllerConfig.ts). The `controller` property has keys from the [controller export](/src/controllers/index.ts), which is an exhaustive collection of the available controller classes. In order to see the path(s) associated with a controller one must look in the controller source code. - The easiest way to start creating a controller config would be to copy [defaultControllers.ts](/src/chains-config/ControllerConfig.ts) and name the file and export `{specName}Controllers`. Ensure to export the controller config from `chains-config` by adding `export * from './{specName}Controllers.ts'` in [/src/chains-config/index.ts](/src/chains-config/index.ts). Then change the boolean values to indicate wether or not to mount a controller and its paths. + The easiest way to start creating a controller config would be to copy [defaultControllers.ts](/src/chains-config/ControllerConfig.ts) and name the file and export `{specName}Controllers`. Then change the boolean values to indicate wether or not to mount a controller and its paths. Ensure to export the controller config from `chains-config` by adding `export * from './{specName}Controllers.ts'` in [/src/chains-config/index.ts](/src/chains-config/index.ts). To determine what controllers to include, one must consider the runtime logic, specifically what pallets the chain uses. It is important to keep in mind the assumptions the service's logic makes and what exact pallets the service queries. E.g. in order to use [`PalletsStakingProgressController`](/src/controllers/pallets/PalletsStakingProgressController.ts), one would check [`PalletsStakingProgressService.ts`](/src/services/pallets/PalletsStakingProgressService.ts). There one would see it queries `staking`, `sessions`, `babe` pallets and makes certain assumptions about how the pallets are used together in the runtime. -In some circumstance, a chain may need a new path, modify a path or altered business logic for a path. Path changes that help a chain support custodial wallets will be given priority. Breaking path changes are strongly not preferred. +In some circumstance, a chain may need a new path, modify a path or altered business logic for a path. Path changes that help a chain support wallets will be given priority. Breaking path changes are strongly not preferred. ##### Basic balance transfer support From b81c0d196bb675f5dcc69e555bf3837f6409f29f Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Mon, 7 Dec 2020 18:58:35 -0800 Subject: [PATCH 15/22] Bump deps --- package.json | 14 +-- yarn.lock | 345 ++++++++++++++++++++++++--------------------------- 2 files changed, 169 insertions(+), 190 deletions(-) diff --git a/package.json b/package.json index de436f803..d335fd39d 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,8 @@ "test": "jest --silent" }, "dependencies": { - "@polkadot/api": "^2.9.1", - "@polkadot/apps-config": "^0.68.1", + "@polkadot/api": "^2.10.1", + "@polkadot/apps-config": "^0.70.1", "@polkadot/util-crypto": "^4.2.1", "@substrate/calc": "^0.1.2", "confmgr": "^1.0.6", @@ -53,11 +53,11 @@ "@types/jest": "^26.0.16", "@types/morgan": "^1.9.2", "@types/triple-beam": "^1.3.2", - "@typescript-eslint/eslint-plugin": "4.9.0", - "@typescript-eslint/parser": "4.9.0", - "eslint": "^7.14.0", - "eslint-config-prettier": "^6.15.0", - "eslint-plugin-prettier": "^3.1.4", + "@typescript-eslint/eslint-plugin": "4.9.1", + "@typescript-eslint/parser": "4.9.1", + "eslint": "^7.15.0", + "eslint-config-prettier": "^7.0.0", + "eslint-plugin-prettier": "^3.2.0", "eslint-plugin-simple-import-sort": "^6.0.1", "jest": "^26.6.3", "prettier": "^2.2.1", diff --git a/yarn.lock b/yarn.lock index 26a0d97f4..7b7288a17 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3,9 +3,9 @@ "@acala-network/type-definitions@^0.4.0-beta.33": - version "0.4.0-beta.33" - resolved "https://registry.yarnpkg.com/@acala-network/type-definitions/-/type-definitions-0.4.0-beta.33.tgz#6b57fb5c415990ed33806ddf2547f797db125b9c" - integrity sha512-3c5WoUs23d2euM58w55itaiU35+CQrT5v8dOjX+I/Q7bqz0c/Q/qgKsZ22rtzjur18j0unBMbgM6OJSzuOTFQg== + version "0.4.0-beta.34" + resolved "https://registry.yarnpkg.com/@acala-network/type-definitions/-/type-definitions-0.4.0-beta.34.tgz#7e58d4990be76b6d0b6da5d15985e0cace06d479" + integrity sha512-NWUOm0cINP0FYWdOoQ64FFLDPzb1etwFuJnRQqcG7F4p6fCvxczuxWdmYx6adJKeiPO4UQaPEuZo2Y/jBetQig== dependencies: "@open-web3/orml-type-definitions" "^0.6.0-beta.26" @@ -309,15 +309,15 @@ enabled "2.0.x" kuler "^2.0.0" -"@edgeware/node-types@^3.0.7": +"@edgeware/node-types@^3.0.10": version "3.0.10" resolved "https://registry.yarnpkg.com/@edgeware/node-types/-/node-types-3.0.10.tgz#1b44af24dd0fdf48c1eedf90a90cda62e8f946aa" integrity sha512-fQgXhlnNPfRv+xUB/HRqbwt22c+BeofMDQzQ22GwOU8NQBXERhwgA2Hi0z1K3IKMqCtSIQlu1uepuFOQIIqrZQ== -"@eslint/eslintrc@^0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.2.1.tgz#f72069c330461a06684d119384435e12a5d76e3c" - integrity sha512-XRUeBZ5zBWLYgSANMpThFddrZZkEbGHgUdt5UJjZfnlN9BGCiUBrf+nvbRupSjMvqzwnQN0qwCmOxITt1cfywA== +"@eslint/eslintrc@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.2.2.tgz#d01fc791e2fc33e88a29d6f3dc7e93d0cd784b76" + integrity sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ== dependencies: ajv "^6.12.4" debug "^4.1.1" @@ -550,51 +550,52 @@ resolved "https://registry.yarnpkg.com/@open-web3/orml-type-definitions/-/orml-type-definitions-0.6.1.tgz#eb7fadf598f24f5024f5d2a1fd39ccc97c801104" integrity sha512-6asf2W/sluGQ6LNiGSdCg/Xop54mq/Q2FcV2Z9cBxys6QC4qXfo4JwUL6kJsRh/vcIIbUxoyGgKUrU/6Xdm7wA== -"@polkadot/api-derive@2.9.1": - version "2.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-2.9.1.tgz#e7f496d1b26f82471b649851e6d913769752ae2a" - integrity sha512-AIdWHbRcqXhymRDNrdR+WQHpDK131doFkOgR+7ZjoiI6PVMW79nqFCzlf/mBpdHGP2oBpx5Fc/YEIz5JyYm1hw== +"@polkadot/api-derive@2.10.1": + version "2.10.1" + resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-2.10.1.tgz#6dc6c0030e036e8a38d44b7e06fd884e9c1b32fb" + integrity sha512-cMbXrOyHWJ/uLxNiAjmRa6a8WM/FEDMansWbQGJtN7ebHrJD3t1SE53aM4zgD+AgaEJgPAUfI5RuOrEzxDDTdw== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/api" "2.9.1" - "@polkadot/rpc-core" "2.9.1" - "@polkadot/types" "2.9.1" + "@polkadot/api" "2.10.1" + "@polkadot/rpc-core" "2.10.1" + "@polkadot/types" "2.10.1" "@polkadot/util" "^4.2.1" "@polkadot/util-crypto" "^4.2.1" bn.js "^4.11.9" memoizee "^0.4.14" rxjs "^6.6.3" -"@polkadot/api@2.9.1", "@polkadot/api@^2.9.1": - version "2.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-2.9.1.tgz#ed594b7da3421230408250d2bb5564a45a4917fc" - integrity sha512-4yVLFiU9L8uawFJYGmkN4IcwtkXaw4exaXDP1qVzcFoLqKnn0bKsBNXdeB6Va1uM6bZwfLW6kkIsn3i7lHMgpg== +"@polkadot/api@2.10.1", "@polkadot/api@^2.10.1": + version "2.10.1" + resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-2.10.1.tgz#750987bccbf8e607c3690a7bdfed818bfc2c7571" + integrity sha512-C/vd5eGK3SDpPBWfs6tbNJM6uKpThE9GiTs5Lb5yR83J2ssvnZnn4qGOoEZnpPH+2iW7hVS4GR5sE9YcZxUXTg== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/api-derive" "2.9.1" + "@polkadot/api-derive" "2.10.1" "@polkadot/keyring" "^4.2.1" - "@polkadot/metadata" "2.9.1" - "@polkadot/rpc-core" "2.9.1" - "@polkadot/rpc-provider" "2.9.1" - "@polkadot/types" "2.9.1" - "@polkadot/types-known" "2.9.1" + "@polkadot/metadata" "2.10.1" + "@polkadot/rpc-core" "2.10.1" + "@polkadot/rpc-provider" "2.10.1" + "@polkadot/types" "2.10.1" + "@polkadot/types-known" "2.10.1" "@polkadot/util" "^4.2.1" "@polkadot/util-crypto" "^4.2.1" bn.js "^4.11.9" eventemitter3 "^4.0.7" rxjs "^6.6.3" -"@polkadot/apps-config@^0.68.1": - version "0.68.1" - resolved "https://registry.yarnpkg.com/@polkadot/apps-config/-/apps-config-0.68.1.tgz#ae3ad6cb8b6c34ca7aab8a3bc6923e6fbabe7af3" - integrity sha512-MSWqpVuZxMw3Fnzwakbf7ODAiB9BvjOWJS48sUTnZg1Obbp/vBAEZteBUkgEBSwuBupju9DjXkVXeJw8OU7WHA== +"@polkadot/apps-config@^0.70.1": + version "0.70.1" + resolved "https://registry.yarnpkg.com/@polkadot/apps-config/-/apps-config-0.70.1.tgz#f0a18c807b83966bb5fe37ded42ee7d0c45e13e7" + integrity sha512-T8BLYXnSqiGvVuYPV4rZk8ZtXae+j9OMEOe4+ubXZEUIR0gF69CYbEh3B+bLHGjaSx5AFPG64SHNAZCSJkN8hA== dependencies: "@acala-network/type-definitions" "^0.4.0-beta.33" "@babel/runtime" "^7.12.5" - "@edgeware/node-types" "^3.0.7" + "@edgeware/node-types" "^3.0.10" "@laminar/type-definitions" "^0.2.0-beta.141" "@polkadot/networks" "^4.2.1" - "@subsocial/types" "^0.4.7" + "@sora-substrate/type-definitions" "^0.1.7" + "@subsocial/types" "^0.4.23" "@polkadot/keyring@^4.2.1": version "4.2.1" @@ -605,14 +606,14 @@ "@polkadot/util" "4.2.1" "@polkadot/util-crypto" "4.2.1" -"@polkadot/metadata@2.9.1": - version "2.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/metadata/-/metadata-2.9.1.tgz#2028a0e7fe1060057f9e606cea2b29bf93ec3fd9" - integrity sha512-CV5ux4zsRMhPT6cGezqCSNToFASr+JftVgCrIGo05N8KmSds0vy2TaL4c1jPc6c0ZZ6DLLPefnGitPlEdZh6EQ== +"@polkadot/metadata@2.10.1": + version "2.10.1" + resolved "https://registry.yarnpkg.com/@polkadot/metadata/-/metadata-2.10.1.tgz#bea4696c8773af4214c071ab5017bef215d978c1" + integrity sha512-ilB81k4ZDFVLHYo8mhxs9VFpL7Vi/Q0tqTSuQ+ziD3U7fYh0QV5si+1nqo5EBzvIKws6hsC7B4bTPQLJHHTC9w== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/types" "2.9.1" - "@polkadot/types-known" "2.9.1" + "@polkadot/types" "2.10.1" + "@polkadot/types-known" "2.10.1" "@polkadot/util" "^4.2.1" "@polkadot/util-crypto" "^4.2.1" bn.js "^4.11.9" @@ -624,26 +625,26 @@ dependencies: "@babel/runtime" "^7.12.5" -"@polkadot/rpc-core@2.9.1": - version "2.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-2.9.1.tgz#4048e0fc4561609fb660c065435c13e3b96cf7e4" - integrity sha512-Pjqw6QepG1ctfDKOKVfDyDUU4KWshls5LI95N8mRFolkp2wTnCJPp897+4iDtTKUA6S5Dl4pUFypzuo8Ok/wVQ== +"@polkadot/rpc-core@2.10.1": + version "2.10.1" + resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-2.10.1.tgz#6d9cca349dc03324dbf9c3bfe2a9db555808a664" + integrity sha512-oyEEhSwlKW3FNO5v7MJYSoiF5kIxcJKMKVJSIpLHp6G2oHhgKRZtsGlX4n6QJYxIBWb0EueewpkuEMCGAv3R7g== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/metadata" "2.9.1" - "@polkadot/rpc-provider" "2.9.1" - "@polkadot/types" "2.9.1" + "@polkadot/metadata" "2.10.1" + "@polkadot/rpc-provider" "2.10.1" + "@polkadot/types" "2.10.1" "@polkadot/util" "^4.2.1" memoizee "^0.4.14" rxjs "^6.6.3" -"@polkadot/rpc-provider@2.9.1": - version "2.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-2.9.1.tgz#833d737e42c14b24449535093171bc693b67c4b8" - integrity sha512-LLweHTOnpbX7tBhrt5DVAYb0UUXsKosMFlpCQfyoyIQ1ACRT0cnd+AKF8eKf04Ayytg+q/USD8tGGDbH+XElOg== +"@polkadot/rpc-provider@2.10.1": + version "2.10.1" + resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-2.10.1.tgz#7929b5aa8899033ba127984b4411baef92a1232d" + integrity sha512-VvrFedxIbPrcm3CadZLdVwm3eWyyaZV1Sh0BSGZ2u9Pi2JkONshWrg7mf32SbKhckXWt/BNwUnpCQfIUjnKaDw== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/types" "2.9.1" + "@polkadot/types" "2.10.1" "@polkadot/util" "^4.2.1" "@polkadot/util-crypto" "^4.2.1" "@polkadot/x-fetch" "^4.2.1" @@ -651,23 +652,23 @@ bn.js "^4.11.9" eventemitter3 "^4.0.7" -"@polkadot/types-known@2.9.1": - version "2.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-2.9.1.tgz#8af3a81b09e7e4d6b82d4453240e7e5ab3bb06cd" - integrity sha512-veSPubDFQd7Ql8Lxly+pE4fCN+rei7O2j0yGkoCHi06yFxkATqM3aj6DI1Z3g7Uk9kLJTTIb4db3aQbaVFXpNQ== +"@polkadot/types-known@2.10.1": + version "2.10.1" + resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-2.10.1.tgz#37bc032aae7db12e9a4480caf5aa65f619cffac9" + integrity sha512-RmnRPMoypxodfXRRqO+t4ogeaHTEC1S968+Djo8SYeSSmeUrlo9LdoJ5DZBXd0dTOUJbo0wXl9DOjL5qVnRy6A== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/types" "2.9.1" + "@polkadot/types" "2.10.1" "@polkadot/util" "^4.2.1" bn.js "^4.11.9" -"@polkadot/types@2.9.1": - version "2.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-2.9.1.tgz#2e113d30759d69928202b83e67c2caafe632201b" - integrity sha512-CaDFaeHgf3RYI7soiXK2V7UghEVwystp+o4LCMeT6UUgxS0I0kOkpNYcjLD5P02gUtHhQYxcWqUnGi8X8R3kOg== +"@polkadot/types@2.10.1": + version "2.10.1" + resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-2.10.1.tgz#84189d508c28d375ec562a049aaf58aa34256a74" + integrity sha512-wRs9X7uiSRNQBFxcuCDv++FU+HgFml55U73zsqxDgBb7+bor4QGLPpki8rV+xQOpqhfPjKHN1gosK99sFcC3Aw== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/metadata" "2.9.1" + "@polkadot/metadata" "2.10.1" "@polkadot/util" "^4.2.1" "@polkadot/util-crypto" "^4.2.1" "@types/bn.js" "^4.11.6" @@ -767,18 +768,25 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@subsocial/types@^0.4.7": - version "0.4.23" - resolved "https://registry.yarnpkg.com/@subsocial/types/-/types-0.4.23.tgz#c1a5a5628e991fd91e74e5f20297cad63b8c5b84" - integrity sha512-O4rZP4rzznnEOtbgpQlTqcN/NJtYGFymPV/0pTladW471nawELuLlzxImP4ytH5/XWOXl4bdWJ1lcuukzkfOVQ== +"@sora-substrate/type-definitions@^0.1.7": + version "0.1.8" + resolved "https://registry.yarnpkg.com/@sora-substrate/type-definitions/-/type-definitions-0.1.8.tgz#64eb12744f4cca28b4dff993d5017b626ff8387f" + integrity sha512-b1mSS21PWkXMf54sVmWlkR9CxB64u+2z+loD+DSxFuYGbv5/Bae1stdiwyx1UkXjjWEk2aosux31YH1QMvbWeQ== dependencies: - "@subsocial/utils" latest + "@open-web3/orml-type-definitions" "^0.6.0-beta.26" + +"@subsocial/types@^0.4.23": + version "0.4.26" + resolved "https://registry.yarnpkg.com/@subsocial/types/-/types-0.4.26.tgz#5dae4939971a5b4acf10e90ebfa2672a2caca95d" + integrity sha512-jBYVsBowkx+yEtxQ4hZLT6mpkBy36MP31zIAUUDVQWdEp1esnr5ASRiU9SCwIDBEiZcZkv+tz+bRnuSZCr23Ag== + dependencies: + "@subsocial/utils" "^0.4.25" cids "^0.7.1" -"@subsocial/utils@latest": - version "0.4.23" - resolved "https://registry.yarnpkg.com/@subsocial/utils/-/utils-0.4.23.tgz#592714cc3cfb81c7ec38fe0ad15c69ae5b9f1de0" - integrity sha512-53PSVvyjDdP3cxgbXscQ8n85PWMD96V7zel+p3o6Qj1hl7Ad+jxwpJNsR35sat63NnbJWeUwvG+y7NZG6vJOmg== +"@subsocial/utils@^0.4.25": + version "0.4.25" + resolved "https://registry.yarnpkg.com/@subsocial/utils/-/utils-0.4.25.tgz#11aa5524979f9bd38ff26b9c00f794a8dc70fc61" + integrity sha512-YpAwLmY5XP3Md1ogi8lWKCqressHeMNiCUO9Bg8b5mNajfDvfjX5ujUz2p6aF3dzh3lJDqZ1CeTCm8+rFankkA== dependencies: bn.js "^5.1.1" chalk "^3.0.0" @@ -999,67 +1007,67 @@ integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== "@types/yargs@^15.0.0": - version "15.0.10" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.10.tgz#0fe3c8173a0d5c3e780b389050140c3f5ea6ea74" - integrity sha512-z8PNtlhrj7eJNLmrAivM7rjBESG6JwC5xP3RVk12i/8HVP7Xnx/sEmERnRImyEuUaJfO942X0qMOYsoupaJbZQ== + version "15.0.11" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.11.tgz#361d7579ecdac1527687bcebf9946621c12ab78c" + integrity sha512-jfcNBxHFYJ4nPIacsi3woz1+kvUO6s1CyeEhtnDHBjHUMNj5UlW2GynmnSgiJJEdNg9yW5C8lfoNRZrHGv5EqA== dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@4.9.0": - version "4.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.9.0.tgz#8fde15743413661fdc086c9f1f5d74a80b856113" - integrity sha512-WrVzGMzzCrgrpnQMQm4Tnf+dk+wdl/YbgIgd5hKGa2P+lnJ2MON+nQnbwgbxtN9QDLi8HO+JAq0/krMnjQK6Cw== +"@typescript-eslint/eslint-plugin@4.9.1": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.9.1.tgz#66758cbe129b965fe9c63b04b405d0cf5280868b" + integrity sha512-QRLDSvIPeI1pz5tVuurD+cStNR4sle4avtHhxA+2uyixWGFjKzJ+EaFVRW6dA/jOgjV5DTAjOxboQkRDE8cRlQ== dependencies: - "@typescript-eslint/experimental-utils" "4.9.0" - "@typescript-eslint/scope-manager" "4.9.0" + "@typescript-eslint/experimental-utils" "4.9.1" + "@typescript-eslint/scope-manager" "4.9.1" debug "^4.1.1" functional-red-black-tree "^1.0.1" regexpp "^3.0.0" semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@4.9.0": - version "4.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.9.0.tgz#23a296b85d243afba24e75a43fd55aceda5141f0" - integrity sha512-0p8GnDWB3R2oGhmRXlEnCvYOtaBCijtA5uBfH5GxQKsukdSQyI4opC4NGTUb88CagsoNQ4rb/hId2JuMbzWKFQ== +"@typescript-eslint/experimental-utils@4.9.1": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.9.1.tgz#86633e8395191d65786a808dc3df030a55267ae2" + integrity sha512-c3k/xJqk0exLFs+cWSJxIjqLYwdHCuLWhnpnikmPQD2+NGAx9KjLYlBDcSI81EArh9FDYSL6dslAUSwILeWOxg== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.9.0" - "@typescript-eslint/types" "4.9.0" - "@typescript-eslint/typescript-estree" "4.9.0" + "@typescript-eslint/scope-manager" "4.9.1" + "@typescript-eslint/types" "4.9.1" + "@typescript-eslint/typescript-estree" "4.9.1" eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/parser@4.9.0": - version "4.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.9.0.tgz#bb65f1214b5e221604996db53ef77c9d62b09249" - integrity sha512-QRSDAV8tGZoQye/ogp28ypb8qpsZPV6FOLD+tbN4ohKUWHD2n/u0Q2tIBnCsGwQCiD94RdtLkcqpdK4vKcLCCw== +"@typescript-eslint/parser@4.9.1": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.9.1.tgz#2d74c4db5dd5117379a9659081a4d1ec02629055" + integrity sha512-Gv2VpqiomvQ2v4UL+dXlQcZ8zCX4eTkoIW+1aGVWT6yTO+6jbxsw7yQl2z2pPl/4B9qa5JXeIbhJpONKjXIy3g== dependencies: - "@typescript-eslint/scope-manager" "4.9.0" - "@typescript-eslint/types" "4.9.0" - "@typescript-eslint/typescript-estree" "4.9.0" + "@typescript-eslint/scope-manager" "4.9.1" + "@typescript-eslint/types" "4.9.1" + "@typescript-eslint/typescript-estree" "4.9.1" debug "^4.1.1" -"@typescript-eslint/scope-manager@4.9.0": - version "4.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.9.0.tgz#5eefe305d6b71d1c85af6587b048426bfd4d3708" - integrity sha512-q/81jtmcDtMRE+nfFt5pWqO0R41k46gpVLnuefqVOXl4QV1GdQoBWfk5REcipoJNQH9+F5l+dwa9Li5fbALjzg== +"@typescript-eslint/scope-manager@4.9.1": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.9.1.tgz#cc2fde310b3f3deafe8436a924e784eaab265103" + integrity sha512-sa4L9yUfD/1sg9Kl8OxPxvpUcqxKXRjBeZxBuZSSV1v13hjfEJkn84n0An2hN8oLQ1PmEl2uA6FkI07idXeFgQ== dependencies: - "@typescript-eslint/types" "4.9.0" - "@typescript-eslint/visitor-keys" "4.9.0" + "@typescript-eslint/types" "4.9.1" + "@typescript-eslint/visitor-keys" "4.9.1" -"@typescript-eslint/types@4.9.0": - version "4.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.9.0.tgz#3fe8c3632abd07095c7458f7451bd14c85d0033c" - integrity sha512-luzLKmowfiM/IoJL/rus1K9iZpSJK6GlOS/1ezKplb7MkORt2dDcfi8g9B0bsF6JoRGhqn0D3Va55b+vredFHA== +"@typescript-eslint/types@4.9.1": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.9.1.tgz#a1a7dd80e4e5ac2c593bc458d75dd1edaf77faa2" + integrity sha512-fjkT+tXR13ks6Le7JiEdagnwEFc49IkOyys7ueWQ4O8k4quKPwPJudrwlVOJCUQhXo45PrfIvIarcrEjFTNwUA== -"@typescript-eslint/typescript-estree@4.9.0": - version "4.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.9.0.tgz#38a98df6ee281cfd6164d6f9d91795b37d9e508c" - integrity sha512-rmDR++PGrIyQzAtt3pPcmKWLr7MA+u/Cmq9b/rON3//t5WofNR4m/Ybft2vOLj0WtUzjn018ekHjTsnIyBsQug== +"@typescript-eslint/typescript-estree@4.9.1": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.9.1.tgz#6e5b86ff5a5f66809e1f347469fadeec69ac50bf" + integrity sha512-bzP8vqwX6Vgmvs81bPtCkLtM/Skh36NE6unu6tsDeU/ZFoYthlTXbBmpIrvosgiDKlWTfb2ZpPELHH89aQjeQw== dependencies: - "@typescript-eslint/types" "4.9.0" - "@typescript-eslint/visitor-keys" "4.9.0" + "@typescript-eslint/types" "4.9.1" + "@typescript-eslint/visitor-keys" "4.9.1" debug "^4.1.1" globby "^11.0.1" is-glob "^4.0.1" @@ -1067,12 +1075,12 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/visitor-keys@4.9.0": - version "4.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.9.0.tgz#f284e9fac43f2d6d35094ce137473ee321f266c8" - integrity sha512-sV45zfdRqQo1A97pOSx3fsjR+3blmwtdCt8LDrXgCX36v4Vmz4KHrhpV6Fo2cRdXmyumxx11AHw0pNJqCNpDyg== +"@typescript-eslint/visitor-keys@4.9.1": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.9.1.tgz#d76374a58c4ead9e92b454d186fea63487b25ae1" + integrity sha512-9gspzc6UqLQHd7lXQS7oWs+hrYggspv/rk6zzEMhCbYwPE/sF7oxo7GAjkS35Tdlt7wguIG+ViWCPtVZHz/ybQ== dependencies: - "@typescript-eslint/types" "4.9.0" + "@typescript-eslint/types" "4.9.1" eslint-visitor-keys "^2.0.0" JSONStream@^1.0.4: @@ -1104,7 +1112,7 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" -acorn-jsx@^5.2.0: +acorn-jsx@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== @@ -2377,17 +2385,15 @@ escodegen@^1.14.1: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^6.15.0: - version "6.15.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz#7f93f6cb7d45a92f1537a70ecc06366e1ac6fed9" - integrity sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw== - dependencies: - get-stdin "^6.0.0" +eslint-config-prettier@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.0.0.tgz#c1ae4106f74e6c0357f44adb076771d032ac0e97" + integrity sha512-8Y8lGLVPPZdaNA7JXqnvETVC7IiVRgAP6afQu9gOQRn90YY3otMNh+x7Vr2vMePQntF+5erdSUBqSzCmU/AxaQ== -eslint-plugin-prettier@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz#168ab43154e2ea57db992a2cd097c828171f75c2" - integrity sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg== +eslint-plugin-prettier@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.2.0.tgz#af391b2226fa0e15c96f36c733f6e9035dbd952c" + integrity sha512-kOUSJnFjAUFKwVxuzy6sA5yyMx6+o9ino4gCdShzBNx4eyFRudWRYKCFolKjoM40PEiuU6Cn7wBLfq3WsGg7qg== dependencies: prettier-linter-helpers "^1.0.0" @@ -2421,13 +2427,13 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint@^7.14.0: - version "7.14.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.14.0.tgz#2d2cac1d28174c510a97b377f122a5507958e344" - integrity sha512-5YubdnPXrlrYAFCKybPuHIAH++PINe1pmKNc5wQRB9HSbqIK1ywAnntE3Wwua4giKu0bjligf1gLF6qxMGOYRA== +eslint@^7.15.0: + version "7.15.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.15.0.tgz#eb155fb8ed0865fcf5d903f76be2e5b6cd7e0bc7" + integrity sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA== dependencies: "@babel/code-frame" "^7.0.0" - "@eslint/eslintrc" "^0.2.1" + "@eslint/eslintrc" "^0.2.2" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -2437,10 +2443,10 @@ eslint@^7.14.0: eslint-scope "^5.1.1" eslint-utils "^2.1.0" eslint-visitor-keys "^2.0.0" - espree "^7.3.0" + espree "^7.3.1" esquery "^1.2.0" esutils "^2.0.2" - file-entry-cache "^5.0.1" + file-entry-cache "^6.0.0" functional-red-black-tree "^1.0.1" glob-parent "^5.0.0" globals "^12.1.0" @@ -2464,13 +2470,13 @@ eslint@^7.14.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.0.tgz#dc30437cf67947cf576121ebd780f15eeac72348" - integrity sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw== +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== dependencies: acorn "^7.4.0" - acorn-jsx "^5.2.0" + acorn-jsx "^5.3.1" eslint-visitor-keys "^1.3.0" esprima@^4.0.0, esprima@^4.0.1: @@ -2759,12 +2765,12 @@ figures@^3.1.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== +file-entry-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.0.tgz#7921a89c391c6d93efec2169ac6bf300c527ea0a" + integrity sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA== dependencies: - flat-cache "^2.0.1" + flat-cache "^3.0.4" fill-range@^4.0.0: version "4.0.0" @@ -2826,19 +2832,18 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" + flatted "^3.1.0" + rimraf "^3.0.2" -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== +flatted@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" + integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA== fn.name@1.x.x: version "1.1.0" @@ -2953,11 +2958,6 @@ get-stdin@^4.0.1: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= -get-stdin@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" - integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== - get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -4010,9 +4010,9 @@ js-tokens@^4.0.0: integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -4578,13 +4578,6 @@ mkdirp@1.x: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - modify-values@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" @@ -5474,13 +5467,6 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -6628,17 +6614,10 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - ws@^7.2.3: - version "7.4.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.0.tgz#a5dd76a24197940d4a8bb9e0e152bb4503764da7" - integrity sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ== + version "7.4.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.1.tgz#a333be02696bd0e54cea0434e21dcc8a9ac294bb" + integrity sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ== xml-name-validator@^3.0.0: version "3.0.0" From 92a8856d6a9814e4d72b6ddede675c42371ec623 Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Mon, 7 Dec 2020 19:44:51 -0800 Subject: [PATCH 16/22] Use whole options object for controller creation --- src/chains-config/index.ts | 4 +--- src/controllers/blocks/BlocksController.ts | 8 ++++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/chains-config/index.ts b/src/chains-config/index.ts index 82ea7183e..5fb9934f0 100644 --- a/src/chains-config/index.ts +++ b/src/chains-config/index.ts @@ -48,9 +48,7 @@ function getControllersFromConfig(api: ApiPromise, config: ControllerConfig) { return controllersToInclude.reduce((acc, [controllerName, shouldMount]) => { if (shouldMount) { - acc.push( - new controllers[controllerName](api, config.options.finalizes) - ); + acc.push(new controllers[controllerName](api, config.options)); } return acc; diff --git a/src/controllers/blocks/BlocksController.ts b/src/controllers/blocks/BlocksController.ts index c5400daed..ca95a9ba2 100644 --- a/src/controllers/blocks/BlocksController.ts +++ b/src/controllers/blocks/BlocksController.ts @@ -5,6 +5,10 @@ import { BlocksService } from '../../services'; import { INumberParam } from '../../types/requests'; import AbstractController from '../AbstractController'; +interface ControllerOptions { + finalizes: boolean; +} + /** * GET a block. * @@ -65,7 +69,7 @@ import AbstractController from '../AbstractController'; * - `OnFinalize`: https://crates.parity.io/frame_support/traits/trait.OnFinalize.html */ export default class BlocksController extends AbstractController { - constructor(api: ApiPromise, private finalizes = true) { + constructor(api: ApiPromise, private readonly options: ControllerOptions) { super(api, '/blocks', new BlocksService(api)); this.initRoutes(); } @@ -91,7 +95,7 @@ export default class BlocksController extends AbstractController const extrsinsicDocsArg = extrinsicDocs === 'true'; const hash = - finalized === 'false' || !this.finalizes + finalized === 'false' || !this.options.finalizes ? (await this.api.rpc.chain.getHeader()).hash : await this.api.rpc.chain.getFinalizedHead(); From 84513097fdaf8162ba13db2d1204233e27027239 Mon Sep 17 00:00:00 2001 From: Zeke Mostov <32168567+emostov@users.noreply.github.com> Date: Tue, 8 Dec 2020 18:21:08 -0800 Subject: [PATCH 17/22] Apply suggestions from code review Co-authored-by: David --- CHAIN_INTEGRATION.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/CHAIN_INTEGRATION.md b/CHAIN_INTEGRATION.md index 0c795b8a0..9c96c29a2 100644 --- a/CHAIN_INTEGRATION.md +++ b/CHAIN_INTEGRATION.md @@ -19,7 +19,7 @@ Before taking any other steps to integrate a chain with Sidecar, a chain's up-to Sidecar offers the ability to configure which controllers to mount. Sidecar uses a chain's spec name to determine which controller config to use, and if no config is linked to a spec name, then the [default config](/src/chains-config/defaultControllers.ts) is used. -A chain builder can follow the below steps and submit a chain's controller config via PR, where it will be reviewed and merged once deemed ready by the maintainers. +A chain builder can follow the steps below and submit a chain's controller config via PR, where it will be reviewed and merged once deemed ready by the maintainers. #### 1) Create a controller config @@ -27,15 +27,16 @@ A chain builder can follow the below steps and submit a chain's controller confi The easiest way to start creating a controller config would be to copy [defaultControllers.ts](/src/chains-config/ControllerConfig.ts) and name the file and export `{specName}Controllers`. Then change the boolean values to indicate wether or not to mount a controller and its paths. Ensure to export the controller config from `chains-config` by adding `export * from './{specName}Controllers.ts'` in [/src/chains-config/index.ts](/src/chains-config/index.ts). - To determine what controllers to include, one must consider the runtime logic, specifically what pallets the chain uses. It is important to keep in mind the assumptions the service's logic makes and what exact pallets the service queries. E.g. in order to use [`PalletsStakingProgressController`](/src/controllers/pallets/PalletsStakingProgressController.ts), one would check [`PalletsStakingProgressService.ts`](/src/services/pallets/PalletsStakingProgressService.ts). There one would see it queries `staking`, `sessions`, `babe` pallets and makes certain assumptions about how the pallets are used together in the runtime. + To determine what controllers to include, one must consider the runtime logic, specifically what pallets the chain uses. It is important to keep in mind the assumptions the service's logic makes and what exact pallets the service queries. +An example is in order. If we want to use [`PalletsStakingProgressController`](/src/controllers/pallets/PalletsStakingProgressController.ts), first check [`PalletsStakingProgressService.ts`](/src/services/pallets/PalletsStakingProgressService.ts); here we see it queries `staking`, `sessions`, `babe` pallets and makes certain assumptions about how the pallets are used together in the runtime. -In some circumstance, a chain may need a new path, modify a path or altered business logic for a path. Path changes that help a chain support wallets will be given priority. Breaking path changes are strongly not preferred. +In some circumstance, a chain may need a new path, modify a path or altered business logic for a path. Path changes that help a chain support wallets will be given priority. Breaking changes to paths are usually rejected. ##### Basic balance transfer support In order to support traditional balance transfers the chain's Sidecar endpoints should support account balance lookup, transaction submission, transaction material retrieval, and block queries. -To support those actions the following endpoints are necessary: +To support these features the following endpoints are necessary: | Path | Controller | Description | |:----------------------------------------:|:-----------------------------:|:--------------------------------------------------------------------------:| @@ -58,9 +59,9 @@ const specToControllerMap = { #### 3) Test -Run it against an archive version of your chain's node: +Run it against a node running your chain in archive mode: -- Ensure all the correct paths work, including the root path +- Ensure all the expected paths work, including the root path, preferably with tests - Exercise each query param of every path - Make sure transaction submission works - Try out historic queries across runtimes where types might change From 87572a9efebb3b0da84bdea9522fc39d041f45de Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Tue, 8 Dec 2020 18:27:51 -0800 Subject: [PATCH 18/22] Respond to maciej feedback --- CHAIN_INTEGRATION.md | 2 +- src/main.ts | 4 +--- src/services/blocks/BlocksService.ts | 16 +++++++++++----- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/CHAIN_INTEGRATION.md b/CHAIN_INTEGRATION.md index 0c795b8a0..ed2685ed3 100644 --- a/CHAIN_INTEGRATION.md +++ b/CHAIN_INTEGRATION.md @@ -72,4 +72,4 @@ Make sure it passes lint with `yarn lint --fix` and tests with `yarn test`. Then #### 5) Maintenance - Keep types up-to-date in `@polkadot/apps-config` -- If the business logic or storage of a chain's pallet queried by a Sidecar endpoint is changed, ensure Sidecar has service logic has any relevant updates. +- If the business logic or storage of a chain's pallet queried by a Sidecar endpoint is changed, ensure that the corresponding service logic is updated in Sidecar as well diff --git a/src/main.ts b/src/main.ts index 1707e95e8..4a822db9e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -135,9 +135,7 @@ function startUpPrompt(wsUrl: string, chainName: string, implName: string) { const isSecure: boolean = splitUrl[0] === 'wss'; // Check if its a local IP. const isLocal: boolean = - splitUrl[1] === '//0.0.0.0' || - splitUrl[1] === '//127.0.0.1' || - splitUrl[1] === '//localhost'; + splitUrl[1] === '//127.0.0.1' || splitUrl[1] === '//localhost'; if (!isSecure && !isLocal) { logger.warn( diff --git a/src/services/blocks/BlocksService.ts b/src/services/blocks/BlocksService.ts index 196c93a4b..06def1d2e 100644 --- a/src/services/blocks/BlocksService.ts +++ b/src/services/blocks/BlocksService.ts @@ -47,7 +47,10 @@ export class BlocksService extends AbstractService { let block; let events; let author; - if (typeof api.query?.session?.validators?.at === 'function') { + if (typeof api.query.session?.validators?.at === 'function') { + // `api.derive.chain.getBlock` requires that `api.query.session?.validators?.at` + // is a function in order to query the validator set to pull out the author + // see: https://github.com/polkadot-js/api/blob/master/packages/api-derive/src/chain/getBlock.ts#L31 [{ author, block }, events] = await Promise.all([ api.derive.chain.getBlock(hash) as Promise, this.fetchEvents(api, hash), @@ -338,7 +341,12 @@ export class BlocksService extends AbstractService { const extrinsicBaseWeight = api?.consts?.system?.extrinsicBaseWeight; let calcFee, specName, specVersion; - if (perByte === undefined || extrinsicBaseWeight === undefined) { + if ( + perByte === undefined || + extrinsicBaseWeight === undefined || + typeof api.query.transactionPayment?.nextFeeMultiplier?.at !== + 'function' + ) { // We do not have the neccesary materials to build calcFee, so we just give a dummy function // that aligns with the expected API of calcFee. calcFee = { calc_fee: () => null }; @@ -374,9 +382,7 @@ export class BlocksService extends AbstractService { const [version, multiplier] = await Promise.all([ api.rpc.state.getRuntimeVersion(parentParentHash), - api.query?.transactionPayment?.nextFeeMultiplier?.at( - parentHash - ), + api.query.transactionPayment.nextFeeMultiplier.at(parentHash), ]); [specName, specVersion] = [ From a1a988aadc6427f81df8086c2ea85f903cd0665c Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Tue, 8 Dec 2020 18:36:22 -0800 Subject: [PATCH 19/22] Update chain integration guide --- CHAIN_INTEGRATION.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHAIN_INTEGRATION.md b/CHAIN_INTEGRATION.md index 4cea40f4b..2e524e326 100644 --- a/CHAIN_INTEGRATION.md +++ b/CHAIN_INTEGRATION.md @@ -28,7 +28,8 @@ A chain builder can follow the steps below and submit a chain's controller confi The easiest way to start creating a controller config would be to copy [defaultControllers.ts](/src/chains-config/ControllerConfig.ts) and name the file and export `{specName}Controllers`. Then change the boolean values to indicate wether or not to mount a controller and its paths. Ensure to export the controller config from `chains-config` by adding `export * from './{specName}Controllers.ts'` in [/src/chains-config/index.ts](/src/chains-config/index.ts). To determine what controllers to include, one must consider the runtime logic, specifically what pallets the chain uses. It is important to keep in mind the assumptions the service's logic makes and what exact pallets the service queries. -An example is in order. If we want to use [`PalletsStakingProgressController`](/src/controllers/pallets/PalletsStakingProgressController.ts), first check [`PalletsStakingProgressService.ts`](/src/services/pallets/PalletsStakingProgressService.ts); here we see it queries `staking`, `sessions`, `babe` pallets and makes certain assumptions about how the pallets are used together in the runtime. + +An example is in order. If we want to use [`PalletsStakingProgressController`](/src/controllers/pallets/PalletsStakingProgressController.ts), first check [`PalletsStakingProgressService.ts`](/src/services/pallets/PalletsStakingProgressService.ts); here we see it queries `staking`, `sessions`, `babe` pallets and makes certain assumptions about how the pallets are used together in the runtime. If we determine that both have all storage items queried, and the assumptions made about the staking system are correct, we can then declare in `{specName}Controllers` (the controller config object) that we want to mount the controller by giving `PalletsStakingProgressController` property `true` as the value (`{ PalletsStakingProgressController: true }`). Finally, we can test it out by starting up Sidecar against our chain and accessing the `pallets/staking/progress` endpoint, verifying that the information returned is correct. In some circumstance, a chain may need a new path, modify a path or altered business logic for a path. Path changes that help a chain support wallets will be given priority. Breaking changes to paths are usually rejected. From 79f9eb8d7ffd7d90199787c7ae71e4ae90211155 Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Tue, 8 Dec 2020 18:41:47 -0800 Subject: [PATCH 20/22] Remove excessive nullish colescing operators --- src/services/blocks/BlocksService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/blocks/BlocksService.ts b/src/services/blocks/BlocksService.ts index 06def1d2e..e476df475 100644 --- a/src/services/blocks/BlocksService.ts +++ b/src/services/blocks/BlocksService.ts @@ -337,8 +337,8 @@ export class BlocksService extends AbstractService { parentHash: Hash, block: Block ) { - const perByte = api?.consts?.transactionPayment?.transactionByteFee; - const extrinsicBaseWeight = api?.consts?.system?.extrinsicBaseWeight; + const perByte = api.consts.transactionPayment?.transactionByteFee; + const extrinsicBaseWeight = api.consts.system?.extrinsicBaseWeight; let calcFee, specName, specVersion; if ( From b34cca210ad96186cd90665e7d9e55868b7ef536 Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Tue, 8 Dec 2020 18:48:26 -0800 Subject: [PATCH 21/22] Fix merge issue --- .../accounts/AccountsBalanceInfoService.ts | 41 +------------------ 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/src/services/accounts/AccountsBalanceInfoService.ts b/src/services/accounts/AccountsBalanceInfoService.ts index 6ece0e706..ad9f526c6 100644 --- a/src/services/accounts/AccountsBalanceInfoService.ts +++ b/src/services/accounts/AccountsBalanceInfoService.ts @@ -1,40 +1,3 @@ -Skip to content -Search or jump to… - -Pull requests -Issues -Marketplace -Explore - -@emostov -paritytech - / - substrate - api - sidecar -12 -56 -29 -Code -Issues -20 -Pull requests -1 -Actions -Security -4 -Insights -Settings -substrate - api - sidecar / src / services / accounts / AccountsBalanceInfoService.ts / -@emostov -emostov Initial reply david review -Latest commit be66056 6 days ago -History -2 contributors -@emostov @joepetrowski -We found potential security vulnerabilities in your dependencies. -You can see this message because you have been granted access to Dependabot alerts for this repository. - -95 lines(87 sloc) 2.38 KB - import { Vec } from '@polkadot/types'; import { AccountData, @@ -94,7 +57,7 @@ export class AccountsBalanceInfoService extends AbstractService { } catch { throw new BadRequest( 'An error occured while attempting to query for a non-native token; ' + - 'the token specified is likely invalid.' + 'the token specified is likely invalid.' ); } @@ -123,7 +86,7 @@ export class AccountsBalanceInfoService extends AbstractService { locks, }; } else { - throw new BadRequest('Account not found') + throw new BadRequest('Account not found'); } } } From a16235a2d726676e0d917a0ae28e6291b3e9904b Mon Sep 17 00:00:00 2001 From: Zeke Mostov <32168567+emostov@users.noreply.github.com> Date: Wed, 9 Dec 2020 12:22:54 -0800 Subject: [PATCH 22/22] Update CHAIN_INTEGRATION.md Co-authored-by: David --- CHAIN_INTEGRATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHAIN_INTEGRATION.md b/CHAIN_INTEGRATION.md index 2e524e326..d0bb5adf0 100644 --- a/CHAIN_INTEGRATION.md +++ b/CHAIN_INTEGRATION.md @@ -31,7 +31,7 @@ A chain builder can follow the steps below and submit a chain's controller confi An example is in order. If we want to use [`PalletsStakingProgressController`](/src/controllers/pallets/PalletsStakingProgressController.ts), first check [`PalletsStakingProgressService.ts`](/src/services/pallets/PalletsStakingProgressService.ts); here we see it queries `staking`, `sessions`, `babe` pallets and makes certain assumptions about how the pallets are used together in the runtime. If we determine that both have all storage items queried, and the assumptions made about the staking system are correct, we can then declare in `{specName}Controllers` (the controller config object) that we want to mount the controller by giving `PalletsStakingProgressController` property `true` as the value (`{ PalletsStakingProgressController: true }`). Finally, we can test it out by starting up Sidecar against our chain and accessing the `pallets/staking/progress` endpoint, verifying that the information returned is correct. -In some circumstance, a chain may need a new path, modify a path or altered business logic for a path. Path changes that help a chain support wallets will be given priority. Breaking changes to paths are usually rejected. +In some circumstances, a chain may need a new path, modify a path or alter business logic for a path. Path changes that help a chain support wallets will be given priority. Breaking changes to paths are usually rejected. ##### Basic balance transfer support