def test_create_address_accounts(dbsession, eth_network_id, eth_service, eth_faux_address, eth_asset_id):
    """Check that we can cerate different accounts under an account."""

    # Create ETH account
    with transaction.manager:
        network = dbsession.query(AssetNetwork).get(eth_network_id)
        address = CryptoAddress(network=network, address=eth_address_to_bin(TEST_ADDRESS))
        asset = dbsession.query(Asset).get(eth_asset_id)
        dbsession.flush()
        account = address.get_or_create_account(asset)
        account_id = account.id

    # We get it reflected back second time
    with transaction.manager:
        address = dbsession.query(CryptoAddress).one()
        asset = dbsession.query(Asset).get(eth_asset_id)
        account = address.get_or_create_account(asset)
        assert account.id == account_id

    # We cannot create double account for the same asset
    with pytest.raises(MultipleAssetAccountsPerAddress):
        with transaction.manager:
            address = dbsession.query(CryptoAddress).one()
            asset = dbsession.query(Asset).get(eth_asset_id)
            address.create_account(asset)
示例#2
0
def test_create_address_accounts(dbsession, eth_network_id, eth_service,
                                 eth_faux_address, eth_asset_id):
    """Check that we can cerate different accounts under an account."""

    # Create ETH account
    with transaction.manager:
        network = dbsession.query(AssetNetwork).get(eth_network_id)
        address = CryptoAddress(network=network,
                                address=eth_address_to_bin(TEST_ADDRESS))
        asset = dbsession.query(Asset).get(eth_asset_id)
        dbsession.flush()
        account = address.get_or_create_account(asset)
        account_id = account.id

    # We get it reflected back second time
    with transaction.manager:
        address = dbsession.query(CryptoAddress).one()
        asset = dbsession.query(Asset).get(eth_asset_id)
        account = address.get_or_create_account(asset)
        assert account.id == account_id

    # We cannot create double account for the same asset
    with pytest.raises(MultipleAssetAccountsPerAddress):
        with transaction.manager:
            address = dbsession.query(CryptoAddress).one()
            asset = dbsession.query(Asset).get(eth_asset_id)
            address.create_account(asset)
def test_withdraw_eth_account(dbsession, eth_service, eth_network_id, eth_asset_id):
    """Withdraw ETHs to an address."""

    # Create ETH holding account under an address
    with transaction.manager:

        # First create the address which holds our account
        network = dbsession.query(AssetNetwork).get(eth_network_id)
        address = CryptoAddress(network=network, address=eth_address_to_bin(TEST_ADDRESS))
        dbsession.flush()

        assert address.id
        assert address.address
        asset = dbsession.query(Asset).get(eth_asset_id)

        # Create an account of ETH tokens on that address
        ca_account = address.create_account(asset)

    # It should have zero balance by default
    with transaction.manager:
        ca_account = dbsession.query(CryptoAddressAccount).one_or_none()
        assert ca_account.account.asset_id == eth_asset_id
        assert ca_account.account.get_balance() == Decimal(0)

    # Faux top up so we have value to withdraw
    with transaction.manager:
        ca_account = dbsession.query(CryptoAddressAccount).one_or_none()
        assert ca_account.account.do_withdraw_or_deposit(Decimal("+10"), "Faux top up")

    # Create withdraw operations
    withdraw_address = eth_address_to_bin(TEST_ADDRESS)
    with transaction.manager:
        ca_account = dbsession.query(CryptoAddressAccount).one_or_none()
        op = ca_account.withdraw(Decimal("10"), withdraw_address, "Bailing out")

        # We withdraw 10 ETHs
        assert op.holding_account.get_balance() == Decimal("10")
        assert op.holding_account.asset == dbsession.query(Asset).get(eth_asset_id)
        assert op.holding_account.transactions.count() == 1
        assert op.holding_account.transactions.first().message == "Bailing out"

        # Check all looks good on sending account
        assert ca_account.account.transactions.count() == 2
        assert ca_account.account.transactions.all()[0].message == "Faux top up"
        assert ca_account.account.transactions.all()[1].message == "Bailing out"
        assert ca_account.account.get_balance() == 0

    def _withdraw_eth(service, dbsession, opid):
        # Mocked withdraw op that always success
        with transaction.manager:
            op = dbsession.query(CryptoOperation).get(opid)
            op.txid = txid_to_bin(TEST_TXID)
            op.mark_complete()

    with mock.patch("websauna.wallet.ethereum.ops.withdraw_eth", new=_withdraw_eth):
        success_op_count, failed_op_count = eth_service.run_waiting_operations()

    # Check that operations have been marked as success
    with transaction.manager:
        ops = list(dbsession.query(CryptoOperation).all())
        assert len(ops) == 1
        assert isinstance(ops[0], CryptoAddressWithdraw)
        assert ops[0].state == CryptoOperationState.success
        assert ops[0].txid == txid_to_bin(TEST_TXID)
示例#4
0
def test_withdraw_eth_account(dbsession, eth_service, eth_network_id,
                              eth_asset_id):
    """Withdraw ETHs to an address."""

    # Create ETH holding account under an address
    with transaction.manager:

        # First create the address which holds our account
        network = dbsession.query(AssetNetwork).get(eth_network_id)
        address = CryptoAddress(network=network,
                                address=eth_address_to_bin(TEST_ADDRESS))
        dbsession.flush()

        assert address.id
        assert address.address
        asset = dbsession.query(Asset).get(eth_asset_id)

        # Create an account of ETH tokens on that address
        ca_account = address.create_account(asset)

    # It should have zero balance by default
    with transaction.manager:
        ca_account = dbsession.query(CryptoAddressAccount).one_or_none()
        assert ca_account.account.asset_id == eth_asset_id
        assert ca_account.account.get_balance() == Decimal(0)

    # Faux top up so we have value to withdraw
    with transaction.manager:
        ca_account = dbsession.query(CryptoAddressAccount).one_or_none()
        assert ca_account.account.do_withdraw_or_deposit(
            Decimal("+10"), "Faux top up")

    # Create withdraw operations
    withdraw_address = eth_address_to_bin(TEST_ADDRESS)
    with transaction.manager:
        ca_account = dbsession.query(CryptoAddressAccount).one_or_none()
        op = ca_account.withdraw(Decimal("10"), withdraw_address,
                                 "Bailing out")

        # We withdraw 10 ETHs
        assert op.holding_account.get_balance() == Decimal("10")
        assert op.holding_account.asset == dbsession.query(Asset).get(
            eth_asset_id)
        assert op.holding_account.transactions.count() == 1
        assert op.holding_account.transactions.first().message == "Bailing out"

        # Check all looks good on sending account
        assert ca_account.account.transactions.count() == 2
        assert ca_account.account.transactions.all(
        )[0].message == "Faux top up"
        assert ca_account.account.transactions.all(
        )[1].message == "Bailing out"
        assert ca_account.account.get_balance() == 0

    def _withdraw_eth(service, dbsession, opid):
        # Mocked withdraw op that always success
        with transaction.manager:
            op = dbsession.query(CryptoOperation).get(opid)
            op.txid = txid_to_bin(TEST_TXID)
            op.mark_complete()

    with mock.patch("websauna.wallet.ethereum.ops.withdraw_eth",
                    new=_withdraw_eth):
        success_op_count, failed_op_count = eth_service.run_waiting_operations(
        )

    # Check that operations have been marked as success
    with transaction.manager:
        ops = list(dbsession.query(CryptoOperation).all())
        assert len(ops) == 1
        assert isinstance(ops[0], CryptoAddressWithdraw)
        assert ops[0].state == CryptoOperationState.success
        assert ops[0].txid == txid_to_bin(TEST_TXID)