Skip to content

feat: add Invoice Key QR screen for LaChispaPOS integration#99

Open
Delgado74 wants to merge 6 commits into
lachispame:mainfrom
Delgado74:feature/invoice-key-clean
Open

feat: add Invoice Key QR screen for LaChispaPOS integration#99
Delgado74 wants to merge 6 commits into
lachispame:mainfrom
Delgado74:feature/invoice-key-clean

Conversation

@Delgado74

@Delgado74 Delgado74 commented May 3, 2026

Copy link
Copy Markdown
Contributor

Resolves #68


Description:
Adds a dedicated screen to display the invoice key (readKey) as a QR code, accessible from Settings. Enables POS integration and allows external apps to read the invoice key.


How it works:

  • New InvoiceKeyScreen accessible from Settings > Invoice Key QR
  • Displays the wallet's invoice key (readKey) as a QR code
  • Includes copy button for easy copying

Use Cases:

  • POS Integration: External POS apps can scan the QR to get the invoice key programmatically
  • Backup: Users can export their invoice key for backup purposes

Files Modified:

  • lib/screens/19invoice_key_screen.dart - New screen with QR code display
  • lib/screens/17settings_screen.dart - Added link to Invoice Key screen in Settings menu

Summary by CodeRabbit

  • New Features

    • Invoice Key QR screen: view invoice key as QR, toggle masked/unmasked text, copy to clipboard, and see security warnings and unavailable/empty states
    • New Invoice Key settings tile for quick access
  • Localization

    • Added pluralized currency count messaging and translated Invoice Key UI strings (copy success/failure, show/hide, titles, descriptions) for DE/EN/ES/FR/IT/PT/RU

Delgado74 added 3 commits May 3, 2026 04:28
- Add InvoiceKeyScreen with QR code display for readKey
- Use readKey with fallback to inKey (least privilege)
- Add 'Invoice Key QR' option in Settings screen
- Update localizations for all 7 supported languages
- Make readKey required in WalletInfo model
- Update WalletProvider to forward readKey when updating wallet

Resolves lachispame#68
- Add invoice_key localization strings for all 7 languages
- Add currency_count plural support for localized currency display
- Regenerate localization files
@coderabbitai

coderabbitai Bot commented May 3, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b8904c60-daac-4557-a283-0927f2a68bcc

📥 Commits

Reviewing files that changed from the base of the PR and between fc0b9e0 and d51e0ec.

