coinbase 0.0.1 → 4.2.0

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.

Potentially problematic release.


This version of coinbase might be problematic. Click here for more details.

Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +7 -0
  4. data/CONTRIBUTING.md +53 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +201 -0
  7. data/README.md +615 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +7 -0
  11. data/coinbase.gemspec +26 -0
  12. data/lib/coinbase/util.rb +16 -0
  13. data/lib/coinbase/wallet/adapters/em_http.rb +78 -0
  14. data/lib/coinbase/wallet/adapters/net_http.rb +68 -0
  15. data/lib/coinbase/wallet/api_client.rb +755 -0
  16. data/lib/coinbase/wallet/api_errors.rb +120 -0
  17. data/lib/coinbase/wallet/api_response.rb +41 -0
  18. data/lib/coinbase/wallet/ca-coinbase.crt +78 -0
  19. data/lib/coinbase/wallet/client.rb +101 -0
  20. data/lib/coinbase/wallet/coinbase-callback.pub +14 -0
  21. data/lib/coinbase/wallet/models/account.rb +193 -0
  22. data/lib/coinbase/wallet/models/address.rb +12 -0
  23. data/lib/coinbase/wallet/models/api_object.rb +46 -0
  24. data/lib/coinbase/wallet/models/checkout.rb +19 -0
  25. data/lib/coinbase/wallet/models/order.rb +12 -0
  26. data/lib/coinbase/wallet/models/transaction.rb +21 -0
  27. data/lib/coinbase/wallet/models/transfer.rb +13 -0
  28. data/lib/coinbase/wallet/models/user.rb +15 -0
  29. data/lib/coinbase/wallet/version.rb +5 -0
  30. data/lib/coinbase/wallet.rb +24 -156
  31. data/spec/account_spec.rb +199 -0
  32. data/spec/callback_signature_verification_spec.rb +16 -0
  33. data/spec/clients/client_spec.rb +34 -0
  34. data/spec/clients/oauth_client_spec.rb +56 -0
  35. data/spec/endpoints_spec.rb +352 -0
  36. data/spec/error_spec.rb +137 -0
  37. data/spec/models/address_spec.rb +26 -0
  38. data/spec/models/api_object_spec.rb +63 -0
  39. data/spec/models/checkout_spec.rb +52 -0
  40. data/spec/models/current_user_spec.rb +29 -0
  41. data/spec/models/order_spec.rb +52 -0
  42. data/spec/models/request_spec.rb +47 -0
  43. data/spec/models/transfer_spec.rb +64 -0
  44. data/spec/models/user_spec.rb +24 -0
  45. data/spec/spec_helper.rb +13 -0
  46. metadata +66 -110
  47. data/lib/coinbase/address.rb +0 -127
  48. data/lib/coinbase/asset.rb +0 -20
  49. data/lib/coinbase/balance_map.rb +0 -48
  50. data/lib/coinbase/constants.rb +0 -38
  51. data/lib/coinbase/network.rb +0 -55
  52. data/lib/coinbase/transfer.rb +0 -153
  53. data/lib/coinbase.rb +0 -18
@@ -0,0 +1,755 @@
1
+ module Coinbase
2
+ module Wallet
3
+ class APIClient
4
+ def auth_headers(method, path, body)
5
+ raise NotImplementedError, "APIClient is not intended to be used directly"
6
+ end
7
+
8
+ #
9
+ # Market Data
10
+ #
11
+ def currencies(params = {})
12
+ out = nil
13
+ get("/v2/currencies", params) do |resp|
14
+ out = resp.data.map { |item| APIObject.new(self, item) }
15
+ yield(out, resp) if block_given?
16
+ end
17
+ out
18
+ end
19
+
20
+ def exchange_rates(params = {})
21
+ out = nil
22
+ get("/v2/exchange-rates", params) do |resp|
23
+ out = APIObject.new(self, resp.data)
24
+ yield(out, resp) if block_given?
25
+ end
26
+ out
27
+ end
28
+
29
+ def buy_price(params = {})
30
+ out = nil
31
+ pair = determine_currency_pair(params)
32
+
33
+ get("/v2/prices/#{pair}/buy", params) do |resp|
34
+ out = APIObject.new(self, resp.data)
35
+ yield(out, resp) if block_given?
36
+ end
37
+ out
38
+ end
39
+
40
+ def sell_price(params = {})
41
+ out = nil
42
+ pair = determine_currency_pair(params)
43
+
44
+ get("/v2/prices/#{pair}/sell", params) do |resp|
45
+ out = APIObject.new(self, resp.data)
46
+ yield(out, resp) if block_given?
47
+ end
48
+ out
49
+ end
50
+
51
+ def spot_price(params = {})
52
+ out = nil
53
+ pair = determine_currency_pair(params)
54
+
55
+ get("/v2/prices/#{pair}/spot", params) do |resp|
56
+ out = APIObject.new(self, resp.data)
57
+ yield(out, resp) if block_given?
58
+ end
59
+ out
60
+ end
61
+
62
+ def historic_prices(params = {})
63
+ out = nil
64
+ get("/v2/prices/historic", params) do |resp|
65
+ out = APIObject.new(self, resp.data)
66
+ yield(out, resp) if block_given?
67
+ end
68
+ out
69
+ end
70
+
71
+ def time(params = {})
72
+ out = nil
73
+ get("/v2/time", params) do |resp|
74
+ out = APIObject.new(self, resp.data)
75
+ yield(out, resp) if block_given?
76
+ end
77
+ out
78
+ end
79
+
80
+ #
81
+ # Users
82
+ #
83
+ def user(user_id, params = {})
84
+ out = nil
85
+ get("/v2/users/#{user_id}", params) do |resp|
86
+ out = User.new(self, resp.data)
87
+ yield(out, resp) if block_given?
88
+ end
89
+ out
90
+ end
91
+
92
+ def current_user(params = {})
93
+ out = nil
94
+ get("/v2/user", params) do |resp|
95
+ out = CurrentUser.new(self, resp.data)
96
+ yield(out, resp) if block_given?
97
+ end
98
+ out
99
+ end
100
+
101
+ def auth_info(params = {})
102
+ out = nil
103
+ get("/v2/user/auth", params) do |resp|
104
+ out = APIObject.new(self, resp.data)
105
+ yield(out, resp) if block_given?
106
+ end
107
+ out
108
+ end
109
+
110
+ def update_current_user(params = {})
111
+ out = nil
112
+ put("/v2/user", params) do |resp|
113
+ out = CurrentUser.new(self, resp.data)
114
+ yield(out, resp) if block_given?
115
+ end
116
+ out
117
+ end
118
+
119
+ #
120
+ # Accounts
121
+ #
122
+ def accounts(params = {})
123
+ out = nil
124
+ get("/v2/accounts", params) do |resp|
125
+ out = resp.data.map { |item| Account.new(self, item) }
126
+ yield(out, resp) if block_given?
127
+ end
128
+ out
129
+ end
130
+
131
+ def account(account_id, params = {})
132
+ out = nil
133
+ get("/v2/accounts/#{account_id}", params) do |resp|
134
+ out = Account.new(self, resp.data)
135
+ yield(out, resp) if block_given?
136
+ end
137
+ out
138
+ end
139
+
140
+ def primary_account(params = {})
141
+ out = nil
142
+ get("/v2/accounts/primary", params) do |resp|
143
+ out = Account.new(self, resp.data)
144
+ yield(out, resp) if block_given?
145
+ end
146
+ out
147
+ end
148
+
149
+ def set_primary_account(account_id, params = {})
150
+ out = nil
151
+ post("/v2/accounts/#{account_id}/primary", params) do |resp|
152
+ out = Account.new(self, resp.data)
153
+ yield(out, resp) if block_given?
154
+ end
155
+ out
156
+ end
157
+
158
+ def create_account(params = {})
159
+ out = nil
160
+ post("/v2/accounts", params) do |resp|
161
+ out = Account.new(self, resp.data)
162
+ yield(out, resp) if block_given?
163
+ end
164
+ out
165
+ end
166
+
167
+ def update_account(account_id, params = {})
168
+ out = nil
169
+ put("/v2/accounts/#{account_id}", params) do |resp|
170
+ out = Account.new(self, resp.data)
171
+ yield(out, resp) if block_given?
172
+ end
173
+ out
174
+ end
175
+
176
+ def delete_account(account_id, params = {})
177
+ out = nil
178
+ delete("/v2/accounts/#{account_id}", params) do |resp|
179
+ out = APIObject.new(self, resp.data)
180
+ yield(out, resp) if block_given?
181
+ end
182
+ out
183
+ end
184
+
185
+ #
186
+ # Notifications
187
+ #
188
+ def notifications(params = {})
189
+ out = nil
190
+ get("/v2/notifications", params) do |resp|
191
+ out = resp.data.map { |item| APIObject.new(self, item) }
192
+ yield(out, resp) if block_given?
193
+ end
194
+ out
195
+ end
196
+
197
+ def notification(notification_id, params = {})
198
+ out = nil
199
+ get("/v2/notifications/#{notification_id}", params) do |resp|
200
+ out = APIObject.new(self, resp.data)
201
+ yield(out, resp) if block_given?
202
+ end
203
+ out
204
+ end
205
+
206
+
207
+ #
208
+ # Addresses
209
+ #
210
+ def addresses(account_id, params = {})
211
+ out = nil
212
+ get("/v2/accounts/#{account_id}/addresses", params) do |resp|
213
+ out = resp.data.map { |item| Address.new(self, item) }
214
+ yield(out, resp) if block_given?
215
+ end
216
+ out
217
+ end
218
+
219
+ def address(account_id, address_id, params = {})
220
+ out = nil
221
+ get("/v2/accounts/#{account_id}/addresses/#{address_id}", params) do |resp|
222
+ out = Address.new(self, resp.data)
223
+ yield(out, resp) if block_given?
224
+ end
225
+ out
226
+ end
227
+
228
+ def address_transactions(account_id, address_id, params = {})
229
+ out = nil
230
+ get("/v2/accounts/#{account_id}/addresses/#{address_id}/transactions", params) do |resp|
231
+ out = resp.data.map { |item| Transaction.new(self, item) }
232
+ yield(out, resp) if block_given?
233
+ end
234
+ out
235
+ end
236
+
237
+ def create_address(account_id, params = {})
238
+ out = nil
239
+ post("/v2/accounts/#{account_id}/addresses", params) do |resp|
240
+ out = Address.new(self, resp.data)
241
+ yield(out, resp) if block_given?
242
+ end
243
+ out
244
+ end
245
+
246
+ #
247
+ # Transactions
248
+ #
249
+ def transactions(account_id, params = {})
250
+ out = nil
251
+ get("/v2/accounts/#{account_id}/transactions", params) do |resp|
252
+ out = resp.data.map { |item| Transaction.new(self, item) }
253
+ yield(out, resp) if block_given?
254
+ end
255
+ out
256
+ end
257
+
258
+ def transaction(account_id, transaction_id, params = {})
259
+ out = nil
260
+ get("/v2/accounts/#{account_id}/transactions/#{transaction_id}", params) do |resp|
261
+ out = Transaction.new(self, resp.data)
262
+ yield(out, resp) if block_given?
263
+ end
264
+ out
265
+ end
266
+
267
+ def send(account_id, params = {})
268
+ [ :to, :amount ].each do |param|
269
+ raise APIError, "Missing parameter: #{param}" unless params.include? param
270
+ end
271
+ params['type'] = 'send'
272
+
273
+ out = nil
274
+ post("/v2/accounts/#{account_id}/transactions", params) do |resp|
275
+ out = Transaction.new(self, resp.data)
276
+ yield(out, resp) if block_given?
277
+ end
278
+ out
279
+ end
280
+
281
+ def transfer(account_id, params = {})
282
+ [ :to, :amount ].each do |param|
283
+ raise APIError, "Missing parameter: #{param}" unless params.include? param
284
+ end
285
+ params['type'] = 'transfer'
286
+
287
+ out = nil
288
+ post("/v2/accounts/#{account_id}/transactions", params) do |resp|
289
+ out = Transaction.new(self, resp.data)
290
+ yield(out, resp) if block_given?
291
+ end
292
+ out
293
+ end
294
+
295
+ def request(account_id, params = {})
296
+ [ :to, :amount, :currency ].each do |param|
297
+ raise APIError, "Missing parameter: #{param}" unless params.include? param
298
+ end
299
+ params['type'] = 'request'
300
+
301
+ out = nil
302
+ post("/v2/accounts/#{account_id}/transactions", params) do |resp|
303
+ out = Request.new(self, resp.data)
304
+ yield(out, resp) if block_given?
305
+ end
306
+ out
307
+ end
308
+
309
+ def resend_request(account_id, transaction_id, params = {})
310
+ out = nil
311
+ post("/v2/accounts/#{account_id}/transactions/#{transaction_id}/resend", params) do |resp|
312
+ out = APIObject.new(self, resp.data)
313
+ yield(out, resp) if block_given?
314
+ end
315
+ out
316
+ end
317
+
318
+ def cancel_request(account_id, transaction_id, params = {})
319
+ out = nil
320
+ delete("/v2/accounts/#{account_id}/transactions/#{transaction_id}", params) do |resp|
321
+ out = APIObject.new(self, resp.data)
322
+ yield(out, resp) if block_given?
323
+ end
324
+ out
325
+ end
326
+
327
+ def complete_request(account_id, transaction_id, params = {})
328
+ out = nil
329
+ post("/v2/accounts/#{account_id}/transactions/#{transaction_id}/complete", params) do |resp|
330
+ out = APIObject.new(self, resp.data)
331
+ yield(out, resp) if block_given?
332
+ end
333
+ out
334
+ end
335
+
336
+ #
337
+ # Buys
338
+ #
339
+ def list_buys(account_id, params={})
340
+ out = nil
341
+ get("/v2/accounts/#{account_id}/buys", params) do |resp|
342
+ out = resp.data.map { |item| Transfer.new(self, item) }
343
+ yield(out, resp) if block_given?
344
+ end
345
+ out
346
+ end
347
+
348
+ def list_buy(account_id, transaction_id, params = {})
349
+ out = nil
350
+ get("/v2/accounts/#{account_id}/buys/#{transaction_id}", params) do |resp|
351
+ out = Transfer.new(self, resp.data)
352
+ yield(out, resp) if block_given?
353
+ end
354
+ out
355
+ end
356
+
357
+ def buy(account_id, params = {})
358
+ raise APIError, "Missing parameter: 'amount' or 'total'" unless params.include? :amount or params.include? :total
359
+
360
+ out = nil
361
+ post("/v2/accounts/#{account_id}/buys", params) do |resp|
362
+ out = Transfer.new(self, resp.data)
363
+ yield(out, resp) if block_given?
364
+ end
365
+ out
366
+ end
367
+
368
+ def commit_buy(account_id, transaction_id, params = {})
369
+ out = nil
370
+ post("/v2/accounts/#{account_id}/buys/#{transaction_id}/commit", params) do |resp|
371
+ out = Transfer.new(self, resp.data)
372
+ yield(out, resp) if block_given?
373
+ end
374
+ out
375
+ end
376
+
377
+ #
378
+ # Sells
379
+ #
380
+ def list_sells(account_id, params = {})
381
+ out = nil
382
+ get("/v2/accounts/#{account_id}/sells", params) do |resp|
383
+ out = resp.data.map { |item| Transfer.new(self, item) }
384
+ yield(out, resp) if block_given?
385
+ end
386
+ out
387
+ end
388
+
389
+ def list_sell(account_id, transaction_id, params = {})
390
+ out = nil
391
+ get("/v2/accounts/#{account_id}/sells/#{transaction_id}", params) do |resp|
392
+ out = Transfer.new(self, resp.data)
393
+ yield(out, resp) if block_given?
394
+ end
395
+ out
396
+ end
397
+
398
+ def sell(account_id, params = {})
399
+ raise APIError, "Missing parameter: 'amount' or 'total'" unless params.include? :amount or params.include? :total
400
+
401
+ out = nil
402
+ post("/v2/accounts/#{account_id}/sells", params) do |resp|
403
+ out = Transfer.new(self, resp.data)
404
+ yield(out, resp) if block_given?
405
+ end
406
+ out
407
+ end
408
+
409
+ def commit_sell(account_id, transaction_id, params = {})
410
+ out = nil
411
+ post("/v2/accounts/#{account_id}/sells/#{transaction_id}/commit", params) do |resp|
412
+ out = Transfer.new(self, resp.data)
413
+ yield(out, resp) if block_given?
414
+ end
415
+ out
416
+ end
417
+
418
+ #
419
+ # Deposits
420
+ #
421
+ def list_deposits(account_id, params={})
422
+ out = nil
423
+ get("/v2/accounts/#{account_id}/deposits", params) do |resp|
424
+ out = resp.data.map { |item| Transfer.new(self, item) }
425
+ yield(out, resp) if block_given?
426
+ end
427
+ out
428
+ end
429
+
430
+ def list_deposit(account_id, transaction_id, params = {})
431
+ out = nil
432
+ get("/v2/accounts/#{account_id}/deposits/#{transaction_id}", params) do |resp|
433
+ out = Transfer.new(self, resp.data)
434
+ yield(out, resp) if block_given?
435
+ end
436
+ out
437
+ end
438
+
439
+ def deposit(account_id, params = {})
440
+ [ :amount ].each do |param|
441
+ raise APIError, "Missing parameter: #{param}" unless params.include? param
442
+ end
443
+
444
+ out = nil
445
+ post("/v2/accounts/#{account_id}/deposits", params) do |resp|
446
+ out = Transfer.new(self, resp.data)
447
+ yield(out, resp) if block_given?
448
+ end
449
+ out
450
+ end
451
+
452
+ def commit_deposit(account_id, transaction_id, params = {})
453
+ out = nil
454
+ post("/v2/accounts/#{account_id}/deposits/#{transaction_id}/commit", params) do |resp|
455
+ out = APIObject.new(self, resp.data)
456
+ yield(out, resp) if block_given?
457
+ end
458
+ out
459
+ end
460
+
461
+ #
462
+ # withdrawals
463
+ #
464
+ def list_withdrawals(account_id, params={})
465
+ out = nil
466
+ get("/v2/accounts/#{account_id}/withdrawals", params) do |resp|
467
+ out = resp.data.map { |item| Transfer.new(self, item) }
468
+ yield(out, resp) if block_given?
469
+ end
470
+ out
471
+ end
472
+
473
+ def list_withdrawal(account_id, transaction_id, params = {})
474
+ out = nil
475
+ get("/v2/accounts/#{account_id}/withdrawals/#{transaction_id}", params) do |resp|
476
+ out = Transfer.new(self, resp.data)
477
+ yield(out, resp) if block_given?
478
+ end
479
+ out
480
+ end
481
+
482
+ def withdraw(account_id, params = {})
483
+ [ :amount ].each do |param|
484
+ raise APIError, "Missing parameter: #{param}" unless params.include? param
485
+ end
486
+
487
+ out = nil
488
+ post("/v2/accounts/#{account_id}/withdrawals", params) do |resp|
489
+ out = Transfer.new(self, resp.data)
490
+ yield(out, resp) if block_given?
491
+ end
492
+ out
493
+ end
494
+
495
+ def commit_withdrawal(account_id, transaction_id, params = {})
496
+ out = nil
497
+ post("/v2/accounts/#{account_id}/withdrawals/#{transaction_id}/commit", params) do |resp|
498
+ out = APIObject.new(self, resp.data)
499
+ yield(out, resp) if block_given?
500
+ end
501
+ out
502
+ end
503
+
504
+ #
505
+ # Payment Methods
506
+ #
507
+ def payment_methods(params = {})
508
+ out = nil
509
+ get("/v2/payment-methods", params) do |resp|
510
+ out = resp.data.map { |item| APIObject.new(self, item) }
511
+ yield(out, resp) if block_given?
512
+ end
513
+ out
514
+ end
515
+
516
+ def payment_method(payment_method_id, params = {})
517
+ out = nil
518
+ get("/v2/payment-methods/#{payment_method_id}", params) do |resp|
519
+ out = APIObject.new(self, resp.data)
520
+ yield(out, resp) if block_given?
521
+ end
522
+ out
523
+ end
524
+
525
+ #
526
+ # Merchants
527
+ #
528
+ def merchant(merchant_id, params = {})
529
+ out = nil
530
+ get("/v2/merchants/#{merchant_id}", params) do |resp|
531
+ out = APIObject.new(self, resp.data)
532
+ yield(out, resp) if block_given?
533
+ end
534
+ out
535
+ end
536
+
537
+ #
538
+ # Orders
539
+ #
540
+ def orders(params = {})
541
+ out = nil
542
+ get("/v2/orders", params) do |resp|
543
+ out = resp.data.map { |item| Order.new(self, item) }
544
+ yield(out, resp) if block_given?
545
+ end
546
+ out
547
+ end
548
+
549
+ def order(order_id, params = {})
550
+ out = nil
551
+ get("/v2/orders/#{order_id}", params) do |resp|
552
+ out = Order.new(self, resp.data)
553
+ yield(out, resp) if block_given?
554
+ end
555
+ out
556
+ end
557
+
558
+ def create_order(params = {})
559
+ [ :amount, :currency, :name ].each do |param|
560
+ fail APIError, "Missing parameter: #{param}" unless params.include? param
561
+ end
562
+
563
+ out = nil
564
+ post("/v2/orders", params) do |resp|
565
+ out = Order.new(self, resp.data)
566
+ yield(out, resp) if block_given?
567
+ end
568
+ out
569
+ end
570
+
571
+ def refund_order(order_id, params={})
572
+ [ :currency ].each do |param|
573
+ fail APIError, "Missing parameter: #{param}" unless params.include? param
574
+ end
575
+
576
+ out = nil
577
+ post("/v2/orders/#{order_id}/refund", params) do |resp|
578
+ out = Order.new(self, resp.data)
579
+ yield(out, resp) if block_given?
580
+ end
581
+ out
582
+ end
583
+
584
+ #
585
+ # Checkouts
586
+ #
587
+ def checkouts(params = {})
588
+ out = nil
589
+ get("/v2/checkouts", params) do |resp|
590
+ out = resp.data.map { |item| Checkout.new(self, item) }
591
+ yield(out, resp) if block_given?
592
+ end
593
+ out
594
+ end
595
+
596
+ def checkout(checkout_id, params = {})
597
+ out = nil
598
+ get("/v2/checkouts/#{checkout_id}", params) do |resp|
599
+ out = Checkout.new(self, resp.data)
600
+ yield(out, resp) if block_given?
601
+ end
602
+ out
603
+ end
604
+
605
+ def create_checkout(params = {})
606
+ [ :amount, :currency, :name ].each do |param|
607
+ fail APIError, "Missing parameter: #{param}" unless params.include? param
608
+ end
609
+
610
+ out = nil
611
+ post("/v2/checkouts", params) do |resp|
612
+ out = Checkout.new(self, resp.data)
613
+ yield(out, resp) if block_given?
614
+ end
615
+ out
616
+ end
617
+
618
+ def checkout_orders(checkout_id, params = {})
619
+ out = nil
620
+ get("/v2/checkouts/#{checkout_id}/orders", params) do |resp|
621
+ out = resp.data.map { |item| Order.new(self, item) }
622
+ yield(out, resp) if block_given?
623
+ end
624
+ out
625
+ end
626
+
627
+ def create_checkout_order(checkout_id, params={})
628
+ out = nil
629
+ post("/v2/checkouts/#{checkout_id}/orders", params) do |resp|
630
+ out = Order.new(self, resp.data)
631
+ yield(out, resp) if block_given?
632
+ end
633
+ out
634
+ end
635
+
636
+ #
637
+ # HTTP Stuff
638
+ #
639
+ def get(path, params)
640
+ uri = path
641
+ if params.count > 0
642
+ uri += "?#{URI.encode_www_form(params)}"
643
+ end
644
+
645
+ headers = {}
646
+ if params.has_key? :two_factor_token
647
+ headers['CB-2FA-TOKEN'] = params[:two_factor_token]
648
+ params.delete(:two_factor_token)
649
+ end
650
+
651
+ http_verb('GET', uri, nil, headers) do |resp|
652
+ if params[:fetch_all] == true &&
653
+ resp.body.has_key?('pagination') &&
654
+ resp.body['pagination']['next_uri'] != nil
655
+ params[:starting_after] = resp.body['data'].last['id']
656
+ get(path, params) do |page|
657
+ body = resp.body
658
+ body['data'] += page.data
659
+ resp.body = body
660
+ yield(resp)
661
+ end
662
+ else
663
+ yield(resp)
664
+ end
665
+ end
666
+ end
667
+
668
+ def put(path, params)
669
+ headers = {}
670
+ if params.has_key? :two_factor_token
671
+ headers['CB-2FA-TOKEN'] = params[:two_factor_token]
672
+ params.delete(:two_factor_token)
673
+ end
674
+
675
+ http_verb('PUT', path, params.to_json, headers) do |resp|
676
+ yield(resp)
677
+ end
678
+ end
679
+
680
+ def post(path, params)
681
+ headers = {}
682
+ if params.has_key? :two_factor_token
683
+ headers['CB-2FA-TOKEN'] = params[:two_factor_token]
684
+ params.delete(:two_factor_token)
685
+ end
686
+
687
+ http_verb('POST', path, params.to_json, headers) do |resp|
688
+ yield(resp)
689
+ end
690
+ end
691
+
692
+ def delete(path, params)
693
+ headers = {}
694
+ if params.has_key? :two_factor_token
695
+ headers['CB-2FA-TOKEN'] = params[:two_factor_token]
696
+ params.delete(:two_factor_token)
697
+ end
698
+
699
+ http_verb('DELETE', path, nil, headers) do |resp|
700
+ yield(resp)
701
+ end
702
+ end
703
+
704
+ CALLBACK_DIGEST = OpenSSL::Digest.new("SHA256")
705
+ def self.verify_callback(body, signature)
706
+ return false unless callback_signing_public_key
707
+ callback_signing_public_key.verify(CALLBACK_DIGEST, signature.unpack("m0")[0], body)
708
+ rescue OpenSSL::PKey::RSAError, ArgumentError
709
+ false
710
+ end
711
+
712
+ def self.callback_signing_public_key
713
+ @@callback_signing_public_key ||= nil
714
+ return @@callback_signing_public_key if @@callback_signing_public_key
715
+ path = File.expand_path(File.join(File.dirname(__FILE__), 'coinbase-callback.pub'))
716
+ @@callback_signing_public_key = OpenSSL::PKey::RSA.new(File.read(path))
717
+ end
718
+
719
+ def callback_signing_public_key
720
+ Coinbase::Wallet::APIClient.callback_signing_public_key
721
+ end
722
+
723
+ def verify_callback(body, signature)
724
+ Coinbase::Wallet::APIClient.verify_callback(body, signature)
725
+ end
726
+
727
+ def self.whitelisted_certificates
728
+ path = File.expand_path(File.join(File.dirname(__FILE__), 'ca-coinbase.crt'))
729
+
730
+ certs = [ [] ]
731
+ File.readlines(path).each do |line|
732
+ next if ["\n","#"].include?(line[0])
733
+ certs.last << line
734
+ certs << [] if line == "-----END CERTIFICATE-----\n"
735
+ end
736
+
737
+ result = OpenSSL::X509::Store.new
738
+
739
+ certs.each do |lines|
740
+ next if lines.empty?
741
+ cert = OpenSSL::X509::Certificate.new(lines.join)
742
+ result.add_cert(cert)
743
+ end
744
+
745
+ result
746
+ end
747
+
748
+ private
749
+
750
+ def determine_currency_pair(params)
751
+ Coinbase::Util.determine_currency_pair(params)
752
+ end
753
+ end
754
+ end
755
+ end