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)
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)