# JAW Configuration Reference > Configuration options for JAW - applies to both core and wagmi integrations. **This file is self-contained.** You have everything needed to help with this topic. Do NOT fetch other llms-*.txt files unless the user explicitly asks about a different topic. ## Key Info - **Package:** `@jaw.id/wagmi or @jaw.id/core` - **Dashboard:** https://dashboard.jaw.id - **Docs:** https://docs.jaw.id ## Quick Example ```typescript jaw({ apiKey: 'YOUR_API_KEY', // Required - from dashboard.jaw.id appName: 'My App', // Required - shown in passkey prompts mode: 'crossPlatform', // Optional - 'crossPlatform' | 'appSpecific' paymasterUrl: '...', // Optional - for gas sponsoring ensConfig: { ... }, // Optional - for ENS subnames }) ``` --- ## apiKey Source: https://docs.jaw.id/configuration/apiKey ## apiKey Your JAW API key for authentication with JAW services. **Type:** `string` **Required:** Yes ### Usage #### With Wagmi (Recommended) ```typescript import { jaw } from '@jaw.id/wagmi'; const connector = jaw({ apiKey: 'your-api-key-here', }); ``` #### With Provider Directly ```typescript import { JAW } from '@jaw.id/core'; const jaw = JAW.create({ apiKey: 'your-api-key-here', }); ``` ### How to Get an API Key 1. Visit the [JAW Dashboard](https://dashboard.jaw.id/) 2. Create a new project or select an existing one 3. Navigate to the API Keys section 4. Generate a new API key ### Setting Up Allowed Domains For security, you must configure which domains are allowed to use your API key: 1. In the [JAW Dashboard](https://dashboard.jaw.id/), go to your api-key settings 2. Find the **Allowed Domains** section 3. Add the domains where your application will run: * `localhost` for local development * `yourdomain.com` for production * `staging.yourdomain.com` for staging environments Requests from domains not in your allowed list will be rejected. ### Related Configuration * [appName](/configuration/appName) - Application name * [mode](/configuration/mode) - Authentication mode options ## appLogoUrl Source: https://docs.jaw.id/configuration/appLogoUrl ## appLogoUrl URL to your application's logo image. Displayed alongside your app name in the authentication interface. **Type:** `string | null` **Required:** No **Default:** `null` (uses default icon) ### Usage #### With Wagmi (Recommended) ```typescript import { jaw } from '@jaw.id/wagmi'; const connector = jaw({ apiKey: 'your-api-key', appName: 'My DApp', appLogoUrl: 'https://my-dapp.com/logo.png', }); ``` #### With Provider Directly ```typescript import { JAW } from '@jaw.id/core'; const jaw = JAW.create({ apiKey: 'your-api-key', appName: 'My DApp', appLogoUrl: 'https://my-dapp.com/logo.png', }); ``` ### Where It Appears Your app logo is shown to users in: * Authentication popup header * Transaction approval screens * Permission grant dialogs ### Image Requirements * **Format:** PNG, JPG, or SVG * **Size:** 200x200px minimum (square recommended) * **Protocol:** Must use HTTPS ### Related Configuration * [appName](/configuration/appName) - Application name * [apiKey](/configuration/apiKey) - API key for authentication ## appName Source: https://docs.jaw.id/configuration/appName ## appName The name of your application, displayed to users during authentication and transaction signing. **Type:** `string` **Required:** No **Default:** `'DApp'` ### Usage #### With Wagmi (Recommended) ```typescript import { jaw } from '@jaw.id/wagmi'; const connector = jaw({ apiKey: 'your-api-key', appName: 'My Awesome DApp', }); ``` #### With Provider Directly ```typescript import { JAW } from '@jaw.id/core'; const jaw = JAW.create({ apiKey: 'your-api-key', appName: 'My Awesome DApp', }); ``` ### Where It Appears Your app name is shown to users in: * Authentication popup header * Transaction approval screens * Permission grant dialogs ### Related Configuration * [appLogoUrl](/configuration/appLogoUrl) - Application logo * [apiKey](/configuration/apiKey) - API key for authentication ## defaultChainId Source: https://docs.jaw.id/configuration/defaultChainId ## defaultChainId The default blockchain network to connect to when the SDK initializes. **Type:** `number` **Required:** No **Default:** `1` (Ethereum Mainnet) ### Usage #### With Wagmi (Recommended) ```typescript import { jaw } from '@jaw.id/wagmi'; const connector = jaw({ apiKey: 'your-api-key', defaultChainId: 1, // Mainnet }); ``` #### With Provider Directly ```typescript import { JAW } from '@jaw.id/core'; const jaw = JAW.create({ apiKey: 'your-api-key', defaultChainId: 1, // Mainnet }); ``` ### Using Testnets To use a testnet as the default chain, enable `showTestnets` in preferences: #### With Wagmi (Recommended) ```typescript import { jaw } from '@jaw.id/wagmi'; const connector = jaw({ apiKey: 'your-api-key', defaultChainId: 84532, // Base Sepolia preference: { showTestnets: true, }, }); ``` #### With Provider Directly ```typescript import { JAW } from '@jaw.id/core'; const jaw = JAW.create({ apiKey: 'your-api-key', defaultChainId: 84532, // Base Sepolia preference: { showTestnets: true, }, }); ``` ### Related * [Supported Networks](/supported-networks) - Full list of supported chains * [mode](/configuration/mode) - Authentication mode options * [wallet\_switchEthereumChain](/api-reference/wallet_switchEthereumChain) - Switch networks programmatically ## ens Source: https://docs.jaw.id/configuration/ens ## ens ENS domain used to issue subnames to users during authentication. **Type:** `string` **Required:** No :::warning **Important:** Configuring your ENS at the [JAW Dashboard](https://dashboard.jaw.id/) is a pre-requirement for subname issuance and management. ::: ### Usage #### With Wagmi (Recommended) ```typescript import { jaw } from '@jaw.id/wagmi'; const connector = jaw({ apiKey: 'your-api-key', ens: 'myapp.eth', }); ``` #### With Provider Directly ```typescript import { JAW } from '@jaw.id/core'; const jaw = JAW.create({ apiKey: 'your-api-key', ens: 'myapp.eth', }); ``` ### Description When configured, users can receive a subname under your ENS domain during the authentication flow. For example, if your `ens` is set to `myapp.eth`, users can get subnames like `alice.myapp.eth`. By default, subname will be active on all supported networks. To attach text records on creation, please check the [wallet\_connect](/api-reference/wallet_connect) `subnameTextRecords` capability. ### Related Configuration * [apiKey](/configuration/apiKey) - API key for authentication * [wallet\_connect](/api-reference/wallet_connect) - Add subname text records using wallet\_connect capability ## Configuration Source: https://docs.jaw.id/configuration/index ## Configuration Configuration options for the JAW SDK. These options apply to both the **Wagmi connector** and the **direct provider**. ### Usage #### With Wagmi (Recommended) ```typescript import { jaw } from '@jaw.id/wagmi'; const connector = jaw({ apiKey: 'your-api-key', appName: 'My DApp', appLogoUrl: 'https://my-dapp.com/logo.png', defaultChainId: 1, ens: 'myapp.eth', preference: { showTestnets: true, }, paymasters: { 1: { url: 'https://paymaster.example.com/mainnet' }, }, }); ``` #### With Provider Directly ```typescript import { JAW } from '@jaw.id/core'; const jaw = JAW.create({ apiKey: 'your-api-key', appName: 'My DApp', appLogoUrl: 'https://my-dapp.com/logo.png', defaultChainId: 1, ens: 'myapp.eth', preference: { showTestnets: true, }, paymasters: { 1: { url: 'https://paymaster.example.com/mainnet' }, }, }); ``` ### Configuration Options #### Core Parameters \| Parameter | Type | Required | Description | \|-----------|------|----------|-------------| \| [apiKey](/configuration/apiKey) | `string` | Yes | API key for JAW services authentication | \| [appName](/configuration/appName) | `string` | No | Application name displayed to users | \| [appLogoUrl](/configuration/appLogoUrl) | `string \| null` | No | URL to application logo image | \| [ens](/configuration/ens) | `string` | No | ENS domain for issuing subnames | \| [defaultChainId](/configuration/defaultChainId) | `number` | No | Default blockchain network | \| [preference](/configuration/mode) | `object` | No | Advanced SDK behavior options | \| [paymasters](/configuration/paymasters) | `Record }>` | No | Custom paymaster configuration per chain | ### Preference Options The `preference` object contains advanced configuration: \| Option | Type | Default | Description | \|--------|------|---------|-------------| \| [mode](/configuration/mode) | `Mode.CrossPlatform` | `Mode.AppSpecific` | `Mode.CrossPlatform` | Authentication mode | \| [uiHandler](/configuration/mode/app-specific#uihandler) | `UIHandler` | `undefined` | UI handler for rendering dialogs (required when mode is `Mode.AppSpecific`) | \| showTestnets | `boolean` | `false` | Include testnet networks (see [Supported Networks](/supported-networks)) | \| authTTL | `number` | `86400` | Session cache TTL in seconds. Set to `0` to disable caching (require auth on every page load). | [Learn more about authentication modes →](/configuration/mode) ### Return Value #### Wagmi Connector The `jaw()` function returns a Wagmi `Connector` that can be used in your wagmi config. ```typescript import { createConfig } from 'wagmi'; import { jaw } from '@jaw.id/wagmi'; const config = createConfig({ connectors: [jaw({ apiKey: 'your-api-key' })], // ... }); ``` #### Provider The `JAW.create()` function returns an object with: ##### provider **Type:** `ProviderInterface` An EIP-1193 compatible Ethereum provider for making RPC requests. ```typescript const jaw = JAW.create({ apiKey: 'your-api-key' }); const accounts = await jaw.provider.request({ method: 'wallet_connect', }); ``` ##### disconnect() **Type:** `() => Promise` Method to disconnect the current session and clean up resources. ```typescript await jaw.disconnect(); ``` ### Minimal Configuration The only required option is `apiKey`: ```typescript // Wagmi const connector = jaw({ apiKey: 'your-api-key' }); // Provider const jaw = JAW.create({ apiKey: 'your-api-key' }); ``` ### Related * [Wagmi Integration](/wagmi) - Using with Wagmi * [Provider API](/api-reference) - Direct provider methods * [Supported Networks](/supported-networks) - Available chains ## AppSpecific Mode Source: https://docs.jaw.id/configuration/mode/app-specific ## AppSpecific Mode Passkey operations stay within your dApp with no external redirects. Wallets are specific to your application's origin. ### Usage AppSpecific mode requires a `uiHandler` to render authentication dialogs within your app. #### Using ReactUIHandler (Recommended for React) For React applications, install the `@jaw.id/ui` package which provides pre-built UI dialogs: :::code-group ```bash [npm] npm install @jaw.id/wagmi @jaw.id/ui ``` ```bash [pnpm] pnpm add @jaw.id/wagmi @jaw.id/ui ``` ```bash [yarn] yarn add @jaw.id/wagmi @jaw.id/ui ``` ```bash [bun] bun add @jaw.id/wagmi @jaw.id/ui ``` ::: Then configure the SDK with `ReactUIHandler`: #### With Wagmi (Recommended) ```typescript import { jaw } from '@jaw.id/wagmi'; import { Mode } from '@jaw.id/core'; import { ReactUIHandler } from '@jaw.id/ui'; const connector = jaw({ apiKey: 'your-api-key', preference: { mode: Mode.AppSpecific, uiHandler: new ReactUIHandler(), }, }); ``` #### With Provider Directly ```typescript import { JAW, Mode } from '@jaw.id/core'; import { ReactUIHandler } from '@jaw.id/ui'; const jaw = JAW.create({ apiKey: 'your-api-key', preference: { mode: Mode.AppSpecific, uiHandler: new ReactUIHandler(), }, }); ``` #### Custom UI Implementation For non-React apps or fully custom UI, see the [Custom UI Handler](/advanced/custom-ui-handler) documentation. ### How It Works 1. User clicks "Connect" in your dApp 2. A modal opens within your application (no popup/redirect) 3. User authenticates with their passkey on your domain's origin 4. Modal closes and user is connected 5. The wallet is tied to your application's origin ### Benefits * **Users never leave your dApp** - No popups or redirects * **Full control over UI/UX** - Customize the authentication experience * **White-label experience** - Your branding throughout * **Origin-bound security** - Passkeys are tied to your domain ### User Flow ``` Your dApp │ │ 1. User clicks Connect │ │ 2. Modal opens (within your app) │ ┌─────────────────────────┐ │ │ Authentication UI │ │ │ (ReactUIHandler or │ │ │ custom uiHandler) │ │ └─────────────────────────┘ │ │ 3. User authenticates with passkey │ │ 4. Modal closes │ │ 5. User connected └────────────────────────────────── ``` ### uiHandler The `uiHandler` is responsible for rendering approval dialogs for wallet operations (connect, sign, transact, etc.). **Type:** `UIHandler` **Required:** Yes (for AppSpecific mode) #### ReactUIHandler For React applications, `ReactUIHandler` from `@jaw.id/ui` provides pre-built, styled dialogs that handle all wallet operations: * Onboarding / Connect * Message signing * Typed data signing (EIP-712) * Transaction approval * Permission management ```typescript import { ReactUIHandler } from '@jaw.id/ui'; const uiHandler = new ReactUIHandler(); ``` #### Custom UIHandler For non-React apps or when you need complete control over the UI, implement the `UIHandler` interface: ```typescript interface UIHandler { init(config: UIHandlerConfig): void; request(method: string, params: unknown): Promise; canHandle(method: string): boolean; cleanup(): void; } ``` See the [Custom UI Handler](/advanced/custom-ui-handler) documentation for the full interface specification and implementation examples. ### Related * [Mode Overview](/configuration/mode) - Compare all authentication modes * [CrossPlatform Mode](/configuration/mode/cross-platform) - Enable wallet reuse across apps * [Custom UI Handler](/advanced/custom-ui-handler) - Build your own authentication UI ## CrossPlatform Mode Source: https://docs.jaw.id/configuration/mode/cross-platform ## CrossPlatform Mode Passkey operations redirect to `keys.jaw.id` in a popup, enabling wallet reuse across multiple applications. This is the default mode. ### Usage #### With Wagmi (Recommended) ```typescript import { jaw } from '@jaw.id/wagmi'; import { Mode } from '@jaw.id/core'; const connector = jaw({ apiKey: 'your-api-key', preference: { mode: Mode.CrossPlatform, }, }); ``` #### With Provider Directly ```typescript import { JAW, Mode } from '@jaw.id/core'; const jaw = JAW.create({ apiKey: 'your-api-key', preference: { mode: Mode.CrossPlatform, }, }); ``` :::info Since CrossPlatform is the default mode, you can omit the `preference` object entirely if you don't need to configure other options. ::: ### How It Works 1. User clicks "Connect" in your dApp 2. A popup opens to `keys.jaw.id` 3. User authenticates with their passkey on the `keys.jaw.id` origin 4. Popup closes and user is connected to your dApp 5. The same wallet can be used across any app using CrossPlatform mode ### Benefits * **Single wallet across multiple dApps** - Users don't need to create separate wallets for each application * **Seamless cross-application experience** - Connect once, use everywhere * **Consistent authentication flow** - Users see the same familiar interface * **No UI implementation required** - Authentication UI is handled by JAW ### User Flow ``` Your dApp keys.jaw.id (popup) │ │ │ 1. User clicks Connect │ │ ─────────────────────────────> │ │ │ 2. Popup opens │ │ │ 3. User authenticates │ with passkey │ │ │ 4. Wallet address returned │ │ <───────────────────────────── │ │ │ 5. User connected │ └──────────────────────────────┘ ``` ### Related * [Mode Overview](/configuration/mode) - Compare all authentication modes * [AppSpecific Mode](/configuration/mode/app-specific) - Keep users within your app ## mode Source: https://docs.jaw.id/configuration/mode/index ## mode Authentication mode that determines where passkey operations occur. **Type:** `Mode.CrossPlatform` | `Mode.AppSpecific` **Default:** `Mode.CrossPlatform` ### Mode Comparison \| Feature | CrossPlatform | AppSpecific | \|---------|---------------|-------------| \| **Passkey operations** | On `keys.jaw.id` (popup) | Within your dApp | \| **User experience** | Redirects to popup | Stays in your app | \| **Wallet reuse** | Universal | App-specific only | \| **Origin binding** | `keys.jaw.id` | Your domain | \| **Branding** | JAW interface | Custom UI supported | :::warning **Important:** Passkeys are always stored by the browser/device (not on any server). The mode determines where passkey operations happen and whether wallets can be reused across applications. ::: ### Choosing a Mode #### Use CrossPlatform (Default) when: * You want users to reuse their wallet across multiple dApps * You prefer a consistent, maintained authentication UI * Quick integration is a priority #### Use AppSpecific when: * You want users to stay entirely within your application * You need full control over the UI/UX * You're building a white-label experience * Wallet portability across apps is not needed ### Related * [CrossPlatform Mode](/configuration/mode/cross-platform) - Detailed setup and usage * [AppSpecific Mode](/configuration/mode/app-specific) - Detailed setup and usage ## paymasters Source: https://docs.jaw.id/configuration/paymasters ## paymasters Custom paymaster configuration for fully sponsoring gas fees on different blockchain networks. **Type:** `Record }>` **Required:** No **Default:** `undefined` :::info\[Gas Payment Options] JAW SDK supports multiple ways to handle transaction gas fees: \| Option | Who Pays | Configuration | \|--------|----------|---------------| \| **Native (ETH)** | User | Default behavior | \| **ERC-20 Tokens** | User (with USDC, etc.) | Built-in — user selects token in transaction dialog | \| **Full Sponsorship** | You (dApp) | Requires `paymasters` config (this page) | This page covers **full sponsorship** where you pay gas on behalf of users. ::: ### Usage #### With Wagmi (Recommended) ```typescript import { jaw } from '@jaw.id/wagmi'; const connector = jaw({ apiKey: 'your-api-key', paymasters: { 1: { url: 'https://paymaster.example.com/mainnet' }, 8453: { url: 'https://paymaster.example.com/base', context: { sponsorshipPolicyId: 'sp_my_policy' } }, }, }); ``` #### With Provider Directly ```typescript import { JAW } from '@jaw.id/core'; const jaw = JAW.create({ apiKey: 'your-api-key', paymasters: { 1: { url: 'https://paymaster.example.com/mainnet' }, 8453: { url: 'https://paymaster.example.com/base', context: { sponsorshipPolicyId: 'sp_my_policy' } }, }, }); ``` ### Description Paymasters are services that sponsor transaction gas fees, enabling gasless transactions for your users. The `paymasters` configuration allows you to specify custom paymaster endpoints and context for each supported network. **Benefits:** * **Gasless Transactions**: Users don't need native tokens to pay gas * **Better UX**: Remove friction from onboarding * **Flexible Sponsorship**: Control which transactions to sponsor via context/policies * **Cost Management**: Use your own paymaster infrastructure #### Sponsorship Levels You can configure sponsorship at two levels: ##### Global (SDK Config) Configure paymasters in the SDK initialization to sponsor all transactions by default: ```typescript const connector = jaw({ apiKey: 'your-api-key', paymasters: { 8453: { url: 'https://paymaster.example.com/base' }, }, }); ``` ##### Per-Call Override Override or specify paymasters for individual transactions using EIP-5792 capabilities: ```typescript await provider.request({ method: 'wallet_sendCalls', params: [{ calls: [{ to: '0x...', value: '0x0', data: '0x...' }], capabilities: { paymasterService: { url: 'https://different-paymaster.com', context: { sponsorshipPolicyId: 'special-policy' } } } }] }); ``` **Priority:** Per-call `capabilities.paymasterService` > Global `paymasters` config > No sponsorship ### Important Requirements #### EntryPoint Version JAW SDK **only supports EntryPoint v0.8** (ERC-4337 v0.8). Your paymaster service must be compatible with: * [EntryPoint v0.8](https://github.com/eth-infinitism/account-abstraction/releases/tag/v0.8.0) * [EIP-7677](https://eips.ethereum.org/EIPS/eip-7677) Paymaster Web Service Capability #### Compatible Paymaster Providers Works with any EIP-7677 compliant paymaster that supports EntryPoint v0.8: * **[Pimlico](https://dashboard.pimlico.io/)** * **[Etherspot](https://developer.etherspot.io/dashboard)** ### Configuration Format ```typescript paymasters: { [chainId: number]: { url: string; // Paymaster service URL (required) context?: Record; // Additional context sent with requests (optional) } } ``` #### Properties \| Property | Type | Required | Description | \|----------|------|----------|-------------| \| `url` | `string` | Yes | The paymaster service endpoint URL | \| `context` | `Record` | No | Additional context passed to the paymaster (e.g., sponsorship policy ID) | ### Examples #### Basic Configuration ```typescript import { jaw } from '@jaw.id/wagmi'; const connector = jaw({ apiKey: 'your-api-key', paymasters: { 8453: { url: 'https://paymaster.etherspot.io/base' }, }, }); ``` #### With Sponsorship Policy ```typescript import { jaw } from '@jaw.id/wagmi'; const connector = jaw({ apiKey: 'your-api-key', paymasters: { 8453: { url: 'https://paymaster.etherspot.io/base', context: { sponsorshipPolicyId: 'sp_my_policy_id' } }, }, }); ``` #### Multiple Networks ```typescript import { jaw } from '@jaw.id/wagmi'; const connector = jaw({ apiKey: 'your-api-key', paymasters: { 1: { url: 'https://pm.etherspot.io/eth' }, // Ethereum Mainnet 10: { url: 'https://pm.etherspot.io/op' }, // Optimism 8453: { url: 'https://pm.etherspot.io/base' }, // Base 42161: { url: 'https://pm.etherspot.io/arb' }, // Arbitrum 84532: { url: 'https://api.pimlico.io/v2/84532/rpc?apikey=YOUR_API_KEY', // Base Sepolia context: { sponsorshipPolicyId: 'sp_test_policy' } }, }, }); ``` ### Paymaster Services #### Recommended Provider * **[Etherspot](https://developer.etherspot.io/dashboard)** * **[Pimlico](https://dashboard.pimlico.io/)** #### Other Compatible Providers Ensure any provider you use supports: * EntryPoint v0.8 * EIP-7677 Paymaster Web Service Capability ### Related * [eth\_sendTransaction](/api-reference/eth_sendTransaction) - Sponsor Transactions * [wallet\_sendCalls](/api-reference/wallet_sendCalls) - Sponsor Calls Bundle