coinbase-sdk 0.0.7 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/lib/coinbase/address/external_address.rb +173 -0
  3. data/lib/coinbase/address/wallet_address.rb +219 -0
  4. data/lib/coinbase/address.rb +32 -219
  5. data/lib/coinbase/asset.rb +76 -66
  6. data/lib/coinbase/authenticator.rb +2 -0
  7. data/lib/coinbase/balance.rb +10 -6
  8. data/lib/coinbase/client/api/addresses_api.rb +1 -1
  9. data/lib/coinbase/client/api/assets_api.rb +91 -0
  10. data/lib/coinbase/client/api/external_addresses_api.rb +242 -0
  11. data/lib/coinbase/client/api/server_signers_api.rb +1 -1
  12. data/lib/coinbase/client/api/stake_api.rb +157 -7
  13. data/lib/coinbase/client/api/trades_api.rb +1 -1
  14. data/lib/coinbase/client/api/transfers_api.rb +1 -1
  15. data/lib/coinbase/client/api/users_api.rb +1 -1
  16. data/lib/coinbase/client/api/wallets_api.rb +1 -1
  17. data/lib/coinbase/client/api_client.rb +3 -3
  18. data/lib/coinbase/client/api_error.rb +1 -1
  19. data/lib/coinbase/client/configuration.rb +1 -1
  20. data/lib/coinbase/client/models/address.rb +1 -1
  21. data/lib/coinbase/client/models/address_balance_list.rb +1 -1
  22. data/lib/coinbase/client/models/address_list.rb +1 -1
  23. data/lib/coinbase/client/models/asset.rb +1 -1
  24. data/lib/coinbase/client/models/balance.rb +1 -1
  25. data/lib/coinbase/client/models/broadcast_trade_request.rb +1 -1
  26. data/lib/coinbase/client/models/broadcast_transfer_request.rb +1 -1
  27. data/lib/coinbase/client/models/build_staking_operation_request.rb +1 -1
  28. data/lib/coinbase/client/models/create_address_request.rb +1 -1
  29. data/lib/coinbase/client/models/create_server_signer_request.rb +22 -5
  30. data/lib/coinbase/client/models/create_trade_request.rb +1 -1
  31. data/lib/coinbase/client/models/create_transfer_request.rb +1 -1
  32. data/lib/coinbase/client/models/create_wallet_request.rb +1 -1
  33. data/lib/coinbase/client/models/create_wallet_request_wallet.rb +1 -1
  34. data/lib/coinbase/client/models/error.rb +1 -1
  35. data/lib/coinbase/client/models/faucet_transaction.rb +23 -5
  36. data/lib/coinbase/client/models/feature.rb +1 -1
  37. data/lib/coinbase/client/models/fetch_staking_rewards200_response.rb +258 -0
  38. data/lib/coinbase/client/models/fetch_staking_rewards_request.rb +330 -0
  39. data/lib/coinbase/client/models/get_staking_context_request.rb +274 -0
  40. data/lib/coinbase/client/models/partial_eth_staking_context.rb +254 -0
  41. data/lib/coinbase/client/models/seed_creation_event.rb +1 -1
  42. data/lib/coinbase/client/models/seed_creation_event_result.rb +1 -1
  43. data/lib/coinbase/client/models/server_signer.rb +22 -5
  44. data/lib/coinbase/client/models/server_signer_event.rb +1 -1
  45. data/lib/coinbase/client/models/server_signer_event_event.rb +1 -1
  46. data/lib/coinbase/client/models/server_signer_event_list.rb +1 -1
  47. data/lib/coinbase/client/models/server_signer_list.rb +1 -1
  48. data/lib/coinbase/client/models/signature_creation_event.rb +1 -1
  49. data/lib/coinbase/client/models/signature_creation_event_result.rb +1 -1
  50. data/lib/coinbase/client/models/{request_faucet_funds200_response.rb → staking_context.rb} +16 -16
  51. data/lib/coinbase/client/models/staking_context_context.rb +104 -0
  52. data/lib/coinbase/client/models/staking_operation.rb +15 -12
  53. data/lib/coinbase/client/models/staking_reward.rb +324 -0
  54. data/lib/coinbase/client/models/staking_reward_format.rb +40 -0
  55. data/lib/coinbase/client/models/trade.rb +1 -1
  56. data/lib/coinbase/client/models/trade_list.rb +1 -1
  57. data/lib/coinbase/client/models/transaction.rb +1 -1
  58. data/lib/coinbase/client/models/transaction_type.rb +1 -1
  59. data/lib/coinbase/client/models/transfer.rb +1 -1
  60. data/lib/coinbase/client/models/transfer_list.rb +1 -1
  61. data/lib/coinbase/client/models/user.rb +1 -1
  62. data/lib/coinbase/client/models/wallet.rb +1 -1
  63. data/lib/coinbase/client/models/wallet_list.rb +1 -1
  64. data/lib/coinbase/client/version.rb +1 -1
  65. data/lib/coinbase/client.rb +11 -1
  66. data/lib/coinbase/constants.rb +2 -27
  67. data/lib/coinbase/errors.rb +56 -64
  68. data/lib/coinbase/faucet_transaction.rb +5 -4
  69. data/lib/coinbase/network.rb +6 -20
  70. data/lib/coinbase/pagination.rb +26 -0
  71. data/lib/coinbase/staking_operation.rb +29 -0
  72. data/lib/coinbase/staking_reward.rb +79 -0
  73. data/lib/coinbase/transaction.rb +6 -0
  74. data/lib/coinbase/user.rb +5 -51
  75. data/lib/coinbase/wallet.rb +97 -102
  76. data/lib/coinbase.rb +19 -11
  77. metadata +17 -17
