From 5c7bf98e5972c447c3e220be4797aa98da7d40d6 Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Fri, 18 Dec 2020 13:11:42 -0800 Subject: [PATCH 1/9] chore(release): 2.1.0 --- CHANGELOG.md | 24 ++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 564a7a2f1..144e8e034 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,30 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [2.1.0](https://github.com/paritytech/substrate-api-sidecar/compare/v1.0.0-rc4...v2.1.0) (2020-12-18) + + +### ⚠ BREAKING CHANGES + +* Bump polkadot-js and document runtime/metadata API regression (#338) +* Remove all v0 routes to prepare for v1 release + +### Features + +* Bump polkadot-js and document runtime/metadata API regression ([#338](https://github.com/paritytech/substrate-api-sidecar/issues/338)) ([effc5eb](https://github.com/paritytech/substrate-api-sidecar/commit/effc5eb159587b2b3c333f0f545b8a3fe793c789)) +* chainSpec based controller config; Types from apps-config ([#351](https://github.com/paritytech/substrate-api-sidecar/issues/351)) ([5936a1c](https://github.com/paritytech/substrate-api-sidecar/commit/5936a1c9907d0a2add8c3265121a8f66d20a62f2)) +* Impl `/pallets/{pallets}/storage`; Impl index lookup for `/pallets/{palletId}/storage/{, storageItemId}` ([#356](https://github.com/paritytech/substrate-api-sidecar/issues/356)) ([a8387df](https://github.com/paritytech/substrate-api-sidecar/commit/a8387dfbbcc8ce3df68a7768643e1a5e2202148e)) +* Remove all v0 routes to prepare for v1 release ([410a2e9](https://github.com/paritytech/substrate-api-sidecar/commit/410a2e9251bf341b9e0f151bccf9c83617c7673f)) +* Support Dock's multiplier & add Dock controller config ([#365](https://github.com/paritytech/substrate-api-sidecar/issues/365)) ([fb5df84](https://github.com/paritytech/substrate-api-sidecar/commit/fb5df845881a2364df7afa4da14f44dddd947083)) + + +### Bug Fixes + +* **env:** typo SAS_EXPRESS_BIND_PORT -> SAS_EXPRESS_PORT in .env.docker ([#364](https://github.com/paritytech/substrate-api-sidecar/issues/364)) ([8cbafea](https://github.com/paritytech/substrate-api-sidecar/commit/8cbafea9edb9ee5c1e69eb4b9cc906603b5dffc4)) +* Bump polkadot-js and adjust imports; Update specs ([#344](https://github.com/paritytech/substrate-api-sidecar/issues/344)) ([eeea29b](https://github.com/paritytech/substrate-api-sidecar/commit/eeea29b74ef50eb45356e4a7e1ea04344097cc00)) +* Catch errors decoding opaque calls ([#347](https://github.com/paritytech/substrate-api-sidecar/issues/347)) ([d128e54](https://github.com/paritytech/substrate-api-sidecar/commit/d128e54133e1b14c883b68c967b7fa1806f60b2e)) +* Use http BadRequest (400) when balance-info not found ([#355](https://github.com/paritytech/substrate-api-sidecar/issues/355)) ([c2a4937](https://github.com/paritytech/substrate-api-sidecar/commit/c2a4937ac5a67f71c89e49ea0237fda01000d217)) + ## [2.0.0](https://github.com/paritytech/substrate-api-sidecar/compare/v1.0.0...v2.0.0) (2020-11-19) diff --git a/package.json b/package.json index dbb9589dc..f233bbaba 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "2.0.0", + "version": "2.1.0", "name": "@substrate/api-sidecar", "description": "REST service that makes it easy to interact with blockchain nodes built using Substrate's FRAME framework.", "homepage": "https://github.com/paritytech/substrate-api-sidecar#readme", From 471edcc0387c7b11457234270b7a97a327b3dc41 Mon Sep 17 00:00:00 2001 From: Zeke Mostov <32168567+emostov@users.noreply.github.com> Date: Sat, 19 Dec 2020 21:32:54 -0800 Subject: [PATCH 2/9] refactor: Optimize `accounts/{accountId}/staking-payouts` blocking query --- CHANGELOG.md | 24 -- package.json | 2 +- .../accounts/AccountsStakingPayoutsService.ts | 290 +++++++++++++----- 3 files changed, 217 insertions(+), 99 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 144e8e034..564a7a2f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,30 +2,6 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. -## [2.1.0](https://github.com/paritytech/substrate-api-sidecar/compare/v1.0.0-rc4...v2.1.0) (2020-12-18) - - -### ⚠ BREAKING CHANGES - -* Bump polkadot-js and document runtime/metadata API regression (#338) -* Remove all v0 routes to prepare for v1 release - -### Features - -* Bump polkadot-js and document runtime/metadata API regression ([#338](https://github.com/paritytech/substrate-api-sidecar/issues/338)) ([effc5eb](https://github.com/paritytech/substrate-api-sidecar/commit/effc5eb159587b2b3c333f0f545b8a3fe793c789)) -* chainSpec based controller config; Types from apps-config ([#351](https://github.com/paritytech/substrate-api-sidecar/issues/351)) ([5936a1c](https://github.com/paritytech/substrate-api-sidecar/commit/5936a1c9907d0a2add8c3265121a8f66d20a62f2)) -* Impl `/pallets/{pallets}/storage`; Impl index lookup for `/pallets/{palletId}/storage/{, storageItemId}` ([#356](https://github.com/paritytech/substrate-api-sidecar/issues/356)) ([a8387df](https://github.com/paritytech/substrate-api-sidecar/commit/a8387dfbbcc8ce3df68a7768643e1a5e2202148e)) -* Remove all v0 routes to prepare for v1 release ([410a2e9](https://github.com/paritytech/substrate-api-sidecar/commit/410a2e9251bf341b9e0f151bccf9c83617c7673f)) -* Support Dock's multiplier & add Dock controller config ([#365](https://github.com/paritytech/substrate-api-sidecar/issues/365)) ([fb5df84](https://github.com/paritytech/substrate-api-sidecar/commit/fb5df845881a2364df7afa4da14f44dddd947083)) - - -### Bug Fixes - -* **env:** typo SAS_EXPRESS_BIND_PORT -> SAS_EXPRESS_PORT in .env.docker ([#364](https://github.com/paritytech/substrate-api-sidecar/issues/364)) ([8cbafea](https://github.com/paritytech/substrate-api-sidecar/commit/8cbafea9edb9ee5c1e69eb4b9cc906603b5dffc4)) -* Bump polkadot-js and adjust imports; Update specs ([#344](https://github.com/paritytech/substrate-api-sidecar/issues/344)) ([eeea29b](https://github.com/paritytech/substrate-api-sidecar/commit/eeea29b74ef50eb45356e4a7e1ea04344097cc00)) -* Catch errors decoding opaque calls ([#347](https://github.com/paritytech/substrate-api-sidecar/issues/347)) ([d128e54](https://github.com/paritytech/substrate-api-sidecar/commit/d128e54133e1b14c883b68c967b7fa1806f60b2e)) -* Use http BadRequest (400) when balance-info not found ([#355](https://github.com/paritytech/substrate-api-sidecar/issues/355)) ([c2a4937](https://github.com/paritytech/substrate-api-sidecar/commit/c2a4937ac5a67f71c89e49ea0237fda01000d217)) - ## [2.0.0](https://github.com/paritytech/substrate-api-sidecar/compare/v1.0.0...v2.0.0) (2020-11-19) diff --git a/package.json b/package.json index f233bbaba..dbb9589dc 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "2.1.0", + "version": "2.0.0", "name": "@substrate/api-sidecar", "description": "REST service that makes it easy to interact with blockchain nodes built using Substrate's FRAME framework.", "homepage": "https://github.com/paritytech/substrate-api-sidecar#readme", diff --git a/src/services/accounts/AccountsStakingPayoutsService.ts b/src/services/accounts/AccountsStakingPayoutsService.ts index 505328f75..fbeae914d 100644 --- a/src/services/accounts/AccountsStakingPayoutsService.ts +++ b/src/services/accounts/AccountsStakingPayoutsService.ts @@ -1,7 +1,13 @@ import { ApiPromise } from '@polkadot/api'; -import { DeriveEraExposure } from '@polkadot/api-derive/staking/types'; -import { BlockHash } from '@polkadot/types/interfaces'; import { + DeriveEraExposure, + DeriveEraExposureNominating, +} from '@polkadot/api-derive/staking/types'; +import { Option } from '@polkadot/types'; +import { + BalanceOf, + BlockHash, + EraIndex, EraRewardPoints, Perbill, StakingLedger, @@ -16,6 +22,31 @@ import { } from '../../types/responses'; import { AbstractService } from '../AbstractService'; +/** + * General information about an era, in tuple form because we initially get it + * by destructuring a Promise.all(...) + */ +type IErasGeneral = [DeriveEraExposure, EraRewardPoints, Option]; + +/** + * Commission and staking ledger of a validator + */ +interface ICommissionAndLedger { + commission: Perbill; + validatorLedger?: StakingLedger; +} + +/** + * All the data we need to calculate payouts for an address at a given era. + */ +interface IEraData { + deriveEraExposure: DeriveEraExposure; + eraRewardPoints: EraRewardPoints; + erasValidatorRewardOption: Option; + exposuresWithCommision: (ICommissionAndLedger & { validatorId: string })[]; + eraIndex: EraIndex; +} + export class AccountsStakingPayoutsService extends AbstractService { /** * Fetch and derive payouts for `address`. @@ -55,96 +86,186 @@ export class AccountsStakingPayoutsService extends AbstractService { 'than or equal to current_era - history_depth.' ); } + const at = { height: number.unwrap().toString(10), hash, }; - const erasPayouts: (IEraPayouts | { message: string })[] = []; - // User friendly - we don't error if the user specified era & depth combo <= 0, instead just start at 0 const startEra = era - (depth - 1) < 0 ? 0 : era - (depth - 1); - for (let e = startEra; e <= era; e += 1) { - erasPayouts.push( - await this.deriveEraPayouts( - api, - hash, + // Fetch general data about the era + const allErasGeneral = await this.fetchAllErasGeneral( + api, + hash, + startEra, + era + ); + + // With the general data, we can now fetch the commission of each validator `address` nominates + const allErasCommissions = await this.fetchAllErasCommissions( + api, + hash, + address, + startEra, + allErasGeneral.map((el) => el[0]) + ); + + // Group together data by Era so we can easily associate parts that are used congruently later + const allEraData = allErasGeneral.map( + (signleeraGeneral: IErasGeneral, idx: number): IEraData => { + const [ + deriveEraExposure, + eraRewardPoints, + erasValidatorRewardOption, + ] = signleeraGeneral; + + const eraCommisions = allErasCommissions[idx]; + const nominatedExposures = this.deriveNominatedExposures( address, - e, - unclaimedOnly - ) - ); - } + deriveEraExposure + ); + + // Zip the `validatorId` with its associated `commision`, making the data easier to reason + // about downstream + const exposuresWithCommision = nominatedExposures.map( + ({ validatorId }, idx) => { + return { + validatorId, + ...eraCommisions[idx], + }; + } + ); + + return { + deriveEraExposure, + eraRewardPoints, + erasValidatorRewardOption, + exposuresWithCommision, + eraIndex: api.createType('EraIndex', idx + startEra), + }; + } + ); return { at, - erasPayouts, + erasPayouts: allEraData.map((eraData) => + this.deriveEraPayouts(address, unclaimedOnly, eraData) + ), }; } /** - * Derive all the payouts for `address` at `era`. + * Fetch general info about eras in the inclusive range `startEra` .. `era`. * - * @param api + * @param api `ApiPromise` + * @param hash `BlockHash` to make call at + * @param startEra first era to get data for + * @param era the last era to get data for + */ + async fetchAllErasGeneral( + api: ApiPromise, + hash: BlockHash, + startEra: number, + era: number + ): Promise { + const allDeriveQuerys: Promise[] = []; + for (let e = startEra; e <= era; e += 1) { + const eraIndex = api.createType('EraIndex', era); + + const eraGeneralTuple = Promise.all([ + api.derive.staking.eraExposure(eraIndex), + api.query.staking.erasRewardPoints.at(hash, era), + api.query.staking.erasValidatorReward.at(hash, era), + ]); + + allDeriveQuerys.push(eraGeneralTuple); + } + + return Promise.all(allDeriveQuerys); + } + + /** + * Fetch the commision & staking ledger for each `validatorId` in `deriveErasExposures`. + * + * @param api `ApiPromise` * @param hash `BlockHash` to make call at * @param address address of the _Stash_ account to get the payouts of - * @param era the era to query - * @param unclaimedOnly whether or not to only show unclaimed payouts + * @param startEra first era to get data for + * @param deriveErasExposures exposures per era for `address` */ - async deriveEraPayouts( + fetchAllErasCommissions( api: ApiPromise, hash: BlockHash, address: string, - era: number, - unclaimedOnly: boolean - ): Promise { - const eraIndex = api.createType('EraIndex', era); + startEra: number, + deriveErasExposures: DeriveEraExposure[] + ): Promise { + // Cache StakingLedger to reduce redundant queries to node + const validatorLedgerCache: { [id: string]: StakingLedger } = {}; - const [ + const allErasCommisions = deriveErasExposures.map( + (deriveEraExposure, idx) => { + const currEra = idx + startEra; + + const nominatedExposures = this.deriveNominatedExposures( + address, + deriveEraExposure + ); + + if (!nominatedExposures) { + return []; + } + + const singleEraCommissions = nominatedExposures.map( + ({ validatorId }) => + this.fetchCommissionAndLedger( + api, + validatorId, + currEra, + hash, + validatorLedgerCache + ) + ); + + return Promise.all(singleEraCommissions); + } + ); + + return Promise.all(allErasCommisions); + } + + /** + * Derive all the payouts for `address` at `era`. + * + * @param address address of the _Stash_ account to get the payouts of + * @param era the era to query + * @param eraData data about the address and era we are calculating payouts for + */ + deriveEraPayouts( + address: string, + unclaimedOnly: boolean, + { deriveEraExposure, eraRewardPoints, erasValidatorRewardOption, - ] = await Promise.all([ - api.derive.staking.eraExposure(eraIndex), - api.query.staking.erasRewardPoints.at(hash, era), - api.query.staking.erasValidatorReward.at(hash, era), - ]); - - let nominatedExposures = deriveEraExposure.nominators[address]; - if (deriveEraExposure.validators[address]) { - // We treat an `address` that is a validator as nominating itself - nominatedExposures = nominatedExposures - ? nominatedExposures.concat({ - validatorId: address, - validatorIndex: 0, - }) - : [ - { - validatorId: address, - validatorIndex: 0, - }, - ]; - } - - if (!nominatedExposures) { + exposuresWithCommision, + eraIndex, + }: IEraData + ): IEraPayouts | { message: string } { + if (!exposuresWithCommision) { return { - message: `${address} has no nominations for the era ${era}`, + message: `${address} has no nominations for the era ${eraIndex.toString()}`, }; } if (erasValidatorRewardOption.isNone) { return { - message: `No ErasValidatorReward for the era ${era}`, + message: `No ErasValidatorReward for the era ${eraIndex.toString()}`, }; } - // Cache StakingLedger to reduce redundant queries to node - const validatorLedgerCache: { [id: string]: StakingLedger } = {}; - - // Payouts for the era - const payouts: IPayout[] = []; - const totalEraRewardPoints = eraRewardPoints.total; const totalEraPayout = erasValidatorRewardOption.unwrap(); const calcPayout = CalcPayout.from_params( @@ -152,8 +273,13 @@ export class AccountsStakingPayoutsService extends AbstractService { totalEraPayout.toString(10) ); - // Loop through validators that this nominator backs - for (const { validatorId } of nominatedExposures) { + // Iterate through validators that this nominator backs and calculate payouts for the era + const payouts: IPayout[] = []; + for (const { + validatorId, + commission: validatorCommission, + validatorLedger, + } of exposuresWithCommision) { const totalValidatorRewardPoints = this.extractTotalValidatorRewardPoints( eraRewardPoints, validatorId @@ -163,6 +289,7 @@ export class AccountsStakingPayoutsService extends AbstractService { !totalValidatorRewardPoints || totalValidatorRewardPoints?.toNumber() === 0 ) { + console.log('no reward points'); // Nothing to do if there are no reward points for the validator continue; } @@ -178,21 +305,9 @@ export class AccountsStakingPayoutsService extends AbstractService { continue; } - const { - commission: validatorCommission, - validatorLedger, - } = await this.fetchCommissionAndLedger( - api, - validatorId, - era, - hash, - validatorLedgerCache - ); - if (!validatorLedger) { continue; } - // Check if the reward has already been claimed const claimed = validatorLedger.claimedRewards.includes(eraIndex); if (unclaimedOnly && claimed) { @@ -241,10 +356,7 @@ export class AccountsStakingPayoutsService extends AbstractService { era: number, hash: BlockHash, validatorLedgerCache: { [id: string]: StakingLedger } - ): Promise<{ - commission: Perbill; - validatorLedger?: StakingLedger; - }> { + ): Promise { let commission; let validatorLedger; if (validatorId in validatorLedgerCache) { @@ -339,4 +451,34 @@ export class AccountsStakingPayoutsService extends AbstractService { nominatorExposure, }; } + + /** + * Derive the list of validators `address` nominates. Note: we count validators as nominating + * themself. + * + * @param address address of the _Stash_ account to get the payouts of + * @param deriveEraExposure result of query api.derive.staking.eraExposure(eraIndex) + */ + deriveNominatedExposures( + address: string, + deriveEraExposure: DeriveEraExposure + ): DeriveEraExposureNominating[] { + let nominatedExposures = deriveEraExposure.nominators[address]; + if (deriveEraExposure.validators[address]) { + // We treat an `address` that is a validator as nominating itself + nominatedExposures = nominatedExposures + ? nominatedExposures.concat({ + validatorId: address, + validatorIndex: 0, + }) + : [ + { + validatorId: address, + validatorIndex: 0, + }, + ]; + } + + return nominatedExposures; + } } From 0edb7b2623ef41fbe4dd98d432c63203b9fad712 Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Sat, 19 Dec 2020 21:40:09 -0800 Subject: [PATCH 3/9] Bump deps --- package.json | 6 +- yarn.lock | 209 +++++++++++++++++++++------------------------------ 2 files changed, 89 insertions(+), 126 deletions(-) diff --git a/package.json b/package.json index dbb9589dc..ef64d1d94 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "dependencies": { "@polkadot/api": "^3.0.1", "@polkadot/apps-config": "^0.71.2", - "@polkadot/util-crypto": "^5.0.1", + "@polkadot/util-crypto": "^5.1.1", "@substrate/calc": "^0.1.3", "confmgr": "^1.0.6", "express": "^4.17.1", @@ -55,8 +55,8 @@ "@types/triple-beam": "^1.3.2", "@typescript-eslint/eslint-plugin": "4.10.0", "@typescript-eslint/parser": "4.10.0", - "eslint": "^7.15.0", - "eslint-config-prettier": "^7.0.0", + "eslint": "^7.16.0", + "eslint-config-prettier": "^7.1.0", "eslint-plugin-prettier": "^3.3.0", "eslint-plugin-simple-import-sort": "^7.0.0", "jest": "^26.6.3", diff --git a/yarn.lock b/yarn.lock index 5652329bc..fed30056b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -601,13 +601,13 @@ "@subsocial/types" "^0.4.26" "@polkadot/keyring@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-5.0.1.tgz#698b9918d43395bbc47ca317772ec1cbe899680e" - integrity sha512-TZz5HrSzmGlWNFmvT4ewdDFT2DdCCgS1sRZtfMGvJq4AtJTNLDKe7twUKphiNjuaIaiIbHJLvs4Wnhmu0MBRxw== + version "5.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-5.1.1.tgz#6553b4f763f79987815f12fb7c84104542bd9b3c" + integrity sha512-oLUc7y/46EOl/Qw11R3LzYJipshEeaFuYo2cijcjM+tGEZuCHf1Wa1d8onZvRcoSwPuvQrmP/l62OhQfyJWCjw== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/util" "5.0.1" - "@polkadot/util-crypto" "5.0.1" + "@polkadot/util" "5.1.1" + "@polkadot/util-crypto" "5.1.1" "@polkadot/metadata@3.0.1": version "3.0.1" @@ -621,10 +621,10 @@ "@polkadot/util-crypto" "^5.0.1" bn.js "^4.11.9" -"@polkadot/networks@5.0.1", "@polkadot/networks@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-5.0.1.tgz#757d5fa79296d600b5be7360dd088e6038ca6bad" - integrity sha512-RgGT5gMsT8zSiFQPI87lnz3nVNhgDArTdm+Y6wGVgrD+SNy/XcPLf3iO8xc2n+bMVmQfB5QzEZugwxE3nLJ4PA== +"@polkadot/networks@5.1.1", "@polkadot/networks@^5.0.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-5.1.1.tgz#d0291fc9b6f1b8c7d2abbddc9ee6bac59b778ca7" + integrity sha512-q0PttJbwKL/kv4WhTyZi/g2GsCpTlkg5OGRJz+2iFJR85EokxtFfSN6IvuYykWH8xj/McyX5IlFQuoey0q1DOg== dependencies: "@babel/runtime" "^7.12.5" @@ -677,16 +677,16 @@ "@types/bn.js" "^4.11.6" bn.js "^4.11.9" -"@polkadot/util-crypto@5.0.1", "@polkadot/util-crypto@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-5.0.1.tgz#87ef8a14e133a169b7d5dba109f0bd7460d3a8bd" - integrity sha512-lZHDnbchNJxvMh8NnRoRZtazgn6dGSiXVwHgygVm3EkEw/30ULdT5eyD9PhTbYxeNxfoHmSGHugUhfNmlyYSuw== +"@polkadot/util-crypto@5.1.1", "@polkadot/util-crypto@^5.0.1", "@polkadot/util-crypto@^5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-5.1.1.tgz#ad9cdd1955cbfb8505550e47d66b8a656a264857" + integrity sha512-ht9aVJ+PQcGo7BbQKN1BixC6u685nr1WPIvrG2deGYTNwZh9gSp2nI0i0qfNxbH/6uS37QsT5sTwPRSXWjHvug== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/networks" "5.0.1" - "@polkadot/util" "5.0.1" - "@polkadot/wasm-crypto" "^3.0.1" - "@polkadot/x-randomvalues" "5.0.1" + "@polkadot/networks" "5.1.1" + "@polkadot/util" "5.1.1" + "@polkadot/wasm-crypto" "^3.1.1" + "@polkadot/x-randomvalues" "5.1.1" base-x "^3.0.8" blakejs "^1.1.0" bn.js "^4.11.9" @@ -698,56 +698,55 @@ tweetnacl "^1.0.3" xxhashjs "^0.2.2" -"@polkadot/util@5.0.1", "@polkadot/util@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-5.0.1.tgz#a3435b526632c897c8d721e2f71edf838db29f7c" - integrity sha512-XqAWE6ZZEDQkSqSpaJg8f2uKDdUZ3lhRWKnumO+7nj4k0alOp5tD4mc1Pd6KxdnkserNMV4KxeNQxfCSJ0pu/Q== +"@polkadot/util@5.1.1", "@polkadot/util@^5.0.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-5.1.1.tgz#b3361ae44de03937558955a20e6970ca19ff8154" + integrity sha512-r/j3GtLZb+Az6xyKtT/I73/jawXWKrbJxvcUqwJiM/naBbNRbUyMROemD/JxXy4QEYdN5cEUKdFPka9ZLnAJxw== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/x-textdecoder" "5.0.1" - "@polkadot/x-textencoder" "5.0.1" + "@polkadot/x-textdecoder" "5.1.1" + "@polkadot/x-textencoder" "5.1.1" "@types/bn.js" "^4.11.6" bn.js "^4.11.9" camelcase "^5.3.1" ip-regex "^4.2.0" -"@polkadot/wasm-crypto-asmjs@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-3.0.1.tgz#91d712a2aea0d59bc044376ed1dde70368c3c04f" - integrity sha512-PXdBDl28QDUKzFp63yP7b+zWTC1xseY9egjQmqjAZ0lRpIePwE2Z2SVhSXuCR9ejxxHGZZye+yELJ1djeOXoMg== +"@polkadot/wasm-crypto-asmjs@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-3.1.1.tgz#391e1be6f7d65552b09c2e2486d108c379e46dc6" + integrity sha512-7Lt4B/6dwUhb5OAuSes0qMd83TpkngvEpiXTt2ccf/t2OvAXY9msfeJ9as3dI2jvjA9edD//jiejJ0BHJgpuXw== dependencies: "@babel/runtime" "^7.12.5" -"@polkadot/wasm-crypto-wasm@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-3.0.1.tgz#b0b211188631bb4953625ca552842421941ddec3" - integrity sha512-qWcN3XDqYi7uAAPUaZIUnZDvFrJ3mU0WdoEWjF7iZYU1rDCA8mDRS09vfvTnECaNeIBS/2qZVs9oQPZtXMjKvg== +"@polkadot/wasm-crypto-wasm@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-3.1.1.tgz#94638daa7642e6a9681cb854757d98401913f087" + integrity sha512-KaP1Ojf889ZeXHGPmyFTj0Qxr/jQ4yfpaGiEOCvYKXRYsDsbZKfxcb96PFil/x0yoZswWG3TX2S3hebnAzkmBg== dependencies: "@babel/runtime" "^7.12.5" - fflate "^0.4.2" -"@polkadot/wasm-crypto@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-3.0.1.tgz#4e320e126704d0a793da9ea03686d8db17e3e613" - integrity sha512-4cbiaqnvd13D4bqJBOKSYtg0dRLXfhbQc/Ha59EC5wQ2JVItUyRC0FS5wfkrsOtlNIEn3rRa92jMdlYL0bg4IA== +"@polkadot/wasm-crypto@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-3.1.1.tgz#e9ec63204f508541dfda72f0b6b98be40e27de50" + integrity sha512-uApLRojJY9Q7Arji6w9/eOYEu8Pg8dm+zt+640QLzC4KVVCpbdMmrcFAXCZXeOIJwsKveZsNehGUCcG77ypVPg== dependencies: "@babel/runtime" "^7.12.5" - "@polkadot/wasm-crypto-asmjs" "^3.0.1" - "@polkadot/wasm-crypto-wasm" "^3.0.1" + "@polkadot/wasm-crypto-asmjs" "^3.1.1" + "@polkadot/wasm-crypto-wasm" "^3.1.1" "@polkadot/x-fetch@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-5.0.1.tgz#f8835f75b517a6155bc8e43652248ff3b08569d4" - integrity sha512-mUEDEmqEKcV0yDJ0XTIaBYLLHurCpA2j76ffRI8YevscwLJJy+FUpm1IOIQr+VSGi5GfjLewY02jgG7dMSSDRA== + version "5.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-5.1.1.tgz#2d89d0f4a8130f6f9d7132ae863ce106086f1bca" + integrity sha512-mQFgIa0aF2Ha5fMviPB7jZZwRe8ot72ox6+sWbSgi091GWzVAvsHSCBFn/d0wnl+s5PY7Y3NQZOUyHc76AOfnA== dependencies: "@babel/runtime" "^7.12.5" "@types/node-fetch" "^2.5.7" node-fetch "^2.6.1" -"@polkadot/x-randomvalues@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-5.0.1.tgz#55232b34f0244cd2c94de63f56a8efc824948f2e" - integrity sha512-ynv3OzDdSs24QZSXCuhT7c0hYKO7M+9tHaUpsYTz6vbHFj16sLCi8XYNtQbgRk2bW4jf1J1R9d9Mek6y3FziCg== +"@polkadot/x-randomvalues@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-5.1.1.tgz#4ea84050af951fb8080326ec73382345d76ae376" + integrity sha512-ZGqPQ82FInUs8HYj88BaseRpK2Cekvh75PFoU+LyqKH2bMTvIHkpnUWVOA6seRRp6kHC03NF2NkVCpawiwxIHQ== dependencies: "@babel/runtime" "^7.12.5" @@ -759,24 +758,24 @@ "@babel/runtime" "^7.12.5" rxjs "^6.6.3" -"@polkadot/x-textdecoder@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-5.0.1.tgz#34d6c189d0e143c9ddbc5aba10e803faec28c5bb" - integrity sha512-pQDO2OlzRgcXtdzopcdiSSvfJMTyI/l5vLX4VNLfxXSN4n3FTlZurPnHyPM7Tuigr9kMVwWoDMGNQYug8fCavA== +"@polkadot/x-textdecoder@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-5.1.1.tgz#39d859742603b39eda3afc65a6fd3879264341ae" + integrity sha512-rGnB0mZVeXzYmXp6HwAMTj8mPhQawB/zPL5/hDCa/uBwEfMDpiu8fFTdU7Znmf4BGfspHmKqpVKMc27YIk9A0w== dependencies: "@babel/runtime" "^7.12.5" -"@polkadot/x-textencoder@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-5.0.1.tgz#401a264f317111e25c8e45eb0efd686c1b6a37af" - integrity sha512-hMFLJ5Udi0boHE3rMt+IWZ+T2khuzHgsPGoaSIxvEiTFUU4tt+26fESiE+vy+gbHfMaUvSWirwW2EnC2lsn6tA== +"@polkadot/x-textencoder@5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-5.1.1.tgz#337bbfa2751df262588184a9c8da2d0320ac0d87" + integrity sha512-74jCz3KxtL215fDZsKH+983FCzIYGgzFhelVjU633bpSVt1EOVaEDidMIACXqPO0Rr9PSMDm/loV2MJjuzo5bA== dependencies: "@babel/runtime" "^7.12.5" "@polkadot/x-ws@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-5.0.1.tgz#6d0a62dbee0058672c374488cba2400cec57a3e7" - integrity sha512-LrglkT8S17gMahkBKEoRkXAv5hEB1t31qthNuFzwCHst97tpPLDlrm3OdgC7vzGtAnVk22WHe6QnWjbCtGytPg== + version "5.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-5.1.1.tgz#e2c8c4464b9cca355aaa9cebf584acb7b51d170e" + integrity sha512-gZMkkrR749vIkmhb7q1srbzw1QQqfD/M9jrNSzqMcJ9Z6BdURMCUu96bzN83jX1KOTtWKbaBW7fdIHxrlsQ4HQ== dependencies: "@babel/runtime" "^7.12.5" "@types/websocket" "^1.0.1" @@ -1160,7 +1159,7 @@ add-stream@^1.0.0: resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" integrity sha1-anmQQ3ynNtXhKI25K9MmbV9csqo= -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4: +ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1182,17 +1181,12 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.11.0" -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - ansi-regex@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== -ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -1291,10 +1285,10 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== async@^3.1.0: version "3.2.0" @@ -2309,11 +2303,6 @@ emittery@^0.7.1: resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82" integrity sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ== -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -2403,10 +2392,10 @@ escodegen@^1.14.1: optionalDependencies: source-map "~0.6.1" -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-config-prettier@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.1.0.tgz#5402eb559aa94b894effd6bddfa0b1ca051c858f" + integrity sha512-9sm5/PxaFG7qNJvJzTROMM1Bk1ozXVTKI0buKOyb0Bsr1hrwi0H/TzxF/COtf1uxikIK8SwhX7K6zg78jAzbeA== eslint-plugin-prettier@^3.3.0: version "3.3.0" @@ -2445,10 +2434,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.15.0: - version "7.15.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.15.0.tgz#eb155fb8ed0865fcf5d903f76be2e5b6cd7e0bc7" - integrity sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA== +eslint@^7.16.0: + version "7.16.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.16.0.tgz#a761605bf9a7b32d24bb7cde59aeb0fd76f06092" + integrity sha512-iVWPS785RuDA4dWuhhgXTNrGxHHK3a8HLSMBgbbU59ruJDubUraXN8N5rn7kb8tG6sjg74eE0RA3YWT51eusEw== dependencies: "@babel/code-frame" "^7.0.0" "@eslint/eslintrc" "^0.2.2" @@ -2484,7 +2473,7 @@ eslint@^7.15.0: semver "^7.2.1" strip-ansi "^6.0.0" strip-json-comments "^3.1.0" - table "^5.2.3" + table "^6.0.4" text-table "^0.2.0" v8-compile-cache "^2.0.3" @@ -2768,11 +2757,6 @@ fecha@^4.2.0: resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.0.tgz#3ffb6395453e3f3efff850404f0a59b6747f5f41" integrity sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg== -fflate@^0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.2.tgz#90be9712dae6e874ce9d61f9678355da15ec7011" - integrity sha512-othuEXeiFBIaYC8crEkvcYjLw4tAFD4WypT7iyivcT6NxAN1Ib+w/pmeM1SyvwxlsbWPAvoUiMmfClaxq/yVow== - figures@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" @@ -3473,11 +3457,6 @@ is-finite@^1.0.0: resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -4270,7 +4249,7 @@ lodash.truncate@^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: +lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -5681,14 +5660,14 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" snapdragon-node@^2.0.1: version "2.1.1" @@ -5904,15 +5883,6 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -string-width@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - string-width@^4.1.0, string-width@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" @@ -5941,13 +5911,6 @@ stringify-package@^1.0.1: resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.1.tgz#e5aa3643e7f74d0f28628b72f3dad5cecfc3ba85" integrity sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg== -strip-ansi@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - strip-ansi@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" @@ -6033,15 +5996,15 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== +table@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/table/-/table-6.0.4.tgz#c523dd182177e926c723eb20e1b341238188aa0d" + integrity sha512-sBT4xRLdALd+NFBvwOz8bw4b15htyythha+q+DVZqy2RS08PPC8O2sZFgJYEY7bJvbCFKccs+WIZ/cd+xxTWCw== dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" + ajv "^6.12.4" + lodash "^4.17.20" + slice-ansi "^4.0.0" + string-width "^4.2.0" terminal-link@^2.0.0: version "2.1.1" From 57e87d636b64ea9c9a7a62c926b8239f53a086fb Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Mon, 21 Dec 2020 14:05:33 -0800 Subject: [PATCH 4/9] Fix issues with deriveNominatedExposures --- .../accounts/AccountsStakingPayoutsService.ts | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/src/services/accounts/AccountsStakingPayoutsService.ts b/src/services/accounts/AccountsStakingPayoutsService.ts index fbeae914d..a45ba1a87 100644 --- a/src/services/accounts/AccountsStakingPayoutsService.ts +++ b/src/services/accounts/AccountsStakingPayoutsService.ts @@ -13,6 +13,7 @@ import { StakingLedger, } from '@polkadot/types/interfaces'; import { CalcPayout } from '@substrate/calc'; +// import * as BN from 'bn.js'; import { BadRequest } from 'http-errors'; import { @@ -43,7 +44,9 @@ interface IEraData { deriveEraExposure: DeriveEraExposure; eraRewardPoints: EraRewardPoints; erasValidatorRewardOption: Option; - exposuresWithCommision: (ICommissionAndLedger & { validatorId: string })[]; + exposuresWithCommission?: (ICommissionAndLedger & { + validatorId: string; + })[]; eraIndex: EraIndex; } @@ -114,26 +117,28 @@ export class AccountsStakingPayoutsService extends AbstractService { // Group together data by Era so we can easily associate parts that are used congruently later const allEraData = allErasGeneral.map( - (signleeraGeneral: IErasGeneral, idx: number): IEraData => { - const [ + ( + [ deriveEraExposure, eraRewardPoints, erasValidatorRewardOption, - ] = signleeraGeneral; + ]: IErasGeneral, + idx: number + ): IEraData => { + const eraCommissions = allErasCommissions[idx]; - const eraCommisions = allErasCommissions[idx]; const nominatedExposures = this.deriveNominatedExposures( address, deriveEraExposure ); - // Zip the `validatorId` with its associated `commision`, making the data easier to reason + // Zip the `validatorId` with its associated `commission`, making the data easier to reason // about downstream - const exposuresWithCommision = nominatedExposures.map( + const exposuresWithCommission = nominatedExposures?.map( ({ validatorId }, idx) => { return { validatorId, - ...eraCommisions[idx], + ...eraCommissions[idx], }; } ); @@ -142,7 +147,7 @@ export class AccountsStakingPayoutsService extends AbstractService { deriveEraExposure, eraRewardPoints, erasValidatorRewardOption, - exposuresWithCommision, + exposuresWithCommission, eraIndex: api.createType('EraIndex', idx + startEra), }; } @@ -172,12 +177,12 @@ export class AccountsStakingPayoutsService extends AbstractService { ): Promise { const allDeriveQuerys: Promise[] = []; for (let e = startEra; e <= era; e += 1) { - const eraIndex = api.createType('EraIndex', era); + const eraIndex = api.createType('EraIndex', e); const eraGeneralTuple = Promise.all([ api.derive.staking.eraExposure(eraIndex), - api.query.staking.erasRewardPoints.at(hash, era), - api.query.staking.erasValidatorReward.at(hash, era), + api.query.staking.erasRewardPoints.at(hash, eraIndex), + api.query.staking.erasValidatorReward.at(hash, eraIndex), ]); allDeriveQuerys.push(eraGeneralTuple); @@ -187,7 +192,7 @@ export class AccountsStakingPayoutsService extends AbstractService { } /** - * Fetch the commision & staking ledger for each `validatorId` in `deriveErasExposures`. + * Fetch the commission & staking ledger for each `validatorId` in `deriveErasExposures`. * * @param api `ApiPromise` * @param hash `BlockHash` to make call at @@ -205,7 +210,7 @@ export class AccountsStakingPayoutsService extends AbstractService { // Cache StakingLedger to reduce redundant queries to node const validatorLedgerCache: { [id: string]: StakingLedger } = {}; - const allErasCommisions = deriveErasExposures.map( + const allErasCommissions = deriveErasExposures.map( (deriveEraExposure, idx) => { const currEra = idx + startEra; @@ -233,7 +238,7 @@ export class AccountsStakingPayoutsService extends AbstractService { } ); - return Promise.all(allErasCommisions); + return Promise.all(allErasCommissions); } /** @@ -250,11 +255,11 @@ export class AccountsStakingPayoutsService extends AbstractService { deriveEraExposure, eraRewardPoints, erasValidatorRewardOption, - exposuresWithCommision, + exposuresWithCommission, eraIndex, }: IEraData ): IEraPayouts | { message: string } { - if (!exposuresWithCommision) { + if (!exposuresWithCommission) { return { message: `${address} has no nominations for the era ${eraIndex.toString()}`, }; @@ -279,7 +284,7 @@ export class AccountsStakingPayoutsService extends AbstractService { validatorId, commission: validatorCommission, validatorLedger, - } of exposuresWithCommision) { + } of exposuresWithCommission) { const totalValidatorRewardPoints = this.extractTotalValidatorRewardPoints( eraRewardPoints, validatorId @@ -289,7 +294,6 @@ export class AccountsStakingPayoutsService extends AbstractService { !totalValidatorRewardPoints || totalValidatorRewardPoints?.toNumber() === 0 ) { - console.log('no reward points'); // Nothing to do if there are no reward points for the validator continue; } @@ -462,8 +466,9 @@ export class AccountsStakingPayoutsService extends AbstractService { deriveNominatedExposures( address: string, deriveEraExposure: DeriveEraExposure - ): DeriveEraExposureNominating[] { - let nominatedExposures = deriveEraExposure.nominators[address]; + ): DeriveEraExposureNominating[] | undefined { + let nominatedExposures: DeriveEraExposureNominating[] | undefined = + deriveEraExposure.nominators[address]; if (deriveEraExposure.validators[address]) { // We treat an `address` that is a validator as nominating itself nominatedExposures = nominatedExposures From af985a8ca96f59ce1257bb571e32565941f7c828 Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Mon, 21 Dec 2020 14:07:00 -0800 Subject: [PATCH 5/9] Update comment --- src/services/accounts/AccountsStakingPayoutsService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/accounts/AccountsStakingPayoutsService.ts b/src/services/accounts/AccountsStakingPayoutsService.ts index a45ba1a87..0b2e6b11a 100644 --- a/src/services/accounts/AccountsStakingPayoutsService.ts +++ b/src/services/accounts/AccountsStakingPayoutsService.ts @@ -115,7 +115,7 @@ export class AccountsStakingPayoutsService extends AbstractService { allErasGeneral.map((el) => el[0]) ); - // Group together data by Era so we can easily associate parts that are used congruently later + // Group together data by Era so we can easily associate parts that are used congruently downstream const allEraData = allErasGeneral.map( ( [ From 965e370310ee507385a0ef023a89762dd6a5f148 Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Mon, 21 Dec 2020 14:23:52 -0800 Subject: [PATCH 6/9] Remove commented out code --- src/services/accounts/AccountsStakingPayoutsService.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/services/accounts/AccountsStakingPayoutsService.ts b/src/services/accounts/AccountsStakingPayoutsService.ts index 0b2e6b11a..68b34b562 100644 --- a/src/services/accounts/AccountsStakingPayoutsService.ts +++ b/src/services/accounts/AccountsStakingPayoutsService.ts @@ -13,7 +13,6 @@ import { StakingLedger, } from '@polkadot/types/interfaces'; import { CalcPayout } from '@substrate/calc'; -// import * as BN from 'bn.js'; import { BadRequest } from 'http-errors'; import { From 20288d6dd3621cf863208f3e1086283b79bd7651 Mon Sep 17 00:00:00 2001 From: Zeke Mostov <32168567+emostov@users.noreply.github.com> Date: Mon, 4 Jan 2021 09:16:52 -0800 Subject: [PATCH 7/9] Update src/services/accounts/AccountsStakingPayoutsService.ts Co-authored-by: David --- src/services/accounts/AccountsStakingPayoutsService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/accounts/AccountsStakingPayoutsService.ts b/src/services/accounts/AccountsStakingPayoutsService.ts index 68b34b562..889df8c7b 100644 --- a/src/services/accounts/AccountsStakingPayoutsService.ts +++ b/src/services/accounts/AccountsStakingPayoutsService.ts @@ -456,7 +456,7 @@ export class AccountsStakingPayoutsService extends AbstractService { } /** - * Derive the list of validators `address` nominates. Note: we count validators as nominating + * Derive the list of validators nominated by `address`. Note: we count validators as nominating * themself. * * @param address address of the _Stash_ account to get the payouts of From 9ea7cbc7b0412b4baff94ab78ce8b84b7c05622c Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Mon, 4 Jan 2021 09:19:44 -0800 Subject: [PATCH 8/9] Rename el variable --- src/services/accounts/AccountsStakingPayoutsService.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/services/accounts/AccountsStakingPayoutsService.ts b/src/services/accounts/AccountsStakingPayoutsService.ts index 68b34b562..a0e5fa9df 100644 --- a/src/services/accounts/AccountsStakingPayoutsService.ts +++ b/src/services/accounts/AccountsStakingPayoutsService.ts @@ -95,7 +95,7 @@ export class AccountsStakingPayoutsService extends AbstractService { }; // User friendly - we don't error if the user specified era & depth combo <= 0, instead just start at 0 - const startEra = era - (depth - 1) < 0 ? 0 : era - (depth - 1); + const startEra = Math.max(0, era - (depth - 1)); // Fetch general data about the era const allErasGeneral = await this.fetchAllErasGeneral( @@ -111,7 +111,8 @@ export class AccountsStakingPayoutsService extends AbstractService { hash, address, startEra, - allErasGeneral.map((el) => el[0]) + // Create an array of `DeriveEraExposure` + allErasGeneral.map((eraGeneral) => eraGeneral[0]) ); // Group together data by Era so we can easily associate parts that are used congruently downstream From c555be7354d8670b088e76faea7b946a26f66ee8 Mon Sep 17 00:00:00 2001 From: emostov <32168567+emostov@users.noreply.github.com> Date: Mon, 4 Jan 2021 10:34:13 -0800 Subject: [PATCH 9/9] update --- .../accounts/AccountsStakingPayoutsService.ts | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/services/accounts/AccountsStakingPayoutsService.ts b/src/services/accounts/AccountsStakingPayoutsService.ts index 2d5983929..83ce64c16 100644 --- a/src/services/accounts/AccountsStakingPayoutsService.ts +++ b/src/services/accounts/AccountsStakingPayoutsService.ts @@ -467,21 +467,15 @@ export class AccountsStakingPayoutsService extends AbstractService { address: string, deriveEraExposure: DeriveEraExposure ): DeriveEraExposureNominating[] | undefined { - let nominatedExposures: DeriveEraExposureNominating[] | undefined = - deriveEraExposure.nominators[address]; + let nominatedExposures: DeriveEraExposureNominating[] = + deriveEraExposure.nominators[address] ?? []; if (deriveEraExposure.validators[address]) { // We treat an `address` that is a validator as nominating itself - nominatedExposures = nominatedExposures - ? nominatedExposures.concat({ - validatorId: address, - validatorIndex: 0, - }) - : [ - { - validatorId: address, - validatorIndex: 0, - }, - ]; + nominatedExposures = nominatedExposures.concat({ + validatorId: address, + // We put in an arbitrary number because we do not use the index + validatorIndex: 9999, + }); } return nominatedExposures;