-
Notifications
You must be signed in to change notification settings - Fork 4
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Feature: Nostr Wallet Connect (NWC / NIP-47) Support
Overview
Implement Nostr Wallet Connect (NIP-47) as a "wallet service" in the Flash stack, allowing external Nostr-enabled apps to send Lightning payments from a user's Flash wallet using a connection URI, subject to configurable spending limits.
Goals
- Users can create NWC connections from the Flash mobile app
- Each connection has independent spending limits (separate from account limits)
- External apps can use NWC URIs to send Lightning payments without manual confirmation
- Users can view, manage, and revoke connections at any time
- Full NIP-47 compliance with encryption (NIP-44/NIP-04)
References
- NIP-47 Spec: https://nips.nostr.com/47
- NWC Docs: https://docs.nwc.dev
- Flash Backend: https://github.com/lnflash/flash
- Flash Mobile: https://github.com/lnflash/flash-mobile
Implementation Plan - 7 PRs
Each PR is independently deployable and reviewable.
PR #1: NWC Foundation & Feature Flag
~280 lines | Backend
Deliverables:
- MongoDB schema for
NwcConnectioncollection - TypeScript types for NWC connection records
- Repository pattern implementation (
NwcConnectionsRepository) - Database migration script
- Feature flag environment variable (
NWC_ENABLED) - Unit tests for repository CRUD operations
Files:
flash/src/services/mongoose/schema.tsflash/src/services/mongoose/schema.types.d.tsflash/src/services/mongoose/nwc-connections.tsflash/src/migrations/[timestamp]-add-nwc-connections.tsflash/src/config/index.tsflash/test/unit/services/nwc/repository.spec.ts
Deployment:
- Run migration, feature flag defaults to
false, no user-facing changes
PR #2: NIP-47 Protocol Layer
~250 lines | Backend
Deliverables:
- NIP-47 encryption/decryption utilities (NIP-44 & NIP-04)
- Request/response type definitions
- Info event creation (kind 13194)
- Notification event creation (kind 23197)
- NWC URI generator utility
- Unit tests for all crypto functions
Files:
flash/src/services/nostr/nip47.tsflash/src/services/nwc/uri-generator.tsflash/test/unit/services/nostr/nip47.spec.ts
Deployment:
- Pure utilities, no side effects, independently testable
PR #3: NWC Wallet Service Daemon
~450 lines | Backend
Deliverables:
-
NwcWalletServiceclass with relay management - Nostr relay subscription handling
- Request event processing (
pay_invoice,get_balance,get_info) - NWC-specific spending limit enforcement (separate from account limits)
- Integration with existing
Payments.payInvoiceByWalletId() - Server entry point (
nwc-wallet-service.ts) - Package.json script to run service
- Unit tests for limit checking and request handling
Files:
flash/src/services/nwc/wallet-service.tsflash/src/servers/nwc-wallet-service.tsflash/package.jsonflash/test/unit/services/nwc/wallet-service.spec.tsflash/test/unit/services/nwc/limits.spec.ts
Deployment:
- Service binary deployable, only starts if
NWC_ENABLED=true - No user-facing impact yet
PR #4: GraphQL API Layer
~380 lines | Backend
Deliverables:
- GraphQL object types (
NwcConnection,NwcConnectionStatus) - GraphQL input types (
NwcConnectionCreateInput,NwcConnectionRevokeInput) -
nwcConnectionCreatemutation (generates NWC URI) -
nwcConnectionRevokemutation -
nwcConnectionsquery - Feature flag checks in resolvers
- Integration tests for all GraphQL operations
- Authorization tests (users can only manage own connections)
Files:
flash/src/graphql/public/types/object/nwc-connection.tsflash/src/graphql/public/types/input/nwc-connection.tsflash/src/graphql/public/root/mutation/nwc-connection-create.tsflash/src/graphql/public/root/mutation/nwc-connection-revoke.tsflash/src/graphql/public/root/query/nwc-connections.tsflash/src/graphql/public/mutations.tsflash/src/graphql/public/queries.tsflash/test/integration/graphql/nwc-mutations.spec.ts
Deployment:
- GraphQL endpoints available but gated by feature flag
- Backend complete, ready for mobile integration
Key Technical Decisions
Code Reuse Strategy
- Nostr Pool: Reuse existing
poolfrom/flash/src/utils/nostr.ts - Payment Flow: Use
Payments.payInvoiceByWalletId()(existing) - Invoice Validation: Use
decodeInvoice()(existing) - Repositories: Follow existing Mongoose repository patterns
- GraphQL: Follow existing mutation/query structure patterns
- Mobile UI: Reuse
SettingsRow,GaloyPrimaryButton,GaloyInputcomponents - QR Codes: Use existing
react-native-qrcode-svgintegration
NWC-Specific Limits (Separate from Account Limits)
- Independent tracking:
totalSpentSats,spendingResetAtonNwcConnection - Connection-level limits:
spendingLimitSats,maxSinglePaymentSats,spendingPeriodHours - Separate validation in
checkNwcLimits()method - Account limits still enforced as secondary safeguard via existing payment flow
Feature Flag Strategy
Backend:
NWC_ENABLED=true|false // Main feature toggle
NWC_DEFAULT_RELAYS=wss://relay1,wss://relay2
NWC_DEFAULT_SPENDING_LIMIT_SATS=50000
GraphQL:
- Mutations/queries return error if NWC_ENABLED=false
Mobile:
- Settings row conditionally shown based on backend feature availability
- Query nwcConnections to detect backend support
---
Deployment & Rollout Plan
| Step | Action | Impact |
|------|--------------------------------------------------|----------------------------|
| 1 | Deploy PRs #1-4 to prod with NWC_ENABLED=false | No user impact |
| 2 | Test on staging with NWC_ENABLED=true | Verify full backend |
| 3 | Deploy PRs #5-7 to mobile (app store submission) | Users see disabled feature |
| 4 | Enable NWC_ENABLED=true in production | Feature goes live |
| 5 | Monitor logs, limits, and error rates | Operational monitoring |
| 6 | Announce feature to users | Documentation & support |
Rollback Plan
- Set NWC_ENABLED=false to disable feature
- Stop nwc-wallet-service daemon
- Mobile app gracefully hides settings row
---
Testing Strategy
Unit Tests
- Repository CRUD operations (PR #1)
- NIP-47 encryption/decryption (PR #2)
- NWC limit checking logic (PR #3)
- GraphQL resolvers (PR #4)
- Mobile component rendering (PR #6, #7)
Integration Tests
- GraphQL mutation/query flows (PR #4)
- Payment flow with mock Nostr relay (PR #3)
- E2E mobile flow: create → display → copy (PR #7)
Manual Testing
- Connect external NWC client (e.g., Amethyst, Alby)
- Verify payments work end-to-end
- Test limit enforcement (single payment & period limits)
- Test connection revocation
- Test error scenarios (expired invoice, insufficient balance, etc.)
---
Success Criteria
- Users can create NWC connections with custom limits
- External Nostr apps can pay Lightning invoices via NWC URI
- Spending limits enforced correctly (connection-level)
- Users can view connection usage and revoke access
- NIP-47 spec compliance verified
- No existing payment flows broken
- Documentation complete (user + developer)
- Feature flag allows safe rollout
---
Dependencies
- nostr-tools (already in backend & mobile)
- react-native-qrcode-svg (already in mobile)
- @react-native-clipboard/clipboard (already in mobile)
- MongoDB 4.4+
- Redis (for existing infra)Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request