@@ -1,50 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'balance_map'
4
- require_relative 'constants'
5
- require_relative 'wallet'
6
- require 'bigdecimal'
7
- require 'eth'
8
- require 'jimson'
9
-
10
3
  module Coinbase
11
4
  # A representation of a blockchain Address, which is a user-controlled account on a Network. Addresses are used to
12
- # send and receive Assets, and should be created using Wallet#create_address. Addresses require an
13
- # Eth::Key to sign transaction data.
5
+ # send and receive Assets.
6
+ # @attr_reader [Symbol] network_id The Network ID
7
+ # @attr_reader [String] id The onchain Address ID
14
8
  class Address
15
- # Returns a new Address object. Do not use this method directly. Instead, use Wallet#create_address, or use
16
- # the Wallet's default_address.
17
- # @param model [Coinbase::Client::Address] The underlying Address object
18
- # @param key [Eth::Key] The key backing the Address. Can be nil.
19
- def initialize(model, key)
20
- @model = model
21
- @key = key
22
- end
9
+ attr_reader :network_id, :id
23
10
 
24
- # Returns the Network ID of the Address.
25
- # @return [Symbol] The Network ID
26
- def network_id
27
- Coinbase.to_sym(@model.network_id)
11
+ # Returns a new Address object.
12
+ # @param network_id [Symbol] The Network ID
13
+ # @param id [String] The onchain Address ID
14
+ def initialize(network_id, id)
15
+ @network_id = Coinbase.to_sym(network_id)
16
+ @id = id
28
17
  end
29
18
 
30
- # Returns the Wallet ID of the Address.
31
- # @return [String] The Wallet ID
32
- def wallet_id
33
- @model.wallet_id
19
+ # Returns a String representation of the Address.
20
+ # @return [String] a String representation of the Address
21
+ def to_s
22
+ "Coinbase::Address{id: '#{id}', network_id: '#{network_id}'}"
34
23
  end
35
24
 
36
- # Returns the Address ID.
37
- # @return [String] The Address ID
38
- def id
39
- @model.address_id
25
+ # Same as to_s.
26
+ # @return [String] a String representation of the Address
27
+ def inspect
28
+ to_s
40
29
  end
41
30
 
42
- # Sets the private key backing the Address. This key is used to sign transactions.
43
- # @param key [Eth::Key] The key backing the Address
44
- def key=(key)
45
- raise 'Private key is already set' unless @key.nil?
46
-
47
- @key = key
31
+ # Returns true if the Address can sign transactions.
32
+ # @return [Boolean] true if the Address can sign transactions
33
+ def can_sign?
34
+ false
48
35
  end
49
36
 
50
37
  # Returns the balances of the Address.
@@ -52,7 +39,7 @@ module Coinbase
52
39
  # in ETH.
53
40
  def balances
54
41
  response = Coinbase.call_api do
55
- addresses_api.list_address_balances(wallet_id, id)
42
+ addresses_api.list_external_address_balances(Coinbase.normalize_network(network_id), id)
56
43
  end
57
44
 
58
45
  Coinbase::BalanceMap.from_balances(response.data)
@@ -63,7 +50,11 @@ module Coinbase
63
50
  # @return [BigDecimal] The balance of the Asset
64
51
  def balance(asset_id)
65
52
  response = Coinbase.call_api do
66
- addresses_api.get_address_balance(wallet_id, id, Coinbase::Asset.primary_denomination(asset_id).to_s)
53
+ addresses_api.get_external_address_balance(
54
+ Coinbase.normalize_network(network_id),
55
+ id,
56
+ Coinbase::Asset.primary_denomination(asset_id).to_s
57
+ )
67
58
  end
68
59
 
69
60
  return BigDecimal('0') if response.nil?
@@ -71,64 +62,6 @@ module Coinbase
71
62
  Coinbase::Balance.from_model_and_asset_id(response, asset_id).amount
72
63
  end
73
64
 
74
- # Transfers the given amount of the given Asset to the specified address or wallet.
75
- # Only same-network Transfers are supported.
76
- # @param amount [Integer, Float, BigDecimal] The amount of the Asset to send.
77
- # @param asset_id [Symbol] The ID of the Asset to send. For Ether, :eth, :gwei, and :wei are supported.
78
- # @param destination [Wallet | Address | String] The destination of the transfer. If a Wallet, sends to the Wallet's
79
- # default address. If a String, interprets it as the address ID.
80
- # @return [Coinbase::Transfer] The Transfer object.
81
- def transfer(amount, asset_id, destination)
82
- destination_address, destination_network = destination_address_and_network(destination)
83
-
84
- validate_can_transfer!(amount, asset_id, destination_network)
85
-
86
- transfer = create_transfer(amount, asset_id, destination_address)
87
-
88
- # If a server signer is managing keys, it will sign and broadcast the underlying transfer transaction out of band.
89
- return transfer if Coinbase.use_server_signer?
90
-
91
- broadcast_transfer(transfer, transfer.transaction.sign(@key))
92
- end
93
-
94
- # Trades the given amount of the given Asset for another Asset.
95
- # Only same-network Trades are supported.
96
- # @param amount [Integer, Float, BigDecimal] The amount of the Asset to send.
97
- # @param from_asset_id [Symbol] The ID of the Asset to trade from. For Ether, :eth, :gwei, and :wei are supported.
98
- # @param to_asset_id [Symbol] The ID of the Asset to trade to. For Ether, :eth, :gwei, and :wei are supported.
99
- # @return [Coinbase::Trade] The Trade object.
100
- def trade(amount, from_asset_id, to_asset_id)
101
- validate_can_trade!(amount, from_asset_id, to_asset_id)
102
-
103
- trade = create_trade(amount, from_asset_id, to_asset_id)
104
-
105
- # NOTE: Trading does not yet support server signers at this point.
106
-
107
- payloads = { signed_payload: trade.transaction.sign(@key) }
108
-
109
- payloads[:approve_tx_signed_payload] = trade.approve_transaction.sign(@key) unless trade.approve_transaction.nil?
110
-
111
- broadcast_trade(trade, **payloads)
112
- end
113
-
114
- # Returns whether the Address has a private key backing it to sign transactions.
115
- # @return [Boolean] Whether the Address has a private key backing it to sign transactions.
116
- def can_sign?
117
- !@key.nil?
118
- end
119
-
120
- # Returns a String representation of the Address.
121
- # @return [String] a String representation of the Address
122
- def to_s
123
- "Coinbase::Address{id: '#{id}', network_id: '#{network_id}', wallet_id: '#{wallet_id}'}"
124
- end
125
-
126
- # Same as to_s.
127
- # @return [String] a String representation of the Address
128
- def inspect
129
- to_s
130
- end
131
-
132
65
  # Requests funds for the address from the faucet and returns the faucet transaction.
133
66
  # This is only supported on testnet networks.
