diff --git a/README.md b/README.md index c5ab30b5..7e36b5d6 100644 --- a/README.md +++ b/README.md @@ -487,32 +487,93 @@ The arguments are the private key of the sender, the receiver's address and the * privtopub : (privkey) -> pubkey * pubtoaddr : (pubkey) -> address -* privtoaddr : (privkey) -> address +* privtoaddr : (privkey) -> Convert a wif encoded private key to correct address, if not wif encoded then p2pkh +* privtop2pkh : (privkey) -> p2pkh address * encode_privkey : (privkey, format, script_type="p2pkh") -> privkey * sign : (txobj, i, privkey) -> create digital signature of tx with privkey and add to input i * signall : (txobj, privkey) -> create digital signature of tx with privkey for all inputs -* history : (address, merkle_proof=False) -> tx history and balance of an address +* history : (address, merkle_proof=False) -> tx history of an address +* get_histories : (*addresses, merkle_proof=False) -> tx histories of an address * unspent : (address, merkle_proof=False) -> unspent outputs for an addresses -* pushtx : (hex or bin tx) -> push a transaction to the blockchain -* get_tx : (txhash) -> fetch a tx from the blockchain +* get_unspents : (addresses, merkle_proof=False) -> unspent outputs for multiple addresses +* pushtx : (hex or tx object) -> push a transaction to the blockchain +* get_raw_tx : (txid) -> Get the raw hex of a transaction id +* get_tx : (txid) -> fetch a tx from the blockchain +* get_verbose_tx : (txid) -> Transaction details verbose output +* get_txs : (*txids) -> Fetch multiple transaction details +* calculate_fee : (Tx) -> Calculate the fee of a transaction * send : (privkey, frm, to, value, change_addr=None, fee=None, estimate_fee_blocks: int = 6) -> create and a push a simple transaction to send coins to an address and return change to the change address or sender * send_to_multiple_receivers_tx : (privkey, addr outs:value pairs, change_addr=None,fee=10000,, estimate_fee_blocks: int = 6) -> create and a push a transaction to send coins to multiple addresses and return change to the change address or sender * preparetx : (frm, to, value, fee, estimate_fee_blocks: int = 6,change_addr=None): -> create unsigned txobj with change output * preparemultitx : (frm, outs:value pairs, change_addr=None, fee=None, estimate_fee_blocks: int = 6): -> create unsigned txobj with multiple outputs and additional change output * preparesignedtx : (privkey, frm, to, value, change_addr=None, fee=10000, estimate_fee_blocks: int = 6) -> create signed txobj with change output * preparesignedmultirecipienttx : (privkey, frm, outs: value pairs, change_addr=None, fee=10000, estimate_fee_blocks: int = 6) -> create signed txobj with multiple outputs and additional change output -* mktx : (inputs, outputs, locktime=0, sequence=0xFFFFFFFF) -> create unsigned txobj +* mktx : (inputs, outputs, locktifme=0, sequence=0xFFFFFFFF) -> create unsigned txobj * mktx_with_change : (inputs, outputs, change_addr=None, fee=None, estimate_fee_blocks=6, locktime=0, sequence=0xFFFFFFFF) -> create unsigned txobj -* mk_multisig_address : (pubkeys, M) -> Returns both M-of-N multsig script and address pubkeys +* mk_multisig_address : (pubkeys, M) -> Returns both M-of-N multisig script and address +* multisign : (txobj, i, script, privkey) -> signature +* apply_multisignatures: (txobj, i, script, sigs) -> tx with index i signed with sigs +* mk_multsig_segwit_address : (pubkeys, M)- Returns both M-of-N multisig script and native segwit address +* mk_multsig_cash_address: (pubkeys, M)- Returns both M-of-N multisig script and Bitcoin Cash address * pubtop2w : (pub) -> pay to witness script hash (segwit address) * privtop2w : (priv) -> pay to witness script hash (segwit address) +* pubtop2wpkh_p2sh : (pub) -> Convert a public key to a segwit address encoded in a p2sh script +* privtop2wpkh_p2sh : (priv) -> Convert a private key to a segwit address encoded in a p2sh script +* hash_to_segwit_addr : (hash) -. Convert a public key hash to a native segwit address +* scripthash_to_segwit_addr: (hash) -> Convert the hash of a p2sh script to a native segwit address * is_address : (addr) -> true if addr is a valid address for this network +* is_p2pkh : (address) -> Return true if an address is in p2pkh format * is_p2sh : (addr) -> true if addr is a pay to script hash for this network * is_segwit : (priv, addr) -> true if priv-addr pair represent a pay to witness script hash +* is_cash_or_legacy_p2pkh_address : (address) -> Returns true if an address is a legacy p2pkh address or a Bitcoin Cash formatted p2pkh address +* is_native_segwit : (address) -> Returns true if an address is of native segwit type +* is_cash_address : (address) -> Returns true if an address is of Bitcoin Cash address format +* maybe_legacy_segwit : (address) -> Returns true if address is likely a legacy segwit p2sh address +* is_p2wsh : (address) -> Returns true is address is a Pay To Witness Script Address +* is_segwit_or_p2sh : (address) -> Returns true if an address is a Pay to Witness or Pay to Script address * current_block_height : () -> Latest block height * block_height : (txhash) -> Block height containing the txhash * inspect : (tx_hex) -> Deserialize a transaction and decode and ins and outs * merkle_prove : (txhash) -> Proves a transaction is valid and returns txhash, merkle siblings and block header. +* estimate_fee_per_kb : (numblocks) -> Get estimated fee kb to get transaction confirmed within numblocks number of blocks +* tx_size : (tx) -> Estimate final transaction size of an unsigned transaction +* estimate_fee : (tx, numblocks=6) -> Estimate required fee of an unsigned transaction +* raw_block_header : (height) -> Get the raw data of a block header +* block_header : (height) -> Get the decoded details of a block header +* block_headers : (*heights) -> Get a list of decoded block headers +* subscribe_to_block_headers: (callback(height, raw_header, decoded_header)) -> Run a callback whenever a new block is added to the blockchain +* unsubscribe_from_block_headers: () -> Remove all subscriptions to block headers +* confirmations : (height) -> Number of confirmations a transaction at this height has +* subscribe_to_address : (callback(addr, status), addr) -> Run a callback every time there is an activity on an address +* subscribe_to_address_transactions : (callback(address: str, txs, newly_confirmed, history, unspent, confirmed, unconfirmed, proven), addr) -> Run a callback every time there is an activity on an address with details transaction and balance information already retrieved +* unsubscribe_from_address: (addr) -> Remove all subscriptions for this address +* get_balance : (addr) -> Get the balance, confirmed and unconfirmed, for an address +* get_balances : (*addrs) -> Get the balance, confirmed and unconfirmed, for multiple addresses +* get_merkle : (tx) -> Get the merkle root of a transaction +* merkle_prove : (tx) -> Prove a transaction is valid +* merkle_prove_by_txid : (txid) -> Prove a transaction id is valid +* balance_merkle_proven : (addr) -> Get the merkle proven balance for an address +* balance_merkle_proven : (*addrs) -> Get the merkle proven balance for multiple addresses +* get_address_variations: (addr) -> Return alternative formats for an address (e.g. Standard + Bitcoin Cash address) +* pub_is_for_p2pkh_addr : (pub, addr) -> Returns true if the p2pkh address for pub is addr +* wiftoaddr : (priv) -> Convert a private key in WIF format to the correct address type +* electrum_address : (masterkey, n, for_change) -> Electrum Address (for old Electrum seeds) +* encode_privkey : (privkey, format, script_type) -> Convert a private key to a different format or script types +* output_script_to_address : (script) -> Convert an output script to an address +* scripttoaddr : (script) -> Convert an input script to an address +* addrtoscript : (address) -> Convert an address to an output script +* addrtoscripthash : (address) -> Convert an address to scripthash as required by ElectrumX servers +* p2sh_scriptaddr : (script) -> Convert an output P2SH script to a P2SH address +* p2sh_segwit_addr : (script) -> Convert an output P2SH script to a native segwit P2WSH address +* pubtosegwitaddress : (pub) -> Convert a public key to a native segwit address +* privtosegwitaddress : (priv) -> Convert a private key to a native segwit address +* scripthash_to_cash_addr: (scripthash) -> Convert a scripthash to a Bitcoin Cash address +* pubtocashaddress : (pub) -> Convert a public key to a Bitcoin Cash address +* privtocashaddress : (priv) -> Convert a private key to a Bitcoin Cash address +* p2sh_cash_addr : (script) -> Convert an script to a Bitcoin Cash address +* hash_to_cash_addr : (hash) -> Convert the hash of a p2sh script to a Bitcoin Cash address +* legacy_addr_to_cash_address: (addr) -> Convert a legacy P2PKH address to a Bitcoin Cash address +* cash_address_to_legacy_addr: (addr) -> Convert a Bitcoin Cash address to a legalcy P2PKH address ### Listing of main non-coin specific commands: @@ -538,11 +599,7 @@ The arguments are the private key of the sender, the receiver's address and the * deserialize : (hex or bin transaction) -> JSON tx * serialize : (JSON tx) -> hex or bin tx -* multisign : (txobj, i, script, privkey) -> signature -* apply_multisignatures: (txobj, i, script, sigs) -> tx with index i signed with sigs -* scriptaddr : (script) -> P2SH address -* mk_multisig_script : (pubkeys, M) -> M-of-N multisig script from pubkeys -* verify_tx_input : (tx, i, script, sig, pub) -> True/False +s* verify_tx_input : (tx, i, script, sig, pub) -> True/False * tx_hash : (hex or bin tx) -> hash * access : (json list/object, prop) -> desired property of that json object diff --git a/crypto_scripts/convert_private_key.py b/crypto_scripts/convert_private_key.py index 912a81aa..7e610248 100644 --- a/crypto_scripts/convert_private_key.py +++ b/crypto_scripts/convert_private_key.py @@ -29,7 +29,7 @@ def main(): address = coin.pubtoaddr(public_key) print(f'P2PKH Address: {address}') elif script_type == "p2wpkh" and coin.segwit_supported: - native_segwit_address = coin.pub_to_segwit_address(public_key) + native_segwit_address = coin.pubtosegwitaddress(public_key) print(f'P2WPKH Native Segwit address: {native_segwit_address}') elif script_type == "p2wpkh-p2sh" and coin.segwit_supported: p2pkhw_p2sh = coin.pubtop2wpkh_p2sh(public_key) diff --git a/crypto_scripts/explorer.py b/crypto_scripts/explorer.py index 56d05273..5655d60a 100644 --- a/crypto_scripts/explorer.py +++ b/crypto_scripts/explorer.py @@ -72,7 +72,7 @@ async def input_belongs_to_address(coin: BaseCoin, inp: Dict[str, Any], address: elif coin.is_segwit_or_p2sh(address): if is_pubkey(pubkey_or_script): return any(addr == address for addr in ( # P2W - coin.pub_to_segwit_address(pubkey_or_script), + coin.pubtosegwitaddress(pubkey_or_script), coin.pubtop2wpkh_p2sh(pubkey_or_script), )) return False diff --git a/crypto_scripts/view_private_key_addresses.py b/crypto_scripts/view_private_key_addresses.py index 75120b9f..51ccb69e 100644 --- a/crypto_scripts/view_private_key_addresses.py +++ b/crypto_scripts/view_private_key_addresses.py @@ -56,8 +56,8 @@ def main(): assert native_segwit_address == native_segwit_compressed_address - native_segwit_address2 = coin.pub_to_segwit_address(public_key) - native_segwit_compressed_address2 = coin.pub_to_segwit_address(compressed_public_key) + native_segwit_address2 = coin.pubtosegwitaddress(public_key) + native_segwit_compressed_address2 = coin.pubtosegwitaddress(compressed_public_key) assert native_segwit_address2 == native_segwit_compressed_address2 diff --git a/cryptos/coins/base.py b/cryptos/coins/base.py index 1636e13d..7eadf450 100644 --- a/cryptos/coins/base.py +++ b/cryptos/coins/base.py @@ -93,12 +93,12 @@ def close(self): self._request_queue.sync_q.put((fut, "close", (), {})) fut.result(timeout=100) - def tx_size(self, txobj: Tx) -> float: - return self._async_coin.tx_size(txobj) - def estimate_fee_per_kb(self, numblocks: int = 6) -> float: return self._run_async("estimate_fee_per_kb", numblocks=numblocks) + def tx_size(self, txobj: Tx) -> float: + return self._async_coin.tx_size(txobj) + def estimate_fee(self, txobj: Tx, numblocks: int = 6) -> int: return self._run_async("estimate_fee", txobj, numblocks=numblocks) @@ -169,11 +169,11 @@ def get_histories(self, *args: str, merkle_proof: bool = False) -> List[Electrum def get_raw_tx(self, tx_hash: str) -> str: return self._run_async("get_raw_tx", tx_hash) - def get_tx(self, tx_hash: str) -> Tx: - return self._run_async("get_tx", tx_hash) + def get_tx(self, txid: str) -> Tx: + return self._run_async("get_tx", txid) - def get_verbose_tx(self, tx_hash: str) -> Dict[str, Any]: # Make TypedDict - return self._run_async("get_verbose_tx", tx_hash) + def get_verbose_tx(self, txid: str) -> Dict[str, Any]: # Make TypedDict + return self._run_async("get_verbose_tx", txid) def get_txs(self, *args: str) -> List[Tx]: return self._run_async("get_txs", *args) @@ -190,6 +190,15 @@ def pubtoaddr(self, pubkey: PubKeyType) -> str: def privtoaddr(self, privkey: PrivkeyType) -> str: return self._async_coin.privtoaddr(privkey) + def privtop2pkh(self, privkey: PrivkeyType) -> str: + return self._async_coin.privtop2pkh(privkey) + + def pub_is_for_p2pkh_addr(self, pubkey: PubKeyType, address: str) -> bool: + return self._async_coin.pub_is_for_p2pkh_addr(pubkey, address) + + def wiftoaddr(self, privkey: PrivkeyType) -> str: + return self._async_coin.wiftoaddr(privkey) + def electrum_address(self, masterkey: AnyStr, n: int, for_change: int = 0) -> str: return self._async_coin.electrum_address(masterkey, n, for_change=for_change) @@ -208,9 +217,18 @@ def is_native_segwit(self, addr: str) -> bool: def is_address(self, addr: str) -> bool: return self._async_coin.is_address(addr) - def is_legacy_segwit_or_multisig(self, addr: str) -> bool: + def is_cash_or_legacy_p2pkh_address(self, addr: str)-> bool: + return self._async_coin.is_cash_or_legacy_p2pkh_address(addr) + + def maybe_legacy_segwit(self, addr: str) -> bool: return self._async_coin.maybe_legacy_segwit(addr) + def is_p2wsh(self, addr: str) -> bool: + return self._async_coin.is_p2wsh(addr) + + def is_segwit_or_p2sh(self, addr: str) -> bool: + return self._async_coin.is_segwit_or_p2sh(addr) + def is_segwit_or_multisig(self, addr: str) -> bool: return self._async_coin.is_segwit_or_p2sh(addr) @@ -223,26 +241,38 @@ def scripttoaddr(self, script: str) -> str: def p2sh_scriptaddr(self, script: str) -> str: return self._async_coin.p2sh_scriptaddr(script) + def p2sh_segwit_addr(self, script: str) -> str: + return self._async_coin.p2sh_segwit_addr(script) + def addrtoscript(self, addr: str) -> str: return self._async_coin.addrtoscript(addr) def addrtoscripthash(self, addr: str) -> str: return self._async_coin.addrtoscripthash(addr) - def pubtop2w(self, pub: str) -> str: + def pubtop2wpkh_p2sh(self, pub: str) -> str: return self._async_coin.pubtop2wpkh_p2sh(pub) + def privtop2wpkh_p2sh(self, priv: str) -> str: + return self._async_coin.privtop2wpkh_p2sh(priv) + def hash_to_segwit_addr(self, pub_hash: str) -> str: return self._async_coin.hash_to_segwit_addr(pub_hash) - def pub_to_segwit_address(self, pubkey) -> str: - return self._async_coin.pub_to_segwit_address(pubkey) + def scripthash_to_segwit_addr(self, script_hash: AnyStr) -> str: + return self._async_coin.scripthash_to_segwit_addr(script_hash) + + def pubtosegwitaddress(self, pubkey) -> str: + return self._async_coin.pubtosegwitaddress(pubkey) def script_to_p2wsh(self, script) -> str: return self._async_coin.script_to_p2wsh(script) - def mk_multsig_address(self, *args: str, num_required: int = None) -> Tuple[str, str]: - return self._async_coin.mk_multsig_address(*args, num_required=num_required) + def mk_multisig_address(self, *args: str, num_required: int = None) -> Tuple[str, str]: + return self._async_coin.mk_multisig_address(*args, num_required=num_required) + + def mk_multsig_segwit_address(self, *args: str, num_required: int = None) -> Tuple[str, str]: + return self._async_coin.mk_multsig_segwit_address(*args, num_required=num_required) def sign(self, txobj: Union[Tx, AnyStr], i: int, priv: PrivkeyType) -> Tx: return self._async_coin.sign(txobj, i, priv) @@ -333,11 +363,14 @@ def is_cash_address(self, addr: str) -> bool: def scripthash_to_cash_addr(self, scripthash: bytes) -> str: return self._async_coin.scripthash_to_cash_addr(scripthash) + def p2sh_cash_addr(self, script: str) -> str: + return self._async_coin.p2sh_cash_addr(script) + def hash_to_cash_addr(self, pub_hash: AnyStr) -> str: return self._async_coin.hash_to_cash_addr(pub_hash) - def pub_to_cash_address(self, pubkey: str) -> str: - return self._async_coin.pub_to_cash_address(pubkey) + def pubtocashaddress(self, pubkey: str) -> str: + return self._async_coin.pubtocashaddress(pubkey) def privtocashaddress(self, privkey: PrivkeyType) -> str: return self._async_coin.privtocashaddress(privkey) @@ -351,5 +384,11 @@ def cash_address_to_legacy_addr(self, addr: str) -> str: def mk_multsig_cash_address(self, *args: str, num_required: int = None) -> Tuple[str, str]: return self._async_coin.mk_multsig_cash_address(*args, num_required=num_required) + def apply_multisignatures(self, txobj: Tx, i: int, script, *args): + return self._async_coin.apply_multisignatures(txobj, i, script, *args) + def calculate_fee(self, tx: Tx) -> int: return self._run_async("calculate_fee", tx) + + def privtosegwitaddress(self, privkey: PrivkeyType) -> str: + return self._async_coin.privtosegwitaddress(privkey) diff --git a/cryptos/coins_async/base.py b/cryptos/coins_async/base.py index 84aa7048..9501242f 100644 --- a/cryptos/coins_async/base.py +++ b/cryptos/coins_async/base.py @@ -440,25 +440,25 @@ async def get_raw_tx(self, tx_hash: str) -> str: """ return await self.client.get_tx(tx_hash) - async def get_tx(self, tx_hash: str) -> Tx: + async def get_tx(self, txid: str) -> Tx: """ Fetch transaction from the blockchain and deserialise it to a dictionary """ - tx = await self.get_raw_tx(tx_hash) + tx = await self.get_raw_tx(txid) deserialized_tx = deserialize(tx) return deserialized_tx - async def get_verbose_tx(self, tx_hash: str) -> ElectrumXVerboseTX: + async def get_verbose_tx(self, txid: str) -> ElectrumXVerboseTX: """ Fetch transaction from the blockchain in verbose form """ - return await self.client.get_tx(tx_hash, verbose=True) + return await self.client.get_tx(txid, verbose=True) async def get_txs(self, *args: str) -> AsyncGenerator[Tx, None]: for tx in await asyncio.gather(*[self.get_tx(tx_hash) for tx_hash in args]): yield tx - async def ensure_values(self, tx: Tx) -> Tx: + async def _ensure_values(self, tx: Tx) -> Tx: if not all(inp.get('value') for inp in tx['ins']): tx_hashes = list(dict.fromkeys([inp['tx_hash'] for inp in tx['ins'] if not inp.get('value')])) try: @@ -473,7 +473,7 @@ async def ensure_values(self, tx: Tx) -> Tx: async def calculate_fee(self, tx: Tx) -> int: try: - tx = await self.ensure_values(tx) + tx = await self._ensure_values(tx) except RuntimeError: pass in_value = sum(i['value'] for i in tx['ins']) @@ -521,7 +521,7 @@ def get_address_variations(self, address: str) -> List[str]: def pub_is_for_p2pkh_addr(self, pubkey: PubKeyType, address: str) -> bool: return self.pubtoaddr(pubkey) == address or ( - self.cash_address_supported and self.pub_to_cash_address(pubkey) == address) + self.cash_address_supported and self.pubtocashaddress(pubkey) == address) def wiftoaddr(self, privkey: PrivkeyType) -> str: magicbyte, priv = b58check_to_bin(privkey) @@ -617,7 +617,7 @@ def output_script_to_address(self, script: str) -> str: def scripttoaddr(self, script: str) -> str: """ - Convert an input public key hash to an address + Convert an input public key has or script to an address """ if is_hex(script): script = binascii.unhexlify(script) @@ -730,9 +730,9 @@ def privtosegwitaddress(self, privkey: PrivkeyType) -> str: """ Convert a private key to the new segwit address format outlined in BIP01743 """ - return self.pub_to_segwit_address(self.privtopub(privkey)) + return self.pubtosegwitaddress(self.privtopub(privkey)) - def pub_to_cash_address(self, pubkey: str) -> str: + def pubtocashaddress(self, pubkey: str) -> str: """ Convert a public key to a cash address """ @@ -742,7 +742,7 @@ def privtocashaddress(self, privkey: PrivkeyType) -> str: """ Convert a private key to a cash address """ - return self.pub_to_cash_address(self.privtopub(privkey)) + return self.pubtocashaddress(self.privtopub(privkey)) def legacy_addr_to_cash_address(self, addr: str) -> str: """ @@ -765,13 +765,13 @@ def cash_address_to_legacy_addr(self, addr: str) -> str: return bin_to_b58check(pubkey_hash, self.magicbyte) return bin_to_b58check(pubkey_hash, self.script_magicbyte) - def pub_to_segwit_address(self, pubkey: str) -> str: + def pubtosegwitaddress(self, pubkey: str) -> str: """ Convert a public key to the new segwit address format outlined in BIP01743 """ return self.hash_to_segwit_addr(pubkey_to_hash(compress(pubkey))) - def mk_multsig_address(self, *args: str, num_required: int = None) -> Tuple[str, str]: + def mk_multisig_address(self, *args: str, num_required: int = None) -> Tuple[str, str]: """ :param args: List of public keys to used to create multisig :param num_required: The number of signatures required to spend (defaults to number of public keys provided) diff --git a/cryptos/testing/testcases.py b/cryptos/testing/testcases.py index a649fd80..5e25dda1 100644 --- a/cryptos/testing/testcases.py +++ b/cryptos/testing/testcases.py @@ -541,10 +541,10 @@ def assertGetSegwitTxsOK(self): def assertMultiSigTransactionOK(self): pubs = [privtopub(priv) for priv in self.privkeys] - script, address1 = self._coin.mk_multsig_address(*pubs, num_required=2) + script, address1 = self._coin.mk_multisig_address(*pubs, num_required=2) self.assertEqual(address1, self.multisig_addresses[0]) pubs2 = [privtopub(priv) for priv in self.privkeys[0:2]] - script2, address2 = self._coin.mk_multsig_address(*pubs2) + script2, address2 = self._coin.mk_multisig_address(*pubs2) self.assertEqual(address2, self.multisig_addresses[1]) # Find which of the three addresses currently has the most coins and choose that as the sender diff --git a/cryptos/testing/testcases_async.py b/cryptos/testing/testcases_async.py index a679ec5b..1d532e0f 100644 --- a/cryptos/testing/testcases_async.py +++ b/cryptos/testing/testcases_async.py @@ -132,8 +132,8 @@ def assertP2WPKH_WIFOK(self): self.assertEqual(self._coin.privtosegwitaddress(privkey), address) self.assertEqual(self._coin.privtosegwitaddress(wif), address) self.assertEqual(self._coin.privtoaddr(wif), address) - self.assertEqual(self._coin.pub_to_segwit_address(privtopub(privkey)), address) - self.assertEqual(self._coin.pub_to_segwit_address(privtopub(wif)), address) + self.assertEqual(self._coin.pubtosegwitaddress(privtopub(privkey)), address) + self.assertEqual(self._coin.pubtosegwitaddress(privtopub(wif)), address) self.assertTrue(self._coin.is_native_segwit(address)) self.assertTrue(self._coin.is_address(address)) self.assertFalse(self._coin.is_p2sh(address)) @@ -804,10 +804,10 @@ async def assertGetSegwitTxsOK(self): async def assertMultiSigTransactionOK(self, expected_tx_id: str = None): pubs = [privtopub(priv) for priv in self.privkeys] - script1, address1 = self._coin.mk_multsig_address(*pubs, num_required=2) + script1, address1 = self._coin.mk_multisig_address(*pubs, num_required=2) self.assertEqual(address1, self.multisig_addresses[0]) pubs2 = pubs[0:2] - script2, address2 = self._coin.mk_multsig_address(*pubs2) + script2, address2 = self._coin.mk_multisig_address(*pubs2) self.assertEqual(address2, self.multisig_addresses[1]) # Find which of the three addresses currently has the most coins and choose that as the sender diff --git a/cryptos/wallet.py b/cryptos/wallet.py index 740a0cfb..ee07c82d 100644 --- a/cryptos/wallet.py +++ b/cryptos/wallet.py @@ -49,7 +49,7 @@ def pubtoaddr(self, pubkey): if self.xtype == "p2pkh": return self.coin.pubtoaddr(pubkey) elif self.xtype == "p2wpkh": - return self.coin.pub_to_segwit_address(pubkey) + return self.coin.pubtosegwitaddress(pubkey) elif self.xtype == "p2wpkh-p2sh": return self.coin.pubtop2wpkh_p2sh(pubkey) @@ -224,7 +224,7 @@ def pubtoaddr(self, pubkey): if self.xtype == "p2pkh": return self.coin.pubtoaddr(pubkey) elif self.xtype == "p2wpkh": - return self.coin.pub_to_segwit_address(pubkey) + return self.coin.pubtosegwitaddress(pubkey) elif self.xtype == "p2wpkh-p2sh": return self.coin.pubtop2wpkh_p2sh(pubkey) diff --git a/setup.py b/setup.py index 84f36213..708ac6a5 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup(name='cryptos', - version='2.0.7', + version='2.0.8', description='Python Crypto Coin Tools', long_description=open('README.md').read(), long_description_content_type='text/markdown', diff --git a/tests/test_coins_async/test_litecoin.py b/tests/test_coins_async/test_litecoin.py index 69595dcc..f76ce058 100644 --- a/tests/test_coins_async/test_litecoin.py +++ b/tests/test_coins_async/test_litecoin.py @@ -42,7 +42,7 @@ class TestLitecoin(BaseAsyncCoinTestCase): testnet: bool = False unspent_addresses: List[str] = ["LSdTvMHRm8sScqwCi6x9wzYQae8JeZhx6y"] - balance: ElectrumXMultiBalanceResponse = {'confirmed': 83515295, 'unconfirmed': 0} + balance: ElectrumXMultiBalanceResponse = {'confirmed': 83571855, 'unconfirmed': 0} balances: List[ElectrumXMultiBalanceResponse] = [{'address': unspent_addresses[0]} | dict(balance)] unspent: List[ElectrumXTx] = [{'address': 'LSdTvMHRm8sScqwCi6x9wzYQae8JeZhx6y', 'height': 1495972, @@ -93,7 +93,13 @@ class TestLitecoin(BaseAsyncCoinTestCase): 'height': 2352771, 'tx_hash': '7158c6f05ef2b06a40cd00b64647da6735d2eb3908f958fcbc5d0584f34be460', 'tx_pos': 0, - 'value': 1121169}] + 'value': 1121169}, + {'address': 'LSdTvMHRm8sScqwCi6x9wzYQae8JeZhx6y', + 'height': 2454373, + 'tx_hash': '02c0665f6ddaed09a365ddafdff05b188969ee754acf6867b9dd1b970d254a8b', + 'tx_pos': 0, + 'value': 56560 + }] history: List[ElectrumXTx] = [{'height': 1495972, 'tx_hash': '6cf532663cd14013aa6ccb394f86d64aa48fce4d6aa8a175f9b75ea486465ca9'}, {'height': 1509957, @@ -113,7 +119,9 @@ class TestLitecoin(BaseAsyncCoinTestCase): {'height': 2262951, 'tx_hash': '43eb70acc4c8c6bdbfabdf76cdbf0a6a969b82051514d105f8c00dff23e715c6'}, {'height': 2352771, - 'tx_hash': '7158c6f05ef2b06a40cd00b64647da6735d2eb3908f958fcbc5d0584f34be460'}] + 'tx_hash': '7158c6f05ef2b06a40cd00b64647da6735d2eb3908f958fcbc5d0584f34be460'}, + {'height': 2454373, + 'tx_hash': '02c0665f6ddaed09a365ddafdff05b188969ee754acf6867b9dd1b970d254a8b'}] histories: List[ElectrumXTx] = [dict(h) | {'address': "LSdTvMHRm8sScqwCi6x9wzYQae8JeZhx6y"} for h in history] unspents: List[ElectrumXTx] = unspent min_latest_height: int = 2360220 @@ -178,46 +186,46 @@ async def test_balances_merkle_proven(self): async def test_transaction(self): with mock.patch('cryptos.electrumx_client.client.NotificationSession.send_request', side_effect=self.mock_electrumx_send_request): - await self.assertTransactionOK("9e60e1f5257950837bbbe7f2ca84410a59d9b6326823c4e0defdb01fb115df97") + await self.assertTransactionOK("5f2bee84fdd62038a5f34848cd427cca3ed278d990d7ed4e50d7f62378c23757") async def test_transaction_segwit(self): with mock.patch('cryptos.electrumx_client.client.NotificationSession.send_request', side_effect=self.mock_electrumx_send_request): await self.assertSegwitTransactionOK( - "c263194aed2d18f3289105f99636b2187f7228c0a5d3b0c757d68a7a9099a4c4") + "1956512ac84a0624d1c771463ed08c19b9e4add2d7f23975b4c4fcd9c6d0a006") async def test_transaction_native_segwit(self): with mock.patch('cryptos.electrumx_client.client.NotificationSession.send_request', side_effect=self.mock_electrumx_send_request): await self.assertNativeSegwitTransactionOK( - "41c45ea2381ec4da825712d1cee6d598247edac93e8fedb79ff6d426bfb2af6f") + "eab7dcbf60408c9a72bfd5f60ffcef3c266e8b9a0f159686f97334740ff2b88c") async def test_transaction_mixed_segwit(self): with mock.patch('cryptos.electrumx_client.client.NotificationSession.send_request', side_effect=self.mock_electrumx_send_request): await self.assertMixedSegwitTransactionOK( - "5e918bfc41e912b581adb513efe4f480d37950c386842ad1bbd052b3fb5c1a48") + "69678157448b00cfdafaf07bf7825072094552c5f5f3626152845118b3b30969") async def test_transaction_multisig(self): with mock.patch('cryptos.electrumx_client.client.NotificationSession.send_request', side_effect=self.mock_electrumx_send_request): await self.assertMultiSigTransactionOK( - "a0c54d9e45a7bd3ab224d154760f08c7fcfc8aeaecbb46914796ff52e27e6c85") + "6ecbbfe2af2744b3000e02e21f70c96d5e2128a04db07e3d1c983036f7683d70") async def test_transaction_native_segwit_multisig(self): with mock.patch('cryptos.electrumx_client.client.NotificationSession.send_request', side_effect=self.mock_electrumx_send_request): - await self.assertNativeSegwitMultiSigTransactionOK("37d3c7f0ff6846a34bbd69a472cadb83ee631b5ea1bc7695cfe52a3442ed7397") + await self.assertNativeSegwitMultiSigTransactionOK("27fb482d29a85b3141141622dde4015499cdf17ecc41b57c01dc387e9e87431e") async def test_sendmulti_recipient_tx(self): with mock.patch('cryptos.electrumx_client.client.NotificationSession.send_request', side_effect=self.mock_electrumx_send_request): - await self.assertSendMultiRecipientsTXOK("c85e3e899b43c5a1f68647c852ee13f9e3e2b409b4cc73cce131d70dba1a793d") + await self.assertSendMultiRecipientsTXOK("b714d2614e05ae9442c44f39faa82cc41ef4d37348d04075e5315f41b9467071") async def test_send(self): with mock.patch('cryptos.electrumx_client.client.NotificationSession.send_request', side_effect=self.mock_electrumx_send_request): - await self.assertSendOK("6d2cfbc85d56284f0ee88f977979d20e8e66017b48737568d1b23ae597594e2d") + await self.assertSendOK("ba75fb9bafeb6dd02d044b7814f3da917037bedf3d187eae4b94c10a6559e7d1") async def test_subscribe_block_headers(self): await self.assertSubscribeBlockHeadersOK()