mirror of
https://github.com/basicswap/basicswap.git
synced 2025-12-04 14:37:07 +01:00
@@ -391,7 +391,7 @@ class BasicSwap(BaseApp):
|
|||||||
Coins.PART_BLIND,
|
Coins.PART_BLIND,
|
||||||
Coins.BCH,
|
Coins.BCH,
|
||||||
)
|
)
|
||||||
self.coins_without_segwit = (Coins.PIVX, Coins.DASH, Coins.NMC)
|
self.coins_without_segwit = (Coins.PIVX, Coins.DASH)
|
||||||
|
|
||||||
# TODO: Adjust ranges
|
# TODO: Adjust ranges
|
||||||
self.min_delay_event = self.get_int_setting("min_delay_event", 10, 0, 20 * 60)
|
self.min_delay_event = self.get_int_setting("min_delay_event", 10, 0, 20 * 60)
|
||||||
|
|||||||
@@ -52,11 +52,17 @@ PARTICL_VERSION = os.getenv("PARTICL_VERSION", "23.2.7.0")
|
|||||||
PARTICL_VERSION_TAG = os.getenv("PARTICL_VERSION_TAG", "")
|
PARTICL_VERSION_TAG = os.getenv("PARTICL_VERSION_TAG", "")
|
||||||
PARTICL_LINUX_EXTRA = os.getenv("PARTICL_LINUX_EXTRA", "nousb")
|
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 = os.getenv("LITECOIN_VERSION", "0.21.4")
|
||||||
LITECOIN_VERSION_TAG = os.getenv("LITECOIN_VERSION_TAG", "")
|
LITECOIN_VERSION_TAG = os.getenv("LITECOIN_VERSION_TAG", "")
|
||||||
|
|
||||||
BITCOIN_VERSION = os.getenv("BITCOIN_VERSION", "28.0")
|
DCR_VERSION = os.getenv("DCR_VERSION", "1.8.1")
|
||||||
BITCOIN_VERSION_TAG = os.getenv("BITCOIN_VERSION_TAG", "")
|
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 = os.getenv("MONERO_VERSION", "0.18.3.4")
|
||||||
MONERO_VERSION_TAG = os.getenv("MONERO_VERSION_TAG", "")
|
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 = os.getenv("NAV_VERSION", "7.0.3")
|
||||||
NAV_VERSION_TAG = os.getenv("NAV_VERSION_TAG", "")
|
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 = os.getenv("BITCOINCASH_VERSION", "28.0.1")
|
||||||
BITCOINCASH_VERSION_TAG = os.getenv("BITCOINCASH_VERSION_TAG", "")
|
BITCOINCASH_VERSION_TAG = os.getenv("BITCOINCASH_VERSION_TAG", "")
|
||||||
|
|
||||||
@@ -103,7 +106,7 @@ known_coins = {
|
|||||||
"bitcoin": (BITCOIN_VERSION, BITCOIN_VERSION_TAG, ("laanwj",)),
|
"bitcoin": (BITCOIN_VERSION, BITCOIN_VERSION_TAG, ("laanwj",)),
|
||||||
"litecoin": (LITECOIN_VERSION, LITECOIN_VERSION_TAG, ("davidburkett38",)),
|
"litecoin": (LITECOIN_VERSION, LITECOIN_VERSION_TAG, ("davidburkett38",)),
|
||||||
"decred": (DCR_VERSION, DCR_VERSION_TAG, ("decred_release",)),
|
"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",)),
|
"monero": (MONERO_VERSION, MONERO_VERSION_TAG, ("binaryfate",)),
|
||||||
"wownero": (WOWNERO_VERSION, WOWNERO_VERSION_TAG, ("wowario",)),
|
"wownero": (WOWNERO_VERSION, WOWNERO_VERSION_TAG, ("wowario",)),
|
||||||
"pivx": (PIVX_VERSION, PIVX_VERSION_TAG, ("fuzzbawls",)),
|
"pivx": (PIVX_VERSION, PIVX_VERSION_TAG, ("fuzzbawls",)),
|
||||||
@@ -116,26 +119,32 @@ known_coins = {
|
|||||||
|
|
||||||
disabled_coins = [
|
disabled_coins = [
|
||||||
"navcoin",
|
"navcoin",
|
||||||
"namecoin", # Needs update
|
|
||||||
]
|
]
|
||||||
|
|
||||||
expected_key_ids = {
|
expected_key_ids = {
|
||||||
"tecnovert": ("13F13651C9CF0D6B",),
|
"tecnovert": ("8E517DC12EC1CC37F6423A8A13F13651C9CF0D6B",),
|
||||||
"thrasher": ("FE3348877809386C",),
|
"thrasher": ("59CAF0E96F23F53747945FD4FE3348877809386C",),
|
||||||
"laanwj": ("1E4AED62986CD25D",),
|
"laanwj": ("9DEAE0DC7063249FB05474681E4AED62986CD25D",),
|
||||||
"JeremyRand": ("2DBE339E29F6294C",),
|
"RoseTuring": ("FD8366A807A99FA27FD9CCEA9FE3BFDDA6C53495",),
|
||||||
"binaryfate": ("F0AF4D462A0BDF92",),
|
"binaryfate": ("81AC591FE9C4B65C5806AFC3F0AF4D462A0BDF92",),
|
||||||
"wowario": ("793504B449C69220",),
|
"wowario": ("AB3A2F725818FCFF2794841C793504B449C69220",),
|
||||||
"davidburkett38": ("3620E9D387E55666",),
|
"davidburkett38": ("D35621D53A1CC6A3456758D03620E9D387E55666",),
|
||||||
"xanimo": ("6E8F17C1B1BCDCBE",),
|
"xanimo": ("2EAA8B1021C71AD5186CA07F6E8F17C1B1BCDCBE",),
|
||||||
"patricklodder": ("2D3A345B98D0DC1F",),
|
"patricklodder": ("DC6EF4A8BF9F1B1E4DE1EE522D3A345B98D0DC1F",),
|
||||||
"fuzzbawls": ("C1ABA64407731FD9",),
|
"fuzzbawls": ("0CFBDA9F60D661BA31EB5D50C1ABA64407731FD9",),
|
||||||
"pasta": ("52527BEDABE87984", "E2F3D7916E722D38"),
|
"pasta": (
|
||||||
"reuben": ("1290A1D0FA7EE109",),
|
"29590362EC878A81FD3C202B52527BEDABE87984",
|
||||||
"nav_builder": ("2782262BF6E7FADB",),
|
"02B8E7D002167C8B451AF05FE2F3D7916E722D38",
|
||||||
"nicolasdorier": ("6618763EF09186FE", "223FDA69DEBEA82D", "62FE85647DEDDA2E"),
|
),
|
||||||
"decred_release": ("6D897EDF518A031D",),
|
"reuben": ("0186454D63E83D85EF91DE4E1290A1D0FA7EE109",),
|
||||||
"Calin_Culianu": ("21810A542031C02C",),
|
"nav_builder": ("1BF9B51BAED51BA0B3A174EE2782262BF6E7FADB",),
|
||||||
|
"nicolasdorier": (
|
||||||
|
"AB4CFA9895ACA0DBE27F6B346618763EF09186FE",
|
||||||
|
"015B4C837B245509E4AC8995223FDA69DEBEA82D",
|
||||||
|
"7121BDE3555D9BE06BDDC68162FE85647DEDDA2E",
|
||||||
|
),
|
||||||
|
"decred_release": ("F516ADB7A069852C7C28A02D6D897EDF518A031D",),
|
||||||
|
"Calin_Culianu": ("D465135F97D0047E18E99DC321810A542031C02C",),
|
||||||
}
|
}
|
||||||
|
|
||||||
USE_PLATFORM = os.getenv("USE_PLATFORM", platform.system())
|
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_USER = os.getenv("PART_RPC_USER", "")
|
||||||
PART_RPC_PWD = os.getenv("PART_RPC_PWD", "")
|
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_HOST = os.getenv("XMR_RPC_HOST", "127.0.0.1")
|
||||||
XMR_RPC_PORT = int(os.getenv("XMR_RPC_PORT", 29798))
|
XMR_RPC_PORT = int(os.getenv("XMR_RPC_PORT", 29798))
|
||||||
XMR_ZMQ_PORT = int(os.getenv("XMR_ZMQ_PORT", 30898))
|
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", "")
|
WOW_RPC_PWD = os.getenv("WOW_RPC_PWD", "")
|
||||||
DEFAULT_WOW_RESTORE_HEIGHT = int(os.getenv("DEFAULT_WOW_RESTORE_HEIGHT", 450000))
|
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_HOST = os.getenv("PIVX_RPC_HOST", "127.0.0.1")
|
||||||
PIVX_RPC_PORT = int(os.getenv("PIVX_RPC_PORT", 51473))
|
PIVX_RPC_PORT = int(os.getenv("PIVX_RPC_PORT", 51473))
|
||||||
PIVX_ONION_PORT = int(os.getenv("PIVX_ONION_PORT", 51472)) # nDefaultPort
|
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
|
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:
|
def getKnownVersion(coin_name: str) -> str:
|
||||||
version, version_tag, _ = known_coins[coin_name]
|
version, version_tag, _ = known_coins[coin_name]
|
||||||
return version + version_tag
|
return version + version_tag
|
||||||
@@ -528,7 +547,7 @@ def testOnionLink():
|
|||||||
|
|
||||||
def havePubkey(gpg, key_id):
|
def havePubkey(gpg, key_id):
|
||||||
for key in gpg.list_keys():
|
for key in gpg.list_keys():
|
||||||
if key["keyid"] == key_id:
|
if key["fingerprint"] == key_id:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -591,8 +610,10 @@ def ensureValidSignatureBy(result, signing_key_name):
|
|||||||
if not isValidSignature(result):
|
if not isValidSignature(result):
|
||||||
raise ValueError("Signature verification failed.")
|
raise ValueError("Signature verification failed.")
|
||||||
|
|
||||||
if result.key_id not in expected_key_ids[signing_key_name]:
|
if result.fingerprint not in expected_key_ids[signing_key_name]:
|
||||||
raise ValueError("Signature made by unexpected keyid: " + result.key_id)
|
raise ValueError(
|
||||||
|
"Signature made by unexpected key fingerprint: " + result.fingerprint
|
||||||
|
)
|
||||||
|
|
||||||
logger.debug(f"Found valid signature by {signing_key_name} ({result.key_id}).")
|
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)
|
% (version, assert_filename)
|
||||||
)
|
)
|
||||||
elif coin == "namecoin":
|
elif coin == "namecoin":
|
||||||
release_url = "https://beta.namecoin.org/files/namecoin-core/namecoin-core-{}/{}".format(
|
release_url = f"https://www.namecoin.org/files/namecoin-core/namecoin-core-{version}/{release_filename}"
|
||||||
version, release_filename
|
signing_key = "Rose%20Turing"
|
||||||
)
|
assert_filename = "noncodesigned.SHA256SUMS"
|
||||||
assert_filename = "{}-{}-{}-build.assert".format(
|
assert_url = f"https://raw.githubusercontent.com/namecoin/guix.sigs/main/{version}/{signing_key}/{assert_filename}"
|
||||||
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)
|
|
||||||
)
|
|
||||||
elif coin == "pivx":
|
elif coin == "pivx":
|
||||||
release_filename = "{}-{}-{}.{}".format(coin, version, BIN_ARCH, FILE_EXT)
|
release_filename = "{}-{}-{}.{}".format(coin, version, BIN_ARCH, FILE_EXT)
|
||||||
release_url = (
|
release_url = (
|
||||||
@@ -1345,6 +1360,8 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic, extra_opts={}):
|
|||||||
fp.write("printtoconsole=0\n")
|
fp.write("printtoconsole=0\n")
|
||||||
fp.write("daemon=0\n")
|
fp.write("daemon=0\n")
|
||||||
fp.write(f"wallet={wallet_name}\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:
|
if tor_control_password is not None:
|
||||||
writeTorSettings(fp, coin, core_settings, tor_control_password)
|
writeTorSettings(fp, coin, core_settings, tor_control_password)
|
||||||
@@ -1401,6 +1418,10 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic, extra_opts={}):
|
|||||||
)
|
)
|
||||||
elif coin == "namecoin":
|
elif coin == "namecoin":
|
||||||
fp.write("prune=2000\n")
|
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":
|
elif coin == "pivx":
|
||||||
params_dir = os.path.join(data_dir, "pivx-params")
|
params_dir = os.path.join(data_dir, "pivx-params")
|
||||||
downloadPIVXParams(params_dir)
|
downloadPIVXParams(params_dir)
|
||||||
@@ -1804,6 +1825,7 @@ def initialise_wallets(
|
|||||||
Coins.DOGE,
|
Coins.DOGE,
|
||||||
Coins.DCR,
|
Coins.DCR,
|
||||||
Coins.DASH,
|
Coins.DASH,
|
||||||
|
Coins.NMC,
|
||||||
)
|
)
|
||||||
# Always start Particl, it must be running to initialise a wallet in addcoin mode
|
# 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
|
# 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)}.'
|
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
|
# wallet_name, disable_private_keys, blank, passphrase, avoid_reuse, descriptors
|
||||||
|
|
||||||
use_descriptors = coin_settings.get("use_descriptors", False)
|
use_descriptors = coin_settings.get("use_descriptors", False)
|
||||||
@@ -1926,11 +1948,15 @@ def initialise_wallets(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
if use_descriptors:
|
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(
|
swap_client.callcoinrpc(
|
||||||
c,
|
c,
|
||||||
"createwallet",
|
"createwallet",
|
||||||
[
|
[
|
||||||
coin_settings["watch_wallet_name"],
|
watch_wallet_name,
|
||||||
True,
|
True,
|
||||||
True,
|
True,
|
||||||
"",
|
"",
|
||||||
@@ -2073,7 +2099,10 @@ def check_btc_fastsync_data(base_dir, sync_filename):
|
|||||||
importPubkey(gpg, pubkey_filename, pubkeyurls)
|
importPubkey(gpg, pubkey_filename, pubkeyurls)
|
||||||
with open(asc_file_path, "rb") as fp:
|
with open(asc_file_path, "rb") as fp:
|
||||||
verified = gpg.verify_file(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")
|
ensureValidSignatureBy(verified, "tecnovert")
|
||||||
else:
|
else:
|
||||||
pubkey_filename = "nicolasdorier.asc"
|
pubkey_filename = "nicolasdorier.asc"
|
||||||
@@ -2379,22 +2408,6 @@ def main():
|
|||||||
"core_version_no": getKnownVersion("bitcoin"),
|
"core_version_no": getKnownVersion("bitcoin"),
|
||||||
"core_version_group": 28,
|
"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": {
|
"litecoin": {
|
||||||
"connection_type": "rpc",
|
"connection_type": "rpc",
|
||||||
"manage_daemon": shouldManageDaemon("LTC"),
|
"manage_daemon": shouldManageDaemon("LTC"),
|
||||||
@@ -2410,22 +2423,6 @@ def main():
|
|||||||
"core_version_group": 20,
|
"core_version_group": 20,
|
||||||
"min_relay_fee": 0.00001,
|
"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": {
|
"decred": {
|
||||||
"connection_type": "rpc",
|
"connection_type": "rpc",
|
||||||
"manage_daemon": shouldManageDaemon("DCR"),
|
"manage_daemon": shouldManageDaemon("DCR"),
|
||||||
@@ -2453,14 +2450,16 @@ def main():
|
|||||||
"manage_daemon": shouldManageDaemon("NMC"),
|
"manage_daemon": shouldManageDaemon("NMC"),
|
||||||
"rpchost": NMC_RPC_HOST,
|
"rpchost": NMC_RPC_HOST,
|
||||||
"rpcport": NMC_RPC_PORT + port_offset,
|
"rpcport": NMC_RPC_PORT + port_offset,
|
||||||
|
"onionport": NMC_ONION_PORT + port_offset,
|
||||||
"datadir": os.getenv("NMC_DATA_DIR", os.path.join(data_dir, "namecoin")),
|
"datadir": os.getenv("NMC_DATA_DIR", os.path.join(data_dir, "namecoin")),
|
||||||
"bindir": os.path.join(bin_dir, "namecoin"),
|
"bindir": os.path.join(bin_dir, "namecoin"),
|
||||||
"use_segwit": False,
|
"port": NMC_PORT + port_offset,
|
||||||
"use_csv": False,
|
"use_segwit": True,
|
||||||
|
"use_csv": True,
|
||||||
"blocks_confirmed": 1,
|
"blocks_confirmed": 1,
|
||||||
"conf_target": 2,
|
"conf_target": 2,
|
||||||
"core_version_no": getKnownVersion("namecoin"),
|
"core_version_no": getKnownVersion("namecoin"),
|
||||||
"core_version_group": 18,
|
"core_version_group": 28,
|
||||||
"chain_lookups": "local",
|
"chain_lookups": "local",
|
||||||
},
|
},
|
||||||
"monero": {
|
"monero": {
|
||||||
@@ -2486,6 +2485,28 @@ def main():
|
|||||||
"core_version_no": getKnownVersion("monero"),
|
"core_version_no": getKnownVersion("monero"),
|
||||||
"core_type_group": "xmr",
|
"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": {
|
"pivx": {
|
||||||
"connection_type": "rpc",
|
"connection_type": "rpc",
|
||||||
"manage_daemon": shouldManageDaemon("PIVX"),
|
"manage_daemon": shouldManageDaemon("PIVX"),
|
||||||
@@ -2549,27 +2570,37 @@ def main():
|
|||||||
"chain_lookups": "local",
|
"chain_lookups": "local",
|
||||||
"startup_tries": 40,
|
"startup_tries": 40,
|
||||||
},
|
},
|
||||||
"wownero": {
|
"bitcoincash": {
|
||||||
"connection_type": "rpc",
|
"connection_type": "rpc",
|
||||||
"manage_daemon": shouldManageDaemon("WOW"),
|
"manage_daemon": shouldManageDaemon("BCH"),
|
||||||
"manage_wallet_daemon": shouldManageDaemon("WOW_WALLET"),
|
"rpchost": BCH_RPC_HOST,
|
||||||
"rpcport": WOW_RPC_PORT + port_offset,
|
"rpcport": BCH_RPC_PORT + port_offset,
|
||||||
"zmqport": WOW_ZMQ_PORT + port_offset,
|
"onionport": BCH_ONION_PORT + port_offset,
|
||||||
"walletrpcport": WOW_WALLET_RPC_PORT + port_offset,
|
"datadir": os.getenv("BCH_DATA_DIR", os.path.join(data_dir, "bitcoincash")),
|
||||||
"rpchost": WOW_RPC_HOST,
|
"bindir": os.path.join(bin_dir, "bitcoincash"),
|
||||||
"trusted_daemon": extra_opts.get("trust_remote_node", "auto"),
|
"port": BCH_PORT + port_offset,
|
||||||
"walletrpchost": WOW_WALLET_RPC_HOST,
|
"config_filename": "bitcoin.conf",
|
||||||
"walletrpcuser": WOW_WALLET_RPC_USER,
|
"use_segwit": False,
|
||||||
"walletrpcpassword": WOW_WALLET_RPC_PWD,
|
"blocks_confirmed": 1,
|
||||||
"datadir": os.getenv("WOW_DATA_DIR", os.path.join(data_dir, "wownero")),
|
"conf_target": 2,
|
||||||
"bindir": os.path.join(bin_dir, "wownero"),
|
"core_version_no": getKnownVersion("bitcoincash"),
|
||||||
"restore_height": wow_restore_height,
|
"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,
|
"blocks_confirmed": 2,
|
||||||
"rpctimeout": 60,
|
"conf_target": 2,
|
||||||
"walletrpctimeout": 120,
|
"core_version_no": getKnownVersion("dogecoin"),
|
||||||
"walletrpctimeoutlong": 300,
|
"core_version_group": 23,
|
||||||
"core_version_no": getKnownVersion("wownero"),
|
"min_relay_fee": 0.01, # RECOMMENDED_MIN_TX_FEE
|
||||||
"core_type_group": "xmr",
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2593,9 +2624,8 @@ def main():
|
|||||||
coin_settings["wallet_name"] = set_name
|
coin_settings["wallet_name"] = set_name
|
||||||
|
|
||||||
ticker: str = coin_params["ticker"]
|
ticker: str = coin_params["ticker"]
|
||||||
if toBool(os.getenv(ticker + "_USE_DESCRIPTORS", False)):
|
if getDescriptorWalletOption(coin_params):
|
||||||
|
if coin_id not in (Coins.BTC, Coins.NMC):
|
||||||
if coin_id not in (Coins.BTC,):
|
|
||||||
raise ValueError(f"Descriptor wallet unavailable for {coin_name}")
|
raise ValueError(f"Descriptor wallet unavailable for {coin_name}")
|
||||||
|
|
||||||
coin_settings["use_descriptors"] = True
|
coin_settings["use_descriptors"] = True
|
||||||
|
|||||||
@@ -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.
|
# 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.
|
# 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
|
# 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)
|
port: int = coin_settings.get("port", 8333)
|
||||||
extra_args.append(f"--bind=0.0.0.0:{port}")
|
extra_args.append(f"--bind=0.0.0.0:{port}")
|
||||||
return extra_args
|
return extra_args
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ chainparams = {
|
|||||||
"bip44": 44,
|
"bip44": 44,
|
||||||
"min_amount": 100000,
|
"min_amount": 100000,
|
||||||
"max_amount": 10000000 * COIN,
|
"max_amount": 10000000 * COIN,
|
||||||
|
"ext_public_key_prefix": 0x696E82D1,
|
||||||
|
"ext_secret_key_prefix": 0x8F1DAEB8,
|
||||||
},
|
},
|
||||||
"testnet": {
|
"testnet": {
|
||||||
"rpcport": 51935,
|
"rpcport": 51935,
|
||||||
@@ -69,6 +71,8 @@ chainparams = {
|
|||||||
"bip44": 1,
|
"bip44": 1,
|
||||||
"min_amount": 100000,
|
"min_amount": 100000,
|
||||||
"max_amount": 10000000 * COIN,
|
"max_amount": 10000000 * COIN,
|
||||||
|
"ext_public_key_prefix": 0xE1427800,
|
||||||
|
"ext_secret_key_prefix": 0x04889478,
|
||||||
},
|
},
|
||||||
"regtest": {
|
"regtest": {
|
||||||
"rpcport": 51936,
|
"rpcport": 51936,
|
||||||
@@ -80,6 +84,8 @@ chainparams = {
|
|||||||
"bip44": 1,
|
"bip44": 1,
|
||||||
"min_amount": 100000,
|
"min_amount": 100000,
|
||||||
"max_amount": 10000000 * COIN,
|
"max_amount": 10000000 * COIN,
|
||||||
|
"ext_public_key_prefix": 0xE1427800,
|
||||||
|
"ext_secret_key_prefix": 0x04889478,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Coins.BTC: {
|
Coins.BTC: {
|
||||||
@@ -251,29 +257,38 @@ chainparams = {
|
|||||||
"rpcport": 8336,
|
"rpcport": 8336,
|
||||||
"pubkey_address": 52,
|
"pubkey_address": 52,
|
||||||
"script_address": 13,
|
"script_address": 13,
|
||||||
|
"key_prefix": 180,
|
||||||
"hrp": "nc",
|
"hrp": "nc",
|
||||||
"bip44": 7,
|
"bip44": 7,
|
||||||
"min_amount": 100000,
|
"min_amount": 100000,
|
||||||
"max_amount": 10000000 * COIN,
|
"max_amount": 10000000 * COIN,
|
||||||
|
"ext_public_key_prefix": 0x0488B21E, # base58Prefixes[EXT_PUBLIC_KEY]
|
||||||
|
"ext_secret_key_prefix": 0x0488ADE4,
|
||||||
},
|
},
|
||||||
"testnet": {
|
"testnet": {
|
||||||
"rpcport": 18336,
|
"rpcport": 18336,
|
||||||
"pubkey_address": 111,
|
"pubkey_address": 111,
|
||||||
"script_address": 196,
|
"script_address": 196,
|
||||||
|
"key_prefix": 239,
|
||||||
"hrp": "tn",
|
"hrp": "tn",
|
||||||
"bip44": 1,
|
"bip44": 1,
|
||||||
"min_amount": 100000,
|
"min_amount": 100000,
|
||||||
"max_amount": 10000000 * COIN,
|
"max_amount": 10000000 * COIN,
|
||||||
"name": "testnet3",
|
"name": "testnet3",
|
||||||
|
"ext_public_key_prefix": 0x043587CF,
|
||||||
|
"ext_secret_key_prefix": 0x04358394,
|
||||||
},
|
},
|
||||||
"regtest": {
|
"regtest": {
|
||||||
"rpcport": 18443,
|
"rpcport": 18443,
|
||||||
"pubkey_address": 111,
|
"pubkey_address": 111,
|
||||||
"script_address": 196,
|
"script_address": 196,
|
||||||
|
"key_prefix": 239,
|
||||||
"hrp": "ncrt",
|
"hrp": "ncrt",
|
||||||
"bip44": 1,
|
"bip44": 1,
|
||||||
"min_amount": 100000,
|
"min_amount": 100000,
|
||||||
"max_amount": 10000000 * COIN,
|
"max_amount": 10000000 * COIN,
|
||||||
|
"ext_public_key_prefix": 0x043587CF,
|
||||||
|
"ext_secret_key_prefix": 0x04358394,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Coins.XMR: {
|
Coins.XMR: {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- 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
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
# 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_CLI = os.getenv("DOGECOIN_CLI", "dogecoin-cli" + bin_suffix)
|
||||||
DOGECOIN_TX = os.getenv("DOGECOIN_TX", "dogecoin-tx" + 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(
|
XMR_BINDIR = os.path.expanduser(
|
||||||
os.getenv("XMR_BINDIR", os.path.join(DEFAULT_TEST_BINDIR, "monero"))
|
os.getenv("XMR_BINDIR", os.path.join(DEFAULT_TEST_BINDIR, "monero"))
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1862,19 +1862,69 @@ class BTCInterface(Secp256k1Interface):
|
|||||||
"Could not find address with enough funds for proof",
|
"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 (
|
if (
|
||||||
self.using_segwit()
|
self.using_segwit()
|
||||||
): # TODO: Use isSegwitAddress when scantxoutset can use combo
|
): # TODO: Use isSegwitAddress when scantxoutset can use combo
|
||||||
# 'Address does not refer to key' for non p2pkh
|
# 'Address does not refer to key' for non p2pkh
|
||||||
pkh = self.decodeAddress(sign_for_addr)
|
pkh = self.decodeAddress(sign_for_addr)
|
||||||
sign_for_addr = self.pkh_to_address(pkh)
|
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}")
|
||||||
|
|
||||||
|
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(
|
signature = self.rpc_wallet(
|
||||||
"signmessage",
|
"signmessage",
|
||||||
[sign_for_addr, sign_for_addr + "_swap_proof_" + extra_commit_bytes.hex()],
|
[
|
||||||
|
sign_for_addr,
|
||||||
|
sign_for_addr + "_swap_proof_" + extra_commit_bytes.hex(),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
prove_utxos = [] # TODO: Send specific utxos
|
prove_utxos = [] # TODO: Send specific utxos
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Copyright (c) 2020-2022 tecnovert
|
# Copyright (c) 2020-2022 tecnovert
|
||||||
|
# Copyright (c) 2025 The Basicswap developers
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
@@ -13,39 +14,3 @@ class NMCInterface(BTCInterface):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def coin_type():
|
def coin_type():
|
||||||
return Coins.NMC
|
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
|
|
||||||
|
|||||||
25
basicswap/pgp/keys/bitcoincash_Calin_Culianu.pgp
Normal file
25
basicswap/pgp/keys/bitcoincash_Calin_Culianu.pgp
Normal file
@@ -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-----
|
||||||
@@ -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-----
|
|
||||||
52
basicswap/pgp/keys/namecoin_RoseTuring.pgp
Normal file
52
basicswap/pgp/keys/namecoin_RoseTuring.pgp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
=atlH
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
@@ -1,78 +1,29 @@
|
|||||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
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
|
r41bcxUIfMEDefPm5wnXep8W
|
||||||
XEP7UJRk5bFFKdn0wMONgmQLMjjspU5byMQDJ0hFNMmmrbKX2AXqRpkCDQRZS8mC
|
=szpX
|
||||||
ARAA1t6CZ1TAwveIPuzgdfyAVGDXrwqiSDgLQtHnhUuYNFxr76kS8djS1Kp+bXvk
|
|
||||||
e3XqBhJZGRSSy8RVMBJ4ahgkR+dCKLuWmp1M74COX1QGyt5NH6fb3CygkdH0FSIn
|
|
||||||
XC8qjKZC2aPAUhN/gVsRaf69jh74dnWLSQvgWVcG5ZA0t3KsCr1GcSKHLw7OO1qN
|
|
||||||
7c2XxLKlGr224hsfg5tHwle01R3VS1O6t22bB0kYsk1GdhAAKaAJk4q/XLFcb9iD
|
|
||||||
PMn+vx8Fouvy6e3YEhtfqgWdZVDz02PnRSz2crf5Lpfr7jo+hi2WlLNw+une02jw
|
|
||||||
hylgDpz/UR6YnP4lzg11V6NShyX2tMfH1uyPsu/xm/ucf5uDtAc9kwYr3a0gLhaV
|
|
||||||
5D6sGsJcOAj4CPX3PNNYPN/mRcw9oyeqsZBIH55Zn/sxjZ+bQuDeYzUU0Phsh6Nc
|
|
||||||
OPNuEl3EjefdMIM/IKBiQt0DycW4n7zgPBs0CFc6cR3JKHzlcqiBKqkp5D9sZ+Jh
|
|
||||||
C6g+x3BZ6KI2QahWxdnDfqFkPp4izfr+Kq1J3KUCPUlVpcqeukvtUwYQUI9kLl/t
|
|
||||||
wfituxIg24TVexF+sRGxrJwdaaDHNmjIs+r3sm1txp6DPtqaa/CqP9diI+5fmQOO
|
|
||||||
Lej1lH0EGzUm1JP9GIXfUCfFUFXJPk2kuoLWq021EZUnZh8AEQEAAbQpdGVjbm92
|
|
||||||
ZXJ0IChnaXRpYW4pIDx0ZWNub3ZlcnRAcGFydGljbC5pbz6JAlQEEwEIAD4WIQSO
|
|
||||||
UX3BLsHMN/ZCOooT8TZRyc8NawUCWUvJggIbAwUJEswDAAULCQgHAgYVCAkKCwIE
|
|
||||||
FgIDAQIeAQIXgAAKCRAT8TZRyc8Na7XWD/9tokV/DtkPvjGsjxzceVxwJTJPZn4u
|
|
||||||
RQdaicLIbZYXWuz/VP4Tk4ttu8B/jM4eXQY3uLdg5KB88Zc/1q+HEEFCTDmHdDhG
|
|
||||||
WOpKQEJL7cmKGyG+s5UUCtZKAHzTMXsJn2WRk5a9eiFFQqLxkhb2foXWEQxI7h6l
|
|
||||||
46cAX68RQMvxwp32NdKkkZCXOcNcqY9SJM5Wp0vsXkSUg70U0AwBK8798SnDBowg
|
|
||||||
h2mgj/rcgGlYgWlDpb5mXVsINIMEArjy6iIdHHw23INKrnIkSKZ8qcyDZn8J4GQs
|
|
||||||
F3SGHwM5gszB8NSd4joqn6itBHKRzLC+vPVckEj4LKBB7XDhh2I0S6TDxr0RR7SA
|
|
||||||
q5whxDStyHMBVgxl1vot84DpQO4OPMmFlr0rqfrfCOmE/hXnhZcUjnY9RnXjANDu
|
|
||||||
4F2e85y1XbqJC9hH+HWY3PtzcAZRaL+dr8AmcEDABrDK4sBAwdqw2Qe2DrwMZVAf
|
|
||||||
5Gr7cf6BPH1e5mXLsGINNpauG6MxfcZYYzhWkYresV5y1YtE7iO+nLs+u5wfVZFn
|
|
||||||
M0iyMwsozchaVm8dQTMU2H3oWV9/mDWo18Buh3RKfQgGCtLuOhrs/z7Yeu22zVWM
|
|
||||||
j/3LjiK7/4akOsaOJjgTAw8XAhAF8d68MX28TTPL5cKzHKSE67TTja+NW3MVCHzB
|
|
||||||
A3nz5ucJ13qfFrkCDQRZS8mCARAA7QMvR0fFA1FZKzcS6/W5Jcm0g6FQ1xHaMeEh
|
|
||||||
LECOQpM3wSOL1A8trbpC2VgMLjRFq+h3YQRlF8Y4oIaIz2UzziqK6mGZxhtEN6y3
|
|
||||||
IIXrVC5CTpcDXxlvJyHeHQONvMnEbmnbHfZAtxJq2wFOr7BWiLVzfioyNSND/JOP
|
|
||||||
VlgezL6YRAocQbHU7mQKY7gCqU4jDZIxru01e2hoIHSbAFXjmEcFBFoErWXAMf5w
|
|
||||||
HaK7dGGMpJXgNCK2weatNCBxD/krv1gA7nheT665K7HUQxu/NhUIk8XnOPD5iDoJ
|
|
||||||
zeQXHY3SM8jrhhabRubm27c/Oads9lgk9EGZhxLhIMQ9jUu7TsX1sPZpfnoE/JAq
|
|
||||||
ofY3WwimOXYb+p0jetg4FQaqul6FpgesSI4Nl5nHHB8/4CWUv2oV2YjUJlBpazyc
|
|
||||||
ullt8a7GdwzQMbiw23Jgz1frrMuq/zQc4wLGUFchhnYMrva+6t0ewjxD7bCL/7N7
|
|
||||||
3UDdNpVi+ZcBVQPVididC4iRcCLDqmr+WtTfVKw58Rnb7Qt9Z+2MqVZa1/numTG1
|
|
||||||
DastjRg6KGkN6eYaxKcXHf7t/lYZ5ejGFVUh+wtwlb1tTpOvWKq130tuO/aDWTa2
|
|
||||||
jViwy2UUpbyg5UbBvd0PHTJ+8TTdxEoC5wQCYHZ5Ueg9wwLhs0VQ44GI7vnXJZ8b
|
|
||||||
aXUe/mEAEQEAAYkCPAQYAQgAJhYhBI5RfcEuwcw39kI6ihPxNlHJzw1rBQJZS8mC
|
|
||||||
AhsMBQkSzAMAAAoJEBPxNlHJzw1r+3YQAM5648S/oQLnK5WO0/w3gIUI5g7BrdJO
|
|
||||||
kRINe8SNYs6PvCFjKij/3p9YMxrc/TojTQfhxew7bNxkhDU7sudxIr6TcKW5SK9f
|
|
||||||
g9zz2Ib5heR+orjPSX9hgSLX66t4DvJfdph+O1O3l83g0bsDUPCivTSnQ5XtdiVK
|
|
||||||
ytOoM26/GaQHwzKbk1Qzn1nrZeLaeDAsJ30GdmteNRMof1G2H9kg/33xbcyRCMaT
|
|
||||||
xjKS0ssa8RUmxuYsR+fjc7t5FvXwnfoXapkqUWcddFCCgAiTc0NZjzcDSXVB/++2
|
|
||||||
KxLZ0Q86kuJwdb7KEq0SwPQAM6ikmIaoke9fJAZzhyyWX7AeSQx1ime31Xrjh0CC
|
|
||||||
MHW+PdQMpLSNTAHEZDuybGKaShVMiHASXs7XsnJr6lOObMYzSGr0+B5fQWU7aHlM
|
|
||||||
u+4YNHUwQldx/EqkL/DjIpocVC5ozaW+dV1zSMLBHdk24soWI+gLrL3FG0NMyNZ+
|
|
||||||
O95X/bB/X+dqOBYpitR3xpYZes4Jl4Kechi60+mdDktFKfKfiRxyJlg2LNd7/OLB
|
|
||||||
hpxg2zsXlHhqhSJAo9IGih2rOgcMwtCXKmHCGG5KGsNF8x3H9bPOwynAUMqUJ2cR
|
|
||||||
7BCjzmUxUnsLcJnokUnHMbECZ+pee9YcaRNrlbVAIvED3ZHEhFJxIMaArxSLmRwE
|
|
||||||
XHovfCfpcB/C
|
|
||||||
=0Wkp
|
|
||||||
-----END PGP PUBLIC KEY BLOCK-----
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
|||||||
29
basicswap/pgp/keys/wownero_wowario.pgp
Normal file
29
basicswap/pgp/keys/wownero_wowario.pgp
Normal file
@@ -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-----
|
||||||
BIN
basicswap/static/images/coins/Namecoin-20.png
Normal file
BIN
basicswap/static/images/coins/Namecoin-20.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 743 B |
BIN
basicswap/static/images/coins/Namecoin.png
Normal file
BIN
basicswap/static/images/coins/Namecoin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@@ -10,6 +10,7 @@ const COIN_NAME_TO_SYMBOL = {
|
|||||||
'Firo': 'FIRO',
|
'Firo': 'FIRO',
|
||||||
'Dash': 'DASH',
|
'Dash': 'DASH',
|
||||||
'Decred': 'DCR',
|
'Decred': 'DCR',
|
||||||
|
'Namecoin': 'NMC',
|
||||||
'Wownero': 'WOW',
|
'Wownero': 'WOW',
|
||||||
'Bitcoin Cash': 'BCH',
|
'Bitcoin Cash': 'BCH',
|
||||||
'Dogecoin': 'DOGE'
|
'Dogecoin': 'DOGE'
|
||||||
@@ -383,7 +384,6 @@ const createBidTableRow = async (bid) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- You Get Column -->
|
<!-- You Get Column -->
|
||||||
<td class="py-0">
|
<td class="py-0">
|
||||||
<div class="py-3 px-4 text-right">
|
<div class="py-3 px-4 text-right">
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ const ApiManager = (function() {
|
|||||||
.filter(coin => coin.usesCoinGecko)
|
.filter(coin => coin.usesCoinGecko)
|
||||||
.map(coin => coin.name)
|
.map(coin => coin.name)
|
||||||
.join(',') :
|
.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);
|
//console.log('Fetching coin prices for:', coins);
|
||||||
const response = await this.fetchCoinPrices(coins);
|
const response = await this.fetchCoinPrices(coins);
|
||||||
@@ -254,7 +254,7 @@ const ApiManager = (function() {
|
|||||||
.filter(coin => coin.usesCoinGecko)
|
.filter(coin => coin.usesCoinGecko)
|
||||||
.map(coin => getCoinBackendId ? getCoinBackendId(coin.name) : coin.name)
|
.map(coin => getCoinBackendId ? getCoinBackendId(coin.name) : coin.name)
|
||||||
.join(',') :
|
.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`;
|
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${coins}&vs_currencies=usd&include_24hr_vol=true&include_24hr_change=true`;
|
||||||
|
|
||||||
|
|||||||
@@ -504,13 +504,14 @@ const CacheManager = (function() {
|
|||||||
'bitcoin': 'BTC',
|
'bitcoin': 'BTC',
|
||||||
'litecoin': 'LTC',
|
'litecoin': 'LTC',
|
||||||
'monero': 'XMR',
|
'monero': 'XMR',
|
||||||
|
'wownero': 'WOW',
|
||||||
'particl': 'PART',
|
'particl': 'PART',
|
||||||
'pivx': 'PIVX',
|
'pivx': 'PIVX',
|
||||||
'firo': 'FIRO',
|
'firo': 'FIRO',
|
||||||
'zcoin': 'FIRO',
|
'zcoin': 'FIRO',
|
||||||
'dash': 'DASH',
|
'dash': 'DASH',
|
||||||
'decred': 'DCR',
|
'decred': 'DCR',
|
||||||
'wownero': 'WOW',
|
'namecoin': 'NMR',
|
||||||
'bitcoin-cash': 'BCH',
|
'bitcoin-cash': 'BCH',
|
||||||
'dogecoin': 'DOGE'
|
'dogecoin': 'DOGE'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ const ConfigManager = (function() {
|
|||||||
{ symbol: 'LTC', name: 'litecoin', usesCryptoCompare: true, usesCoinGecko: true, historicalDays: 30 },
|
{ symbol: 'LTC', name: 'litecoin', usesCryptoCompare: true, usesCoinGecko: true, historicalDays: 30 },
|
||||||
{ symbol: 'DOGE', name: 'dogecoin', 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: '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 }
|
{ symbol: 'WOW', name: 'wownero', usesCryptoCompare: false, usesCoinGecko: true, historicalDays: 30 }
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -88,6 +89,7 @@ const ConfigManager = (function() {
|
|||||||
'Zcoin': 'FIRO',
|
'Zcoin': 'FIRO',
|
||||||
'Dash': 'DASH',
|
'Dash': 'DASH',
|
||||||
'Decred': 'DCR',
|
'Decred': 'DCR',
|
||||||
|
'Namecoin': 'NMC',
|
||||||
'Wownero': 'WOW',
|
'Wownero': 'WOW',
|
||||||
'Bitcoin Cash': 'BCH',
|
'Bitcoin Cash': 'BCH',
|
||||||
'Dogecoin': 'DOGE'
|
'Dogecoin': 'DOGE'
|
||||||
@@ -105,13 +107,14 @@ const ConfigManager = (function() {
|
|||||||
'Zcoin': 'Firo',
|
'Zcoin': 'Firo',
|
||||||
'Dash': 'Dash',
|
'Dash': 'Dash',
|
||||||
'Decred': 'Decred',
|
'Decred': 'Decred',
|
||||||
|
'Namecoin': 'Namecoin',
|
||||||
'Wownero': 'Wownero',
|
'Wownero': 'Wownero',
|
||||||
'Bitcoin Cash': 'Bitcoin Cash',
|
'Bitcoin Cash': 'Bitcoin Cash',
|
||||||
'Dogecoin': 'Dogecoin'
|
'Dogecoin': 'Dogecoin'
|
||||||
},
|
},
|
||||||
|
|
||||||
idToName: {
|
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',
|
6: 'monero', 7: 'particl blind', 8: 'particl anon',
|
||||||
9: 'wownero', 11: 'pivx', 13: 'firo', 17: 'bitcoincash',
|
9: 'wownero', 11: 'pivx', 13: 'firo', 17: 'bitcoincash',
|
||||||
18: 'dogecoin'
|
18: 'dogecoin'
|
||||||
@@ -130,6 +133,7 @@ const ConfigManager = (function() {
|
|||||||
'litecoin': 'litecoin',
|
'litecoin': 'litecoin',
|
||||||
'dogecoin': 'dogecoin',
|
'dogecoin': 'dogecoin',
|
||||||
'decred': 'decred',
|
'decred': 'decred',
|
||||||
|
'namecoin': 'namecoin',
|
||||||
'wownero': 'wownero'
|
'wownero': 'wownero'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -367,6 +371,7 @@ const ConfigManager = (function() {
|
|||||||
'dash': { usd: null, btc: null },
|
'dash': { usd: null, btc: null },
|
||||||
'dogecoin': { usd: null, btc: null },
|
'dogecoin': { usd: null, btc: null },
|
||||||
'decred': { usd: null, btc: null },
|
'decred': { usd: null, btc: null },
|
||||||
|
'namecoin': { usd: null, btc: null },
|
||||||
'litecoin': { usd: null, btc: null },
|
'litecoin': { usd: null, btc: null },
|
||||||
'particl': { usd: null, btc: null },
|
'particl': { usd: null, btc: null },
|
||||||
'pivx': { usd: null, btc: null },
|
'pivx': { usd: null, btc: null },
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ const WalletManager = (function() {
|
|||||||
'Dash': 'DASH',
|
'Dash': 'DASH',
|
||||||
'PIVX': 'PIVX',
|
'PIVX': 'PIVX',
|
||||||
'Decred': 'DCR',
|
'Decred': 'DCR',
|
||||||
|
'Namecoin': 'NMC',
|
||||||
'Bitcoin Cash': 'BCH'
|
'Bitcoin Cash': 'BCH'
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -49,6 +50,7 @@ const WalletManager = (function() {
|
|||||||
'DASH': 'dash',
|
'DASH': 'dash',
|
||||||
'PIVX': 'pivx',
|
'PIVX': 'pivx',
|
||||||
'DCR': 'dcr',
|
'DCR': 'dcr',
|
||||||
|
'NMC': 'nmc',
|
||||||
'BCH': 'bch'
|
'BCH': 'bch'
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -63,6 +65,7 @@ const WalletManager = (function() {
|
|||||||
'Dash': 'DASH',
|
'Dash': 'DASH',
|
||||||
'PIVX': 'PIVX',
|
'PIVX': 'PIVX',
|
||||||
'Decred': 'DCR',
|
'Decred': 'DCR',
|
||||||
|
'Namecoin': 'NMC',
|
||||||
'Bitcoin Cash': 'BCH',
|
'Bitcoin Cash': 'BCH',
|
||||||
'Dogecoin': 'DOGE'
|
'Dogecoin': 'DOGE'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ window.tableRateModule = {
|
|||||||
'Dash': 'DASH',
|
'Dash': 'DASH',
|
||||||
'PIVX': 'PIVX',
|
'PIVX': 'PIVX',
|
||||||
'Decred': 'DCR',
|
'Decred': 'DCR',
|
||||||
|
'Namecoin': 'NMC',
|
||||||
'Zano': 'ZANO',
|
'Zano': 'ZANO',
|
||||||
'Bitcoin Cash': 'BCH',
|
'Bitcoin Cash': 'BCH',
|
||||||
'Dogecoin': 'DOGE'
|
'Dogecoin': 'DOGE'
|
||||||
@@ -306,6 +307,7 @@ async function calculateProfitLoss(fromCoin, toCoin, fromAmount, toAmount, isOwn
|
|||||||
'ltc': 'litecoin',
|
'ltc': 'litecoin',
|
||||||
'doge': 'dogecoin',
|
'doge': 'dogecoin',
|
||||||
'dcr': 'decred',
|
'dcr': 'decred',
|
||||||
|
'nmc': 'namecoin',
|
||||||
'wow': 'wownero'
|
'wow': 'wownero'
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -406,7 +408,7 @@ async function fetchLatestPrices() {
|
|||||||
const coinIds = [
|
const coinIds = [
|
||||||
'bitcoin', 'particl', 'monero', 'litecoin',
|
'bitcoin', 'particl', 'monero', 'litecoin',
|
||||||
'dogecoin', 'firo', 'dash', 'pivx',
|
'dogecoin', 'firo', 'dash', 'pivx',
|
||||||
'decred', 'bitcoincash'
|
'decred', 'namecoin', 'bitcoincash'
|
||||||
];
|
];
|
||||||
|
|
||||||
let processedData = {};
|
let processedData = {};
|
||||||
@@ -1365,6 +1367,7 @@ function createRateColumn(offer, coinFrom, coinTo) {
|
|||||||
'ltc': 'litecoin',
|
'ltc': 'litecoin',
|
||||||
'doge': 'dogecoin',
|
'doge': 'dogecoin',
|
||||||
'dcr': 'decred',
|
'dcr': 'decred',
|
||||||
|
'nmc': 'namecoin',
|
||||||
'wow': 'wownero'
|
'wow': 'wownero'
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1655,6 +1658,7 @@ function createTooltipContent(isSentOffers, coinFrom, coinTo, fromAmount, toAmou
|
|||||||
'ltc': 'litecoin',
|
'ltc': 'litecoin',
|
||||||
'doge': 'dogecoin',
|
'doge': 'dogecoin',
|
||||||
'dcr': 'decred',
|
'dcr': 'decred',
|
||||||
|
'nmc': 'namecoin',
|
||||||
'wow': 'wownero'
|
'wow': 'wownero'
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1757,6 +1761,7 @@ function createCombinedRateTooltip(offer, coinFrom, coinTo, treatAsSentOffer) {
|
|||||||
'ltc': 'litecoin',
|
'ltc': 'litecoin',
|
||||||
'doge': 'dogecoin',
|
'doge': 'dogecoin',
|
||||||
'dcr': 'decred',
|
'dcr': 'decred',
|
||||||
|
'nmc': 'namecoin',
|
||||||
'wow': 'wownero'
|
'wow': 'wownero'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -548,7 +548,7 @@ const ui = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
setActiveContainer: (containerId) => {
|
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 => {
|
containerIds.forEach(id => {
|
||||||
const container = document.getElementById(id);
|
const container = document.getElementById(id);
|
||||||
if (container) {
|
if (container) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ const COIN_NAME_TO_SYMBOL = {
|
|||||||
'Firo': 'FIRO',
|
'Firo': 'FIRO',
|
||||||
'Dash': 'DASH',
|
'Dash': 'DASH',
|
||||||
'Decred': 'DCR',
|
'Decred': 'DCR',
|
||||||
|
'Namecoin': 'NMC',
|
||||||
'Wownero': 'WOW',
|
'Wownero': 'WOW',
|
||||||
'Bitcoin Cash': 'BCH',
|
'Bitcoin Cash': 'BCH',
|
||||||
'Dogecoin': 'DOGE'
|
'Dogecoin': 'DOGE'
|
||||||
|
|||||||
@@ -136,11 +136,12 @@
|
|||||||
'ETH': {'name': 'Ethereum', 'symbol': 'ETH', 'image': 'Ethereum.png', 'show': false},
|
'ETH': {'name': 'Ethereum', 'symbol': 'ETH', 'image': 'Ethereum.png', 'show': false},
|
||||||
'DOGE': {'name': 'Dogecoin', 'symbol': 'DOGE', 'image': 'Dogecoin.png', 'show': true},
|
'DOGE': {'name': 'Dogecoin', 'symbol': 'DOGE', 'image': 'Dogecoin.png', 'show': true},
|
||||||
'DCR': {'name': 'Decred', 'symbol': 'DCR', 'image': 'Decred.png', 'show': true},
|
'DCR': {'name': 'Decred', 'symbol': 'DCR', 'image': 'Decred.png', 'show': true},
|
||||||
|
'NMC': {'name': 'Namecoin', 'symbol': 'NMC', 'image': 'Namecoin.png', 'show': true},
|
||||||
'ZANO': {'name': 'Zano', 'symbol': 'ZANO', 'image': 'Zano.png', 'show': false},
|
'ZANO': {'name': 'Zano', 'symbol': 'ZANO', 'image': 'Zano.png', 'show': false},
|
||||||
'WOW': {'name': 'Wownero', 'symbol': 'WOW', 'image': 'Wownero.png', 'show': true}
|
'WOW': {'name': 'Wownero', 'symbol': 'WOW', 'image': 'Wownero.png', 'show': true}
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
{% set custom_order = ['BTC', 'ETH', 'XMR', 'PART', 'LTC', 'BCH', 'FIRO', 'PIVX', 'DASH', 'DOGE', 'DCR', 'ZANO', 'WOW'] %}
|
{% set custom_order = ['BTC', 'ETH', 'XMR', 'PART', 'LTC', 'BCH', 'FIRO', 'PIVX', 'DASH', 'DOGE', 'DCR', 'NMC', 'ZANO', 'WOW'] %}
|
||||||
|
|
||||||
{% if enabled_chart_coins is string %}
|
{% if enabled_chart_coins is string %}
|
||||||
{% if enabled_chart_coins == "" %}
|
{% if enabled_chart_coins == "" %}
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ from tests.basicswap.common import (
|
|||||||
PIVX_BASE_PORT,
|
PIVX_BASE_PORT,
|
||||||
BTC_USE_DESCRIPTORS,
|
BTC_USE_DESCRIPTORS,
|
||||||
)
|
)
|
||||||
|
from tests.basicswap.extended.test_nmc import (
|
||||||
|
NMC_BASE_PORT,
|
||||||
|
NMC_BASE_RPC_PORT,
|
||||||
|
NMC_BASE_TOR_PORT,
|
||||||
|
)
|
||||||
from tests.basicswap.extended.test_dcr import (
|
from tests.basicswap.extended.test_dcr import (
|
||||||
DCR_BASE_PORT,
|
DCR_BASE_PORT,
|
||||||
DCR_BASE_RPC_PORT,
|
DCR_BASE_RPC_PORT,
|
||||||
@@ -50,13 +55,6 @@ from tests.basicswap.extended.test_doge import (
|
|||||||
import basicswap.config as cfg
|
import basicswap.config as cfg
|
||||||
import basicswap.bin.run as runSystem
|
import basicswap.bin.run as runSystem
|
||||||
|
|
||||||
XMR_BASE_P2P_PORT = 17792
|
|
||||||
XMR_BASE_RPC_PORT = 29798
|
|
||||||
XMR_BASE_WALLET_RPC_PORT = 29998
|
|
||||||
|
|
||||||
FIRO_BASE_PORT = 34832
|
|
||||||
FIRO_BASE_RPC_PORT = 35832
|
|
||||||
FIRO_RPC_PORT_BASE = int(os.getenv("FIRO_RPC_PORT_BASE", FIRO_BASE_RPC_PORT))
|
|
||||||
|
|
||||||
TEST_PATH = os.path.expanduser(os.getenv("TEST_PATH", "~/test_basicswap1"))
|
TEST_PATH = os.path.expanduser(os.getenv("TEST_PATH", "~/test_basicswap1"))
|
||||||
|
|
||||||
@@ -68,7 +66,21 @@ BITCOIN_RPC_PORT_BASE = int(os.getenv("BITCOIN_RPC_PORT_BASE", BTC_BASE_RPC_PORT
|
|||||||
BITCOIN_TOR_PORT_BASE = int(os.getenv("BITCOIN_TOR_PORT_BASE", BTC_BASE_TOR_PORT))
|
BITCOIN_TOR_PORT_BASE = int(os.getenv("BITCOIN_TOR_PORT_BASE", BTC_BASE_TOR_PORT))
|
||||||
|
|
||||||
LITECOIN_RPC_PORT_BASE = int(os.getenv("LITECOIN_RPC_PORT_BASE", LTC_BASE_RPC_PORT))
|
LITECOIN_RPC_PORT_BASE = int(os.getenv("LITECOIN_RPC_PORT_BASE", LTC_BASE_RPC_PORT))
|
||||||
|
|
||||||
DECRED_RPC_PORT_BASE = int(os.getenv("DECRED_RPC_PORT_BASE", DCR_BASE_RPC_PORT))
|
DECRED_RPC_PORT_BASE = int(os.getenv("DECRED_RPC_PORT_BASE", DCR_BASE_RPC_PORT))
|
||||||
|
|
||||||
|
NAMECOIN_PORT_BASE = int(os.getenv("NAMECOIN_PORT_BASE", NMC_BASE_PORT))
|
||||||
|
NAMECOIN_RPC_PORT_BASE = int(os.getenv("NAMECOIN_RPC_PORT_BASE", NMC_BASE_RPC_PORT))
|
||||||
|
NAMECOIN_TOR_PORT_BASE = int(os.getenv("NAMECOIN_TOR_PORT_BASE", NMC_BASE_TOR_PORT))
|
||||||
|
|
||||||
|
XMR_BASE_P2P_PORT = 17792
|
||||||
|
XMR_BASE_RPC_PORT = 29798
|
||||||
|
XMR_BASE_WALLET_RPC_PORT = 29998
|
||||||
|
|
||||||
|
FIRO_BASE_PORT = 34832
|
||||||
|
FIRO_BASE_RPC_PORT = 35832
|
||||||
|
FIRO_RPC_PORT_BASE = int(os.getenv("FIRO_RPC_PORT_BASE", FIRO_BASE_RPC_PORT))
|
||||||
|
|
||||||
BITCOINCASH_RPC_PORT_BASE = int(
|
BITCOINCASH_RPC_PORT_BASE = int(
|
||||||
os.getenv("BITCOINCASH_RPC_PORT_BASE", BCH_BASE_RPC_PORT)
|
os.getenv("BITCOINCASH_RPC_PORT_BASE", BCH_BASE_RPC_PORT)
|
||||||
)
|
)
|
||||||
@@ -130,19 +142,21 @@ def run_prepare(
|
|||||||
os.environ["BTC_RPC_PORT"] = str(BITCOIN_RPC_PORT_BASE)
|
os.environ["BTC_RPC_PORT"] = str(BITCOIN_RPC_PORT_BASE)
|
||||||
os.environ["BTC_PORT"] = str(BITCOIN_PORT_BASE)
|
os.environ["BTC_PORT"] = str(BITCOIN_PORT_BASE)
|
||||||
os.environ["BTC_USE_DESCRIPTORS"] = str(BTC_USE_DESCRIPTORS)
|
os.environ["BTC_USE_DESCRIPTORS"] = str(BTC_USE_DESCRIPTORS)
|
||||||
|
os.environ["BTC_ONION_PORT"] = str(BITCOIN_TOR_PORT_BASE)
|
||||||
os.environ["LTC_RPC_PORT"] = str(LITECOIN_RPC_PORT_BASE)
|
os.environ["LTC_RPC_PORT"] = str(LITECOIN_RPC_PORT_BASE)
|
||||||
os.environ["DCR_RPC_PORT"] = str(DECRED_RPC_PORT_BASE)
|
os.environ["DCR_RPC_PORT"] = str(DECRED_RPC_PORT_BASE)
|
||||||
|
os.environ["DCR_RPC_PWD"] = "dcr_pwd"
|
||||||
|
os.environ["NMC_RPC_PORT"] = str(NAMECOIN_RPC_PORT_BASE)
|
||||||
|
os.environ["NMC_PORT"] = str(NMC_BASE_PORT)
|
||||||
|
os.environ["NMC_ONION_PORT"] = str(NAMECOIN_TOR_PORT_BASE)
|
||||||
|
os.environ["XMR_RPC_USER"] = "xmr_user"
|
||||||
|
os.environ["XMR_RPC_PWD"] = "xmr_pwd"
|
||||||
os.environ["FIRO_RPC_PORT"] = str(FIRO_RPC_PORT_BASE)
|
os.environ["FIRO_RPC_PORT"] = str(FIRO_RPC_PORT_BASE)
|
||||||
os.environ["BCH_PORT"] = str(BCH_BASE_PORT)
|
os.environ["BCH_PORT"] = str(BCH_BASE_PORT)
|
||||||
os.environ["BCH_RPC_PORT"] = str(BITCOINCASH_RPC_PORT_BASE)
|
os.environ["BCH_RPC_PORT"] = str(BITCOINCASH_RPC_PORT_BASE)
|
||||||
os.environ["DOGE_PORT"] = str(DOGE_BASE_PORT)
|
os.environ["DOGE_PORT"] = str(DOGE_BASE_PORT)
|
||||||
os.environ["DOGE_RPC_PORT"] = str(DOGECOIN_RPC_PORT_BASE)
|
os.environ["DOGE_RPC_PORT"] = str(DOGECOIN_RPC_PORT_BASE)
|
||||||
|
|
||||||
os.environ["XMR_RPC_USER"] = "xmr_user"
|
|
||||||
os.environ["XMR_RPC_PWD"] = "xmr_pwd"
|
|
||||||
|
|
||||||
os.environ["DCR_RPC_PWD"] = "dcr_pwd"
|
|
||||||
|
|
||||||
import basicswap.bin.prepare as prepareSystem
|
import basicswap.bin.prepare as prepareSystem
|
||||||
|
|
||||||
# Hack: Reload module to set env vars as the basicswap_prepare module is initialised if imported from elsewhere earlier
|
# Hack: Reload module to set env vars as the basicswap_prepare module is initialised if imported from elsewhere earlier
|
||||||
@@ -320,6 +334,62 @@ def run_prepare(
|
|||||||
with open(config_filename, "a") as fp:
|
with open(config_filename, "a") as fp:
|
||||||
fp.write("enablevoting=1\n")
|
fp.write("enablevoting=1\n")
|
||||||
|
|
||||||
|
if "namecoin" in coins_array:
|
||||||
|
# Pruned nodes don't provide blocks
|
||||||
|
config_filename = os.path.join(datadir_path, "namecoin", "namecoin.conf")
|
||||||
|
with open(config_filename, "r") as fp:
|
||||||
|
lines = fp.readlines()
|
||||||
|
with open(config_filename, "w") as fp:
|
||||||
|
for line in lines:
|
||||||
|
if not line.startswith("prune"):
|
||||||
|
fp.write(line)
|
||||||
|
# fp.write("bind=127.0.0.1\n") # Causes BTC v28 to try and bind to bind=127.0.0.1:8444, even with a bind...=onion present
|
||||||
|
# listenonion=0 does not stop the node from trying to bind to the tor port
|
||||||
|
# https://github.com/bitcoin/bitcoin/issues/22726
|
||||||
|
fp.write(
|
||||||
|
"bind=127.0.0.1:{}=onion\n".format(
|
||||||
|
NAMECOIN_TOR_PORT_BASE + node_id + port_ofs
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fp.write("dnsseed=0\n")
|
||||||
|
fp.write("discover=0\n")
|
||||||
|
fp.write("listenonion=0\n")
|
||||||
|
fp.write("upnp=0\n")
|
||||||
|
if use_rpcauth:
|
||||||
|
salt = generate_salt(16)
|
||||||
|
rpc_user = "test_nmc_" + str(node_id)
|
||||||
|
rpc_pass = "test_nmc_pwd_" + str(node_id)
|
||||||
|
fp.write(
|
||||||
|
"rpcauth={}:{}${}\n".format(
|
||||||
|
rpc_user, salt, password_to_hmac(salt, rpc_pass)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
settings["chainclients"]["namecoin"]["rpcuser"] = rpc_user
|
||||||
|
settings["chainclients"]["namecoin"]["rpcpassword"] = rpc_pass
|
||||||
|
for ip in range(num_nodes):
|
||||||
|
if ip != node_id:
|
||||||
|
fp.write(
|
||||||
|
"connect=127.0.0.1:{}\n".format(
|
||||||
|
NAMECOIN_PORT_BASE + ip + port_ofs
|
||||||
|
)
|
||||||
|
)
|
||||||
|
for opt in EXTRA_CONFIG_JSON.get("ncm{}".format(node_id), []):
|
||||||
|
fp.write(opt + "\n")
|
||||||
|
|
||||||
|
if "monero" in coins_array:
|
||||||
|
with open(os.path.join(datadir_path, "monero", "monerod.conf"), "a") as fp:
|
||||||
|
fp.write("p2p-bind-ip=127.0.0.1\n")
|
||||||
|
fp.write(
|
||||||
|
"p2p-bind-port={}\n".format(XMR_BASE_P2P_PORT + node_id + port_ofs)
|
||||||
|
)
|
||||||
|
for ip in range(num_nodes):
|
||||||
|
if ip != node_id:
|
||||||
|
fp.write(
|
||||||
|
"add-exclusive-node=127.0.0.1:{}\n".format(
|
||||||
|
XMR_BASE_P2P_PORT + ip + port_ofs
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if "pivx" in coins_array:
|
if "pivx" in coins_array:
|
||||||
# Pruned nodes don't provide blocks
|
# Pruned nodes don't provide blocks
|
||||||
config_filename = os.path.join(datadir_path, "pivx", "pivx.conf")
|
config_filename = os.path.join(datadir_path, "pivx", "pivx.conf")
|
||||||
@@ -388,20 +458,6 @@ def run_prepare(
|
|||||||
for opt in EXTRA_CONFIG_JSON.get("firo{}".format(node_id), []):
|
for opt in EXTRA_CONFIG_JSON.get("firo{}".format(node_id), []):
|
||||||
fp.write(opt + "\n")
|
fp.write(opt + "\n")
|
||||||
|
|
||||||
if "monero" in coins_array:
|
|
||||||
with open(os.path.join(datadir_path, "monero", "monerod.conf"), "a") as fp:
|
|
||||||
fp.write("p2p-bind-ip=127.0.0.1\n")
|
|
||||||
fp.write(
|
|
||||||
"p2p-bind-port={}\n".format(XMR_BASE_P2P_PORT + node_id + port_ofs)
|
|
||||||
)
|
|
||||||
for ip in range(num_nodes):
|
|
||||||
if ip != node_id:
|
|
||||||
fp.write(
|
|
||||||
"add-exclusive-node=127.0.0.1:{}\n".format(
|
|
||||||
XMR_BASE_P2P_PORT + ip + port_ofs
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if "bitcoincash" in coins_array:
|
if "bitcoincash" in coins_array:
|
||||||
config_filename = os.path.join(datadir_path, "bitcoincash", "bitcoin.conf")
|
config_filename = os.path.join(datadir_path, "bitcoincash", "bitcoin.conf")
|
||||||
with open(config_filename, "r") as fp:
|
with open(config_filename, "r") as fp:
|
||||||
|
|||||||
@@ -138,7 +138,6 @@ def run_test_success_path(self, coin_from: Coins, coin_to: Coins):
|
|||||||
|
|
||||||
# Verify lock tx spends are found in the expected wallets
|
# Verify lock tx spends are found in the expected wallets
|
||||||
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
||||||
max_fee: int = 10000
|
|
||||||
itx_spend = bid.initiate_tx.spend_txid.hex()
|
itx_spend = bid.initiate_tx.spend_txid.hex()
|
||||||
node_to_ci_from = swap_clients[node_to].ci(coin_from)
|
node_to_ci_from = swap_clients[node_to].ci(coin_from)
|
||||||
wtx = node_to_ci_from.rpc_wallet(
|
wtx = node_to_ci_from.rpc_wallet(
|
||||||
@@ -147,7 +146,9 @@ def run_test_success_path(self, coin_from: Coins, coin_to: Coins):
|
|||||||
itx_spend,
|
itx_spend,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert amt_swap - node_to_ci_from.make_int(wtx["details"][0]["amount"]) < max_fee
|
assert (
|
||||||
|
amt_swap - node_to_ci_from.make_int(wtx["details"][0]["amount"]) < self.max_fee
|
||||||
|
)
|
||||||
|
|
||||||
node_from_ci_to = swap_clients[node_from].ci(coin_to)
|
node_from_ci_to = swap_clients[node_from].ci(coin_to)
|
||||||
ptx_spend = bid.participate_tx.spend_txid.hex()
|
ptx_spend = bid.participate_tx.spend_txid.hex()
|
||||||
@@ -158,7 +159,8 @@ def run_test_success_path(self, coin_from: Coins, coin_to: Coins):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
bid.amount_to - node_from_ci_to.make_int(wtx["details"][0]["amount"]) < max_fee
|
bid.amount_to - node_from_ci_to.make_int(wtx["details"][0]["amount"])
|
||||||
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
js_0 = read_json_api(1800 + node_from)
|
js_0 = read_json_api(1800 + node_from)
|
||||||
@@ -235,7 +237,6 @@ def run_test_bad_ptx(self, coin_from: Coins, coin_to: Coins):
|
|||||||
|
|
||||||
# Verify lock tx spends are found in the expected wallets
|
# Verify lock tx spends are found in the expected wallets
|
||||||
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
||||||
max_fee: int = 10000
|
|
||||||
itx_spend = bid.initiate_tx.spend_txid.hex()
|
itx_spend = bid.initiate_tx.spend_txid.hex()
|
||||||
node_from_ci_from = swap_clients[node_from].ci(coin_from)
|
node_from_ci_from = swap_clients[node_from].ci(coin_from)
|
||||||
wtx = node_from_ci_from.rpc_wallet(
|
wtx = node_from_ci_from.rpc_wallet(
|
||||||
@@ -244,7 +245,10 @@ def run_test_bad_ptx(self, coin_from: Coins, coin_to: Coins):
|
|||||||
itx_spend,
|
itx_spend,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert amt_swap - node_from_ci_from.make_int(wtx["details"][0]["amount"]) < max_fee
|
assert (
|
||||||
|
amt_swap - node_from_ci_from.make_int(wtx["details"][0]["amount"])
|
||||||
|
< self.max_fee
|
||||||
|
)
|
||||||
|
|
||||||
node_to_ci_to = swap_clients[node_to].ci(coin_to)
|
node_to_ci_to = swap_clients[node_to].ci(coin_to)
|
||||||
bid, offer = swap_clients[node_to].getBidAndOffer(bid_id)
|
bid, offer = swap_clients[node_to].getBidAndOffer(bid_id)
|
||||||
@@ -255,7 +259,10 @@ def run_test_bad_ptx(self, coin_from: Coins, coin_to: Coins):
|
|||||||
ptx_spend,
|
ptx_spend,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert bid.amount_to - node_to_ci_to.make_int(wtx["details"][0]["amount"]) < max_fee
|
assert (
|
||||||
|
bid.amount_to - node_to_ci_to.make_int(wtx["details"][0]["amount"])
|
||||||
|
< self.max_fee
|
||||||
|
)
|
||||||
|
|
||||||
bid_id_hex = bid_id.hex()
|
bid_id_hex = bid_id.hex()
|
||||||
path = f"bids/{bid_id_hex}/states"
|
path = f"bids/{bid_id_hex}/states"
|
||||||
@@ -338,7 +345,6 @@ def run_test_itx_refund(self, coin_from: Coins, coin_to: Coins):
|
|||||||
|
|
||||||
# Verify lock tx spends are found in the expected wallets
|
# Verify lock tx spends are found in the expected wallets
|
||||||
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
||||||
max_fee: int = 10000
|
|
||||||
itx_spend = bid.initiate_tx.spend_txid.hex()
|
itx_spend = bid.initiate_tx.spend_txid.hex()
|
||||||
node_from_ci_from = swap_clients[node_from].ci(coin_from)
|
node_from_ci_from = swap_clients[node_from].ci(coin_from)
|
||||||
wtx = node_from_ci_from.rpc_wallet(
|
wtx = node_from_ci_from.rpc_wallet(
|
||||||
@@ -348,7 +354,8 @@ def run_test_itx_refund(self, coin_from: Coins, coin_to: Coins):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
swap_value - node_from_ci_from.make_int(wtx["details"][0]["amount"]) < max_fee
|
swap_value - node_from_ci_from.make_int(wtx["details"][0]["amount"])
|
||||||
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
node_from_ci_to = swap_clients[node_from].ci(coin_to)
|
node_from_ci_to = swap_clients[node_from].ci(coin_to)
|
||||||
@@ -360,7 +367,8 @@ def run_test_itx_refund(self, coin_from: Coins, coin_to: Coins):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
bid.amount_to - node_from_ci_to.make_int(wtx["details"][0]["amount"]) < max_fee
|
bid.amount_to - node_from_ci_to.make_int(wtx["details"][0]["amount"])
|
||||||
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -425,7 +433,6 @@ def run_test_ads_success_path(self, coin_from: Coins, coin_to: Coins):
|
|||||||
bid, xmr_swap = swap_clients[id_offerer].getXmrBid(bid_id)
|
bid, xmr_swap = swap_clients[id_offerer].getXmrBid(bid_id)
|
||||||
|
|
||||||
node_from_ci_to = swap_clients[0].ci(coin_to)
|
node_from_ci_to = swap_clients[0].ci(coin_to)
|
||||||
max_fee: int = 10000
|
|
||||||
if node_from_ci_to.coin_type() in (Coins.XMR, Coins.WOW):
|
if node_from_ci_to.coin_type() in (Coins.XMR, Coins.WOW):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@@ -437,7 +444,7 @@ def run_test_ads_success_path(self, coin_from: Coins, coin_to: Coins):
|
|||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
bid.amount_to - node_from_ci_to.make_int(wtx["details"][0]["amount"])
|
bid.amount_to - node_from_ci_to.make_int(wtx["details"][0]["amount"])
|
||||||
< max_fee
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
node_to_ci_from = swap_clients[1].ci(coin_from)
|
node_to_ci_from = swap_clients[1].ci(coin_from)
|
||||||
@@ -451,7 +458,8 @@ def run_test_ads_success_path(self, coin_from: Coins, coin_to: Coins):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
bid.amount - node_to_ci_from.make_int(wtx["details"][0]["amount"]) < max_fee
|
bid.amount - node_to_ci_from.make_int(wtx["details"][0]["amount"])
|
||||||
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
bid_id_hex = bid_id.hex()
|
bid_id_hex = bid_id.hex()
|
||||||
@@ -550,7 +558,6 @@ def run_test_ads_both_refund(
|
|||||||
bid, xmr_swap = swap_clients[id_bidder].getXmrBid(bid_id)
|
bid, xmr_swap = swap_clients[id_bidder].getXmrBid(bid_id)
|
||||||
|
|
||||||
node_from_ci_from = swap_clients[0].ci(coin_from)
|
node_from_ci_from = swap_clients[0].ci(coin_from)
|
||||||
max_fee: int = 10000
|
|
||||||
if node_from_ci_from.coin_type() in (Coins.XMR, Coins.WOW):
|
if node_from_ci_from.coin_type() in (Coins.XMR, Coins.WOW):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@@ -562,7 +569,7 @@ def run_test_ads_both_refund(
|
|||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
bid.amount - node_from_ci_from.make_int(wtx["details"][0]["amount"])
|
bid.amount - node_from_ci_from.make_int(wtx["details"][0]["amount"])
|
||||||
< max_fee
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
node_to_ci_to = swap_clients[1].ci(coin_to)
|
node_to_ci_to = swap_clients[1].ci(coin_to)
|
||||||
@@ -577,7 +584,7 @@ def run_test_ads_both_refund(
|
|||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
bid.amount_to - node_to_ci_to.make_int(wtx["details"][0]["amount"])
|
bid.amount_to - node_to_ci_to.make_int(wtx["details"][0]["amount"])
|
||||||
< max_fee
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
bid_id_hex = bid_id.hex()
|
bid_id_hex = bid_id.hex()
|
||||||
@@ -720,6 +727,7 @@ class Test(BaseTest):
|
|||||||
start_xmr_nodes = True
|
start_xmr_nodes = True
|
||||||
dcr_mining_addr = "SsYbXyjkKAEXXcGdFgr4u4bo4L8RkCxwQpH"
|
dcr_mining_addr = "SsYbXyjkKAEXXcGdFgr4u4bo4L8RkCxwQpH"
|
||||||
extra_wait_time = 0
|
extra_wait_time = 0
|
||||||
|
max_fee: int = 10000
|
||||||
|
|
||||||
hex_seeds = [
|
hex_seeds = [
|
||||||
"e8574b2a94404ee62d8acc0258cab4c0defcfab8a5dfc2f4954c1f9d7e09d72a",
|
"e8574b2a94404ee62d8acc0258cab4c0defcfab8a5dfc2f4954c1f9d7e09d72a",
|
||||||
|
|||||||
@@ -11,78 +11,58 @@ basicswap]$ python tests/basicswap/extended/test_nmc.py
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import shutil
|
import random
|
||||||
import signal
|
|
||||||
import sys
|
import sys
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import basicswap.config as cfg
|
import basicswap.config as cfg
|
||||||
from basicswap.basicswap import (
|
from basicswap.basicswap import (
|
||||||
BasicSwap,
|
|
||||||
Coins,
|
Coins,
|
||||||
SwapTypes,
|
|
||||||
BidStates,
|
|
||||||
TxStates,
|
|
||||||
)
|
)
|
||||||
from basicswap.util import (
|
from basicswap.util import (
|
||||||
COIN,
|
toBool,
|
||||||
)
|
|
||||||
from basicswap.basicswap_util import (
|
|
||||||
TxLockTypes,
|
|
||||||
)
|
|
||||||
from basicswap.util.address import (
|
|
||||||
toWIF,
|
|
||||||
)
|
|
||||||
from basicswap.rpc import (
|
|
||||||
callrpc_cli,
|
|
||||||
)
|
|
||||||
from basicswap.contrib.key import (
|
|
||||||
ECKey,
|
|
||||||
)
|
|
||||||
from basicswap.http_server import (
|
|
||||||
HttpThread,
|
|
||||||
)
|
|
||||||
from tests.basicswap.util import (
|
|
||||||
read_json_api,
|
|
||||||
)
|
|
||||||
from tests.basicswap.common import (
|
|
||||||
checkForks,
|
|
||||||
stopDaemons,
|
|
||||||
wait_for_offer,
|
|
||||||
wait_for_bid,
|
|
||||||
wait_for_bid_tx_state,
|
|
||||||
wait_for_in_progress,
|
|
||||||
TEST_HTTP_HOST,
|
|
||||||
TEST_HTTP_PORT,
|
|
||||||
BASE_PORT,
|
|
||||||
BASE_RPC_PORT,
|
|
||||||
BASE_ZMQ_PORT,
|
|
||||||
PREFIX_SECRET_KEY_REGTEST,
|
|
||||||
waitForRPC,
|
|
||||||
)
|
)
|
||||||
from basicswap.bin.run import startDaemon
|
from basicswap.bin.run import startDaemon
|
||||||
|
from basicswap.contrib.rpcauth import generate_salt, password_to_hmac
|
||||||
|
from tests.basicswap.common import (
|
||||||
|
stopDaemons,
|
||||||
|
waitForRPC,
|
||||||
|
make_rpc_func,
|
||||||
|
)
|
||||||
|
|
||||||
|
from tests.basicswap.test_btc_xmr import BasicSwapTest, test_delay_event
|
||||||
|
from tests.basicswap.test_xmr import NUM_NODES
|
||||||
|
from tests.basicswap.extended.test_dcr import (
|
||||||
|
run_test_success_path,
|
||||||
|
run_test_bad_ptx,
|
||||||
|
run_test_itx_refund,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger("BSX Tests")
|
||||||
logger.level = logging.DEBUG
|
|
||||||
if not len(logger.handlers):
|
if not len(logger.handlers):
|
||||||
logger.addHandler(logging.StreamHandler(sys.stdout))
|
logger.addHandler(logging.StreamHandler(sys.stdout))
|
||||||
|
|
||||||
NUM_NODES = 3
|
|
||||||
NMC_NODE = 3
|
|
||||||
BTC_NODE = 4
|
|
||||||
|
|
||||||
delay_event = threading.Event()
|
NAMECOIN_BINDIR = os.path.expanduser(
|
||||||
stop_test = False
|
os.getenv("NAMECOIN_BINDIR", os.path.join(cfg.DEFAULT_TEST_BINDIR, "namecoin"))
|
||||||
|
)
|
||||||
|
NAMECOIND = os.getenv("NAMECOIND", "namecoind" + cfg.bin_suffix)
|
||||||
|
NAMECOIN_CLI = os.getenv("NAMECOIN_CLI", "namecoin-cli" + cfg.bin_suffix)
|
||||||
|
NAMECOIN_TX = os.getenv("NAMECOIN_TX", "namecoin-tx" + cfg.bin_suffix)
|
||||||
|
|
||||||
|
NMC_USE_DESCRIPTORS = toBool(os.getenv("NMC_USE_DESCRIPTORS", True))
|
||||||
|
|
||||||
|
NMC_BASE_PORT = 8136
|
||||||
|
NMC_BASE_RPC_PORT = 8146
|
||||||
|
NMC_BASE_TOR_PORT = 8156
|
||||||
|
|
||||||
|
|
||||||
def prepareOtherDir(datadir, nodeId, conf_file="namecoin.conf"):
|
def prepareNMCDataDir(datadir, nodeId, conf_file="namecoin.conf"):
|
||||||
node_dir = os.path.join(datadir, str(nodeId))
|
node_dir = os.path.join(datadir, "nmc_" + str(nodeId))
|
||||||
if not os.path.exists(node_dir):
|
if not os.path.exists(node_dir):
|
||||||
os.makedirs(node_dir)
|
os.makedirs(node_dir)
|
||||||
filePath = os.path.join(node_dir, conf_file)
|
filePath = os.path.join(node_dir, conf_file)
|
||||||
@@ -90,8 +70,17 @@ def prepareOtherDir(datadir, nodeId, conf_file="namecoin.conf"):
|
|||||||
with open(filePath, "w+") as fp:
|
with open(filePath, "w+") as fp:
|
||||||
fp.write("regtest=1\n")
|
fp.write("regtest=1\n")
|
||||||
fp.write("[regtest]\n")
|
fp.write("[regtest]\n")
|
||||||
fp.write("port=" + str(BASE_PORT + nodeId) + "\n")
|
|
||||||
fp.write("rpcport=" + str(BASE_RPC_PORT + nodeId) + "\n")
|
fp.write("port=" + str(NMC_BASE_PORT + nodeId) + "\n")
|
||||||
|
fp.write("rpcport=" + str(NMC_BASE_RPC_PORT + nodeId) + "\n")
|
||||||
|
salt = generate_salt(16)
|
||||||
|
fp.write(
|
||||||
|
"rpcauth={}:{}${}\n".format(
|
||||||
|
"test" + str(nodeId),
|
||||||
|
salt,
|
||||||
|
password_to_hmac(salt, "test_pass" + str(nodeId)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
fp.write("daemon=0\n")
|
fp.write("daemon=0\n")
|
||||||
fp.write("printtoconsole=0\n")
|
fp.write("printtoconsole=0\n")
|
||||||
@@ -99,595 +88,182 @@ def prepareOtherDir(datadir, nodeId, conf_file="namecoin.conf"):
|
|||||||
fp.write("discover=0\n")
|
fp.write("discover=0\n")
|
||||||
fp.write("listenonion=0\n")
|
fp.write("listenonion=0\n")
|
||||||
fp.write("bind=127.0.0.1\n")
|
fp.write("bind=127.0.0.1\n")
|
||||||
fp.write("findpeers=0\n")
|
|
||||||
fp.write("debug=1\n")
|
fp.write("debug=1\n")
|
||||||
fp.write("debugexclude=libevent\n")
|
fp.write("debugexclude=libevent\n")
|
||||||
|
|
||||||
fp.write("fallbackfee=0.01\n")
|
fp.write("fallbackfee=0.01\n")
|
||||||
fp.write("acceptnonstdtxn=0\n")
|
fp.write("acceptnonstdtxn=0\n")
|
||||||
|
fp.write("deprecatedrpc=create_bdb\n")
|
||||||
if conf_file == "bitcoin.conf":
|
fp.write("addresstype=bech32\n")
|
||||||
fp.write("wallet=wallet.dat\n")
|
fp.write("changetype=bech32\n")
|
||||||
|
|
||||||
|
|
||||||
def prepareDir(datadir, nodeId, network_key, network_pubkey):
|
|
||||||
node_dir = os.path.join(datadir, str(nodeId))
|
|
||||||
if not os.path.exists(node_dir):
|
|
||||||
os.makedirs(node_dir)
|
|
||||||
filePath = os.path.join(node_dir, "particl.conf")
|
|
||||||
|
|
||||||
with open(filePath, "w+") as fp:
|
|
||||||
fp.write("regtest=1\n")
|
|
||||||
fp.write("[regtest]\n")
|
|
||||||
fp.write("port=" + str(BASE_PORT + nodeId) + "\n")
|
|
||||||
fp.write("rpcport=" + str(BASE_RPC_PORT + nodeId) + "\n")
|
|
||||||
|
|
||||||
fp.write("daemon=0\n")
|
|
||||||
fp.write("printtoconsole=0\n")
|
|
||||||
fp.write("server=1\n")
|
|
||||||
fp.write("discover=0\n")
|
|
||||||
fp.write("listenonion=0\n")
|
|
||||||
fp.write("bind=127.0.0.1\n")
|
|
||||||
fp.write("findpeers=0\n")
|
|
||||||
fp.write("debug=1\n")
|
|
||||||
fp.write("debugexclude=libevent\n")
|
|
||||||
fp.write("zmqpubsmsg=tcp://127.0.0.1:" + str(BASE_ZMQ_PORT + nodeId) + "\n")
|
|
||||||
fp.write("wallet=wallet.dat\n")
|
|
||||||
fp.write("fallbackfee=0.01\n")
|
|
||||||
|
|
||||||
fp.write("acceptnonstdtxn=0\n")
|
|
||||||
fp.write("minstakeinterval=5\n")
|
|
||||||
fp.write("smsgsregtestadjust=0\n")
|
|
||||||
|
|
||||||
for i in range(0, NUM_NODES):
|
for i in range(0, NUM_NODES):
|
||||||
if nodeId == i:
|
if nodeId == i:
|
||||||
continue
|
continue
|
||||||
fp.write("addnode=127.0.0.1:%d\n" % (BASE_PORT + i))
|
fp.write("addnode=127.0.0.1:{}\n".format(NMC_BASE_PORT + i))
|
||||||
|
|
||||||
if nodeId < 2:
|
|
||||||
fp.write("spentindex=1\n")
|
|
||||||
fp.write("txindex=1\n")
|
|
||||||
|
|
||||||
basicswap_dir = os.path.join(datadir, str(nodeId), "basicswap")
|
|
||||||
if not os.path.exists(basicswap_dir):
|
|
||||||
os.makedirs(basicswap_dir)
|
|
||||||
|
|
||||||
nmcdatadir = os.path.join(datadir, str(NMC_NODE))
|
|
||||||
btcdatadir = os.path.join(datadir, str(BTC_NODE))
|
|
||||||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
|
||||||
settings = {
|
|
||||||
"debug": True,
|
|
||||||
"zmqhost": "tcp://127.0.0.1",
|
|
||||||
"zmqport": BASE_ZMQ_PORT + nodeId,
|
|
||||||
"htmlhost": "127.0.0.1",
|
|
||||||
"htmlport": 12700 + nodeId,
|
|
||||||
"network_key": network_key,
|
|
||||||
"network_pubkey": network_pubkey,
|
|
||||||
"chainclients": {
|
|
||||||
"particl": {
|
|
||||||
"connection_type": "rpc",
|
|
||||||
"manage_daemon": False,
|
|
||||||
"rpcport": BASE_RPC_PORT + nodeId,
|
|
||||||
"datadir": node_dir,
|
|
||||||
"bindir": cfg.PARTICL_BINDIR,
|
|
||||||
"blocks_confirmed": 2, # Faster testing
|
|
||||||
},
|
|
||||||
"namecoin": {
|
|
||||||
"connection_type": "rpc",
|
|
||||||
"manage_daemon": False,
|
|
||||||
"rpcport": BASE_RPC_PORT + NMC_NODE,
|
|
||||||
"datadir": nmcdatadir,
|
|
||||||
"bindir": cfg.NAMECOIN_BINDIR,
|
|
||||||
"use_csv": False,
|
|
||||||
# 'use_segwit': True,
|
|
||||||
},
|
|
||||||
"bitcoin": {
|
|
||||||
"connection_type": "rpc",
|
|
||||||
"manage_daemon": False,
|
|
||||||
"rpcport": BASE_RPC_PORT + BTC_NODE,
|
|
||||||
"datadir": btcdatadir,
|
|
||||||
"bindir": cfg.BITCOIN_BINDIR,
|
|
||||||
"use_segwit": True,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"check_progress_seconds": 2,
|
|
||||||
"check_watched_seconds": 4,
|
|
||||||
"check_expired_seconds": 60,
|
|
||||||
"restrict_unknown_seed_wallets": False,
|
|
||||||
}
|
|
||||||
with open(settings_path, "w") as fp:
|
|
||||||
json.dump(settings, fp, indent=4)
|
|
||||||
|
|
||||||
|
|
||||||
def partRpc(cmd, node_id=0):
|
class TestNMC(BasicSwapTest):
|
||||||
return callrpc_cli(
|
__test__ = True
|
||||||
cfg.PARTICL_BINDIR,
|
test_coin = Coins.NMC
|
||||||
os.path.join(cfg.TEST_DATADIRS, str(node_id)),
|
test_coin_from = Coins.NMC
|
||||||
"regtest",
|
nmc_daemons = []
|
||||||
cmd,
|
start_ltc_nodes = False
|
||||||
cfg.PARTICL_CLI,
|
start_xmr_nodes = True
|
||||||
)
|
base_rpc_port = NMC_BASE_RPC_PORT
|
||||||
|
nmc_addr = None
|
||||||
|
max_fee: int = 200000
|
||||||
|
test_fee_rate: int = 100000 # sats/kvB
|
||||||
|
|
||||||
|
def mineBlock(self, num_blocks: int = 1) -> None:
|
||||||
def btcRpc(cmd):
|
self.callnoderpc("generatetoaddress", [num_blocks, self.nmc_addr])
|
||||||
return callrpc_cli(
|
|
||||||
cfg.BITCOIN_BINDIR,
|
|
||||||
os.path.join(cfg.TEST_DATADIRS, str(BTC_NODE)),
|
|
||||||
"regtest",
|
|
||||||
cmd,
|
|
||||||
cfg.BITCOIN_CLI,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def nmcRpc(cmd):
|
|
||||||
return callrpc_cli(
|
|
||||||
cfg.NAMECOIN_BINDIR,
|
|
||||||
os.path.join(cfg.TEST_DATADIRS, str(NMC_NODE)),
|
|
||||||
"regtest",
|
|
||||||
cmd,
|
|
||||||
cfg.NAMECOIN_CLI,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def signal_handler(sig, frame):
|
|
||||||
global stop_test
|
|
||||||
os.write(sys.stdout.fileno(), f"Signal {sig} detected.\n".encode("utf-8"))
|
|
||||||
stop_test = True
|
|
||||||
delay_event.set()
|
|
||||||
|
|
||||||
|
|
||||||
def run_coins_loop(cls):
|
|
||||||
while not stop_test:
|
|
||||||
try:
|
|
||||||
nmcRpc("generatetoaddress 1 {}".format(cls.nmc_addr))
|
|
||||||
btcRpc("generatetoaddress 1 {}".format(cls.btc_addr))
|
|
||||||
except Exception as e:
|
|
||||||
logging.warning("run_coins_loop " + str(e))
|
|
||||||
time.sleep(1.0)
|
|
||||||
|
|
||||||
|
|
||||||
def run_loop(self):
|
|
||||||
while not stop_test:
|
|
||||||
for c in self.swap_clients:
|
|
||||||
c.update()
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
|
|
||||||
def make_part_cli_rpc_func(node_id):
|
|
||||||
node_id = node_id
|
|
||||||
|
|
||||||
def rpc_func(method, params=None, wallet=None):
|
|
||||||
cmd = method
|
|
||||||
if params:
|
|
||||||
for p in params:
|
|
||||||
cmd += ' "' + p + '"'
|
|
||||||
return partRpc(cmd, node_id)
|
|
||||||
|
|
||||||
return rpc_func
|
|
||||||
|
|
||||||
|
|
||||||
class Test(unittest.TestCase):
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
super(Test, cls).setUpClass()
|
|
||||||
|
|
||||||
eckey = ECKey()
|
|
||||||
eckey.generate()
|
|
||||||
cls.network_key = toWIF(PREFIX_SECRET_KEY_REGTEST, eckey.get_bytes())
|
|
||||||
cls.network_pubkey = eckey.get_pubkey().get_bytes().hex()
|
|
||||||
|
|
||||||
if os.path.isdir(cfg.TEST_DATADIRS):
|
|
||||||
logging.info("Removing " + cfg.TEST_DATADIRS)
|
|
||||||
shutil.rmtree(cfg.TEST_DATADIRS)
|
|
||||||
|
|
||||||
for i in range(NUM_NODES):
|
|
||||||
prepareDir(cfg.TEST_DATADIRS, i, cls.network_key, cls.network_pubkey)
|
|
||||||
|
|
||||||
prepareOtherDir(cfg.TEST_DATADIRS, NMC_NODE)
|
|
||||||
prepareOtherDir(cfg.TEST_DATADIRS, BTC_NODE, "bitcoin.conf")
|
|
||||||
|
|
||||||
cls.daemons = []
|
|
||||||
cls.swap_clients = []
|
|
||||||
cls.http_threads = []
|
|
||||||
|
|
||||||
btc_data_dir = os.path.join(cfg.TEST_DATADIRS, str(BTC_NODE))
|
|
||||||
if os.path.exists(os.path.join(cfg.BITCOIN_BINDIR, "bitcoin-wallet")):
|
|
||||||
callrpc_cli(
|
|
||||||
cfg.BITCOIN_BINDIR,
|
|
||||||
btc_data_dir,
|
|
||||||
"regtest",
|
|
||||||
"-wallet=wallet.dat -legacy create",
|
|
||||||
"bitcoin-wallet",
|
|
||||||
)
|
|
||||||
cls.daemons.append(startDaemon(btc_data_dir, cfg.BITCOIN_BINDIR, cfg.BITCOIND))
|
|
||||||
logging.info("Started %s %d", cfg.BITCOIND, cls.daemons[-1].handle.pid)
|
|
||||||
cls.daemons.append(
|
|
||||||
startDaemon(
|
|
||||||
os.path.join(cfg.TEST_DATADIRS, str(NMC_NODE)),
|
|
||||||
cfg.NAMECOIN_BINDIR,
|
|
||||||
cfg.NAMECOIND,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
logging.info("Started %s %d", cfg.NAMECOIND, cls.daemons[-1].handle.pid)
|
|
||||||
|
|
||||||
for i in range(NUM_NODES):
|
|
||||||
data_dir = os.path.join(cfg.TEST_DATADIRS, str(i))
|
|
||||||
if os.path.exists(os.path.join(cfg.PARTICL_BINDIR, "particl-wallet")):
|
|
||||||
callrpc_cli(
|
|
||||||
cfg.PARTICL_BINDIR,
|
|
||||||
data_dir,
|
|
||||||
"regtest",
|
|
||||||
"-wallet=wallet.dat -legacy create",
|
|
||||||
"particl-wallet",
|
|
||||||
)
|
|
||||||
cls.daemons.append(startDaemon(data_dir, cfg.PARTICL_BINDIR, cfg.PARTICLD))
|
|
||||||
logging.info("Started %s %d", cfg.PARTICLD, cls.daemons[-1].handle.pid)
|
|
||||||
|
|
||||||
for i in range(NUM_NODES):
|
|
||||||
rpc = make_part_cli_rpc_func(i)
|
|
||||||
waitForRPC(rpc, delay_event)
|
|
||||||
if i == 0:
|
|
||||||
rpc(
|
|
||||||
"extkeyimportmaster",
|
|
||||||
[
|
|
||||||
"abandon baby cabbage dad eager fabric gadget habit ice kangaroo lab absorb"
|
|
||||||
],
|
|
||||||
)
|
|
||||||
elif i == 1:
|
|
||||||
rpc(
|
|
||||||
"extkeyimportmaster",
|
|
||||||
[
|
|
||||||
"pact mammal barrel matrix local final lecture chunk wasp survey bid various book strong spread fall ozone daring like topple door fatigue limb olympic",
|
|
||||||
"",
|
|
||||||
"true",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
rpc("getnewextaddress", ["lblExtTest"])
|
|
||||||
rpc("rescanblockchain")
|
|
||||||
else:
|
|
||||||
rpc("extkeyimportmaster", [rpc("mnemonic", ["new"])["master"]])
|
|
||||||
rpc(
|
|
||||||
"walletsettings",
|
|
||||||
[
|
|
||||||
"stakingoptions",
|
|
||||||
json.dumps(
|
|
||||||
{"stakecombinethreshold": 100, "stakesplitthreshold": 200}
|
|
||||||
).replace('"', '\\"'),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
rpc("reservebalance", ["false"])
|
|
||||||
|
|
||||||
basicswap_dir = os.path.join(
|
|
||||||
os.path.join(cfg.TEST_DATADIRS, str(i)), "basicswap"
|
|
||||||
)
|
|
||||||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
|
||||||
with open(settings_path) as fs:
|
|
||||||
settings = json.load(fs)
|
|
||||||
sc = BasicSwap(
|
|
||||||
basicswap_dir, settings, "regtest", log_name="BasicSwap{}".format(i)
|
|
||||||
)
|
|
||||||
cls.swap_clients.append(sc)
|
|
||||||
|
|
||||||
sc.setDaemonPID(Coins.BTC, cls.daemons[0].handle.pid)
|
|
||||||
sc.setDaemonPID(Coins.NMC, cls.daemons[1].handle.pid)
|
|
||||||
sc.setDaemonPID(Coins.PART, cls.daemons[2 + i].handle.pid)
|
|
||||||
sc.start()
|
|
||||||
|
|
||||||
t = HttpThread(TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, sc)
|
|
||||||
cls.http_threads.append(t)
|
|
||||||
t.start()
|
|
||||||
|
|
||||||
waitForRPC(nmcRpc, delay_event)
|
|
||||||
num_blocks = 500
|
|
||||||
logging.info("Mining %d namecoin blocks", num_blocks)
|
|
||||||
cls.nmc_addr = nmcRpc("getnewaddress mining_addr legacy")
|
|
||||||
nmcRpc("generatetoaddress {} {}".format(num_blocks, cls.nmc_addr))
|
|
||||||
|
|
||||||
ro = nmcRpc("getblockchaininfo")
|
|
||||||
try:
|
|
||||||
assert ro["bip9_softforks"]["csv"]["status"] == "active"
|
|
||||||
except Exception:
|
|
||||||
logging.info("nmc: csv is not active")
|
|
||||||
try:
|
|
||||||
assert ro["bip9_softforks"]["segwit"]["status"] == "active"
|
|
||||||
except Exception:
|
|
||||||
logging.info("nmc: segwit is not active")
|
|
||||||
|
|
||||||
waitForRPC(btcRpc, delay_event)
|
|
||||||
cls.btc_addr = btcRpc("getnewaddress mining_addr bech32")
|
|
||||||
logging.info("Mining %d Bitcoin blocks to %s", num_blocks, cls.btc_addr)
|
|
||||||
btcRpc("generatetoaddress {} {}".format(num_blocks, cls.btc_addr))
|
|
||||||
|
|
||||||
ro = btcRpc("getblockchaininfo")
|
|
||||||
checkForks(ro)
|
|
||||||
|
|
||||||
ro = nmcRpc("getwalletinfo")
|
|
||||||
print("nmcRpc", ro)
|
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, signal_handler)
|
|
||||||
cls.update_thread = threading.Thread(target=run_loop, args=(cls,))
|
|
||||||
cls.update_thread.start()
|
|
||||||
|
|
||||||
cls.coins_update_thread = threading.Thread(target=run_coins_loop, args=(cls,))
|
|
||||||
cls.coins_update_thread.start()
|
|
||||||
|
|
||||||
# Wait for height, or sequencelock is thrown off by genesis blocktime
|
|
||||||
num_blocks = 3
|
|
||||||
logging.info("Waiting for Particl chain height %d", num_blocks)
|
|
||||||
for i in range(60):
|
|
||||||
particl_blocks = cls.swap_clients[0].callrpc("getblockcount")
|
|
||||||
print("particl_blocks", particl_blocks)
|
|
||||||
if particl_blocks >= num_blocks:
|
|
||||||
break
|
|
||||||
delay_event.wait(1)
|
|
||||||
assert particl_blocks >= num_blocks
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
global stop_test
|
logging.info("Finalising Namecoin Test")
|
||||||
logging.info("Finalising")
|
stopDaemons(cls.nmc_daemons)
|
||||||
stop_test = True
|
cls.nmc_daemons.clear()
|
||||||
cls.update_thread.join()
|
|
||||||
cls.coins_update_thread.join()
|
|
||||||
for t in cls.http_threads:
|
|
||||||
t.stop()
|
|
||||||
t.join()
|
|
||||||
for c in cls.swap_clients:
|
|
||||||
c.finalise()
|
|
||||||
|
|
||||||
stopDaemons(cls.daemons)
|
super(TestNMC, cls).tearDownClass()
|
||||||
cls.http_threads.clear()
|
|
||||||
cls.swap_clients.clear()
|
|
||||||
cls.daemons.clear()
|
|
||||||
|
|
||||||
super(Test, cls).tearDownClass()
|
@classmethod
|
||||||
|
def coins_loop(cls):
|
||||||
def test_02_part_nmc(self):
|
super(TestNMC, cls).coins_loop()
|
||||||
logging.info("---------- Test PART to NMC")
|
ci0 = cls.swap_clients[0].ci(cls.test_coin)
|
||||||
swap_clients = self.swap_clients
|
|
||||||
|
|
||||||
offer_id = swap_clients[0].postOffer(
|
|
||||||
Coins.PART,
|
|
||||||
Coins.NMC,
|
|
||||||
100 * COIN,
|
|
||||||
0.1 * COIN,
|
|
||||||
100 * COIN,
|
|
||||||
SwapTypes.SELLER_FIRST,
|
|
||||||
TxLockTypes.ABS_LOCK_TIME,
|
|
||||||
)
|
|
||||||
|
|
||||||
wait_for_offer(delay_event, swap_clients[1], offer_id)
|
|
||||||
offer = swap_clients[1].getOffer(offer_id)
|
|
||||||
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
|
|
||||||
|
|
||||||
wait_for_bid(delay_event, swap_clients[0], bid_id)
|
|
||||||
|
|
||||||
swap_clients[0].acceptBid(bid_id)
|
|
||||||
|
|
||||||
wait_for_in_progress(delay_event, swap_clients[1], bid_id, sent=True)
|
|
||||||
|
|
||||||
wait_for_bid(
|
|
||||||
delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60
|
|
||||||
)
|
|
||||||
wait_for_bid(
|
|
||||||
delay_event,
|
|
||||||
swap_clients[1],
|
|
||||||
bid_id,
|
|
||||||
BidStates.SWAP_COMPLETED,
|
|
||||||
sent=True,
|
|
||||||
wait_for=60,
|
|
||||||
)
|
|
||||||
|
|
||||||
js_0 = read_json_api(1800)
|
|
||||||
js_1 = read_json_api(1801)
|
|
||||||
assert js_0["num_swapping"] == 0 and js_0["num_watched_outputs"] == 0
|
|
||||||
assert js_1["num_swapping"] == 0 and js_1["num_watched_outputs"] == 0
|
|
||||||
|
|
||||||
def test_03_nmc_part(self):
|
|
||||||
logging.info("---------- Test NMC to PART")
|
|
||||||
swap_clients = self.swap_clients
|
|
||||||
|
|
||||||
offer_id = swap_clients[1].postOffer(
|
|
||||||
Coins.NMC,
|
|
||||||
Coins.PART,
|
|
||||||
10 * COIN,
|
|
||||||
9.0 * COIN,
|
|
||||||
10 * COIN,
|
|
||||||
SwapTypes.SELLER_FIRST,
|
|
||||||
TxLockTypes.ABS_LOCK_TIME,
|
|
||||||
)
|
|
||||||
|
|
||||||
wait_for_offer(delay_event, swap_clients[0], offer_id)
|
|
||||||
offer = swap_clients[0].getOffer(offer_id)
|
|
||||||
bid_id = swap_clients[0].postBid(offer_id, offer.amount_from)
|
|
||||||
|
|
||||||
wait_for_bid(delay_event, swap_clients[1], bid_id)
|
|
||||||
swap_clients[1].acceptBid(bid_id)
|
|
||||||
|
|
||||||
wait_for_in_progress(delay_event, swap_clients[0], bid_id, sent=True)
|
|
||||||
|
|
||||||
wait_for_bid(
|
|
||||||
delay_event,
|
|
||||||
swap_clients[0],
|
|
||||||
bid_id,
|
|
||||||
BidStates.SWAP_COMPLETED,
|
|
||||||
sent=True,
|
|
||||||
wait_for=60,
|
|
||||||
)
|
|
||||||
wait_for_bid(
|
|
||||||
delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, wait_for=60
|
|
||||||
)
|
|
||||||
|
|
||||||
js_0 = read_json_api(1800)
|
|
||||||
js_1 = read_json_api(1801)
|
|
||||||
assert js_0["num_swapping"] == 0 and js_0["num_watched_outputs"] == 0
|
|
||||||
assert js_1["num_swapping"] == 0 and js_1["num_watched_outputs"] == 0
|
|
||||||
|
|
||||||
def test_04_nmc_btc(self):
|
|
||||||
logging.info("---------- Test NMC to BTC")
|
|
||||||
swap_clients = self.swap_clients
|
|
||||||
|
|
||||||
offer_id = swap_clients[0].postOffer(
|
|
||||||
Coins.NMC,
|
|
||||||
Coins.BTC,
|
|
||||||
10 * COIN,
|
|
||||||
0.1 * COIN,
|
|
||||||
10 * COIN,
|
|
||||||
SwapTypes.SELLER_FIRST,
|
|
||||||
TxLockTypes.ABS_LOCK_TIME,
|
|
||||||
)
|
|
||||||
|
|
||||||
wait_for_offer(delay_event, swap_clients[1], offer_id)
|
|
||||||
offer = swap_clients[1].getOffer(offer_id)
|
|
||||||
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
|
|
||||||
|
|
||||||
wait_for_bid(delay_event, swap_clients[0], bid_id)
|
|
||||||
swap_clients[0].acceptBid(bid_id)
|
|
||||||
|
|
||||||
wait_for_in_progress(delay_event, swap_clients[1], bid_id, sent=True)
|
|
||||||
|
|
||||||
wait_for_bid(
|
|
||||||
delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60
|
|
||||||
)
|
|
||||||
wait_for_bid(
|
|
||||||
delay_event,
|
|
||||||
swap_clients[1],
|
|
||||||
bid_id,
|
|
||||||
BidStates.SWAP_COMPLETED,
|
|
||||||
sent=True,
|
|
||||||
wait_for=60,
|
|
||||||
)
|
|
||||||
|
|
||||||
js_0 = read_json_api(1800)
|
|
||||||
js_1 = read_json_api(1801)
|
|
||||||
|
|
||||||
assert js_0["num_swapping"] == 0 and js_0["num_watched_outputs"] == 0
|
|
||||||
assert js_1["num_swapping"] == 0 and js_1["num_watched_outputs"] == 0
|
|
||||||
|
|
||||||
def test_05_refund(self):
|
|
||||||
# Seller submits initiate txn, buyer doesn't respond
|
|
||||||
logging.info("---------- Test refund, NMC to BTC")
|
|
||||||
swap_clients = self.swap_clients
|
|
||||||
|
|
||||||
offer_id = swap_clients[0].postOffer(
|
|
||||||
Coins.NMC,
|
|
||||||
Coins.BTC,
|
|
||||||
10 * COIN,
|
|
||||||
0.1 * COIN,
|
|
||||||
10 * COIN,
|
|
||||||
SwapTypes.SELLER_FIRST,
|
|
||||||
TxLockTypes.ABS_LOCK_BLOCKS,
|
|
||||||
10,
|
|
||||||
)
|
|
||||||
|
|
||||||
wait_for_offer(delay_event, swap_clients[1], offer_id)
|
|
||||||
offer = swap_clients[1].getOffer(offer_id)
|
|
||||||
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
|
|
||||||
|
|
||||||
wait_for_bid(delay_event, swap_clients[0], bid_id)
|
|
||||||
swap_clients[1].abandonBid(bid_id)
|
|
||||||
swap_clients[0].acceptBid(bid_id)
|
|
||||||
|
|
||||||
wait_for_bid(
|
|
||||||
delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60
|
|
||||||
)
|
|
||||||
wait_for_bid(
|
|
||||||
delay_event,
|
|
||||||
swap_clients[1],
|
|
||||||
bid_id,
|
|
||||||
BidStates.BID_ABANDONED,
|
|
||||||
sent=True,
|
|
||||||
wait_for=60,
|
|
||||||
)
|
|
||||||
|
|
||||||
js_0 = read_json_api(1800)
|
|
||||||
js_1 = read_json_api(1801)
|
|
||||||
assert js_0["num_swapping"] == 0 and js_0["num_watched_outputs"] == 0
|
|
||||||
assert js_1["num_swapping"] == 0 and js_1["num_watched_outputs"] == 0
|
|
||||||
|
|
||||||
def test_06_self_bid(self):
|
|
||||||
logging.info("---------- Test same client, BTC to NMC")
|
|
||||||
swap_clients = self.swap_clients
|
|
||||||
|
|
||||||
js_0_before = read_json_api(1800)
|
|
||||||
|
|
||||||
offer_id = swap_clients[0].postOffer(
|
|
||||||
Coins.NMC,
|
|
||||||
Coins.BTC,
|
|
||||||
10 * COIN,
|
|
||||||
10 * COIN,
|
|
||||||
10 * COIN,
|
|
||||||
SwapTypes.SELLER_FIRST,
|
|
||||||
TxLockTypes.ABS_LOCK_TIME,
|
|
||||||
)
|
|
||||||
|
|
||||||
wait_for_offer(delay_event, swap_clients[0], offer_id)
|
|
||||||
offer = swap_clients[0].getOffer(offer_id)
|
|
||||||
bid_id = swap_clients[0].postBid(offer_id, offer.amount_from)
|
|
||||||
|
|
||||||
wait_for_bid(delay_event, swap_clients[0], bid_id)
|
|
||||||
swap_clients[0].acceptBid(bid_id)
|
|
||||||
|
|
||||||
wait_for_bid_tx_state(
|
|
||||||
delay_event,
|
|
||||||
swap_clients[0],
|
|
||||||
bid_id,
|
|
||||||
TxStates.TX_REDEEMED,
|
|
||||||
TxStates.TX_REDEEMED,
|
|
||||||
wait_for=60,
|
|
||||||
)
|
|
||||||
wait_for_bid(
|
|
||||||
delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60
|
|
||||||
)
|
|
||||||
|
|
||||||
js_0 = read_json_api(1800)
|
|
||||||
assert js_0["num_swapping"] == 0 and js_0["num_watched_outputs"] == 0
|
|
||||||
assert (
|
|
||||||
js_0["num_recv_bids"] == js_0_before["num_recv_bids"] + 1
|
|
||||||
and js_0["num_sent_bids"] == js_0_before["num_sent_bids"] + 1
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_07_error(self):
|
|
||||||
logging.info("---------- Test error, BTC to NMC, set fee above bid value")
|
|
||||||
swap_clients = self.swap_clients
|
|
||||||
|
|
||||||
offer_id = swap_clients[0].postOffer(
|
|
||||||
Coins.NMC,
|
|
||||||
Coins.BTC,
|
|
||||||
0.001 * COIN,
|
|
||||||
1.0 * COIN,
|
|
||||||
0.001 * COIN,
|
|
||||||
SwapTypes.SELLER_FIRST,
|
|
||||||
TxLockTypes.ABS_LOCK_TIME,
|
|
||||||
)
|
|
||||||
|
|
||||||
wait_for_offer(delay_event, swap_clients[0], offer_id)
|
|
||||||
offer = swap_clients[0].getOffer(offer_id)
|
|
||||||
bid_id = swap_clients[0].postBid(offer_id, offer.amount_from)
|
|
||||||
|
|
||||||
wait_for_bid(delay_event, swap_clients[0], bid_id)
|
|
||||||
swap_clients[0].acceptBid(bid_id)
|
|
||||||
try:
|
try:
|
||||||
swap_clients[0].getChainClientSettings(Coins.BTC)["override_feerate"] = 10.0
|
if cls.nmc_addr is not None:
|
||||||
swap_clients[0].getChainClientSettings(Coins.NMC)["override_feerate"] = 10.0
|
ci0.rpc_wallet("generatetoaddress", [1, cls.nmc_addr])
|
||||||
wait_for_bid(
|
except Exception as e:
|
||||||
delay_event, swap_clients[0], bid_id, BidStates.BID_ERROR, wait_for=60
|
logging.warning(f"coins_loop generate {e}")
|
||||||
)
|
|
||||||
swap_clients[0].abandonBid(bid_id)
|
|
||||||
finally:
|
|
||||||
del swap_clients[0].getChainClientSettings(Coins.BTC)["override_feerate"]
|
|
||||||
del swap_clients[0].getChainClientSettings(Coins.NMC)["override_feerate"]
|
|
||||||
|
|
||||||
def pass_99_delay(self):
|
@classmethod
|
||||||
global stop_test
|
def prepareExtraDataDir(cls, i: int) -> None:
|
||||||
logging.info("Delay")
|
if not cls.restore_instance:
|
||||||
for i in range(60 * 5):
|
prepareNMCDataDir(cfg.TEST_DATADIRS, i)
|
||||||
if stop_test:
|
|
||||||
break
|
cls.nmc_daemons.append(
|
||||||
time.sleep(1)
|
startDaemon(
|
||||||
print("delay", i)
|
os.path.join(cfg.TEST_DATADIRS, "nmc_" + str(i)),
|
||||||
stop_test = True
|
NAMECOIN_BINDIR,
|
||||||
|
NAMECOIND,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
logging.info("Started {} {}".format(NAMECOIND, cls.nmc_daemons[-1].handle.pid))
|
||||||
|
|
||||||
|
nmc_rpc = make_rpc_func(i, base_rpc_port=NMC_BASE_RPC_PORT)
|
||||||
|
waitForRPC(
|
||||||
|
nmc_rpc,
|
||||||
|
test_delay_event,
|
||||||
|
rpc_command="getnetworkinfo",
|
||||||
|
max_tries=12,
|
||||||
|
)
|
||||||
|
waitForRPC(nmc_rpc, test_delay_event, rpc_command="getblockchaininfo")
|
||||||
|
if len(nmc_rpc("listwallets")) < 1:
|
||||||
|
nmc_rpc(
|
||||||
|
"createwallet",
|
||||||
|
["wallet.dat", False, True, "", False, NMC_USE_DESCRIPTORS],
|
||||||
|
)
|
||||||
|
if NMC_USE_DESCRIPTORS:
|
||||||
|
nmc_rpc(
|
||||||
|
"createwallet",
|
||||||
|
["bsx_watch", True, True, "", False, True],
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def addPIDInfo(cls, sc, i):
|
||||||
|
sc.setDaemonPID(Coins.DCR, cls.nmc_daemons[i].handle.pid)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def addCoinSettings(cls, settings, datadir, node_id):
|
||||||
|
settings["chainclients"]["namecoin"] = {
|
||||||
|
"connection_type": "rpc",
|
||||||
|
"manage_daemon": False,
|
||||||
|
"rpcport": NMC_BASE_RPC_PORT + node_id,
|
||||||
|
"rpcuser": "test" + str(node_id),
|
||||||
|
"rpcpassword": "test_pass" + str(node_id),
|
||||||
|
"datadir": os.path.join(datadir, "nmc_" + str(node_id)),
|
||||||
|
"bindir": NAMECOIN_BINDIR,
|
||||||
|
"use_csv": True,
|
||||||
|
"use_segwit": True,
|
||||||
|
"blocks_confirmed": 1,
|
||||||
|
"use_descriptors": NMC_USE_DESCRIPTORS,
|
||||||
|
}
|
||||||
|
if NMC_USE_DESCRIPTORS:
|
||||||
|
settings["chainclients"]["namecoin"]["watch_wallet_name"] = "bsx_watch"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def prepareExtraCoins(cls):
|
||||||
|
ci0 = cls.swap_clients[0].ci(cls.test_coin)
|
||||||
|
if not cls.restore_instance:
|
||||||
|
for sc in cls.swap_clients:
|
||||||
|
ci = sc.ci(cls.test_coin)
|
||||||
|
ci.initialiseWallet(ci.getNewRandomKey())
|
||||||
|
cls.nmc_addr = ci0.rpc_wallet("getnewaddress", ["mining_addr", "bech32"])
|
||||||
|
else:
|
||||||
|
addrs = ci0.rpc_wallet(
|
||||||
|
"getaddressesbylabel",
|
||||||
|
[
|
||||||
|
"mining_addr",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
cls.nmc_addr = addrs.keys()[0]
|
||||||
|
|
||||||
|
num_blocks: int = 500
|
||||||
|
if ci0.rpc("getblockcount") < num_blocks:
|
||||||
|
logging.info(f"Mining {num_blocks} Namecoin blocks to {cls.nmc_addr}")
|
||||||
|
ci0.rpc("generatetoaddress", [num_blocks, cls.nmc_addr])
|
||||||
|
logging.info("NMC blocks: {}".format(ci0.rpc("getblockcount")))
|
||||||
|
|
||||||
|
def test_007_hdwallet(self):
|
||||||
|
logging.info("---------- Test {} hdwallet".format(self.test_coin_from.name))
|
||||||
|
|
||||||
|
test_seed = "8e54a313e6df8918df6d758fafdbf127a115175fdd2238d0e908dd8093c9ac3b"
|
||||||
|
test_wif = (
|
||||||
|
self.swap_clients[0]
|
||||||
|
.ci(self.test_coin_from)
|
||||||
|
.encodeKey(bytes.fromhex(test_seed))
|
||||||
|
)
|
||||||
|
new_wallet_name = random.randbytes(10).hex()
|
||||||
|
self.callnoderpc(
|
||||||
|
"createwallet",
|
||||||
|
[new_wallet_name, False, False, "", False, NMC_USE_DESCRIPTORS],
|
||||||
|
)
|
||||||
|
self.callnoderpc("sethdseed", [True, test_wif], wallet=new_wallet_name)
|
||||||
|
addr = self.callnoderpc(
|
||||||
|
"getnewaddress", ["add test", "bech32"], wallet=new_wallet_name
|
||||||
|
)
|
||||||
|
self.callnoderpc("unloadwallet", [new_wallet_name])
|
||||||
|
assert addr == "ncrt1qps7hnjd866e9ynxadgseprkc2l56m00dxkl7pk"
|
||||||
|
|
||||||
|
def test_012_p2sh_p2wsh(self):
|
||||||
|
# Fee rate
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_02_sh_part_coin(self):
|
||||||
|
self.prepare_balance(self.test_coin, 200.0, 1801, 1800)
|
||||||
|
run_test_success_path(self, Coins.PART, self.test_coin)
|
||||||
|
|
||||||
|
def test_03_sh_coin_part(self):
|
||||||
|
run_test_success_path(self, self.test_coin, Coins.PART)
|
||||||
|
|
||||||
|
def test_04_sh_part_coin_bad_ptx(self):
|
||||||
|
self.prepare_balance(self.test_coin, 200.0, 1801, 1800)
|
||||||
|
run_test_bad_ptx(self, Coins.PART, self.test_coin)
|
||||||
|
|
||||||
|
def test_05_sh_coin_part_bad_ptx(self):
|
||||||
|
self.prepare_balance(self.test_coin, 200.0, 1801, 1800)
|
||||||
|
run_test_bad_ptx(self, self.test_coin, Coins.PART)
|
||||||
|
|
||||||
|
def test_06_sh_part_coin_itx_refund(self):
|
||||||
|
run_test_itx_refund(self, Coins.PART, self.test_coin)
|
||||||
|
|
||||||
|
def test_07_sh_coin_part_itx_refund(self):
|
||||||
|
self.prepare_balance(self.test_coin, 200.0, 1801, 1800)
|
||||||
|
run_test_itx_refund(self, self.test_coin, Coins.PART)
|
||||||
|
|
||||||
|
def test_01_b_full_swap_reverse(self):
|
||||||
|
self.prepare_balance(self.test_coin, 100.0, 1801, 1800)
|
||||||
|
self.do_test_01_full_swap(Coins.XMR, self.test_coin_from)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ from tests.basicswap.common_xmr import (
|
|||||||
prepare_nodes,
|
prepare_nodes,
|
||||||
XMR_BASE_RPC_PORT,
|
XMR_BASE_RPC_PORT,
|
||||||
DOGE_BASE_RPC_PORT,
|
DOGE_BASE_RPC_PORT,
|
||||||
|
NMC_BASE_RPC_PORT,
|
||||||
)
|
)
|
||||||
from basicswap.interface.dcr.rpc import callrpc as callrpc_dcr
|
from basicswap.interface.dcr.rpc import callrpc as callrpc_dcr
|
||||||
import basicswap.bin.run as runSystem
|
import basicswap.bin.run as runSystem
|
||||||
@@ -73,12 +74,13 @@ UI_PORT = 12700 + PORT_OFS
|
|||||||
PARTICL_RPC_PORT_BASE = int(os.getenv("PARTICL_RPC_PORT_BASE", BASE_RPC_PORT))
|
PARTICL_RPC_PORT_BASE = int(os.getenv("PARTICL_RPC_PORT_BASE", BASE_RPC_PORT))
|
||||||
BITCOIN_RPC_PORT_BASE = int(os.getenv("BITCOIN_RPC_PORT_BASE", BTC_BASE_RPC_PORT))
|
BITCOIN_RPC_PORT_BASE = int(os.getenv("BITCOIN_RPC_PORT_BASE", BTC_BASE_RPC_PORT))
|
||||||
LITECOIN_RPC_PORT_BASE = int(os.getenv("LITECOIN_RPC_PORT_BASE", LTC_BASE_RPC_PORT))
|
LITECOIN_RPC_PORT_BASE = int(os.getenv("LITECOIN_RPC_PORT_BASE", LTC_BASE_RPC_PORT))
|
||||||
DOGECOIN_RPC_PORT_BASE = int(os.getenv("DOGECOIN_RPC_PORT_BASE", DOGE_BASE_RPC_PORT))
|
DECRED_WALLET_RPC_PORT_BASE = int(os.getenv("DECRED_WALLET_RPC_PORT_BASE", 9210))
|
||||||
|
NAMECOIN_RPC_PORT_BASE = int(os.getenv("NAMECOIN_RPC_PORT_BASE", NMC_BASE_RPC_PORT))
|
||||||
|
XMR_BASE_RPC_PORT = int(os.getenv("XMR_BASE_RPC_PORT", XMR_BASE_RPC_PORT))
|
||||||
BITCOINCASH_RPC_PORT_BASE = int(
|
BITCOINCASH_RPC_PORT_BASE = int(
|
||||||
os.getenv("BITCOINCASH_RPC_PORT_BASE", BCH_BASE_RPC_PORT)
|
os.getenv("BITCOINCASH_RPC_PORT_BASE", BCH_BASE_RPC_PORT)
|
||||||
)
|
)
|
||||||
DECRED_WALLET_RPC_PORT_BASE = int(os.getenv("DECRED_WALLET_RPC_PORT_BASE", 9210))
|
DOGECOIN_RPC_PORT_BASE = int(os.getenv("DOGECOIN_RPC_PORT_BASE", DOGE_BASE_RPC_PORT))
|
||||||
XMR_BASE_RPC_PORT = int(os.getenv("XMR_BASE_RPC_PORT", XMR_BASE_RPC_PORT))
|
|
||||||
TEST_COINS_LIST = os.getenv("TEST_COINS_LIST", "bitcoin,monero")
|
TEST_COINS_LIST = os.getenv("TEST_COINS_LIST", "bitcoin,monero")
|
||||||
|
|
||||||
NUM_NODES = int(os.getenv("NUM_NODES", 3))
|
NUM_NODES = int(os.getenv("NUM_NODES", 3))
|
||||||
@@ -130,6 +132,17 @@ def calldcrrpc(
|
|||||||
return callrpc_dcr(base_rpc_port + node_id, auth, method, params)
|
return callrpc_dcr(base_rpc_port + node_id, auth, method, params)
|
||||||
|
|
||||||
|
|
||||||
|
def callnmcrpc(
|
||||||
|
node_id,
|
||||||
|
method,
|
||||||
|
params=[],
|
||||||
|
wallet="wallet.dat",
|
||||||
|
base_rpc_port=NAMECOIN_RPC_PORT_BASE + PORT_OFS,
|
||||||
|
):
|
||||||
|
auth = "test_nmc_{0}:test_nmc_pwd_{0}".format(node_id)
|
||||||
|
return callrpc(base_rpc_port + node_id, auth, method, params, wallet)
|
||||||
|
|
||||||
|
|
||||||
def callbchrpc(
|
def callbchrpc(
|
||||||
node_id,
|
node_id,
|
||||||
method,
|
method,
|
||||||
@@ -163,6 +176,8 @@ def updateThread(cls):
|
|||||||
callbchrpc(0, "generatetoaddress", [1, cls.bch_addr])
|
callbchrpc(0, "generatetoaddress", [1, cls.bch_addr])
|
||||||
if cls.doge_addr is not None:
|
if cls.doge_addr is not None:
|
||||||
calldogerpc(0, "generatetoaddress", [1, cls.doge_addr])
|
calldogerpc(0, "generatetoaddress", [1, cls.doge_addr])
|
||||||
|
if cls.nmc_addr is not None:
|
||||||
|
callnmcrpc(0, "generatetoaddress", [1, cls.nmc_addr])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("updateThread error", str(e))
|
print("updateThread error", str(e))
|
||||||
cls.delay_event.wait(random.randrange(cls.update_min, cls.update_max))
|
cls.delay_event.wait(random.randrange(cls.update_min, cls.update_max))
|
||||||
@@ -388,6 +403,18 @@ def start_processes(self):
|
|||||||
0, "generatetoaddress", [num_blocks - have_blocks, self.doge_addr]
|
0, "generatetoaddress", [num_blocks - have_blocks, self.doge_addr]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if "namecoin" in TEST_COINS_LIST:
|
||||||
|
self.nmc_addr = callnmcrpc(0, "getnewaddress", ["mining_addr", "bech32"])
|
||||||
|
num_blocks: int = 500
|
||||||
|
have_blocks: int = callnmcrpc(0, "getblockcount")
|
||||||
|
if have_blocks < num_blocks:
|
||||||
|
logging.info(
|
||||||
|
f"Mining {num_blocks - have_blocks} Namecoin blocks to {self.nmc_addr}"
|
||||||
|
)
|
||||||
|
callnmcrpc(
|
||||||
|
0, "generatetoaddress", [num_blocks - have_blocks, self.nmc_addr]
|
||||||
|
)
|
||||||
|
|
||||||
if RESET_TEST:
|
if RESET_TEST:
|
||||||
# Lower output split threshold for more stakeable outputs
|
# Lower output split threshold for more stakeable outputs
|
||||||
for i in range(NUM_NODES):
|
for i in range(NUM_NODES):
|
||||||
@@ -444,6 +471,7 @@ class BaseTestWithPrepare(unittest.TestCase):
|
|||||||
dcr_addr = "SsYbXyjkKAEXXcGdFgr4u4bo4L8RkCxwQpH"
|
dcr_addr = "SsYbXyjkKAEXXcGdFgr4u4bo4L8RkCxwQpH"
|
||||||
dcr_acc = None
|
dcr_acc = None
|
||||||
doge_addr = None
|
doge_addr = None
|
||||||
|
nmc_addr = None
|
||||||
|
|
||||||
initialised = False
|
initialised = False
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ from basicswap.db import (
|
|||||||
from basicswap.util import (
|
from basicswap.util import (
|
||||||
make_int,
|
make_int,
|
||||||
)
|
)
|
||||||
|
from basicswap.util.address import (
|
||||||
|
decodeAddress,
|
||||||
|
)
|
||||||
from basicswap.util.extkey import ExtKeyPair
|
from basicswap.util.extkey import ExtKeyPair
|
||||||
from basicswap.interface.base import Curves
|
from basicswap.interface.base import Curves
|
||||||
from tests.basicswap.util import (
|
from tests.basicswap.util import (
|
||||||
@@ -59,7 +62,6 @@ from basicswap.contrib.test_framework.script import (
|
|||||||
from .test_xmr import BaseTest, test_delay_event, callnoderpc
|
from .test_xmr import BaseTest, test_delay_event, callnoderpc
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
test_seed = "8e54a313e6df8918df6d758fafdbf127a115175fdd2238d0e908dd8093c9ac3b"
|
test_seed = "8e54a313e6df8918df6d758fafdbf127a115175fdd2238d0e908dd8093c9ac3b"
|
||||||
|
|
||||||
|
|
||||||
@@ -183,7 +185,7 @@ class TestFunctions(BaseTest):
|
|||||||
bid0 = read_json_api(1800 + id_offerer, f"bids/{bid_id.hex()}")
|
bid0 = read_json_api(1800 + id_offerer, f"bids/{bid_id.hex()}")
|
||||||
bid1 = read_json_api(1800 + id_bidder, f"bids/{bid_id.hex()}")
|
bid1 = read_json_api(1800 + id_bidder, f"bids/{bid_id.hex()}")
|
||||||
|
|
||||||
tolerance = 1
|
tolerance = 2
|
||||||
assert bid0["ticker_from"] == ci_from.ticker()
|
assert bid0["ticker_from"] == ci_from.ticker()
|
||||||
assert bid1["ticker_from"] == ci_from.ticker()
|
assert bid1["ticker_from"] == ci_from.ticker()
|
||||||
assert bid0["ticker_to"] == ci_to.ticker()
|
assert bid0["ticker_to"] == ci_to.ticker()
|
||||||
@@ -666,7 +668,7 @@ class TestFunctions(BaseTest):
|
|||||||
balance_from_before: float = self.getBalance(jsw, coin_from)
|
balance_from_before: float = self.getBalance(jsw, coin_from)
|
||||||
self.prepare_balance(
|
self.prepare_balance(
|
||||||
coin_to,
|
coin_to,
|
||||||
balance_from_before + 1,
|
balance_from_before * 3,
|
||||||
1800 + id_bidder,
|
1800 + id_bidder,
|
||||||
1801 if coin_to in (Coins.XMR,) else 1800,
|
1801 if coin_to in (Coins.XMR,) else 1800,
|
||||||
)
|
)
|
||||||
@@ -718,6 +720,7 @@ class TestFunctions(BaseTest):
|
|||||||
assert False, "Should fail"
|
assert False, "Should fail"
|
||||||
|
|
||||||
amt_swap -= ci_from.make_int(1)
|
amt_swap -= ci_from.make_int(1)
|
||||||
|
rate_swap = ci_to.make_int(1.0, r=1)
|
||||||
offer_id = swap_clients[id_offerer].postOffer(
|
offer_id = swap_clients[id_offerer].postOffer(
|
||||||
coin_from,
|
coin_from,
|
||||||
coin_to,
|
coin_to,
|
||||||
@@ -770,6 +773,8 @@ class TestFunctions(BaseTest):
|
|||||||
|
|
||||||
class BasicSwapTest(TestFunctions):
|
class BasicSwapTest(TestFunctions):
|
||||||
|
|
||||||
|
test_fee_rate: int = 1000 # sats/kvB
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
super(BasicSwapTest, cls).setUpClass()
|
super(BasicSwapTest, cls).setUpClass()
|
||||||
@@ -1178,6 +1183,10 @@ class BasicSwapTest(TestFunctions):
|
|||||||
logging.info("---------- Test {} hdwallet".format(self.test_coin_from.name))
|
logging.info("---------- Test {} hdwallet".format(self.test_coin_from.name))
|
||||||
ci = self.swap_clients[0].ci(self.test_coin_from)
|
ci = self.swap_clients[0].ci(self.test_coin_from)
|
||||||
|
|
||||||
|
if hasattr(ci, "_use_descriptors") and ci._use_descriptors:
|
||||||
|
logging.warning("Skipping test")
|
||||||
|
return
|
||||||
|
|
||||||
test_wif = (
|
test_wif = (
|
||||||
self.swap_clients[0]
|
self.swap_clients[0]
|
||||||
.ci(self.test_coin_from)
|
.ci(self.test_coin_from)
|
||||||
@@ -1236,12 +1245,7 @@ class BasicSwapTest(TestFunctions):
|
|||||||
swap_client = self.swap_clients[0]
|
swap_client = self.swap_clients[0]
|
||||||
ci = swap_client.ci(self.test_coin_from)
|
ci = swap_client.ci(self.test_coin_from)
|
||||||
|
|
||||||
addr_1 = ci.rpc_wallet(
|
addr_1 = ci.getNewAddress(True, "gettxout test 1")
|
||||||
"getnewaddress",
|
|
||||||
[
|
|
||||||
"gettxout test 1",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
txid = ci.rpc_wallet("sendtoaddress", [addr_1, 1.0])
|
txid = ci.rpc_wallet("sendtoaddress", [addr_1, 1.0])
|
||||||
assert len(txid) == 64
|
assert len(txid) == 64
|
||||||
|
|
||||||
@@ -1266,12 +1270,7 @@ class BasicSwapTest(TestFunctions):
|
|||||||
else:
|
else:
|
||||||
assert addr_1 in txout["scriptPubKey"]["addresses"]
|
assert addr_1 in txout["scriptPubKey"]["addresses"]
|
||||||
# Spend
|
# Spend
|
||||||
addr_2 = ci.rpc_wallet(
|
addr_2 = ci.getNewAddress(True, "gettxout test 2")
|
||||||
"getnewaddress",
|
|
||||||
[
|
|
||||||
"gettxout test 2",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
tx_funded = ci.rpc(
|
tx_funded = ci.rpc(
|
||||||
"createrawtransaction",
|
"createrawtransaction",
|
||||||
[[{"txid": utxo["txid"], "vout": utxo["vout"]}], {addr_2: 0.99}],
|
[[{"txid": utxo["txid"], "vout": utxo["vout"]}], {addr_2: 0.99}],
|
||||||
@@ -1297,12 +1296,7 @@ class BasicSwapTest(TestFunctions):
|
|||||||
logging.info("---------- Test {} scantxoutset".format(self.test_coin_from.name))
|
logging.info("---------- Test {} scantxoutset".format(self.test_coin_from.name))
|
||||||
ci = self.swap_clients[0].ci(self.test_coin_from)
|
ci = self.swap_clients[0].ci(self.test_coin_from)
|
||||||
|
|
||||||
addr_1 = ci.rpc_wallet(
|
addr_1 = ci.getNewAddress(True, "scantxoutset test")
|
||||||
"getnewaddress",
|
|
||||||
[
|
|
||||||
"scantxoutset test",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
txid = ci.rpc_wallet("sendtoaddress", [addr_1, 1.0])
|
txid = ci.rpc_wallet("sendtoaddress", [addr_1, 1.0])
|
||||||
assert len(txid) == 64
|
assert len(txid) == 64
|
||||||
|
|
||||||
@@ -1323,10 +1317,7 @@ class BasicSwapTest(TestFunctions):
|
|||||||
|
|
||||||
# Record unspents before createSCLockTx as the used ones will be locked
|
# Record unspents before createSCLockTx as the used ones will be locked
|
||||||
unspents = ci.rpc_wallet("listunspent")
|
unspents = ci.rpc_wallet("listunspent")
|
||||||
|
lockedunspents_before = ci.rpc_wallet("listlockunspent")
|
||||||
# fee_rate is in sats/kvB
|
|
||||||
fee_rate: int = 1000
|
|
||||||
|
|
||||||
a = ci.getNewRandomKey()
|
a = ci.getNewRandomKey()
|
||||||
b = ci.getNewRandomKey()
|
b = ci.getNewRandomKey()
|
||||||
|
|
||||||
@@ -1335,17 +1326,26 @@ class BasicSwapTest(TestFunctions):
|
|||||||
lock_tx_script = pi.genScriptLockTxScript(ci, A, B)
|
lock_tx_script = pi.genScriptLockTxScript(ci, A, B)
|
||||||
|
|
||||||
lock_tx = ci.createSCLockTx(amount, lock_tx_script)
|
lock_tx = ci.createSCLockTx(amount, lock_tx_script)
|
||||||
lock_tx = ci.fundSCLockTx(lock_tx, fee_rate)
|
lock_tx = ci.fundSCLockTx(lock_tx, self.test_fee_rate)
|
||||||
lock_tx = ci.signTxWithWallet(lock_tx)
|
lock_tx = ci.signTxWithWallet(lock_tx)
|
||||||
|
|
||||||
|
# Check that inputs were locked
|
||||||
|
lockedunspents = ci.rpc_wallet("listlockunspent")
|
||||||
|
assert len(lockedunspents) > len(lockedunspents_before)
|
||||||
unspents_after = ci.rpc_wallet("listunspent")
|
unspents_after = ci.rpc_wallet("listunspent")
|
||||||
assert len(unspents) > len(unspents_after)
|
for utxo in unspents_after:
|
||||||
|
for locked_utxo in lockedunspents:
|
||||||
|
if (
|
||||||
|
locked_utxo["txid"] == utxo["txid"]
|
||||||
|
and locked_utxo["vout"] == utxo["vout"]
|
||||||
|
):
|
||||||
|
raise ValueError("Locked utxo in listunspent")
|
||||||
|
|
||||||
tx_decoded = ci.rpc("decoderawtransaction", [lock_tx.hex()])
|
tx_decoded = ci.rpc("decoderawtransaction", [lock_tx.hex()])
|
||||||
txid = tx_decoded["txid"]
|
txid = tx_decoded["txid"]
|
||||||
|
|
||||||
vsize = tx_decoded["vsize"]
|
vsize = tx_decoded["vsize"]
|
||||||
expect_fee_int = round(fee_rate * vsize / 1000)
|
expect_fee_int = round(self.test_fee_rate * vsize / 1000)
|
||||||
|
|
||||||
out_value: int = 0
|
out_value: int = 0
|
||||||
for txo in tx_decoded["vout"]:
|
for txo in tx_decoded["vout"]:
|
||||||
@@ -1372,7 +1372,7 @@ class BasicSwapTest(TestFunctions):
|
|||||||
pkh_out = ci.decodeAddress(addr_out)
|
pkh_out = ci.decodeAddress(addr_out)
|
||||||
fee_info = {}
|
fee_info = {}
|
||||||
lock_spend_tx = ci.createSCLockSpendTx(
|
lock_spend_tx = ci.createSCLockSpendTx(
|
||||||
lock_tx, lock_tx_script, pkh_out, fee_rate, fee_info=fee_info
|
lock_tx, lock_tx_script, pkh_out, self.test_fee_rate, fee_info=fee_info
|
||||||
)
|
)
|
||||||
vsize_estimated: int = fee_info["vsize"]
|
vsize_estimated: int = fee_info["vsize"]
|
||||||
|
|
||||||
@@ -1400,11 +1400,11 @@ class BasicSwapTest(TestFunctions):
|
|||||||
v = ci.getNewRandomKey()
|
v = ci.getNewRandomKey()
|
||||||
s = ci.getNewRandomKey()
|
s = ci.getNewRandomKey()
|
||||||
S = ci.getPubkey(s)
|
S = ci.getPubkey(s)
|
||||||
lock_tx_b_txid = ci.publishBLockTx(v, S, amount, fee_rate)
|
lock_tx_b_txid = ci.publishBLockTx(v, S, amount, self.test_fee_rate)
|
||||||
|
|
||||||
addr_out = ci.getNewAddress(True)
|
addr_out = ci.getNewAddress(True)
|
||||||
lock_tx_b_spend_txid = ci.spendBLockTx(
|
lock_tx_b_spend_txid = ci.spendBLockTx(
|
||||||
lock_tx_b_txid, addr_out, v, s, amount, fee_rate, 0
|
lock_tx_b_txid, addr_out, v, s, amount, self.test_fee_rate, 0
|
||||||
)
|
)
|
||||||
lock_tx_b_spend = ci.getTransaction(lock_tx_b_spend_txid)
|
lock_tx_b_spend = ci.getTransaction(lock_tx_b_spend_txid)
|
||||||
if lock_tx_b_spend is None:
|
if lock_tx_b_spend is None:
|
||||||
@@ -1635,7 +1635,9 @@ class BasicSwapTest(TestFunctions):
|
|||||||
wallet=new_wallet_name,
|
wallet=new_wallet_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
addr = self.callnoderpc("getnewaddress", wallet=new_wallet_name)
|
addr = self.callnoderpc(
|
||||||
|
"getnewaddress", ["test descriptors"], wallet=new_wallet_name
|
||||||
|
)
|
||||||
addr_info = self.callnoderpc(
|
addr_info = self.callnoderpc(
|
||||||
"getaddressinfo",
|
"getaddressinfo",
|
||||||
[
|
[
|
||||||
@@ -1645,6 +1647,7 @@ class BasicSwapTest(TestFunctions):
|
|||||||
)
|
)
|
||||||
assert addr_info["hdmasterfingerprint"] == "a55b7ea9"
|
assert addr_info["hdmasterfingerprint"] == "a55b7ea9"
|
||||||
assert addr_info["hdkeypath"] == "m/0h/0h/0h"
|
assert addr_info["hdkeypath"] == "m/0h/0h/0h"
|
||||||
|
if self.test_coin_from == Coins.BTC:
|
||||||
assert addr == "bcrt1qps7hnjd866e9ynxadgseprkc2l56m00dvwargr"
|
assert addr == "bcrt1qps7hnjd866e9ynxadgseprkc2l56m00dvwargr"
|
||||||
|
|
||||||
addr_change = self.callnoderpc("getrawchangeaddress", wallet=new_wallet_name)
|
addr_change = self.callnoderpc("getrawchangeaddress", wallet=new_wallet_name)
|
||||||
@@ -1657,6 +1660,7 @@ class BasicSwapTest(TestFunctions):
|
|||||||
)
|
)
|
||||||
assert addr_info["hdmasterfingerprint"] == "a55b7ea9"
|
assert addr_info["hdmasterfingerprint"] == "a55b7ea9"
|
||||||
assert addr_info["hdkeypath"] == "m/0h/1h/0h"
|
assert addr_info["hdkeypath"] == "m/0h/1h/0h"
|
||||||
|
if self.test_coin_from == Coins.BTC:
|
||||||
assert addr_change == "bcrt1qdl9ryxkqjltv42lhfnqgdjf9tagxsjpp2xak9a"
|
assert addr_change == "bcrt1qdl9ryxkqjltv42lhfnqgdjf9tagxsjpp2xak9a"
|
||||||
|
|
||||||
desc_watch = descsum_create(f"addr({addr})")
|
desc_watch = descsum_create(f"addr({addr})")
|
||||||
@@ -1683,7 +1687,56 @@ class BasicSwapTest(TestFunctions):
|
|||||||
|
|
||||||
# Test that addresses can be generated beyond range in listdescriptors
|
# Test that addresses can be generated beyond range in listdescriptors
|
||||||
for i in range(2000):
|
for i in range(2000):
|
||||||
self.callnoderpc("getnewaddress", wallet=new_wallet_name)
|
self.callnoderpc(
|
||||||
|
"getnewaddress",
|
||||||
|
[
|
||||||
|
f"t{i}",
|
||||||
|
],
|
||||||
|
wallet=new_wallet_name,
|
||||||
|
)
|
||||||
|
|
||||||
|
# https://github.com/bitcoin/bitcoin/issues/10542
|
||||||
|
# https://github.com/bitcoin/bitcoin/issues/26046
|
||||||
|
sign_for_address: str = self.callnoderpc(
|
||||||
|
"getnewaddress",
|
||||||
|
[
|
||||||
|
"sign address",
|
||||||
|
],
|
||||||
|
wallet=new_wallet_name,
|
||||||
|
)
|
||||||
|
priv_keys = self.callnoderpc("listdescriptors", [True], wallet=new_wallet_name)
|
||||||
|
addr_info = self.callnoderpc(
|
||||||
|
"getaddressinfo", [sign_for_address], wallet=new_wallet_name
|
||||||
|
)
|
||||||
|
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.swap_clients[0].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)
|
||||||
|
addr = ci.encodeSegwitAddress(ci.getAddressHashFromKey(ek._key))
|
||||||
|
assert addr == sign_for_address
|
||||||
|
sign_for_address_key = ci.encodeKey(ek._key)
|
||||||
|
break
|
||||||
|
assert sign_for_address_key is not None
|
||||||
|
sign_message: str = "Would be better if dumpprivkey or signmessage worked"
|
||||||
|
sig = self.callnoderpc(
|
||||||
|
"signmessagewithprivkey",
|
||||||
|
[sign_for_address_key, sign_message],
|
||||||
|
wallet=new_wallet_name,
|
||||||
|
)
|
||||||
|
assert ci.verifyMessage(sign_for_address, sign_message, sig)
|
||||||
|
|
||||||
self.callnoderpc("unloadwallet", [new_wallet_name])
|
self.callnoderpc("unloadwallet", [new_wallet_name])
|
||||||
self.callnoderpc("unloadwallet", [new_watch_wallet_name])
|
self.callnoderpc("unloadwallet", [new_watch_wallet_name])
|
||||||
|
|||||||
Reference in New Issue
Block a user