Esempio n. 1
0
    def get(self, configuration_file_name):
        # Returns the highest estimate of ETH needed to get required service token amount
        configuration_file = RaidenConfigurationFile.get_by_filename(
            configuration_file_name)
        account = configuration_file.account
        w3 = make_web3_provider(
            configuration_file.ethereum_client_rpc_endpoint, account)
        required = RequiredAmounts.for_network(configuration_file.network.name)

        kyber = Kyber(w3=w3)
        uniswap = Uniswap(w3=w3)

        highest_cost = 0
        for exchange in (kyber, uniswap):
            exchange_costs = exchange.calculate_transaction_costs(
                required.service_token, account)
            if not exchange_costs:
                continue
            total_cost = exchange_costs["total"].as_wei
            highest_cost = max(highest_cost, total_cost)

        estimated_cost = EthereumAmount(Wei(highest_cost))
        self.render_json({
            "dex_swap_RDN": {
                "as_wei": estimated_cost.as_wei,
                "formatted": estimated_cost.formatted,
            }
        })
Esempio n. 2
0
    def _run_launch(self, **kw):
        configuration_file_name = kw.get("configuration_file_name")
        configuration_file = RaidenConfigurationFile.get_by_filename(
            configuration_file_name)
        network_name = configuration_file.network.name
        raiden_client = RaidenClient.get_client(network_name)
        required = RequiredAmounts.for_network(network_name)

        if not raiden_client.is_installed:
            self._send_status_update(
                f"Downloading and installing raiden {raiden_client.release}")
            raiden_client.install()
            self._send_status_update("Installation complete")

        account = configuration_file.account
        w3 = make_web3_provider(
            configuration_file.ethereum_client_rpc_endpoint, account)
        service_token = Erc20Token.find_by_ticker(
            required.service_token.ticker, network_name)

        service_token_balance = get_token_balance(w3=w3,
                                                  account=account,
                                                  token=service_token)
        service_token_in_deposit = get_token_deposit(w3=w3,
                                                     account=account,
                                                     token=service_token)
        if service_token_balance.as_wei and service_token_in_deposit < required.service_token:
            self._send_status_update(
                f"Making deposit of {service_token_balance.formatted} for Raiden Services"
            )
            deposit_service_tokens(w3=w3,
                                   account=account,
                                   token=service_token,
                                   amount=service_token_balance.as_wei)
            service_token_deposited = get_token_deposit(w3=w3,
                                                        account=account,
                                                        token=service_token)
            self._send_status_update(
                f"Amount deposited at UDC: {service_token_deposited.formatted}"
            )

        self._send_status_update(
            "Launching Raiden, this might take a couple of minutes, do not close the browser"
        )

        if not raiden_client.is_running:
            raiden_client.launch(configuration_file)

        try:
            raiden_client.wait_for_web_ui_ready(
                status_callback=lambda stat: log.info(str(stat)))
            self._send_task_complete("Raiden is ready!")
            self._send_redirect(raiden_client.WEB_UI_INDEX_URL)
        except (RaidenClientError, RuntimeError) as exc:
            self._send_error_message(f"Raiden process failed to start: {exc}")
            raiden_client.kill()
Esempio n. 3
0
    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)

        required = RequiredAmounts.for_network(network)
        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({
            "url":
            self.reverse_url("api-configuration-detail",
                             configuration_file.file_name),
            "file_name":
            configuration_file.file_name,
            "account_page_url":
            self.reverse_url("account", configuration_file.file_name),
            "account":
            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,
        })
