diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index 39b3b35..8a5e1d4 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -391,7 +391,7 @@ class BasicSwap(BaseApp): Coins.PART_BLIND, Coins.BCH, ) - self.coins_without_segwit = (Coins.PIVX, Coins.DASH, Coins.NMC) + self.coins_without_segwit = (Coins.PIVX, Coins.DASH) # TODO: Adjust ranges self.min_delay_event = self.get_int_setting("min_delay_event", 10, 0, 20 * 60) diff --git a/basicswap/bin/prepare.py b/basicswap/bin/prepare.py index b5f3a11..4bea5c1 100755 --- a/basicswap/bin/prepare.py +++ b/basicswap/bin/prepare.py @@ -52,11 +52,17 @@ PARTICL_VERSION = os.getenv("PARTICL_VERSION", "23.2.7.0") PARTICL_VERSION_TAG = os.getenv("PARTICL_VERSION_TAG", "") PARTICL_LINUX_EXTRA = os.getenv("PARTICL_LINUX_EXTRA", "nousb") +BITCOIN_VERSION = os.getenv("BITCOIN_VERSION", "28.0") +BITCOIN_VERSION_TAG = os.getenv("BITCOIN_VERSION_TAG", "") + LITECOIN_VERSION = os.getenv("LITECOIN_VERSION", "0.21.4") LITECOIN_VERSION_TAG = os.getenv("LITECOIN_VERSION_TAG", "") -BITCOIN_VERSION = os.getenv("BITCOIN_VERSION", "28.0") -BITCOIN_VERSION_TAG = os.getenv("BITCOIN_VERSION_TAG", "") +DCR_VERSION = os.getenv("DCR_VERSION", "1.8.1") +DCR_VERSION_TAG = os.getenv("DCR_VERSION_TAG", "") + +NMC_VERSION = os.getenv("NMC_VERSION", "28.0") +NMC_VERSION_TAG = os.getenv("NMC_VERSION_TAG", "") MONERO_VERSION = os.getenv("MONERO_VERSION", "0.18.3.4") MONERO_VERSION_TAG = os.getenv("MONERO_VERSION_TAG", "") @@ -82,9 +88,6 @@ FIRO_VERSION_TAG = os.getenv("FIRO_VERSION_TAG", "") NAV_VERSION = os.getenv("NAV_VERSION", "7.0.3") NAV_VERSION_TAG = os.getenv("NAV_VERSION_TAG", "") -DCR_VERSION = os.getenv("DCR_VERSION", "1.8.1") -DCR_VERSION_TAG = os.getenv("DCR_VERSION_TAG", "") - BITCOINCASH_VERSION = os.getenv("BITCOINCASH_VERSION", "28.0.1") BITCOINCASH_VERSION_TAG = os.getenv("BITCOINCASH_VERSION_TAG", "") @@ -103,7 +106,7 @@ known_coins = { "bitcoin": (BITCOIN_VERSION, BITCOIN_VERSION_TAG, ("laanwj",)), "litecoin": (LITECOIN_VERSION, LITECOIN_VERSION_TAG, ("davidburkett38",)), "decred": (DCR_VERSION, DCR_VERSION_TAG, ("decred_release",)), - "namecoin": ("0.18.0", "", ("JeremyRand",)), + "namecoin": (NMC_VERSION, NMC_VERSION_TAG, ("RoseTuring",)), "monero": (MONERO_VERSION, MONERO_VERSION_TAG, ("binaryfate",)), "wownero": (WOWNERO_VERSION, WOWNERO_VERSION_TAG, ("wowario",)), "pivx": (PIVX_VERSION, PIVX_VERSION_TAG, ("fuzzbawls",)), @@ -116,26 +119,32 @@ known_coins = { disabled_coins = [ "navcoin", - "namecoin", # Needs update ] expected_key_ids = { - "tecnovert": ("13F13651C9CF0D6B",), - "thrasher": ("FE3348877809386C",), - "laanwj": ("1E4AED62986CD25D",), - "JeremyRand": ("2DBE339E29F6294C",), - "binaryfate": ("F0AF4D462A0BDF92",), - "wowario": ("793504B449C69220",), - "davidburkett38": ("3620E9D387E55666",), - "xanimo": ("6E8F17C1B1BCDCBE",), - "patricklodder": ("2D3A345B98D0DC1F",), - "fuzzbawls": ("C1ABA64407731FD9",), - "pasta": ("52527BEDABE87984", "E2F3D7916E722D38"), - "reuben": ("1290A1D0FA7EE109",), - "nav_builder": ("2782262BF6E7FADB",), - "nicolasdorier": ("6618763EF09186FE", "223FDA69DEBEA82D", "62FE85647DEDDA2E"), - "decred_release": ("6D897EDF518A031D",), - "Calin_Culianu": ("21810A542031C02C",), + "tecnovert": ("8E517DC12EC1CC37F6423A8A13F13651C9CF0D6B",), + "thrasher": ("59CAF0E96F23F53747945FD4FE3348877809386C",), + "laanwj": ("9DEAE0DC7063249FB05474681E4AED62986CD25D",), + "RoseTuring": ("FD8366A807A99FA27FD9CCEA9FE3BFDDA6C53495",), + "binaryfate": ("81AC591FE9C4B65C5806AFC3F0AF4D462A0BDF92",), + "wowario": ("AB3A2F725818FCFF2794841C793504B449C69220",), + "davidburkett38": ("D35621D53A1CC6A3456758D03620E9D387E55666",), + "xanimo": ("2EAA8B1021C71AD5186CA07F6E8F17C1B1BCDCBE",), + "patricklodder": ("DC6EF4A8BF9F1B1E4DE1EE522D3A345B98D0DC1F",), + "fuzzbawls": ("0CFBDA9F60D661BA31EB5D50C1ABA64407731FD9",), + "pasta": ( + "29590362EC878A81FD3C202B52527BEDABE87984", + "02B8E7D002167C8B451AF05FE2F3D7916E722D38", + ), + "reuben": ("0186454D63E83D85EF91DE4E1290A1D0FA7EE109",), + "nav_builder": ("1BF9B51BAED51BA0B3A174EE2782262BF6E7FADB",), + "nicolasdorier": ( + "AB4CFA9895ACA0DBE27F6B346618763EF09186FE", + "015B4C837B245509E4AC8995223FDA69DEBEA82D", + "7121BDE3555D9BE06BDDC68162FE85647DEDDA2E", + ), + "decred_release": ("F516ADB7A069852C7C28A02D6D897EDF518A031D",), + "Calin_Culianu": ("D465135F97D0047E18E99DC321810A542031C02C",), } USE_PLATFORM = os.getenv("USE_PLATFORM", platform.system()) @@ -181,6 +190,36 @@ PART_ONION_PORT = int(os.getenv("PART_ONION_PORT", 51734)) PART_RPC_USER = os.getenv("PART_RPC_USER", "") PART_RPC_PWD = os.getenv("PART_RPC_PWD", "") +BTC_RPC_HOST = os.getenv("BTC_RPC_HOST", "127.0.0.1") +BTC_RPC_PORT = int(os.getenv("BTC_RPC_PORT", 19996)) +BTC_PORT = int(os.getenv("BTC_PORT", 8333)) +BTC_ONION_PORT = int(os.getenv("BTC_ONION_PORT", 8334)) +BTC_RPC_USER = os.getenv("BTC_RPC_USER", "") +BTC_RPC_PWD = os.getenv("BTC_RPC_PWD", "") + +LTC_RPC_HOST = os.getenv("LTC_RPC_HOST", "127.0.0.1") +LTC_RPC_PORT = int(os.getenv("LTC_RPC_PORT", 19895)) +LTC_ONION_PORT = int(os.getenv("LTC_ONION_PORT", 9333)) +LTC_RPC_USER = os.getenv("LTC_RPC_USER", "") +LTC_RPC_PWD = os.getenv("LTC_RPC_PWD", "") + +DCR_RPC_HOST = os.getenv("DCR_RPC_HOST", "127.0.0.1") +DCR_RPC_PORT = int(os.getenv("DCR_RPC_PORT", 9109)) +DCR_WALLET_RPC_HOST = os.getenv("DCR_WALLET_RPC_HOST", "127.0.0.1") +DCR_WALLET_RPC_PORT = int(os.getenv("DCR_WALLET_RPC_PORT", 9209)) +DCR_WALLET_PWD = os.getenv( + "DCR_WALLET_PWD", random.randbytes(random.randint(14, 18)).hex() +) +DCR_RPC_USER = os.getenv("DCR_RPC_USER", "user") +DCR_RPC_PWD = os.getenv("DCR_RPC_PWD", random.randbytes(random.randint(14, 18)).hex()) + +NMC_RPC_HOST = os.getenv("NMC_RPC_HOST", "127.0.0.1") +NMC_RPC_PORT = int(os.getenv("NMC_RPC_PORT", 19698)) +NMC_PORT = int(os.getenv("NMC_PORT", 8134)) +NMC_ONION_PORT = int(os.getenv("NMC_ONION_PORT", 9698)) +NMC_RPC_USER = os.getenv("NMC_RPC_USER", "") +NMC_RPC_PWD = os.getenv("NMC_RPC_PWD", "") + XMR_RPC_HOST = os.getenv("XMR_RPC_HOST", "127.0.0.1") XMR_RPC_PORT = int(os.getenv("XMR_RPC_PORT", 29798)) XMR_ZMQ_PORT = int(os.getenv("XMR_ZMQ_PORT", 30898)) @@ -203,32 +242,6 @@ WOW_RPC_USER = os.getenv("WOW_RPC_USER", "") WOW_RPC_PWD = os.getenv("WOW_RPC_PWD", "") DEFAULT_WOW_RESTORE_HEIGHT = int(os.getenv("DEFAULT_WOW_RESTORE_HEIGHT", 450000)) -LTC_RPC_HOST = os.getenv("LTC_RPC_HOST", "127.0.0.1") -LTC_RPC_PORT = int(os.getenv("LTC_RPC_PORT", 19895)) -LTC_ONION_PORT = int(os.getenv("LTC_ONION_PORT", 9333)) -LTC_RPC_USER = os.getenv("LTC_RPC_USER", "") -LTC_RPC_PWD = os.getenv("LTC_RPC_PWD", "") - -BTC_RPC_HOST = os.getenv("BTC_RPC_HOST", "127.0.0.1") -BTC_RPC_PORT = int(os.getenv("BTC_RPC_PORT", 19996)) -BTC_PORT = int(os.getenv("BTC_PORT", 8333)) -BTC_ONION_PORT = int(os.getenv("BTC_ONION_PORT", 8334)) -BTC_RPC_USER = os.getenv("BTC_RPC_USER", "") -BTC_RPC_PWD = os.getenv("BTC_RPC_PWD", "") - -DCR_RPC_HOST = os.getenv("DCR_RPC_HOST", "127.0.0.1") -DCR_RPC_PORT = int(os.getenv("DCR_RPC_PORT", 9109)) -DCR_WALLET_RPC_HOST = os.getenv("DCR_WALLET_RPC_HOST", "127.0.0.1") -DCR_WALLET_RPC_PORT = int(os.getenv("DCR_WALLET_RPC_PORT", 9209)) -DCR_WALLET_PWD = os.getenv( - "DCR_WALLET_PWD", random.randbytes(random.randint(14, 18)).hex() -) -DCR_RPC_USER = os.getenv("DCR_RPC_USER", "user") -DCR_RPC_PWD = os.getenv("DCR_RPC_PWD", random.randbytes(random.randint(14, 18)).hex()) - -NMC_RPC_HOST = os.getenv("NMC_RPC_HOST", "127.0.0.1") -NMC_RPC_PORT = int(os.getenv("NMC_RPC_PORT", 19698)) - PIVX_RPC_HOST = os.getenv("PIVX_RPC_HOST", "127.0.0.1") PIVX_RPC_PORT = int(os.getenv("PIVX_RPC_PORT", 51473)) PIVX_ONION_PORT = int(os.getenv("PIVX_ONION_PORT", 51472)) # nDefaultPort @@ -375,6 +388,12 @@ def getWalletName(coin_params: str, default_name: str, prefix_override=None) -> return wallet_name +def getDescriptorWalletOption(coin_params): + ticker: str = coin_params["ticker"] + default_option: bool = True if ticker in ("NMC",) else False + return toBool(os.getenv(ticker + "_USE_DESCRIPTORS", default_option)) + + def getKnownVersion(coin_name: str) -> str: version, version_tag, _ = known_coins[coin_name] return version + version_tag @@ -528,7 +547,7 @@ def testOnionLink(): def havePubkey(gpg, key_id): for key in gpg.list_keys(): - if key["keyid"] == key_id: + if key["fingerprint"] == key_id: return True return False @@ -591,8 +610,10 @@ def ensureValidSignatureBy(result, signing_key_name): if not isValidSignature(result): raise ValueError("Signature verification failed.") - if result.key_id not in expected_key_ids[signing_key_name]: - raise ValueError("Signature made by unexpected keyid: " + result.key_id) + if result.fingerprint not in expected_key_ids[signing_key_name]: + raise ValueError( + "Signature made by unexpected key fingerprint: " + result.fingerprint + ) logger.debug(f"Found valid signature by {signing_key_name} ({result.key_id}).") @@ -931,16 +952,10 @@ def prepareCore(coin, version_data, settings, data_dir, extra_opts={}): % (version, assert_filename) ) elif coin == "namecoin": - release_url = "https://beta.namecoin.org/files/namecoin-core/namecoin-core-{}/{}".format( - version, release_filename - ) - assert_filename = "{}-{}-{}-build.assert".format( - coin, os_name, version.rsplit(".", 1)[0] - ) - assert_url = ( - "https://raw.githubusercontent.com/namecoin/gitian.sigs/master/%s-%s/%s/%s" - % (version, os_dir_name, signing_key_name, assert_filename) - ) + release_url = f"https://www.namecoin.org/files/namecoin-core/namecoin-core-{version}/{release_filename}" + signing_key = "Rose%20Turing" + assert_filename = "noncodesigned.SHA256SUMS" + assert_url = f"https://raw.githubusercontent.com/namecoin/guix.sigs/main/{version}/{signing_key}/{assert_filename}" elif coin == "pivx": release_filename = "{}-{}-{}.{}".format(coin, version, BIN_ARCH, FILE_EXT) release_url = ( @@ -1345,6 +1360,8 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic, extra_opts={}): fp.write("printtoconsole=0\n") fp.write("daemon=0\n") fp.write(f"wallet={wallet_name}\n") + if "watch_wallet_name" in core_settings: + fp.write("wallet={}\n".format(core_settings["watch_wallet_name"])) if tor_control_password is not None: writeTorSettings(fp, coin, core_settings, tor_control_password) @@ -1401,6 +1418,10 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic, extra_opts={}): ) elif coin == "namecoin": fp.write("prune=2000\n") + fp.write("deprecatedrpc=create_bdb\n") + fp.write("addresstype=bech32\n") + fp.write("changetype=bech32\n") + fp.write("fallbackfee=0.001\n") # minrelaytxfee elif coin == "pivx": params_dir = os.path.join(data_dir, "pivx-params") downloadPIVXParams(params_dir) @@ -1804,6 +1825,7 @@ def initialise_wallets( Coins.DOGE, Coins.DCR, Coins.DASH, + Coins.NMC, ) # Always start Particl, it must be running to initialise a wallet in addcoin mode # Particl must be loaded first as subsequent coins are initialised from the Particl mnemonic @@ -1909,7 +1931,7 @@ def initialise_wallets( f'Creating wallet "{wallet_name}" for {getCoinName(c)}.' ) - if c in (Coins.BTC, Coins.LTC, Coins.DOGE, Coins.DASH): + if c in (Coins.BTC, Coins.LTC, Coins.NMC, Coins.DOGE, Coins.DASH): # wallet_name, disable_private_keys, blank, passphrase, avoid_reuse, descriptors use_descriptors = coin_settings.get("use_descriptors", False) @@ -1926,11 +1948,15 @@ def initialise_wallets( ], ) if use_descriptors: + watch_wallet_name = coin_settings["watch_wallet_name"] + logger.info( + f'Creating wallet "{watch_wallet_name}" for {getCoinName(c)}.' + ) swap_client.callcoinrpc( c, "createwallet", [ - coin_settings["watch_wallet_name"], + watch_wallet_name, True, True, "", @@ -2073,7 +2099,10 @@ def check_btc_fastsync_data(base_dir, sync_filename): importPubkey(gpg, pubkey_filename, pubkeyurls) with open(asc_file_path, "rb") as fp: verified = gpg.verify_file(fp) - if isValidSignature(verified) and verified.key_id in expected_key_ids["tecnovert"]: + if ( + isValidSignature(verified) + and verified.fingerprint in expected_key_ids["tecnovert"] + ): ensureValidSignatureBy(verified, "tecnovert") else: pubkey_filename = "nicolasdorier.asc" @@ -2379,22 +2408,6 @@ def main(): "core_version_no": getKnownVersion("bitcoin"), "core_version_group": 28, }, - "bitcoincash": { - "connection_type": "rpc", - "manage_daemon": shouldManageDaemon("BCH"), - "rpchost": BCH_RPC_HOST, - "rpcport": BCH_RPC_PORT + port_offset, - "onionport": BCH_ONION_PORT + port_offset, - "datadir": os.getenv("BCH_DATA_DIR", os.path.join(data_dir, "bitcoincash")), - "bindir": os.path.join(bin_dir, "bitcoincash"), - "port": BCH_PORT + port_offset, - "config_filename": "bitcoin.conf", - "use_segwit": False, - "blocks_confirmed": 1, - "conf_target": 2, - "core_version_no": getKnownVersion("bitcoincash"), - "core_version_group": 22, - }, "litecoin": { "connection_type": "rpc", "manage_daemon": shouldManageDaemon("LTC"), @@ -2410,22 +2423,6 @@ def main(): "core_version_group": 20, "min_relay_fee": 0.00001, }, - "dogecoin": { - "connection_type": "rpc", - "manage_daemon": shouldManageDaemon("DOGE"), - "rpchost": DOGE_RPC_HOST, - "rpcport": DOGE_RPC_PORT + port_offset, - "onionport": DOGE_ONION_PORT + port_offset, - "datadir": os.getenv("DOGE_DATA_DIR", os.path.join(data_dir, "dogecoin")), - "bindir": os.path.join(bin_dir, "dogecoin"), - "use_segwit": False, - "use_csv": False, - "blocks_confirmed": 2, - "conf_target": 2, - "core_version_no": getKnownVersion("dogecoin"), - "core_version_group": 23, - "min_relay_fee": 0.01, # RECOMMENDED_MIN_TX_FEE - }, "decred": { "connection_type": "rpc", "manage_daemon": shouldManageDaemon("DCR"), @@ -2453,14 +2450,16 @@ def main(): "manage_daemon": shouldManageDaemon("NMC"), "rpchost": NMC_RPC_HOST, "rpcport": NMC_RPC_PORT + port_offset, + "onionport": NMC_ONION_PORT + port_offset, "datadir": os.getenv("NMC_DATA_DIR", os.path.join(data_dir, "namecoin")), "bindir": os.path.join(bin_dir, "namecoin"), - "use_segwit": False, - "use_csv": False, + "port": NMC_PORT + port_offset, + "use_segwit": True, + "use_csv": True, "blocks_confirmed": 1, "conf_target": 2, "core_version_no": getKnownVersion("namecoin"), - "core_version_group": 18, + "core_version_group": 28, "chain_lookups": "local", }, "monero": { @@ -2486,6 +2485,28 @@ def main(): "core_version_no": getKnownVersion("monero"), "core_type_group": "xmr", }, + "wownero": { + "connection_type": "rpc", + "manage_daemon": shouldManageDaemon("WOW"), + "manage_wallet_daemon": shouldManageDaemon("WOW_WALLET"), + "rpcport": WOW_RPC_PORT + port_offset, + "zmqport": WOW_ZMQ_PORT + port_offset, + "walletrpcport": WOW_WALLET_RPC_PORT + port_offset, + "rpchost": WOW_RPC_HOST, + "trusted_daemon": extra_opts.get("trust_remote_node", "auto"), + "walletrpchost": WOW_WALLET_RPC_HOST, + "walletrpcuser": WOW_WALLET_RPC_USER, + "walletrpcpassword": WOW_WALLET_RPC_PWD, + "datadir": os.getenv("WOW_DATA_DIR", os.path.join(data_dir, "wownero")), + "bindir": os.path.join(bin_dir, "wownero"), + "restore_height": wow_restore_height, + "blocks_confirmed": 2, + "rpctimeout": 60, + "walletrpctimeout": 120, + "walletrpctimeoutlong": 300, + "core_version_no": getKnownVersion("wownero"), + "core_type_group": "xmr", + }, "pivx": { "connection_type": "rpc", "manage_daemon": shouldManageDaemon("PIVX"), @@ -2549,27 +2570,37 @@ def main(): "chain_lookups": "local", "startup_tries": 40, }, - "wownero": { + "bitcoincash": { "connection_type": "rpc", - "manage_daemon": shouldManageDaemon("WOW"), - "manage_wallet_daemon": shouldManageDaemon("WOW_WALLET"), - "rpcport": WOW_RPC_PORT + port_offset, - "zmqport": WOW_ZMQ_PORT + port_offset, - "walletrpcport": WOW_WALLET_RPC_PORT + port_offset, - "rpchost": WOW_RPC_HOST, - "trusted_daemon": extra_opts.get("trust_remote_node", "auto"), - "walletrpchost": WOW_WALLET_RPC_HOST, - "walletrpcuser": WOW_WALLET_RPC_USER, - "walletrpcpassword": WOW_WALLET_RPC_PWD, - "datadir": os.getenv("WOW_DATA_DIR", os.path.join(data_dir, "wownero")), - "bindir": os.path.join(bin_dir, "wownero"), - "restore_height": wow_restore_height, + "manage_daemon": shouldManageDaemon("BCH"), + "rpchost": BCH_RPC_HOST, + "rpcport": BCH_RPC_PORT + port_offset, + "onionport": BCH_ONION_PORT + port_offset, + "datadir": os.getenv("BCH_DATA_DIR", os.path.join(data_dir, "bitcoincash")), + "bindir": os.path.join(bin_dir, "bitcoincash"), + "port": BCH_PORT + port_offset, + "config_filename": "bitcoin.conf", + "use_segwit": False, + "blocks_confirmed": 1, + "conf_target": 2, + "core_version_no": getKnownVersion("bitcoincash"), + "core_version_group": 22, + }, + "dogecoin": { + "connection_type": "rpc", + "manage_daemon": shouldManageDaemon("DOGE"), + "rpchost": DOGE_RPC_HOST, + "rpcport": DOGE_RPC_PORT + port_offset, + "onionport": DOGE_ONION_PORT + port_offset, + "datadir": os.getenv("DOGE_DATA_DIR", os.path.join(data_dir, "dogecoin")), + "bindir": os.path.join(bin_dir, "dogecoin"), + "use_segwit": False, + "use_csv": False, "blocks_confirmed": 2, - "rpctimeout": 60, - "walletrpctimeout": 120, - "walletrpctimeoutlong": 300, - "core_version_no": getKnownVersion("wownero"), - "core_type_group": "xmr", + "conf_target": 2, + "core_version_no": getKnownVersion("dogecoin"), + "core_version_group": 23, + "min_relay_fee": 0.01, # RECOMMENDED_MIN_TX_FEE }, } @@ -2593,9 +2624,8 @@ def main(): coin_settings["wallet_name"] = set_name ticker: str = coin_params["ticker"] - if toBool(os.getenv(ticker + "_USE_DESCRIPTORS", False)): - - if coin_id not in (Coins.BTC,): + if getDescriptorWalletOption(coin_params): + if coin_id not in (Coins.BTC, Coins.NMC): raise ValueError(f"Descriptor wallet unavailable for {coin_name}") coin_settings["use_descriptors"] = True diff --git a/basicswap/bin/run.py b/basicswap/bin/run.py index 091e857..c34c721 100755 --- a/basicswap/bin/run.py +++ b/basicswap/bin/run.py @@ -265,7 +265,11 @@ def getCoreBinArgs(coin_id: int, coin_settings, prepare=False, use_tor_proxy=Fal # As BCH may use port 8334, disable it here. # When tor is enabled a bind option for the onionport will be added to bitcoin.conf. # https://github.com/bitcoin/bitcoin/blob/master/doc/release-notes/release-notes-28.0.md?plain=1#L84 - if prepare is False and use_tor_proxy is False and coin_id == Coins.BTC: + if ( + prepare is False + and use_tor_proxy is False + and coin_id in (Coins.BTC, Coins.NMC) + ): port: int = coin_settings.get("port", 8333) extra_args.append(f"--bind=0.0.0.0:{port}") return extra_args diff --git a/basicswap/chainparams.py b/basicswap/chainparams.py index 7ed0935..efbb58b 100644 --- a/basicswap/chainparams.py +++ b/basicswap/chainparams.py @@ -58,6 +58,8 @@ chainparams = { "bip44": 44, "min_amount": 100000, "max_amount": 10000000 * COIN, + "ext_public_key_prefix": 0x696E82D1, + "ext_secret_key_prefix": 0x8F1DAEB8, }, "testnet": { "rpcport": 51935, @@ -69,6 +71,8 @@ chainparams = { "bip44": 1, "min_amount": 100000, "max_amount": 10000000 * COIN, + "ext_public_key_prefix": 0xE1427800, + "ext_secret_key_prefix": 0x04889478, }, "regtest": { "rpcport": 51936, @@ -80,6 +84,8 @@ chainparams = { "bip44": 1, "min_amount": 100000, "max_amount": 10000000 * COIN, + "ext_public_key_prefix": 0xE1427800, + "ext_secret_key_prefix": 0x04889478, }, }, Coins.BTC: { @@ -251,29 +257,38 @@ chainparams = { "rpcport": 8336, "pubkey_address": 52, "script_address": 13, + "key_prefix": 180, "hrp": "nc", "bip44": 7, "min_amount": 100000, "max_amount": 10000000 * COIN, + "ext_public_key_prefix": 0x0488B21E, # base58Prefixes[EXT_PUBLIC_KEY] + "ext_secret_key_prefix": 0x0488ADE4, }, "testnet": { "rpcport": 18336, "pubkey_address": 111, "script_address": 196, + "key_prefix": 239, "hrp": "tn", "bip44": 1, "min_amount": 100000, "max_amount": 10000000 * COIN, "name": "testnet3", + "ext_public_key_prefix": 0x043587CF, + "ext_secret_key_prefix": 0x04358394, }, "regtest": { "rpcport": 18443, "pubkey_address": 111, "script_address": 196, + "key_prefix": 239, "hrp": "ncrt", "bip44": 1, "min_amount": 100000, "max_amount": 10000000 * COIN, + "ext_public_key_prefix": 0x043587CF, + "ext_secret_key_prefix": 0x04358394, }, }, Coins.XMR: { diff --git a/basicswap/config.py b/basicswap/config.py index 9c8d06d..cc010a0 100644 --- a/basicswap/config.py +++ b/basicswap/config.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2019-2024 The Basicswap developers +# Copyright (c) 2019-2025 The Basicswap developers # Distributed under the MIT software license, see the accompanying # file LICENSE or http://www.opensource.org/licenses/mit-license.php. @@ -40,13 +40,6 @@ DOGECOIND = os.getenv("DOGECOIND", "dogecoind" + bin_suffix) DOGECOIN_CLI = os.getenv("DOGECOIN_CLI", "dogecoin-cli" + bin_suffix) DOGECOIN_TX = os.getenv("DOGECOIN_TX", "dogecoin-tx" + bin_suffix) -NAMECOIN_BINDIR = os.path.expanduser( - os.getenv("NAMECOIN_BINDIR", os.path.join(DEFAULT_TEST_BINDIR, "namecoin")) -) -NAMECOIND = os.getenv("NAMECOIND", "namecoind" + bin_suffix) -NAMECOIN_CLI = os.getenv("NAMECOIN_CLI", "namecoin-cli" + bin_suffix) -NAMECOIN_TX = os.getenv("NAMECOIN_TX", "namecoin-tx" + bin_suffix) - XMR_BINDIR = os.path.expanduser( os.getenv("XMR_BINDIR", os.path.join(DEFAULT_TEST_BINDIR, "monero")) ) diff --git a/basicswap/interface/btc.py b/basicswap/interface/btc.py index 618ddec..b8656c8 100644 --- a/basicswap/interface/btc.py +++ b/basicswap/interface/btc.py @@ -1862,20 +1862,70 @@ class BTCInterface(Secp256k1Interface): "Could not find address with enough funds for proof", ) - self._log.debug("sign_for_addr %s", sign_for_addr) + self._log.debug(f"sign_for_addr {sign_for_addr}") + funds_addr: str = sign_for_addr if ( self.using_segwit() ): # TODO: Use isSegwitAddress when scantxoutset can use combo # 'Address does not refer to key' for non p2pkh pkh = self.decodeAddress(sign_for_addr) sign_for_addr = self.pkh_to_address(pkh) - self._log.debug("sign_for_addr converted %s", sign_for_addr) + self._log.debug(f"sign_for_addr converted {sign_for_addr}") - signature = self.rpc_wallet( - "signmessage", - [sign_for_addr, sign_for_addr + "_swap_proof_" + extra_commit_bytes.hex()], - ) + if self._use_descriptors: + # https://github.com/bitcoin/bitcoin/issues/10542 + # https://github.com/bitcoin/bitcoin/issues/26046 + priv_keys = self.rpc_wallet( + "listdescriptors", + [ + True, + ], + ) + addr_info = self.rpc_wallet( + "getaddressinfo", + [ + funds_addr, + ], + ) + hdkeypath = addr_info["hdkeypath"] + + sign_for_address_key = None + for descriptor in priv_keys["descriptors"]: + if descriptor["active"] is False or descriptor["internal"] is True: + continue + desc = descriptor["desc"] + assert desc.startswith("wpkh(") + ext_key = desc[5:].split(")")[0].split("/", 1)[0] + ext_key_data = decodeAddress(ext_key)[4:] + ci_part = self._sc.ci(Coins.PART) + ext_key_data_part = ci_part.encode_secret_extkey(ext_key_data) + rv = ci_part.rpc_wallet( + "extkey", ["info", ext_key_data_part, hdkeypath] + ) + extkey_derived = rv["key_info"]["result"] + ext_key_data = decodeAddress(extkey_derived)[4:] + ek = ExtKeyPair() + ek.decode(ext_key_data) + sign_for_address_key = self.encodeKey(ek._key) + break + assert sign_for_address_key is not None + signature = self.rpc( + "signmessagewithprivkey", + [ + sign_for_address_key, + sign_for_addr + "_swap_proof_" + extra_commit_bytes.hex(), + ], + ) + del priv_keys + else: + signature = self.rpc_wallet( + "signmessage", + [ + sign_for_addr, + sign_for_addr + "_swap_proof_" + extra_commit_bytes.hex(), + ], + ) prove_utxos = [] # TODO: Send specific utxos return (sign_for_addr, signature, prove_utxos) diff --git a/basicswap/interface/nmc.py b/basicswap/interface/nmc.py index cf9bae7..0214857 100644 --- a/basicswap/interface/nmc.py +++ b/basicswap/interface/nmc.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- # Copyright (c) 2020-2022 tecnovert +# Copyright (c) 2025 The Basicswap developers # Distributed under the MIT software license, see the accompanying # file LICENSE or http://www.opensource.org/licenses/mit-license.php. @@ -13,39 +14,3 @@ class NMCInterface(BTCInterface): @staticmethod def coin_type(): return Coins.NMC - - def getLockTxHeight( - self, - txid, - dest_address, - bid_amount, - rescan_from, - find_index: bool = False, - vout: int = -1, - ): - self._log.debug("[rm] scantxoutset start") # scantxoutset is slow - ro = self.rpc( - "scantxoutset", ["start", ["addr({})".format(dest_address)]] - ) # TODO: Use combo(address) where possible - self._log.debug("[rm] scantxoutset end") - return_txid = True if txid is None else False - for o in ro["unspents"]: - if txid and o["txid"] != txid.hex(): - continue - # Verify amount - if self.make_int(o["amount"]) != int(bid_amount): - self._log.warning( - "Found output to lock tx address of incorrect value: %s, %s", - str(o["amount"]), - o["txid"], - ) - continue - - rv = {"depth": 0, "height": o["height"]} - if o["height"] > 0: - rv["depth"] = ro["height"] - o["height"] - if find_index: - rv["index"] = o["vout"] - if return_txid: - rv["txid"] = o["txid"] - return rv diff --git a/basicswap/pgp/keys/bitcoincash_Calin_Culianu.pgp b/basicswap/pgp/keys/bitcoincash_Calin_Culianu.pgp new file mode 100644 index 0000000..7ddba13 --- /dev/null +++ b/basicswap/pgp/keys/bitcoincash_Calin_Culianu.pgp @@ -0,0 +1,25 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQMuBFmZ6L4RCACuqDDCIe2bzKznyKVN1aInzRQnSxdGTXuw0mcDz5HYudAhBjR8 +gY6sxCRPNxvZCJVDZDpCygXMhWZlJtWLR8KMTCXxC4HLXXOY4RxQ5KGnYWxEAcKY +deq1ymmuOuMUp7ltRTSyWcBKbR9xTd2vW/+0W7GQIOxUW/aiT1V0x3cky+6kqaec +BorP3+uxJcx0Q8WdlS/6N4x3pBv/lfsdrZSaDD8fU/29pQGMDUEnupKoWJVVei6r +G+vxLHEtIFYYO8VWjZntymw3dl+aogrjyuxqWzl8mfPi9M/DgiRb4pJnH2yOGDI6 +Lvg+oo9E79Vwi98UjYSicsB1dtcptKiA96UXAQD/hDB+dil7/SX/SDTlaw/+uTdd +Xg0No63dbN++iY4k3Qf/Xk1ZzbuDviLhe+zEhlJOw6TaMlxfwwQOtxEJXILS5uIL +jYlGcDbBtJh3p4qUoUduDOgjumJ9m47XqIq81rQ0pqzzGMbK1Y82NQjX5Sn8yTm9 +p1hmOZ/uX9vCrUSbYBjxJXyQ1OXlerlLRLfBf5WQ0+LO+0cmgtCyX0zV4oGK7vph +XEm7lar7AezOOXaSrWAB+CTPUdJF1E7lcJiUuMVcqMx8pphrH+rfcsqPtN6tkyUD +TmPDpc5ViqFFelEEQnKSlmAY+3iCNZ3y/VdPPhuJ2lAsL3tm9MMh2JGV378LG45a +6SOkQrC977Qq1dhgJA+PGJxQvL2RJWsYlJwp79+Npgf9EfFaJVNzbdjGVq1XmNie +MZYqHRfABkyK0ooDxSyzJrq4vvuhWKInS4JhpKSabgNSsNiiaoDR+YYMHb0H8GRR +Za6JCmfU8w97R41UTI32N7dhul4xCDs5OV6maOIoNts20oigNGb7TKH9b5N7sDJB +zh3Of/fHCChO9Y2chbzU0bERfcn+evrWBf/9XdQGQ3ggoLbOtGpcUQuB/7ofTcBZ +awL6K4VJ2Qlb8DPlRgju6uU9AR/KTYeAlVFC8FX7R0FGgPRcJ3GNkNHGqrbuQ72q +AOhYOPx9nRrU5u+E2J325vOabLnLbOazze3j6LFPSFV4vfmTO9exYlwhz3g+lFAd +CrQ2Q2FsaW4gQ3VsaWFudSAoTmlsYWNUaGVHcmltKSA8Y2FsaW4uY3VsaWFudUBn +bWFpbC5jb20+iHoEExEIACIFAlmZ6L4CGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4B +AheAAAoJECGBClQgMcAsU5cBAO/ngONpHsxny2uTV4ge2f+5V2ajTjcIfN2jUZtg +31jJAQCl1NcrwcIu98+aM2IyjB1UFXkoaMANpr8L9jBopivRGQ== +=cf8I +-----END PGP PUBLIC KEY BLOCK----- diff --git a/basicswap/pgp/keys/namecoin_JeremyRand.pgp b/basicswap/pgp/keys/namecoin_JeremyRand.pgp deleted file mode 100644 index 0e0ce2a..0000000 --- a/basicswap/pgp/keys/namecoin_JeremyRand.pgp +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -mDMEXPNfCBYJKwYBBAHaRw8BAQdAWGFiEJYnlV2TDTesLIO/eoQ3IPduzcG97GpA -6K+Gj+K0K0BKZXJlbXlSYW5kIG9uIEdpdEh1YiA8amVyZW15QG5hbWVjb2luLm9y -Zz6IlgQTFggAPhYhBJza8EpykDv+wJWdvi2+M54p9ilMBQJc88q7AhsDBQkB4TOA -BQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEC2+M54p9ilMMUoA/1oZn8AtwQ7D -wXgNKq++zqHaiEcHGgsyFeDRbQARsYRVAQDxa36p181id1YuMjeV1KhC5vaDS4nY -GB4FHPsQ4bbqDLRESmVyZW15IFJhbmQgKE5hbWVjb2luIENvcmUgR2l0aWFuIFNp -Z25pbmcgS2V5KSA8amVyZW15QG5hbWVjb2luLm9yZz6ImQQTFggAQQIbAwUJAeEz -gAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBJza8EpykDv+wJWdvi2+M54p9ilM -BQJc9WDrAhkBAAoJEC2+M54p9ilMz3IA/3mCKeFYcEJFlwP43mdIMGOV2zt/R4Fn -z/rBJpv5hFoHAQDXAY8+mbY/9N+5Rn8Iy51tXEaTq3khdruuFFdty+bXAg== -=EpnJ ------END PGP PUBLIC KEY BLOCK----- diff --git a/basicswap/pgp/keys/namecoin_RoseTuring.pgp b/basicswap/pgp/keys/namecoin_RoseTuring.pgp new file mode 100644 index 0000000..97c8076 --- /dev/null +++ b/basicswap/pgp/keys/namecoin_RoseTuring.pgp @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=atlH +-----END PGP PUBLIC KEY BLOCK----- diff --git a/basicswap/pgp/keys/particl_tecnovert.pgp b/basicswap/pgp/keys/particl_tecnovert.pgp index fdc95c3..833df15 100644 --- a/basicswap/pgp/keys/particl_tecnovert.pgp +++ b/basicswap/pgp/keys/particl_tecnovert.pgp @@ -1,78 +1,29 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- -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 -XHovfCfpcB/C -=0Wkp +mQINBFlLyYIBEADW3oJnVMDC94g+7OB1/IBUYNevCqJIOAtC0eeFS5g0XGvvqRLx +2NLUqn5te+R7deoGElkZFJLLxFUwEnhqGCRH50Iou5aanUzvgI5fVAbK3k0fp9vc +LKCR0fQVIidcLyqMpkLZo8BSE3+BWxFp/r2OHvh2dYtJC+BZVwblkDS3cqwKvUZx +IocvDs47Wo3tzZfEsqUavbbiGx+Dm0fCV7TVHdVLU7q3bZsHSRiyTUZ2EAApoAmT +ir9csVxv2IM8yf6/HwWi6/Lp7dgSG1+qBZ1lUPPTY+dFLPZyt/kul+vuOj6GLZaU +s3D66d7TaPCHKWAOnP9RHpic/iXODXVXo1KHJfa0x8fW7I+y7/Gb+5x/m4O0Bz2T +BivdrSAuFpXkPqwawlw4CPgI9fc801g83+ZFzD2jJ6qxkEgfnlmf+zGNn5tC4N5j +NRTQ+GyHo1w4824SXcSN590wgz8goGJC3QPJxbifvOA8GzQIVzpxHckofOVyqIEq +qSnkP2xn4mELqD7HcFnoojZBqFbF2cN+oWQ+niLN+v4qrUncpQI9SVWlyp66S+1T +BhBQj2QuX+3B+K27EiDbhNV7EX6xEbGsnB1poMc2aMiz6veybW3GnoM+2ppr8Ko/ +12Ij7l+ZA44t6PWUfQQbNSbUk/0Yhd9QJ8VQVck+TaS6gtarTbURlSdmHwARAQAB +tCl0ZWNub3ZlcnQgKGdpdGlhbikgPHRlY25vdmVydEBwYXJ0aWNsLmlvPokCVAQT +AQgAPhYhBI5RfcEuwcw39kI6ihPxNlHJzw1rBQJZS8mCAhsDBQkSzAMABQsJCAcC +BhUICQoLAgQWAgMBAh4BAheAAAoJEBPxNlHJzw1rtdYP/22iRX8O2Q++MayPHNx5 +XHAlMk9mfi5FB1qJwshtlhda7P9U/hOTi227wH+Mzh5dBje4t2DkoHzxlz/Wr4cQ +QUJMOYd0OEZY6kpAQkvtyYobIb6zlRQK1koAfNMxewmfZZGTlr16IUVCovGSFvZ+ +hdYRDEjuHqXjpwBfrxFAy/HCnfY10qSRkJc5w1ypj1IkzlanS+xeRJSDvRTQDAEr +zv3xKcMGjCCHaaCP+tyAaViBaUOlvmZdWwg0gwQCuPLqIh0cfDbcg0quciRIpnyp +zINmfwngZCwXdIYfAzmCzMHw1J3iOiqfqK0EcpHMsL689VyQSPgsoEHtcOGHYjRL +pMPGvRFHtICrnCHENK3IcwFWDGXW+i3zgOlA7g48yYWWvSup+t8I6YT+FeeFlxSO +dj1GdeMA0O7gXZ7znLVduokL2Ef4dZjc+3NwBlFov52vwCZwQMAGsMriwEDB2rDZ +B7YOvAxlUB/kavtx/oE8fV7mZcuwYg02lq4bozF9xlhjOFaRit6xXnLVi0TuI76c +uz67nB9VkWczSLIzCyjNyFpWbx1BMxTYfehZX3+YNajXwG6HdEp9CAYK0u46Guz/ +Pth67bbNVYyP/cuOIrv/hqQ6xo4mOBMDDxcCEAXx3rwxfbxNM8vlwrMcpITrtNON +r41bcxUIfMEDefPm5wnXep8W +=szpX -----END PGP PUBLIC KEY BLOCK----- diff --git a/basicswap/pgp/keys/wownero_wowario.pgp b/basicswap/pgp/keys/wownero_wowario.pgp new file mode 100644 index 0000000..fb6078b --- /dev/null +++ b/basicswap/pgp/keys/wownero_wowario.pgp @@ -0,0 +1,29 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBGROehcBEACXWWc6dHqCos1PmKI32iHi0jP3mYM3jU57YxbjwT78QEtEwSqf +YklpXkgTYq7jexx2JElfegM6w1sPYarq1y051RjnCgzl32da5I506SMvcJTmXumV +Rw6erPeDxAO74PflDSlALgtGOgbKhwwWRudbWgT5hKGkl62qy0mI6GStul0rbT+3 +gq77DCGyURfe1PG1pymhO5XVz3WGtOa12NvRA+3wGIcqIji2MbtXuOhGMg//kVI5 +m2vcfHyMMuQ01xUXRu57WxRujYaJ1RB4p86JCbDX3YU2XlzTxGAhqChDLuJGqo54 +AZMUWDceftXsAoOqH8Hwmm5gFkYSpMt86ZT+umvWygmxohD5k85MuRj4AGagFj/u +CMcQjI/SN1UU/Qozg6VL/5FO8aH9IybDzX7eE3j0V/jTweStw1CIUajYgfemWOWl +whLPBDflRz/8EEqTN0CaSSaiYiULZUiawBO/bRIiCO2Q6QrAi3KpPUhCwiw/Yecd +rAMLH7bytpECDdbNonQ/VMxWwtWJQ87qBtWvHFQxXBKjyuANsKL9X7v3KcYOUdd2 +fSt7eqE9GDT4DbK6sTmuTpq2TgHXET0cA39+N2zxTh5xFupI/pi2iAHJ6hgIiQnn +662TngjGOSFvrTV/51Ua0Vx8OCMJJOcRdOVaYzuzg9DsjVcJin3aRqUh4wARAQAB +tCBXb3dhcmlvIDx3b3dhcmlvQHByb3Rvbm1haWwuY29tPokCVAQTAQgAPhYhBKs6 +L3JYGPz/J5SEHHk1BLRJxpIgBQJkTnoXAhsDBQkHhh77BQsJCAcCBhUKCQgLAgQW +AgMBAh4BAheAAAoJEHk1BLRJxpIgwgEP/109vw1WXRh9EaRr3Y1+sBi+/PRQ5TCx +UEcP9ru5sQPJ0BsZK8RYw0BNIfDQX9OB1k/AoiBelL+0EoDKvjXmwz9fPUmSVk5r +3RzfClXTnxn4HXPKkSGMt4WBUnvohTexK7CPkb9xy+K0Jtx8XF1XiQLDFg2a9lBj +IIX2H6aHn4VjdUBv7TrTCAI2Vg0cQUpeJUwyHH+lk0r2WM3zAxzS3Iy2yDDstNT8 +audXEX4BtJhyEU1m57jwgscrbTtgwYOAsaRLcnUaAFWhbov3IiGInk7N1fkMsuW5 +HE5RcegSZRS3X4o6O/nmwdSjCEB9weydOCPrtfdbvfvuTiMg/jZBikOk/Sj7FM/D +eZKghSHpLbT/V3S76FyIcc/xFkUmR+2fGvCNjJ1Qn2lXTS8xcbyzqR4LZPeUGppV +hvriilLnXSjyc60wuD3kmCCo1Zw4tNL8pr09BtVmScUy6eiwca8LLzvbbivqxF1g +Mrkkv8yQE0ZwO1kgNSn+PSzUPbwAoklcyN5Rhr5DxZh0UudiH5Jt5WWYeE8O2Uc1 +si13X575kymGkkeiUcp9WtBkh2uial+RVmTrUTDUTIR2HzT6MAR84/DHlC5dsW8a +h4uDUhzeG2cTxuIfZC881UHKL+xT/I3PPuFdLbU5uoWJpXYpxKYulYWd7LA/k4bi +JWBrQo7VDvvP +=H3wS +-----END PGP PUBLIC KEY BLOCK----- diff --git a/basicswap/static/images/coins/Namecoin-20.png b/basicswap/static/images/coins/Namecoin-20.png new file mode 100644 index 0000000..204808d Binary files /dev/null and b/basicswap/static/images/coins/Namecoin-20.png differ diff --git a/basicswap/static/images/coins/Namecoin.png b/basicswap/static/images/coins/Namecoin.png new file mode 100644 index 0000000..4e8f2d6 Binary files /dev/null and b/basicswap/static/images/coins/Namecoin.png differ diff --git a/basicswap/static/js/bids_available.js b/basicswap/static/js/bids_available.js index 3cb11e8..53d5251 100644 --- a/basicswap/static/js/bids_available.js +++ b/basicswap/static/js/bids_available.js @@ -10,6 +10,7 @@ const COIN_NAME_TO_SYMBOL = { 'Firo': 'FIRO', 'Dash': 'DASH', 'Decred': 'DCR', + 'Namecoin': 'NMC', 'Wownero': 'WOW', 'Bitcoin Cash': 'BCH', 'Dogecoin': 'DOGE' @@ -335,13 +336,13 @@ const createBidTableRow = async (bid) => {
- Offer ID: + Offer ID: ${formatAddress(bid.offer_id)}
- Bid ID: + Bid ID: ${formatAddress(bid.bid_id)} @@ -366,8 +367,8 @@ const createBidTableRow = async (bid) => {
- ${bid.coin_from} @@ -375,15 +376,14 @@ const createBidTableRow = async (bid) => { - ${bid.coin_to}
-
@@ -410,7 +410,7 @@ const createBidTableRow = async (bid) => { - Accept @@ -506,13 +506,13 @@ const createDetailsColumn = (bid, identity, uniqueId) => `
- Offer ID: + Offer ID: ${formatAddress(bid.offer_id)}
- Bid ID: + Bid ID: ${formatAddress(bid.bid_id)} diff --git a/basicswap/static/js/modules/api-manager.js b/basicswap/static/js/modules/api-manager.js index 9f299e1..e166593 100644 --- a/basicswap/static/js/modules/api-manager.js +++ b/basicswap/static/js/modules/api-manager.js @@ -220,7 +220,7 @@ const ApiManager = (function() { .filter(coin => coin.usesCoinGecko) .map(coin => coin.name) .join(',') : - 'bitcoin,monero,particl,bitcoincash,pivx,firo,dash,litecoin,dogecoin,decred'; + 'bitcoin,monero,particl,bitcoincash,pivx,firo,dash,litecoin,dogecoin,decred,namecoin'; //console.log('Fetching coin prices for:', coins); const response = await this.fetchCoinPrices(coins); @@ -254,7 +254,7 @@ const ApiManager = (function() { .filter(coin => coin.usesCoinGecko) .map(coin => getCoinBackendId ? getCoinBackendId(coin.name) : coin.name) .join(',') : - 'bitcoin,monero,particl,bitcoin-cash,pivx,firo,dash,litecoin,dogecoin,decred'; + 'bitcoin,monero,particl,bitcoin-cash,pivx,firo,dash,litecoin,dogecoin,decred,namecoin'; const url = `https://api.coingecko.com/api/v3/simple/price?ids=${coins}&vs_currencies=usd&include_24hr_vol=true&include_24hr_change=true`; diff --git a/basicswap/static/js/modules/cache-manager.js b/basicswap/static/js/modules/cache-manager.js index e8fba7c..1deddc8 100644 --- a/basicswap/static/js/modules/cache-manager.js +++ b/basicswap/static/js/modules/cache-manager.js @@ -504,13 +504,14 @@ const CacheManager = (function() { 'bitcoin': 'BTC', 'litecoin': 'LTC', 'monero': 'XMR', + 'wownero': 'WOW', 'particl': 'PART', 'pivx': 'PIVX', 'firo': 'FIRO', 'zcoin': 'FIRO', 'dash': 'DASH', 'decred': 'DCR', - 'wownero': 'WOW', + 'namecoin': 'NMR', 'bitcoin-cash': 'BCH', 'dogecoin': 'DOGE' }; diff --git a/basicswap/static/js/modules/config-manager.js b/basicswap/static/js/modules/config-manager.js index 1176cc3..0b70751 100644 --- a/basicswap/static/js/modules/config-manager.js +++ b/basicswap/static/js/modules/config-manager.js @@ -72,6 +72,7 @@ const ConfigManager = (function() { { symbol: 'LTC', name: 'litecoin', usesCryptoCompare: true, usesCoinGecko: true, historicalDays: 30 }, { symbol: 'DOGE', name: 'dogecoin', usesCryptoCompare: true, usesCoinGecko: true, historicalDays: 30 }, { symbol: 'DCR', name: 'decred', usesCryptoCompare: true, usesCoinGecko: true, historicalDays: 30 }, + { symbol: 'NMC', name: 'namecoin', usesCryptoCompare: true, usesCoinGecko: true, historicalDays: 30 }, { symbol: 'WOW', name: 'wownero', usesCryptoCompare: false, usesCoinGecko: true, historicalDays: 30 } ], @@ -88,6 +89,7 @@ const ConfigManager = (function() { 'Zcoin': 'FIRO', 'Dash': 'DASH', 'Decred': 'DCR', + 'Namecoin': 'NMC', 'Wownero': 'WOW', 'Bitcoin Cash': 'BCH', 'Dogecoin': 'DOGE' @@ -105,13 +107,14 @@ const ConfigManager = (function() { 'Zcoin': 'Firo', 'Dash': 'Dash', 'Decred': 'Decred', + 'Namecoin': 'Namecoin', 'Wownero': 'Wownero', 'Bitcoin Cash': 'Bitcoin Cash', 'Dogecoin': 'Dogecoin' }, idToName: { - 1: 'particl', 2: 'bitcoin', 3: 'litecoin', 4: 'decred', + 1: 'particl', 2: 'bitcoin', 3: 'litecoin', 4: 'decred', 5: 'namecoin', 6: 'monero', 7: 'particl blind', 8: 'particl anon', 9: 'wownero', 11: 'pivx', 13: 'firo', 17: 'bitcoincash', 18: 'dogecoin' @@ -130,6 +133,7 @@ const ConfigManager = (function() { 'litecoin': 'litecoin', 'dogecoin': 'dogecoin', 'decred': 'decred', + 'namecoin': 'namecoin', 'wownero': 'wownero' } }, @@ -367,6 +371,7 @@ const ConfigManager = (function() { 'dash': { usd: null, btc: null }, 'dogecoin': { usd: null, btc: null }, 'decred': { usd: null, btc: null }, + 'namecoin': { usd: null, btc: null }, 'litecoin': { usd: null, btc: null }, 'particl': { usd: null, btc: null }, 'pivx': { usd: null, btc: null }, diff --git a/basicswap/static/js/modules/wallet-manager.js b/basicswap/static/js/modules/wallet-manager.js index b97f5b6..6b4b775 100644 --- a/basicswap/static/js/modules/wallet-manager.js +++ b/basicswap/static/js/modules/wallet-manager.js @@ -35,6 +35,7 @@ const WalletManager = (function() { 'Dash': 'DASH', 'PIVX': 'PIVX', 'Decred': 'DCR', + 'Namecoin': 'NMC', 'Bitcoin Cash': 'BCH' }, @@ -49,6 +50,7 @@ const WalletManager = (function() { 'DASH': 'dash', 'PIVX': 'pivx', 'DCR': 'dcr', + 'NMC': 'nmc', 'BCH': 'bch' }, @@ -63,6 +65,7 @@ const WalletManager = (function() { 'Dash': 'DASH', 'PIVX': 'PIVX', 'Decred': 'DCR', + 'Namecoin': 'NMC', 'Bitcoin Cash': 'BCH', 'Dogecoin': 'DOGE' } diff --git a/basicswap/static/js/offers.js b/basicswap/static/js/offers.js index 1d534cf..355f3ec 100644 --- a/basicswap/static/js/offers.js +++ b/basicswap/static/js/offers.js @@ -34,6 +34,7 @@ window.tableRateModule = { 'Dash': 'DASH', 'PIVX': 'PIVX', 'Decred': 'DCR', + 'Namecoin': 'NMC', 'Zano': 'ZANO', 'Bitcoin Cash': 'BCH', 'Dogecoin': 'DOGE' @@ -56,9 +57,9 @@ window.tableRateModule = { }, setCachedValue(key, value, resourceType = null) { - const ttl = resourceType ? - window.config.cacheConfig.ttlSettings[resourceType] || - window.config.cacheConfig.defaultTTL : + const ttl = resourceType ? + window.config.cacheConfig.ttlSettings[resourceType] || + window.config.cacheConfig.defaultTTL : 900000; const item = { @@ -306,13 +307,14 @@ async function calculateProfitLoss(fromCoin, toCoin, fromAmount, toAmount, isOwn 'ltc': 'litecoin', 'doge': 'dogecoin', 'dcr': 'decred', + 'nmc': 'namecoin', 'wow': 'wownero' }; if (lowerCoin === 'zcoin') return 'firo'; if (lowerCoin === 'bitcoin cash') return 'bitcoin-cash'; if (lowerCoin === 'particl anon' || lowerCoin === 'particl blind') return 'particl'; - + return symbolToName[lowerCoin] || lowerCoin; }; @@ -406,7 +408,7 @@ async function fetchLatestPrices() { const coinIds = [ 'bitcoin', 'particl', 'monero', 'litecoin', 'dogecoin', 'firo', 'dash', 'pivx', - 'decred', 'bitcoincash' + 'decred', 'namecoin', 'bitcoincash' ]; let processedData = {}; @@ -419,7 +421,7 @@ async function fetchLatestPrices() { if (mainResponse && mainResponse.rates) { Object.entries(mainResponse.rates).forEach(([coinId, price]) => { const normalizedCoinId = coinId === 'bitcoincash' ? 'bitcoin-cash' : coinId.toLowerCase(); - + processedData[normalizedCoinId] = { usd: price, btc: normalizedCoinId === 'bitcoin' ? 1 : price / (mainResponse.rates.bitcoin || 1) @@ -453,7 +455,7 @@ async function fetchLatestPrices() { } catch (error) { console.error(`Price fetch attempt ${attempt + 1} failed:`, error); NetworkManager.handleNetworkError(error); - + if (attempt < MAX_RETRIES - 1) { const delay = Math.min(500 * Math.pow(2, attempt), 5000); await new Promise(resolve => setTimeout(resolve, delay)); @@ -520,7 +522,7 @@ async function fetchOffers() { originalJsonData = [...jsonData]; latestPrices = pricesData || getEmptyPriceData(); - + CacheManager.set('offers_cached', jsonData, 'offers'); await updateOffersTable(); @@ -1353,7 +1355,7 @@ function createRateColumn(offer, coinFrom, coinTo) { const getPriceKey = (coin) => { const lowerCoin = coin.toLowerCase(); - + const symbolToName = { 'btc': 'bitcoin', 'xmr': 'monero', @@ -1365,13 +1367,14 @@ function createRateColumn(offer, coinFrom, coinTo) { 'ltc': 'litecoin', 'doge': 'dogecoin', 'dcr': 'decred', + 'nmc': 'namecoin', 'wow': 'wownero' }; - + if (lowerCoin === 'zcoin') return 'firo'; if (lowerCoin === 'bitcoin cash') return 'bitcoin-cash'; if (lowerCoin === 'particl anon' || lowerCoin === 'particl blind') return 'particl'; - + return symbolToName[lowerCoin] || lowerCoin; }; @@ -1655,23 +1658,24 @@ function createTooltipContent(isSentOffers, coinFrom, coinTo, fromAmount, toAmou 'ltc': 'litecoin', 'doge': 'dogecoin', 'dcr': 'decred', + 'nmc': 'namecoin', 'wow': 'wownero' }; if (lowerCoin === 'zcoin') return 'firo'; if (lowerCoin === 'bitcoin cash') return 'bitcoin-cash'; if (lowerCoin === 'particl anon' || lowerCoin === 'particl blind') return 'particl'; - + return symbolToName[lowerCoin] || lowerCoin; }; - + if (latestPrices && latestPrices['firo'] && !latestPrices['zcoin']) { latestPrices['zcoin'] = JSON.parse(JSON.stringify(latestPrices['firo'])); } const fromSymbol = getPriceKey(coinFrom); const toSymbol = getPriceKey(coinTo); - + let fromPriceUSD = latestPrices && latestPrices[fromSymbol] ? latestPrices[fromSymbol].usd : null; let toPriceUSD = latestPrices && latestPrices[toSymbol] ? latestPrices[toSymbol].usd : null; @@ -1685,7 +1689,7 @@ function createTooltipContent(isSentOffers, coinFrom, coinTo, fromAmount, toAmou isNaN(fromPriceUSD) || isNaN(toPriceUSD)) { return `

Price Information Unavailable

Current market prices are temporarily unavailable.

-

You are ${isSentOffers ? 'selling' : 'buying'} ${fromAmount.toFixed(8)} ${coinFrom} +

You are ${isSentOffers ? 'selling' : 'buying'} ${fromAmount.toFixed(8)} ${coinFrom} for ${toAmount.toFixed(8)} ${coinTo}.

Note:

Profit/loss calculations will be available when price data is restored.

`; @@ -1757,13 +1761,14 @@ function createCombinedRateTooltip(offer, coinFrom, coinTo, treatAsSentOffer) { 'ltc': 'litecoin', 'doge': 'dogecoin', 'dcr': 'decred', + 'nmc': 'namecoin', 'wow': 'wownero' }; if (lowerCoin === 'zcoin') return 'firo'; if (lowerCoin === 'bitcoin cash') return 'bitcoin-cash'; if (lowerCoin === 'particl anon' || lowerCoin === 'particl blind') return 'particl'; - + return symbolToName[lowerCoin] || lowerCoin; }; @@ -1876,7 +1881,7 @@ function clearFilters() { jsonData = [...originalJsonData]; currentPage = 1; - + const storageKey = isSentOffers ? 'sentOffersTableSettings' : 'networkOffersTableSettings'; localStorage.removeItem(storageKey); @@ -2194,7 +2199,7 @@ async function initializeTableAndData() { function loadSavedSettings() { const storageKey = isSentOffers ? 'sentOffersTableSettings' : 'networkOffersTableSettings'; const saved = localStorage.getItem(storageKey); - + if (saved) { const settings = JSON.parse(saved); @@ -2229,7 +2234,7 @@ document.addEventListener('DOMContentLoaded', async () => { NetworkManager.initialize({ connectionTestEndpoint: '/json', connectionTestTimeout: 3000, - reconnectDelay: 5000, + reconnectDelay: 5000, maxReconnectAttempts: 5 }); window.networkManagerInitialized = true; @@ -2252,7 +2257,7 @@ document.addEventListener('DOMContentLoaded', async () => { }); const tableLoadPromise = initializeTableAndData(); - + WebSocketManager.initialize({ debug: false }); @@ -2262,7 +2267,7 @@ document.addEventListener('DOMContentLoaded', async () => { if (!NetworkManager.isOnline()) { return; } - + const endpoint = isSentOffers ? '/json/sentoffers' : '/json/offers'; const response = await fetch(endpoint); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); @@ -2349,7 +2354,7 @@ async function cleanup() { lastRefreshTime = null; const domRefs = [ - 'offersBody', 'filterForm', 'prevPageButton', 'nextPageButton', + 'offersBody', 'filterForm', 'prevPageButton', 'nextPageButton', 'currentPageSpan', 'totalPagesSpan', 'lastRefreshTimeSpan', 'newEntriesCountSpan' ]; diff --git a/basicswap/static/js/pricechart.js b/basicswap/static/js/pricechart.js index 1e785d1..b8b818a 100644 --- a/basicswap/static/js/pricechart.js +++ b/basicswap/static/js/pricechart.js @@ -548,7 +548,7 @@ const ui = { }, setActiveContainer: (containerId) => { - const containerIds = ['btc', 'xmr', 'part', 'pivx', 'firo', 'dash', 'ltc', 'doge', 'eth', 'dcr', 'zano', 'wow', 'bch'].map(id => `${id}-container`); + const containerIds = ['btc', 'xmr', 'part', 'pivx', 'firo', 'dash', 'ltc', 'doge', 'eth', 'dcr', 'nmc', 'zano', 'wow', 'bch'].map(id => `${id}-container`); containerIds.forEach(id => { const container = document.getElementById(id); if (container) { diff --git a/basicswap/static/js/swaps_in_progress.js b/basicswap/static/js/swaps_in_progress.js index 3724bbd..8aeee3d 100644 --- a/basicswap/static/js/swaps_in_progress.js +++ b/basicswap/static/js/swaps_in_progress.js @@ -10,6 +10,7 @@ const COIN_NAME_TO_SYMBOL = { 'Firo': 'FIRO', 'Dash': 'DASH', 'Decred': 'DCR', + 'Namecoin': 'NMC', 'Wownero': 'WOW', 'Bitcoin Cash': 'BCH', 'Dogecoin': 'DOGE' @@ -383,8 +384,8 @@ const createSwapTableRow = async (swap) => {
- ${swap.coin_from} @@ -392,8 +393,8 @@ const createSwapTableRow = async (swap) => { - ${swap.coin_to} @@ -421,7 +422,7 @@ const createSwapTableRow = async (swap) => { - Details diff --git a/basicswap/templates/offers.html b/basicswap/templates/offers.html index eb04efb..7cb93b1 100644 --- a/basicswap/templates/offers.html +++ b/basicswap/templates/offers.html @@ -13,7 +13,7 @@
-
@@ -21,7 +21,7 @@

{{ page_type_description }}