Compare commits

..

1 commit
v0.0.4 ... main

Author SHA1 Message Date
Patrick Mulligan
c4f784360d Fix Pay User lightning payment bugs
- Fix default amount showing fiat instead of sats when lightning payment selected
- Fix invoice response field name (bolt11 instead of payment_request)
- Fix NameError in payables/pay endpoint (wallet -> auth.user_id)
- Add get_user_wallet_settings_by_prefix() for truncated 8-char user IDs
- Update user-wallet endpoint to handle truncated IDs from Beancount accounts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 07:17:12 -05:00
3 changed files with 40 additions and 5 deletions

20
crud.py
View file

@ -424,6 +424,26 @@ async def get_user_wallet_settings(user_id: str) -> Optional[UserWalletSettings]
)
async def get_user_wallet_settings_by_prefix(
user_id_prefix: str,
) -> Optional[StoredUserWalletSettings]:
"""
Get user wallet settings by user ID prefix (for truncated 8-char IDs from Beancount).
Beancount accounts use truncated user IDs (first 8 chars), but the database
stores full UUIDs. This function looks up by prefix to bridge the gap.
"""
return await db.fetchone(
"""
SELECT * FROM user_wallet_settings
WHERE id LIKE :prefix || '%'
LIMIT 1
""",
{"prefix": user_id_prefix},
StoredUserWalletSettings,
)
async def update_user_wallet_settings(
user_id: str, data: UserWalletSettings
) -> UserWalletSettings:

View file

@ -1424,7 +1424,7 @@ window.app = Vue.createApp({
maxAmount: maxAmountSats, // Positive sats amount castle owes
maxAmountFiat: maxAmountFiat, // EUR or other fiat amount (positive)
fiatCurrency: fiatCurrency,
amount: fiatCurrency ? maxAmountFiat : maxAmountSats, // Default to fiat if available
amount: maxAmountSats, // Default to sats since lightning is the default payment method
payment_method: 'lightning', // Default to lightning for paying
description: '',
reference: '',
@ -1456,8 +1456,9 @@ window.app = Vue.createApp({
memo: `Payment from Castle to ${this.payUserDialog.username}`
}
)
console.log(invoiceResponse)
const paymentRequest = invoiceResponse.data.payment_request
const paymentRequest = invoiceResponse.data.bolt11
// Pay the invoice from Castle's wallet
const paymentResponse = await LNbits.api.request(

View file

@ -2113,7 +2113,7 @@ async def api_pay_user(
if "meta" not in entry:
entry["meta"] = {}
entry["meta"]["payment-method"] = data.payment_method
entry["meta"]["paid-by"] = wallet.wallet.user
entry["meta"]["paid-by"] = auth.user_id
if data.txid:
entry["meta"]["txid"] = data.txid
@ -2174,10 +2174,24 @@ async def api_get_user_wallet(
user_id: str,
auth: AuthContext = Depends(require_super_user),
) -> dict:
"""Get user's wallet settings (super user only)"""
"""Get user's wallet settings (super user only)
Supports both full UUIDs and truncated 8-char IDs (from Beancount accounts).
"""
from .crud import get_user_wallet_settings_by_prefix
# First try exact match
user_wallet = await get_user_wallet(user_id)
if not user_wallet:
# If not found and user_id looks like a truncated ID (8 chars), try prefix match
if not user_wallet or not user_wallet.user_wallet_id:
if len(user_id) <= 8:
stored_wallet = await get_user_wallet_settings_by_prefix(user_id)
if stored_wallet and stored_wallet.user_wallet_id:
user_wallet = stored_wallet
user_id = stored_wallet.id # Use the full ID
if not user_wallet or not user_wallet.user_wallet_id:
return {"user_id": user_id, "user_wallet_id": None}
# Get invoice key for the user's wallet (needed to generate invoices)