Skip to content

feat(cards): provider directory routed through the standard app-install flow#2366

Draft
reneaaron wants to merge 21 commits into
masterfrom
feat/cards-page
Draft

feat(cards): provider directory routed through the standard app-install flow#2366
reneaaron wants to merge 21 commits into
masterfrom
feat/cards-page

Conversation

@reneaaron
Copy link
Copy Markdown
Member

@reneaaron reneaaron commented May 20, 2026

Summary

Cards page is now a discovery + setup directory for crypto debit cards, routing every provider through Alby Hub's standard NWC app-install flow rather than a bespoke topup-link dialog.

  • Discovery — A /cards page with hero + 3-step strip, filter bar (region / Apple Pay / Google Pay / Lightning-native / No KYC), and a table of providers (RedotPay, 2fiat, Freedomia, Bringin, wavecard).
  • Each row is fully clickable — opens the provider's marketing site in a new tab. The previous tiny arrow-icon action column is gone; rows are the action.
  • "Connect card" button + picker dialog — top-right of the Cards header. Opens a lightweight provider-picker (tiles with logo + name + network/type). Picking a provider routes to /apps/new?app=<appStoreId> — the standard NWC pairing flow. Includes an "Other card" tile (dashed border) for any crypto card not in the list, routing to bitcoin-card-topup.
  • New bitcoin-card-topup app store entry — used by RedotPay, Freedomia, and the "Other card" fallback. Install guide: "Open card.albylabs.com on the device you'll top up from → Add it to your home screen (or bookmark it) → Enter your card's deposit address, network, and currency to set it up." Finalize guide: paste connection secret into the topup app's Connect Wallet button. Logo is the topup PWA's own shortcut-icon (copied into suggested-apps/).
  • Existing app store entries reused — 2fiat → 2fiat, Bringin → bringin, wavecard → wavespace. All three already had setup guides.

