Skip to content

[Bug]: The UI wallet store discards permission results and never revalidates per-account state #228

Description

@re-gius

Component

Other

Priority

P1

What happened?

Three defects in packages/ui/src/store/useWalletStore.ts with one root cause: state is captured at connect and never revalidated, and grant results are discarded.

Grants are requested and ignored. ensureSignerReady:279 discards the ensureChainSubmit() boolean, and requestWritePermissions:87-94 swallows both a non-Allocated result and a throw. A signer is returned either way. The store's comment at :112-113 records the consequence: the host then rejects every write with PermissionDenied, "often as a silent hang".

The signer is a connect-time snapshot. injected (:179) is never replaced, and the subscription at :224-228 reacts only to status === "disconnected". The SDK's attemptReconnect builds a new provider and new accounts and returns to connected, which goes unnoticed, and ensureReady:252 refuses to refresh because injected is still non-null. Later writes sign with a dead signer.

Derived state is never refreshed. userPopState is written only at services/AppInitializer.ts:34-38, and components RegisterModal.vue:391-411 gates requirementMet on it, so after an account switch or reconnect a verified user's Register button is disabled with no explanation while the search panel still offers it. handleDisconnect:207-218 also leaves transactionStatus set, wedging the timeline mid-flight under a "Not signed in" header.

There is no recovery path: connectWallet() is reachable only from two docs demos, and components/WalletButton.vue:17-20 no action, so a page reload is the only way back.

Expected behavior

  • A denied or failed grant fails the write with a message naming the missing permission, instead of submitting and hanging.
  • The store keys on account and provider identity rather than connection status alone, and refreshes the signer and any per-account derived state when either changes.
  • Disconnect resets transaction state.
  • The header offers a way to reconnect without reloading.

Reproduction

  1. Decline the ChainSubmit prompt, then attempt any write. The timeline stays on "Signing" with no error; the rejection appears only in the console.
  2. With a session established, force a host reconnect, then attempt a write. It is signed with the pre-reconnect signer.
  3. Switch account in the host, then open the register modal for a name requiring PoP. Register is disabled even for a verified account.

Additional context

Related to #227: a failed personhood read also yields NoStatus through safeRead, so the disabled Register button has two possible causes. This issue covers the not-refetched half.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Secondary Prioritydotns-sdkRelated to the DotNS SDKtype: bugBug report

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions