coinbase-sdk 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,7 +12,7 @@ module Coinbase
12
12
  # Returns the default middleware configuration for the Coinbase SDK.
13
13
  def self.config
14
14
  Coinbase::Client::Configuration.default.tap do |config|
15
- config.debugging = true
15
+ config.debugging = Coinbase.configuration.debug_api
16
16
  config.host = Coinbase.configuration.api_url
17
17
  config.request(:authenticator)
18
18
  end
@@ -37,7 +37,7 @@ module Coinbase
37
37
 
38
38
  # Returns the Transfer ID.
39
39
  # @return [String] The Transfer ID
40
- def transfer_id
40
+ def id
41
41
  @model.transfer_id
42
42
  end
43
43
 
@@ -72,9 +72,21 @@ module Coinbase
72
72
  end
73
73
 
74
74
  # Returns the amount of the asset for the Transfer.
75
- # @return [BigDecimal] The amount in units of ETH
75
+ # @return [BigDecimal] The amount of the asset
76
76
  def amount
77
- BigDecimal(@model.amount) / BigDecimal(Coinbase::WEI_PER_ETHER.to_s)
77
+ case asset_id
78
+ when :eth
79
+ BigDecimal(@model.amount) / BigDecimal(Coinbase::WEI_PER_ETHER.to_s)
80
+ else
81
+ BigDecimal(@model.amount)
82
+ end
83
+ end
84
+
85
+ # Returns the link to the transaction on the blockchain explorer.
86
+ # @return [String] The link to the transaction on the blockchain explorer
87
+ def transaction_link
88
+ # TODO: Parameterize this by Network.
89
+ "https://sepolia.basescan.org/tx/#{transaction_hash}"
78
90
  end
79
91
 
80
92
  # Returns the Unsigned Payload of the Transfer.
@@ -83,6 +95,18 @@ module Coinbase
83
95
  @model.unsigned_payload
84
96
  end
85
97
 
98
+ # Returns the Signed Payload of the Transfer.
99
+ # @return [String] The Signed Payload
100
+ def signed_payload
101
+ @model.signed_payload
102
+ end
103
+
104
+ # Returns the Transaction Hash of the Transfer.
105
+ # @return [String] The Transaction Hash
106
+ def transaction_hash
107
+ @model.transaction_hash
108
+ end
109
+
86
110
  # Returns the underlying Transfer transaction, creating it if it has not been yet.
87
111
  # @return [Eth::Tx::Eip1559] The Transfer transaction
88
112
  def transaction
@@ -110,13 +134,8 @@ module Coinbase
110
134
  # Returns the status of the Transfer.
111
135
  # @return [Symbol] The status
112
136
  def status
113
- begin
114
- # Create the transaction, and attempt to get the hash to see if it has been signed.
115
- transaction.hash
116
- rescue Eth::Signature::SignatureError
117
- # If the transaction has not been signed, it is still pending.
118
- return Status::PENDING
119
- end
137
+ # Check if the transfer has been signed yet.
138
+ return Status::PENDING if transaction_hash.nil?
120
139
 
121
140
  onchain_transaction = Coinbase.configuration.base_sepolia_client.eth_getTransactionByHash(transaction_hash)
122
141
 
@@ -157,12 +176,19 @@ module Coinbase
157
176
  self
158
177
  end
159
178
 
160
- # Returns the transaction hash of the Transfer, or nil if not yet available.
161
- # @return [String] The transaction hash
162
- def transaction_hash
163
- "0x#{transaction.hash}"
164
- rescue Eth::Signature::SignatureError
165
- nil
179
+ # Returns a String representation of the Transfer.
180
+ # @return [String] a String representation of the Transfer
181
+ def to_s
182
+ "Coinbase::Transfer{transfer_id: '#{id}', network_id: '#{network_id}', " \
183
+ "from_address_id: '#{from_address_id}', destination_address_id: '#{destination_address_id}', " \
184
+ "asset_id: '#{asset_id}', amount: '#{amount}', transaction_hash: '#{transaction_hash}', " \
185
+ "transaction_link: '#{transaction_link}', status: '#{status}'}"
186
+ end
187
+
188
+ # Same as to_s.
189
+ # @return [String] a String representation of the Transfer
190
+ def inspect
191
+ to_s
166
192
  end
167
193
  end
168
194
  end
data/lib/coinbase/user.rb CHANGED
@@ -15,7 +15,7 @@ module Coinbase
15
15
 
16
16
  # Returns the User ID.
17
17
  # @return [String] the User ID
18
- def user_id
18
+ def id
19
19
  @model.id
20
20
  end
21
21
 
@@ -30,7 +30,9 @@ module Coinbase
30
30
  }
31
31
  opts = { create_wallet_request: create_wallet_request }
32
32
 
33
- model = wallets_api.create_wallet(opts)
33
+ model = Coinbase.call_api do
34
+ wallets_api.create_wallet(opts)
35
+ end
34
36
 
35
37
  Wallet.new(model)
36
38
  end
@@ -39,18 +41,107 @@ module Coinbase
39
41
  # @param data [Coinbase::Wallet::Data] the Wallet data to import
40
42
  # @return [Coinbase::Wallet] the imported Wallet
41
43
  def import_wallet(data)
42
- model = wallets_api.get_wallet(data.wallet_id)
43
- address_count = addresses_api.list_addresses(model.id).total_count
44
- Wallet.new(model, seed: data.seed, address_count: address_count)
44
+ Wallet.import(data)
45
45
  end
46
46
 
47
47
  # Lists the IDs of the Wallets belonging to the User.
48
48
  # @return [Array<String>] the IDs of the Wallets belonging to the User
49
- def list_wallet_ids
50
- wallets = wallets_api.list_wallets
49
+ def wallet_ids
50
+ wallets = Coinbase.call_api do
51
+ wallets_api.list_wallets
52
+ end
53
+
51
54
  wallets.data.map(&:id)
52
55
  end
53
56
 
57
+ # Saves a wallet to local file system. Wallet saved this way can be re-instantiated with load_wallets_from_local
58
+ # function, provided the backup_file is available. This is an insecure method of storing wallet seeds and should
59
+ # only be used for development purposes. If you call save_wallet_locally! twice with wallets containing the same
60
+ # wallet_id, the backup will be overwritten during the second attempt.
61
+ # The default backup_file is `seeds.json` in the root folder. It can be configured by changing
62
+ # Coinbase.configuration.backup_file_path.
63
+ #
64
+ # @param wallet [Coinbase::Wallet] The wallet model to save.
65
+ # @param encrypt [bool] (Optional) Boolean representing whether the backup persisted to local file system should be
66
+ # encrypted or not. Data is unencrypted by default.
67
+ # @return [Coinbase::Wallet] the saved wallet.
68
+ def save_wallet_locally!(wallet, encrypt: false)
69
+ existing_seeds_in_store = existing_seeds
70
+ data = wallet.export
71
+ seed_to_store = data.seed
72
+ auth_tag = ''
73
+ iv = ''
74
+ if encrypt
75
+ shared_secret = store_encryption_key
76
+ cipher = OpenSSL::Cipher.new('aes-256-gcm').encrypt
77
+ cipher.key = OpenSSL::Digest.digest('SHA256', shared_secret)
78
+ iv = cipher.random_iv
79
+ cipher.iv = iv
80
+ cipher.auth_data = ''
81
+ encrypted_data = cipher.update(data.seed) + cipher.final
82
+ auth_tag = cipher.auth_tag.unpack1('H*')
83
+ iv = iv.unpack1('H*')
84
+ seed_to_store = encrypted_data.unpack1('H*')
85
+ end
86
+
87
+ existing_seeds_in_store[data.wallet_id] = {
88
+ seed: seed_to_store,
89
+ encrypted: encrypt,
90
+ auth_tag: auth_tag,
91
+ iv: iv
92
+ }
93
+
94
+ File.open(Coinbase.configuration.backup_file_path, 'w') do |file|
95
+ file.write(JSON.pretty_generate(existing_seeds_in_store))
96
+ end
97
+ wallet
98
+ end
99
+
100
+ # Loads all wallets belonging to the User with backup persisted to the local file system.
101
+ # @return [Map<String>Coinbase::Wallet] the map of wallet_ids to the wallets.
102
+ def load_wallets_from_local
103
+ existing_seeds_in_store = existing_seeds
104
+ raise ArgumentError, 'Backup file not found' if existing_seeds_in_store == {}
105
+
106
+ wallets = {}
107
+ existing_seeds_in_store.each do |wallet_id, seed_data|
108
+ seed = seed_data['seed']
109
+ raise ArgumentError, 'Malformed backup data' if seed.nil? || seed == ''
110
+
111
+ if seed_data['encrypted']
112
+ shared_secret = store_encryption_key
113
+ raise ArgumentError, 'Malformed encrypted seed data' if seed_data['iv'] == '' ||
114
+ seed_data['auth_tag'] == ''
115
+
116
+ cipher = OpenSSL::Cipher.new('aes-256-gcm').decrypt
117
+ cipher.key = OpenSSL::Digest.digest('SHA256', shared_secret)
118
+ iv = [seed_data['iv']].pack('H*')
119
+ cipher.iv = iv
120
+ auth_tag = [seed_data['auth_tag']].pack('H*')
121
+ cipher.auth_tag = auth_tag
122
+ cipher.auth_data = ''
123
+ hex_decoded_data = [seed_data['seed']].pack('H*')
124
+ seed = cipher.update(hex_decoded_data) + cipher.final
125
+ end
126
+
127
+ data = Coinbase::Wallet::Data.new(wallet_id: wallet_id, seed: seed)
128
+ wallets[wallet_id] = import_wallet(data)
129
+ end
130
+ wallets
131
+ end
132
+
133
+ # Returns a string representation of the User.
134
+ # @return [String] a string representation of the User
135
+ def to_s
136
+ "Coinbase::User{user_id: '#{id}'}"
137
+ end
138
+
139
+ # Same as to_s.
140
+ # @return [String] a string representation of the User
141
+ def inspect
142
+ to_s
143
+ end
144
+
54
145
  private
55
146
 
56
147
  def addresses_api
@@ -60,5 +151,22 @@ module Coinbase
60
151
  def wallets_api
61
152
  @wallets_api ||= Coinbase::Client::WalletsApi.new(Coinbase.configuration.api_client)
62
153
  end
154
+
155
+ def existing_seeds
156
+ existing_seed_data = '{}'
157
+ file_path = Coinbase.configuration.backup_file_path
158
+ existing_seed_data = File.read(file_path) if File.exist?(file_path)
159
+ output = JSON.parse(existing_seed_data)
160
+
161
+ raise ArgumentError, 'Malformed backup data' unless output.is_a?(Hash)
162
+
163
+ output
164
+ end
165
+
166
+ def store_encryption_key
167
+ pk = OpenSSL::PKey.read(Coinbase.configuration.api_key_private_key)
168
+ public_key = pk.public_key # use own public key to generate the shared secret.
169
+ pk.dh_compute_key(public_key)
170
+ end
63
171
  end
64
172
  end
@@ -12,6 +12,39 @@ module Coinbase
12
12
  # list their balances, and transfer Assets to other Addresses. Wallets should be created through User#create_wallet or
13
13
  # User#import_wallet.
14
14
  class Wallet
15
+ attr_reader :addresses
16
+
17
+ class << self
18
+ # Imports a Wallet from previously exported wallet data.
19
+ # @param data [Coinbase::Wallet::Data] the Wallet data to import
20
+ # @return [Coinbase::Wallet] the imported Wallet
21
+ def import(data)
22
+ raise ArgumentError, 'data must be a Coinbase::Wallet::Data object' unless data.is_a?(Data)
23
+
24
+ model = Coinbase.call_api do
25
+ wallets_api.get_wallet(data.wallet_id)
26
+ end
27
+
28
+ # TODO: Pass these addresses in directly
29
+ address_count = Coinbase.call_api do
30
+ addresses_api.list_addresses(model.id).total_count
31
+ end
32
+
33
+ new(model, seed: data.seed, address_count: address_count)
34
+ end
35
+
36
+ private
37
+
38
+ # TODO: Memoize these objects in a thread-safe way at the top-level.
39
+ def addresses_api
40
+ Coinbase::Client::AddressesApi.new(Coinbase.configuration.api_client)
41
+ end
42
+
43
+ def wallets_api
44
+ Coinbase::Client::WalletsApi.new(Coinbase.configuration.api_client)
45
+ end
46
+ end
47
+
15
48
  # Returns a new Wallet object. Do not use this method directly. Instead, use User#create_wallet or
16
49
  # User#import_wallet.
17
50
  # @param model [Coinbase::Client::Wallet] The underlying Wallet object
@@ -45,7 +78,7 @@ module Coinbase
45
78
 
46
79
  # Returns the Wallet ID.
47
80
  # @return [String] The Wallet ID
48
- def wallet_id
81
+ def id
49
82
  @model.id
50
83
  end
51
84
 
@@ -68,7 +101,9 @@ module Coinbase
68
101
  attestation: attestation
69
102
  }
70
103
  }
71
- address_model = addresses_api.create_address(wallet_id, opts)
104
+ address_model = Coinbase.call_api do
105
+ addresses_api.create_address(id, opts)
106
+ end
72
107
 
73
108
  cache_address(address_model, key)
74
109
  end
@@ -76,55 +111,37 @@ module Coinbase
76
111
  # Returns the default address of the Wallet.
77
112
  # @return [Address] The default address
78
113
  def default_address
79
- @addresses.find { |address| address.address_id == @model.default_address.address_id }
114
+ address(@model.default_address.address_id)
80
115
  end
81
116
 
82
117
  # Returns the Address with the given ID.
83
118
  # @param address_id [String] The ID of the Address to retrieve
84
119
  # @return [Address] The Address
85
- def get_address(address_id)
86
- @addresses.find { |address| address.address_id == address_id }
87
- end
88
-
89
- # Returns the list of Addresses in the Wallet.
90
- # @return [Array<Address>] The list of Addresses
91
- def list_addresses
92
- @addresses
120
+ def address(address_id)
121
+ @addresses.find { |address| address.id == address_id }
93
122
  end
94
123
 
95
124
  # Returns the list of balances of this Wallet. Balances are aggregated across all Addresses in the Wallet.
96
125
  # @return [BalanceMap] The list of balances. The key is the Asset ID, and the value is the balance.
97
- def list_balances
98
- response = wallets_api.list_wallet_balances(wallet_id)
99
- Coinbase.to_balance_map(response)
126
+ def balances
127
+ response = Coinbase.call_api do
128
+ wallets_api.list_wallet_balances(id)
129
+ end
130
+
131
+ Coinbase::BalanceMap.from_balances(response.data)
100
132
  end
101
133
 
102
134
  # Returns the balance of the provided Asset. Balances are aggregated across all Addresses in the Wallet.
103
135
  # @param asset_id [Symbol] The ID of the Asset to retrieve the balance for
104
136
  # @return [BigDecimal] The balance of the Asset
105
- def get_balance(asset_id)
106
- normalized_asset_id = if %i[wei gwei].include?(asset_id)
107
- :eth
108
- else
109
- asset_id
110
- end
111
-
112
- response = wallets_api.get_wallet_balance(wallet_id, normalized_asset_id.to_s)
137
+ def balance(asset_id)
138
+ response = Coinbase.call_api do
139
+ wallets_api.get_wallet_balance(id, Coinbase::Asset.primary_denomination(asset_id).to_s)
140
+ end
113
141
 
114
142
  return BigDecimal('0') if response.nil?
115
143
 
116
- amount = BigDecimal(response.amount)
117
-
118
- case asset_id
119
- when :eth
120
- amount / BigDecimal(Coinbase::WEI_PER_ETHER.to_s)
121
- when :gwei
122
- amount / BigDecimal(Coinbase::GWEI_PER_ETHER.to_s)
123
- when :usdc
124
- amount / BigDecimal(Coinbase::ATOMIC_UNITS_PER_USDC.to_s)
125
- else
126
- amount
127
- end
144
+ Coinbase::Balance.from_model_and_asset_id(response, asset_id).amount
128
145
  end
129
146
 
130
147
  # Transfers the given amount of the given Asset to the given address. Only same-Network Transfers are supported.
@@ -138,11 +155,11 @@ module Coinbase
138
155
  if destination.is_a?(Wallet)
139
156
  raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != @network_id
140
157
 
141
- destination = destination.default_address.address_id
158
+ destination = destination.default_address.id
142
159
  elsif destination.is_a?(Address)
143
160
  raise ArgumentError, 'Transfer must be on the same Network' if destination.network_id != @network_id
144
161
 
145
- destination = destination.address_id
162
+ destination = destination.id
146
163
  end
147
164
 
148
165
  default_address.transfer(amount, asset_id, destination)
@@ -151,7 +168,31 @@ module Coinbase
151
168
  # Exports the Wallet's data to a Data object.
152
169
  # @return [Data] The Wallet data
153
170
  def export
154
- Data.new(wallet_id: wallet_id, seed: @master.seed_hex)
171
+ Data.new(wallet_id: id, seed: @master.seed_hex)
172
+ end
173
+
174
+ # Requests funds from the faucet for the Wallet's default address and returns the faucet transaction.
175
+ # This is only supported on testnet networks.
176
+ # @return [Coinbase::FaucetTransaction] The successful faucet transaction
177
+ # @raise [Coinbase::FaucetLimitReachedError] If the faucet limit has been reached for the address or user.
178
+ # @raise [Coinbase::Client::ApiError] If an unexpected error occurs while requesting faucet funds.
179
+ def faucet
180
+ Coinbase.call_api do
181
+ Coinbase::FaucetTransaction.new(addresses_api.request_faucet_funds(id, default_address.id))
182
+ end
183
+ end
184
+
185
+ # Returns a String representation of the Wallet.
186
+ # @return [String] a String representation of the Wallet
187
+ def to_s
188
+ "Coinbase::Wallet{wallet_id: '#{id}', network_id: '#{network_id}', " \
189
+ "default_address: '#{default_address.id}'}"
190
+ end
191
+
192
+ # Same as to_s.
193
+ # @return [String] a String representation of the Wallet
194
+ def inspect
195
+ to_s
155
196
  end
156
197
 
157
198
  # The data required to recreate a Wallet.
@@ -188,7 +229,9 @@ module Coinbase
188
229
  key = derive_key
189
230
 
190
231
  address_id = key.address.to_s
191
- address_model = addresses_api.get_address(wallet_id, address_id)
232
+ address_model = Coinbase.call_api do
233
+ addresses_api.get_address(id, address_id)
234
+ end
192
235
 
193
236
  cache_address(address_model, key)
194
237
  end
@@ -218,7 +261,7 @@ module Coinbase
218
261
  def create_attestation(key)
219
262
  public_key = key.public_key.compressed.unpack1('H*')
220
263
  payload = {
221
- wallet_id: wallet_id,
264
+ wallet_id: id,
222
265
  public_key: public_key
223
266
  }.to_json
224
267
  hashed_payload = Digest::SHA256.digest(payload)
@@ -238,7 +281,9 @@ module Coinbase
238
281
 
239
282
  # Updates the Wallet model with the latest data.
240
283
  def update_model
241
- @model = wallets_api.get_wallet(wallet_id)
284
+ @model = Coinbase.call_api do
285
+ wallets_api.get_wallet(id)
286
+ end
242
287
  end
243
288
 
244
289
  def addresses_api
data/lib/coinbase.rb CHANGED
@@ -3,23 +3,30 @@
3
3
  require_relative 'coinbase/address'
4
4
  require_relative 'coinbase/asset'
5
5
  require_relative 'coinbase/authenticator'
6
+ require_relative 'coinbase/balance'
6
7
  require_relative 'coinbase/balance_map'
7
8
  require_relative 'coinbase/client'
8
9
  require_relative 'coinbase/constants'
10
+ require_relative 'coinbase/errors'
11
+ require_relative 'coinbase/faucet_transaction'
9
12
  require_relative 'coinbase/middleware'
10
13
  require_relative 'coinbase/network'
11
14
  require_relative 'coinbase/transfer'
12
15
  require_relative 'coinbase/user'
13
16
  require_relative 'coinbase/wallet'
17
+ require 'json'
14
18
 
15
19
  # The Coinbase SDK.
16
20
  module Coinbase
17
21
  class InvalidConfiguration < StandardError; end
18
22
 
23
+ # Returns the configuration object.
24
+ # @return [Configuration] the configuration object
19
25
  def self.configuration
20
26
  @configuration ||= Configuration.new
21
27
  end
22
28
 
29
+ # Configures the Coinbase SDK.
23
30
  def self.configure
24
31
  yield(configuration)
25
32
 
@@ -27,22 +34,54 @@ module Coinbase
27
34
  raise InvalidConfiguration, 'API key name is not set' unless configuration.api_key_name
28
35
  end
29
36
 
30
- # Configuration object for the Coinbase SDK
37
+ # Configures the Coinbase SDK from the given CDP API Key JSON file.
38
+ # @param file_path [String] (Optional) the path to the CDP API Key JSON file
39
+ # file in the root directory by default.
40
+ def self.configure_from_json(file_path = 'coinbase_cloud_api_key.json')
41
+ configuration.from_json(file_path)
42
+
43
+ raise InvalidConfiguration, 'API key private key is not set' unless configuration.api_key_private_key
44
+ raise InvalidConfiguration, 'API key name is not set' unless configuration.api_key_name
45
+ end
46
+
47
+ # Configuration object for the Coinbase SDK.
31
48
  class Configuration
32
49
  attr_reader :base_sepolia_rpc_url, :base_sepolia_client
33
- attr_accessor :api_url, :api_key_name, :api_key_private_key
50
+ attr_accessor :api_url, :api_key_name, :api_key_private_key, :debug_api, :backup_file_path
34
51
 
52
+ # Initializes the configuration object.
35
53
  def initialize
36
54
  @base_sepolia_rpc_url = 'https://sepolia.base.org'
37
55
  @base_sepolia_client = Jimson::Client.new(@base_sepolia_rpc_url)
38
56
  @api_url = 'https://api.cdp.coinbase.com'
57
+ @debug_api = false
58
+ @backup_file_path = 'seeds.json'
59
+ end
60
+
61
+ # Sets configuration values based on the provided CDP API Key JSON file.
62
+ # @param file_path [String] (Optional) the path to the CDP API Key JSON file
63
+ # file in the root directory by default.
64
+ def from_json(file_path = 'coinbase_cloud_api_key.json')
65
+ # Expand paths to respect shortcuts like ~.
66
+ file_path = File.expand_path(file_path)
67
+
68
+ raise InvalidConfiguration, 'Invalid configuration file type' unless file_path.end_with?('.json')
69
+
70
+ file = File.read(file_path)
71
+ data = JSON.parse(file)
72
+ @api_key_name = data['name']
73
+ @api_key_private_key = data['privateKey']
39
74
  end
40
75
 
76
+ # Sets the Base Sepolia RPC URL.
77
+ # @param new_base_sepolia_rpc_url [String] the new Base Sepolia RPC URL
41
78
  def base_sepolia_rpc_url=(new_base_sepolia_rpc_url)
42
79
  @base_sepolia_rpc_url = new_base_sepolia_rpc_url
43
80
  @base_sepolia_client = Jimson::Client.new(@base_sepolia_rpc_url)
44
81
  end
45
82
 
83
+ # Returns the API client.
84
+ # @return [Coinbase::Client::ApiClient] the API client
46
85
  def api_client
47
86
  @api_client ||= Coinbase::Client::ApiClient.new(Middleware.config)
48
87
  end
