Skip to content

Decide how close canton-connect's hook results sit to wagmi's #52

Description

@fernandomg

User story / Problem statement

canton-connect is described as wagmi-style, and at the level that matters most it is: the hook
names and the split of responsibility match, so a developer arriving from wagmi knows which hook to
reach for. Each hook's JSDoc now names its wagmi counterpart (usePartyuseAccount,
useExecuteuseWriteContract + useWaitForTransactionReceipt, and so on).

The resemblance stops at the return shapes. wagmi's mutation hooks are wrappers around TanStack
Query's useMutation, so they return mutate / mutateAsync / isPending / data / status /
failureCount / reset. Ours resolve plain promises and return domain-named fields:
isSigning, isExecuting, signature, lastTx. Someone with wagmi muscle memory reaches for
isPending and data and doesn't find them.

That is a real papercut, but the fix has two very different sizes, and conflating them is how this
turns into an accidental architecture change.

Proposed solution

Level 1 — align the vocabulary. No new dependency.

Rename the status flags to wagmi's uniform isPending (replacing isSigning and isExecuting),
and keep error and reset, which already match. This is a pure rename of the public surface,
free right now because the package has no consumers.

Deliberately not proposed: renaming the payloads to data. useSignMessage().signature is
clearer than data, and useExecute().lastTx is not wagmi's data at all — see below. Adopting
data everywhere buys canonicality at the cost of saying less. Worth arguing either way, which is
why it is an open question rather than an acceptance criterion.

Level 2 — actually adopt TanStack Query. New peer dependency, consumer-visible.

This is what would make the hooks genuinely wagmi-shaped: useMutation under the covers, so
mutate/mutateAsync/status/failureCount come for free, plus useQuery for reads. It also
requires every consumer to wrap the app in a QueryClientProvider and pulls the package's users
into a specific data-layer choice — a heavy import for a package whose stated value is being thin
and cheap to delete once the SDK ships hooks of its own.

Recommendation: do Level 1 if the papercut is worth a rename; hold Level 2 until the package
grows a read surface.
TanStack Query earns its keep on cached, refetchable, deduplicated
queries. Today this package has three write-shaped operations (sign, execute, ledger call) and two
context reads (party, status), and mutations don't cache. The moment useLedger becomes typed
cached reads — ACS queries, balances, listAccounts — the calculus flips and Level 2 becomes the
obvious answer rather than ceremony.

One Canton-specific reason not to force the fit. wagmi's mutations model one request producing
one result. useExecute().lastTx models a wallet-pushed lifecycle — pending → signed → executed
or failed — arriving as txChanged events after the call resolves. wagmi's nearest equivalent
splits that across useWriteContract (submit) and useWaitForTransactionReceipt (one receipt at
the end); it has no concept of a status stream from the wallet. Mapping lastTx onto data would
misrepresent it. Whatever shape this lands on, the tx lifecycle stays a first-class field of its
own.

Acceptance criteria

  • Every hook with a pending state reports isPending and error
  • disconnect has its own hook
  • The differences with wagmi are findable in one place
  • The TanStack Query decision is recorded, with the trigger for revisiting it
  • lastTx stays its own field

Out of scope

  • Adding @tanstack/react-query as a dependency in this issue. If Level 2 wins, it gets its own
    issue with the QueryClientProvider requirement spelled out for consumers.
  • Renaming the hooks themselves. The names already match wagmi and are not in question.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area: connectcanton-connect: hooks, adapters, session, SDK facadepriority: lowNice to have, can waitspikeTime-boxed investigation to reduce uncertainty

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions