@closeloop/sdk 0.1.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.
@@ -0,0 +1,909 @@
1
+ /**
2
+ * Credit balance for a wallet and plan
3
+ */
4
+ interface CreditBalance {
5
+ /**
6
+ * Unique balance ID
7
+ */
8
+ id: string;
9
+ /**
10
+ * Wallet address of the balance owner
11
+ */
12
+ walletAddress: string;
13
+ /**
14
+ * Plan ID this balance is for
15
+ */
16
+ planId: string;
17
+ /**
18
+ * Plan name for display
19
+ */
20
+ planName: string;
21
+ /**
22
+ * Total credits purchased
23
+ */
24
+ totalCredits: number;
25
+ /**
26
+ * Credits consumed
27
+ */
28
+ usedCredits: number;
29
+ /**
30
+ * Remaining available credits
31
+ */
32
+ remainingCredits: number;
33
+ /**
34
+ * Whether the balance is active
35
+ */
36
+ isActive: boolean;
37
+ /**
38
+ * When the credits expire (if applicable)
39
+ */
40
+ expiresAt: string | null;
41
+ /**
42
+ * When the balance was created
43
+ */
44
+ createdAt: string;
45
+ /**
46
+ * When the balance was last updated
47
+ */
48
+ updatedAt: string;
49
+ }
50
+ /**
51
+ * Parameters for getting a specific balance
52
+ */
53
+ interface GetBalanceParams {
54
+ /**
55
+ * The wallet address of the user
56
+ */
57
+ walletAddress: string;
58
+ /**
59
+ * The plan ID to get balance for
60
+ */
61
+ planId: string;
62
+ }
63
+ /**
64
+ * Parameters for listing balances
65
+ */
66
+ interface ListBalancesParams {
67
+ /**
68
+ * The wallet address to get all balances for
69
+ */
70
+ walletAddress: string;
71
+ /**
72
+ * Only return active balances
73
+ */
74
+ activeOnly?: boolean;
75
+ /**
76
+ * Maximum number of results
77
+ */
78
+ limit?: number;
79
+ /**
80
+ * Cursor for pagination
81
+ */
82
+ cursor?: string;
83
+ }
84
+ /**
85
+ * Response from listing balances
86
+ */
87
+ interface ListBalancesResponse {
88
+ /**
89
+ * Array of credit balances
90
+ */
91
+ balances: CreditBalance[];
92
+ /**
93
+ * Cursor for next page (null if no more)
94
+ */
95
+ nextCursor: string | null;
96
+ /**
97
+ * Total count of balances
98
+ */
99
+ totalCount: number;
100
+ }
101
+ /**
102
+ * Credit transaction record
103
+ */
104
+ interface CreditTransaction {
105
+ /**
106
+ * Transaction ID
107
+ */
108
+ id: string;
109
+ /**
110
+ * Balance ID this transaction belongs to
111
+ */
112
+ balanceId: string;
113
+ /**
114
+ * Type of transaction
115
+ */
116
+ type: "PURCHASE" | "CONSUMPTION" | "REFUND" | "EXPIRATION";
117
+ /**
118
+ * Amount (positive for additions, negative for deductions)
119
+ */
120
+ amount: number;
121
+ /**
122
+ * Description of the transaction
123
+ */
124
+ description: string | null;
125
+ /**
126
+ * What consumed the credits (for CONSUMPTION type)
127
+ */
128
+ consumedBy: string | null;
129
+ /**
130
+ * Additional metadata
131
+ */
132
+ metadata: Record<string, unknown> | null;
133
+ /**
134
+ * When the transaction occurred
135
+ */
136
+ createdAt: string;
137
+ }
138
+ /**
139
+ * Parameters for listing transactions
140
+ */
141
+ interface ListTransactionsParams {
142
+ /**
143
+ * Balance ID to get transactions for
144
+ */
145
+ balanceId: string;
146
+ /**
147
+ * Filter by transaction type
148
+ */
149
+ type?: "PURCHASE" | "CONSUMPTION" | "REFUND" | "EXPIRATION";
150
+ /**
151
+ * Maximum number of results
152
+ */
153
+ limit?: number;
154
+ /**
155
+ * Cursor for pagination
156
+ */
157
+ cursor?: string;
158
+ }
159
+ /**
160
+ * Response from listing transactions
161
+ */
162
+ interface ListTransactionsResponse {
163
+ /**
164
+ * Array of transactions
165
+ */
166
+ transactions: CreditTransaction[];
167
+ /**
168
+ * Cursor for next page
169
+ */
170
+ nextCursor: string | null;
171
+ }
172
+ /**
173
+ * Aggregated stats for a wallet's credits
174
+ */
175
+ interface CreditStats {
176
+ /**
177
+ * Total credits across all balances
178
+ */
179
+ totalCredits: number;
180
+ /**
181
+ * Total credits used
182
+ */
183
+ totalUsed: number;
184
+ /**
185
+ * Total remaining credits
186
+ */
187
+ totalRemaining: number;
188
+ /**
189
+ * Number of active balances
190
+ */
191
+ activeBalances: number;
192
+ }
193
+
194
+ interface HttpClientOptions {
195
+ baseUrl: string;
196
+ apiKey: string;
197
+ timeout?: number;
198
+ }
199
+ interface RequestOptions {
200
+ method: "GET" | "POST" | "PUT" | "DELETE";
201
+ path: string;
202
+ body?: unknown;
203
+ headers?: Record<string, string>;
204
+ }
205
+ /**
206
+ * HTTP client for making requests to the CloseLoop API
207
+ */
208
+ declare class HttpClient {
209
+ private baseUrl;
210
+ private apiKey;
211
+ private timeout;
212
+ constructor(options: HttpClientOptions);
213
+ /**
214
+ * Make an HTTP request to the CloseLoop API
215
+ */
216
+ request<T>(options: RequestOptions): Promise<T>;
217
+ private handleErrorResponse;
218
+ }
219
+
220
+ /**
221
+ * Resource for querying credit balances and transaction history
222
+ */
223
+ declare class Balances {
224
+ private readonly http;
225
+ constructor(http: HttpClient);
226
+ /**
227
+ * Get a specific credit balance for a wallet and plan.
228
+ *
229
+ * @example
230
+ * ```typescript
231
+ * const balance = await client.balances.get({
232
+ * walletAddress: "0x1234...",
233
+ * planId: "plan_abc123"
234
+ * })
235
+ *
236
+ * if (balance) {
237
+ * console.log(`Credits: ${balance.remainingCredits}/${balance.totalCredits}`)
238
+ * }
239
+ * ```
240
+ *
241
+ * @returns The credit balance, or null if not found
242
+ * @throws {CloseLoopError} When input validation fails
243
+ */
244
+ get(params: GetBalanceParams): Promise<CreditBalance | null>;
245
+ /**
246
+ * List all credit balances for a wallet.
247
+ *
248
+ * @example
249
+ * ```typescript
250
+ * const { balances, nextCursor } = await client.balances.list({
251
+ * walletAddress: "0x1234...",
252
+ * activeOnly: true,
253
+ * limit: 10
254
+ * })
255
+ *
256
+ * for (const balance of balances) {
257
+ * console.log(`${balance.planName}: ${balance.remainingCredits} credits`)
258
+ * }
259
+ *
260
+ * // Paginate if needed
261
+ * if (nextCursor) {
262
+ * const nextPage = await client.balances.list({
263
+ * walletAddress: "0x1234...",
264
+ * cursor: nextCursor
265
+ * })
266
+ * }
267
+ * ```
268
+ *
269
+ * @throws {CloseLoopError} When input validation fails
270
+ */
271
+ list(params: ListBalancesParams): Promise<ListBalancesResponse>;
272
+ /**
273
+ * Get transaction history for a balance.
274
+ *
275
+ * @example
276
+ * ```typescript
277
+ * const { transactions } = await client.balances.transactions({
278
+ * balanceId: "bal_xyz",
279
+ * type: "CONSUMPTION",
280
+ * limit: 50
281
+ * })
282
+ *
283
+ * for (const tx of transactions) {
284
+ * console.log(`${tx.type}: ${tx.amount} - ${tx.description}`)
285
+ * }
286
+ * ```
287
+ *
288
+ * @throws {CloseLoopError} When input validation fails
289
+ */
290
+ transactions(params: ListTransactionsParams): Promise<ListTransactionsResponse>;
291
+ /**
292
+ * Get aggregated stats for a wallet's credits.
293
+ *
294
+ * @example
295
+ * ```typescript
296
+ * const stats = await client.balances.stats("0x1234...")
297
+ * console.log(`Total: ${stats.totalCredits}, Used: ${stats.totalUsed}`)
298
+ * ```
299
+ *
300
+ * @throws {CloseLoopError} When input validation fails
301
+ */
302
+ stats(walletAddress: string): Promise<CreditStats>;
303
+ /**
304
+ * Build URL query string from params, filtering out undefined values
305
+ */
306
+ private buildQueryString;
307
+ }
308
+
309
+ /**
310
+ * Parameters for verifying credits
311
+ */
312
+ interface VerifyCreditsParams {
313
+ /**
314
+ * The wallet address of the user
315
+ */
316
+ walletAddress: string;
317
+ /**
318
+ * The plan ID to check credits for
319
+ */
320
+ planId: string;
321
+ /**
322
+ * The number of credits required
323
+ */
324
+ amount: number;
325
+ }
326
+ /**
327
+ * Response from credit verification
328
+ */
329
+ interface VerifyCreditsResponse {
330
+ /**
331
+ * Whether the user has enough credits
332
+ */
333
+ hasEnoughCredits: boolean;
334
+ /**
335
+ * Current remaining credits
336
+ */
337
+ remainingCredits: number;
338
+ /**
339
+ * When the credits expire (if applicable)
340
+ */
341
+ expiresAt: string | null;
342
+ }
343
+ /**
344
+ * Parameters for consuming credits
345
+ */
346
+ interface ConsumeCreditsParams {
347
+ /**
348
+ * The wallet address of the user
349
+ */
350
+ walletAddress: string;
351
+ /**
352
+ * The plan ID to consume credits from
353
+ */
354
+ planId: string;
355
+ /**
356
+ * The number of credits to consume
357
+ */
358
+ amount: number;
359
+ /**
360
+ * Optional identifier for what consumed the credits
361
+ * (e.g., "ai-text-generation", "image-processing")
362
+ */
363
+ consumedBy?: string;
364
+ /**
365
+ * Optional metadata to attach to the transaction
366
+ */
367
+ metadata?: Record<string, unknown>;
368
+ /**
369
+ * Idempotency key to prevent duplicate consumption
370
+ */
371
+ idempotencyKey?: string;
372
+ }
373
+ /**
374
+ * Response from credit consumption
375
+ */
376
+ interface ConsumeCreditsResponse {
377
+ /**
378
+ * Whether the consumption was successful
379
+ */
380
+ success: boolean;
381
+ /**
382
+ * Remaining credits after consumption
383
+ */
384
+ remainingCredits: number;
385
+ /**
386
+ * Total credits used
387
+ */
388
+ usedCredits: number;
389
+ /**
390
+ * The transaction ID for this consumption
391
+ */
392
+ transactionId: string;
393
+ }
394
+ /**
395
+ * Parameters for batch credit consumption
396
+ */
397
+ interface BatchConsumeParams {
398
+ /**
399
+ * Array of consumption operations
400
+ */
401
+ operations: Array<{
402
+ walletAddress: string;
403
+ planId: string;
404
+ amount: number;
405
+ consumedBy?: string;
406
+ metadata?: Record<string, unknown>;
407
+ }>;
408
+ /**
409
+ * If true, fail the entire batch if any operation fails
410
+ */
411
+ atomic?: boolean;
412
+ }
413
+ /**
414
+ * Response from batch credit consumption
415
+ */
416
+ interface BatchConsumeResponse {
417
+ /**
418
+ * Results for each operation
419
+ */
420
+ results: Array<{
421
+ success: boolean;
422
+ remainingCredits?: number;
423
+ error?: string;
424
+ }>;
425
+ /**
426
+ * Number of successful operations
427
+ */
428
+ successCount: number;
429
+ /**
430
+ * Number of failed operations
431
+ */
432
+ failedCount: number;
433
+ }
434
+
435
+ /**
436
+ * Resource for credit verification and consumption operations
437
+ */
438
+ declare class Credits {
439
+ private readonly http;
440
+ constructor(http: HttpClient);
441
+ /**
442
+ * Verify if a user has enough credits without consuming them.
443
+ *
444
+ * @example
445
+ * ```typescript
446
+ * const result = await client.credits.verify({
447
+ * walletAddress: "0x1234...",
448
+ * planId: "plan_abc123",
449
+ * amount: 10
450
+ * })
451
+ *
452
+ * if (result.hasEnoughCredits) {
453
+ * // Proceed with service
454
+ * }
455
+ * ```
456
+ *
457
+ * @throws {CloseLoopError} When input validation fails
458
+ */
459
+ verify(params: VerifyCreditsParams): Promise<VerifyCreditsResponse>;
460
+ /**
461
+ * Consume credits from a user's balance.
462
+ *
463
+ * @example
464
+ * ```typescript
465
+ * const result = await client.credits.consume({
466
+ * walletAddress: "0x1234...",
467
+ * planId: "plan_abc123",
468
+ * amount: 1,
469
+ * consumedBy: "ai-generation",
470
+ * metadata: { requestId: "req_xyz" }
471
+ * })
472
+ *
473
+ * console.log(`Remaining: ${result.remainingCredits}`)
474
+ * ```
475
+ *
476
+ * @throws {InsufficientCreditsError} When user doesn't have enough credits
477
+ * @throws {CreditsExpiredError} When credits have expired
478
+ * @throws {CloseLoopError} When input validation fails
479
+ */
480
+ consume(params: ConsumeCreditsParams): Promise<ConsumeCreditsResponse>;
481
+ /**
482
+ * Verify and consume credits in a single atomic operation.
483
+ * This is useful when you want to ensure credits are available
484
+ * before consuming them, without race conditions.
485
+ *
486
+ * @example
487
+ * ```typescript
488
+ * try {
489
+ * const result = await client.credits.verifyAndConsume({
490
+ * walletAddress: "0x1234...",
491
+ * planId: "plan_abc123",
492
+ * amount: 5,
493
+ * consumedBy: "batch-processing"
494
+ * })
495
+ * // Credits were verified and consumed
496
+ * } catch (error) {
497
+ * if (error instanceof InsufficientCreditsError) {
498
+ * // Handle insufficient credits
499
+ * }
500
+ * }
501
+ * ```
502
+ *
503
+ * @throws {InsufficientCreditsError} When user doesn't have enough credits
504
+ * @throws {CreditsExpiredError} When credits have expired
505
+ * @throws {CloseLoopError} When input validation fails
506
+ */
507
+ verifyAndConsume(params: ConsumeCreditsParams): Promise<ConsumeCreditsResponse>;
508
+ /**
509
+ * Consume credits in batch.
510
+ *
511
+ * @example
512
+ * ```typescript
513
+ * const result = await client.credits.batchConsume({
514
+ * operations: [
515
+ * { walletAddress: "0x1234...", planId: "plan_a", amount: 1 },
516
+ * { walletAddress: "0x5678...", planId: "plan_b", amount: 2 }
517
+ * ],
518
+ * atomic: false // Allow partial success
519
+ * })
520
+ *
521
+ * console.log(`Success: ${result.successCount}, Failed: ${result.failedCount}`)
522
+ * ```
523
+ *
524
+ * @throws {CloseLoopError} When input validation fails
525
+ */
526
+ batchConsume(params: BatchConsumeParams): Promise<BatchConsumeResponse>;
527
+ /**
528
+ * Build consumption request body with sanitized metadata
529
+ */
530
+ private buildConsumeBody;
531
+ /**
532
+ * Build idempotency headers if key is provided
533
+ */
534
+ private buildIdempotencyHeaders;
535
+ /**
536
+ * Assert credits are available, throw typed errors if not
537
+ */
538
+ private assertCreditsAvailable;
539
+ }
540
+
541
+ /**
542
+ * Webhook event types
543
+ */
544
+ type WebhookEventType = "payment.success" | "credits.low" | "credits.expired";
545
+ /**
546
+ * Webhook event wrapper
547
+ */
548
+ interface WebhookEvent<T = WebhookPayload> {
549
+ /**
550
+ * Event type
551
+ */
552
+ type: WebhookEventType;
553
+ /**
554
+ * Unique event ID
555
+ */
556
+ id: string;
557
+ /**
558
+ * When the event was created
559
+ */
560
+ createdAt: string;
561
+ /**
562
+ * Event payload
563
+ */
564
+ data: T;
565
+ }
566
+ /**
567
+ * Payload for payment.success events
568
+ */
569
+ interface PaymentSuccessPayload {
570
+ /**
571
+ * Transaction ID
572
+ */
573
+ transactionId: string;
574
+ /**
575
+ * Plan ID that was purchased
576
+ */
577
+ planId: string;
578
+ /**
579
+ * Plan name
580
+ */
581
+ planName: string;
582
+ /**
583
+ * Payment amount in USDC
584
+ */
585
+ amount: number;
586
+ /**
587
+ * Number of API requests (for API access type)
588
+ */
589
+ requests: number | null;
590
+ /**
591
+ * Number of credits (for CREDIT access type)
592
+ */
593
+ creditAmount: number | null;
594
+ /**
595
+ * Blockchain transaction hash
596
+ */
597
+ transactionHash: string;
598
+ /**
599
+ * Wallet address of the payer
600
+ */
601
+ payerAddress: string;
602
+ /**
603
+ * Access type of the plan
604
+ */
605
+ accessType: string;
606
+ }
607
+ /**
608
+ * Payload for credits.low events
609
+ */
610
+ interface CreditsLowPayload {
611
+ /**
612
+ * Wallet address
613
+ */
614
+ walletAddress: string;
615
+ /**
616
+ * Plan ID
617
+ */
618
+ planId: string;
619
+ /**
620
+ * Remaining credits
621
+ */
622
+ remainingCredits: number;
623
+ /**
624
+ * Low balance threshold that triggered this event
625
+ */
626
+ threshold: number;
627
+ }
628
+ /**
629
+ * Payload for credits.expired events
630
+ */
631
+ interface CreditsExpiredPayload {
632
+ /**
633
+ * Wallet address
634
+ */
635
+ walletAddress: string;
636
+ /**
637
+ * Plan ID
638
+ */
639
+ planId: string;
640
+ /**
641
+ * Number of credits that expired
642
+ */
643
+ expiredCredits: number;
644
+ /**
645
+ * When the credits expired
646
+ */
647
+ expiresAt: string;
648
+ }
649
+ /**
650
+ * Union of all webhook payloads
651
+ */
652
+ type WebhookPayload = PaymentSuccessPayload | CreditsLowPayload | CreditsExpiredPayload;
653
+
654
+ /**
655
+ * Parameters for verifying a webhook
656
+ */
657
+ interface VerifyWebhookParams {
658
+ /**
659
+ * Raw request body as string or Buffer
660
+ */
661
+ payload: string | Buffer;
662
+ /**
663
+ * X-CloseLoop-Signature header value
664
+ */
665
+ signature: string;
666
+ /**
667
+ * Your webhook secret
668
+ */
669
+ secret: string;
670
+ }
671
+ /**
672
+ * Resource for webhook signature verification and event handling
673
+ */
674
+ declare class Webhooks {
675
+ /**
676
+ * Verify a webhook signature and parse the event.
677
+ *
678
+ * @example
679
+ * ```typescript
680
+ * // Express handler
681
+ * app.post("/webhook", (req, res) => {
682
+ * try {
683
+ * const event = client.webhooks.verify({
684
+ * payload: req.body,
685
+ * signature: req.headers["x-closeloop-signature"],
686
+ * secret: process.env.WEBHOOK_SECRET!
687
+ * })
688
+ *
689
+ * if (client.webhooks.isPaymentSuccess(event)) {
690
+ * const { creditAmount, payerAddress } = event.data
691
+ * // Handle credit purchase
692
+ * }
693
+ *
694
+ * res.json({ received: true })
695
+ * } catch (error) {
696
+ * res.status(400).json({ error: "Invalid signature" })
697
+ * }
698
+ * })
699
+ * ```
700
+ *
701
+ * @example
702
+ * ```typescript
703
+ * // Next.js App Router
704
+ * export async function POST(request: Request) {
705
+ * const payload = await request.text()
706
+ * const signature = request.headers.get("x-closeloop-signature")!
707
+ *
708
+ * const event = client.webhooks.verify({
709
+ * payload,
710
+ * signature,
711
+ * secret: process.env.WEBHOOK_SECRET!
712
+ * })
713
+ *
714
+ * // Handle event...
715
+ * return Response.json({ received: true })
716
+ * }
717
+ * ```
718
+ *
719
+ * @throws {CloseLoopError} When signature is invalid or payload is malformed
720
+ */
721
+ verify(params: VerifyWebhookParams): WebhookEvent;
722
+ /**
723
+ * Type guard for payment.success events
724
+ * Also validates the payload structure
725
+ *
726
+ * @example
727
+ * ```typescript
728
+ * if (client.webhooks.isPaymentSuccess(event)) {
729
+ * // TypeScript knows event.data is PaymentSuccessPayload
730
+ * console.log(event.data.creditAmount)
731
+ * }
732
+ * ```
733
+ */
734
+ isPaymentSuccess(event: WebhookEvent<WebhookPayload>): event is WebhookEvent<PaymentSuccessPayload>;
735
+ /**
736
+ * Type guard for credits.low events
737
+ * Also validates the payload structure
738
+ *
739
+ * @example
740
+ * ```typescript
741
+ * if (client.webhooks.isCreditsLow(event)) {
742
+ * // TypeScript knows event.data is CreditsLowPayload
743
+ * console.log(`Low balance: ${event.data.remainingCredits}`)
744
+ * }
745
+ * ```
746
+ */
747
+ isCreditsLow(event: WebhookEvent<WebhookPayload>): event is WebhookEvent<CreditsLowPayload>;
748
+ /**
749
+ * Type guard for credits.expired events
750
+ * Also validates the payload structure
751
+ *
752
+ * @example
753
+ * ```typescript
754
+ * if (client.webhooks.isCreditsExpired(event)) {
755
+ * // TypeScript knows event.data is CreditsExpiredPayload
756
+ * console.log(`Expired: ${event.data.expiredCredits} credits`)
757
+ * }
758
+ * ```
759
+ */
760
+ isCreditsExpired(event: WebhookEvent<WebhookPayload>): event is WebhookEvent<CreditsExpiredPayload>;
761
+ /**
762
+ * Validate that all required parameters are present
763
+ */
764
+ private validateRequiredParams;
765
+ /**
766
+ * Convert payload to string regardless of input type
767
+ */
768
+ private normalizePayload;
769
+ /**
770
+ * Verify HMAC signature or throw error
771
+ */
772
+ private verifySignatureOrThrow;
773
+ /**
774
+ * Parse JSON payload or throw error
775
+ */
776
+ private parseJsonOrThrow;
777
+ /**
778
+ * Validate event structure using Zod schema
779
+ */
780
+ private validateEventStructure;
781
+ }
782
+
783
+ /**
784
+ * Configuration options for the CloseLoop client
785
+ */
786
+ interface CloseLoopOptions {
787
+ /**
788
+ * Your CloseLoop API key.
789
+ * Get this from your CloseLoop dashboard.
790
+ */
791
+ apiKey: string;
792
+ /**
793
+ * Base URL for the CloseLoop API.
794
+ * Defaults to https://closeloop.app
795
+ */
796
+ baseUrl?: string;
797
+ /**
798
+ * Request timeout in milliseconds.
799
+ * Defaults to 30000 (30 seconds)
800
+ */
801
+ timeout?: number;
802
+ }
803
+ /**
804
+ * CloseLoop SDK client for credit billing integration.
805
+ *
806
+ * @example
807
+ * ```typescript
808
+ * import { CloseLoop } from "@closeloop/sdk"
809
+ *
810
+ * const client = new CloseLoop({
811
+ * apiKey: process.env.CLOSELOOP_API_KEY!
812
+ * })
813
+ *
814
+ * // Verify credits
815
+ * const verification = await client.credits.verify({
816
+ * walletAddress: "0x1234...",
817
+ * planId: "plan_abc123",
818
+ * amount: 1
819
+ * })
820
+ *
821
+ * if (verification.hasEnoughCredits) {
822
+ * // Process request...
823
+ *
824
+ * // Consume credit
825
+ * await client.credits.consume({
826
+ * walletAddress: "0x1234...",
827
+ * planId: "plan_abc123",
828
+ * amount: 1,
829
+ * consumedBy: "my-service"
830
+ * })
831
+ * }
832
+ * ```
833
+ */
834
+ declare class CloseLoop {
835
+ private httpClient;
836
+ /**
837
+ * Credit consumption and verification operations
838
+ */
839
+ readonly credits: Credits;
840
+ /**
841
+ * Credit balance queries
842
+ */
843
+ readonly balances: Balances;
844
+ /**
845
+ * Webhook signature verification utilities
846
+ */
847
+ readonly webhooks: Webhooks;
848
+ constructor(options: CloseLoopOptions);
849
+ }
850
+
851
+ /**
852
+ * Base error class for all CloseLoop SDK errors
853
+ */
854
+ declare class CloseLoopError extends Error {
855
+ code: string;
856
+ statusCode?: number | undefined;
857
+ details?: Record<string, unknown> | undefined;
858
+ constructor(message: string, code: string, statusCode?: number | undefined, details?: Record<string, unknown> | undefined);
859
+ }
860
+ /**
861
+ * Thrown when a user doesn't have enough credits for an operation
862
+ */
863
+ declare class InsufficientCreditsError extends CloseLoopError {
864
+ remainingCredits: number;
865
+ requiredCredits: number;
866
+ constructor(remainingCredits: number, requiredCredits: number);
867
+ }
868
+ /**
869
+ * Thrown when credits have expired
870
+ */
871
+ declare class CreditsExpiredError extends CloseLoopError {
872
+ expiresAt: Date;
873
+ constructor(expiresAt: Date);
874
+ }
875
+ /**
876
+ * Thrown when authentication fails (invalid API key)
877
+ */
878
+ declare class AuthenticationError extends CloseLoopError {
879
+ constructor(message?: string);
880
+ }
881
+ /**
882
+ * Thrown when rate limit is exceeded
883
+ */
884
+ declare class RateLimitError extends CloseLoopError {
885
+ retryAfter?: number | undefined;
886
+ constructor(retryAfter?: number | undefined);
887
+ }
888
+ /**
889
+ * Thrown when a network error occurs
890
+ */
891
+ declare class NetworkError extends CloseLoopError {
892
+ cause?: Error | undefined;
893
+ constructor(message: string, cause?: Error | undefined);
894
+ }
895
+ /**
896
+ * Thrown when a resource is not found
897
+ */
898
+ declare class NotFoundError extends CloseLoopError {
899
+ constructor(resource: string);
900
+ }
901
+ /**
902
+ * Thrown when input validation fails
903
+ */
904
+ declare class ValidationError extends CloseLoopError {
905
+ field?: string | undefined;
906
+ constructor(message: string, field?: string | undefined);
907
+ }
908
+
909
+ export { AuthenticationError as A, Balances as B, CloseLoop as C, type GetBalanceParams as G, InsufficientCreditsError as I, type ListBalancesParams as L, NetworkError as N, type PaymentSuccessPayload as P, RateLimitError as R, type VerifyWebhookParams as V, Webhooks as W, type CloseLoopOptions as a, Credits as b, CloseLoopError as c, CreditsExpiredError as d, NotFoundError as e, ValidationError as f, type VerifyCreditsParams as g, type VerifyCreditsResponse as h, type ConsumeCreditsParams as i, type ConsumeCreditsResponse as j, type BatchConsumeParams as k, type BatchConsumeResponse as l, type CreditBalance as m, type ListBalancesResponse as n, type CreditTransaction as o, type ListTransactionsParams as p, type ListTransactionsResponse as q, type CreditStats as r, type WebhookEventType as s, type WebhookEvent as t, type CreditsLowPayload as u, type CreditsExpiredPayload as v, type WebhookPayload as w };