@fundedfast/sdk 1.3.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +352 -0
  3. package/dist/cjs/client.d.ts +130 -0
  4. package/dist/cjs/client.d.ts.map +1 -0
  5. package/dist/cjs/client.js +362 -0
  6. package/dist/cjs/client.js.map +1 -0
  7. package/dist/cjs/index.d.ts +27 -0
  8. package/dist/cjs/index.d.ts.map +1 -0
  9. package/dist/cjs/index.js +33 -0
  10. package/dist/cjs/index.js.map +1 -0
  11. package/dist/cjs/package.json +1 -0
  12. package/dist/cjs/resources/admin.d.ts +597 -0
  13. package/dist/cjs/resources/admin.d.ts.map +1 -0
  14. package/dist/cjs/resources/admin.js +842 -0
  15. package/dist/cjs/resources/admin.js.map +1 -0
  16. package/dist/cjs/resources/public.d.ts +519 -0
  17. package/dist/cjs/resources/public.d.ts.map +1 -0
  18. package/dist/cjs/resources/public.js +588 -0
  19. package/dist/cjs/resources/public.js.map +1 -0
  20. package/dist/cjs/types.d.ts +651 -0
  21. package/dist/cjs/types.d.ts.map +1 -0
  22. package/dist/cjs/types.js +11 -0
  23. package/dist/cjs/types.js.map +1 -0
  24. package/dist/cjs/webhooks.d.ts +104 -0
  25. package/dist/cjs/webhooks.d.ts.map +1 -0
  26. package/dist/cjs/webhooks.js +199 -0
  27. package/dist/cjs/webhooks.js.map +1 -0
  28. package/dist/esm/client.d.ts +130 -0
  29. package/dist/esm/client.d.ts.map +1 -0
  30. package/dist/esm/client.js +355 -0
  31. package/dist/esm/client.js.map +1 -0
  32. package/dist/esm/index.d.ts +27 -0
  33. package/dist/esm/index.d.ts.map +1 -0
  34. package/dist/esm/index.js +26 -0
  35. package/dist/esm/index.js.map +1 -0
  36. package/dist/esm/resources/admin.d.ts +597 -0
  37. package/dist/esm/resources/admin.d.ts.map +1 -0
  38. package/dist/esm/resources/admin.js +816 -0
  39. package/dist/esm/resources/admin.js.map +1 -0
  40. package/dist/esm/resources/public.d.ts +519 -0
  41. package/dist/esm/resources/public.d.ts.map +1 -0
  42. package/dist/esm/resources/public.js +578 -0
  43. package/dist/esm/resources/public.js.map +1 -0
  44. package/dist/esm/types.d.ts +651 -0
  45. package/dist/esm/types.d.ts.map +1 -0
  46. package/dist/esm/types.js +10 -0
  47. package/dist/esm/types.js.map +1 -0
  48. package/dist/esm/webhooks.d.ts +104 -0
  49. package/dist/esm/webhooks.d.ts.map +1 -0
  50. package/dist/esm/webhooks.js +159 -0
  51. package/dist/esm/webhooks.js.map +1 -0
  52. package/package.json +72 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @fundedfast/sdk/webhooks - Webhook Signature Verification
3
+ *
4
+ * Helpers for verifying FAST webhook deliveries in your backend.
5
+ * FAST signs all webhook payloads with HMAC-SHA256 using your webhook secret.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { verifyWebhookSignature, parseWebhookEvent } from '@fundedfast/sdk/webhooks';
10
+ *
11
+ * app.post('/webhooks/fast', express.raw({ type: 'application/json' }), async (req, res) => {
12
+ * const signature = req.headers['x-webhook-signature'] as string;
13
+ * const rawBody = req.body.toString('utf-8'); // the raw bytes, not parsed JSON
14
+ *
15
+ * // It is async: without `await` the check is a Promise, always truthy, and
16
+ * // every request passes.
17
+ * if (!await verifyWebhookSignature(rawBody, signature, process.env.FAST_WEBHOOK_SECRET!)) {
18
+ * return res.status(401).send('Invalid signature');
19
+ * }
20
+ *
21
+ * const event = parseWebhookEvent(rawBody);
22
+ * switch (event.eventType) {
23
+ * case 'challenge.completed':
24
+ * handleChallengeCompleted(event.userId, event.data);
25
+ * break;
26
+ * case 'funded_account.revoked':
27
+ * handleRevocation(event.userId, event.data);
28
+ * break;
29
+ * }
30
+ *
31
+ * res.status(200).send({ received: true });
32
+ * });
33
+ * ```
34
+ *
35
+ * @module webhooks
36
+ */
37
+ import type { WebhookPayload, WebhookEventType } from './types.js';
38
+ /**
39
+ * Verify the HMAC-SHA256 signature of a webhook payload.
40
+ *
41
+ * Uses timing-safe comparison to prevent timing attacks.
42
+ * Works in Node.js (crypto module) and edge runtimes (Web Crypto API).
43
+ *
44
+ * @param rawBody - The raw request body as a string (NOT parsed JSON)
45
+ * @param signature - The X-Webhook-Signature header value
46
+ * @param secret - Your webhook secret (from tenant setup)
47
+ * @returns true if signature is valid
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * // Express with raw body parser
52
+ * app.use('/webhooks', express.raw({ type: 'application/json' }));
53
+ *
54
+ * app.post('/webhooks/fast', async (req, res) => {
55
+ * const rawBody = req.body.toString('utf-8');
56
+ * const sig = req.headers['x-webhook-signature'] as string;
57
+ *
58
+ * if (!await verifyWebhookSignature(rawBody, sig, WEBHOOK_SECRET)) {
59
+ * return res.status(401).json({ error: 'invalid_signature' });
60
+ * }
61
+ * // ... handle event
62
+ * });
63
+ * ```
64
+ */
65
+ export declare function verifyWebhookSignature(rawBody: string, signature: string, secret: string): Promise<boolean>;
66
+ /**
67
+ * Synchronous signature verification using Web Crypto (browser/edge compatible).
68
+ *
69
+ * NOTE: This is async because Web Crypto API is async.
70
+ * If you need sync verification in Node.js, import crypto directly:
71
+ *
72
+ * ```typescript
73
+ * import { createHmac, timingSafeEqual } from 'node:crypto';
74
+ * const expected = createHmac('sha256', secret).update(rawBody).digest('hex');
75
+ * const valid = timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(signature, 'hex'));
76
+ * ```
77
+ */
78
+ /**
79
+ * Parse a webhook event payload.
80
+ *
81
+ * @param rawBody - The raw request body as a string or parsed object
82
+ * @returns Typed webhook payload with eventId, eventType, userId, timestamp, and data
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const event = parseWebhookEvent(rawBody);
87
+ * console.log(event.eventType); // 'challenge.completed'
88
+ * console.log(event.data); // { challengeId: '...', balance: 105.50, ... }
89
+ * ```
90
+ */
91
+ export declare function parseWebhookEvent<T = Record<string, unknown>>(rawBody: string | Record<string, unknown>): WebhookPayload<T>;
92
+ /**
93
+ * Check if an event type is one of the challenge lifecycle events.
94
+ */
95
+ export declare function isChallengeEvent(eventType: WebhookEventType): boolean;
96
+ /**
97
+ * Check if an event type is one of the funded account lifecycle events.
98
+ */
99
+ export declare function isFundedAccountEvent(eventType: WebhookEventType): boolean;
100
+ /**
101
+ * Check if an event type is one of the user lifecycle events.
102
+ */
103
+ export declare function isUserEvent(eventType: WebhookEventType): boolean;
104
+ //# sourceMappingURL=webhooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/webhooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CAuClB;AAED;;;;;;;;;;;GAWG;AAIH;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAG3H;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAErE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAEzE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAEhE"}
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ /**
3
+ * @fundedfast/sdk/webhooks - Webhook Signature Verification
4
+ *
5
+ * Helpers for verifying FAST webhook deliveries in your backend.
6
+ * FAST signs all webhook payloads with HMAC-SHA256 using your webhook secret.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { verifyWebhookSignature, parseWebhookEvent } from '@fundedfast/sdk/webhooks';
11
+ *
12
+ * app.post('/webhooks/fast', express.raw({ type: 'application/json' }), async (req, res) => {
13
+ * const signature = req.headers['x-webhook-signature'] as string;
14
+ * const rawBody = req.body.toString('utf-8'); // the raw bytes, not parsed JSON
15
+ *
16
+ * // It is async: without `await` the check is a Promise, always truthy, and
17
+ * // every request passes.
18
+ * if (!await verifyWebhookSignature(rawBody, signature, process.env.FAST_WEBHOOK_SECRET!)) {
19
+ * return res.status(401).send('Invalid signature');
20
+ * }
21
+ *
22
+ * const event = parseWebhookEvent(rawBody);
23
+ * switch (event.eventType) {
24
+ * case 'challenge.completed':
25
+ * handleChallengeCompleted(event.userId, event.data);
26
+ * break;
27
+ * case 'funded_account.revoked':
28
+ * handleRevocation(event.userId, event.data);
29
+ * break;
30
+ * }
31
+ *
32
+ * res.status(200).send({ received: true });
33
+ * });
34
+ * ```
35
+ *
36
+ * @module webhooks
37
+ */
38
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
39
+ if (k2 === undefined) k2 = k;
40
+ var desc = Object.getOwnPropertyDescriptor(m, k);
41
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
42
+ desc = { enumerable: true, get: function() { return m[k]; } };
43
+ }
44
+ Object.defineProperty(o, k2, desc);
45
+ }) : (function(o, m, k, k2) {
46
+ if (k2 === undefined) k2 = k;
47
+ o[k2] = m[k];
48
+ }));
49
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
50
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
51
+ }) : function(o, v) {
52
+ o["default"] = v;
53
+ });
54
+ var __importStar = (this && this.__importStar) || (function () {
55
+ var ownKeys = function(o) {
56
+ ownKeys = Object.getOwnPropertyNames || function (o) {
57
+ var ar = [];
58
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
59
+ return ar;
60
+ };
61
+ return ownKeys(o);
62
+ };
63
+ return function (mod) {
64
+ if (mod && mod.__esModule) return mod;
65
+ var result = {};
66
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
67
+ __setModuleDefault(result, mod);
68
+ return result;
69
+ };
70
+ })();
71
+ Object.defineProperty(exports, "__esModule", { value: true });
72
+ exports.verifyWebhookSignature = verifyWebhookSignature;
73
+ exports.parseWebhookEvent = parseWebhookEvent;
74
+ exports.isChallengeEvent = isChallengeEvent;
75
+ exports.isFundedAccountEvent = isFundedAccountEvent;
76
+ exports.isUserEvent = isUserEvent;
77
+ /**
78
+ * Verify the HMAC-SHA256 signature of a webhook payload.
79
+ *
80
+ * Uses timing-safe comparison to prevent timing attacks.
81
+ * Works in Node.js (crypto module) and edge runtimes (Web Crypto API).
82
+ *
83
+ * @param rawBody - The raw request body as a string (NOT parsed JSON)
84
+ * @param signature - The X-Webhook-Signature header value
85
+ * @param secret - Your webhook secret (from tenant setup)
86
+ * @returns true if signature is valid
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * // Express with raw body parser
91
+ * app.use('/webhooks', express.raw({ type: 'application/json' }));
92
+ *
93
+ * app.post('/webhooks/fast', async (req, res) => {
94
+ * const rawBody = req.body.toString('utf-8');
95
+ * const sig = req.headers['x-webhook-signature'] as string;
96
+ *
97
+ * if (!await verifyWebhookSignature(rawBody, sig, WEBHOOK_SECRET)) {
98
+ * return res.status(401).json({ error: 'invalid_signature' });
99
+ * }
100
+ * // ... handle event
101
+ * });
102
+ * ```
103
+ */
104
+ async function verifyWebhookSignature(rawBody, signature, secret) {
105
+ if (!rawBody || !signature || !secret)
106
+ return false;
107
+ // SHA-256 hex is exactly 64 hex characters. Anything else is not a signature
108
+ // FAST produced; refuse it before parsing rather than let parseInt guess.
109
+ if (typeof signature !== 'string' || !/^[0-9a-f]{64}$/i.test(signature))
110
+ return false;
111
+ signature = signature.toLowerCase();
112
+ // Try Node.js crypto first (fastest path)
113
+ try {
114
+ const crypto = await Promise.resolve().then(() => __importStar(require('node:crypto')));
115
+ const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
116
+ if (expected.length !== signature.length)
117
+ return false;
118
+ const a = new Uint8Array(expected.length / 2);
119
+ const b = new Uint8Array(signature.length / 2);
120
+ for (let i = 0; i < a.length; i++) {
121
+ a[i] = parseInt(expected.slice(i * 2, i * 2 + 2), 16);
122
+ b[i] = parseInt(signature.slice(i * 2, i * 2 + 2), 16);
123
+ }
124
+ return crypto.timingSafeEqual(a, b);
125
+ }
126
+ catch {
127
+ // Not in Node.js - fall through to Web Crypto
128
+ }
129
+ // Web Crypto API (edge runtimes, Deno, Bun, Cloudflare Workers)
130
+ try {
131
+ const encoder = new TextEncoder();
132
+ const key = await crypto.subtle.importKey('raw', encoder.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
133
+ const sig = await crypto.subtle.sign('HMAC', key, encoder.encode(rawBody));
134
+ const expected = Array.from(new Uint8Array(sig)).map(b => b.toString(16).padStart(2, '0')).join('');
135
+ return timingSafeCompare(expected, signature);
136
+ }
137
+ catch {
138
+ return false;
139
+ }
140
+ }
141
+ /**
142
+ * Synchronous signature verification using Web Crypto (browser/edge compatible).
143
+ *
144
+ * NOTE: This is async because Web Crypto API is async.
145
+ * If you need sync verification in Node.js, import crypto directly:
146
+ *
147
+ * ```typescript
148
+ * import { createHmac, timingSafeEqual } from 'node:crypto';
149
+ * const expected = createHmac('sha256', secret).update(rawBody).digest('hex');
150
+ * const valid = timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(signature, 'hex'));
151
+ * ```
152
+ */
153
+ // Re-export verifyWebhookSignature as the primary API - it works everywhere.
154
+ /**
155
+ * Parse a webhook event payload.
156
+ *
157
+ * @param rawBody - The raw request body as a string or parsed object
158
+ * @returns Typed webhook payload with eventId, eventType, userId, timestamp, and data
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * const event = parseWebhookEvent(rawBody);
163
+ * console.log(event.eventType); // 'challenge.completed'
164
+ * console.log(event.data); // { challengeId: '...', balance: 105.50, ... }
165
+ * ```
166
+ */
167
+ function parseWebhookEvent(rawBody) {
168
+ const parsed = typeof rawBody === 'string' ? JSON.parse(rawBody) : rawBody;
169
+ return parsed;
170
+ }
171
+ /**
172
+ * Check if an event type is one of the challenge lifecycle events.
173
+ */
174
+ function isChallengeEvent(eventType) {
175
+ return eventType.startsWith('challenge.');
176
+ }
177
+ /**
178
+ * Check if an event type is one of the funded account lifecycle events.
179
+ */
180
+ function isFundedAccountEvent(eventType) {
181
+ return eventType.startsWith('funded_account.');
182
+ }
183
+ /**
184
+ * Check if an event type is one of the user lifecycle events.
185
+ */
186
+ function isUserEvent(eventType) {
187
+ return eventType.startsWith('user.');
188
+ }
189
+ // ---- Internals ----
190
+ function timingSafeCompare(a, b) {
191
+ if (a.length !== b.length)
192
+ return false;
193
+ let result = 0;
194
+ for (let i = 0; i < a.length; i++) {
195
+ result |= a.charCodeAt(i) ^ b.charCodeAt(i);
196
+ }
197
+ return result === 0;
198
+ }
199
+ //# sourceMappingURL=webhooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/webhooks.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BH,wDA2CC;AA8BD,8CAGC;AAKD,4CAEC;AAKD,oDAEC;AAKD,kCAEC;AA5HD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACI,KAAK,UAAU,sBAAsB,CAC1C,OAAe,EACf,SAAiB,EACjB,MAAc;IAEd,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACpD,6EAA6E;IAC7E,0EAA0E;IAC1E,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC;QAAE,OAAO,KAAK,CAAC;IACtF,SAAS,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;IAEpC,0CAA0C;IAC1C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,wDAAa,aAAa,GAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnF,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QACvD,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtD,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,8CAA8C;IAChD,CAAC;IAED,gEAAgE;IAChE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CACvC,KAAK,EACL,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EACtB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EACjC,KAAK,EACL,CAAC,MAAM,CAAC,CACT,CAAC;QACF,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3E,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpG,OAAO,iBAAiB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AAEH,6EAA6E;AAE7E;;;;;;;;;;;;GAYG;AACH,SAAgB,iBAAiB,CAA8B,OAAyC;IACtG,MAAM,MAAM,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC3E,OAAO,MAA2B,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,SAA2B;IAC1D,OAAO,SAAS,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAAC,SAA2B;IAC9D,OAAO,SAAS,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,SAA2B;IACrD,OAAO,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,sBAAsB;AAEtB,SAAS,iBAAiB,CAAC,CAAS,EAAE,CAAS;IAC7C,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,MAAM,KAAK,CAAC,CAAC;AACtB,CAAC"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * @fundedfast/sdk - Client
3
+ *
4
+ * Production-grade HTTP client for the FAST platform API.
5
+ * Features: automatic retries with exponential backoff, rate limit awareness,
6
+ * request/response hooks, idempotency support, debug logging, and proper error handling.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { FastClient } from '@fundedfast/sdk';
11
+ *
12
+ * const fast = new FastClient({
13
+ * apiKey: process.env.FAST_API_KEY!,
14
+ * retry: { maxRetries: 3 },
15
+ * onResponse: ({ status, durationMs, correlationId }) => {
16
+ * metrics.histogram('fast.request.duration', durationMs, { status });
17
+ * },
18
+ * });
19
+ *
20
+ * const result = await fast.bets.validate({
21
+ * userId: 'player-42',
22
+ * externalBetId: 'BET-001',
23
+ * stakeAmount: 5.00,
24
+ * odds: 2.10,
25
+ * status: 'placed',
26
+ * });
27
+ * ```
28
+ *
29
+ * @module client
30
+ */
31
+ import type { FastClientConfig, FastError } from './types.js';
32
+ import { ChallengesApi, BetsApi, UsersApi, ReconciliationApi, EventsApi, SandboxApi, WidgetApi } from './resources/public.js';
33
+ import { AdminApi } from './resources/admin.js';
34
+ export declare const SDK_VERSION = "1.3.0";
35
+ /**
36
+ * Error thrown when the FAST API returns a non-2xx response.
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * try {
41
+ * await fast.challenges.purchase({ userId: 'x', challengeTierId: 'invalid' });
42
+ * } catch (err) {
43
+ * if (err instanceof FastApiError) {
44
+ * console.log(err.status); // 400
45
+ * console.log(err.code); // 'validation_error'
46
+ * console.log(err.correlationId); // 'abc-123' (for support)
47
+ * console.log(err.isRetryable); // false
48
+ * }
49
+ * }
50
+ * ```
51
+ */
52
+ export declare class FastApiError extends Error {
53
+ readonly status: number;
54
+ readonly code: string;
55
+ readonly correlationId: string;
56
+ readonly isRetryable: boolean;
57
+ readonly rateLimitReset?: number;
58
+ constructor(status: number, body: FastError, rateLimitReset?: number);
59
+ }
60
+ /**
61
+ * Error thrown when a request times out.
62
+ */
63
+ export declare class FastTimeoutError extends Error {
64
+ readonly timeoutMs: number;
65
+ constructor(timeoutMs: number);
66
+ }
67
+ /**
68
+ * Error thrown when a network error occurs (DNS, connection refused, etc.)
69
+ */
70
+ export declare class FastNetworkError extends Error {
71
+ readonly cause: Error;
72
+ constructor(cause: Error);
73
+ }
74
+ /**
75
+ * FAST Platform API client.
76
+ *
77
+ * Provides typed access to all operator-facing endpoints with automatic retry,
78
+ * rate limit handling, and observability hooks.
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * const fast = new FastClient({ apiKey: 'key-...' });
83
+ *
84
+ * // Namespaced APIs
85
+ * const tiers = await fast.challenges.listTiers();
86
+ * const result = await fast.bets.validate(betEvent);
87
+ * const progress = await fast.users.getProgress('player-42');
88
+ * ```
89
+ */
90
+ export declare class FastClient {
91
+ private readonly baseUrl;
92
+ private readonly apiKey;
93
+ private readonly timeout;
94
+ private readonly retryConfig;
95
+ private readonly onRequest?;
96
+ private readonly onResponse?;
97
+ private readonly _fetch;
98
+ private readonly customHeaders;
99
+ private readonly debug;
100
+ /** Challenge purchase and tier management */
101
+ readonly challenges: ChallengesApi;
102
+ /** Bet validation and ingestion */
103
+ readonly bets: BetsApi;
104
+ /** User progress, history, and withdrawals */
105
+ readonly users: UsersApi;
106
+ /** Bet event reconciliation */
107
+ readonly reconciliation: ReconciliationApi;
108
+ /** Real-time event streaming (SSE) */
109
+ readonly events: EventsApi;
110
+ /** Sandbox operations (staging only) */
111
+ readonly sandbox: SandboxApi;
112
+ /** Widget module and branding configuration */
113
+ readonly widget: WidgetApi;
114
+ /** Admin / backoffice operations (tenant management) */
115
+ readonly admin: AdminApi;
116
+ constructor(config: FastClientConfig);
117
+ /**
118
+ * Execute an authenticated request against the FAST API.
119
+ * Handles retries, timeouts, rate limits, and hooks automatically.
120
+ *
121
+ * @internal Use the namespaced APIs (challenges, bets, users, etc.) instead.
122
+ */
123
+ request<T>(method: string, path: string, options?: {
124
+ body?: unknown;
125
+ query?: Record<string, string | undefined>;
126
+ idempotencyKey?: string;
127
+ }): Promise<T>;
128
+ private calculateDelay;
129
+ }
130
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,SAAS,EAIV,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,OAAO,EACP,QAAQ,EACR,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,SAAS,EACV,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQhD,eAAO,MAAM,WAAW,UAAU,CAAC;AAgCnC;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,aAAa,EAAE,MAAM,CAAC;IACtC,SAAgB,WAAW,EAAE,OAAO,CAAC;IACrC,SAAgB,cAAc,CAAC,EAAE,MAAM,CAAC;gBAE5B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM;CASrE;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,SAAgB,SAAS,EAAE,MAAM,CAAC;gBAEtB,SAAS,EAAE,MAAM;CAK9B;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,SAAgB,KAAK,EAAE,KAAK,CAAC;gBAEjB,KAAK,EAAE,KAAK;CAKzB;AAMD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAe;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IACvD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAEhC,6CAA6C;IAC7C,SAAgB,UAAU,EAAE,aAAa,CAAC;IAC1C,mCAAmC;IACnC,SAAgB,IAAI,EAAE,OAAO,CAAC;IAC9B,8CAA8C;IAC9C,SAAgB,KAAK,EAAE,QAAQ,CAAC;IAChC,+BAA+B;IAC/B,SAAgB,cAAc,EAAE,iBAAiB,CAAC;IAClD,sCAAsC;IACtC,SAAgB,MAAM,EAAE,SAAS,CAAC;IAClC,wCAAwC;IACxC,SAAgB,OAAO,EAAE,UAAU,CAAC;IACpC,+CAA+C;IAC/C,SAAgB,MAAM,EAAE,SAAS,CAAC;IAClC,wDAAwD;IACxD,SAAgB,KAAK,EAAE,QAAQ,CAAC;gBAEpB,MAAM,EAAE,gBAAgB;IAwCpC;;;;;OAKG;IACG,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;QAC3C,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GACA,OAAO,CAAC,CAAC,CAAC;IAgKb,OAAO,CAAC,cAAc;CASvB"}