print("Estimated Transaction Fee:", estimated_transaction_fee) # Build Bytom advanced transaction unsigned_advanced_transaction.build_transaction( wallet.address(vapor=VAPOR), # address [ spend_utxo(utxo=find_p2wsh_utxo( transaction_id= "049d4c26bb15885572c16e0eefac5b2f4d0fde50eaf90f002272d39507ff315b", network=NETWORK, vapor=VAPOR)) ], # inputs [ control_address(asset=ASSET, amount=0.0001, address=wallet.address(vapor=VAPOR), symbol="BTM") ], # outputs estimated_transaction_fee, # fee 1, # confirmations False, # forbid_chain_tx ) print("\nUnsigned Advanced Transaction Fee:", unsigned_advanced_transaction.fee()) print("Unsigned Advanced Transaction Confirmations:", unsigned_advanced_transaction.confirmations()) print("Unsigned Advanced Transaction Hash:", unsigned_advanced_transaction.hash()) print("Unsigned Advanced Transaction Raw:", unsigned_advanced_transaction.raw())
def build_transaction( self, address: str, transaction_hash: str, asset: Union[str, AssetNamespace] = config["asset"] ) -> "RefundTransaction": """ Build Vapor refund transaction. :param address: Vapor sender wallet address. :type address: str :param transaction_hash: Vapor funded transaction hash/id :type transaction_hash: str :param asset: Vapor asset id, defaults to ``BTM``. :type asset: str, vapor.assets.AssetNamespace :returns: RefundTransaction -- Vapor refund transaction instance. >>> from swap.providers.vapor.transaction import RefundTransaction >>> refund_transaction: RefundTransaction = RefundTransaction(network="mainnet") >>> refund_transaction.build_transaction(address="vp1qk9vj4jaezlcnjdckds4fkm8fwv5kawmqwpnpvs", transaction_hash="37b36d7be5dfda0cc5dc3c918705464ff901dc5eadb6f4f049db03a679e02bfe", asset="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") <swap.providers.vapor.transaction.RefundTransaction object at 0x0409DAF0> """ # Check parameter instances if not is_address(address, self._network): raise AddressError( f"Invalid Vapor sender '{address}' {self._network} address.") # Set address, fee, confirmations and transaction_hash self._address, self._asset, self._confirmations, self._transaction_hash = ( address, (str(asset.ID) if isinstance(asset, AssetNamespace) else asset), config["confirmations"], transaction_hash) # Get transaction self._transaction_detail = get_transaction( transaction_hash=self._transaction_hash, network=self._network) # Find HTLC UTXO self._htlc_utxo = find_p2wsh_utxo(transaction=self._transaction_detail) if self._htlc_utxo is None: raise ValueError( "Invalid transaction id, there is no pay to witness script hash (P2WSH) address." ) self._amount = self._htlc_utxo["amount"] # Estimating transaction fee self._fee = estimate_transaction_fee( address=self._htlc_utxo["address"], amount=self._amount, asset=self._asset, confirmations=self._confirmations, network=self._network) + 60000 # Build transaction self._transaction = build_transaction( address=self._htlc_utxo["address"], transaction=dict(fee=str( amount_unit_converter(amount=self._fee, unit_from="NEU2BTM")), confirmations=self._confirmations, inputs=[spend_utxo(utxo=self._htlc_utxo["id"])], outputs=[ control_address(asset=self._asset, amount=(self._amount - self._fee), address=self._address, vapor=True) ]), network=self._network) # Set transaction type self._type = "vapor_refund_unsigned" return self
def test_transaction(): estimated_transaction_fee: int = estimate_transaction_fee( address=_["wallet"]["vapor_address"]["mainnet"], asset=ASSET, amount=amount_converter(0.0001, "BTM2NEU"), confirmations=1, network=_["network"], vapor=True) assert isinstance(estimated_transaction_fee, int) assert estimated_transaction_fee == 449000 unsigned_transaction: Transaction = Transaction( network=_["network"], vapor=True ).build_transaction( address=_["wallet"]["vapor_address"]["mainnet"], inputs=[ spend_utxo(utxo=find_p2wsh_utxo( transaction_id= "675392fcbc1867e247add457597611717229e5d2c46a53c44e3e61d6ce351474", network=_["network"], vapor=True)) ], outputs=[ control_address(asset=ASSET, amount=amount_converter(0.0001, "BTM2NEU"), address=_["wallet"]["vapor_address"]["mainnet"], symbol="NEU", vapor=True) ], fee=estimated_transaction_fee, confirmations=1, forbid_chain_tx=False) assert unsigned_transaction.fee( ) == _["transaction"]["transaction"]["unsigned"]["fee"] assert unsigned_transaction.confirmations( ) == _["transaction"]["transaction"]["unsigned"]["confirmations"] assert unsigned_transaction.hash( ) == _["transaction"]["transaction"]["unsigned"]["hash"] assert unsigned_transaction.raw( ) == _["transaction"]["transaction"]["unsigned"]["raw"] assert unsigned_transaction.json( ) == _["transaction"]["transaction"]["unsigned"]["json"] assert unsigned_transaction.unsigned_datas( False) == _["transaction"]["transaction"]["unsigned"]["unsigned_datas"] assert unsigned_transaction.signatures( ) == _["transaction"]["transaction"]["unsigned"]["signatures"] signed_transaction = unsigned_transaction.sign( xprivate_key=_["wallet"]["xprivate_key"], indexes=_["wallet"]["indexes"]) assert signed_transaction.fee( ) == _["transaction"]["transaction"]["signed"]["fee"] assert signed_transaction.confirmations( ) == _["transaction"]["transaction"]["signed"]["confirmations"] assert signed_transaction.hash( ) == _["transaction"]["transaction"]["signed"]["hash"] assert signed_transaction.raw( ) == _["transaction"]["transaction"]["signed"]["raw"] assert signed_transaction.json( ) == _["transaction"]["transaction"]["signed"]["json"] assert signed_transaction.unsigned_datas( False) == _["transaction"]["transaction"]["signed"]["unsigned_datas"] assert signed_transaction.signatures( ) == _["transaction"]["transaction"]["signed"]["signatures"]
def build_transaction(self, address: str, htlc: HTLC, amount: int, asset: Union[str, AssetNamespace] = config["asset"], unit: str = config["unit"]) -> "FundTransaction": """ Build Vapor fund transaction. :param address: Vapor sender wallet address. :type address: str :param htlc: Vapor Hash Time Lock Contract (HTLC) instance. :type htlc: str :param amount: Vapor amount to fund. :type amount: int, float :param asset: Vapor asset id, defaults to ``BTM``. :type asset: str, vapor.assets.AssetNamespace :param unit: Vapor unit, default to ``NEU``. :type unit: str :returns: FundTransaction -- Vapor fund transaction instance. >>> 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") <swap.providers.vapor.transaction.FundTransaction object at 0x0409DAF0> """ # Check parameter instances if not is_address(address, self._network): raise AddressError( f"Invalid Vapor sender '{address}' {self._network} address.") if not isinstance(htlc, HTLC): raise TypeError( "Invalid Vapor HTLC instance, only takes Vapor HTLC class") if unit not in ["BTM", "mBTM", "NEU"]: raise UnitError( "Invalid Vapor unit, choose only 'BTM', 'mBTM' or 'NEU' units." ) # Set address, fee and confirmations self._address, self._asset, self._contract_address, self._confirmations, self._amount = ( address, (str(asset.ID) if isinstance(asset, AssetNamespace) else asset), htlc.contract_address(), config["confirmations"], (amount if unit == "NEU" else amount_unit_converter( amount=amount, unit_from=f"{unit}2NEU"))) self._fee = estimate_transaction_fee(address=self._address, amount=self._amount, asset=self._asset, confirmations=self._confirmations, network=self._network) # Build transaction self._transaction = build_transaction( address=self._address, transaction=dict( fee=str( amount_unit_converter(amount=self._fee, unit_from="NEU2BTM")), confirmations=self._confirmations, inputs=[spend_wallet(asset=self._asset, amount=self._amount)], outputs=[ control_address(asset=self._asset, amount=self._amount, address=self._contract_address, vapor=True) ]), network=self._network) # Set transaction type self._type = "vapor_fund_unsigned" return self
def test_advanced_transaction(): estimated_transaction_fee: int = estimate_transaction_fee( address=_["wallet"]["address"]["mainnet"], asset=ASSET, amount=amount_converter(0.0001, "BTM2NEU"), confirmations=1, network=_["network"], vapor=False ) assert isinstance(estimated_transaction_fee, int) assert estimated_transaction_fee == 449000 unsigned_advanced_transaction: AdvancedTransaction = AdvancedTransaction( network=_["network"], vapor=False ).build_transaction( address=_["wallet"]["address"]["mainnet"], inputs=[ spend_utxo( utxo=find_p2wsh_utxo( transaction_id="049d4c26bb15885572c16e0eefac5b2f4d0fde50eaf90f002272d39507ff315b", network=_["network"], vapor=False ) ) ], outputs=[ control_address( asset=ASSET, amount=10_000, address=_["wallet"]["address"]["mainnet"], symbol="NEU", vapor=False ) ], fee=estimated_transaction_fee, confirmations=1, forbid_chain_tx=False ) assert unsigned_advanced_transaction.fee() == _["transaction"]["advanced_transaction"]["unsigned"]["fee"] assert unsigned_advanced_transaction.confirmations() == _["transaction"]["advanced_transaction"]["unsigned"]["confirmations"] assert unsigned_advanced_transaction.hash() == _["transaction"]["advanced_transaction"]["unsigned"]["hash"] assert unsigned_advanced_transaction.raw() == _["transaction"]["advanced_transaction"]["unsigned"]["raw"] assert unsigned_advanced_transaction.json() == _["transaction"]["advanced_transaction"]["unsigned"]["json"] assert unsigned_advanced_transaction.unsigned_datas(False) == _["transaction"]["advanced_transaction"]["unsigned"]["unsigned_datas"] assert unsigned_advanced_transaction.signatures() == _["transaction"]["advanced_transaction"]["unsigned"]["signatures"] signed_advanced_transaction = unsigned_advanced_transaction.sign( xprivate_key=_["wallet"]["xprivate_key"], indexes=_["wallet"]["indexes"] ) assert signed_advanced_transaction.fee() == _["transaction"]["advanced_transaction"]["signed"]["fee"] assert signed_advanced_transaction.confirmations() == _["transaction"]["advanced_transaction"]["signed"]["confirmations"] assert signed_advanced_transaction.hash() == _["transaction"]["advanced_transaction"]["signed"]["hash"] assert signed_advanced_transaction.raw() == _["transaction"]["advanced_transaction"]["signed"]["raw"] assert signed_advanced_transaction.json() == _["transaction"]["advanced_transaction"]["signed"]["json"] assert signed_advanced_transaction.unsigned_datas(False) == _["transaction"]["advanced_transaction"]["signed"]["unsigned_datas"] assert signed_advanced_transaction.signatures() == _["transaction"]["advanced_transaction"]["signed"]["signatures"]
def build_transaction( self, address: str, transaction_hash: str, asset: Union[str, AssetNamespace] = config["asset"] ) -> "RefundTransaction": """ Build Bytom refund transaction. :param address: Bytom sender wallet address. :type address: str :param transaction_hash: Bytom funded transaction hash/id :type transaction_hash: str :param asset: Bytom asset id, defaults to ``BTM``. :type asset: str, bytom.assets.AssetNamespace :returns: RefundTransaction -- Bytom refund transaction instance. >>> from swap.providers.bytom.transaction import RefundTransaction >>> refund_transaction: RefundTransaction = RefundTransaction(network="mainnet") >>> refund_transaction.build_transaction(address="bm1qk9vj4jaezlcnjdckds4fkm8fwv5kawmq9qrufx", transaction_hash="59b1e43b57cba1afa5834eb9886e4a9fba031c9880ce7ae29d32c36f6b47496f", asset="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") <swap.providers.bytom.transaction.RefundTransaction object at 0x0409DAF0> """ # Check parameter instances if not is_address(address, self._network): raise AddressError( f"Invalid Bytom sender '{address}' {self._network} address.") # Set address, fee, confirmations and transaction_hash self._address, self._asset, self._confirmations, self._transaction_hash = ( address, (str(asset.ID) if isinstance(asset, AssetNamespace) else asset), config["confirmations"], transaction_hash) # Get transaction self._transaction_detail = get_transaction( transaction_hash=self._transaction_hash, network=self._network) # Find HTLC UTXO self._htlc_utxo = find_p2wsh_utxo(transaction=self._transaction_detail) if self._htlc_utxo is None: raise ValueError( "Invalid transaction id, there is no pay to witness script hash (P2WSH) address." ) self._amount = self._htlc_utxo["amount"] # Estimating transaction fee self._fee = estimate_transaction_fee( address=self._htlc_utxo["address"], amount=self._amount, asset=self._asset, confirmations=self._confirmations, network=self._network) + 60000 # Build transaction self._transaction = build_transaction( address=self._htlc_utxo["address"], transaction=dict(fee=str( amount_unit_converter(amount=self._fee, unit_from="NEU2BTM")), confirmations=self._confirmations, inputs=[spend_utxo(utxo=self._htlc_utxo["id"])], outputs=[ control_address(asset=self._asset, amount=(self._amount - self._fee), address=self._address, vapor=False) ]), network=self._network) # Set transaction type self._type = "bytom_refund_unsigned" return self
print("Estimated Transaction Fee:", estimated_transaction_fee) # Build Bytom transaction unsigned_transaction.build_transaction( address=wallet.address(vapor=VAPOR), inputs=[ spend_utxo(utxo=find_p2wsh_utxo( transaction_id= "675392fcbc1867e247add457597611717229e5d2c46a53c44e3e61d6ce351474", network=NETWORK, vapor=VAPOR)) ], outputs=[ control_address(asset=ASSET, amount=amount_converter(0.0001, "BTM2NEU"), address=wallet.address(vapor=VAPOR), symbol="NEU", vapor=VAPOR) ], fee=estimated_transaction_fee, confirmations=1) print("\nUnsigned Transaction Fee:", unsigned_transaction.fee()) print("Unsigned Transaction Confirmations:", unsigned_transaction.confirmations()) print("Unsigned Transaction Hash:", unsigned_transaction.hash()) print("Unsigned Transaction Raw:", unsigned_transaction.raw()) # print("Unsigned Transaction Json:", json.dumps(unsigned_transaction.json(), indent=4)) print("Unsigned Transaction Unsigned Datas:", json.dumps(unsigned_transaction.unsigned_datas(detail=False), indent=4)) print("Unsigned Transaction Signatures:",
def build_transaction(self, address: str, recipients: dict, asset: Union[str, AssetNamespace] = config["asset"], unit: str = config["unit"]) -> "NormalTransaction": """ Build Vapor normal transaction. :param address: Vapor sender wallet address. :type address: str :param recipients: Recipients Vapor address and amount. :type recipients: dict :param asset: Vapor asset id, defaults to ``BTM``. :type asset: str, vapor.assets.AssetNamespace :param unit: Vapor unit, default to ``NEU``. :type unit: str :returns: NormalTransaction -- Vapor normal transaction instance. >>> from swap.providers.vapor.transaction import NormalTransaction >>> normal_transaction: NormalTransaction = NormalTransaction(network="mainnet") >>> normal_transaction.build_transaction(address="vp1q9ndylx02syfwd7npehfxz4lddhzqsve2za23ag", recipients={"vp1qf78sazxs539nmzztq7md63fk2x8lew6ed2gu5rnt9um7jerrh07qcyvk37": 10000000}, asset="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") <swap.providers.vapor.transaction.NormalTransaction object at 0x0409DAF0> """ # Check parameter instances if not is_address(address, self._network): raise AddressError(f"Invalid Vapor sender '{address}' {self._network} address.") if unit not in ["BTM", "mBTM", "NEU"]: raise UnitError("Invalid Vapor unit, choose only 'BTM', 'mBTM' or 'NEU' units.") # Set address, fee and confirmations self._address, self._asset, self._confirmations, inputs, outputs, self._amount = ( address, (str(asset.ID) if isinstance(asset, AssetNamespace) else asset), config["confirmations"], [], [], ( sum(recipients.values()) if unit == "NEU" else amount_unit_converter( amount=sum(recipients.values()), unit_from=f"{unit}2NEU" ) ) ) amount: int = get_balance(self._address, self._asset) if amount < self._amount: raise BalanceError( "Insufficient spend UTXO's", "you don't have enough amount." ) self._fee = estimate_transaction_fee( address=self._address, amount=self._amount, asset=self._asset, confirmations=self._confirmations, network=self._network ) if amount < (self._amount + self._fee): raise BalanceError( f"You don't have enough amount to pay '{self._fee}' NEU fee", f"you can spend maximum '{amount - self._fee}' NEU amount." ) # Outputs action for _address, _amount in recipients.items(): if not is_address(_address, self._network): raise AddressError(f"Invalid Vapor recipients '{_address}' {self._network} address.") outputs.append(control_address( asset=self._asset, address=_address, amount=_amount, vapor=True )) # Build transaction self._transaction = build_transaction( address=self._address, transaction=dict( fee=str(amount_unit_converter( amount=self._fee, unit_from="NEU2BTM" )), confirmations=self._confirmations, inputs=[spend_wallet( asset=self._asset, amount=self._amount )], outputs=outputs ), network=self._network ) # Set transaction type self._type = "vapor_normal_unsigned" return self