> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chipipay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Spending Policy Methods

> API reference for spending policy management — set, query, and remove per-token spending caps on session keys

Spending policies enforce per-token limits on ERC-20 operations executed by session keys. The CHIPI wallet contract enforces these automatically during transaction execution.

> [!NOTE]
>
> Requires **CHIPI v33** wallets. See the [Spending Policies guide](/sdk/guides/spending-policies) for concepts and use cases.

***

> [!NOTE]
>
> **SHHH wallets supported (14.10.0):** `setSpendingPolicy` / `removeSpendingPolicy`
> now accept `walletType: "SHHH"` (V8.4) in addition to CHIPI — both embed the same
> SNIP-163 session-key + spending-policy component. `undefined` still defaults to
> CHIPI; READY remains unsupported (no sessions component). Proven on mainnet:
> in-cap approve succeeds, over-cap is refused with `'Spending: exceeds per-call'`.

> [!WARNING]
>
> **A refused session call can still report success.** Sent through Chipi's paymaster
> (`executeTransactionWithSession`), the sponsoring transaction succeeds even when the
> wallet refuses the call inside it: over a cap, not whitelisted, or from a revoked
> session. The receipt says `success: true` and nothing moved. Measured on mainnet
> on a SHHH V8.4 wallet (2026-10-02). Check the receipt's events: a `Transfer` (or
> `Approval`) from your wallet is the proof, not the status.

## sessions.setSpendingPolicy()

Set a spending policy for a session key + token pair. Requires owner signature.

### Usage

```typescript theme={null}
const txHash = await sdk.sessions.setSpendingPolicy({
  encryptKey: "user-secure-pin",
  wallet: userWallet,
  spendingPolicyConfig: {
    sessionPublicKey: session.publicKey,
    token: "0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb",
    maxPerCall: 1_000_000n,
    maxPerWindow: 50_000_000n,
    windowSeconds: 86400,
  },
}, bearerToken);
```

### Parameters

| Parameter | Type | Required | Description |
| - | - | - | - |
| `encryptKey` | string | Yes | PIN to decrypt owner's private key |
| `wallet` | WalletData | Yes | Wallet data with encrypted private key |
| `spendingPolicyConfig.sessionPublicKey` | string | Yes | Session key to apply the policy to |
| `spendingPolicyConfig.token` | string | Yes | ERC-20 token contract address |
| `spendingPolicyConfig.maxPerCall` | bigint | Yes | Max amount per single call (u256) |
| `spendingPolicyConfig.maxPerWindow` | bigint | Yes | Max cumulative amount in rolling window (u256) |
| `spendingPolicyConfig.windowSeconds` | number | Yes | Rolling window duration in seconds (u64) |

### Return Value

`Promise<string>` — Transaction hash of the on-chain `set_spending_policy` call.

***

## sessions.getSpendingPolicy()

Query a spending policy from the contract. Read-only, no signature or gas required.

### Usage

```typescript theme={null}
const policy = await sdk.sessions.getSpendingPolicy({
  walletAddress: "0x04abc...def",
  sessionPublicKey: session.publicKey,
  token: "0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb",
});
```

### Parameters

| Parameter | Type | Required | Description |
| - | - | - | - |
| `walletAddress` | string | Yes | Wallet contract address |
| `sessionPublicKey` | string | Yes | Session public key |
| `token` | string | Yes | ERC-20 token contract address |

### Return Value

`SpendingPolicyData`:

| Field | Type | Description |
| - | - | - |
| `maxPerCall` | bigint | Maximum amount per single call |
| `maxPerWindow` | bigint | Maximum cumulative amount in rolling window |
| `windowSeconds` | number | Rolling window duration in seconds |
| `spentInWindow` | bigint | Amount spent in the current active window |
| `windowStart` | number | Unix timestamp when the current window started |

Returns all zeros if no policy is set (meaning no enforcement).

***

## sessions.removeSpendingPolicy()

Remove a spending policy. After removal, the session has no limits for this token. Requires owner signature.

### Usage

```typescript theme={null}
const txHash = await sdk.sessions.removeSpendingPolicy({
  encryptKey: "user-secure-pin",
  wallet: userWallet,
  sessionPublicKey: session.publicKey,
  token: "0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb",
}, bearerToken);
```

### Parameters

| Parameter | Type | Required | Description |
| - | - | - | - |
| `encryptKey` | string | Yes | PIN to decrypt owner's private key |
| `wallet` | WalletData | Yes | Wallet data with encrypted private key |
| `sessionPublicKey` | string | Yes | Session key to remove policy from |
| `token` | string | Yes | ERC-20 token contract address |

### Return Value

`Promise<string>` — Transaction hash of the on-chain `remove_spending_policy` call.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.