def unsigned_datas(self, detail: bool = False) -> List[dict]: """ Get Vapor transaction unsigned datas(messages) with instruction. :param detail: Vapor unsigned datas to see detail, defaults to False. :type detail: bool :returns: list -- Vapor transaction unsigned datas. >>> from swap.providers.vapor.htlc import HTLC >>> from swap.providers.vapor.transaction import FundTransaction >>> htlc: HTLC = HTLC(network="mainnet") >>> htlc.build_htlc(secret_hash="3a26da82ead15a80533a02696656b14b5dbfd84eb14790f2e1be5e9e45820eeb", recipient_public_key="3e0a377ae4afa031d4551599d9bb7d5b27f4736d77f78cac4d476f0ffba5ae3e", sender_public_key="fe6b3fd4458291b19605d92837ae1060cc0237e68022b2eb9faf01a118226212", endblock=120723497) >>> fund_transaction: FundTransaction = FundTransaction(network="mainnet") >>> fund_transaction.build_transaction(address="vp1qk9vj4jaezlcnjdckds4fkm8fwv5kawmqwpnpvs", htlc=htlc, amount=0.1, asset="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", unit="BTM") >>> fund_transaction.unsigned_datas() [{'datas': ['d7107257ef5fbfb04fc4747d6887f230a30676ecd6703a58015878b54f1f7b4f'], 'public_key': 'fe6b3fd4458291b19605d92837ae1060cc0237e68022b2eb9faf01a118226212', 'network': 'mainnet', 'path': 'm/44/153/1/0/1'}] """ # Check transaction if self._transaction is None: raise ValueError("Transaction is none, build transaction first.") unsigned_datas: List[dict] = [] for signing_instruction in self._transaction["signing_instructions"]: unsigned_data = dict(datas=signing_instruction["sign_data"]) if "pubkey" in signing_instruction and signing_instruction["pubkey"]: unsigned_data.setdefault("public_key", signing_instruction["pubkey"]) if detail: program = get_program(public_key=signing_instruction["pubkey"]) address = get_address(program=program, network=self._network) unsigned_data.setdefault("program", program) unsigned_data.setdefault("address", address) else: unsigned_data.setdefault("network", self._network) else: if detail: unsigned_data.setdefault("public_key", None) unsigned_data.setdefault("program", None) unsigned_data.setdefault("address", None) else: unsigned_data.setdefault("network", self._network) if "derivation_path" in signing_instruction and signing_instruction["derivation_path"]: path = indexes_to_path(indexes=signing_instruction["derivation_path"]) if detail: unsigned_data.setdefault("indexes", signing_instruction["derivation_path"]) unsigned_data.setdefault("path", path) else: if detail: unsigned_data.setdefault("indexes", None) unsigned_data.setdefault("path", None) # Append unsigned datas unsigned_datas.append(unsigned_data) return unsigned_datas
def unsigned(self, detail=False): unsigned_datas = list() if self.transaction is None: raise ValueError("transaction is none, build transaction first.") for signing_instruction in self.transaction["signing_instructions"]: unsigned_data = dict(datas=signing_instruction["sign_data"]) if "pubkey" in signing_instruction and signing_instruction[ "pubkey"]: unsigned_data.setdefault("public_key", signing_instruction["pubkey"]) if detail: program = get_program( public_key=signing_instruction["pubkey"]) address = get_address(program=program, network=self.network) unsigned_data.setdefault("program", program) unsigned_data.setdefault("address", address) else: unsigned_data.setdefault("network", self.network) else: if detail: unsigned_data.setdefault("public_key", None) unsigned_data.setdefault("program", None) unsigned_data.setdefault("address", None) else: unsigned_data.setdefault("network", self.network) if "derivation_path" in signing_instruction and signing_instruction[ "derivation_path"]: path = indexes_to_path( indexes=signing_instruction["derivation_path"]) if detail: unsigned_data.setdefault( "indexes", signing_instruction["derivation_path"]) unsigned_data.setdefault("path", path) else: if detail: unsigned_data.setdefault("indexes", None) unsigned_data.setdefault("path", None) # Append unsigned datas unsigned_datas.append(unsigned_data) # Returning return unsigned_datas
def from_public_key(self, public): """ Initiate Bytom wallet from public key. :param public: Bytom wallet public key. :type public: str. :returns: Wallet -- Bytom wallet instance. >>> from swap.providers.bytom.wallet import Wallet >>> wallet = Wallet(network="mainnet") >>> wallet.from_public_key("91ff7f525ff40874c4f47f0cab42e46e3bf53adad59adef9558ad1b6448f22e2") <swap.providers.bytom.wallet.Wallet object at 0x040DA268> """ # Bytom wallet initialization. Bytom = BTMWallet() self._public_key = public self._program = get_program(public_key=self._public_key) self._address = get_address(program=self._program, network=self.network) return self
def from_xpublic_key(self, xpublic_key): """ Initiate Bytom wallet from xpublic key. :param xpublic_key: Bytom wallet xpublic key. :type xpublic_key: str. :returns: Wallet -- Bytom wallet instance. >>> from swap.providers.bytom.wallet import Wallet >>> wallet = Wallet(network="mainnet") >>> wallet.from_xpublic_key("16476b7fd68ca2acd92cfc38fa353e75d6103f828276f44d587e660a6bd7a5c5ef4490504bd2b6f997113671892458830de09518e6bd5958d5d5dd97624cfa4b") <swap.providers.bytom.wallet.Wallet object at 0x040DA268> """ # Bytom wallet initialization. Bytom = BTMWallet() self._xpublic_key = xpublic_key self._public_key = get_public_key(xpublic_key=self._xpublic_key, path=self.path()) self._program = get_program(public_key=self._public_key) self._address = get_address(program=self._program, network=self.network) return self
def test_wallet_tools(): assert get_xpublic_key( xprivate_key=_["wallet"]["xprivate_key"]) == _["wallet"]["xpublic_key"] assert get_expand_xprivate_key(xprivate_key=_["wallet"]["xprivate_key"] ) == _["wallet"]["expand_xprivate_key"] assert indexes_to_path( indexes=_["wallet"]["indexes"]) == _["wallet"]["path"] assert path_to_indexes(path=_["wallet"]["path"]) == _["wallet"]["indexes"] assert get_child_xprivate_key(xprivate_key=_["wallet"]["xprivate_key"] ) == _["wallet"]["xprivate_key"] assert get_child_xprivate_key( xprivate_key=_["wallet"]["xprivate_key"], indexes=_["wallet"]["indexes"]) == _["wallet"]["child_xprivate_key"] assert get_child_xprivate_key( xprivate_key=_["wallet"]["xprivate_key"], path=_["wallet"]["path"]) == _["wallet"]["child_xprivate_key"] assert get_child_xpublic_key( xpublic_key=_["wallet"]["xpublic_key"]) == _["wallet"]["xpublic_key"] assert get_child_xpublic_key( xpublic_key=_["wallet"]["xpublic_key"], indexes=_["wallet"]["indexes"]) == _["wallet"]["child_xpublic_key"] assert get_child_xpublic_key( xpublic_key=_["wallet"]["xpublic_key"], path=_["wallet"]["path"]) == _["wallet"]["child_xpublic_key"] assert get_private_key(xprivate_key=_["wallet"] ["xprivate_key"]) == _["wallet"]["xprivate_key"] assert get_private_key( xprivate_key=_["wallet"]["xprivate_key"], indexes=_["wallet"]["indexes"]) == _["wallet"]["child_xprivate_key"] assert get_private_key( xprivate_key=_["wallet"]["xprivate_key"], path=_["wallet"]["path"]) == _["wallet"]["child_xprivate_key"] assert get_public_key(xpublic_key=_["wallet"] ["xpublic_key"]) == _["wallet"]["xpublic_key"][:64] assert get_public_key( xpublic_key=_["wallet"]["xpublic_key"], indexes=_["wallet"]["indexes"]) == _["wallet"]["public_key"] assert get_public_key( xpublic_key=_["wallet"]["xpublic_key"], path=_["wallet"]["path"]) == _["wallet"]["public_key"] assert get_program( public_key=_["wallet"]["public_key"]) == _["wallet"]["program"] assert get_address(program=_["wallet"]["program"], network="mainnet", vapor=False) == _["wallet"]["address"]["mainnet"] assert get_address(program=_["wallet"]["program"], network="solonet", vapor=False) == _["wallet"]["address"]["solonet"] assert get_address(program=_["wallet"]["program"], network="testnet", vapor=False) == _["wallet"]["address"]["testnet"] assert get_address(program=_["wallet"]["program"], network="mainnet", vapor=True) == _["wallet"]["vapor_address"]["mainnet"] assert get_address(program=_["wallet"]["program"], network="solonet", vapor=True) == _["wallet"]["vapor_address"]["solonet"] assert get_address(program=_["wallet"]["program"], network="testnet", vapor=True) == _["wallet"]["vapor_address"]["testnet"]
def unsigned_datas(self, detail=False): """ Get Bytom transaction unsigned datas with instruction. :param detail: Bytom unsigned datas to see detail, defaults to False. :type detail: bool :returns: list -- Bytom transaction unsigned datas. >>> from swap.providers.bytom.htlc import HTLC >>> from swap.providers.bytom.transaction import FundTransaction >>> from swap.providers.bytom.wallet import Wallet >>> htlc = HTLC(network="testnet").init("821124b554d13f247b1e5d10b84e44fb1296f18f38bbaa1bea34a12c843e0158", "3e0a377ae4afa031d4551599d9bb7d5b27f4736d77f78cac4d476f0ffba5ae3e", "91ff7f525ff40874c4f47f0cab42e46e3bf53adad59adef9558ad1b6448f22e2", 1000) >>> sender_wallet = Wallet(network="testnet").from_mnemonic("indicate warm sock mistake code spot acid ribbon sing over taxi toast") >>> fund_transaction = FundTransaction(network="testnet") >>> fund_transaction.build_transaction(sender_wallet, htlc, 10000) >>> fund_transaction.unsigned_datas() [{'datas': ['38601bf7ce08dab921916f2c723acca0451d8904649bbec16c2076f1455dd1a2'], 'public_key': '91ff7f525ff40874c4f47f0cab42e46e3bf53adad59adef9558ad1b6448f22e2', 'network': 'mainnet', 'path': 'm/44/153/1/0/1'}] """ # Checking transaction if self.transaction is None: raise ValueError("transaction is none, build transaction first.") unsigned_datas = [] for signing_instruction in self.transaction["signing_instructions"]: unsigned_data = dict(datas=signing_instruction["sign_data"]) if "pubkey" in signing_instruction and signing_instruction[ "pubkey"]: unsigned_data.setdefault("public_key", signing_instruction["pubkey"]) if detail: program = get_program( public_key=signing_instruction["pubkey"]) address = get_address(program=program, network=self.network) unsigned_data.setdefault("program", program) unsigned_data.setdefault("address", address) else: unsigned_data.setdefault("network", self.network) else: if detail: unsigned_data.setdefault("public_key", None) unsigned_data.setdefault("program", None) unsigned_data.setdefault("address", None) else: unsigned_data.setdefault("network", self.network) if "derivation_path" in signing_instruction and signing_instruction[ "derivation_path"]: path = indexes_to_path( indexes=signing_instruction["derivation_path"]) if detail: unsigned_data.setdefault( "indexes", signing_instruction["derivation_path"]) unsigned_data.setdefault("path", path) else: if detail: unsigned_data.setdefault("indexes", None) unsigned_data.setdefault("path", None) # Append unsigned datas unsigned_datas.append(unsigned_data) # Returning return unsigned_datas
def build_htlc(self, secret_hash: str, recipient_public_key: str, sender_public_key: str, endblock: int, use_script: bool = False) -> "HTLC": """ Build Bytom Hash Time Lock Contract (HTLC). :param secret_hash: secret sha-256 hash. :type secret_hash: str :param recipient_public_key: Bytom recipient public key. :type recipient_public_key: str :param sender_public_key: Bytom sender public key. :type sender_public_key: str :param endblock: Bytom expiration block height. :type endblock: int :param use_script: Initialize HTLC by using script, default to ``False``. :type use_script: bool :returns: HTLC -- Bytom Hash Time Lock Contract (HTLC) instance. >>> from swap.providers.bytom.htlc import HTLC >>> from swap.providers.bytom.rpc import get_current_block_height >>> from swap.utils import sha256 >>> htlc: HTLC = HTLC(network="mainnet") >>> htlc.build_htlc(secret_hash=sha256("Hello Meheret!"), recipient_public_key="3e0a377ae4afa031d4551599d9bb7d5b27f4736d77f78cac4d476f0ffba5ae3e", sender_public_key="fe6b3fd4458291b19605d92837ae1060cc0237e68022b2eb9faf01a118226212", endblock=get_current_block_height(plus=100), use_script=False) <swap.providers.bytom.htlc.HTLC object at 0x0409DAF0> """ # Checking parameters instances if len(secret_hash) != 64: raise ValueError("Invalid secret hash, length must be 64") if len(recipient_public_key) != 64: raise ValueError( "Invalid Bytom recipient public key, length must be 64") if len(sender_public_key) != 64: raise ValueError( "Invalid Bytom sender public key, length must be 64") if use_script: # Get current working directory path (like linux or unix path). cwd: str = PurePosixPath( os.path.dirname(os.path.realpath(__file__))).__str__().replace( "\\", "/") with open(f"{cwd}/contracts/htlc.equity", "r", encoding="utf-8") as htlc_equity_file: htlc_script: str = "".join(htlc_equity_file.readlines()[-14:]) htlc_equity_file.close() htlc_agreement: List[str, int] = [ secret_hash, recipient_public_key, sender_public_key, endblock ] # Compile HTLC by script self._script = Equity(config[self._network]["bytom-core"])\ .compile_source(htlc_script, htlc_agreement) else: # Compile HTLC by script binary builder: Builder = Builder() builder.add_int(endblock) builder.add_bytes(bytes.fromhex(sender_public_key)) builder.add_bytes(bytes.fromhex(recipient_public_key)) builder.add_bytes(bytes.fromhex(secret_hash)) builder.add_op(OP_DEPTH) builder.add_bytes(bytes.fromhex(config["htlc_script_binary"])) builder.add_op(OP_FALSE) builder.add_op(OP_CHECKPREDICATE) sequence: str = bytes(c_int64(endblock)).rstrip(b'\x00').hex() self._script = dict( program=builder.hex_digest(), opcodes= f"0x{sequence} 0x{sender_public_key} 0x{recipient_public_key} " f"0x{secret_hash} DEPTH 0x{config['htlc_script_binary']} FALSE CHECKPREDICATE" ) self.agreements = { "secret_hash": secret_hash, "recipient": { "public_key": recipient_public_key, "address": get_address( program=get_program(public_key=recipient_public_key), network=self._network, vapor=False) }, "sender": { "public_key": sender_public_key, "address": get_address(program=get_program(public_key=sender_public_key), network=self._network, vapor=False) }, "endblock": endblock } return self
PATH: str = "m/44/153/1/0/1" print("Get XPublic Key:", get_xpublic_key(xprivate_key=XPRIVATE_KEY)) print("Get Expand XPrivate Key:", get_expand_xprivate_key(xprivate_key=XPRIVATE_KEY)) print("Indexes To Path:", indexes_to_path(indexes=INDEXES)) print("Path To Indexes:", path_to_indexes(path=PATH)) print("Get Child XPrivate Key:", get_child_xprivate_key(xprivate_key=XPRIVATE_KEY)) print("Get Child XPublic Key:", get_child_xpublic_key(xpublic_key=XPUBLIC_KEY)) print("Get Private Key:", get_private_key(xprivate_key=XPRIVATE_KEY)) print("Get Public Key:", get_public_key(xpublic_key=XPUBLIC_KEY)) print("Get Program:", get_program(public_key=get_public_key(xpublic_key=XPUBLIC_KEY))) print( "Get Address:", get_address(program=get_program(public_key=get_public_key( xpublic_key=XPUBLIC_KEY)), network="mainnet", vapor=False)) print( "Get Vapor Address:", get_address(program=get_program(public_key=get_public_key( xpublic_key=XPUBLIC_KEY)), network="mainnet", vapor=True))
def unsigned_datas(self, detail: bool = False) -> List[dict]: """ Get Bytom transaction unsigned datas(messages) with instruction. :param detail: Bytom unsigned datas to see detail, defaults to False. :type detail: bool :returns: list -- Bytom transaction unsigned datas. >>> from swap.providers.bytom.htlc import HTLC >>> from swap.providers.bytom.transaction import FundTransaction >>> htlc: HTLC = HTLC(network="mainnet") >>> htlc.build_htlc(secret_hash="3a26da82ead15a80533a02696656b14b5dbfd84eb14790f2e1be5e9e45820eeb", recipient_public_key="3e0a377ae4afa031d4551599d9bb7d5b27f4736d77f78cac4d476f0ffba5ae3e", sender_public_key="fe6b3fd4458291b19605d92837ae1060cc0237e68022b2eb9faf01a118226212", endblock=679208) >>> fund_transaction: FundTransaction = FundTransaction(network="mainnet") >>> fund_transaction.build_transaction(address="bm1qk9vj4jaezlcnjdckds4fkm8fwv5kawmq9qrufx", htlc=htlc, amount=0.1, asset="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", unit="BTM") >>> fund_transaction.unsigned_datas() [{"datas": ["f42a2b6e15585b88da8b34237c7a6fd83af12ee6971813d66cf794a63ebcc16f"], "public_key": "fe6b3fd4458291b19605d92837ae1060cc0237e68022b2eb9faf01a118226212", "network": "mainnet", "path": "m/44/153/1/0/1"}] """ # Check transaction if self._transaction is None: raise ValueError("Transaction is none, build transaction first.") unsigned_datas: List[dict] = [] for signing_instruction in self._transaction["signing_instructions"]: unsigned_data = dict(datas=signing_instruction["sign_data"]) if "pubkey" in signing_instruction and signing_instruction[ "pubkey"]: unsigned_data.setdefault("public_key", signing_instruction["pubkey"]) if detail: program = get_program( public_key=signing_instruction["pubkey"]) address = get_address(program=program, network=self._network) unsigned_data.setdefault("program", program) unsigned_data.setdefault("address", address) else: unsigned_data.setdefault("network", self._network) else: if detail: unsigned_data.setdefault("public_key", None) unsigned_data.setdefault("program", None) unsigned_data.setdefault("address", None) else: unsigned_data.setdefault("network", self._network) if "derivation_path" in signing_instruction and signing_instruction[ "derivation_path"]: path = indexes_to_path( indexes=signing_instruction["derivation_path"]) if detail: unsigned_data.setdefault( "indexes", signing_instruction["derivation_path"]) unsigned_data.setdefault("path", path) else: if detail: unsigned_data.setdefault("indexes", None) unsigned_data.setdefault("path", None) # Append unsigned datas unsigned_datas.append(unsigned_data) return unsigned_datas
from pybytom.wallet.tools import (get_program, get_address) # Choose network mainnet, solonet or testnet NETWORK: str = "mainnet" # Bytom public key PUBLIC_KEY: str = "5b5a06f6fbcb74b58ebb42293808fec6222234df6c97d7c1cff6d857a6024dc2" # Get public key hash public_key_hash = get_public_key_hash(public_key=PUBLIC_KEY) print("Public Key Hash:", public_key_hash) # Get Pay to Public Key Hash(P2PKH) program p2pkh_program = get_p2pkh_program(public_key_hash=public_key_hash) print("P2PKH Program:", p2pkh_program) # Get Pay to Witness Public Key Hash(P2WPKH) program p2wpkh_program = get_p2wpkh_program(public_key_hash=public_key_hash) assert get_program(public_key=PUBLIC_KEY) == p2wpkh_program print("P2WPKH Program:", p2wpkh_program) # Get Pay to Witness Public Key Hash(P2WPKH) address p2wpkh_address = get_p2wpkh_address(public_key_hash=public_key_hash, network=NETWORK, vapor=False) assert get_address(program=get_program(public_key=PUBLIC_KEY), network=NETWORK, vapor=False) == p2wpkh_address print("P2WPKH Address:", p2wpkh_address) # Get Pay to Witness Public Key Hash(P2WPKH) vapor address p2wpkh_vapor_address = get_p2wpkh_address(public_key_hash=public_key_hash, network=NETWORK, vapor=True) assert get_address(program=get_program(public_key=PUBLIC_KEY), network=NETWORK,