Skip to main content

Overview

Sovran supports NFC (Near Field Communication) payments for contactless ecash transfers. Users can tap their device to a point-of-sale terminal or another device to send/receive Cashu tokens instantly.

NFC Architecture

The NFC implementation is modular and located in helper/nfc/:

Payment Hook

The useNfcEcashPayment hook provides a declarative interface for NFC payments:
From hooks/useNfcEcashPayment.tsx:29-219.

Payment Flow

The NFC payment flow consists of four phases:

Phase 1: Read Payment Request

  1. Acquire IsoDep technology
  2. Select AID (Application Identifier)
  3. Select NDEF file
  4. Read NLEN (NDEF length)
  5. Read NDEF content (chunked if > 250 bytes)
  6. Decode payment request
From helper/nfc/payment.ts:114-183.

Phase 2: Decode and Validate

  1. Decode NUT-18 payment request
  2. Extract amount, unit, allowed mints
  3. Validate amount against limit
  4. Wait for mint availability
  5. Select best mint
From helper/nfc/payment.ts:214-247.

Phase 3: Create Token

  1. Call createToken callback
  2. Generate ecash token for amount
  3. Encode as V4 token
From helper/nfc/payment.ts:249-265.

Phase 4: Write Token Back

  1. Re-select NDEF file
  2. Write NLEN
  3. Write NDEF content (chunked if > 250 bytes)
  4. Release NFC technology
From helper/nfc/payment.ts:267-307.

Token Recovery

If the write fails after token creation, the token is automatically recovered:
From hooks/useNfcEcashPayment.tsx:123-176.

Lightning Invoice Detection

NFC can detect Lightning invoices and redirect to Lightning flow:
From helper/nfc/payment.ts:198-212.

Mint Selection

The selectBestMint function chooses the optimal mint:
From helper/nfc/mint-selection.ts.

Payment Limit Tiers

Users select a payment limit before tapping:
From hooks/useNfcEcashPayment.tsx:197-205.

P2P Token Writing

Write tokens to NFC tags for peer-to-peer sharing:
From helper/nfc/write-token.ts:20-97.

Error Handling

Typed errors with user-friendly messages:
Error codes include:
  • NOT_SUPPORTED - NFC not available on device
  • NOT_ENABLED - NFC disabled in settings
  • TAG_LOST - Connection lost during operation
  • AMOUNT_EXCEEDED - Payment exceeds limit
  • NO_AVAILABLE_MINTS - No mints with balance
  • INVALID_AMOUNT - Invalid payment amount
  • TOKEN_CREATION_FAILED - Failed to create token
  • WRITE_CHUNK_FAILED - Failed to write token

Header Integration

NFC payment button in wallet header:
From app/(drawer)/(tabs)/index/_layout.tsx:70-97.

Key Features

Contactless Payments

Tap-to-pay at NFC-enabled point-of-sale terminals

Automatic Recovery

Token rollback if write fails after creation

Lightning Detection

Automatic detection and routing for Lightning invoices

Smart Mint Selection

Intelligent mint selection based on balance and restrictions