@chipi-stack/chipi-react 14.15.1 → 14.16.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.
@@ -1897,19 +1897,52 @@ type ChipiApprovalRequest = {
1897
1897
  * `[session_pubkey, r, s, valid_until]`.
1898
1898
  */
1899
1899
  interface ChipiSessionPolicy {
1900
- /** Allowed (contractAddress, entrypoint) pairs the session may call. */
1900
+ /**
1901
+ * Allowed (contractAddress, entrypoint) pairs the session may call.
1902
+ *
1903
+ * Client side, `useChipiWalletObject` only routes a call through the session
1904
+ * when its exact (contract, entrypoint) pair is listed. On-chain, though, the
1905
+ * session whitelist is per entrypoint selector only: allowing `transfer` lets
1906
+ * the session call `transfer` on ANY contract. Use `spendCaps` to bound what
1907
+ * the session can move per token.
1908
+ */
1901
1909
  allowedCalls: Array<{
1902
1910
  contractAddress: string;
1903
1911
  entrypoint: string;
1904
1912
  }>;
1905
1913
  /** Unix seconds after which the session is invalid. */
1906
1914
  validUntil: number;
1907
- /** Optional per-token spend caps, by token address. */
1908
- spendCaps?: Array<{
1909
- token: string;
1910
- amount: string;
1911
- }>;
1915
+ /**
1916
+ * Optional per-token spend caps, registered on-chain as spending policies in
1917
+ * the same transaction as the session. A cap must never resolve to a window
1918
+ * limit of 0 (on-chain, 0 means unlimited); that is rejected.
1919
+ */
1920
+ spendCaps?: ChipiSessionSpendCap[];
1921
+ }
1922
+ /**
1923
+ * Simple per-token cap: `amount` (base units, decimal or hex string) is used as
1924
+ * both the per-call and the per-window limit, with a window equal to the
1925
+ * session lifetime.
1926
+ */
1927
+ interface ChipiSessionSpendCapAmount {
1928
+ /** ERC-20 token contract address. */
1929
+ token: string;
1930
+ /** Cap in token base units (e.g. "5000000" = 5 USDC). Must be > 0. */
1931
+ amount: string;
1932
+ }
1933
+ /** Full per-token spending policy (mirrors `SpendingPolicyConfig`). */
1934
+ interface ChipiSessionSpendCapPolicy {
1935
+ /** ERC-20 token contract address. */
1936
+ token: string;
1937
+ /** Max amount per single call, in token base units. */
1938
+ maxPerCall: string | bigint;
1939
+ /** Max cumulative amount within the rolling window, in base units. Must be > 0. */
1940
+ maxPerWindow: string | bigint;
1941
+ /** Rolling window duration in seconds (positive integer). */
1942
+ windowSeconds: number;
1912
1943
  }
1944
+ /** A per-token spend cap: the simple `{ token, amount }` form or a full policy. */
1945
+ type ChipiSessionSpendCap = ChipiSessionSpendCapAmount | ChipiSessionSpendCapPolicy;
1913
1946
  /**
1914
1947
  * Everything the framework-agnostic SWO needs, supplied by the host layer
1915
1948
  * (`@chipi-stack/react`'s `useChipiWalletObject`, the hosted web-wallet, etc.).
@@ -1939,7 +1972,11 @@ interface ChipiWindowObjectDeps {
1939
1972
  getDeploymentData: () => Promise<AccountDeploymentData>;
1940
1973
  /** Optional: establish a session from a dApp-proposed policy (approve once). */
1941
1974
  createSession?: (policy: ChipiSessionPolicy) => Promise<void>;
1942
- /** Host approval gate. Defaults to auto-approve (harness) when omitted. */
1975
+ /**
1976
+ * Host approval gate: render the prompt and resolve `true` to approve.
1977
+ * When omitted, every approval is denied (deny by default) and a single
1978
+ * `console.warn` explains that `requestApproval` must be provided.
1979
+ */
1943
1980
  requestApproval?: (req: ChipiApprovalRequest) => Promise<boolean>;
1944
1981
  }
1945
1982
 
@@ -1958,7 +1995,11 @@ interface UseChipiWalletObjectConfig {
1958
1995
  sessionPolicy?: ChipiSessionPolicy | null;
1959
1996
  /** Chain id felt; defaults to SN_MAIN. */
1960
1997
  chainId?: string;
1961
- /** Host approval gate (connect / execute / signTypedData / session). */
1998
+ /**
1999
+ * Host approval gate (connect / execute / signTypedData / session). When
2000
+ * omitted, every approval is denied and a single `console.warn` explains
2001
+ * that `requestApproval` must be provided.
2002
+ */
1962
2003
  requestApproval?: (req: ChipiApprovalRequest) => Promise<boolean>;
1963
2004
  }
1964
2005
  /**
@@ -1971,6 +2012,15 @@ interface UseChipiWalletObjectConfig {
1971
2012
  * `injectChipiWallet`. `createSession(policy)` establishes a session on-chain
1972
2013
  * from a dApp-proposed policy (the "approve once" flow); the host stores the
1973
2014
  * returned SessionKeyData and feeds it back via `config.session`.
2015
+ *
2016
+ * Note: `allowedCalls` is matched per (contract, entrypoint) only client-side,
2017
+ * for routing. On-chain the session whitelist is per entrypoint selector, not
2018
+ * per contract, so pass `spendCaps` to bound token spend; with caps, the
2019
+ * session and its spending policies are registered in one owner-signed
2020
+ * transaction (`sdk.sessions.setupSession`).
2021
+ *
2022
+ * Approvals are deny-by-default: without `config.requestApproval`, every
2023
+ * approval is denied and a single `console.warn` says so.
1974
2024
  */
