Interleave bids & crowdloan on results (#4951)
* Interleave bds & crowdloan on results * Display crowdload flag
This commit is contained in:
parent
3d11bac0a6
commit
9d971b9aca
@ -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<Props> {
|
||||
function Auction ({ auctionInfo, campaigns, className, winningData }: Props): React.ReactElement<Props> {
|
||||
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 (
|
||||
<Table
|
||||
className={className}
|
||||
@ -40,7 +57,7 @@ function Auction ({ auctionInfo, className, winningData }: Props): React.ReactEl
|
||||
>
|
||||
{auctionInfo && winningData?.map(({ blockNumber, winners }, round) => (
|
||||
<tbody key={round}>
|
||||
{winners.map((value, index) => (
|
||||
{interleave(winners, round !== 0 || winningData.length !== 1).map((value, index) => (
|
||||
<WinRange
|
||||
auctionInfo={auctionInfo}
|
||||
blockNumber={blockNumber}
|
||||
|
||||
@ -21,7 +21,7 @@ interface Props {
|
||||
value: WinnerData;
|
||||
}
|
||||
|
||||
function WinRanges ({ auctionInfo, blockNumber, className = '', isFirst, isLatest, value: { accountId, firstSlot, lastSlot, paraId, value } }: Props): React.ReactElement<Props> {
|
||||
function WinRanges ({ auctionInfo, blockNumber, className = '', isFirst, isLatest, value: { accountId, firstSlot, isCrowdloan, lastSlot, paraId, value } }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
@ -37,6 +37,7 @@ function WinRanges ({ auctionInfo, blockNumber, className = '', isFirst, isLates
|
||||
<td className='number'><h1>{formatNumber(paraId)}</h1></td>
|
||||
<td className='badge'><ParaLink id={paraId} /></td>
|
||||
<td className='address'><AddressMini value={accountId} /></td>
|
||||
<td className='all number'>{isCrowdloan ? t<string>('Yes') : t<string>('No')}</td>
|
||||
<td className='all number'>
|
||||
<Digits value={`${formatNumber(firstSlot)} - ${formatNumber(lastSlot)}`} />
|
||||
</td>
|
||||
|
||||
@ -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<Props> {
|
||||
function Auctions ({ auctionInfo, campaigns, className, ownedIds, winningData }: Props): React.ReactElement<Props> {
|
||||
const lastWinners = winningData && winningData[0];
|
||||
|
||||
return (
|
||||
@ -36,6 +37,7 @@ function Auctions ({ auctionInfo, className, ownedIds, winningData }: Props): Re
|
||||
</Button.Group>
|
||||
<Auction
|
||||
auctionInfo={auctionInfo}
|
||||
campaigns={campaigns}
|
||||
winningData={winningData}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -62,7 +62,7 @@ function Funds ({ bestNumber, className, value }: Props): React.ReactElement<Pro
|
||||
<Fund
|
||||
bestNumber={bestNumber}
|
||||
isOngoing
|
||||
key={fund.key}
|
||||
key={fund.accountId}
|
||||
value={fund}
|
||||
/>
|
||||
))}
|
||||
@ -75,7 +75,7 @@ function Funds ({ bestNumber, className, value }: Props): React.ReactElement<Pro
|
||||
{ended?.map((fund) => (
|
||||
<Fund
|
||||
bestNumber={bestNumber}
|
||||
key={fund.key}
|
||||
key={fund.accountId}
|
||||
value={fund}
|
||||
/>
|
||||
))}
|
||||
|
||||
@ -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');
|
||||
|
||||
@ -67,6 +67,7 @@ function ParachainsApp ({ basePath, className }: Props): React.ReactElement<Prop
|
||||
<Route path={`${basePath}/auctions`}>
|
||||
<Auctions
|
||||
auctionInfo={auctionInfo}
|
||||
campaigns={campaigns}
|
||||
ownedIds={ownedIds}
|
||||
winningData={winningData}
|
||||
/>
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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) ||
|
||||
|
||||
@ -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<WinningData>)
|
||||
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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user