cwallet-ruby 0.0.1

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.
@@ -0,0 +1,120 @@
1
+ module Cwallet
2
+ module Wallet
3
+ def self.format_error(resp)
4
+ error = resp.body && (resp.body['errors'] || resp.body['warnings']).first
5
+ return resp.body unless error
6
+ message = error['message']
7
+ message += " (#{error['url']})" if error["url"]
8
+ message
9
+ end
10
+
11
+ def self.check_response_status(resp)
12
+ (resp.body['warnings'] || []).each do |warning|
13
+ message = "WARNING: #{warning['message']}"
14
+ message += " (#{warning['url']})" if warning["url"]
15
+ $stderr.puts message
16
+ end
17
+
18
+ # OAuth2 errors
19
+ if resp.status >= 400 && resp.body['error']
20
+ raise APIError, resp.body['error_description']
21
+ end
22
+
23
+ # Regular errors
24
+ if resp.body['errors']
25
+ case resp.status
26
+ when 400
27
+ case resp.body['errors'].first['id']
28
+ when 'param_required' then raise ParamRequiredError, format_error(resp)
29
+ when 'invalid_request' then raise InvalidRequestError, format_error(resp)
30
+ when 'personal_details_required' then raise PersonalDetailsRequiredError, format_error(resp)
31
+ end
32
+ raise BadRequestError, format_error(resp)
33
+ when 401
34
+ case resp.body['errors'].first['id']
35
+ when 'authentication_error' then raise AuthenticationError, format_error(resp)
36
+ when 'unverified_email' then raise UnverifiedEmailError, format_error(resp)
37
+ when 'invalid_token' then raise InvalidTokenError, format_error(resp)
38
+ when 'revoked_token' then raise RevokedTokenError, format_error(resp)
39
+ when 'expired_token' then raise ExpiredTokenError, format_error(resp)
40
+ end
41
+ raise AuthenticationError, format_error(resp)
42
+ when 402 then raise TwoFactorRequiredError, format_error(resp)
43
+ when 403 then raise InvalidScopeError, format_error(resp)
44
+ when 404 then raise NotFoundError, format_error(resp)
45
+ when 422 then raise ValidationError, format_error(resp)
46
+ when 429 then raise RateLimitError, format_error(resp)
47
+ when 500 then raise InternalServerError, format_error(resp)
48
+ when 503 then raise ServiceUnavailableError, format_error(resp)
49
+ end
50
+ end
51
+
52
+ if resp.status > 400
53
+ raise APIError, "[#{resp.status}] #{resp.body}"
54
+ end
55
+ end
56
+
57
+ #
58
+ # Rest API Errors
59
+ #
60
+ class APIError < RuntimeError
61
+ end
62
+
63
+ # Status 400
64
+ class BadRequestError < APIError
65
+ end
66
+
67
+ class ParamRequiredError < APIError
68
+ end
69
+
70
+ class InvalidRequestError < APIError
71
+ end
72
+
73
+ class PersonalDetailsRequiredError < APIError
74
+ end
75
+
76
+ # Status 401
77
+ class AuthenticationError < APIError
78
+ end
79
+
80
+ class UnverifiedEmailError < APIError
81
+ end
82
+
83
+ class InvalidTokenError < APIError
84
+ end
85
+
86
+ class RevokedTokenError < APIError
87
+ end
88
+
89
+ class ExpiredTokenError < APIError
90
+ end
91
+
92
+ # Status 402
93
+ class TwoFactorRequiredError < APIError
94
+ end
95
+
96
+ # Status 403
97
+ class InvalidScopeError < APIError
98
+ end
99
+
100
+ # Status 404
101
+ class NotFoundError < APIError
102
+ end
103
+
104
+ # Status 422
105
+ class ValidationError < APIError
106
+ end
107
+
108
+ # Status 429
109
+ class RateLimitError < APIError
110
+ end
111
+
112
+ # Status 500
113
+ class InternalServerError < APIError
114
+ end
115
+
116
+ # Status 503
117
+ class ServiceUnavailableError < APIError
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,41 @@
1
+ module Cwallet
2
+ module Wallet
3
+ # Encapsulate data for an API response
4
+ class APIResponse
5
+ attr_reader :received_at
6
+ attr_accessor :client
7
+ attr_accessor :method
8
+ attr_accessor :params
9
+
10
+ def initialize(resp)
11
+ @received_at = Time.now
12
+ @response = resp
13
+ end
14
+
15
+ def raw
16
+ @response
17
+ end
18
+
19
+ def body
20
+ raise NotImplementedError
21
+ end
22
+ alias_method :data, :body
23
+
24
+ def body=(body)
25
+ raise NotImplementedError
26
+ end
27
+
28
+ def headers
29
+ raise NotImplementedError
30
+ end
31
+
32
+ def status
33
+ raise NotImplementedError
34
+ end
35
+
36
+ def has_more?
37
+ body.has_key?('pagination') && body['pagination']['next_uri'] != nil
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,101 @@
1
+ module Cwallet
2
+ module Wallet
3
+ BASE_API_URL = 'https://stg-wallet.fiahub.com'.freeze
4
+ API_VERSION = '2018-10-10'.freeze
5
+
6
+ class Client < NetHTTPClient
7
+ def initialize(options={})
8
+ [ :api_key, :api_secret ].each do |opt|
9
+ raise unless options.has_key? opt
10
+ end
11
+ @api_key = options[:api_key]
12
+ @api_secret = options[:api_secret]
13
+ @api_uri = URI.parse(options[:api_url] || BASE_API_URL)
14
+ super(@api_uri, options)
15
+ end
16
+
17
+ def auth_headers(method, path, body)
18
+ ts = Time.now.to_i.to_s
19
+ signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'),
20
+ @api_secret,
21
+ ts + method + path + body.to_s)
22
+ { 'CB-ACCESS-KEY' => @api_key,
23
+ 'CB-ACCESS-SIGN' => signature,
24
+ 'CB-ACCESS-TIMESTAMP' => ts,
25
+ 'CB-VERSION' => API_VERSION }
26
+ end
27
+ end
28
+
29
+ class OAuthClient < NetHTTPClient
30
+ attr_accessor :access_token, :refresh_token
31
+
32
+ def initialize(options={})
33
+ raise unless options.has_key? :access_token
34
+ @access_token = options[:access_token]
35
+ @refresh_token = options[:refresh_token]
36
+ @oauth_uri = URI.parse(options[:api_url] || BASE_API_URL)
37
+ super(@oauth_uri, options)
38
+ end
39
+
40
+ def auth_headers(method, path, body)
41
+ { 'Authorization' => "Bearer #{@access_token}",
42
+ 'CB-VERSION' => API_VERSION }
43
+ end
44
+
45
+ def authorize!(redirect_url, params = {})
46
+ raise NotImplementedError
47
+ end
48
+
49
+ def revoke!(params = {})
50
+ params[:token] ||= @access_token
51
+
52
+ out = nil
53
+ post("/oauth/revoke", params) do |resp|
54
+ out = APIObject.new(self, resp.body)
55
+ yield(out, resp) if block_given?
56
+ end
57
+ out
58
+ end
59
+
60
+ def refresh!(params = {})
61
+ params[:grant_type] = 'refresh_token'
62
+ params[:refresh_token] ||= @refresh_token
63
+
64
+ raise "Missing Parameter: refresh_token" unless params.has_key?(:refresh_token)
65
+
66
+ out = nil
67
+ post("/oauth/token", params) do |resp|
68
+ out = APIObject.new(self, resp.body)
69
+ # Update tokens to current instance
70
+ # Developer should always persist them
71
+ @access_token = out.access_token
72
+ @refresh_token = out.refresh_token
73
+ yield(out, resp) if block_given?
74
+ end
75
+ out
76
+ end
77
+ end
78
+
79
+ class AsyncClient < EMHTTPClient
80
+ def initialize(options={})
81
+ [ :api_key, :api_secret ].each do |opt|
82
+ raise unless options.has_key? opt
83
+ end
84
+ @api_key = options[:api_key]
85
+ @api_secret = options[:api_secret]
86
+ @api_uri = URI.parse(options[:api_url] || BASE_API_URL)
87
+ end
88
+
89
+ def auth_headers(method, path, body)
90
+ ts = Time.now.to_i.to_s
91
+ signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'),
92
+ @api_secret,
93
+ ts + method + path + body.to_s)
94
+ { 'CB-ACCESS-KEY' => @api_key,
95
+ 'CB-ACCESS-SIGN' => signature,
96
+ 'CB-ACCESS-TIMESTAMP' => ts,
97
+ 'CB-VERSION' => API_VERSION }
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,9 @@
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi/BwkgBBZESQNFEAuuFN
3
+ M+entJ+ULJAcBi5RNyU36Si4VjsLIdIiVDGso7tOgPVb0aCzjJdIGeVAxxaUJJzS
4
+ Jgf6/a3T4F8ZEvf0OndoxcHe6M9hh4O+ImcWbTL9VRlflSQ3Ebu8ZDvWYjsQf7xR
5
+ 1mmk6QAPh294coCCCFNgMOcQsg/gNETD65OddQbwU+GRPjcM4qI5HvcTPYP+uiVT
6
+ rCeJh7mzDdFgJ/CqtSghAxiriQeTZTJ3FyRmAQU35+Ih0T7/JWVLeY6a1bTTf3k/
7
+ Z58l0eAhlJs5JBPuaVY5JFB4CfeAecAvBXXn/4SJ25MnFcGP4UcdKZwk/m/UjDsa
8
+ EwIDAQAB
9
+ -----END PUBLIC KEY-----
@@ -0,0 +1,193 @@
1
+ module Cwallet
2
+ module Wallet
3
+ class Account < APIObject
4
+ def update!(params = {})
5
+ @client.update_account(self['id'], params) do |data, resp|
6
+ update(data)
7
+ yield(data, resp) if block_given?
8
+ end
9
+ end
10
+
11
+ def make_primary!(params = {})
12
+ @client.set_primary_account(self['id'], params) do |data, resp|
13
+ update(data)
14
+ yield(data, resp) if block_given?
15
+ end
16
+ end
17
+
18
+ def delete!(params = {})
19
+ @client.delete_account(self['id'], params) do |data, resp|
20
+ yield(data, resp) if block_given?
21
+ end
22
+ end
23
+
24
+ #
25
+ # Addresses
26
+ #
27
+ def addresses(params = {})
28
+ @client.addresses(self['id'], params) do |data, resp|
29
+ yield(data, resp) if block_given?
30
+ end
31
+ end
32
+
33
+ def address(address_id, params = {})
34
+ @client.address(self['id'], address_id, params) do |data, resp|
35
+ yield(data, resp) if block_given?
36
+ end
37
+ end
38
+
39
+ def address_transactions(address_id, params = {})
40
+ @client.address_transactions(self['id'], address_id, params) do |data, resp|
41
+ yield(data, resp) if block_given?
42
+ end
43
+ end
44
+
45
+ def create_address(params = {})
46
+ @client.create_address(self['id'], params) do |data, resp|
47
+ yield(data, resp) if block_given?
48
+ end
49
+ end
50
+
51
+ #
52
+ # Transactions
53
+ #
54
+ def transactions(params = {})
55
+ @client.transactions(self['id'], params) do |data, resp|
56
+ yield(data, resp) if block_given?
57
+ end
58
+ end
59
+
60
+ def transaction(transaction_id, params = {})
61
+ @client.transaction(self['id'], transaction_id, params) do |data, resp|
62
+ yield(data, resp) if block_given?
63
+ end
64
+ end
65
+
66
+ def send(params = {})
67
+ @client.send(self['id'], params) do |data, resp|
68
+ yield(data, resp) if block_given?
69
+ end
70
+ end
71
+
72
+ def transfer(params = {})
73
+ @client.transfer(self['id'], params) do |data, resp|
74
+ yield(data, resp) if block_given?
75
+ end
76
+ end
77
+
78
+ def request(params = {})
79
+ @client.request(self['id'], params) do |data, resp|
80
+ yield(data, resp) if block_given?
81
+ end
82
+ end
83
+
84
+ #
85
+ # Buys
86
+ #
87
+ def list_buys(params = {})
88
+ @client.list_buys(self['id'], params) do |data, resp|
89
+ yield(data, resp) if block_given?
90
+ end
91
+ end
92
+
93
+ def list_buy(transaction_id, params = {})
94
+ @client.list_buy(self['id'], transaction_id, params) do |data, resp|
95
+ yield(data, resp) if block_given?
96
+ end
97
+ end
98
+
99
+ def buy(params = {})
100
+ @client.buy(self['id'], params) do |data, resp|
101
+ yield(data, resp) if block_given?
102
+ end
103
+ end
104
+
105
+ def commit_buy(transaction_id, params = {})
106
+ @client.commit_buy(self['id'], transaction_id, params) do |data, resp|
107
+ yield(data, resp) if block_given?
108
+ end
109
+ end
110
+
111
+ #
112
+ # Sells
113
+ #
114
+ def list_sells(params = {})
115
+ @client.list_sells(self['id'], params) do |data, resp|
116
+ yield(data, resp) if block_given?
117
+ end
118
+ end
119
+
120
+ def list_sell(transaction_id, params = {})
121
+ @client.list_sell(self['id'], transaction_id, params) do |data, resp|
122
+ yield(data, resp) if block_given?
123
+ end
124
+ end
125
+
126
+ def sell(params = {})
127
+ @client.sell(self['id'], params) do |data, resp|
128
+ yield(data, resp) if block_given?
129
+ end
130
+ end
131
+
132
+ def commit_sell(transaction_id, params = {})
133
+ @client.commit_sell(self['id'], transaction_id, params) do |data, resp|
134
+ yield(data, resp) if block_given?
135
+ end
136
+ end
137
+
138
+ #
139
+ # Deposit
140
+ #
141
+ def list_deposits(params = {})
142
+ @client.list_deposits(self['id'], params) do |data, resp|
143
+ yield(data, resp) if block_given?
144
+ end
145
+ end
146
+
147
+ def list_deposit(transaction_id, params = {})
148
+ @client.list_deposit(self['id'], transaction_id, params) do |data, resp|
149
+ yield(data, resp) if block_given?
150
+ end
151
+ end
152
+
153
+ def deposit(params = {})
154
+ @client.deposit(self['id'], params) do |data, resp|
155
+ yield(data, resp) if block_given?
156
+ end
157
+ end
158
+
159
+ def commit_deposit(transaction_id, params = {})
160
+ @client.commit_deposit(self['id'], transaction_id, params) do |data, resp|
161
+ yield(data, resp) if block_given?
162
+ end
163
+ end
164
+
165
+ #
166
+ # Withdrawals
167
+ #
168
+ def list_withdrawals(params = {})
169
+ @client.list_withdrawals(self['id'], params) do |data, resp|
170
+ yield(data, resp) if block_given?
171
+ end
172
+ end
173
+
174
+ def list_withdrawal(transaction_id, params = {})
175
+ @client.list_withdrawal(self['id'], transaction_id, params) do |data, resp|
176
+ yield(data, resp) if block_given?
177
+ end
178
+ end
179
+
180
+ def withdraw(params = {})
181
+ @client.withdraw(self['id'], params) do |data, resp|
182
+ yield(data, resp) if block_given?
183
+ end
184
+ end
185
+
186
+ def commit_withdrawal(transaction_id, params = {})
187
+ @client.commit_withdrawal(self['id'], transaction_id, params) do |data, resp|
188
+ yield(data, resp) if block_given?
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end