private DataTransaction MapTransaction(
     string key,
     EthereumTransactionHash hash,
     BloxyTokenTransfer summary,
     EthplorerTransaction transaction)
 {
     return(new DataTransaction()
     {
         Address = key,
         Hash = hash,
         BlockNumber = transaction.BlockNumber,
         Confirmations = transaction.Confirmations,
         ConfirmedAt = summary.ConfirmedAt.UtcDateTime,
         Sender = string.IsNullOrWhiteSpace(transaction.From)
             ? EthereumAddress.Empty.Address
             : transaction.From,
         Recipient = string.IsNullOrWhiteSpace(transaction.To)
             ? EthereumAddress.Empty.Address
             : transaction.To,
         Input = transaction.Input,
         Gas = transaction.GasUsed,
         GasLimit = transaction.GasLimit,
         Eth = transaction.Value,
         Success = transaction.Success
     });
 }
        public async Task <DataTransaction> GetTransactionAsync(Symbol symbol, EthereumTransactionHash hash)
        {
            var key = dataKeyProvider.GetKey(symbol);

            var response = await DynamoDB.GetItemAsync(
                TableName,
                new Dictionary <string, AttributeValue>()
            {
                [nameof(DataTransaction.Address)] = new AttributeValue(key),
                [nameof(DataTransaction.Hash)]    = new AttributeValue(hash)
            },
                CancellationToken);

            if (response.HttpStatusCode != HttpStatusCode.OK)
            {
                throw new HttpRequestException($"Response code did not indicate success: {response.HttpStatusCode}");
            }

            if (response.Item.Any())
            {
                return(Map(response.Item));
            }

            return(null);
        }
        public async Task <DataOperation> GetOperationAsync(EthereumTransactionHash hash, int order)
        {
            var response = await DynamoDB.GetItemAsync(
                TableName,
                new Dictionary <string, AttributeValue>()
            {
                [nameof(DataOperation.Hash)]  = new AttributeValue(hash),
                [nameof(DataOperation.Order)] = new AttributeValue()
                {
                    N = order.ToString()
                }
            },
                CancellationToken);

            if (response.HttpStatusCode != HttpStatusCode.OK)
            {
                throw new HttpRequestException($"Response code did not indicate success: {response.HttpStatusCode}");
            }

            if (response.Item.Any())
            {
                return(Map(response.Item));
            }

            return(null);
        }
 private DataOperation MapOperation(EthereumTransactionHash hash, EthplorerOperation operation, int order)
 {
     return(new DataOperation()
     {
         Hash = hash,
         Order = order,
         Type = operation.Type.ToUpper(),
         Address = operation.Address,
         Sender = string.IsNullOrWhiteSpace(operation.From)
             ? EthereumAddress.Empty.Address
             : operation.From,
         Recipient = string.IsNullOrWhiteSpace(operation.To)
             ? EthereumAddress.Empty.Address
             : operation.To,
         Addresses = operation.Addresses,
         Value = operation.Value,
         Price = operation.Price,
         IsEth = operation.IsEth,
         Priority = operation.Priority,
         ContractAddress = operation.TokenInfo.ContractAddress,
         ContractName = operation.TokenInfo.Name,
         ContractSymbol = operation.TokenInfo.Symbol,
         ContractDecimals = int.Parse(operation.TokenInfo.Decimals),
         ContractHolders = operation.TokenInfo.HolderCount,
         ContractIssuances = operation.TokenInfo.IssuanceCount,
         ContractLink = operation.TokenInfo.WebsiteUri
     });
 }
Esempio n. 5
0
        private async Task SyncTransactionsAsync(
            IEthplorerClient ethplorerClient,
            IBloxyClient bloxyClient,
            ITransactionRepository transactionService,
            IOperationRepository operationService,
            EthereumAddress contractAddress,
            DateTime startDate,
            DateTime endDate)
        {
            Console.WriteLine($"[{contractAddress}] Processing Batch: {startDate} -> {endDate}");

            await foreach (var transactionSummary in bloxyClient.ListTransactionsAsync(contractAddress, startDate, endDate))
            {
                var hash = new EthereumTransactionHash(transactionSummary.Hash);

                var transaction = await ethplorerClient.GetTransactionAsync(hash);

                if (transaction != null)
                {
                    Console.WriteLine($"[{contractAddress}] Discovering Hash {hash} with ({transaction.Operations.Count}) operations.");

                    var dynamoTransaction = MapTransaction(hash, contractAddress, transactionSummary, transaction);

                    await transactionService.UploadItemsAsync(dynamoTransaction);

                    var dynamoOperations = Enumerable.Range(0, transaction.Operations.Count)
                                           .Select(i => MapOperation(hash, transaction.Operations[i], i))
                                           .ToArray();

                    await operationService.UploadItemsAsync(dynamoOperations);
                }
            }

            Console.WriteLine($"[{contractAddress}] Finished Batch: {startDate} -> {endDate}");
        }
