alby-hub/http
René Aaron 40dcf11a2b
feat(cards): provider directory routed through the standard app-install flow (#2366)
* feat: add cards directory page with provider listings

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>

* feat(cards): connect-card flow with NWC top-up link

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>

* feat(cards): derive cards from /api/apps, polish

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>

* chore(cards): tidy provider tiles, filter, and column header

- 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>

* chore(cards): drop unused provider logos

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>

* chore(cards): downgrade RedotPay KYC from Full to Light

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.

* chore(cards): tighten copy and mobile layout

- 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.

* feat(cards): list Bringin and wavecard

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.

* chore(cards): retitle 3rd hero step to highlight top-up speed

"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.

* feat(cards): route app-store cards through the Connect dialog

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.

* chore(cards): link app-store cards straight to /apps/new

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.

* chore(cards): correct Bringin and wavecard table data

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.

* chore(cards): tighten created-dialog copy

- 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.

* refactor(cards): route every provider through the standard app flow

- 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.

* feat(cards): add Connect card picker dialog + clickable rows

- 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).

* feat(cards): add Other card option + broaden install wording

- 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.

* chore(cards): fix bitcoin-card-topup logo + broaden copy to "any crypto"

- 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.

* chore(cards): use bitcoin-card-topup's own PWA icon as the app logo

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.

* fix(apps): align Connect-to-app header logo size with the appstore page

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.

* fix(appstore): use AppHeader's standard icon/description slots

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.

* chore(cards): use Freedomia affiliate URL

* chore: add affiliate links

* fix: always show global cards

* fix: make 2fiat lightning native

* chore: update card instructions

* chore: optimize bitcoin card topup app image

* chore: improve bitcoin card topup copy

* chore: add card events, fix http service event endpoint url

* chore(cards): drop redundant 'Get a card' section heading

* chore(cards): tighten hero subtext + 3-step copy, hide filter footer when inactive

- Hero subtext drops the "one click" claim that's no longer accurate
  post-refactor and the em-dash.
- 3-step descriptions reworded for length and fix "Setup" -> "Set up";
  bottom step matches the "in seconds" heading instead of saying
  "under a minute".
- "Showing N of M providers" footer is hidden unless a filter is
  active — silent when there's nothing to clarify.

* chore(cards): apply Alby button gradient + brand stroke to hero card

Use the same vertical white→cream highlight and 1px #ffdf6f stroke that
alby.css applies to default primary buttons, so the hero card visual
reads as part of the same theme family instead of an isolated panel.

* chore(cards): reframe step 2 around the top-up link + drop hero gradient

- Step 2 title shifts from "Connect it" to "Get a top-up link" so the
  deliverable (a saveable link) is what users see, matching what
  actually happens at that step post-refactor.
- Drop the white→cream gradient overlay from the hero card; the flat
  yellow with the existing shadow is the look we want.

* chore: change wave.space kyc level

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
2026-05-24 12:22:48 +07:00
..
alby_http_service.go fix: fetch currencies through alby backend api (#2212) 2026-04-09 23:03:26 +05:30
http_service.go feat(cards): provider directory routed through the standard app-install flow (#2366) 2026-05-24 12:22:48 +07:00
http_service_test.go fix: unlock error when node is not started (#2151) 2026-04-07 17:38:47 +05:30
models.go Refactor: API cleanup (#338) 2024-05-30 00:06:06 +07:00