mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
* display methods accordion * add method_id to methods * query read method via public client * query read methods without inputs at accordion section open * add custom abi tabs * add proxy tabs * custom wagmi config if wc is not configured * remove ContractAbiItemConstant component * display tuple properties in method outputs * display read result * clean up * support nested arrays in the read result * re-write test for contract methods * change result view for address output * refactoring * fix tests * remove web3 provider fallback * fix tab loading * refactoring * add implementation contract selector * add "copy to clipboard" for address, remove top-level square brackets * add preview mode to contract method result * tests for read result * fix tests * change styles for result preview * review fix
74 lines
2.4 KiB
TypeScript
74 lines
2.4 KiB
TypeScript
import React from 'react';
|
|
import { getAddress, type Abi } from 'viem';
|
|
import { useAccount, useWalletClient, useSwitchChain } from 'wagmi';
|
|
|
|
import type { FormSubmitResult, SmartContractMethod } from './types';
|
|
|
|
import config from 'configs/app';
|
|
|
|
import { getNativeCoinValue } from './utils';
|
|
|
|
interface Params {
|
|
item: SmartContractMethod;
|
|
args: Array<unknown>;
|
|
addressHash: string;
|
|
}
|
|
|
|
export default function useCallMethodWalletClient(): (params: Params) => Promise<FormSubmitResult> {
|
|
const { data: walletClient } = useWalletClient();
|
|
const { isConnected, chainId, address: account } = useAccount();
|
|
const { switchChainAsync } = useSwitchChain();
|
|
|
|
return React.useCallback(async({ args, item, addressHash }) => {
|
|
if (!isConnected) {
|
|
throw new Error('Wallet is not connected');
|
|
}
|
|
|
|
if (!walletClient) {
|
|
throw new Error('Wallet Client is not defined');
|
|
}
|
|
|
|
if (chainId && String(chainId) !== config.chain.id) {
|
|
await switchChainAsync?.({ chainId: Number(config.chain.id) });
|
|
}
|
|
|
|
const address = getAddress(addressHash);
|
|
|
|
if (item.type === 'receive' || item.type === 'fallback') {
|
|
const value = getNativeCoinValue(args[0]);
|
|
const hash = await walletClient.sendTransaction({
|
|
to: address,
|
|
value,
|
|
});
|
|
return { source: 'wallet_client', data: { hash } };
|
|
}
|
|
|
|
const methodName = item.name;
|
|
|
|
if (!methodName) {
|
|
throw new Error('Method name is not defined');
|
|
}
|
|
|
|
const _args = args.slice(0, item.inputs.length);
|
|
const value = getNativeCoinValue(args[item.inputs.length]);
|
|
|
|
const hash = await walletClient.writeContract({
|
|
args: _args,
|
|
// Here we provide the ABI as an array containing only one item from the submitted form.
|
|
// This is a workaround for the issue with the "viem" library.
|
|
// It lacks a "method_id" field to uniquely identify the correct method and instead attempts to find a method based on its name.
|
|
// But the name is not unique in the contract ABI and this behavior in the "viem" could result in calling the wrong method.
|
|
// See related issues:
|
|
// - https://github.com/blockscout/frontend/issues/1032,
|
|
// - https://github.com/blockscout/frontend/issues/1327
|
|
abi: [ item ] as Abi,
|
|
functionName: methodName,
|
|
address,
|
|
value,
|
|
account,
|
|
});
|
|
|
|
return { source: 'wallet_client', data: { hash } };
|
|
}, [ chainId, isConnected, switchChainAsync, walletClient, account ]);
|
|
}
|