diff --git a/packages/apps-routing/src/contracts.ts b/packages/apps-routing/src/contracts.ts index 6055d46b09..06b4d99615 100644 --- a/packages/apps-routing/src/contracts.ts +++ b/packages/apps-routing/src/contracts.ts @@ -2,9 +2,22 @@ // SPDX-License-Identifier: Apache-2.0 import type { TFunction } from 'i18next'; +import type { ApiPromise } from '@polkadot/api'; import type { Route } from './types'; import Component from '@polkadot/app-contracts'; +import { assertReturn } from '@polkadot/util'; + +function needsApiCheck (api: ApiPromise): boolean { + try { + // needs storageDepositLimit + return assertReturn(api.tx.contracts.instantiateWithCode.meta.args.length === 6, 'Invalid args'); + } catch (error) { + console.warn('Contract interface does not support storageDepositLimit, disabling route'); + + return false; + } +} export default function create (t: TFunction): Route { return { @@ -13,7 +26,8 @@ export default function create (t: TFunction): Route { needsAccounts: true, needsApi: [ 'tx.contracts.instantiateWithCode' - ] + ], + needsApiCheck }, group: 'developer', icon: 'compress', diff --git a/packages/page-contracts/src/Codes/Upload.tsx b/packages/page-contracts/src/Codes/Upload.tsx index ac679477b7..5cf3317dc3 100644 --- a/packages/page-contracts/src/Codes/Upload.tsx +++ b/packages/page-contracts/src/Codes/Upload.tsx @@ -37,8 +37,6 @@ function Upload ({ onClose }: Props): React.ReactElement { const { abiName, contractAbi, errorText, isAbiError, isAbiSupplied, isAbiValid, onChangeAbi, onRemoveAbi } = useAbi(); const weight = useWeight(); - const hasStorageDeposit = api.tx.contracts.instantiate.meta.args.length === 6; - const code = useMemo( () => isAbiValid && isWasmValid && wasm && contractAbi ? new CodePromise(api, contractAbi, wasm) @@ -204,7 +202,7 @@ function Upload ({ onClose }: Props): React.ReactElement { ('The balance to transfer from the `origin` to the newly created contract.')} isError={!isValueValid} - isZeroable={hasStorageDeposit} + isZeroable label={t('value')} onChange={setValue} value={value} diff --git a/packages/page-contracts/src/Contracts/Call.tsx b/packages/page-contracts/src/Contracts/Call.tsx index 64e464f6d3..df84a88569 100644 --- a/packages/page-contracts/src/Contracts/Call.tsx +++ b/packages/page-contracts/src/Contracts/Call.tsx @@ -10,7 +10,7 @@ import React, { useCallback, useEffect, useState } from 'react'; import styled from 'styled-components'; import { Button, Dropdown, Expander, InputAddress, InputBalance, Modal, Toggle, TxButton } from '@polkadot/react-components'; -import { useAccountId, useApi, useDebounce, useFormField, useToggle } from '@polkadot/react-hooks'; +import { useAccountId, useDebounce, useFormField, useToggle } from '@polkadot/react-hooks'; import { Available } from '@polkadot/react-query'; import { BN, BN_ONE, BN_ZERO } from '@polkadot/util'; @@ -33,7 +33,6 @@ const MAX_CALL_WEIGHT = new BN(5_000_000_000_000).isub(BN_ONE); function Call ({ className = '', contract, messageIndex, onCallResult, onChangeMessage, onClose }: Props): React.ReactElement | null { const { t } = useTranslation(); - const { api } = useApi(); const message = contract.abi.messages[messageIndex]; const [accountId, setAccountId] = useAccountId(); const [estimatedWeight, setEstimatedWeight] = useState(null); @@ -45,7 +44,6 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM const weight = useWeight(); const dbValue = useDebounce(value); const dbParams = useDebounce(params); - const hasStorageDeposit = api.tx.contracts.call.meta.args.length === 5; useEffect((): void => { setEstimatedWeight(null); @@ -55,32 +53,27 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM useEffect((): void => { value && message.isMutating && setExecTx((): SubmittableExtrinsic<'promise'> | null => { try { - return hasStorageDeposit - ? contract.tx[message.method]({ gasLimit: weight.weight, storageDepositLimit: null, value: message.isPayable ? value : 0 }, ...params) - : contract.tx[message.method]({ gasLimit: weight.weight, value: message.isPayable ? value : 0 }, ...params); + return contract.tx[message.method]({ gasLimit: weight.weight, storageDepositLimit: null, value: message.isPayable ? value : 0 }, ...params); } catch (error) { return null; } }); - }, [accountId, contract, message, value, weight, params, hasStorageDeposit]); + }, [accountId, contract, message, value, weight, params]); useEffect((): void => { if (!accountId || !message || !dbParams || !dbValue) { return; } - const query = hasStorageDeposit - ? contract.query[message.method](accountId, { gasLimit: -1, storageDepositLimit: null, value: message.isPayable ? dbValue : 0 }, ...dbParams) - : contract.query[message.method](accountId, { gasLimit: -1, value: message.isPayable ? dbValue : 0 }, ...dbParams); - - query + contract + .query[message.method](accountId, { gasLimit: -1, storageDepositLimit: null, value: message.isPayable ? dbValue : 0 }, ...dbParams) .then(({ gasRequired, result }) => setEstimatedWeight( result.isOk ? gasRequired : null )) .catch(() => setEstimatedWeight(null)); - }, [accountId, contract, message, dbParams, dbValue, hasStorageDeposit]); + }, [accountId, contract, message, dbParams, dbValue]); const _onSubmitRpc = useCallback( (): void => { @@ -88,26 +81,24 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM return; } - const query = hasStorageDeposit - ? contract.query[message.method](accountId, { gasLimit: weight.isEmpty ? -1 : weight.weight, storageDepositLimit: null, value: message.isPayable ? value : 0 }, ...params) - : contract.query[message.method](accountId, { gasLimit: weight.isEmpty ? -1 : weight.weight, value: message.isPayable ? value : 0 }, ...params); - - query.then((result): void => { - setOutcomes([{ - ...result, - from: accountId, - message, - params, - when: new Date() - }, ...outcomes]); - onCallResult && onCallResult(messageIndex, result); - }) + contract + .query[message.method](accountId, { gasLimit: weight.isEmpty ? -1 : weight.weight, storageDepositLimit: null, value: message.isPayable ? value : 0 }, ...params) + .then((result): void => { + setOutcomes([{ + ...result, + from: accountId, + message, + params, + when: new Date() + }, ...outcomes]); + onCallResult && onCallResult(messageIndex, result); + }) .catch((error): void => { console.error(error); onCallResult && onCallResult(messageIndex); }); }, - [accountId, contract.query, hasStorageDeposit, message, messageIndex, onCallResult, outcomes, params, value, weight] + [accountId, contract.query, message, messageIndex, onCallResult, outcomes, params, value, weight] ); const _onClearOutcome = useCallback( diff --git a/packages/page-contracts/src/Contracts/Deploy.tsx b/packages/page-contracts/src/Contracts/Deploy.tsx index 21b5548b1d..6b2ce3ed79 100644 --- a/packages/page-contracts/src/Contracts/Deploy.tsx +++ b/packages/page-contracts/src/Contracts/Deploy.tsx @@ -38,8 +38,6 @@ function Deploy ({ codeHash, constructorIndex = 0, onClose, setConstructorIndex const [withSalt, setWithSalt] = useState(false); const weight = useWeight(); - const hasStorageDeposit = api.tx.contracts.instantiate.meta.args.length === 6; - useEffect((): void => { setParams([]); }, [constructorIndex]); @@ -176,7 +174,7 @@ function Deploy ({ codeHash, constructorIndex = 0, onClose, setConstructorIndex ('The balance to transfer from the `origin` to the newly created contract.')} isError={!isValueValid} - isZeroable={hasStorageDeposit} + isZeroable label={t('value')} onChange={setValue} value={value}