diff --git a/lib/coinbase.rb b/lib/coinbase.rb index 559695a0..a3472c87 100644 --- a/lib/coinbase.rb +++ b/lib/coinbase.rb @@ -1,15 +1,16 @@ # frozen_string_literal: true +require_relative 'coinbase/client' require_relative 'coinbase/address' require_relative 'coinbase/address/wallet_address' require_relative 'coinbase/address/external_address' +require_relative 'coinbase/address_reputation' require_relative 'coinbase/asset' require_relative 'coinbase/authenticator' require_relative 'coinbase/correlation' require_relative 'coinbase/balance' require_relative 'coinbase/balance_map' require_relative 'coinbase/historical_balance' -require_relative 'coinbase/client' require_relative 'coinbase/constants' require_relative 'coinbase/contract_event' require_relative 'coinbase/contract_invocation' diff --git a/lib/coinbase/address.rb b/lib/coinbase/address.rb index d5837abd..552ed122 100644 --- a/lib/coinbase/address.rb +++ b/lib/coinbase/address.rb @@ -17,7 +17,14 @@ def initialize(network, id) # Returns a String representation of the Address. # @return [String] a String representation of the Address def to_s - Coinbase.pretty_print_object(self.class, id: id, network_id: network.id) + Coinbase.pretty_print_object( + self.class, + **{ + id: id, + network_id: network.id, + reputation_score: @reputation.nil? ? nil : reputation.score + }.compact + ) end # Same as to_s. @@ -32,6 +39,18 @@ def can_sign? false end + # Returns the reputation of the Address. + # @return [Coinbase::AddressReputation] The reputation of the Address + def reputation + @reputation ||= Coinbase::AddressReputation.fetch(network: network, address_id: id) + end + + # Returns wheth the Address's reputation is risky. + # @return [Boolean] true if the Address's reputation is risky + def risky? + reputation.risky? + end + # Returns the balances of the Address. # @return [BalanceMap] The balances of the Address, keyed by asset ID. Ether balances are denominated # in ETH. @@ -66,7 +85,7 @@ def balance(asset_id) # @return [Enumerable] Enumerator that returns historical_balance def historical_balances(asset_id) Coinbase::Pagination.enumerate( - ->(page) { list_page(asset_id, page) } + ->(page) { list_historical_balance_page(asset_id, page) } ) do |historical_balance| Coinbase::HistoricalBalance.from_model(historical_balance) end @@ -265,7 +284,7 @@ def stake_api @stake_api ||= Coinbase::Client::StakeApi.new(Coinbase.configuration.api_client) end - def list_page(asset_id, page) + def list_historical_balance_page(asset_id, page) balance_history_api.list_address_historical_balance( network.normalized_id, id, diff --git a/lib/coinbase/address_reputation.rb b/lib/coinbase/address_reputation.rb new file mode 100644 index 00000000..f50e3dca --- /dev/null +++ b/lib/coinbase/address_reputation.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +module Coinbase + # A representation of the reputation of a blockchain address. + class AddressReputation + # A metadata object associated with an address reputation. + Metadata = Struct.new( + *Client::AddressReputationMetadata.attribute_map.keys.map(&:to_sym), + keyword_init: true + ) do + def to_s + Coinbase.pretty_print_object( + self.class, + **to_h + ) + end + end + + class << self + def fetch(address_id:, network: Coinbase.default_network) + network = Coinbase::Network.from_id(network) + + model = Coinbase.call_api do + reputation_api.get_address_reputation(network.normalized_id, address_id) + end + + new(model) + end + + private + + def reputation_api + Coinbase::Client::ReputationApi.new(Coinbase.configuration.api_client) + end + end + + def initialize(model) + unless model.is_a?(Coinbase::Client::AddressReputation) + raise ArgumentError, + 'must be an AddressReputation client object' + end + + @model = model + end + + def score + @model.score + end + + def metadata + @metadata ||= Metadata.new(**@model.metadata) + end + + def risky? + score.negative? + end + + def to_s + Coinbase.pretty_print_object( + self.class, + score: score, + **metadata.to_h + ) + end + + def inspect + to_s + end + end +end