Skip to content

feat(send): smart source selection by gift-card config - #1042

Merged
gudnuf merged 1 commit into
masterfrom
wt/smart-selection-rework
May 4, 2026
Merged

gudnuf merged 1 commit into
masterfrom
wt/smart-selection-rework

Conversation

@gudnuf

@gudnuf gudnuf commented May 1, 2026 •

Copy link
Copy Markdown
Contributor

Adds validPaymentDestinations: { descriptions, nodePubkeys } to gift-card config and a pickSendAccount helper that uses it to preselect the right cashu account for an incoming BOLT11 invoice. Priority: offer > gift-card > default. Selection happens in the route loader (no first-render flash) and on every paste/scan via the send store.

Supersedes #1025.

@vercel

vercel Bot commented May 1, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agicash Ready Ready Preview, Comment May 4, 2026 8:54pm

Request Review

@supabase

supabase Bot commented May 1, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project hrebgkfhjpkbxpztqqke because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

Comment thread app/features/send/pick-send-account.ts Outdated
Comment thread app/features/send/pick-send-account.ts Outdated
Comment thread app/features/send/resolve-destination.ts
Comment thread app/features/send/send-store.ts
Comment thread app/routes/_protected.send.tsx Outdated
const initialAccount = useAccountOrDefault(accountId);
const accountIdParam = searchParams.get('accountId');
const initialAccount = useAccountOrDefault(
loaderData.initialAccountId ?? accountIdParam,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are all the places that accountIdParam will be set from the app? I'm wondering because it will inform which one has priority

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two places: gift-card-details Send and offer-details Pay buttons. Both pass the currently-viewed account. The picker overriding it is correct — closed-loop mints can only pay invoices matching their config, so if the picker swaps to a different offer/gift-card it's because the original couldn't have paid the invoice anyway. If nothing matches, accountIdParam wins via the defaultAccount fallback.

Comment thread app/routes/_protected.send.tsx Outdated
Base automatically changed from wt/gift-card-mint-configs to master May 1, 2026 17:53
@gudnuf
gudnuf force-pushed the wt/smart-selection-rework branch from df22b65 to 712ad16 Compare May 1, 2026 17:54

@jbojcic1 jbojcic1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is all still pretty confusing to me

Comment thread app/features/send/send-store.ts
Comment thread app/routes/_protected.send.tsx Outdated
Comment thread app/routes/_protected.send.tsx Outdated
Comment thread app/routes/_protected.send.tsx Outdated
@gudnuf

gudnuf commented May 1, 2026

Copy link
Copy Markdown
Contributor Author

this is all still pretty confusing to me

how about now? I only changed app/routes/_protected.send.tsx and made candidates in pick-send-account from a single reduce loop rather than filters and maps

@gudnuf
gudnuf requested a review from jbojcic1 May 1, 2026 22:04
Comment thread app/features/send/pick-send-account.ts Outdated
Comment thread app/features/send/pick-send-account.ts Outdated
Comment thread app/features/gift-cards/gift-card-config.ts Outdated
Comment thread app/routes/_protected.send.tsx Outdated
Comment thread app/features/send/send-store.ts Outdated
Comment thread app/features/send/pick-send-account.ts Outdated
Comment thread app/features/send/pick-send-account.ts Outdated
@jbojcic1

jbojcic1 commented May 4, 2026

Copy link
Copy Markdown
Collaborator

this is all still pretty confusing to me

how about now? I only changed app/routes/_protected.send.tsx and made candidates in pick-send-account from a single reduce loop rather than filters and maps

much better now

const isAllowedDestination = (
config: NonNullable<GiftCardInfo['validPaymentDestinations']>,
): boolean => {
if (description && config.descriptions.includes(description)) return true;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so if both description and node pubkeyes are set in the config, it is enough to just match the description?

Adds validPaymentDestinations: { descriptions, nodePubkeys } to the
gift-card config schema and a findMatchingOfferOrGiftCardAccount helper
that uses it to preselect the right cashu account for an incoming
BOLT11 invoice. Priority: offer > gift-card > default.

Selection happens in the send route loader (no first-render flash) and
on every paste/scan via the send store. Both populated lists in
validPaymentDestinations are required checks (AND); an empty list means
the dimension is unconstrained; both empty means the mint is
unconfigured and never matches.

To support pubkey matching, decodeBolt11 now recovers the payee node
key from the invoice signature — the n tag is optional in BOLT11 and
rarely included. Recovery uses a manual 5→8 bit packer to produce the
canonical preimage, since @scure/base's strict bech32.fromWords rejects
the partial trailing byte that real-world invoices commonly have.
nodePubkeys are normalized to lowercase at zod parse time.

Supersedes #1025. Production VITE_GIFT_CARDS must add
validPaymentDestinations to every entry before this deploys, or vite
will throw at startup.
@gudnuf
gudnuf force-pushed the wt/smart-selection-rework branch from 06c61ce to cbe7cba Compare May 4, 2026 20:53
@gudnuf
gudnuf merged commit 91186fb into master May 4, 2026
5 checks passed
@gudnuf
gudnuf deleted the wt/smart-selection-rework branch May 4, 2026 21:44

This branch was successfully deployed

1 active deployment
Preview — cbe7cba2 Deployed May 4, 2026 by vercel[bot]
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.

3 participants