mirror of
https://github.com/basicswap/basicswap.git
synced 2026-03-19 08:17:25 +01:00
feat: implement Spark balance display and withdrawal options
feat: complete FIRO + Spark integration (balance, withdrawal, address caching, refactor) feat: add support for Spark address handling remove white space ref
This commit is contained in:
@@ -2966,25 +2966,12 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
self.log.info_s(f"In txn: {txid}")
|
self.log.info_s(f"In txn: {txid}")
|
||||||
return txid
|
return txid
|
||||||
|
|
||||||
def withdrawLTC(self, type_from, value, addr_to, subfee: bool) -> str:
|
def withdrawCoinExtended(
|
||||||
ci = self.ci(Coins.LTC)
|
self, coin_type, type_from, value, addr_to, subfee: bool
|
||||||
|
) -> str:
|
||||||
|
ci = self.ci(coin_type)
|
||||||
self.log.info(
|
self.log.info(
|
||||||
"withdrawLTC{}".format(
|
"withdrawCoinExtended{}".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 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
|
if self.log.safe_logs
|
||||||
else " {} {} to {} {}".format(
|
else " {} {} to {} {}".format(
|
||||||
@@ -3145,15 +3132,6 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
self.setStringKV(key_str, addr)
|
self.setStringKV(key_str, addr)
|
||||||
return 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):
|
def getCachedStealthAddressForCoin(self, coin_type, cursor=None):
|
||||||
self.log.debug(f"getCachedStealthAddressForCoin {Coins(coin_type).name}")
|
self.log.debug(f"getCachedStealthAddressForCoin {Coins(coin_type).name}")
|
||||||
|
|
||||||
@@ -3173,23 +3151,6 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
self.closeDB(use_cursor)
|
self.closeDB(use_cursor)
|
||||||
return addr
|
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):
|
def getCachedWalletRestoreHeight(self, ci, cursor=None):
|
||||||
self.log.debug(f"getCachedWalletRestoreHeight {ci.coin_name()}")
|
self.log.debug(f"getCachedWalletRestoreHeight {ci.coin_name()}")
|
||||||
|
|
||||||
@@ -11661,15 +11622,25 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
)
|
)
|
||||||
elif coin == Coins.FIRO:
|
elif coin == Coins.FIRO:
|
||||||
try:
|
try:
|
||||||
rv["spark_address"] = self.getCachedSparkAddressForCoin(Coins.FIRO)
|
rv["spark_address"] = self.getCachedStealthAddressForCoin(
|
||||||
|
Coins.FIRO
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.warning(
|
self.log.warning(
|
||||||
f"getCachedSparkAddressForCoin for {ci.coin_name()} failed with: {e}."
|
f"getCachedStealthAddressForCoin for {ci.coin_name()} failed with: {e}."
|
||||||
)
|
)
|
||||||
rv["spark_balance"] = walletinfo["spark_balance"]
|
# Spark balances are in atomic units, format them
|
||||||
rv["spark_pending"] = (
|
rv["spark_balance"] = (
|
||||||
|
0
|
||||||
|
if walletinfo["spark_balance"] == 0
|
||||||
|
else ci.format_amount(walletinfo["spark_balance"])
|
||||||
|
)
|
||||||
|
spark_pending_int = (
|
||||||
walletinfo["spark_unconfirmed"] + walletinfo["spark_immature"]
|
walletinfo["spark_unconfirmed"] + walletinfo["spark_immature"]
|
||||||
)
|
)
|
||||||
|
rv["spark_pending"] = (
|
||||||
|
0 if spark_pending_int == 0 else ci.format_amount(spark_pending_int)
|
||||||
|
)
|
||||||
|
|
||||||
return rv
|
return rv
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -11792,6 +11763,8 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
if row2[0].startswith("stealth"):
|
if row2[0].startswith("stealth"):
|
||||||
if coin_id == Coins.LTC:
|
if coin_id == Coins.LTC:
|
||||||
wallet_data["mweb_address"] = row2[1]
|
wallet_data["mweb_address"] = row2[1]
|
||||||
|
elif coin_id == Coins.FIRO:
|
||||||
|
wallet_data["spark_address"] = row2[1]
|
||||||
else:
|
else:
|
||||||
wallet_data["stealth_address"] = row2[1]
|
wallet_data["stealth_address"] = row2[1]
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -102,30 +102,33 @@ class FIROInterface(BTCInterface):
|
|||||||
return addr_info["ismine"]
|
return addr_info["ismine"]
|
||||||
return addr_info["ismine"] or addr_info["iswatchonly"]
|
return addr_info["ismine"] or addr_info["iswatchonly"]
|
||||||
|
|
||||||
def getNewSparkAddress(self, label="swap_receive") -> str:
|
def getNewSparkAddress(self) -> str:
|
||||||
"""Generate a new Spark address for receiving private funds.
|
|
||||||
RPC: getnewsparkaddress [label]
|
|
||||||
"""
|
|
||||||
try:
|
try:
|
||||||
return self.rpc("getnewsparkaddress", [label])
|
return self.rpc_wallet("getnewsparkaddress")[0]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._log.error(f"getnewsparkaddress failed: {str(e)}")
|
self._log.error(f"getnewsparkaddress failed: {str(e)}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def getNewStealthAddress(self, label=""):
|
def getNewStealthAddress(self):
|
||||||
"""Get a new Spark address (alias for consistency with other coins)."""
|
"""Get a new Spark address (alias for consistency with other coins)."""
|
||||||
return self.getNewSparkAddress(label)
|
return self.getNewSparkAddress()
|
||||||
|
|
||||||
def getWalletInfo(self):
|
def getWalletInfo(self):
|
||||||
"""Get wallet info including Spark balance."""
|
"""Get wallet info including Spark balance."""
|
||||||
rv = super(FIROInterface, self).getWalletInfo()
|
rv = super(FIROInterface, self).getWalletInfo()
|
||||||
try:
|
try:
|
||||||
spark_balance_info = self.rpc("getsparkbalance")
|
spark_balance_info = self.rpc("getsparkbalance")
|
||||||
# getsparkbalance returns a dict with confirmed, unconfirmed, immature
|
# getsparkbalance returns amounts in atomic units (satoshis)
|
||||||
# Values are in FIRO (not satoshis), similar to getwalletinfo balance
|
# Field names: availableBalance, unconfirmedBalance, fullBalance
|
||||||
rv["spark_balance"] = spark_balance_info.get("confirmed", 0)
|
confirmed = spark_balance_info.get("availableBalance", 0)
|
||||||
rv["spark_unconfirmed"] = spark_balance_info.get("unconfirmed", 0)
|
unconfirmed = spark_balance_info.get("unconfirmedBalance", 0)
|
||||||
rv["spark_immature"] = spark_balance_info.get("immature", 0)
|
full_balance = spark_balance_info.get("fullBalance", 0)
|
||||||
|
# Values are already in atomic units, keep as integers
|
||||||
|
# basicswap.py will format them using format_amount
|
||||||
|
rv["spark_balance"] = confirmed if confirmed else 0
|
||||||
|
rv["spark_unconfirmed"] = unconfirmed if unconfirmed else 0
|
||||||
|
immature = full_balance - confirmed - unconfirmed
|
||||||
|
rv["spark_immature"] = immature if immature > 0 else 0
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._log.warning(f"getsparkbalance failed: {str(e)}")
|
self._log.warning(f"getsparkbalance failed: {str(e)}")
|
||||||
rv["spark_balance"] = 0
|
rv["spark_balance"] = 0
|
||||||
@@ -135,36 +138,48 @@ class FIROInterface(BTCInterface):
|
|||||||
|
|
||||||
def withdrawCoin(self, value, type_from: str, addr_to: str, subfee: bool) -> str:
|
def withdrawCoin(self, value, type_from: str, addr_to: str, subfee: bool) -> str:
|
||||||
"""Withdraw coins, supporting both transparent and Spark transactions.
|
"""Withdraw coins, supporting both transparent and Spark transactions.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
value: Amount to withdraw
|
value: Amount to withdraw
|
||||||
type_from: "plain" for transparent, "spark" for Spark
|
type_from: "plain" for transparent, "spark" for Spark
|
||||||
addr_to: Destination address
|
addr_to: Destination address
|
||||||
subfee: Whether to subtract fee from amount
|
subfee: Whether to subtract fee from amount
|
||||||
"""
|
"""
|
||||||
if type_from == "spark":
|
type_to = "spark" if addr_to.startswith("sm1") else "plain"
|
||||||
# Use spendspark RPC for Spark transactions
|
|
||||||
# RPC: spendspark {"address": {"amount": ..., "subtractfee": ..., "memo": ...}}
|
if "spark" in (type_from, type_to):
|
||||||
|
# RPC format: spendspark {"address": {"amount": ..., "subtractfee": ..., "memo": ...}}
|
||||||
|
# RPC wrapper will serialize this as: {"method": "spendspark", "params": [{...}], ...}
|
||||||
try:
|
try:
|
||||||
params = {
|
if type_from == "spark":
|
||||||
addr_to: {
|
# Construct params: dict where address is the key, wrapped in array for RPC
|
||||||
"amount": value,
|
params = [
|
||||||
"subtractfee": subfee,
|
{"address": addr_to, "amount": value, "subtractfee": subfee}
|
||||||
"memo": ""
|
]
|
||||||
}
|
result = self.rpc_wallet("spendspark", params)
|
||||||
}
|
else:
|
||||||
result = self.rpc("spendspark", params)
|
# Use automintspark to perform a plain -> spark tx of full balance
|
||||||
# spendspark returns a txid string directly or in a result dict
|
balance = self.rpc_wallet("getbalance")
|
||||||
|
print(f"balance {balance} value {value} subfee {subfee}")
|
||||||
|
if str(balance) == str(value) and subfee:
|
||||||
|
result = self.rpc_wallet("automintspark")
|
||||||
|
else:
|
||||||
|
# subtractFee param is not available on plain -> spark transactions
|
||||||
|
params = [{addr_to: {"amount": value}}]
|
||||||
|
result = self.rpc_wallet("mintspark", params)
|
||||||
|
# spendspark returns a txid string directly, in a result dict, or as an array
|
||||||
|
if isinstance(result, list) and len(result) > 0:
|
||||||
|
return result[0]
|
||||||
if isinstance(result, dict):
|
if isinstance(result, dict):
|
||||||
return result.get("txid", result.get("tx", ""))
|
return result.get("txid", result.get("tx", ""))
|
||||||
return result
|
return result
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._log.error(f"spendspark failed: {str(e)}")
|
self._log.error(f"spark tx failed: {str(e)}")
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
# Use standard sendtoaddress for transparent transactions
|
# Use standard sendtoaddress for transparent transactions
|
||||||
params = [addr_to, value, "", "", subfee]
|
params = [addr_to, value, "", "", subfee]
|
||||||
return self.rpc("sendtoaddress", params)
|
return self.rpc_wallet("sendtoaddress", params)
|
||||||
|
|
||||||
def getSCLockScriptAddress(self, lock_script: bytes) -> str:
|
def getSCLockScriptAddress(self, lock_script: bytes) -> str:
|
||||||
lock_tx_dest = self.getScriptDest(lock_script)
|
lock_tx_dest = self.getScriptDest(lock_script)
|
||||||
@@ -316,10 +331,6 @@ class FIROInterface(BTCInterface):
|
|||||||
assert len(script_hash) == 20
|
assert len(script_hash) == 20
|
||||||
return CScript([OP_HASH160, script_hash, OP_EQUAL])
|
return CScript([OP_HASH160, script_hash, OP_EQUAL])
|
||||||
|
|
||||||
def withdrawCoin(self, value, addr_to, subfee):
|
|
||||||
params = [addr_to, value, "", "", subfee]
|
|
||||||
return self.rpc("sendtoaddress", params)
|
|
||||||
|
|
||||||
def getWalletSeedID(self):
|
def getWalletSeedID(self):
|
||||||
return self.rpc("getwalletinfo")["hdmasterkeyid"]
|
return self.rpc("getwalletinfo")["hdmasterkeyid"]
|
||||||
|
|
||||||
|
|||||||
@@ -79,12 +79,11 @@ def withdraw_coin(swap_client, coin_type, post_string, is_json):
|
|||||||
txid_hex = swap_client.withdrawParticl(
|
txid_hex = swap_client.withdrawParticl(
|
||||||
type_from, type_to, value, address, subfee
|
type_from, type_to, value, address, subfee
|
||||||
)
|
)
|
||||||
elif coin_type == Coins.LTC:
|
elif coin_type in (Coins.LTC, Coins.FIRO):
|
||||||
type_from = get_data_entry_or(post_data, "type_from", "plain")
|
type_from = get_data_entry_or(post_data, "type_from", "plain")
|
||||||
txid_hex = swap_client.withdrawLTC(type_from, value, address, subfee)
|
txid_hex = swap_client.withdrawCoinExtended(
|
||||||
elif coin_type == Coins.FIRO:
|
coin_type, type_from, value, address, subfee
|
||||||
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):
|
elif coin_type in (Coins.XMR, Coins.WOW):
|
||||||
txid_hex = swap_client.withdrawCoin(coin_type, value, address, sweepall)
|
txid_hex = swap_client.withdrawCoin(coin_type, value, address, sweepall)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -23,6 +23,11 @@
|
|||||||
types: ['default'],
|
types: ['default'],
|
||||||
hasSubfee: false,
|
hasSubfee: false,
|
||||||
hasSweepAll: true
|
hasSweepAll: true
|
||||||
|
},
|
||||||
|
13: {
|
||||||
|
types: ['plain', 'spark'],
|
||||||
|
hasSubfee: true,
|
||||||
|
hasSweepAll: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -64,6 +69,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cid === 13) {
|
||||||
|
switch(selectedType) {
|
||||||
|
case 'plain':
|
||||||
|
return this.safeParseFloat(balances.main || balances.balance);
|
||||||
|
case 'spark':
|
||||||
|
return this.safeParseFloat(balances.spark);
|
||||||
|
default:
|
||||||
|
return this.safeParseFloat(balances.main || balances.balance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return this.safeParseFloat(balances.main || balances.balance);
|
return this.safeParseFloat(balances.main || balances.balance);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -188,7 +204,8 @@
|
|||||||
balance: balance,
|
balance: balance,
|
||||||
blind: balance2,
|
blind: balance2,
|
||||||
anon: balance3,
|
anon: balance3,
|
||||||
mweb: balance2
|
mweb: balance2,
|
||||||
|
spark: balance2
|
||||||
};
|
};
|
||||||
WalletAmountManager.setAmount(percent, balances, coinId);
|
WalletAmountManager.setAmount(percent, balances, coinId);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
</section>
|
</section>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% if w.havedata %}
|
{% if w.havedata %}
|
||||||
{% if w.error %}
|
{% if w.error %}
|
||||||
<section class="py-4 px-6" id="messages_error" role="alert">
|
<section class="py-4 px-6" id="messages_error" role="alert">
|
||||||
@@ -146,8 +148,20 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{% elif w.cid == '13' %} {# FIRO #}
|
||||||
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
||||||
|
<td class="py-3 px-6 bold"> <span class="inline-flex align-middle items-center justify-center w-9 h-10 bg-white-50 rounded"> <img class="h-7" src="/static/images/coins/{{ w.name }}.png" alt="{{ w.name }} Spark"> </span>Spark Balance: </td>
|
||||||
|
<td class="py-3 px-6 bold">
|
||||||
|
<span class="coinname-value" data-coinname="{{ w.name }}">{{ w.spark_balance }} {{ w.ticker }}</span>
|
||||||
|
(<span class="usd-value"></span>)
|
||||||
|
{% if w.spark_pending %}
|
||||||
|
<span class="inline-block py-1 px-2 rounded-full bg-green-100 text-green-500 dark:bg-gray-500 dark:text-green-500">Pending: +{{ w.spark_pending }} {{ w.ticker }} </span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{# / LTC #}
|
{# / LTC #}
|
||||||
|
{# / FIRO #}
|
||||||
{% if w.locked_utxos %}
|
{% if w.locked_utxos %}
|
||||||
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
||||||
<td class="py-3 px-6 bold">Locked Outputs:</td>
|
<td class="py-3 px-6 bold">Locked Outputs:</td>
|
||||||
@@ -286,8 +300,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if w.cid in '1, 3, 6, 9' %}
|
{% if w.cid in '1, 3, 6, 9, 13' %}
|
||||||
{# PART | LTC | XMR | WOW | #}
|
{# PART | LTC | XMR | WOW | FIRO #}
|
||||||
<div class="w-full md:w-1/2 p-3 flex justify-center items-center">
|
<div class="w-full md:w-1/2 p-3 flex justify-center items-center">
|
||||||
<div class="h-full">
|
<div class="h-full">
|
||||||
<div class="flex flex-wrap -m-3">
|
<div class="flex flex-wrap -m-3">
|
||||||
@@ -334,6 +348,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{# / LTC #}
|
{# / LTC #}
|
||||||
|
{% elif w.cid == '13' %}
|
||||||
|
{# FIRO #}
|
||||||
|
<div id="qrcode-spark" class="qrcode" data-qrcode data-address="{{ w.spark_address }}"> </div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="font-normal bold text-gray-500 text-center dark:text-white mb-5">Spark Address: </div>
|
||||||
|
<div class="text-center relative">
|
||||||
|
<div class="input-like-container hover:border-blue-500 bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-400 text-lg lg:text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0" id="stealth_address">{{ w.spark_address }}</div>
|
||||||
|
<span class="absolute inset-y-0 right-0 flex items-center pr-3 cursor-pointer" id="copyIcon"></span>
|
||||||
|
</div>
|
||||||
|
<div class="opacity-100 text-gray-500 dark:text-gray-100 flex justify-center items-center">
|
||||||
|
<div class="py-3 px-6 bold mt-5">
|
||||||
|
<button type="submit" class="flex justify-center py-2 px-4 bg-blue-500 hover:bg-blue-600 font-medium text-sm text-white border border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none" name="newsparkaddr_{{ w.cid }}" value="New Spark Address"> {{ circular_arrows_svg }} New Spark Address </button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{# / FIRO #}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -397,6 +427,15 @@
|
|||||||
(<span class="usd-value"></span>)
|
(<span class="usd-value"></span>)
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{% elif w.cid == '13' %}
|
||||||
|
{# FIRO #}
|
||||||
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100">
|
||||||
|
<td class="py-4 pl-6 bold w-1/4"> <span class="inline-flex align-middle items-center justify-center w-9 h-10 bg-white-50 rounded"> <img class="h-7" src="/static/images/coins/{{ w.name }}.png" alt="{{ w.name }}"> </span>Spark Balance: </td>
|
||||||
|
<td class="py-3 px-6">
|
||||||
|
<span class="coinname-value" data-coinname="{{ w.name }}">{{ w.spark_balance }} {{ w.ticker }}</span>
|
||||||
|
(<span class="usd-value"></span>)
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
{% elif w.cid == '1' %}
|
{% elif w.cid == '1' %}
|
||||||
{# PART #}
|
{# PART #}
|
||||||
<tr class="opacity-100 text-gray-500 dark:text-gray-100">
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100">
|
||||||
@@ -487,6 +526,14 @@
|
|||||||
<button type="button" class="ml-2 py-1 px-2 bg-blue-500 text-white text-lg lg:text-sm rounded-md focus:outline-none" onclick="setAmount(1, '{{ w.balance }}', {{ w.cid }}, '{{ w.mweb_balance }}')">100%</button>
|
<button type="button" class="ml-2 py-1 px-2 bg-blue-500 text-white text-lg lg:text-sm rounded-md focus:outline-none" onclick="setAmount(1, '{{ w.balance }}', {{ w.cid }}, '{{ w.mweb_balance }}')">100%</button>
|
||||||
|
|
||||||
{# / LTC #}
|
{# / LTC #}
|
||||||
|
|
||||||
|
{% elif w.cid == '13' %}
|
||||||
|
{# FIRO #}
|
||||||
|
<button type="button" class="hidden md:block py-1 px-2 bg-blue-500 text-white text-lg lg:text-sm rounded-md focus:outline-none" onclick="setAmount(0.25, '{{ w.balance }}', {{ w.cid }}, '{{ w.spark_balance }}')">25%</button>
|
||||||
|
<button type="button" class="hidden md:block ml-2 py-1 px-2 bg-blue-500 text-white text-lg lg:text-sm rounded-md focus:outline-none" onclick="setAmount(0.5, '{{ w.balance }}', {{ w.cid }}, '{{ w.spark_balance }}')">50%</button>
|
||||||
|
<button type="button" class="ml-2 py-1 px-2 bg-blue-500 text-white text-lg lg:text-sm rounded-md focus:outline-none" onclick="setAmount(1, '{{ w.balance }}', {{ w.cid }}, '{{ w.spark_balance }}')">100%</button>
|
||||||
|
|
||||||
|
{# / FIRO #}
|
||||||
{% else %}
|
{% else %}
|
||||||
<button type="button" class="hidden md:block py-1 px-2 bg-blue-500 text-white text-lg lg:text-sm rounded-md focus:outline-none" onclick="setAmount(0.25, '{{ w.balance }}', {{ w.cid }})">25%</button>
|
<button type="button" class="hidden md:block py-1 px-2 bg-blue-500 text-white text-lg lg:text-sm rounded-md focus:outline-none" onclick="setAmount(0.25, '{{ w.balance }}', {{ w.cid }})">25%</button>
|
||||||
<button type="button" class="hidden md:block ml-2 py-1 px-2 bg-blue-500 text-white text-lg lg:text-sm rounded-md focus:outline-none" onclick="setAmount(0.5, '{{ w.balance }}', {{ w.cid }})">50%</button>
|
<button type="button" class="hidden md:block ml-2 py-1 px-2 bg-blue-500 text-white text-lg lg:text-sm rounded-md focus:outline-none" onclick="setAmount(0.5, '{{ w.balance }}', {{ w.cid }})">50%</button>
|
||||||
@@ -553,8 +600,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{% elif w.cid == '13' %} {# FIRO #}
|
||||||
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100">
|
||||||
|
<td class="py-3 px-6 bold">Type From:</td>
|
||||||
|
<td class="py-3 px-6">
|
||||||
|
<div class="w-full md:flex-1">
|
||||||
|
<div class="relative"> {{ select_box_arrow_svg }} <select id="withdraw_type" class="{{ select_box_class }}" name="withdraw_type_from_{{ w.cid }}">
|
||||||
|
<option value="spark" {% if w.wd_type_from=='spark' %} selected{% endif %}>Spark</option>
|
||||||
|
<option value="plain" {% if w.wd_type_from=='plain' %} selected{% endif %}>Plain</option>
|
||||||
|
</select> </div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{# / LTC #}
|
{# / LTC #}
|
||||||
|
{# / FIRO #}
|
||||||
{% if w.cid not in '6,9' %} {# Not XMR WOW #}
|
{% if w.cid not in '6,9' %} {# Not XMR WOW #}
|
||||||
<tr class="opacity-100 text-gray-500 dark:text-gray-100">
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100">
|
||||||
<td class="py-3 px-6 bold">Fee Rate:</td>
|
<td class="py-3 px-6 bold">Fee Rate:</td>
|
||||||
|
|||||||
@@ -132,6 +132,28 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{# / LTC #}
|
{# / LTC #}
|
||||||
|
{% if w.cid == '13' %} {# FIRO #}
|
||||||
|
<div class="flex mb-2 justify-between items-center">
|
||||||
|
<h4 class="text-xs font-medium dark:text-white">Spark Balance:</h4>
|
||||||
|
<span class="bold inline-block py-1 px-2 rounded-full bg-blue-100 text-xs text-black-500 dark:bg-gray-500 dark:text-gray-200 coinname-value" data-coinname="{{ w.name }}">{{ w.spark_balance }} {{ w.ticker }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex mb-2 justify-between items-center">
|
||||||
|
<h4 class="text-xs font-medium dark:text-white">Spark USD value:</h4>
|
||||||
|
<div class="bold inline-block py-1 px-2 rounded-full bg-blue-100 text-xs text-black-500 dark:bg-gray-500 dark:text-gray-200 usd-value"></div>
|
||||||
|
</div>
|
||||||
|
{% if w.spark_pending %}
|
||||||
|
<div class="flex mb-2 justify-between items-center">
|
||||||
|
<h4 class="text-xs font-bold text-green-500 dark:text-green-500">Spark Pending:</h4>
|
||||||
|
<span class="bold inline-block py-1 px-2 rounded-full bg-green-100 text-xs text-green-500 dark:bg-gray-500 dark:text-green-500 coinname-value" data-coinname="{{ w.name }}">
|
||||||
|
+{{ w.spark_pending }} {{ w.ticker }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex mb-2 justify-between items-center">
|
||||||
|
<h4 class="text-xs font-bold text-green-500 dark:text-green-500">Spark Pending USD value:</h4>
|
||||||
|
<div class="bold inline-block py-1 px-2 rounded-full bg-green-100 text-xs text-green-500 dark:bg-gray-500 dark:text-green-500 usd-value"></div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{# / FIRO #}
|
||||||
<hr class="border-t border-gray-100 dark:border-gray-500 my-5">
|
<hr class="border-t border-gray-100 dark:border-gray-500 my-5">
|
||||||
<div class="flex mb-2 justify-between items-center">
|
<div class="flex mb-2 justify-between items-center">
|
||||||
<h4 class="text-xs font-medium dark:text-white">Blocks:</h4>
|
<h4 class="text-xs font-medium dark:text-white">Blocks:</h4>
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ def page_wallet(self, url_split, post_string):
|
|||||||
elif have_data_entry(form_data, "newmwebaddr_" + cid):
|
elif have_data_entry(form_data, "newmwebaddr_" + cid):
|
||||||
swap_client.cacheNewStealthAddressForCoin(coin_id)
|
swap_client.cacheNewStealthAddressForCoin(coin_id)
|
||||||
elif have_data_entry(form_data, "newsparkaddr_" + cid):
|
elif have_data_entry(form_data, "newsparkaddr_" + cid):
|
||||||
swap_client.cacheNewSparkAddressForCoin(coin_id)
|
swap_client.cacheNewStealthAddressForCoin(coin_id)
|
||||||
elif have_data_entry(form_data, "reseed_" + cid):
|
elif have_data_entry(form_data, "reseed_" + cid):
|
||||||
try:
|
try:
|
||||||
swap_client.reseedWallet(coin_id)
|
swap_client.reseedWallet(coin_id)
|
||||||
@@ -214,15 +214,7 @@ def page_wallet(self, url_split, post_string):
|
|||||||
page_data["wd_type_to_" + cid] = type_to
|
page_data["wd_type_to_" + cid] = type_to
|
||||||
except Exception as e: # noqa: F841
|
except Exception as e: # noqa: F841
|
||||||
err_messages.append("Missing type")
|
err_messages.append("Missing type")
|
||||||
elif coin_id == Coins.LTC:
|
elif coin_id in (Coins.LTC, Coins.FIRO):
|
||||||
try:
|
|
||||||
type_from = form_data[bytes("withdraw_type_from_" + cid, "utf-8")][
|
|
||||||
0
|
|
||||||
].decode("utf-8")
|
|
||||||
page_data["wd_type_from_" + cid] = type_from
|
|
||||||
except Exception as e: # noqa: F841
|
|
||||||
err_messages.append("Missing type")
|
|
||||||
elif coin_id == Coins.FIRO:
|
|
||||||
try:
|
try:
|
||||||
type_from = form_data[bytes("withdraw_type_from_" + cid, "utf-8")][
|
type_from = form_data[bytes("withdraw_type_from_" + cid, "utf-8")][
|
||||||
0
|
0
|
||||||
@@ -244,18 +236,9 @@ def page_wallet(self, url_split, post_string):
|
|||||||
value, ticker, type_from, type_to, address, txid
|
value, ticker, type_from, type_to, address, txid
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif coin_id == Coins.LTC:
|
elif coin_id in (Coins.LTC, Coins.FIRO):
|
||||||
txid = swap_client.withdrawLTC(
|
txid = swap_client.withdrawCoinExtended(
|
||||||
type_from, value, address, subfee
|
coin_id, type_from, value, address, subfee
|
||||||
)
|
|
||||||
messages.append(
|
|
||||||
"Withdrew {} {} (from {}) to address {}<br/>In txid: {}".format(
|
|
||||||
value, ticker, type_from, address, txid
|
|
||||||
)
|
|
||||||
)
|
|
||||||
elif coin_id == Coins.FIRO:
|
|
||||||
txid = swap_client.withdrawFIRO(
|
|
||||||
type_from, value, address, subfee
|
|
||||||
)
|
)
|
||||||
messages.append(
|
messages.append(
|
||||||
"Withdrew {} {} (from {}) to address {}<br/>In txid: {}".format(
|
"Withdrew {} {} (from {}) to address {}<br/>In txid: {}".format(
|
||||||
|
|||||||
Reference in New Issue
Block a user