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())
Beispiel #2
0
    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
Beispiel #3
0
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"]
Beispiel #4
0
    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
Beispiel #5
0
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"]
Beispiel #6
0
    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
Beispiel #7
0
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:",
Beispiel #8
0
    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