synapse_api 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.
@@ -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