Esempio n. 4
0
 def render(self, template_name, **context_data):
     configuration_file = context_data.get('configuration_file')
     if configuration_file:
         network = configuration_file.network
     else:
         network = Network.get_by_name(default_settings.network)
     required = RequiredAmounts.for_network(network.name)
     context_data.update({
         "network": network,
         "ethereum_required": required.eth,
         "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)
Esempio n. 5
0
    def get(self, configuration_file_name):
        configuration_file = RaidenConfigurationFile.get_by_filename(
            configuration_file_name)
        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_checksum_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.for_network(configuration_file.network.name)
        eth_balance = configuration_file.account.get_ethereum_balance(w3)
        log.info(f"Checking balance {eth_balance} > {required.eth}")
        if eth_balance < required.eth:
            log.info(
                f"funding tx {configuration_file._initial_funding_txhash}")
            if configuration_file._initial_funding_txhash is not None:
                return self.render(
                    "account.html",
                    configuration_file=configuration_file,
                    keystore=filename,
                )
        else:
            configuration_file._initial_funding_txhash = None
            configuration_file.save()

        if PASSPHRASE is not None:
            self.render("account.html",
                        configuration_file=configuration_file,
                        keystore=filename)
        else:
            self.render(
                "account_unlock.html",
                keystore_file_path=configuration_file.account.
                keystore_file_path,
                return_to=f"/account/{configuration_file_name}",
            )
Esempio n. 6
0
    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
                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")
                self._send_status_update(
                    f"maximal costs estimated: {needed_funds} ")

                transaction_receipt = exchange.buy_tokens(
                    account, token_amount, costs)
                block_with_transaction = transaction_receipt["blockNumber"]
                current_block = w3.eth.blockNumber

                while current_block < block_with_transaction:
                    log.debug("wait for block with transaction to be fetched")
                    current_block = w3.eth.blockNumber
                    time.sleep(1)

                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.for_network(network_name)
                service_token = Erc20Token.find_by_ticker(
                    required.service_token.ticker, network_name)
                service_token_balance = get_token_balance(
                    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)
                time.sleep(2)

                if service_token_balance < required.service_token:
                    self._send_redirect(
                        self.reverse_url("swap", configuration_file.file_name,
                                         service_token.ticker))
                elif transfer_token_balance < required.transfer_token:
                    self._send_redirect(
                        self.reverse_url("swap", configuration_file.file_name,
                                         transfer_token.ticker))
                else:
                    self._send_redirect(
                        self.reverse_url("launch",
                                         configuration_file.file_name))
            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._send_error_message(str(exc))
Esempio n. 7
0
    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")

                transaction_receipt = exchange.buy_tokens(
                    account, token_amount, costs)
                wait_for_transaction(w3, transaction_receipt)

                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.for_network(network_name)
                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 service_token_balance.as_wei > 0:

                    self._send_status_update(
                        f"Making deposit of {service_token_balance.formatted} to the User Deposit Contract"
                    )
                    self._send_status_update(f"This might take a few minutes")
                    transaction_receipt = deposit_service_tokens(
                        w3=w3,
                        account=account,
                        token=service_token,
                        amount=service_token_balance.as_wei,
                    )
                    wait_for_transaction(w3, transaction_receipt)
                    service_token_deposited = get_token_deposit(
                        w3=w3, account=account, token=service_token)
                    self._send_status_update(
                        f"Total amount deposited at UDC: {service_token_deposited.formatted}"
                    )

                if transfer_token_balance < required.transfer_token:
                    redirect_url = self.reverse_url(
                        "swap", configuration_file.file_name,
                        transfer_token.ticker)
                    next_page = "Moving on to exchanging DAI ..."

                else:
                    redirect_url = self.reverse_url(
                        "launch", configuration_file.file_name)
                    next_page = "You are ready to launch Raiden! ..."

                self._send_summary(
                    ["Congratulations! Swap Successful!", next_page],
                    icon=token_ticker)
                time.sleep(5)
                self._send_redirect(redirect_url)
            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._send_error_message(str(exc))
            redirect_url = self.reverse_url("swap",
                                            configuration_file.file_name,
                                            token_ticker)
            next_page = f"Try again to exchange {token_ticker}..."
            self._send_summary(["Transaction failed",
                                str(exc), next_page],
                               icon="error")
            time.sleep(5)
            self._send_redirect(redirect_url)