coinbase-sdk 0.0.5 → 0.0.6

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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/lib/coinbase/address.rb +63 -44
  3. data/lib/coinbase/authenticator.rb +1 -1
  4. data/lib/coinbase/client/api/server_signers_api.rb +419 -0
  5. data/lib/coinbase/client/api/trades_api.rb +342 -0
  6. data/lib/coinbase/client/models/broadcast_trade_request.rb +222 -0
  7. data/lib/coinbase/client/models/create_address_request.rb +0 -14
  8. data/lib/coinbase/client/models/create_server_signer_request.rb +239 -0
  9. data/lib/coinbase/client/models/create_trade_request.rb +256 -0
  10. data/lib/coinbase/client/models/create_wallet_request.rb +1 -1
  11. data/lib/coinbase/client/models/create_wallet_request_wallet.rb +233 -0
  12. data/lib/coinbase/client/models/seed_creation_event.rb +240 -0
  13. data/lib/coinbase/client/models/seed_creation_event_result.rb +274 -0
  14. data/lib/coinbase/client/models/server_signer.rb +235 -0
  15. data/lib/coinbase/client/models/server_signer_event.rb +239 -0
  16. data/lib/coinbase/client/models/server_signer_event_event.rb +105 -0
  17. data/lib/coinbase/client/models/server_signer_event_list.rb +275 -0
  18. data/lib/coinbase/client/models/signature_creation_event.rb +363 -0
  19. data/lib/coinbase/client/models/signature_creation_event_result.rb +329 -0
  20. data/lib/coinbase/client/models/trade.rb +356 -0
  21. data/lib/coinbase/client/models/trade_list.rb +275 -0
  22. data/lib/coinbase/client/models/transaction.rb +294 -0
  23. data/lib/coinbase/client/models/transaction_type.rb +39 -0
  24. data/lib/coinbase/client/models/wallet.rb +55 -4
  25. data/lib/coinbase/client.rb +18 -0
  26. data/lib/coinbase/transfer.rb +21 -21
  27. data/lib/coinbase/user.rb +14 -89
  28. data/lib/coinbase/wallet.rb +176 -26
  29. data/lib/coinbase.rb +16 -4
  30. metadata +34 -2
@@ -0,0 +1,294 @@
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.5.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Coinbase::Client
17
+ # An onchain transaction.
18
+ class Transaction
19
+ # The unsigned payload of the transaction. This is the payload that needs to be signed by the sender.
20
+ attr_accessor :unsigned_payload
21
+
22
+ # The signed payload of the transaction. This is the payload that has been signed by the sender.
23
+ attr_accessor :signed_payload
24
+
25
+ # The hash of the transaction
26
+ attr_accessor :transaction_hash
27
+
28
+ # The status of the transaction
29
+ attr_accessor :status
30
+
31
+ class EnumAttributeValidator
32
+ attr_reader :datatype
33
+ attr_reader :allowable_values
34
+
35
+ def initialize(datatype, allowable_values)
36
+ @allowable_values = allowable_values.map do |value|
37
+ case datatype.to_s
38
+ when /Integer/i
39
+ value.to_i
40
+ when /Float/i
41
+ value.to_f
42
+ else
43
+ value
44
+ end
45
+ end
46
+ end
47
+
48
+ def valid?(value)
49
+ !value || allowable_values.include?(value)
50
+ end
51
+ end
52
+
53
+ # Attribute mapping from ruby-style variable name to JSON key.
54
+ def self.attribute_map
55
+ {
56
+ :'unsigned_payload' => :'unsigned_payload',
57
+ :'signed_payload' => :'signed_payload',
58
+ :'transaction_hash' => :'transaction_hash',
59
+ :'status' => :'status'
60
+ }
61
+ end
62
+
63
+ # Returns all the JSON keys this model knows about
64
+ def self.acceptable_attributes
65
+ attribute_map.values
66
+ end
67
+
68
+ # Attribute type mapping.
69
+ def self.openapi_types
70
+ {
71
+ :'unsigned_payload' => :'String',
72
+ :'signed_payload' => :'String',
73
+ :'transaction_hash' => :'String',
74
+ :'status' => :'String'
75
+ }
76
+ end
77
+
78
+ # List of attributes with nullable: true
79
+ def self.openapi_nullable
80
+ Set.new([
81
+ ])
82
+ end
83
+
84
+ # Initializes the object
85
+ # @param [Hash] attributes Model attributes in the form of hash
86
+ def initialize(attributes = {})
87
+ if (!attributes.is_a?(Hash))
88
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Coinbase::Client::Transaction` initialize method"
89
+ end
90
+
91
+ # check to see if the attribute exists and convert string to symbol for hash key
92
+ attributes = attributes.each_with_object({}) { |(k, v), h|
93
+ if (!self.class.attribute_map.key?(k.to_sym))
94
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Coinbase::Client::Transaction`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
95
+ end
96
+ h[k.to_sym] = v
97
+ }
98
+
99
+ if attributes.key?(:'unsigned_payload')
100
+ self.unsigned_payload = attributes[:'unsigned_payload']
101
+ else
102
+ self.unsigned_payload = nil
103
+ end
104
+
105
+ if attributes.key?(:'signed_payload')
106
+ self.signed_payload = attributes[:'signed_payload']
107
+ end
108
+
109
+ if attributes.key?(:'transaction_hash')
110
+ self.transaction_hash = attributes[:'transaction_hash']
111
+ end
112
+
113
+ if attributes.key?(:'status')
114
+ self.status = attributes[:'status']
115
+ else
116
+ self.status = nil
117
+ end
118
+ end
119
+
120
+ # Show invalid properties with the reasons. Usually used together with valid?
121
+ # @return Array for valid properties with the reasons
122
+ def list_invalid_properties
123
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
124
+ invalid_properties = Array.new
125
+ if @unsigned_payload.nil?
126
+ invalid_properties.push('invalid value for "unsigned_payload", unsigned_payload cannot be nil.')
127
+ end
128
+
129
+ if @status.nil?
130
+ invalid_properties.push('invalid value for "status", status cannot be nil.')
131
+ end
132
+
133
+ invalid_properties
134
+ end
135
+
136
+ # Check to see if the all the properties in the model are valid
137
+ # @return true if the model is valid
138
+ def valid?
139
+ warn '[DEPRECATED] the `valid?` method is obsolete'
140
+ return false if @unsigned_payload.nil?
141
+ return false if @status.nil?
142
+ status_validator = EnumAttributeValidator.new('String', ["pending", "broadcast", "complete", "failed"])
143
+ return false unless status_validator.valid?(@status)
144
+ true
145
+ end
146
+
147
+ # Custom attribute writer method checking allowed values (enum).
148
+ # @param [Object] status Object to be assigned
149
+ def status=(status)
150
+ validator = EnumAttributeValidator.new('String', ["pending", "broadcast", "complete", "failed"])
151
+ unless validator.valid?(status)
152
+ fail ArgumentError, "invalid value for \"status\", must be one of #{validator.allowable_values}."
153
+ end
154
+ @status = status
155
+ end
156
+
157
+ # Checks equality by comparing each attribute.
158
+ # @param [Object] Object to be compared
159
+ def ==(o)
160
+ return true if self.equal?(o)
161
+ self.class == o.class &&
162
+ unsigned_payload == o.unsigned_payload &&
163
+ signed_payload == o.signed_payload &&
164
+ transaction_hash == o.transaction_hash &&
165
+ status == o.status
166
+ end
167
+
168
+ # @see the `==` method
169
+ # @param [Object] Object to be compared
170
+ def eql?(o)
171
+ self == o
172
+ end
173
+
174
+ # Calculates hash code according to all attributes.
175
+ # @return [Integer] Hash code
176
+ def hash
177
+ [unsigned_payload, signed_payload, transaction_hash, status].hash
178
+ end
179
+
180
+ # Builds the object from hash
181
+ # @param [Hash] attributes Model attributes in the form of hash
182
+ # @return [Object] Returns the model itself
183
+ def self.build_from_hash(attributes)
184
+ return nil unless attributes.is_a?(Hash)
185
+ attributes = attributes.transform_keys(&:to_sym)
186
+ transformed_hash = {}
187
+ openapi_types.each_pair do |key, type|
188
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
189
+ transformed_hash["#{key}"] = nil
190
+ elsif type =~ /\AArray<(.*)>/i
191
+ # check to ensure the input is an array given that the attribute
192
+ # is documented as an array but the input is not
193
+ if attributes[attribute_map[key]].is_a?(Array)
194
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
195
+ end
196
+ elsif !attributes[attribute_map[key]].nil?
197
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
198
+ end
199
+ end
200
+ new(transformed_hash)
201
+ end
202
+
203
+ # Deserializes the data based on type
204
+ # @param string type Data type
205
+ # @param string value Value to be deserialized
206
+ # @return [Object] Deserialized data
207
+ def self._deserialize(type, value)
208
+ case type.to_sym
209
+ when :Time
210
+ Time.parse(value)
211
+ when :Date
212
+ Date.parse(value)
213
+ when :String
214
+ value.to_s
215
+ when :Integer
216
+ value.to_i
217
+ when :Float
218
+ value.to_f
219
+ when :Boolean
220
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
221
+ true
222
+ else
223
+ false
224
+ end
225
+ when :Object
226
+ # generic object (usually a Hash), return directly
227
+ value
228
+ when /\AArray<(?<inner_type>.+)>\z/
229
+ inner_type = Regexp.last_match[:inner_type]
230
+ value.map { |v| _deserialize(inner_type, v) }
231
+ when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
232
+ k_type = Regexp.last_match[:k_type]
233
+ v_type = Regexp.last_match[:v_type]
234
+ {}.tap do |hash|
235
+ value.each do |k, v|
236
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
237
+ end
238
+ end
239
+ else # model
240
+ # models (e.g. Pet) or oneOf
241
+ klass = Coinbase::Client.const_get(type)
242
+ klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
243
+ end
244
+ end
245
+
246
+ # Returns the string representation of the object
247
+ # @return [String] String presentation of the object
248
+ def to_s
249
+ to_hash.to_s
250
+ end
251
+
252
+ # to_body is an alias to to_hash (backward compatibility)
253
+ # @return [Hash] Returns the object in the form of hash
254
+ def to_body
255
+ to_hash
256
+ end
257
+
258
+ # Returns the object in the form of hash
259
+ # @return [Hash] Returns the object in the form of hash
260
+ def to_hash
261
+ hash = {}
262
+ self.class.attribute_map.each_pair do |attr, param|
263
+ value = self.send(attr)
264
+ if value.nil?
265
+ is_nullable = self.class.openapi_nullable.include?(attr)
266
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
267
+ end
268
+
269
+ hash[param] = _to_hash(value)
270
+ end
271
+ hash
272
+ end
273
+
274
+ # Outputs non-array value in the form of hash
275
+ # For object, use to_hash. Otherwise, just return the value
276
+ # @param [Object] value Any valid value
277
+ # @return [Hash] Returns the value in the form of hash
278
+ def _to_hash(value)
279
+ if value.is_a?(Array)
280
+ value.compact.map { |v| _to_hash(v) }
281
+ elsif value.is_a?(Hash)
282
+ {}.tap do |hash|
283
+ value.each { |k, v| hash[k] = _to_hash(v) }
284
+ end
285
+ elsif value.respond_to? :to_hash
286
+ value.to_hash
287
+ else
288
+ value
289
+ end
290
+ end
291
+
292
+ end
293
+
294
+ end
@@ -0,0 +1,39 @@
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.5.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Coinbase::Client
17
+ class TransactionType
18
+ TRANSFER = "transfer".freeze
19
+
20
+ def self.all_vars
21
+ @all_vars ||= [TRANSFER].freeze
22
+ end
23
+
24
+ # Builds the enum from string
25
+ # @param [String] The enum value in the form of the string
26
+ # @return [String] The enum value
27
+ def self.build_from_hash(value)
28
+ new.build_from_hash(value)
29
+ end
30
+
31
+ # Builds the enum from string
32
+ # @param [String] The enum value in the form of the string
33
+ # @return [String] The enum value
34
+ def build_from_hash(value)
35
+ return value if TransactionType.all_vars.include?(value)
36
+ raise "Invalid ENUM value #{value} for class #TransactionType"
37
+ end
38
+ end
39
+ end
@@ -23,12 +23,38 @@ module Coinbase::Client
23
23
 