Esempio n. 6
0
        public async Task <ApiStakeEvent> GetStake(
            [Required, FromRoute, EthereumAddress] string address,
            [Required, FromRoute] Symbol symbol,
            [Required, FromRoute] Symbol fundSymbol,
            [Required, FromRoute, TransactionHash] string hash)
        {
            var txHash = new EthereumTransactionHash(hash);
            var stake  = await stakeService.GetStakeEventAsync(
                symbol,
                GetAddress(address),
                fundSymbol,
                txHash);

            return(MapStakeEvent(stake));
        }
        public async IAsyncEnumerable <DataOperation> ListOperationsAsync(EthereumTransactionHash hash)
        {
            var lastEvaluatedKey = new Dictionary <string, AttributeValue>();

            while (!CancellationToken.IsCancellationRequested)
            {
                var response = await DynamoDB.QueryAsync(
                    new QueryRequest()
                {
                    TableName = TableName,
                    Select    = Select.ALL_ATTRIBUTES,
                    KeyConditionExpression   = string.Format("#{0} = :{0}Val", nameof(DataOperation.Hash)),
                    ExpressionAttributeNames = new Dictionary <string, string>()
                    {
                        [$"#{nameof(DataOperation.Hash)}"] = nameof(DataOperation.Hash),
                    },
                    ExpressionAttributeValues = new Dictionary <string, AttributeValue>()
                    {
                        [$":{nameof(DataOperation.Hash)}Val"] = new AttributeValue {
                            S = hash
                        },
                    },
                    ExclusiveStartKey = lastEvaluatedKey.Any()
                            ? lastEvaluatedKey
                            : null
                },
                    CancellationToken);

                if (response.HttpStatusCode != HttpStatusCode.OK)
                {
                    throw new HttpRequestException($"Response code did not indicate success: {response.HttpStatusCode}");
                }
                else
                {
                    lastEvaluatedKey = response.LastEvaluatedKey;
                }

                foreach (var attributes in response.Items)
                {
                    yield return(Map(attributes));
                }

                if (!lastEvaluatedKey.Any())
                {
                    break;
                }
            }
        }
        public async Task <ITransactionSet> GetTransactionAsync(Symbol symbol, EthereumTransactionHash hash, CurrencyCode currencyCode)
        {
            var fundInfo    = GetFundInfo(symbol);
            var transaction = await Transactions.GetTransactionAsync(fundInfo.Symbol, hash)
                              ?? throw new PermanentException($"Transaction not found {hash}");

            var transactionSet = MapTransaction <BusinessTransactionSet>(transaction);

            var operations = await Operations
                             .ListOperationsAsync(hash)
                             .ToListAsync(CancellationToken);

            transactionSet.Operations = operations
                                        .Select(o => MapOperation(o, currencyCode))
                                        .ToList();

            return(transactionSet);
        }
Esempio n. 9
0
 public Task <EthplorerTransaction> GetTransactionAsync(EthereumTransactionHash hash)
 {
     return(GetAsync <EthplorerTransaction>($"/getTxInfo/{hash}"));
 }
Esempio n. 10
0
        public async Task <IStakeEvent> GetStakeEventAsync(Symbol stakeSymbol, EthereumAddress?address, Symbol symbol, EthereumTransactionHash hash)
        {
            var fundInfo  = GetFundInfo(symbol);
            var stakeInfo = GetStakeInfo(stakeSymbol);

            var transaction = await Transactions.GetTransactionAsync(fundInfo.ContractAddress, hash);

            if (transaction != null)
            {
                var stake = transaction.Sender.Equals(stakeInfo.StakingAddress, StringComparison.OrdinalIgnoreCase)
                    ? await GetStakeReleaseAsync(fundInfo, stakeInfo, MapTransaction <BusinessTransaction>(transaction))
                    : await GetStakeLockupAsync(fundInfo, stakeInfo, MapTransaction <BusinessTransaction>(transaction))
                            ?? await GetStakeReleaseAsync(fundInfo, stakeInfo, MapTransaction <BusinessTransaction>(transaction));

                if (stake != null)
                {
                    return(stake);
                }
            }

            throw new PermanentException($"No transaction found with hash {hash}{(address.HasValue ? $" for address {address}." : ".")}");
        }
