Skip to content

Web: Refund panel does not notice a wallet connected after the modal is opened #189

Description

@mallison031

Repo context. accensa-app is the off-chain half of Accensa — the merchant back-office for x402 sellers on Stellar. Three workspace packages matter: apps/web (Next.js dashboard and the indexer at src/app/api/sync), packages/sdk (@accensa/sdk), and apps/demo-merchant. The Soroban contracts live in accensa-contracts.

🟢 Unblocked. Small, self-contained fix in one component.

Problem

components/refund-panel.tsx reads wallet status exactly once, in an effect with an empty dependency array:

useEffect(() => {
  let live = true;
  void readStatus().then((status) => {
    if (live) setMerchant(status.kind === 'connected' ? status.address : null);
  });
  return () => { live = false; };
}, []);

If no wallet is connected at that moment, merchant stays null and the panel renders "Connect a Stellar wallet to issue refunds" permanently. A merchant who reads that message, connects Freighter, and comes back finds the same message — the panel never re-checks.

The only way out is to close the modal and reopen it, which is not signposted anywhere. The message tells the user exactly what to do and then ignores them doing it.

What to build

Re-read wallet status when it can have changed.

  1. Re-check on a trigger the user controls at minimum — a "Check again" affordance next to the connect prompt is the smallest honest fix.
  2. Prefer reacting to the wallet itself if practical. Look at what lib/freighter.ts exposes; if connection state can be observed rather than polled, that is the better answer. Do not add a polling loop against the extension without saying why in the PR.
  3. Keep the existing live guard. The unmount-safety pattern is correct and should survive the change.

Out of scope: initiating the wallet connection from inside the refund panel. Connecting is the login flow's job.

Acceptance criteria

  • A merchant who connects a wallet while the payment modal is open can reach the refund flow without reopening it.
  • No state is written after unmount.
  • The connect prompt tells the user what to do after connecting.
  • pnpm lint passes in apps/web.
  • pnpm test passes, including new tests covering this change.
  • pnpm build succeeds for apps/web.
  • PR description includes Closes #<this issue>.

Contact & Support

Metadata

Metadata

Assignees

Labels

Stellar WaveDrips Wave Programarea: webWork in webbugSomething isn't workingcomplexity: trivial100 pts — small, clearly bounded, obvious acceptance criteria

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions