private async Task UpdateSwapBalanceAsync() { queryingNotify = "Querying balance ..."; await InvokeAsync(() => { StateHasChanged(); }); lyrReserveBalance = await SwapUtils.GetLyraBalanceAsync(Configuration["network"], swapOptions.CurrentValue.lyrPvk); tlyrReserveBalance = await SwapUtils.GetEthContractBalanceAsync(swapOptions.CurrentValue.ethUrl, swapOptions.CurrentValue.ethContract, swapOptions.CurrentValue.ethPub); // var ethGas = await SwapUtils.EstimateEthTransferFeeAsync(swapOptions.CurrentValue.ethUrl, // swapOptions.CurrentValue.ethContract, swapOptions.CurrentValue.ethPub); // ICoinGeckoClient _client; // _client = CoinGeckoClient.Instance; // const string vsCurrencies = "usd"; // var prices = await _client.SimpleClient.GetSimplePrice(new[] { "ethereum", "lyra" }, new[] { vsCurrencies }); //ethGasFee = (decimal)((double)(ethGas / 10000000000) * prices["ethereum"]["usd"].GetValueOrDefault()); //lyraPrice = (decimal) prices["lyra"]["usd"].Value; queryingNotify = ""; await InvokeAsync(() => { StateHasChanged(); }); }
private async Task UpdateSwapFromBalanceAsync() { if (string.IsNullOrEmpty(_swapFromTokenName)) { _swapFromTokenName = "LYR"; } if (_swapFromTokenName == "LYR") { // get lyr balance fromTokenBalance = walletState.Value.wallet.BaseBalance; } else if (_swapFromTokenName == "TLYR") { fromTokenBalance = 0; fromTokenBalance = await SwapUtils.GetEthContractBalanceAsync(swapOptions.CurrentValue.ethUrl, swapOptions.CurrentValue.ethContract, SelectedAccount); } await InvokeAsync(() => { StateHasChanged(); }); }
public async Task HandleSwap(WebWalletBeginSwapTLYRAction action, IDispatcher dispatcher) { bool IsSuccess = false; try { if (action.fromToken == "LYR" && action.toToken == "TLYR") { var syncResult = await action.wallet.Sync(null); if (syncResult == APIResultCodes.Success) { var sendResult = await action.wallet.Send(action.fromAmount, action.options.lyrPub, "LYR"); if (sendResult.ResultCode == APIResultCodes.Success) { logger.LogInformation($"TokenSwap: first stage is ok for {action.fromAddress}"); var(txHash, result) = await SwapUtils.SendEthContractTokenAsync( action.options.ethUrl, action.options.ethContract, action.options.ethPub, action.options.ethPvk, action.toAddress, new BigInteger(action.toAmount * 100000000), // 10^8 action.gasPrice, action.gasLimit, null); logger.LogInformation($"TokenSwap: second stage for {action.fromAddress} eth tx hash is {txHash} IsSuccess: {result}"); if (!result) { throw new Exception("Eth sending failed."); } IsSuccess = true; } else { throw new Exception("Unable to send from your Lyra wallet."); } } else { throw new Exception("Unable to sync Lyra Wallet."); } } if (action.fromToken == "TLYR" && action.toToken == "LYR") { var(txHash, result) = await SwapUtils.SendEthContractTokenAsync( action.options.ethUrl, action.options.ethContract, action.fromAddress, null, action.options.ethPub, new BigInteger(action.fromAmount * 100000000), // 10^8 action.gasPrice, action.gasLimit, action.metamask); logger.LogInformation($"TokenSwap: first stage for {action.fromAddress} eth tx hash {result} IsSuccess: {result}"); if (result) // test if success transfer { var store = new AccountInMemoryStorage(); var wallet = Wallet.Create(store, "default", "", config["network"], action.options.lyrPvk); var syncResult = await wallet.Sync(client); if (syncResult == APIResultCodes.Success) { var sendResult = await wallet.Send(action.toAmount, action.toAddress, "LYR"); if (sendResult.ResultCode == Lyra.Core.Blocks.APIResultCodes.Success) { IsSuccess = true; } else { throw new Exception("Unable to send from your wallet."); } } else { throw new Exception("Unable to sync Lyra Wallet."); } } else { throw new Exception("Eth sending failed."); } } logger.LogInformation($"TokenSwap: Swapping {action.fromAmount} from {action.fromAddress} to {action.toAddress} is succeed."); dispatcher.Dispatch(new WebWalletSwapTLYRResultAction { Success = IsSuccess }); } catch (Exception ex) { logger.LogInformation($"TokenSwap: Swapping {action.fromAmount} from {action.fromAddress} to {action.toAddress} is failed. Error: {ex}"); dispatcher.Dispatch(new WebWalletSwapTLYRResultAction { Success = false, errMessage = ex.ToString() }); } }
private void UpdateSwapToBalance() { if (walletState.Value.stage == UIStage.SwapToken) { _ = Task.Run(async() => { await UpdateSwapToBalanceForLyraSwapAsync(); }); return; } if (_swapToTokenName == "TLYR") { swapToAddress = SelectedAccount; } else if (_swapToTokenName == "LYR") { swapToAddress = walletState.Value.wallet.AccountId; } if (swapFromCount == 0) { swapToCount = 0; return; } if (swapToAddress == null || _svcFeeCalculationTask != null) { return; } walletState.Value.IsLoading = true; swapToCount = 0; IsDisabled = true; swapFeeDesc = "Calculating swap service fee..."; _svcFeeCalculationTask = Task.Run(async() => { try { ICoinGeckoClient _client; _client = CoinGeckoClient.Instance; const string vsCurrencies = "usd"; var priceTask = _client.SimpleClient.GetSimplePrice(new[] { "ethereum", "lyra" }, new[] { vsCurrencies }); var gasOracleTask = SwapUtils.GetGasOracle(swapOptions.CurrentValue.ethScanApiKey); await Task.WhenAll(priceTask, gasOracleTask); if (priceTask.IsCompletedSuccessfully && gasOracleTask.IsCompletedSuccessfully) { var estFrom = _swapToTokenName == "TLYR" ? swapOptions.CurrentValue.ethPub : SelectedAccount; var estTo = _swapToTokenName == "TLYR" ? SelectedAccount : swapOptions.CurrentValue.ethPub; var estimateGasTask = SwapUtils.EstimateEthTransferFeeAsync(swapOptions.CurrentValue.ethUrl, swapOptions.CurrentValue.ethContract, estFrom, estTo, new BigInteger(swapFromCount), gasOracleTask.Result); await Task.WhenAll(estimateGasTask); if (priceTask.IsCompletedSuccessfully && estimateGasTask.IsCompletedSuccessfully && gasOracleTask.IsCompletedSuccessfully) { var prices = priceTask.Result; var gasOracle = gasOracleTask.Result; var gasLimit = estimateGasTask.Result; EthGasPrice = gasOracle; EthGasLimit = gasLimit; if (_swapToTokenName == "TLYR") { ethGasFee = (decimal)(gasOracle * (int)gasLimit * prices["ethereum"]["usd"] / 1000000000); lyraPrice = (decimal)prices["lyra"]["usd"]; var totalFee = swapFromCount * 0.0001m + 1 + ethGasFee / lyraPrice; var totalfeeInLyra = Math.Round(totalFee, 2); //swapFeeDesc = $"Ethereum Gas price: {gasOracle} Gas limit: {gasLimit} ETH price: ${prices["ethereum"]["usd"]} Lyra price: ${prices["lyra"]["usd"].Value} Final fee ${ethGasFee} in LYR: {feeInLyra}"; swapFeeDesc = $"{totalfeeInLyra} LYR ($ {Math.Round(totalfeeInLyra * lyraPrice, 2)})"; swapToCount = swapFromCount - totalfeeInLyra; } else { var totalFee = swapFromCount * 0.0001m + 1; var totalfeeInLyra = Math.Round(totalFee, 2); swapFeeDesc = $"{totalfeeInLyra} LYR ($ {Math.Round(totalfeeInLyra * lyraPrice, 2)})"; swapToCount = swapFromCount - totalfeeInLyra; } IsDisabled = false; swapFeeDesc = "Estimated OK."; } else { throw new Exception("Can't query fee. Network error."); } } else { throw new Exception("Can't query fee. Network error."); } } catch (Exception ex) { swapFeeDesc = $"Error: {ex.Message}"; } await InvokeAsync(() => { walletState.Value.IsLoading = false; StateHasChanged(); _svcFeeCalculationTask = null; }); }); }
private async Task BeginSwapTLYR(MouseEventArgs e) { IsDisabled = true; swapResultMessage = "Checking for configurations..."; await InvokeAsync(() => { StateHasChanged(); }); // do check swapResultMessage = ""; // check network id CurrentChainName = await metamaskService.GetChainName(); if (Configuration["network"] == "testnet" && CurrentChainName != "Rinkeby Test Network") { swapResultMessage = "Only Rinkeby Test Network is supported for testnet."; } else if (Configuration["network"] == "mainnet" && CurrentChainName != "Ethereum Main Network") { swapResultMessage = "Only Ethereum Main Network is supported for mainnet."; } else if (!EthereumEnabled || !walletState.Value.IsOpening) { swapResultMessage = "Wallet(s) not opening or connected."; } else if (swapFromToken == swapToToken) { swapResultMessage = "No need to swap."; } else if (!((swapFromToken == "LYR" && swapToToken == "TLYR") || (swapFromToken == "TLYR" && swapToToken == "LYR"))) { swapResultMessage = "Unknown token pair"; } else if (swapFromCount < 10) { swapResultMessage = "Swap amount too small. (< 10)"; } else if (swapFromCount > 1000000) { swapResultMessage = "Swap amount too large. (> 1M)"; } else if (swapFromToken == "LYR" && swapFromCount > walletState.Value.wallet.BaseBalance) { swapResultMessage = "Not enough LYR in Lyra Wallet."; } else if (string.IsNullOrWhiteSpace(swapToAddress)) { swapResultMessage = "Not valid swap to address."; } else if (swapToToken == "TLYR" && swapToCount > 0.8m * tlyrReserveBalance) { swapResultMessage = "Reserve account of TLYR is running low. Please contact support."; } else if (swapToToken == "LYR" && swapToCount > 0.8m * lyrReserveBalance) { swapResultMessage = "Reserve account of LYR is running low. Please contact support."; } else if (swapToCount < 1) { swapResultMessage = "Swap to amount too small."; } else if (swapFromToken == "TLYR") { try { var tlyrBalance = await SwapUtils.GetEthContractBalanceAsync(swapOptions.CurrentValue.ethUrl, swapOptions.CurrentValue.ethContract, SelectedAccount); if (tlyrBalance < swapFromCount) { swapResultMessage = "Not enough TLYR in Ethereum Wallet."; } } catch (Exception) { swapResultMessage = "Unable to get TLYR balance."; } } if (!string.IsNullOrEmpty(swapResultMessage)) { IsDisabled = false; await InvokeAsync(() => { StateHasChanged(); }); return; } var mmmsg = swapFromToken == "TLYR" ? "Please open Matamask and confirm transaction." : ""; swapResultMessage = $"Do swapping... {mmmsg} Please wait for a moment... "; walletState.Value.Message = ""; await InvokeAsync(() => { StateHasChanged(); }); var arg = new WebWalletBeginSwapTLYRAction { wallet = walletState.Value.wallet, fromToken = swapFromToken, fromAddress = swapFromToken == "LYR" ? walletState.Value.wallet.AccountId : SelectedAccount, fromAmount = swapFromCount, toToken = swapToToken, toAddress = swapToAddress, toAmount = swapToCount, gasPrice = EthGasPrice, gasLimit = EthGasLimit, options = swapOptions.CurrentValue, metamask = metamaskInterceptor }; logger.LogInformation($"TokenSwap: Begin {arg.fromAmount} from {arg.fromAddress} to {arg.toAddress} amount {arg.toAmount}"); Dispatcher.Dispatch(arg); IsDisabled = true; }