Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Session Setup

Prerequisites

Make sure your ~/.jaw/config.json has:

  • apiKey — your JAW API key
  • defaultChain or use --chain flag
  • permissions — the scope for the session key
  • paymasters (optional) — for gas-sponsored transactions

Use the Config Generator to build your config.

Create a Session

jaw session setup --chain 84532

This will:

  1. Generate a random secp256k1 session key
  2. Derive the session key's smart account address
  3. Open your browser for passkey approval of wallet_grantPermissions
  4. Save the key to ~/.jaw/keystore.json
  5. Save session metadata to ~/.jaw/session-config.json

Output:

Session created successfully.
 
  Session address:  0xee3EC45...
  Owner address:    0x810440...
  Permission ID:    0x60a8d6...
  Chain:            84532
  Expires:          2026-04-16T09:15:18.000Z (7 days)
 
Use --session flag to execute RPC calls in auto mode.

Flags

--permissions (optional override)

Override config.permissions for this setup. Accepts inline JSON or a file path:

# Inline JSON
jaw session setup --permissions '{"calls":[{"target":"0x...","selector":"0x..."}]}'
 
# File path
jaw session setup --permissions ./my-permissions.json

Resolution order: --permissions flag > config.permissions. Error if neither is set.

--expiry (optional override)

Override config.sessionExpiry for this setup. Value in days:

jaw session setup --expiry 14

Resolution order: --expiry flag > config.sessionExpiry > default 7 days.

--yes / -y

Skip the confirmation prompt when overwriting an existing session:

jaw session setup --chain 84532 --yes

Permission Format

Call Permissions

Define which contracts and functions the session key can call:

{
  "calls": [
    {
      "target": "0x3232323232323232323232323232323232323232",
      "selector": "0xe0e0e0e0"
    }
  ]
}
Wildcards:
targetselectorMeaning
0x3232...32320x32323232Any contract, any function
0x3232...32320xe0e0e0e0Any contract, empty calldata only (ETH transfers)
0xYourContract0xa9059cbbSpecific contract, specific function (e.g., transfer)
0xYourContract0x32323232Specific contract, any function

Spend Limits

Cap how much the session key can spend:

{
  "spends": [
    {
      "token": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
      "allowance": "0x16345785d8a0000",
      "unit": "day",
      "multiplier": 1
    }
  ]
}
  • token0xEeee...EEeE for native ETH, or any ERC-20 address
  • allowance — Max amount in wei (hex). 0x16345785d8a0000 = 0.1 ETH
  • unitminute, hour, day, week, month, year, forever
  • multiplier — Number of periods (e.g., 2 + day = every 2 days)

Files Created

After setup, two files are created in ~/.jaw/:

keystore.json

Session private key (file permissions 0o600):

{
  "version": 2,
  "privateKey": "0x...",
  "address": "0x...",
  "createdAt": "2026-04-09T..."
}

On-chain PermissionManager is the primary security boundary — even if the key is read from disk, it can only act within its granted permission scope. The session key's smart account is never funded, so a compromised key cannot independently hold or transfer assets.

session-config.json

Session metadata:

{
  "ownerAddress": "0x...",
  "sessionAddress": "0x...",
  "permissionId": "0x...",
  "chainId": 84532,
  "expiry": 1749100800,
  "createdAt": "2026-04-09T..."
}
  • ownerAddress — The human's smart account (the account being acted on behalf of)
  • sessionAddress — The session key's smart account (the agent's identity)
  • permissionId — On-chain permission hash from PermissionManager

Next Steps

  • Usage — Run commands with --session