Support for time-delay proxy params (defaults) (#3358)
* Support for time-delay proxy params (defaults) * All proxy queries adjusted * Proxy extraction * Re-use proxy map * Update after testing * Cleanups * Typ detection based on args * CHANGELOG
This commit is contained in:
parent
5ccfc5beb8
commit
0ed89585fc
@ -1,5 +1,9 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 0.54.0-beta.x
|
||||
|
||||
- Base support for time-delay proxies (API-level only, both old and new calls)
|
||||
|
||||
## 0.53.1 Aug 10, 2020
|
||||
|
||||
- ko i18n first-round support (Thanks to https://github.com/hskang9)
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
import { SubmittableExtrinsic } from '@polkadot/api/types';
|
||||
import { DeriveBalancesAll, DeriveDemocracyLock } from '@polkadot/api-derive/types';
|
||||
import { ActionStatus } from '@polkadot/react-components/Status/types';
|
||||
import { AccountId, ProxyType, RecoveryConfig } from '@polkadot/types/interfaces';
|
||||
import { ProxyDefinition, RecoveryConfig } from '@polkadot/types/interfaces';
|
||||
import { KeyringAddress } from '@polkadot/ui-keyring/types';
|
||||
import { Delegation } from '../types';
|
||||
|
||||
@ -43,7 +43,7 @@ interface Props {
|
||||
delegation?: Delegation;
|
||||
filter: string;
|
||||
isFavorite: boolean;
|
||||
proxy?: [[AccountId, ProxyType][], BN];
|
||||
proxy?: [ProxyDefinition[], BN];
|
||||
setBalance: (address: string, value: BN) => void;
|
||||
toggleFavorite: (address: string) => void;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ActionStatus } from '@polkadot/react-components/Status/types';
|
||||
import { AccountId, ProxyType, Voting } from '@polkadot/types/interfaces';
|
||||
import { AccountId, ProxyDefinition, ProxyType, Voting } from '@polkadot/types/interfaces';
|
||||
import { Delegation, SortedAccount } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
@ -74,7 +74,14 @@ function Overview ({ className = '', onStatusChange }: Props): React.ReactElemen
|
||||
const [sortedAccountsWithDelegation, setSortedAccountsWithDelegation] = useState<SortedAccount[] | undefined>();
|
||||
const [{ sortedAccounts, sortedAddresses }, setSorted] = useState<Sorted>({ sortedAccounts: [], sortedAddresses: [] });
|
||||
const delegations = useCall<Voting[]>(api.query.democracy?.votingOf?.multi, [sortedAddresses]);
|
||||
const proxies = useCall<[[AccountId, ProxyType][], BN][]>(api.query.proxy?.proxies.multi, [sortedAddresses]);
|
||||
const proxies = useCall<[ProxyDefinition[], BN][]>(api.query.proxy?.proxies.multi, [sortedAddresses], {
|
||||
transform: (result: [([AccountId, ProxyType] | ProxyDefinition)[], BN][]): [ProxyDefinition[], BN][] =>
|
||||
api.tx.proxy.addProxy.meta.args.length === 4
|
||||
? result as [ProxyDefinition[], BN][]
|
||||
: (result as [[AccountId, ProxyType][], BN][]).map(([arr, bn]): [ProxyDefinition[], BN] =>
|
||||
[arr.map(([delegate, proxyType]): ProxyDefinition => api.createType('ProxyDefinition', { delegate, proxyType })), bn]
|
||||
)
|
||||
});
|
||||
const isLoading = useLoadingDelay();
|
||||
|
||||
useEffect((): void => {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { ApiPromise } from '@polkadot/api';
|
||||
import { SubmittableExtrinsic } from '@polkadot/api/types';
|
||||
import { AccountId, ProxyType } from '@polkadot/types/interfaces';
|
||||
import { AccountId, ProxyDefinition, ProxyType } from '@polkadot/types/interfaces';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
@ -20,7 +20,7 @@ type PrevProxy = [AccountId, ProxyType];
|
||||
interface Props {
|
||||
className?: string;
|
||||
onClose: () => void;
|
||||
previousProxy?: [PrevProxy[], BN];
|
||||
previousProxy?: [ProxyDefinition[], BN];
|
||||
proxiedAccount: string;
|
||||
}
|
||||
|
||||
@ -50,6 +50,22 @@ function createExtrinsic (api: ApiPromise, batchPrevious: SubmittableExtrinsic<'
|
||||
return api.tx.utility.batch([...batchPrevious, ...batchAdded]);
|
||||
}
|
||||
|
||||
function createAddProxy (api: ApiPromise, account: AccountId, type: ProxyType): SubmittableExtrinsic<'promise'> {
|
||||
return api.tx.proxy.addProxy.meta.args.length === 2
|
||||
? api.tx.proxy.addProxy(account, type)
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore new version
|
||||
: api.tx.proxy.addProxy(account, type, 0);
|
||||
}
|
||||
|
||||
function createRmProxy (api: ApiPromise, account: AccountId, type: ProxyType): SubmittableExtrinsic<'promise'> {
|
||||
return api.tx.proxy.removeProxy.meta.args.length === 2
|
||||
? api.tx.proxy.removeProxy(account, type)
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore new version
|
||||
: api.tx.proxy.removeProxy(account, type, 0);
|
||||
}
|
||||
|
||||
function PrevProxy ({ index, onRemove, typeOpts, value: [accountId, type] }: PrevProxyProps): React.ReactElement<PrevProxyProps> {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -135,22 +151,17 @@ function NewProxy ({ index, onChangeAccount, onChangeType, onRemove, typeOpts, v
|
||||
function ProxyOverview ({ className, onClose, previousProxy, proxiedAccount }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
// the stack of extrinsics on the previous proxies
|
||||
const [batchStackPrevious, setBatchStackPrevious] = useState<SubmittableExtrinsic<'promise'>[]>([]);
|
||||
// the stack of extrinsics on newly added proxies
|
||||
const [batchStackAdded, setBatchStackAdded] = useState<SubmittableExtrinsic<'promise'>[]>([]);
|
||||
// the final extrinsic (either single or a batch)
|
||||
const [extrinsic, setExtrinsic] = useState<SubmittableExtrinsic<'promise'> | null>(null);
|
||||
// list of previous accounts and proxy types
|
||||
const [previousProxyAccountsTypes] = previousProxy || [];
|
||||
// actualized list of previous proxy including new changes (deletion if any)
|
||||
const [previousProxyDisplay, setPreviousProxyDisplay] = useState<[AccountId, ProxyType][] | undefined>(previousProxyAccountsTypes);
|
||||
// actualized list of new proxies (additions, if any)
|
||||
const [addedProxies, setAddedProxies] = useState<[AccountId, ProxyType][]>([]);
|
||||
const [previousProxyDisplay, setPreviousProxyDisplay] = useState<PrevProxy[] | undefined>(
|
||||
previousProxy?.[0].map(({ delegate, proxyType }): [AccountId, ProxyType] => [delegate, proxyType]) || undefined
|
||||
);
|
||||
const [addedProxies, setAddedProxies] = useState<PrevProxy[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (batchStackPrevious.length || batchStackAdded.length) {
|
||||
setExtrinsic(createExtrinsic(api, batchStackPrevious, batchStackAdded));
|
||||
setExtrinsic(() => createExtrinsic(api, batchStackPrevious, batchStackAdded));
|
||||
}
|
||||
}, [api, batchStackPrevious, batchStackAdded]);
|
||||
|
||||
@ -172,7 +183,7 @@ function ProxyOverview ({ className, onClose, previousProxy, proxiedAccount }: P
|
||||
: [...prevState, newProxy];
|
||||
});
|
||||
|
||||
setBatchStackAdded((prev) => prev.concat(api.tx.proxy.addProxy(newAccount, newType)));
|
||||
setBatchStackAdded((prev) => prev.concat(createAddProxy(api, newAccount, newType)));
|
||||
},
|
||||
[api, proxiedAccount]
|
||||
);
|
||||
@ -188,7 +199,7 @@ function ProxyOverview ({ className, onClose, previousProxy, proxiedAccount }: P
|
||||
const _delPrev = useCallback(
|
||||
(accountId: AccountId, type: ProxyType, index: number) => {
|
||||
setPreviousProxyDisplay((previousProxyDisplay) => previousProxyDisplay?.filter((_, i) => i !== index));
|
||||
setBatchStackPrevious((batchStackPrevious) => [...batchStackPrevious, api.tx.proxy.removeProxy(accountId, type)]);
|
||||
setBatchStackPrevious((batchStackPrevious) => [...batchStackPrevious, createRmProxy(api, accountId, type)]);
|
||||
},
|
||||
[api]
|
||||
);
|
||||
@ -211,7 +222,7 @@ function ProxyOverview ({ className, onClose, previousProxy, proxiedAccount }: P
|
||||
setBatchStackAdded((batchStackAdded): SubmittableExtrinsic<'promise'>[] => {
|
||||
const newBatchAdded = batchStackAdded.filter((_, i) => i !== index);
|
||||
|
||||
newBatchAdded.push(api.tx.proxy.addProxy(accountId, oldType));
|
||||
newBatchAdded.push(createAddProxy(api, accountId, oldType));
|
||||
|
||||
return newBatchAdded;
|
||||
});
|
||||
@ -238,7 +249,7 @@ function ProxyOverview ({ className, onClose, previousProxy, proxiedAccount }: P
|
||||
const newBatchStackAdded = batchStackAdded.filter((_, i) => i !== index);
|
||||
|
||||
// Then add the new extrinsic to the batch stack with the new account
|
||||
newBatchStackAdded.push(api.tx.proxy.addProxy(oldAccount, newType));
|
||||
newBatchStackAdded.push(createAddProxy(api, oldAccount, newType));
|
||||
setBatchStackAdded(newBatchStackAdded);
|
||||
},
|
||||
[addedProxies, api, batchStackAdded]
|
||||
@ -269,7 +280,7 @@ function ProxyOverview ({ className, onClose, previousProxy, proxiedAccount }: P
|
||||
{previousProxyDisplay?.map((value, index) => (
|
||||
<PrevProxy
|
||||
index={index}
|
||||
key={`${value[0].toString()}-${index}`}
|
||||
key={`${value.toString()}-${index}`}
|
||||
onRemove={_delPrev}
|
||||
typeOpts={typeOpts}
|
||||
value={value}
|
||||
@ -278,7 +289,7 @@ function ProxyOverview ({ className, onClose, previousProxy, proxiedAccount }: P
|
||||
{addedProxies.map((value, index) => (
|
||||
<NewProxy
|
||||
index={index}
|
||||
key={`${value[0].toString()}-${index}`}
|
||||
key={`${value.toString()}-${index}`}
|
||||
onChangeAccount={_changeProxyAccount}
|
||||
onChangeType={_changeProxyType}
|
||||
onRemove={_delProxy}
|
||||
|
||||
@ -2,13 +2,18 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ProxyType } from '@polkadot/types/interfaces';
|
||||
import { AccountId, BalanceOf, ProxyDefinition, ProxyType } from '@polkadot/types/interfaces';
|
||||
import { ITuple } from '@polkadot/types/types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useAccounts, useApi, useIsMountedRef } from '@polkadot/react-hooks';
|
||||
import { Vec } from '@polkadot/types';
|
||||
import { BN_ZERO } from '@polkadot/util';
|
||||
|
||||
interface Proxy {
|
||||
address: string;
|
||||
delay: BN;
|
||||
isOwned: boolean;
|
||||
type: ProxyType;
|
||||
}
|
||||
@ -25,6 +30,17 @@ const EMPTY_STATE: State = {
|
||||
proxies: []
|
||||
};
|
||||
|
||||
function createProxy (allAccounts: string[], delegate: AccountId, type: ProxyType, delay = BN_ZERO): Proxy {
|
||||
const address = delegate.toString();
|
||||
|
||||
return {
|
||||
address,
|
||||
delay,
|
||||
isOwned: allAccounts.includes(address),
|
||||
type
|
||||
};
|
||||
}
|
||||
|
||||
export default function useProxies (address?: string | null): State {
|
||||
const { api } = useApi();
|
||||
const { allAccounts } = useAccounts();
|
||||
@ -36,13 +52,15 @@ export default function useProxies (address?: string | null): State {
|
||||
|
||||
address && api.query.proxy &&
|
||||
api.query.proxy
|
||||
.proxies(address)
|
||||
.proxies<ITuple<[Vec<ITuple<[AccountId, ProxyType]> | ProxyDefinition>, BalanceOf]>>(address)
|
||||
.then(([_proxies]): void => {
|
||||
const proxies = _proxies.map(([accountId, type]): Proxy => ({
|
||||
address: accountId.toString(),
|
||||
isOwned: allAccounts.includes(accountId.toString()),
|
||||
type
|
||||
}));
|
||||
const proxies = api.tx.proxy.addProxy.meta.args.length === 4
|
||||
? (_proxies as ProxyDefinition[]).map(({ delay, delegate, proxyType }) =>
|
||||
createProxy(allAccounts, delegate, proxyType, delay)
|
||||
)
|
||||
: (_proxies as [AccountId, ProxyType][]).map(([delegate, proxyType]) =>
|
||||
createProxy(allAccounts, delegate, proxyType)
|
||||
);
|
||||
const owned = proxies.filter(({ isOwned }) => isOwned);
|
||||
|
||||
mountedRef.current && setState({
|
||||
|
||||
@ -4,7 +4,8 @@
|
||||
|
||||
import { SubmittableExtrinsic } from '@polkadot/api/types';
|
||||
import { QueueTx } from '@polkadot/react-components/Status/types';
|
||||
import { Call, Multisig, ProxyType } from '@polkadot/types/interfaces';
|
||||
import { AccountId, BalanceOf, Call, Multisig, ProxyDefinition, ProxyType } from '@polkadot/types/interfaces';
|
||||
import { ITuple } from '@polkadot/types/types';
|
||||
import { AddressProxy } from './types';
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
@ -121,8 +122,10 @@ async function queryForMultisig (api: ApiPromise, requestAddress: string, proxyA
|
||||
async function queryForProxy (api: ApiPromise, allAccounts: string[], address: string, tx: SubmittableExtrinsic<'promise'>): Promise<ProxyState | null> {
|
||||
if (isFunction(api.query.proxy?.proxies)) {
|
||||
const { isProxied } = extractExternal(address);
|
||||
const [_proxies] = await api.query.proxy.proxies(address);
|
||||
const proxies = _proxies.map(([accountId, type]): [string, ProxyType] => [accountId.toString(), type]);
|
||||
const [_proxies] = await api.query.proxy.proxies<ITuple<[Vec<ITuple<[AccountId, ProxyType]> | ProxyDefinition>, BalanceOf]>>(address);
|
||||
const proxies = api.tx.proxy.addProxy.meta.args.length === 4
|
||||
? (_proxies as ProxyDefinition[]).map(({ delegate, proxyType }): [string, ProxyType] => [delegate.toString(), proxyType])
|
||||
: (_proxies as [AccountId, ProxyType][]).map(([delegate, proxyType]): [string, ProxyType] => [delegate.toString(), proxyType]);
|
||||
const proxiesFilter = filterProxies(allAccounts, tx, proxies);
|
||||
|
||||
if (proxiesFilter.length) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user