From 9d971b9aca6aef3f8b60b61994983a238536e5d0 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 26 Mar 2021 18:04:23 +0100 Subject: [PATCH] Interleave bids & crowdloan on results (#4951) * Interleave bds & crowdloan on results * Display crowdload flag --- .../page-parachains/src/Auctions/Auction.tsx | 27 +++++++++++++++---- .../page-parachains/src/Auctions/WinRange.tsx | 3 ++- .../page-parachains/src/Auctions/index.tsx | 6 +++-- .../page-parachains/src/Crowdloan/Funds.tsx | 4 +-- packages/page-parachains/src/constants.ts | 4 +++ packages/page-parachains/src/index.tsx | 1 + packages/page-parachains/src/types.ts | 11 ++++---- packages/page-parachains/src/useFunds.ts | 20 ++++++++++---- .../page-parachains/src/useWinningData.ts | 13 ++++++--- 9 files changed, 65 insertions(+), 24 deletions(-) diff --git a/packages/page-parachains/src/Auctions/Auction.tsx b/packages/page-parachains/src/Auctions/Auction.tsx index 8ce34bfbe2..91f13cb476 100644 --- a/packages/page-parachains/src/Auctions/Auction.tsx +++ b/packages/page-parachains/src/Auctions/Auction.tsx @@ -1,9 +1,9 @@ // Copyright 2017-2021 @polkadot/app-parachains authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { AuctionInfo, Winning } from '../types'; +import type { AuctionInfo, Campaigns, WinnerData, Winning } from '../types'; -import React, { useRef } from 'react'; +import React, { useCallback, useRef } from 'react'; import { Table } from '@polkadot/react-components'; @@ -12,19 +12,36 @@ import WinRange from './WinRange'; interface Props { auctionInfo?: AuctionInfo; + campaigns: Campaigns; className?: string; winningData?: Winning[]; } -function Auction ({ auctionInfo, className, winningData }: Props): React.ReactElement { +function Auction ({ auctionInfo, campaigns, className, winningData }: Props): React.ReactElement { const { t } = useTranslation(); const headerRef = useRef([ - [t('bids'), 'start', 4], + [t('bids'), 'start', 3], + [t('bidder'), 'address'], + [t('crowdloan')], [t('periods')], [t('value')] ]); + const interleave = useCallback( + (winners: WinnerData[], asIs: boolean): WinnerData[] => + asIs + ? winners + : winners.map((w): WinnerData => + campaigns.funds?.find(({ firstSlot, lastSlot, value }) => + w.firstSlot === firstSlot && + w.lastSlot === lastSlot && + w.value.lt(value) + ) || w + ), + [campaigns] + ); + return ( {auctionInfo && winningData?.map(({ blockNumber, winners }, round) => ( - {winners.map((value, index) => ( + {interleave(winners, round !== 0 || winningData.length !== 1).map((value, index) => ( { +function WinRanges ({ auctionInfo, blockNumber, className = '', isFirst, isLatest, value: { accountId, firstSlot, isCrowdloan, lastSlot, paraId, value } }: Props): React.ReactElement { const { t } = useTranslation(); return ( @@ -37,6 +37,7 @@ function WinRanges ({ auctionInfo, blockNumber, className = '', isFirst, isLates + diff --git a/packages/page-parachains/src/Auctions/index.tsx b/packages/page-parachains/src/Auctions/index.tsx index 532eb82617..6b1c9f2f77 100644 --- a/packages/page-parachains/src/Auctions/index.tsx +++ b/packages/page-parachains/src/Auctions/index.tsx @@ -1,7 +1,7 @@ // Copyright 2017-2021 @polkadot/app-parachains authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { AuctionInfo, OwnedId, Winning } from '../types'; +import type { AuctionInfo, Campaigns, OwnedId, Winning } from '../types'; import React from 'react'; @@ -13,12 +13,13 @@ import Summary from './Summary'; interface Props { auctionInfo?: AuctionInfo; + campaigns: Campaigns; className?: string; ownedIds: OwnedId[]; winningData?: Winning[]; } -function Auctions ({ auctionInfo, className, ownedIds, winningData }: Props): React.ReactElement { +function Auctions ({ auctionInfo, campaigns, className, ownedIds, winningData }: Props): React.ReactElement { const lastWinners = winningData && winningData[0]; return ( @@ -36,6 +37,7 @@ function Auctions ({ auctionInfo, className, ownedIds, winningData }: Props): Re diff --git a/packages/page-parachains/src/Crowdloan/Funds.tsx b/packages/page-parachains/src/Crowdloan/Funds.tsx index 5148342a14..7a731f2fd7 100644 --- a/packages/page-parachains/src/Crowdloan/Funds.tsx +++ b/packages/page-parachains/src/Crowdloan/Funds.tsx @@ -62,7 +62,7 @@ function Funds ({ bestNumber, className, value }: Props): React.ReactElement ))} @@ -75,7 +75,7 @@ function Funds ({ bestNumber, className, value }: Props): React.ReactElement ( ))} diff --git a/packages/page-parachains/src/constants.ts b/packages/page-parachains/src/constants.ts index 19f7a67ebc..63c28ceacd 100644 --- a/packages/page-parachains/src/constants.ts +++ b/packages/page-parachains/src/constants.ts @@ -1,9 +1,13 @@ // Copyright 2017-2021 @polkadot/app-parachains authors & contributors // SPDX-License-Identifier: Apache-2.0 +import { stringToU8a } from '@polkadot/util'; + export const RANGES: [number, number][] = [ [0, 0], [0, 1], [0, 2], [0, 3], [1, 1], [1, 2], [1, 3], [2, 2], [2, 3], [3, 3] ]; + +export const CROWD_PREFIX = stringToU8a('modlpy/cfund'); diff --git a/packages/page-parachains/src/index.tsx b/packages/page-parachains/src/index.tsx index 5bade99200..2ad834f7df 100644 --- a/packages/page-parachains/src/index.tsx +++ b/packages/page-parachains/src/index.tsx @@ -67,6 +67,7 @@ function ParachainsApp ({ basePath, className }: Props): React.ReactElement diff --git a/packages/page-parachains/src/types.ts b/packages/page-parachains/src/types.ts index ddd3ca1b61..7879269359 100644 --- a/packages/page-parachains/src/types.ts +++ b/packages/page-parachains/src/types.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type BN from 'bn.js'; -import type { AccountId, AuctionIndex, BalanceOf, BlockNumber, FundInfo, LeasePeriodOf, ParachainProposal, ParaId, ParaInfo, SessionIndex } from '@polkadot/types/interfaces'; +import type { AuctionIndex, BlockNumber, FundInfo, LeasePeriodOf, ParachainProposal, ParaId, ParaInfo, SessionIndex } from '@polkadot/types/interfaces'; export interface AuctionInfo { endBlock: BlockNumber | null; @@ -30,14 +30,12 @@ export interface Campaigns { totalRaised: BN; } -export interface Campaign { +export interface Campaign extends WinnerData { info: FundInfo; isCapped?: boolean; isEnded?: boolean; isRetired?: boolean; isWinner?: boolean; - key: string; - paraId: ParaId; retireEnd?: BN; } @@ -66,11 +64,12 @@ export interface OwnerInfo { } export interface WinnerData { - accountId: AccountId; + accountId: string; firstSlot: number; + isCrowdloan: boolean; lastSlot: number; paraId: ParaId; - value: BalanceOf; + value: BN; } export interface Winning { diff --git a/packages/page-parachains/src/useFunds.ts b/packages/page-parachains/src/useFunds.ts index cea32350a4..83bfff513a 100644 --- a/packages/page-parachains/src/useFunds.ts +++ b/packages/page-parachains/src/useFunds.ts @@ -10,7 +10,10 @@ import BN from 'bn.js'; import { useEffect, useState } from 'react'; import { useApi, useBestNumber, useCall, useEventTrigger } from '@polkadot/react-hooks'; -import { BN_ZERO, stringToU8a, u8aConcat } from '@polkadot/util'; +import { BN_ZERO, u8aConcat } from '@polkadot/util'; +import { encodeAddress } from '@polkadot/util-crypto'; + +import { CROWD_PREFIX } from './constants'; const EMPTY: Campaigns = { activeCap: BN_ZERO, @@ -20,11 +23,14 @@ const EMPTY: Campaigns = { totalRaised: BN_ZERO }; -const PREFIX = stringToU8a('modlpy/cfund'); const EMPTY_U8A = new Uint8Array(32); +function createAddress (paraId: ParaId): Uint8Array { + return u8aConcat(CROWD_PREFIX, paraId.toU8a(), EMPTY_U8A).subarray(0, 32); +} + function isCrowdloadAccount (paraId: ParaId, accountId: AccountId): boolean { - return accountId.eq(u8aConcat(PREFIX, paraId.toU8a(), EMPTY_U8A).subarray(0, 32)); + return accountId.eq(); } function hasLease (paraId: ParaId, leased: ParaId[]): boolean { @@ -116,9 +122,13 @@ const optFundMulti = { .map((paraId, i): [ParaId, FundInfo | null] => [paraId, optFunds[i].unwrapOr(null)]) .filter((v): v is [ParaId, FundInfo] => !!v[1]) .map(([paraId, info]): Campaign => ({ + accountId: encodeAddress(createAddress(paraId)), + firstSlot: info.firstSlot.toNumber(), info, - key: paraId.toString(), - paraId + isCrowdloan: true, + lastSlot: info.lastSlot.toNumber(), + paraId, + value: info.raised })) .sort((a, b) => a.info.end.cmp(b.info.end) || diff --git a/packages/page-parachains/src/useWinningData.ts b/packages/page-parachains/src/useWinningData.ts index 16e4b51d0c..fe58445ead 100644 --- a/packages/page-parachains/src/useWinningData.ts +++ b/packages/page-parachains/src/useWinningData.ts @@ -9,9 +9,9 @@ import BN from 'bn.js'; import { useEffect, useRef, useState } from 'react'; import { useApi, useBestNumber, useCall, useEventTrigger } from '@polkadot/react-hooks'; -import { BN_ONE, BN_ZERO } from '@polkadot/util'; +import { BN_ONE, BN_ZERO, u8aEq } from '@polkadot/util'; -import { RANGES } from './constants'; +import { CROWD_PREFIX, RANGES } from './constants'; const FIRST_PARAM = [0]; @@ -36,7 +36,14 @@ function extractWinners (auctionInfo: AuctionInfo, optData: Option) const period = auctionInfo.leasePeriod?.toNumber() || 0; const [first, last] = RANGES[index]; - winners.push({ accountId, firstSlot: first + period, lastSlot: last + period, paraId, value }); + winners.push({ + accountId: accountId.toString(), + firstSlot: first + period, + isCrowdloan: u8aEq(CROWD_PREFIX, accountId.subarray(0, CROWD_PREFIX.length)), + lastSlot: last + period, + paraId, + value + }); } return winners;

{formatNumber(paraId)}

{isCrowdloan ? t('Yes') : t('No')}