Usage
const {
callAnyContract,
callAnyContractAsync,
data,
isLoading,
isError,
error,
isSuccess,
reset
} = useCallAnyContract();
Parameters
The hook accepts an object with:
params (CallAnyContractParams):
encryptKey (string): User’s decryption PIN
wallet (WalletData): Wallet credentials
contractAddress (string): Target contract address
calls (Call[]): Array of contract calls with contractAddress, entrypoint, and calldata
bearerToken (string): Bearer token for authentication
Return Value
Returns an object containing:
callAnyContract: Function to trigger contract call (fire-and-forget)
callAnyContractAsync: Promise-based function that resolves with the transaction hash
data: Transaction hash of the call (string | undefined)
isLoading: Boolean indicating if the operation is in progress
isError: Boolean indicating if an error occurred
error: Error instance when isError is true, otherwise null
isSuccess: Boolean indicating if the call completed successfully
reset: Function to reset the mutation state
Example Implementation
export function GenericContractForm() {
const { callAnyContractAsync, data, isLoading, isError, error } = useCallAnyContract();
const [form, setForm] = useState({
pin: '',
contractAddress: '',
entrypoint: '',
calldata: ''
});
const handleCall = async (e: React.FormEvent) => {
e.preventDefault();
const bearerToken = await getBearerToken();
try {
await callAnyContractAsync({
params: {
encryptKey: form.pin,
wallet: walletData,
contractAddress: form.contractAddress,
calls: [
{
contractAddress: form.contractAddress,
entrypoint: form.entrypoint,
calldata: JSON.parse(form.calldata || '[]')
}
],
},
bearerToken,
});
} catch (err) {
console.error('Contract call failed:', err);
}
};
return (
<div className="bg-white rounded-xl shadow-lg p-6">
<h2 className="text-2xl font-bold mb-4">Contract Interaction</h2>
<form onSubmit={handleCall} className="space-y-4">
<div>
<label className="block text-sm font-medium mb-1">Security PIN</label>
<input
type="password"
value={form.pin}
onChange={(e) => setForm({...form, pin: e.target.value})}
className="w-full p-2 border rounded-md"
required
/>
</div>
<div>
<label className="block text-sm font-medium mb-1">Contract Address</label>
<input
type="text"
value={form.contractAddress}
onChange={(e) => setForm({...form, contractAddress: e.target.value})}
className="w-full p-2 border rounded-md"
required
/>
</div>
<div>
<label className="block text-sm font-medium mb-1">Method Name</label>
<input
type="text"
value={form.entrypoint}
onChange={(e) => setForm({...form, entrypoint: e.target.value})}
className="w-full p-2 border rounded-md"
required
/>
</div>
<div>
<label className="block text-sm font-medium mb-1">Call Data (JSON array)</label>
<input
type="text"
value={form.calldata}
onChange={(e) => setForm({...form, calldata: e.target.value})}
className="w-full p-2 border rounded-md"
placeholder='Example: [123, "0xabc...", true]'
/>
</div>
<button
type="submit"
disabled={isLoading}
className="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 disabled:bg-gray-400"
>
{isLoading ? 'Processing...' : 'Execute'}
</button>
</form>
{data && (
<div className="mt-4 p-3 bg-gray-50 rounded-md">
<p className="text-sm font-mono break-all">
TX Hash: {data}
</p>
</div>
)}
{isError && error && (
<div className="mt-4 p-3 bg-red-50 text-red-700 rounded-md">
Error: {error.message}
</div>
)}
</div>
);
}
Security Considerations
- Verify contract addresses
- Validate calldata format
- Use encrypted private keys
- Implement proper PIN validation
- Review contract ABI before calling
Error Handling
- Handle invalid contract addresses
- Validate calldata format
- Monitor gas fees
- Implement retry logic for failed calls
Use with caution. Direct contract calls require deep understanding of the target contract’s ABI and security implications.