134
67
  # @return [Coinbase::FaucetTransaction] The successful faucet transaction
@@ -136,136 +69,16 @@ module Coinbase
136
69
  # @raise [Coinbase::Client::ApiError] If an unexpected error occurs while requesting faucet funds.
137
70
  def faucet
138
71
  Coinbase.call_api do
139
- Coinbase::FaucetTransaction.new(addresses_api.request_faucet_funds(wallet_id, id))
140
- end
141
- end
142
-
143
- # Exports the Address's private key to a hex string.
144
- # @return [String] The Address's private key as a hex String
145
- def export
146
- raise 'Cannot export key without private key loaded' if @key.nil?
147
-
148
- @key.private_hex
149
- end
150
-
151
- # Returns all of the transfers associated with the address.
152
- # @return [Array<Coinbase::Transfer>] The transfers associated with the address
153
- def transfers
154
- transfers = []
155
- page = nil
156
-
157
- loop do
158
- response = Coinbase.call_api do
159
- transfers_api.list_transfers(wallet_id, id, { limit: 100, page: page })
160
- end
161
-
162
- break if response.data.empty?
163
-
164
- transfers.concat(response.data.map { |transfer| Coinbase::Transfer.new(transfer) })
165
-
166
- break unless response.has_more
167
-
168
- page = response.next_page
72
+ Coinbase::FaucetTransaction.new(
73
+ addresses_api.request_external_faucet_funds(Coinbase.normalize_network(network_id), id)
74
+ )
169
75
  end
170
-
171
- transfers
172
76
  end
173
77
 
174
78
  private
175
79
 
176
80
  def addresses_api
177
- @addresses_api ||= Coinbase::Client::AddressesApi.new(Coinbase.configuration.api_client)
178
- end
179
-
180
- def transfers_api
181
- @transfers_api ||= Coinbase::Client::TransfersApi.new(Coinbase.configuration.api_client)
182
- end
183
-
184
- def trades_api
185
- @trades_api ||= Coinbase::Client::TradesApi.new(Coinbase.configuration.api_client)
186
- end
187
-
188
- def destination_address_and_network(destination)
189
- return [destination.default_address.id, destination.network_id] if destination.is_a?(Wallet)
190
- return [destination.id, destination.network_id] if destination.is_a?(Address)
191
-
192
- [destination, network_id]
193
- end
194
-
195
- def validate_can_transfer!(amount, asset_id, destination_network_id)
196
- raise 'Cannot transfer from address without private key loaded' unless can_sign? || Coinbase.use_server_signer?
197
-
198
- raise ArgumentError, "Unsupported asset: #{asset_id}" unless Coinbase::Asset.supported?(asset_id)
199
-
200
- raise ArgumentError, 'Transfer must be on the same Network' unless destination_network_id == network_id
201
-
202
- current_balance = balance(asset_id)
203
-
204
- return unless current_balance < amount
205
-
206
- raise ArgumentError, "Insufficient funds: #{amount} requested, but only #{current_balance} available"
207
- end
208
-
209
- def create_transfer(amount, asset_id, destination)
210
- create_transfer_request = {
211
- amount: Coinbase::Asset.to_atomic_amount(amount, asset_id).to_i.to_s,
212
- network_id: network_id,
213
- asset_id: Coinbase::Asset.primary_denomination(asset_id).to_s,
214
- destination: destination
215
- }
216
-
217
- transfer_model = Coinbase.call_api do
218
- transfers_api.create_transfer(wallet_id, id, create_transfer_request)
219
- end
220
-
221
- Coinbase::Transfer.new(transfer_model)
222
- end
223
-
224
- def broadcast_transfer(transfer, signed_payload)
225
- transfer_model = Coinbase.call_api do
226
- transfers_api.broadcast_transfer(wallet_id, id, transfer.id, { signed_payload: signed_payload })
227
- end
228
-
229
- Coinbase::Transfer.new(transfer_model)
230
- end
231
-
232
- def validate_can_trade!(amount, from_asset_id, to_asset_id)
233
- raise 'Cannot trade from address without private key loaded' unless can_sign?
234
-
235
- raise ArgumentError, "Unsupported from asset: #{from_asset_id}" unless Coinbase::Asset.supported?(from_asset_id)
236
- raise ArgumentError, "Unsupported to asset: #{to_asset_id}" unless Coinbase::Asset.supported?(to_asset_id)
237
-
238
- current_balance = balance(from_asset_id)
239
-
240
- return unless current_balance < amount
241
-
242
- raise ArgumentError, "Insufficient funds: #{amount} requested, but only #{current_balance} available"
243
- end
244
-
245
- def create_trade(amount, from_asset_id, to_asset_id)
246
- create_trade_request = {
247
- amount: Coinbase::Asset.to_atomic_amount(amount, from_asset_id).to_i.to_s,
248
- from_asset_id: Coinbase::Asset.primary_denomination(from_asset_id).to_s,
249
- to_asset_id: Coinbase::Asset.primary_denomination(to_asset_id).to_s
250
- }
251
-
252
- trade_model = Coinbase.call_api do
253
- trades_api.create_trade(wallet_id, id, create_trade_request)
254
- end
255
-
256
- Coinbase::Trade.new(trade_model)
257
- end
258
-
259
- def broadcast_trade(trade, signed_payload:, approve_tx_signed_payload: nil)
260
- req = { signed_payload: signed_payload }
261
-
262
- req[:approve_transaction_signed_payload] = approve_tx_signed_payload unless approve_tx_signed_payload.nil?
263
-
264
- trade_model = Coinbase.call_api do
265
- trades_api.broadcast_trade(wallet_id, id, trade.id, req)
266
- end
267
-
268
- Coinbase::Trade.new(trade_model)
81
+ @addresses_api ||= Coinbase::Client::ExternalAddressesApi.new(Coinbase.configuration.api_client)
269
82
  end