24
24
  attr_accessor :default_address
25
25
 
26
+ # The status of the Server-Signer for the wallet if present.
27
+ attr_accessor :server_signer_status
28
+
29
+ class EnumAttributeValidator
30
+ attr_reader :datatype
31
+ attr_reader :allowable_values
32
+
33
+ def initialize(datatype, allowable_values)
34
+ @allowable_values = allowable_values.map do |value|
35
+ case datatype.to_s
36
+ when /Integer/i
37
+ value.to_i
38
+ when /Float/i
39
+ value.to_f
40
+ else
41
+ value
42
+ end
43
+ end
44
+ end
45
+
46
+ def valid?(value)
47
+ !value || allowable_values.include?(value)
48
+ end
49
+ end
50
+
26
51
  # Attribute mapping from ruby-style variable name to JSON key.
27
52
  def self.attribute_map
28
53
  {
29
54
  :'id' => :'id',
30
55
  :'network_id' => :'network_id',
31
- :'default_address' => :'default_address'
56
+ :'default_address' => :'default_address',
57
+ :'server_signer_status' => :'server_signer_status'
32
58
  }
33
59
  end
34
60
 
@@ -42,7 +68,8 @@ module Coinbase::Client
42
68
  {
43
69
  :'id' => :'String',
44
70
  :'network_id' => :'String',
45
- :'default_address' => :'Address'
71
+ :'default_address' => :'Address',
72
+ :'server_signer_status' => :'String'
46
73
  }
