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 <DataFundPerformance> GetPerformanceAsync(Symbol symbol, DateTime timeStamp)
        {
            var key = dataKeyProvider.GetKey(symbol);

            var response = await DynamoDB.GetItemAsync(
                TableName,
                new Dictionary <string, AttributeValue>()
            {
                [nameof(DataFundPerformance.Address)] = new AttributeValue(key),
                [nameof(DataFundPerformance.Date)]    = new AttributeValue(timeStamp.ToISO8601String())
            },
                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 async IAsyncEnumerable <EthereumTransactionHash> ListAddressHashesAsync(
            EthereumAddress address,
            Symbol symbol,
            string indexName,
            string attributeName)
        {
            var key = dataKeyProvider.GetKey(symbol);
            var lastEvaluatedKey = new Dictionary <string, AttributeValue>();

            while (!CancellationToken.IsCancellationRequested)
            {
                var response = await DynamoDB.QueryAsync(
                    new QueryRequest()
                {
                    TableName = TableName,
                    IndexName = indexName,
                    Select    = Select.ALL_PROJECTED_ATTRIBUTES,
                    KeyConditionExpression = string.Format(
                        "#{0} = :{0}Val AND #{1} = :{1}Val",
                        attributeName,
                        nameof(DataOperation.ContractAddress)),
                    ExpressionAttributeNames = new Dictionary <string, string>()
                    {
                        [$"#{attributeName}"] = attributeName,
                        [$"#{nameof(DataOperation.ContractAddress)}"] = nameof(DataOperation.ContractAddress)
                    },
                    ExpressionAttributeValues = new Dictionary <string, AttributeValue>()
                    {
                        [$":{attributeName}Val"] = new AttributeValue(address),
                        [$":{nameof(DataOperation.ContractAddress)}Val"] = new AttributeValue(key)
                    },
                    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)
                {
                    if (attributes.ContainsKey(nameof(DataOperation.Hash)))
                    {
                        yield return(new EthereumTransactionHash(attributes[nameof(DataOperation.Hash)].S));
                    }
                }

                if (!lastEvaluatedKey.Any())
                {
                    break;
                }
            }
        }