diff --git a/package.json b/package.json index 11dfff8144..1538f5a888 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,8 @@ "@babel/core": "^7.8.7", "@babel/register": "^7.8.6", "@babel/runtime": "^7.8.7", - "@polkadot/dev": "^0.50.33", - "@polkadot/ts": "^0.3.10", + "@polkadot/dev": "^0.51.1", + "@polkadot/ts": "^0.3.11", "@polkadot/typegen": "workspace:packages/typegen", "copyfiles": "^2.2.0" } diff --git a/packages/api-derive/src/staking/erasPrefs.ts b/packages/api-derive/src/staking/erasPrefs.ts new file mode 100644 index 0000000000..826737ed1e --- /dev/null +++ b/packages/api-derive/src/staking/erasPrefs.ts @@ -0,0 +1,48 @@ +// Copyright 2017-2020 @polkadot/api-derive authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { ApiInterfaceRx } from '@polkadot/api/types'; +import { EraIndex, ValidatorPrefs } from '@polkadot/types/interfaces'; +import { DeriveEraPrefs, DeriveEraValPrefs } from '../types'; + +import BN from 'bn.js'; +import { Observable, combineLatest, of } from 'rxjs'; +import { map, switchMap } from 'rxjs/operators'; +import { StorageKey } from '@polkadot/types'; + +import { memo } from '../util'; + +type KeysAndPrefs = [StorageKey, ValidatorPrefs][]; + +function mapPrefs (era: EraIndex, all: KeysAndPrefs): DeriveEraPrefs { + const validators: DeriveEraValPrefs = {}; + + all.forEach(([key, prefs]): void => { + validators[key.args[1].toString()] = prefs; + }); + + return { era, validators }; +} + +export function eraPrefs (api: ApiInterfaceRx): (era: EraIndex) => Observable { + return memo((era: EraIndex): Observable => + api.query.staking.erasValidatorPrefs.entries(era).pipe( + map((prefs) => mapPrefs(era, prefs)) + ) + ); +} + +export function erasPrefs (api: ApiInterfaceRx): (withActive?: boolean | BN | number) => Observable { + return memo((withActive?: boolean | BN | number): Observable => + api.derive.staking.erasHistoric(withActive).pipe( + switchMap((eras): Observable => + eras.length + ? combineLatest( + eras.map((era) => api.derive.staking.eraPrefs(era)) + ) + : of([]) + ) + ) + ); +} diff --git a/packages/api-derive/src/staking/index.ts b/packages/api-derive/src/staking/index.ts index 13018906aa..5f3967ef46 100644 --- a/packages/api-derive/src/staking/index.ts +++ b/packages/api-derive/src/staking/index.ts @@ -6,6 +6,7 @@ export * from './account'; export * from './erasExposure'; export * from './erasHistoric'; export * from './erasPoints'; +export * from './erasPrefs'; export * from './erasRewards'; export * from './controllers'; export * from './electedInfo'; diff --git a/packages/api-derive/src/staking/stakerRewards.ts b/packages/api-derive/src/staking/stakerRewards.ts index b964d644a0..dffe40d549 100644 --- a/packages/api-derive/src/staking/stakerRewards.ts +++ b/packages/api-derive/src/staking/stakerRewards.ts @@ -4,7 +4,7 @@ import { ApiInterfaceRx } from '@polkadot/api/types'; import { Balance } from '@polkadot/types/interfaces'; -import { DeriveEraPoints, DeriveEraRewards, DeriveStakerExposure, DeriveStakerReward } from '../types'; +import { DeriveEraPoints, DeriveEraPrefs, DeriveEraRewards, DeriveEraValPrefs, DeriveStakerExposure, DeriveStakerReward } from '../types'; import BN from 'bn.js'; import { Observable, combineLatest } from 'rxjs'; @@ -12,18 +12,24 @@ import { map } from 'rxjs/operators'; import { memo } from '../util'; -type Result = [DeriveEraPoints[], DeriveEraRewards[], DeriveStakerExposure[]]; -const ZERO = new BN(0); +type Result = [DeriveEraPoints[], DeriveEraPrefs[], DeriveEraRewards[], DeriveStakerExposure[]]; -function parseRewards (api: ApiInterfaceRx, stakerId: string, [erasPoints, erasRewards, exposures]: Result): DeriveStakerReward[] { +const ZERO = new BN(0); +const COMM_DIV = new BN(1_000_000_000); + +function parseRewards (api: ApiInterfaceRx, stakerId: string, [erasPoints, erasPrefs, erasRewards, exposures]: Result): DeriveStakerReward[] { return exposures.map(({ era, isEmpty, isValidator, nominating, validators: eraValidators }): DeriveStakerReward => { const { eraPoints, validators: allValPoints } = erasPoints.find((p) => p.era.eq(era)) || { eraPoints: new BN(0), validators: {} }; - const { eraReward } = erasRewards.find((r) => r.era.eq(era)) || { eraReward: new BN(0) }; + const { eraReward } = erasRewards.find((r) => r.era.eq(era)) || { eraReward: ZERO }; + const { validators: allValPrefs } = erasPrefs.find((p) => p.era.eq(era)) || { validators: {} as DeriveEraValPrefs }; const validators: Record = {}; let total = ZERO; Object.entries(eraValidators).forEach(([validatorId, exposure]): void => { - const valPoints = allValPoints[validatorId] || new BN(0); + const valPoints = allValPoints[validatorId] || ZERO; + const valComm = allValPrefs[validatorId]?.commission.unwrap() || ZERO; + const avail = eraReward.mul(valPoints).div(eraPoints); + const valCut = valComm.mul(avail).div(COMM_DIV); const expTotal = exposure.total.unwrap(); let value: BN | undefined; @@ -40,7 +46,7 @@ function parseRewards (api: ApiInterfaceRx, stakerId: string, [erasPoints, erasR : ZERO; } - value = eraReward.mul(valPoints).mul(staked).div(eraPoints).div(expTotal); + value = avail.sub(valCut).mul(staked).div(expTotal).add(validatorId === stakerId ? valCut : ZERO); total = total.add(value); } @@ -64,6 +70,7 @@ export function stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | st return combineLatest([ api.derive.staking.erasPoints(startEra), + api.derive.staking.erasPrefs(startEra), api.derive.staking.erasRewards(startEra), api.derive.staking.stakerExposure(stakerId, startEra) ]).pipe( diff --git a/packages/api-derive/src/staking/types.ts b/packages/api-derive/src/staking/types.ts index 94a3c017f7..5a2bb6ec47 100644 --- a/packages/api-derive/src/staking/types.ts +++ b/packages/api-derive/src/staking/types.ts @@ -7,12 +7,19 @@ import { DeriveSessionIndexes } from '../session/types'; export type DeriveEraValPoints = Record; +export type DeriveEraValPrefs = Record; + export interface DeriveEraPoints { era: EraIndex; eraPoints: RewardPoint; validators: DeriveEraValPoints; } +export interface DeriveEraPrefs { + era: EraIndex; + validators: DeriveEraValPrefs; +} + export interface DeriveEraRewards { era: EraIndex; eraReward: Balance; diff --git a/yarn.lock b/yarn.lock index a4da64db33..e699be566e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2536,25 +2536,25 @@ __metadata: resolution: "@polkadot/api-contract@workspace:packages/api-contract" dependencies: "@babel/runtime": ^7.8.7 - "@polkadot/api": 1.7.0-beta.10 - "@polkadot/rpc-core": 1.7.0-beta.10 - "@polkadot/types": 1.7.0-beta.10 + "@polkadot/api": 1.7.0-beta.11 + "@polkadot/rpc-core": 1.7.0-beta.11 + "@polkadot/types": 1.7.0-beta.11 "@polkadot/util": ^2.6.2 bn.js: ^5.1.1 rxjs: ^6.5.4 languageName: unknown linkType: soft -"@polkadot/api-derive@1.7.0-beta.10, @polkadot/api-derive@workspace:packages/api-derive": +"@polkadot/api-derive@1.7.0-beta.11, @polkadot/api-derive@workspace:packages/api-derive": version: 0.0.0-use.local resolution: "@polkadot/api-derive@workspace:packages/api-derive" dependencies: "@babel/runtime": ^7.8.7 - "@polkadot/api": 1.7.0-beta.10 + "@polkadot/api": 1.7.0-beta.11 "@polkadot/keyring": ^2.6.2 - "@polkadot/rpc-core": 1.7.0-beta.10 - "@polkadot/rpc-provider": 1.7.0-beta.10 - "@polkadot/types": 1.7.0-beta.10 + "@polkadot/rpc-core": 1.7.0-beta.11 + "@polkadot/rpc-provider": 1.7.0-beta.11 + "@polkadot/types": 1.7.0-beta.11 "@polkadot/util": ^2.6.2 "@polkadot/util-crypto": ^2.6.2 bn.js: ^5.1.1 @@ -2563,17 +2563,17 @@ __metadata: languageName: unknown linkType: soft -"@polkadot/api@1.7.0-beta.10, @polkadot/api@workspace:packages/api": +"@polkadot/api@1.7.0-beta.11, @polkadot/api@workspace:packages/api": version: 0.0.0-use.local resolution: "@polkadot/api@workspace:packages/api" dependencies: "@babel/runtime": ^7.8.7 - "@polkadot/api-derive": 1.7.0-beta.10 + "@polkadot/api-derive": 1.7.0-beta.11 "@polkadot/keyring": ^2.6.2 - "@polkadot/metadata": 1.7.0-beta.10 - "@polkadot/rpc-core": 1.7.0-beta.10 - "@polkadot/rpc-provider": 1.7.0-beta.10 - "@polkadot/types": 1.7.0-beta.10 + "@polkadot/metadata": 1.7.0-beta.11 + "@polkadot/rpc-core": 1.7.0-beta.11 + "@polkadot/rpc-provider": 1.7.0-beta.11 + "@polkadot/types": 1.7.0-beta.11 "@polkadot/util": ^2.6.2 "@polkadot/util-crypto": ^2.6.2 bn.js: ^5.1.1 @@ -2582,9 +2582,9 @@ __metadata: languageName: unknown linkType: soft -"@polkadot/dev@npm:^0.50.33": - version: 0.50.35 - resolution: "@polkadot/dev@npm:0.50.35" +"@polkadot/dev@npm:^0.51.1": + version: 0.51.1 + resolution: "@polkadot/dev@npm:0.51.1" dependencies: "@babel/cli": ^7.8.4 "@babel/core": ^7.8.7 @@ -2662,20 +2662,21 @@ __metadata: polkadot-dev-yarn-only: scripts/polkadot-dev-yarn-only.js polkadot-exec-eslint: scripts/polkadot-exec-eslint.js polkadot-exec-ghpages: scripts/polkadot-exec-ghpages.js + polkadot-exec-lerna: scripts/polkadot-exec-lerna.js polkadot-exec-tsc: scripts/polkadot-exec-tsc.js polkadot-exec-typedoc: scripts/polkadot-exec-typedoc.js polkadot-exec-vuepress: scripts/polkadot-exec-vuepress.js polkadot-exec-webpack: scripts/polkadot-exec-webpack.js - checksum: 2/b083a64079ee709c1d2601d7abb296f0f0230977a804014768e52202d23f8d63668cb6f16d0eb3e53935ecc420dc9f7410f4b91aa26fe14acc86a42c83a04686 + checksum: 2/0419da3d3333764965d45c3d735c641dd8c6a355ba75e447bfbec4d2cf58648d1067984a9f7e84767a9a334e5d3b68aeb9cd9e575573bc96033834ceaa10d9d3 languageName: node linkType: hard -"@polkadot/jsonrpc@1.7.0-beta.10, @polkadot/jsonrpc@workspace:packages/jsonrpc": +"@polkadot/jsonrpc@1.7.0-beta.11, @polkadot/jsonrpc@workspace:packages/jsonrpc": version: 0.0.0-use.local resolution: "@polkadot/jsonrpc@workspace:packages/jsonrpc" dependencies: "@babel/runtime": ^7.8.7 - "@polkadot/types": 1.7.0-beta.10 + "@polkadot/types": 1.7.0-beta.11 "@polkadot/util": ^2.6.2 languageName: unknown linkType: soft @@ -2691,44 +2692,44 @@ __metadata: languageName: node linkType: hard -"@polkadot/metadata@1.7.0-beta.10, @polkadot/metadata@workspace:packages/metadata": +"@polkadot/metadata@1.7.0-beta.11, @polkadot/metadata@workspace:packages/metadata": version: 0.0.0-use.local resolution: "@polkadot/metadata@workspace:packages/metadata" dependencies: "@babel/runtime": ^7.8.7 "@polkadot/keyring": ^2.6.2 - "@polkadot/types": 1.7.0-beta.10 + "@polkadot/types": 1.7.0-beta.11 "@polkadot/util": ^2.6.2 "@polkadot/util-crypto": ^2.6.2 bn.js: ^5.1.1 languageName: unknown linkType: soft -"@polkadot/rpc-core@1.7.0-beta.10, @polkadot/rpc-core@workspace:packages/rpc-core": +"@polkadot/rpc-core@1.7.0-beta.11, @polkadot/rpc-core@workspace:packages/rpc-core": version: 0.0.0-use.local resolution: "@polkadot/rpc-core@workspace:packages/rpc-core" dependencies: "@babel/runtime": ^7.8.7 - "@polkadot/jsonrpc": 1.7.0-beta.10 + "@polkadot/jsonrpc": 1.7.0-beta.11 "@polkadot/keyring": ^2.6.2 - "@polkadot/metadata": 1.7.0-beta.10 - "@polkadot/rpc-provider": 1.7.0-beta.10 - "@polkadot/types": 1.7.0-beta.10 + "@polkadot/metadata": 1.7.0-beta.11 + "@polkadot/rpc-provider": 1.7.0-beta.11 + "@polkadot/types": 1.7.0-beta.11 "@polkadot/util": ^2.6.2 memoizee: ^0.4.14 rxjs: ^6.5.4 languageName: unknown linkType: soft -"@polkadot/rpc-provider@1.7.0-beta.10, @polkadot/rpc-provider@workspace:packages/rpc-provider": +"@polkadot/rpc-provider@1.7.0-beta.11, @polkadot/rpc-provider@workspace:packages/rpc-provider": version: 0.0.0-use.local resolution: "@polkadot/rpc-provider@workspace:packages/rpc-provider" dependencies: "@babel/runtime": ^7.8.7 - "@polkadot/jsonrpc": 1.7.0-beta.10 + "@polkadot/jsonrpc": 1.7.0-beta.11 "@polkadot/keyring": ^2.6.2 - "@polkadot/metadata": 1.7.0-beta.10 - "@polkadot/types": 1.7.0-beta.10 + "@polkadot/metadata": 1.7.0-beta.11 + "@polkadot/types": 1.7.0-beta.11 "@polkadot/util": ^2.6.2 "@polkadot/util-crypto": ^2.6.2 bn.js: ^5.1.1 @@ -2740,12 +2741,12 @@ __metadata: languageName: unknown linkType: soft -"@polkadot/ts@npm:^0.3.10": - version: 0.3.10 - resolution: "@polkadot/ts@npm:0.3.10" +"@polkadot/ts@npm:^0.3.11": + version: 0.3.11 + resolution: "@polkadot/ts@npm:0.3.11" dependencies: "@types/chrome": ^0.0.100 - checksum: 2/f3469cc60371ce60d92c028e25c39f5c3cd89868bf2e2d57acaac81483fddf019fb8e078ae1516adb495a600ac367c43817fe420e2f50e2b9294edfcb57bb9fd + checksum: 2/1d99c03b83d5de42b294b72cb4cc5fbb665174dd4e7abb451ad43bd8ae3a20ef8893601964d4ca1806b86180eac9f806d73852acac07f49094dccbd0d53d7a33 languageName: node linkType: hard @@ -2756,11 +2757,11 @@ __metadata: "@babel/core": ^7.8.7 "@babel/register": ^7.8.6 "@babel/runtime": ^7.8.7 - "@polkadot/api": 1.7.0-beta.10 - "@polkadot/jsonrpc": 1.7.0-beta.10 - "@polkadot/metadata": 1.7.0-beta.10 - "@polkadot/rpc-provider": 1.7.0-beta.10 - "@polkadot/types": 1.7.0-beta.10 + "@polkadot/api": 1.7.0-beta.11 + "@polkadot/jsonrpc": 1.7.0-beta.11 + "@polkadot/metadata": 1.7.0-beta.11 + "@polkadot/rpc-provider": 1.7.0-beta.11 + "@polkadot/types": 1.7.0-beta.11 "@polkadot/util": ^2.6.2 "@types/websocket": ^1.0.0 "@types/yargs": ^15.0.4 @@ -2775,13 +2776,13 @@ __metadata: languageName: unknown linkType: soft -"@polkadot/types@1.7.0-beta.10, @polkadot/types@workspace:packages/types": +"@polkadot/types@1.7.0-beta.11, @polkadot/types@workspace:packages/types": version: 0.0.0-use.local resolution: "@polkadot/types@workspace:packages/types" dependencies: "@babel/runtime": ^7.8.7 "@polkadot/keyring": ^2.6.2 - "@polkadot/metadata": 1.7.0-beta.10 + "@polkadot/metadata": 1.7.0-beta.11 "@polkadot/util": ^2.6.2 "@polkadot/util-crypto": ^2.6.2 "@types/bn.js": ^4.11.6 @@ -15296,8 +15297,8 @@ __metadata: "@babel/core": ^7.8.7 "@babel/register": ^7.8.6 "@babel/runtime": ^7.8.7 - "@polkadot/dev": ^0.50.33 - "@polkadot/ts": ^0.3.10 + "@polkadot/dev": ^0.51.1 + "@polkadot/ts": ^0.3.11 "@polkadot/typegen": "workspace:packages/typegen" copyfiles: ^2.2.0 languageName: unknown