Add source wallet ID support for DCA distributions: update Lamassu configuration to include source_wallet_id, modify related models and CRUD operations, and enhance transaction processing to utilize the configured source wallet for payments. Update UI components to allow selection of the source wallet.

This commit is contained in:
padreug 2025-06-19 16:35:11 +02:00
parent 1388133f22
commit 1c1f358d82
6 changed files with 58 additions and 18 deletions

View file

@ -309,9 +309,9 @@ async def create_lamassu_config(data: CreateLamassuConfigData) -> LamassuConfig:
await db.execute( await db.execute(
""" """
INSERT INTO myextension.lamassu_config INSERT INTO myextension.lamassu_config
(id, host, port, database_name, username, password, is_active, created_at, updated_at, (id, host, port, database_name, username, password, source_wallet_id, is_active, created_at, updated_at,
use_ssh_tunnel, ssh_host, ssh_port, ssh_username, ssh_password, ssh_private_key) use_ssh_tunnel, ssh_host, ssh_port, ssh_username, ssh_password, ssh_private_key)
VALUES (:id, :host, :port, :database_name, :username, :password, :is_active, :created_at, :updated_at, VALUES (:id, :host, :port, :database_name, :username, :password, :source_wallet_id, :is_active, :created_at, :updated_at,
:use_ssh_tunnel, :ssh_host, :ssh_port, :ssh_username, :ssh_password, :ssh_private_key) :use_ssh_tunnel, :ssh_host, :ssh_port, :ssh_username, :ssh_password, :ssh_private_key)
""", """,
{ {
@ -321,6 +321,7 @@ async def create_lamassu_config(data: CreateLamassuConfigData) -> LamassuConfig:
"database_name": data.database_name, "database_name": data.database_name,
"username": data.username, "username": data.username,
"password": data.password, "password": data.password,
"source_wallet_id": data.source_wallet_id,
"is_active": True, "is_active": True,
"created_at": datetime.now(), "created_at": datetime.now(),
"updated_at": datetime.now(), "updated_at": datetime.now(),

View file

@ -188,3 +188,15 @@ async def m009_add_username_to_dca_clients(db):
ADD COLUMN username TEXT; ADD COLUMN username TEXT;
""" """
) )
async def m010_add_source_wallet_to_lamassu_config(db):
"""
Add source wallet ID to Lamassu configuration table for DCA distributions.
"""
await db.execute(
"""
ALTER TABLE myextension.lamassu_config
ADD COLUMN source_wallet_id TEXT;
"""
)

View file

@ -109,6 +109,8 @@ class CreateLamassuConfigData(BaseModel):
database_name: str database_name: str
username: str username: str
password: str password: str
# Source wallet for DCA distributions
source_wallet_id: Optional[str] = None
# SSH Tunnel settings # SSH Tunnel settings
use_ssh_tunnel: bool = False use_ssh_tunnel: bool = False
ssh_host: Optional[str] = None ssh_host: Optional[str] = None
@ -130,6 +132,8 @@ class LamassuConfig(BaseModel):
test_connection_success: Optional[bool] test_connection_success: Optional[bool]
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
# Source wallet for DCA distributions
source_wallet_id: Optional[str] = None
# SSH Tunnel settings # SSH Tunnel settings
use_ssh_tunnel: bool = False use_ssh_tunnel: bool = False
ssh_host: Optional[str] = None ssh_host: Optional[str] = None
@ -149,6 +153,8 @@ class UpdateLamassuConfigData(BaseModel):
username: Optional[str] = None username: Optional[str] = None
password: Optional[str] = None password: Optional[str] = None
is_active: Optional[bool] = None is_active: Optional[bool] = None
# Source wallet for DCA distributions
source_wallet_id: Optional[str] = None
# SSH Tunnel settings # SSH Tunnel settings
use_ssh_tunnel: Optional[bool] = None use_ssh_tunnel: Optional[bool] = None
ssh_host: Optional[str] = None ssh_host: Optional[str] = None

View file

@ -71,6 +71,7 @@ window.app = Vue.createApp({
database_name: '', database_name: '',
username: '', username: '',
password: '', password: '',
selectedWallet: null,
// SSH Tunnel settings // SSH Tunnel settings
use_ssh_tunnel: false, use_ssh_tunnel: false,
ssh_host: '', ssh_host: '',
@ -169,6 +170,7 @@ window.app = Vue.createApp({
database_name: this.configDialog.data.database_name, database_name: this.configDialog.data.database_name,
username: this.configDialog.data.username, username: this.configDialog.data.username,
password: this.configDialog.data.password, password: this.configDialog.data.password,
source_wallet_id: this.configDialog.data.selectedWallet?.id,
// SSH Tunnel settings // SSH Tunnel settings
use_ssh_tunnel: this.configDialog.data.use_ssh_tunnel, use_ssh_tunnel: this.configDialog.data.use_ssh_tunnel,
ssh_host: this.configDialog.data.ssh_host, ssh_host: this.configDialog.data.ssh_host,
@ -206,6 +208,7 @@ window.app = Vue.createApp({
database_name: '', database_name: '',
username: '', username: '',
password: '', password: '',
selectedWallet: null,
// SSH Tunnel settings // SSH Tunnel settings
use_ssh_tunnel: false, use_ssh_tunnel: false,
ssh_host: '', ssh_host: '',
@ -705,7 +708,7 @@ window.app = Vue.createApp({
const data = this.configDialog.data const data = this.configDialog.data
// Basic database fields are required // Basic database fields are required
const basicValid = data.host && data.database_name && data.username const basicValid = data.host && data.database_name && data.username && data.selectedWallet
// If SSH tunnel is enabled, validate SSH fields // If SSH tunnel is enabled, validate SSH fields
if (data.use_ssh_tunnel) { if (data.use_ssh_tunnel) {

View file

@ -568,6 +568,20 @@
<q-separator class="q-my-md"></q-separator> <q-separator class="q-my-md"></q-separator>
<div class="text-h6 q-mb-md">DCA Source Wallet</div>
<q-select
filled
dense
:options="g.user.wallets"
v-model="configDialog.data.selectedWallet"
label="Source Wallet for DCA Distributions *"
option-label="name"
hint="Wallet that holds Bitcoin for distribution to DCA clients"
></q-select>
<q-separator class="q-my-md"></q-separator>
<div class="text-h6 q-mb-md">SSH Tunnel (Recommended)</div> <div class="text-h6 q-mb-md">SSH Tunnel (Recommended)</div>
<div class="row items-center q-mb-md"> <div class="row items-center q-mb-md">

View file

@ -650,27 +650,31 @@ class LamassuTransactionProcessor:
return False return False
# Pay the invoice from the DCA admin wallet (this extension's wallet) # Pay the invoice from the DCA admin wallet (this extension's wallet)
# We need to get the admin wallet that manages DCA funds # Get the admin wallet that manages DCA funds
admin_config = await get_active_lamassu_config() admin_config = await get_active_lamassu_config()
if not admin_config: if not admin_config:
logger.error("No active Lamassu config found - cannot determine source wallet") logger.error("No active Lamassu config found - cannot determine source wallet")
return False return False
# TODO: We need to determine which wallet holds the DCA funds if not admin_config.source_wallet_id:
# For now, we'll need to add a source_wallet_id to the LamassuConfig logger.warning("DCA source wallet not configured - payment creation successful but not sent")
# This is the wallet that receives the Bitcoin from Lamassu and distributes to clients logger.info(f"Created invoice for {amount_sats} sats to client {client.username or client.user_id}")
logger.warning("DCA source wallet not configured - payment creation successful but not sent") logger.info(f"Invoice: {new_payment.bolt11}")
logger.info(f"Created invoice for {amount_sats} sats to client {client.username or client.user_id}") return True
logger.info(f"Invoice: {new_payment.bolt11}")
# TODO: Implement the actual payment once source wallet is configured # Pay the invoice from the configured source wallet
# await pay_invoice( try:
# payment_request=new_payment.bolt11, await pay_invoice(
# wallet_id=source_wallet_id, payment_request=new_payment.bolt11,
# description=memo, wallet_id=admin_config.source_wallet_id,
# extra=extra ) description=memo,
extra=extra
return True )
logger.info(f"DCA payment completed: {amount_sats} sats sent to {client.username or client.user_id}")
return True
except Exception as e:
logger.error(f"Failed to pay invoice for client {client.username or client.user_id}: {e}")
return False
except Exception as e: except Exception as e:
logger.error(f"Error sending DCA payment to client {client.username or client.user_id}: {e}") logger.error(f"Error sending DCA payment to client {client.username or client.user_id}: {e}")