uphold 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rubocop.yml +32 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +10 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +335 -0
  8. data/Rakefile +14 -0
  9. data/lib/uphold/api/auth_token.rb +17 -0
  10. data/lib/uphold/api/card.rb +36 -0
  11. data/lib/uphold/api/contact.rb +34 -0
  12. data/lib/uphold/api/endpoints.rb +26 -0
  13. data/lib/uphold/api/private_transaction.rb +58 -0
  14. data/lib/uphold/api/public_transaction.rb +23 -0
  15. data/lib/uphold/api/ticker.rb +23 -0
  16. data/lib/uphold/api/transparency.rb +15 -0
  17. data/lib/uphold/api/user.rb +23 -0
  18. data/lib/uphold/api.rb +22 -0
  19. data/lib/uphold/client.rb +14 -0
  20. data/lib/uphold/entities/asset.rb +9 -0
  21. data/lib/uphold/entities/auth_token.rb +9 -0
  22. data/lib/uphold/entities/base_entity.rb +27 -0
  23. data/lib/uphold/entities/card.rb +15 -0
  24. data/lib/uphold/entities/contact.rb +13 -0
  25. data/lib/uphold/entities/error.rb +8 -0
  26. data/lib/uphold/entities/ledger_entry.rb +10 -0
  27. data/lib/uphold/entities/oauth_error.rb +9 -0
  28. data/lib/uphold/entities/phone.rb +12 -0
  29. data/lib/uphold/entities/ticker.rb +10 -0
  30. data/lib/uphold/entities/transaction.rb +17 -0
  31. data/lib/uphold/entities/user.rb +18 -0
  32. data/lib/uphold/helpers.rb +23 -0
  33. data/lib/uphold/options.rb +39 -0
  34. data/lib/uphold/pagination.rb +9 -0
  35. data/lib/uphold/request.rb +70 -0
  36. data/lib/uphold/request_data.rb +7 -0
  37. data/lib/uphold/version.rb +3 -0
  38. data/lib/uphold.rb +46 -0
  39. data/spec/fixtures/vcr_cassettes/ledger.yml +56 -0
  40. data/spec/fixtures/vcr_cassettes/me/card.yml +61 -0
  41. data/spec/fixtures/vcr_cassettes/me/cards.yml +67 -0
  42. data/spec/fixtures/vcr_cassettes/me/contact.yml +61 -0
  43. data/spec/fixtures/vcr_cassettes/me/contacts.yml +61 -0
  44. data/spec/fixtures/vcr_cassettes/me/created_card.yml +61 -0
  45. data/spec/fixtures/vcr_cassettes/me/created_contact.yml +61 -0
  46. data/spec/fixtures/vcr_cassettes/me/phones.yml +61 -0
  47. data/spec/fixtures/vcr_cassettes/me/transactions/cancel.yml +61 -0
  48. data/spec/fixtures/vcr_cassettes/me/transactions/commit.yml +62 -0
  49. data/spec/fixtures/vcr_cassettes/me/transactions/create.yml +61 -0
  50. data/spec/fixtures/vcr_cassettes/me/transactions/create_waiting_cancel.yml +118 -0
  51. data/spec/fixtures/vcr_cassettes/me/transactions/create_waiting_resend.yml +118 -0
  52. data/spec/fixtures/vcr_cassettes/me/transactions/resend.yml +61 -0
  53. data/spec/fixtures/vcr_cassettes/me.yml +185 -0
  54. data/spec/fixtures/vcr_cassettes/pats.yml +61 -0
  55. data/spec/fixtures/vcr_cassettes/reserve/transaction.yml +60 -0
  56. data/spec/fixtures/vcr_cassettes/reserve/transactions.yml +60 -0
  57. data/spec/fixtures/vcr_cassettes/tickers.yml +60 -0
  58. data/spec/fixtures/vcr_cassettes/transparency.yml +60 -0
  59. data/spec/integration/api/auth_token_spec.rb +20 -0
  60. data/spec/integration/api/card_spec.rb +47 -0
  61. data/spec/integration/api/contact_spec.rb +53 -0
  62. data/spec/integration/api/private_transactions_spec.rb +74 -0
  63. data/spec/integration/api/public_transaction_spec.rb +35 -0
  64. data/spec/integration/api/ticker_spec.rb +21 -0
  65. data/spec/integration/api/transparency_spec.rb +33 -0
  66. data/spec/integration/api/user_spec.rb +32 -0
  67. data/spec/spec_helper.rb +26 -0
  68. data/spec/support/vcr.rb +8 -0
  69. data/spec/support/webmock.rb +11 -0
  70. data/spec/unit/api/auth_spec.rb +21 -0
  71. data/spec/unit/api/card_spec.rb +47 -0
  72. data/spec/unit/api/contact_spec.rb +53 -0
  73. data/spec/unit/api/private_transaction_spec.rb +114 -0
  74. data/spec/unit/api/public_transaction_spec.rb +34 -0
  75. data/spec/unit/api/ticker_spec.rb +34 -0
  76. data/spec/unit/api/transparency_spec.rb +33 -0
  77. data/spec/unit/api/user_spec.rb +33 -0
  78. data/spec/unit/client_spec.rb +33 -0
  79. data/spec/unit/entities/base_entity_spec.rb +36 -0
  80. data/spec/unit/helper_spec.rb +37 -0
  81. data/spec/unit/request_spec.rb +94 -0
  82. data/uphold.gemspec +30 -0
  83. metadata +296 -0
@@ -0,0 +1,23 @@
1
+ module Uphold
2
+ module API
3
+ module User
4
+ def me
5
+ request_data = RequestData.new(
6
+ Endpoints::USER,
7
+ Entities::User,
8
+ authorization_header
9
+ )
10
+ Request.perform_with_object(:get, request_data)
11
+ end
12
+
13
+ def phones
14
+ request_data = RequestData.new(
15
+ Endpoints::USER_PHONES,
16
+ Entities::Phone,
17
+ authorization_header
18
+ )
19
+ Request.perform_with_objects(:get, request_data)
20
+ end
21
+ end
22
+ end
23
+ end
data/lib/uphold/api.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'uphold/api/auth_token'
2
+ require 'uphold/api/card'
3
+ require 'uphold/api/contact'
4
+ require 'uphold/api/endpoints'
5
+ require 'uphold/api/private_transaction'
6
+ require 'uphold/api/public_transaction'
7
+ require 'uphold/api/ticker'
8
+ require 'uphold/api/transparency'
9
+ require 'uphold/api/user'
10
+
11
+ module Uphold
12
+ module API
13
+ include API::AuthToken
14
+ include API::Card
15
+ include API::Contact
16
+ include API::PrivateTransaction
17
+ include API::PublicTransaction
18
+ include API::Ticker
19
+ include API::Transparency
20
+ include API::User
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ require 'uphold/api'
2
+ require 'uphold/pagination'
3
+
4
+ module Uphold
5
+ class Client
6
+ include Pagination
7
+ include API
8
+ include Options
9
+
10
+ def initialize(**options)
11
+ @options = options
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module Uphold
2
+ module Entities
3
+ class Asset < BaseEntity
4
+ attribute :currency
5
+ attribute :values
6
+ attribute :totals
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Uphold
2
+ module Entities
3
+ class AuthToken < BaseEntity
4
+ attribute :access_token
5
+ attribute :description
6
+ attribute :expires, DateTime
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ module Uphold
2
+ module Entities
3
+ class BaseEntity
4
+ include Virtus.model
5
+
6
+ def self.from_collection(entities, content_range)
7
+ total_size = (content_range && content_range.split('/')[1]) || entities.size
8
+ items = entities.map { |entity| new(entity) }
9
+
10
+ PaginatedCollection.new(items, total_size)
11
+ end
12
+
13
+ def initialize(attributes = {})
14
+ super(Uphold::Helpers.underscored_hash(attributes))
15
+ end
16
+
17
+ class PaginatedCollection < Array
18
+ attr_reader :total_size
19
+
20
+ def initialize(items, total_size)
21
+ super(items)
22
+ @total_size = total_size.to_i
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ module Uphold
2
+ module Entities
3
+ class Card < BaseEntity
4
+ attribute :id
5
+ attribute :address
6
+ attribute :addresses
7
+ attribute :label
8
+ attribute :currency
9
+ attribute :balance
10
+ attribute :available
11
+ attribute :lastTransactionAt, DateTime
12
+ attribute :settings
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ module Uphold
2
+ module Entities
3
+ class Contact < BaseEntity
4
+ attribute :id
5
+ attribute :first_name
6
+ attribute :last_name
7
+ attribute :company
8
+ attribute :emails
9
+ attribute :addresses
10
+ attribute :name
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ module Uphold
2
+ module Entities
3
+ class Error < BaseEntity
4
+ attribute :code
5
+ attribute :errors
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ module Uphold
2
+ module Entities
3
+ class LedgerEntry < BaseEntity
4
+ attribute :type
5
+ attribute :out
6
+ attribute :in
7
+ attribute :created_at
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Uphold
2
+ module Entities
3
+ class OAuthError < BaseEntity
4
+ attribute :code
5
+ attribute :error
6
+ attribute :error_description
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module Uphold
2
+ module Entities
3
+ class Phone < BaseEntity
4
+ attribute :id
5
+ attribute :verified, Boolean
6
+ attribute :primary, Boolean
7
+ attribute :e164_masked
8
+ attribute :national_masked
9
+ attribute :international_masked
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ module Uphold
2
+ module Entities
3
+ class Ticker < BaseEntity
4
+ attribute :ask
5
+ attribute :bid
6
+ attribute :currency
7
+ attribute :pair
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ module Uphold
2
+ module Entities
3
+ class Transaction < BaseEntity
4
+ attribute :id
5
+ attribute :message
6
+ attribute :status
7
+ attribute :type
8
+ attribute :refunded_by_id
9
+ attribute :created_at, DateTime
10
+ attribute :quoted_at, DateTime
11
+ attribute :denomination
12
+ attribute :origin
13
+ attribute :destination
14
+ attribute :params
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module Uphold
2
+ module Entities
3
+ class User < BaseEntity
4
+ attribute :username, String
5
+ attribute :email, String
6
+ attribute :first_name, String
7
+ attribute :last_name, String
8
+ attribute :country, String
9
+ attribute :state, String
10
+ attribute :currencies
11
+ attribute :settings
12
+ attribute :status
13
+ attribute :balances
14
+ attribute :phones, Array[Entities::Phone]
15
+ attribute :cards, Array[Entities::Card]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ module Uphold
2
+ module Helpers
3
+ def self.underscored_hash(hash)
4
+ Hash[hash.map do |key, val|
5
+ [underscored_key(key), val]
6
+ end]
7
+ end
8
+
9
+ def self.camelized_hash(hash)
10
+ Hash[hash.map do |key, val|
11
+ [camelized_key(key), val]
12
+ end]
13
+ end
14
+
15
+ def self.underscored_key(key)
16
+ key.to_s.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase.to_sym
17
+ end
18
+
19
+ def self.camelized_key(key)
20
+ key.to_s.gsub(/(?:_)([a-z\d]*)/i) { Regexp.last_match[1].capitalize }.to_sym
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,39 @@
1
+ module Uphold
2
+ module Options
3
+ attr_reader :options
4
+ API_BASE = 'https://api.uphold.com'
5
+ SANDBOX_API_BASE = 'https://api-sandbox.uphold.com'
6
+
7
+ def bearer_token?
8
+ !bearer_token.nil?
9
+ end
10
+
11
+ def bearer_token
12
+ @bearer_token ||= authenticate!
13
+ end
14
+
15
+ def authorization_header
16
+ return {} unless bearer_token?
17
+
18
+ { 'Authorization' => "Bearer #{bearer_token}" }
19
+ end
20
+
21
+ private
22
+
23
+ def authenticate!
24
+ return options[:token] if options[:token]
25
+ return ENV['UPHOLD_AUTH_TOKEN'] if !options[:client_id] || !options[:client_secret]
26
+
27
+ response = Request.new(RequestData.new('/me/tokens', nil, {}, authentication_body)).post #perform(:post, '/oauth/token', body: authentication_body)
28
+ Hash(response).fetch('access_token', nil)
29
+ end
30
+
31
+ def authentication_body
32
+ {
33
+ grant_type: 'client_credentials',
34
+ client_id: options[:client_id],
35
+ client_secret: options[:client_secret]
36
+ }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,9 @@
1
+ module Uphold
2
+ module Pagination
3
+ def pagination_header_for_range(range)
4
+ return {} unless range
5
+
6
+ { 'Range' => "items=#{range.min}-#{range.max}" }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,70 @@
1
+ module Uphold
2
+ class Request
3
+ class APIError < StandardError; end
4
+
5
+ def self.update_base_uri
6
+ base_uri "#{Uphold.api_base}/v#{Uphold.api_version}"
7
+ end
8
+
9
+ include ::HTTParty
10
+ update_base_uri
11
+
12
+ def self.perform_with_objects(http_method, request_data)
13
+ response = new(request_data).public_send(http_method)
14
+
15
+ with_valid_response(response) do
16
+ request_data.entity.from_collection(response.parsed_response, response.headers['content-range'])
17
+ end
18
+ end
19
+
20
+ def self.perform_with_object(http_method, request_data)
21
+ response = new(request_data).public_send(http_method)
22
+
23
+ with_valid_response(response) do
24
+ request_data.entity.new(response.parsed_response)
25
+ end
26
+ end
27
+
28
+ def initialize(request_data)
29
+ @path = request_data.endpoint
30
+ @data = request_data.payload
31
+ @headers = request_data.headers
32
+ end
33
+
34
+ def get
35
+ response = self.class.get(path, options)
36
+ log_request_info(:get, response)
37
+ response
38
+ end
39
+
40
+ def post
41
+ response = self.class.post(path, options)
42
+ log_request_info(:post, response)
43
+ response
44
+ end
45
+
46
+ private
47
+
48
+ attr_reader :path, :data, :auth, :headers
49
+
50
+ def self.with_valid_response(response)
51
+ return yield unless response.code >= 400
52
+
53
+ if response['error_description']
54
+ Entities::OAuthError.new(response)
55
+ else
56
+ Entities::Error.new(response)
57
+ end
58
+ end
59
+
60
+ def options
61
+ { body: data, headers: headers }.
62
+ reject { |_k, v| v.nil? }
63
+ end
64
+
65
+ def log_request_info(http_method, response)
66
+ Uphold.logger.info "[Uphold] #{http_method.to_s.upcase} #{self.class.base_uri}#{path} #{options[:headers]} #{response.code}"
67
+ Uphold.logger.debug response.parsed_response
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,7 @@
1
+ module Uphold
2
+ RequestData = Struct.new(:endpoint, :entity, :headers, :payload) do
3
+ def initialize(endpoint, entity, headers = {}, payload = nil)
4
+ super
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Uphold
2
+ VERSION = '1.0.0'
3
+ end
data/lib/uphold.rb ADDED
@@ -0,0 +1,46 @@
1
+ require 'logger'
2
+ require 'httparty'
3
+ require 'dotenv'
4
+ require 'virtus'
5
+ Dotenv.load
6
+
7
+ require 'uphold/version'
8
+ require 'uphold/options'
9
+ require 'uphold/client'
10
+
11
+ module Uphold
12
+ ROOT_PATH = File.dirname(__FILE__)
13
+
14
+ @api_base = Options::API_BASE
15
+ @api_version = 0
16
+ @logger = Logger.new(STDOUT)
17
+
18
+ class << self
19
+ attr_accessor :api_base, :api_version, :logger
20
+
21
+ def sandbox=(value)
22
+ self.api_base = if value
23
+ Options::SANDBOX_API_BASE
24
+ else
25
+ Options::API_BASE
26
+ end
27
+ Uphold::Request.update_base_uri
28
+ end
29
+ end
30
+ end
31
+
32
+ require 'uphold/helpers'
33
+ require 'uphold/request'
34
+ require 'uphold/request_data'
35
+ require 'uphold/entities/base_entity'
36
+ require 'uphold/entities/asset'
37
+ require 'uphold/entities/auth_token'
38
+ require 'uphold/entities/card'
39
+ require 'uphold/entities/contact'
40
+ require 'uphold/entities/ledger_entry'
41
+ require 'uphold/entities/phone'
42
+ require 'uphold/entities/ticker'
43
+ require 'uphold/entities/transaction'
44
+ require 'uphold/entities/user'
45
+ require 'uphold/entities/oauth_error'
46
+ require 'uphold/entities/error'
@@ -0,0 +1,56 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.uphold.com/v0/reserve/ledger
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Authorization:
11
+ - Bearer <UPHOLD_AUTH_TOKEN>
12
+ response:
13
+ status:
14
+ code: 200
15
+ message: OK
16
+ headers:
17
+ Server:
18
+ - nginx
19
+ Date:
20
+ - Wed, 11 Mar 2015 17:02:48 GMT
21
+ Content-Type:
22
+ - application/json; charset=utf-8
23
+ Content-Length:
24
+ - '8207'
25
+ Connection:
26
+ - keep-alive
27
+ X-Content-Security-Policy:
28
+ - default-src "none"
29
+ Content-Security-Policy:
30
+ - default-src "none"
31
+ X-Webkit-Csp:
32
+ - default-src "none"
33
+ Strict-Transport-Security:
34
+ - max-age=31536000
35
+ X-Xss-Protection:
36
+ - 1; mode=block
37
+ X-Content-Type-Options:
38
+ - nosniff
39
+ X-Frame-Options:
40
+ - DENY
41
+ X-Uphold-Request-Id:
42
+ - fe6c7f3b-e8ce-4151-a39a-ac8b92913522
43
+ X-Ratelimit-Limit:
44
+ - '300'
45
+ X-Ratelimit-Remaining:
46
+ - '299'
47
+ X-Ratelimit-Reset:
48
+ - '1426093668'
49
+ Content-Range:
50
+ - items 0-49/54765
51
+ body:
52
+ encoding: UTF-8
53
+ string: '[{"type":"asset","out":{"amount":"0.2","currency":"BTC"},"in":{"amount":"58.48","currency":"USD"},"createdAt":"2015-03-11T17:02:24.638Z"},{"type":"liability","out":{"amount":"0.00","currency":"BTC"},"in":{"amount":"0.2","currency":"BTC"},"TransactionId":"85694bac-6056-4dc8-a6a8-1cba0fd753d7","createdAt":"2015-03-11T17:01:52.509Z"},{"type":"asset","out":{"amount":"0.00","currency":"BTC"},"in":{"amount":"0.2","currency":"BTC"},"createdAt":"2015-03-11T17:01:52.509Z"},{"type":"asset","out":{"amount":"0.05","currency":"BTC"},"in":{"amount":"0.05","currency":"BTC"},"createdAt":"2015-03-11T17:01:14.158Z"},{"type":"asset","out":{"amount":"0.05","currency":"BTC"},"in":{"amount":"0.05","currency":"BTC"},"createdAt":"2015-03-11T17:01:14.093Z"},{"type":"asset","out":{"amount":"0.05","currency":"BTC"},"in":{"amount":"0.05","currency":"BTC"},"createdAt":"2015-03-11T17:00:08.512Z"},{"type":"asset","out":{"amount":"22.4421","currency":"BTC"},"in":{"amount":"0.00","currency":"BTC"},"createdAt":"2015-03-11T17:00:08.449Z"},{"type":"asset","out":{"amount":"0.05","currency":"BTC"},"in":{"amount":"0.05","currency":"BTC"},"createdAt":"2015-03-11T17:00:08.445Z"},{"type":"asset","out":{"amount":"22.0001","currency":"BTC"},"in":{"amount":"0.00","currency":"BTC"},"createdAt":"2015-03-11T17:00:08.441Z"},{"type":"asset","out":{"amount":"22.29","currency":"USD"},"in":{"amount":"0.07565012","currency":"BTC"},"createdAt":"2015-03-11T16:42:38.108Z"},{"type":"liability","out":{"amount":"0.07565012","currency":"BTC"},"in":{"amount":"0.00","currency":"BTC"},"TransactionId":"5ea024f8-5728-48b1-a6d6-b4bc574c2f7e","createdAt":"2015-03-11T16:42:32.052Z"},{"type":"liability","out":{"amount":"22.29","currency":"USD"},"in":{"amount":"0.07565012","currency":"BTC"},"TransactionId":"5ea024f8-5728-48b1-a6d6-b4bc574c2f7e","createdAt":"2015-03-11T16:42:32.051Z"},{"type":"liability","out":{"amount":"15.00","currency":"GBP"},"in":{"amount":"22.29","currency":"USD"},"TransactionId":"5ea024f8-5728-48b1-a6d6-b4bc574c2f7e","createdAt":"2015-03-11T16:42:32.049Z"},{"type":"liability","out":{"amount":"6000.00","currency":"EUR"},"in":{"amount":"6000.00","currency":"EUR"},"TransactionId":"d881428f-f5e1-42cd-bbc6-a503293286e7","createdAt":"2015-03-11T16:36:06.485Z"},{"type":"asset","out":{"amount":"6000.00","currency":"EUR"},"in":{"amount":"6000.00","currency":"EUR"},"createdAt":"2015-03-11T16:36:06.485Z"},{"type":"asset","out":{"amount":"0.67992828","currency":"BTC"},"in":{"amount":"0.00","currency":"BTC"},"createdAt":"2015-03-11T16:29:01.535Z"},{"type":"asset","out":{"amount":"0.082924","currency":"BTC"},"in":{"amount":"0.00","currency":"BTC"},"createdAt":"2015-03-11T16:19:38.928Z"},{"type":"asset","out":{"amount":"147.44","currency":"USD"},"in":{"amount":"0.5002","currency":"BTC"},"createdAt":"2015-03-11T16:08:09.487Z"},{"type":"liability","out":{"amount":"0.5002","currency":"BTC"},"in":{"amount":"0.00","currency":"BTC"},"TransactionId":"76f3c454-364a-4a32-bc59-7ef1b99d0f46","createdAt":"2015-03-11T16:08:04.832Z"},{"type":"liability","out":{"amount":"147.44","currency":"USD"},"in":{"amount":"0.5002","currency":"BTC"},"TransactionId":"76f3c454-364a-4a32-bc59-7ef1b99d0f46","createdAt":"2015-03-11T16:08:04.831Z"},{"type":"asset","out":{"amount":"0.080612","currency":"BTC"},"in":{"amount":"0.00","currency":"BTC"},"createdAt":"2015-03-11T16:07:51.497Z"},{"type":"liability","out":{"amount":"0.00","currency":"BTC"},"in":{"amount":"0.00206286","currency":"BTC"},"TransactionId":"3ab9192a-5dc9-4f12-a14f-c7eca0aaa52c","createdAt":"2015-03-11T16:07:51.483Z"},{"type":"asset","out":{"amount":"0.00","currency":"BTC"},"in":{"amount":"0.00206286","currency":"BTC"},"createdAt":"2015-03-11T16:07:51.483Z"},{"type":"liability","out":{"amount":"0.2","currency":"BTC"},"in":{"amount":"58.48","currency":"USD"},"TransactionId":"85694bac-6056-4dc8-a6a8-1cba0fd753d7","createdAt":"2015-03-11T16:03:43.034Z"},{"type":"asset","out":{"amount":"0.05","currency":"BTC"},"in":{"amount":"14.61","currency":"USD"},"createdAt":"2015-03-11T15:59:32.253Z"},{"type":"liability","out":{"amount":"0.05","currency":"BTC"},"in":{"amount":"14.61","currency":"USD"},"TransactionId":"b4d7de1b-f207-4fdf-b0db-3c01eb39682d","createdAt":"2015-03-11T15:59:28.425Z"},{"type":"asset","out":{"amount":"0.05","currency":"BTC"},"in":{"amount":"14.61","currency":"USD"},"createdAt":"2015-03-11T15:59:01.447Z"},{"type":"liability","out":{"amount":"0.05","currency":"BTC"},"in":{"amount":"14.61","currency":"USD"},"TransactionId":"5dedcec0-4636-4356-9c28-d5979a864193","createdAt":"2015-03-11T15:59:00.967Z"},{"type":"asset","out":{"amount":"0.163719","currency":"BTC"},"in":{"amount":"0.00","currency":"BTC"},"createdAt":"2015-03-11T15:58:48.864Z"},{"type":"asset","out":{"amount":"0.05","currency":"BTC"},"in":{"amount":"14.60","currency":"USD"},"createdAt":"2015-03-11T15:56:29.003Z"},{"type":"liability","out":{"amount":"0.05","currency":"BTC"},"in":{"amount":"14.60","currency":"USD"},"TransactionId":"fe907110-a797-4ff8-8975-77877d809503","createdAt":"2015-03-11T15:56:09.971Z"},{"type":"asset","out":{"amount":"14.75","currency":"USD"},"in":{"amount":"0.05","currency":"BTC"},"createdAt":"2015-03-11T15:54:56.703Z"},{"type":"liability","out":{"amount":"0.05","currency":"BTC"},"in":{"amount":"0.05","currency":"BTC"},"TransactionId":"af24c746-f5d8-4807-aee1-a91640b696f4","createdAt":"2015-03-11T15:54:30.052Z"},{"type":"liability","out":{"amount":"14.75","currency":"USD"},"in":{"amount":"0.05","currency":"BTC"},"TransactionId":"af24c746-f5d8-4807-aee1-a91640b696f4","createdAt":"2015-03-11T15:54:30.051Z"},{"type":"asset","out":{"amount":"14.75","currency":"USD"},"in":{"amount":"0.05","currency":"BTC"},"createdAt":"2015-03-11T15:48:51.126Z"},{"type":"liability","out":{"amount":"0.05","currency":"BTC"},"in":{"amount":"0.05","currency":"BTC"},"TransactionId":"f06d74c5-2597-44af-b10c-8a1d5ce5849d","createdAt":"2015-03-11T15:48:46.435Z"},{"type":"liability","out":{"amount":"14.75","currency":"USD"},"in":{"amount":"0.05","currency":"BTC"},"TransactionId":"f06d74c5-2597-44af-b10c-8a1d5ce5849d","createdAt":"2015-03-11T15:48:46.434Z"},{"type":"asset","out":{"amount":"21.83","currency":"BTC"},"in":{"amount":"6343.60","currency":"USD"},"createdAt":"2015-03-11T15:48:20.314Z"},{"type":"asset","out":{"amount":"0.2389","currency":"BTC"},"in":{"amount":"69.38","currency":"USD"},"createdAt":"2015-03-11T15:48:20.311Z"},{"type":"asset","out":{"amount":"0.37830871","currency":"BTC"},"in":{"amount":"0.00","currency":"BTC"},"createdAt":"2015-03-11T15:48:11.085Z"},{"type":"asset","out":{"amount":"0.06393526","currency":"BTC"},"in":{"amount":"0.00","currency":"BTC"},"createdAt":"2015-03-11T15:48:11.054Z"},{"type":"liability","out":{"amount":"0.00","currency":"BTC"},"in":{"amount":"0.2389","currency":"BTC"},"TransactionId":"dceb1e5d-3cc2-4f7c-a8ef-b0ed7939f163","createdAt":"2015-03-11T15:48:11.050Z"},{"type":"asset","out":{"amount":"0.00","currency":"BTC"},"in":{"amount":"0.2389","currency":"BTC"},"createdAt":"2015-03-11T15:48:11.050Z"},{"type":"asset","out":{"amount":"0.00","currency":"BTC"},"in":{"amount":"50.00","currency":"BTC"},"createdAt":"2015-03-11T15:48:11.047Z"},{"type":"liability","out":{"amount":"0.00","currency":"BTC"},"in":{"amount":"50.00","currency":"BTC"},"TransactionId":"f007ad0e-f482-44df-8efa-a1561cee8d7c","createdAt":"2015-03-11T15:48:11.047Z"},{"type":"liability","out":{"amount":"0.00","currency":"BTC"},"in":{"amount":"21.83","currency":"BTC"},"TransactionId":"1ae86bd0-2c3c-42f9-baf0-92c67b985383","createdAt":"2015-03-11T15:48:11.041Z"},{"type":"asset","out":{"amount":"0.00","currency":"BTC"},"in":{"amount":"21.83","currency":"BTC"},"createdAt":"2015-03-11T15:48:11.041Z"},{"type":"asset","out":{"amount":"14.75","currency":"USD"},"in":{"amount":"0.05","currency":"BTC"},"createdAt":"2015-03-11T15:46:17.917Z"},{"type":"liability","out":{"amount":"0.05","currency":"BTC"},"in":{"amount":"0.05","currency":"BTC"},"TransactionId":"cd6ea33b-c612-446a-b751-001da67e2f93","createdAt":"2015-03-11T15:46:05.540Z"},{"type":"liability","out":{"amount":"14.75","currency":"USD"},"in":{"amount":"0.05","currency":"BTC"},"TransactionId":"cd6ea33b-c612-446a-b751-001da67e2f93","createdAt":"2015-03-11T15:46:05.539Z"}]'
54
+ http_version:
55
+ recorded_at: Wed, 11 Mar 2015 17:02:48 GMT
56
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,61 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.uphold.com/v0/me/cards/d9cfb5ec-27b3-427a-8ee6-084a7c6b5d2a
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Authorization:
11
+ - Bearer <UPHOLD_AUTH_TOKEN>
12
+ response:
13
+ status:
14
+ code: 200
15
+ message: OK
16
+ headers:
17
+ Server:
18
+ - cloudflare-nginx
19
+ Date:
20
+ - Tue, 27 Jan 2015 14:24:24 GMT
21
+ Content-Type:
22
+ - application/json; charset=utf-8
23
+ Content-Length:
24
+ - '292'
25
+ Connection:
26
+ - keep-alive
27
+ Set-Cookie:
28
+ - __cfduid=d4f27a752f54e7760240b39abdad253961422368664; expires=Wed, 27-Jan-16
29
+ 14:24:24 GMT; path=/; domain=.uphold.com; HttpOnly
30
+ X-Content-Security-Policy:
31
+ - default-src "none"
32
+ Content-Security-Policy:
33
+ - default-src "none"
34
+ X-Webkit-Csp:
35
+ - default-src "none"
36
+ Strict-Transport-Security:
37
+ - max-age=31536000
38
+ X-Xss-Protection:
39
+ - 1; mode=block
40
+ X-Content-Type-Options:
41
+ - nosniff
42
+ - nosniff
43
+ X-Frame-Options:
44
+ - DENY
45
+ X-Uphold-Request-Id:
46
+ - c0b1263d-ff9c-4c39-b859-90dbd35cfb77
47
+ X-Ratelimit-Limit:
48
+ - '300'
49
+ X-Ratelimit-Remaining:
50
+ - '296'
51
+ X-Ratelimit-Reset:
52
+ - '1422368769'
53
+ Cf-Ray:
54
+ - 1af59d1724d80db7-MAD
55
+ body:
56
+ encoding: UTF-8
57
+ string: '{"id":"d9cfb5ec-27b3-427a-8ee6-084a7c6b5d2a","address":{"bitcoin":"1JbnsnxESsu1bV3DV4DPCSNp15JQ6yCPgC"},"label":"USD
58
+ card","currency":"USD","balance":"0.00","available":"0.00","lastTransactionAt":null,"position":2,"addresses":[{"id":"1JbnsnxESsu1bV3DV4DPCSNp15JQ6yCPgC","network":"bitcoin"}]}'
59
+ http_version:
60
+ recorded_at: Tue, 27 Jan 2015 14:24:24 GMT
61
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,67 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.uphold.com/v0/me/cards
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Authorization:
11
+ - Bearer <UPHOLD_AUTH_TOKEN>
12
+ response:
13
+ status:
14
+ code: 200
15
+ message: OK
16
+ headers:
17
+ Server:
18
+ - cloudflare-nginx
19
+ Date:
20
+ - Tue, 27 Jan 2015 14:13:03 GMT
21
+ Content-Type:
22
+ - application/json; charset=utf-8
23
+ Content-Length:
24
+ - '2098'
25
+ Connection:
26
+ - keep-alive
27
+ Set-Cookie:
28
+ - __cfduid=df0760f1660ae5cc237b20d2b9f91ad061422367982; expires=Wed, 27-Jan-16
29
+ 14:13:02 GMT; path=/; domain=.uphold.com; HttpOnly
30
+ X-Content-Security-Policy:
31
+ - default-src "none"
32
+ Content-Security-Policy:
33
+ - default-src "none"
34
+ X-Webkit-Csp:
35
+ - default-src "none"
36
+ Strict-Transport-Security:
37
+ - max-age=31536000
38
+ X-Xss-Protection:
39
+ - 1; mode=block
40
+ X-Content-Type-Options:
41
+ - nosniff
42
+ - nosniff
43
+ X-Frame-Options:
44
+ - DENY
45
+ X-Uphold-Request-Id:
46
+ - 9a40e5ab-ad6e-4865-aeda-e84bee568191
47
+ X-Ratelimit-Limit:
48
+ - '300'
49
+ X-Ratelimit-Remaining:
50
+ - '299'
51
+ X-Ratelimit-Reset:
52
+ - '1422368282'
53
+ Cf-Ray:
54
+ - 1af58c71cb8c0ded-MAD
55
+ body:
56
+ encoding: UTF-8
57
+ string: '[{"id":"2daa59e8-89c5-4cbe-99fc-f66435024bcf","address":{"bitcoin":"1LbHhVFjLeC3hVhW4FXrwu7MNUCkoGTwA5"},"label":"XAU
58
+ card","currency":"XAU","balance":"0.001","available":"0.001","lastTransactionAt":"2014-12-02T00:29:45.507Z","position":7,"addresses":[{"id":"1LbHhVFjLeC3hVhW4FXrwu7MNUCkoGTwA5","network":"bitcoin"}]},{"id":"8a77ed0e-d89b-4d73-b438-33cd47dcafef","address":{"bitcoin":"1GXDSRdmEyLbgvGa3zBtW1Pftggc8Y8FWK"},"label":"BTC
59
+ card","currency":"BTC","balance":"0.00","available":"0.00","lastTransactionAt":null,"position":1,"addresses":[{"id":"1GXDSRdmEyLbgvGa3zBtW1Pftggc8Y8FWK","network":"bitcoin"}]},{"id":"d9cfb5ec-27b3-427a-8ee6-084a7c6b5d2a","address":{"bitcoin":"1JbnsnxESsu1bV3DV4DPCSNp15JQ6yCPgC"},"label":"USD
60
+ card","currency":"USD","balance":"0.00","available":"0.00","lastTransactionAt":null,"position":2,"addresses":[{"id":"1JbnsnxESsu1bV3DV4DPCSNp15JQ6yCPgC","network":"bitcoin"}]},{"id":"7faab8e0-fbb7-4bb4-ad2f-9e0e05eabc35","address":{"bitcoin":"1BsvBJnjXGPC68mPPmcsvUYzidGSXgJd7Q"},"label":"GBP
61
+ card","currency":"GBP","balance":"0.00","available":"0.00","lastTransactionAt":null,"position":4,"addresses":[{"id":"1BsvBJnjXGPC68mPPmcsvUYzidGSXgJd7Q","network":"bitcoin"}]},{"id":"1f3e8557-5a42-4cf9-a3fd-919b614b87f5","address":{"bitcoin":"19xscksV9K5tG3PQEkKfNWjaxSu8gzX1pi"},"label":"CNY
62
+ card","currency":"CNY","balance":"0.00","available":"0.00","lastTransactionAt":null,"position":5,"addresses":[{"id":"19xscksV9K5tG3PQEkKfNWjaxSu8gzX1pi","network":"bitcoin"}]},{"id":"353cc6d4-b19f-42ec-a733-bbaf45cb0089","address":{"bitcoin":"192R94xg5acCAYJqXYWve4L6WEaEEMU3RY"},"label":"JPY
63
+ card","currency":"JPY","balance":"0.00","available":"0.00","lastTransactionAt":null,"position":6,"addresses":[{"id":"192R94xg5acCAYJqXYWve4L6WEaEEMU3RY","network":"bitcoin"}]},{"id":"21a6f110-a684-4627-afda-bf03eca733cf","address":{"bitcoin":"1M8JNAoPxKfQivX8rzo3x1qKX6tf857HGf"},"label":"EUR
64
+ card","currency":"EUR","balance":"5.85","available":"5.85","lastTransactionAt":"2014-11-21T17:37:04.769Z","position":3,"addresses":[{"id":"1M8JNAoPxKfQivX8rzo3x1qKX6tf857HGf","network":"bitcoin"}]}]'
65
+ http_version:
66
+ recorded_at: Tue, 27 Jan 2015 14:13:03 GMT
67
+ recorded_with: VCR 2.9.3