sydecar 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sydecar
4
+ class Expense
5
+ URL = '/v1/expenses'
6
+ CREATE_URL = "#{URL}/create"
7
+
8
+ class << self
9
+ def create(body:)
10
+ Connection.instance.post(CREATE_URL, body)
11
+ end
12
+
13
+ # @param [UUID] id
14
+ def find(id:)
15
+ Connection.instance.get("#{URL}/#{id}", { reveal_pii: true })
16
+ end
17
+
18
+ # @param [UUID] id
19
+ # @param [Hash] body
20
+ def update(id:, body:)
21
+ Connection.instance.patch("#{URL}/#{id}", body)
22
+ end
23
+
24
+ # @param [Hash] params argument expects to have the following keys
25
+ # [String] sort: asc / desc
26
+ # [Integer] limit
27
+ # [Integer] offset
28
+ # [String] start_date (format: yyyy-mm-dd)
29
+ # [String] end_date (format: yyyy-mm-dd)
30
+ # @param [Hash] body: expects to have "ids" key
31
+ def find_all(params: {}, body: {})
32
+ query = '?'
33
+ query += URI.encode_www_form(params)
34
+ Connection.instance.post("#{URL}#{query}", body)
35
+ end
36
+
37
+ # @param [UUID] id
38
+ def delete(id:)
39
+ Connection.instance.delete("#{URL}/#{id}")
40
+ end
41
+
42
+ def pay_url(id:)
43
+ "/v1/expenses/#{id}/pay"
44
+ end
45
+
46
+ def pay(id:)
47
+ url = pay_url(id: id)
48
+ Connection.instance.post(url)
49
+ end
50
+
51
+ def cancel_url(id:)
52
+ "/v1/expenses/#{id}/cancel"
53
+ end
54
+
55
+ def cancel(id:)
56
+ url = cancel_url(id: id)
57
+ Connection.instance.post(url)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,26 @@
1
+ module Sydecar
2
+ class FileConnection < BaseConnection
3
+ class << self
4
+ def headers
5
+ common_headers.merge(
6
+ 'Content-Type' => 'multipart/form-data',
7
+ 'Accept' => '*/*'
8
+ )
9
+ end
10
+
11
+ def instance
12
+ super
13
+ return @@instance if @@instance
14
+
15
+ @@instance = create_instance(headers, base_url, env, format_of_request: :multipart)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ @@instance = nil
22
+
23
+ def initialize
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sydecar
4
+ class Person
5
+ URL = '/v1/persons'
6
+ CREATE_URL = "#{URL}/create"
7
+ class << self
8
+ # @param [Hash] body
9
+ def create(body:, idempotency_key:)
10
+ Connection.instance.post(CREATE_URL, body, { 'idempotency-key': idempotency_key })
11
+ end
12
+
13
+ # @param [UUID] id
14
+ def find(id:)
15
+ Connection.instance.get("#{URL}/#{id}", { reveal_pii: true })
16
+ end
17
+
18
+ # @param [UUID] id
19
+ # @param [Hash] body
20
+ def update(id:, body:)
21
+ Connection.instance.patch("#{URL}/#{id}", body)
22
+ end
23
+
24
+ # @param [Hash] params argument expects to have the following keys:
25
+ # [String] sort: asc / desc
26
+ # [Integer] limit
27
+ # [Integer] offset
28
+ # [String] start_date (format: yyyy-mm-dd)
29
+ # [String] end_date (format: yyyy-mm-dd)
30
+ # @param [Hash] body: expects to have "ids" key
31
+ def find_all(params: {}, body: {})
32
+ query = '?'
33
+ query += URI.encode_www_form(params)
34
+ Connection.instance.post("#{URL}#{query}", body)
35
+ end
36
+
37
+ # @param [UUID] id
38
+ def kyc(id:)
39
+ Connection.instance.post("#{URL}/#{id}/kyc")
40
+ end
41
+
42
+ # TODO: implement "Upload documents for KYC" endpoint
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,164 @@
1
+ module Sydecar
2
+ class Plaid
3
+ CREATE_LINK_TOKEN_URL = 'v1/plaid/create_link_token'
4
+ PLAID_INSTITUTIONS_URL = 'v1/plaid/plaid_institutions'
5
+ CREATE_PLAID_BANK_ACCOUNT_URL = 'v1/plaid/create_plaid_bank_account'
6
+ class << self
7
+ def reset_plaid_login_url(bank_account_id:)
8
+ "v1/plaid/#{bank_account_id}/reset_plaid_login"
9
+ end
10
+ def create_bank_account_url
11
+ '/v1/plaid/link_plaid_bank_account'
12
+ end
13
+
14
+ # body argument expects to have the following keys:
15
+ # [String] profile_id: required
16
+ # [String] public_token: required
17
+ # [Hash] metadata: PlaidLinkOnSuccessMetadata =>
18
+ # {
19
+ # [Hash or nil] institution: required
20
+ # [Array of objects (PlaidAccount)] accounts: required
21
+ # [String] link_session_id: required
22
+ # }
23
+ # See more for details: https://api-docs.sydecar.io/api/#tag/Plaid/operation/setPlaidAccessToken
24
+ def create_bank_account(body:)
25
+ url = create_bank_account_url
26
+ Connection.instance.post(url, body)
27
+ end
28
+
29
+ # This method creates a bank account using the specified body parameters.
30
+ # @param [Hash] body
31
+ # - The request body [Hash] with the following keys:
32
+ # - 'profile_id': [String] (required)
33
+ # - 'bank_account_id': [String] (optional)
34
+ # See more details: https://api-docs.sydecar.io/api/#tag/Plaid/operation/createPlaidLinkToken
35
+ #
36
+ # @return [Hash] - application/json -
37
+ # { link_token: [String], expiration: [String], request_id: [String] }
38
+ #
39
+ # RESPONSES: > '201'
40
+ def create_link_token(body:)
41
+ Connection.instance.post(CREATE_LINK_TOKEN_URL, body)
42
+ end
43
+
44
+ # This method Fetch a list of all available Plaid institutions.
45
+ # @param [Hash] body
46
+ # QUERY PARAMETERS:
47
+ # - 'limit': [Number] (<= 500) (optional)
48
+ # - 'offset': [Number] (optional)
49
+ # See more details: https://api-docs.sydecar.io/api/#tag/Plaid/operation/setPlaidAccessToken
50
+ # @example
51
+ # Responses sample:
52
+ # {
53
+ # "data": [
54
+ # {
55
+ # "institution_id": "string",
56
+ # "name": "string",
57
+ # "products": [
58
+ # "assets"
59
+ # ],
60
+ # "country_codes": [
61
+ # "US"
62
+ # ],
63
+ # "url": "string",
64
+ # "primary_color": "string",
65
+ # "logo": "string",
66
+ # "routing_numbers": [
67
+ # "string"
68
+ # ],
69
+ # "oauth": true,
70
+ # "status": {},
71
+ # "payment_initiation_metadata": {},
72
+ # "auth_metadata": {}
73
+ # }
74
+ # ],
75
+ # "pagination": {
76
+ # "limit": 0,
77
+ # "offset": 0,
78
+ # "total": 0
79
+ # }
80
+ # }
81
+ # @return See example data [Hash] Responses : > '200'
82
+ def fetch_plaid_institutions(query: {})
83
+ Connection.instance.get(PLAID_INSTITUTIONS_URL, query)
84
+ end
85
+
86
+ # Create a Plaid account without using Plaid link (Sandbox only)
87
+ # @param [Hash] body
88
+ # - "institution_id": "string", (required)
89
+ # - "profile_id": "string" (required)
90
+ # This method create a Plaid account without using Plaid link (Sandbox only). This route is meant to quickly setup a plaid account for testing.
91
+ # See https://api-docs.sydecar.io/api/#tag/Plaid/operation/createPlaidPublicToken
92
+ # @Example
93
+ # Response sample (application/json) :
94
+ # {
95
+ # "id": "string",
96
+ # "created_at": "2019-08-24T14:15:22Z",
97
+ # "updated_at": "2019-08-24T14:15:22Z",
98
+ # "bank_name": "string",
99
+ # "account_name": "string",
100
+ # "type": "STANDARD",
101
+ # "account_type": "CHECKING",
102
+ # "is_us_based": true,
103
+ # "account_number": "string",
104
+ # "routing_number": "string",
105
+ # "street_1": "123 Maple Street",
106
+ # "street_2": "Unit 2",
107
+ # "city": "Maple Town",
108
+ # "state": "CA",
109
+ # "zip_code": "94033",
110
+ # "country_code": "US",
111
+ # "for_further_credit": "string",
112
+ # "profile_ids": [
113
+ # "string"
114
+ # ],
115
+ # "plaid_consent_expiration_time": "2022-10-12T07:30:50.52Z",
116
+ # "plaid_account_number_mask": "1111",
117
+ # "plaid_institution_id": "string"
118
+ # }
119
+ #
120
+ # @return See example data [Hash] Responses : > '201'
121
+ def create_plaid_account(body:)
122
+ Connection.instance.post(CREATE_PLAID_BANK_ACCOUNT_URL, body)
123
+ end
124
+
125
+ # This method reset a Plaid account's login (Sandbox only)
126
+ # @param
127
+ # - 'bank_account_id': [String] (required)
128
+ # Resets the Plaid account's login information forcing the user to reauthenticate. As part of the reset, the 'plaid_consent_expiration_time' attribute is set to yesterday's date. When plaid link is called in update mode the 'plaid_consent_expiration_time' gets set back to the item's value. This route is only available in sandbox.
129
+ # See https://api-docs.sydecar.io/api/#tag/Plaid/operation/resetPlaidLogin
130
+ # @Example
131
+ # Response sample (application/json) :
132
+ # {
133
+ # "id": "string",
134
+ # "created_at": "2019-08-24T14:15:22Z",
135
+ # "updated_at": "2019-08-24T14:15:22Z",
136
+ # "bank_name": "string",
137
+ # "account_name": "string",
138
+ # "type": "STANDARD",
139
+ # "account_type": "CHECKING",
140
+ # "is_us_based": true,
141
+ # "account_number": "string",
142
+ # "routing_number": "string",
143
+ # "street_1": "123 Maple Street",
144
+ # "street_2": "Unit 2",
145
+ # "city": "Maple Town",
146
+ # "state": "CA",
147
+ # "zip_code": "94033",
148
+ # "country_code": "US",
149
+ # "for_further_credit": "string",
150
+ # "profile_ids": [
151
+ # "string"
152
+ # ],
153
+ # "plaid_consent_expiration_time": "2022-10-12T07:30:50.52Z",
154
+ # "plaid_account_number_mask": "1111",
155
+ # "plaid_institution_id": "string"
156
+ # }
157
+ #
158
+ # @return See example data [Hash] Responses : > '200'
159
+ def reset_plaid_login(bank_account_id:)
160
+ Connection.instance.post(reset_plaid_login_url(bank_account_id: bank_account_id), body:{})
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sydecar
4
+ class Profile
5
+ class Entity
6
+ URL = '/v1/profiles/entity'
7
+
8
+ class << self
9
+ # @param [Hash] body
10
+ def create(body:)
11
+ Connection.instance.post(URL, body)
12
+ end
13
+
14
+ def update(id:, body:)
15
+ Connection.instance.patch(update_url(id: id), body)
16
+ end
17
+
18
+ def update_url(id:)
19
+ "/v1/profiles/#{id}/entity"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sydecar
4
+ class Profile
5
+ class Individual
6
+ URL = '/v1/profiles/individual'
7
+
8
+ class << self
9
+ # @param [Hash] body
10
+ def create(body:)
11
+ Connection.instance.post(URL, body)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sydecar
4
+ class Profile
5
+ URL = '/v1/profiles'
6
+ ACCREDITATION_QUALIFICATION_URL = "#{URL}/accreditation_qualification_options"
7
+ class << self
8
+ def find(id:)
9
+ url = "#{URL}/#{id}"
10
+ Connection.instance.get(url, { reveal_pii: true, include: 'subscriptions,spvs' })
11
+ end
12
+
13
+ # @param [UUID] id. Warning: this must be PROFILE_ID. Not SPV ID
14
+ def activate_spv_url(id:)
15
+ "/v1/profiles/#{id}/activate"
16
+ end
17
+
18
+ # TODO: check with Sydecar why this is called "activate SPV" whereas a PROFILE_ID is passed
19
+ # @param [UUID] id. Warning: this must be PROFILE_ID. Not SPV ID
20
+ def activate_spv(id:)
21
+ Connection.instance.post(activate_spv_url(id: id))
22
+ end
23
+
24
+ # @param [UUID] id. Warning: this must be PROFILE_ID. Not SPV ID
25
+ def deactivate_spv_url(id:)
26
+ "/v1/profiles/#{id}/deactivate"
27
+ end
28
+
29
+ # TODO: check with Sydecar why this is called "deactivate SPV" whereas a PROFILE_ID is passed
30
+ # @param [UUID] id. Warning: this must be PROFILE_ID. Not SPV ID
31
+ def deactivate_spv(id:)
32
+ Connection.instance.post(deactivate_spv_url(id: id))
33
+ end
34
+
35
+ # @param [Hash] params argument expects to have the following keys
36
+ # [String] sort: asc / desc
37
+ # [Integer] limit
38
+ # [Integer] offset
39
+ # [String] start_date (format: yyyy-mm-dd)
40
+ # [String] end_date (format: yyyy-mm-dd)
41
+ # @param [Hash] body: expects to have "ids" key
42
+ def find_all(params: {}, body: {})
43
+ query = '?'
44
+ query += URI.encode_www_form(params)
45
+ Connection.instance.post("#{URL}#{query}", body)
46
+ end
47
+
48
+ # @param [String] sub_type. Enum: "ENTITY", "PERSON"
49
+ # @param [String] entity_type. Enum: "SOLE_PROPRIETOR"
50
+ # "SINGLE_MEMBER_LLC"
51
+ # "LLC"
52
+ # "PARTNERSHIP"
53
+ # "C_CORPORATION"
54
+ # "S_CORPORATION"
55
+ # "TRUST"
56
+ # "IRA_OR_TAX_EXEMPT"
57
+ # "NON_US_CORPORATION"
58
+ # "PRIVATE_LIMITED_COMPANY"
59
+ # "PUBLIC_LIMITED_COMPANY"
60
+ # "TAX_EXEMPT_ENTITY"
61
+ # "FOREIGN_TRUST"
62
+ # "OTHER"
63
+ def accreditation_qualification_opts(sub_type: , entity_type:)
64
+ body = { sub_type: sub_type, entity_type: entity_type }
65
+ Connection.instance.post(ACCREDITATION_QUALIFICATION_URL, body)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sydecar
4
+ class Spv
5
+ URL = '/v1/spvs'
6
+ CREATE_URL = "#{URL}/create"
7
+ class << self
8
+ # @param [Hash] body
9
+ def create(body:, idempotency_key:)
10
+ Connection.instance.post(CREATE_URL, body, { 'idempotency-key': idempotency_key })
11
+ end
12
+
13
+ # @param [UUID] id
14
+ # @param [Boolean] bank_accounts
15
+ # @param [Boolean] capital_call_events
16
+ # @param [Boolean] dates
17
+ # @param [Boolean] docset
18
+ # @param [Boolean] documents
19
+ # @param [Boolean] expenses
20
+ # @param [Boolean] profile
21
+ # @param [Boolean] subscriptions
22
+ def find(
23
+ id:,
24
+ bank_accounts: false,
25
+ capital_call_events: false,
26
+ dates: false,
27
+ docset: false,
28
+ documents: false,
29
+ expenses: false,
30
+ profile: false,
31
+ subscriptions: false
32
+ )
33
+ query = compile_find_params(
34
+ bank_accounts: bank_accounts,
35
+ capital_call_events: capital_call_events,
36
+ dates: dates,
37
+ docset: docset,
38
+ documents: documents,
39
+ expenses: expenses,
40
+ profile: profile,
41
+ subscriptions: subscriptions
42
+ )
43
+
44
+ Connection.instance.get("#{URL}/#{id}", query)
45
+ end
46
+
47
+ # @param [UUID] id
48
+ # @param [Hash] body
49
+ def update(id:, body:)
50
+ Connection.instance.patch("#{URL}/#{id}", body)
51
+ end
52
+
53
+ # @param [Hash] params argument expects to have the following keys
54
+ # [String] sort: asc / desc
55
+ # [Integer] limit
56
+ # [Integer] offset
57
+ # [String] start_date (format: yyyy-mm-dd)
58
+ # [String] end_date (format: yyyy-mm-dd)
59
+ # @param [Hash] body: expects to have "ids" key
60
+ def find_all(params: {}, body: {})
61
+ query = '?'
62
+ query += URI.encode_www_form(params)
63
+ Connection.instance.post("#{URL}#{query}", body)
64
+ end
65
+
66
+ # @param [UUID] id
67
+ def initiate_close_url(id:)
68
+ "/v1/spvs/#{id}/close/initiate"
69
+ end
70
+
71
+ # @param [UUID] id
72
+ # @param [UUID] idempotency_key
73
+ def initiate_close(id:, idempotency_key:)
74
+ url = initiate_close_url(id: id)
75
+ Connection.instance.post(url, nil, { 'idempotency-key': idempotency_key })
76
+ end
77
+
78
+ def disburse_close_url(id:)
79
+ "/v1/spvs/#{id}/close/disburse"
80
+ end
81
+
82
+ def disburse_close(id:, idempotency_key:)
83
+ url = disburse_close_url(id: id)
84
+ Connection.instance.post(url, nil, { 'idempotency-key': idempotency_key })
85
+ end
86
+
87
+ def counter_sign_close_url(id:)
88
+ "/v1/spvs/#{id}/close/counter_sign"
89
+ end
90
+
91
+ def counter_sign_close(id:, idempotency_key:)
92
+ url = counter_sign_close_url(id: id)
93
+ Connection.instance.post(url, nil, { 'idempotency-key': idempotency_key })
94
+ end
95
+
96
+ def request_approval_url(id:)
97
+ "/v1/spvs/#{id}/request_approval"
98
+ end
99
+
100
+ def request_approval(id:, body:)
101
+ url = request_approval_url(id: id)
102
+ Connection.instance.post(url, body)
103
+ end
104
+
105
+ def request_bank_account_url(id:)
106
+ "/v1/spvs/#{:id}/request_bank_account"
107
+ end
108
+
109
+ def request_bank_account(id:, idempotency_key:)
110
+ url = request_bank_account_url(id: id)
111
+ Connection.instance.post(url, nil, { 'idempotency-key': idempotency_key })
112
+ end
113
+
114
+ def disbursements_url(id:)
115
+ "/v1/spvs/#{id}/disbursements"
116
+ end
117
+
118
+ def disbursements(id:)
119
+ url = disbursements_url(id: id)
120
+ Connection.instance.get(url)
121
+ end
122
+
123
+ def adjust_disbursements_url(id:)
124
+ "/v1/spvs/#{id}/adjust_disbursements"
125
+ end
126
+
127
+ def adjust_disbursements(id:, body:)
128
+ url = adjust_disbursements_url(id: id)
129
+ Connection.instance.post(url, body)
130
+ end
131
+
132
+ def adjust_fund_deal_investments_url(id:)
133
+ "/v1/spvs/#{id}/adjust_fund_deal_investments"
134
+ end
135
+
136
+ def adjust_fund_deal_investments(id:)
137
+ url = adjust_fund_deal_investments_url(id: id)
138
+ Connection.instance.post(url)
139
+ end
140
+
141
+ private
142
+ def compile_find_params(
143
+ bank_accounts: false,
144
+ capital_call_events: false,
145
+ dates: false,
146
+ docset: false,
147
+ documents: false,
148
+ expenses: false,
149
+ profile: false,
150
+ subscriptions: false
151
+ )
152
+ include_queries = []
153
+ include_queries << 'bank_accounts' if bank_accounts
154
+ include_queries << 'capital_call_events' if capital_call_events
155
+ include_queries << 'dates' if dates
156
+ include_queries << 'docset' if docset
157
+ include_queries << 'documents' if documents
158
+ include_queries << 'expenses' if expenses
159
+ include_queries << 'profile' if profile
160
+ include_queries << 'subscriptions' if subscriptions
161
+
162
+ return {} if include_queries.size.zero?
163
+
164
+ { include: include_queries.join(',') }
165
+ end
166
+ end
167
+ end
168
+ end