coinbase-sdk 0.0.7 → 0.0.9

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.
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