Package: btc-hd-wallet
Installationinstall python3.6 or higher for your OSinstallgitinstall btc_hd_wallet:a.) via pypipip install btc_hd_walletb.) from source# clone btc-hd-wallet repositorygitclonehttps://github.com/scgbckbone/btc-hd-wallet.git# change directory to project rootcdbtc-hd-wallet# create virtual environmentpython3-mvenvbtc-hd-wallet# activate virtual environmentsourcebtc-hd-wallet/bin/activate# upgrade pip, setuptools and wheel (optional)pipinstall-Upipsetuptoolswheel# install projectpythonsetup.pyinstall# run unittests (optional)pythonsetup.pytestBase Walletfrombtc_hd_walletimportBaseWallet# many ways how to initialize BaseWallet object# 1. totally new wallet# this will generate new mainnet wallet with 24 words mnemonicw=BaseWallet.new_wallet()# you can also generate testnet wallet with different length mnemonicw=BaseWallet.new_wallet(mnemonic_length=12,testnet=True)assertlen(w.mnemonic.split(" "))==12andw.testnet# you can also secure your wallet with optional passphrasew=BaseWallet.new_wallet(mnemonic_length=18,password="optional_secret_pwd")assertlen(w.mnemonic.split(" "))==18andnotw.testnetandw.password=="optional_secret_pwd"# 2. from entropy hex stringw=BaseWallet.from_entropy_hex(entropy_hex="064338c5a50fcf96436142e164e005be3d0a51cb7bcc6050a6d0798e863c5b44")# testnet with passwordw=BaseWallet.from_entropy_hex(entropy_hex="1e0479633a5c856b88a78b1977d3c214",password="optional_super_secret_password",testnet=True)# 3. from bip39 seed hexw=BaseWallet.from_bip39_seed_hex(bip39_seed="353cc8f20663196c2181b462e5d5d1a62192521b7604a578f87a3224a7ea9df91925c7e5b399094d996a2951acb1a95eba44b8293a5218bb6d964ba1def5f501",testnet=True)assertw.mnemonicisNoneandw.passwordisNone# 4. from mnemonicw=BaseWallet.from_mnemonic(mnemonic="bulk cat flee input sign remind card vapor bonus salon vacuum cinnamon",password="optional_secret_pwd",testnet=False)# 5. from extended keyw=BaseWallet.from_extended_key(extended_key="xprv9s21ZrQH143K2n9ryKS5EXxvQaNSbCxrVHSUigxG9ywY6GVQYsrk6n8e9j6m9z9LvBULFnSyjcLFxbG6WtXoeYRF19f1FY23nni39XSLPWm")# here you can also create watch only wallet from extended pub key# for instance: generate wallet offline, derive external chain extended pub keyew=BaseWallet.from_extended_key(extended_key="xpub6BvTr9tVPEDEDQ12sR7Ty4tVGnNGfDEeDg7dgmNkYzr3QXLS9amBxYHWRBbCJ2uD1RpVXZNkqXji2u3YE1bKxR7g6TUpxxB7C3Cx76i6wHL")# this will pass just fine as wallet loaded from extended public key is warch onlyassertew.watch_only==True# 'ew' represents wallet which has as its master key external chain of# hundredth account of bip84 purpose bitcoin mainnet wallet (m/84'/0'/100'/0)# create generatorbip84_gen=ew.address_generator(node=ew.master)# generate addressesnext(bip84_gen)# yields tuple of path and address>("m/84'/0'/100'/0/0","bc1qqv548euf07gx0h87d4sjczn65t8wnlv5jshp0z")Paper Walletfrombtc_hd_walletimportPaperWalletw=PaperWallet.new_wallet()# to display paper wallet in consolew.pprint()# get python dictionary repsresentation of paper walltejson_dct=w.generate()# get json serialized string representation of paper walletjson_str=w.json(indent=4)# wasabi import file format (inspired by ColdCard)file_path="/home/john/wasabi0.json"w.export_wasabi(file_path=file_path)Private and Public keysfrombtc_hd_walletimportPrivateKey,PublicKey# initialize private key object from secret exponentsk=PrivateKey(sec_exp=61513215313213513843213)# from wif formatsk=PrivateKey.from_wif("KxNH4NuQoDJjA9LwvHXn5KBTDPSG9YeoA7RBed2LwLRNqd1Tc4Wv")# from byte sequencesk=PrivateKey.parse(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15&X\xc0\xe3\xee\\\r$bU\x18')# secret exponentsecret_exponent=sk.sec_exp# to wifwif_str=sk.wif(testnet=False)# to bytessk_bytes=bytes(sk)# to access corresponding public keypk=sk.K# RIPEMD160(SHA256) of public keyh160=pk.h160()# p2pkh testnet addressp2pkh=pk.address(addr_type="p2pkh",testnet=True)# p2wpkh address (p2wpkh is default 'addr_type')p2wpkh=pk.address()# SEC encoding (bytes)sec=pk.sec()# elliptic curve pointpoint=pk.point# public key can also be parsed from secsec_str="030975d7fc3e27bcb3d37dd83a84f5ae2f48cec392e781e35ec849142bcc6e2cce"pk=PublicKey.parse(bytes.fromhex(sec_str))# or from ecdsa Point or PointJacobipk=PublicKey.from_point(point)Bip39 related methodsfrombtc_hd_walletimport(bip39_seed_from_mnemonic,mnemonic_from_entropy_bits,mnemonic_from_entropy)# mnemonic from number of entropy bits (allowed entropy bits 128,160,192,224,256)menmonic=mnemonic_from_entropy_bits(entropy_bits=256)# mnemonic from entropy hexmnemonic=mnemonic_from_entropy("0a84d45bb74a0d80c144f9ad765c3b9edc40a8dbb5c053c0930ef040992036d2")# create bip39 seed from mnemonicseed=bip39_seed_from_mnemonic(mnemonic=mnemonic)# or with optional passwordseed=bip39_seed_from_mnemonic(mnemonic=mnemonic,password="secret")ScriptfromioimportBytesIOfrombtc_hd_walletimportBaseWalletfrombtc_hd_walletimport(Script,p2wsh_script,p2wpkh_script,p2sh_script,p2pkh_script)# you can parse script hexscript_hex="1976a9148ca70d5eda840e9fb5d38234ae948dfad1d266d788ac"script=Script.parse(BytesIO(bytes.fromhex(script_hex)))str(script)>OP_DUPOP_HASH1608ca70d5eda840e9fb5d38234ae948dfad1d266d7OP_EQUALVERIFYOP_CHECKSIG# script can be raw serializedscript.raw_serialize()# or it can be serialized with length prependedscript.serialize()# or creating script pubkeys from walletw=BaseWallet.new_wallet()# derive some child node to use (I'll go with bip84)node=w.by_path("m/84'/0'/100'/0/0")hash160_pub_key=node.public_key.h160()script=p2wpkh_script(hash160_pub_key)str(script)>OP_08ca70d5eda840e9fb5d38234ae948dfad1d266d7Bip85frombtc_hd_walletimportBIP85DeterministicEntropyxprv="xprv9s21ZrQH143K2n9ryKS5EXxvQaNSbCxrVHSUigxG9ywY6GVQYsrk6n8e9j6m9z9LvBULFnSyjcLFxbG6WtXoeYRF19f1FY23nni39XSLPWm"# create new deterministic entropy object from extended private keybip85=BIP85DeterministicEntropy.from_xprv(xprv=xprv)# bip39 mnemonicbip85.bip39_mnemonic(word_count=24,index=0)>liftboostvaguevanishoccurstampeagletwicekitepausesunnyexecutedefygrocerymercyassistvolumeventuresubjectanalystfiscallectureconnectbunkerbip85.bip39_mnemonic(word_count=12,index=0)>goodbravehuntlicensedeliverconductmoredutchdonkeygreenskillgaugebip85.bip39_mnemonic(word_count=15,index=1)>vesselnervebuzzwifegoodskisockwalnutcrewtowardteamvastdynamicparadecandy# wallet import format (WIF)bip85.wif(index=0)>'KyxeP1pijLmtKZv8ry7d3tbNsq3XDeGgN99Mqi2Gn2Kx6WwPr2wC'bip85.wif(index=1)>'KxsrnifkxsZTBeP52VxHzZGawyUSULBi1trHrJhU7ndQxkTXguFJ'# extended private key (XPRV)bip85.xprv(index=0)>'xprv9s21ZrQH143K2SrZ37WGmQ4TcqHbcAxy7tfuoVNZBxnd7huX6XuD2UZBUuXVfrZjjtw5X3B9JgUvoVegVALTeTXWsiUSK9F4FWXFZLfZVzV'bip85.xprv(index=1)>'xprv9s21ZrQH143K4RPx2iS7FecFHCUiC4CA2x4PqY6rtqjgqpxqWNcTxK88oRDyiZf8WiTLA6GWwR7BSoFkjjNSEx4wAgGq7nnxukd2FJP7AKH'# hexbip85.hex(index=0)>'78ebebfc701429f60ab4540168950c8fc9db5d275324545e7512f9e23b1fcd42'bip85.hex(num_bytes=64,index=0)>'2205163efb2ae4e78609b4a7410e9a4856f673b04dd0af7ce9851a9f2f7883c854f76a3e1cf639c217adde4956604dcdd853104dfcb93751856e3e13dcb9ab35'# bip85 is also available in BaseWallet class as its attributefrombtc_hd_wallet.base_walletimportBaseWalletw=BaseWallet.new_wallet()type(w.bip85)==BIP85DeterministicEntropy>TrueDocumentationSphinx documentation is located in thedocssubdirectory.
Runmake htmlfrom there to create html documentation from docstrings.
Documentation html is available indocs/build/html/index.htmldependency: SphinxpipinstallSphinxRoadmap:This project is Work In Progressbasic HD paper wallet generator supporting bip32, bip44, bip49, bip84, slip132 (Multi-signature P2WSH in P2SH, Multi-signature P2WSH)storagenetwork calls(to be decided)