1975
2025
  declare function useChipiWalletObject(config: UseChipiWalletObjectConfig): {
1976
2026
  deps: ChipiWindowObjectDeps;
@@ -2916,4 +2966,4 @@ declare function usePrivateBalance(input: PrivateBalanceInput): {
2916
2966
  refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<Record<string, bigint>, Error>>;
2917
2967
  };
2918
2968
 
2919
- export { usePrivateBalance as $, useCallAnyContract as A, useSignTypedData as B, type ChipiWindowObjectDeps as C, useChipiWalletObject as D, useRecordSendTransaction as E, useGetTokenBalance as F, useCreateSessionKey as G, useAddSessionKeyToContract as H, useRevokeSessionKey as I, useGetSessionData as J, useExecuteWithSession as K, useX402Payment as L, type UseX402PaymentConfig as M, type UseX402PaymentReturn as N, useShhhSigner as O, type UseShhhSignerReturn as P, useGuardianRecovery as Q, type RegisterSessionConfig as R, type SessionState as S, type UseGuardianRecoveryReturn as T, type UseChipiWalletObjectConfig as U, useThresholdSign as V, type UseThresholdSignReturn as W, type UseThresholdSignOptions as X, type ThresholdSignState as Y, useShield as Z, useUnshield as _, type ChipiApprovalRequest as a, derivePrivacyAccount as a0, netPrivateBalance as a1, type PrivacyConfig as a2, type PrivacyKeys as a3, type PrivacyStep as a4, type ShieldHookInput as a5, type PrivacyLedgerEvent as a6, type PrivateBalanceInput as a7, type ChipiSessionPolicy as b, useGetWallet as c, useChipiWallet as d, type UseChipiWalletConfig as e, type UseChipiWalletReturn as f, type ChipiWalletData as g, useChipiSession as h, type UseChipiSessionConfig as i, type UseChipiSessionReturn as j, type SessionWallet as k, useMigrateWalletToPasskey as l, useUpdateWalletEncryption as m, useMigrateWalletToShhh as n, useTransfer as o, type UseTransferConfig as p, useApprove as q, useGetTransactionList as r, useGetTransaction as s, useGetTransactionStatus as t, useCreateWallet as u, useSyncOnChainTransfers as v, usePurchaseSku as w, useGetSkuPurchase as x, useGetSkuList as y, useGetSku as z };
2969
+ export { type ThresholdSignState as $, useGetSkuPurchase as A, useGetSkuList as B, type ChipiWindowObjectDeps as C, useGetSku as D, useCallAnyContract as E, useSignTypedData as F, useChipiWalletObject as G, useRecordSendTransaction as H, useGetTokenBalance as I, useCreateSessionKey as J, useAddSessionKeyToContract as K, useRevokeSessionKey as L, useGetSessionData as M, useExecuteWithSession as N, useX402Payment as O, type UseX402PaymentConfig as P, type UseX402PaymentReturn as Q, type RegisterSessionConfig as R, type SessionState as S, useShhhSigner as T, type UseChipiWalletObjectConfig as U, type UseShhhSignerReturn as V, useGuardianRecovery as W, type UseGuardianRecoveryReturn as X, useThresholdSign as Y, type UseThresholdSignReturn as Z, type UseThresholdSignOptions as _, type ChipiApprovalRequest as a, useShield as a0, useUnshield as a1, usePrivateBalance as a2, derivePrivacyAccount as a3, netPrivateBalance as a4, type PrivacyConfig as a5, type PrivacyKeys as a6, type PrivacyStep as a7, type ShieldHookInput as a8, type PrivacyLedgerEvent as a9, type PrivateBalanceInput as aa, type ChipiSessionPolicy as b, type ChipiSessionSpendCap as c, type ChipiSessionSpendCapAmount as d, type ChipiSessionSpendCapPolicy as e, useGetWallet as f, useChipiWallet as g, type UseChipiWalletConfig as h, type UseChipiWalletReturn as i, type ChipiWalletData as j, useChipiSession as k, type UseChipiSessionConfig as l, type UseChipiSessionReturn as m, type SessionWallet as n, useMigrateWalletToPasskey as o, useUpdateWalletEncryption as p, useMigrateWalletToShhh as q, useTransfer as r, type UseTransferConfig as s, useApprove as t, useCreateWallet as u, useGetTransactionList as v, useGetTransaction as w, useGetTransactionStatus as x, useSyncOnChainTransfers as y, usePurchaseSku as z };
@@ -1897,19 +1897,52 @@ type ChipiApprovalRequest = {
1897
1897
  * `[session_pubkey, r, s, valid_until]`.
1898
1898
  */
1899
1899
  interface ChipiSessionPolicy {
1900
- /** Allowed (contractAddress, entrypoint) pairs the session may call. */
1900
+ /**
1901
+ * Allowed (contractAddress, entrypoint) pairs the session may call.
1902
+ *
1903
+ * Client side, `useChipiWalletObject` only routes a call through the session
1904
+ * when its exact (contract, entrypoint) pair is listed. On-chain, though, the
1905
+ * session whitelist is per entrypoint selector only: allowing `transfer` lets
1906
+ * the session call `transfer` on ANY contract. Use `spendCaps` to bound what
1907
+ * the session can move per token.
1908
+ */
1901
1909
  allowedCalls: Array<{
1902
1910
  contractAddress: string;
1903
1911
  entrypoint: string;
1904
1912
  }>;
1905
1913
  /** Unix seconds after which the session is invalid. */
1906
1914
  validUntil: number;
1907
- /** Optional per-token spend caps, by token address. */
1908
- spendCaps?: Array<{
1909
- token: string;
1910
- amount: string;
1911
- }>;
1915
+ /**
1916
+ * Optional per-token spend caps, registered on-chain as spending policies in
1917
+ * the same transaction as the session. A cap must never resolve to a window
1918
+ * limit of 0 (on-chain, 0 means unlimited); that is rejected.
1919
+ */
1920
+ spendCaps?: ChipiSessionSpendCap[];
1921
+ }
1922
+ /**
1923
+ * Simple per-token cap: `amount` (base units, decimal or hex string) is used as
1924
+ * both the per-call and the per-window limit, with a window equal to the
1925
+ * session lifetime.
1926
+ */
1927
+ interface ChipiSessionSpendCapAmount {
1928
+ /** ERC-20 token contract address. */
1929
+ token: string;
1930
+ /** Cap in token base units (e.g. "5000000" = 5 USDC). Must be > 0. */
1931
+ amount: string;
1932
+ }
1933
+ /** Full per-token spending policy (mirrors `SpendingPolicyConfig`). */
1934
+ interface ChipiSessionSpendCapPolicy {
1935
+ /** ERC-20 token contract address. */
1936
+ token: string;
1937
+ /** Max amount per single call, in token base units. */
1938
+ maxPerCall: string | bigint;
1939
+ /** Max cumulative amount within the rolling window, in base units. Must be > 0. */
1940
+ maxPerWindow: string | bigint;
1941
+ /** Rolling window duration in seconds (positive integer). */
1942
+ windowSeconds: number;
1912
1943
  }
1944
+ /** A per-token spend cap: the simple `{ token, amount }` form or a full policy. */
1945
+ type ChipiSessionSpendCap = ChipiSessionSpendCapAmount | ChipiSessionSpendCapPolicy;
1913
1946
  /**
1914
1947
  * Everything the framework-agnostic SWO needs, supplied by the host layer
1915
1948
  * (`@chipi-stack/react`'s `useChipiWalletObject`, the hosted web-wallet, etc.).
@@ -1939,7 +1972,11 @@ interface ChipiWindowObjectDeps {
1939
1972
  getDeploymentData: () => Promise<AccountDeploymentData>;
1940
1973
  /** Optional: establish a session from a dApp-proposed policy (approve once). */
1941
1974
  createSession?: (policy: ChipiSessionPolicy) => Promise<void>;
1942
- /** Host approval gate. Defaults to auto-approve (harness) when omitted. */
1975
+ /**
1976
+ * Host approval gate: render the prompt and resolve `true` to approve.
1977
+ * When omitted, every approval is denied (deny by default) and a single
1978
+ * `console.warn` explains that `requestApproval` must be provided.
1979
+ */
1943
1980
  requestApproval?: (req: ChipiApprovalRequest) => Promise<boolean>;
1944
1981
  }
1945
1982
 
@@ -1958,7 +1995,11 @@ interface UseChipiWalletObjectConfig {
1958
1995
  sessionPolicy?: ChipiSessionPolicy | null;
1959
1996
  /** Chain id felt; defaults to SN_MAIN. */
1960
1997
  chainId?: string;
1961
- /** Host approval gate (connect / execute / signTypedData / session). */
1998
+ /**
1999
+ * Host approval gate (connect / execute / signTypedData / session). When
2000
+ * omitted, every approval is denied and a single `console.warn` explains
2001
+ * that `requestApproval` must be provided.
2002
+ */
1962
2003
  requestApproval?: (req: ChipiApprovalRequest) => Promise<boolean>;
1963
2004
  }
1964
2005
  /**
@@ -1971,6 +2012,15 @@ interface UseChipiWalletObjectConfig {
1971
2012
  * `injectChipiWallet`. `createSession(policy)` establishes a session on-chain
1972
2013
  * from a dApp-proposed policy (the "approve once" flow); the host stores the
1973
2014
  * returned SessionKeyData and feeds it back via `config.session`.
2015
+ *
2016
+ * Note: `allowedCalls` is matched per (contract, entrypoint) only client-side,
2017
+ * for routing. On-chain the session whitelist is per entrypoint selector, not
2018
+ * per contract, so pass `spendCaps` to bound token spend; with caps, the
2019
+ * session and its spending policies are registered in one owner-signed
2020
+ * transaction (`sdk.sessions.setupSession`).
2021
+ *
2022
+ * Approvals are deny-by-default: without `config.requestApproval`, every
2023
+ * approval is denied and a single `console.warn` says so.
1974
2024
  */
1975
2025
  declare function useChipiWalletObject(config: UseChipiWalletObjectConfig): {
1976
2026
  deps: ChipiWindowObjectDeps;
@@ -2916,4 +2966,4 @@ declare function usePrivateBalance(input: PrivateBalanceInput): {
2916
2966
  refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<Record<string, bigint>, Error>>;
2917
2967
  };
2918
2968
 
2919
- export { usePrivateBalance as $, useCallAnyContract as A, useSignTypedData as B, type ChipiWindowObjectDeps as C, useChipiWalletObject as D, useRecordSendTransaction as E, useGetTokenBalance as F, useCreateSessionKey as G, useAddSessionKeyToContract as H, useRevokeSessionKey as I, useGetSessionData as J, useExecuteWithSession as K, useX402Payment as L, type UseX402PaymentConfig as M, type UseX402PaymentReturn as N, useShhhSigner as O, type UseShhhSignerReturn as P, useGuardianRecovery as Q, type RegisterSessionConfig as R, type SessionState as S, type UseGuardianRecoveryReturn as T, type UseChipiWalletObjectConfig as U, useThresholdSign as V, type UseThresholdSignReturn as W, type UseThresholdSignOptions as X, type ThresholdSignState as Y, useShield as Z, useUnshield as _, type ChipiApprovalRequest as a, derivePrivacyAccount as a0, netPrivateBalance as a1, type PrivacyConfig as a2, type PrivacyKeys as a3, type PrivacyStep as a4, type ShieldHookInput as a5, type PrivacyLedgerEvent as a6, type PrivateBalanceInput as a7, type ChipiSessionPolicy as b, useGetWallet as c, useChipiWallet as d, type UseChipiWalletConfig as e, type UseChipiWalletReturn as f, type ChipiWalletData as g, useChipiSession as h, type UseChipiSessionConfig as i, type UseChipiSessionReturn as j, type SessionWallet as k, useMigrateWalletToPasskey as l, useUpdateWalletEncryption as m, useMigrateWalletToShhh as n, useTransfer as o, type UseTransferConfig as p, useApprove as q, useGetTransactionList as r, useGetTransaction as s, useGetTransactionStatus as t, useCreateWallet as u, useSyncOnChainTransfers as v, usePurchaseSku as w, useGetSkuPurchase as x, useGetSkuList as y, useGetSku as z };
2969
+ export { type ThresholdSignState as $, useGetSkuPurchase as A, useGetSkuList as B, type ChipiWindowObjectDeps as C, useGetSku as D, useCallAnyContract as E, useSignTypedData as F, useChipiWalletObject as G, useRecordSendTransaction as H, useGetTokenBalance as I, useCreateSessionKey as J, useAddSessionKeyToContract as K, useRevokeSessionKey as L, useGetSessionData as M, useExecuteWithSession as N, useX402Payment as O, type UseX402PaymentConfig as P, type UseX402PaymentReturn as Q, type RegisterSessionConfig as R, type SessionState as S, useShhhSigner as T, type UseChipiWalletObjectConfig as U, type UseShhhSignerReturn as V, useGuardianRecovery as W, type UseGuardianRecoveryReturn as X, useThresholdSign as Y, type UseThresholdSignReturn as Z, type UseThresholdSignOptions as _, type ChipiApprovalRequest as a, useShield as a0, useUnshield as a1, usePrivateBalance as a2, derivePrivacyAccount as a3, netPrivateBalance as a4, type PrivacyConfig as a5, type PrivacyKeys as a6, type PrivacyStep as a7, type ShieldHookInput as a8, type PrivacyLedgerEvent as a9, type PrivateBalanceInput as aa, type ChipiSessionPolicy as b, type ChipiSessionSpendCap as c, type ChipiSessionSpendCapAmount as d, type ChipiSessionSpendCapPolicy as e, useGetWallet as f, useChipiWallet as g, type UseChipiWalletConfig as h, type UseChipiWalletReturn as i, type ChipiWalletData as j, useChipiSession as k, type UseChipiSessionConfig as l, type UseChipiSessionReturn as m, type SessionWallet as n, useMigrateWalletToPasskey as o, useUpdateWalletEncryption as p, useMigrateWalletToShhh as q, useTransfer as r, type UseTransferConfig as s, useApprove as t, useCreateWallet as u, useGetTransactionList as v, useGetTransaction as w, useGetTransactionStatus as x, useSyncOnChainTransfers as y, usePurchaseSku as z };
package/dist/index.d.mts CHANGED
@@ -4,8 +4,8 @@ import { ChipiSDK, NewOwnerInput } from '@chipi-stack/backend';
4
4
  import { ChipiSDKConfig, WalletType } from '@chipi-stack/types';
5
5
  export * from '@chipi-stack/types';
6
6
  export { Chain, ChainToken } from '@chipi-stack/types';
7
- import { C as ChipiWindowObjectDeps, U as UseChipiWalletObjectConfig } from './index-gNLTF6ix.mjs';
8
- export { a as ChipiApprovalRequest, b as ChipiSessionPolicy, g as ChipiWalletData, a2 as PrivacyConfig, a3 as PrivacyKeys, a6 as PrivacyLedgerEvent, a4 as PrivacyStep, a7 as PrivateBalanceInput, R as RegisterSessionConfig, S as SessionState, k as SessionWallet, a5 as ShieldHookInput, Y as ThresholdSignState, i as UseChipiSessionConfig, j as UseChipiSessionReturn, e as UseChipiWalletConfig, f as UseChipiWalletReturn, T as UseGuardianRecoveryReturn, P as UseShhhSignerReturn, X as UseThresholdSignOptions, W as UseThresholdSignReturn, p as UseTransferConfig, M as UseX402PaymentConfig, N as UseX402PaymentReturn, a0 as derivePrivacyAccount, a1 as netPrivateBalance, H as useAddSessionKeyToContract, q as useApprove, A as useCallAnyContract, h as useChipiSession, d as useChipiWallet, D as useChipiWalletObject, G as useCreateSessionKey, u as useCreateWallet, K as useExecuteWithSession, J as useGetSessionData, z as useGetSku, y as useGetSkuList, x as useGetSkuPurchase, F as useGetTokenBalance, s as useGetTransaction, r as useGetTransactionList, t as useGetTransactionStatus, c as useGetWallet, Q as useGuardianRecovery, l as useMigrateWalletToPasskey, n as useMigrateWalletToShhh, $ as usePrivateBalance, w as usePurchaseSku, E as useRecordSendTransaction, I as useRevokeSessionKey, O as useShhhSigner, Z as useShield, B as useSignTypedData, v as useSyncOnChainTransfers, V as useThresholdSign, o as useTransfer, _ as useUnshield, m as useUpdateWalletEncryption, L as useX402Payment } from './index-gNLTF6ix.mjs';
7
+ import { C as ChipiWindowObjectDeps, U as UseChipiWalletObjectConfig } from './index-Dbqp9oNS.mjs';
8
+ export { a as ChipiApprovalRequest, b as ChipiSessionPolicy, c as ChipiSessionSpendCap, d as ChipiSessionSpendCapAmount, e as ChipiSessionSpendCapPolicy, j as ChipiWalletData, a5 as PrivacyConfig, a6 as PrivacyKeys, a9 as PrivacyLedgerEvent, a7 as PrivacyStep, aa as PrivateBalanceInput, R as RegisterSessionConfig, S as SessionState, n as SessionWallet, a8 as ShieldHookInput, $ as ThresholdSignState, l as UseChipiSessionConfig, m as UseChipiSessionReturn, h as UseChipiWalletConfig, i as UseChipiWalletReturn, X as UseGuardianRecoveryReturn, V as UseShhhSignerReturn, _ as UseThresholdSignOptions, Z as UseThresholdSignReturn, s as UseTransferConfig, P as UseX402PaymentConfig, Q as UseX402PaymentReturn, a3 as derivePrivacyAccount, a4 as netPrivateBalance, K as useAddSessionKeyToContract, t as useApprove, E as useCallAnyContract, k as useChipiSession, g as useChipiWallet, G as useChipiWalletObject, J as useCreateSessionKey, u as useCreateWallet, N as useExecuteWithSession, M as useGetSessionData, D as useGetSku, B as useGetSkuList, A as useGetSkuPurchase, I as useGetTokenBalance, w as useGetTransaction, v as useGetTransactionList, x as useGetTransactionStatus, f as useGetWallet, W as useGuardianRecovery, o as useMigrateWalletToPasskey, q as useMigrateWalletToShhh, a2 as usePrivateBalance, z as usePurchaseSku, H as useRecordSendTransaction, L as useRevokeSessionKey, T as useShhhSigner, a0 as useShield, F as useSignTypedData, y as useSyncOnChainTransfers, Y as useThresholdSign, r as useTransfer, a1 as useUnshield, p as useUpdateWalletEncryption, O as useX402Payment } from './index-Dbqp9oNS.mjs';
9
9
  import { StarknetWindowObject } from '@starknet-io/types-js';
10
10
  import '@tanstack/react-query';
11
11
  import 'starknet';
@@ -61,6 +61,19 @@ declare function walletSupportsSessions(wallet: {
61
61
  * `deps`, so the same object powers walletv2's in-app browser, the hosted
62
62
  * web-wallet connector, and WalletConnect transport identically.
63
63
  *
64
+ * Approvals are deny-by-default: every sensitive action goes through
65
+ * `deps.requestApproval`. When it is omitted, every approval is denied (and a
66
+ * single `console.warn` says so) instead of being auto-approved.
67
+ *
68
+ * Connection model (per window object, i.e. per injected dApp page):
69
+ * - `wallet_requestAccounts` asks for a `connect` approval once, even when the
70
+ * wallet is unlocked and has accounts. With `silent_mode: true` it never
71
+ * prompts: it returns the accounts if already approved, else `[]`.
72
+ * - `wallet_getPermissions` returns `[]` until that approval, `["accounts"]` after.
73
+ * - `wallet_signTypedData` rejects (INVALID_REQUEST_PAYLOAD, no prompt) when
74
+ * the typed data's `domain.chainId` is set and differs from `deps.chainId`.
75
+ * "SN_MAIN" and "0x534e5f4d41494e" are treated as the same chain.
76
+ *
64
77
  * Returns the wallet plus an `emit` controller so the host can fire
65
78
  * accountsChanged / networkChanged on connect, disconnect, or lock.
66
79
  */
package/dist/index.d.ts CHANGED
@@ -4,8 +4,8 @@ import { ChipiSDK, NewOwnerInput } from '@chipi-stack/backend';
4
4
  import { ChipiSDKConfig, WalletType } from '@chipi-stack/types';
5
5
  export * from '@chipi-stack/types';
6
6
  export { Chain, ChainToken } from '@chipi-stack/types';
7
- import { C as ChipiWindowObjectDeps, U as UseChipiWalletObjectConfig } from './index-gNLTF6ix.js';
8
- export { a as ChipiApprovalRequest, b as ChipiSessionPolicy, g as ChipiWalletData, a2 as PrivacyConfig, a3 as PrivacyKeys, a6 as PrivacyLedgerEvent, a4 as PrivacyStep, a7 as PrivateBalanceInput, R as RegisterSessionConfig, S as SessionState, k as SessionWallet, a5 as ShieldHookInput, Y as ThresholdSignState, i as UseChipiSessionConfig, j as UseChipiSessionReturn, e as UseChipiWalletConfig, f as UseChipiWalletReturn, T as UseGuardianRecoveryReturn, P as UseShhhSignerReturn, X as UseThresholdSignOptions, W as UseThresholdSignReturn, p as UseTransferConfig, M as UseX402PaymentConfig, N as UseX402PaymentReturn, a0 as derivePrivacyAccount, a1 as netPrivateBalance, H as useAddSessionKeyToContract, q as useApprove, A as useCallAnyContract, h as useChipiSession, d as useChipiWallet, D as useChipiWalletObject, G as useCreateSessionKey, u as useCreateWallet, K as useExecuteWithSession, J as useGetSessionData, z as useGetSku, y as useGetSkuList, x as useGetSkuPurchase, F as useGetTokenBalance, s as useGetTransaction, r as useGetTransactionList, t as useGetTransactionStatus, c as useGetWallet, Q as useGuardianRecovery, l as useMigrateWalletToPasskey, n as useMigrateWalletToShhh, $ as usePrivateBalance, w as usePurchaseSku, E as useRecordSendTransaction, I as useRevokeSessionKey, O as useShhhSigner, Z as useShield, B as useSignTypedData, v as useSyncOnChainTransfers, V as useThresholdSign, o as useTransfer, _ as useUnshield, m as useUpdateWalletEncryption, L as useX402Payment } from './index-gNLTF6ix.js';
7
+ import { C as ChipiWindowObjectDeps, U as UseChipiWalletObjectConfig } from './index-Dbqp9oNS.js';
8
+ export { a as ChipiApprovalRequest, b as ChipiSessionPolicy, c as ChipiSessionSpendCap, d as ChipiSessionSpendCapAmount, e as ChipiSessionSpendCapPolicy, j as ChipiWalletData, a5 as PrivacyConfig, a6 as PrivacyKeys, a9 as PrivacyLedgerEvent, a7 as PrivacyStep, aa as PrivateBalanceInput, R as RegisterSessionConfig, S as SessionState, n as SessionWallet, a8 as ShieldHookInput, $ as ThresholdSignState, l as UseChipiSessionConfig, m as UseChipiSessionReturn, h as UseChipiWalletConfig, i as UseChipiWalletReturn, X as UseGuardianRecoveryReturn, V as UseShhhSignerReturn, _ as UseThresholdSignOptions, Z as UseThresholdSignReturn, s as UseTransferConfig, P as UseX402PaymentConfig, Q as UseX402PaymentReturn, a3 as derivePrivacyAccount, a4 as netPrivateBalance, K as useAddSessionKeyToContract, t as useApprove, E as useCallAnyContract, k as useChipiSession, g as useChipiWallet, G as useChipiWalletObject, J as useCreateSessionKey, u as useCreateWallet, N as useExecuteWithSession, M as useGetSessionData, D as useGetSku, B as useGetSkuList, A as useGetSkuPurchase, I as useGetTokenBalance, w as useGetTransaction, v as useGetTransactionList, x as useGetTransactionStatus, f as useGetWallet, W as useGuardianRecovery, o as useMigrateWalletToPasskey, q as useMigrateWalletToShhh, a2 as usePrivateBalance, z as usePurchaseSku, H as useRecordSendTransaction, L as useRevokeSessionKey, T as useShhhSigner, a0 as useShield, F as useSignTypedData, y as useSyncOnChainTransfers, Y as useThresholdSign, r as useTransfer, a1 as useUnshield, p as useUpdateWalletEncryption, O as useX402Payment } from './index-Dbqp9oNS.js';
9
9
  import { StarknetWindowObject } from '@starknet-io/types-js';
10
10
  import '@tanstack/react-query';
11
11
  import 'starknet';
@@ -61,6 +61,19 @@ declare function walletSupportsSessions(wallet: {
61
61
  * `deps`, so the same object powers walletv2's in-app browser, the hosted
62
62
  * web-wallet connector, and WalletConnect transport identically.
63
63
  *
64
+ * Approvals are deny-by-default: every sensitive action goes through
65
+ * `deps.requestApproval`. When it is omitted, every approval is denied (and a
66
+ * single `console.warn` says so) instead of being auto-approved.
67
+ *
68
+ * Connection model (per window object, i.e. per injected dApp page):
69
+ * - `wallet_requestAccounts` asks for a `connect` approval once, even when the
70
+ * wallet is unlocked and has accounts. With `silent_mode: true` it never
71
+ * prompts: it returns the accounts if already approved, else `[]`.
72
+ * - `wallet_getPermissions` returns `[]` until that approval, `["accounts"]` after.
73
+ * - `wallet_signTypedData` rejects (INVALID_REQUEST_PAYLOAD, no prompt) when
74
+ * the typed data's `domain.chainId` is set and differs from `deps.chainId`.
75
+ * "SN_MAIN" and "0x534e5f4d41494e" are treated as the same chain.
76
+ *
64
77
  * Returns the wallet plus an `emit` controller so the host can fire
65
78
  * accountsChanged / networkChanged on connect, disconnect, or lock.
66
79
  */
package/dist/index.js CHANGED
@@ -20418,6 +20418,41 @@ function hexEq(a, b) {
20418
20418
  return a === b;
20419
20419
  }
20420
20420
  }
20421
+ function parseCapAmount(value, field, token) {
20422
+ try {
20423
+ const v = typeof value === "bigint" ? value : BigInt(String(value).trim());
20424
+ if (v < 0n) throw new Error("negative");
20425
+ return v;
20426
+ } catch {
20427
+ throw new Error(
20428
+ `session_spend_cap_invalid: ${field} for token ${token} must be a non-negative integer in base units (got "${String(value)}")`
20429
+ );
20430
+ }
20431
+ }
20432
+ function toSpendingPolicies(caps, lifetimeSeconds) {
20433
+ return caps.map((cap) => {
20434
+ const policy = "maxPerWindow" in cap ? {
20435
+ token: cap.token,
20436
+ maxPerCall: parseCapAmount(cap.maxPerCall, "maxPerCall", cap.token),
20437
+ maxPerWindow: parseCapAmount(cap.maxPerWindow, "maxPerWindow", cap.token),
20438
+ windowSeconds: cap.windowSeconds
20439
+ } : (() => {
20440
+ const amount = parseCapAmount(cap.amount, "amount", cap.token);
20441
+ return {
20442
+ token: cap.token,
20443
+ maxPerCall: amount,
20444
+ maxPerWindow: amount,
20445
+ windowSeconds: Math.max(1, lifetimeSeconds)
20446
+ };
20447
+ })();
20448
+ if (policy.maxPerWindow === 0n) {
20449
+ throw new Error(
20450
+ `session_spend_cap_zero: the cap for token ${cap.token} resolves to maxPerWindow = 0, which means unlimited on-chain. Use a positive cap.`
20451
+ );
20452
+ }
20453
+ return policy;
20454
+ });
20455
+ }
20421
20456
  function sessionCovers(policy, calls) {
20422
20457
  if (!policy?.allowedCalls?.length) return false;
20423
20458
  return calls.every(
@@ -20432,6 +20467,10 @@ function useChipiWalletObject(config3) {
20432
20467
  const { signTypedDataAsync } = useSignTypedData();
20433
20468
  const { createSessionKeyAsync } = useCreateSessionKey();
20434
20469
  const { addSessionKeyToContractAsync } = useAddSessionKeyToContract();
20470
+ const { chipiSDK } = useChipiContext();
20471
+ const sdk = React.useRef(chipiSDK);
20472
+ sdk.current = chipiSDK;
20473
+ const warnedMissingApproval = React.useRef(false);
20435
20474
  const cfg = React.useRef(config3);
20436
20475
  cfg.current = config3;
20437
20476
  const requireWallet = () => {
@@ -20444,28 +20483,33 @@ function useChipiWalletObject(config3) {
20444
20483
  if (policy.validUntil <= nowSec()) throw new Error("session_policy_expired");
20445
20484
  const c = cfg.current;
20446
20485
  const wallet = requireWallet();
20486
+ const lifetimeSeconds = Math.max(1, policy.validUntil - nowSec());
20487
+ const spendingPolicies = policy.spendCaps?.length ? toSpendingPolicies(policy.spendCaps, lifetimeSeconds) : [];
20447
20488
  const encryptKey = await c.getEncryptKey();
20448
20489
  const session = await createSessionKeyAsync({
20449
20490
  encryptKey,
20450
- durationSeconds: Math.max(1, policy.validUntil - nowSec())
20491
+ durationSeconds: lifetimeSeconds
20451
20492
  });
20452
20493
  const bearerToken = await c.getBearerToken();
20453
- await addSessionKeyToContractAsync({
20454
- params: {
20455
- encryptKey,
20456
- wallet,
20457
- sessionConfig: {
20458
- sessionPublicKey: session.publicKey,
20459
- validUntil: policy.validUntil,
20460
- maxCalls: 1e3,
20461
- // selectors; empty = all entrypoints allowed
20462
- allowedEntrypoints: policy.allowedCalls.map(
20463
- (a) => hash_exports.getSelectorFromName(a.entrypoint)
20464
- )
20465
- }
20466
- },
20467
- bearerToken
20468
- });
20494
+ const params = {
20495
+ encryptKey,
20496
+ wallet,
20497
+ sessionConfig: {
20498
+ sessionPublicKey: session.publicKey,
20499
+ validUntil: policy.validUntil,
20500
+ maxCalls: 1e3,
20501
+ // Selectors; empty = all entrypoints allowed. On-chain this is a
20502
+ // per-selector whitelist, NOT scoped to allowedCalls' contracts.
20503
+ allowedEntrypoints: policy.allowedCalls.map(
20504
+ (a) => hash_exports.getSelectorFromName(a.entrypoint)
20505
+ )
20506
+ }
20507
+ };
20508
+ if (spendingPolicies.length > 0) {
20509
+ await sdk.current.sessions.setupSession({ ...params, spendingPolicies }, bearerToken);
20510
+ } else {
20511
+ await addSessionKeyToContractAsync({ params, bearerToken });
20512
+ }
20469
20513
  return session;
20470
20514
  },
20471
20515
  [createSessionKeyAsync, addSessionKeyToContractAsync]
@@ -20510,7 +20554,17 @@ function useChipiWalletObject(config3) {
20510
20554
  createSession: async (policy) => {
20511
20555
  await createSession(policy);
20512
20556
  },
20513
- requestApproval: (req) => cfg.current.requestApproval?.(req) ?? Promise.resolve(true)
20557
+ requestApproval: (req) => {
20558
+ const gate = cfg.current.requestApproval;
20559
+ if (gate) return gate(req);
20560
+ if (!warnedMissingApproval.current) {
20561
+ warnedMissingApproval.current = true;
20562
+ console.warn(
20563
+ "[ChipiSDK:Connect] No `requestApproval` was provided to useChipiWalletObject, so every approval (connect, execute, signTypedData, session) is denied. Pass `requestApproval` to show the user an approval UI and resolve true/false."
20564
+ );
20565
+ }
20566
+ return Promise.resolve(false);
20567
+ }
20514
20568
  }),
20515
20569
  [callAnyContractAsync, executeWithSessionAsync, signTypedDataAsync, createSession]
20516
20570
  );
@@ -21190,10 +21244,33 @@ var USER_REFUSED_OP = 113;
21190
21244
  var INVALID_REQUEST_PAYLOAD = 114;
21191
21245
  var ACCOUNT_ALREADY_DEPLOYED = 115;
21192
21246
  var UNKNOWN_ERROR = 163;
21247
+ var MISSING_APPROVAL_WARNING = "[ChipiSDK:Connect] No `requestApproval` was provided, so every approval (connect, execute, signTypedData, session) is denied. Pass `requestApproval` to show the user an approval UI and resolve true/false.";
21248
+ function normalizeChainId(value) {
21249
+ try {
21250
+ if (typeof value === "bigint") return value;
21251
+ if (typeof value === "number") {
21252
+ return Number.isSafeInteger(value) && value >= 0 ? BigInt(value) : null;
21253
+ }
21254
+ if (typeof value !== "string" || value.length === 0) return null;
21255
+ if (/^0x[0-9a-f]+$/i.test(value) || /^[0-9]+$/.test(value)) return BigInt(value);
21256
+ return BigInt(shortString_exports.encodeShortString(value));
21257
+ } catch {
21258
+ return null;
21259
+ }
21260
+ }
21193
21261
  function createChipiWindowObject(deps) {
21194
21262
  const accountListeners = /* @__PURE__ */ new Set();
21195
21263
  const networkListeners = /* @__PURE__ */ new Set();
21196
- const approve = deps.requestApproval ?? (async () => true);
21264
+ let approved = false;
21265
+ let pendingConnect = null;
21266
+ let warnedMissingApproval = false;
21267
+ const approve = deps.requestApproval ?? (async () => {
21268
+ if (!warnedMissingApproval) {
21269
+ warnedMissingApproval = true;
21270
+ console.warn(MISSING_APPROVAL_WARNING);
21271
+ }
21272
+ return false;
21273
+ });
21197
21274
  async function requireApproval(req) {
21198
21275
  const ok = await approve(req);
21199
21276
  if (!ok) throw new RpcError2(USER_REFUSED_OP, "User refused the operation");
@@ -21201,19 +21278,27 @@ function createChipiWindowObject(deps) {
21201
21278
  const request = (async (call) => {
21202
21279
  switch (call.type) {
21203
21280
  case "wallet_requestAccounts": {
21204
- const accounts = await deps.getAccounts();
21205
- if (accounts.length === 0) {
21206
- await requireApproval({ type: "connect" });
21207
- return deps.getAccounts();
21281
+ if (call.params?.silent_mode) {
21282
+ return approved ? deps.getAccounts() : [];
21283
+ }
21284
+ if (approved) {
21285
+ const accounts = await deps.getAccounts();
21286
+ if (accounts.length > 0) return accounts;
21208
21287
  }
21209
- return accounts;
21288
+ if (!pendingConnect) {
21289
+ pendingConnect = requireApproval({ type: "connect" }).then(() => {
21290
+ approved = true;
21291
+ }).finally(() => {
21292
+ pendingConnect = null;
21293
+ });
21294
+ }
21295
+ await pendingConnect;
21296
+ return deps.getAccounts();
21210
21297
  }
21211
21298
  case "wallet_requestChainId":
21212
21299
  return deps.chainId;
21213
- case "wallet_getPermissions": {
21214
- const accounts = await deps.getAccounts();
21215
- return accounts.length > 0 ? ["accounts"] : [];
21216
- }
21300
+ case "wallet_getPermissions":
21301
+ return approved ? ["accounts"] : [];
21217
21302
  case "wallet_addInvokeTransaction": {
21218
21303
  const wireCalls = call.params?.calls ?? [];
21219
21304
  if (wireCalls.length === 0) {
@@ -21226,14 +21311,31 @@ function createChipiWindowObject(deps) {
21226
21311
  }
21227
21312
  case "wallet_signTypedData": {
21228
21313
  const typedData = call.params;
21314
+ const domainChainId = typedData?.domain?.chainId;
21315
+ if (domainChainId !== void 0 && domainChainId !== null) {
21316
+ const expected = normalizeChainId(deps.chainId);
21317
+ const actual = normalizeChainId(domainChainId);
21318
+ if (actual === null || expected === null || actual !== expected) {
21319
+ throw new RpcError2(
21320
+ INVALID_REQUEST_PAYLOAD,
21321
+ `wallet_signTypedData: domain.chainId ${String(domainChainId)} does not match the wallet chain ${deps.chainId}`
21322
+ );
21323
+ }
21324
+ }
21229
21325
  await requireApproval({ type: "signTypedData", typedData });
21230
21326
  return deps.signTypedData(typedData);
21231
21327
  }
21232
21328
  case "wallet_deploymentData":
21233
21329
  try {
21234
21330
  return await deps.getDeploymentData();
21235
- } catch {
21236
- throw new RpcError2(ACCOUNT_ALREADY_DEPLOYED, "Account already deployed");
21331
+ } catch (err2) {
21332
+ if (err2 instanceof Error && err2.message === "account_already_deployed") {
21333
+ throw new RpcError2(ACCOUNT_ALREADY_DEPLOYED, "Account already deployed");
21334
+ }
21335
+ throw new RpcError2(
21336
+ UNKNOWN_ERROR,
21337
+ err2 instanceof Error ? err2.message : "Could not read deployment data"
21338
+ );
21237
21339
  }
21238
21340
  case "wallet_supportedSpecs":
21239
21341
  return SUPPORTED_SPECS;