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

> [!NOTE]
>
> 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`.

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

> [!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.


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