@@ -61,30 +100,21 @@ module Coinbase
61
100
  value.to_s.gsub('-', '_').to_sym
62
101
  end
63
102
 
64
- # Converts a Coinbase::Client::AddressBalanceList to a BalanceMap.
65
- # @param address_balance_list [Coinbase::Client::AddressBalanceList] The AddressBalanceList to convert
66
- # @return [BalanceMap] The converted BalanceMap
67
- def self.to_balance_map(address_balance_list)
68
- balances = {}
69
-
70
- address_balance_list.data.each do |balance|
71
- asset_id = Coinbase.to_sym(balance.asset.asset_id.downcase)
72
- amount = if asset_id == :eth
73
- BigDecimal(balance.amount) / BigDecimal(Coinbase::WEI_PER_ETHER)
74
- elsif asset_id == :usdc
75
- BigDecimal(balance.amount) / BigDecimal(Coinbase::ATOMIC_UNITS_PER_USDC)
76
- else
77
- BigDecimal(balance.amount)
78
- end
79
- balances[asset_id] = amount
80
- end
81
-
82
- BalanceMap.new(balances)
83
- end
84
-
103
+ # Loads the default user.
104
+ # @return [Coinbase::User] the default user
85
105
  def self.load_default_user
86
106
  users_api = Coinbase::Client::UsersApi.new(configuration.api_client)
87
107
  user_model = users_api.get_current_user
88
108
  Coinbase::User.new(user_model)
89
109
  end
110
+
111
+ # Wraps a call to the Platform API to ensure that the error is caught and
112
+ # wrapped as an APIError.
113
+ def self.call_api
114
+ yield
115
+ rescue Coinbase::Client::ApiError => e
116
+ raise Coinbase::APIError.from_error(e)
117
+ rescue StandardError => e
118
+ raise e
119
+ end
90
120
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coinbase-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuga Cohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-30 00:00:00.000000000 Z
11
+ date: 2024-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eth
@@ -192,6 +192,20 @@ dependencies:
192
192
  - - '='
193
193
  - !ruby/object:Gem::Version
194
194
  version: 0.9.36
195
+ - !ruby/object:Gem::Dependency
196
+ name: yard-markdown
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
195
209
  description: Coinbase Ruby SDK for accessing Coinbase Platform APIs
196
210
  email: yuga.cohler@coinbase.com
197
211
  executables: []
@@ -202,6 +216,7 @@ files:
202
216
  - lib/coinbase/address.rb
203
217
  - lib/coinbase/asset.rb
204
218
  - lib/coinbase/authenticator.rb
219
+ - lib/coinbase/balance.rb
205
220
  - lib/coinbase/balance_map.rb
206
221
  - lib/coinbase/client.rb
207
222
  - lib/coinbase/client/api/addresses_api.rb
@@ -216,10 +231,12 @@ files:
216
231
  - lib/coinbase/client/models/address_list.rb
217
232
  - lib/coinbase/client/models/asset.rb
218
233
  - lib/coinbase/client/models/balance.rb
234
+ - lib/coinbase/client/models/broadcast_transfer_request.rb
219
235
  - lib/coinbase/client/models/create_address_request.rb
220
236
  - lib/coinbase/client/models/create_transfer_request.rb
221
237
  - lib/coinbase/client/models/create_wallet_request.rb
222
238
  - lib/coinbase/client/models/error.rb
239
+ - lib/coinbase/client/models/faucet_transaction.rb
223
240
  - lib/coinbase/client/models/transfer.rb
224
241
  - lib/coinbase/client/models/transfer_list.rb
225
242
  - lib/coinbase/client/models/user.rb
@@ -227,6 +244,8 @@ files:
227
244
  - lib/coinbase/client/models/wallet_list.rb
228
245
  - lib/coinbase/client/version.rb
229
246
  - lib/coinbase/constants.rb
247
+ - lib/coinbase/errors.rb
248
+ - lib/coinbase/faucet_transaction.rb
230
249
  - lib/coinbase/middleware.rb
231
250
  - lib/coinbase/network.rb
232
251
  - lib/coinbase/transfer.rb