Esempio n. 11
0
 public Task <IStakeEvent> GetStakeEventAsync(Symbol stakeSymbol, EthereumAddress address, Symbol symbol, EthereumTransactionHash hash)
 {
     return(GetStakeEventAsync(stakeSymbol, new EthereumAddress?(address), symbol, hash));
 }
Esempio n. 12
0
 public Task <IStakeEvent> GetStakeEventAsync(Symbol stakeSymbol, Symbol symbol, EthereumTransactionHash hash)
 {
     return(GetStakeEventAsync(stakeSymbol, null, symbol, hash));
 }
Esempio n. 13
0
        protected BusinessOperation MapOperation(DataOperation operation, CurrencyCode currencyCode)
        {
            var sanitisedId = operation.ContractName?.Replace(" ", "-").Replace(".", "-").ToLower().Trim() ?? string.Empty;
            var isInvictus  = Enum.TryParse(operation.ContractSymbol, out Symbol symbol);

            var assetInfo       = GetAssetInfo(operation.ContractSymbol);
            var coinloreId      = assetInfo?.CoinLore ?? sanitisedId;
            var coinMarketCapId = assetInfo?.CoinMarketCap ?? sanitisedId;
            var isUSDStableCoin = assetInfo?.IsUSDStableCoin ?? false;

            var fund = isInvictus && symbol.IsFund()
                ? GetFundInfo(symbol)
                : null;

            var stake = isInvictus && symbol.IsStake()
                ? GetStakeInfo(symbol)
                : null;

            return(new BusinessOperation()
            {
                Hash = new EthereumTransactionHash(operation.Hash),
                Order = operation.Order,
                Type = operation.Type,
                Address = string.IsNullOrEmpty(operation.Address)
                    ? default(EthereumAddress?)
                          : new EthereumAddress(operation.Address),
                Sender = string.IsNullOrEmpty(operation.Sender)
                    ? default(EthereumAddress?)
                         : new EthereumAddress(operation.Sender),
                Recipient = string.IsNullOrEmpty(operation.Recipient)
                    ? default(EthereumAddress?)
                            : new EthereumAddress(operation.Recipient),
                Addresses = operation.Addresses
                            .Select(a => new EthereumAddress(a))
                            .ToList(),
                IsEth = operation.IsEth,
                PricePerToken = operation.Price == default && isUSDStableCoin
                    ? CurrencyConverter.Convert(1, currencyCode)
                    : CurrencyConverter.Convert(operation.Price, currencyCode),
                Quantity = operation.Type == OperationTypes.Transfer
                    ? Web3.Convert.FromWei(BigInteger.Parse(operation.Value), fund?.Decimals ?? stake?.Decimals ?? operation.ContractDecimals)
                    : 0,
                Value = operation.Value,
                Priority = operation.Priority,
                ContractAddress = new EthereumAddress(operation.ContractAddress),
                ContractSymbol = operation.ContractSymbol,
                ContractDecimals = operation.ContractDecimals,
                ContractHolders = operation.ContractHolders,
                ContractIssuances = operation.ContractIssuances,
                ContractName = fund?.Name ?? stake?.Name ?? operation.ContractName,
                ContractLink = fund?.Links?.External
                               ?? stake?.Links?.External
                               ?? (!string.IsNullOrEmpty(operation.ContractLink)
                        ? new Uri(operation.ContractLink, UriKind.Absolute)
                        : new Uri(string.Format(LinkTemplate, coinMarketCapId), UriKind.Absolute)),
                ContractImageLink = isInvictus
                    ? new Uri($"https://{HostUrl.Host}/resources/{symbol}.png", UriKind.Absolute)
                    : new Uri(string.Format(ImageTemplate, coinloreId), UriKind.Absolute),
                ContractMarketLink = !string.IsNullOrEmpty(coinloreId) && !symbol.IsStake() && (fund == null || fund.Tradable)
                    ? new Uri(string.Format(MarketTemplate, coinloreId, currencyCode), UriKind.Absolute)
                    : null
            });