wagmi for Canton developers
If you have built an EVM frontend, you already know most of the shape of a Canton one. This page maps what you know onto what PartyLayer gives you, and then spends most of its length on the places where the analogy stops working, because those are the ones that cost time.
3.7.7, verified 2026-09-03. The version is pinned here because it is the claim on this page most likely to go stale without anything telling us: wagmi renames hooks across majors. Both matter, because wagmi renamed several hooks in v3 and a mapping written from memory would be wrong on the most familiar one: useAccount no longer exists in wagmi. It is useConnection now.The first thing that will confuse you
PartyLayer has a hook called useAccount. wagmi does not, any more. If you arrive from wagmi v3 expecting useConnection and reach for the name you used in v2, you will find it here and it will work, which is more disorienting than if it were missing. Ours reports the connected party, not an EVM address.
What maps cleanly
Connection and signing are close enough that porting is mechanical.
| wagmi 3.7.7 | PartyLayer | Notes |
|---|---|---|
| WagmiProvider + createConfig | PartyLayerKit | One provider at the root. Adapters replace connectors. |
| useConnection | useAccount | Reports the connected party id, not an address. |
| useConnect | useConnect | Same shape. Takes a wallet id rather than a connector. |
| useDisconnect | useDisconnect | Same. |
| useConnectors | useWallets | Registry-backed rather than statically configured. |
| useSignMessage | useSignMessage | Same intent. Check the base64 note below. |
| useSendTransaction | useSubmitTransaction | Submits Daml commands, not calldata. |
| useWaitForTransactionReceipt | submit result | Awaited in the submit call, not a separate hook. |
| ConnectButton (RainbowKit) | ConnectButton | Drop-in, themeable. See Theming. |
Side by side, the connect flow you already know:
Where the analogy breaks
These are not gaps waiting to be filled. They follow from Canton being privacy-first and contract-based rather than account-and-storage based, so a hook that papers over them would be lying.
1. There is no useReadContract, because there is no public state
This is the big one. On an EVM chain any client can read any storage slot, which is what makes useReadContract possible without a wallet. On Canton you can only read contracts you are a witness to, and what you are a witness to depends on which party you are. There is no global state to query.
So reads are party-scoped and require a connection. useTokenHoldings, useDamlContract and useLedgerApi all read as the connected party, and a different party running the same code legitimately sees different results. Privacy and reads covers how visibility actually works.
Practical consequence: a landing page that shows chain data before the user connects has no Canton equivalent. Design for connect-first.
2. No ABI. Templates and choices instead
There is no ABI to import and no function selector. A Daml contract is a template instance, and you act on it by exercising a named choice. useChoice is the closest thing to useWriteContract, and the shape it takes is a command, not an encoded call.
3. Contracts are archived and recreated, not mutated
Exercising a choice typically archives the current contract and creates a successor. There is no in-place update, so a contract id is not a stable handle across a state change the way an EVM address is. Code that caches a contract id and reuses it after a write will be holding a reference to an archived contract.
4. useSwitchChain has no working equivalent
Not a design position on our side, a fact about the ecosystem today: every wallet in the registry declares switchNetwork: false, all ten of them. You can see it in the capability matrix on the Canton wallet directory, which is generated from the registry, so if that changes the page changes.
Configure the network on PartyLayerKit and treat it as fixed for the session. A multi-network app mounts per network rather than switching in place.
5. Gas is traffic, and it is priced differently
There is no gas price to estimate and no priority fee to bid. Canton charges for traffic, and the cost of a submission can be read before you submit it rather than estimated. See Performance for the measured side, and the cost hooks for pre-submission estimates. Nothing here corresponds to useEstimateFeesPerGas.
6. A party id is not an address
An EVM address is derived from a keypair, so anyone can compute one offline and it is self-certifying. A Canton party id is allocated on a participant node and carries a namespace. You cannot derive it from a public key alone, and two parties can be backed by the same key material. Treat it as an identifier issued to the user, not as a hash of their key.
7. Some transactions need more than one signature
A Daml choice can require several signatories, which has no EVM single-signer equivalent and is not a multisig contract pattern either: it is in the model. If your app coordinates two parties, read Multi-party patterns before designing the flow, because retrofitting it is expensive.
signMessageBase64: true. If you verify a signature against raw bytes the way you would with personal_sign, it will not match. Per-wallet notes are on the wallet directory.If you are porting an app
- Start from Quick Start. The connect layer is the part that ports mechanically, so get it working first and it will feel familiar.
- Then find every read in your app that runs before connect. Those are the ones that need rethinking, and there are usually more than you expect.
- Replace ABI-and-selector thinking with template-and-choice thinking before you write the write path. Token transfers is a worked example.
- Check the wallet directory for what your target wallets actually support through their adapters. Capability flags there map to specific hooks, and several wallets do not implement signing at all.