Skip to content

Wallet Usage

This page covers the common operations you can perform with the Averer Wallet via the useAvererWallet hook. All examples assume the component is rendered inside an AvererSdkProvider.

Reading blockchain data (Public Client)

Use getPublicClient() to get a Viem Public Client for read-only operations such as querying ENS names, reading contract state, or fetching block data.

import { useAvererWallet } from '@averer/averer-websdk';

const EnsName = () => {
  const wallet = useAvererWallet();

  const [ens, setEns] = useState<string | null>(null);

  const fetchEnsName = async () => {
    if (wallet) {
      const publicClient = await wallet.getPublicClient();
      const name = await publicClient.getEnsName({
        address: wallet.address,
      });
      setEns(name);
    }
  };

  return (
    <div>
      <button onClick={fetchEnsName}>Get ENS Name</button>
      {ens && <p>ENS Name: {ens}</p>}
    </div>
  );
};

Sending transactions (Wallet Client)

Use getWalletClient() to get a Viem Wallet Client for signing and sending transactions. This is equivalent to a "Signer" in Ethers terminology.

const SendTransaction = () => {
  const wallet = useAvererWallet();

  const SendTransaction = async () => {
    if (!wallet) {
      console.error('No wallet connected');
      return;
    }

    try {
      const walletClient = await wallet.getWalletClient();

      await wallet.ensureMfaForSigning(); // Check if MFA required for Action
      const txHash = await walletClient.sendTransaction({
        to: '0xRecipientAddressHere',
        value: 1000000000000000000n,
      });
      console.log('Transaction sent with hash:', txHash);
    } catch (error) {
      console.error('Error sending transaction:', error);
    }
  };

  return (
    <div>
      <button onClick={SendTransaction}>Send Transaction</button>
    </div>
  );
};

Getting the wallet balance

const WalletBalance = () => {
  const avererWallet = useAvererWallet();

  const [balance, setBalance] = useState<string | undefined>(undefined);

  const fetchBalance = async () => {
    if (avererWallet) {
      const bal = await avererWallet.getBalance();
      setBalance(bal);
    }
  };

  return (
    <div>
      <button onClick={fetchBalance}>Get Wallet Balance</button>
      {balance && <p>Balance: {balance} ETH</p>}
    </div>
  );
};

Reading the ONCHAINID address

const IdentityRegistrySetup = () => {
  const avererWallet = useAvererWallet();

  if (!avererWallet) {
    return <p>No Averer wallet connected</p>;
  }

  if (!avererWallet.onChainIdentityAddress) {
    return <p>ONCHAINID is not available yet</p>;
  }

  return (
    <p>ONCHAINID contract: {avererWallet.onChainIdentityAddress}</p>
  );
};

The onChainIdentityAddress field is optional. It may be empty if the user's on-chain identity has not been created yet, the backend has not returned it yet, or the SDK is still syncing it into Dynamic metadata for the current user session. The SDK reads this value from Dynamic metadata using the connected wallet address as the mapping key.

Signing a message

const SignMessageButton = () => {
  const avererWallet = useAvererWallet();

  const handleSignMessage = async () => {
    if (!avererWallet) {
      console.error('No Averer wallet connected');
      return;
    }

    try {
      await avererWallet.ensureMfaForSigning(); // Check if MFA required for Action
      const message = 'Hello from Averer Wallet!';
      const signature = await avererWallet.signMessage(message);
      console.log('Message signed successfully:', signature);
    } catch (error) {
      console.error('Error signing message:', error);
    }
  };
  return <button onClick={handleSignMessage}>Sign Message</button>;
};

Account abstraction transaction receipts

Smart-wallet writes return a userOpHash immediately. Use the helpers below to check status and read receipt.receipt.transactionHash for block explorer links. No bundler URL is required in your dApp. Requires a ZeroDev smart wallet session.

Wait until confirmed

const wallet = useAvererWallet();

if (!wallet) {
  return null;
}

const userOpHash = '0x...' as `0x${string}`;

const receipt = await wallet.waitForUserOperationReceipt(userOpHash, {
  timeout: 120_000,
  pollingInterval: 3_000,
});

const bundleTxHash = receipt.receipt.transactionHash;

Poll manually

const wallet = useAvererWallet();

if (!wallet) {
  return null;
}

const receipt = await wallet.getUserOperationReceipt(userOpHash);

if (!receipt) {
  // still pending
} else {
  const bundleTxHash = receipt.receipt.transactionHash;
  const failed = !receipt.success;
}

Logging out

Call logout() to sign the user out of the Averer WebSDK. The SDK returns to the eligibility screen, and useAvererWallet() returns null until the user signs in again.

const LogoutButton = () => {
  const wallet = useAvererWallet();

  if (!wallet) {
    return null;
  }

  return <button onClick={() => wallet.logout()}>Log out</button>;
};