@chipi-stack/backend 14.1.0 → 14.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -43,6 +43,15 @@ const tx = await sdk.transfer({
43
43
  });
44
44
  ```
45
45
 
46
+ ## What you can ship
47
+
48
+ - **Wallet-as-a-service APIs** — provision and manage wallets for your users from your backend
49
+ - **SKU marketplace (airtime, bill pay, gift cards)** — integrate real-world purchases with crypto rails
50
+ - **Crypto remittance backends** — build cross-border payment services with stablecoin settlement
51
+ - **Gasless payment processing for fintechs** — accept and send USDC without your users paying gas
52
+
53
+ Have an idea? [Tell us what you want to build](https://github.com/chipi-pay/build-with-chipi/issues/new)
54
+
46
55
  ## Documentation
47
56
 
48
57
  Full docs at [docs.chipipay.com](https://docs.chipipay.com)
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _chipi_stack_types from '@chipi-stack/types';
2
- import { CreateSessionKeyParams, SessionKeyData, AddSessionKeyParams, RevokeSessionKeyParams, GetSessionDataParams, SessionDataResponse, ExecuteWithSessionParams, Currency, PaymasterAdapter, PaymasterAccount, X402FacilitatorConfig, NonceStore, PaymentPayload, VerifyResponse, SettleResponse, ChipiSDKConfig, ExecuteTransactionParams, SignTypedDataParams, SignTypedDataResult, TransferParams, ApproveParams, CallAnyContractParams, CreateWalletParams, CreateWalletResponse, RecordSendTransactionParams, Transaction, GetTransactionListQuery, PaginatedResponse, GetWalletParams, GetTokenBalanceParams, GetTokenBalanceResponse, CreateSkuPurchaseParams, GetSkuListQuery, Sku, TransactionStatusResponse, PrepareWalletUpgradeParams, PrepareWalletUpgradeResponse, ExecuteWalletUpgradeParams, ExecuteWalletUpgradeResponse, ChipiServerSDKConfig, ChipiBrowserSDKConfig, X402PaymentConfig } from '@chipi-stack/types';
2
+ import { CreateSessionKeyParams, SessionKeyData, AddSessionKeyParams, RevokeSessionKeyParams, GetSessionDataParams, SessionDataResponse, ExecuteWithSessionParams, SetSpendingPolicyParams, GetSpendingPolicyParams, SpendingPolicyData, RemoveSpendingPolicyParams, Currency, PaymasterAdapter, PaymasterAccount, X402FacilitatorConfig, NonceStore, PaymentPayload, VerifyResponse, SettleResponse, ChipiSDKConfig, ExecuteTransactionParams, SignTypedDataParams, SignTypedDataResult, TransferParams, ApproveParams, CallAnyContractParams, CreateWalletParams, CreateWalletResponse, RecordSendTransactionParams, Transaction, GetTransactionListQuery, PaginatedResponse, GetWalletParams, GetTokenBalanceParams, GetTokenBalanceResponse, CreateSkuPurchaseParams, GetSkuListQuery, Sku, TransactionStatusResponse, PrepareWalletUpgradeParams, PrepareWalletUpgradeResponse, ExecuteWalletUpgradeParams, ExecuteWalletUpgradeResponse, ChipiServerSDKConfig, ChipiBrowserSDKConfig, X402PaymentConfig } from '@chipi-stack/types';
3
3
  export * from '@chipi-stack/types';
4
4
  export { Chain, ChainToken } from '@chipi-stack/types';
5
5
  import { ChipiWallets } from './wallets.mjs';
@@ -168,6 +168,89 @@ declare class ChipiSessions {
168
168
  * ```
169
169
  */
170
170
  executeTransactionWithSession(params: ExecuteWithSessionParams, bearerToken: string): Promise<string>;
171
+ /**
172
+ * Split a bigint into Cairo u256 representation (low u128, high u128).
173
+ */
174
+ private splitU256;
175
+ /**
176
+ * Reconstruct a bigint from Cairo u256 (low, high) hex strings.
177
+ */
178
+ private joinU256;
179
+ /**
180
+ * Set a spending policy for a session key + token pair.
181
+ *
182
+ * This executes a sponsored transaction (using owner signature) to call
183
+ * `set_spending_policy` on the CHIPI wallet contract.
184
+ *
185
+ * The contract enforces these limits automatically during `__execute__()` on
186
+ * ERC-20 operations (transfer, approve, increase_allowance) made by the session.
187
+ *
188
+ * @param params - Spending policy parameters
189
+ * @param bearerToken - Authentication token
190
+ * @returns Transaction hash
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * // Set a spending limit: max 1 USDC per call, 50 USDC per day
195
+ * const txHash = await sdk.sessions.setSpendingPolicy({
196
+ * encryptKey: userEncryptKey,
197
+ * wallet: userWallet,
198
+ * spendingPolicyConfig: {
199
+ * sessionPublicKey: session.publicKey,
200
+ * token: USDC_ADDRESS,
201
+ * maxPerCall: 1_000_000n, // 1 USDC (6 decimals)
202
+ * maxPerWindow: 50_000_000n, // 50 USDC
203
+ * windowSeconds: 86400, // 24 hours
204
+ * }
205
+ * }, bearerToken);
206
+ * ```
207
+ */
208
+ setSpendingPolicy(params: SetSpendingPolicyParams, bearerToken: string): Promise<string>;
209
+ /**
210
+ * Query a spending policy from the smart contract.
211
+ *
212
+ * This is a read-only call that does not require signing or gas.
213
+ * Returns zeroed data if no policy is set (meaning no enforcement).
214
+ *
215
+ * @param params - Query parameters
216
+ * @returns Spending policy data including limits and current window state
217
+ *
218
+ * @example
219
+ * ```typescript
220
+ * const policy = await sdk.sessions.getSpendingPolicy({
221
+ * walletAddress: userWallet.publicKey,
222
+ * sessionPublicKey: session.publicKey,
223
+ * token: USDC_ADDRESS,
224
+ * });
225
+ * if (policy.maxPerWindow > 0n) {
226
+ * console.log(`Spent ${policy.spentInWindow} of ${policy.maxPerWindow} this window`);
227
+ * }
228
+ * ```
229
+ */
230
+ getSpendingPolicy(params: GetSpendingPolicyParams): Promise<SpendingPolicyData>;
231
+ /**
232
+ * Remove a spending policy for a session key + token pair.
233
+ *
234
+ * This executes a sponsored transaction (using owner signature) to call
235
+ * `remove_spending_policy` on the CHIPI wallet contract.
236
+ *
237
+ * After removal, the session key has no spending limits for this token.
238
+ *
239
+ * @param params - Policy removal parameters
240
+ * @param bearerToken - Authentication token
241
+ * @returns Transaction hash
242
+ *
243
+ * @example
244
+ * ```typescript
245
+ * const txHash = await sdk.sessions.removeSpendingPolicy({
246
+ * encryptKey: userEncryptKey,
247
+ * wallet: userWallet,
248
+ * sessionPublicKey: session.publicKey,
249
+ * token: USDC_ADDRESS,
250
+ * }, bearerToken);
251
+ * ```
252
+ */
253
+ removeSpendingPolicy(params: RemoveSpendingPolicyParams, bearerToken: string): Promise<string>;
171
254
  }
172
255
 
173
256
  declare class ChipiExchanges {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _chipi_stack_types from '@chipi-stack/types';
2
- import { CreateSessionKeyParams, SessionKeyData, AddSessionKeyParams, RevokeSessionKeyParams, GetSessionDataParams, SessionDataResponse, ExecuteWithSessionParams, Currency, PaymasterAdapter, PaymasterAccount, X402FacilitatorConfig, NonceStore, PaymentPayload, VerifyResponse, SettleResponse, ChipiSDKConfig, ExecuteTransactionParams, SignTypedDataParams, SignTypedDataResult, TransferParams, ApproveParams, CallAnyContractParams, CreateWalletParams, CreateWalletResponse, RecordSendTransactionParams, Transaction, GetTransactionListQuery, PaginatedResponse, GetWalletParams, GetTokenBalanceParams, GetTokenBalanceResponse, CreateSkuPurchaseParams, GetSkuListQuery, Sku, TransactionStatusResponse, PrepareWalletUpgradeParams, PrepareWalletUpgradeResponse, ExecuteWalletUpgradeParams, ExecuteWalletUpgradeResponse, ChipiServerSDKConfig, ChipiBrowserSDKConfig, X402PaymentConfig } from '@chipi-stack/types';
2
+ import { CreateSessionKeyParams, SessionKeyData, AddSessionKeyParams, RevokeSessionKeyParams, GetSessionDataParams, SessionDataResponse, ExecuteWithSessionParams, SetSpendingPolicyParams, GetSpendingPolicyParams, SpendingPolicyData, RemoveSpendingPolicyParams, Currency, PaymasterAdapter, PaymasterAccount, X402FacilitatorConfig, NonceStore, PaymentPayload, VerifyResponse, SettleResponse, ChipiSDKConfig, ExecuteTransactionParams, SignTypedDataParams, SignTypedDataResult, TransferParams, ApproveParams, CallAnyContractParams, CreateWalletParams, CreateWalletResponse, RecordSendTransactionParams, Transaction, GetTransactionListQuery, PaginatedResponse, GetWalletParams, GetTokenBalanceParams, GetTokenBalanceResponse, CreateSkuPurchaseParams, GetSkuListQuery, Sku, TransactionStatusResponse, PrepareWalletUpgradeParams, PrepareWalletUpgradeResponse, ExecuteWalletUpgradeParams, ExecuteWalletUpgradeResponse, ChipiServerSDKConfig, ChipiBrowserSDKConfig, X402PaymentConfig } from '@chipi-stack/types';
3
3
  export * from '@chipi-stack/types';
4
4
  export { Chain, ChainToken } from '@chipi-stack/types';
5
5
  import { ChipiWallets } from './wallets.js';
@@ -168,6 +168,89 @@ declare class ChipiSessions {
168
168
  * ```
169
169
  */
170
170
  executeTransactionWithSession(params: ExecuteWithSessionParams, bearerToken: string): Promise<string>;
171
+ /**
172
+ * Split a bigint into Cairo u256 representation (low u128, high u128).
173
+ */
174
+ private splitU256;
175
+ /**
176
+ * Reconstruct a bigint from Cairo u256 (low, high) hex strings.
177
+ */
178
+ private joinU256;
179
+ /**
180
+ * Set a spending policy for a session key + token pair.
181
+ *
182
+ * This executes a sponsored transaction (using owner signature) to call
183
+ * `set_spending_policy` on the CHIPI wallet contract.
184
+ *
185
+ * The contract enforces these limits automatically during `__execute__()` on
186
+ * ERC-20 operations (transfer, approve, increase_allowance) made by the session.
187
+ *
188
+ * @param params - Spending policy parameters
189
+ * @param bearerToken - Authentication token
190
+ * @returns Transaction hash
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * // Set a spending limit: max 1 USDC per call, 50 USDC per day
195
+ * const txHash = await sdk.sessions.setSpendingPolicy({
196
+ * encryptKey: userEncryptKey,
197
+ * wallet: userWallet,
198
+ * spendingPolicyConfig: {
199
+ * sessionPublicKey: session.publicKey,
200
+ * token: USDC_ADDRESS,
201
+ * maxPerCall: 1_000_000n, // 1 USDC (6 decimals)
202
+ * maxPerWindow: 50_000_000n, // 50 USDC
203
+ * windowSeconds: 86400, // 24 hours
204
+ * }
205
+ * }, bearerToken);
206
+ * ```
207
+ */
208
+ setSpendingPolicy(params: SetSpendingPolicyParams, bearerToken: string): Promise<string>;
209
+ /**
210
+ * Query a spending policy from the smart contract.
211
+ *
212
+ * This is a read-only call that does not require signing or gas.
213
+ * Returns zeroed data if no policy is set (meaning no enforcement).
214
+ *
215
+ * @param params - Query parameters
216
+ * @returns Spending policy data including limits and current window state
217
+ *
218
+ * @example
219
+ * ```typescript
220
+ * const policy = await sdk.sessions.getSpendingPolicy({
221
+ * walletAddress: userWallet.publicKey,
222
+ * sessionPublicKey: session.publicKey,
223
+ * token: USDC_ADDRESS,
224
+ * });
225
+ * if (policy.maxPerWindow > 0n) {
226
+ * console.log(`Spent ${policy.spentInWindow} of ${policy.maxPerWindow} this window`);
227
+ * }
228
+ * ```
229
+ */
230
+ getSpendingPolicy(params: GetSpendingPolicyParams): Promise<SpendingPolicyData>;
231
+ /**
232
+ * Remove a spending policy for a session key + token pair.
233
+ *
234
+ * This executes a sponsored transaction (using owner signature) to call
235
+ * `remove_spending_policy` on the CHIPI wallet contract.
236
+ *
237
+ * After removal, the session key has no spending limits for this token.
238
+ *
239
+ * @param params - Policy removal parameters
240
+ * @param bearerToken - Authentication token
241
+ * @returns Transaction hash
242
+ *
243
+ * @example
244
+ * ```typescript
245
+ * const txHash = await sdk.sessions.removeSpendingPolicy({
246
+ * encryptKey: userEncryptKey,
247
+ * wallet: userWallet,
248
+ * sessionPublicKey: session.publicKey,
249
+ * token: USDC_ADDRESS,
250
+ * }, bearerToken);
251
+ * ```
252
+ */
253
+ removeSpendingPolicy(params: RemoveSpendingPolicyParams, bearerToken: string): Promise<string>;
171
254
  }
172
255
 
173
256
  declare class ChipiExchanges {
package/dist/index.js CHANGED
@@ -1424,6 +1424,324 @@ var ChipiSessions = class {
1424
1424
  client: this.client
1425
1425
  });
1426
1426
  }
1427
+ // --- Spending Policy Methods ---
1428
+ // Wraps ISessionSpendingPolicy contract interface.
1429
+ // Spending policies enforce per-token limits on ERC-20 operations
1430
+ // (transfer, approve, increase_allowance) executed by session keys.
1431
+ /**
1432
+ * Split a bigint into Cairo u256 representation (low u128, high u128).
1433
+ */
1434
+ splitU256(value) {
1435
+ const mask = (1n << 128n) - 1n;
1436
+ return [starknet.num.toHex(value & mask), starknet.num.toHex(value >> 128n)];
1437
+ }
1438
+ /**
1439
+ * Reconstruct a bigint from Cairo u256 (low, high) hex strings.
1440
+ */
1441
+ joinU256(low, high) {
1442
+ return BigInt(low) + (BigInt(high) << 128n);
1443
+ }
1444
+ /**
1445
+ * Set a spending policy for a session key + token pair.
1446
+ *
1447
+ * This executes a sponsored transaction (using owner signature) to call
1448
+ * `set_spending_policy` on the CHIPI wallet contract.
1449
+ *
1450
+ * The contract enforces these limits automatically during `__execute__()` on
1451
+ * ERC-20 operations (transfer, approve, increase_allowance) made by the session.
1452
+ *
1453
+ * @param params - Spending policy parameters
1454
+ * @param bearerToken - Authentication token
1455
+ * @returns Transaction hash
1456
+ *
1457
+ * @example
1458
+ * ```typescript
1459
+ * // Set a spending limit: max 1 USDC per call, 50 USDC per day
1460
+ * const txHash = await sdk.sessions.setSpendingPolicy({
1461
+ * encryptKey: userEncryptKey,
1462
+ * wallet: userWallet,
1463
+ * spendingPolicyConfig: {
1464
+ * sessionPublicKey: session.publicKey,
1465
+ * token: USDC_ADDRESS,
1466
+ * maxPerCall: 1_000_000n, // 1 USDC (6 decimals)
1467
+ * maxPerWindow: 50_000_000n, // 50 USDC
1468
+ * windowSeconds: 86400, // 24 hours
1469
+ * }
1470
+ * }, bearerToken);
1471
+ * ```
1472
+ */
1473
+ async setSpendingPolicy(params, bearerToken) {
1474
+ const { encryptKey, wallet, spendingPolicyConfig } = params;
1475
+ const { sessionPublicKey, token, maxPerCall, maxPerWindow, windowSeconds } = spendingPolicyConfig;
1476
+ if (wallet.walletType && wallet.walletType !== "CHIPI") {
1477
+ throw new shared.ChipiSessionError(
1478
+ `Spending policies only support CHIPI wallets. Got: ${wallet.walletType}`,
1479
+ shared.SESSION_ERRORS.INVALID_WALLET_TYPE_FOR_SESSION
1480
+ );
1481
+ }
1482
+ const U256_MAX = (1n << 256n) - 1n;
1483
+ const U64_MAX = (1n << 64n) - 1n;
1484
+ if (!token || token.trim().length === 0) {
1485
+ throw new shared.ChipiSessionError(
1486
+ `Invalid token address for spending policy: "${token}"`,
1487
+ shared.SESSION_ERRORS.INVALID_SPENDING_POLICY
1488
+ );
1489
+ }
1490
+ if (typeof windowSeconds !== "number" || !Number.isFinite(windowSeconds) || !Number.isInteger(windowSeconds) || windowSeconds <= 0 || BigInt(windowSeconds) > U64_MAX) {
1491
+ throw new shared.ChipiSessionError(
1492
+ `Invalid window duration: ${windowSeconds}. Must be a positive integer within u64 range.`,
1493
+ shared.SESSION_ERRORS.INVALID_SPENDING_POLICY
1494
+ );
1495
+ }
1496
+ if (maxPerCall < 0n || maxPerCall > U256_MAX) {
1497
+ throw new shared.ChipiSessionError(
1498
+ `Invalid maxPerCall: must be >= 0 and <= 2^256 - 1`,
1499
+ shared.SESSION_ERRORS.INVALID_SPENDING_POLICY
1500
+ );
1501
+ }
1502
+ if (maxPerWindow < 0n || maxPerWindow > U256_MAX) {
1503
+ throw new shared.ChipiSessionError(
1504
+ `Invalid maxPerWindow: must be >= 0 and <= 2^256 - 1`,
1505
+ shared.SESSION_ERRORS.INVALID_SPENDING_POLICY
1506
+ );
1507
+ }
1508
+ if (maxPerWindow > 0n && maxPerCall > maxPerWindow) {
1509
+ throw new shared.ChipiSessionError(
1510
+ `Invalid spending policy: maxPerCall (${maxPerCall}) cannot exceed maxPerWindow (${maxPerWindow})`,
1511
+ shared.SESSION_ERRORS.INVALID_SPENDING_POLICY
1512
+ );
1513
+ }
1514
+ try {
1515
+ console.log("[ChipiSDK:Session:SetSpendingPolicy] Setting spending policy", {
1516
+ walletAddress: wallet.publicKey.slice(0, 15) + "...",
1517
+ sessionPubKey: sessionPublicKey.slice(0, 15) + "...",
1518
+ token: token.slice(0, 15) + "...",
1519
+ maxPerCall: maxPerCall.toString(),
1520
+ maxPerWindow: maxPerWindow.toString(),
1521
+ windowSeconds
1522
+ });
1523
+ const [maxPerCallLow, maxPerCallHigh] = this.splitU256(maxPerCall);
1524
+ const [maxPerWindowLow, maxPerWindowHigh] = this.splitU256(maxPerWindow);
1525
+ const calldata = [
1526
+ sessionPublicKey,
1527
+ token,
1528
+ maxPerCallLow,
1529
+ maxPerCallHigh,
1530
+ maxPerWindowLow,
1531
+ maxPerWindowHigh,
1532
+ starknet.num.toHex(windowSeconds)
1533
+ ];
1534
+ const txHash = await executePaymasterTransaction({
1535
+ params: {
1536
+ encryptKey,
1537
+ wallet: { ...wallet, walletType: "CHIPI" },
1538
+ calls: [
1539
+ {
1540
+ contractAddress: wallet.publicKey,
1541
+ entrypoint: shared.SESSION_ENTRYPOINTS.SET_SPENDING_POLICY,
1542
+ calldata
1543
+ }
1544
+ ],
1545
+ saveToDatabase: false
1546
+ },
1547
+ bearerToken,
1548
+ client: this.client
1549
+ });
1550
+ console.log("[ChipiSDK:Session:SetSpendingPolicy] Spending policy set successfully", {
1551
+ txHash,
1552
+ sessionPubKey: sessionPublicKey.slice(0, 15) + "...",
1553
+ token: token.slice(0, 15) + "..."
1554
+ });
1555
+ return txHash;
1556
+ } catch (error) {
1557
+ const err = error instanceof Error ? error : new Error(String(error));
1558
+ console.error("[ChipiSDK:Session:SetSpendingPolicy] Failed to set spending policy", {
1559
+ error: err.message,
1560
+ walletAddress: wallet.publicKey?.slice(0, 15) + "...",
1561
+ sessionPubKey: sessionPublicKey?.slice(0, 15) + "...",
1562
+ token: token?.slice(0, 15) + "..."
1563
+ });
1564
+ throw error;
1565
+ }
1566
+ }
1567
+ /**
1568
+ * Query a spending policy from the smart contract.
1569
+ *
1570
+ * This is a read-only call that does not require signing or gas.
1571
+ * Returns zeroed data if no policy is set (meaning no enforcement).
1572
+ *
1573
+ * @param params - Query parameters
1574
+ * @returns Spending policy data including limits and current window state
1575
+ *
1576
+ * @example
1577
+ * ```typescript
1578
+ * const policy = await sdk.sessions.getSpendingPolicy({
1579
+ * walletAddress: userWallet.publicKey,
1580
+ * sessionPublicKey: session.publicKey,
1581
+ * token: USDC_ADDRESS,
1582
+ * });
1583
+ * if (policy.maxPerWindow > 0n) {
1584
+ * console.log(`Spent ${policy.spentInWindow} of ${policy.maxPerWindow} this window`);
1585
+ * }
1586
+ * ```
1587
+ */
1588
+ async getSpendingPolicy(params) {
1589
+ const { walletAddress, sessionPublicKey, token } = params;
1590
+ try {
1591
+ const provider = new starknet.RpcProvider({
1592
+ nodeUrl: shared.WALLET_RPC_ENDPOINTS["CHIPI"]
1593
+ });
1594
+ console.log("[ChipiSDK:Session:GetSpendingPolicy] Querying spending policy", {
1595
+ walletAddress: walletAddress.slice(0, 15) + "...",
1596
+ sessionPubKey: sessionPublicKey.slice(0, 15) + "...",
1597
+ token: token.slice(0, 15) + "..."
1598
+ });
1599
+ const result = await provider.callContract({
1600
+ contractAddress: walletAddress,
1601
+ entrypoint: shared.SESSION_ENTRYPOINTS.GET_SPENDING_POLICY,
1602
+ calldata: [sessionPublicKey, token]
1603
+ });
1604
+ const resultArray = Array.isArray(result) ? result : result.result || [];
1605
+ if (resultArray.length < 8) {
1606
+ console.warn("[ChipiSDK:Session:GetSpendingPolicy] Unexpected response format", {
1607
+ resultLength: resultArray.length,
1608
+ result: resultArray
1609
+ });
1610
+ return {
1611
+ maxPerCall: 0n,
1612
+ maxPerWindow: 0n,
1613
+ windowSeconds: 0,
1614
+ spentInWindow: 0n,
1615
+ windowStart: 0
1616
+ };
1617
+ }
1618
+ const policyData = {
1619
+ maxPerCall: this.joinU256(resultArray[0], resultArray[1]),
1620
+ maxPerWindow: this.joinU256(resultArray[2], resultArray[3]),
1621
+ windowSeconds: Number(BigInt(resultArray[4])),
1622
+ spentInWindow: this.joinU256(resultArray[5], resultArray[6]),
1623
+ windowStart: Number(BigInt(resultArray[7]))
1624
+ };
1625
+ console.log("[ChipiSDK:Session:GetSpendingPolicy] Spending policy retrieved", {
1626
+ maxPerCall: policyData.maxPerCall.toString(),
1627
+ maxPerWindow: policyData.maxPerWindow.toString(),
1628
+ windowSeconds: policyData.windowSeconds,
1629
+ spentInWindow: policyData.spentInWindow.toString(),
1630
+ windowStart: policyData.windowStart
1631
+ });
1632
+ return policyData;
1633
+ } catch (error) {
1634
+ const err = error instanceof Error ? error : new Error(String(error));
1635
+ const notFoundPatterns = [
1636
+ /entry point.*not found/i,
1637
+ /requested entrypoint was not found/i,
1638
+ /invalid message selector/i,
1639
+ /contract not found/i,
1640
+ /is not deployed/i
1641
+ ];
1642
+ const isNotFound = notFoundPatterns.some((p) => p.test(err.message));
1643
+ if (isNotFound) {
1644
+ console.log(
1645
+ "[ChipiSDK:Session:GetSpendingPolicy] No policy found (contract or entrypoint missing)",
1646
+ {
1647
+ walletAddress: walletAddress?.slice(0, 15) + "...",
1648
+ sessionPubKey: sessionPublicKey?.slice(0, 15) + "...",
1649
+ token: token?.slice(0, 15) + "..."
1650
+ }
1651
+ );
1652
+ return {
1653
+ maxPerCall: 0n,
1654
+ maxPerWindow: 0n,
1655
+ windowSeconds: 0,
1656
+ spentInWindow: 0n,
1657
+ windowStart: 0
1658
+ };
1659
+ }
1660
+ console.error("[ChipiSDK:Session:GetSpendingPolicy] RPC/network error", {
1661
+ error: err.message,
1662
+ walletAddress: walletAddress?.slice(0, 15) + "...",
1663
+ sessionPubKey: sessionPublicKey?.slice(0, 15) + "...",
1664
+ token: token?.slice(0, 15) + "..."
1665
+ });
1666
+ throw err;
1667
+ }
1668
+ }
1669
+ /**
1670
+ * Remove a spending policy for a session key + token pair.
1671
+ *
1672
+ * This executes a sponsored transaction (using owner signature) to call
1673
+ * `remove_spending_policy` on the CHIPI wallet contract.
1674
+ *
1675
+ * After removal, the session key has no spending limits for this token.
1676
+ *
1677
+ * @param params - Policy removal parameters
1678
+ * @param bearerToken - Authentication token
1679
+ * @returns Transaction hash
1680
+ *
1681
+ * @example
1682
+ * ```typescript
1683
+ * const txHash = await sdk.sessions.removeSpendingPolicy({
1684
+ * encryptKey: userEncryptKey,
1685
+ * wallet: userWallet,
1686
+ * sessionPublicKey: session.publicKey,
1687
+ * token: USDC_ADDRESS,
1688
+ * }, bearerToken);
1689
+ * ```
1690
+ */
1691
+ async removeSpendingPolicy(params, bearerToken) {
1692
+ const { encryptKey, wallet, sessionPublicKey, token } = params;
1693
+ if (wallet.walletType && wallet.walletType !== "CHIPI") {
1694
+ throw new shared.ChipiSessionError(
1695
+ `Spending policies only support CHIPI wallets. Got: ${wallet.walletType}`,
1696
+ shared.SESSION_ERRORS.INVALID_WALLET_TYPE_FOR_SESSION
1697
+ );
1698
+ }
1699
+ if (!token || token.trim().length === 0) {
1700
+ throw new shared.ChipiSessionError(
1701
+ `Invalid token address for spending policy removal: "${token}"`,
1702
+ shared.SESSION_ERRORS.INVALID_SPENDING_POLICY
1703
+ );
1704
+ }
1705
+ try {
1706
+ console.log("[ChipiSDK:Session:RemoveSpendingPolicy] Removing spending policy", {
1707
+ walletAddress: wallet.publicKey.slice(0, 15) + "...",
1708
+ sessionPubKey: sessionPublicKey.slice(0, 15) + "...",
1709
+ token: token.slice(0, 15) + "..."
1710
+ });
1711
+ const calldata = [sessionPublicKey, token];
1712
+ const txHash = await executePaymasterTransaction({
1713
+ params: {
1714
+ encryptKey,
1715
+ wallet: { ...wallet, walletType: "CHIPI" },
1716
+ calls: [
1717
+ {
1718
+ contractAddress: wallet.publicKey,
1719
+ entrypoint: shared.SESSION_ENTRYPOINTS.REMOVE_SPENDING_POLICY,
1720
+ calldata
1721
+ }
1722
+ ],
1723
+ saveToDatabase: false
1724
+ },
1725
+ bearerToken,
1726
+ client: this.client
1727
+ });
1728
+ console.log("[ChipiSDK:Session:RemoveSpendingPolicy] Spending policy removed successfully", {
1729
+ txHash,
1730
+ sessionPubKey: sessionPublicKey.slice(0, 15) + "...",
1731
+ token: token.slice(0, 15) + "..."
1732
+ });
1733
+ return txHash;
1734
+ } catch (error) {
1735
+ const err = error instanceof Error ? error : new Error(String(error));
1736
+ console.error("[ChipiSDK:Session:RemoveSpendingPolicy] Failed to remove spending policy", {
1737
+ error: err.message,
1738
+ walletAddress: wallet.publicKey?.slice(0, 15) + "...",
1739
+ sessionPubKey: sessionPublicKey?.slice(0, 15) + "...",
1740
+ token: token?.slice(0, 15) + "..."
1741
+ });
1742
+ throw error;
1743
+ }
1744
+ }
1427
1745
  };
1428
1746
  var InMemoryNonceStore = class {
1429
1747
  constructor() {