Problem
Numo POS currently only handles satoshis (SAT). However, mints like Cuba Bitcoin (mint.cubabitcoin.org) implement stablesat, allowing funds to be managed in SAT and USD.
The specific problem: When a user attempts to receive funds in USD (stablesat) from a mint that supports it:
- Funds are NOT added to the balance
- Do not appear in the history
- Tokens are rejected or silently lost
Note: The fiat currency (USD) shown in Numo is only price reference, not separate accounts. Payment is received in SAT or Stablesat according to the mint configuration.
Current Situation
Token Reception in Numo
Numo does have the token reception functionality implemented (CashuPaymentHelper.redeemToken()), but it's limited to SAT tokens only.
Numo uses the CDK library (org.cashudevkit:cdk-kotlin:0.15.1), which already supports multiple units (CurrencyUnit.Sat, CurrencyUnit.Usd). The problem is in Numo's code that has CurrencyUnit.Sat hardcoded.
In CashuPaymentHelper.kt:345-347:
if (cdkToken.unit() != CurrencyUnit.Sat) {
throw RedemptionException("Unsupported token unit: ${cdkToken.unit()}")
}
And at line 352:
val mintWallet = wallet.getWallet(mintUrl, CurrencyUnit.Sat)
The problem is:
- Unit detection exists (
cdkToken.unit())
- But it's explicitly rejected if not SAT
- Uses
CurrencyUnit.Sat hardcoded when getting the wallet
Example of the Problem
User tries to send $10 USD from Cuba Bitcoin to Numo:
→ CashuPaymentHelper detects it's USD unit
→ Throws exception "Unsupported token unit: USD"
→ The $10 USD are NOT added to balance
→ Do NOT appear in payment history
→ User loses their funds
Feasibility Analysis
✅ Implementation is feasible. The CDK library (org.cashudevkit:cdk-kotlin:0.15.1) already supports multiple units. The problem is only in Numo's code that has CurrencyUnit.Sat hardcoded in several places.
The Cuba Bitcoin mint already has USD implemented and working.
Proposed Solution
Implement per-unit fund reception in Numo:
Architecture
| Concept |
Implementation |
| Wallet per unit |
Each mintUrl:unit combination has its own balance |
| Example |
cubabitcoin.org → SAT account, USD account |
| Automatic detection |
Use keyset_id to identify the unit of the received token |
| Dual display |
Show SAT balance and USD balance separately |
Benefits
- Funds received correctly: USD tokens are credited to the corresponding account
- Complete history: All received payments are recorded with their original unit
- Clear display: The user knows exactly how much they have in each unit
Technical Implementation
Fix in CashuPaymentHelper
ndef/CashuPaymentHelper.kt
- Change validation to allow USD (currently rejects with "Unsupported token unit")
- Use
cdkToken.unit() instead of hardcoded CurrencyUnit.Sat
- Current code at lines 345-352:
// CURRENT (incorrect):
if (cdkToken.unit() != CurrencyUnit.Sat) {
throw RedemptionException("Unsupported token unit: ${cdkToken.unit()}")
}
val mintWallet = wallet.getWallet(mintUrl, CurrencyUnit.Sat)
// SHOULD BE:
val tokenUnit = cdkToken.unit()
val mintWallet = wallet.getWallet(mintUrl, tokenUnit)
Changes in CashuWalletManager
-
core/cashu/CashuWalletManager.kt
- Create/get wallets with appropriate
CurrencyUnit for each unit
- Maintain separate balances:
getBalanceForMintUnit(mintUrl, unit)
-
payment/LightningMintHandler.kt
- Create mint quotes with the correct
CurrencyUnit according to active unit
-
payment/SwapToLightningMintManager.kt
- Use destination mint's
CurrencyUnit when processing swaps
UI Changes
-
ui/components/PosUiCoordinator.kt
- Show dual balances:
₿ SAT | $ USD
- Allow selecting active unit for payments
-
core/data/model/PaymentHistoryEntry.kt (partially implemented)
- Ensure
unit and entryUnit are saved correctly
Compatible Mints
| Mint |
Supported Units |
Status |
mint.cubabitcoin.org |
SAT, USD |
✅ Verified and working |
Current Status
~30% of the infrastructure is already in place:
- ✅ Mint unit detection (NUT-04)
- ✅ Unit selector in MintDetailsActivity
- ✅ Fields
unit and entryUnit in PaymentHistoryEntry
- ✅
AmountDisplayManager with activeUnit
- 🔄 Pending: Implement reception and separate balances
Files to Modify
| Priority |
File |
Main Change |
| Critical |
ndef/CashuPaymentHelper.kt |
Allow USD, use token's unit |
| Critical |
core/cashu/CashuWalletManager.kt |
Create/get wallets by CurrencyUnit |
| Critical |
payment/LightningMintHandler.kt |
Use correct CurrencyUnit in mintQuote |
| Critical |
payment/SwapToLightningMintManager.kt |
Use destination mint's CurrencyUnit |
| Important |
ui/components/PosUiCoordinator.kt |
Show dual balances in UI |
Problem
Numo POS currently only handles satoshis (SAT). However, mints like Cuba Bitcoin (
mint.cubabitcoin.org) implement stablesat, allowing funds to be managed in SAT and USD.The specific problem: When a user attempts to receive funds in USD (stablesat) from a mint that supports it:
Note: The fiat currency (USD) shown in Numo is only price reference, not separate accounts. Payment is received in SAT or Stablesat according to the mint configuration.
Current Situation
Token Reception in Numo
Numo does have the token reception functionality implemented (
CashuPaymentHelper.redeemToken()), but it's limited to SAT tokens only.Numo uses the CDK library (
org.cashudevkit:cdk-kotlin:0.15.1), which already supports multiple units (CurrencyUnit.Sat,CurrencyUnit.Usd). The problem is in Numo's code that hasCurrencyUnit.Sathardcoded.In
CashuPaymentHelper.kt:345-347:And at line 352:
The problem is:
cdkToken.unit())CurrencyUnit.Sathardcoded when getting the walletExample of the Problem
Feasibility Analysis
✅ Implementation is feasible. The CDK library (
org.cashudevkit:cdk-kotlin:0.15.1) already supports multiple units. The problem is only in Numo's code that hasCurrencyUnit.Sathardcoded in several places.The Cuba Bitcoin mint already has USD implemented and working.
Proposed Solution
Implement per-unit fund reception in Numo:
Architecture
mintUrl:unitcombination has its own balancecubabitcoin.org→ SAT account, USD accountBenefits
Technical Implementation
Fix in CashuPaymentHelper
ndef/CashuPaymentHelper.ktcdkToken.unit()instead of hardcodedCurrencyUnit.SatChanges in CashuWalletManager
core/cashu/CashuWalletManager.ktCurrencyUnitfor each unitgetBalanceForMintUnit(mintUrl, unit)payment/LightningMintHandler.ktCurrencyUnitaccording to active unitpayment/SwapToLightningMintManager.ktCurrencyUnitwhen processing swapsUI Changes
ui/components/PosUiCoordinator.kt₿ SAT | $ USDcore/data/model/PaymentHistoryEntry.kt(partially implemented)unitandentryUnitare saved correctlyCompatible Mints
mint.cubabitcoin.orgCurrent Status
~30% of the infrastructure is already in place:
unitandentryUnitin PaymentHistoryEntryAmountDisplayManagerwithactiveUnitFiles to Modify
ndef/CashuPaymentHelper.ktcore/cashu/CashuWalletManager.ktpayment/LightningMintHandler.ktpayment/SwapToLightningMintManager.ktui/components/PosUiCoordinator.kt