Skip to content

[PLAN] Prepare GoodWallet for GoodWidget integration #56

Description

@L03TJ3

[DRAFT][PLAN] Prepare GoodWallet for GoodWidget integration

Closes / tracks: #55


Overview

This plan covers the steps needed to wire @goodwidget/ai-credits-widget into GoodWallet so that authenticated users can open AI Credits from the home dashboard / More drawer. The work is split into two phases:

  1. Wallet foundation – reusable host infrastructure that any future widget can use (already partially present from Add secure GoodWidget integration boundary #54; gaps to close listed below).
  2. AI Credits widget integration – the specific registry entry, route, icon, dashboard action, and tests for @goodwidget/ai-credits-widget.

Phase 1 – Wallet foundation (reusable, widget-agnostic)

These steps produce or harden the hosting surface that every widget, including AI Credits, will rely on.

1.1 Package install & local tarball workflow

Behaviour required

  • @goodwidget/ai-credits-widget must be resolvable at build time.
  • Because the package is not yet published to npm, the install must use a local tarball produced by pnpm --filter @goodwidget/ai-credits-widget pack inside the GoodDollar/GoodWidget monorepo.

Steps

  1. Document the tarball build + yarn add file:… workflow in a short CONTRIBUTING note or README section so every developer can reproduce it.
  2. Add a resolutions / overrides entry in package.json if the tarball path must be pinned for CI.
  3. Validate that yarn install (or the project's lock-file flow) succeeds with the tarball reference.

Acceptance criteria

  • yarn build completes without module-not-found errors for @goodwidget/ai-credits-widget.
  • Local tarball path is not hard-coded in committed source files; only package.json / yarn.lock reference it.

1.2 RestrictedEip1193Provider policy completeness

Behaviour required

  • The provider policy layer introduced in Add secure GoodWidget integration boundary #54 (src/widgets/provider/policy.ts) must cover all methods and chain IDs that AI Credits needs.
  • WIDGET_PROVIDER_METHODS and WIDGET_EVM_CHAIN_IDS must be kept as the single source of truth; no widget entry should bypass them.

Steps

  1. Audit the AI Credits widget API surface (inspect package exports / README inside GoodDollar/GoodWidget packages/ai-credits-widget) and list the EIP-1193 methods it calls.
  2. If new methods are required (e.g. eth_getBalance, eth_call), add them to WIDGET_PROVIDER_METHODS in policy.ts with a comment explaining which widget requires them.
  3. Verify WIDGET_EVM_CHAIN_IDS already includes CELO_CHAIN_ID (it does – confirm no regression).

Acceptance criteria

  • Calling any method the widget needs does not throw "unsupported provider methods" from RestrictedEip1193Provider.
  • No existing passing test in RestrictedEip1193Provider.test.ts is broken.

1.3 AuthenticatedWidgetRoute / bottom-sheet host hardening

Behaviour required

Steps

  1. Review AuthenticatedWidgetRoute.tsx and confirm that session-guard logic is applied generically (not tied to specific widget IDs).
  2. If widget state leaks across logout, add an equivalent resetWidgetState() call in src/login/context/SessionContext/storage.ts alongside the existing resetWalletConnectDialogs() call.

Acceptance criteria

  • Navigating to /{locale}/ai-credits while unauthenticated renders the login screen, not the widget.
  • Logging out while a widget bottom-sheet is open does not leave stale widget state.

Phase 2 – AI Credits widget: registry entry, route, dashboard action, icon, and tests

These steps are widget-specific and depend on Phase 1 being complete.

2.1 Registry entry in src/widgets/registry.ts

Behaviour required

  • A defineWidget(…) call must be added to WIDGETS for @goodwidget/ai-credits-widget.
  • It must pass all validators in createWidgetRegistry (exact semver, valid slug, no reserved route, ≥1 chain, all methods in allowlist).

Required fields

Field Value
widgetId "goodwidget.ai-credits"
packageName "@goodwidget/ai-credits-widget"
packageVersion Exact semver from the tarball (e.g. "0.1.0")
routeSlug "ai-credits"
displayName "AI Credits"
integrationMode "web-component" (Custom Element ai-credits-widget)
entry.tagName "ai-credits-widget"
entry.load Dynamic import("@goodwidget/ai-credits-widget/register")
providerPolicy.chainIds [CELO_CHAIN_ID]
providerPolicy.requiredMethods Determined in step 1.2 above

Steps

  1. Add the defineWidget entry to registry.ts.
  2. Remove it from the process.env.NEXT_PUBLIC_PLAYWRIGHT_TEST_MODE guard so it is active in production builds (the test fixture widget must stay guard-gated).

Acceptance criteria

  • createWidgetRegistry(WIDGETS) does not throw.
  • getWidgetByRoute("ai-credits") returns the registered widget.
  • widgetDashboardActions includes an entry for AI Credits.

2.2 Dashboard icon for AI Credits

Behaviour required

  • The AI Credits RoundButton on the home dashboard must display a recognisable icon.
  • Follow the DashboardIcon union: prefer { kind: "system"; name: IconName } if a suitable system icon exists, otherwise use { kind: "local"; render: () => ReactNode } with an inline SVG or imported asset.

Steps

  1. Check the ui package's IconName union for a suitable icon (e.g. "Ai", "Credits", "Spark").
  2. If none fits, create a minimal SVG asset under src/widgets/icons/AiCreditsIcon.tsx and wire it as { kind: "local", render: () => <AiCreditsIcon /> }.

Acceptance criteria

  • An icon renders in the dashboard action button without a broken-image placeholder.
  • No new third-party icon library is added.

2.3 Home dashboard and More drawer wiring

Behaviour required

  • widgetDashboardActions (derived automatically from WIDGETS) must surface the AI Credits button in the home dashboard action row and the More drawer.
  • No manual edits to WalletSection.tsx are needed beyond confirming that widgetDashboardActions is already consumed (it is, from the Add secure GoodWidget integration boundary #54 diff).

Steps

  1. Confirm WalletSection.tsx spreads both coreDashboardActions and widgetDashboardActions into the rendered action rows.
  2. Verify that the More drawer (if separate from the inline row) also iterates over all actions including widget-sourced ones.
  3. Add a translation key home.aiCredits (or similar) and map it to displayName if the label must be localised.

Acceptance criteria

  • AI Credits button appears in the home dashboard action row when the user is authenticated.
  • Tapping / clicking the button opens the bottom-sheet route at /{locale}/ai-credits.

2.4 [widgetRoute]/page.tsx static params

Behaviour required

  • generateStaticParams in src/app/[locale]/@home/(home)/(bottomsheet)/[widgetRoute]/page.tsx already maps over WIDGETS – no change needed once the registry entry is added in 2.1.

Acceptance criteria

  • Next.js static generation includes the ai-credits param without additional code changes.

2.5 Unit tests

Behaviour required

  • Registry validation tests must cover the new AI Credits entry.
  • WidgetRenderer / hostProperties tests must cover the web-component host path for ai-credits-widget.

Steps

  1. In src/widgets/registry.test.ts, add a test asserting that the live WIDGETS array contains an entry with widgetId === "goodwidget.ai-credits" and that createWidgetRegistry(WIDGETS) does not throw.
  2. In src/widgets/WidgetRenderer.test.tsx, add a test rendering AuthenticatedWidgetRoute with widgetId="goodwidget.ai-credits" and asserting the Custom Element is mounted.
  3. Mock @goodwidget/ai-credits-widget/register in vitest config (add to existing alias map in vitest.config.ts or a __mocks__ file).

Acceptance criteria

  • vitest run passes with zero new failures.
  • Coverage for the new registry entry is not below the repo's existing threshold.

2.6 Playwright / E2E smoke test

Behaviour required

  • A single happy-path smoke test verifying that an authenticated user can open the AI Credits bottom-sheet.

Steps

  1. Add a test file in tests-playwright/ (follow the naming convention of existing widget/route tests).
  2. Use the testFixtureWidget pattern as a reference but target the real ai-credits-widget Custom Element.
  3. Assert that ai-credits-widget is present in the DOM and the bottom-sheet is visible.

Acceptance criteria

  • playwright test for the new file passes in CI with NEXT_PUBLIC_PLAYWRIGHT_TEST_MODE off (real widget, not fixture).

Human-reviewer checklist

  • Package tarball resolves at build time; no hard-coded local paths in source
  • RestrictedEip1193Provider policy covers all methods AI Credits requires
  • Registry entry passes all validators (exact semver, valid slug, no reserved route)
  • widgetId follows the goodwidget.<slug> convention
  • Dashboard icon renders; no broken placeholder
  • AI Credits button appears in home dashboard for authenticated users
  • Unauthenticated access to /ai-credits redirects to login
  • Logout clears any open widget state
  • Vitest passes; no regressions in existing widget tests
  • Playwright smoke test passes in CI
  • No new third-party packages added beyond @goodwidget/ai-credits-widget
  • No backwards-compatibility shims introduced

Metadata

Metadata

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions