def withdraw_eth(web3: Web3, dbsession: Session, opid: UUID): """Perform ETH withdraw operation from the wallet.""" @retryable(tm=dbsession.transaction_manager) def prepare_withdraw(): # Check everyting looks sane op = dbsession.query(CryptoOperation).get(opid) assert op.crypto_account.id assert op.crypto_account.account.id assert op.holding_account.id assert op.holding_account.get_balance() > 0 assert op.external_address assert op.required_confirmation_count # Should be set by the creator address = bin_to_eth_address(op.crypto_account.address.address) # How much we are withdrawing amount = op.holding_account.transactions.one().amount op.mark_performed() # Don't pick this to action list anymore gas = op.other_data.get("gas") data = op.other_data.get("data") return address, amount, op.external_address, gas, data @retryable(tm=dbsession.transaction_manager) def close_withdraw(): # Fill in details. # Block number will be filled in later, when confirmation updater picks a transaction receipt for this operation. op = dbsession.query(CryptoOperation).get(opid) op.txid = txid_to_bin(txid) op.block = None op.mark_broadcasted() address, amount, external_address, gas, data = prepare_withdraw() # Do actual network communications outside the transaction, # so we avoid double withdraws in the case transaction is retried wallet = HostedWallet.get(web3, address) txid = wallet.withdraw(bin_to_eth_address(external_address), amount, max_gas=gas, data=data) close_withdraw()
def withdraw_token(web3: Web3, dbsession: Session, opid: UUID): """Perform token withdraw operation from the wallet.""" @retryable(tm=dbsession.transaction_manager) def prepare_withdraw(): # Check everyting looks sane op = dbsession.query(CryptoOperation).get(opid) assert op.crypto_account.id assert op.crypto_account.account.id assert op.holding_account.id assert op.holding_account.get_balance() > 0 assert op.external_address assert op.required_confirmation_count # Should be set by the creator asset = op.holding_account.asset assert asset.asset_class == AssetClass.token from_address = bin_to_eth_address(op.crypto_account.address.address) to_address = bin_to_eth_address(op.external_address) asset_address = bin_to_eth_address(asset.external_id) # How much we are withdrawing amount = op.holding_account.transactions.one().amount op.mark_performed() # Don't try to pick this op automatically again return from_address, to_address, asset_address, amount @retryable(tm=dbsession.transaction_manager) def close_withdraw(): # Fill in details. # Block number will be filled in later, when confirmation updater picks a transaction receipt for this operation. op = dbsession.query(CryptoOperation).get(opid) op.txid = txid_to_bin(txid) op.block = None op.mark_broadcasted() from_address, to_address, asset_address, amount = prepare_withdraw() wallet = HostedWallet.get(web3, from_address) token = Token.get(web3, asset_address) amount = token.validate_transfer_amount(amount) # Perform actual transfer outside retryable transaction # boundaries to avoid double withdrwa txid = wallet.execute(token.contract, "transfer", [to_address, amount]) close_withdraw()
def withdraw_eth(web3: Web3, dbsession: Session, opid: UUID): """Perform ETH withdraw operation from the wallet.""" @retryable(tm=dbsession.transaction_manager) def prepare_withdraw(): # Check everyting looks sane op = dbsession.query(CryptoOperation).get(opid) assert op.crypto_account.id assert op.crypto_account.account.id assert op.holding_account.id assert op.holding_account.get_balance() > 0 assert op.external_address assert op.required_confirmation_count # Should be set by the creator address = bin_to_eth_address(op.crypto_account.address.address) # How much we are withdrawing amount = op.holding_account.transactions.one().amount op.mark_performed() # Don't pick this to action list anymore return address, amount, op.external_address @retryable(tm=dbsession.transaction_manager) def close_withdraw(): # Fill in details. # Block number will be filled in later, when confirmation updater picks a transaction receipt for this operation. op = dbsession.query(CryptoOperation).get(opid) op.txid = txid_to_bin(txid) op.block = None op.mark_broadcasted() address, amount, external_address = prepare_withdraw() # Do actual network communications outside the transaction, # so we avoid double withdraws in the case transaction is retried wallet = HostedWallet.get(web3, address) txid = wallet.withdraw(bin_to_eth_address(external_address), amount) close_withdraw()
def get_wallet(web3, address): return HostedWallet.get(web3, address)