Add ClientWithSubscribeToPayer/Identity interfaces#1551
Conversation
🦋 Changeset detectedLatest commit: 66f08b9 The changes in this PR will be included in the next version bump. This PR includes changesets to release 46 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
BundleMonUnchanged files (144)
No change in files bundle size Final result: ✅ View report in BundleMon website ➡️ |
trevor-cortex
left a comment
There was a problem hiding this comment.
Summary
Adds two new type-only exports to @solana/plugin-interfaces: ClientWithSubscribeToPayer and ClientWithSubscribeToIdentity, each advertising a sibling subscribeTo<Capability>(listener): () => void function on the client. The goal is to let reactive consumers (UI hooks, stores) observe changes to client.payer / client.identity without naming the specific plugin that made them reactive.
The PR is type-only — no runtime code, no behavior change for existing consumers. Comes with a changeset (minor on both plugin-interfaces and kit), README entry with a clear table, and compile-time type tests covering both interfaces and their composability.
Design notes
The convention is sound and fits the package's existing style. A few things worth calling out for subsequent reviewers / implementers:
- Listener takes no arguments and consumers must re-read
client.payer/client.identityafter a notification. This is deliberate and matches the snapshot-based model used by React'suseSyncExternalStore— the docblock explains it and notes that over-notification is acceptable. Good choice; a value-passing listener would make it too easy to leak stale references. - Idempotent unsubscribe is a documented contract (
"must be idempotent") but not enforced by the type system. Worth verifying this actually holds in the wallet-plugin implementation (kit-plugins#200) — calling unsubscribe twice should not throw or double-remove. - Duck-typing via intersection (
ClientWithPayer & ClientWithSubscribeToPayer) is the intended usage pattern shown in the README and@example. Plugins that don't make the capability reactive simply don't install the hook, and downstream libraries that want to stay agnostic can fall back to a no-op subscribe as the docblock suggests. readonlymodifier: the new types usereadonly subscribeToPayer: ...while existing sibling interfaces (ClientWithPayer,ClientWithIdentity) use plain{ payer: TransactionSigner }. Not worth changing —readonlyis semantically correct here (consumers shouldn't reassign the subscribe fn), just noting the minor stylistic divergence.
Things to watch out for
- The type name
SubscribeToCapabilityreads ambiguously — it's the signature of a subscribe function, not "subscribe to a capability." Minor bikeshed, happy to leave as-is given the docblock clarifies it, but a name likeSubscribeToFnwould be slightly more self-describing. Not blocking. - Since this lands in
plugin-interfaces, any future plugin that wants to participate in the convention needs to use exactly these names (subscribeToPayer,subscribeToIdentity) — the whole point is duck-typing. Worth keeping that in mind if a third pattern emerges later (e.g.subscribeToRpc); the convention should probably be documented somewhere more permanent than just this module's top-of-file comment once there are 3+ instances.
Looks good to me — no blocking concerns.
a7a7aa6 to
8b00943
Compare
|
Documentation Preview: https://kit-docs-h05kcvstw-anza-tech.vercel.app |
|
Renamed |
8b00943 to
66f08b9
Compare
|
🔎💬 Inkeep AI search and chat service is syncing content for source 'Solana Kit Docs' |
|
Because there has been no activity on this PR for 14 days since it was merged, it has been automatically locked. Please open a new issue if it requires a follow up. |
This PR adds new types
ClientWithSubscribeToPayerandClientWithSubscribeToIdentityinplugin-interfaces. These allow a plugin (such as the wallet plugin) to notify subscribers when they modify these fields, without those consumers needing to know which plugin has made them reactive.It's already the case that
client.payercan be made dynamic by the wallet plugin, by using a get() function. This retains compatibility with thepayer: TransactionSignertype. But in order to make this useful for a reactive UI that may for example render based on the current value ofclient.payer, we also need to be able to subscribe to changes.Reactive consumers can then use
client.subscribeToPayer(() => {})to receive these notifications.Alternatives considered:
Extracted from anza-xyz/kit-plugins#200, which originally added these types to kit-plugin-signer.