def render(self, template_name, **context_data): network = Network.get_by_name(self.installer_settings.network) required = RequiredAmounts.from_settings(self.installer_settings) context_data.update({ "network": network, "ethereum_required": required.eth, "ethereum_required_after_swap": required.eth_after_swap, "service_token_required": required.service_token, "transfer_token_required": required.transfer_token, "eip20_abi": json.dumps(EIP20_ABI), }) return super().render(template_name, **context_data)
def _run_udc_deposit(self, **kw): try: configuration_file_name = kw.get("configuration_file_name") configuration_file = RaidenConfigurationFile.get_by_filename( configuration_file_name) except (ValueError, KeyError, TypeError) as exc: self._send_error_message(f"Invalid request: {exc}") return try: settings = self.installer_settings required = RequiredAmounts.from_settings(settings) swap_amounts = SwapAmounts.from_settings(settings) service_token = Erc20Token.find_by_ticker( required.service_token.ticker, settings.network) account = configuration_file.account try_unlock(account) w3 = make_web3_provider( configuration_file.ethereum_client_rpc_endpoint, account) service_token_balance = get_token_balance(w3, account, service_token) service_token_deposited = get_token_deposit( w3, account, service_token) if service_token_deposited < required.service_token: swap_amount = swap_amounts.service_token if service_token_balance >= swap_amount: deposit = swap_amount - service_token_deposited else: deposit = service_token_balance self._deposit_to_udc(w3, account, service_token, deposit) else: self._send_status_update( f"Service token deposited at UDC: {service_token_deposited.formatted} is enough" ) time.sleep(5) transfer_token = Erc20Token.find_by_ticker( required.transfer_token.ticker, settings.network) transfer_token_balance = get_token_balance(w3, account, transfer_token) self._redirect_transfer_swap(configuration_file, transfer_token_balance, required) except (json.decoder.JSONDecodeError, KeyError, ExchangeError, ValueError) as exc: self._redirect_after_swap_error(exc, configuration_file.file_name, service_token.ticker)
def get(self, configuration_file_name): configuration_file = RaidenConfigurationFile.get_by_filename( configuration_file_name) network = configuration_file.network.name account = configuration_file.account try_unlock(account) w3 = make_web3_provider( configuration_file.ethereum_client_rpc_endpoint, account) settings = configuration_file.settings required = RequiredAmounts.from_settings(settings) service_token = Erc20Token.find_by_ticker( required.service_token.ticker, network) transfer_token = Erc20Token.find_by_ticker( required.transfer_token.ticker, network) service_token_balance = get_total_token_owned( w3=w3, account=configuration_file.account, token=service_token) transfer_token_balance = get_token_balance( w3=w3, account=configuration_file.account, token=transfer_token) eth_balance = configuration_file.account.get_ethereum_balance(w3) def serialize_balance(balance_amount): return ({ "as_wei": balance_amount.as_wei, "formatted": balance_amount.formatted } if balance_amount else None) self.render_json({ "file_name": configuration_file.file_name, "account": to_checksum_address(configuration_file.account.address), "network": configuration_file.network.name, "balance": { "ETH": serialize_balance(eth_balance), "service_token": serialize_balance(service_token_balance), "transfer_token": serialize_balance(transfer_token_balance), }, "_initial_funding_txhash": configuration_file._initial_funding_txhash, })
def test_create_required_amounts(self): required_amounts = RequiredAmounts.from_settings(self.settings) self.assertEqual( required_amounts.eth, EthereumAmount(Wei(self.settings.ethereum_amount_required)) ) self.assertEqual( required_amounts.eth_after_swap, EthereumAmount(Wei(self.settings.ethereum_amount_required_after_swap)) ) self.assertEqual( required_amounts.service_token, TokenAmount(Wei(self.settings.service_token.amount_required), self.service_token) ) self.assertEqual( required_amounts.transfer_token, TokenAmount(Wei(self.settings.transfer_token.amount_required), self.transfer_token) )
def get(self, configuration_file_name): configuration_file = RaidenConfigurationFile.get_by_filename( configuration_file_name) if get_passphrase() is None: self.render( "account_unlock.html", keystore_file_path=configuration_file.account. keystore_file_path, return_to=f"/account/{configuration_file_name}", ) return keystore_path = configuration_file.configuration_data["keystore-path"] filename = "" for file in glob(f"{keystore_path}/UTC--*"): file_path = Path(file) if file_path.is_file(): keystore_content = json.loads(file_path.read_text()) if (to_canonical_address(keystore_content["address"]) == configuration_file.account.address): filename = os.path.basename(file) break w3 = make_web3_provider( configuration_file.ethereum_client_rpc_endpoint, configuration_file.account) required = RequiredAmounts.from_settings(self.installer_settings) eth_balance = configuration_file.account.get_ethereum_balance(w3) log.info(f"funding tx {configuration_file._initial_funding_txhash}") log.info(f"Checking balance {eth_balance} >= {required.eth}") if eth_balance >= required.eth: configuration_file._initial_funding_txhash = None configuration_file.save() self.render( "account.html", configuration_file=configuration_file, keystore=filename, ramp_api_key=RAMP_API_KEY, )
def _run_swap(self, **kw): try: configuration_file_name = kw.get("configuration_file_name") exchange_name = kw["exchange"] token_amount = kw["amount"] token_ticker = kw["token"] except (ValueError, KeyError, TypeError) as exc: self._send_error_message(f"Invalid request: {exc}") return try: configuration_file = RaidenConfigurationFile.get_by_filename( configuration_file_name) network_name = configuration_file.network.name form = TokenExchangeForm({ "network": [network_name], "exchange": [exchange_name], "token_amount": [token_amount], "token_ticker": [token_ticker], }) if form.validate(): account = configuration_file.account try_unlock(account) w3 = make_web3_provider( configuration_file.ethereum_client_rpc_endpoint, account) token = Erc20Token.find_by_ticker(form.data["token_ticker"], network_name) token_amount = TokenAmount(Wei(form.data["token_amount"]), token) exchange = Exchange.get_by_name(form.data["exchange"])(w3=w3) self._send_status_update(f"Starting swap at {exchange.name}") costs = exchange.calculate_transaction_costs( token_amount, account) needed_funds = costs["total"] exchange_rate = costs["exchange_rate"] balance_before_swap = account.get_ethereum_balance(w3) if needed_funds > balance_before_swap: raise ValueError(( f"Not enough ETH. {balance_before_swap.formatted} available, but " f"{needed_funds.formatted} needed")) self._send_status_update( (f"Best exchange rate found at {exchange.name}: " f"{exchange_rate} / {token_amount.ticker}")) self._send_status_update( f"Trying to acquire {token_amount} at this rate") tx_hash = exchange.buy_tokens(account, token_amount, costs) wait_for_transaction(w3, tx_hash) token_balance = get_token_balance(w3, account, token) balance_after_swap = account.get_ethereum_balance(w3) actual_total_costs = balance_before_swap - balance_after_swap self._send_status_update( f"Swap complete. {token_balance.formatted} available") self._send_status_update(f"Actual costs: {actual_total_costs}") required = RequiredAmounts.from_settings( self.installer_settings) service_token = Erc20Token.find_by_ticker( required.service_token.ticker, network_name) service_token_balance = get_token_balance( w3, account, service_token) total_service_token_balance = get_total_token_owned( w3, account, service_token) transfer_token = Erc20Token.find_by_ticker( required.transfer_token.ticker, network_name) transfer_token_balance = get_token_balance( w3, account, transfer_token) if total_service_token_balance < required.service_token: raise ExchangeError("Exchange was not successful") elif token_ticker == service_token.ticker and service_token_balance > required.service_token: self._deposit_to_udc(w3, account, service_token, service_token_balance) self._redirect_transfer_swap(configuration_file, transfer_token_balance, required) else: for key, error_list in form.errors.items(): error_message = f"{key}: {'/'.join(error_list)}" self._send_error_message(error_message) except (json.decoder.JSONDecodeError, KeyError, ExchangeError, ValueError) as exc: self._redirect_after_swap_error(exc, configuration_file.file_name, token_ticker)