public async Task <(string, string, Error)> GenerateOrGetAddressIdAsync(string bitgoCoin, string bitgoWalletId, string label) { var coin = await GetCoin(bitgoCoin); var addresses = await _bitgoClient.Get(coin.IsMainNet).GetAddressesAsync(bitgoCoin, bitgoWalletId, label, 50); if (addresses.Data.TotalAddressCount > 0) { return(addresses.Data.Addresses.Last().AddressId, addresses.Data.Addresses.Last().Label, null); } var newAddress = await _bitgoClient.Get(coin.IsMainNet).CreateAddressAsync(bitgoCoin, bitgoWalletId, label); return(newAddress.Data?.AddressId, newAddress.Data?.Label, newAddress.Error); }
public async Task HandledDepositAsync(SignalBitGoTransfer transferId) { transferId.AddToActivityAsJsonTag("bitgo signal"); _logger.LogInformation("Request to handle transfer from BitGo: {transferJson}", JsonConvert.SerializeObject(transferId)); var(brokerId, assetSymbol) = _assetMapper.BitgoCoinToAsset(transferId.Coin, transferId.WalletId); if (string.IsNullOrEmpty(brokerId) || string.IsNullOrEmpty(assetSymbol)) { _logger.LogWarning("Cannot handle BitGo deposit, asset do not found {transferJson}", JsonConvert.SerializeObject(transferId)); return; } var coin = _bitgoCoinReader.Get(BitgoCoinEntity.GeneratePartitionKey(), BitgoCoinEntity.GenerateRowKey(transferId.Coin)); var transferResp = await _bitgoClient.Get(coin.IsMainNet) .GetTransferAsync(transferId.Coin, transferId.WalletId, transferId.TransferId); var transfer = transferResp.Data; if (transfer == null) { _logger.LogWarning("Cannot handle BitGo deposit, transfer do not found {transferJson}", JsonConvert.SerializeObject(transferId)); Activity.Current?.SetStatus(Status.Error); return; } transfer.AddToActivityAsJsonTag("bitgo-transfer"); _logger.LogInformation("Transfer from BitGo: {transferJson}", JsonConvert.SerializeObject(transfer)); var requirement = _assetMapper.GetRequiredConfirmations(transfer.Coin); if (transfer.Confirmations < requirement) { _logger.LogError( $"Transaction do not has enough conformations. Transaction has: {transfer.Confirmations}, requirement: {requirement}"); Activity.Current?.SetStatus(Status.Error); throw new Exception( $"Transaction do not has enough conformations. Transaction has: {transfer.Confirmations}, requirement: {requirement}"); } if (!_assetMapper.IsWalletEnabled(transfer.Coin, transfer.WalletId)) { _logger.LogError( "Transfer {transferIdString} from BitGo is skipped, Wallet do not include in enabled wallet list", transfer.TransferId); Activity.Current?.SetStatus(Status.Error); return; } foreach (var entryGroup in transfer.Entries .Where(e => e.Value > 0 && !string.IsNullOrEmpty(e.Label) && e.WalletId == transferId.WalletId && (e.Token == null || e.Token == transferId.Coin)) .GroupBy(e => e.Label)) { var label = entryGroup.Key; var wallet = _walletMapper.BitgoLabelToWallet(label); if (wallet == null) { _logger.LogWarning("Cannot found wallet for transfer entry with label={label} address={address}", label, entryGroup.First().Address); continue; } wallet.WalletId.AddToActivityAsTag("walletId"); wallet.ClientId.AddToActivityAsTag("clientId"); var bitgoAmount = entryGroup.Sum(e => e.Value); var meAmount = _assetMapper.ConvertAmountFromBitgo(transferId.Coin, bitgoAmount); var accuracy = _assetsDictionary.GetAssetById(new AssetIdentity() { Symbol = assetSymbol, BrokerId = wallet.BrokerId }).Accuracy; var roundedAmount = Math.Round(meAmount, accuracy, MidpointRounding.ToNegativeInfinity); try { await using var ctx = DatabaseContext.Create(_dbContextOptionsBuilder); await ctx.InsertAsync(new DepositEntity { BrokerId = wallet.BrokerId, WalletId = wallet.WalletId, ClientId = wallet.ClientId, TransactionId = $"{transfer.TransferId}:{wallet.WalletId}", Amount = (decimal)roundedAmount, AssetSymbol = assetSymbol, Comment = $"Bitgo transfer [{transferId.Coin}:{transferId.WalletId}] entry label='{label}', count entry={entryGroup.Count()}", Integration = "BitGo", Txid = transfer.TxId, Status = DepositStatus.New, EventDate = DateTime.UtcNow, UpdateDate = DateTime.UtcNow, FeeAmount = 0, FeeAssetSymbol = assetSymbol, CardLast4 = string.Empty }); } catch (Exception e) { Console.WriteLine(e); throw; } } _logger.LogInformation("Deposit request from BitGo {transferIdString} is handled", transfer.TransferId); }