WalletConnect, Ledger, and every constructed provider: now trackable
Wallet discovery covers EIP-6963 announcements and window.ethereum, which is every injected wallet and nothing else. A WalletConnect or Ledger provider is constructed by the app and announces nothing; on the EIP-1193 path its whole session was invisible. registerProvider is the handoff:
const provider = await EthereumProvider.init({ projectId, chains });
formo.registerProvider(provider);Call it whenever the provider exists: a session that already predates the SDK is adopted on the spot from synchronous state (session.namespaces included, chain-aware), with no RPC ever issued on the wallet transport. Returns true only when capture verifiably works. Wagmi apps do not need this: their WalletConnect sessions are already tracked, and the call refuses there to prevent double-reporting.
Events name the wallet, not the transport
WalletConnect is a transport; the signing wallet (Ledger Live, MetaMask Mobile, Safe) names itself in the session's peer metadata. Events now carry that name, resolved live per event so a session swap renames correctly.
Wallet attribution on signature and transaction events
provider_name (and rdns on the EIP-1193 path) now rides on every signature, transaction, and batch-call event on both capture paths. Per-wallet activity - "how many transactions came through Ledger" - becomes answerable in analytics for the first time.
Opt-in capture for imperative viem calls in Wagmi mode
Wagmi-mode autocapture sees wagmi hooks; imperative viem calls (walletClient.sendTransaction, .signMessage, .writeContract) create no mutation and were not captured. Opt in with wagmi: { eip1193Fallback: true } and the SDK instruments the active connector's provider with the same request wrapper the default mode uses. Hook-driven calls are never double-counted: the wrapper stands down whenever a pending wagmi mutation already covers the request, deterministically. Off by default, so Wagmi mode never touches the signing transport without an explicit configuration decision.
Fixes
- WalletConnect user rejections were silently uncounted: wallets over WalletConnect reject with sdkError codes 5000-5005, not EIP-1193's 4001, and only 4001 was matched. Both paths now recognize the full family plus viem's typed
UserRejectedRequestError, walking the error's cause chain. - An SDK rebuild no longer loses request-derived events: the request wrapper survives rebuilds and used to keep reporting to the torn-down instance's closed queue; it now routes each call to the newest live instance. This affected every provider under HMR or remounts, not only registered ones.
Everything above was verified live with a real MetaMask Mobile wallet over WalletConnect, in the reference example and in a production dapp's UI.
What's Changed
- feat: registerProvider for constructed wallets, WalletConnect peer naming by @yosriady in #364
- feat: wallet attribution on signature and transaction events by @yosriady in #368
- feat: opt-in hybrid capture for imperative viem calls in wagmi mode by @yosriady in #367
- chore(release): 1.38.0 by @yosriady in #369
Full Changelog: v1.37.0...v1.38.0
CDN
<script src="https://cdn.formo.so/analytics@1.38.0" integrity="sha384-yZ5P9y6V+cwCivcy4BXusB2bra261inTOUsMVaQ6jRCQ2Nm5dhvXYg2+6PqdVi5M" crossorigin="anonymous"></script>