47
74
  end
48
75
 
@@ -69,6 +96,8 @@ module Coinbase::Client
69
96
 
70
97
  if attributes.key?(:'id')
71
98
  self.id = attributes[:'id']
99
+ else
100
+ self.id = nil
72
101
  end
73
102
 
74
103
  if attributes.key?(:'network_id')
@@ -80,6 +109,10 @@ module Coinbase::Client
80
109
  if attributes.key?(:'default_address')
81
110
  self.default_address = attributes[:'default_address']
82
111
  end
112
+
113
+ if attributes.key?(:'server_signer_status')
114
+ self.server_signer_status = attributes[:'server_signer_status']
115
+ end
83
116
  end
84
117
 
85
118
  # Show invalid properties with the reasons. Usually used together with valid?
@@ -87,6 +120,10 @@ module Coinbase::Client
87
120
  def list_invalid_properties
88
121
  warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
89
122
  invalid_properties = Array.new
123
+ if @id.nil?
124
+ invalid_properties.push('invalid value for "id", id cannot be nil.')
125
+ end
126
+
90
127
  if @network_id.nil?
91
128
  invalid_properties.push('invalid value for "network_id", network_id cannot be nil.')
92
129
  end
@@ -98,10 +135,23 @@ module Coinbase::Client
98
135
  # @return true if the model is valid
99
136
  def valid?
100
137
  warn '[DEPRECATED] the `valid?` method is obsolete'
138
+ return false if @id.nil?
101
139
  return false if @network_id.nil?
140
+ server_signer_status_validator = EnumAttributeValidator.new('String', ["pending_seed_creation", "active_seed"])
141
+ return false unless server_signer_status_validator.valid?(@server_signer_status)
102
142
  true
103
143
  end
104
144
 
145
+ # Custom attribute writer method checking allowed values (enum).
146
+ # @param [Object] server_signer_status Object to be assigned
147
+ def server_signer_status=(server_signer_status)
148
+ validator = EnumAttributeValidator.new('String', ["pending_seed_creation", "active_seed"])
149
+ unless validator.valid?(server_signer_status)
150
+ fail ArgumentError, "invalid value for \"server_signer_status\", must be one of #{validator.allowable_values}."
151
+ end
152
+ @server_signer_status = server_signer_status
153
+ end
154
+
105
155
  # Checks equality by comparing each attribute.
106
156
  # @param [Object] Object to be compared
107
157
  def ==(o)
@@ -109,7 +159,8 @@ module Coinbase::Client
109
159
  self.class == o.class &&
110
160
  id == o.id &&
111
161
  network_id == o.network_id &&
112
- default_address == o.default_address
162
+ default_address == o.default_address &&
163
+ server_signer_status == o.server_signer_status
113
164
  end
114
165
 
115
166
  # @see the `==` method
@@ -121,7 +172,7 @@ module Coinbase::Client
121
172
  # Calculates hash code according to all attributes.
122
173
  # @return [Integer] Hash code
123
174
  def hash
124
- [id, network_id, default_address].hash
175
+ [id, network_id, default_address, server_signer_status].hash
125
176
  end
126
177
 
127
178
  # Builds the object from hash
@@ -22,12 +22,28 @@ Coinbase::Client.autoload :AddressBalanceList, 'coinbase/client/models/address_b
22
22
  Coinbase::Client.autoload :AddressList, 'coinbase/client/models/address_list'
23
23
  Coinbase::Client.autoload :Asset, 'coinbase/client/models/asset'
24
24
  Coinbase::Client.autoload :Balance, 'coinbase/client/models/balance'
25
+ Coinbase::Client.autoload :BroadcastTradeRequest, 'coinbase/client/models/broadcast_trade_request'
25
26
  Coinbase::Client.autoload :BroadcastTransferRequest, 'coinbase/client/models/broadcast_transfer_request'
26
27
  Coinbase::Client.autoload :CreateAddressRequest, 'coinbase/client/models/create_address_request'
28
+ Coinbase::Client.autoload :CreateServerSignerRequest, 'coinbase/client/models/create_server_signer_request'
29
+ Coinbase::Client.autoload :CreateTradeRequest, 'coinbase/client/models/create_trade_request'
27
30
  Coinbase::Client.autoload :CreateTransferRequest, 'coinbase/client/models/create_transfer_request'
28
31
  Coinbase::Client.autoload :CreateWalletRequest, 'coinbase/client/models/create_wallet_request'
32
+ Coinbase::Client.autoload :CreateWalletRequestWallet, 'coinbase/client/models/create_wallet_request_wallet'
29
33
  Coinbase::Client.autoload :Error, 'coinbase/client/models/error'
30
34
  Coinbase::Client.autoload :FaucetTransaction, 'coinbase/client/models/faucet_transaction'
35
+ Coinbase::Client.autoload :SeedCreationEvent, 'coinbase/client/models/seed_creation_event'
36
+ Coinbase::Client.autoload :SeedCreationEventResult, 'coinbase/client/models/seed_creation_event_result'
37
+ Coinbase::Client.autoload :ServerSigner, 'coinbase/client/models/server_signer'
38
+ Coinbase::Client.autoload :ServerSignerEvent, 'coinbase/client/models/server_signer_event'
39
+ Coinbase::Client.autoload :ServerSignerEventEvent, 'coinbase/client/models/server_signer_event_event'
40
+ Coinbase::Client.autoload :ServerSignerEventList, 'coinbase/client/models/server_signer_event_list'
41
+ Coinbase::Client.autoload :SignatureCreationEvent, 'coinbase/client/models/signature_creation_event'
42
+ Coinbase::Client.autoload :SignatureCreationEventResult, 'coinbase/client/models/signature_creation_event_result'
43
+ Coinbase::Client.autoload :Trade, 'coinbase/client/models/trade'
44
+ Coinbase::Client.autoload :TradeList, 'coinbase/client/models/trade_list'
45
+ Coinbase::Client.autoload :Transaction, 'coinbase/client/models/transaction'
46
+ Coinbase::Client.autoload :TransactionType, 'coinbase/client/models/transaction_type'
31
47
  Coinbase::Client.autoload :Transfer, 'coinbase/client/models/transfer'
32
48
  Coinbase::Client.autoload :TransferList, 'coinbase/client/models/transfer_list'
33
49
  Coinbase::Client.autoload :User, 'coinbase/client/models/user'
@@ -36,6 +52,8 @@ Coinbase::Client.autoload :WalletList, 'coinbase/client/models/wallet_list'
36
52
 
37
53
  # APIs
38
54
  Coinbase::Client.autoload :AddressesApi, 'coinbase/client/api/addresses_api'
55
+ Coinbase::Client.autoload :ServerSignersApi, 'coinbase/client/api/server_signers_api'
56
+ Coinbase::Client.autoload :TradesApi, 'coinbase/client/api/trades_api'
39
57
  Coinbase::Client.autoload :TransfersApi, 'coinbase/client/api/transfers_api'
40
58
  Coinbase::Client.autoload :UsersApi, 'coinbase/client/api/users_api'
41
59
  Coinbase::Client.autoload :WalletsApi, 'coinbase/client/api/wallets_api'
@@ -134,27 +134,17 @@ module Coinbase
134
134
  # Returns the status of the Transfer.
135
135
  # @return [Symbol] The status
136
136
  def status
137
- # Check if the transfer has been signed yet.
138
- return Status::PENDING if transaction_hash.nil?
139
-
140
- onchain_transaction = Coinbase.configuration.base_sepolia_client.eth_getTransactionByHash(transaction_hash)
141
-
142
- if onchain_transaction.nil?
143
- # If the transaction has not been broadcast, it is still pending.
144
- Status::PENDING
145
- elsif onchain_transaction['blockHash'].nil?
146
- # If the transaction has been broadcast but hasn't been included in a block, it is
147
- # broadcast.
148
- Status::BROADCAST
149
- else
150
- transaction_receipt = Coinbase.configuration.base_sepolia_client.eth_getTransactionReceipt(transaction_hash)
137
+ @model.status
138
+ end
151
139
 
152
- if transaction_receipt['status'].to_i(16) == 1
153
- Status::COMPLETE
154
- else
155
- Status::FAILED
156
- end
140
+ # Reload reloads the Transfer model with the latest version from the server side.
141
+ # @return [Transfer] The most recent version of Transfer from the server.
142
+ def reload
143
+ @model = Coinbase.call_api do
144
+ transfers_api.get_transfer(wallet_id, from_address_id, id)
157
145
  end
146
+
147
+ self
158
148
  end
159
149
 
160
150
  # Waits until the Transfer is completed or failed by polling the Network at the given interval. Raises a
@@ -162,11 +152,13 @@ module Coinbase
162
152
  # @param interval_seconds [Integer] The interval at which to poll the Network, in seconds
163
153
  # @param timeout_seconds [Integer] The maximum amount of time to wait for the Transfer to complete, in seconds
164
154
  # @return [Transfer] The completed Transfer object
165
- def wait!(interval_seconds = 0.2, timeout_seconds = 10)
155
+ def wait!(interval_seconds = 0.2, timeout_seconds = 20)
166
156
  start_time = Time.now
167
157
 
168
158
  loop do
169
- return self if status == Status::COMPLETE || status == Status::FAILED
159
+ reload
160
+
161
+ return self if terminal_state?
170
162
 
171
163
  raise Timeout::Error, 'Transfer timed out' if Time.now - start_time > timeout_seconds
172
164
 
@@ -190,5 +182,13 @@ module Coinbase
190
182
  def inspect
191
183
  to_s
192
184
  end
185
+
186
+ def transfers_api
187
+ @transfers_api ||= Coinbase::Client::TransfersApi.new(Coinbase.configuration.api_client)
188
+ end
189
+
190
+ def terminal_state?
191
+ status == Status::COMPLETE.to_s || status == Status::FAILED.to_s
192
+ end
193
193
  end
194
194
  end
data/lib/coinbase/user.rb CHANGED
@@ -40,7 +40,8 @@ module Coinbase
40
40
  # Lists the Wallets belonging to the User.
41
41
  # @param page_size [Integer] (Optional) the number of Wallets to return per page. Defaults to 10
42
42
  # @param next_page_token [String] (Optional) the token for the next page of Wallets
43
- # @return [Coinbase::Wallet] the Wallets belonging to the User
43
+ # @return [Array<Coinbase::Wallet, String>] the Wallets belonging to the User and the pagination token, if
44
+ # any.
44
45
  def wallets(page_size: 10, next_page_token: nil)
45
46
  opts = {
46
47
  limit: page_size
@@ -63,85 +64,26 @@ module Coinbase
63
64
  address_model_map[wallet_model.id] = addresses_list.data
64
65
  end
65
66
 
66
- wallet_list.data.map do |wallet_model|
67
+ wallets = wallet_list.data.map do |wallet_model|
67
68
  Wallet.new(wallet_model, seed: '', address_models: address_model_map[wallet_model.id])
68
69
  end
70
+
71
+ [wallets, wallet_list.next_page]
69
72
  end
70
73
 
71
- # Saves a wallet to local file system. Wallet saved this way can be re-instantiated with load_wallets_from_local
72
- # function, provided the backup_file is available. This is an insecure method of storing wallet seeds and should
73
- # only be used for development purposes. If you call save_wallet_locally! twice with wallets containing the same
74
- # wallet_id, the backup will be overwritten during the second attempt.
75
- # The default backup_file is `seeds.json` in the root folder. It can be configured by changing
76
- # Coinbase.configuration.backup_file_path.
77
- #
78
- # @param wallet [Coinbase::Wallet] The wallet model to save.
79
- # @param encrypt [bool] (Optional) Boolean representing whether the backup persisted to local file system should be
80
- # encrypted or not. Data is unencrypted by default.
81
- # @return [Coinbase::Wallet] the saved wallet.
82
- def save_wallet_locally!(wallet, encrypt: false)
83
- existing_seeds_in_store = existing_seeds
84
- data = wallet.export
85
- seed_to_store = data.seed
86
- auth_tag = ''
87
- iv = ''
88
- if encrypt
89
- shared_secret = store_encryption_key
90
- cipher = OpenSSL::Cipher.new('aes-256-gcm').encrypt
91
- cipher.key = OpenSSL::Digest.digest('SHA256', shared_secret)
92
- iv = cipher.random_iv
93
- cipher.iv = iv
94
- cipher.auth_data = ''
95
- encrypted_data = cipher.update(data.seed) + cipher.final
96
- auth_tag = cipher.auth_tag.unpack1('H*')
97
- iv = iv.unpack1('H*')
98
- seed_to_store = encrypted_data.unpack1('H*')
74
+ # Returns the Wallet with the given ID.
75
+ # @param wallet_id [String] the ID of the Wallet
76
+ # @return [Coinbase::Wallet] the unhydrated Wallet
77
+ def wallet(wallet_id)
78
+ wallet_model = Coinbase.call_api do
79
+ wallets_api.get_wallet(wallet_id)
99
80
  end
100
81
 
101
- existing_seeds_in_store[data.wallet_id] = {
102
- seed: seed_to_store,
103
- encrypted: encrypt,
104
- auth_tag: auth_tag,
105
- iv: iv
106
- }
107
-
108
- File.open(Coinbase.configuration.backup_file_path, 'w') do |file|
109
- file.write(JSON.pretty_generate(existing_seeds_in_store))
82
+ addresses_list = Coinbase.call_api do
83
+ addresses_api.list_addresses(wallet_model.id, { limit: Coinbase::Wallet::MAX_ADDRESSES })
110
84
  end
111
- wallet
112
- end
113
85
 
114
- # Loads all wallets belonging to the User with backup persisted to the local file system.
115
- # @return [Map<String>Coinbase::Wallet] the map of wallet_ids to the wallets.
116
- def load_wallets_from_local
117
- existing_seeds_in_store = existing_seeds
118
- raise ArgumentError, 'Backup file not found' if existing_seeds_in_store == {}
119
-
120
- wallets = {}
121
- existing_seeds_in_store.each do |wallet_id, seed_data|
122
- seed = seed_data['seed']
123
- raise ArgumentError, 'Malformed backup data' if seed.nil? || seed == ''
124
-
125
- if seed_data['encrypted']
126
- shared_secret = store_encryption_key
127
- raise ArgumentError, 'Malformed encrypted seed data' if seed_data['iv'] == '' ||
128
- seed_data['auth_tag'] == ''
129
-
130
- cipher = OpenSSL::Cipher.new('aes-256-gcm').decrypt
131
- cipher.key = OpenSSL::Digest.digest('SHA256', shared_secret)
132
- iv = [seed_data['iv']].pack('H*')
133
- cipher.iv = iv
134
- auth_tag = [seed_data['auth_tag']].pack('H*')
135
- cipher.auth_tag = auth_tag
136
- cipher.auth_data = ''
137
- hex_decoded_data = [seed_data['seed']].pack('H*')
138
- seed = cipher.update(hex_decoded_data) + cipher.final
139
- end
140
-
141
- data = Coinbase::Wallet::Data.new(wallet_id: wallet_id, seed: seed)
142
- wallets[wallet_id] = import_wallet(data)
143
- end
144
- wallets
86
+ Wallet.new(wallet_model, seed: '', address_models: addresses_list.data)
145
87
  end
146
88
 
147
89
  # Returns a string representation of the User.
@@ -165,22 +107,5 @@ module Coinbase
165
107
  def wallets_api
166
108
  @wallets_api ||= Coinbase::Client::WalletsApi.new(Coinbase.configuration.api_client)
167
109
  end
168
-
169
- def existing_seeds
170
- existing_seed_data = '{}'
171
- file_path = Coinbase.configuration.backup_file_path
172
- existing_seed_data = File.read(file_path) if File.exist?(file_path)
173
- output = JSON.parse(existing_seed_data)
174
-
175
- raise ArgumentError, 'Malformed backup data' unless output.is_a?(Hash)
176
-
177
- output
178
- end
179
-
180
- def store_encryption_key
181
- pk = OpenSSL::PKey.read(Coinbase.configuration.api_key_private_key)
182
- public_key = pk.public_key # use own public key to generate the shared secret.
183
- pk.dh_compute_key(public_key)
184
- end
185
110
  end
186
111
  end