Ensure decode fills non-existent MultiAddress (allPlus) (#7506)

This commit is contained in:
Jaco 2022-05-02 20:25:56 +02:00 committed by GitHub
parent 2e45933e67
commit 4fb02896b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 29 deletions

View File

@ -12,6 +12,7 @@ import { withMulti, withObservable } from '@polkadot/react-api/hoc';
import { keyring } from '@polkadot/ui-keyring';
import { createOptionItem } from '@polkadot/ui-keyring/options/item';
import { isNull, isUndefined } from '@polkadot/util';
import { isAddress } from '@polkadot/util-crypto';
import Dropdown from '../Dropdown';
import Static from '../Static';
@ -170,7 +171,7 @@ class InputAddress extends React.PureComponent<Props, State> {
const { lastValue, value } = this.state;
const lastOption = this.getLastOptionValue();
const actualValue = transformToAddress(
isDisabled || (defaultValue && this.hasValue(defaultValue))
isDisabled || (defaultValue && (this.hasValue(defaultValue) || type === 'allPlus'))
? defaultValue
: this.hasValue(lastValue)
? lastValue
@ -180,7 +181,9 @@ class InputAddress extends React.PureComponent<Props, State> {
? dedupe(options.map((o) => createItem(o)))
: isDisabled && actualValue
? [createOption(actualValue)]
: this.getFiltered();
: actualValue
? this.addActual(actualValue)
: this.getFiltered();
const _defaultValue = (isMultiple || !isUndefined(value))
? undefined
: actualValue;
@ -219,6 +222,14 @@ class InputAddress extends React.PureComponent<Props, State> {
);
}
private addActual (actualValue: string): Option[] {
const base = this.getFiltered();
return this.hasValue(actualValue)
? base
: base.concat(createOption(actualValue));
}
private renderLabel = ({ value }: KeyringSectionOption): React.ReactNode => {
if (!value) {
return undefined;
@ -263,7 +274,7 @@ class InputAddress extends React.PureComponent<Props, State> {
!filter && setLastValue(type, address);
onChange && onChange(
this.hasValue(address)
!!address && (this.hasValue(address) || (type === 'allPlus' && isAddress(address)))
? transformToAccountId(address)
: null
);

View File

@ -1,6 +1,7 @@
// Copyright 2017-2022 @polkadot/app-extrinsics authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { ApiPromise } from '@polkadot/api';
import type { SubmittableExtrinsic, SubmittableExtrinsicFunction } from '@polkadot/api/types';
import type { Props, RawParam } from '@polkadot/react-params/types';
import type { Call } from '@polkadot/types/interfaces';
@ -27,29 +28,31 @@ function mapArgs (args: unknown[]): RawParam[] {
}));
}
export function extractInitial (api: ApiPromise, initialValue: SubmittableExtrinsicFunction<'promise'>, input?: RawParam): { initialArgs?: RawParam[], initialValue: SubmittableExtrinsicFunction<'promise'> } {
try {
return input && input.value
? isCall(input.value)
? {
initialArgs: mapArgs(input.value.args),
initialValue: api.tx[input.value.section][input.value.method]
}
: isSubmittable(input.value)
? {
initialArgs: mapArgs(input.value.method.args),
initialValue: api.tx[input.value.method.section][input.value.method.method]
}
: { initialValue: (input.value as SubmittableExtrinsicFunction<'promise'>) }
: { initialValue };
} catch (error) {
return { initialValue };
}
}
function CallDisplay ({ className = '', defaultValue, isDisabled, isError, label, onChange, onEnter, onEscape, withLabel }: Props): React.ReactElement<Props> {
const { api, apiDefaultTx } = useApi();
const [{ initialArgs, initialValue }] = useState(
(): { initialArgs?: RawParam[], initialValue: SubmittableExtrinsicFunction<'promise'> } => {
try {
return defaultValue && defaultValue.value
? isCall(defaultValue.value)
? {
initialArgs: mapArgs(defaultValue.value.args),
initialValue: api.tx[defaultValue.value.section][defaultValue.value.method]
}
: isSubmittable(defaultValue.value)
? {
initialArgs: mapArgs(defaultValue.value.method.args),
initialValue: api.tx[defaultValue.value.method.section][defaultValue.value.method.method]
}
: { initialValue: (defaultValue.value as SubmittableExtrinsicFunction<'promise'>) }
: { initialValue: api.tx.balances.transfer };
} catch (error) {
return { initialValue: apiDefaultTx };
}
}
() => extractInitial(api, apiDefaultTx, defaultValue)
);
return (

View File

@ -4,14 +4,19 @@
import type { SubmittableExtrinsic } from '@polkadot/api/types';
import type { Props, RawParam } from '@polkadot/react-params/types';
import React, { useCallback } from 'react';
import React, { useCallback, useState } from 'react';
import { useApi } from '@polkadot/react-hooks';
import { extractInitial } from './Call';
import ExtrinsicDisplay from './Extrinsic';
function OpaqueCall ({ className = '', isDisabled, isError, label, onChange, onEnter, onEscape, withLabel }: Props): React.ReactElement<Props> {
const { apiDefaultTxSudo } = useApi();
function OpaqueCall ({ className = '', defaultValue, isDisabled, isError, label, onChange, onEnter, onEscape, withLabel }: Props): React.ReactElement<Props> {
const { api, apiDefaultTxSudo } = useApi();
const [{ initialArgs, initialValue }] = useState(
() => extractInitial(api, apiDefaultTxSudo, defaultValue)
);
const _onChange = useCallback(
({ isValid, value }: RawParam): void => {
@ -32,7 +37,8 @@ function OpaqueCall ({ className = '', isDisabled, isError, label, onChange, onE
return (
<ExtrinsicDisplay
className={className}
defaultValue={apiDefaultTxSudo}
defaultArgs={initialArgs}
defaultValue={initialValue}
isDisabled={isDisabled}
isError={isError}
isPrivate

View File

@ -3,15 +3,20 @@
import type { Props, RawParam } from '@polkadot/react-params/types';
import React, { useCallback } from 'react';
import React, { useCallback, useState } from 'react';
import { useApi } from '@polkadot/react-hooks';
import { extractInitial } from './Call';
import ExtrinsicDisplay from './Extrinsic';
function ProposalDisplay ({ className = '', isDisabled, isError, label, onChange, onEnter, onEscape, withLabel }: Props): React.ReactElement<Props> {
function ProposalDisplay ({ className = '', defaultValue, isDisabled, isError, label, onChange, onEnter, onEscape, withLabel }: Props): React.ReactElement<Props> {
const { api, apiDefaultTxSudo } = useApi();
const [{ initialArgs, initialValue }] = useState(
() => extractInitial(api, apiDefaultTxSudo, defaultValue)
);
const _onChange = useCallback(
({ isValid, value }: RawParam): void => {
let proposal = null;
@ -31,7 +36,8 @@ function ProposalDisplay ({ className = '', isDisabled, isError, label, onChange
return (
<ExtrinsicDisplay
className={className}
defaultValue={apiDefaultTxSudo}
defaultArgs={initialArgs}
defaultValue={initialValue}
isDisabled={isDisabled}
isError={isError}
isPrivate