/// <summary> /// Converts total supply from ethereum format to Lykke's number of coins /// </summary> /// <param name="token"> /// Instance of Erc20Token. /// </param> /// <returns> /// String instance, that repesents total supply in Lykke's format. /// </returns> private static string GetNumberOfCoins(Erc20Token token) { if (string.IsNullOrEmpty(token.TokenTotalSupply)) { return(string.Empty); } else { var tokenDecimals = token.TokenDecimals ?? 0; if (tokenDecimals == 0) { return(token.TokenTotalSupply); } string numberOfCoins; if (tokenDecimals >= token.TokenTotalSupply.Length) { numberOfCoins = token.TokenTotalSupply.PadLeft(tokenDecimals + 1, '0'); numberOfCoins = numberOfCoins.Insert(numberOfCoins.Length - tokenDecimals, "."); } else { numberOfCoins = token.TokenTotalSupply.Insert(token.TokenTotalSupply.Length - tokenDecimals, "."); } numberOfCoins = numberOfCoins.TrimEnd('0').TrimEnd('.'); return(numberOfCoins); } }
private async Task ProcessMessageAsync(Erc20ContractCreatedMessage arg) { _log.Info($"Got Erc20ContractCreatedMessage: {arg.Address} "); var token = new Erc20Token { Address = arg.Address, AssetId = null, BlockHash = arg.BlockHash, BlockTimestamp = arg.BlockTimestamp, DeployerAddress = arg.DeployerAddress, TokenDecimals = (int?)arg.TokenDecimals, TokenName = arg.TokenName, TokenSymbol = arg.TokenSymbol, TokenTotalSupply = arg.TokenTotalSupply, TransactionHash = arg.TransactionHash }; // todo: refactor into event generation + projection logic var existingContract = await _erc20TokenService.GetByTokenAddressAsync(token.Address); if (existingContract == null) { await _erc20TokenService.AddAsync(token); } }
public async Task <IReadOnlyList <BlockchainBalanceResult> > GetBalancesAsync(string address) { var balances = new List <BlockchainBalanceResult>(); object response = await _retryPolicy.ExecuteAsync(() => _ethereumServiceClient.ApiErc20BalancePostAsync(new GetErcBalance(address))); if (response is ApiException ex) { _log.Error(message: ex.Error?.Message, context: ex.ToJson()); throw new WalletAddressBalanceException(BlockchainType.EthereumIata, address); } if (response is AddressTokenBalanceContainerResponse result) { foreach (AddressTokenBalanceResponse balanceResponse in result.Balances) { Erc20Token token = await _assetsService.Erc20TokenGetByAddressAsync(balanceResponse.Erc20TokenAddress); if (string.IsNullOrEmpty(token?.AssetId)) { continue; } Asset asset = await _assetsLocalCache.GetAssetByIdAsync(token.AssetId); if (asset == null) { continue; } balances.Add(new BlockchainBalanceResult { AssetId = asset.Id, Balance = balanceResponse.Balance.FromContract(asset.MultiplierPower, asset.Accuracy) }); } return(balances); } throw new UnrecognizedApiResponse(response?.GetType().FullName); }
public async Task Handle(TransferEvent transferEvent) { if (transferEvent == null) { return; } Erc20Token token = await _assetsService.Erc20TokenGetByAddressAsync(transferEvent.TokenAddress); if (token == null) { throw new UnknownErc20TokenException(transferEvent.TokenAddress); } Asset asset = await _assetsService.AssetGetAsync(token.AssetId); if (asset == null) { throw new UnknownErc20AssetException(token.AssetId); } switch (transferEvent.SenderType) { case SenderType.Customer: var inboundTransactionRequest = Mapper.Map <RegisterInboundTxModel>( transferEvent, opt => { opt.Items["AssetId"] = asset.DisplayId; opt.Items["AssetMultiplier"] = asset.MultiplierPower; opt.Items["AssetAccuracy"] = asset.Accuracy; }); await _log.LogPayInternalExceptionIfAny(() => _payInternalClient.RegisterEthereumInboundTransactionAsync(inboundTransactionRequest)); break; case SenderType.EthereumCore: switch (transferEvent.EventType) { case EventType.Started: var outboundTransactionRequest = Mapper.Map <RegisterOutboundTxModel>( transferEvent, opt => { opt.Items["AssetId"] = asset.DisplayId; opt.Items["AssetMultiplier"] = asset.MultiplierPower; opt.Items["AssetAccuracy"] = asset.Accuracy; }); await _log.LogPayInternalExceptionIfAny(() => _payInternalClient .RegisterEthereumOutboundTransactionAsync(outboundTransactionRequest)); break; case EventType.Failed: await _log.LogPayInternalExceptionIfAny(() => _payInternalClient.FailEthereumOutboundTransactionAsync( Mapper.Map <FailOutboundTxModel>(transferEvent))); break; case EventType.Completed: await _log.LogPayInternalExceptionIfAny(() => _payInternalClient.CompleteEthereumOutboundTransactionAsync( Mapper.Map <CompleteOutboundTxModel>(transferEvent, opt => { opt.Items["AssetMultiplier"] = asset.MultiplierPower; opt.Items["AssetAccuracy"] = asset.Accuracy; }))); break; case EventType.NotEnoughFunds: await _log.LogPayInternalExceptionIfAny(() => _payInternalClient.FailEthereumOutboundTransactionAsync( Mapper.Map <NotEnoughFundsOutboundTxModel>(transferEvent))); break; default: throw new UnexpectedEthereumEventTypeException(transferEvent.EventType); } break; default: throw new UnexpectedEthereumTransferTypeException(transferEvent.SenderType); } }
public async Task <IActionResult> Update([FromBody] Erc20Token token) { await _erc20TokenService.UpdateAsync(token); return(NoContent()); }
public async Task <IActionResult> Add([FromBody] Erc20Token token) { await _erc20TokenService.AddAsync(token); return(Ok()); }
private static IEnumerable <string> CreateAssets(IEnumerable <ContractMetadata> contracts, bool skipTransferCheck) { var assetIds = new ConcurrentBag <string>(); ResetOutputCounter(); Console.WriteLine("Creating assets..."); Parallel.ForEach(contracts, contract => { var operationResult = ""; var operationSucceeded = true; try { var tokenAddress = contract.Address.ToLowerInvariant(); var erc20Token = _assetsService.Erc20TokenGetByAddress(tokenAddress); if (erc20Token == null) { erc20Token = new Erc20Token { Address = tokenAddress }; if (!skipTransferCheck) { if (!ContractHasOrCallsTransferMethod(contract)) { operationResult = "transfer method not detected"; operationSucceeded = false; } } if (operationSucceeded) { if (TryGetTokenDecimals(contract, out var tokenDecimals)) { erc20Token.TokenDecimals = tokenDecimals; } else { operationResult = "can not get token decimals"; operationSucceeded = false; } } if (operationSucceeded) { if (TryGetTokenSymbol(contract, out var tokenSymbol)) { erc20Token.TokenName = GetTokenName(contract, tokenSymbol); erc20Token.TokenSymbol = tokenSymbol; } else { operationResult = "can not get token symbol"; operationSucceeded = false; } } if (operationSucceeded) { erc20Token.TokenTotalSupply = GetTokenTotalSupply(contract); } // Bug workaround try { _assetsService.Erc20TokenAdd(erc20Token); } catch (HttpOperationException e) when(e.Response.StatusCode == HttpStatusCode.OK) { } } if (operationSucceeded) { var assetId = contract.AssetId; Asset asset = null; bool updateAsset = !string.IsNullOrEmpty(contract.AssetId); if (updateAsset) { asset = _assetsService.AssetGet(contract.AssetId); if (asset == null) { Console.WriteLine($"Wrong assetId {contract.AssetId}"); return; } } if (!updateAsset && string.IsNullOrEmpty(assetId)) { asset = _assetsService.Erc20TokenCreateAsset(contract.Address); assetId = asset.Id; operationResult = $"asset {assetId} created"; } else { operationResult = "asset already exists"; } if (updateAsset) { var oldTokens = _assetsService.Erc20TokenGetBySpecification(new Erc20TokenSpecification() { Ids = new List <string>() { assetId } }); var oldToken = oldTokens.Items?.FirstOrDefault(); if (oldToken != null) { oldToken.AssetId = null; _assetsService.Erc20TokenUpdate(oldToken); } asset.BlockChainAssetId = tokenAddress; erc20Token = erc20Token ?? _assetsService.Erc20TokenGetByAddress(tokenAddress); erc20Token.AssetId = assetId; asset.Blockchain = Blockchain.Ethereum; asset.Type = AssetType.Erc20Token; _assetsService.AssetUpdate(asset); _assetsService.Erc20TokenUpdate(erc20Token); } else { assetIds.Add(assetId); } } } catch (Exception e) { operationResult = e.ToOperationResult(); operationSucceeded = false; } OutputOperationResult(contract.Address, operationResult, operationSucceeded); }); return(assetIds); }