Draft
Conversation
Adds merchant screen + NFC layer for issuing Flash cards loaded
with Cashu proofs (NUT-XX Profile B, offline bearer payments).
New files:
src/nfc/cashu-apdu.ts APDU builders + response parsers
- buildSelectAid, buildGetInfo, buildGetPubkey, buildLoadProof,
buildSetPin, buildVerifyPin + matching parsers
- reconstructP2PKSecret() — rebuilds secret JSON from nonce+pubkey
(avoids storing full ~120-byte JSON on 32-byte on-card field)
src/nfc/useCashuCard.ts IsoDep NFC session hook
- startSession() / cleanup() — NfcTech.IsoDep lifecycle
- readBlankCardPubkey() — verify blank + return pubkey
- writeProofs() — SET_PIN (blank) + VERIFY_PIN + LOAD_PROOF × N
- individual command methods for flexible use in ENG-178
src/graphql/cashu.ts GQL mutation + proof shape helpers
- CASHU_CARD_PROVISION mutation document
- extractNonceFromSecret() — pull 32-byte nonce from P2PK JSON
- toCardWriteProof() — convert GQL proof to flat card-write format
src/screens/CashuProvision.tsx 6-step provisioning screen
- Step 1: enter USD amount
- Step 2: set provisioning PIN
- Step 3: NFC tap — read card (blank check or top-up detect)
- Step 4: mint proofs via cashuCardProvision GQL
- Step 5: write proofs via SET_PIN + VERIFY_PIN + LOAD_PROOF × N
- Step 6: success / retry on error
Modified:
src/types/routes.d.ts added CashuProvision route
src/routes/index.tsx registered CashuProvision screen
src/screens/Profile.tsx added 'Issue Flash Card' entry button
Closes ENG-177
Customer taps Flash card → merchant receives Lightning payment.
New files:
src/utils/sha256.ts Pure-TS SHA-256 (FIPS 180-4, zero deps)
Used to hash P2PK secrets for SPEND_PROOF signing
src/nfc/cashu-melt.ts Nutshell melt API client
createMeltQuote() + meltProofs() + selectProofsForAmount()
src/screens/CashuPayment.tsx 6-state tap-to-pay screen
waiting → reading → spending → melting → success/error
Payment flow:
1. NFC: SELECT + GET_INFO + GET_PUBKEY + read unspent proof slots
2. Proof selection: greedy minimum-set covering amountCents
3. NFC: SPEND_PROOF × N — SHA256(P2PKsecret) → Schnorr sig per proof
4. API: createMeltQuote(mint, 'usd', bolt11) → quoteId
5. API: meltProofs(mint, quoteId, proofs+witness) → paid
6. Navigate to Success screen
Proof witness format: '{"signatures":["<64-byte-schnorr-hex>"]}'
Mint URL from CASHU_MINT_URL env (default: https://forge.flashapp.me)
Modified:
src/nfc/useCashuCard.ts added spendProof(slotIndex, msg) method
src/screens/Invoice.tsx added 'Pay with Flash Card' button
src/screens/Keypad.tsx stores usdCents in invoice slice on create
src/store/slices/invoiceSlice.ts added usdCents field
src/types/env.d.ts added CASHU_MINT_URL
src/types/routes.d.ts added CashuPayment route params
src/routes/index.tsx registered CashuPayment screen
Closes ENG-178
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Merchant screen for issuing Flash cards loaded with Cashu proofs (NUT-XX Profile B offline bearer payments).
New files
src/nfc/cashu-apdu.ts— APDU layer for CashuApplet (D2 76 00 00 85 01 02)src/nfc/useCashuCard.ts— IsoDep NFC session hook (NfcTech.IsoDep)src/graphql/cashu.ts—cashuCardProvisionmutation + proof helperssrc/screens/CashuProvision.tsx— 6-step provisioning screenFlow
cashuCardProvisionGQLSET_PIN+VERIFY_PIN+LOAD_PROOF × NTop-up: same flow, existing PIN used for
VERIFY_PIN(skipsSET_PIN).Depends on
cashuCardProvisionmutation — ENG-174/175)Next
ENG-178: tap-to-pay settlement screen (
SPEND_PROOF→ proof redemption at mint)