nmc: Use descriptor wallets by default.

This commit is contained in:
tecnovert
2025-03-30 00:32:08 +02:00
parent f263bb53c3
commit e9ed334a54
6 changed files with 152 additions and 71 deletions

View File

@@ -379,6 +379,12 @@ def getWalletName(coin_params: str, default_name: str, prefix_override=None) ->
return wallet_name
def getDescriptorWalletOption(coin_params):
ticker: str = coin_params["ticker"]
default_option: bool = True if ticker in ("NMC",) else False
return toBool(os.getenv(ticker + "_USE_DESCRIPTORS", default_option))
def getKnownVersion(coin_name: str) -> str:
version, version_tag, _ = known_coins[coin_name]
return version + version_tag
@@ -1928,11 +1934,15 @@ def initialise_wallets(
],
)
if use_descriptors:
watch_wallet_name = coin_settings["watch_wallet_name"]
logger.info(
f'Creating wallet "{watch_wallet_name}" for {getCoinName(c)}.'
)
swap_client.callcoinrpc(
c,
"createwallet",
[
coin_settings["watch_wallet_name"],
watch_wallet_name,
True,
True,
"",
@@ -2596,9 +2606,8 @@ def main():
coin_settings["wallet_name"] = set_name
ticker: str = coin_params["ticker"]
if toBool(os.getenv(ticker + "_USE_DESCRIPTORS", False)):
if coin_id not in (Coins.BTC,):
if getDescriptorWalletOption(coin_params):
if coin_id not in (Coins.BTC, Coins.NMC):
raise ValueError(f"Descriptor wallet unavailable for {coin_name}")
coin_settings["use_descriptors"] = True

View File

@@ -58,6 +58,8 @@ chainparams = {
"bip44": 44,
"min_amount": 100000,
"max_amount": 10000000 * COIN,
"ext_public_key_prefix": 0x696E82D1,
"ext_secret_key_prefix": 0x8F1DAEB8,
},
"testnet": {
"rpcport": 51935,
@@ -69,6 +71,8 @@ chainparams = {
"bip44": 1,
"min_amount": 100000,
"max_amount": 10000000 * COIN,
"ext_public_key_prefix": 0xE1427800,
"ext_secret_key_prefix": 0x04889478,
},
"regtest": {
"rpcport": 51936,
@@ -80,6 +84,8 @@ chainparams = {
"bip44": 1,
"min_amount": 100000,
"max_amount": 10000000 * COIN,
"ext_public_key_prefix": 0xE1427800,
"ext_secret_key_prefix": 0x04889478,
},
},
Coins.BTC: {

View File

@@ -1862,20 +1862,70 @@ class BTCInterface(Secp256k1Interface):
"Could not find address with enough funds for proof",
)
self._log.debug("sign_for_addr %s", sign_for_addr)
self._log.debug(f"sign_for_addr {sign_for_addr}")
funds_addr: str = sign_for_addr
if (
self.using_segwit()
): # TODO: Use isSegwitAddress when scantxoutset can use combo
# 'Address does not refer to key' for non p2pkh
pkh = self.decodeAddress(sign_for_addr)
sign_for_addr = self.pkh_to_address(pkh)
self._log.debug("sign_for_addr converted %s", sign_for_addr)
self._log.debug(f"sign_for_addr converted {sign_for_addr}")
signature = self.rpc_wallet(
"signmessage",
[sign_for_addr, sign_for_addr + "_swap_proof_" + extra_commit_bytes.hex()],
)
if self._use_descriptors:
# https://github.com/bitcoin/bitcoin/issues/10542
# https://github.com/bitcoin/bitcoin/issues/26046
priv_keys = self.rpc_wallet(
"listdescriptors",
[
True,
],
)
addr_info = self.rpc_wallet(
"getaddressinfo",
[
funds_addr,
],
)
hdkeypath = addr_info["hdkeypath"]
sign_for_address_key = None
for descriptor in priv_keys["descriptors"]:
if descriptor["active"] is False or descriptor["internal"] is True:
continue
desc = descriptor["desc"]
assert desc.startswith("wpkh(")
ext_key = desc[5:].split(")")[0].split("/", 1)[0]
ext_key_data = decodeAddress(ext_key)[4:]
ci_part = self._sc.ci(Coins.PART)
ext_key_data_part = ci_part.encode_secret_extkey(ext_key_data)
rv = ci_part.rpc_wallet(
"extkey", ["info", ext_key_data_part, hdkeypath]
)
extkey_derived = rv["key_info"]["result"]
ext_key_data = decodeAddress(extkey_derived)[4:]
ek = ExtKeyPair()
ek.decode(ext_key_data)
sign_for_address_key = self.encodeKey(ek._key)
break
assert sign_for_address_key is not None
signature = self.rpc(
"signmessagewithprivkey",
[
sign_for_address_key,
sign_for_addr + "_swap_proof_" + extra_commit_bytes.hex(),
],
)
del priv_keys
else:
signature = self.rpc_wallet(
"signmessage",
[
sign_for_addr,
sign_for_addr + "_swap_proof_" + extra_commit_bytes.hex(),
],
)
prove_utxos = [] # TODO: Send specific utxos
return (sign_for_addr, signature, prove_utxos)

View File

@@ -14,57 +14,3 @@ class NMCInterface(BTCInterface):
@staticmethod
def coin_type():
return Coins.NMC
def lockNonSegwitPrevouts(self) -> None:
# For tests
# NMC Seems to ignore utxo locks
unspent = self.rpc_wallet("listunspent")
to_lock = []
for u in unspent:
if u.get("spendable", False) is False:
continue
if "desc" in u:
desc = u["desc"]
if self.use_p2shp2wsh():
if not desc.startswith("sh(wpkh"):
to_lock.append(
{
"txid": u["txid"],
"vout": u["vout"],
"amount": u["amount"],
}
)
else:
if not desc.startswith("wpkh"):
to_lock.append(
{
"txid": u["txid"],
"vout": u["vout"],
"amount": u["amount"],
}
)
if len(to_lock) > 0:
self._log.debug(f"Spending {len(to_lock)} non segwit prevouts")
addr_out = self.rpc_wallet(
"getnewaddress", ["convert non segwit", "bech32"]
)
prevouts = []
sum_amount: int = 0
for utxo in to_lock:
prevouts.append(
{
"txid": utxo["txid"],
"vout": utxo["vout"],
}
)
sum_amount += self.make_int(utxo["amount"])
fee = 100000 * len(prevouts)
funded_tx = self.rpc(
"createrawtransaction",
[prevouts, {addr_out: self.format_amount(sum_amount - fee)}],
)
signed_tx = self.rpc_wallet("signrawtransactionwithwallet", [funded_tx])
self.rpc("sendrawtransaction", [signed_tx["hex"]])