Commit 524ef776 authored by tom's avatar tom

Merge branch 'hotfix/contract-method-name-collision'

parents 97af5224 9faebc10
...@@ -15,7 +15,7 @@ import ContractImplementationAddress from './ContractImplementationAddress'; ...@@ -15,7 +15,7 @@ import ContractImplementationAddress from './ContractImplementationAddress';
import ContractMethodCallable from './ContractMethodCallable'; import ContractMethodCallable from './ContractMethodCallable';
import ContractWriteResult from './ContractWriteResult'; import ContractWriteResult from './ContractWriteResult';
import useContractAbi from './useContractAbi'; import useContractAbi from './useContractAbi';
import { getNativeCoinValue } from './utils'; import { getNativeCoinValue, prepareAbi } from './utils';
interface Props { interface Props {
addressHash?: string; addressHash?: string;
...@@ -71,9 +71,10 @@ const ContractWrite = ({ addressHash, isProxy, isCustomAbi }: Props) => { ...@@ -71,9 +71,10 @@ const ContractWrite = ({ addressHash, isProxy, isCustomAbi }: Props) => {
throw new Error('Method name is not defined'); throw new Error('Method name is not defined');
} }
const abi = prepareAbi(contractAbi, item);
const hash = await walletClient?.writeContract({ const hash = await walletClient?.writeContract({
args: _args, args: _args,
abi: contractAbi, abi,
functionName: methodName, functionName: methodName,
address: addressHash as `0x${ string }`, address: addressHash as `0x${ string }`,
value: value as undefined, value: value as undefined,
......
import { prepareAbi } from './utils';
describe('function prepareAbi()', () => {
const commonAbi = [
{
inputs: [
{ internalType: 'address', name: '_pool', type: 'address' },
{ internalType: 'address', name: '_token', type: 'address' },
{ internalType: 'uint256', name: '_denominator', type: 'uint256' },
],
stateMutability: 'nonpayable' as const,
type: 'constructor' as const,
},
{
anonymous: false,
inputs: [
{ indexed: false, internalType: 'uint256[]', name: 'indices', type: 'uint256[]' },
],
name: 'CompleteDirectDepositBatch',
type: 'event' as const,
},
{
inputs: [
{ internalType: 'address', name: '_fallbackUser', type: 'address' },
{ internalType: 'string', name: '_zkAddress', type: 'string' },
],
name: 'directNativeDeposit',
outputs: [
{ internalType: 'uint256', name: '', type: 'uint256' },
],
stateMutability: 'payable' as const,
type: 'function' as const,
},
];
const method = {
inputs: [
{ internalType: 'address' as const, name: '_fallbackUser', type: 'address' as const },
{ internalType: 'string' as const, name: '_zkAddress', type: 'string' as const },
],
name: 'directNativeDeposit',
outputs: [
{ internalType: 'uint256' as const, name: '', type: 'uint256' as const },
],
stateMutability: 'payable' as const,
type: 'function' as const,
constant: false,
payable: true,
};
it('if there is only one method with provided name, does nothing', () => {
const abi = prepareAbi(commonAbi, method);
expect(abi).toHaveLength(commonAbi.length);
});
it('if there are two or more methods with the same name, filters out those which inputs are not matched', () => {
const abi = prepareAbi([
...commonAbi,
{
inputs: [
{ internalType: 'address', name: '_fallbackUser', type: 'address' },
{ internalType: 'bytes', name: '_rawZkAddress', type: 'bytes' },
],
name: 'directNativeDeposit',
outputs: [
{ internalType: 'uint256', name: '', type: 'uint256' },
],
stateMutability: 'payable',
type: 'function',
},
], method);
expect(abi).toHaveLength(commonAbi.length);
const item = abi.find((item) => 'name' in item ? item.name === method.name : false);
expect(item).toEqual(commonAbi[2]);
});
});
import type { Abi } from 'abitype';
import type { SmartContractWriteMethod } from 'types/api/contract';
export const getNativeCoinValue = (value: string | Array<unknown>) => { export const getNativeCoinValue = (value: string | Array<unknown>) => {
const _value = Array.isArray(value) ? value[0] : value; const _value = Array.isArray(value) ? value[0] : value;
...@@ -42,3 +46,28 @@ export function isExtendedError(error: unknown): error is ExtendedError { ...@@ -42,3 +46,28 @@ export function isExtendedError(error: unknown): error is ExtendedError {
typeof (error as Record<string, unknown>).message === 'string' typeof (error as Record<string, unknown>).message === 'string'
); );
} }
export function prepareAbi(abi: Abi, item: SmartContractWriteMethod): Abi {
if ('name' in item) {
const hasMethodsWithSameName = abi.filter((abiItem) => 'name' in abiItem ? abiItem.name === item.name : false).length > 1;
if (hasMethodsWithSameName) {
return abi.filter((abiItem) => {
if (!('name' in abiItem)) {
return true;
}
if (abiItem.name !== item.name) {
return true;
}
return abiItem.inputs.every(({ name, type }) => {
const itemInput = item.inputs.find((input) => input.name === name);
return Boolean(itemInput) && itemInput?.type === type;
});
});
}
}
return abi;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment