@layerhop/wagmi

Execute LayerHop quotes with the user's wallet through wagmi or a
viem WalletClient. It handles the ERC-20 approval (checking the allowance first), the swap,
and any extraTxs, then reports the hash to LayerHop.
When the wallet supports EIP-5792 atomic batching (wallet_getCapabilities), the approval, swap and fee transfer go
in one wallet_sendCalls confirmation. Other wallets get sequential transactions.
Never holds keys. Every transaction is confirmed by the user in their wallet.
Install
npm install @layerhop/wagmi @layerhop/sdk wagmi viem @tanstack/react-query
React
import { LayerHopProvider, useExecuteQuote, useLayerHopQuote, useOrderStatus } from "@layerhop/wagmi";
import { useAccount } from "wagmi";
function Swap() {
const { address } = useAccount();
const quote = useLayerHopQuote(address && {
srcChain: "base", srcToken: "USDC", amount: "25000000",
dstChain: "solana", dstToken: "SOL", sender: address, recipient: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
});
const exec = useExecuteQuote();
const best = quote.data?.best;
const order = useOrderStatus(best?.provider, exec.hash);
return <button disabled={!best || exec.isPending} onClick={() => best && exec.execute({ quote: best })}>{exec.status}</button>;
}
useExecuteQuote() → { execute, reset, status, hash, mode, approval, result, error, isPending }.
status: idle → building → (switching) → (approving) → signing → reporting → submitted | error.
mode: batch (one EIP-5792 confirmation), sequential or sandbox (test-mode placeholder, nothing sent).
useLayerHopQuote is useQuote from @layerhop/react.
Actions (no React): @layerhop/wagmi/actions
import { executeQuote, executeQuoteWithWalletClient } from "@layerhop/wagmi/actions";
import { LayerHop } from "@layerhop/sdk";
const lh = new LayerHop({ apiKey: process.env.LAYERHOP_API_KEY });
const { best } = await lh.quote(params);
const sent = await executeQuote(wagmiConfig, { quote: best, client: lh });
sent.hash;
sent.mode;
await sent.wait();
Options: batch ("auto" default, "never", "require"), tx (an already built tx), report (default true),
onStep, onApproval({ batched }), onBatchFallback, onExtraTxError.
How batching works
- The wallet switches to the transaction's chain if needed.
- The allowance is read. An exact-amount
approve is added only when the allowance is short.
- If there is more than one call and
wallet_getCapabilities reports atomic.status supported/ready (or the older
atomicBatch.supported), all calls go in one wallet_sendCalls with atomicRequired: true. The hash comes from
wallet_getCallsStatus once the batch lands.
- Otherwise, or when the wallet rejects the batch as unsupported (4200, 5700, 5710, 5740, 5750, 5760, -32601), the calls
go sequentially: approve (and wait), main call, then each extra call. A failed extra call never fails the send.
A user rejection (4001) is never retried.
Lower-level building blocks: sendEvmTx(driver, tx), wagmiDriver(config), walletClientDriver(walletClient),
evmCalls, supportsAtomicBatch, getAtomicBatchSupport(config, chainId).
Guide with Privy, Dynamic, thirdweb, Coinbase Smart Wallet and Reown snippets: https://docs.layerhop.com/guides/wallets.
Example: example/Swap.tsx.
License
MIT