@spritz-finance/api-client 0.5.0 → 0.7.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.
- package/README.md +50 -10
- package/dist/spritz-api-client.cjs +77 -70
- package/dist/spritz-api-client.d.ts +17212 -6458
- package/dist/spritz-api-client.mjs +76 -69
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -817,15 +817,23 @@ const accounts = await client.virtualAccounts.list()
|
|
|
817
817
|
|
|
818
818
|
## ACH Onramp (Direct Debit)
|
|
819
819
|
|
|
820
|
-
ACH onramp lets users convert USD from their bank account into USDC delivered to a Solana wallet. The flow
|
|
820
|
+
ACH onramp lets users convert USD from their bank account into USDC delivered to a Solana wallet. The integration is a short server-side flow with one client-side Plaid step:
|
|
821
821
|
|
|
822
|
-
1. **
|
|
823
|
-
2. **
|
|
824
|
-
3. **
|
|
822
|
+
1. **Server:** create a Plaid link token with `client.bankAccount.createLinkToken()`
|
|
823
|
+
2. **Client:** run Plaid Link and send the public token/account IDs back to your server
|
|
824
|
+
3. **Server:** complete linking with `client.bankAccount.completeLinking(...)`
|
|
825
|
+
4. **Server:** find an active funding source and fetch limits with `client.fundingSource.getDepositLimits(id)`
|
|
826
|
+
5. **Server:** prepare a quote with `client.deposit.prepare(...)`
|
|
827
|
+
6. **Client:** show the quote and ACH authorization message to the user
|
|
828
|
+
7. **Server:** create the deposit with `client.deposit.create(...)`; Spritz runs risk checks before initiating the ACH pull
|
|
829
|
+
|
|
830
|
+
Authorization is derived from the verified ACH funding source — no wallet signature is required.
|
|
831
|
+
|
|
832
|
+
If risk checks block the create step, the API returns 409 before any ACH debit is pulled. Prepare a new quote before retrying; blocked create attempts consume the original `preparationId`.
|
|
825
833
|
|
|
826
834
|
For a complete walkthrough with code examples, request/response schemas, and deposit lifecycle documentation, see the **[ACH Onramp Integration Guide](docs/ach-onramp-guide.md)**.
|
|
827
835
|
|
|
828
|
-
A standalone sandbox demo is available at `scripts/sandbox/ach-onramp.html`
|
|
836
|
+
A standalone sandbox demo is available at `scripts/sandbox/ach-onramp.html`. Run `yarn build && node scripts/sandbox/evidence-server.mjs`, then open `http://localhost:3001/ach-onramp.html` to test the SDK-backed flow and save redacted QC evidence.
|
|
829
837
|
|
|
830
838
|
## Sandbox
|
|
831
839
|
|
|
@@ -873,12 +881,31 @@ This endpoint returns 403 in production.
|
|
|
873
881
|
|
|
874
882
|
- `capabilities.updated` — user capabilities changed
|
|
875
883
|
|
|
884
|
+
#### On-Ramp Events
|
|
885
|
+
|
|
886
|
+
- `onramp.created` — on-ramp record created after a deposit is authorized
|
|
887
|
+
- `onramp.updated` — on-ramp status, delivery, or reversal details updated
|
|
888
|
+
- `onramp.completed` — on-ramp delivery completed
|
|
889
|
+
|
|
890
|
+
#### ACH Debit Return Events
|
|
891
|
+
|
|
892
|
+
- `achDebitReturn.created` — ACH debit return recorded
|
|
893
|
+
- `achDebitReturn.updated` — ACH debit return details updated
|
|
894
|
+
|
|
895
|
+
Use `'*'` to subscribe a webhook endpoint to all current and future webhook events.
|
|
896
|
+
|
|
876
897
|
### Setup
|
|
877
898
|
|
|
878
899
|
```typescript
|
|
879
900
|
const webhook = await client.webhook.create({
|
|
880
901
|
url: 'https://my.webhook.url/spritz',
|
|
881
|
-
events: ['
|
|
902
|
+
events: ['onramp.created', 'onramp.updated', 'achDebitReturn.created'],
|
|
903
|
+
})
|
|
904
|
+
|
|
905
|
+
// Subscribe to all events
|
|
906
|
+
await client.webhook.create({
|
|
907
|
+
url: 'https://my.webhook.url/spritz/all',
|
|
908
|
+
events: ['*'],
|
|
882
909
|
})
|
|
883
910
|
```
|
|
884
911
|
|
|
@@ -898,13 +925,18 @@ Webhook payloads have the following shape:
|
|
|
898
925
|
// List all webhooks
|
|
899
926
|
const webhooks = await client.webhook.list()
|
|
900
927
|
|
|
928
|
+
// Update a webhook's event subscriptions
|
|
929
|
+
await client.webhook.update('webhook-id', {
|
|
930
|
+
events: ['onramp.updated', 'achDebitReturn.created', 'achDebitReturn.updated'],
|
|
931
|
+
})
|
|
932
|
+
|
|
901
933
|
// Delete a webhook
|
|
902
934
|
await client.webhook.delete('webhook-id')
|
|
903
935
|
```
|
|
904
936
|
|
|
905
937
|
### Security and Signing
|
|
906
938
|
|
|
907
|
-
Webhook requests are signed with HMAC SHA256 using your webhook secret. The signature is sent in the `Signature` HTTP header.
|
|
939
|
+
Webhook requests are signed with HMAC SHA256 using your webhook secret. The signature is sent in the `Signature` HTTP header. Verify the signature against the raw request body before parsing JSON.
|
|
908
940
|
|
|
909
941
|
#### Setting a Webhook Secret
|
|
910
942
|
|
|
@@ -915,11 +947,19 @@ await client.webhook.updateWebhookSecret('your-secret')
|
|
|
915
947
|
#### Verifying Signatures
|
|
916
948
|
|
|
917
949
|
```typescript
|
|
918
|
-
import { createHmac } from 'crypto'
|
|
950
|
+
import { createHmac, timingSafeEqual } from 'node:crypto'
|
|
951
|
+
|
|
952
|
+
function verifySpritzWebhook(rawBody: string, signature: string, secret: string) {
|
|
953
|
+
const expected = createHmac('sha256', secret).update(rawBody).digest('hex')
|
|
954
|
+
const expectedBuffer = Buffer.from(expected, 'utf8')
|
|
955
|
+
const signatureBuffer = Buffer.from(signature, 'utf8')
|
|
919
956
|
|
|
920
|
-
|
|
957
|
+
if (expectedBuffer.length !== signatureBuffer.length) return false
|
|
958
|
+
return timingSafeEqual(expectedBuffer, signatureBuffer)
|
|
959
|
+
}
|
|
921
960
|
|
|
922
|
-
|
|
961
|
+
const signature = request.headers['signature']
|
|
962
|
+
if (!signature || !verifySpritzWebhook(rawBody, signature, WEBHOOK_SECRET)) {
|
|
923
963
|
throw new Error('Invalid webhook signature')
|
|
924
964
|
}
|
|
925
965
|
```
|