@spritz-finance/api-client 0.4.16 → 0.4.19

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 CHANGED
@@ -118,6 +118,14 @@ const transactionData = await client.paymentRequest.getWeb3PaymentParams({
118
118
  - [Webhooks](#webhooks)
119
119
  - [Supported webhook events](#supported-webhook-events)
120
120
  - [Setting up webhooks](#setting-up-webhooks)
121
+ - [On-ramp Setup Guide](#on-ramp-setup-guide)
122
+ - [Prerequisites](#prerequisites)
123
+ - [Checking User Access Capabilities](#checking-user-access-capabilities)
124
+ - [Step-by-Step On-ramp Activation](#step-by-step-on-ramp-activation)
125
+ - [Creating Virtual Accounts](#creating-virtual-accounts)
126
+ - [Listing Virtual Accounts](#listing-virtual-accounts)
127
+ - [Supported Token Matrix](#supported-token-matrix)
128
+ - [Complete Example](#complete-example)
121
129
 
122
130
  ## API Overview
123
131
 
@@ -283,12 +291,25 @@ When a user's verification fails, Spritz now provides additional metadata to hel
283
291
 
284
292
  The verification metadata is available when a verification has failed and includes:
285
293
 
286
- - **`failureReason`**: The specific reason why the verification failed (e.g., `DuplicateIdentity`)
294
+ - **`failureReason`**: The specific reason why the verification failed
287
295
  - **`details.matchedEmail`**: For duplicate identity failures, shows the email of the matched user (only if created through the same integration)
288
296
 
297
+ #### Verification Failure Reasons
298
+
299
+ The following verification failure reasons may be returned:
300
+
301
+ - **`verify_sms`**: SMS verification failed
302
+ - **`documentary_verification`**: Document verification failed
303
+ - **`risk_check`**: Risk assessment check failed
304
+ - **`kyc_check`**: KYC (Know Your Customer) check failed
305
+ - **`watchlist_screening`**: Watchlist screening check failed
306
+ - **`selfie_check`**: Selfie verification check failed
307
+ - **`address_invalid`**: Provided address is invalid
308
+ - **`duplicate_identity`**: Identity already exists in the system
309
+
289
310
  #### Duplicate Identity Handling
290
311
 
291
- When a verification fails due to `DuplicateIdentity`, the system detects that the user has already been verified under a different account. The `matchedEmail` field helps determine:
312
+ When a verification fails due to `duplicate_identity`, the system detects that the user has already been verified under a different account. The `matchedEmail` field helps determine:
292
313
 
293
314
  - **If `matchedEmail` is populated**: The duplicate user was created through your integration
294
315
  - **If `matchedEmail` is `null`**: The duplicate user was created through a different integration (e.g., the main Spritz app)
@@ -298,9 +319,9 @@ This allows you to provide appropriate guidance to your users:
298
319
  ```typescript
299
320
  const userData = await client.user.getCurrentUser()
300
321
 
301
- if (userData.verificationMetadata?.failureReason === 'DuplicateIdentity') {
322
+ if (userData.verificationMetadata?.failureReason === 'duplicate_identity') {
302
323
  const matchedEmail = userData.verificationMetadata.details.matchedEmail
303
-
324
+
304
325
  if (matchedEmail) {
305
326
  // User exists within your integration
306
327
  console.log(`This identity is already verified with account: ${matchedEmail}`)
@@ -1181,3 +1202,251 @@ const result = await client.webhook.updateWebhookSecret('your-webhook-secret-her
1181
1202
  ```
1182
1203
 
1183
1204
  This secret will be used to sign all subsequent webhook requests sent to your endpoint. Always store your webhook secret securely and never expose it in client-side code.
1205
+
1206
+ ## On-ramp Setup Guide
1207
+
1208
+ The on-ramp feature allows users to purchase cryptocurrency using traditional payment methods (ACH, Wire transfers). Before users can on-ramp, they must complete identity verification and accept terms of service.
1209
+
1210
+ ### Prerequisites
1211
+
1212
+ Before a user can on-ramp, they must:
1213
+ 1. Complete platform-level KYC (identity verification)
1214
+ 2. Accept the third-party on-ramp provider's Terms of Service
1215
+ 3. Wait for the provider's KYC to process (happens automatically after accepting ToS)
1216
+
1217
+ ### Checking User Access Capabilities
1218
+
1219
+ Use the `getUserAccess()` method to check what features are available to a user and what requirements they need to complete:
1220
+
1221
+ ```typescript
1222
+ const accessCapabilities = await client.user.getUserAccess()
1223
+
1224
+ // Check if on-ramp is active
1225
+ if (accessCapabilities.capabilities.onramp.active) {
1226
+ console.log('User can on-ramp!')
1227
+ console.log('Available features:', accessCapabilities.capabilities.onramp.features)
1228
+ // Features may include: 'ach_purchase', 'wire_purchase'
1229
+ } else {
1230
+ console.log('User needs to complete requirements:')
1231
+ accessCapabilities.capabilities.onramp.requirements.forEach(req => {
1232
+ console.log(`- ${req.type}: ${req.description}`)
1233
+ if (req.actionUrl) {
1234
+ console.log(` Action URL: ${req.actionUrl}`)
1235
+ }
1236
+ })
1237
+ }
1238
+ ```
1239
+
1240
+ ### Step-by-Step On-ramp Activation
1241
+
1242
+ #### 1. Check Initial Requirements
1243
+
1244
+ ```typescript
1245
+ const access = await client.user.getUserAccess()
1246
+
1247
+ // Check platform-level KYC first
1248
+ if (!access.kycStatus.verified) {
1249
+ // User needs to complete platform KYC
1250
+ if (access.kycRequirement) {
1251
+ if (access.kycRequirement.actionUrl) {
1252
+ // Direct user to complete KYC
1253
+ console.log('Complete KYC at:', access.kycRequirement.actionUrl)
1254
+ }
1255
+ if (access.kycRequirement.status === 'failed' && access.kycRequirement.retryable) {
1256
+ // User can retry failed verification
1257
+ await client.user.retryFailedVerification()
1258
+ }
1259
+ }
1260
+ }
1261
+ ```
1262
+
1263
+ #### 2. Accept Terms of Service
1264
+
1265
+ Once platform KYC is complete, the user needs to accept the third-party on-ramp provider's Terms of Service:
1266
+
1267
+ ```typescript
1268
+ const access = await client.user.getUserAccess()
1269
+
1270
+ // Find the Terms of Service requirement
1271
+ const tosRequirement = access.capabilities.onramp.requirements.find(
1272
+ req => req.type === 'terms_acceptance'
1273
+ )
1274
+
1275
+ if (tosRequirement && tosRequirement.actionUrl) {
1276
+ // Use this URL to guide the customer towards Terms of Service acceptance
1277
+ // You can embed this URL in an iFrame or display in a new browser window
1278
+
1279
+ // For iFrame and WebView implementations:
1280
+ // Listen to the postMessage event for the signedAgreementId
1281
+ window.addEventListener('message', (event) => {
1282
+ if (event.data.signedAgreementId) {
1283
+ // Use the agreement ID to complete acceptance
1284
+ await client.onramp.acceptTermsOfService(event.data.signedAgreementId)
1285
+ }
1286
+ })
1287
+
1288
+ // Direct user to review the terms at tosRequirement.actionUrl
1289
+ console.log('Terms of Service URL:', tosRequirement.actionUrl)
1290
+ }
1291
+ ```
1292
+
1293
+ #### 3. Provider KYC Processing (Automatic)
1294
+
1295
+ After accepting the Terms of Service, the third-party provider's KYC process happens automatically in the background. When you accept the ToS, the platform automatically submits the user's existing KYC data to the provider. The integrator doesn't need to take any action - just monitor the status:
1296
+
1297
+ ```typescript
1298
+ // After accepting ToS, provider KYC is processed automatically
1299
+ // You can monitor the status but no action is required
1300
+ const access = await client.user.getUserAccess()
1301
+
1302
+ // Check provider KYC status (for monitoring only)
1303
+ const kycRequirement = access.capabilities.onramp.requirements.find(
1304
+ req => req.type === 'identity_verification'
1305
+ )
1306
+
1307
+ if (kycRequirement) {
1308
+ switch (kycRequirement.status) {
1309
+ case 'pending':
1310
+ console.log('Provider KYC is being processed automatically')
1311
+ break
1312
+ case 'failed':
1313
+ console.log('Provider KYC failed - user may need to retry')
1314
+ break
1315
+ default:
1316
+ // KYC completed successfully if no requirement exists
1317
+ console.log('Provider KYC complete!')
1318
+ }
1319
+ }
1320
+ ```
1321
+
1322
+ #### 4. Monitor Capability Updates
1323
+
1324
+ Use webhooks to be notified when user capabilities change:
1325
+
1326
+ ```typescript
1327
+ // Set up a webhook to monitor capability updates
1328
+ const webhook = await client.webhook.create({
1329
+ url: 'https://your-server.com/webhook',
1330
+ events: ['capabilities.updated']
1331
+ })
1332
+
1333
+ // In your webhook handler:
1334
+ // When you receive a 'capabilities.updated' event, check the user's access again
1335
+ const updatedAccess = await client.user.getUserAccess()
1336
+ if (updatedAccess.capabilities.onramp.active) {
1337
+ console.log('User can now on-ramp!')
1338
+ }
1339
+ ```
1340
+
1341
+ ### Creating Virtual Accounts
1342
+
1343
+ Once on-ramp is active, users can create virtual accounts to receive funds:
1344
+
1345
+ ```typescript
1346
+ import { PaymentNetwork, onrampSupportedTokens } from '@spritz-finance/api-client'
1347
+
1348
+ // Check supported tokens for a network
1349
+ const supportedTokens = onrampSupportedTokens[PaymentNetwork.Ethereum]
1350
+ console.log('Supported tokens on Ethereum:', supportedTokens)
1351
+ // Output: ['USDC', 'USDT', 'DAI', 'USDP', 'PYUSD']
1352
+
1353
+ // Create a virtual account
1354
+ const virtualAccount = await client.virtualAccounts.create({
1355
+ network: PaymentNetwork.Ethereum,
1356
+ address: '0xYourEthereumAddress',
1357
+ token: 'USDC'
1358
+ })
1359
+
1360
+ // The virtual account includes deposit instructions
1361
+ if (virtualAccount.depositInstructions) {
1362
+ const instructions = virtualAccount.depositInstructions
1363
+ console.log('Bank Name:', instructions.bankName)
1364
+ console.log('Account Number:', instructions.bankAccountNumber)
1365
+ console.log('Routing Number:', instructions.bankRoutingNumber)
1366
+ console.log('Bank Address:', instructions.bankAddress)
1367
+ // User sends wire/ACH to these details to fund their account
1368
+ }
1369
+ ```
1370
+
1371
+ ### Listing Virtual Accounts
1372
+
1373
+ ```typescript
1374
+ // Get all virtual accounts for the user
1375
+ const accounts = await client.virtualAccounts.list()
1376
+
1377
+ accounts.forEach(account => {
1378
+ console.log(`Network: ${account.network}`)
1379
+ console.log(`Address: ${account.address}`)
1380
+ console.log(`Token: ${account.token}`)
1381
+ console.log(`Deposited: ${account.deposited}`)
1382
+
1383
+ if (account.microdeposits) {
1384
+ console.log('Microdeposits:', account.microdeposits)
1385
+ }
1386
+ })
1387
+ ```
1388
+
1389
+ ### Supported Token Matrix
1390
+
1391
+ The following tokens are supported on each network for virtual accounts:
1392
+
1393
+ - **Ethereum**: USDC, USDT, DAI, USDP, PYUSD
1394
+ - **Polygon**: USDC
1395
+ - **Base**: USDC
1396
+ - **Arbitrum**: USDC
1397
+ - **Avalanche**: USDC
1398
+ - **Optimism**: USDC
1399
+ - **Solana**: USDC, PYUSD
1400
+ - **Tron**: USDT
1401
+
1402
+ ### Complete Example
1403
+
1404
+ ```typescript
1405
+ import { SpritzApiClient, Environment, PaymentNetwork } from '@spritz-finance/api-client'
1406
+
1407
+ const client = SpritzApiClient.initialize({
1408
+ environment: Environment.Production,
1409
+ integrationKey: 'YOUR_INTEGRATION_KEY'
1410
+ })
1411
+
1412
+ // Set user API key
1413
+ client.setApiKey(userApiKey)
1414
+
1415
+ async function setupOnramp() {
1416
+ // 1. Check current access
1417
+ const access = await client.user.getUserAccess()
1418
+
1419
+ if (!access.capabilities.onramp.active) {
1420
+ console.log('On-ramp not active. Requirements:')
1421
+
1422
+ for (const req of access.capabilities.onramp.requirements) {
1423
+ if (req.type === 'terms_acceptance' && req.actionUrl) {
1424
+ // Direct user to accept terms
1425
+ console.log('Accept terms at:', req.actionUrl)
1426
+ // After acceptance, call:
1427
+ // await client.onramp.acceptTermsOfService(agreementId)
1428
+ }
1429
+ }
1430
+
1431
+ return false
1432
+ }
1433
+
1434
+ // 2. Create virtual account
1435
+ const virtualAccount = await client.virtualAccounts.create({
1436
+ network: PaymentNetwork.Ethereum,
1437
+ address: '0xUserWalletAddress',
1438
+ token: 'USDC'
1439
+ })
1440
+
1441
+ console.log('Virtual account created!')
1442
+ console.log('Send funds to:', virtualAccount.depositInstructions)
1443
+
1444
+ return true
1445
+ }
1446
+
1447
+ setupOnramp().then(success => {
1448
+ if (success) {
1449
+ console.log('On-ramp setup complete!')
1450
+ }
1451
+ })
1452
+ ```