@venturialstd/capa 0.0.3 → 0.0.4
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.
- package/README.md +253 -253
- package/dist/capa.module.d.ts.map +1 -1
- package/dist/capa.module.js +11 -0
- package/dist/capa.module.js.map +1 -1
- package/dist/clients/capa.client.d.ts.map +1 -1
- package/dist/clients/capa.client.js +1 -2
- package/dist/clients/capa.client.js.map +1 -1
- package/dist/entities/capa-kyb-verification.entity.d.ts +19 -0
- package/dist/entities/capa-kyb-verification.entity.d.ts.map +1 -0
- package/dist/entities/capa-kyb-verification.entity.js +86 -0
- package/dist/entities/capa-kyb-verification.entity.js.map +1 -0
- package/dist/entities/capa-kyc-verification.entity.d.ts +145 -0
- package/dist/entities/capa-kyc-verification.entity.d.ts.map +1 -0
- package/dist/entities/capa-kyc-verification.entity.js +118 -0
- package/dist/entities/capa-kyc-verification.entity.js.map +1 -0
- package/dist/entities/capa-quote.entity.d.ts +37 -0
- package/dist/entities/capa-quote.entity.d.ts.map +1 -0
- package/dist/entities/capa-quote.entity.js +192 -0
- package/dist/entities/capa-quote.entity.js.map +1 -0
- package/dist/entities/capa-receiver.entity.d.ts +28 -0
- package/dist/entities/capa-receiver.entity.d.ts.map +1 -0
- package/dist/entities/capa-receiver.entity.js +181 -0
- package/dist/entities/capa-receiver.entity.js.map +1 -0
- package/dist/entities/capa-transaction.entity.d.ts +67 -0
- package/dist/entities/capa-transaction.entity.d.ts.map +1 -0
- package/dist/entities/capa-transaction.entity.js +221 -0
- package/dist/entities/capa-transaction.entity.js.map +1 -0
- package/dist/entities/capa-user.entity.d.ts +16 -0
- package/dist/entities/capa-user.entity.d.ts.map +1 -0
- package/dist/entities/capa-user.entity.js +109 -0
- package/dist/entities/capa-user.entity.js.map +1 -0
- package/dist/entities/capa-webhook-settings.entity.d.ts +9 -0
- package/dist/entities/capa-webhook-settings.entity.d.ts.map +1 -0
- package/dist/entities/capa-webhook-settings.entity.js +64 -0
- package/dist/entities/capa-webhook-settings.entity.js.map +1 -0
- package/dist/entities/index.d.ts +8 -0
- package/dist/entities/index.d.ts.map +1 -0
- package/dist/entities/index.js +24 -0
- package/dist/entities/index.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/services/capa-base.service.d.ts +1 -1
- package/dist/services/capa-base.service.d.ts.map +1 -1
- package/dist/services/capa-base.service.js.map +1 -1
- package/dist/services/capa-cross-ramp.service.d.ts +9 -3
- package/dist/services/capa-cross-ramp.service.d.ts.map +1 -1
- package/dist/services/capa-cross-ramp.service.js +68 -6
- package/dist/services/capa-cross-ramp.service.js.map +1 -1
- package/dist/services/capa-kyb.service.d.ts +6 -3
- package/dist/services/capa-kyb.service.d.ts.map +1 -1
- package/dist/services/capa-kyb.service.js +24 -4
- package/dist/services/capa-kyb.service.js.map +1 -1
- package/dist/services/capa-kyc.service.d.ts +6 -3
- package/dist/services/capa-kyc.service.d.ts.map +1 -1
- package/dist/services/capa-kyc.service.js +30 -4
- package/dist/services/capa-kyc.service.js.map +1 -1
- package/dist/services/capa-off-ramp.service.d.ts +6 -3
- package/dist/services/capa-off-ramp.service.d.ts.map +1 -1
- package/dist/services/capa-off-ramp.service.js +53 -4
- package/dist/services/capa-off-ramp.service.js.map +1 -1
- package/dist/services/capa-on-ramp.service.d.ts +6 -3
- package/dist/services/capa-on-ramp.service.d.ts.map +1 -1
- package/dist/services/capa-on-ramp.service.js +47 -4
- package/dist/services/capa-on-ramp.service.js.map +1 -1
- package/dist/services/capa-quotes.service.d.ts +7 -3
- package/dist/services/capa-quotes.service.d.ts.map +1 -1
- package/dist/services/capa-quotes.service.js +37 -5
- package/dist/services/capa-quotes.service.js.map +1 -1
- package/dist/services/capa-receivers.service.d.ts +6 -3
- package/dist/services/capa-receivers.service.d.ts.map +1 -1
- package/dist/services/capa-receivers.service.js +64 -6
- package/dist/services/capa-receivers.service.js.map +1 -1
- package/dist/services/capa-transactions.service.d.ts +7 -3
- package/dist/services/capa-transactions.service.d.ts.map +1 -1
- package/dist/services/capa-transactions.service.js +62 -5
- package/dist/services/capa-transactions.service.js.map +1 -1
- package/dist/services/capa-users.service.d.ts +9 -4
- package/dist/services/capa-users.service.d.ts.map +1 -1
- package/dist/services/capa-users.service.js +73 -4
- package/dist/services/capa-users.service.js.map +1 -1
- package/dist/services/capa-webhook-settings.service.d.ts +6 -3
- package/dist/services/capa-webhook-settings.service.d.ts.map +1 -1
- package/dist/services/capa-webhook-settings.service.js +31 -4
- package/dist/services/capa-webhook-settings.service.js.map +1 -1
- package/dist/services/index.d.ts +6 -6
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +6 -6
- package/dist/services/index.js.map +1 -1
- package/dist/settings/capa.settings.d.ts.map +1 -1
- package/dist/settings/capa.settings.js.map +1 -1
- package/dist/types/capa-api.types.d.ts +70 -9
- package/dist/types/capa-api.types.d.ts.map +1 -1
- package/package.json +58 -46
package/README.md
CHANGED
|
@@ -1,253 +1,253 @@
|
|
|
1
|
-
# @venturialstd/capa
|
|
2
|
-
|
|
3
|
-
A comprehensive **NestJS SDK for Capa Partner API v2**, developed by **Venturial**, that provides full integration with Capa.fi's payment infrastructure. This module enables seamless fiat-to-crypto, crypto-to-fiat, and fiat-to-fiat transactions, along with complete KYC/KYB verification management.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Features
|
|
8
|
-
|
|
9
|
-
- **Quotes Management**: Get and create quotes for on-ramp, off-ramp, and cross-ramp transactions
|
|
10
|
-
- **Transaction Processing**: Create and manage on-ramp (fiat→crypto), off-ramp (crypto→fiat), and cross-ramp (fiat→fiat) transactions
|
|
11
|
-
- **User Management**: Create users, manage agreements, and handle document signatures
|
|
12
|
-
- **KYC/KYB Verification**: Complete KYC and KYB verification workflows with detailed status retrieval
|
|
13
|
-
- **Receiver Management**: Create, list, and manage payment receivers
|
|
14
|
-
- **Transaction Tracking**: List, filter, and cancel transactions with comprehensive status management
|
|
15
|
-
- **Webhook Configuration**: Configure webhooks for real-time transaction notifications
|
|
16
|
-
- **Enhanced Error Handling**: Detailed error messages with validation feedback and troubleshooting hints
|
|
17
|
-
- **Type Safety**: Full TypeScript support with comprehensive type definitions
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Installation
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
npm install @venturialstd/capa
|
|
25
|
-
# or
|
|
26
|
-
yarn add @venturialstd/capa
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### Peer Dependencies
|
|
30
|
-
|
|
31
|
-
This package requires the following peer dependencies:
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
npm install @nestjs/common@^11.0.11 @nestjs/core@^11.0.5 @nestjs/axios@^4.0.0 @venturialstd/core@^1.0.16 rxjs@^7.8.1
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Basic Usage
|
|
40
|
-
|
|
41
|
-
### 1. Import the Module
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
import { Module } from '@nestjs/common';
|
|
45
|
-
import { CapaModule } from '@venturialstd/capa';
|
|
46
|
-
|
|
47
|
-
@Module({
|
|
48
|
-
imports: [
|
|
49
|
-
CapaModule,
|
|
50
|
-
],
|
|
51
|
-
})
|
|
52
|
-
export class AppModule {}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### 2. Inject and Use Services
|
|
56
|
-
|
|
57
|
-
```typescript
|
|
58
|
-
import { Injectable } from '@nestjs/common';
|
|
59
|
-
import {
|
|
60
|
-
CapaQuotesService,
|
|
61
|
-
CapaOnRampService,
|
|
62
|
-
CapaUsersService,
|
|
63
|
-
CapaKycService,
|
|
64
|
-
} from '@venturialstd/capa';
|
|
65
|
-
|
|
66
|
-
@Injectable()
|
|
67
|
-
export class PaymentService {
|
|
68
|
-
constructor(
|
|
69
|
-
private readonly quotesService: CapaQuotesService,
|
|
70
|
-
private readonly onRampService: CapaOnRampService,
|
|
71
|
-
private readonly usersService: CapaUsersService,
|
|
72
|
-
private readonly kycService: CapaKycService,
|
|
73
|
-
) {}
|
|
74
|
-
|
|
75
|
-
async processPayment(userId: string, amount: number) {
|
|
76
|
-
// Get a quote
|
|
77
|
-
const quote = await this.quotesService.getQuote({
|
|
78
|
-
tokenSymbol: 'USDC',
|
|
79
|
-
transactionType: 'ON_RAMP',
|
|
80
|
-
blockchainSymbol: 'POL',
|
|
81
|
-
fiatCurrency: 'MXN',
|
|
82
|
-
fiatAmount: amount,
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
// Create on-ramp transaction
|
|
86
|
-
const transaction = await this.onRampService.createOnRamp({
|
|
87
|
-
userId,
|
|
88
|
-
destinationWalletAddress: '0x...',
|
|
89
|
-
fiatCurrency: 'MXN',
|
|
90
|
-
blockchainSymbol: 'POL',
|
|
91
|
-
tokenSymbol: 'USDC',
|
|
92
|
-
fiatAmount: amount,
|
|
93
|
-
quoteId: quote.quoteId,
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
return transaction;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
async checkKycStatus(userId: string) {
|
|
100
|
-
const kycDetails = await this.kycService.getVerificationDetails(userId);
|
|
101
|
-
return kycDetails;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### 3. Configuration
|
|
107
|
-
|
|
108
|
-
The module uses `SettingsService` from `@venturialstd/core` to retrieve credentials. Configure the following settings:
|
|
109
|
-
|
|
110
|
-
- `CAPA_PARTNER_API_KEY`: Your Capa partner API key
|
|
111
|
-
- `CAPA_BASE_URL`: Base URL for the API (optional, defaults based on environment)
|
|
112
|
-
- `CAPA_ENVIRONMENT`: Environment setting (`staging` or `production`)
|
|
113
|
-
|
|
114
|
-
Alternatively, you can pass configuration directly to service methods:
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
await this.quotesService.getQuote(query, {
|
|
118
|
-
partnerApiKey: 'your-api-key',
|
|
119
|
-
environment: 'staging',
|
|
120
|
-
});
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
---
|
|
124
|
-
|
|
125
|
-
## API
|
|
126
|
-
|
|
127
|
-
### CapaQuotesService
|
|
128
|
-
|
|
129
|
-
| Method | Endpoint | Description |
|
|
130
|
-
|--------|----------|-------------|
|
|
131
|
-
| `getQuote(query: CapaGetQuoteQuery)` | `GET /api/partner/v2/quotes` | Get quote rate using query parameters |
|
|
132
|
-
| `createQuote(request: CapaCreateQuoteRequest)` | `POST /api/partner/v2/quotes` | Create a new quote |
|
|
133
|
-
|
|
134
|
-
### CapaOnRampService
|
|
135
|
-
|
|
136
|
-
| Method | Endpoint | Description |
|
|
137
|
-
|--------|----------|-------------|
|
|
138
|
-
| `createOnRamp(request: CapaCreateOnRampRequest)` | `POST /api/partner/v2/on-ramp` | Create a fiat-to-crypto transaction |
|
|
139
|
-
|
|
140
|
-
### CapaOffRampService
|
|
141
|
-
|
|
142
|
-
| Method | Endpoint | Description |
|
|
143
|
-
|--------|----------|-------------|
|
|
144
|
-
| `createOffRamp(request: CapaCreateOffRampRequest)` | `POST /api/partner/v2/off-ramp` | Create a crypto-to-fiat transaction |
|
|
145
|
-
|
|
146
|
-
### CapaCrossRampService
|
|
147
|
-
|
|
148
|
-
| Method | Endpoint | Description |
|
|
149
|
-
|--------|----------|-------------|
|
|
150
|
-
| `getCrossRampQuote(query: CapaGetCrossRampQuoteQuery)` | `GET /api/partner/v2/cross-ramp/quotes` | Get cross-ramp quote rate |
|
|
151
|
-
| `createCrossRampQuote(request: CapaCreateCrossRampQuoteRequest)` | `POST /api/partner/v2/cross-ramp/quotes` | Create a cross-ramp quote |
|
|
152
|
-
| `createCrossRamp(request: CapaCreateCrossRampRequest)` | `POST /api/partner/v2/cross-ramp` | Create a fiat-to-fiat transaction |
|
|
153
|
-
|
|
154
|
-
### CapaUsersService
|
|
155
|
-
|
|
156
|
-
| Method | Endpoint | Description |
|
|
157
|
-
|--------|----------|-------------|
|
|
158
|
-
| `createUser(request: CapaCreateUserRequest)` | `POST /api/partner/v2/users` | Create a new user |
|
|
159
|
-
| `getUserAgreements(userId: string)` | `GET /api/partner/v2/users/{id}/agreements` | Get user agreements |
|
|
160
|
-
| `requestDocumentSignature(userId: string, request: CapaDocumentSignRequest)` | `POST /api/partner/v2/users/{id}/documents/sign` | Request document signature |
|
|
161
|
-
|
|
162
|
-
### CapaKycService
|
|
163
|
-
|
|
164
|
-
| Method | Endpoint | Description |
|
|
165
|
-
|--------|----------|-------------|
|
|
166
|
-
| `getVerificationDetails(userId: string)` | `GET /api/partner/v2/kyc/details?userId={userId}` | Get KYC verification details including AML, face match, fraud insights, and ID information |
|
|
167
|
-
|
|
168
|
-
### CapaKybService
|
|
169
|
-
|
|
170
|
-
| Method | Endpoint | Description |
|
|
171
|
-
|--------|----------|-------------|
|
|
172
|
-
| `getUserKybDetails(userId: string)` | `GET /api/partner/v2/kyb/details?userId={userId}` | Get KYB verification details including business info and beneficial owners |
|
|
173
|
-
|
|
174
|
-
### CapaReceiversService
|
|
175
|
-
|
|
176
|
-
| Method | Endpoint | Description |
|
|
177
|
-
|--------|----------|-------------|
|
|
178
|
-
| `createReceiver(request: CapaCreateReceiverRequest)` | `POST /api/partner/v2/receivers` | Create a payment receiver |
|
|
179
|
-
| `listReceivers(query?: CapaListReceiversQuery)` | `GET /api/partner/v2/receivers` | List receivers with optional filtering |
|
|
180
|
-
| `deleteReceiver(id: string, request: CapaDeleteReceiverRequest)` | `DELETE /api/partner/v2/receivers/{id}` | Disable (soft-delete) a receiver |
|
|
181
|
-
|
|
182
|
-
### CapaTransactionsService
|
|
183
|
-
|
|
184
|
-
| Method | Endpoint | Description |
|
|
185
|
-
|--------|----------|-------------|
|
|
186
|
-
| `listTransactions(query?: CapaListTransactionsQuery)` | `GET /api/partner/v2/transactions` | List transactions with filtering options |
|
|
187
|
-
| `cancelTransaction(transactionId: string)` | `PUT /api/partner/v2/transactions/{id}/cancel` | Cancel a transaction |
|
|
188
|
-
| `getMockTestingGuide()` | `GET /api/partner/v2/transactions/mock-testing-guide` | Get mock testing guide for staging environment |
|
|
189
|
-
|
|
190
|
-
### CapaWebhookSettingsService
|
|
191
|
-
|
|
192
|
-
| Method | Endpoint | Description |
|
|
193
|
-
|--------|----------|-------------|
|
|
194
|
-
| `updateWebhookSettings(request: CapaUpdateWebhookSettingsRequest)` | `PUT /api/partner/v2/webhook-settings` | Update webhook notification URL |
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
## Error Handling
|
|
199
|
-
|
|
200
|
-
The module includes enhanced error handling that provides detailed information about:
|
|
201
|
-
|
|
202
|
-
- **HTTP Status Codes**: Identifies error types (400, 401, 404, 422, 500, etc.)
|
|
203
|
-
- **Error Messages**: Shows specific error messages from Capa API
|
|
204
|
-
- **Validation Errors**: Lists fields that failed validation with specific messages
|
|
205
|
-
- **Contextual Information**: Includes endpoint, HTTP method, and response time
|
|
206
|
-
- **Troubleshooting Hints**: Provides suggestions on what might be missing or incorrect
|
|
207
|
-
|
|
208
|
-
### Example Error Message
|
|
209
|
-
|
|
210
|
-
```
|
|
211
|
-
Capa API call failed: POST /quotes (HTTP 422) - Validation failed | Validation errors: fiatAmount: Required field, tokenSymbol: Invalid token symbol | Unprocessable Entity: Check request body validation
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
### Error Object Properties
|
|
215
|
-
|
|
216
|
-
When an error is thrown, you can access:
|
|
217
|
-
|
|
218
|
-
```typescript
|
|
219
|
-
try {
|
|
220
|
-
await this.quotesService.createQuote(request);
|
|
221
|
-
} catch (error: any) {
|
|
222
|
-
console.log(error.statusCode); // HTTP status code
|
|
223
|
-
console.log(error.responseData); // Full response data
|
|
224
|
-
console.log(error.endpoint); // API endpoint
|
|
225
|
-
console.log(error.method); // HTTP method
|
|
226
|
-
console.log(error.message); // Detailed error message
|
|
227
|
-
}
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
---
|
|
231
|
-
|
|
232
|
-
## Notes
|
|
233
|
-
|
|
234
|
-
- **Environment Support**: The module supports both staging and production environments. Defaults to staging if not specified.
|
|
235
|
-
- **Type Safety**: All request and response types are fully typed for better IDE support and compile-time error checking.
|
|
236
|
-
- **Logging**: All API calls are automatically logged with timing information using `AppLogger` from `@venturialstd/core`.
|
|
237
|
-
- **Configuration Flexibility**: You can configure credentials globally via settings or pass them per-request.
|
|
238
|
-
- **Rate Limiting**: Be aware of Capa's rate limits when making multiple API calls.
|
|
239
|
-
- **Quote Expiration**: Quotes have expiration times. Always check `expiresAt` before using a quote.
|
|
240
|
-
- **KYC/KYB Requirements**: Users must complete KYC/KYB verification before creating transactions.
|
|
241
|
-
- **Webhook Security**: Ensure your webhook endpoints are secured and validate webhook signatures from Capa.
|
|
242
|
-
|
|
243
|
-
---
|
|
244
|
-
|
|
245
|
-
## License
|
|
246
|
-
|
|
247
|
-
MIT
|
|
248
|
-
|
|
249
|
-
---
|
|
250
|
-
|
|
251
|
-
## Support
|
|
252
|
-
|
|
253
|
-
For issues, questions, or contributions, please contact the Venturial development team.
|
|
1
|
+
# @venturialstd/capa
|
|
2
|
+
|
|
3
|
+
A comprehensive **NestJS SDK for Capa Partner API v2**, developed by **Venturial**, that provides full integration with Capa.fi's payment infrastructure. This module enables seamless fiat-to-crypto, crypto-to-fiat, and fiat-to-fiat transactions, along with complete KYC/KYB verification management.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Quotes Management**: Get and create quotes for on-ramp, off-ramp, and cross-ramp transactions
|
|
10
|
+
- **Transaction Processing**: Create and manage on-ramp (fiat→crypto), off-ramp (crypto→fiat), and cross-ramp (fiat→fiat) transactions
|
|
11
|
+
- **User Management**: Create users, manage agreements, and handle document signatures
|
|
12
|
+
- **KYC/KYB Verification**: Complete KYC and KYB verification workflows with detailed status retrieval
|
|
13
|
+
- **Receiver Management**: Create, list, and manage payment receivers
|
|
14
|
+
- **Transaction Tracking**: List, filter, and cancel transactions with comprehensive status management
|
|
15
|
+
- **Webhook Configuration**: Configure webhooks for real-time transaction notifications
|
|
16
|
+
- **Enhanced Error Handling**: Detailed error messages with validation feedback and troubleshooting hints
|
|
17
|
+
- **Type Safety**: Full TypeScript support with comprehensive type definitions
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @venturialstd/capa
|
|
25
|
+
# or
|
|
26
|
+
yarn add @venturialstd/capa
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Peer Dependencies
|
|
30
|
+
|
|
31
|
+
This package requires the following peer dependencies:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install @nestjs/common@^11.0.11 @nestjs/core@^11.0.5 @nestjs/axios@^4.0.0 @venturialstd/core@^1.0.16 rxjs@^7.8.1
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Basic Usage
|
|
40
|
+
|
|
41
|
+
### 1. Import the Module
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { Module } from '@nestjs/common';
|
|
45
|
+
import { CapaModule } from '@venturialstd/capa';
|
|
46
|
+
|
|
47
|
+
@Module({
|
|
48
|
+
imports: [
|
|
49
|
+
CapaModule,
|
|
50
|
+
],
|
|
51
|
+
})
|
|
52
|
+
export class AppModule {}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 2. Inject and Use Services
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { Injectable } from '@nestjs/common';
|
|
59
|
+
import {
|
|
60
|
+
CapaQuotesService,
|
|
61
|
+
CapaOnRampService,
|
|
62
|
+
CapaUsersService,
|
|
63
|
+
CapaKycService,
|
|
64
|
+
} from '@venturialstd/capa';
|
|
65
|
+
|
|
66
|
+
@Injectable()
|
|
67
|
+
export class PaymentService {
|
|
68
|
+
constructor(
|
|
69
|
+
private readonly quotesService: CapaQuotesService,
|
|
70
|
+
private readonly onRampService: CapaOnRampService,
|
|
71
|
+
private readonly usersService: CapaUsersService,
|
|
72
|
+
private readonly kycService: CapaKycService,
|
|
73
|
+
) {}
|
|
74
|
+
|
|
75
|
+
async processPayment(userId: string, amount: number) {
|
|
76
|
+
// Get a quote
|
|
77
|
+
const quote = await this.quotesService.getQuote({
|
|
78
|
+
tokenSymbol: 'USDC',
|
|
79
|
+
transactionType: 'ON_RAMP',
|
|
80
|
+
blockchainSymbol: 'POL',
|
|
81
|
+
fiatCurrency: 'MXN',
|
|
82
|
+
fiatAmount: amount,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Create on-ramp transaction
|
|
86
|
+
const transaction = await this.onRampService.createOnRamp({
|
|
87
|
+
userId,
|
|
88
|
+
destinationWalletAddress: '0x...',
|
|
89
|
+
fiatCurrency: 'MXN',
|
|
90
|
+
blockchainSymbol: 'POL',
|
|
91
|
+
tokenSymbol: 'USDC',
|
|
92
|
+
fiatAmount: amount,
|
|
93
|
+
quoteId: quote.quoteId,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return transaction;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async checkKycStatus(userId: string) {
|
|
100
|
+
const kycDetails = await this.kycService.getVerificationDetails(userId);
|
|
101
|
+
return kycDetails;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 3. Configuration
|
|
107
|
+
|
|
108
|
+
The module uses `SettingsService` from `@venturialstd/core` to retrieve credentials. Configure the following settings:
|
|
109
|
+
|
|
110
|
+
- `CAPA_PARTNER_API_KEY`: Your Capa partner API key
|
|
111
|
+
- `CAPA_BASE_URL`: Base URL for the API (optional, defaults based on environment)
|
|
112
|
+
- `CAPA_ENVIRONMENT`: Environment setting (`staging` or `production`)
|
|
113
|
+
|
|
114
|
+
Alternatively, you can pass configuration directly to service methods:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
await this.quotesService.getQuote(query, {
|
|
118
|
+
partnerApiKey: 'your-api-key',
|
|
119
|
+
environment: 'staging',
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## API
|
|
126
|
+
|
|
127
|
+
### CapaQuotesService
|
|
128
|
+
|
|
129
|
+
| Method | Endpoint | Description |
|
|
130
|
+
|--------|----------|-------------|
|
|
131
|
+
| `getQuote(query: CapaGetQuoteQuery)` | `GET /api/partner/v2/quotes` | Get quote rate using query parameters |
|
|
132
|
+
| `createQuote(request: CapaCreateQuoteRequest)` | `POST /api/partner/v2/quotes` | Create a new quote |
|
|
133
|
+
|
|
134
|
+
### CapaOnRampService
|
|
135
|
+
|
|
136
|
+
| Method | Endpoint | Description |
|
|
137
|
+
|--------|----------|-------------|
|
|
138
|
+
| `createOnRamp(request: CapaCreateOnRampRequest)` | `POST /api/partner/v2/on-ramp` | Create a fiat-to-crypto transaction |
|
|
139
|
+
|
|
140
|
+
### CapaOffRampService
|
|
141
|
+
|
|
142
|
+
| Method | Endpoint | Description |
|
|
143
|
+
|--------|----------|-------------|
|
|
144
|
+
| `createOffRamp(request: CapaCreateOffRampRequest)` | `POST /api/partner/v2/off-ramp` | Create a crypto-to-fiat transaction |
|
|
145
|
+
|
|
146
|
+
### CapaCrossRampService
|
|
147
|
+
|
|
148
|
+
| Method | Endpoint | Description |
|
|
149
|
+
|--------|----------|-------------|
|
|
150
|
+
| `getCrossRampQuote(query: CapaGetCrossRampQuoteQuery)` | `GET /api/partner/v2/cross-ramp/quotes` | Get cross-ramp quote rate |
|
|
151
|
+
| `createCrossRampQuote(request: CapaCreateCrossRampQuoteRequest)` | `POST /api/partner/v2/cross-ramp/quotes` | Create a cross-ramp quote |
|
|
152
|
+
| `createCrossRamp(request: CapaCreateCrossRampRequest)` | `POST /api/partner/v2/cross-ramp` | Create a fiat-to-fiat transaction |
|
|
153
|
+
|
|
154
|
+
### CapaUsersService
|
|
155
|
+
|
|
156
|
+
| Method | Endpoint | Description |
|
|
157
|
+
|--------|----------|-------------|
|
|
158
|
+
| `createUser(request: CapaCreateUserRequest)` | `POST /api/partner/v2/users` | Create a new user |
|
|
159
|
+
| `getUserAgreements(userId: string)` | `GET /api/partner/v2/users/{id}/agreements` | Get user agreements |
|
|
160
|
+
| `requestDocumentSignature(userId: string, request: CapaDocumentSignRequest)` | `POST /api/partner/v2/users/{id}/documents/sign` | Request document signature |
|
|
161
|
+
|
|
162
|
+
### CapaKycService
|
|
163
|
+
|
|
164
|
+
| Method | Endpoint | Description |
|
|
165
|
+
|--------|----------|-------------|
|
|
166
|
+
| `getVerificationDetails(userId: string)` | `GET /api/partner/v2/kyc/details?userId={userId}` | Get KYC verification details including AML, face match, fraud insights, and ID information |
|
|
167
|
+
|
|
168
|
+
### CapaKybService
|
|
169
|
+
|
|
170
|
+
| Method | Endpoint | Description |
|
|
171
|
+
|--------|----------|-------------|
|
|
172
|
+
| `getUserKybDetails(userId: string)` | `GET /api/partner/v2/kyb/details?userId={userId}` | Get KYB verification details including business info and beneficial owners |
|
|
173
|
+
|
|
174
|
+
### CapaReceiversService
|
|
175
|
+
|
|
176
|
+
| Method | Endpoint | Description |
|
|
177
|
+
|--------|----------|-------------|
|
|
178
|
+
| `createReceiver(request: CapaCreateReceiverRequest)` | `POST /api/partner/v2/receivers` | Create a payment receiver |
|
|
179
|
+
| `listReceivers(query?: CapaListReceiversQuery)` | `GET /api/partner/v2/receivers` | List receivers with optional filtering |
|
|
180
|
+
| `deleteReceiver(id: string, request: CapaDeleteReceiverRequest)` | `DELETE /api/partner/v2/receivers/{id}` | Disable (soft-delete) a receiver |
|
|
181
|
+
|
|
182
|
+
### CapaTransactionsService
|
|
183
|
+
|
|
184
|
+
| Method | Endpoint | Description |
|
|
185
|
+
|--------|----------|-------------|
|
|
186
|
+
| `listTransactions(query?: CapaListTransactionsQuery)` | `GET /api/partner/v2/transactions` | List transactions with filtering options |
|
|
187
|
+
| `cancelTransaction(transactionId: string)` | `PUT /api/partner/v2/transactions/{id}/cancel` | Cancel a transaction |
|
|
188
|
+
| `getMockTestingGuide()` | `GET /api/partner/v2/transactions/mock-testing-guide` | Get mock testing guide for staging environment |
|
|
189
|
+
|
|
190
|
+
### CapaWebhookSettingsService
|
|
191
|
+
|
|
192
|
+
| Method | Endpoint | Description |
|
|
193
|
+
|--------|----------|-------------|
|
|
194
|
+
| `updateWebhookSettings(request: CapaUpdateWebhookSettingsRequest)` | `PUT /api/partner/v2/webhook-settings` | Update webhook notification URL |
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Error Handling
|
|
199
|
+
|
|
200
|
+
The module includes enhanced error handling that provides detailed information about:
|
|
201
|
+
|
|
202
|
+
- **HTTP Status Codes**: Identifies error types (400, 401, 404, 422, 500, etc.)
|
|
203
|
+
- **Error Messages**: Shows specific error messages from Capa API
|
|
204
|
+
- **Validation Errors**: Lists fields that failed validation with specific messages
|
|
205
|
+
- **Contextual Information**: Includes endpoint, HTTP method, and response time
|
|
206
|
+
- **Troubleshooting Hints**: Provides suggestions on what might be missing or incorrect
|
|
207
|
+
|
|
208
|
+
### Example Error Message
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
Capa API call failed: POST /quotes (HTTP 422) - Validation failed | Validation errors: fiatAmount: Required field, tokenSymbol: Invalid token symbol | Unprocessable Entity: Check request body validation
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Error Object Properties
|
|
215
|
+
|
|
216
|
+
When an error is thrown, you can access:
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
try {
|
|
220
|
+
await this.quotesService.createQuote(request);
|
|
221
|
+
} catch (error: any) {
|
|
222
|
+
console.log(error.statusCode); // HTTP status code
|
|
223
|
+
console.log(error.responseData); // Full response data
|
|
224
|
+
console.log(error.endpoint); // API endpoint
|
|
225
|
+
console.log(error.method); // HTTP method
|
|
226
|
+
console.log(error.message); // Detailed error message
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Notes
|
|
233
|
+
|
|
234
|
+
- **Environment Support**: The module supports both staging and production environments. Defaults to staging if not specified.
|
|
235
|
+
- **Type Safety**: All request and response types are fully typed for better IDE support and compile-time error checking.
|
|
236
|
+
- **Logging**: All API calls are automatically logged with timing information using `AppLogger` from `@venturialstd/core`.
|
|
237
|
+
- **Configuration Flexibility**: You can configure credentials globally via settings or pass them per-request.
|
|
238
|
+
- **Rate Limiting**: Be aware of Capa's rate limits when making multiple API calls.
|
|
239
|
+
- **Quote Expiration**: Quotes have expiration times. Always check `expiresAt` before using a quote.
|
|
240
|
+
- **KYC/KYB Requirements**: Users must complete KYC/KYB verification before creating transactions.
|
|
241
|
+
- **Webhook Security**: Ensure your webhook endpoints are secured and validate webhook signatures from Capa.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## License
|
|
246
|
+
|
|
247
|
+
MIT
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Support
|
|
252
|
+
|
|
253
|
+
For issues, questions, or contributions, please contact the Venturial development team.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capa.module.d.ts","sourceRoot":"","sources":["../src/capa.module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"capa.module.d.ts","sourceRoot":"","sources":["../src/capa.module.ts"],"names":[],"mappings":"AA4BA,qBA0Ca,UAAU;CAAG"}
|
package/dist/capa.module.js
CHANGED
|
@@ -9,8 +9,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
exports.CapaModule = void 0;
|
|
10
10
|
const axios_1 = require("@nestjs/axios");
|
|
11
11
|
const common_1 = require("@nestjs/common");
|
|
12
|
+
const typeorm_1 = require("@nestjs/typeorm");
|
|
12
13
|
const core_1 = require("@venturialstd/core");
|
|
13
14
|
const capa_client_1 = require("./clients/capa.client");
|
|
15
|
+
const entities_1 = require("./entities");
|
|
14
16
|
const services_1 = require("./services");
|
|
15
17
|
let CapaModule = class CapaModule {
|
|
16
18
|
};
|
|
@@ -20,6 +22,15 @@ exports.CapaModule = CapaModule = __decorate([
|
|
|
20
22
|
imports: [
|
|
21
23
|
core_1.SharedModule,
|
|
22
24
|
axios_1.HttpModule,
|
|
25
|
+
typeorm_1.TypeOrmModule.forFeature([
|
|
26
|
+
entities_1.CapaUser,
|
|
27
|
+
entities_1.CapaReceiver,
|
|
28
|
+
entities_1.CapaTransaction,
|
|
29
|
+
entities_1.CapaQuote,
|
|
30
|
+
entities_1.CapaKycVerification,
|
|
31
|
+
entities_1.CapaKybVerification,
|
|
32
|
+
entities_1.CapaWebhookSettings,
|
|
33
|
+
]),
|
|
23
34
|
],
|
|
24
35
|
controllers: [],
|
|
25
36
|
providers: [
|
package/dist/capa.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capa.module.js","sourceRoot":"","sources":["../src/capa.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,yCAA2C;AAC3C,2CAAwC;AACxC,6CAAkD;AAElD,uDAAmD;AACnD,yCAWoB;
|
|
1
|
+
{"version":3,"file":"capa.module.js","sourceRoot":"","sources":["../src/capa.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,yCAA2C;AAC3C,2CAAwC;AACxC,6CAAgD;AAChD,6CAAkD;AAElD,uDAAmD;AACnD,yCAQoB;AACpB,yCAWoB;AA4Cb,IAAM,UAAU,GAAhB,MAAM,UAAU;CAAG,CAAA;AAAb,gCAAU;qBAAV,UAAU;IA1CtB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,mBAAY;YACZ,kBAAU;YACV,uBAAa,CAAC,UAAU,CAAC;gBACvB,mBAAQ;gBACR,uBAAY;gBACZ,0BAAe;gBACf,oBAAS;gBACT,8BAAmB;gBACnB,8BAAmB;gBACnB,8BAAmB;aACpB,CAAC;SACH;QACD,WAAW,EAAE,EAAE;QACf,SAAS,EAAE;YACT,wBAAU;YACV,4BAAiB;YACjB,+BAAoB;YACpB,2BAAgB;YAChB,kCAAuB;YACvB,4BAAiB;YACjB,6BAAkB;YAClB,+BAAoB;YACpB,yBAAc;YACd,yBAAc;YACd,qCAA0B;SAC3B;QACD,OAAO,EAAE;YACP,wBAAU;YACV,4BAAiB;YACjB,+BAAoB;YACpB,2BAAgB;YAChB,kCAAuB;YACvB,4BAAiB;YACjB,6BAAkB;YAClB,+BAAoB;YACpB,yBAAc;YACd,yBAAc;YACd,qCAA0B;SAC3B;KACF,CAAC;GACW,UAAU,CAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capa.client.d.ts","sourceRoot":"","sources":["../../src/clients/capa.client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAIrD,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE9E,qBACa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAAf,eAAe,EAAE,eAAe;IAEvD,cAAc,CAAC,MAAM,GAAE,UAAU,GAAG,IAAW,GAAG,OAAO,CAAC,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"capa.client.d.ts","sourceRoot":"","sources":["../../src/clients/capa.client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAIrD,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE9E,qBACa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAAf,eAAe,EAAE,eAAe;IAEvD,cAAc,CAAC,MAAM,GAAE,UAAU,GAAG,IAAW,GAAG,OAAO,CAAC,qBAAqB,CAAC;CA+BvF"}
|
|
@@ -37,8 +37,7 @@ let CapaClient = class CapaClient {
|
|
|
37
37
|
]);
|
|
38
38
|
const environment = capaSettings[capa_settings_constant_1.CAPA_SETTING_KEYS.GENERAL_ENVIRONMENT] ||
|
|
39
39
|
capa_constant_1.CapaEnvironment.STAGING;
|
|
40
|
-
const baseUrl = capaSettings[capa_settings_constant_1.CAPA_SETTING_KEYS.GENERAL_BASE_URL] ||
|
|
41
|
-
capa_constant_1.CAPA_BASE_URLS[environment];
|
|
40
|
+
const baseUrl = capaSettings[capa_settings_constant_1.CAPA_SETTING_KEYS.GENERAL_BASE_URL] || capa_constant_1.CAPA_BASE_URLS[environment];
|
|
42
41
|
return {
|
|
43
42
|
partnerApiKey: capaSettings[capa_settings_constant_1.CAPA_SETTING_KEYS.GENERAL_PARTNER_API_KEY],
|
|
44
43
|
baseUrl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capa.client.js","sourceRoot":"","sources":["../../src/clients/capa.client.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6CAAqD;AAErD,8DAA6E;AAC7E,gFAAwE;AAIjE,IAAM,UAAU,GAAhB,MAAM,UAAU;IACQ;IAA7B,YAA6B,eAAgC;QAAhC,oBAAe,GAAf,eAAe,CAAiB;IAAG,CAAC;IAEjE,KAAK,CAAC,cAAc,CAAC,SAA4B,IAAI;QACnD,IAAI,MAAM,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACnC,MAAM,OAAO,GACX,MAAM,CAAC,OAAO;gBACd,CAAC,MAAM,CAAC,WAAW;oBACjB,CAAC,CAAC,8BAAc,CAAC,MAAM,CAAC,WAAW,CAAC;oBACpC,CAAC,CAAC,8BAAc,CAAC,+BAAe,CAAC,OAAO,CAAC,CAAC,CAAC;YAE/C,OAAO;gBACL,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,OAAO;aACR,CAAC;QACJ,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC;YAClE,0CAAiB,CAAC,uBAAuB;YACzC,0CAAiB,CAAC,gBAAgB;YAClC,0CAAiB,CAAC,mBAAmB;SACtC,CAAC,CAAC;QAEH,MAAM,WAAW,GACd,YAAY,CAAC,0CAAiB,CAAC,mBAAmB,CAAqB;YACxE,+BAAe,CAAC,OAAO,CAAC;QAE1B,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"capa.client.js","sourceRoot":"","sources":["../../src/clients/capa.client.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6CAAqD;AAErD,8DAA6E;AAC7E,gFAAwE;AAIjE,IAAM,UAAU,GAAhB,MAAM,UAAU;IACQ;IAA7B,YAA6B,eAAgC;QAAhC,oBAAe,GAAf,eAAe,CAAiB;IAAG,CAAC;IAEjE,KAAK,CAAC,cAAc,CAAC,SAA4B,IAAI;QACnD,IAAI,MAAM,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACnC,MAAM,OAAO,GACX,MAAM,CAAC,OAAO;gBACd,CAAC,MAAM,CAAC,WAAW;oBACjB,CAAC,CAAC,8BAAc,CAAC,MAAM,CAAC,WAAW,CAAC;oBACpC,CAAC,CAAC,8BAAc,CAAC,+BAAe,CAAC,OAAO,CAAC,CAAC,CAAC;YAE/C,OAAO;gBACL,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,OAAO;aACR,CAAC;QACJ,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC;YAClE,0CAAiB,CAAC,uBAAuB;YACzC,0CAAiB,CAAC,gBAAgB;YAClC,0CAAiB,CAAC,mBAAmB;SACtC,CAAC,CAAC;QAEH,MAAM,WAAW,GACd,YAAY,CAAC,0CAAiB,CAAC,mBAAmB,CAAqB;YACxE,+BAAe,CAAC,OAAO,CAAC;QAE1B,MAAM,OAAO,GAAG,YAAY,CAAC,0CAAiB,CAAC,gBAAgB,CAAC,IAAI,8BAAc,CAAC,WAAW,CAAC,CAAC;QAEhG,OAAO;YACL,aAAa,EAAE,YAAY,CAAC,0CAAiB,CAAC,uBAAuB,CAAC;YACtE,OAAO;SACR,CAAC;IACJ,CAAC;CACF,CAAA;AAlCY,gCAAU;qBAAV,UAAU;IADtB,IAAA,mBAAU,GAAE;qCAEmC,sBAAe;GADlD,UAAU,CAkCtB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare class CapaKybVerification {
|
|
2
|
+
id: string;
|
|
3
|
+
userId: string;
|
|
4
|
+
verificationSessionId: string;
|
|
5
|
+
verificationStatus: string;
|
|
6
|
+
businessInfo?: {
|
|
7
|
+
businessName: string;
|
|
8
|
+
countryOfConstitution: string;
|
|
9
|
+
taxId: string;
|
|
10
|
+
};
|
|
11
|
+
beneficialOwners?: Array<{
|
|
12
|
+
fullName: string;
|
|
13
|
+
ownershipPercent: number;
|
|
14
|
+
}>;
|
|
15
|
+
metadata: Record<string, unknown>;
|
|
16
|
+
createdAt: Date;
|
|
17
|
+
updatedAt: Date;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=capa-kyb-verification.entity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capa-kyb-verification.entity.d.ts","sourceRoot":"","sources":["../../src/entities/capa-kyb-verification.entity.ts"],"names":[],"mappings":"AAUA,qBAGa,mBAAmB;IAE9B,EAAE,EAAE,MAAM,CAAC;IAMX,MAAM,EAAE,MAAM,CAAC;IAMf,qBAAqB,EAAE,MAAM,CAAC;IAK9B,kBAAkB,EAAE,MAAM,CAAC;IAI3B,YAAY,CAAC,EAAE;QACb,YAAY,EAAE,MAAM,CAAC;QACrB,qBAAqB,EAAE,MAAM,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IAIF,gBAAgB,CAAC,EAAE,KAAK,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC,CAAC;IAGH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAQlC,SAAS,EAAE,IAAI,CAAC;IAQhB,SAAS,EAAE,IAAI,CAAC;CACjB"}
|