270
83
  end
271
84
  end
@@ -3,98 +3,108 @@
3
3
  module Coinbase
4
4
  # A representation of an Asset.
5
5
  class Asset
6
- # Retuns whether the provided asset ID is supported.
7
- # @param asset_id [Symbol] The Asset ID
8
- # @return [Boolean] Whether the Asset ID is supported
9
- def self.supported?(asset_id)
10
- !!Coinbase::SUPPORTED_ASSET_IDS[asset_id]
11
- end
6
+ class << self
7
+ # Returns the primary denomination for the provided Asset ID.
8
+ # For assets with multiple denominations, e.g. eth can also be denominated in wei and gwei,
9
+ # this method will return the primary denomination.
10
+ # e.g. eth.
11
+ # @param asset_id [Symbol] The Asset ID
12
+ # @return [Symbol] The primary denomination for the Asset ID
13
+ def primary_denomination(asset_id)
14
+ return :eth if %i[wei gwei].include?(asset_id)
12
15
 
13
- # Converts the amount of the Asset to the atomic units of the primary denomination of the Asset.
14
- # @param amount [Integer, Float, BigDecimal] The amount to normalize
15
- # @param asset_id [Symbol] The ID of the Asset being transferred
16
- # @return [BigDecimal] The normalized amount in atomic units
17
- def self.to_atomic_amount(amount, asset_id)
18
- case asset_id
19
- when :eth
20
- amount * BigDecimal(Coinbase::WEI_PER_ETHER.to_s)
21
- when :gwei
22
- amount * BigDecimal(Coinbase::WEI_PER_GWEI.to_s)
23
- when :usdc
24
- amount * BigDecimal(Coinbase::ATOMIC_UNITS_PER_USDC.to_s)
25
- when :weth
26
- amount * BigDecimal(Coinbase::WEI_PER_ETHER)
27
- else
28
- amount
16
+ asset_id
29
17
  end
30
- end
31
18
 
32
- # Converts an amount from the atomic value of the primary denomination of the provided Asset ID
33
- # to whole units of the specified asset ID.
34
- # @param atomic_amount [BigDecimal] The amount in atomic units
35
- # @param asset_id [Symbol] The Asset ID
36
- # @return [BigDecimal] The amount in whole units of the specified asset ID
37
- def self.from_atomic_amount(atomic_amount, asset_id)
38
- case asset_id
39
- when :eth
40
- atomic_amount / BigDecimal(Coinbase::WEI_PER_ETHER.to_s)
41
- when :gwei
42
- atomic_amount / BigDecimal(Coinbase::WEI_PER_GWEI.to_s)
43
- when :usdc
44
- atomic_amount / BigDecimal(Coinbase::ATOMIC_UNITS_PER_USDC.to_s)
45
- when :weth
46
- atomic_amount / BigDecimal(Coinbase::WEI_PER_ETHER)
47
- else
48
- atomic_amount
19
+ def from_model(asset_model, asset_id: nil)
20
+ raise unless asset_model.is_a?(Coinbase::Client::Asset)
21
+
22
+ decimals = asset_model.decimals
23
+
24
+ # Handle the non-primary denomination case at the asset level.
25
+ # TODO: Push this logic down to the backend.
26
+ if asset_id && Coinbase.to_sym(asset_id) != Coinbase.to_sym(asset_model.asset_id)
27
+ case asset_id
28
+ when :gwei
29
+ decimals = GWEI_DECIMALS
30
+ when :wei
31
+ decimals = 0
32
+ else
33
+ raise ArgumentError, "Unsupported asset ID: #{asset_id}"
34
+ end
35
+ end
36
+
37
+ new(
38
+ network_id: Coinbase.to_sym(asset_model.network_id),
39
+ asset_id: asset_id || Coinbase.to_sym(asset_model.asset_id),
40
+ address_id: asset_model.contract_address,
41
+ decimals: decimals
42
+ )
49
43
  end
50
- end
51
44
 
52
- # Returns the primary denomination for the provided Asset ID.
53
- # For assets with multiple denominations, e.g. eth can also be denominated in wei and gwei,
54
- # this method will return the primary denomination.
55
- # e.g. eth.
56
- # @param asset_id [Symbol] The Asset ID
57
- # @return [Symbol] The primary denomination for the Asset ID
58
- def self.primary_denomination(asset_id)
59
- return :eth if %i[wei gwei].include?(asset_id)
45
+ # Fetches the Asset with the provided Asset ID.
46
+ # @param asset_id [Symbol] The Asset ID
47
+ # @return [Coinbase::Asset] The Asset
48
+ def fetch(network_id, asset_id)
49
+ asset_model = Coinbase.call_api do
50
+ assets_api.get_asset(
51
+ Coinbase.normalize_network(network_id),
52
+ primary_denomination(asset_id).to_s
53
+ )
54
+ end
60
55
 
61
- asset_id
62
- end
56
+ from_model(asset_model, asset_id: asset_id)
57
+ end
63
58
 
64
- def self.from_model(asset_model)
65
- raise unless asset_model.is_a?(Coinbase::Client::Asset)
59
+ private
66
60
 
67
- new(
68
- network_id: Coinbase.to_sym(asset_model.network_id),
69
- asset_id: Coinbase.to_sym(asset_model.asset_id),
70
- address_id: asset_model.contract_address,
71
- decimals: asset_model.decimals
72
- )
61
+ def assets_api
62
+ Coinbase::Client::AssetsApi.new(Coinbase.configuration.api_client)
63
+ end
73
64
  end
74
65
 
75
66
  # Returns a new Asset object. Do not use this method. Instead, use the Asset constants defined in
76
67
  # the Coinbase module.
77
68
  # @param network_id [Symbol] The ID of the Network to which the Asset belongs
78
69
  # @param asset_id [Symbol] The Asset ID
79
- # @param display_name [String] (Optional) The Asset's display name
80
70
  # @param address_id [String] (Optional) The Asset's address ID, if one exists
81
71
  # @param decimals [Integer] (Optional) The number of decimal places the Asset uses
82
- def initialize(network_id:, asset_id:, display_name: nil, address_id: nil, decimals: nil)
72
+ def initialize(network_id:, asset_id:, decimals:, address_id: nil)
83
73
  @network_id = network_id
84
74
  @asset_id = asset_id
85
- @display_name = display_name
86
75
  @address_id = address_id
87
76
  @decimals = decimals
88
77
  end
89
78
 
90
- attr_reader :network_id, :asset_id, :display_name, :address_id, :decimals
79
+ attr_reader :network_id, :asset_id, :address_id, :decimals
80
+
81
+ # Converts the amount of the Asset from atomic to whole units.
82
+ # @param atomic_amount [Integer, Float, BigDecimal] The atomic amount to convert to whole units.
83
+ # @return [BigDecimal] The amount in whole units
84
+ def from_atomic_amount(atomic_amount)
85
+ BigDecimal(atomic_amount) / BigDecimal(10).power(decimals)
86
+ end
87
+
88
+ # Converts the amount of the Asset from whole to atomic units.
89
+ # @param whole_amount [Integer, Float, BigDecimal] The whole amount to convert to atomic units.
90
+ # @return [BigDecimal] The amount in atomic units
91
+ def to_atomic_amount(whole_amount)
92
+ whole_amount * BigDecimal(10).power(decimals)
93
+ end
94
+
95
+ # Returns the primary denomination for the Asset.
96
+ # For `gwei` and `wei` the primary denomination is `eth`.
97
+ # For all other assets, the primary denomination is the same asset ID.
98
+ # @return [Symbol] The primary denomination for the Asset
99
+ def primary_denomination
100
+ self.class.primary_denomination(asset_id)
101
+ end
91
102
 
92
103
  # Returns a string representation of the Asset.
93
104
  # @return [String] a string representation of the Asset
94
105
  def to_s
95
- "Coinbase::Asset{network_id: '#{network_id}', asset_id: '#{asset_id}', display_name: '#{display_name}'" +
96
- (address_id.nil? ? '}' : ", address_id: '#{address_id}'}") +
97
- (decimals.nil? ? '}' : ", decimals: '#{decimals}'}")
106
+ "Coinbase::Asset{network_id: '#{network_id}', asset_id: '#{asset_id}', decimals: '#{decimals}'" \
107
+ "#{address_id.nil? ? '' : ", address_id: '#{address_id}'"}}"
98
108
  end
99
109
 
100
110
  # Same as to_s.
@@ -45,6 +45,8 @@ module Coinbase
45
45
  uris: [uri]
46
46
  }
47
47
 
48
+ raise Coinbase::InvalidConfiguration, 'API key not configured' unless Coinbase.configured?
49
+
48
50
  private_key = OpenSSL::PKey.read(Coinbase.configuration.api_key_private_key)
49
51
  JWT.encode(claims, private_key, 'ES256', header)
50
52
  end
@@ -7,9 +7,9 @@ module Coinbase
7
7
  # @param balance_model [Coinbase::Client::Balance] The balance fetched from the API.
8
8
  # @return [Balance] The converted Balance object.
9
9
  def self.from_model(balance_model)
10
- asset_id = Coinbase.to_sym(balance_model.asset.asset_id.downcase)
10
+ asset = Coinbase::Asset.from_model(balance_model.asset)
11
11
 
12
- from_model_and_asset_id(balance_model, asset_id)
12
+ new(amount: asset.from_atomic_amount(balance_model.amount), asset: asset)
13
13
  end
14
14
 
15
15
  # Converts a Coinbase::Client::Balance model and asset ID to a Coinbase::Balance
@@ -19,8 +19,11 @@ module Coinbase
19
19
  # @param asset_id [Symbol] The Asset ID of the denomination we want returned.
20
20
  # @return [Balance] The converted Balance object.
21
21
  def self.from_model_and_asset_id(balance_model, asset_id)
22
+ asset = Coinbase::Asset.from_model(balance_model.asset, asset_id: asset_id)
23
+
22
24
  new(
23
- amount: Coinbase::Asset.from_atomic_amount(BigDecimal(balance_model.amount), asset_id),
25
+ amount: asset.from_atomic_amount(balance_model.amount),
26
+ asset: asset,
24
27
  asset_id: asset_id
25
28
  )
26
29
  end
@@ -29,12 +32,13 @@ module Coinbase
29
32
  # Balance.from_model_and_asset_id.
30
33
  # @param amount [BigDecimal] The amount of the Asset
31
34
  # @param asset_id [Symbol] The Asset ID
32
- def initialize(amount:, asset_id:)
35
+ def initialize(amount:, asset:, asset_id: nil)
33
36
  @amount = amount
34
- @asset_id = asset_id
37
+ @asset = asset
38
+ @asset_id = asset_id || asset.asset_id
35
39
  end
36
40
 
37
- attr_reader :amount, :asset_id
41
+ attr_reader :amount, :asset, :asset_id
38
42
 