What was removed

  • Custom ConnectCardDialog form (address / network / currency fields) — the topup app collects this itself.
  • CardCreatedDialog with the hash-encoded one-shot NWC topup link (#label=…&address=…&chainId=…&currency=…&nwc=…).
  • "Your card connections" section, useUserCards hook, and CardManagement.tsx — connected cards now appear in the standard /apps list like any other app.

Files

  • frontend/src/screens/cards/Cards.tsx — providers list, hero, filter bar, picker dialog, clickable rows
  • frontend/src/components/connections/SuggestedAppData.tsx — new bitcoin-card-topup entry
  • frontend/src/assets/suggested-apps/bitcoin-card-topup.png — logo, copied from bitcoin-card-topup/public/shortcut-icon.png
  • frontend/src/components/icons/MastercardLogo.tsx (new) — paired with the existing VisaLogo

Test plan

  • Open /cards → hero, filter bar, and 5-row provider table render
  • Click any provider row → opens the provider's website in a new tab
  • Click Connect card → picker dialog shows 5 provider tiles + "Other card" fallback
  • Click RedotPay in picker → lands on /apps/new?app=bitcoin-card-topup with the install guide pointing to card.albylabs.com
  • Click 2fiat / Bringin / wavecard → land on their existing app store entries
  • Click Other card/apps/new?app=bitcoin-card-topup (same as RedotPay)
  • Complete the standard NWC pairing → the connection appears under /apps like any other NWC app

reneaaron and others added 2 commits May 18, 2026 14:23
Adds a dedicated Cards screen that surfaces crypto debit card
providers users can top up from their Alby Hub balance, with region
and feature filters and a fees comparison table.

Co-Authored-By: Claude <noreply@anthropic.com>
Iterates on the cards directory page (#ae087d0b) to wire up the full
connect-card flow described with the bitcoin-card-topup PWA at
card.albylabs.com.

- AI-style hero with three steps: Get a card → Connect it → 1-click top-ups
- Trimmed provider list to RedotPay / 2fiat / Freedomia (the providers
  we've validated end-to-end)
- New "Time to get" column so users see physical vs virtual at a glance
- Renamed "Add card" → "Connect card" everywhere; submit mints a real
  NWC connection via createApp (same pattern as the AI page) with
  scopes for the topup app (get_info / get_balance / list_transactions /
  lookup_invoice / make_invoice / pay_invoice / notifications)
- CardCreatedDialog shown once at creation with QR code + bookmarkable
  top-up link of the form

    https://card.albylabs.com/#label=...&address=0x...&chainId=42161&currency=USDC&nwc=<pairing-uri>

  Includes prominent "save this link — you won't see it again" warning
  (Alert with warning variant) and "scan with your phone's camera app
  (this is a URL, not a Lightning invoice)" caption under the QR
- Saved card tiles link to /apps/:appId so users get back to the NWC
  connection detail; no separate top-up affordance from the hub
- useUserCards hook persists cards in localStorage with appId pointing
  at the NWC connection; ready to migrate to deriving the list from
  /api/apps filtered by metadata.app_store_app_id = "bitcoin-card-topup"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 404ffe6f-aa71-4f82-aed2-397d73def1c1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cards-page

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

reneaaron and others added 18 commits May 21, 2026 11:34
Replaces the localStorage card store with a derivation from /api/apps
filtered by metadata.app_store_app_id = "bitcoin-card-topup". Card
provider/destination/chain/currency now ride on the NWC app's metadata,
so cards survive across devices, reloads and DB backups, and "forget
card" flows through the existing /apps/:id delete affordance.

- Gate /cards through DefaultRedirect so a locked hub redirects to
  /unlock (matches /wallet, /apps, etc.)
- Hub-generated top-up link now uses #?... prefix so bitcoin-connect's
  parser branches to the URLSearchParams path (works in all cases vs.
  the bare #... which mis-parsed for some users)
- Remove EmptyCards empty state (the Connect card button in the page
  header is the sole entry point)
- Drop the "Experimental" filter and badge — too small a catalog for
  it to be useful, and the toggle behavior confused users
- Replace "Top up via" column with "Card cost" (more decision-relevant)
- Verified all provider data from each provider's site; updated
  - RedotPay: KYC Full (not Light), regions add US/UK, fees ~2.2% + FX
  - 2fiat: Mastercard (not Visa), Apple Pay + Google Pay supported, KYC
    None (not Light), card cost $50, fees ~6.8%
  - Freedomia: Google Pay supported, card cost $5–30/mo subscription,
    fees 1.3–4.3%
- Add a hoverable info-icon tooltip on the "None" KYC badge so privacy-
  focused users keep the signal they want while cautious users see the
  merchant-of-record-fragility caveat
- Field label "Destination address" → "Top-up address" (matches what
  the user pastes from their provider)
- Connect dialog copy de-emdashed
- Various smaller copy/layout tweaks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Switch Freedomia tile bg to bg-orange-500 to match the brand's
  orange F logo
- Drop the upscaled watermark logo from card-tile backgrounds for a
  cleaner surface
- Hide filter toggles whose criterion no provider satisfies, so the
  filter bar only offers actionable options
- Rename "Mobile pay" column header to "Mobile" — the icons already
  identify Apple/Google Pay

Co-Authored-By: Claude <noreply@anthropic.com>
We trimmed the catalog to RedotPay/2fiat/Freedomia in an earlier
commit; the other 8 PNGs were left behind. Remove them to keep the
asset directory tight.

Co-Authored-By: Claude <noreply@anthropic.com>
RedotPay only requires ID verification — no proof of address, employer
details, or source-of-funds questions. "Full" overstates it and may
deter users from even trying.

Adds a Light KYC tooltip alongside the existing None one so the
distinction is visible at a glance.
- CardCreatedDialog: drop the "regular URL, not a Lightning invoice"
  caveat and replace with actionable "save it as an app to your
  homescreen" guidance.
- Hide the QR + scan instruction on mobile — the user is already on
  their phone, so scanning their own screen is nonsense.
- Provider table: switch wrapper from overflow-hidden to overflow-x-auto
  and set a 720px min-width so 9 columns scroll horizontally on narrow
  viewports instead of cramming/clipping.
Both already ship as suggested apps with their own NWC pairing flows, so
the table row's action arrow links to /appstore/<id> rather than the
stablecoin connect-card dialog. Marked via a new optional appStoreId
flag on Provider; the Connect-card dropdown filters these out so the
top-up form never offers a chain/currency for cards that don't need one.
Reuses the existing suggested-apps logos to avoid duplicating assets.
"Top up in seconds — your card is funded in under a minute, ready to
spend on the go" lands the speed promise harder than "1-click top-ups"
did, and frames the value as on-the-go spending rather than mechanics.
Bringin and wavecard are now in the provider dropdown. Picking either
hides the address/network/currency fields and replaces the primary
button with an "Open setup guide" link to /appstore/<id>, where their
own NWC pairing flow lives. Keeps a single entry point for "connect a
card" without forcing the stablecoin form onto cards that don't use it.

Also tightens the hero subtitle to lead with the speed promise.
Skip the app-store detail page — /apps/new?app=<id> drops users into
the connection flow with the right app preselected, which is what they
actually wanted.
Verified against bringin.app/bitcoin-debit-cards and wave.space/card:

- Both offer physical *and* virtual cards (added "Both" to cardType).
- wave.space is EEA-only for issuance (card itself is accepted globally)
  — regions changed from Global to EU.
- Direct Apple Pay isn't live for either; both currently work via Curve,
  which is too indirect to claim native Apple Pay support.
- Issuance is not free: Bringin charges a €3.49/mo subscription that
  bundles both cards; wave.space charges €2.99 virtual / €29.99 physical
  one-time.
- Conversion fees are 1% + ~0.5% LP spread for both, not flat ~1%.
- Bringin URL fixed to bringin.app (they migrated from bringin.xyz);
  wave.space URL points at the card landing page.

Doesn't change the dialog routing — picking Bringin/wavecard still drops
the user into /apps/new?app=<id> for the NWC pairing.
- Title and subtitle now describe the link instead of warning.
- Alert highlights the device-specific action ("save it on the phone
  you'll top up from") and drops the redundant secret-recovery prose.
- QR caption mentions bookmark as an alternative to home-screen install.
- Add a bitcoin-card-topup app store entry pointing to card.albylabs.com
  with a "visit + add to home screen + enter card details" install guide.
- Wire RedotPay and Freedomia to bitcoin-card-topup, and 2fiat to its
  existing app store entry. Bringin and wavespace already had theirs.
- Drop the custom Connect card dialog, address/network/currency form,
  and the one-shot CardCreatedDialog with embedded NWC link. Card config
  is now collected inside the topup app itself.
- Drop the "Your card connections" section and the useUserCards hook —
  connected cards show up in the standard /apps list like any other app.
- Bring back the Connect card button in the header; opens a lightweight
  provider-picker dialog where each tile routes straight to
  /apps/new?app=<appStoreId>.
- Drop the table's action column entirely; the whole provider row is now
  clickable and opens the provider's website in a new tab. This separates
  discovery (row click → learn more) from action (Connect card → setup).
- Add an "Other card" tile to the Connect card picker (dashed border,
  generic credit-card icon). Routes to /apps/new?app=bitcoin-card-topup
  so anyone holding a USDC/USDT card not in the listed providers can
  still set up the topup flow.
- Reword the install guide from "phone you'll top up from" to "device" —
  the topup app works equally well on a tablet or any browser.
- Swap the placeholder 2fiat logo for the Alby logo (alby.png).
- Drop USDC/USDT specifics from the app description, extended
  description, and the picker dialog's "Other card" tile copy. From the
  user's perspective the topup app just takes a crypto card.
Copy bitcoin-card-topup/public/shortcut-icon.png (the topup PWA's home-
screen icon) into suggested-apps/ and point the bitcoin-card-topup app
store entry at it, replacing the Alby-logo placeholder.
NewApp.tsx rendered the app logo at w-12 h-12 (48px) while
AppStoreDetailHeader uses w-14 h-14 (56px) — the logo visually jumps
between /apps/new?app=<id> and /appstore/<id>. Unify on w-14 h-14.
AppStoreDetailHeader was rendering the logo + title + description inside
a custom flex container nested into AppHeader's title prop, which gave
the icon a different vertical alignment than every other AppHeader use.
Pass them via the icon and description props instead so the header
layout stays consistent with /apps/new and the rest of the app.
@reneaaron reneaaron changed the title feat(cards): connect-card flow with NWC top-up link feat(cards): provider directory routed through the standard app-install flow May 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant