sydecar 0.1.6

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,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