39
43
  # Returns a string representation of the Balance.
40
44
  # @return [String] a string representation of the Balance
@@ -6,7 +6,7 @@
6
6
  The version of the OpenAPI document: 0.0.1-alpha
7
7
  Contact: yuga.cohler@coinbase.com
8
8
  Generated by: https://openapi-generator.tech
9
- Generator version: 7.5.0
9
+ Generator version: 7.6.0
10
10
 
11
11
  =end
12
12
 
@@ -0,0 +1,91 @@
1
+ =begin
2
+ #Coinbase Platform API
3
+
4
+ #This is the OpenAPI 3.0 specification for the Coinbase Platform APIs, used in conjunction with the Coinbase Platform SDKs.
5
+
6
+ The version of the OpenAPI document: 0.0.1-alpha
7
+ Contact: yuga.cohler@coinbase.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.6.0
10
+
11
+ =end
12
+
13
+ require 'cgi'
14
+
15
+ module Coinbase::Client
16
+ class AssetsApi
17
+ attr_accessor :api_client
18
+
19
+ def initialize(api_client = ApiClient.default)
20
+ @api_client = api_client
21
+ end
22
+ # Get the asset for the specified asset ID.
23
+ # Get the asset for the specified asset ID.
24
+ # @param network_id [String] The ID of the blockchain network
25
+ # @param asset_id [String] The ID of the asset to fetch
26
+ # @param [Hash] opts the optional parameters
27
+ # @return [Asset]
28
+ def get_asset(network_id, asset_id, opts = {})
29
+ data, _status_code, _headers = get_asset_with_http_info(network_id, asset_id, opts)
30
+ data
31
+ end
32
+
33
+ # Get the asset for the specified asset ID.
34
+ # Get the asset for the specified asset ID.
35
+ # @param network_id [String] The ID of the blockchain network
36
+ # @param asset_id [String] The ID of the asset to fetch
37
+ # @param [Hash] opts the optional parameters
38
+ # @return [Array<(Asset, Integer, Hash)>] Asset data, response status code and response headers
39
+ def get_asset_with_http_info(network_id, asset_id, opts = {})
40
+ if @api_client.config.debugging
41
+ @api_client.config.logger.debug 'Calling API: AssetsApi.get_asset ...'
42
+ end
43
+ # verify the required parameter 'network_id' is set
44
+ if @api_client.config.client_side_validation && network_id.nil?
45
+ fail ArgumentError, "Missing the required parameter 'network_id' when calling AssetsApi.get_asset"
46
+ end
47
+ # verify the required parameter 'asset_id' is set
48
+ if @api_client.config.client_side_validation && asset_id.nil?
49
+ fail ArgumentError, "Missing the required parameter 'asset_id' when calling AssetsApi.get_asset"
50
+ end
51
+ # resource path
52
+ local_var_path = '/v1/networks/{network_id}/assets/{asset_id}'.sub('{' + 'network_id' + '}', CGI.escape(network_id.to_s)).sub('{' + 'asset_id' + '}', CGI.escape(asset_id.to_s))
53
+
54
+ # query parameters
55
+ query_params = opts[:query_params] || {}
56
+
57
+ # header parameters
58
+ header_params = opts[:header_params] || {}
59
+ # HTTP header 'Accept' (if needed)
60
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
61
+
62
+ # form parameters
63
+ form_params = opts[:form_params] || {}
64
+
65
+ # http body (model)
66
+ post_body = opts[:debug_body]
67
+
68
+ # return_type
69
+ return_type = opts[:debug_return_type] || 'Asset'
70
+
71
+ # auth_names
72
+ auth_names = opts[:debug_auth_names] || []
73
+
74
+ new_options = opts.merge(
75
+ :operation => :"AssetsApi.get_asset",
76
+ :header_params => header_params,
77
+ :query_params => query_params,
78
+ :form_params => form_params,
79
+ :body => post_body,
80
+ :auth_names => auth_names,
81
+ :return_type => return_type
82
+ )
83
+
84
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
85
+ if @api_client.config.debugging
86
+ @api_client.config.logger.debug "API called: AssetsApi#get_asset\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
87
+ end
88
+ return data, status_code, headers
89
+ end
90
+ end
91
+ end