Ejemplo n.º 1
0
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()
Ejemplo n.º 2
0
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()
Ejemplo n.º 3
0
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()
Ejemplo n.º 4
0
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()
Ejemplo n.º 5
0
def get_wallet(web3, address):
    return HostedWallet.get(web3, address)