@zendfi/sdk 0.8.4 → 1.0.1
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 +45 -437
- package/dist/chunk-DAJL2Q36.mjs +907 -0
- package/dist/express.d.mts +1 -1
- package/dist/express.d.ts +1 -1
- package/dist/helpers/index.d.mts +402 -0
- package/dist/helpers/index.d.ts +402 -0
- package/dist/helpers/index.js +944 -0
- package/dist/helpers/index.mjs +17 -0
- package/dist/index.d.mts +468 -3121
- package/dist/index.d.ts +468 -3121
- package/dist/index.js +421 -4020
- package/dist/index.mjs +1188 -5267
- package/dist/nextjs.d.mts +1 -1
- package/dist/nextjs.d.ts +1 -1
- package/dist/webhook-handler-61UWBtDI.d.mts +339 -0
- package/dist/webhook-handler-61UWBtDI.d.ts +339 -0
- package/package.json +19 -15
- package/README.md.old +0 -326
- package/dist/cache-T5YPC7OK.mjs +0 -9
- package/dist/chunk-5O5NAX65.mjs +0 -366
- package/dist/webhook-handler-CdtQHVU5.d.mts +0 -1130
- package/dist/webhook-handler-CdtQHVU5.d.ts +0 -1130
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
3
|
-
|
|
1
|
+
import { Z as ZendFiConfig, C as CreatePaymentRequest, P as Payment, b as CreateSubscriptionPlanRequest, S as SubscriptionPlan, c as CreateSubscriptionRequest, d as Subscription, e as CreatePaymentLinkRequest, f as PaymentLink, g as CreateInstallmentPlanRequest, I as InstallmentPlan, h as CreateInvoiceRequest, i as Invoice, V as VerifyWebhookRequest, j as WebhookPayload, A as ApiKeyMode } from './webhook-handler-61UWBtDI.mjs';
|
|
2
|
+
export { B as Brand, R as CreateInstallmentPlanResponse, y as Currency, E as Environment, q as InstallmentPlanId, G as InstallmentPlanStatus, Q as InstallmentScheduleItem, n as InvoiceId, T as InvoiceLineItem, H as InvoiceStatus, N as ListPaymentsRequest, M as MerchantId, O as PaginatedResponse, m as PaymentId, r as PaymentLinkCode, D as PaymentStatus, z as PaymentToken, L as SplitRecipient, J as SplitStatus, o as SubscriptionId, F as SubscriptionStatus, K as WebhookEvent, l as WebhookEventHandler, W as WebhookHandlerConfig, a as WebhookHandlers, k as WebhookResult, w as asInstallmentPlanId, u as asInvoiceId, t as asMerchantId, s as asPaymentId, x as asPaymentLinkCode, v as asSubscriptionId, p as processWebhook } from './webhook-handler-61UWBtDI.mjs';
|
|
3
|
+
export { ConnectedWallet, DevTools, MockWallet, PerformanceMonitor, PollingOptions, TestSessionKey, TransactionMonitor, TransactionPoller, TransactionStatus, WalletConnector, createWalletHook } from './helpers/index.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Request/Response Interceptor System
|
|
@@ -59,3316 +59,663 @@ interface Interceptors {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* @example
|
|
65
|
-
* ```typescript
|
|
66
|
-
* // Create an agent API key
|
|
67
|
-
* const agentKey = await zendfi.agent.createKey({
|
|
68
|
-
* name: 'Shopping Assistant',
|
|
69
|
-
* agent_id: 'shopping-assistant-v1',
|
|
70
|
-
* scopes: ['create_payments', 'read_analytics'],
|
|
71
|
-
* rate_limit_per_hour: 1000,
|
|
72
|
-
* });
|
|
73
|
-
*
|
|
74
|
-
* // Create an agent session with spending limits
|
|
75
|
-
* const session = await zendfi.agent.createSession({
|
|
76
|
-
* agent_id: 'shopping-assistant-v1',
|
|
77
|
-
* user_wallet: 'Hx7B...abc',
|
|
78
|
-
* limits: {
|
|
79
|
-
* max_per_transaction: 100,
|
|
80
|
-
* max_per_day: 500,
|
|
81
|
-
* },
|
|
82
|
-
* duration_hours: 24,
|
|
83
|
-
* });
|
|
84
|
-
* ```
|
|
62
|
+
* ZendFi SDK Client.
|
|
63
|
+
* Zero-config TypeScript SDK for crypto payments
|
|
85
64
|
*/
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
constructor(request: RequestFn$5);
|
|
65
|
+
declare class ZendFiClient {
|
|
66
|
+
private config;
|
|
67
|
+
readonly interceptors: Interceptors;
|
|
68
|
+
constructor(options?: Partial<ZendFiConfig>);
|
|
91
69
|
/**
|
|
92
|
-
* Create a new
|
|
93
|
-
*
|
|
94
|
-
* Agent keys (prefixed with `zai_`) have limited permissions compared to
|
|
95
|
-
* merchant keys. This enables safe delegation to AI agents.
|
|
96
|
-
*
|
|
97
|
-
* @param request - Agent key configuration
|
|
98
|
-
* @returns The created agent key (full_key only returned on creation!)
|
|
99
|
-
*
|
|
100
|
-
* @example
|
|
101
|
-
* ```typescript
|
|
102
|
-
* const agentKey = await zendfi.agent.createKey({
|
|
103
|
-
* name: 'Shopping Assistant',
|
|
104
|
-
* agent_id: 'shopping-assistant-v1',
|
|
105
|
-
* scopes: ['create_payments'],
|
|
106
|
-
* rate_limit_per_hour: 500,
|
|
107
|
-
* });
|
|
108
|
-
*
|
|
109
|
-
* // IMPORTANT: Save the full_key now - it won't be shown again!
|
|
110
|
-
* console.log(agentKey.full_key); // => "zai_test_abc123..."
|
|
111
|
-
* ```
|
|
70
|
+
* Create a new payment
|
|
112
71
|
*/
|
|
113
|
-
|
|
72
|
+
createPayment(request: CreatePaymentRequest): Promise<Payment>;
|
|
114
73
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* @returns Array of agent API keys (without full_key for security)
|
|
118
|
-
*
|
|
119
|
-
* @example
|
|
120
|
-
* ```typescript
|
|
121
|
-
* const keys = await zendfi.agent.listKeys();
|
|
122
|
-
* keys.forEach(key => {
|
|
123
|
-
* console.log(`${key.name}: ${key.key_prefix}*** (${key.scopes.join(', ')})`);
|
|
124
|
-
* });
|
|
125
|
-
* ```
|
|
74
|
+
* Get payment by ID
|
|
126
75
|
*/
|
|
127
|
-
|
|
76
|
+
getPayment(paymentId: string): Promise<Payment>;
|
|
128
77
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* Once revoked, the key cannot be used for any API calls.
|
|
132
|
-
* This action is irreversible.
|
|
133
|
-
*
|
|
134
|
-
* @param keyId - UUID of the agent key to revoke
|
|
135
|
-
*
|
|
136
|
-
* @example
|
|
137
|
-
* ```typescript
|
|
138
|
-
* await zendfi.agent.revokeKey('ak_123...');
|
|
139
|
-
* console.log('Agent key revoked');
|
|
140
|
-
* ```
|
|
78
|
+
* Create a subscription plan
|
|
141
79
|
*/
|
|
142
|
-
|
|
80
|
+
createSubscriptionPlan(request: CreateSubscriptionPlanRequest): Promise<SubscriptionPlan>;
|
|
143
81
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* Sessions provide time-bounded authorization for agents to make payments
|
|
147
|
-
* on behalf of users, with configurable spending limits.
|
|
148
|
-
*
|
|
149
|
-
* @param request - Session configuration
|
|
150
|
-
* @returns The created session with token
|
|
151
|
-
*
|
|
152
|
-
* @example
|
|
153
|
-
* ```typescript
|
|
154
|
-
* const session = await zendfi.agent.createSession({
|
|
155
|
-
* agent_id: 'shopping-assistant-v1',
|
|
156
|
-
* agent_name: 'Shopping Assistant',
|
|
157
|
-
* user_wallet: 'Hx7B...abc',
|
|
158
|
-
* limits: {
|
|
159
|
-
* max_per_transaction: 100,
|
|
160
|
-
* max_per_day: 500,
|
|
161
|
-
* require_approval_above: 50,
|
|
162
|
-
* },
|
|
163
|
-
* duration_hours: 24,
|
|
164
|
-
* });
|
|
165
|
-
*
|
|
166
|
-
* // Use session_token for subsequent API calls
|
|
167
|
-
* console.log(session.session_token); // => "zai_session_..."
|
|
168
|
-
* ```
|
|
82
|
+
* Get subscription plan by ID
|
|
169
83
|
*/
|
|
170
|
-
|
|
84
|
+
getSubscriptionPlan(planId: string): Promise<SubscriptionPlan>;
|
|
171
85
|
/**
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* @returns Array of agent sessions (both active and expired)
|
|
175
|
-
*
|
|
176
|
-
* @example
|
|
177
|
-
* ```typescript
|
|
178
|
-
* const sessions = await zendfi.agent.listSessions();
|
|
179
|
-
* const activeSessions = sessions.filter(s => s.is_active);
|
|
180
|
-
* console.log(`${activeSessions.length} active sessions`);
|
|
181
|
-
* ```
|
|
86
|
+
* Create a subscription
|
|
182
87
|
*/
|
|
183
|
-
|
|
88
|
+
createSubscription(request: CreateSubscriptionRequest): Promise<Subscription>;
|
|
184
89
|
/**
|
|
185
|
-
* Get
|
|
186
|
-
*
|
|
187
|
-
* @param sessionId - UUID of the session
|
|
188
|
-
* @returns The session details with remaining limits
|
|
189
|
-
*
|
|
190
|
-
* @example
|
|
191
|
-
* ```typescript
|
|
192
|
-
* const session = await zendfi.agent.getSession('sess_123...');
|
|
193
|
-
* console.log(`Remaining today: $${session.remaining_today}`);
|
|
194
|
-
* console.log(`Expires: ${session.expires_at}`);
|
|
195
|
-
* ```
|
|
90
|
+
* Get subscription by ID
|
|
196
91
|
*/
|
|
197
|
-
|
|
92
|
+
getSubscription(subscriptionId: string): Promise<Subscription>;
|
|
198
93
|
/**
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* Immediately invalidates the session, preventing any further payments.
|
|
202
|
-
* This action is irreversible.
|
|
203
|
-
*
|
|
204
|
-
* @param sessionId - UUID of the session to revoke
|
|
205
|
-
*
|
|
206
|
-
* @example
|
|
207
|
-
* ```typescript
|
|
208
|
-
* await zendfi.agent.revokeSession('sess_123...');
|
|
209
|
-
* console.log('Session revoked - agent can no longer make payments');
|
|
210
|
-
* ```
|
|
94
|
+
* Cancel a subscription
|
|
211
95
|
*/
|
|
212
|
-
|
|
96
|
+
cancelSubscription(subscriptionId: string): Promise<Subscription>;
|
|
213
97
|
/**
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
* This is the primary method for AI agents to make payments. It uses the
|
|
217
|
-
* session token to enforce spending limits and automatically routes the
|
|
218
|
-
* payment through the optimal path.
|
|
219
|
-
*
|
|
220
|
-
* The session token comes from `createSession()` and enforces:
|
|
221
|
-
* - Per-transaction limits
|
|
222
|
-
* - Daily limits
|
|
223
|
-
* - Weekly limits
|
|
224
|
-
* - Monthly limits
|
|
225
|
-
*
|
|
226
|
-
* @param request - Payment request with session token
|
|
227
|
-
* @returns Payment result with status and receipt
|
|
228
|
-
*
|
|
229
|
-
* @example
|
|
230
|
-
* ```typescript
|
|
231
|
-
* // Create a session first
|
|
232
|
-
* const session = await zendfi.agent.createSession({
|
|
233
|
-
* agent_id: 'shopping-bot',
|
|
234
|
-
* user_wallet: 'Hx7B...abc',
|
|
235
|
-
* limits: {
|
|
236
|
-
* max_per_transaction: 50,
|
|
237
|
-
* max_per_day: 200,
|
|
238
|
-
* },
|
|
239
|
-
* duration_hours: 24,
|
|
240
|
-
* });
|
|
241
|
-
*
|
|
242
|
-
* // Make payments within the session limits
|
|
243
|
-
* const payment = await zendfi.agent.pay({
|
|
244
|
-
* session_token: session.session_token,
|
|
245
|
-
* amount: 29.99,
|
|
246
|
-
* description: 'Premium widget',
|
|
247
|
-
* auto_gasless: true,
|
|
248
|
-
* });
|
|
249
|
-
*
|
|
250
|
-
* if (payment.requires_signature) {
|
|
251
|
-
* // Device-bound: user must sign
|
|
252
|
-
* console.log('Sign and submit to:', payment.submit_url);
|
|
253
|
-
* } else {
|
|
254
|
-
* // Auto-signed: payment complete
|
|
255
|
-
* console.log('Payment confirmed:', payment.transaction_signature);
|
|
256
|
-
* }
|
|
257
|
-
* ```
|
|
98
|
+
* Create a payment link (shareable checkout URL)
|
|
258
99
|
*/
|
|
259
|
-
|
|
100
|
+
createPaymentLink(request: CreatePaymentLinkRequest): Promise<PaymentLink>;
|
|
260
101
|
/**
|
|
261
|
-
* Get
|
|
262
|
-
*
|
|
263
|
-
* @returns Comprehensive analytics including payments, success rate, and PPP savings
|
|
264
|
-
*
|
|
265
|
-
* @example
|
|
266
|
-
* ```typescript
|
|
267
|
-
* const analytics = await zendfi.agent.getAnalytics();
|
|
268
|
-
* console.log(`Total volume: $${analytics.total_volume_usd}`);
|
|
269
|
-
* console.log(`Success rate: ${(analytics.success_rate * 100).toFixed(1)}%`);
|
|
270
|
-
* console.log(`PPP savings: $${analytics.ppp_savings_usd}`);
|
|
271
|
-
* ```
|
|
102
|
+
* Get payment link by link code
|
|
272
103
|
*/
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Payment Intents API - Two-phase payment flow
|
|
278
|
-
*
|
|
279
|
-
* Payment Intents provide a modern checkout experience with:
|
|
280
|
-
* - Create intent first (reserves amount)
|
|
281
|
-
* - Confirm when ready (completes payment)
|
|
282
|
-
* - Cancel if needed (releases hold)
|
|
283
|
-
*
|
|
284
|
-
* @example
|
|
285
|
-
* ```typescript
|
|
286
|
-
* // Step 1: Create intent when user starts checkout
|
|
287
|
-
* const intent = await zendfi.intents.create({
|
|
288
|
-
* amount: 99.99,
|
|
289
|
-
* description: 'Premium subscription',
|
|
290
|
-
* });
|
|
291
|
-
*
|
|
292
|
-
* // Step 2: Show payment form, collect wallet
|
|
293
|
-
* // ...
|
|
294
|
-
*
|
|
295
|
-
* // Step 3: Confirm when user clicks "Pay"
|
|
296
|
-
* const confirmed = await zendfi.intents.confirm(intent.id, {
|
|
297
|
-
* client_secret: intent.client_secret,
|
|
298
|
-
* customer_wallet: userWallet,
|
|
299
|
-
* });
|
|
300
|
-
* ```
|
|
301
|
-
*/
|
|
302
|
-
|
|
303
|
-
type RequestFn$4 = <T>(method: string, endpoint: string, data?: any) => Promise<T>;
|
|
304
|
-
interface ListIntentsOptions {
|
|
305
|
-
/** Filter by status */
|
|
306
|
-
status?: string;
|
|
307
|
-
/** Maximum results to return */
|
|
308
|
-
limit?: number;
|
|
309
|
-
/** Pagination offset */
|
|
310
|
-
offset?: number;
|
|
311
|
-
}
|
|
312
|
-
declare class PaymentIntentsAPI {
|
|
313
|
-
private request;
|
|
314
|
-
constructor(request: RequestFn$4);
|
|
104
|
+
getPaymentLink(linkCode: string): Promise<PaymentLink>;
|
|
315
105
|
/**
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
* This is step 1 of the two-phase payment flow. The intent reserves
|
|
319
|
-
* the payment amount and provides a client_secret for confirmation.
|
|
320
|
-
*
|
|
321
|
-
* @param request - Payment intent configuration
|
|
322
|
-
* @returns The created payment intent with client_secret
|
|
323
|
-
*
|
|
324
|
-
* @example
|
|
325
|
-
* ```typescript
|
|
326
|
-
* const intent = await zendfi.intents.create({
|
|
327
|
-
* amount: 49.99,
|
|
328
|
-
* description: 'Pro Plan - Monthly',
|
|
329
|
-
* capture_method: 'automatic', // or 'manual' for auth-only
|
|
330
|
-
* expires_in_seconds: 3600, // 1 hour
|
|
331
|
-
* });
|
|
332
|
-
*
|
|
333
|
-
* // Store intent.id and pass intent.client_secret to frontend
|
|
334
|
-
* console.log(`Intent created: ${intent.id}`);
|
|
335
|
-
* console.log(`Status: ${intent.status}`); // "requires_payment"
|
|
336
|
-
* ```
|
|
106
|
+
* List all payment links for the authenticated merchant
|
|
337
107
|
*/
|
|
338
|
-
|
|
108
|
+
listPaymentLinks(): Promise<PaymentLink[]>;
|
|
339
109
|
/**
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
* @param intentId - UUID of the payment intent
|
|
343
|
-
* @returns The payment intent details
|
|
344
|
-
*
|
|
345
|
-
* @example
|
|
346
|
-
* ```typescript
|
|
347
|
-
* const intent = await zendfi.intents.get('pi_123...');
|
|
348
|
-
* console.log(`Status: ${intent.status}`);
|
|
349
|
-
* if (intent.payment_id) {
|
|
350
|
-
* console.log(`Payment: ${intent.payment_id}`);
|
|
351
|
-
* }
|
|
352
|
-
* ```
|
|
110
|
+
* Create an installment plan
|
|
111
|
+
* Split a purchase into multiple scheduled payments
|
|
353
112
|
*/
|
|
354
|
-
|
|
113
|
+
createInstallmentPlan(request: CreateInstallmentPlanRequest): Promise<InstallmentPlan>;
|
|
355
114
|
/**
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
* @param options - Filter and pagination options
|
|
359
|
-
* @returns Array of payment intents
|
|
360
|
-
*
|
|
361
|
-
* @example
|
|
362
|
-
* ```typescript
|
|
363
|
-
* // Get recent pending intents
|
|
364
|
-
* const intents = await zendfi.intents.list({
|
|
365
|
-
* status: 'requires_payment',
|
|
366
|
-
* limit: 20,
|
|
367
|
-
* });
|
|
368
|
-
* ```
|
|
115
|
+
* Get installment plan by ID
|
|
369
116
|
*/
|
|
370
|
-
|
|
117
|
+
getInstallmentPlan(planId: string): Promise<InstallmentPlan>;
|
|
371
118
|
/**
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
* This is step 2 of the two-phase payment flow. Confirmation triggers
|
|
375
|
-
* the actual payment using the customer's wallet.
|
|
376
|
-
*
|
|
377
|
-
* @param intentId - UUID of the payment intent
|
|
378
|
-
* @param request - Confirmation details including customer wallet
|
|
379
|
-
* @returns The confirmed payment intent with payment_id
|
|
380
|
-
*
|
|
381
|
-
* @example
|
|
382
|
-
* ```typescript
|
|
383
|
-
* const confirmed = await zendfi.intents.confirm('pi_123...', {
|
|
384
|
-
* client_secret: 'pi_secret_abc...',
|
|
385
|
-
* customer_wallet: 'Hx7B...abc',
|
|
386
|
-
* auto_gasless: true,
|
|
387
|
-
* });
|
|
388
|
-
*
|
|
389
|
-
* if (confirmed.status === 'succeeded') {
|
|
390
|
-
* console.log(`Payment complete: ${confirmed.payment_id}`);
|
|
391
|
-
* }
|
|
392
|
-
* ```
|
|
119
|
+
* List all installment plans for merchant
|
|
393
120
|
*/
|
|
394
|
-
|
|
121
|
+
listInstallmentPlans(params?: {
|
|
122
|
+
limit?: number;
|
|
123
|
+
offset?: number;
|
|
124
|
+
}): Promise<InstallmentPlan[]>;
|
|
395
125
|
/**
|
|
396
|
-
*
|
|
397
|
-
*
|
|
398
|
-
* Canceling releases any hold on the payment amount. Cannot cancel
|
|
399
|
-
* intents that are already processing or succeeded.
|
|
400
|
-
*
|
|
401
|
-
* @param intentId - UUID of the payment intent
|
|
402
|
-
* @returns The canceled payment intent
|
|
403
|
-
*
|
|
404
|
-
* @example
|
|
405
|
-
* ```typescript
|
|
406
|
-
* const canceled = await zendfi.intents.cancel('pi_123...');
|
|
407
|
-
* console.log(`Status: ${canceled.status}`); // "canceled"
|
|
408
|
-
* ```
|
|
126
|
+
* List installment plans for a specific customer
|
|
409
127
|
*/
|
|
410
|
-
|
|
128
|
+
listCustomerInstallmentPlans(customerWallet: string): Promise<InstallmentPlan[]>;
|
|
411
129
|
/**
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
* Events track the full lifecycle of the intent, including creation,
|
|
415
|
-
* confirmation attempts, and status changes.
|
|
416
|
-
*
|
|
417
|
-
* @param intentId - UUID of the payment intent
|
|
418
|
-
* @returns Array of events in chronological order
|
|
419
|
-
*
|
|
420
|
-
* @example
|
|
421
|
-
* ```typescript
|
|
422
|
-
* const events = await zendfi.intents.getEvents('pi_123...');
|
|
423
|
-
* events.forEach(event => {
|
|
424
|
-
* console.log(`${event.created_at}: ${event.event_type}`);
|
|
425
|
-
* });
|
|
426
|
-
* ```
|
|
130
|
+
* Cancel an installment plan
|
|
427
131
|
*/
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
* Pricing API - Purchasing Power Parity (PPP) and AI-powered pricing
|
|
433
|
-
*
|
|
434
|
-
* Enable global reach with geo-aware pricing that automatically adjusts
|
|
435
|
-
* prices based on the customer's location and purchasing power.
|
|
436
|
-
*
|
|
437
|
-
* @example
|
|
438
|
-
* ```typescript
|
|
439
|
-
* // Get PPP factor for Brazil
|
|
440
|
-
* const factor = await zendfi.pricing.getPPPFactor('BR');
|
|
441
|
-
* console.log(`Brazil: ${factor.adjustment_percentage}% discount suggested`);
|
|
442
|
-
*
|
|
443
|
-
* // Apply PPP to a product price
|
|
444
|
-
* const basePrice = 100;
|
|
445
|
-
* const localPrice = basePrice * factor.ppp_factor;
|
|
446
|
-
* console.log(`$${basePrice} → $${localPrice.toFixed(2)} for Brazilian customers`);
|
|
447
|
-
* ```
|
|
448
|
-
*/
|
|
449
|
-
|
|
450
|
-
type RequestFn$3 = <T>(method: string, endpoint: string, data?: any) => Promise<T>;
|
|
451
|
-
declare class PricingAPI {
|
|
452
|
-
private request;
|
|
453
|
-
constructor(request: RequestFn$3);
|
|
132
|
+
cancelInstallmentPlan(planId: string): Promise<{
|
|
133
|
+
message: string;
|
|
134
|
+
plan_id: string;
|
|
135
|
+
}>;
|
|
454
136
|
/**
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
* Returns the purchasing power parity adjustment factor for the given
|
|
458
|
-
* country code. Use this to calculate localized pricing.
|
|
459
|
-
*
|
|
460
|
-
* @param countryCode - ISO 3166-1 alpha-2 country code (e.g., "BR", "IN", "NG")
|
|
461
|
-
* @returns PPP factor and suggested adjustment
|
|
462
|
-
*
|
|
463
|
-
* @example
|
|
464
|
-
* ```typescript
|
|
465
|
-
* const factor = await zendfi.pricing.getPPPFactor('BR');
|
|
466
|
-
* // {
|
|
467
|
-
* // country_code: 'BR',
|
|
468
|
-
* // country_name: 'Brazil',
|
|
469
|
-
* // ppp_factor: 0.35,
|
|
470
|
-
* // currency_code: 'BRL',
|
|
471
|
-
* // adjustment_percentage: 35.0
|
|
472
|
-
* // }
|
|
473
|
-
*
|
|
474
|
-
* // Calculate localized price
|
|
475
|
-
* const usdPrice = 100;
|
|
476
|
-
* const localPrice = usdPrice * (1 - factor.adjustment_percentage / 100);
|
|
477
|
-
* console.log(`$${localPrice} for Brazilian customers`);
|
|
478
|
-
* ```
|
|
137
|
+
* Create an invoice
|
|
479
138
|
*/
|
|
480
|
-
|
|
139
|
+
createInvoice(request: CreateInvoiceRequest): Promise<Invoice>;
|
|
481
140
|
/**
|
|
482
|
-
*
|
|
483
|
-
*
|
|
484
|
-
* Returns PPP factors for all supported countries. Useful for building
|
|
485
|
-
* pricing tables or pre-computing regional prices.
|
|
486
|
-
*
|
|
487
|
-
* @returns Array of PPP factors for all supported countries
|
|
488
|
-
*
|
|
489
|
-
* @example
|
|
490
|
-
* ```typescript
|
|
491
|
-
* const factors = await zendfi.pricing.listFactors();
|
|
492
|
-
*
|
|
493
|
-
* // Create pricing tiers
|
|
494
|
-
* const tiers = factors.map(f => ({
|
|
495
|
-
* country: f.country_name,
|
|
496
|
-
* price: (100 * f.ppp_factor).toFixed(2),
|
|
497
|
-
* }));
|
|
498
|
-
*
|
|
499
|
-
* console.table(tiers);
|
|
500
|
-
* ```
|
|
141
|
+
* Get invoice by ID
|
|
501
142
|
*/
|
|
502
|
-
|
|
143
|
+
getInvoice(invoiceId: string): Promise<Invoice>;
|
|
503
144
|
/**
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
* Returns an intelligent pricing recommendation based on the user's
|
|
507
|
-
* location, wallet history, and your pricing configuration.
|
|
508
|
-
*
|
|
509
|
-
* @param request - Pricing suggestion request with user context
|
|
510
|
-
* @returns AI-generated pricing suggestion with reasoning
|
|
511
|
-
*
|
|
512
|
-
* @example
|
|
513
|
-
* ```typescript
|
|
514
|
-
* const suggestion = await zendfi.pricing.getSuggestion({
|
|
515
|
-
* agent_id: 'shopping-assistant',
|
|
516
|
-
* base_price: 99.99,
|
|
517
|
-
* user_profile: {
|
|
518
|
-
* location_country: 'BR',
|
|
519
|
-
* context: 'first-time',
|
|
520
|
-
* },
|
|
521
|
-
* ppp_config: {
|
|
522
|
-
* enabled: true,
|
|
523
|
-
* max_discount_percent: 50,
|
|
524
|
-
* floor_price: 29.99,
|
|
525
|
-
* },
|
|
526
|
-
* });
|
|
527
|
-
*
|
|
528
|
-
* console.log(`Suggested: $${suggestion.suggested_amount}`);
|
|
529
|
-
* console.log(`Reason: ${suggestion.reasoning}`);
|
|
530
|
-
* // => "Price adjusted for Brazilian purchasing power (35% PPP discount)
|
|
531
|
-
* // plus 10% first-time customer discount"
|
|
532
|
-
* ```
|
|
145
|
+
* List all invoices for merchant
|
|
533
146
|
*/
|
|
534
|
-
|
|
147
|
+
listInvoices(): Promise<Invoice[]>;
|
|
535
148
|
/**
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
* Convenience method that combines getPPPFactor with price calculation.
|
|
539
|
-
*
|
|
540
|
-
* @param basePrice - Original price in USD
|
|
541
|
-
* @param countryCode - ISO 3166-1 alpha-2 country code
|
|
542
|
-
* @returns Object with original and adjusted prices
|
|
543
|
-
*
|
|
544
|
-
* @example
|
|
545
|
-
* ```typescript
|
|
546
|
-
* const result = await zendfi.pricing.calculateLocalPrice(100, 'IN');
|
|
547
|
-
* console.log(`Original: $${result.original}`);
|
|
548
|
-
* console.log(`Local: $${result.adjusted}`);
|
|
549
|
-
* console.log(`Savings: $${result.savings} (${result.discount_percentage}%)`);
|
|
550
|
-
* ```
|
|
149
|
+
* Send invoice to customer via email
|
|
551
150
|
*/
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
151
|
+
sendInvoice(invoiceId: string): Promise<{
|
|
152
|
+
success: boolean;
|
|
153
|
+
invoice_id: string;
|
|
154
|
+
invoice_number: string;
|
|
155
|
+
sent_to: string;
|
|
156
|
+
payment_url: string;
|
|
157
|
+
status: string;
|
|
559
158
|
}>;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
/**
|
|
563
|
-
* Autonomy API - Enable autonomous agent signing
|
|
564
|
-
*
|
|
565
|
-
* The Autonomy API enables AI agents to make payments without user interaction
|
|
566
|
-
* for each transaction, while maintaining cryptographic security through:
|
|
567
|
-
*
|
|
568
|
-
* 1. **Delegation Signatures** - User signs a message authorizing the agent
|
|
569
|
-
* 2. **Spending Limits** - Hard caps on total spending
|
|
570
|
-
* 3. **Time Bounds** - Automatic expiration
|
|
571
|
-
* 4. **Lit Protocol** (optional) - Threshold cryptography for key management
|
|
572
|
-
*
|
|
573
|
-
* @example
|
|
574
|
-
* ```typescript
|
|
575
|
-
* // Enable autonomous mode for a session key
|
|
576
|
-
* const delegate = await zendfi.autonomy.enable({
|
|
577
|
-
* session_key_id: 'sk_123...',
|
|
578
|
-
* max_amount_usd: 100,
|
|
579
|
-
* duration_hours: 24,
|
|
580
|
-
* delegation_signature: signature, // Ed25519 sig from user
|
|
581
|
-
* });
|
|
582
|
-
*
|
|
583
|
-
* // Agent can now make payments automatically
|
|
584
|
-
* console.log(`Delegate active: $${delegate.max_amount_usd} limit`);
|
|
585
|
-
* ```
|
|
586
|
-
*/
|
|
587
|
-
|
|
588
|
-
type RequestFn$2 = <T>(method: string, endpoint: string, data?: any) => Promise<T>;
|
|
589
|
-
declare class AutonomyAPI {
|
|
590
|
-
private request;
|
|
591
|
-
constructor(request: RequestFn$2);
|
|
592
159
|
/**
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
* This grants an AI agent the ability to sign transactions on behalf of
|
|
596
|
-
* the user, up to the specified spending limit and duration.
|
|
597
|
-
*
|
|
598
|
-
* **Prerequisites:**
|
|
599
|
-
* 1. Create a device-bound session key first
|
|
600
|
-
* 2. Generate a delegation signature (see `createDelegationMessage`)
|
|
601
|
-
* 3. Optionally encrypt keypair with Lit Protocol for true autonomy
|
|
160
|
+
* Verify webhook signature using HMAC-SHA256
|
|
602
161
|
*
|
|
603
|
-
* @param
|
|
604
|
-
* @
|
|
605
|
-
* @returns The created autonomous delegate
|
|
162
|
+
* @param request - Webhook verification request containing payload, signature, and secret
|
|
163
|
+
* @returns true if signature is valid, false otherwise
|
|
606
164
|
*
|
|
607
165
|
* @example
|
|
608
166
|
* ```typescript
|
|
609
|
-
*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
-
* // Have user sign with their session key
|
|
615
|
-
* const signature = await signWithSessionKey(message, pin);
|
|
616
|
-
*
|
|
617
|
-
* // Enable autonomous mode
|
|
618
|
-
* const delegate = await zendfi.autonomy.enable(sessionKeyId, {
|
|
619
|
-
* max_amount_usd: 100,
|
|
620
|
-
* duration_hours: 24,
|
|
621
|
-
* delegation_signature: signature,
|
|
167
|
+
* const isValid = zendfi.verifyWebhook({
|
|
168
|
+
* payload: req.body,
|
|
169
|
+
* signature: req.headers['x-zendfi-signature'],
|
|
170
|
+
* secret: process.env.ZENDFI_WEBHOOK_SECRET
|
|
622
171
|
* });
|
|
623
172
|
*
|
|
624
|
-
*
|
|
625
|
-
*
|
|
173
|
+
* if (!isValid) {
|
|
174
|
+
* return res.status(401).json({ error: 'Invalid signature' });
|
|
175
|
+
* }
|
|
626
176
|
* ```
|
|
627
177
|
*/
|
|
628
|
-
|
|
629
|
-
/**
|
|
630
|
-
* Revoke autonomous mode for a session key
|
|
631
|
-
*
|
|
632
|
-
* Immediately invalidates the autonomous delegate, preventing any further
|
|
633
|
-
* automatic payments. The session key itself remains valid for manual use.
|
|
634
|
-
*
|
|
635
|
-
* @param sessionKeyId - UUID of the session key
|
|
636
|
-
* @param reason - Optional reason for revocation (logged for audit)
|
|
637
|
-
*
|
|
638
|
-
* @example
|
|
639
|
-
* ```typescript
|
|
640
|
-
* await zendfi.autonomy.revoke('sk_123...', 'User requested revocation');
|
|
641
|
-
* console.log('Autonomous mode disabled');
|
|
642
|
-
* ```
|
|
643
|
-
*/
|
|
644
|
-
revoke(sessionKeyId: string, reason?: string): Promise<void>;
|
|
645
|
-
/**
|
|
646
|
-
* Get autonomy status for a session key
|
|
647
|
-
*
|
|
648
|
-
* Returns whether autonomous mode is enabled and details about the
|
|
649
|
-
* active delegate including remaining spending allowance.
|
|
650
|
-
*
|
|
651
|
-
* @param sessionKeyId - UUID of the session key
|
|
652
|
-
* @returns Autonomy status with delegate details
|
|
653
|
-
*
|
|
654
|
-
* @example
|
|
655
|
-
* ```typescript
|
|
656
|
-
* const status = await zendfi.autonomy.getStatus('sk_123...');
|
|
657
|
-
*
|
|
658
|
-
* if (status.autonomous_mode_enabled && status.delegate) {
|
|
659
|
-
* console.log(`Remaining: $${status.delegate.remaining_usd}`);
|
|
660
|
-
* console.log(`Expires: ${status.delegate.expires_at}`);
|
|
661
|
-
* } else {
|
|
662
|
-
* console.log('Autonomous mode not enabled');
|
|
663
|
-
* }
|
|
664
|
-
* ```
|
|
665
|
-
*/
|
|
666
|
-
getStatus(sessionKeyId: string): Promise<AutonomyStatus>;
|
|
667
|
-
/**
|
|
668
|
-
* Create the delegation message that needs to be signed
|
|
669
|
-
*
|
|
670
|
-
* This generates the exact message format required for the delegation
|
|
671
|
-
* signature. The user must sign this message with their session key.
|
|
672
|
-
*
|
|
673
|
-
* **Message format:**
|
|
674
|
-
* ```
|
|
675
|
-
* I authorize autonomous delegate for session {id} to spend up to ${amount} until {expiry}
|
|
676
|
-
* ```
|
|
677
|
-
*
|
|
678
|
-
* @param sessionKeyId - UUID of the session key
|
|
679
|
-
* @param maxAmountUsd - Maximum spending amount in USD
|
|
680
|
-
* @param expiresAt - ISO 8601 expiration timestamp
|
|
681
|
-
* @returns The message to be signed
|
|
682
|
-
*
|
|
683
|
-
* @example
|
|
684
|
-
* ```typescript
|
|
685
|
-
* const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString();
|
|
686
|
-
* const message = zendfi.autonomy.createDelegationMessage(
|
|
687
|
-
* 'sk_123...',
|
|
688
|
-
* 100,
|
|
689
|
-
* expiresAt
|
|
690
|
-
* );
|
|
691
|
-
* // => "I authorize autonomous delegate for session sk_123... to spend up to $100 until 2024-12-06T..."
|
|
692
|
-
*
|
|
693
|
-
* // Sign with nacl.sign.detached() or similar
|
|
694
|
-
* const signature = signMessage(message, keypair);
|
|
695
|
-
* ```
|
|
696
|
-
*/
|
|
697
|
-
createDelegationMessage(sessionKeyId: string, maxAmountUsd: number, expiresAt: string): string;
|
|
698
|
-
/**
|
|
699
|
-
* Validate delegation signature parameters
|
|
700
|
-
*
|
|
701
|
-
* Helper method to check if autonomy parameters are valid before
|
|
702
|
-
* making the API call.
|
|
703
|
-
*
|
|
704
|
-
* @param request - The enable autonomy request to validate
|
|
705
|
-
* @throws Error if validation fails
|
|
706
|
-
*
|
|
707
|
-
* @example
|
|
708
|
-
* ```typescript
|
|
709
|
-
* try {
|
|
710
|
-
* zendfi.autonomy.validateRequest(request);
|
|
711
|
-
* const delegate = await zendfi.autonomy.enable(sessionKeyId, request);
|
|
712
|
-
* } catch (error) {
|
|
713
|
-
* console.error('Invalid request:', error.message);
|
|
714
|
-
* }
|
|
715
|
-
* ```
|
|
716
|
-
*/
|
|
717
|
-
validateRequest(request: EnableAutonomyRequest): void;
|
|
718
|
-
/**
|
|
719
|
-
* Get spending attestations for a delegate (audit trail)
|
|
720
|
-
*
|
|
721
|
-
* Returns all cryptographically signed attestations ZendFi created for
|
|
722
|
-
* this delegate. Each attestation contains:
|
|
723
|
-
* - The spending state at the time of payment
|
|
724
|
-
* - ZendFi's Ed25519 signature
|
|
725
|
-
* - Timestamp and nonce (for replay protection)
|
|
726
|
-
*
|
|
727
|
-
* These attestations can be independently verified using ZendFi's public key
|
|
728
|
-
* to confirm spending limit enforcement was applied correctly.
|
|
729
|
-
*
|
|
730
|
-
* @param delegateId - UUID of the autonomous delegate
|
|
731
|
-
* @returns Attestation audit response with all signed attestations
|
|
732
|
-
*
|
|
733
|
-
* @example
|
|
734
|
-
* ```typescript
|
|
735
|
-
* const audit = await zendfi.autonomy.getAttestations('delegate_123...');
|
|
736
|
-
*
|
|
737
|
-
* console.log(`Found ${audit.attestation_count} attestations`);
|
|
738
|
-
* console.log(`ZendFi public key: ${audit.zendfi_attestation_public_key}`);
|
|
739
|
-
*
|
|
740
|
-
* // Verify each attestation independently
|
|
741
|
-
* for (const signed of audit.attestations) {
|
|
742
|
-
* console.log(`Payment ${signed.attestation.payment_id}:`);
|
|
743
|
-
* console.log(` Requested: $${signed.attestation.requested_usd}`);
|
|
744
|
-
* console.log(` Remaining after: $${signed.attestation.remaining_after_usd}`);
|
|
745
|
-
* // Verify signature with nacl.sign.detached.verify()
|
|
746
|
-
* }
|
|
747
|
-
* ```
|
|
748
|
-
*/
|
|
749
|
-
getAttestations(delegateId: string): Promise<AttestationAuditResponse>;
|
|
750
|
-
}
|
|
751
|
-
/** Spending attestation - ZendFi's signed commitment to spending state */
|
|
752
|
-
interface SpendingAttestation {
|
|
753
|
-
delegate_id: string;
|
|
754
|
-
session_key_id: string;
|
|
755
|
-
merchant_id: string;
|
|
756
|
-
spent_usd: number;
|
|
757
|
-
limit_usd: number;
|
|
758
|
-
requested_usd: number;
|
|
759
|
-
remaining_after_usd: number;
|
|
760
|
-
timestamp_ms: number;
|
|
761
|
-
nonce: string;
|
|
762
|
-
payment_id: string;
|
|
763
|
-
version: number;
|
|
764
|
-
}
|
|
765
|
-
/** Signed attestation with ZendFi's cryptographic signature */
|
|
766
|
-
interface SignedSpendingAttestation {
|
|
767
|
-
attestation: SpendingAttestation;
|
|
768
|
-
/** Base64-encoded Ed25519 signature */
|
|
769
|
-
signature: string;
|
|
770
|
-
/** Base58-encoded ZendFi public key */
|
|
771
|
-
signer_public_key: string;
|
|
772
|
-
}
|
|
773
|
-
/** Response from the attestation audit endpoint */
|
|
774
|
-
interface AttestationAuditResponse {
|
|
775
|
-
delegate_id: string;
|
|
776
|
-
attestation_count: number;
|
|
777
|
-
attestations: SignedSpendingAttestation[];
|
|
778
|
-
/** ZendFi's attestation public key for independent verification */
|
|
779
|
-
zendfi_attestation_public_key: string | null;
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
/**
|
|
783
|
-
* Smart Payments API - AI-powered payment routing
|
|
784
|
-
*
|
|
785
|
-
* Smart payments combine multiple features into a single intelligent API:
|
|
786
|
-
* - Automatic PPP pricing adjustments
|
|
787
|
-
* - Gasless transaction detection
|
|
788
|
-
* - Instant settlement options
|
|
789
|
-
* - Escrow integration
|
|
790
|
-
* - Receipt generation
|
|
791
|
-
*
|
|
792
|
-
* @example
|
|
793
|
-
* ```typescript
|
|
794
|
-
* const result = await zendfi.payments.smart({
|
|
795
|
-
* agent_id: 'shopping-assistant',
|
|
796
|
-
* user_wallet: 'Hx7B...abc',
|
|
797
|
-
* amount_usd: 50,
|
|
798
|
-
* auto_detect_gasless: true,
|
|
799
|
-
* description: 'Premium subscription',
|
|
800
|
-
* });
|
|
801
|
-
*
|
|
802
|
-
* console.log(`Payment: ${result.payment_id}`);
|
|
803
|
-
* console.log(`Receipt: ${result.receipt_url}`);
|
|
804
|
-
* ```
|
|
805
|
-
*/
|
|
806
|
-
|
|
807
|
-
type RequestFn$1 = <T>(method: string, endpoint: string, data?: any) => Promise<T>;
|
|
808
|
-
declare class SmartPaymentsAPI {
|
|
809
|
-
private request;
|
|
810
|
-
constructor(request: RequestFn$1);
|
|
811
|
-
/**
|
|
812
|
-
* Execute an AI-powered smart payment
|
|
813
|
-
*
|
|
814
|
-
* Smart payments analyze the context and automatically apply optimizations:
|
|
815
|
-
* - **PPP Pricing**: Auto-adjusts based on customer location
|
|
816
|
-
* - **Gasless**: Detects when user needs gas subsidization
|
|
817
|
-
* - **Instant Settlement**: Optional immediate merchant payout
|
|
818
|
-
* - **Escrow**: Optional fund holding for service delivery
|
|
819
|
-
*
|
|
820
|
-
* @param request - Smart payment request configuration
|
|
821
|
-
* @returns Payment result with status and receipt
|
|
822
|
-
*
|
|
823
|
-
* @example
|
|
824
|
-
* ```typescript
|
|
825
|
-
* // Basic smart payment
|
|
826
|
-
* const result = await zendfi.payments.smart({
|
|
827
|
-
* agent_id: 'my-agent',
|
|
828
|
-
* user_wallet: 'Hx7B...abc',
|
|
829
|
-
* amount_usd: 99.99,
|
|
830
|
-
* description: 'Annual Pro Plan',
|
|
831
|
-
* });
|
|
832
|
-
*
|
|
833
|
-
* // With all options
|
|
834
|
-
* const result = await zendfi.payments.smart({
|
|
835
|
-
* agent_id: 'my-agent',
|
|
836
|
-
* session_token: 'zai_session_...', // For limit enforcement
|
|
837
|
-
* user_wallet: 'Hx7B...abc',
|
|
838
|
-
* amount_usd: 99.99,
|
|
839
|
-
* token: 'USDC',
|
|
840
|
-
* auto_detect_gasless: true,
|
|
841
|
-
* instant_settlement: true,
|
|
842
|
-
* enable_escrow: false,
|
|
843
|
-
* description: 'Annual Pro Plan',
|
|
844
|
-
* product_details: {
|
|
845
|
-
* name: 'Pro Plan',
|
|
846
|
-
* sku: 'PRO-ANNUAL',
|
|
847
|
-
* },
|
|
848
|
-
* metadata: {
|
|
849
|
-
* user_id: 'usr_123',
|
|
850
|
-
* },
|
|
851
|
-
* });
|
|
852
|
-
*
|
|
853
|
-
* if (result.requires_signature) {
|
|
854
|
-
* // Device-bound flow: need user to sign
|
|
855
|
-
* console.log('Please sign:', result.unsigned_transaction);
|
|
856
|
-
* console.log('Submit to:', result.submit_url);
|
|
857
|
-
* } else {
|
|
858
|
-
* // Auto-signed (custodial or autonomous delegate)
|
|
859
|
-
* console.log('Payment complete:', result.transaction_signature);
|
|
860
|
-
* }
|
|
861
|
-
* ```
|
|
862
|
-
*/
|
|
863
|
-
execute(request: SmartPaymentRequest): Promise<SmartPaymentResponse>;
|
|
864
|
-
/**
|
|
865
|
-
* Submit a signed transaction from device-bound flow
|
|
866
|
-
*
|
|
867
|
-
* When a smart payment returns `requires_signature: true`, the client
|
|
868
|
-
* must sign the transaction and submit it here.
|
|
869
|
-
*
|
|
870
|
-
* @param paymentId - UUID of the payment
|
|
871
|
-
* @param signedTransaction - Base64 encoded signed transaction
|
|
872
|
-
* @returns Updated payment response
|
|
873
|
-
*
|
|
874
|
-
* @example
|
|
875
|
-
* ```typescript
|
|
876
|
-
* // After user signs the transaction
|
|
877
|
-
* const result = await zendfi.payments.submitSigned(
|
|
878
|
-
* payment.payment_id,
|
|
879
|
-
* signedTransaction
|
|
880
|
-
* );
|
|
881
|
-
*
|
|
882
|
-
* console.log(`Confirmed in ${result.confirmed_in_ms}ms`);
|
|
883
|
-
* ```
|
|
884
|
-
*/
|
|
885
|
-
submitSigned(paymentId: string, signedTransaction: string): Promise<SmartPaymentResponse>;
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
/**
|
|
889
|
-
* Session Keys API - Device-Bound Non-Custodial Session Keys
|
|
890
|
-
*
|
|
891
|
-
* TRUE non-custodial session keys where:
|
|
892
|
-
* - Client generates keypair (backend NEVER sees private key)
|
|
893
|
-
* - Client encrypts with PIN + device fingerprint (Argon2id + AES-256-GCM)
|
|
894
|
-
* - Backend stores encrypted blob (cannot decrypt!)
|
|
895
|
-
* - Client decrypts and signs for each payment
|
|
896
|
-
*
|
|
897
|
-
* This is the ONLY supported mode. Custodial session keys are deprecated.
|
|
898
|
-
*
|
|
899
|
-
* @example
|
|
900
|
-
* ```typescript
|
|
901
|
-
* // Create a session key with PIN encryption
|
|
902
|
-
* const result = await zendfi.sessionKeys.create({
|
|
903
|
-
* userWallet: '7xKNH...',
|
|
904
|
-
* agentId: 'shopping-assistant-v1',
|
|
905
|
-
* agentName: 'AI Shopping Assistant',
|
|
906
|
-
* limitUSDC: 100,
|
|
907
|
-
* durationDays: 7,
|
|
908
|
-
* pin: '123456',
|
|
909
|
-
* generateRecoveryQR: true,
|
|
910
|
-
* });
|
|
911
|
-
*
|
|
912
|
-
* console.log(`Session key: ${result.sessionKeyId}`);
|
|
913
|
-
* console.log(`Works across all apps with agent: ${result.agentId}`);
|
|
914
|
-
*
|
|
915
|
-
* // Unlock for auto-signing (one-time PIN entry)
|
|
916
|
-
* await zendfi.sessionKeys.unlock(result.sessionKeyId, '123456');
|
|
917
|
-
*
|
|
918
|
-
* // Make payments without PIN (instant!)
|
|
919
|
-
* const payment = await zendfi.sessionKeys.makePayment({
|
|
920
|
-
* sessionKeyId: result.sessionKeyId,
|
|
921
|
-
* amount: 5.0,
|
|
922
|
-
* recipient: '8xYZA...',
|
|
923
|
-
* description: 'Coffee purchase',
|
|
924
|
-
* });
|
|
925
|
-
* ```
|
|
926
|
-
*
|
|
927
|
-
* @module aip/session-keys
|
|
928
|
-
*/
|
|
929
|
-
type RequestFn = <T>(method: string, endpoint: string, data?: any) => Promise<T>;
|
|
930
|
-
interface CreateSessionKeyOptions {
|
|
931
|
-
/** User's main wallet address */
|
|
932
|
-
userWallet: string;
|
|
933
|
-
/** Agent identifier for cross-app compatibility (e.g., "shopping-assistant-v1") */
|
|
934
|
-
agentId: string;
|
|
935
|
-
/** Human-readable agent name (e.g., "AI Shopping Assistant") */
|
|
936
|
-
agentName?: string;
|
|
937
|
-
/** Spending limit in USDC */
|
|
938
|
-
limitUSDC: number;
|
|
939
|
-
/** Duration in days (1-30) */
|
|
940
|
-
durationDays: number;
|
|
941
|
-
/** 6-digit numeric PIN for encryption */
|
|
942
|
-
pin: string;
|
|
943
|
-
/** Generate recovery QR code (recommended) */
|
|
944
|
-
generateRecoveryQR?: boolean;
|
|
945
|
-
/** Enable Lit Protocol for true autonomous signing (default: true) */
|
|
946
|
-
enableLitProtocol?: boolean;
|
|
947
|
-
/** Lit Protocol network (default: 'datil-dev') */
|
|
948
|
-
litNetwork?: 'datil' | 'datil-dev' | 'datil-test';
|
|
949
|
-
}
|
|
950
|
-
interface SessionKeyResult {
|
|
951
|
-
/** UUID of the created session key */
|
|
952
|
-
sessionKeyId: string;
|
|
953
|
-
/** Agent identifier */
|
|
954
|
-
agentId: string;
|
|
955
|
-
/** Agent name (if provided) */
|
|
956
|
-
agentName?: string;
|
|
957
|
-
/** Session wallet public key */
|
|
958
|
-
sessionWallet: string;
|
|
959
|
-
/** Spending limit in USDC */
|
|
960
|
-
limitUsdc: number;
|
|
961
|
-
/** Expiration timestamp */
|
|
962
|
-
expiresAt: string;
|
|
963
|
-
/** Recovery QR code data (if generated) */
|
|
964
|
-
recoveryQR?: string;
|
|
965
|
-
/** True if this session key works across multiple apps with same agent_id */
|
|
966
|
-
crossAppCompatible: boolean;
|
|
967
|
-
}
|
|
968
|
-
interface MakePaymentOptions {
|
|
969
|
-
/** Session key ID to pay from */
|
|
970
|
-
sessionKeyId: string;
|
|
971
|
-
/** Payment amount in USD */
|
|
972
|
-
amount: number;
|
|
973
|
-
/** Recipient wallet address */
|
|
974
|
-
recipient: string;
|
|
975
|
-
/** Token to pay with (default: USDC) */
|
|
976
|
-
token?: string;
|
|
977
|
-
/** Payment description */
|
|
978
|
-
description?: string;
|
|
979
|
-
/** PIN (only required if session key not unlocked) */
|
|
980
|
-
pin?: string;
|
|
981
|
-
/** Whether to cache keypair for future payments (default: true) */
|
|
982
|
-
enableAutoSign?: boolean;
|
|
983
|
-
}
|
|
984
|
-
interface PaymentResult$1 {
|
|
985
|
-
paymentId: string;
|
|
986
|
-
signature: string;
|
|
987
|
-
status: string;
|
|
988
|
-
}
|
|
989
|
-
interface SessionKeyInfo {
|
|
990
|
-
sessionKeyId: string;
|
|
991
|
-
isActive: boolean;
|
|
992
|
-
isApproved: boolean;
|
|
993
|
-
limitUsdc: number;
|
|
994
|
-
usedAmountUsdc: number;
|
|
995
|
-
remainingUsdc: number;
|
|
996
|
-
expiresAt: string;
|
|
997
|
-
daysUntilExpiry: number;
|
|
998
|
-
}
|
|
999
|
-
declare class SessionKeysAPI {
|
|
1000
|
-
private sessionKeys;
|
|
1001
|
-
private sessionMetadata;
|
|
1002
|
-
private requestFn;
|
|
1003
|
-
private debugMode;
|
|
1004
|
-
constructor(request: RequestFn);
|
|
1005
|
-
/**
|
|
1006
|
-
* Enable debug logging
|
|
1007
|
-
*/
|
|
1008
|
-
private debug;
|
|
1009
|
-
/**
|
|
1010
|
-
* Create a new device-bound session key
|
|
1011
|
-
*
|
|
1012
|
-
* The keypair is generated client-side and encrypted with your PIN.
|
|
1013
|
-
* The backend NEVER sees your private key.
|
|
1014
|
-
*
|
|
1015
|
-
* @param options - Session key configuration
|
|
1016
|
-
* @returns Created session key info with optional recovery QR
|
|
1017
|
-
*
|
|
1018
|
-
* @example
|
|
1019
|
-
* ```typescript
|
|
1020
|
-
* const result = await zendfi.sessionKeys.create({
|
|
1021
|
-
* userWallet: '7xKNH...',
|
|
1022
|
-
* agentId: 'shopping-assistant-v1',
|
|
1023
|
-
* agentName: 'AI Shopping Assistant',
|
|
1024
|
-
* limitUSDC: 100,
|
|
1025
|
-
* durationDays: 7,
|
|
1026
|
-
* pin: '123456',
|
|
1027
|
-
* generateRecoveryQR: true,
|
|
1028
|
-
* });
|
|
1029
|
-
*
|
|
1030
|
-
* console.log(`Session key: ${result.sessionKeyId}`);
|
|
1031
|
-
* console.log(`Recovery QR: ${result.recoveryQR}`);
|
|
1032
|
-
* ```
|
|
1033
|
-
*/
|
|
1034
|
-
create(options: CreateSessionKeyOptions): Promise<SessionKeyResult>;
|
|
1035
|
-
/**
|
|
1036
|
-
* Load an existing session key from backend
|
|
1037
|
-
*
|
|
1038
|
-
* Fetches the encrypted session key and decrypts it with your PIN.
|
|
1039
|
-
* Use this when resuming a session on the same device.
|
|
1040
|
-
*
|
|
1041
|
-
* @param sessionKeyId - UUID of the session key
|
|
1042
|
-
* @param pin - PIN to decrypt the session key
|
|
1043
|
-
*
|
|
1044
|
-
* @example
|
|
1045
|
-
* ```typescript
|
|
1046
|
-
* // Resume session on same device
|
|
1047
|
-
* await zendfi.sessionKeys.load('uuid-of-session-key', '123456');
|
|
1048
|
-
*
|
|
1049
|
-
* // Now you can make payments
|
|
1050
|
-
* await zendfi.sessionKeys.makePayment({...});
|
|
1051
|
-
* ```
|
|
1052
|
-
*/
|
|
1053
|
-
load(sessionKeyId: string, pin: string): Promise<void>;
|
|
1054
|
-
/**
|
|
1055
|
-
* Unlock a session key for auto-signing
|
|
1056
|
-
*
|
|
1057
|
-
* After unlocking, payments can be made without entering PIN.
|
|
1058
|
-
* The decrypted keypair is cached in memory with a TTL.
|
|
1059
|
-
*
|
|
1060
|
-
* @param sessionKeyId - UUID of the session key
|
|
1061
|
-
* @param pin - PIN to decrypt the session key
|
|
1062
|
-
* @param cacheTTL - How long to cache (default: 30 minutes)
|
|
1063
|
-
*
|
|
1064
|
-
* @example
|
|
1065
|
-
* ```typescript
|
|
1066
|
-
* // Unlock once
|
|
1067
|
-
* await zendfi.sessionKeys.unlock('uuid', '123456');
|
|
1068
|
-
*
|
|
1069
|
-
* // Make payments instantly (no PIN!)
|
|
1070
|
-
* await zendfi.sessionKeys.makePayment({...}); // Instant!
|
|
1071
|
-
* await zendfi.sessionKeys.makePayment({...}); // Instant!
|
|
1072
|
-
* ```
|
|
1073
|
-
*/
|
|
1074
|
-
unlock(sessionKeyId: string, pin: string, cacheTTL?: number): Promise<void>;
|
|
1075
|
-
/**
|
|
1076
|
-
* Make a payment using a session key
|
|
1077
|
-
*
|
|
1078
|
-
* If the session key is unlocked (cached), no PIN is needed.
|
|
1079
|
-
* Otherwise, you must provide the PIN.
|
|
1080
|
-
*
|
|
1081
|
-
* @param options - Payment configuration
|
|
1082
|
-
* @returns Payment result with signature
|
|
1083
|
-
*
|
|
1084
|
-
* @example
|
|
1085
|
-
* ```typescript
|
|
1086
|
-
* // With unlocked session key (no PIN)
|
|
1087
|
-
* const result = await zendfi.sessionKeys.makePayment({
|
|
1088
|
-
* sessionKeyId: 'uuid',
|
|
1089
|
-
* amount: 5.0,
|
|
1090
|
-
* recipient: '8xYZA...',
|
|
1091
|
-
* description: 'Coffee purchase',
|
|
1092
|
-
* });
|
|
1093
|
-
*
|
|
1094
|
-
* // Or with PIN (one-time)
|
|
1095
|
-
* const result = await zendfi.sessionKeys.makePayment({
|
|
1096
|
-
* sessionKeyId: 'uuid',
|
|
1097
|
-
* amount: 5.0,
|
|
1098
|
-
* recipient: '8xYZA...',
|
|
1099
|
-
* pin: '123456',
|
|
1100
|
-
* });
|
|
1101
|
-
* ```
|
|
1102
|
-
*/
|
|
1103
|
-
makePayment(options: MakePaymentOptions): Promise<PaymentResult$1>;
|
|
1104
|
-
/**
|
|
1105
|
-
* Get session key status
|
|
1106
|
-
*
|
|
1107
|
-
* @param sessionKeyId - UUID of the session key
|
|
1108
|
-
* @returns Current status including balance and expiry
|
|
1109
|
-
*/
|
|
1110
|
-
getStatus(sessionKeyId: string): Promise<SessionKeyInfo>;
|
|
1111
|
-
/**
|
|
1112
|
-
* Revoke a session key
|
|
1113
|
-
*
|
|
1114
|
-
* Permanently deactivates the session key. Cannot be undone.
|
|
1115
|
-
*
|
|
1116
|
-
* @param sessionKeyId - UUID of the session key to revoke
|
|
1117
|
-
*/
|
|
1118
|
-
revoke(sessionKeyId: string): Promise<void>;
|
|
1119
|
-
/**
|
|
1120
|
-
* Recover session key on new device
|
|
1121
|
-
*
|
|
1122
|
-
* Use this when moving to a new device with a recovery QR code.
|
|
1123
|
-
*
|
|
1124
|
-
* @param options - Recovery configuration
|
|
1125
|
-
*
|
|
1126
|
-
* @example
|
|
1127
|
-
* ```typescript
|
|
1128
|
-
* await zendfi.sessionKeys.recover({
|
|
1129
|
-
* sessionKeyId: 'uuid',
|
|
1130
|
-
* recoveryQR: '{"encryptedSessionKey":"..."}',
|
|
1131
|
-
* oldPin: '123456',
|
|
1132
|
-
* newPin: '654321',
|
|
1133
|
-
* });
|
|
1134
|
-
* ```
|
|
1135
|
-
*/
|
|
1136
|
-
recover(options: {
|
|
1137
|
-
sessionKeyId: string;
|
|
1138
|
-
recoveryQR: string;
|
|
1139
|
-
oldPin: string;
|
|
1140
|
-
newPin: string;
|
|
1141
|
-
}): Promise<void>;
|
|
1142
|
-
/**
|
|
1143
|
-
* Clear cached keypair for a session key
|
|
1144
|
-
*
|
|
1145
|
-
* Use this on logout or when session ends.
|
|
1146
|
-
*
|
|
1147
|
-
* @param sessionKeyId - UUID of the session key (or all if not specified)
|
|
1148
|
-
*/
|
|
1149
|
-
clearCache(sessionKeyId?: string): void;
|
|
1150
|
-
/**
|
|
1151
|
-
* Check if a session key is cached (unlocked)
|
|
1152
|
-
*
|
|
1153
|
-
* @param sessionKeyId - UUID of the session key
|
|
1154
|
-
* @returns True if keypair is cached and auto-signing is enabled
|
|
1155
|
-
*/
|
|
1156
|
-
isCached(sessionKeyId: string): boolean;
|
|
1157
|
-
/**
|
|
1158
|
-
* Get time remaining until cache expires
|
|
1159
|
-
*
|
|
1160
|
-
* @param sessionKeyId - UUID of the session key
|
|
1161
|
-
* @returns Milliseconds until cache expires
|
|
1162
|
-
*/
|
|
1163
|
-
getCacheTimeRemaining(sessionKeyId: string): number;
|
|
1164
|
-
/**
|
|
1165
|
-
* Extend cache expiry time
|
|
1166
|
-
*
|
|
1167
|
-
* Useful to keep session active during user activity.
|
|
1168
|
-
*
|
|
1169
|
-
* @param sessionKeyId - UUID of the session key
|
|
1170
|
-
* @param additionalTTL - Additional time in milliseconds
|
|
1171
|
-
*/
|
|
1172
|
-
extendCache(sessionKeyId: string, additionalTTL: number): void;
|
|
1173
|
-
/**
|
|
1174
|
-
* Get all loaded session key IDs
|
|
1175
|
-
*
|
|
1176
|
-
* @returns Array of session key UUIDs currently loaded
|
|
1177
|
-
*/
|
|
1178
|
-
getLoadedSessionKeys(): string[];
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
/**
|
|
1182
|
-
* ZendFi SDK Client.
|
|
1183
|
-
* AZero-config TypeScript SDK for crypto payments
|
|
1184
|
-
*/
|
|
1185
|
-
declare class ZendFiClient {
|
|
1186
|
-
private config;
|
|
1187
|
-
readonly interceptors: Interceptors;
|
|
1188
|
-
/**
|
|
1189
|
-
* Agent API - Manage agent API keys and sessions
|
|
1190
|
-
*
|
|
1191
|
-
* @example
|
|
1192
|
-
* ```typescript
|
|
1193
|
-
* // Create an agent API key
|
|
1194
|
-
* const agentKey = await zendfi.agent.createKey({
|
|
1195
|
-
* name: 'Shopping Assistant',
|
|
1196
|
-
* agent_id: 'shopping-assistant-v1',
|
|
1197
|
-
* scopes: ['create_payments'],
|
|
1198
|
-
* });
|
|
1199
|
-
*
|
|
1200
|
-
* // Create an agent session
|
|
1201
|
-
* const session = await zendfi.agent.createSession({
|
|
1202
|
-
* agent_id: 'shopping-assistant-v1',
|
|
1203
|
-
* user_wallet: 'Hx7B...abc',
|
|
1204
|
-
* limits: { max_per_day: 500 },
|
|
1205
|
-
* });
|
|
1206
|
-
* ```
|
|
1207
|
-
*/
|
|
1208
|
-
readonly agent: AgentAPI;
|
|
1209
|
-
/**
|
|
1210
|
-
* Payment Intents API - Two-phase payment flow
|
|
1211
|
-
*
|
|
1212
|
-
* @example
|
|
1213
|
-
* ```typescript
|
|
1214
|
-
* // Create intent
|
|
1215
|
-
* const intent = await zendfi.intents.create({ amount: 99.99 });
|
|
1216
|
-
*
|
|
1217
|
-
* // Confirm when ready
|
|
1218
|
-
* await zendfi.intents.confirm(intent.id, {
|
|
1219
|
-
* client_secret: intent.client_secret,
|
|
1220
|
-
* customer_wallet: 'Hx7B...abc',
|
|
1221
|
-
* });
|
|
1222
|
-
* ```
|
|
1223
|
-
*/
|
|
1224
|
-
readonly intents: PaymentIntentsAPI;
|
|
1225
|
-
/**
|
|
1226
|
-
* Pricing API - PPP and AI-powered pricing
|
|
1227
|
-
*
|
|
1228
|
-
* @example
|
|
1229
|
-
* ```typescript
|
|
1230
|
-
* // Get PPP factor for Brazil
|
|
1231
|
-
* const factor = await zendfi.pricing.getPPPFactor('BR');
|
|
1232
|
-
* const localPrice = 100 * factor.ppp_factor; // $35 for Brazil
|
|
1233
|
-
*
|
|
1234
|
-
* // Get AI pricing suggestion
|
|
1235
|
-
* const suggestion = await zendfi.pricing.getSuggestion({
|
|
1236
|
-
* agent_id: 'my-agent',
|
|
1237
|
-
* base_price: 100,
|
|
1238
|
-
* user_profile: { location_country: 'BR' },
|
|
1239
|
-
* });
|
|
1240
|
-
* ```
|
|
1241
|
-
*/
|
|
1242
|
-
readonly pricing: PricingAPI;
|
|
1243
|
-
/**
|
|
1244
|
-
* Autonomy API - Enable autonomous agent signing
|
|
1245
|
-
*
|
|
1246
|
-
* @example
|
|
1247
|
-
* ```typescript
|
|
1248
|
-
* // Enable autonomous mode for a session key
|
|
1249
|
-
* const delegate = await zendfi.autonomy.enable(sessionKeyId, {
|
|
1250
|
-
* max_amount_usd: 100,
|
|
1251
|
-
* duration_hours: 24,
|
|
1252
|
-
* delegation_signature: signature,
|
|
1253
|
-
* });
|
|
1254
|
-
*
|
|
1255
|
-
* // Check status
|
|
1256
|
-
* const status = await zendfi.autonomy.getStatus(sessionKeyId);
|
|
1257
|
-
* ```
|
|
1258
|
-
*/
|
|
1259
|
-
readonly autonomy: AutonomyAPI;
|
|
1260
|
-
/**
|
|
1261
|
-
* Smart Payments API - AI-powered payment routing
|
|
1262
|
-
*
|
|
1263
|
-
* Create intelligent payments that automatically:
|
|
1264
|
-
* - Apply PPP discounts based on user location
|
|
1265
|
-
* - Use agent sessions when available
|
|
1266
|
-
* - Route to optimal payment paths
|
|
1267
|
-
*
|
|
1268
|
-
* @example
|
|
1269
|
-
* ```typescript
|
|
1270
|
-
* const payment = await zendfi.smart.create({
|
|
1271
|
-
* amount_usd: 99.99,
|
|
1272
|
-
* wallet_address: 'Hx7B...abc',
|
|
1273
|
-
* merchant_id: 'merch_123',
|
|
1274
|
-
* country_code: 'BR', // Apply PPP
|
|
1275
|
-
* enable_ppp: true,
|
|
1276
|
-
* });
|
|
1277
|
-
*
|
|
1278
|
-
* console.log(`Original: $${payment.original_amount_usd}`);
|
|
1279
|
-
* console.log(`Final: $${payment.final_amount_usd}`);
|
|
1280
|
-
* // Original: $99.99
|
|
1281
|
-
* // Final: $64.99 (35% PPP discount applied)
|
|
1282
|
-
* ```
|
|
1283
|
-
*/
|
|
1284
|
-
readonly smart: SmartPaymentsAPI;
|
|
1285
|
-
/**
|
|
1286
|
-
* Session Keys API - On-chain funded session keys with PKP identity
|
|
1287
|
-
*
|
|
1288
|
-
* Session keys are pre-funded wallets with spending limits that enable
|
|
1289
|
-
* AI agents to make autonomous payments without user signatures.
|
|
1290
|
-
*
|
|
1291
|
-
* The flow:
|
|
1292
|
-
* 1. Create a session key (user approves spending limit)
|
|
1293
|
-
* 2. User signs the approval transaction (one-time)
|
|
1294
|
-
* 3. Agent can now make payments up to the limit
|
|
1295
|
-
*
|
|
1296
|
-
* @example
|
|
1297
|
-
* ```typescript
|
|
1298
|
-
* // Create session key
|
|
1299
|
-
* const key = await zendfi.sessionKeys.create({
|
|
1300
|
-
* agent_id: 'shopping-bot',
|
|
1301
|
-
* user_wallet: 'Hx7B...abc',
|
|
1302
|
-
* max_amount: 100,
|
|
1303
|
-
* expiry_hours: 24,
|
|
1304
|
-
* });
|
|
1305
|
-
*
|
|
1306
|
-
* // User signs the approval
|
|
1307
|
-
* await zendfi.sessionKeys.submitApproval(key.session_key_id, {
|
|
1308
|
-
* signed_transaction: signedTx,
|
|
1309
|
-
* });
|
|
1310
|
-
*
|
|
1311
|
-
* // Check status
|
|
1312
|
-
* const status = await zendfi.sessionKeys.getStatus(key.session_key_id);
|
|
1313
|
-
* console.log(`Remaining: $${status.remaining_amount}`);
|
|
1314
|
-
* ```
|
|
1315
|
-
*/
|
|
1316
|
-
readonly sessionKeys: SessionKeysAPI;
|
|
1317
|
-
constructor(options?: Partial<ZendFiConfig>);
|
|
1318
|
-
/**
|
|
1319
|
-
* Create a new payment
|
|
1320
|
-
*/
|
|
1321
|
-
createPayment(request: CreatePaymentRequest): Promise<Payment>;
|
|
1322
|
-
/**
|
|
1323
|
-
* Get payment by ID
|
|
1324
|
-
*/
|
|
1325
|
-
getPayment(paymentId: string): Promise<Payment>;
|
|
1326
|
-
/**
|
|
1327
|
-
* List all payments with pagination
|
|
1328
|
-
*/
|
|
1329
|
-
listPayments(request?: ListPaymentsRequest): Promise<PaginatedResponse<Payment>>;
|
|
1330
|
-
/**
|
|
1331
|
-
* Create a subscription plan
|
|
1332
|
-
*/
|
|
1333
|
-
createSubscriptionPlan(request: CreateSubscriptionPlanRequest): Promise<SubscriptionPlan>;
|
|
1334
|
-
/**
|
|
1335
|
-
* Get subscription plan by ID
|
|
1336
|
-
*/
|
|
1337
|
-
getSubscriptionPlan(planId: string): Promise<SubscriptionPlan>;
|
|
1338
|
-
/**
|
|
1339
|
-
* Create a subscription
|
|
1340
|
-
*/
|
|
1341
|
-
createSubscription(request: CreateSubscriptionRequest): Promise<Subscription>;
|
|
1342
|
-
/**
|
|
1343
|
-
* Get subscription by ID
|
|
1344
|
-
*/
|
|
1345
|
-
getSubscription(subscriptionId: string): Promise<Subscription>;
|
|
1346
|
-
/**
|
|
1347
|
-
* Cancel a subscription
|
|
1348
|
-
*/
|
|
1349
|
-
cancelSubscription(subscriptionId: string): Promise<Subscription>;
|
|
1350
|
-
/**
|
|
1351
|
-
* Create a payment link (shareable checkout URL)
|
|
1352
|
-
*/
|
|
1353
|
-
createPaymentLink(request: CreatePaymentLinkRequest): Promise<PaymentLink>;
|
|
1354
|
-
/**
|
|
1355
|
-
* Get payment link by link code
|
|
1356
|
-
*/
|
|
1357
|
-
getPaymentLink(linkCode: string): Promise<PaymentLink>;
|
|
1358
|
-
/**
|
|
1359
|
-
* List all payment links for the authenticated merchant
|
|
1360
|
-
*/
|
|
1361
|
-
listPaymentLinks(): Promise<PaymentLink[]>;
|
|
1362
|
-
/**
|
|
1363
|
-
* Create an installment plan
|
|
1364
|
-
* Split a purchase into multiple scheduled payments
|
|
1365
|
-
*/
|
|
1366
|
-
createInstallmentPlan(request: CreateInstallmentPlanRequest): Promise<InstallmentPlan>;
|
|
1367
|
-
/**
|
|
1368
|
-
* Get installment plan by ID
|
|
1369
|
-
*/
|
|
1370
|
-
getInstallmentPlan(planId: string): Promise<InstallmentPlan>;
|
|
1371
|
-
/**
|
|
1372
|
-
* List all installment plans for merchant
|
|
1373
|
-
*/
|
|
1374
|
-
listInstallmentPlans(params?: {
|
|
1375
|
-
limit?: number;
|
|
1376
|
-
offset?: number;
|
|
1377
|
-
}): Promise<InstallmentPlan[]>;
|
|
1378
|
-
/**
|
|
1379
|
-
* List installment plans for a specific customer
|
|
1380
|
-
*/
|
|
1381
|
-
listCustomerInstallmentPlans(customerWallet: string): Promise<InstallmentPlan[]>;
|
|
1382
|
-
/**
|
|
1383
|
-
* Cancel an installment plan
|
|
1384
|
-
*/
|
|
1385
|
-
cancelInstallmentPlan(planId: string): Promise<{
|
|
1386
|
-
message: string;
|
|
1387
|
-
plan_id: string;
|
|
1388
|
-
}>;
|
|
1389
|
-
/**
|
|
1390
|
-
* Create an escrow transaction
|
|
1391
|
-
* Hold funds until conditions are met
|
|
1392
|
-
*/
|
|
1393
|
-
createEscrow(request: CreateEscrowRequest): Promise<Escrow>;
|
|
1394
|
-
/**
|
|
1395
|
-
* Get escrow by ID
|
|
1396
|
-
*/
|
|
1397
|
-
getEscrow(escrowId: string): Promise<Escrow>;
|
|
1398
|
-
/**
|
|
1399
|
-
* List all escrows for merchant
|
|
1400
|
-
*/
|
|
1401
|
-
listEscrows(params?: {
|
|
1402
|
-
limit?: number;
|
|
1403
|
-
offset?: number;
|
|
1404
|
-
}): Promise<Escrow[]>;
|
|
1405
|
-
/**
|
|
1406
|
-
* Approve escrow release to seller
|
|
1407
|
-
*/
|
|
1408
|
-
approveEscrow(escrowId: string, request: ApproveEscrowRequest): Promise<{
|
|
1409
|
-
status: string;
|
|
1410
|
-
transaction_signature?: string;
|
|
1411
|
-
message: string;
|
|
1412
|
-
}>;
|
|
1413
|
-
/**
|
|
1414
|
-
* Refund escrow to buyer
|
|
1415
|
-
*/
|
|
1416
|
-
refundEscrow(escrowId: string, request: RefundEscrowRequest): Promise<{
|
|
1417
|
-
status: string;
|
|
1418
|
-
transaction_signature: string;
|
|
1419
|
-
message: string;
|
|
1420
|
-
reason: string;
|
|
1421
|
-
}>;
|
|
1422
|
-
/**
|
|
1423
|
-
* Raise a dispute for an escrow
|
|
1424
|
-
*/
|
|
1425
|
-
disputeEscrow(escrowId: string, request: DisputeEscrowRequest): Promise<{
|
|
1426
|
-
status: string;
|
|
1427
|
-
message: string;
|
|
1428
|
-
dispute_id: string;
|
|
1429
|
-
created_at: string;
|
|
1430
|
-
}>;
|
|
1431
|
-
/**
|
|
1432
|
-
* Create an invoice
|
|
1433
|
-
*/
|
|
1434
|
-
createInvoice(request: CreateInvoiceRequest): Promise<Invoice>;
|
|
1435
|
-
/**
|
|
1436
|
-
* Get invoice by ID
|
|
1437
|
-
*/
|
|
1438
|
-
getInvoice(invoiceId: string): Promise<Invoice>;
|
|
1439
|
-
/**
|
|
1440
|
-
* List all invoices for merchant
|
|
1441
|
-
*/
|
|
1442
|
-
listInvoices(): Promise<Invoice[]>;
|
|
1443
|
-
/**
|
|
1444
|
-
* Send invoice to customer via email
|
|
1445
|
-
*/
|
|
1446
|
-
sendInvoice(invoiceId: string): Promise<{
|
|
1447
|
-
success: boolean;
|
|
1448
|
-
invoice_id: string;
|
|
1449
|
-
invoice_number: string;
|
|
1450
|
-
sent_to: string;
|
|
1451
|
-
payment_url: string;
|
|
1452
|
-
status: string;
|
|
1453
|
-
}>;
|
|
1454
|
-
/**
|
|
1455
|
-
* Execute an AI-powered smart payment
|
|
1456
|
-
*
|
|
1457
|
-
* Smart payments combine multiple features:
|
|
1458
|
-
* - Automatic PPP pricing adjustments
|
|
1459
|
-
* - Gasless transaction detection
|
|
1460
|
-
* - Instant settlement options
|
|
1461
|
-
* - Escrow integration
|
|
1462
|
-
* - Receipt generation
|
|
1463
|
-
*
|
|
1464
|
-
* @param request - Smart payment configuration
|
|
1465
|
-
* @returns Payment result with status and receipt
|
|
1466
|
-
*
|
|
1467
|
-
* @example
|
|
1468
|
-
* ```typescript
|
|
1469
|
-
* const result = await zendfi.smartPayment({
|
|
1470
|
-
* agent_id: 'shopping-assistant',
|
|
1471
|
-
* user_wallet: 'Hx7B...abc',
|
|
1472
|
-
* amount_usd: 50,
|
|
1473
|
-
* auto_detect_gasless: true,
|
|
1474
|
-
* description: 'Premium subscription',
|
|
1475
|
-
* });
|
|
1476
|
-
*
|
|
1477
|
-
* if (result.requires_signature) {
|
|
1478
|
-
* // Device-bound flow: user needs to sign
|
|
1479
|
-
* console.log('Sign and submit:', result.submit_url);
|
|
1480
|
-
* } else {
|
|
1481
|
-
* // Auto-signed
|
|
1482
|
-
* console.log('Payment complete:', result.transaction_signature);
|
|
1483
|
-
* }
|
|
1484
|
-
* ```
|
|
1485
|
-
*/
|
|
1486
|
-
smartPayment(request: SmartPaymentRequest): Promise<SmartPaymentResponse>;
|
|
1487
|
-
/**
|
|
1488
|
-
* Submit a signed transaction for device-bound smart payment
|
|
1489
|
-
*
|
|
1490
|
-
* @param paymentId - UUID of the payment
|
|
1491
|
-
* @param signedTransaction - Base64 encoded signed transaction
|
|
1492
|
-
* @returns Updated payment response
|
|
1493
|
-
*/
|
|
1494
|
-
submitSignedPayment(paymentId: string, signedTransaction: string): Promise<SmartPaymentResponse>;
|
|
1495
|
-
/**
|
|
1496
|
-
* Verify webhook signature using HMAC-SHA256
|
|
1497
|
-
*
|
|
1498
|
-
* @param request - Webhook verification request containing payload, signature, and secret
|
|
1499
|
-
* @returns true if signature is valid, false otherwise
|
|
1500
|
-
*
|
|
1501
|
-
* @example
|
|
1502
|
-
* ```typescript
|
|
1503
|
-
* const isValid = zendfi.verifyWebhook({
|
|
1504
|
-
* payload: req.body,
|
|
1505
|
-
* signature: req.headers['x-zendfi-signature'],
|
|
1506
|
-
* secret: process.env.ZENDFI_WEBHOOK_SECRET
|
|
1507
|
-
* });
|
|
1508
|
-
*
|
|
1509
|
-
* if (!isValid) {
|
|
1510
|
-
* return res.status(401).json({ error: 'Invalid signature' });
|
|
1511
|
-
* }
|
|
1512
|
-
* ```
|
|
1513
|
-
*/
|
|
1514
|
-
verifyWebhook(request: VerifyWebhookRequest): boolean;
|
|
1515
|
-
/**
|
|
1516
|
-
* Compute HMAC-SHA256 signature
|
|
1517
|
-
* Works in both Node.js and browser environments
|
|
1518
|
-
*/
|
|
1519
|
-
private computeHmacSignature;
|
|
1520
|
-
/**
|
|
1521
|
-
* Timing-safe string comparison to prevent timing attacks
|
|
1522
|
-
*/
|
|
1523
|
-
private timingSafeEqual;
|
|
1524
|
-
/**
|
|
1525
|
-
* Make an HTTP request with retry logic, interceptors, and debug logging
|
|
1526
|
-
*/
|
|
1527
|
-
private request;
|
|
1528
|
-
}
|
|
1529
|
-
/**
|
|
1530
|
-
* Default singleton instance
|
|
1531
|
-
* Auto-configured from environment
|
|
1532
|
-
*
|
|
1533
|
-
* Note: This will throw if ZENDFI_API_KEY is not set.
|
|
1534
|
-
* For custom configuration, create your own instance:
|
|
1535
|
-
* const client = new ZendFiClient({ apiKey: '...' })
|
|
1536
|
-
*/
|
|
1537
|
-
declare const zendfi: ZendFiClient;
|
|
1538
|
-
|
|
1539
|
-
/**
|
|
1540
|
-
* Configuration loader and environment detector
|
|
1541
|
-
*/
|
|
1542
|
-
declare class ConfigLoader {
|
|
1543
|
-
/**
|
|
1544
|
-
* Load configuration from various sources
|
|
1545
|
-
*/
|
|
1546
|
-
static load(options?: Partial<ZendFiConfig>): Required<ZendFiConfig>;
|
|
1547
|
-
/**
|
|
1548
|
-
* Detect mode (test/live) from API key prefix
|
|
1549
|
-
*/
|
|
1550
|
-
private static detectMode;
|
|
1551
|
-
/**
|
|
1552
|
-
* Detect environment based on various signals
|
|
1553
|
-
*/
|
|
1554
|
-
private static detectEnvironment;
|
|
1555
|
-
/**
|
|
1556
|
-
* Load API key from various sources
|
|
1557
|
-
*/
|
|
1558
|
-
private static loadApiKey;
|
|
1559
|
-
/**
|
|
1560
|
-
* Get base URL for API
|
|
1561
|
-
* Note: Both test and live modes use the same API endpoint.
|
|
1562
|
-
* The backend routes requests to devnet or mainnet based on API key prefix.
|
|
1563
|
-
*/
|
|
1564
|
-
private static getBaseURL;
|
|
1565
|
-
/**
|
|
1566
|
-
* Load credentials from CLI config file (~/.zendfi/credentials.json)
|
|
1567
|
-
*/
|
|
1568
|
-
private static loadCLICredentials;
|
|
1569
|
-
/**
|
|
1570
|
-
* Validate API key format
|
|
1571
|
-
*/
|
|
1572
|
-
static validateApiKey(apiKey: string): void;
|
|
1573
|
-
}
|
|
1574
|
-
/**
|
|
1575
|
-
* Generate idempotency key
|
|
1576
|
-
*/
|
|
1577
|
-
declare function generateIdempotencyKey(): string;
|
|
1578
|
-
/**
|
|
1579
|
-
* Sleep utility for retry backoff
|
|
1580
|
-
*/
|
|
1581
|
-
declare function sleep(ms: number): Promise<void>;
|
|
1582
|
-
/**
|
|
1583
|
-
* Client-side rate limiter to prevent hitting API rate limits
|
|
1584
|
-
*
|
|
1585
|
-
* @example
|
|
1586
|
-
* ```typescript
|
|
1587
|
-
* const limiter = new RateLimiter({
|
|
1588
|
-
* maxRequests: 100,
|
|
1589
|
-
* windowMs: 60000, // 100 requests per minute
|
|
1590
|
-
* });
|
|
1591
|
-
*
|
|
1592
|
-
* if (limiter.canMakeRequest()) {
|
|
1593
|
-
* limiter.recordRequest();
|
|
1594
|
-
* await zendfi.createPayment({ amount: 50 });
|
|
1595
|
-
* } else {
|
|
1596
|
-
* const waitTime = limiter.getTimeUntilReset();
|
|
1597
|
-
* console.log(`Rate limited. Try again in ${waitTime}ms`);
|
|
1598
|
-
* }
|
|
1599
|
-
* ```
|
|
1600
|
-
*/
|
|
1601
|
-
declare class RateLimiter {
|
|
1602
|
-
private requests;
|
|
1603
|
-
private maxRequests;
|
|
1604
|
-
private windowMs;
|
|
1605
|
-
constructor(options?: {
|
|
1606
|
-
maxRequests?: number;
|
|
1607
|
-
windowMs?: number;
|
|
1608
|
-
});
|
|
1609
|
-
/**
|
|
1610
|
-
* Check if a request can be made without exceeding rate limit
|
|
1611
|
-
*/
|
|
1612
|
-
canMakeRequest(): boolean;
|
|
1613
|
-
/**
|
|
1614
|
-
* Record a request timestamp
|
|
1615
|
-
*/
|
|
1616
|
-
recordRequest(): void;
|
|
1617
|
-
/**
|
|
1618
|
-
* Get remaining requests in current window
|
|
1619
|
-
*/
|
|
1620
|
-
getRemainingRequests(): number;
|
|
1621
|
-
/**
|
|
1622
|
-
* Get time in ms until the rate limit window resets
|
|
1623
|
-
*/
|
|
1624
|
-
getTimeUntilReset(): number;
|
|
1625
|
-
/**
|
|
1626
|
-
* Get current rate limit status
|
|
1627
|
-
*/
|
|
1628
|
-
getStatus(): {
|
|
1629
|
-
remaining: number;
|
|
1630
|
-
limit: number;
|
|
1631
|
-
resetInMs: number;
|
|
1632
|
-
isLimited: boolean;
|
|
1633
|
-
};
|
|
1634
|
-
/**
|
|
1635
|
-
* Reset the rate limiter (useful for testing)
|
|
1636
|
-
*/
|
|
1637
|
-
reset(): void;
|
|
1638
|
-
private pruneOldRequests;
|
|
1639
|
-
}
|
|
1640
|
-
|
|
1641
|
-
/**
|
|
1642
|
-
* Webhook Verification Helpers
|
|
1643
|
-
* Convenience functions for common frameworks
|
|
1644
|
-
*/
|
|
1645
|
-
|
|
1646
|
-
/**
|
|
1647
|
-
* Verify and parse webhook for Next.js API routes
|
|
1648
|
-
*
|
|
1649
|
-
* @example
|
|
1650
|
-
* ```typescript
|
|
1651
|
-
* // app/api/webhooks/zendfi/route.ts
|
|
1652
|
-
* import { verifyNextWebhook } from '@zendfi/sdk/webhooks';
|
|
1653
|
-
*
|
|
1654
|
-
* export async function POST(request: Request) {
|
|
1655
|
-
* const webhook = await verifyNextWebhook(request);
|
|
1656
|
-
*
|
|
1657
|
-
* if (!webhook) {
|
|
1658
|
-
* return new Response('Invalid signature', { status: 401 });
|
|
1659
|
-
* }
|
|
1660
|
-
*
|
|
1661
|
-
* // Process webhook
|
|
1662
|
-
* switch (webhook.event) {
|
|
1663
|
-
* case 'payment.confirmed':
|
|
1664
|
-
* // Handle payment
|
|
1665
|
-
* break;
|
|
1666
|
-
* }
|
|
1667
|
-
*
|
|
1668
|
-
* return new Response('OK');
|
|
1669
|
-
* }
|
|
1670
|
-
* ```
|
|
1671
|
-
*/
|
|
1672
|
-
declare function verifyNextWebhook(request: Request, secret?: string): Promise<WebhookPayload | null>;
|
|
1673
|
-
/**
|
|
1674
|
-
* Verify and parse webhook for Express.js
|
|
1675
|
-
*
|
|
1676
|
-
* @example
|
|
1677
|
-
* ```typescript
|
|
1678
|
-
* import { verifyExpressWebhook } from '@zendfi/sdk/webhooks';
|
|
1679
|
-
*
|
|
1680
|
-
* app.post('/webhooks/zendfi', async (req, res) => {
|
|
1681
|
-
* const webhook = await verifyExpressWebhook(req);
|
|
1682
|
-
*
|
|
1683
|
-
* if (!webhook) {
|
|
1684
|
-
* return res.status(401).json({ error: 'Invalid signature' });
|
|
1685
|
-
* }
|
|
1686
|
-
*
|
|
1687
|
-
* // Process webhook
|
|
1688
|
-
* console.log('Event:', webhook.event);
|
|
1689
|
-
*
|
|
1690
|
-
* res.json({ received: true });
|
|
1691
|
-
* });
|
|
1692
|
-
* ```
|
|
1693
|
-
*/
|
|
1694
|
-
declare function verifyExpressWebhook(request: any, secret?: string): Promise<WebhookPayload | null>;
|
|
1695
|
-
/**
|
|
1696
|
-
* Verify webhook signature manually
|
|
1697
|
-
* Use this for custom integrations
|
|
1698
|
-
*
|
|
1699
|
-
* @example
|
|
1700
|
-
* ```typescript
|
|
1701
|
-
* import { verifyWebhookSignature } from '@zendfi/sdk/webhooks';
|
|
1702
|
-
*
|
|
1703
|
-
* const isValid = verifyWebhookSignature(
|
|
1704
|
-
* payloadString,
|
|
1705
|
-
* signatureHeader,
|
|
1706
|
-
* process.env.ZENDFI_WEBHOOK_SECRET
|
|
1707
|
-
* );
|
|
1708
|
-
* ```
|
|
1709
|
-
*/
|
|
1710
|
-
declare function verifyWebhookSignature(payload: string, signature: string, secret: string): boolean;
|
|
1711
|
-
|
|
1712
|
-
/**
|
|
1713
|
-
* ZendFi Embedded Checkout
|
|
1714
|
-
*
|
|
1715
|
-
* Embed the ZendFi checkout directly into your website/app
|
|
1716
|
-
* without redirecting to checkout.zendfi.tech
|
|
1717
|
-
*
|
|
1718
|
-
* @example
|
|
1719
|
-
* ```typescript
|
|
1720
|
-
* import { ZendFiEmbeddedCheckout } from '@zendfi/sdk';
|
|
1721
|
-
*
|
|
1722
|
-
* const checkout = new ZendFiEmbeddedCheckout({
|
|
1723
|
-
* linkCode: 'abc123xyz',
|
|
1724
|
-
* containerId: 'zendfi-checkout',
|
|
1725
|
-
* mode: 'live',
|
|
1726
|
-
* onSuccess: (payment) => {
|
|
1727
|
-
* console.log('Payment successful!', payment);
|
|
1728
|
-
* },
|
|
1729
|
-
* onError: (error) => {
|
|
1730
|
-
* console.error('Payment failed:', error);
|
|
1731
|
-
* }
|
|
1732
|
-
* });
|
|
1733
|
-
*
|
|
1734
|
-
* checkout.mount();
|
|
1735
|
-
* ```
|
|
1736
|
-
*/
|
|
1737
|
-
|
|
1738
|
-
interface EmbeddedCheckoutConfig {
|
|
1739
|
-
/** Payment link code or payment ID */
|
|
1740
|
-
linkCode?: string;
|
|
1741
|
-
paymentId?: string;
|
|
1742
|
-
/** Container element ID where checkout will be mounted */
|
|
1743
|
-
containerId: string;
|
|
1744
|
-
/** API mode - 'test' for devnet, 'live' for mainnet */
|
|
1745
|
-
mode?: ApiKeyMode;
|
|
1746
|
-
/** API base URL (defaults to production) */
|
|
1747
|
-
apiUrl?: string;
|
|
1748
|
-
/** Callback when payment is successful */
|
|
1749
|
-
onSuccess?: (payment: PaymentSuccessData) => void;
|
|
1750
|
-
/** Callback when payment fails */
|
|
1751
|
-
onError?: (error: CheckoutError) => void;
|
|
1752
|
-
/** Callback when checkout is loaded */
|
|
1753
|
-
onLoad?: () => void;
|
|
1754
|
-
/** Custom theme overrides */
|
|
1755
|
-
theme?: CheckoutTheme;
|
|
1756
|
-
/** Enable custom amount (Pay What You Want) */
|
|
1757
|
-
allowCustomAmount?: boolean;
|
|
1758
|
-
/** Show/hide specific payment methods */
|
|
1759
|
-
paymentMethods?: {
|
|
1760
|
-
walletConnect?: boolean;
|
|
1761
|
-
qrCode?: boolean;
|
|
1762
|
-
solanaWallet?: boolean;
|
|
1763
|
-
};
|
|
1764
|
-
}
|
|
1765
|
-
interface CheckoutTheme {
|
|
1766
|
-
primaryColor?: string;
|
|
1767
|
-
backgroundColor?: string;
|
|
1768
|
-
borderRadius?: string;
|
|
1769
|
-
fontFamily?: string;
|
|
1770
|
-
textColor?: string;
|
|
1771
|
-
buttonStyle?: 'solid' | 'outlined' | 'minimal';
|
|
1772
|
-
}
|
|
1773
|
-
interface PaymentSuccessData {
|
|
1774
|
-
paymentId: string;
|
|
1775
|
-
transactionSignature: string;
|
|
1776
|
-
amount: number;
|
|
1777
|
-
token: string;
|
|
1778
|
-
merchantName: string;
|
|
1779
|
-
}
|
|
1780
|
-
interface CheckoutError {
|
|
1781
|
-
code: string;
|
|
1782
|
-
message: string;
|
|
1783
|
-
details?: any;
|
|
1784
|
-
}
|
|
1785
|
-
/**
|
|
1786
|
-
* ZendFi Embedded Checkout Component
|
|
1787
|
-
*
|
|
1788
|
-
* Provides a fully-functional checkout experience that can be
|
|
1789
|
-
* embedded directly into any web application.
|
|
1790
|
-
*/
|
|
1791
|
-
declare class ZendFiEmbeddedCheckout {
|
|
1792
|
-
private config;
|
|
1793
|
-
private container;
|
|
1794
|
-
private checkoutData;
|
|
1795
|
-
private pollInterval;
|
|
1796
|
-
private mounted;
|
|
1797
|
-
private paymentProcessed;
|
|
1798
|
-
constructor(config: EmbeddedCheckoutConfig);
|
|
1799
|
-
private getDefaultApiUrl;
|
|
1800
|
-
/**
|
|
1801
|
-
* Mount the checkout to the DOM
|
|
1802
|
-
*/
|
|
1803
|
-
mount(): Promise<void>;
|
|
1804
|
-
/**
|
|
1805
|
-
* Unmount and cleanup
|
|
1806
|
-
*/
|
|
1807
|
-
unmount(): void;
|
|
1808
|
-
/**
|
|
1809
|
-
* Fetch checkout data from API
|
|
1810
|
-
*/
|
|
1811
|
-
private fetchCheckoutData;
|
|
1812
|
-
/**
|
|
1813
|
-
* Poll for payment confirmation
|
|
1814
|
-
*/
|
|
1815
|
-
private startPaymentPolling;
|
|
1816
|
-
/**
|
|
1817
|
-
* Handle successful payment
|
|
1818
|
-
*/
|
|
1819
|
-
private handlePaymentSuccess;
|
|
1820
|
-
/**
|
|
1821
|
-
* Handle payment failure
|
|
1822
|
-
*/
|
|
1823
|
-
private handlePaymentFailure;
|
|
1824
|
-
/**
|
|
1825
|
-
* Handle payment expiration
|
|
1826
|
-
*/
|
|
1827
|
-
private handlePaymentExpired;
|
|
1828
|
-
/**
|
|
1829
|
-
* Render loading state
|
|
1830
|
-
*/
|
|
1831
|
-
private renderLoading;
|
|
1832
|
-
/**
|
|
1833
|
-
* Render the main checkout UI
|
|
1834
|
-
*/
|
|
1835
|
-
private render;
|
|
1836
|
-
/**
|
|
1837
|
-
* Render header section
|
|
1838
|
-
*/
|
|
1839
|
-
private renderHeader;
|
|
1840
|
-
/**
|
|
1841
|
-
* Render payment information
|
|
1842
|
-
*/
|
|
1843
|
-
private renderPaymentInfo;
|
|
1844
|
-
/**
|
|
1845
|
-
* Render custom amount input (Pay What You Want)
|
|
1846
|
-
*/
|
|
1847
|
-
private renderCustomAmountInput;
|
|
1848
|
-
/**
|
|
1849
|
-
* Render payment methods
|
|
1850
|
-
*/
|
|
1851
|
-
private renderPaymentMethods;
|
|
1852
|
-
/**
|
|
1853
|
-
* Render QR code payment method
|
|
1854
|
-
*/
|
|
1855
|
-
private renderQRCodeMethod;
|
|
1856
|
-
/**
|
|
1857
|
-
* Render browser wallet method
|
|
1858
|
-
*/
|
|
1859
|
-
private renderWalletMethod;
|
|
1860
|
-
/**
|
|
1861
|
-
* Render WalletConnect method
|
|
1862
|
-
*/
|
|
1863
|
-
private renderWalletConnectMethod;
|
|
1864
|
-
/**
|
|
1865
|
-
* Render footer
|
|
1866
|
-
*/
|
|
1867
|
-
private renderFooter;
|
|
1868
|
-
/**
|
|
1869
|
-
* Render success state
|
|
1870
|
-
*/
|
|
1871
|
-
private renderSuccess;
|
|
1872
|
-
/**
|
|
1873
|
-
* Render error state
|
|
1874
|
-
*/
|
|
1875
|
-
private renderError;
|
|
1876
|
-
/**
|
|
1877
|
-
* Attach event listeners to interactive elements
|
|
1878
|
-
*/
|
|
1879
|
-
private attachEventListeners;
|
|
1880
|
-
/**
|
|
1881
|
-
* Handle wallet connection and payment
|
|
1882
|
-
*/
|
|
1883
|
-
private handleWalletConnect;
|
|
1884
|
-
/**
|
|
1885
|
-
* Handle mobile wallet connection via Solana Pay deep link
|
|
1886
|
-
*/
|
|
1887
|
-
private handleWalletConnectScan;
|
|
1888
|
-
/**
|
|
1889
|
-
* Generate QR code on canvas using QRious library
|
|
1890
|
-
*/
|
|
1891
|
-
private generateQRCode;
|
|
1892
|
-
/**
|
|
1893
|
-
* Inject custom styles
|
|
1894
|
-
*/
|
|
1895
|
-
private injectStyles;
|
|
1896
|
-
/**
|
|
1897
|
-
* Load external dependencies (QR code library, Solana web3.js)
|
|
1898
|
-
*/
|
|
1899
|
-
private loadDependencies;
|
|
1900
|
-
/**
|
|
1901
|
-
* Load external script
|
|
1902
|
-
*/
|
|
1903
|
-
private loadScript;
|
|
1904
|
-
/**
|
|
1905
|
-
* Get computed theme with defaults
|
|
1906
|
-
*/
|
|
1907
|
-
private getComputedTheme;
|
|
1908
|
-
/**
|
|
1909
|
-
* Style helpers
|
|
1910
|
-
*/
|
|
1911
|
-
private getCheckoutContainerStyles;
|
|
1912
|
-
private getLoadingStyles;
|
|
1913
|
-
private getSpinnerStyles;
|
|
1914
|
-
private getSuccessStyles;
|
|
1915
|
-
private getErrorStyles;
|
|
1916
|
-
}
|
|
1917
|
-
|
|
1918
|
-
/**
|
|
1919
|
-
* ZendFi SDK Error Classes
|
|
1920
|
-
*
|
|
1921
|
-
* Custom error types with helpful messages, error codes, and documentation links
|
|
1922
|
-
*/
|
|
1923
|
-
type ZendFiErrorType = 'authentication_error' | 'payment_error' | 'validation_error' | 'network_error' | 'rate_limit_error' | 'api_error' | 'webhook_error' | 'unknown_error';
|
|
1924
|
-
interface ZendFiErrorData {
|
|
1925
|
-
code: string;
|
|
1926
|
-
message: string;
|
|
1927
|
-
type: ZendFiErrorType;
|
|
1928
|
-
suggestion?: string;
|
|
1929
|
-
statusCode?: number;
|
|
1930
|
-
response?: unknown;
|
|
1931
|
-
}
|
|
1932
|
-
/**
|
|
1933
|
-
* Base ZendFi Error class with enhanced developer experience
|
|
1934
|
-
*/
|
|
1935
|
-
declare class ZendFiError extends Error {
|
|
1936
|
-
readonly code: string;
|
|
1937
|
-
readonly type: ZendFiErrorType;
|
|
1938
|
-
readonly suggestion?: string;
|
|
1939
|
-
readonly docs_url: string;
|
|
1940
|
-
readonly statusCode?: number;
|
|
1941
|
-
readonly response?: unknown;
|
|
1942
|
-
constructor(data: ZendFiErrorData);
|
|
1943
|
-
/**
|
|
1944
|
-
* Format error for display
|
|
1945
|
-
*/
|
|
1946
|
-
toString(): string;
|
|
1947
|
-
/**
|
|
1948
|
-
* Convert error to JSON
|
|
1949
|
-
*/
|
|
1950
|
-
toJSON(): Record<string, unknown>;
|
|
1951
|
-
}
|
|
1952
|
-
/**
|
|
1953
|
-
* Authentication errors
|
|
1954
|
-
*/
|
|
1955
|
-
declare class AuthenticationError extends ZendFiError {
|
|
1956
|
-
constructor(message: string, code?: string, suggestion?: string);
|
|
1957
|
-
}
|
|
1958
|
-
/**
|
|
1959
|
-
* Payment processing errors
|
|
1960
|
-
*/
|
|
1961
|
-
declare class PaymentError extends ZendFiError {
|
|
1962
|
-
constructor(message: string, code?: string, suggestion?: string);
|
|
1963
|
-
}
|
|
1964
|
-
/**
|
|
1965
|
-
* Validation errors
|
|
1966
|
-
*/
|
|
1967
|
-
declare class ValidationError extends ZendFiError {
|
|
1968
|
-
constructor(message: string, code?: string, suggestion?: string);
|
|
1969
|
-
}
|
|
1970
|
-
/**
|
|
1971
|
-
* Network/connection errors
|
|
1972
|
-
*/
|
|
1973
|
-
declare class NetworkError extends ZendFiError {
|
|
1974
|
-
constructor(message: string, code?: string, suggestion?: string);
|
|
1975
|
-
}
|
|
1976
|
-
/**
|
|
1977
|
-
* Rate limit errors
|
|
1978
|
-
*/
|
|
1979
|
-
declare class RateLimitError extends ZendFiError {
|
|
1980
|
-
constructor(message: string, retryAfter?: number);
|
|
1981
|
-
}
|
|
1982
|
-
/**
|
|
1983
|
-
* Generic API errors
|
|
1984
|
-
*/
|
|
1985
|
-
declare class ApiError extends ZendFiError {
|
|
1986
|
-
constructor(message: string, code: string, statusCode: number, response?: unknown);
|
|
1987
|
-
}
|
|
1988
|
-
/**
|
|
1989
|
-
* Webhook verification errors
|
|
1990
|
-
*/
|
|
1991
|
-
declare class WebhookError extends ZendFiError {
|
|
1992
|
-
constructor(message: string, code?: string, suggestion?: string);
|
|
1993
|
-
}
|
|
1994
|
-
/**
|
|
1995
|
-
* Error factory - creates appropriate error based on response
|
|
1996
|
-
*/
|
|
1997
|
-
declare function createZendFiError(statusCode: number, responseBody: any, message?: string): ZendFiError;
|
|
1998
|
-
/**
|
|
1999
|
-
* Common error codes and their messages
|
|
2000
|
-
*/
|
|
2001
|
-
declare const ERROR_CODES: {
|
|
2002
|
-
readonly INVALID_API_KEY: "invalid_api_key";
|
|
2003
|
-
readonly API_KEY_EXPIRED: "api_key_expired";
|
|
2004
|
-
readonly API_KEY_REVOKED: "api_key_revoked";
|
|
2005
|
-
readonly INSUFFICIENT_BALANCE: "insufficient_balance";
|
|
2006
|
-
readonly PAYMENT_DECLINED: "payment_declined";
|
|
2007
|
-
readonly PAYMENT_EXPIRED: "payment_expired";
|
|
2008
|
-
readonly INVALID_AMOUNT: "invalid_amount";
|
|
2009
|
-
readonly INVALID_CURRENCY: "invalid_currency";
|
|
2010
|
-
readonly MISSING_REQUIRED_FIELD: "missing_required_field";
|
|
2011
|
-
readonly INVALID_PARAMETER: "invalid_parameter";
|
|
2012
|
-
readonly NETWORK_ERROR: "network_error";
|
|
2013
|
-
readonly TIMEOUT: "timeout";
|
|
2014
|
-
readonly RATE_LIMIT_EXCEEDED: "rate_limit_exceeded";
|
|
2015
|
-
readonly WEBHOOK_SIGNATURE_INVALID: "webhook_signature_invalid";
|
|
2016
|
-
readonly WEBHOOK_TIMESTAMP_TOO_OLD: "webhook_timestamp_too_old";
|
|
2017
|
-
};
|
|
2018
|
-
/**
|
|
2019
|
-
* Helper to check if error is a ZendFi error
|
|
2020
|
-
*/
|
|
2021
|
-
declare function isZendFiError(error: unknown): error is ZendFiError;
|
|
2022
|
-
|
|
2023
|
-
/**
|
|
2024
|
-
* Device-Bound Session Keys - Client-Side Cryptography
|
|
2025
|
-
*
|
|
2026
|
-
* This module provides TRUE non-custodial session keys where:
|
|
2027
|
-
* - Client generates keypair (backend NEVER sees private key)
|
|
2028
|
-
* - Client encrypts with PIN + device fingerprint
|
|
2029
|
-
* - Backend stores encrypted blob (cannot decrypt!)
|
|
2030
|
-
* - Client decrypts for each payment
|
|
2031
|
-
*
|
|
2032
|
-
* Security: Argon2id key derivation + AES-256-GCM encryption
|
|
2033
|
-
*
|
|
2034
|
-
* @module device-bound-crypto
|
|
2035
|
-
*/
|
|
2036
|
-
|
|
2037
|
-
interface DeviceFingerprint {
|
|
2038
|
-
/** SHA-256 hash of device attributes */
|
|
2039
|
-
fingerprint: string;
|
|
2040
|
-
/** Timestamp when fingerprint was generated */
|
|
2041
|
-
generatedAt: number;
|
|
2042
|
-
/** Raw components (for debugging) */
|
|
2043
|
-
components: {
|
|
2044
|
-
canvas?: string;
|
|
2045
|
-
webgl?: string;
|
|
2046
|
-
audio?: string;
|
|
2047
|
-
screen?: string;
|
|
2048
|
-
timezone?: string;
|
|
2049
|
-
languages?: string;
|
|
2050
|
-
platform?: string;
|
|
2051
|
-
hardwareConcurrency?: string;
|
|
2052
|
-
};
|
|
2053
|
-
}
|
|
2054
|
-
interface EncryptedSessionKey {
|
|
2055
|
-
/** Base64 encoded encrypted private key */
|
|
2056
|
-
encryptedData: string;
|
|
2057
|
-
/** Base64 encoded nonce (12 bytes) */
|
|
2058
|
-
nonce: string;
|
|
2059
|
-
/** Solana public key (base58) */
|
|
2060
|
-
publicKey: string;
|
|
2061
|
-
/** Device fingerprint hash */
|
|
2062
|
-
deviceFingerprint: string;
|
|
2063
|
-
/** Encryption algorithm version */
|
|
2064
|
-
version: 'argon2id-aes256gcm-v1';
|
|
2065
|
-
}
|
|
2066
|
-
interface RecoveryQR {
|
|
2067
|
-
/** Base64 encoded encrypted session key */
|
|
2068
|
-
encryptedSessionKey: string;
|
|
2069
|
-
/** Base64 encoded nonce */
|
|
2070
|
-
nonce: string;
|
|
2071
|
-
/** Public key */
|
|
2072
|
-
publicKey: string;
|
|
2073
|
-
/** Recovery QR version */
|
|
2074
|
-
version: string;
|
|
2075
|
-
/** Timestamp */
|
|
2076
|
-
createdAt: number;
|
|
2077
|
-
}
|
|
2078
|
-
interface DeviceBoundSessionKeyOptions {
|
|
2079
|
-
/** 6-digit numeric PIN */
|
|
2080
|
-
pin: string;
|
|
2081
|
-
/** Spending limit in USD */
|
|
2082
|
-
limitUSDC: number;
|
|
2083
|
-
/** Duration in days */
|
|
2084
|
-
durationDays: number;
|
|
2085
|
-
/** User's wallet address */
|
|
2086
|
-
userWallet: string;
|
|
2087
|
-
/** Generate recovery QR (recommended) */
|
|
2088
|
-
generateRecoveryQR?: boolean;
|
|
2089
|
-
}
|
|
2090
|
-
declare class DeviceFingerprintGenerator {
|
|
2091
|
-
/**
|
|
2092
|
-
* Generate a unique device fingerprint
|
|
2093
|
-
* Combines multiple browser attributes for uniqueness
|
|
2094
|
-
*/
|
|
2095
|
-
static generate(): Promise<DeviceFingerprint>;
|
|
2096
|
-
/**
|
|
2097
|
-
* Graceful fallback fingerprint generation
|
|
2098
|
-
* Works in headless browsers, SSR, and restricted environments
|
|
2099
|
-
*/
|
|
2100
|
-
private static generateFallbackFingerprint;
|
|
2101
|
-
private static getCanvasFingerprint;
|
|
2102
|
-
private static getWebGLFingerprint;
|
|
2103
|
-
private static getAudioFingerprint;
|
|
2104
|
-
private static sha256;
|
|
2105
|
-
}
|
|
2106
|
-
declare class SessionKeyCrypto {
|
|
2107
|
-
/**
|
|
2108
|
-
* Encrypt a Solana keypair with PIN + device fingerprint
|
|
2109
|
-
* Uses Argon2id for key derivation and AES-256-GCM for encryption
|
|
2110
|
-
*/
|
|
2111
|
-
static encrypt(keypair: Keypair, pin: string, deviceFingerprint: string): Promise<EncryptedSessionKey>;
|
|
2112
|
-
/**
|
|
2113
|
-
* Decrypt an encrypted session key with PIN + device fingerprint
|
|
2114
|
-
*/
|
|
2115
|
-
static decrypt(encrypted: EncryptedSessionKey, pin: string, deviceFingerprint: string): Promise<Keypair>;
|
|
2116
|
-
/**
|
|
2117
|
-
* Derive encryption key from PIN + device fingerprint using Argon2id
|
|
2118
|
-
*
|
|
2119
|
-
* Argon2id parameters (OWASP recommended):
|
|
2120
|
-
* - Memory: 64MB (65536 KB)
|
|
2121
|
-
* - Iterations: 3
|
|
2122
|
-
* - Parallelism: 4
|
|
2123
|
-
* - Salt: device fingerprint
|
|
2124
|
-
*/
|
|
2125
|
-
private static deriveKey;
|
|
2126
|
-
/**
|
|
2127
|
-
* Generate random nonce for AES-GCM (12 bytes)
|
|
2128
|
-
*/
|
|
2129
|
-
private static generateNonce;
|
|
2130
|
-
/**
|
|
2131
|
-
* Encrypt with AES-256-GCM
|
|
2132
|
-
*/
|
|
2133
|
-
private static aesEncrypt;
|
|
2134
|
-
/**
|
|
2135
|
-
* Decrypt with AES-256-GCM
|
|
2136
|
-
*/
|
|
2137
|
-
private static aesDecrypt;
|
|
2138
|
-
}
|
|
2139
|
-
declare class RecoveryQRGenerator {
|
|
2140
|
-
/**
|
|
2141
|
-
* Generate recovery QR data
|
|
2142
|
-
* This allows users to recover their session key on a new device
|
|
2143
|
-
*/
|
|
2144
|
-
static generate(encrypted: EncryptedSessionKey): RecoveryQR;
|
|
2145
|
-
/**
|
|
2146
|
-
* Encode recovery QR as JSON string
|
|
2147
|
-
*/
|
|
2148
|
-
static encode(recoveryQR: RecoveryQR): string;
|
|
2149
|
-
/**
|
|
2150
|
-
* Decode recovery QR from JSON string
|
|
2151
|
-
*/
|
|
2152
|
-
static decode(qrData: string): RecoveryQR;
|
|
2153
|
-
/**
|
|
2154
|
-
* Re-encrypt session key for new device
|
|
2155
|
-
*/
|
|
2156
|
-
static reEncryptForNewDevice(recoveryQR: RecoveryQR, oldPin: string, oldDeviceFingerprint: string, newPin: string, newDeviceFingerprint: string): Promise<EncryptedSessionKey>;
|
|
2157
|
-
}
|
|
2158
|
-
declare class DeviceBoundSessionKey {
|
|
2159
|
-
private encrypted;
|
|
2160
|
-
private deviceFingerprint;
|
|
2161
|
-
private sessionKeyId;
|
|
2162
|
-
private recoveryQR;
|
|
2163
|
-
private originalKeypair;
|
|
2164
|
-
private cachedKeypair;
|
|
2165
|
-
private cacheExpiry;
|
|
2166
|
-
private readonly DEFAULT_CACHE_TTL_MS;
|
|
2167
|
-
/**
|
|
2168
|
-
* Create a new device-bound session key
|
|
2169
|
-
*/
|
|
2170
|
-
static create(options: DeviceBoundSessionKeyOptions): Promise<DeviceBoundSessionKey>;
|
|
2171
|
-
/**
|
|
2172
|
-
* Get the original keypair (only available immediately after creation)
|
|
2173
|
-
* Used for Lit Protocol encryption during session creation
|
|
2174
|
-
* @internal
|
|
2175
|
-
*/
|
|
2176
|
-
getKeypair(): Keypair;
|
|
2177
|
-
/**
|
|
2178
|
-
* Get encrypted data for backend storage
|
|
2179
|
-
*/
|
|
2180
|
-
getEncryptedData(): EncryptedSessionKey;
|
|
2181
|
-
/**
|
|
2182
|
-
* Get device fingerprint
|
|
2183
|
-
*/
|
|
2184
|
-
getDeviceFingerprint(): string;
|
|
2185
|
-
/**
|
|
2186
|
-
* Get public key
|
|
2187
|
-
*/
|
|
2188
|
-
getPublicKey(): string;
|
|
2189
|
-
/**
|
|
2190
|
-
* Get recovery QR data (if generated)
|
|
2191
|
-
*/
|
|
2192
|
-
getRecoveryQR(): RecoveryQR | null;
|
|
2193
|
-
/**
|
|
2194
|
-
* Decrypt and sign a transaction
|
|
2195
|
-
*
|
|
2196
|
-
* @param transaction - The transaction to sign
|
|
2197
|
-
* @param pin - User's PIN (required only if keypair not cached)
|
|
2198
|
-
* @param cacheKeypair - Whether to cache the decrypted keypair for future use (default: true)
|
|
2199
|
-
* @param cacheTTL - Cache time-to-live in milliseconds (default: 30 minutes)
|
|
2200
|
-
*
|
|
2201
|
-
* @example
|
|
2202
|
-
* ```typescript
|
|
2203
|
-
* // First payment: requires PIN, caches keypair
|
|
2204
|
-
* await sessionKey.signTransaction(tx1, '123456', true);
|
|
2205
|
-
*
|
|
2206
|
-
* // Subsequent payments: uses cached keypair, no PIN needed!
|
|
2207
|
-
* await sessionKey.signTransaction(tx2, '', false); // PIN ignored if cached
|
|
2208
|
-
*
|
|
2209
|
-
* // Clear cache when done
|
|
2210
|
-
* sessionKey.clearCache();
|
|
2211
|
-
* ```
|
|
2212
|
-
*/
|
|
2213
|
-
signTransaction(transaction: Transaction, pin?: string, cacheKeypair?: boolean, cacheTTL?: number): Promise<Transaction>;
|
|
2214
|
-
/**
|
|
2215
|
-
* Check if keypair is cached and valid
|
|
2216
|
-
*/
|
|
2217
|
-
isCached(): boolean;
|
|
2218
|
-
/**
|
|
2219
|
-
* Manually cache a keypair
|
|
2220
|
-
* Called internally after PIN decryption
|
|
2221
|
-
*/
|
|
2222
|
-
private cacheKeypair;
|
|
2223
|
-
/**
|
|
2224
|
-
* Clear cached keypair
|
|
2225
|
-
* Should be called when user logs out or session ends
|
|
2226
|
-
*
|
|
2227
|
-
* @example
|
|
2228
|
-
* ```typescript
|
|
2229
|
-
* // Clear cache on logout
|
|
2230
|
-
* sessionKey.clearCache();
|
|
2231
|
-
*
|
|
2232
|
-
* // Or clear automatically on tab close
|
|
2233
|
-
* window.addEventListener('beforeunload', () => {
|
|
2234
|
-
* sessionKey.clearCache();
|
|
2235
|
-
* });
|
|
2236
|
-
* ```
|
|
2237
|
-
*/
|
|
2238
|
-
clearCache(): void;
|
|
2239
|
-
/**
|
|
2240
|
-
* Decrypt and cache keypair without signing a transaction
|
|
2241
|
-
* Useful for pre-warming the cache before user makes payments
|
|
2242
|
-
*
|
|
2243
|
-
* @example
|
|
2244
|
-
* ```typescript
|
|
2245
|
-
* // After session key creation, decrypt and cache
|
|
2246
|
-
* await sessionKey.unlockWithPin('123456');
|
|
2247
|
-
*
|
|
2248
|
-
* // Now all subsequent payments are instant (no PIN)
|
|
2249
|
-
* await sessionKey.signTransaction(tx1, '', false); // Instant!
|
|
2250
|
-
* await sessionKey.signTransaction(tx2, '', false); // Instant!
|
|
2251
|
-
* ```
|
|
2252
|
-
*/
|
|
2253
|
-
unlockWithPin(pin: string, cacheTTL?: number): Promise<void>;
|
|
2254
|
-
/**
|
|
2255
|
-
* Get time remaining until cache expires (in milliseconds)
|
|
2256
|
-
* Returns 0 if not cached
|
|
2257
|
-
*/
|
|
2258
|
-
getCacheTimeRemaining(): number;
|
|
2259
|
-
/**
|
|
2260
|
-
* Extend cache expiry time
|
|
2261
|
-
* Useful to keep session active during user activity
|
|
2262
|
-
*
|
|
2263
|
-
* @example
|
|
2264
|
-
* ```typescript
|
|
2265
|
-
* // Extend cache by 15 minutes on each payment
|
|
2266
|
-
* await sessionKey.signTransaction(tx, '');
|
|
2267
|
-
* sessionKey.extendCache(15 * 60 * 1000);
|
|
2268
|
-
* ```
|
|
2269
|
-
*/
|
|
2270
|
-
extendCache(additionalTTL: number): void;
|
|
2271
|
-
/**
|
|
2272
|
-
* Set session key ID after backend creation
|
|
2273
|
-
*/
|
|
2274
|
-
setSessionKeyId(id: string): void;
|
|
2275
|
-
/**
|
|
2276
|
-
* Get session key ID
|
|
2277
|
-
*/
|
|
2278
|
-
getSessionKeyId(): string;
|
|
2279
|
-
}
|
|
2280
|
-
|
|
2281
|
-
/**
|
|
2282
|
-
* Lit Protocol PKP Session Identity Module
|
|
2283
|
-
*
|
|
2284
|
-
* ⚠️ STATUS: EXPERIMENTAL / AUDIT TRAIL ONLY
|
|
2285
|
-
*
|
|
2286
|
-
* This module provides client-side integration with Lit Protocol for
|
|
2287
|
-
* on-chain session identity. When a session has `mint_pkp: true`,
|
|
2288
|
-
* a PKP (Programmable Key Pair) is minted to create a blockchain-verified
|
|
2289
|
-
* session identity for audit and compliance purposes.
|
|
2290
|
-
*
|
|
2291
|
-
* ## Current Limitations
|
|
2292
|
-
*
|
|
2293
|
-
* **PKP Cannot Sign Solana Transactions**: Due to ECDSA vs Ed25519
|
|
2294
|
-
* incompatibility, PKPs cannot directly sign Solana transactions.
|
|
2295
|
-
* The PKP serves as an IDENTITY ANCHOR and AUDIT TRAIL only.
|
|
2296
|
-
*
|
|
2297
|
-
* **Spending Limits Are Server-Side**: All spending limit enforcement
|
|
2298
|
-
* happens in the backend via `validate_session_and_check_limits()`.
|
|
2299
|
-
* The PKP does NOT enforce spending limits cryptographically.
|
|
2300
|
-
*
|
|
2301
|
-
* ## What PKP Provides
|
|
2302
|
-
*
|
|
2303
|
-
* 1. **On-chain Identity**: Verifiable session identity on Lit Protocol
|
|
2304
|
-
* 2. **Audit Trail**: Immutable record of session creation
|
|
2305
|
-
* 3. **Future Extensibility**: Foundation for cross-chain identity
|
|
2306
|
-
*
|
|
2307
|
-
* ## Future Roadmap
|
|
2308
|
-
*
|
|
2309
|
-
* - Cross-chain identity verification
|
|
2310
|
-
* - Solana Ed25519 support in Lit Actions (pending Lit Protocol update)
|
|
2311
|
-
* - Decentralized spending limit enforcement
|
|
2312
|
-
*
|
|
2313
|
-
* @example
|
|
2314
|
-
* ```typescript
|
|
2315
|
-
* import { LitCryptoSigner, requiresLitSigning } from '@zendfi/sdk';
|
|
2316
|
-
*
|
|
2317
|
-
* // Check if session has PKP identity
|
|
2318
|
-
* if (session.mint_pkp) {
|
|
2319
|
-
* console.log('Session has on-chain identity:', session.pkp_address);
|
|
2320
|
-
* // Note: This is for audit purposes only, not for signing
|
|
2321
|
-
* }
|
|
2322
|
-
*
|
|
2323
|
-
* // Spending limits are enforced server-side automatically
|
|
2324
|
-
* // No client-side PKP interaction needed for payments
|
|
2325
|
-
* ```
|
|
2326
|
-
*
|
|
2327
|
-
* @module lit-crypto-signer
|
|
2328
|
-
* @experimental
|
|
2329
|
-
*/
|
|
2330
|
-
declare const SPENDING_LIMIT_ACTION_CID = "QmXXunoMeNhXhnr4onzBuvnMzDqH8rf1qdM94RKXayypX3";
|
|
2331
|
-
type LitNetwork = 'datil' | 'datil-test' | 'datil-dev';
|
|
2332
|
-
interface LitCryptoSignerConfig {
|
|
2333
|
-
network?: LitNetwork;
|
|
2334
|
-
apiEndpoint?: string;
|
|
2335
|
-
apiKey?: string;
|
|
2336
|
-
debug?: boolean;
|
|
2337
|
-
}
|
|
2338
|
-
interface SignPaymentParams {
|
|
2339
|
-
sessionId: string;
|
|
2340
|
-
amountUsd: number;
|
|
2341
|
-
transactionToSign: string;
|
|
2342
|
-
pkpPublicKey: string;
|
|
2343
|
-
merchantId?: string;
|
|
2344
|
-
sessionSigs?: any;
|
|
2345
|
-
}
|
|
2346
|
-
interface SignPaymentResult {
|
|
2347
|
-
success: boolean;
|
|
2348
|
-
signature?: string;
|
|
2349
|
-
publicKey?: string;
|
|
2350
|
-
recid?: number;
|
|
2351
|
-
sessionId?: string;
|
|
2352
|
-
amountUsd?: number;
|
|
2353
|
-
remainingBudget?: number;
|
|
2354
|
-
cryptoEnforced: boolean;
|
|
2355
|
-
error?: string;
|
|
2356
|
-
code?: string;
|
|
2357
|
-
currentSpent?: number;
|
|
2358
|
-
limit?: number;
|
|
2359
|
-
remaining?: number;
|
|
2360
|
-
}
|
|
2361
|
-
declare class LitCryptoSigner {
|
|
2362
|
-
private config;
|
|
2363
|
-
private litNodeClient;
|
|
2364
|
-
private connected;
|
|
2365
|
-
constructor(config?: LitCryptoSignerConfig);
|
|
2366
|
-
connect(): Promise<void>;
|
|
2367
|
-
disconnect(): Promise<void>;
|
|
2368
|
-
signPayment(params: SignPaymentParams): Promise<SignPaymentResult>;
|
|
2369
|
-
private getSessionSigs;
|
|
2370
|
-
private log;
|
|
2371
|
-
}
|
|
2372
|
-
/**
|
|
2373
|
-
* Helper function to check if a session has PKP identity
|
|
2374
|
-
* @deprecated Spending limits are enforced server-side. This checks for audit trail only.
|
|
2375
|
-
*/
|
|
2376
|
-
declare function requiresLitSigning(session: {
|
|
2377
|
-
crypto_enforced?: boolean;
|
|
2378
|
-
mint_pkp?: boolean;
|
|
2379
|
-
}): boolean;
|
|
2380
|
-
declare function encodeTransactionForLit(transaction: Uint8Array | Buffer): string;
|
|
2381
|
-
declare function decodeSignatureFromLit(result: SignPaymentResult): Uint8Array | null;
|
|
2382
|
-
|
|
2383
|
-
/**
|
|
2384
|
-
* Session Key Cache Manager
|
|
2385
|
-
* Optional caching utility for session key keypairs
|
|
2386
|
-
*
|
|
2387
|
-
* @example
|
|
2388
|
-
* ```typescript
|
|
2389
|
-
* import { SessionKeyCache } from '@zendfi/sdk/helpers';
|
|
2390
|
-
*
|
|
2391
|
-
* const cache = new SessionKeyCache({
|
|
2392
|
-
* storage: 'localStorage',
|
|
2393
|
-
* ttl: 3600000, // 1 hour
|
|
2394
|
-
* autoRefresh: true,
|
|
2395
|
-
* });
|
|
2396
|
-
*
|
|
2397
|
-
* // Get cached or decrypt
|
|
2398
|
-
* const keypair = await cache.getCached(sessionKeyId, async () => {
|
|
2399
|
-
* return await SessionKeyCrypto.decrypt(encrypted, pin, fingerprint);
|
|
2400
|
-
* });
|
|
2401
|
-
*
|
|
2402
|
-
* // Invalidate on logout
|
|
2403
|
-
* await cache.clear();
|
|
2404
|
-
* ```
|
|
2405
|
-
*/
|
|
2406
|
-
interface CachedKeypair {
|
|
2407
|
-
keypair: any;
|
|
2408
|
-
expiry: number;
|
|
2409
|
-
sessionKeyId: string;
|
|
2410
|
-
deviceFingerprint?: string;
|
|
2411
|
-
}
|
|
2412
|
-
interface SessionKeyCacheConfig {
|
|
2413
|
-
/** Storage backend */
|
|
2414
|
-
storage?: 'memory' | 'localStorage' | 'indexedDB' | CustomStorageAdapter;
|
|
2415
|
-
/** Time-to-live in milliseconds (default: 30 minutes) */
|
|
2416
|
-
ttl?: number;
|
|
2417
|
-
/** Auto-refresh before expiry (default: false) */
|
|
2418
|
-
autoRefresh?: boolean;
|
|
2419
|
-
/** Namespace for storage keys (default: 'zendfi_cache') */
|
|
2420
|
-
namespace?: string;
|
|
2421
|
-
/** Enable debug logging (default: false) */
|
|
2422
|
-
debug?: boolean;
|
|
2423
|
-
}
|
|
2424
|
-
interface CustomStorageAdapter {
|
|
2425
|
-
get(key: string): Promise<string | null>;
|
|
2426
|
-
set(key: string, value: string): Promise<void>;
|
|
2427
|
-
remove(key: string): Promise<void>;
|
|
2428
|
-
clear(): Promise<void>;
|
|
2429
|
-
}
|
|
2430
|
-
/**
|
|
2431
|
-
* Session Key Cache Manager
|
|
2432
|
-
* Provides flexible caching with multiple storage backends
|
|
2433
|
-
*/
|
|
2434
|
-
declare class SessionKeyCache {
|
|
2435
|
-
private memoryCache;
|
|
2436
|
-
private config;
|
|
2437
|
-
private refreshTimers;
|
|
2438
|
-
constructor(config?: SessionKeyCacheConfig);
|
|
2439
|
-
/**
|
|
2440
|
-
* Get cached keypair or decrypt and cache
|
|
2441
|
-
*/
|
|
2442
|
-
getCached(sessionKeyId: string, decryptFn: () => Promise<any>, options?: {
|
|
2443
|
-
deviceFingerprint?: string;
|
|
2444
|
-
}): Promise<any>;
|
|
2445
|
-
/**
|
|
2446
|
-
* Decrypt keypair and cache it
|
|
2447
|
-
*/
|
|
2448
|
-
private decryptAndCache;
|
|
2449
|
-
/**
|
|
2450
|
-
* Invalidate cached keypair
|
|
2451
|
-
*/
|
|
2452
|
-
invalidate(sessionKeyId: string): Promise<void>;
|
|
2453
|
-
/**
|
|
2454
|
-
* Clear all cached keypairs
|
|
2455
|
-
*/
|
|
2456
|
-
clear(): Promise<void>;
|
|
2457
|
-
/**
|
|
2458
|
-
* Get cache statistics
|
|
2459
|
-
*/
|
|
2460
|
-
getStats(): {
|
|
2461
|
-
size: number;
|
|
2462
|
-
entries: Array<{
|
|
2463
|
-
sessionKeyId: string;
|
|
2464
|
-
expiresIn: number;
|
|
2465
|
-
}>;
|
|
2466
|
-
};
|
|
2467
|
-
/**
|
|
2468
|
-
* Check if a session key is cached and valid
|
|
2469
|
-
*/
|
|
2470
|
-
isCached(sessionKeyId: string): boolean;
|
|
2471
|
-
/**
|
|
2472
|
-
* Update TTL for a cached session key
|
|
2473
|
-
*/
|
|
2474
|
-
extendTTL(sessionKeyId: string, additionalMs: number): Promise<boolean>;
|
|
2475
|
-
private getFromStorage;
|
|
2476
|
-
private setInStorage;
|
|
2477
|
-
private removeFromStorage;
|
|
2478
|
-
private clearStorage;
|
|
2479
|
-
private getFromIndexedDB;
|
|
2480
|
-
private setInIndexedDB;
|
|
2481
|
-
private removeFromIndexedDB;
|
|
2482
|
-
private clearIndexedDB;
|
|
2483
|
-
private serializeKeypair;
|
|
2484
|
-
private deserializeKeypair;
|
|
2485
|
-
private setupAutoRefresh;
|
|
2486
|
-
private getStorageKey;
|
|
2487
|
-
private log;
|
|
2488
|
-
}
|
|
2489
|
-
/**
|
|
2490
|
-
* Pre-configured cache instances for common use cases
|
|
2491
|
-
*/
|
|
2492
|
-
declare const QuickCaches: {
|
|
2493
|
-
/** Memory-only cache (30 minutes) */
|
|
2494
|
-
memory: () => SessionKeyCache;
|
|
2495
|
-
/** Persistent cache (1 hour, survives reload) */
|
|
2496
|
-
persistent: () => SessionKeyCache;
|
|
2497
|
-
/** Long-term cache (24 hours, IndexedDB) */
|
|
2498
|
-
longTerm: () => SessionKeyCache;
|
|
2499
|
-
/** Secure cache (5 minutes, memory-only) */
|
|
2500
|
-
secure: () => SessionKeyCache;
|
|
2501
|
-
};
|
|
2502
|
-
|
|
2503
|
-
/**
|
|
2504
|
-
* AI Intent Parser & Adapters
|
|
2505
|
-
* Parse natural language into payment intents
|
|
2506
|
-
*
|
|
2507
|
-
* @example
|
|
2508
|
-
* ```typescript
|
|
2509
|
-
* import { PaymentIntentParser, GeminiAdapter } from '@zendfi/sdk/helpers';
|
|
2510
|
-
*
|
|
2511
|
-
* // Parse AI response
|
|
2512
|
-
* const intent = PaymentIntentParser.parse(aiResponse);
|
|
2513
|
-
* if (intent?.action === 'payment') {
|
|
2514
|
-
* await zendfi.smartPayments.execute({
|
|
2515
|
-
* amount_usd: intent.amount,
|
|
2516
|
-
* description: intent.description,
|
|
2517
|
-
* });
|
|
2518
|
-
* }
|
|
2519
|
-
*
|
|
2520
|
-
* // Or use adapters
|
|
2521
|
-
* const gemini = new GeminiAdapter(apiKey);
|
|
2522
|
-
* const { text, intent } = await gemini.chat('Buy coffee for $5');
|
|
2523
|
-
* ```
|
|
2524
|
-
*/
|
|
2525
|
-
interface ParsedIntent {
|
|
2526
|
-
action: 'payment' | 'create_session' | 'check_balance' | 'check_status' | 'topup' | 'revoke' | 'enable_autonomy' | 'chat_only';
|
|
2527
|
-
amount?: number;
|
|
2528
|
-
description?: string;
|
|
2529
|
-
confidence: number;
|
|
2530
|
-
rawText: string;
|
|
2531
|
-
metadata?: Record<string, any>;
|
|
2532
|
-
}
|
|
2533
|
-
interface AICapabilities {
|
|
2534
|
-
createPayment?: boolean;
|
|
2535
|
-
createSessionKey?: boolean;
|
|
2536
|
-
checkBalance?: boolean;
|
|
2537
|
-
checkStatus?: boolean;
|
|
2538
|
-
topUpSession?: boolean;
|
|
2539
|
-
revokeSession?: boolean;
|
|
2540
|
-
enableAutonomy?: boolean;
|
|
2541
|
-
}
|
|
2542
|
-
/**
|
|
2543
|
-
* Payment Intent Parser
|
|
2544
|
-
* Extract payment information from natural language
|
|
2545
|
-
*/
|
|
2546
|
-
declare class PaymentIntentParser {
|
|
2547
|
-
/**
|
|
2548
|
-
* Parse natural language into structured intent
|
|
2549
|
-
*/
|
|
2550
|
-
static parse(text: string): ParsedIntent | null;
|
|
2551
|
-
/**
|
|
2552
|
-
* Generate system prompt for AI models
|
|
2553
|
-
*/
|
|
2554
|
-
static generateSystemPrompt(capabilities?: AICapabilities): string;
|
|
2555
|
-
private static containsPaymentKeywords;
|
|
2556
|
-
private static containsSessionKeywords;
|
|
2557
|
-
private static containsStatusKeywords;
|
|
2558
|
-
private static containsTopUpKeywords;
|
|
2559
|
-
private static containsRevokeKeywords;
|
|
2560
|
-
private static containsAutonomyKeywords;
|
|
2561
|
-
private static extractAmount;
|
|
2562
|
-
private static extractDescription;
|
|
2563
|
-
}
|
|
2564
|
-
interface AIResponse {
|
|
2565
|
-
text: string;
|
|
2566
|
-
intent: ParsedIntent | null;
|
|
2567
|
-
raw?: any;
|
|
2568
|
-
}
|
|
2569
|
-
/**
|
|
2570
|
-
* OpenAI GPT Adapter
|
|
2571
|
-
*/
|
|
2572
|
-
declare class OpenAIAdapter {
|
|
2573
|
-
private apiKey;
|
|
2574
|
-
private model;
|
|
2575
|
-
private capabilities?;
|
|
2576
|
-
constructor(apiKey: string, model?: string, capabilities?: AICapabilities | undefined);
|
|
2577
|
-
chat(message: string, conversationHistory?: Array<{
|
|
2578
|
-
role: string;
|
|
2579
|
-
content: string;
|
|
2580
|
-
}>): Promise<AIResponse>;
|
|
2581
|
-
}
|
|
2582
|
-
/**
|
|
2583
|
-
* Anthropic Claude Adapter
|
|
2584
|
-
*/
|
|
2585
|
-
declare class AnthropicAdapter {
|
|
2586
|
-
private apiKey;
|
|
2587
|
-
private model;
|
|
2588
|
-
private capabilities?;
|
|
2589
|
-
constructor(apiKey: string, model?: string, capabilities?: AICapabilities | undefined);
|
|
2590
|
-
chat(message: string, conversationHistory?: Array<{
|
|
2591
|
-
role: string;
|
|
2592
|
-
content: string;
|
|
2593
|
-
}>): Promise<AIResponse>;
|
|
2594
|
-
}
|
|
2595
|
-
/**
|
|
2596
|
-
* Google Gemini Adapter
|
|
2597
|
-
*/
|
|
2598
|
-
declare class GeminiAdapter {
|
|
2599
|
-
private apiKey;
|
|
2600
|
-
private model;
|
|
2601
|
-
private capabilities?;
|
|
2602
|
-
constructor(apiKey: string, model?: string, capabilities?: AICapabilities | undefined);
|
|
2603
|
-
chat(message: string): Promise<AIResponse>;
|
|
2604
|
-
}
|
|
2605
|
-
|
|
2606
|
-
/**
|
|
2607
|
-
* Wallet Connector
|
|
2608
|
-
* Simplifies integration with Solana wallets (Phantom, Solflare, Backpack, etc.)
|
|
2609
|
-
*
|
|
2610
|
-
* @example
|
|
2611
|
-
* ```typescript
|
|
2612
|
-
* import { WalletConnector } from '@zendfi/sdk/helpers';
|
|
2613
|
-
*
|
|
2614
|
-
* // Auto-detect and connect
|
|
2615
|
-
* const wallet = await WalletConnector.detectAndConnect();
|
|
2616
|
-
* console.log(`Connected: ${wallet.address}`);
|
|
2617
|
-
* console.log(`Provider: ${wallet.provider}`);
|
|
2618
|
-
*
|
|
2619
|
-
* // Sign transaction
|
|
2620
|
-
* const result = await wallet.signTransaction(transaction);
|
|
2621
|
-
*
|
|
2622
|
-
* // Disconnect
|
|
2623
|
-
* await wallet.disconnect();
|
|
2624
|
-
* ```
|
|
2625
|
-
*/
|
|
2626
|
-
interface ConnectedWallet {
|
|
2627
|
-
address: string;
|
|
2628
|
-
provider: 'phantom' | 'solflare' | 'backpack' | 'coinbase' | 'trust' | 'unknown';
|
|
2629
|
-
publicKey: any;
|
|
2630
|
-
signTransaction: (tx: any) => Promise<any>;
|
|
2631
|
-
signAllTransactions: (txs: any[]) => Promise<any[]>;
|
|
2632
|
-
signMessage: (message: Uint8Array) => Promise<{
|
|
2633
|
-
signature: Uint8Array;
|
|
2634
|
-
}>;
|
|
2635
|
-
disconnect: () => Promise<void>;
|
|
2636
|
-
isConnected: () => boolean;
|
|
2637
|
-
raw: any;
|
|
2638
|
-
}
|
|
2639
|
-
interface WalletConnectorConfig {
|
|
2640
|
-
/** Preferred wallet provider (if multiple detected) */
|
|
2641
|
-
preferredProvider?: 'phantom' | 'solflare' | 'backpack' | 'coinbase' | 'trust';
|
|
2642
|
-
/** Auto-connect on page load if previously connected */
|
|
2643
|
-
autoConnect?: boolean;
|
|
2644
|
-
/** Show connection UI if no wallet detected */
|
|
2645
|
-
showInstallPrompt?: boolean;
|
|
2646
|
-
/** Network (mainnet-beta, devnet, testnet) */
|
|
2647
|
-
network?: string;
|
|
2648
|
-
}
|
|
2649
|
-
/**
|
|
2650
|
-
* Wallet Connector
|
|
2651
|
-
* Detects and connects to Solana wallets
|
|
2652
|
-
*/
|
|
2653
|
-
declare class WalletConnector {
|
|
2654
|
-
private static connectedWallet;
|
|
2655
|
-
/**
|
|
2656
|
-
* Detect and connect to a Solana wallet
|
|
2657
|
-
*/
|
|
2658
|
-
static detectAndConnect(config?: WalletConnectorConfig): Promise<ConnectedWallet>;
|
|
2659
|
-
/**
|
|
2660
|
-
* Detect available Solana wallets
|
|
2661
|
-
*/
|
|
2662
|
-
static detectWallets(): Array<'phantom' | 'solflare' | 'backpack' | 'coinbase' | 'trust'>;
|
|
2663
|
-
/**
|
|
2664
|
-
* Connect to a specific wallet provider
|
|
2665
|
-
*/
|
|
2666
|
-
static connectToProvider(provider: 'phantom' | 'solflare' | 'backpack' | 'coinbase' | 'trust'): Promise<ConnectedWallet>;
|
|
2667
|
-
/**
|
|
2668
|
-
* Sign and submit a transaction
|
|
2669
|
-
*/
|
|
2670
|
-
static signAndSubmit(transaction: any, wallet: ConnectedWallet, connection: any): Promise<{
|
|
2671
|
-
signature: string;
|
|
2672
|
-
}>;
|
|
2673
|
-
/**
|
|
2674
|
-
* Get current connected wallet
|
|
2675
|
-
*/
|
|
2676
|
-
static getConnectedWallet(): ConnectedWallet | null;
|
|
2677
|
-
/**
|
|
2678
|
-
* Disconnect current wallet
|
|
2679
|
-
*/
|
|
2680
|
-
static disconnect(): Promise<void>;
|
|
2681
|
-
/**
|
|
2682
|
-
* Listen for wallet connection changes
|
|
2683
|
-
*/
|
|
2684
|
-
static onAccountChange(callback: (publicKey: any) => void): () => void;
|
|
2685
|
-
/**
|
|
2686
|
-
* Listen for wallet disconnection
|
|
2687
|
-
*/
|
|
2688
|
-
static onDisconnect(callback: () => void): () => void;
|
|
178
|
+
verifyWebhook(request: VerifyWebhookRequest): boolean;
|
|
2689
179
|
/**
|
|
2690
|
-
*
|
|
180
|
+
* Compute HMAC-SHA256 signature
|
|
181
|
+
* Works in both Node.js and browser environments
|
|
2691
182
|
*/
|
|
2692
|
-
private
|
|
183
|
+
private computeHmacSignature;
|
|
2693
184
|
/**
|
|
2694
|
-
*
|
|
185
|
+
* Timing-safe string comparison to prevent timing attacks
|
|
2695
186
|
*/
|
|
2696
|
-
|
|
187
|
+
private timingSafeEqual;
|
|
2697
188
|
/**
|
|
2698
|
-
*
|
|
189
|
+
* Make an HTTP request with retry logic, interceptors, and debug logging
|
|
2699
190
|
*/
|
|
2700
|
-
|
|
191
|
+
private request;
|
|
2701
192
|
}
|
|
2702
193
|
/**
|
|
2703
|
-
*
|
|
2704
|
-
*
|
|
2705
|
-
*/
|
|
2706
|
-
declare function createWalletHook(): () => {
|
|
2707
|
-
wallet: any;
|
|
2708
|
-
connecting: any;
|
|
2709
|
-
error: any;
|
|
2710
|
-
connect: (config?: WalletConnectorConfig) => Promise<void>;
|
|
2711
|
-
disconnect: () => Promise<void>;
|
|
2712
|
-
isConnected: boolean;
|
|
2713
|
-
};
|
|
2714
|
-
|
|
2715
|
-
/**
|
|
2716
|
-
* Security Utilities
|
|
2717
|
-
* PIN validation, rate limiting, and security best practices
|
|
2718
|
-
*
|
|
2719
|
-
* @example
|
|
2720
|
-
* ```typescript
|
|
2721
|
-
* import { PINValidator, PINRateLimiter } from '@zendfi/sdk/helpers';
|
|
2722
|
-
*
|
|
2723
|
-
* // Validate PIN
|
|
2724
|
-
* const validation = PINValidator.validate(pin);
|
|
2725
|
-
* if (!validation.valid) {
|
|
2726
|
-
* console.error(validation.errors);
|
|
2727
|
-
* }
|
|
194
|
+
* Default singleton instance
|
|
195
|
+
* Auto-configured from environment
|
|
2728
196
|
*
|
|
2729
|
-
*
|
|
2730
|
-
*
|
|
2731
|
-
* const
|
|
2732
|
-
* if (!attempt.allowed) {
|
|
2733
|
-
* console.log(`Locked out for ${attempt.lockoutSeconds}s`);
|
|
2734
|
-
* }
|
|
2735
|
-
* ```
|
|
197
|
+
* Note: This will throw if ZENDFI_API_KEY is not set.
|
|
198
|
+
* For custom configuration, create your own instance:
|
|
199
|
+
* const client = new ZendFiClient({ apiKey: '...' })
|
|
2736
200
|
*/
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
strength: 'weak' | 'medium' | 'strong';
|
|
2740
|
-
errors: string[];
|
|
2741
|
-
suggestions: string[];
|
|
2742
|
-
}
|
|
201
|
+
declare const zendfi: ZendFiClient;
|
|
202
|
+
|
|
2743
203
|
/**
|
|
2744
|
-
*
|
|
2745
|
-
* Validates PIN security and strength
|
|
204
|
+
* Configuration loader and environment detector
|
|
2746
205
|
*/
|
|
2747
|
-
declare class
|
|
206
|
+
declare class ConfigLoader {
|
|
2748
207
|
/**
|
|
2749
|
-
*
|
|
208
|
+
* Load configuration from various sources
|
|
2750
209
|
*/
|
|
2751
|
-
static
|
|
210
|
+
static load(options?: Partial<ZendFiConfig>): Required<ZendFiConfig>;
|
|
2752
211
|
/**
|
|
2753
|
-
*
|
|
212
|
+
* Detect mode (test/live) from API key prefix
|
|
2754
213
|
*/
|
|
2755
|
-
static
|
|
214
|
+
private static detectMode;
|
|
2756
215
|
/**
|
|
2757
|
-
*
|
|
216
|
+
* Detect environment based on various signals
|
|
2758
217
|
*/
|
|
2759
|
-
static
|
|
218
|
+
private static detectEnvironment;
|
|
2760
219
|
/**
|
|
2761
|
-
*
|
|
220
|
+
* Load API key from various sources
|
|
2762
221
|
*/
|
|
2763
|
-
private static
|
|
222
|
+
private static loadApiKey;
|
|
2764
223
|
/**
|
|
2765
|
-
*
|
|
224
|
+
* Get base URL for API
|
|
225
|
+
* Note: Both test and live modes use the same API endpoint.
|
|
226
|
+
* The backend routes requests to devnet or mainnet based on API key prefix.
|
|
2766
227
|
*/
|
|
2767
|
-
private static
|
|
228
|
+
private static getBaseURL;
|
|
2768
229
|
/**
|
|
2769
|
-
*
|
|
230
|
+
* Load credentials from CLI config file (~/.zendfi/credentials.json)
|
|
2770
231
|
*/
|
|
2771
|
-
private static
|
|
232
|
+
private static loadCLICredentials;
|
|
2772
233
|
/**
|
|
2773
|
-
*
|
|
2774
|
-
* Note: For device-bound keys, the PIN is used for key derivation, not storage
|
|
234
|
+
* Validate API key format
|
|
2775
235
|
*/
|
|
2776
|
-
static
|
|
236
|
+
static validateApiKey(apiKey: string): void;
|
|
2777
237
|
}
|
|
2778
238
|
/**
|
|
2779
|
-
*
|
|
2780
|
-
|
|
239
|
+
* Generate idempotency key
|
|
240
|
+
*/
|
|
241
|
+
declare function generateIdempotencyKey(): string;
|
|
242
|
+
/**
|
|
243
|
+
* Sleep utility for retry backoff
|
|
244
|
+
*/
|
|
245
|
+
declare function sleep(ms: number): Promise<void>;
|
|
246
|
+
/**
|
|
247
|
+
* Client-side rate limiter to prevent hitting API rate limits
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```typescript
|
|
251
|
+
* const limiter = new RateLimiter({
|
|
252
|
+
* maxRequests: 100,
|
|
253
|
+
* windowMs: 60000, // 100 requests per minute
|
|
254
|
+
* });
|
|
255
|
+
*
|
|
256
|
+
* if (limiter.canMakeRequest()) {
|
|
257
|
+
* limiter.recordRequest();
|
|
258
|
+
* await zendfi.createPayment({ amount: 50 });
|
|
259
|
+
* } else {
|
|
260
|
+
* const waitTime = limiter.getTimeUntilReset();
|
|
261
|
+
* console.log(`Rate limited. Try again in ${waitTime}ms`);
|
|
262
|
+
* }
|
|
263
|
+
* ```
|
|
2781
264
|
*/
|
|
2782
|
-
declare class
|
|
2783
|
-
private
|
|
2784
|
-
private
|
|
2785
|
-
private maxAttempts;
|
|
265
|
+
declare class RateLimiter {
|
|
266
|
+
private requests;
|
|
267
|
+
private maxRequests;
|
|
2786
268
|
private windowMs;
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
maxAttempts?: number;
|
|
269
|
+
constructor(options?: {
|
|
270
|
+
maxRequests?: number;
|
|
2790
271
|
windowMs?: number;
|
|
2791
|
-
lockoutMs?: number;
|
|
2792
272
|
});
|
|
2793
273
|
/**
|
|
2794
|
-
* Check if
|
|
2795
|
-
*/
|
|
2796
|
-
checkAttempt(sessionKeyId: string): Promise<{
|
|
2797
|
-
allowed: boolean;
|
|
2798
|
-
remainingAttempts: number;
|
|
2799
|
-
lockoutSeconds?: number;
|
|
2800
|
-
}>;
|
|
2801
|
-
/**
|
|
2802
|
-
* Record a failed attempt
|
|
274
|
+
* Check if a request can be made without exceeding rate limit
|
|
2803
275
|
*/
|
|
2804
|
-
|
|
276
|
+
canMakeRequest(): boolean;
|
|
2805
277
|
/**
|
|
2806
|
-
* Record a
|
|
278
|
+
* Record a request timestamp
|
|
2807
279
|
*/
|
|
2808
|
-
|
|
280
|
+
recordRequest(): void;
|
|
2809
281
|
/**
|
|
2810
|
-
* Get
|
|
282
|
+
* Get remaining requests in current window
|
|
2811
283
|
*/
|
|
2812
|
-
|
|
284
|
+
getRemainingRequests(): number;
|
|
2813
285
|
/**
|
|
2814
|
-
*
|
|
286
|
+
* Get time in ms until the rate limit window resets
|
|
2815
287
|
*/
|
|
2816
|
-
|
|
288
|
+
getTimeUntilReset(): number;
|
|
2817
289
|
/**
|
|
2818
|
-
*
|
|
290
|
+
* Get current rate limit status
|
|
2819
291
|
*/
|
|
2820
|
-
|
|
292
|
+
getStatus(): {
|
|
293
|
+
remaining: number;
|
|
294
|
+
limit: number;
|
|
295
|
+
resetInMs: number;
|
|
296
|
+
isLimited: boolean;
|
|
297
|
+
};
|
|
2821
298
|
/**
|
|
2822
|
-
*
|
|
299
|
+
* Reset the rate limiter (useful for testing)
|
|
2823
300
|
*/
|
|
2824
|
-
|
|
301
|
+
reset(): void;
|
|
302
|
+
private pruneOldRequests;
|
|
2825
303
|
}
|
|
304
|
+
|
|
2826
305
|
/**
|
|
2827
|
-
*
|
|
2828
|
-
*
|
|
306
|
+
* Webhook Verification Helpers
|
|
307
|
+
* Convenience functions for common frameworks
|
|
2829
308
|
*/
|
|
2830
|
-
declare class SecureStorage {
|
|
2831
|
-
/**
|
|
2832
|
-
* Store data with encryption (basic)
|
|
2833
|
-
* For production, consider using Web Crypto API with user-derived keys
|
|
2834
|
-
*/
|
|
2835
|
-
static setEncrypted(key: string, value: string, secret: string): Promise<void>;
|
|
2836
|
-
/**
|
|
2837
|
-
* Retrieve encrypted data
|
|
2838
|
-
*/
|
|
2839
|
-
static getEncrypted(key: string, secret: string): Promise<string | null>;
|
|
2840
|
-
/**
|
|
2841
|
-
* Encrypt string with AES-GCM
|
|
2842
|
-
*/
|
|
2843
|
-
private static encrypt;
|
|
2844
|
-
/**
|
|
2845
|
-
* Decrypt AES-GCM ciphertext
|
|
2846
|
-
*/
|
|
2847
|
-
private static decrypt;
|
|
2848
|
-
/**
|
|
2849
|
-
* Derive encryption key from secret
|
|
2850
|
-
*/
|
|
2851
|
-
private static deriveKey;
|
|
2852
|
-
/**
|
|
2853
|
-
* Clear all secure storage
|
|
2854
|
-
*/
|
|
2855
|
-
static clearAll(namespace?: string): void;
|
|
2856
|
-
}
|
|
2857
309
|
|
|
2858
310
|
/**
|
|
2859
|
-
*
|
|
2860
|
-
* Poll Solana transactions with exponential backoff
|
|
311
|
+
* Verify and parse webhook for Next.js API routes
|
|
2861
312
|
*
|
|
2862
313
|
* @example
|
|
2863
314
|
* ```typescript
|
|
2864
|
-
*
|
|
315
|
+
* // app/api/webhooks/zendfi/route.ts
|
|
316
|
+
* import { verifyNextWebhook } from '@zendfi/sdk/webhooks';
|
|
2865
317
|
*
|
|
2866
|
-
*
|
|
2867
|
-
*
|
|
2868
|
-
*
|
|
2869
|
-
*
|
|
2870
|
-
* );
|
|
318
|
+
* export async function POST(request: Request) {
|
|
319
|
+
* const webhook = await verifyNextWebhook(request);
|
|
320
|
+
*
|
|
321
|
+
* if (!webhook) {
|
|
322
|
+
* return new Response('Invalid signature', { status: 401 });
|
|
323
|
+
* }
|
|
324
|
+
*
|
|
325
|
+
* // Process webhook
|
|
326
|
+
* switch (webhook.event) {
|
|
327
|
+
* case 'payment.confirmed':
|
|
328
|
+
* // Handle payment
|
|
329
|
+
* break;
|
|
330
|
+
* }
|
|
2871
331
|
*
|
|
2872
|
-
*
|
|
2873
|
-
* console.log(`Confirmed in slot ${status.slot}`);
|
|
332
|
+
* return new Response('OK');
|
|
2874
333
|
* }
|
|
2875
334
|
* ```
|
|
2876
335
|
*/
|
|
2877
|
-
|
|
2878
|
-
confirmed: boolean;
|
|
2879
|
-
signature: string;
|
|
2880
|
-
slot?: number;
|
|
2881
|
-
blockTime?: number;
|
|
2882
|
-
confirmations?: number;
|
|
2883
|
-
error?: string;
|
|
2884
|
-
}
|
|
2885
|
-
interface PollingOptions {
|
|
2886
|
-
/** Maximum time to wait in ms (default: 60000 = 1 minute) */
|
|
2887
|
-
timeout?: number;
|
|
2888
|
-
/** Initial polling interval in ms (default: 2000 = 2 seconds) */
|
|
2889
|
-
interval?: number;
|
|
2890
|
-
/** Maximum polling interval in ms (default: 10000 = 10 seconds) */
|
|
2891
|
-
maxInterval?: number;
|
|
2892
|
-
/** Maximum number of attempts (default: 30) */
|
|
2893
|
-
maxAttempts?: number;
|
|
2894
|
-
/** Commitment level (default: 'confirmed') */
|
|
2895
|
-
commitment?: 'processed' | 'confirmed' | 'finalized';
|
|
2896
|
-
/** RPC endpoint (optional, uses default if not provided) */
|
|
2897
|
-
rpcUrl?: string;
|
|
2898
|
-
}
|
|
336
|
+
declare function verifyNextWebhook(request: Request, secret?: string): Promise<WebhookPayload | null>;
|
|
2899
337
|
/**
|
|
2900
|
-
*
|
|
2901
|
-
*
|
|
338
|
+
* Verify and parse webhook for Express.js
|
|
339
|
+
*
|
|
340
|
+
* @example
|
|
341
|
+
* ```typescript
|
|
342
|
+
* import { verifyExpressWebhook } from '@zendfi/sdk/webhooks';
|
|
343
|
+
*
|
|
344
|
+
* app.post('/webhooks/zendfi', async (req, res) => {
|
|
345
|
+
* const webhook = await verifyExpressWebhook(req);
|
|
346
|
+
*
|
|
347
|
+
* if (!webhook) {
|
|
348
|
+
* return res.status(401).json({ error: 'Invalid signature' });
|
|
349
|
+
* }
|
|
350
|
+
*
|
|
351
|
+
* // Process webhook
|
|
352
|
+
* console.log('Event:', webhook.event);
|
|
353
|
+
*
|
|
354
|
+
* res.json({ received: true });
|
|
355
|
+
* });
|
|
356
|
+
* ```
|
|
2902
357
|
*/
|
|
2903
|
-
declare
|
|
2904
|
-
/**
|
|
2905
|
-
* Wait for transaction confirmation
|
|
2906
|
-
*/
|
|
2907
|
-
static waitForConfirmation(signature: string, options?: PollingOptions): Promise<TransactionStatus>;
|
|
2908
|
-
/**
|
|
2909
|
-
* Check transaction status via RPC
|
|
2910
|
-
*/
|
|
2911
|
-
private static checkTransactionStatus;
|
|
2912
|
-
/**
|
|
2913
|
-
* Check if commitment level is reached
|
|
2914
|
-
*/
|
|
2915
|
-
private static isCommitmentReached;
|
|
2916
|
-
/**
|
|
2917
|
-
* Get default RPC URL based on environment
|
|
2918
|
-
*/
|
|
2919
|
-
private static getDefaultRpcUrl;
|
|
2920
|
-
/**
|
|
2921
|
-
* Poll multiple transactions in parallel
|
|
2922
|
-
*/
|
|
2923
|
-
static waitForMultiple(signatures: string[], options?: PollingOptions): Promise<TransactionStatus[]>;
|
|
2924
|
-
/**
|
|
2925
|
-
* Get transaction details after confirmation
|
|
2926
|
-
*/
|
|
2927
|
-
static getTransactionDetails(signature: string, rpcUrl?: string): Promise<any>;
|
|
2928
|
-
/**
|
|
2929
|
-
* Check if transaction exists on chain
|
|
2930
|
-
*/
|
|
2931
|
-
static exists(signature: string, rpcUrl?: string): Promise<boolean>;
|
|
2932
|
-
/**
|
|
2933
|
-
* Get recent blockhash (useful for transaction building)
|
|
2934
|
-
*/
|
|
2935
|
-
static getRecentBlockhash(rpcUrl?: string): Promise<{
|
|
2936
|
-
blockhash: string;
|
|
2937
|
-
lastValidBlockHeight: number;
|
|
2938
|
-
}>;
|
|
2939
|
-
/**
|
|
2940
|
-
* Sleep utility
|
|
2941
|
-
*/
|
|
2942
|
-
private static sleep;
|
|
2943
|
-
}
|
|
358
|
+
declare function verifyExpressWebhook(request: any, secret?: string): Promise<WebhookPayload | null>;
|
|
2944
359
|
/**
|
|
2945
|
-
*
|
|
2946
|
-
*
|
|
360
|
+
* Verify webhook signature manually
|
|
361
|
+
* Use this for custom integrations
|
|
362
|
+
*
|
|
363
|
+
* @example
|
|
364
|
+
* ```typescript
|
|
365
|
+
* import { verifyWebhookSignature } from '@zendfi/sdk/webhooks';
|
|
366
|
+
*
|
|
367
|
+
* const isValid = verifyWebhookSignature(
|
|
368
|
+
* payloadString,
|
|
369
|
+
* signatureHeader,
|
|
370
|
+
* process.env.ZENDFI_WEBHOOK_SECRET
|
|
371
|
+
* );
|
|
372
|
+
* ```
|
|
2947
373
|
*/
|
|
2948
|
-
declare
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
374
|
+
declare function verifyWebhookSignature(payload: string, signature: string, secret: string): boolean;
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* ZendFi Embedded Checkout
|
|
378
|
+
*
|
|
379
|
+
* Embed the ZendFi checkout directly into your website/app
|
|
380
|
+
* without redirecting to checkout.zendfi.tech
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* ```typescript
|
|
384
|
+
* import { ZendFiEmbeddedCheckout } from '@zendfi/sdk';
|
|
385
|
+
*
|
|
386
|
+
* const checkout = new ZendFiEmbeddedCheckout({
|
|
387
|
+
* linkCode: 'abc123xyz',
|
|
388
|
+
* containerId: 'zendfi-checkout',
|
|
389
|
+
* mode: 'live',
|
|
390
|
+
* onSuccess: (payment) => {
|
|
391
|
+
* console.log('Payment successful!', payment);
|
|
392
|
+
* },
|
|
393
|
+
* onError: (error) => {
|
|
394
|
+
* console.error('Payment failed:', error);
|
|
395
|
+
* }
|
|
396
|
+
* });
|
|
397
|
+
*
|
|
398
|
+
* checkout.mount();
|
|
399
|
+
* ```
|
|
400
|
+
*/
|
|
401
|
+
|
|
402
|
+
interface EmbeddedCheckoutConfig {
|
|
403
|
+
/** Payment link code or payment ID */
|
|
404
|
+
linkCode?: string;
|
|
405
|
+
paymentId?: string;
|
|
406
|
+
/** Container element ID where checkout will be mounted */
|
|
407
|
+
containerId: string;
|
|
408
|
+
/** API mode - 'test' for devnet, 'live' for mainnet */
|
|
409
|
+
mode?: ApiKeyMode;
|
|
410
|
+
/** API base URL (defaults to production) */
|
|
411
|
+
apiUrl?: string;
|
|
412
|
+
/** Callback when payment is successful */
|
|
413
|
+
onSuccess?: (payment: PaymentSuccessData) => void;
|
|
414
|
+
/** Callback when payment fails */
|
|
415
|
+
onError?: (error: CheckoutError) => void;
|
|
416
|
+
/** Callback when checkout is loaded */
|
|
417
|
+
onLoad?: () => void;
|
|
418
|
+
/** Custom theme overrides */
|
|
419
|
+
theme?: CheckoutTheme;
|
|
420
|
+
/** Enable custom amount (Pay What You Want) */
|
|
421
|
+
allowCustomAmount?: boolean;
|
|
422
|
+
/** Show/hide specific payment methods */
|
|
423
|
+
paymentMethods?: {
|
|
424
|
+
walletConnect?: boolean;
|
|
425
|
+
qrCode?: boolean;
|
|
426
|
+
solanaWallet?: boolean;
|
|
427
|
+
bank?: boolean;
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
interface CheckoutTheme {
|
|
431
|
+
primaryColor?: string;
|
|
432
|
+
backgroundColor?: string;
|
|
433
|
+
borderRadius?: string;
|
|
434
|
+
fontFamily?: string;
|
|
435
|
+
textColor?: string;
|
|
436
|
+
buttonStyle?: 'solid' | 'outlined' | 'minimal';
|
|
2970
437
|
}
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
* () => zendfi.smartPayments.execute({ amount_usd: 50 }),
|
|
2983
|
-
* { maxAttempts: 3, backoffMs: 1000 }
|
|
2984
|
-
* );
|
|
2985
|
-
*
|
|
2986
|
-
* // Auto-recover from common errors
|
|
2987
|
-
* const payment = await ErrorRecovery.recoverFromNetworkError(
|
|
2988
|
-
* () => createPayment()
|
|
2989
|
-
* );
|
|
2990
|
-
* ```
|
|
2991
|
-
*/
|
|
2992
|
-
interface RetryOptions {
|
|
2993
|
-
/** Maximum number of retry attempts (default: 3) */
|
|
2994
|
-
maxAttempts?: number;
|
|
2995
|
-
/** Initial backoff delay in ms (default: 1000) */
|
|
2996
|
-
backoffMs?: number;
|
|
2997
|
-
/** Backoff multiplier (default: 2 for exponential) */
|
|
2998
|
-
backoffMultiplier?: number;
|
|
2999
|
-
/** Maximum backoff delay in ms (default: 30000) */
|
|
3000
|
-
maxBackoffMs?: number;
|
|
3001
|
-
/** Function to determine if error is retryable (default: all errors) */
|
|
3002
|
-
shouldRetry?: (error: Error, attempt: number) => boolean;
|
|
3003
|
-
/** Callback on each retry */
|
|
3004
|
-
onRetry?: (error: Error, attempt: number, nextDelayMs: number) => void;
|
|
438
|
+
interface PaymentSuccessData {
|
|
439
|
+
paymentId: string;
|
|
440
|
+
transactionSignature: string;
|
|
441
|
+
amount: number;
|
|
442
|
+
token: string;
|
|
443
|
+
merchantName: string;
|
|
444
|
+
}
|
|
445
|
+
interface CheckoutError {
|
|
446
|
+
code: string;
|
|
447
|
+
message: string;
|
|
448
|
+
details?: any;
|
|
3005
449
|
}
|
|
3006
450
|
/**
|
|
3007
|
-
*
|
|
3008
|
-
*
|
|
451
|
+
* ZendFi Embedded Checkout Component
|
|
452
|
+
*
|
|
453
|
+
* Provides a fully-functional checkout experience that can be
|
|
454
|
+
* embedded directly into any web application.
|
|
3009
455
|
*/
|
|
3010
|
-
declare class
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
* Retry with custom backoff function
|
|
3021
|
-
*/
|
|
3022
|
-
static withCustomBackoff<T>(fn: () => Promise<T>, backoffFn: (attempt: number) => number, maxAttempts?: number): Promise<T>;
|
|
456
|
+
declare class ZendFiEmbeddedCheckout {
|
|
457
|
+
private config;
|
|
458
|
+
private container;
|
|
459
|
+
private checkoutData;
|
|
460
|
+
private pollInterval;
|
|
461
|
+
private mounted;
|
|
462
|
+
private paymentProcessed;
|
|
463
|
+
private bankPaymentState;
|
|
464
|
+
constructor(config: EmbeddedCheckoutConfig);
|
|
465
|
+
private getDefaultApiUrl;
|
|
3023
466
|
/**
|
|
3024
|
-
*
|
|
467
|
+
* Mount the checkout to the DOM
|
|
3025
468
|
*/
|
|
3026
|
-
|
|
3027
|
-
private static sleep;
|
|
3028
|
-
}
|
|
3029
|
-
/**
|
|
3030
|
-
* Error Recovery
|
|
3031
|
-
* Auto-recovery strategies for common failure scenarios
|
|
3032
|
-
*/
|
|
3033
|
-
declare class ErrorRecovery {
|
|
469
|
+
mount(): Promise<void>;
|
|
3034
470
|
/**
|
|
3035
|
-
*
|
|
471
|
+
* Unmount and cleanup
|
|
3036
472
|
*/
|
|
3037
|
-
|
|
473
|
+
unmount(): void;
|
|
3038
474
|
/**
|
|
3039
|
-
*
|
|
475
|
+
* Fetch checkout data from API
|
|
3040
476
|
*/
|
|
3041
|
-
|
|
477
|
+
private fetchCheckoutData;
|
|
3042
478
|
/**
|
|
3043
|
-
*
|
|
479
|
+
* Poll for payment confirmation
|
|
3044
480
|
*/
|
|
3045
|
-
|
|
481
|
+
private startPaymentPolling;
|
|
3046
482
|
/**
|
|
3047
|
-
*
|
|
483
|
+
* Handle successful payment
|
|
3048
484
|
*/
|
|
3049
|
-
|
|
485
|
+
private handlePaymentSuccess;
|
|
3050
486
|
/**
|
|
3051
|
-
*
|
|
487
|
+
* Handle payment failure
|
|
3052
488
|
*/
|
|
3053
|
-
private
|
|
489
|
+
private handlePaymentFailure;
|
|
3054
490
|
/**
|
|
3055
|
-
*
|
|
491
|
+
* Handle payment expiration
|
|
3056
492
|
*/
|
|
3057
|
-
|
|
3058
|
-
failureThreshold?: number;
|
|
3059
|
-
resetTimeoutMs?: number;
|
|
3060
|
-
onStateChange?: (state: 'closed' | 'open' | 'half-open') => void;
|
|
3061
|
-
}): () => Promise<T>;
|
|
493
|
+
private handlePaymentExpired;
|
|
3062
494
|
/**
|
|
3063
|
-
*
|
|
495
|
+
* Render loading state
|
|
3064
496
|
*/
|
|
3065
|
-
|
|
497
|
+
private renderLoading;
|
|
3066
498
|
/**
|
|
3067
|
-
*
|
|
499
|
+
* Render the main checkout UI
|
|
3068
500
|
*/
|
|
3069
|
-
|
|
3070
|
-
}
|
|
3071
|
-
|
|
3072
|
-
/**
|
|
3073
|
-
* Session Key Lifecycle Manager
|
|
3074
|
-
* High-level wrapper for device-bound session keys
|
|
3075
|
-
* Handles common patterns: create → cache → use → revoke
|
|
3076
|
-
*
|
|
3077
|
-
* @example
|
|
3078
|
-
* ```typescript
|
|
3079
|
-
* import { SessionKeyLifecycle } from '@zendfi/sdk/helpers';
|
|
3080
|
-
*
|
|
3081
|
-
* const lifecycle = new SessionKeyLifecycle(zendfi, {
|
|
3082
|
-
* cache: QuickCaches.persistent(),
|
|
3083
|
-
* pinProvider: () => promptUserForPIN(),
|
|
3084
|
-
* });
|
|
3085
|
-
*
|
|
3086
|
-
* // Create and fund in one call
|
|
3087
|
-
* await lifecycle.createAndFund({
|
|
3088
|
-
* userWallet: address,
|
|
3089
|
-
* agentId: 'my-agent',
|
|
3090
|
-
* limitUsdc: 100,
|
|
3091
|
-
* });
|
|
3092
|
-
*
|
|
3093
|
-
* // Make payments (auto-handles caching/PIN)
|
|
3094
|
-
* await lifecycle.pay(5, 'Coffee');
|
|
3095
|
-
*
|
|
3096
|
-
* // Cleanup on app close
|
|
3097
|
-
* await lifecycle.cleanup();
|
|
3098
|
-
* ```
|
|
3099
|
-
*/
|
|
3100
|
-
|
|
3101
|
-
interface LifecycleConfig {
|
|
3102
|
-
/** Optional cache instance */
|
|
3103
|
-
cache?: SessionKeyCache;
|
|
3104
|
-
/** PIN provider function (called when cache expires) */
|
|
3105
|
-
pinProvider?: () => Promise<string>;
|
|
3106
|
-
/** Device fingerprint generator */
|
|
3107
|
-
deviceFingerprintProvider?: () => Promise<string>;
|
|
3108
|
-
/** Auto-cleanup on window/tab close */
|
|
3109
|
-
autoCleanup?: boolean;
|
|
3110
|
-
}
|
|
3111
|
-
interface CreateAndFundConfig {
|
|
3112
|
-
userWallet: string;
|
|
3113
|
-
agentId: string;
|
|
3114
|
-
agentName?: string;
|
|
3115
|
-
limitUsdc: number;
|
|
3116
|
-
durationDays?: number;
|
|
3117
|
-
onApprovalNeeded?: (transaction: string) => Promise<string>;
|
|
3118
|
-
}
|
|
3119
|
-
interface PaymentResult {
|
|
3120
|
-
paymentId: string;
|
|
3121
|
-
status: string;
|
|
3122
|
-
signature?: string;
|
|
3123
|
-
confirmedInMs?: number;
|
|
3124
|
-
}
|
|
3125
|
-
/**
|
|
3126
|
-
* Session Key Lifecycle Manager
|
|
3127
|
-
* Simplifies device-bound session key management
|
|
3128
|
-
*/
|
|
3129
|
-
declare class SessionKeyLifecycle {
|
|
3130
|
-
private client;
|
|
3131
|
-
private config;
|
|
3132
|
-
private sessionKeyId;
|
|
3133
|
-
private sessionWallet;
|
|
3134
|
-
constructor(client: ZendFiClient, config?: LifecycleConfig);
|
|
501
|
+
private render;
|
|
3135
502
|
/**
|
|
3136
|
-
*
|
|
3137
|
-
* Handles: keypair generation → encryption → backend registration
|
|
3138
|
-
* Note: The SDK now handles all crypto internally
|
|
503
|
+
* Render header section
|
|
3139
504
|
*/
|
|
3140
|
-
|
|
3141
|
-
sessionKeyId: string;
|
|
3142
|
-
sessionWallet: string;
|
|
3143
|
-
}>;
|
|
505
|
+
private renderHeader;
|
|
3144
506
|
/**
|
|
3145
|
-
*
|
|
3146
|
-
* Uses the new SDK's makePayment which handles caching internally
|
|
507
|
+
* Render payment information
|
|
3147
508
|
*/
|
|
3148
|
-
|
|
509
|
+
private renderPaymentInfo;
|
|
3149
510
|
/**
|
|
3150
|
-
*
|
|
511
|
+
* Render custom amount input (Pay What You Want)
|
|
3151
512
|
*/
|
|
3152
|
-
|
|
3153
|
-
sessionKeyId: string;
|
|
3154
|
-
isActive: boolean;
|
|
3155
|
-
isApproved: boolean;
|
|
3156
|
-
limitUsdc: number;
|
|
3157
|
-
usedAmountUsdc: number;
|
|
3158
|
-
remainingUsdc: number;
|
|
3159
|
-
expiresAt: string;
|
|
3160
|
-
daysUntilExpiry: number;
|
|
3161
|
-
}>;
|
|
513
|
+
private renderCustomAmountInput;
|
|
3162
514
|
/**
|
|
3163
|
-
*
|
|
3164
|
-
* @deprecated Device-bound session keys are funded directly by the user.
|
|
3165
|
-
* Use the session wallet address to send funds directly.
|
|
515
|
+
* Render payment methods
|
|
3166
516
|
*/
|
|
3167
|
-
|
|
517
|
+
private renderPaymentMethods;
|
|
3168
518
|
/**
|
|
3169
|
-
*
|
|
519
|
+
* Render QR code payment method
|
|
3170
520
|
*/
|
|
3171
|
-
|
|
521
|
+
private renderQRCodeMethod;
|
|
3172
522
|
/**
|
|
3173
|
-
*
|
|
523
|
+
* Render browser wallet method
|
|
3174
524
|
*/
|
|
3175
|
-
|
|
525
|
+
private renderWalletMethod;
|
|
3176
526
|
/**
|
|
3177
|
-
*
|
|
527
|
+
* Render WalletConnect method
|
|
3178
528
|
*/
|
|
3179
|
-
|
|
529
|
+
private renderWalletConnectMethod;
|
|
3180
530
|
/**
|
|
3181
|
-
*
|
|
531
|
+
* Render bank payment method (PAJ Ramp onramp)
|
|
3182
532
|
*/
|
|
3183
|
-
|
|
3184
|
-
private promptForPIN;
|
|
3185
|
-
}
|
|
3186
|
-
/**
|
|
3187
|
-
* Quick setup function for common use case
|
|
3188
|
-
*/
|
|
3189
|
-
declare function setupQuickSessionKey(client: ZendFiClient, config: {
|
|
3190
|
-
userWallet: string;
|
|
3191
|
-
agentId: string;
|
|
3192
|
-
budgetUsdc: number;
|
|
3193
|
-
onApproval: (tx: string) => Promise<string>;
|
|
3194
|
-
}): Promise<SessionKeyLifecycle>;
|
|
3195
|
-
|
|
3196
|
-
/**
|
|
3197
|
-
* Development Tools & Utilities
|
|
3198
|
-
* Debugging helpers for development and testing
|
|
3199
|
-
*
|
|
3200
|
-
* @example
|
|
3201
|
-
* ```typescript
|
|
3202
|
-
* import { DevTools } from '@zendfi/sdk/helpers';
|
|
3203
|
-
*
|
|
3204
|
-
* // Enable debug mode
|
|
3205
|
-
* DevTools.enableDebugMode();
|
|
3206
|
-
*
|
|
3207
|
-
* // Create test session key
|
|
3208
|
-
* const testKey = await DevTools.createTestSessionKey();
|
|
3209
|
-
*
|
|
3210
|
-
* // Mock wallet for testing
|
|
3211
|
-
* const mockWallet = DevTools.mockWallet();
|
|
3212
|
-
*
|
|
3213
|
-
* // Log transaction flow
|
|
3214
|
-
* DevTools.logTransactionFlow(paymentId);
|
|
3215
|
-
* ```
|
|
3216
|
-
*/
|
|
3217
|
-
interface MockWallet {
|
|
3218
|
-
address: string;
|
|
3219
|
-
publicKey: any;
|
|
3220
|
-
signTransaction: (tx: any) => Promise<any>;
|
|
3221
|
-
signMessage: (msg: Uint8Array) => Promise<{
|
|
3222
|
-
signature: Uint8Array;
|
|
3223
|
-
}>;
|
|
3224
|
-
isConnected: () => boolean;
|
|
3225
|
-
disconnect: () => Promise<void>;
|
|
3226
|
-
}
|
|
3227
|
-
interface TestSessionKey {
|
|
3228
|
-
sessionKeyId: string;
|
|
3229
|
-
sessionWallet: string;
|
|
3230
|
-
privateKey: Uint8Array;
|
|
3231
|
-
budget: number;
|
|
3232
|
-
}
|
|
3233
|
-
/**
|
|
3234
|
-
* Development Tools
|
|
3235
|
-
* Utilities for debugging and testing
|
|
3236
|
-
*/
|
|
3237
|
-
declare class DevTools {
|
|
3238
|
-
private static debugEnabled;
|
|
3239
|
-
private static requestLog;
|
|
533
|
+
private renderBankMethod;
|
|
3240
534
|
/**
|
|
3241
|
-
*
|
|
535
|
+
* Render bank email/OTP step
|
|
3242
536
|
*/
|
|
3243
|
-
|
|
537
|
+
private renderBankEmailStep;
|
|
3244
538
|
/**
|
|
3245
|
-
*
|
|
539
|
+
* Render bank details step
|
|
3246
540
|
*/
|
|
3247
|
-
|
|
541
|
+
private renderBankDetailsStep;
|
|
3248
542
|
/**
|
|
3249
|
-
*
|
|
543
|
+
* Render footer
|
|
3250
544
|
*/
|
|
3251
|
-
|
|
545
|
+
private renderFooter;
|
|
3252
546
|
/**
|
|
3253
|
-
*
|
|
547
|
+
* Render success state
|
|
3254
548
|
*/
|
|
3255
|
-
|
|
549
|
+
private renderSuccess;
|
|
3256
550
|
/**
|
|
3257
|
-
*
|
|
551
|
+
* Render error state
|
|
3258
552
|
*/
|
|
3259
|
-
|
|
553
|
+
private renderError;
|
|
3260
554
|
/**
|
|
3261
|
-
*
|
|
555
|
+
* Attach event listeners to interactive elements
|
|
3262
556
|
*/
|
|
3263
|
-
|
|
3264
|
-
timestamp: Date;
|
|
3265
|
-
method: string;
|
|
3266
|
-
url: string;
|
|
3267
|
-
status?: number;
|
|
3268
|
-
duration?: number;
|
|
3269
|
-
}>;
|
|
557
|
+
private attachEventListeners;
|
|
3270
558
|
/**
|
|
3271
|
-
*
|
|
559
|
+
* Handle wallet connection and payment
|
|
3272
560
|
*/
|
|
3273
|
-
|
|
561
|
+
private handleWalletConnect;
|
|
3274
562
|
/**
|
|
3275
|
-
*
|
|
563
|
+
* Handle mobile wallet connection via Solana Pay deep link
|
|
3276
564
|
*/
|
|
3277
|
-
|
|
565
|
+
private handleWalletConnectScan;
|
|
3278
566
|
/**
|
|
3279
|
-
*
|
|
567
|
+
* Generate QR code on canvas using QRious library
|
|
3280
568
|
*/
|
|
3281
|
-
|
|
569
|
+
private generateQRCode;
|
|
3282
570
|
/**
|
|
3283
|
-
*
|
|
571
|
+
* Inject custom styles
|
|
3284
572
|
*/
|
|
3285
|
-
|
|
573
|
+
private injectStyles;
|
|
3286
574
|
/**
|
|
3287
|
-
*
|
|
575
|
+
* Load external dependencies (QR code library, Solana web3.js)
|
|
3288
576
|
*/
|
|
3289
|
-
|
|
577
|
+
private loadDependencies;
|
|
3290
578
|
/**
|
|
3291
|
-
*
|
|
579
|
+
* Load external script
|
|
3292
580
|
*/
|
|
3293
|
-
|
|
3294
|
-
result: T;
|
|
3295
|
-
durationMs: number;
|
|
3296
|
-
}>;
|
|
581
|
+
private loadScript;
|
|
3297
582
|
/**
|
|
3298
|
-
*
|
|
583
|
+
* Get computed theme with defaults
|
|
3299
584
|
*/
|
|
3300
|
-
|
|
3301
|
-
totalRequests: number;
|
|
3302
|
-
successful: number;
|
|
3303
|
-
failed: number;
|
|
3304
|
-
avgDurationMs: number;
|
|
3305
|
-
minDurationMs: number;
|
|
3306
|
-
maxDurationMs: number;
|
|
3307
|
-
}>;
|
|
585
|
+
private getComputedTheme;
|
|
3308
586
|
/**
|
|
3309
|
-
*
|
|
587
|
+
* Style helpers
|
|
3310
588
|
*/
|
|
3311
|
-
|
|
589
|
+
private getCheckoutContainerStyles;
|
|
590
|
+
private getLoadingStyles;
|
|
591
|
+
private getSpinnerStyles;
|
|
592
|
+
private getSuccessStyles;
|
|
593
|
+
private getErrorStyles;
|
|
3312
594
|
/**
|
|
3313
|
-
*
|
|
595
|
+
* Handle bank payment submit (send OTP or verify OTP)
|
|
3314
596
|
*/
|
|
3315
|
-
|
|
3316
|
-
userWallet: string;
|
|
3317
|
-
agentId: string;
|
|
3318
|
-
sessionKeyId: string;
|
|
3319
|
-
paymentId: string;
|
|
3320
|
-
};
|
|
597
|
+
private handleBankSubmit;
|
|
3321
598
|
/**
|
|
3322
|
-
*
|
|
599
|
+
* Start polling bank payment status
|
|
3323
600
|
*/
|
|
3324
|
-
private
|
|
601
|
+
private startBankStatusPolling;
|
|
3325
602
|
/**
|
|
3326
|
-
*
|
|
603
|
+
* Check bank payment status
|
|
3327
604
|
*/
|
|
3328
|
-
private
|
|
605
|
+
private checkBankPaymentStatus;
|
|
3329
606
|
/**
|
|
3330
|
-
*
|
|
607
|
+
* Handle successful bank payment
|
|
3331
608
|
*/
|
|
3332
|
-
private
|
|
609
|
+
private handleBankPaymentSuccess;
|
|
3333
610
|
/**
|
|
3334
|
-
*
|
|
611
|
+
* Manually refresh bank payment status
|
|
3335
612
|
*/
|
|
3336
|
-
private
|
|
613
|
+
private refreshBankStatus;
|
|
3337
614
|
}
|
|
615
|
+
|
|
3338
616
|
/**
|
|
3339
|
-
*
|
|
3340
|
-
*
|
|
617
|
+
* ZendFi SDK Error Classes
|
|
618
|
+
*
|
|
619
|
+
* Custom error types with helpful messages, error codes, and documentation links
|
|
3341
620
|
*/
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
*/
|
|
3363
|
-
getAllStats(): Record<string, ReturnType<typeof this.getStats>>;
|
|
621
|
+
type ZendFiErrorType = 'authentication_error' | 'payment_error' | 'validation_error' | 'network_error' | 'rate_limit_error' | 'api_error' | 'webhook_error' | 'unknown_error';
|
|
622
|
+
interface ZendFiErrorData {
|
|
623
|
+
code: string;
|
|
624
|
+
message: string;
|
|
625
|
+
type: ZendFiErrorType;
|
|
626
|
+
suggestion?: string;
|
|
627
|
+
statusCode?: number;
|
|
628
|
+
response?: unknown;
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Base ZendFi Error class with enhanced developer experience
|
|
632
|
+
*/
|
|
633
|
+
declare class ZendFiError extends Error {
|
|
634
|
+
readonly code: string;
|
|
635
|
+
readonly type: ZendFiErrorType;
|
|
636
|
+
readonly suggestion?: string;
|
|
637
|
+
readonly docs_url: string;
|
|
638
|
+
readonly statusCode?: number;
|
|
639
|
+
readonly response?: unknown;
|
|
640
|
+
constructor(data: ZendFiErrorData);
|
|
3364
641
|
/**
|
|
3365
|
-
*
|
|
642
|
+
* Format error for display
|
|
3366
643
|
*/
|
|
3367
|
-
|
|
644
|
+
toString(): string;
|
|
3368
645
|
/**
|
|
3369
|
-
*
|
|
646
|
+
* Convert error to JSON
|
|
3370
647
|
*/
|
|
3371
|
-
|
|
648
|
+
toJSON(): Record<string, unknown>;
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Authentication errors
|
|
652
|
+
*/
|
|
653
|
+
declare class AuthenticationError extends ZendFiError {
|
|
654
|
+
constructor(message: string, code?: string, suggestion?: string);
|
|
3372
655
|
}
|
|
656
|
+
/**
|
|
657
|
+
* Payment processing errors
|
|
658
|
+
*/
|
|
659
|
+
declare class PaymentError extends ZendFiError {
|
|
660
|
+
constructor(message: string, code?: string, suggestion?: string);
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Validation errors
|
|
664
|
+
*/
|
|
665
|
+
declare class ValidationError extends ZendFiError {
|
|
666
|
+
constructor(message: string, code?: string, suggestion?: string);
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Network/connection errors
|
|
670
|
+
*/
|
|
671
|
+
declare class NetworkError extends ZendFiError {
|
|
672
|
+
constructor(message: string, code?: string, suggestion?: string);
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Rate limit errors
|
|
676
|
+
*/
|
|
677
|
+
declare class RateLimitError extends ZendFiError {
|
|
678
|
+
constructor(message: string, retryAfter?: number);
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Generic API errors
|
|
682
|
+
*/
|
|
683
|
+
declare class ApiError extends ZendFiError {
|
|
684
|
+
constructor(message: string, code: string, statusCode: number, response?: unknown);
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Webhook verification errors
|
|
688
|
+
*/
|
|
689
|
+
declare class WebhookError extends ZendFiError {
|
|
690
|
+
constructor(message: string, code?: string, suggestion?: string);
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Error factory - creates appropriate error based on response
|
|
694
|
+
*/
|
|
695
|
+
declare function createZendFiError(statusCode: number, responseBody: any, message?: string): ZendFiError;
|
|
696
|
+
/**
|
|
697
|
+
* Common error codes and their messages
|
|
698
|
+
*/
|
|
699
|
+
declare const ERROR_CODES: {
|
|
700
|
+
readonly INVALID_API_KEY: "invalid_api_key";
|
|
701
|
+
readonly API_KEY_EXPIRED: "api_key_expired";
|
|
702
|
+
readonly API_KEY_REVOKED: "api_key_revoked";
|
|
703
|
+
readonly INSUFFICIENT_BALANCE: "insufficient_balance";
|
|
704
|
+
readonly PAYMENT_DECLINED: "payment_declined";
|
|
705
|
+
readonly PAYMENT_EXPIRED: "payment_expired";
|
|
706
|
+
readonly INVALID_AMOUNT: "invalid_amount";
|
|
707
|
+
readonly INVALID_CURRENCY: "invalid_currency";
|
|
708
|
+
readonly MISSING_REQUIRED_FIELD: "missing_required_field";
|
|
709
|
+
readonly INVALID_PARAMETER: "invalid_parameter";
|
|
710
|
+
readonly NETWORK_ERROR: "network_error";
|
|
711
|
+
readonly TIMEOUT: "timeout";
|
|
712
|
+
readonly RATE_LIMIT_EXCEEDED: "rate_limit_exceeded";
|
|
713
|
+
readonly WEBHOOK_SIGNATURE_INVALID: "webhook_signature_invalid";
|
|
714
|
+
readonly WEBHOOK_TIMESTAMP_TOO_OLD: "webhook_timestamp_too_old";
|
|
715
|
+
};
|
|
716
|
+
/**
|
|
717
|
+
* Helper to check if error is a ZendFi error
|
|
718
|
+
*/
|
|
719
|
+
declare function isZendFiError(error: unknown): error is ZendFiError;
|
|
3373
720
|
|
|
3374
|
-
export {
|
|
721
|
+
export { ApiError, ApiKeyMode, AuthenticationError, type CheckoutError, type CheckoutTheme, ConfigLoader, CreateInstallmentPlanRequest, CreateInvoiceRequest, CreatePaymentLinkRequest, CreatePaymentRequest, CreateSubscriptionPlanRequest, CreateSubscriptionRequest, ERROR_CODES, type EmbeddedCheckoutConfig, type ErrorInterceptor, InstallmentPlan, InterceptorManager, type Interceptors, Invoice, NetworkError, Payment, PaymentError, PaymentLink, type PaymentSuccessData, RateLimitError, RateLimiter, type RequestConfig, type RequestInterceptor, type ResponseData, type ResponseInterceptor, Subscription, SubscriptionPlan, ValidationError, VerifyWebhookRequest, WebhookError, WebhookPayload, ZendFiClient, ZendFiConfig, ZendFiEmbeddedCheckout, ZendFiError, type ZendFiErrorData, type ZendFiErrorType, createZendFiError, generateIdempotencyKey, isZendFiError, sleep, verifyExpressWebhook, verifyNextWebhook, verifyWebhookSignature, zendfi };
|