> ## 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.

# useExecuteWithSession

> Execute gasless transactions using a session key instead of the owner private key. Enables frictionless UX for gaming, DeFi automation, and more.

<Info>
  This hook uses the session key signature (4-element format) instead of the owner signature. The session must be registered on-chain first via `useAddSessionKeyToContract`.
</Info>

## Usage

```typescript theme={null}
const { 
  executeWithSession,
  executeWithSessionAsync, 
  data, 
  isLoading, 
  error,
  isSuccess,
  reset
} = useExecuteWithSession();
```

### Parameters

| Parameter           | Type           | Required | Description                                               |
| ------------------- | -------------- | -------- | --------------------------------------------------------- |
| `params.encryptKey` | string         | Yes      | PIN to decrypt the **session** private key                |
| `params.wallet`     | WalletData     | Yes      | Wallet object (session executes on behalf of this wallet) |
| `params.session`    | SessionKeyData | Yes      | Session key data from `useCreateSessionKey`               |
| `params.calls`      | Call\[]        | Yes      | Array of contract calls to execute                        |
| `bearerToken`       | string         | Yes      | Authentication token from your auth provider              |

### Call Structure

```typescript theme={null}
{
  contractAddress: string;  // Target contract address
  entrypoint: string;       // Function name to call
  calldata: string[];       // Function arguments
}
```

### Return Value

| Property                  | Type          | Description                                      |
| ------------------------- | ------------- | ------------------------------------------------ |
| `executeWithSession`      | function      | Trigger execution (fire-and-forget)              |
| `executeWithSessionAsync` | function      | Trigger execution (returns Promise with tx hash) |
| `data`                    | string        | Transaction hash                                 |
| `isLoading`               | boolean       | Whether execution is in progress                 |
| `isError`                 | boolean       | Whether an error occurred                        |
| `error`                   | Error \| null | Error details if any                             |
| `isSuccess`               | boolean       | Whether execution succeeded                      |
| `reset`                   | function      | Reset mutation state                             |

## Example: Token Transfer

```typescript theme={null}
import { useExecuteWithSession } from "@chipi-stack/chipi-react";

// Native USDC on Starknet mainnet (not USDC.e bridged)
const USDC_ADDRESS = "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";

export function SessionTransfer() {
  const { executeWithSessionAsync, isLoading, error, data: txHash } = useExecuteWithSession();
  const [amount, setAmount] = useState('');
  const [recipient, setRecipient] = useState('');

  const handleTransfer = async () => {
    const bearerToken = await getBearerToken();
    const session = JSON.parse(localStorage.getItem('chipiSession')!);
    const pin = await promptForPin(); // Your PIN input method

    try {
      const hash = await executeWithSessionAsync({
        params: {
          encryptKey: pin,
          wallet: {
            publicKey: wallet.publicKey,
            encryptedPrivateKey: wallet.encryptedPrivateKey,
            walletType: "CHIPI",
          },
          session,
          calls: [{
            contractAddress: USDC_ADDRESS,
            entrypoint: "transfer",
            calldata: [recipient, amount, "0x0"],
          }],
        },
        bearerToken,
      });
      
      console.log('Transfer executed:', hash);
    } catch (err) {
      console.error('Transfer failed:', err);
    }
  };

  return (
    <div className="p-6 bg-white rounded-lg shadow">
      <h2 className="text-xl font-semibold mb-4">Transfer with Session</h2>
      
      <div className="space-y-4">
        <input
          value={recipient}
          onChange={(e) => setRecipient(e.target.value)}
          placeholder="Recipient address (0x...)"
          className="w-full p-2 border rounded"
        />
        
        <input
          value={amount}
          onChange={(e) => setAmount(e.target.value)}
          placeholder="Amount (in smallest units)"
          className="w-full p-2 border rounded"
        />
        
        <button
          onClick={handleTransfer}
          disabled={isLoading}
          className="w-full bg-green-600 text-white py-2 rounded hover:bg-green-700 disabled:bg-gray-400"
        >
          {isLoading ? 'Executing...' : 'Transfer'}
        </button>
      </div>

      {error && (
        <div className="mt-4 p-3 bg-red-50 text-red-700 rounded">
          Error: {error.message}
        </div>
      )}

      {txHash && (
        <div className="mt-4 p-3 bg-green-50 rounded">
          <a 
            href={`https://starkscan.co/tx/${txHash}`}
            target="_blank"
            rel="noopener noreferrer"
            className="text-green-700 hover:underline"
          >
            View transaction →
          </a>
        </div>
      )}
    </div>
  );
}
```

## Example: Gaming Actions

```typescript theme={null}
import { useExecuteWithSession } from "@chipi-stack/chipi-react";

const GAME_CONTRACT = "0x...";

export function GameBoard() {
  const { executeWithSessionAsync, isLoading } = useExecuteWithSession();

  const makeMove = async (moveData: string) => {
    const session = JSON.parse(localStorage.getItem('chipiSession')!);
    const bearerToken = await getBearerToken();

    // Execute instantly - no wallet popup!
    await executeWithSessionAsync({
      params: {
        encryptKey: userPin,
        wallet: { ...wallet, walletType: "CHIPI" },
        session,
        calls: [{
          contractAddress: GAME_CONTRACT,
          entrypoint: "make_move",
          calldata: [moveData],
        }],
      },
      bearerToken,
    });
  };

  return (
    <div className="grid grid-cols-3 gap-2">
      {[1, 2, 3, 4, 5, 6, 7, 8, 9].map((cell) => (
        <button
          key={cell}
          onClick={() => makeMove(cell.toString())}
          disabled={isLoading}
          className="h-20 bg-blue-500 text-white rounded hover:bg-blue-600 disabled:bg-gray-400"
        >
          {cell}
        </button>
      ))}
    </div>
  );
}
```

## Multi-Call Transactions

Execute multiple calls in a single transaction:

```typescript theme={null}
const txHash = await executeWithSessionAsync({
  params: {
    encryptKey: pin,
    wallet: walletData,
    session,
    calls: [
      // Approve spending
      {
        contractAddress: USDC_ADDRESS,
        entrypoint: "approve",
        calldata: [SWAP_CONTRACT, amount, "0x0"],
      },
      // Execute swap
      {
        contractAddress: SWAP_CONTRACT,
        entrypoint: "swap",
        calldata: [USDC_ADDRESS, ETH_ADDRESS, amount, minReceived],
      },
    ],
  },
  bearerToken,
});
```

## Error Handling

| Error                                           | Cause                         | Solution                                           |
| ----------------------------------------------- | ----------------------------- | -------------------------------------------------- |
| `Session execution only supports CHIPI wallets` | Wallet is READY type          | Use a CHIPI wallet                                 |
| `Session has expired`                           | `validUntil` timestamp passed | Create and register a new session                  |
| `Session not found`                             | Not registered on-chain       | Call `useAddSessionKeyToContract` first            |
| `Max calls exceeded`                            | `remainingCalls` is 0         | Create a new session with higher `maxCalls`        |
| `Entrypoint not allowed`                        | Function not in whitelist     | Register session with correct `allowedEntrypoints` |

<Warning>
  Session transactions decrement `remainingCalls` on the contract. Monitor usage with `useGetSessionData` and create new sessions before exhaustion.
</Warning>

<Tip>
  For the best UX, pre-create sessions during onboarding and store the PIN securely. This allows instant transactions without prompting for PIN each time.
</Tip>