⛔ Files ignored due to path filters (8)
  • lib/l10n/generated/app_localizations.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_de.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_en.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_es.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_fr.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_it.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_pt.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_ru.dart is excluded by !**/generated/**
📒 Files selected for processing (8)
  • lib/l10n/app_de.arb
  • lib/l10n/app_en.arb
  • lib/l10n/app_es.arb
  • lib/l10n/app_fr.arb
  • lib/l10n/app_it.arb
  • lib/l10n/app_pt.arb
  • lib/l10n/app_ru.arb
  • lib/screens/17settings_screen.dart
✅ Files skipped from review due to trivial changes (3)
  • lib/l10n/app_de.arb
  • lib/l10n/app_fr.arb
  • lib/l10n/app_en.arb
🚧 Files skipped from review as they are similar to previous changes (5)
  • lib/l10n/app_ru.arb
  • lib/l10n/app_pt.arb
  • lib/l10n/app_es.arb
  • lib/l10n/app_it.arb
  • lib/screens/17settings_screen.dart

📝 Walkthrough

Walkthrough

Adds an Invoice Key QR feature: WalletInfo readKey, localized strings (7 locales), Settings navigation tile, a new InvoiceKeyScreen (QR, masked/unmasked key, copy), and WalletProvider formatting edits.

Changes

Invoice Key QR Display

Layer / File(s) Summary
WalletInfo readKey field and serialization
lib/models/wallet_info.dart
Added readKey field to WalletInfo with constructor requirement and JSON serialization supporting readkey/read_key/readKey in fromJson() and emitting readkey in toJson().
Localization strings for invoice key QR feature
lib/l10n/app_de.arb, lib/l10n/app_en.arb, lib/l10n/app_es.arb, lib/l10n/app_fr.arb, lib/l10n/app_it.arb, lib/l10n/app_pt.arb, lib/l10n/app_ru.arb
Added currency_count ICU pluralization and invoice key QR strings (invoice_key_qr_title/description/subtitle, copy_invoice_key, invoice_key_copied, invoice_key_show/hide, invoice_key_copy_failed, invoice_key_unavailable_*, invoice_key_empty, invoice_key_security_warning) across all locales.
Settings screen refactoring and invoice key tile
lib/screens/17settings_screen.dart
Replaced token-driven theming with fixed white/translucent/Inter styling, updated header and settings item styling, and added an "Invoice Key QR" settings tile that navigates to InvoiceKeyScreen.
InvoiceKeyScreen widget implementation
lib/screens/19invoice_key_screen.dart
New stateful widget that derives the invoice key from WalletProvider.primaryWallet (prefers readKey, else inKey), shows QR, masked/unmasked key with visibility toggle, copy-to-clipboard with localized snackbars, and a security warning panel.
WalletProvider formatting and maintenance
lib/providers/wallet_provider.dart
Formatting-only reflow across persistence helpers, initialization, primary-wallet selection, balance refresh, create/delete flows, and toString(); no functional changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • lachispame/lachispa#75: Also modifies SettingsScreen theming and may overlap the settings UI/theming changes.

Poem

🐰 Hopping with joy, I code and I cheer,
A QR for invoices now crystal clear,
Masked keys, copy taps, and warnings that sing,
Settings lead the way — scan, share, and bring,
Business and rabbit rejoice — success is near!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely summarizes the main change: adding an Invoice Key QR screen for LaChispaPOS integration, which is the primary feature across all modified files.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from issue #68: created InvoiceKeyScreen with QR display and copy button, added readKey field to WalletInfo model, integrated Invoice Key QR option in Settings, and updated localizations for all supported languages (ES, EN, DE, FR, IT, PT, RU).
Out of Scope Changes check ✅ Passed All changes are directly related to the Invoice Key QR feature: localization strings for UI, WalletInfo model enhancement for readKey support, Settings integration, and the new InvoiceKeyScreen implementation. No out-of-scope or unrelated changes detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
lib/screens/19invoice_key_screen.dart (1)

119-121: 💤 Low value

Simplify the key selection logic for better readability.

The current nested ternary with repeated null-coalescing is harder to read than necessary. Consider extracting the readKey check to a local variable:

♻️ Proposed refactor
-        final invoiceKey = (wallet?.readKey ?? '').isEmpty
-            ? (wallet?.inKey ?? '')
-            : (wallet?.readKey ?? '');
+        final readKey = wallet?.readKey ?? '';
+        final invoiceKey = readKey.isNotEmpty ? readKey : (wallet?.inKey ?? '');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/screens/19invoice_key_screen.dart` around lines 119 - 121, The ternary
expression used to compute invoiceKey is repetitive and hard to read; simplify
by extracting wallet?.readKey into a local variable (e.g., final readKey =
wallet?.readKey ?? '') then compute invoiceKey using that variable and fallback
to wallet?.inKey (e.g., invoiceKey = readKey.isEmpty ? (wallet?.inKey ?? '') :
readKey) so you avoid repeating the null-coalescing and nested ternary and
improve readability around the invoiceKey computation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/models/wallet_info.dart`:
- Line 7: The constructor change for class WalletInfo made the field readKey
required, which breaks callers that construct WalletInfo directly; change the
WalletInfo constructor to make readKey optional with a default (e.g., empty
string) so existing code continues to compile, while leaving fromJson
(WalletInfo.fromJson) unchanged (it already falls back to ''), and ensure the
field declaration final String readKey remains compatible with the new
constructor signature.
- Line 7: The Invoice Key QR screen is preferring readKey over inKey which is
reversed; update the logic in the invoice_key_screen widget (the code that
selects the key for the QR and the security text) to prefer walletInfo.inKey
first and only fall back to walletInfo.readKey when inKey is absent, and ensure
any displayed warning text and QR payload reference the chosen key (symbols:
inKey, readKey, createInvoice(), checkInvoiceStatus()) so POS devices receive
the invoice-creation key.

---

Nitpick comments:
In `@lib/screens/19invoice_key_screen.dart`:
- Around line 119-121: The ternary expression used to compute invoiceKey is
repetitive and hard to read; simplify by extracting wallet?.readKey into a local
variable (e.g., final readKey = wallet?.readKey ?? '') then compute invoiceKey
using that variable and fallback to wallet?.inKey (e.g., invoiceKey =
readKey.isEmpty ? (wallet?.inKey ?? '') : readKey) so you avoid repeating the
null-coalescing and nested ternary and improve readability around the invoiceKey
computation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ebb27c17-05a0-4947-9f7c-a6cebfff42f4

📥 Commits

Reviewing files that changed from the base of the PR and between dbafc40 and fc0b9e0.

⛔ Files ignored due to path filters (8)
  • lib/l10n/generated/app_localizations.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_de.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_en.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_es.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_fr.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_it.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_pt.dart is excluded by !**/generated/**
  • lib/l10n/generated/app_localizations_ru.dart is excluded by !**/generated/**
📒 Files selected for processing (11)
  • lib/l10n/app_de.arb
  • lib/l10n/app_en.arb
  • lib/l10n/app_es.arb
  • lib/l10n/app_fr.arb
  • lib/l10n/app_it.arb
  • lib/l10n/app_pt.arb
  • lib/l10n/app_ru.arb
  • lib/models/wallet_info.dart
  • lib/providers/wallet_provider.dart
  • lib/screens/17settings_screen.dart
  • lib/screens/19invoice_key_screen.dart

final String name;
final String adminKey;
final String inKey;
final String readKey;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Breaking change: making readKey required may break existing code.

The constructor parameter is marked required (line 15), but this introduces a breaking change for any code that constructs WalletInfo objects directly. While fromJson safely handles missing values with an empty-string fallback (line 28), callers using the constructor directly will fail to compile without providing readKey.

Consider making readKey optional with a default value:

final String readKey;

WalletInfo({
  required this.id,
  required this.name,
  required this.adminKey,
  required this.inKey,
  this.readKey = '',  // Default to empty string
  required this.balanceMsat,
});

This preserves backward compatibility while still supporting the new field.

Also applies to: 15-15

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/models/wallet_info.dart` at line 7, The constructor change for class
WalletInfo made the field readKey required, which breaks callers that construct
WalletInfo directly; change the WalletInfo constructor to make readKey optional
with a default (e.g., empty string) so existing code continues to compile, while
leaving fromJson (WalletInfo.fromJson) unchanged (it already falls back to ''),
and ensure the field declaration final String readKey remains compatible with
the new constructor signature.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify LNBits key permission model and check if readKey can create invoices
rg -n -C3 'readKey|inKey' --type=dart -g '!**/l10n/**'

Repository: lachispame/lachispa

Length of output: 30508


🏁 Script executed:

# Search for the security warning mentioned in the review (app_en.arb:408)
find . -name "app_*.arb" -type f | head -5

Repository: lachispame/lachispa

Length of output: 173


🏁 Script executed:

# Look at the invoice key screen more closely
sed -n '115,125p' lib/screens/19invoice_key_screen.dart

Repository: lachispame/lachispa

Length of output: 490


🏁 Script executed:

# Check the app localization file for the security warning
rg -n "create invoices" -A2 -B2 --type=json

Repository: lachispame/lachispa

Length of output: 212


🏁 Script executed:

# Verify what operations actually use readKey vs inKey throughout the codebase
rg -n "\.readKey|\.inKey" lib/screens/ lib/services/ --type=dart | grep -E "(createInvoice|checkInvoice|readKey)" | head -20

Repository: lachispame/lachispa

Length of output: 245


🏁 Script executed:

# Check the security warning in app_en.arb around line 408
sed -n '400,420p' lib/l10n/app_en.arb

Repository: lachispame/lachispa

Length of output: 1044


🏁 Script executed:

# Search for references to the invoice key screen and its purpose
rg -n "invoice.*key|InvoiceKey" lib/screens/19invoice_key_screen.dart -A5 -B5 --type=dart | head -40

Repository: lachispame/lachispa

Length of output: 1400


🏁 Script executed:

# Check if readKey is used anywhere for actual invoice creation
rg -n "readKey" lib/services/ --type=dart -A2 -B2

Repository: lachispame/lachispa

Length of output: 45


🏁 Script executed:

# Look at the LNBits documentation or comments about key permissions
rg -n "readkey|inkey|read.*only|invoice.*creation" -i --type=dart lib/models/ lib/services/ | head -20

Repository: lachispame/lachispa

Length of output: 1657


🏁 Script executed:

# Final verification: check if readKey is ever used for any write operations
rg -n "readKey" lib/ --type=dart -A3 | grep -E "create|send|pay|invoice"

Repository: lachispame/lachispa

Length of output: 527


🏁 Script executed:

# Confirm: is readKey used anywhere except in invoice_key_screen?
rg -n "readKey" lib/ --type=dart --files-with-matches

Repository: lachispame/lachispa

Length of output: 164


Prefer inKey over readKey for the Invoice Key QR screen: the keys are reversed.

The logic in invoice_key_screen.dart (lines 119–121) currently prefers readKey and falls back to inKey. This is backwards:

  • LNBits key semantics: readKey is read-only; inKey creates invoices
  • Screen purpose: "Use this QR code with LaChispaPOS or other Lightning apps to receive payments" — requires invoice creation capability
  • Security warning: Correctly states "This key allows third parties to create invoices" — describing inKey, not readKey
  • All invoice operations throughout the codebase use inKey: createInvoice(), checkInvoiceStatus(), and Lightning Address setup
  • readKey is unused for any write operations in the entire codebase

The current implementation exposes a read-only key to POS devices, breaking payment reception. Swap the preference: use inKey first, fall back to readKey.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/models/wallet_info.dart` at line 7, The Invoice Key QR screen is
preferring readKey over inKey which is reversed; update the logic in the
invoice_key_screen widget (the code that selects the key for the QR and the
security text) to prefer walletInfo.inKey first and only fall back to
walletInfo.readKey when inKey is absent, and ensure any displayed warning text
and QR payload reference the chosen key (symbols: inKey, readKey,
createInvoice(), checkInvoiceStatus()) so POS devices receive the
invoice-creation key.

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.

Feature: Mostrar QR de Invoice Key para integración con LaChispaPOS

1 participant