Skip to content

[Feature] AI Credits widget: Disconnect button (standalone only) #158

Description

@goodbounties-nanoclaw-agent

Feature summary

Add a Disconnect button to the AI Credits widget (packages/ai-credits-widget) so standalone users can disconnect or switch their Reown/AppKit wallet. When the widget is embedded inside GoodWallet, GoodWallet manages the wallet/session itself, so the button must not be shown in that context — following the same integrator-controlled pattern already used by packages/superfluid-campaign-widget.

Problem or opportunity

AiCreditsWidget.tsx currently only has a "Connect Wallet" flow (DisconnectedPanel) — there is no way to disconnect or switch wallets once connected. superfluid-campaign-widget already solves the "integrator controls disconnect" problem via an optional disconnectOverride prop (widgetRuntimeContract.ts) plus its WalletChip component, but in that widget the Disconnect action is always visible and only message-gated (it shows "Disconnect should be done in your wallet's session" when no override is passed, rather than hiding the button). For AI Credits, the button itself must be hidden when embedded, not just non-functional.

Proposed solution

  1. Add disconnectOverride?: () => Promise<void> to AiCreditsWidgetProps/widgetRuntimeContract.ts — same naming/shape as superfluid-campaign-widget's, matching the connectOverride prop that already exists in this package.
  2. Reuse/port superfluid-campaign-widget's WalletChip component (packages/superfluid-campaign-widget/src/components/shared/WalletChip.tsx) into ai-credits-widget for the connected-wallet address display + Disconnect action.
  3. Gate the Disconnect button/action's visibility on Boolean(disconnectOverride) — the standalone AI Credits app passes an override wired to AppKit's disconnect and sees the button; GoodWallet does not pass one when embedding, so the button is not rendered at all.
  4. Clicking Disconnect calls disconnectOverride(), clears the wallet session, and returns the widget to the existing Connect Wallet panel.

Required states, flows, and behaviors

  • Standalone (host passes disconnectOverride) + wallet connected → Disconnect button visible near the wallet address.
  • Standalone + wallet not connected → no Disconnect button (existing Connect Wallet panel only, unaffected).
  • Embedded in GoodWallet (no disconnectOverride passed) → Disconnect button never rendered, in any wallet-connection state.
  • Click Disconnect → disconnectOverride() fires, session clears, widget returns to the Connect Wallet panel.
  • Switching wallets = disconnect then reconnect via the existing Connect Wallet flow — no separate "switch wallet" UI needed.

Acceptance criteria

  • Disconnect button/action is visible only when standalone AND a wallet is connected (i.e. disconnectOverride was provided).
  • Disconnect button/action is never rendered when embedded in GoodWallet, in any connection state.
  • Clicking Disconnect calls disconnectOverride, clears the session, and returns to the existing Connect Wallet panel.
  • disconnectOverride prop added to AiCreditsWidgetProps/widgetRuntimeContract.ts, matching the existing connectOverride convention.
  • Reuses superfluid-campaign-widget's WalletChip pattern where practical — no new UI primitives added.
  • No regression to the existing Connect flow.

Additional context

Requested by Michael An (Bounty Lead) in #goodbounties-lead, 2026-08-11. Implementation should mirror packages/superfluid-campaign-widget's disconnect pattern (WalletChip component, disconnectOverride prop convention) per Michael's explicit direction — do not design a new mechanism. Deliberately diverges from Superfluid's own UX in one respect: visibility of the Disconnect button must be gated on disconnectOverride presence (hidden when embedded), not just message-gated as in Superfluid. Distinct from issue #154 ("Revoke Operator" button) — that's about revoking GoodDollar operator consent, unrelated to wallet session management. Relevant files: packages/ai-credits-widget/src/AiCreditsWidget.tsx, packages/ai-credits-widget/src/widgetRuntimeContract.ts, packages/superfluid-campaign-widget/src/components/shared/WalletChip.tsx, packages/superfluid-campaign-widget/src/widgetRuntimeContract.ts, packages/core/src/provider.tsx.

Create the plan (keep this section in the issue body)

Based on the above description create an execution plan in a new sub-issue and preserve the original issue content unchanged.
Do not execute the plan until given instructions to do so.

Sub-issue requirements:

  • Title format: [DRAFT][PLAN] <what issue is being planned>
  • Type: Task
  • Description must start with: <sub-issue title>
  • Link the sub-issue back to this parent issue.

Instructions when creating the plan:

  • Map relevant files that are too be used as reference from all repos mentioned
  • import existing @GoodDollar packages
  • Map new components that should be created. Assess when a new component should be created in the new savings widget package or made part of the reusable packages/ui

Plan specification required sections:

  • Required states, flows, and behaviors
  • Execution plan
  • acceptance criteria
  • human-reviewer checklist

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status
Prepare AI Task

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions