Usage ===== The main class for generating wallets, fetching address balances, and creating transactions is `zpywallet.Wallet`. It is the most important class in the library and represents a wallet on a particular blockchain. You can create a wallet with a randomly-generated mnemonic phrase like this: .. code-block:: python from zpywallet.network import BitcoinSegwitMainNet from zpywallet import Wallet wallet = Wallet(BitcoinSegwitMainNet, None, "password") The second argument is the mnemonic phrase you want to do, which allows you to restore a wallet using different parameters. There is an additional keyword argument, ``derivation_path``, which takes a string to use as the custom path. For example: ``"m/0'``. If no path is specified, it uses the default path for the network. ZPyWallet follows BIP44 path conventions, and the number of receiving addresses can also be configured by changing the ``receive_gap_limit`` keyword argument to a larger or smaller number. To save the wallet into a file, use the ``serialize()`` method. This returns a byte strem which can be imported using the ``Wallet.deserialize(data, password)`` method. Networks -------- Blockchains can be imported from `zpywallet.network`. For example: .. code-block:: python from zpywallet.network import BitcoinSegwitMainNet # Segwit-enabled Bitcoin mainnet from zpywallet.network import BitcoinMainNet # Bitcoin mainnet which makes only legacy addresses and transactions from zpywallet.network import BitcoinTestNet from zpywallet.network import EthereumMainNet # ... Here are the supported networks: - ``BitcoinMainNet`` - Bitcoin mainnet, creates legacy addresses and transactions - ``BitcoinSegwitMainNet`` - Bitcoin mainnet, creates segwit and legacy addresses and transactions - ``BitcoinTestNet`` - Bitcoin testnet, creates legacy addresses and transactions - ``BitcoinSegwitTestNet`` - Bitcoin testnet, creates segwit and legacy addresses and transactions - ``LitecoinMainNet`` - Litecoin mainnet, creates legacy addresses and transactions - ``LitecoinSegwitMainNet`` - Litecoin mainnet, creates segwit and legacy addresses and transactions - ``LitecoinBTCMainNet`` - Litecoin mainnet, creates legacy addresses and transactions - ``LitecoinBTCSegwitMainNet`` - Litecoin mainnet using Bitcoin xpub/xprv, creates segwit and legacy addresses and transactions - ``LitecoinTestNet`` - Litecoin testnet, creates legacy addresses and transactions - ``LitecoinSegwitTestNet`` - Litecoin testnet, creates segwit and legacy addresses and transactions - ``DashMainNet`` - Dash mainnet - ``DashInvertedMainNet`` - Dash mainnet, with extended public/private bytes swapped - ``DashBTCMainNet`` - Dash mainnet usign Bitcoin xpub/xprv - ``DashTestNet`` - Dash testnet - ``DashInvertedTestNet`` - Dash testnet, with extended public/private bytes swapped - ``DogecoinMainNet`` - Dogecoin mainnet - ``DogecoinBTCMainNet`` - Dogecoin mainnet usign Bitcoin xpub/xprv - ``DogecoinTestNet`` - Dogecoin testnet - ``EthereumMainNet`` - Ethereum mainnet (does not support smart contracts) - ``BitcoinCashMainNet`` - Bitcoin Cash mainnet (limited support) - ``BlockcypherTestNet`` - Blockcypher testnet (limited support) Bitcoin Signet support is planned for a future release. In most cases, if there is a BTC variant of a network, you would want to use that, because many wallets incorrectly use Bitcoin's extended bytes when generating addresses and keys from seed phrases, and for backwards compatibility, you should also use those bytes to continue detecting wallet balances. There is also an inverted version of Dash's network because the Dash specifications and implementation differ on which pair is canonical. Addresses --------- To generate a random address within the gap limit, you can use the ``Wallet.random_adress()`` method. Note that ZPyWallet does not currently make use of change addresses nor does it automatically increase the gap limit. To get a list of all the receiving addresses generated by the wallet, use ``Wallet.addresses()``. The type of addresses created depend on the network used by the wallet. For example, legacy networks will create Base58 P2PKH addresses, while Segwit networks will make Bech32 P2WPKH addresses. Transactions ------------ ZPyWallet has built-in support for fetching transaction history of addresses: .. code-block:: python from zpywallet.network import BitcoinSegwitMainNet # Or you can use BitcoinMainNet from zpywallet import Wallet from zpywallet import Destination from zywallet.address.btc import BitcoinAddress from pprint import pprint as pp wallet = Wallet(...) # Create or restore a wallet here transactions = wallet.get_transaction_history() for tx in transactions: print(f"Transaction Hash: {tx.txid()}") print(f"Timestamp: {tx.timestamp()}") print(f"Confirmed: {tx.confirmed()}") if tx.confirmed(): print(f"Height: {tx.height()}") print(f"Total Fee: {tx.total_fee()}") print(f"Fee Rate: {tx.sat_fee_rate()}") print(f"Inputs: {pp(tx.sat_inputs())}") print(f"Outputs: {pp(tx.sat_outputs())}") utxos = wallet.get_utxos() # Not applicable for Ethereum for utxo in utxos: print(f"Transaction Hash: {utxo.txid()}") print(f"Index: {utxo.index()}") print(f"Amount: {utxo.amount()}") print(f"Address: {utxo.address()}") # You can also get UTXOs directly from transactions: if len(transactions) > 0: utxo = UTXO(transacitons[0], 1) # Get the first UTXO (transaction output) # You can even get the transaction history of random addresses: address = BitcoinAddress(['bc1q34aq5drpuwy3wgl9lhup9892qp6svr8ldzyy7c', '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa']) # ...Then you can call get_transaction_history(), get_utxos() and get_balance() like for a wallet total_balance, confirmed_balance = wallet.get_balance() # On Ethereum these two values are identical # Send coins to an address # Change output is automatically calculated by the wallet address1 = "..." address2 = "..." destinations = [Destination(address1, 0.1, BitcoinSegWitMainNet), Destination(address2, 0.2, BitcoinSegWitMainNet)] # Amounts are in BTC # If you want to spend unconfirmed inputs, pass spend_unconfirmed_inputs=True fee_rate = 1 # sat/vbyte for Segwit network (for legacy networks it is in sat/byte) transaction = wallet.create_transaction("password", destinations, fee_rate) wallet.broadcast_transaction(transaction) Key Generation -------------- Arbitrary private keys can be generated as well: .. code-block:: python from zpywallet.network import BitcoinSegwitMainNet from zpywallet.utils.keys import PrivateKey, PublicKey priv = PrivateKey.from_random(network=BitcoinSegwitMainNet) pub = priv.public_key addr = pub.address() # Specify compressed=False for uncompressed address. Default is compressed. PrivateKey.from_hex("...", network=BitcoinSegwitMainNet) PrivateKey.from_int(1, network=BitcoinSegwitMainNet) wif = priv.to_wif() hex = priv.to_hex() message = priv.rfc2440_sign("Sign a message like this") priv.rfc2440_verify(message) # returns true or false Indices and Tables ------------------ * :ref:`genindex` * :ref:`modindex` * :ref:`search`