Repository navigation
Feature Connect A Wallet Widget - #116
goodbounties-nanoclaw-agent[bot] wants to merge 7 commits into
Conversation
…ht specs Implements the ConnectAWalletWidget for linking a secondary wallet address to the connected host wallet's GoodID across Fuse, Celo, and XDC via @goodsdks/citizen-sdk's IdentitySDK. Adds QA runtime-fixture stories, a manual showcase story, MDX docs, and a Playwright states spec covering the disconnected, connecting, address-entry, checking, mixed per-chain row statuses, unsupported-network, and top-level error/retry states. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…idget Every widget in this repo renders its own GoodDollar/chain-badge header inside its own view (see StreamingWidgetView) rather than relying on the shared MiniAppShell for it — this widget was missing that, and the "Primary verified identity" card showing which host address is linking from, per the #113 design reference. Regenerated Playwright screenshots to reflect both changes.
93ca2ff to
ea4bd47
Compare
…ht specs Implements the ConnectAWalletWidget for linking a secondary wallet address to the connected host wallet's GoodID across Fuse, Celo, and XDC via @goodsdks/citizen-sdk's IdentitySDK. Adds QA runtime-fixture stories, a manual showcase story, MDX docs, and a Playwright states spec covering the disconnected, connecting, address-entry, checking, mixed per-chain row statuses, unsupported-network, and top-level error/retry states. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…idget Every widget in this repo renders its own GoodDollar/chain-badge header inside its own view (see StreamingWidgetView) rather than relying on the shared MiniAppShell for it — this widget was missing that, and the "Primary verified identity" card showing which host address is linking from, per the #113 design reference. Regenerated Playwright screenshots to reflect both changes.
ea4bd47 to
5107fa7
Compare
* fix: UI polish and lint fixes for connect-a-wallet-widget - Fix missing Alert import crash on error/unsupported states - Remove unused address prop from ChainLinkRow (lint fix) - Restructure PrimaryIdentityCard layout (shield/text/copy) - Reduce GlowCard shadow opacity and radius - Update unlink SVG path to match lucide icon - Add flexWrap to ChainLinkRow for 320px viewport support - Reduce input/button sizes for small viewports - Center address in verified identity box with wide gap - Adjust heading spacing and checkmark position - Update Playwright test screenshots * fix: address Copilot review findings on connect-a-wallet-widget Adds a changeSecondaryAddress adapter action and "Change address" button so users can check a different address without reloading, replaces a hardcoded RGBA background with the $infoMuted token, and swaps the copy-address control for an accessible, focusable Button. * fix: address pheobeayo review findings on connect-a-wallet-widget Remove unused ChainRowCard export, disambiguate the duplicate "Connect or Disconnect Address" heading, swap hover-tracked useState for hoverStyle on the disconnect button (RN Web/touch compatible), and clear the copy-feedback timeout on unmount. * fix: restore hover text contrast on disconnect button hoverStyle only flips the background to red; icon/label were still hardcoded to error color, making them invisible on hover. Reintroduce a small hover flag via onHoverIn/onHoverOut to swap text/icon to white on hover, per pheobeayo's review. * test: refresh connect-a-wallet-widget screenshots and fix stale spec assertion The ready-state heading changed to 'Linked address' in earlier review-fix commits; update the unsupported-network assertion and regenerate caw-05, 06, 08 and 09 so the committed evidence matches the current UI. * fix: clear pending copy timeout before scheduling a new one
There was a problem hiding this comment.
🟡 Changes recommended
Provider routing, custom-element integration, dialog concurrency, validation feedback, accessibility, and test artifact issues remain unresolved.
9 open findings
Use configured HTTP transports for per-chain read clients · New Avoid shadowing the bridge-provided widget provider · New Prevent dialog replacement from leaving confirmations unresolved · New Display validation errors in the connected input state · New Add interaction tests for link and unlink transactions · New Add a programmatic label to the wallet address input · New Keep action labels visible while showing the busy spinner · New Apply reduced GlowCard styling only to the identity card · New Store screenshots in the canonical evidence directory · New
What changed in this PR
Adds a provider-first wallet-linking widget using Citizen SDK across Fuse, Celo, and XDC.
Changes:
- Adds the widget package, adapter, custom element, and UI.
- Adds Storybook documentation, runtime fixtures, and Playwright coverage.
- Extends shared icons and adjusts
GlowCardstyling.
| File | Description |
|---|---|
packages/connect-a-wallet-widget/package.json |
Defines the new package. |
packages/connect-a-wallet-widget/tsup.config.ts |
Configures package builds. |
packages/connect-a-wallet-widget/tsconfig.json |
Configures development TypeScript. |
packages/connect-a-wallet-widget/tsconfig.build.json |
Configures build TypeScript. |
packages/connect-a-wallet-widget/src/adapter.ts |
Implements SDK wallet-link behavior. |
packages/connect-a-wallet-widget/src/ConnectAWalletWidget.tsx |
Wires provider, adapter, and view. |
packages/connect-a-wallet-widget/src/element.ts |
Defines the custom element. |
packages/connect-a-wallet-widget/src/index.ts |
Exposes the public API. |
packages/connect-a-wallet-widget/src/integration.ts |
Declares integration metadata. |
packages/connect-a-wallet-widget/src/register.ts |
Registers the custom element. |
packages/connect-a-wallet-widget/src/widgetRuntimeContract.ts |
Defines runtime contracts and states. |
packages/connect-a-wallet-widget/src/components/AddressLinkForm.tsx |
Renders address input controls. |
packages/connect-a-wallet-widget/src/components/ChainLinkRow.tsx |
Renders per-chain actions. |
packages/connect-a-wallet-widget/src/components/ConnectAWalletWidgetView.tsx |
Composes widget states. |
packages/connect-a-wallet-widget/src/components/ConnectPrompt.tsx |
Renders the wallet gate prompt. |
packages/connect-a-wallet-widget/src/components/format.ts |
Maps chain-row presentation state. |
packages/connect-a-wallet-widget/src/components/PrimaryIdentityCard.tsx |
Displays the primary identity. |
packages/connect-a-wallet-widget/src/components/shared.tsx |
Provides widget-local UI helpers. |
packages/connect-a-wallet-widget/src/components/WalletGate.tsx |
Gates disconnected wallets. |
packages/ui/src/components/Icon.tsx |
Adds link and unlink icons. |
packages/ui/src/components/GlowCard.ts |
Changes shared glow styling. |
examples/storybook/package.json |
Adds the widget dependency. |
examples/storybook/src/stories/helpers/connectAWalletWidgetStories.tsx |
Defines deterministic fixtures. |
examples/storybook/src/stories/connect-a-wallet-widget/ConnectAWalletWidgetShowcase.stories.tsx |
Adds the interactive showcase. |
examples/storybook/src/stories/connect-a-wallet-widget/ConnectAWalletWidgetQA.stories.tsx |
Adds QA state stories. |
examples/storybook/src/stories/connect-a-wallet-widget/ConnectAWalletWidget.mdx |
Documents widget usage. |
tests/widgets/connect-a-wallet-widget/states.spec.ts |
Adds Playwright state checks. |
tests/widgets/connect-a-wallet-widget/test-results/caw-01-not-connected.png |
Captures disconnected state. |
tests/widgets/connect-a-wallet-widget/test-results/caw-02-connecting.png |
Captures connecting state. |
tests/widgets/connect-a-wallet-widget/test-results/caw-03-connected-no-input.png |
Captures empty address state. |
tests/widgets/connect-a-wallet-widget/test-results/caw-04-checking-address.png |
Captures address checking. |
tests/widgets/connect-a-wallet-widget/test-results/caw-05-ready-mixed-row-statuses.png |
Captures mixed chain states. |
tests/widgets/connect-a-wallet-widget/test-results/caw-06-unsupported-network.png |
Captures network warning. |
tests/widgets/connect-a-wallet-widget/test-results/caw-07-top-level-error-with-retry.png |
Captures retryable error. |
tests/widgets/connect-a-wallet-widget/test-results/caw-08-mobile-ready.png |
Captures mobile layout. |
tests/widgets/connect-a-wallet-widget/test-results/caw-09-desktop-ready.png |
Captures desktop layout. |
pnpm-lock.yaml |
Locks new workspace dependencies. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
🧠 Review effort: Balanced
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
| const publicClientsByChain = useMemo( | ||
| () => | ||
| CONNECT_A_WALLET_CHAINS.reduce( | ||
| (acc, id) => { | ||
| const chain = CHAIN_CONFIGS[id] | ||
| acc[id] = createPublicClient({ chain, transport: custom(provider as Parameters<typeof custom>[0]) }) |
| */ | ||
| function confirmSecurityMessageViaDialog(message: string): Promise<boolean> { | ||
| return new Promise((resolve) => { | ||
| createDialog({ |
There was a problem hiding this comment.
Addressed in #249 (074b547) with a synchronous widget-wide busy guard. Competing chain actions and address edits stay disabled until settlement; pending confirmation is cancelled on wallet change/unmount. Tests cover rapid clicks, receipt waiting, cancellation and failures. No queue or new dialog architecture added.
| if (!isAddress(trimmed)) { | ||
| setStatus('connected_no_input') | ||
| setError('Enter a valid wallet address.') | ||
| return |
| await sdk.connectAccount(secondaryAddress, { | ||
| onSecurityMessage: confirmSecurityMessageViaDialog, | ||
| onHash: (hash: `0x${string}`) => { | ||
| transactionHash = hash | ||
| }, |
There was a problem hiding this comment.
Added in #249 (074b547): SDK-backed mocked interaction coverage for link/unlink confirmation, cancellation, wallet rejection, reverted receipts, callbacks/toasts and busy-state recovery. All 27 targeted tests pass with retries disabled. QA.md separates automated screenshots from manual Celo link/unlink evidence and documents the local WalletConnect workaround and untested live Fuse/XDC transactions.
|
|
||
| async function saveScreenshot(page: Page, name: string) { | ||
| await page.screenshot({ | ||
| path: `tests/widgets/connect-a-wallet-widget/test-results/${name}.png`, |
There was a problem hiding this comment.
Clarified in #249 (074b547), following the scope specified in #245: root /test-results/ is ignored temporary output, while tests/widgets/<widget>/test-results/ holds curated tracked evidence. Updated AGENTS.md and both QA docs; existing screenshot locations and the anchored ignore rule are unchanged.



Description
Adds the Connect-a-wallet widget: lets a user link a secondary address to their connected host wallet across Fuse, Celo, and XDC via
@goodsdks/citizen-sdk'sIdentitySDK(connectAccount/disconnectAccount/checkConnectedStatus). Follows thestreaming-widgetdecomposition standard (thinConnectAWalletWidget.tsxentry +components/tree), usespackages/ui'sDialogfor the blocking security-confirmation prompt before each link/unlink transaction, andToastfor transaction success/failure. Per-chain rows always show a Connect or Disconnect action (never hidden), with a loading indicator while a row's status is in flight.About #113, #114
How Has This Been Tested?
pnpm turbo run build --filter=@goodwidget/connect-a-wallet-widget...andpnpm --filter @goodwidget/connect-a-wallet-widget lintboth pass clean.QA/ConnectAWalletWidget/Runtime Fixtures) cover: not-connected, connecting, connected-no-input, checking-address, ready-with-mixed-row-statuses, unsupported-network, top-level-error-with-retry.tests/widgets/connect-a-wallet-widget/states.spec.ts— 7/7 passing, with screenshots committed undertests/widgets/connect-a-wallet-widget/test-results/.Checklist: