@zendfi/sdk 0.5.1 → 0.5.3

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/dist/index.js CHANGED
@@ -49,6 +49,7 @@ __export(index_exports, {
49
49
  RecoveryQRGenerator: () => RecoveryQRGenerator,
50
50
  SPENDING_LIMIT_ACTION_CID: () => SPENDING_LIMIT_ACTION_CID,
51
51
  SessionKeyCrypto: () => SessionKeyCrypto,
52
+ SessionKeysAPI: () => SessionKeysAPI,
52
53
  SmartPaymentsAPI: () => SmartPaymentsAPI,
53
54
  ValidationError: () => ValidationError2,
54
55
  WebhookError: () => WebhookError,
@@ -719,6 +720,70 @@ var AgentAPI = class {
719
720
  await this.request("POST", `/api/v1/ai/sessions/${sessionId}/revoke`);
720
721
  }
721
722
  // ============================================
723
+ // Agent Payments
724
+ // ============================================
725
+ /**
726
+ * Execute a payment using an agent session
727
+ *
728
+ * This is the primary method for AI agents to make payments. It uses the
729
+ * session token to enforce spending limits and automatically routes the
730
+ * payment through the optimal path.
731
+ *
732
+ * The session token comes from `createSession()` and enforces:
733
+ * - Per-transaction limits
734
+ * - Daily limits
735
+ * - Weekly limits
736
+ * - Monthly limits
737
+ *
738
+ * @param request - Payment request with session token
739
+ * @returns Payment result with status and receipt
740
+ *
741
+ * @example
742
+ * ```typescript
743
+ * // Create a session first
744
+ * const session = await zendfi.agent.createSession({
745
+ * agent_id: 'shopping-bot',
746
+ * user_wallet: 'Hx7B...abc',
747
+ * limits: {
748
+ * max_per_transaction: 50,
749
+ * max_per_day: 200,
750
+ * },
751
+ * duration_hours: 24,
752
+ * });
753
+ *
754
+ * // Make payments within the session limits
755
+ * const payment = await zendfi.agent.pay({
756
+ * session_token: session.session_token,
757
+ * amount: 29.99,
758
+ * description: 'Premium widget',
759
+ * auto_gasless: true,
760
+ * });
761
+ *
762
+ * if (payment.requires_signature) {
763
+ * // Device-bound: user must sign
764
+ * console.log('Sign and submit to:', payment.submit_url);
765
+ * } else {
766
+ * // Auto-signed: payment complete
767
+ * console.log('Payment confirmed:', payment.transaction_signature);
768
+ * }
769
+ * ```
770
+ */
771
+ async pay(request) {
772
+ return this.request("POST", "/api/v1/ai/smart-payment", {
773
+ session_token: request.session_token,
774
+ agent_id: "session",
775
+ // Session already has agent_id bound
776
+ user_wallet: "",
777
+ // Will be extracted from session
778
+ amount_usd: request.amount,
779
+ merchant_id: request.recipient_merchant_id,
780
+ token: request.token || "USDC",
781
+ auto_detect_gasless: request.auto_gasless,
782
+ description: request.description,
783
+ metadata: request.metadata
784
+ });
785
+ }
786
+ // ============================================
722
787
  // Agent Analytics
723
788
  // ============================================
724
789
  /**
@@ -854,7 +919,8 @@ var PaymentIntentsAPI = class {
854
919
  customer_wallet: request.customer_wallet,
855
920
  payment_type: request.payment_type,
856
921
  auto_gasless: request.auto_gasless,
857
- metadata: request.metadata
922
+ metadata: request.metadata,
923
+ session_token: request.session_token
858
924
  });
859
925
  }
860
926
  /**
@@ -1318,6 +1384,269 @@ var SmartPaymentsAPI = class {
1318
1384
  }
1319
1385
  };
1320
1386
 
1387
+ // src/api/session-keys.ts
1388
+ var SessionKeysAPI = class {
1389
+ constructor(request) {
1390
+ this.request = request;
1391
+ }
1392
+ // ============================================
1393
+ // Custodial Session Keys
1394
+ // ============================================
1395
+ /**
1396
+ * Create a custodial session key
1397
+ *
1398
+ * The backend generates and securely stores the keypair.
1399
+ * Returns an approval transaction that the user must sign to fund the session wallet.
1400
+ *
1401
+ * @param request - Session key configuration
1402
+ * @returns Creation response with approval transaction
1403
+ *
1404
+ * @example
1405
+ * ```typescript
1406
+ * const result = await zendfi.sessionKeys.create({
1407
+ * user_wallet: 'Hx7B...abc',
1408
+ * limit_usdc: 100,
1409
+ * duration_days: 7,
1410
+ * device_fingerprint: deviceFingerprint,
1411
+ * });
1412
+ *
1413
+ * console.log(`Session key: ${result.session_key_id}`);
1414
+ * console.log('Please sign the approval transaction');
1415
+ * ```
1416
+ */
1417
+ async create(request) {
1418
+ return this.request("POST", "/api/v1/ai/session-keys/create", {
1419
+ user_wallet: request.user_wallet,
1420
+ limit_usdc: request.limit_usdc,
1421
+ duration_days: request.duration_days ?? 7,
1422
+ device_fingerprint: request.device_fingerprint
1423
+ });
1424
+ }
1425
+ // ============================================
1426
+ // Device-Bound Session Keys (Non-Custodial)
1427
+ // ============================================
1428
+ /**
1429
+ * Create a device-bound session key (non-custodial)
1430
+ *
1431
+ * The client generates the keypair and encrypts it with a PIN before sending.
1432
+ * The backend cannot decrypt the keypair - only the user's device can.
1433
+ *
1434
+ * @param request - Device-bound session key configuration
1435
+ * @returns Creation response with session wallet address
1436
+ *
1437
+ * @example
1438
+ * ```typescript
1439
+ * // Generate keypair client-side
1440
+ * const keypair = Keypair.generate();
1441
+ *
1442
+ * // Encrypt with PIN
1443
+ * const encrypted = await encryptWithPin(keypair.secretKey, pin);
1444
+ *
1445
+ * const result = await zendfi.sessionKeys.createDeviceBound({
1446
+ * user_wallet: 'Hx7B...abc',
1447
+ * limit_usdc: 100,
1448
+ * duration_days: 7,
1449
+ * encrypted_session_key: encrypted.ciphertext,
1450
+ * nonce: encrypted.nonce,
1451
+ * session_public_key: keypair.publicKey.toBase58(),
1452
+ * device_fingerprint: deviceFingerprint,
1453
+ * });
1454
+ *
1455
+ * console.log(`Session wallet: ${result.session_wallet}`);
1456
+ * ```
1457
+ */
1458
+ async createDeviceBound(request) {
1459
+ return this.request(
1460
+ "POST",
1461
+ "/api/v1/ai/session-keys/device-bound/create",
1462
+ {
1463
+ user_wallet: request.user_wallet,
1464
+ limit_usdc: request.limit_usdc,
1465
+ duration_days: request.duration_days,
1466
+ encrypted_session_key: request.encrypted_session_key,
1467
+ nonce: request.nonce,
1468
+ session_public_key: request.session_public_key,
1469
+ device_fingerprint: request.device_fingerprint,
1470
+ recovery_qr_data: request.recovery_qr_data
1471
+ }
1472
+ );
1473
+ }
1474
+ /**
1475
+ * Get encrypted session key for device-bound mode
1476
+ *
1477
+ * Retrieves the encrypted keypair so the client can decrypt it with their PIN.
1478
+ * The device fingerprint must match the one used during creation.
1479
+ *
1480
+ * @param sessionKeyId - UUID of the session key
1481
+ * @param deviceFingerprint - Current device fingerprint
1482
+ * @returns Encrypted key data
1483
+ */
1484
+ async getEncrypted(sessionKeyId, deviceFingerprint) {
1485
+ return this.request("POST", "/api/v1/ai/session-keys/device-bound/get-encrypted", {
1486
+ session_key_id: sessionKeyId,
1487
+ device_fingerprint: deviceFingerprint
1488
+ });
1489
+ }
1490
+ // ============================================
1491
+ // Transaction Submission
1492
+ // ============================================
1493
+ /**
1494
+ * Submit a signed approval transaction
1495
+ *
1496
+ * After the user signs the approval transaction from `create()`,
1497
+ * submit it here to activate the session key.
1498
+ *
1499
+ * @param request - Signed transaction data
1500
+ * @returns Submission result with signature
1501
+ *
1502
+ * @example
1503
+ * ```typescript
1504
+ * const result = await zendfi.sessionKeys.submitApproval({
1505
+ * session_key_id: sessionKeyId,
1506
+ * signed_transaction: signedTxBase64,
1507
+ * });
1508
+ *
1509
+ * console.log(`Approved! Signature: ${result.signature}`);
1510
+ * ```
1511
+ */
1512
+ async submitApproval(request) {
1513
+ return this.request(
1514
+ "POST",
1515
+ "/api/v1/ai/session-keys/submit-approval",
1516
+ {
1517
+ session_key_id: request.session_key_id,
1518
+ signed_transaction: request.signed_transaction
1519
+ }
1520
+ );
1521
+ }
1522
+ /**
1523
+ * Submit a signed top-up transaction
1524
+ *
1525
+ * After the user signs the top-up transaction from `topUp()`,
1526
+ * submit it here to add funds.
1527
+ *
1528
+ * @param sessionKeyId - UUID of the session key
1529
+ * @param signedTransaction - Base64 encoded signed transaction
1530
+ * @returns Submission result with new limit
1531
+ */
1532
+ async submitTopUp(sessionKeyId, signedTransaction) {
1533
+ return this.request(
1534
+ "POST",
1535
+ `/api/v1/ai/session-keys/${sessionKeyId}/submit-top-up`,
1536
+ {
1537
+ signed_transaction: signedTransaction
1538
+ }
1539
+ );
1540
+ }
1541
+ // ============================================
1542
+ // Status & Management
1543
+ // ============================================
1544
+ /**
1545
+ * Get session key status
1546
+ *
1547
+ * @param sessionKeyId - UUID of the session key
1548
+ * @returns Current status with remaining balance
1549
+ *
1550
+ * @example
1551
+ * ```typescript
1552
+ * const status = await zendfi.sessionKeys.getStatus(sessionKeyId);
1553
+ *
1554
+ * console.log(`Active: ${status.is_active}`);
1555
+ * console.log(`Limit: $${status.limit_usdc}`);
1556
+ * console.log(`Used: $${status.used_amount_usdc}`);
1557
+ * console.log(`Remaining: $${status.remaining_usdc}`);
1558
+ * console.log(`Expires in ${status.days_until_expiry} days`);
1559
+ * ```
1560
+ */
1561
+ async getStatus(sessionKeyId) {
1562
+ return this.request("POST", "/api/v1/ai/session-keys/status", {
1563
+ session_key_id: sessionKeyId
1564
+ });
1565
+ }
1566
+ /**
1567
+ * List all session keys for the merchant
1568
+ *
1569
+ * @returns List of session keys with stats
1570
+ *
1571
+ * @example
1572
+ * ```typescript
1573
+ * const { session_keys, stats } = await zendfi.sessionKeys.list();
1574
+ *
1575
+ * console.log(`Total keys: ${stats.total_keys}`);
1576
+ * console.log(`Active: ${stats.active_keys}`);
1577
+ *
1578
+ * session_keys.forEach(key => {
1579
+ * console.log(`${key.session_key_id}: $${key.remaining_usdc} remaining`);
1580
+ * });
1581
+ * ```
1582
+ */
1583
+ async list() {
1584
+ return this.request("GET", "/api/v1/ai/session-keys/list");
1585
+ }
1586
+ /**
1587
+ * Top up a session key with additional funds
1588
+ *
1589
+ * Returns a transaction that the user must sign to add funds.
1590
+ *
1591
+ * @param sessionKeyId - UUID of the session key
1592
+ * @param request - Top-up configuration
1593
+ * @returns Top-up transaction to sign
1594
+ *
1595
+ * @example
1596
+ * ```typescript
1597
+ * const topUp = await zendfi.sessionKeys.topUp(sessionKeyId, {
1598
+ * user_wallet: 'Hx7B...abc',
1599
+ * amount_usdc: 50,
1600
+ * device_fingerprint: deviceFingerprint,
1601
+ * });
1602
+ *
1603
+ * console.log(`Adding $${topUp.added_amount}`);
1604
+ * console.log(`New limit will be: $${topUp.new_limit}`);
1605
+ *
1606
+ * // User signs the transaction
1607
+ * const signedTx = await wallet.signTransaction(topUp.top_up_transaction);
1608
+ *
1609
+ * // Submit it
1610
+ * await zendfi.sessionKeys.submitTopUp(sessionKeyId, signedTx);
1611
+ * ```
1612
+ */
1613
+ async topUp(sessionKeyId, request) {
1614
+ return this.request(
1615
+ "POST",
1616
+ `/api/v1/ai/session-keys/${sessionKeyId}/top-up`,
1617
+ {
1618
+ user_wallet: request.user_wallet,
1619
+ amount_usdc: request.amount_usdc,
1620
+ device_fingerprint: request.device_fingerprint
1621
+ }
1622
+ );
1623
+ }
1624
+ /**
1625
+ * Revoke a session key
1626
+ *
1627
+ * Immediately deactivates the session key. Any remaining funds
1628
+ * are refunded to the user's wallet.
1629
+ *
1630
+ * @param sessionKeyId - UUID of the session key
1631
+ * @returns Revocation result with optional refund details
1632
+ *
1633
+ * @example
1634
+ * ```typescript
1635
+ * const result = await zendfi.sessionKeys.revoke(sessionKeyId);
1636
+ *
1637
+ * console.log('Session key revoked');
1638
+ * if (result.refund?.refunded) {
1639
+ * console.log(`Refunded: ${result.refund.transaction_signature}`);
1640
+ * }
1641
+ * ```
1642
+ */
1643
+ async revoke(sessionKeyId) {
1644
+ return this.request("POST", "/api/v1/ai/session-keys/revoke", {
1645
+ session_key_id: sessionKeyId
1646
+ });
1647
+ }
1648
+ };
1649
+
1321
1650
  // src/client.ts
1322
1651
  var ZendFiClient = class {
1323
1652
  config;
@@ -1422,6 +1751,38 @@ var ZendFiClient = class {
1422
1751
  * ```
1423
1752
  */
1424
1753
  smart;
1754
+ /**
1755
+ * Session Keys API - On-chain funded session keys with PKP identity
1756
+ *
1757
+ * Session keys are pre-funded wallets with spending limits that enable
1758
+ * AI agents to make autonomous payments without user signatures.
1759
+ *
1760
+ * The flow:
1761
+ * 1. Create a session key (user approves spending limit)
1762
+ * 2. User signs the approval transaction (one-time)
1763
+ * 3. Agent can now make payments up to the limit
1764
+ *
1765
+ * @example
1766
+ * ```typescript
1767
+ * // Create session key
1768
+ * const key = await zendfi.sessionKeys.create({
1769
+ * agent_id: 'shopping-bot',
1770
+ * user_wallet: 'Hx7B...abc',
1771
+ * max_amount: 100,
1772
+ * expiry_hours: 24,
1773
+ * });
1774
+ *
1775
+ * // User signs the approval
1776
+ * await zendfi.sessionKeys.submitApproval(key.session_key_id, {
1777
+ * signed_transaction: signedTx,
1778
+ * });
1779
+ *
1780
+ * // Check status
1781
+ * const status = await zendfi.sessionKeys.getStatus(key.session_key_id);
1782
+ * console.log(`Remaining: $${status.remaining_amount}`);
1783
+ * ```
1784
+ */
1785
+ sessionKeys;
1425
1786
  constructor(options) {
1426
1787
  this.config = ConfigLoader.load(options);
1427
1788
  ConfigLoader.validateApiKey(this.config.apiKey);
@@ -1432,6 +1793,7 @@ var ZendFiClient = class {
1432
1793
  this.pricing = new PricingAPI(boundRequest);
1433
1794
  this.autonomy = new AutonomyAPI(boundRequest);
1434
1795
  this.smart = new SmartPaymentsAPI(boundRequest);
1796
+ this.sessionKeys = new SessionKeysAPI(boundRequest);
1435
1797
  if (this.config.environment === "development" || this.config.debug) {
1436
1798
  console.log(
1437
1799
  `\u2713 ZendFi SDK initialized in ${this.config.mode} mode (${this.config.mode === "test" ? "devnet" : "mainnet"})`
@@ -3224,6 +3586,7 @@ function decodeSignatureFromLit(result) {
3224
3586
  RecoveryQRGenerator,
3225
3587
  SPENDING_LIMIT_ACTION_CID,
3226
3588
  SessionKeyCrypto,
3589
+ SessionKeysAPI,
3227
3590
  SmartPaymentsAPI,
3228
3591
  ValidationError,
3229
3592
  WebhookError,