From 2f783297389290ec73b526aade425bf3eed99b55 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 28 Aug 2020 14:23:05 +0200 Subject: [PATCH] Return democracy locks for delegations (#2531) --- CHANGELOG.md | 1 + packages/api-derive/src/balances/all.ts | 4 ++- packages/api-derive/src/democracy/locks.ts | 29 +++++++++++++++++++--- packages/api-derive/src/democracy/types.ts | 2 ++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6ccf24021..4a3c100010 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - **Important** Substrate changed the `RewardDestination` enum with an extra field for payout-to-any account. If on an older chain consider adding `RewardDestination: 'RewardDestinationTo257'` (Newer chains with this requirement met in their Substrate version should update the API for support) - Add `toBigInt()` (JS built-in `BigInt`) on `Int/Uint`, & `Compact<*>` types +- `derive.democracy.locks` now returns delegated locks for an account as well ## 1.30.1 Aug 24, 2020 diff --git a/packages/api-derive/src/balances/all.ts b/packages/api-derive/src/balances/all.ts index abc3bf81b3..1350811fb2 100644 --- a/packages/api-derive/src/balances/all.ts +++ b/packages/api-derive/src/balances/all.ts @@ -17,6 +17,8 @@ import { memo } from '../util'; type ResultBalance = [VestingInfo | null, (BalanceLock | BalanceLockTo212)[]]; type Result = [DeriveBalancesAccount, BlockNumber, ResultBalance]; +const VESTING_ID = '0x76657374696e6720'; + function calcBalances (api: ApiInterfaceRx, [{ accountId, accountNonce, freeBalance, frozenFee, frozenMisc, reservedBalance, votingBalance }, bestNumber, [vesting, locks]]: Result): DeriveBalancesAll { let lockedBalance = api.registry.createType('Balance'); let lockedBreakdown: (BalanceLock | BalanceLockTo212)[] = []; @@ -30,7 +32,7 @@ function calcBalances (api: ApiInterfaceRx, [{ accountId, accountNonce, freeBala const notAll = lockedBreakdown.filter(({ amount }) => !amount.isMax()); allLocked = lockedBreakdown.some(({ amount }) => amount.isMax()); - vestingLocked = api.registry.createType('Balance', lockedBreakdown.filter(({ id }) => id.eq('0x76657374696e6720')).reduce((result: BN, { amount }) => result.iadd(amount), new BN(0))); + vestingLocked = api.registry.createType('Balance', lockedBreakdown.filter(({ id }) => id.eq(VESTING_ID)).reduce((result: BN, { amount }) => result.iadd(amount), new BN(0))); // get the maximum of the locks according to https://github.com/paritytech/substrate/blob/master/srml/balances/src/lib.rs#L699 if (notAll.length) { diff --git a/packages/api-derive/src/democracy/locks.ts b/packages/api-derive/src/democracy/locks.ts index 51104a8d8e..3ed6f26cde 100644 --- a/packages/api-derive/src/democracy/locks.ts +++ b/packages/api-derive/src/democracy/locks.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { AccountId, ReferendumInfo, ReferendumInfoTo239, VotingDirect, VotingDirectVote } from '@polkadot/types/interfaces'; +import { AccountId, ReferendumInfo, ReferendumInfoTo239, VotingDelegating, VotingDirect, VotingDirectVote } from '@polkadot/types/interfaces'; import { ApiInterfaceRx } from '@polkadot/api/types'; import { DeriveDemocracyLock } from '../types'; @@ -20,16 +20,37 @@ const ZERO = new BN(0); function parseLock (api: ApiInterfaceRx, [referendumId, accountVote]: VotingDirectVote, referendum: ReferendumInfo): DeriveDemocracyLock { const { balance, vote } = accountVote.asStandard; let unlockAt = ZERO; + let referendumEnd = ZERO; if (referendum.isFinished) { const { approved, end } = referendum.asFinished; + referendumEnd = end; + if ((approved.isTrue && vote.isAye) || (approved.isFalse && vote.isNay)) { unlockAt = end.add(api.consts.democracy.enactmentPeriod.muln(LOCKUPS[vote.conviction.index])); } } - return { balance, isFinished: referendum.isFinished, referendumId, unlockAt, vote }; + return { balance, isDelegated: false, isFinished: referendum.isFinished, referendumEnd, referendumId, unlockAt, vote }; +} + +function delegateLocks (api: ApiInterfaceRx, { balance, conviction, target }: VotingDelegating): Observable { + return api.derive.democracy.locks(target).pipe( + map((available): DeriveDemocracyLock[] => + available.map(({ isFinished, referendumEnd, referendumId, unlockAt, vote }): DeriveDemocracyLock => ({ + balance, + isDelegated: true, + isFinished, + referendumEnd, + referendumId, + unlockAt: unlockAt.isZero() + ? unlockAt + : referendumEnd.add(api.consts.democracy.enactmentPeriod.muln(LOCKUPS[conviction.index])), + vote: api.registry.createType('Vote', { aye: vote.isAye, conviction }) + })) + ) + ); } function directLocks (api: ApiInterfaceRx, { votes }: VotingDirect): Observable { @@ -59,7 +80,9 @@ export function locks (api: ApiInterfaceRx): (accountId: string | AccountId) => switchMap((voting): Observable => voting.isDirect ? directLocks(api, voting.asDirect) - : of([]) + : voting.isDelegating + ? delegateLocks(api, voting.asDelegating) + : of([]) ) ) ); diff --git a/packages/api-derive/src/democracy/types.ts b/packages/api-derive/src/democracy/types.ts index 281cd93286..7d755ee01b 100644 --- a/packages/api-derive/src/democracy/types.ts +++ b/packages/api-derive/src/democracy/types.ts @@ -9,7 +9,9 @@ import { Vec } from '@polkadot/types'; export interface DeriveDemocracyLock { balance: Balance; + isDelegated: boolean; isFinished: boolean; + referendumEnd: BN; referendumId: ReferendumIndex; unlockAt: BN; vote: Vote;