<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def approve( self, allowed_address: Address, allowance: TokenAmount, ):
 """ Aprove `allowed_address` to transfer up to `deposit` amount of token. Note: For channel deposit please use the channel proxy, since it does additional validations. """

        # Note that given_block_identifier is not used here as there
        # are no preconditions to check before sending the transaction

        log_details = {
            'node': pex(self.node_address),
            'contract': pex(self.address),
            'allowed_address': pex(allowed_address),
            'allowance': allowance,
        }

        checking_block = self.client.get_checking_block()
        error_prefix = 'Call to approve will fail'
        gas_limit = self.proxy.estimate_gas(
            checking_block,
            'approve',
            to_checksum_address(allowed_address),
            allowance,
        )

        if gas_limit:
            error_prefix = 'Call to approve failed'
            log.debug('approve called', **log_details)
            transaction_hash = self.proxy.transact(
                'approve',
                safe_gas_limit(gas_limit),
                to_checksum_address(allowed_address),
                allowance,
            )

            self.client.poll(transaction_hash)
            receipt_or_none = check_transaction_threw(self.client, transaction_hash)

        transaction_executed = gas_limit is not None
        if not transaction_executed or receipt_or_none:
            if transaction_executed:
                block = receipt_or_none['blockNumber']
            else:
                block = checking_block

            self.proxy.jsonrpc_client.check_for_insufficient_eth(
                transaction_name='approve',
                transaction_executed=transaction_executed,
                required_gas=GAS_REQUIRED_FOR_APPROVE,
                block_identifier=block,
            )

            msg = self._check_why_approved_failed(allowance, block)
            error_msg = f'{error_prefix}. {msg}'
            log.critical(error_msg, **log_details)
            raise RaidenUnrecoverableError(error_msg)

        log.info('approve successful', **log_details)