Skip to content

[Plan]: Build GoodReserve Widget — Reserve swap UI backed by GoodReserve SDK #15

Description

@L03TJ3

Short description of the new GoodWidget

Build the first packages/goodreserve-widget package in GoodWidget: a reserve swap widget backed by @goodsdks/good-reserve, using GoodWalletV2’s swap UX as the UI reference and GoodSDKs’ reserve demo as the behavior reference.

This widget should prove the GoodWidget framework can support a quote-driven swap flow, reserve-specific validation/error handling, and reusable widget packaging beyond the existing claim flows.
Target package: packages/goodreserve-widget
Network context: GoodDollar-related flows should target Celo (42220) and XDC (50).


Which repos and packages the AI should work with

Cross-repo references

GoodSDKs

  • packages/good-reserve/README.md
  • packages/good-reserve/
  • packages/react-hooks/README.md
  • apps/demo-reserve-swap/src/components/ReserveSwap.tsx
  • apps/demo-reserve-swap/src/components/useReserveSwapQuote.ts
  • apps/demo-reserve-swap/src/components/useReserveSwapTx.ts
  • apps/demo-reserve-swap/src/utils/errors.ts

GoodWalletV2

  • src/sections/Swap/SwapView.tsx
  • src/sections/Swap/swapStore.ts
  • src/sections/Swap/swapOverlayStore.ts
  • src/sections/Swap/components/AmountInputBox/
  • src/sections/Swap/components/AssetSelectBox/
  • src/sections/Swap/components/RouteBox/
  • src/sections/Swap/components/TokenInfoSlider/
  • src/sections/Swap/components/TokensDrawer/
  • src/sections/Swap/components/SwapDialog/ConfirmSwapDialog.tsx
  • src/sections/Swap/components/OutOfGasWarn/OutOfGasWarn.tsx
  • src/components/Form/RoundButton/RoundButton.tsx

Scope

  • Create packages/goodreserve-widget with the standard package scaffold.
  • Add widget runtime files (index.ts, widgetRuntimeContract.ts, integration.ts).
  • Implement widget-local swap view, state, hooks, and reserve-specific UI.
  • Wire the widget to @goodsdks/good-reserve.
  • Add Storybook coverage under examples/storybook/src/stories/goodreserve-widget/.
  • Add any widget-specific screenshots under the same widget story folder.
  • Add verification coverage in tests/demo/.

Non-goals

  • No migration of GoodWalletV2’s LiFi swap engine.
  • No unrelated packages/ui refactors.
  • No new wallet/provider abstraction layer.

Source-to-target mapping

  • GoodWalletV2 SwapView → widget-local ReserveSwapView
  • GoodWalletV2 swap state/overlay stores → widget-local reserve stores
  • GoodSDKs reserve quote/tx hooks → widget-local reserve hooks
  • GoodSDKs reserve error utilities → widget-local reserve error mapping
  • Existing @goodwidget/ui primitives should be reused where possible; only add new generic primitives if they are clearly reusable beyond this widget

UI implementation reference

There is an interactive demo on stitch:
https://stitch.withgoogle.com/preview/1645756043403511215?node-id=1d5c2d1b8fcc445f9a060ce226a5d495

And for exact colors, structure, spacing check the figma
https://www.figma.com/design/xsk5EiF6CvStA9mtdbA9OR/GoodWidget-Library?node-id=2311-2&t=3MMOUiTScwCmxTQp-1

Use GoodWalletV2 as the visual reference:

  • amount input layout
  • asset pair selection
  • direction toggle (buy/sell)
  • reserve stats / route summary area
  • confirmation dialog
  • warning/error presentation
  • primary CTA states

Use GoodSDKs apps/demo-reserve-swap as the behavior reference for:

  • SDK initialization
  • quote loading/debounce
  • transaction execution lifecycle
  • reserve stats loading
  • error classification and display

Main swap view reference:
Image

Confirm swap drawer:
Image

Swap success screen:
Image

UI notes:

  • Keep reserve-specific logic inside packages/goodreserve-widget.
  • Reuse existing @goodwidget/ui primitives before creating new ones.
  • Only move a new component into packages/ui if it is generic and reusable.
  • Storybook stories must follow the existing per-widget organization.

User flows, states and behaviours

Required states and flows

  • no_provider: no provider passed; swap UI blocked with connect prompt
  • unsupported_chain: provider is not on Celo Mainnet or XDC ; show switch-network state
  • sdk_initializing: widget is mounting SDK/runtime data
  • idle_buy: buy flow visible, empty input, CTA disabled
  • amount_editing: user input is changing and quote debounce is active
  • quote_loading: quote request in progress
  • quote_ready: valid quote returned and CTA enabled
  • quote_error: quote failed with user-readable error
  • insufficient_balance: input exceeds wallet balance and CTA is disabled
  • slippage_selection: slippage settings sheet/dialog is open and persisted
  • confirm_dialog: user reviews amount, price/slippage/fee summary before submit
  • swap_pending: tx submitted, interaction blocked
  • swap_success: success feedback shown and state reset/refreshed
  • swap_error: tx failed with mapped reserve-specific error

Functional expectations

  • The widget must support reserve buy and sell directions.
  • The widget must read wallet/provider state through the existing GoodWidget runtime path.
  • The widget must validate supported chain, balances, and reserve warnings before execution.
  • The widget must use deterministic Storybook-friendly mocks instead of requiring live network behavior in CI.
  • Storybook should use the existing fixture patterns in examples/storybook/src/fixtures/; reserve-specific SDK mocking should stay separate from wallet-provider fixtures.

Acceptance criteria

  • packages/goodreserve-widget exists with the expected scaffold.
  • GoodReserveWidget renders for connected, disconnected, and unsupported-chain states.
  • Buy and sell flows both support quote loading, quote success, and quote error states.
  • Confirmation, pending, success, and error transaction states are represented.
  • Insufficient-balance and reserve-warning states are represented.
  • config and themeOverrides flow through the standard GoodWidget theming/runtime contract.
  • widgetRuntimeContract.ts and integration.ts accurately describe widget states, events, and dependencies.
  • Storybook covers the required states under the widget-specific story folder.
  • Workspace build/test/lint expectations are defined before implementation.

Verification commands

pnpm install
pnpm build
pnpm lint
pnpm storybook &
pnpm test:storybook
pnpm test:demo

If the SDK or cross-repo dependencies are unavailable, that must be reported as a blocker instead of worked around silently.

Human-reviewer checklist

  • I reviewed the issue before reviewing the diff.
  • I checked that the implementation stays within the defined scope.
  • I checked that reserve/protocol logic stays out of packages/ui unless explicitly justified.
  • I checked Storybook coverage for the required states.
  • I checked the verification command results or reproduced them.
  • I checked for any deviations from the stated references, flows, or network assumptions.
  • I verified that the design matches the shared references/figma/stitch-prototypes

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
In Progress

Relationships

None yet

Development

No branches or pull requests

Issue actions