From 0bf4af100a9db221e7d1800fe33a64be07331129 Mon Sep 17 00:00:00 2001 From: Dhaval Chaudhari Date: Thu, 20 Nov 2025 00:22:03 +0530 Subject: [PATCH] feat: add FIRO withdrawal and Spark address caching functionality --- basicswap/basicswap.py | 52 ++++++++++++++++++++++++++++++++++++++++++ basicswap/js_server.py | 3 +++ 2 files changed, 55 insertions(+) diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index cc565c1..e2bab28 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -2981,6 +2981,21 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp): self.log.info_s(f"In txn: {txid}") return txid + def withdrawFIRO(self, type_from, value, addr_to, subfee: bool) -> str: + ci = self.ci(Coins.FIRO) + self.log.info( + "withdrawFIRO{}".format( + "" + if self.log.safe_logs + else " {} {} to {} {}".format( + value, type_from, addr_to, " subfee" if subfee else "" + ) + ) + ) + txid = ci.withdrawCoin(value, type_from, addr_to, subfee) + self.log.info_s(f"In txn: {txid}") + return txid + def withdrawParticl( self, type_from: str, type_to: str, value, addr_to: str, subfee: bool ) -> str: @@ -3130,6 +3145,15 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp): self.setStringKV(key_str, addr) return addr + def cacheNewSparkAddressForCoin(self, coin_type): + """Cache a new Spark address for FIRO.""" + self.log.debug(f"cacheNewSparkAddressForCoin {Coins(coin_type).name}") + ci = self.ci(coin_type) + key_str = "spark_addr_" + ci.coin_name().lower() + addr = ci.getNewSparkAddress() + self.setStringKV(key_str, addr) + return addr + def getCachedStealthAddressForCoin(self, coin_type, cursor=None): self.log.debug(f"getCachedStealthAddressForCoin {Coins(coin_type).name}") @@ -3149,6 +3173,23 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp): self.closeDB(use_cursor) return addr + def getCachedSparkAddressForCoin(self, coin_type, cursor=None): + """Get cached Spark address for FIRO, generating one if needed.""" + self.log.debug(f"getCachedSparkAddressForCoin {Coins(coin_type).name}") + ci = self.ci(coin_type) + key_str = "spark_addr_" + ci.coin_name().lower() + use_cursor = self.openDB(cursor) + try: + addr = self.getStringKV(key_str, use_cursor) + if addr is None: + addr = ci.getNewSparkAddress() + self.log.info(f"Generated new Spark address for {ci.coin_name()}") + self.setStringKV(key_str, addr, use_cursor) + finally: + if cursor is None: + self.closeDB(use_cursor) + return addr + def getCachedWalletRestoreHeight(self, ci, cursor=None): self.log.debug(f"getCachedWalletRestoreHeight {ci.coin_name()}") @@ -11618,6 +11659,17 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp): rv["mweb_pending"] = ( walletinfo["mweb_unconfirmed"] + walletinfo["mweb_immature"] ) + elif coin == Coins.FIRO: + try: + rv["spark_address"] = self.getCachedSparkAddressForCoin(Coins.FIRO) + except Exception as e: + self.log.warning( + f"getCachedSparkAddressForCoin for {ci.coin_name()} failed with: {e}." + ) + rv["spark_balance"] = walletinfo["spark_balance"] + rv["spark_pending"] = ( + walletinfo["spark_unconfirmed"] + walletinfo["spark_immature"] + ) return rv except Exception as e: diff --git a/basicswap/js_server.py b/basicswap/js_server.py index 1ecd597..7fb8148 100644 --- a/basicswap/js_server.py +++ b/basicswap/js_server.py @@ -82,6 +82,9 @@ def withdraw_coin(swap_client, coin_type, post_string, is_json): elif coin_type == Coins.LTC: type_from = get_data_entry_or(post_data, "type_from", "plain") txid_hex = swap_client.withdrawLTC(type_from, value, address, subfee) + elif coin_type == Coins.FIRO: + type_from = get_data_entry_or(post_data, "type_from", "plain") + txid_hex = swap_client.withdrawFIRO(type_from, value, address, subfee) elif coin_type in (Coins.XMR, Coins.WOW): txid_hex = swap_client.withdrawCoin(coin_type, value, address, sweepall) else: