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