coinbase-sdk 0.0.1 → 0.0.3

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/coinbase/address.rb +152 -51
  3. data/lib/coinbase/asset.rb +2 -1
  4. data/lib/coinbase/authenticator.rb +52 -0
  5. data/lib/coinbase/balance_map.rb +2 -2
  6. data/lib/coinbase/client/api/addresses_api.rb +454 -0
  7. data/lib/coinbase/client/api/transfers_api.rb +342 -0
  8. data/lib/coinbase/client/api/users_api.rb +79 -0
  9. data/lib/coinbase/client/api/wallets_api.rb +348 -0
  10. data/lib/coinbase/client/api_client.rb +431 -0
  11. data/lib/coinbase/client/api_error.rb +58 -0
  12. data/lib/coinbase/client/configuration.rb +375 -0
  13. data/lib/coinbase/client/models/address.rb +273 -0
  14. data/lib/coinbase/client/models/address_balance_list.rb +275 -0
  15. data/lib/coinbase/client/models/address_list.rb +275 -0
  16. data/lib/coinbase/client/models/asset.rb +260 -0
  17. data/lib/coinbase/client/models/balance.rb +239 -0
  18. data/lib/coinbase/client/models/broadcast_transfer_request.rb +222 -0
  19. data/lib/coinbase/client/models/create_address_request.rb +239 -0
  20. data/lib/coinbase/client/models/create_transfer_request.rb +273 -0
  21. data/lib/coinbase/client/models/create_wallet_request.rb +221 -0
  22. data/lib/coinbase/client/models/error.rb +278 -0
  23. data/lib/coinbase/client/models/faucet_transaction.rb +222 -0
  24. data/lib/coinbase/client/models/transfer.rb +413 -0
  25. data/lib/coinbase/client/models/transfer_list.rb +275 -0
  26. data/lib/coinbase/client/models/user.rb +231 -0
  27. data/lib/coinbase/client/models/wallet.rb +241 -0
  28. data/lib/coinbase/client/models/wallet_list.rb +275 -0
  29. data/lib/coinbase/client/version.rb +15 -0
  30. data/lib/coinbase/client.rb +59 -0
  31. data/lib/coinbase/constants.rb +8 -2
  32. data/lib/coinbase/errors.rb +120 -0
  33. data/lib/coinbase/faucet_transaction.rb +42 -0
  34. data/lib/coinbase/middleware.rb +21 -0
  35. data/lib/coinbase/network.rb +2 -2
  36. data/lib/coinbase/transfer.rb +106 -65
  37. data/lib/coinbase/user.rb +180 -0
  38. data/lib/coinbase/wallet.rb +168 -52
  39. data/lib/coinbase.rb +127 -9
  40. metadata +92 -6
@@ -0,0 +1,454 @@
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 'cgi'
14
+
15
+ module Coinbase::Client
16
+ class AddressesApi
17
+ attr_accessor :api_client
18
+
19
+ def initialize(api_client = ApiClient.default)
20
+ @api_client = api_client
21
+ end
22
+ # Create a new address
23
+ # Create a new address scoped to the wallet.
24
+ # @param wallet_id [String] The ID of the wallet to create the address in.
25
+ # @param [Hash] opts the optional parameters
26
+ # @option opts [CreateAddressRequest] :create_address_request
27
+ # @return [Address]
28
+ def create_address(wallet_id, opts = {})
29
+ data, _status_code, _headers = create_address_with_http_info(wallet_id, opts)
30
+ data
31
+ end
32
+
33
+ # Create a new address
34
+ # Create a new address scoped to the wallet.
35
+ # @param wallet_id [String] The ID of the wallet to create the address in.
36
+ # @param [Hash] opts the optional parameters
37
+ # @option opts [CreateAddressRequest] :create_address_request
38
+ # @return [Array<(Address, Integer, Hash)>] Address data, response status code and response headers
39
+ def create_address_with_http_info(wallet_id, opts = {})
40
+ if @api_client.config.debugging
41
+ @api_client.config.logger.debug 'Calling API: AddressesApi.create_address ...'
42
+ end
43
+ # verify the required parameter 'wallet_id' is set
44
+ if @api_client.config.client_side_validation && wallet_id.nil?
45
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling AddressesApi.create_address"
46
+ end
47
+ # resource path
48
+ local_var_path = '/v1/wallets/{wallet_id}/addresses'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s))
49
+
50
+ # query parameters
51
+ query_params = opts[:query_params] || {}
52
+
53
+ # header parameters
54
+ header_params = opts[:header_params] || {}
55
+ # HTTP header 'Accept' (if needed)
56
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
57
+ # HTTP header 'Content-Type'
58
+ content_type = @api_client.select_header_content_type(['application/json'])
59
+ if !content_type.nil?
60
+ header_params['Content-Type'] = content_type
61
+ end
62
+
63
+ # form parameters
64
+ form_params = opts[:form_params] || {}
65
+
66
+ # http body (model)
67
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'create_address_request'])
68
+
69
+ # return_type
70
+ return_type = opts[:debug_return_type] || 'Address'
71
+
72
+ # auth_names
73
+ auth_names = opts[:debug_auth_names] || []
74
+
75
+ new_options = opts.merge(
76
+ :operation => :"AddressesApi.create_address",
77
+ :header_params => header_params,
78
+ :query_params => query_params,
79
+ :form_params => form_params,
80
+ :body => post_body,
81
+ :auth_names => auth_names,
82
+ :return_type => return_type
83
+ )
84
+
85
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
86
+ if @api_client.config.debugging
87
+ @api_client.config.logger.debug "API called: AddressesApi#create_address\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
88
+ end
89
+ return data, status_code, headers
90
+ end
91
+
92
+ # Get address by onchain address
93
+ # Get address
94
+ # @param wallet_id [String] The ID of the wallet the address belongs to.
95
+ # @param address_id [String] The onchain address of the address that is being fetched.
96
+ # @param [Hash] opts the optional parameters
97
+ # @return [Address]
98
+ def get_address(wallet_id, address_id, opts = {})
99
+ data, _status_code, _headers = get_address_with_http_info(wallet_id, address_id, opts)
100
+ data
101
+ end
102
+
103
+ # Get address by onchain address
104
+ # Get address
105
+ # @param wallet_id [String] The ID of the wallet the address belongs to.
106
+ # @param address_id [String] The onchain address of the address that is being fetched.
107
+ # @param [Hash] opts the optional parameters
108
+ # @return [Array<(Address, Integer, Hash)>] Address data, response status code and response headers
109
+ def get_address_with_http_info(wallet_id, address_id, opts = {})
110
+ if @api_client.config.debugging
111
+ @api_client.config.logger.debug 'Calling API: AddressesApi.get_address ...'
112
+ end
113
+ # verify the required parameter 'wallet_id' is set
114
+ if @api_client.config.client_side_validation && wallet_id.nil?
115
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling AddressesApi.get_address"
116
+ end
117
+ # verify the required parameter 'address_id' is set
118
+ if @api_client.config.client_side_validation && address_id.nil?
119
+ fail ArgumentError, "Missing the required parameter 'address_id' when calling AddressesApi.get_address"
120
+ end
121
+ # resource path
122
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s))
123
+
124
+ # query parameters
125
+ query_params = opts[:query_params] || {}
126
+
127
+ # header parameters
128
+ header_params = opts[:header_params] || {}
129
+ # HTTP header 'Accept' (if needed)
130
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
131
+
132
+ # form parameters
133
+ form_params = opts[:form_params] || {}
134
+
135
+ # http body (model)
136
+ post_body = opts[:debug_body]
137
+
138
+ # return_type
139
+ return_type = opts[:debug_return_type] || 'Address'
140
+
141
+ # auth_names
142
+ auth_names = opts[:debug_auth_names] || []
143
+
144
+ new_options = opts.merge(
145
+ :operation => :"AddressesApi.get_address",
146
+ :header_params => header_params,
147
+ :query_params => query_params,
148
+ :form_params => form_params,
149
+ :body => post_body,
150
+ :auth_names => auth_names,
151
+ :return_type => return_type
152
+ )
153
+
154
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
155
+ if @api_client.config.debugging
156
+ @api_client.config.logger.debug "API called: AddressesApi#get_address\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
157
+ end
158
+ return data, status_code, headers
159
+ end
160
+
161
+ # Get address balance for asset
162
+ # Get address balance
163
+ # @param wallet_id [String] The ID of the wallet to fetch the balance for
164
+ # @param address_id [String] The onchain address of the address that is being fetched.
165
+ # @param asset_id [String] The symbol of the asset to fetch the balance for
166
+ # @param [Hash] opts the optional parameters
167
+ # @return [Balance]
168
+ def get_address_balance(wallet_id, address_id, asset_id, opts = {})
169
+ data, _status_code, _headers = get_address_balance_with_http_info(wallet_id, address_id, asset_id, opts)
170
+ data
171
+ end
172
+
173
+ # Get address balance for asset
174
+ # Get address balance
175
+ # @param wallet_id [String] The ID of the wallet to fetch the balance for
176
+ # @param address_id [String] The onchain address of the address that is being fetched.
177
+ # @param asset_id [String] The symbol of the asset to fetch the balance for
178
+ # @param [Hash] opts the optional parameters
179
+ # @return [Array<(Balance, Integer, Hash)>] Balance data, response status code and response headers
180
+ def get_address_balance_with_http_info(wallet_id, address_id, asset_id, opts = {})
181
+ if @api_client.config.debugging
182
+ @api_client.config.logger.debug 'Calling API: AddressesApi.get_address_balance ...'
183
+ end
184
+ # verify the required parameter 'wallet_id' is set
185
+ if @api_client.config.client_side_validation && wallet_id.nil?
186
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling AddressesApi.get_address_balance"
187
+ end
188
+ # verify the required parameter 'address_id' is set
189
+ if @api_client.config.client_side_validation && address_id.nil?
190
+ fail ArgumentError, "Missing the required parameter 'address_id' when calling AddressesApi.get_address_balance"
191
+ end
192
+ # verify the required parameter 'asset_id' is set
193
+ if @api_client.config.client_side_validation && asset_id.nil?
194
+ fail ArgumentError, "Missing the required parameter 'asset_id' when calling AddressesApi.get_address_balance"
195
+ end
196
+ # resource path
197
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/balances/{asset_id}'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s)).sub('{' + 'asset_id' + '}', CGI.escape(asset_id.to_s))
198
+
199
+ # query parameters
200
+ query_params = opts[:query_params] || {}
201
+
202
+ # header parameters
203
+ header_params = opts[:header_params] || {}
204
+ # HTTP header 'Accept' (if needed)
205
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
206
+
207
+ # form parameters
208
+ form_params = opts[:form_params] || {}
209
+
210
+ # http body (model)
211
+ post_body = opts[:debug_body]
212
+
213
+ # return_type
214
+ return_type = opts[:debug_return_type] || 'Balance'
215
+
216
+ # auth_names
217
+ auth_names = opts[:debug_auth_names] || []
218
+
219
+ new_options = opts.merge(
220
+ :operation => :"AddressesApi.get_address_balance",
221
+ :header_params => header_params,
222
+ :query_params => query_params,
223
+ :form_params => form_params,
224
+ :body => post_body,
225
+ :auth_names => auth_names,
226
+ :return_type => return_type
227
+ )
228
+
229
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
230
+ if @api_client.config.debugging
231
+ @api_client.config.logger.debug "API called: AddressesApi#get_address_balance\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
232
+ end
233
+ return data, status_code, headers
234
+ end
235
+
236
+ # Get all balances for address
237
+ # Get address balances
238
+ # @param wallet_id [String] The ID of the wallet to fetch the balances for
239
+ # @param address_id [String] The onchain address of the address that is being fetched.
240
+ # @param [Hash] opts the optional parameters
241
+ # @option opts [String] :page A cursor for pagination across multiple pages of results. Don&#39;t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
242
+ # @return [AddressBalanceList]
243
+ def list_address_balances(wallet_id, address_id, opts = {})
244
+ data, _status_code, _headers = list_address_balances_with_http_info(wallet_id, address_id, opts)
245
+ data
246
+ end
247
+
248
+ # Get all balances for address
249
+ # Get address balances
250
+ # @param wallet_id [String] The ID of the wallet to fetch the balances for
251
+ # @param address_id [String] The onchain address of the address that is being fetched.
252
+ # @param [Hash] opts the optional parameters
253
+ # @option opts [String] :page A cursor for pagination across multiple pages of results. Don&#39;t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
254
+ # @return [Array<(AddressBalanceList, Integer, Hash)>] AddressBalanceList data, response status code and response headers
255
+ def list_address_balances_with_http_info(wallet_id, address_id, opts = {})
256
+ if @api_client.config.debugging
257
+ @api_client.config.logger.debug 'Calling API: AddressesApi.list_address_balances ...'
258
+ end
259
+ # verify the required parameter 'wallet_id' is set
260
+ if @api_client.config.client_side_validation && wallet_id.nil?
261
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling AddressesApi.list_address_balances"
262
+ end
263
+ # verify the required parameter 'address_id' is set
264
+ if @api_client.config.client_side_validation && address_id.nil?
265
+ fail ArgumentError, "Missing the required parameter 'address_id' when calling AddressesApi.list_address_balances"
266
+ end
267
+ if @api_client.config.client_side_validation && !opts[:'page'].nil? && opts[:'page'].to_s.length > 5000
268
+ fail ArgumentError, 'invalid value for "opts[:"page"]" when calling AddressesApi.list_address_balances, the character length must be smaller than or equal to 5000.'
269
+ end
270
+
271
+ # resource path
272
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/balances'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s))
273
+
274
+ # query parameters
275
+ query_params = opts[:query_params] || {}
276
+ query_params[:'page'] = opts[:'page'] if !opts[:'page'].nil?
277
+
278
+ # header parameters
279
+ header_params = opts[:header_params] || {}
280
+ # HTTP header 'Accept' (if needed)
281
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
282
+
283
+ # form parameters
284
+ form_params = opts[:form_params] || {}
285
+
286
+ # http body (model)
287
+ post_body = opts[:debug_body]
288
+
289
+ # return_type
290
+ return_type = opts[:debug_return_type] || 'AddressBalanceList'
291
+
292
+ # auth_names
293
+ auth_names = opts[:debug_auth_names] || []
294
+
295
+ new_options = opts.merge(
296
+ :operation => :"AddressesApi.list_address_balances",
297
+ :header_params => header_params,
298
+ :query_params => query_params,
299
+ :form_params => form_params,
300
+ :body => post_body,
301
+ :auth_names => auth_names,
302
+ :return_type => return_type
303
+ )
304
+
305
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
306
+ if @api_client.config.debugging
307
+ @api_client.config.logger.debug "API called: AddressesApi#list_address_balances\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
308
+ end
309
+ return data, status_code, headers
310
+ end
311
+
312
+ # List addresses in a wallet.
313
+ # List addresses in the wallet.
314
+ # @param wallet_id [String] The ID of the wallet whose addresses to fetch
315
+ # @param [Hash] opts the optional parameters
316
+ # @option opts [Integer] :limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
317
+ # @option opts [String] :page A cursor for pagination across multiple pages of results. Don&#39;t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
318
+ # @return [AddressList]
319
+ def list_addresses(wallet_id, opts = {})
320
+ data, _status_code, _headers = list_addresses_with_http_info(wallet_id, opts)
321
+ data
322
+ end
323
+
324
+ # List addresses in a wallet.
325
+ # List addresses in the wallet.
326
+ # @param wallet_id [String] The ID of the wallet whose addresses to fetch
327
+ # @param [Hash] opts the optional parameters
328
+ # @option opts [Integer] :limit A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.
329
+ # @option opts [String] :page A cursor for pagination across multiple pages of results. Don&#39;t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
330
+ # @return [Array<(AddressList, Integer, Hash)>] AddressList data, response status code and response headers
331
+ def list_addresses_with_http_info(wallet_id, opts = {})
332
+ if @api_client.config.debugging
333
+ @api_client.config.logger.debug 'Calling API: AddressesApi.list_addresses ...'
334
+ end
335
+ # verify the required parameter 'wallet_id' is set
336
+ if @api_client.config.client_side_validation && wallet_id.nil?
337
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling AddressesApi.list_addresses"
338
+ end
339
+ if @api_client.config.client_side_validation && !opts[:'page'].nil? && opts[:'page'].to_s.length > 5000
340
+ fail ArgumentError, 'invalid value for "opts[:"page"]" when calling AddressesApi.list_addresses, the character length must be smaller than or equal to 5000.'
341
+ end
342
+
343
+ # resource path
344
+ local_var_path = '/v1/wallets/{wallet_id}/addresses'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s))
345
+
346
+ # query parameters
347
+ query_params = opts[:query_params] || {}
348
+ query_params[:'limit'] = opts[:'limit'] if !opts[:'limit'].nil?
349
+ query_params[:'page'] = opts[:'page'] if !opts[:'page'].nil?
350
+
351
+ # header parameters
352
+ header_params = opts[:header_params] || {}
353
+ # HTTP header 'Accept' (if needed)
354
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
355
+
356
+ # form parameters
357
+ form_params = opts[:form_params] || {}
358
+
359
+ # http body (model)
360
+ post_body = opts[:debug_body]
361
+
362
+ # return_type
363
+ return_type = opts[:debug_return_type] || 'AddressList'
364
+
365
+ # auth_names
366
+ auth_names = opts[:debug_auth_names] || []
367
+
368
+ new_options = opts.merge(
369
+ :operation => :"AddressesApi.list_addresses",
370
+ :header_params => header_params,
371
+ :query_params => query_params,
372
+ :form_params => form_params,
373
+ :body => post_body,
374
+ :auth_names => auth_names,
375
+ :return_type => return_type
376
+ )
377
+
378
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
379
+ if @api_client.config.debugging
380
+ @api_client.config.logger.debug "API called: AddressesApi#list_addresses\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
381
+ end
382
+ return data, status_code, headers
383
+ end
384
+
385
+ # Request faucet funds for onchain address.
386
+ # Request faucet funds to be sent to onchain address.
387
+ # @param wallet_id [String] The ID of the wallet the address belongs to.
388
+ # @param address_id [String] The onchain address of the address that is being fetched.
389
+ # @param [Hash] opts the optional parameters
390
+ # @return [FaucetTransaction]
391
+ def request_faucet_funds(wallet_id, address_id, opts = {})
392
+ data, _status_code, _headers = request_faucet_funds_with_http_info(wallet_id, address_id, opts)
393
+ data
394
+ end
395
+
396
+ # Request faucet funds for onchain address.
397
+ # Request faucet funds to be sent to onchain address.
398
+ # @param wallet_id [String] The ID of the wallet the address belongs to.
399
+ # @param address_id [String] The onchain address of the address that is being fetched.
400
+ # @param [Hash] opts the optional parameters
401
+ # @return [Array<(FaucetTransaction, Integer, Hash)>] FaucetTransaction data, response status code and response headers
402
+ def request_faucet_funds_with_http_info(wallet_id, address_id, opts = {})
403
+ if @api_client.config.debugging
404
+ @api_client.config.logger.debug 'Calling API: AddressesApi.request_faucet_funds ...'
405
+ end
406
+ # verify the required parameter 'wallet_id' is set
407
+ if @api_client.config.client_side_validation && wallet_id.nil?
408
+ fail ArgumentError, "Missing the required parameter 'wallet_id' when calling AddressesApi.request_faucet_funds"
409
+ end
410
+ # verify the required parameter 'address_id' is set
411
+ if @api_client.config.client_side_validation && address_id.nil?
412
+ fail ArgumentError, "Missing the required parameter 'address_id' when calling AddressesApi.request_faucet_funds"
413
+ end
414
+ # resource path
415
+ local_var_path = '/v1/wallets/{wallet_id}/addresses/{address_id}/faucet'.sub('{' + 'wallet_id' + '}', CGI.escape(wallet_id.to_s)).sub('{' + 'address_id' + '}', CGI.escape(address_id.to_s))
416
+
417
+ # query parameters
418
+ query_params = opts[:query_params] || {}
419
+
420
+ # header parameters
421
+ header_params = opts[:header_params] || {}
422
+ # HTTP header 'Accept' (if needed)
423
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
424
+
425
+ # form parameters
426
+ form_params = opts[:form_params] || {}
427
+
428
+ # http body (model)
429
+ post_body = opts[:debug_body]
430
+
431
+ # return_type
432
+ return_type = opts[:debug_return_type] || 'FaucetTransaction'
433
+
434
+ # auth_names
435
+ auth_names = opts[:debug_auth_names] || []
436
+
437
+ new_options = opts.merge(
438
+ :operation => :"AddressesApi.request_faucet_funds",
439
+ :header_params => header_params,
440
+ :query_params => query_params,
441
+ :form_params => form_params,
442
+ :body => post_body,
443
+ :auth_names => auth_names,
444
+ :return_type => return_type
445
+ )
446
+
447
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
448
+ if @api_client.config.debugging
449
+ @api_client.config.logger.debug "API called: AddressesApi#request_faucet_funds\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
450
+ end
451
+ return data, status_code, headers
452
+ end
453
+ end
454
+ end