Spark Wallet Integration - Pull Request#40
Draft
dmnyc wants to merge 34 commits intoYakiHonne:mainfrom
Draft
Conversation
Major improvements to Spark wallet UI and functionality: Profile & Wallet Linking: - Fix wallet link detection for Spark wallets (kind 4) - Add sparkLightningAddress to Redux selectors - Update checkIsLinked() to compare Lightning addresses with profile lud16 - Hide "wallet not linked" warning when Spark address matches profile Send/Receive UI Improvements: - Match NWC design patterns for consistency - Add close (X) buttons to Send and Receive tabs - Implement "Use invoice" toggle switch in Send tab - Reorder fields: Message (optional) → Amount → Button - Update button labels: "Send Payment" → "Send", "Generate Invoice" → "Generate invoice" Payment History Enhancements: - Add expandable payment details with +/− toggle button - Display comprehensive info: ID, status, amount, fees, time, description, hash, preimage - Add copy-to-clipboard for Payment ID, Payment Hash, and Preimage - Integrate Sparkscan blockchain explorer links - Use correct Sparkscan URL format: https://www.sparkscan.io/tx/{id}?network=mainnet Payment Pagination: - Implement offset-based pagination (20 payments per batch) - Add "Load More" button for infinite scroll - Support append mode for seamless history loading Bug Fixes: - Fix payment direction detection (handle lowercase 'send'/'receive') - Properly convert BigInt amounts to Number for display - Add color-coded status labels (green/orange/red) Files modified: - src/(PagesComponents)/Wallet.js - src/Components/Spark/SparkWalletManager.js - src/Components/Spark/SparkPaymentsList.js - src/Helpers/Spark/spark-wallet-manager.js - DEV_NOTES.md
## Error Handling & User Experience - Convert all wallet connection errors to user-friendly toast notifications - Add specific error messages for NWC relay failures and authorization issues - Implement INSUFFICIENT_FUNDS detection with user-friendly messaging - Change console.log to console.warn for handled errors to prevent Next.js error overlay - Ensure users never see technical runtime errors ## Wallet Linking Fix - Fix "None of connected wallets are linked" appearing incorrectly when switching wallets - Update checkIsLinked() to check all wallets against profile address, not just selected wallet - Users can now switch between Spark, NWC, and Alby without false warnings - Properly recognize Spark Lightning addresses when viewing other wallet types ## Loading State Improvements - Eliminate "Wallet not connected" flash on page refresh - Add proper loading states showing "Connecting wallet..." with animation - Hide balance display during Spark wallet connection instead of showing "N/A" - Add sparkConnecting state check in SparkWalletManager component - Improve sidebar balance behavior when Spark not connected ## UI Layout & Responsive Design - Fix overflow issue where eyeball icon was pushed out by large USD values - Add text truncation with ellipsis for very large balance numbers - Improve number formatting with thousand separators - Add mobile wallet icon in sidebar for narrow viewports - Implement proper flexbox layout to prevent UI breaking with large balances ## Translation & Internationalization - Add 9 new translation keys across all 11 languages: - "Wallet not connected" - "Connecting wallet..." - SparkBackupInvalidJson - SparkBackupWrongAccount - SparkBackupInvalidFormat - SparkBackupUnsupportedVersion - SparkBackupDecryptFailed - SparkWalletUnableReceive - SparkWalletUnableSend - Update generic copy message from "LNURL was copied" to "Copied to clipboard!" ## Code Cleanup - Remove all debug console.log statements - Clean up temporary debugging code - Maintain only console.error for actual failures and console.warn for handled errors - Add descriptive labels to all production logging ## Documentation Updates - Update DEV_NOTES.md with 2025-11-04 changelog entry - Add comprehensive Production Deployment Checklist - Update "Lessons Learned" with 5 new insights - Add Lightning Address Configuration section to Spark README - Document custom domain setup option (@yakihonne.com vs @breez.tips) - Mark completed improvements in "What Could Be Improved" section ## Files Modified (29 files) - Core: Wallet.js, UserBalance.js, SatsToUSD.js - Spark: SparkWalletManager.js, SparkWalletSetup.js, spark.service.js - Translations: All 11 language files (en, zh, fr, es, it, pt, th, ja, ar, hi) - Docs: DEV_NOTES.md, src/Components/Spark/README.md This release improves error handling, eliminates UI flashes, adds mobile support, and prepares the Spark wallet integration for production deployment.
- Add @breeztech/breez-sdk-spark to transpilePackages - Enable webpack layers experiment - Add .wasm to resolve.extensions - Convert Breez SDK imports to dynamic imports (client-side only) - Prevents SSR issues with WebAssembly modules
- Install copy-webpack-plugin - Configure webpack with syncWebAssembly and asyncWebAssembly experiments - Add NormalModuleReplacementPlugin to handle wbg internal imports - Create wbg-shim.js placeholder for WASM internal bindings - Maintain server-side externals for Breez SDK
Feature/breez spark wallet
- Remove wbg-shim workaround (was causing issues) - Simplify webpack config to only use asyncWebAssembly - Remove copy-webpack-plugin dependency - Add better error logging to spark.service.js for WASM init failures - Add server-side external for @breeztech/breez-sdk-spark/web
- Create wbg-stub.js to satisfy webpack module resolution - Add NormalModuleReplacementPlugin to replace wbg imports - WASM bindings are handled at runtime, stub is just for build - Local build successful, WASM bundled to static/wasm/
Problem: The error "e.replace is not a function" occurred because
import.meta.url is not properly resolved by webpack in Vercel's
build environment, causing Breez SDK WASM initialization to fail.
Solution:
- Add postinstall script to copy WASM file to public/wasm/
- Pass explicit WASM path to initBreezSDK() instead of relying on
import.meta.url resolution
- Ensures WASM file is accessible at /wasm/breez_sdk_spark_wasm_bg.wasm
Changes:
- package.json: Add postinstall script for WASM file deployment
- src/Helpers/Spark/spark.service.js: Use explicit path in initializeWasm()
- public/wasm/: Add breez_sdk_spark_wasm_bg.wasm (6.8MB)
Problem: import.meta.url not resolved by webpack, causing "e.replace is not a function" error during WASM initialization. Solution: - Treat Breez WASM as asset/resource for webpack bundling - Dynamically import WASM to get webpack-resolved path - Pass resolved path to SDK init instead of relying on import.meta.url - Use IgnorePlugin for internal wbg imports Files changed: - next.config.mjs: Configure WASM as asset/resource, add IgnorePlugin - spark.service.js: Import WASM dynamically, pass to initBreezSDK() - package.json: Remove postinstall script Build output: WASM bundled to /_next/static/wasm/[hash].wasm
- Add guards to getLinkFromAddr() in Helpers.js - Add guards to decodeNip19() in Helpers.js - Add guard to compactContent() in ClientHelpers.js - Prevents 'Cannot read properties of undefined (reading replaceAll)' errors - Fixes issue when rendering Spark wallet payment details on Vercel
- Add prominent loading spinner with progress messages - Show 'Reading backup file...', 'Initializing Lightning Network...', 'Syncing wallet...' - Full-screen overlay with darkened background for better visibility - Addresses UX issue where 50+ second wallet restoration had minimal feedback - Add spin animation keyframe for loading spinner This provides much better user feedback during the lengthy WASM initialization and Lightning network sync process.
… instead of 'Initializing Lightning Network...'
Merges latest upstream changes while preserving Spark wallet integration: Upstream changes: - Add notification system with real-time updates - Add multi-currency support (fiat selector) - Add Russian language translations - Improve muted list handling with allTags support - Add relay sets management features - Add search relays configuration - Add WOT (Web of Trust) explanation page - Improve DM decryption with worker threads - Add dynamic windowed feed for performance - Various UI/UX improvements and bug fixes Spark wallet features preserved: - All Spark wallet integration files maintained - Redux state for Spark wallet (7 slices) - Wallet balance display now uses improved UI - Compatible with new currency selector feature Resolved conflicts in: - Wallet.js (merged balance display improvements) - AppInit.js (adopted upstream muted list handling) - SatsToUSD.js (merged multi-currency support) - Store.js (added both notification and Spark reducers) - AddWallet.js (removed unnecessary 'use client') 197 files changed, 11744 insertions(+), 5717 deletions(-)
- Change default import to named import for relaysOnPlatform - Update pnpm-lock.yaml after installing react-virtuoso - Regenerate service worker after build Fixes build error: '@/Content/Relays' does not contain a default export
- Update @breeztech/breez-sdk-spark from 0.3.4 to 0.5.2 - Add event-based sync workaround for SDK promise bug - Enable private mode by default (required for recent-payment-pfps) - Fix refreshWalletState to avoid redundant sync calls The SDK 0.5.2 syncWallet() promise doesn't resolve, but the dataSynced event fires correctly. Created syncWalletWithEvent() method to listen for the event instead of waiting for the promise. Also prevents refreshWalletState from triggering another sync via getInfo(ensureSynced=false), since we already synced during connection.
Updated dependencies to fix Next.js CVE vulnerabilities. The fix-react2shell-next tool automatically updated the following packages to their secure versions: - next - react-server-dom-webpack - react-server-dom-parcel - react-server-dom-turbopack All package.json files have been scanned and vulnerable versions have been patched to the correct fixed versions based on the official React advisory. Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
…o-uyt99o Fix React Server Components RCE vulnerability
- Suppress harmless RecvError during wallet disconnect/delete operations - Added global console.error interceptor to catch WASM sync errors - Improved async error handling in disconnect() method - Prevents confusing error messages during normal cleanup - Enable privacy mode by default - Hide payment IDs and Sparkscan block explorer links - Protects user privacy by preventing on-chain correlation - Add Spark wallet auto-connect on app initialization - Automatically restores active Spark wallet when user logs in - Ensures wallet is available across all app pages - Fix null reference errors - Add null checks in getFavRelays() for undefined tags - Prevents crashes when favorite relay data is incomplete - Add comprehensive zap profile investigation documentation - Documents 3 implementation attempts for displaying zap sender profiles - Explains SDK 0.5.2 limitations and SDK 0.6.x requirements - Provides roadmap for future feature implementation Based on Breez SDK 0.5.2 with event-based sync workaround.
- Upgrade Next.js to 15.5.9 (patches CVE-2025-66478 security vulnerability) - Fix method name bug: checkUsernameAvailability -> checkLightningAddressAvailable - Make initial wallet sync non-blocking to prevent UI freezing - Add comprehensive error suppression for harmless SDK disconnect errors - Reorder wallet options to prioritize Spark (self-custodial) over NWC - Remove deprecated Sparkscan blockchain explorer references - Update documentation with SDK 0.5.2 and privacy mode details These changes resolve WASM runtime errors, security vulnerabilities, and improve wallet stability while maintaining full functionality for create, restore, and delete.
- Complete feature list with actual implementation details - Clarifies backup strategy (downloadable files, not Nostr relays) - Documents 3 wallet setup methods and 4-tab wallet manager UI - Includes work-in-progress section for payment profile display - Notes optional Nostr backup infrastructure for future use
- Fix misleading Nostr backup references in SPARK_WALLET_INTEGRATION.md - Update QUICK_START_SPARK.md to reflect file-based backups - Add Claude Code credit to PR_SUMMARY.md Credits section - Clarify that Nostr backup infrastructure exists but is disabled for YakiHonne UX - All docs now accurately reflect downloadable backup file strategy
- Change 'Pay breez.tips user' to 'Pay YakiHonne user' in registerLightningAddress - Ensures proper branding in Lightning address metadata
- Add proactive IndexedDB clearing before each connection to prevent WASM corruption - Clean mnemonics at all entry points (restore, file upload, auto-restore) to remove non-ASCII characters - Fix Redux serialization warning by converting Map to plain object - Fix config property name (privateEnabledDefault vs private_enabled_default) - Add comprehensive mnemonic validation in wallet manager
Root Cause: - Two components (AppInit.js and Wallet.js) were independently calling restoreWallet() on page load, creating a race condition - Concurrent WASM SDK calls caused memory corruption errors: 'closure invoked recursively', 'memory access out of bounds' Fix: - AppInit.js: Single centralized auto-restore point with isConnected() guard - Wallet.js: Removed duplicate restore logic, only refreshes if connected - Added defensive mnemonic validation and connection guards This follows the correct architectural pattern used in working Breez SDK implementations - single initialization point prevents WASM race conditions.
- Fix zap request encoding (encodeURI -> encodeURIComponent) - Fix payment status check (completed -> complete) - Fix payment response structure (return response.payment) - Add waitForPaymentCompletion to wait for async payment events - Fix QR code showing during active payment sending Fixes 4 critical bugs preventing zaps from working correctly.
Contributor
|
Thanks for the contribution, it was an amazing job integrating the Spark wallet in all the necessary places, although, there are rooms for improvement design wise to fully blend with YakiHonne UI/UX, but it's working greatly! |
…ibility - Add NIP-44 v2 encryption for wallet backups (ChaCha20, HKDF-SHA256, HMAC-SHA256) - Maintain full backward compatibility with NIP-04 v1 backups - Support Primal's hybrid v2/NIP-04 backup format via smart encryption detection - Graceful fallback to NIP-04 for browser extensions without NIP-44 support - Add console logging to indicate which encryption method is being used Security improvements: - 5x faster encryption (101K ops/sec vs 19K ops/sec) - HKDF key derivation prevents key exposure attacks - HMAC authentication prevents tampering - Cure53 audited (December 2023) Backward compatibility: - Detects encryption via: explicit field, format pattern (?iv=), or version number - Can restore from v1 (NIP-04), v2 (NIP-44), and v2 (NIP-04) backups - Browser extensions without NIP-44 automatically use NIP-04 fallback
bae04f3 to
9cb0d60
Compare
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.
Overview
This PR introduces a complete integration of Breez SDK Spark into YakiHonne, providing users with a self-custodial Lightning wallet option alongside the existing custodial NWC wallet. The integration enables seamless Bitcoin Lightning payments directly within the YakiHonne platform with full privacy mode support.
Branch:
feat/spark-wallet-integrationBase:
upstream/mainChanges: 45 files changed, 25,120 insertions(+), 332 deletions(-)
Commits: 26
Key Features
✅ Core Wallet Functionality
✅ Wallet Operations (SparkWalletManager with 4 Tabs)
Send Tab
Receive Tab
Transactions Tab
Settings Tab
Balance Display Widget
✅ Backup & Recovery
Downloadable Encrypted Backups (Current Implementation)
Seed Phrase Access
Wallet Restoration Methods
Note on Nostr Relay Backup: The codebase includes infrastructure for optional Nostr-based backups (NIP-78 encrypted storage), but this feature is intentionally disabled in the current build to maintain YakiHonne's UX principle of downloadable, user-controlled backups. This could be enabled as a future enhancement if desired.
✅ Payment History
Comprehensive Transaction List
Payment Details
✅ Zap Integration
Nostr Zap Receipts
Payment Gateway Integration
✅ User Experience
Onboarding Flow
Wallet Setup (3 Methods)
Full-Screen Loading States
✅ WASM & Deployment
Vercel Compatibility
Security
Technical Implementation
New Dependencies
Architecture
Service Layer (
src/Helpers/Spark/)spark.service.js- Core SDK wrapper and connection managementspark-wallet-manager.js- High-level wallet operations coordinatorspark-backup.service.js- Backup and restore functionalityspark-storage.service.js- Persistent storage (IndexedDB)spark-zap-receipt.service.js- Nostr zap receipt publishingspark-profile-sync.service.js- Profile data synchronizationUI Components (
src/Components/Spark/)SparkWalletSetup.js- Complete onboarding wizard with 4 setup methodsSparkWalletManager.js- Main wallet interface with Send/Receive/Transactions/Settings tabsSparkPaymentsList.js- Transaction history with expandable payment detailsSparkBalanceDisplay.js- Balance widget with compact/full modes and USD conversionState Management (
src/Store/)SparkWallet.js- Redux slice for Spark wallet stateStore.jsStyling
src/styles/spark-wallet.css- Complete UI styling (593 lines)Key Technical Decisions
Modified Core Files
src/(PagesComponents)/Login.js- Added Spark wallet to onboardingsrc/Components/AddWallet.js- Added Spark wallet optionsrc/Components/PaymentGateway.js- Integrated Spark into payment flowsrc/Components/UserBalance.js- Added Spark balance displaysrc/Helpers/DB.js- Added Spark wallet storage tablessrc/Helpers/Controlers.js- Added Spark controller methodssrc/Store/Store.js- Added SparkWallet slicenext.config.js- WASM webpack configurationpackage.json- Breez SDK dependencyDocumentation
New Documentation Files
SPARK_WALLET_INTEGRATION.md- Complete integration guideDEV_NOTES.md- Updated with Spark wallet detailsSPARK_ARCHITECTURE.md- Technical architecture documentationCHANGELOG.md- Updated with all Spark wallet changesChangelog Highlights
2025-12-13: Spark Wallet v0.5.2 Integration
Testing
Tested Scenarios
✅ New wallet creation
✅ Wallet restoration from seed phrase
✅ Sending Lightning payments (bolt11, LNURL, Lightning address)
✅ Receiving Lightning payments
✅ Balance synchronization
✅ Backup and restore functionality
✅ Payment history display
✅ Zap receipt publishing
✅ Auto-connect on app reload
✅ Vercel deployment
✅ WASM module loading
✅ Error handling and recovery
Known Working Environments
Work In Progress / Future Enhancements
The following features are planned for future iterations:
🚧 Payment Profile Display
Current State: Payment history shows transaction details without sender/recipient information
Planned Enhancement:
Technical Approach:
UserProfilePiccomponentFiles to Modify:
src/Components/Spark/SparkPaymentsList.jssrc/Helpers/Spark/spark-zap-receipt.service.js🚧 Additional Planned Features
Nostr Relay Backup (Infrastructure exists, feature disabled)
createWallet(true)instead ofcreateWallet(false)Channel Management UI - Visual display of Lightning channel states
Fee Optimization - Automatic routing optimization for lower fees
Payment Filtering - Filter payment history by type, date, amount
Export Functionality - Export payment history as CSV/JSON
Multi-Currency Display - Show balances in USD, EUR, etc.
Advanced Privacy Controls - User-configurable privacy settings
Submarine Swaps - On-chain to Lightning swaps via Breez
LNURL-withdraw - Support for LNURL withdraw flow
Migration Notes
For Existing Users
For New Users
Security Considerations
What's Protected
✅ Private keys stored in encrypted IndexedDB
✅ Seed phrases never sent over network unencrypted
✅ Nostr backups use NIP-04 self-encryption
✅ Privacy mode enabled by default
✅ No analytics or tracking of wallet operations
User Responsibilities
Performance Impact
Breaking Changes
None - This is a purely additive feature. All existing functionality remains unchanged.
Dependencies
Added
@breeztech/breez-sdk-spark@^0.5.2- Lightning wallet SDKUpdated
next@15.5.9- Security patch for CVE-2025-66478react@^19.1.0- Latest stablereact-dom@^19.1.0- Latest stableDeployment Checklist
Before merging:
Screenshots
Demo
Live demo available at: https://sparkihonne.vercel.app
Test the following flows:
Questions & Support
For questions about this PR:
SPARK_WALLET_INTEGRATION.mdfor implementation detailsDEV_NOTES.mdfor development setupSPARK_ARCHITECTURE.mdfor architecture overviewCredits
Integration developed using:
License
This integration maintains the same license as the YakiHonne project.
Reference
This project was developed for the Time2Build worldwide developer challenge to bring bitcoin to the world's leading open-source applications and services using the Breez SDK.