synapse_api 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 045443506a7bba92667a57f1b2df462ec130325c42c683f3dd4e069dabe2590b
4
+ data.tar.gz: 0e8d50efa968105c68073581fc00ba9cd341726bdc037b001a6705a9568f6d12
5
+ SHA512:
6
+ metadata.gz: 9b88547519a9a5a28d64b978c228b099a6d4988e7e564b82a1d48e64520ee644331dd3cf2c4761f39012b12b23abce704efd539d5478811bed7b2b3b6d12a13c
7
+ data.tar.gz: ad711542a3aa43f21935cf67ad8c5fab4658ebab649850a84b65a4fc4578af821db8693eb51f53f4130000297b00a9137a3d6f5561e795b0f0857c1b871f5f37
@@ -0,0 +1,9 @@
1
+ # For development in a console
2
+ CLIENT_ID=your_sandbox_client_id
3
+ CLIENT_SECRET=your_sandbox_client_secret
4
+ FINGERPRINT=your_sandbox_fingerprint
5
+
6
+ # For running tests
7
+ TEST_CLIENT_ID=your_sandbox_client_id
8
+ TEST_CLIENT_SECRET=your_sandbox_client_secret
9
+
@@ -0,0 +1,3 @@
1
+ .env
2
+ .DS_Store
3
+
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+ source 'https://rubygems.org'
3
+
4
+
5
+ # Specify your gem's dependencies in your *.gemspec file
6
+ gemspec
7
+ gem 'rubygems-update'
@@ -0,0 +1,53 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ synapse_api (1.0.0)
5
+ rest-client (~> 2.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ansi (1.5.0)
11
+ builder (3.2.3)
12
+ domain_name (0.5.20190701)
13
+ unf (>= 0.0.5, < 1.0.0)
14
+ dotenv (2.1.2)
15
+ http-accept (1.7.0)
16
+ http-cookie (1.0.3)
17
+ domain_name (~> 0.5)
18
+ mime-types (3.3)
19
+ mime-types-data (~> 3.2015)
20
+ mime-types-data (3.2019.1009)
21
+ minitest (5.8.5)
22
+ minitest-reporters (1.1.19)
23
+ ansi
24
+ builder
25
+ minitest (>= 5.0)
26
+ ruby-progressbar
27
+ netrc (0.11.0)
28
+ rake (10.5.0)
29
+ rest-client (2.1.0)
30
+ http-accept (>= 1.7.0, < 2.0)
31
+ http-cookie (>= 1.0.2, < 2.0)
32
+ mime-types (>= 1.16, < 4.0)
33
+ netrc (~> 0.8)
34
+ ruby-progressbar (1.10.0)
35
+ rubygems-update (3.0.6)
36
+ unf (0.1.4)
37
+ unf_ext
38
+ unf_ext (0.0.7.6)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ bundler (~> 1.10)
45
+ dotenv (~> 2.1.1)
46
+ minitest (~> 5.8.2)
47
+ minitest-reporters (~> 1.1.5)
48
+ rake (~> 10.0)
49
+ rubygems-update
50
+ synapse_api!
51
+
52
+ BUNDLED WITH
53
+ 1.17.2
@@ -0,0 +1,53 @@
1
+ # SynapseRuby
2
+ ![Gem](https://img.shields.io/gem/v/synapseruby.svg)
3
+ ![status](https://img.shields.io/badge/status-beta-yellow.svg)
4
+
5
+ Native API library for SynapseFI REST v3.x
6
+
7
+ Not all API endpoints are supported.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'synapseruby'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ ```bash
20
+ $ bundle
21
+ ```
22
+
23
+ Or install it yourself by executing:
24
+
25
+ ```bash
26
+ $ gem install synapseruby
27
+ ```
28
+ ## Documentation
29
+
30
+ - [API docs](http://docs.synapsefi.com/v3.1)
31
+ - [synapseruby gem docs](https://rubygems.org/gems/synapseruby)
32
+ - [Samples demonstrating common operations](samples.md)
33
+
34
+ ## Contributing
35
+
36
+ For minor issues, please open a pull request. For larger changes or features, please email hello@synapsepay.com. Please document and test any public constants/methods.
37
+
38
+ ## Running the Test Suite
39
+
40
+ If you haven't already, set the `TEST_CLIENT_ID` and `TEST_CLIENT_SECRET` environment variables in `.env` file .
41
+ Please read and update test files with your user own test id's
42
+
43
+ To run all tests, execute:
44
+
45
+ ```bash
46
+ rake test
47
+ ```
48
+
49
+ ## License
50
+
51
+ [MIT License](LICENSE)
52
+
53
+
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "lib"
6
+ t.libs << "test"
7
+ t.test_files = FileList['test/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,28 @@
1
+ # client
2
+ require "synapse_api/client"
3
+ # error
4
+ require "synapse_api/error"
5
+ # http_request
6
+ require "synapse_api/http_request"
7
+ # node
8
+ require "synapse_api/node"
9
+ # nodes
10
+ require "synapse_api/nodes"
11
+ # subnet
12
+ require "synapse_api/subnet"
13
+ # subnets
14
+ require "synapse_api/subnets"
15
+ # subscription
16
+ require "synapse_api/subscription"
17
+ # subscriptions
18
+ require "synapse_api/subscriptions"
19
+ # transaction
20
+ require "synapse_api/transaction"
21
+ # transactions
22
+ require "synapse_api/transactions"
23
+ # user
24
+ require "synapse_api/user"
25
+ # users
26
+ require "synapse_api/users"
27
+ # version
28
+ require "synapse_api/version"
@@ -0,0 +1,405 @@
1
+ require 'synapse_api'
2
+
3
+
4
+ module Synapse
5
+ # Initializes various wrapper settings such as development mode and request
6
+ # header values
7
+
8
+ class Client
9
+ VALID_QUERY_PARAMS = [:query, :page, :per_page, :full_dehydrate, :radius, :zip, :lat, :lon, :limit, :currency, :ticker_symbol].freeze
10
+
11
+ attr_accessor :http_client
12
+
13
+ attr_reader :client_id
14
+
15
+ # Alias for #http_client
16
+ alias_method :client, :http_client
17
+
18
+ # @param client_id [String] should be stored in environment variable
19
+ # @param client_secret [String] should be stored in environment variable
20
+ # @param ip_address [String] user's IP address
21
+ # @param fingerprint [String] a hashed value, either unique to user or static
22
+ # @param development_mode [String] default true
23
+ # @param raise_for_202 [Boolean]
24
+ # @param logging [Boolean] (optional) logs to stdout when true
25
+ # @param log_to [String] (optional) file path to log to file (logging must be true)
26
+ def initialize(client_id:, client_secret:, ip_address:, fingerprint:nil,development_mode: true, raise_for_202:nil, **options)
27
+ base_url = if development_mode
28
+ 'https://uat-api.synapsefi.com/v3.1'
29
+ else
30
+ 'https://api.synapsefi.com/v3.1'
31
+ end
32
+ @client_id = client_id
33
+ @client_secret = client_secret
34
+ @http_client = HTTPClient.new(base_url: base_url,
35
+ client_id: client_id,
36
+ client_secret: client_secret,
37
+ fingerprint: fingerprint,
38
+ ip_address: ip_address,
39
+ raise_for_202: raise_for_202,
40
+ **options
41
+ )
42
+ end
43
+
44
+ # Queries Synapse API to create a new user
45
+ # @param payload [Hash]
46
+ # @param idempotency_key [String] (optional)
47
+ # @param ip_address [String] (optional)
48
+ # @param fingerprint [String] (optional)
49
+ # @return [Synapse::User]
50
+ # @see https://docs.synapsepay.com/docs/create-a-user payload structure
51
+ def create_user(payload:, ip_address:, **options)
52
+ client.update_headers(ip_address: ip_address, fingerprint: options[:fingerprint])
53
+
54
+ response = client.post(user_path,payload, options)
55
+
56
+ User.new(user_id: response['_id'],
57
+ refresh_token: response['refresh_token'],
58
+ client: client,
59
+ full_dehydrate: "no",
60
+ payload: response
61
+ )
62
+ end
63
+
64
+ # Update headers in HTTPClient class
65
+ # for API request headers
66
+ # @param fingerprint [Hash]
67
+ # @param idemopotency_key [Hash]
68
+ # @param ip_address [Hash]
69
+ def update_headers(fingerprint:nil, idemopotency_key:nil, ip_address:nil)
70
+ client.update_headers(fingerprint: fingerprint, idemopotency_key: idemopotency_key, ip_address: ip_address)
71
+ end
72
+
73
+ # Queries Synapse API for a user by user_id
74
+ # @param user_id [String] id of the user to find
75
+ # @param full_dehydrate [String] (optional) if true, returns all KYC on user
76
+ # @param ip_address [String] (optional)
77
+ # @param fingerprint [String] (optional)
78
+ # @see https://docs.synapsefi.com/docs/get-user
79
+ # @return [Synapse::User]
80
+ def get_user(user_id:, **options)
81
+ raise ArgumentError, 'client must be a Synapse::Client' unless self.is_a?(Client)
82
+ raise ArgumentError, 'user_id must be a String' unless user_id.is_a?(String)
83
+
84
+ options[:full_dehydrate] = "yes" if options[:full_dehydrate] == true
85
+ options[:full_dehydrate] = "no" if options[:full_dehydrate] == false
86
+
87
+ client.update_headers(ip_address: options[:ip_address], fingerprint: options[:fingerprint])
88
+
89
+ path = user_path(user_id: user_id, full_dehydrate: options[:full_dehydrate])
90
+ response = client.get(path)
91
+
92
+ User.new(user_id: response['_id'],
93
+ refresh_token: response['refresh_token'],
94
+ client: client,
95
+ full_dehydrate: options[:full_dehydrate] == "yes" ? true : false,
96
+ payload: response
97
+ )
98
+ end
99
+
100
+ # Queries Synapse API for platform users
101
+ # @param query [String] (optional) response will be filtered to
102
+ # users with matching name/email
103
+ # @param page [Integer] (optional) response will default to 1
104
+ # @param per_page [Integer] (optional) response will default to 20
105
+ # @return [Array<Synapse::Users>]
106
+ def get_users(**options)
107
+ path = user_path(options)
108
+ response = client.get(path)
109
+ return [] if response["users"].empty?
110
+ users = response["users"].map { |user_data| User.new(user_id: user_data['_id'],
111
+ refresh_token: user_data['refresh_token'],
112
+ client: client,
113
+ full_dehydrate: "no",
114
+ payload: user_data
115
+ )}
116
+ Users.new(limit: response["limit"],
117
+ page: response["page"],
118
+ page_count: response["page_count"],
119
+ user_count: response["users_count"],
120
+ payload: users,
121
+ http_client: client
122
+ )
123
+ end
124
+
125
+ # Queries Synapse for all transactions on platform
126
+ # @param page [Integer] (optional) response will default to 1
127
+ # @param per_page [Integer] (optional) response will default to 20
128
+ # @return [Array<Synapse::Transactions>]
129
+ def get_all_transaction(**options)
130
+ path = '/trans'
131
+
132
+ params = VALID_QUERY_PARAMS.map do |p|
133
+ options[p] ? "#{p}=#{options[p]}" : nil
134
+ end.compact
135
+
136
+ path += '?' + params.join('&') if params.any?
137
+
138
+ trans = client.get(path)
139
+
140
+ return [] if trans["trans"].empty?
141
+ response = trans["trans"].map { |trans_data| Transaction.new(trans_id: trans_data['_id'], payload: trans_data)}
142
+ Transactions.new(limit: trans["limit"],
143
+ page: trans["page"],
144
+ page_count: trans["page_count"],
145
+ trans_count: trans["trans_count"],
146
+ payload: response
147
+ )
148
+ end
149
+
150
+ # Queries Synapse API for all nodes belonging to platform
151
+ # @param page [Integer] (optional) response will default to 1
152
+ # @param per_page [Integer] (optional) response will default to 20
153
+ # @return [Array<Synapse::Nodes>]
154
+ def get_all_nodes(**options)
155
+ [options[:page], options[:per_page]].each do |arg|
156
+ if arg && (!arg.is_a?(Integer) || arg < 1)
157
+ raise ArgumentError, "#{arg} must be nil or an Integer >= 1"
158
+ end
159
+ end
160
+ path = nodes_path(options: options)
161
+ nodes = client.get(path)
162
+
163
+ return [] if nodes["nodes"].empty?
164
+ response = nodes["nodes"].map { |node_data| Node.new(node_id: node_data['_id'],
165
+ user_id: node_data['user_id'],
166
+ payload: node_data,
167
+ full_dehydrate: "no"
168
+ )}
169
+ Nodes.new(limit: nodes["limit"],
170
+ page: nodes["page"],
171
+ page_count: nodes["page_count"],
172
+ nodes_count: nodes["node_count"],
173
+ payload: response
174
+ )
175
+ end
176
+
177
+ # Queries Synapse API for all institutions available for bank logins
178
+ # @param page [Integer] (optional) response will default to 1
179
+ # @param per_page [Integer] (optional) response will default to 20
180
+ # @return API response [Hash]
181
+ def get_all_institutions(**options)
182
+ client.get(institutions_path(options))
183
+ end
184
+
185
+ # Queries Synapse API to create a webhook subscriptions for platform
186
+ # @param scope [Hash]
187
+ # @param idempotency_key [String] (optional)
188
+ # @see https://docs.synapsefi.com/docs/create-subscription
189
+ # @return [Synapse::Subscription]
190
+ def create_subscriptions(scope:, **options)
191
+ response = client.post(subscriptions_path , scope, options)
192
+
193
+ Subscription.new(subscription_id: response["_id"], url: response["url"], payload: response)
194
+ end
195
+
196
+ # Queries Synapse API for all platform subscriptions
197
+ # @param page [Integer] (optional) response will default to 1
198
+ # @param per_page [Integer] (optional) response will default to 20
199
+ # @return [Array<Synapse::Subscriptions>]
200
+ def get_all_subscriptions(**options)
201
+ subscriptions = client.get(subscriptions_path(options))
202
+
203
+ return [] if subscriptions["subscriptions"].empty?
204
+ response = subscriptions["subscriptions"].map { |subscription_data| Subscription.new(subscription_id: subscription_data["_id"],
205
+ url: subscription_data["url"],
206
+ payload: subscription_data)}
207
+ Subscriptions.new(limit: subscriptions["limit"],
208
+ page: subscriptions["page"],
209
+ page_count: subscriptions["page_count"],
210
+ subscriptions_count: subscriptions["subscription_count"],
211
+ payload: response
212
+ )
213
+ end
214
+
215
+ # Queries Synapse API for a subscription by subscription_id
216
+ # @param subscription_id [String]
217
+ # @return [Synapse::Subscription]
218
+ def get_subscription(subscription_id:)
219
+ path = subscriptions_path + "/#{subscription_id}"
220
+ response = client.get(path)
221
+ Subscription.new(subscription_id: response["_id"], url: response["url"], payload: response)
222
+ end
223
+
224
+ # Updates subscription platform subscription
225
+ # @param subscription_id [String]
226
+ # @param body [Hash]
227
+ # see https://docs.synapsefi.com/docs/update-subscription
228
+ # @return [Synapse::Subscription]
229
+ def update_subscriptions(subscription_id:, body:)
230
+ path = subscriptions_path + "/#{subscription_id}"
231
+
232
+ response = client.patch(path, body)
233
+ Subscription.new(subscription_id: response["_id"], url: response["url"], payload: response)
234
+ end
235
+
236
+ # Returns all of the webhooks belonging to client
237
+ # @param page [Integer] (Optional)
238
+ # @param per_page [Integer] (Optional)
239
+ # @return [Hash]
240
+ def webhook_logs(**options)
241
+ path = subscriptions_path + "/logs"
242
+
243
+ params = VALID_QUERY_PARAMS.map do |p|
244
+ options[p] ? "#{p}=#{options[p]}" : nil
245
+ end.compact
246
+
247
+ path += '?' + params.join('&') if params.any?
248
+
249
+ client.get(path)
250
+ end
251
+
252
+ # Issues public key for client
253
+ # @param scope [String]
254
+ # @param user_id [String] (Optional)
255
+ # @see https://docs.synapsefi.com/docs/issuing-public-key
256
+ # @note valid scope "OAUTH|POST,USERS|POST,USERS|GET,USER|GET,USER|PATCH,SUBSCRIPTIONS|GET,SUBSCRIPTIONS|POST,SUBSCRIPTION|GET,SUBSCRIPTION|PATCH,CLIENT|REPORTS,CLIENT|CONTROLS"
257
+ def issue_public_key(scope:, user_id: nil)
258
+ path = '/client?issue_public_key=YES'
259
+
260
+ path += "&scope=#{scope}"
261
+
262
+ path += "&user_id=#{user_id}" if user_id
263
+
264
+ response = client.get(path)
265
+ response[ "public_key_obj"]
266
+ end
267
+
268
+ # Queries Synapse API for ATMS nearby
269
+ # @param zip [String]
270
+ # @param radius [String]
271
+ # @param lat [String]
272
+ # @param lon [String]
273
+ # @see https://docs.synapsefi.com/docs/locate-atms
274
+ # @return [Hash]
275
+ def locate_atm(**options)
276
+ params = VALID_QUERY_PARAMS.map do |p|
277
+ options[p] ? "#{p}=#{options[p]}" : nil
278
+ end.compact
279
+
280
+ path = "/nodes/atms?"
281
+ path += params.join('&') if params.any?
282
+ atms = client.get(path)
283
+ atms
284
+ end
285
+
286
+ # Queries Synapse API for Crypto Currencies Quotes
287
+ # @return API response [Hash]
288
+ def get_crypto_quotes()
289
+ path = '/nodes/crypto-quotes'
290
+ params = VALID_QUERY_PARAMS.map do |p|
291
+ options[p] ? "#{p}=#{options[p]}" : nil
292
+ end.compact
293
+
294
+ path += '?' + params.join('&') if params.any?
295
+ quotes = client.get(path)
296
+ quotes
297
+ end
298
+
299
+ # Queries Synapse API for Crypto Currencies Market data
300
+ # @param limit [Integer]
301
+ # @param currency [String]
302
+ # @return API response [Hash]
303
+ def get_crypto_market_data(**options)
304
+ path = '/nodes/crypto-market-watch'
305
+
306
+ params = VALID_QUERY_PARAMS.map do |p|
307
+ options[p] ? "#{p}=#{options[p]}" : nil
308
+ end.compact
309
+
310
+ path += '?' + params.join('&') if params.any?
311
+
312
+ data = client.get(path)
313
+ data
314
+ end
315
+
316
+ # Queries Synapse API for Trade Market data
317
+ # @param ticker_symbol [String]
318
+ # @return API response [Hash]
319
+ def get_trade_market_data(**options)
320
+ path = '/nodes/trade-market-watch'
321
+
322
+ params = VALID_QUERY_PARAMS.map do |p|
323
+ options[p] ? "#{p}=#{options[p]}" : nil
324
+ end.compact
325
+
326
+ path += '?' + params.join('&') if params.any?
327
+
328
+ market_data = client.get(path)
329
+ market_data
330
+ end
331
+
332
+ # Queries Synapse API for Routing Verification
333
+ # @param payload [Hash]
334
+ # @return API response [Hash]
335
+ def routing_number_verification(payload:)
336
+ path = '/routing-number-verification'
337
+
338
+ response = client.post(path,payload)
339
+ response
340
+ end
341
+
342
+ # Queries Synapse API for Address Verification
343
+ # @param payload [Hash]
344
+ # @return API response [Hash]
345
+ def address_verification(payload:)
346
+ path = '/address-verification'
347
+
348
+ response = client.post(path,payload)
349
+ response
350
+ end
351
+
352
+ private
353
+ def user_path(user_id: nil, **options)
354
+ path = "/users"
355
+ path += "/#{user_id}" if user_id
356
+
357
+ params = VALID_QUERY_PARAMS.map do |p|
358
+ options[p] ? "#{p}=#{options[p]}" : nil
359
+ end.compact
360
+
361
+ path += '?' + params.join('&') if params.any?
362
+ path
363
+ end
364
+
365
+ def transactions_path(user_id: nil, node_id: nil, **options)
366
+ path = "/users/#{user_id}/trans"
367
+ params = VALID_QUERY_PARAMS.map do |p|
368
+ options[p] ? "#{p}=#{options[p]}" : nil
369
+ end.compact
370
+
371
+ path += '?' + params.join('&') if params.any?
372
+ path
373
+ end
374
+
375
+ def nodes_path(**options)
376
+ path = "/nodes"
377
+ params = VALID_QUERY_PARAMS.map do |p|
378
+ options[p] ? "#{p}=#{options[p]}" : nil
379
+ end.compact
380
+
381
+ path += '?' + params.join('&') if params.any?
382
+ path
383
+ end
384
+
385
+ def institutions_path(**options)
386
+ path = "/institutions"
387
+ params = VALID_QUERY_PARAMS.map do |p|
388
+ options[p] ? "#{p}=#{options[p]}" : nil
389
+ end.compact
390
+
391
+ path += '?' + params.join('&') if params.any?
392
+ path
393
+ end
394
+
395
+ def subscriptions_path(**options)
396
+ path = "/subscriptions"
397
+ params = VALID_QUERY_PARAMS.map do |p|
398
+ options[p] ? "#{p}=#{options[p]}" : nil
399
+ end.compact
400
+
401
+ path += '?' + params.join('&') if params.any?
402
+ path
403
+ end
404
+ end
405
+ end