diff --git a/crud.py b/crud.py index afb8376..60bad39 100644 --- a/crud.py +++ b/crud.py @@ -306,9 +306,9 @@ async def create_lamassu_config(data: CreateLamassuConfigData) -> LamassuConfig: """ INSERT INTO satoshimachine.lamassu_config (id, host, port, database_name, username, password, source_wallet_id, commission_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, max_daily_limit_gtq) VALUES (:id, :host, :port, :database_name, :username, :password, :source_wallet_id, :commission_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, :max_daily_limit_gtq) """, { "id": config_id, @@ -327,7 +327,8 @@ async def create_lamassu_config(data: CreateLamassuConfigData) -> LamassuConfig: "ssh_port": data.ssh_port, "ssh_username": data.ssh_username, "ssh_password": data.ssh_password, - "ssh_private_key": data.ssh_private_key + "ssh_private_key": data.ssh_private_key, + "max_daily_limit_gtq": data.max_daily_limit_gtq } ) return await get_lamassu_config(config_id) diff --git a/migrations.py b/migrations.py index 821507c..0456f43 100644 --- a/migrations.py +++ b/migrations.py @@ -122,4 +122,16 @@ async def m002_add_transaction_time_to_dca_payments(db): ALTER TABLE satoshimachine.dca_payments ADD COLUMN transaction_time TIMESTAMP """ + ) + + +async def m003_add_max_daily_limit_config(db): + """ + Add max_daily_limit_gtq field to lamassu_config table for admin-configurable client limits + """ + await db.execute( + """ + ALTER TABLE satoshimachine.lamassu_config + ADD COLUMN max_daily_limit_gtq INTEGER NOT NULL DEFAULT 2000 + """ ) \ No newline at end of file diff --git a/models.py b/models.py index 7f4eee4..ff8a5b2 100644 --- a/models.py +++ b/models.py @@ -159,6 +159,8 @@ class CreateLamassuConfigData(BaseModel): ssh_username: Optional[str] = None ssh_password: Optional[str] = None ssh_private_key: Optional[str] = None # Path to private key file or key content + # DCA Client Limits + max_daily_limit_gtq: int = 2000 # Maximum daily limit for Fixed mode clients class LamassuConfig(BaseModel): @@ -187,6 +189,8 @@ class LamassuConfig(BaseModel): # Poll tracking last_poll_time: Optional[datetime] = None last_successful_poll: Optional[datetime] = None + # DCA Client Limits + max_daily_limit_gtq: int = 2000 # Maximum daily limit for Fixed mode clients class UpdateLamassuConfigData(BaseModel): @@ -207,5 +211,7 @@ class UpdateLamassuConfigData(BaseModel): ssh_username: Optional[str] = None ssh_password: Optional[str] = None ssh_private_key: Optional[str] = None + # DCA Client Limits + max_daily_limit_gtq: Optional[int] = None diff --git a/static/js/index.js b/static/js/index.js index e246d7e..b70f7d8 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -105,6 +105,8 @@ window.app = Vue.createApp({ password: '', selectedWallet: null, selectedCommissionWallet: null, + // DCA Client Limits + max_daily_limit_gtq: 2000, // SSH Tunnel settings use_ssh_tunnel: false, ssh_host: '', @@ -183,6 +185,11 @@ window.app = Vue.createApp({ this.configDialog.data.selectedCommissionWallet = commissionWallet } } + + // Populate other configuration fields + if (data) { + this.configDialog.data.max_daily_limit_gtq = data.max_daily_limit_gtq || 2000 + } } catch (error) { // It's OK if no config exists yet this.lamassuConfig = null @@ -200,6 +207,7 @@ window.app = Vue.createApp({ source_wallet_id: this.configDialog.data.selectedWallet?.id, commission_wallet_id: this.configDialog.data.selectedCommissionWallet?.id, // SSH Tunnel settings + max_daily_limit_gtq: this.configDialog.data.max_daily_limit_gtq, use_ssh_tunnel: this.configDialog.data.use_ssh_tunnel, ssh_host: this.configDialog.data.ssh_host, ssh_port: this.configDialog.data.ssh_port, @@ -238,6 +246,8 @@ window.app = Vue.createApp({ password: '', selectedWallet: null, selectedCommissionWallet: null, + // DCA Client Limits + max_daily_limit_gtq: 2000, // SSH Tunnel settings use_ssh_tunnel: false, ssh_host: '', diff --git a/templates/satmachineadmin/index.html b/templates/satmachineadmin/index.html index 1d8df50..6555d55 100644 --- a/templates/satmachineadmin/index.html +++ b/templates/satmachineadmin/index.html @@ -563,6 +563,24 @@ +
DCA Client Limits
+ + + + +
SSH Tunnel (Recommended)
diff --git a/views_api.py b/views_api.py index df1bbc0..3700497 100644 --- a/views_api.py +++ b/views_api.py @@ -420,3 +420,28 @@ async def api_delete_lamassu_config( await delete_lamassu_config(config_id) return {"message": "Configuration deleted successfully"} + + +@satmachineadmin_api_router.get("/api/v1/dca/client-limits") +async def api_get_client_limits(): + """Get client-safe configuration limits (public endpoint - no authentication)""" + try: + config = await get_active_lamassu_config() + if not config: + # Return sensible defaults if no config exists + return { + "max_daily_limit_gtq": 2000, + "currency": "GTQ" + } + + # Return only client-safe configuration fields + return { + "max_daily_limit_gtq": config.max_daily_limit_gtq, + "currency": "GTQ" # Could be made configurable later + } + except Exception: + # Return defaults on any error + return { + "max_daily_limit_gtq": 2000, + "currency": "GTQ" + }