# JAW Account API > Direct smart account operations including signing, transactions, and permission management. **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/core` - **Install:** `npm install @jaw.id/core` - **Dashboard:** https://dashboard.jaw.id - **Docs:** https://docs.jaw.id ## Quick Example ```typescript import { JAW } from '@jaw.id/core'; const provider = await JAW.create({ apiKey: 'KEY', appName: 'App', chains: [...] }); const account = provider.getAccount(); // Send a transaction const hash = await account.sendTransaction({ to: '0x...', value: parseEther('0.01'), }); ``` --- ## Account.create() Source: https://docs.jaw.id/account/create ## Account.create() Create a new account with a passkey. **Type:** `static async` ### Signature ```typescript static async create( config: AccountConfig, options: CreateAccountOptions ): Promise ``` ### Parameters #### config Type: `AccountConfig` \| Property | Type | Required | Description | \|----------|------|----------|-------------| \| `chainId` | `number` | Yes | Chain ID for the account | \| `apiKey` | `string` | Yes | API key for JAW services | \| `paymasterUrl` | `string` | No | Custom paymaster URL for gas sponsorship | #### options Type: `CreateAccountOptions` \| Property | Type | Required | Description | \|----------|------|----------|-------------| \| `username` | `string` | Yes | Username/display name for the passkey | \| `rpId` | `string` | No | Relying party identifier (defaults to `window.location.hostname`) | \| `rpName` | `string` | No | Relying party name (defaults to `'JAW'`) | ### Returns `Promise` - The newly created Account instance ### Behavior 1. Triggers WebAuthn credential creation (user will see browser passkey dialog) 2. Creates the smart account from the passkey 3. Stores the passkey account and authentication state 4. Returns the ready-to-use Account instance ### Errors \| Error | Description | \|-------|-------------| \| WebAuthn errors | User cancelled passkey creation or browser doesn't support WebAuthn | \| Network errors | Failed to communicate with JAW services | ### Examples #### Basic Usage ```typescript import { Account } from '@jaw.id/core'; const account = await Account.create( { chainId: 1, apiKey: 'your-api-key' }, { username: 'alice' } ); console.log('Created account:', account.address); console.log('Username:', account.getMetadata()?.username); ``` #### With Custom RP Settings ```typescript const account = await Account.create( { chainId: 1, apiKey: 'your-api-key' }, { username: 'alice', rpId: 'myapp.com', rpName: 'My Awesome App', } ); ``` ### Usage in Custom UI Handler ```typescript class MyUIHandler implements UIHandler { private config?: UIHandlerConfig; async handleConnect(request: ConnectUIRequest) { // Show your custom onboarding UI const username = await this.showUsernameInput(); const account = await Account.create( { chainId: request.data.chainId, apiKey: this.config?.apiKey, }, { username } ); return { id: request.id, approved: true, data: { accounts: [{ address: account.address }], }, }; } } ``` ### Related * [Account.get()](/account/get) - Login with existing account * [Account.import()](/account/import) - Import from cloud backup * [Account.getStoredAccounts()](/account/getStoredAccounts) - List created accounts ## account.estimateGas() Source: https://docs.jaw.id/account/estimateGas ## account.estimateGas() Estimate gas for a transaction. **Type:** `instance async` ### Signature ```typescript async estimateGas( calls: TransactionCall[], options?: { permissionId?: Hex } ): Promise ``` ### Parameters #### calls Type: `TransactionCall[]` Array of transaction calls to estimate. ```typescript interface TransactionCall { /** Target contract address */ to: Address; /** Value to send in wei (bigint or hex string) */ value?: bigint | string; /** Call data */ data?: Hex; } ``` #### options (optional) Type: `{ permissionId?: Hex }` Optional settings for gas estimation. \| Property | Type | Description | \|----------|------|-------------| \| `permissionId` | `Hex` | Permission ID for estimating permission-based execution | When `permissionId` is provided, estimates gas for execution through the JustaPermissionManager contract. ### Returns `Promise` - The estimated gas amount in wei. ### Behavior Estimates the total gas required for the user operation, including: * Call execution gas * Verification gas * Pre-verification gas This estimate is used by the bundler to determine if the operation can be submitted. ### Example #### Getting an Account Instance Before calling instance methods, create an account using one of the factory methods: ```typescript import { Account } from '@jaw.id/core'; // Option 1: Restore existing session or login with passkey const account = await Account.get({ chainId: 1, apiKey: 'your-api-key' }); // Option 2: Create a new account with passkey const account = await Account.create( { chainId: 1, apiKey: 'your-api-key' }, { username: 'alice' } ); // Option 3: Import from cloud backup const account = await Account.import({ chainId: 1, apiKey: 'your-api-key' }); // Option 4: From a local account (server-side / embedded wallets) const account = await Account.fromLocalAccount( { chainId: 1, apiKey: 'your-api-key' }, localAccount ); ``` #### Basic Usage ```typescript import { parseEther } from 'viem'; const gas = await account.estimateGas([ { to: '0x...', value: parseEther('0.1') } ]); console.log('Estimated gas:', gas.toString()); ``` ### Related * [account.sendCalls()](/account/sendCalls) - Send batch transactions * [account.sendTransaction()](/account/sendTransaction) - Send the transaction ## Account.fromLocalAccount() Source: https://docs.jaw.id/account/fromLocalAccount ## Account.fromLocalAccount() Create an account from a viem LocalAccount. Ideal for server-side usage or integration with embedded wallet providers. **Type:** `static async` ### Signature ```typescript static async fromLocalAccount( config: AccountConfig, localAccount: LocalAccount ): Promise ``` ### Parameters #### config Type: `AccountConfig` \| Property | Type | Required | Description | \|----------|------|----------|-------------| \| `chainId` | `number` | Yes | Chain ID for the account | \| `apiKey` | `string` | Yes | API key for JAW services | \| `paymasterUrl` | `string` | No | Custom paymaster URL for gas sponsorship | #### localAccount Type: `LocalAccount` (from viem) A viem LocalAccount instance. Can be created from: * Private key * Mnemonic * Embedded wallet providers (Privy, Dynamic, Magic, Turnkey, etc.) ### Returns `Promise` - The Account instance ### Behavior 1. Creates a smart account using the LocalAccount as the owner 2. No passkey or WebAuthn involved 3. No authentication state stored (since there's no passkey) 4. `getMetadata()` returns `null` for these accounts ### Examples #### From Private Key ```typescript import { Account } from '@jaw.id/core'; import { privateKeyToAccount } from 'viem/accounts'; const localAccount = privateKeyToAccount('0x...'); const account = await Account.fromLocalAccount( { chainId: 1, apiKey: 'your-api-key' }, localAccount ); console.log('Smart account address:', account.address); console.log('Has metadata:', account.getMetadata()); // null ``` ### When to Use Use `fromLocalAccount()` when: * **Server-side automation** - Backend services that need to execute transactions * **Embedded wallets** - Integrating with Privy, Dynamic, Magic, Turnkey, etc. Do **not** use when: * You want passkey-based authentication (use `create()` or `get()`) ### Related * [Account.get()](/account/get) - Passkey-based authentication * [Account.create()](/account/create) - Create passkey account * [getMetadata()](/account/getMetadata) - Returns null for LocalAccount-based accounts ## Account.get() Source: https://docs.jaw.id/account/get ## Account.get() Get an account instance - restores an existing session or triggers WebAuthn login. **Type:** `static async` ### Signature ```typescript static async get( config: AccountConfig, credentialId?: string ): Promise ``` ### Parameters #### config Type: `AccountConfig` \| Property | Type | Required | Description | \|----------|------|----------|-------------| \| `chainId` | `number` | Yes | Chain ID for the account | \| `apiKey` | `string` | Yes | API key for JAW services | \| `paymasterUrl` | `string` | No | Custom paymaster URL for gas sponsorship | #### credentialId Type: `string | undefined` Optional credential ID to login with. If provided and not already authenticated, triggers WebAuthn authentication. ### Returns `Promise` - The Account instance ### Behavior This is the primary method to get an Account instance: 1. **If `credentialId` is provided**: Always triggers WebAuthn authentication, even if already authenticated. This ensures user verification when selecting a specific account. 2. **If no `credentialId` and already authenticated**: Restores the account from storage without prompting WebAuthn. 3. **If no `credentialId` and not authenticated**: Throws an error. ### Errors \| Error | Description | \|-------|-------------| \| `Not authenticated` | Not authenticated and no credentialId provided | \| `No account found for credential ID` | Provided credentialId doesn't exist in storage | ### Examples #### Restore Existing Session ```typescript import { Account } from '@jaw.id/core'; // Restore without WebAuthn prompt (if already authenticated) try { const account = await Account.get({ chainId: 1, apiKey: 'your-api-key', }); console.log('Restored account:', account.address); } catch (error) { console.log('Not authenticated'); } ``` #### Login with Specific Account ```typescript import { Account } from '@jaw.id/core'; // Get stored accounts const accounts = Account.getStoredAccounts('your-api-key'); if (accounts.length > 0) { // Login with first account (triggers WebAuthn) const account = await Account.get( { chainId: 1, apiKey: 'your-api-key' }, accounts[0].credentialId ); console.log('Logged in as:', account.address); } ``` ### Related * [Account.create()](/account/create) - Create a new account * [Account.getAuthenticatedAddress()](/account/getAuthenticatedAddress) - Check authentication status * [Account.getStoredAccounts()](/account/getStoredAccounts) - List available accounts ## account.getAddress() Source: https://docs.jaw.id/account/getAddress ## account.getAddress() Get the smart account address (async). **Type:** `instance async` ### Signature ```typescript async getAddress(): Promise
``` ### Parameters None. ### Returns `Promise
` - The smart account address. ### Behavior This async method returns the smart account address. It's useful for: 1. **Counterfactual addresses** - Getting the address before the account is deployed on-chain 2. **Address verification** - Confirming the computed address matches expectations For deployed accounts, this returns the same value as the synchronous `address` property. ### Example ```typescript import { Account } from '@jaw.id/core'; const account = await Account.get({ chainId: 1, apiKey: 'your-api-key', }); const address = await account.getAddress(); console.log('Address:', address); ``` ### Related * [account.address](/account#instance-properties) - Synchronous address property * [account.getSmartAccount()](/account/getSmartAccount) - Get underlying smart account * [account.sendTransaction()](/account/sendTransaction) - Deploys account if needed ## Account.getAuthenticatedAddress() Source: https://docs.jaw.id/account/getAuthenticatedAddress ## Account.getAuthenticatedAddress() Get the authenticated account address without fully loading the account. **Type:** `static` ### Signature ```typescript static getAuthenticatedAddress(apiKey: string): Address | null ``` ### Parameters #### apiKey Type: `string` API key for JAW services. Used to scope the storage lookup. ### Returns `Address | null` - The account address if authenticated, or `null` if not authenticated. ### Behavior This is a synchronous method that checks the authentication state stored locally: 1. Checks localStorage for stored authentication state 2. Returns the address if found and valid 3. Returns `null` if not authenticated This method does **not** trigger WebAuthn or any network requests. ### Example ```typescript import { Account } from '@jaw.id/core'; const address = Account.getAuthenticatedAddress('your-api-key'); if (address) { console.log('Authenticated as:', address); } else { console.log('Not authenticated'); } ``` ### Use Cases * **Check before restore** - Verify authentication before calling `Account.get()` * **Conditional UI** - Show different UI based on authentication state * **Quick status check** - Get address without full account initialization ### Related * [Account.get()](/account/get) - Load the full account instance * [Account.getStoredAccounts()](/account/getStoredAccounts) - List all stored accounts * [Account.logout()](/account/logout) - Clear authentication state ## account.getCallStatus() Source: https://docs.jaw.id/account/getCallStatus ## account.getCallStatus() Get the status of a previously submitted call batch. **Type:** `instance sync` ### Signature ```typescript getCallStatus(batchId: Hash): CallStatusResponse | undefined ``` ### Parameters #### batchId Type: `Hash` The batch ID (userOpHash) returned from `sendCalls()`. ### Returns `CallStatusResponse | undefined` - The call status in EIP-5792 format, or `undefined` if the batch ID is not found. ```typescript interface CallStatusResponse { /** EIP-5792 version */ version: string; /** The batch ID (userOpHash) */ id: `0x${string}`; /** Chain ID in hex format */ chainId: `0x${string}`; /** Status code: 100=pending, 200=completed, 400=offchain failure, 500=onchain revert */ status: number; /** Whether the operation is atomic (always true for ERC-4337) */ atomic: boolean; /** Transaction receipts (present when completed or reverted) */ receipts?: CallReceipt[]; } interface CallReceipt { logs: Array<{ address: `0x${string}`; data: `0x${string}`; topics: `0x${string}`[]; }>; status: `0x${string}`; blockHash: `0x${string}`; blockNumber: `0x${string}`; gasUsed: `0x${string}`; transactionHash: `0x${string}`; } ``` ### Status Codes \| Code | Name | Description | \|------|------|-------------| \| 100 | Pending | Not yet completed onchain | \| 200 | Completed | Included onchain without reverts | \| 400 | Offchain Failure | Not included onchain, wallet won't retry | \| 500 | Complete Revert | Reverted completely, has receipt with status 0x0 | ### Behavior 1. Looks up the batch ID in the internal call status store 2. Returns the status in EIP-5792 format 3. Returns `undefined` if the batch ID is not found 4. Status is automatically updated in the background after `sendCalls()` ### Example #### Getting an Account Instance Before calling instance methods, create an account using one of the factory methods: ```typescript import { Account } from '@jaw.id/core'; // Option 1: Restore existing session or login with passkey const account = await Account.get({ chainId: 1, apiKey: 'your-api-key' }); // Option 2: Create a new account with passkey const account = await Account.create( { chainId: 1, apiKey: 'your-api-key' }, { username: 'alice' } ); // Option 3: Import from cloud backup const account = await Account.import({ chainId: 1, apiKey: 'your-api-key' }); // Option 4: From a local account (server-side / embedded wallets) const account = await Account.fromLocalAccount( { chainId: 1, apiKey: 'your-api-key' }, localAccount ); ``` #### Basic Usage ```typescript // Send calls and get the batch ID const { id } = await account.sendCalls([ { to: '0x...', value: parseEther('0.1') } ]); // Check status immediately const status = account.getCallStatus(id); ``` ### Related * [account.sendCalls()](/account/sendCalls) - Send calls without waiting * [account.sendTransaction()](/account/sendTransaction) - Send and wait for receipt * [wallet\_getCallsStatus](/api-reference/wallet_getCallsStatus) - EIP-5792 RPC method ## account.getChain() Source: https://docs.jaw.id/account/getChain ## account.getChain() Get the chain configuration. **Type:** `instance` ### Signature ```typescript getChain(): Chain ``` ### Parameters None. ### Returns `Chain` - The chain configuration object. #### Chain ```typescript interface Chain { /** Chain ID */ id: number; /** RPC URL for the chain */ rpcUrl: string; /** Optional paymaster URL for gas sponsorship */ paymasterUrl?: string; } ``` ### Behavior Returns a copy of the chain configuration used by this account instance. Modifying the returned object does not affect the account. ### Example ```typescript import { Account } from '@jaw.id/core'; const account = await Account.get({ chainId: 1, apiKey: 'your-api-key', }); const chain = account.getChain(); console.log('Chain ID:', chain.id); console.log('RPC URL:', chain.rpcUrl); console.log('Paymaster URL:', chain.paymasterUrl); ``` ### Related * [account.chainId](/account#instance-properties) - Quick access to chain ID * [account.getSmartAccount()](/account/getSmartAccount) - Get underlying smart account * [AccountConfig](/account#accountconfig) - Configuration interface ## Account.getCurrentAccount() Source: https://docs.jaw.id/account/getCurrentAccount ## Account.getCurrentAccount() Get the currently authenticated account data. **Type:** `static` ### Signature ```typescript static getCurrentAccount(apiKey?: string): PasskeyAccount | null ``` ### Parameters #### apiKey Type: `string | undefined` Optional API key for JAW services. ### Returns `PasskeyAccount | null` - The current account data if authenticated, `null` otherwise. #### PasskeyAccount ```typescript interface PasskeyAccount { /** Smart account address */ address: `0x${string}`; /** Credential ID of the passkey */ credentialId: string; /** Public key of the passkey (hex encoded) */ publicKey: `0x${string}`; /** Username/display name */ username: string; /** ISO date string when created */ creationDate: string; } ``` ### Behavior Returns the full account data for the currently authenticated session. Unlike `getAuthenticatedAddress()` which only returns the address, this method returns all account metadata including credential information. Returns `null` if: * No authenticated session exists * The session has expired ### Examples #### Check Authentication Status ```typescript import { Account } from '@jaw.id/core'; const account = Account.getCurrentAccount('your-api-key'); if (account) { console.log(`Authenticated as: ${account.username}`); console.log(`Address: ${account.address}`); console.log(`Created: ${account.creationDate}`); } else { console.log('Not authenticated'); } ``` #### Restore Account from Current Session ```typescript import { Account } from '@jaw.id/core'; const currentAccount = Account.getCurrentAccount('your-api-key'); if (currentAccount) { // Use credential data to restore Account instance const account = await Account.restore( { chainId: 1, apiKey: 'your-api-key' }, currentAccount.credentialId, currentAccount.publicKey ); } ``` #### Conditional UI Rendering ```typescript import { Account } from '@jaw.id/core'; function AuthStatus() { const account = Account.getCurrentAccount('your-api-key'); if (!account) { return ; } return (

Welcome, {account.username}

{account.address}

); } ``` ### Related * [Account.getAuthenticatedAddress()](/account/getAuthenticatedAddress) - Get only the address * [Account.getStoredAccounts()](/account/getStoredAccounts) - List all stored accounts * [Account.restore()](/account/restore) - Restore account from credential data * [Account.logout()](/account/logout) - Clear authentication state ## account.getMetadata() Source: https://docs.jaw.id/account/getMetadata ## account.getMetadata() Get account metadata (only available for passkey-based accounts). **Type:** `instance` ### Signature ```typescript getMetadata(): AccountMetadata | null ``` ### Parameters None. ### Returns `AccountMetadata | null` - Account metadata or `null` for LocalAccount-based accounts. #### AccountMetadata ```typescript interface AccountMetadata { /** Username/display name */ username: string; /** ISO date string when the account was created */ creationDate: string; /** Whether the account was imported from cloud backup */ isImported: boolean; /** The credential ID of the passkey */ credentialId: string; } ``` ### Behavior * For accounts created via `Account.create()`: Returns full metadata * For accounts created via `Account.import()`: Returns metadata with `isImported: true` * For accounts created via `Account.fromLocalAccount()`: Returns `null` ### Example ```typescript import { Account } from '@jaw.id/core'; const account = await Account.get({ chainId: 1, apiKey: 'your-api-key', }); const metadata = account.getMetadata(); if (metadata) { console.log('Username:', metadata.username); console.log('Created:', metadata.creationDate); console.log('Imported:', metadata.isImported); console.log('Credential ID:', metadata.credentialId); // Store credentialId in your backend for future sign-ins await yourBackend.storeCredentialId(metadata.username, metadata.credentialId); } else { console.log('Local account - no metadata available'); } ``` ### Related * [Account.create()](/account/create) - Creates account with metadata * [Account.import()](/account/import) - Imports account (sets isImported: true) * [Account.fromLocalAccount()](/account/fromLocalAccount) - Creates account without metadata ## account.getPermission() Source: https://docs.jaw.id/account/getPermission ## account.getPermission() Get details of a previously granted permission. **Type:** `instance async` ### Signature ```typescript async getPermission(permissionId: Hex): Promise ``` ### Parameters #### permissionId Type: `Hex` The permission ID (hash) to fetch. This is the `permissionId` field returned from `grantPermissions()`. ### Returns `Promise` - The permission details. ```typescript interface WalletGrantPermissionsResponse { /** Smart account this permission is valid for */ account: Address; /** Entity that can use this permission */ spender: Address; /** Timestamp (in seconds) that specifies when this permission becomes valid */ start: number; /** Timestamp (in seconds) that specifies the time by which this permission expires */ end: number; /** Salt used for permission uniqueness (as hex string) */ salt: Hex; /** Array of call permissions */ calls: CallPermissionDetail[]; /** Array of spend permissions */ spends: SpendPermissionDetail[]; /** Permission identifier - the permission hash from the contract */ permissionId: Hex; /** Chain ID in hex format */ chainId: Hex; } ``` ### Behavior 1. Fetches the permission from the JAW relay by ID 2. Returns the full permission details in the same format as `grantPermissions()` 3. Throws if the permission is not found ### Example ```typescript import { Account } from '@jaw.id/core'; const account = await Account.get({ chainId: 1, apiKey: 'your-api-key', }); const permission = await account.getPermission( '0x1234567890abcdef...' // Permission ID ); console.log('Spender:', permission.spender); console.log('Expires:', new Date(permission.end * 1000)); console.log('Call permissions:', permission.calls); console.log('Spend permissions:', permission.spends); ``` ### Related * [account.grantPermissions()](/account/grantPermissions) - Grant new permissions * [account.revokePermission()](/account/revokePermission) - Revoke a permission * [Subscription Payments Guide](/guides/subscription) - Learn about the permission system ## account.getSmartAccount() Source: https://docs.jaw.id/account/getSmartAccount ## account.getSmartAccount() Get the underlying viem SmartAccount for advanced operations. **Type:** `instance` ### Signature ```typescript getSmartAccount(): SmartAccount ``` ### Parameters None. ### Returns `SmartAccount` - The raw viem SmartAccount instance. ### Behavior Returns the underlying viem `SmartAccount` instance, giving you direct access to all viem smart account methods and properties. ### Example ```typescript import { Account } from '@jaw.id/core'; const account = await Account.get({ chainId: 1, apiKey: 'your-api-key', }); const smartAccount = account.getSmartAccount(); console.log('SmartAccount type:', smartAccount.type); ``` ### Related * [account.getAddress()](/account/getAddress) - Get account address * [account.getChain()](/account/getChain) - Get chain configuration * [Account Overview](/account) - High-level Account API ## Account.getStoredAccounts() Source: https://docs.jaw.id/account/getStoredAccounts ## Account.getStoredAccounts() Get all stored passkey accounts. **Type:** `static` ### Signature ```typescript static getStoredAccounts(apiKey: string): PasskeyAccount[] ``` ### Parameters #### apiKey Type: `string` API key for JAW services. Used to scope the storage lookup. ### Returns `PasskeyAccount[]` - Array of stored passkey accounts. #### PasskeyAccount ```typescript interface PasskeyAccount { /** WebAuthn credential ID */ credentialId: string; /** Public key (hex encoded) */ publicKey: Hex; /** Smart account address */ address: Address; /** Username/display name */ username: string; /** ISO date string when created */ creationDate: string; /** Whether imported from cloud backup */ isImported: boolean; } ``` ### Behavior This is a synchronous method that retrieves all passkey accounts stored locally: 1. Reads from localStorage 2. Returns all stored accounts regardless of authentication state 3. Returns an empty array if no accounts are stored ### Example ```typescript import { Account } from '@jaw.id/core'; const accounts = Account.getStoredAccounts('your-api-key'); console.log(`Found ${accounts.length} stored accounts:`); accounts.forEach(acc => { console.log(`- ${acc.username}: ${acc.address}`); }); ``` ### Use Cases * **Account selector** - Build UI for selecting which account to login with * **Onboarding flow** - Check if user has existing accounts * **Account management** - Display list of all user accounts * **Pre-fetch account info** - Show account details before authentication ### Related * [Account.get()](/account/get) - Login with a specific account * [Account.getAuthenticatedAddress()](/account/getAuthenticatedAddress) - Get current authenticated address * [Account.create()](/account/create) - Create a new account * [Account.import()](/account/import) - Import account from cloud backup ## account.grantPermissions() Source: https://docs.jaw.id/account/grantPermissions ## account.grantPermissions() Grant permissions to a spender. **Type:** `instance async` ### Signature ```typescript async grantPermissions( expiry: number, spender: Address, permissions: PermissionsDetail, paymasterUrlOverride?: string, paymasterContextOverride?: Record ): Promise ``` ### Parameters #### expiry Type: `number` Unix timestamp (in seconds) when the permission expires. #### spender Type: `Address` The address that can use this permission to execute calls on behalf of the account. #### permissions Type: `PermissionsDetail` The permissions to grant. ```typescript interface PermissionsDetail { /** Call permissions - which contracts and functions can be called */ calls?: CallPermissionDetail[]; /** Spend permissions - token spending limits */ spends?: SpendPermissionDetail[]; } interface CallPermissionDetail { /** Target contract address */ target: Address; /** Function selector (4 bytes) - computed from functionSignature if not provided */ selector?: Hex; /** Human-readable function signature (e.g., "transfer(address,uint256)") */ functionSignature?: string; } interface SpendPermissionDetail { /** Token address (use 0xEee...EEeE for native ETH) */ token: Address; /** Spending allowance in wei (hex format) */ allowance: string; /** Period unit of the spend limit */ unit: 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year' | 'forever'; /** Multiplier for the period (1-255), defaults to 1 */ multiplier?: number; } ``` #### paymasterUrlOverride (optional) Type: `string` Custom paymaster URL for gas sponsorship or ERC-20 token payment. Overrides the paymaster URL configured in `AccountConfig`. #### paymasterContextOverride (optional) Type: `Record` Custom paymaster context. For ERC-20 payment, include the token address: ```typescript { token: '0xUSDC_ADDRESS...' } ``` ### Returns `Promise` - The granted permission details. ```typescript interface WalletGrantPermissionsResponse { /** Smart account this permission is valid for */ account: Address; /** Entity that can use this permission */ spender: Address; /** Timestamp (in seconds) that specifies when this permission becomes valid */ start: number; /** Timestamp (in seconds) that specifies the time by which this permission expires */ end: number; /** Salt used for permission uniqueness (as hex string) */ salt: Hex; /** Array of call permissions */ calls: CallPermissionDetail[]; /** Array of spend permissions */ spends: SpendPermissionDetail[]; /** Permission identifier - the permission hash from the contract */ permissionId: Hex; /** Chain ID in hex format */ chainId: Hex; } ``` ### Behavior 1. Creates a permission with the specified constraints 2. Signs the permission with the smart account 3. Registers the permission with the JAW relay 4. Returns the permission details including the unique ID ### Example ```typescript // Grant both call and spend permissions const permission = await account.grantPermissions( Math.floor(Date.now() / 1000) + 86400 * 7, // 1 week '0xSpenderAddress...', { calls: [ { target: ROUTER_ADDRESS, selector: '0x38ed1739', // swapExactTokensForTokens }, { target: ROUTER_ADDRESS, selector: '0x7ff36ab5', // swapExactETHForTokens } ], spends: [ { token: USDC_ADDRESS, limit: '1000000000', // 1000 USDC period: 'week', } ], } ); console.log('Permission ID:', permission.permissionId); console.log('Expires:', new Date(permission.end * 1000)); ``` ### Use Cases * **Session keys** - Allow a temporary key to perform specific actions * **Subscription services** - Grant recurring spending permissions * **Automated trading** - Allow a bot to execute specific trades * **Gaming** - Let a game contract execute moves without prompts ### Related * [account.revokePermission()](/account/revokePermission) - Revoke a granted permission * [account.getPermission()](/account/getPermission) - Get permission details * [Subscription Payments Guide](/guides/subscription) - Learn more about the permission system ## Account.import() Source: https://docs.jaw.id/account/import ## Account.import() Import a passkey from cloud backup. **Type:** `static async` ### Signature ```typescript static async import(config: AccountConfig): Promise ``` ### Parameters #### config Type: `AccountConfig` \| Property | Type | Required | Description | \|----------|------|----------|-------------| \| `chainId` | `number` | Yes | Chain ID for the account | \| `apiKey` | `string` | Yes | API key for JAW services | \| `paymasterUrl` | `string` | No | Custom paymaster URL for gas sponsorship | ### Returns `Promise` - The imported Account instance ### Behavior 1. Triggers WebAuthn authentication with empty `allowCredentials` (lets user select any available passkey) 2. User selects a passkey from their cloud-synced credentials (iCloud Keychain, Google Password Manager, etc.) 3. Creates the smart account from the imported passkey 4. Stores the passkey account marked as imported 5. Returns the ready-to-use Account instance ### Errors \| Error | Description | \|-------|-------------| \| WebAuthn errors | User cancelled or browser doesn't support WebAuthn | \| `Failed to retrieve imported passkey account` | Backend lookup failed | ### Examples #### Basic Usage ```typescript import { Account } from '@jaw.id/core'; const account = await Account.import({ chainId: 1, apiKey: 'your-api-key', }); console.log('Imported account:', account.address); const metadata = account.getMetadata(); console.log('Is imported:', metadata?.isImported); // true ``` ### Usage in Custom UI Handler ```typescript class MyUIHandler implements UIHandler { async handleConnect(request: ConnectUIRequest) { // Show import option in your UI const action = await this.showConnectOptions(); if (action === 'import') { const account = await Account.import({ chainId: request.data.chainId, apiKey: this.config?.apiKey, }); return { id: request.id, approved: true, data: { accounts: [{ address: account.address }], }, }; } // ... handle other actions } } ``` ### Cloud Sync Providers Passkeys can be synced via: * **Apple**: iCloud Keychain (iOS, macOS, Safari) * **Google**: Google Password Manager (Android, Chrome) * **Microsoft**: Windows Hello (Windows, Edge) * **1Password, Dashlane, etc.**: Third-party password managers The import flow allows users to access their JAW account on any device where their passkeys are synced. ### Related * [Account.create()](/account/create) - Create a new account * [Account.get()](/account/get) - Login with existing account * [Account.getStoredAccounts()](/account/getStoredAccounts) - List local accounts ## Account Source: https://docs.jaw.id/account/index ## Account The `Account` class provides a low-level API for smart account operations. It's the recommended way to interact with JAW smart accounts when building custom UI handlers or server-side applications. ### When to Use Account Use this for headless integration (No UI) + use this to issue smart wallets for AI Agents. The `Account` class is ideal for: * **AI Agents** - Issue programmable smart wallets for AI agents * **Headless Integration** - No UI required, direct programmatic access * **Server-side Applications** - Using `fromLocalAccount()` with embedded wallets (Privy, Dynamic, Turnkey) * **Custom UI Handlers** - When implementing your own `UIHandler` for app-specific mode * **Direct Integration** - When you need fine-grained control over account operations For standard client-side usage with the built-in UI, use the provider-based API instead. ### Installation :::code-group ```bash [npm] npm install @jaw.id/core ``` ```bash [pnpm] pnpm add @jaw.id/core ``` ```bash [yarn] yarn add @jaw.id/core ``` ```bash [bun] bun add @jaw.id/core ``` ::: ### Import The `Account` class is exported from `@jaw.id/core`: ```typescript import { Account } from '@jaw.id/core'; ``` ### Static Methods Factory methods for creating Account instances: \| Method | Description | \|--------|-------------| \| [Account.get()](/account/get) | Get account - restores session or triggers login | \| [Account.create()](/account/create) | Create new account with passkey | \| [Account.import()](/account/import) | Import passkey from cloud backup | \| [Account.restore()](/account/restore) | Restore account from credential data (no WebAuthn prompt) | \| [Account.fromLocalAccount()](/account/fromLocalAccount) | Create from viem LocalAccount (server-side) | Utility methods: \| Method | Description | \|--------|-------------| \| [Account.getAuthenticatedAddress()](/account/getAuthenticatedAddress) | Get current authenticated address | \| [Account.getCurrentAccount()](/account/getCurrentAccount) | Get current authenticated account data | \| [Account.getStoredAccounts()](/account/getStoredAccounts) | Get all stored passkey accounts | \| [Account.logout()](/account/logout) | Clear authentication state | ### Instance Properties \| Property | Type | Description | \|----------|------|-------------| \| `address` | `Address` | Smart account address | \| `chainId` | `number` | Current chain ID | ### Instance Methods #### Information \| Method | Description | \|--------|-------------| \| [getMetadata()](/account/getMetadata) | Get account metadata (username, creation date) | \| [getSmartAccount()](/account/getSmartAccount) | Get underlying viem SmartAccount | \| [getChain()](/account/getChain) | Get chain configuration | \| [getAddress()](/account/getAddress) | Get address (async, for counterfactual) | #### Signing \| Method | Description | \|--------|-------------| \| [signMessage()](/account/signMessage) | Sign a personal message (EIP-191) | \| [signTypedData()](/account/signTypedData) | Sign typed data (EIP-712) | #### Transactions \| Method | Description | \|--------|-------------| \| [sendTransaction()](/account/sendTransaction) | Send transaction and wait for receipt | \| [sendCalls()](/account/sendCalls) | Send bundled calls (returns immediately) | \| [estimateGas()](/account/estimateGas) | Estimate gas for calls | #### Permissions \| Method | Description | \|--------|-------------| \| [grantPermissions()](/account/grantPermissions) | Grant permissions to a spender | \| [revokePermission()](/account/revokePermission) | Revoke a permission | \| [getPermission()](/account/getPermission) | Get permission details | ### Interfaces #### AccountConfig Configuration for creating or loading an account: ```typescript interface AccountConfig { /** Chain ID for the account */ chainId: number; /** API key for JAW services (required) */ apiKey: string; /** Custom paymaster URL for gas sponsorship */ paymasterUrl?: string; /** Custom paymaster context for gas sponsorship */ paymasterContext?: Record; } ``` #### CreateAccountOptions Options for creating a new account: ```typescript interface CreateAccountOptions { /** Username/display name for the passkey */ username: string; /** Relying party identifier (defaults to window.location.hostname) */ rpId?: string; /** Relying party name (defaults to 'JAW') */ rpName?: string; } ``` #### TransactionCall Transaction call structure: ```typescript interface TransactionCall { /** Target contract address */ to: Address; /** Value to send in wei (bigint or hex string) */ value?: bigint | string; /** Call data */ data?: Hex; } ``` #### AccountMetadata Account metadata returned by `getMetadata()`: ```typescript interface AccountMetadata { /** Username/display name */ username: string; /** ISO date string when created */ creationDate: string; /** Whether imported from cloud */ isImported: boolean; } ``` ### Value Format The `value` field in `TransactionCall` must be in **wei** (the smallest unit of ETH): ```typescript import { parseEther } from 'viem'; // BigInt (wei) { to: '0x...', value: 1000000000000000000n } // 1 ETH in wei // Hex string (wei) { to: '0x...', value: '0x0de0b6b3a7640000' } // 1 ETH in wei // Using parseEther for convenience { to: '0x...', value: parseEther('1') } // 1 ETH { to: '0x...', value: parseEther('0.1') } // 0.1 ETH ``` Use `parseEther()` from viem to convert human-readable ETH amounts to wei. ### Related * [Custom UI Handler](/advanced/custom-ui-handler) - Build custom UI with Account class * [Provider - RPC Reference](/api-reference) - Provider-based RPC methods ## Account.logout() Source: https://docs.jaw.id/account/logout ## Account.logout() Clear authentication state (logout). **Type:** `static` ### Signature ```typescript static logout(apiKey: string): void ``` ### Parameters #### apiKey Type: `string` API key for JAW services. Used to scope the storage operation. ### Returns `void` ### Behavior This method clears the current authentication state: 1. Removes the authenticated address from storage 2. Clears the current credential ID association 3. Does **not** remove stored passkey accounts (user can still login later) After logout: * `Account.getAuthenticatedAddress()` returns `null` * `Account.get()` without credentialId will throw * `Account.getStoredAccounts()` still returns all accounts ### Example ```typescript import { Account } from '@jaw.id/core'; Account.logout('your-api-key'); console.log('Logged out'); ``` ### Important Notes * Logout is **local only** - it doesn't affect the smart account * Stored passkey accounts remain available for future login * The user can still access their account by logging in again ### Related * [Account.get()](/account/get) - Login to an account * [Account.getAuthenticatedAddress()](/account/getAuthenticatedAddress) - Check authentication status * [Account.getStoredAccounts()](/account/getStoredAccounts) - List available accounts ## Account.restore() Source: https://docs.jaw.id/account/restore ## Account.restore() Restore an account from existing credential data without triggering a WebAuthn prompt. **Type:** `static async` ### Signature ```typescript static async restore( config: AccountConfig, credentialId: string, publicKey: `0x${string}` ): Promise ``` ### Parameters #### config Type: `AccountConfig` \| Property | Type | Required | Description | \|----------|------|----------|-------------| \| `chainId` | `number` | Yes | Chain ID for the account | \| `apiKey` | `string` | Yes | API key for JAW services | \| `paymasterUrl` | `string` | No | Custom paymaster URL for gas sponsorship | \| `paymasterContext` | `Record` | No | Custom paymaster context | #### credentialId Type: `string` The credential ID of the passkey to restore. #### publicKey Type: `` `0x${string}` `` The public key of the passkey (hex encoded). ### Returns `Promise` - The Account instance ### Behavior This method restores an Account instance from credential data **without triggering a WebAuthn prompt**. The actual signing operations will trigger their own WebAuthn prompts when needed. Use this method when: * The user has already authenticated (e.g., during connection) * You have the credential data stored in your session * You want to avoid redundant WebAuthn prompts ### Errors \| Error | Description | \|-------|-------------| \| `credentialId and publicKey are required` | Missing required parameters | ### Examples #### Restore from Session Data ```typescript import { Account } from '@jaw.id/core'; // Restore account from session data (no WebAuthn prompt) const account = await Account.restore( { chainId: 1, apiKey: 'your-api-key' }, session.authState.credentialId, session.authState.publicKey ); // Signing will trigger WebAuthn when needed const signature = await account.signMessage('Hello'); ``` #### Custom UI Handler Integration ```typescript import { Account } from '@jaw.id/core'; // In your UI handler, restore account from stored credentials async function handleSignRequest(credentialId: string, publicKey: `0x${string}`) { const account = await Account.restore( { chainId: 8453, apiKey: 'your-api-key' }, credentialId, publicKey ); return account; } ``` ### Related * [Account.get()](/account/get) - Get account with optional WebAuthn prompt * [Account.getCurrentAccount()](/account/getCurrentAccount) - Get current account data * [Account.getStoredAccounts()](/account/getStoredAccounts) - List available accounts ## account.revokePermission() Source: https://docs.jaw.id/account/revokePermission ## account.revokePermission() Revoke a previously granted permission. **Type:** `instance async` ### Signature ```typescript async revokePermission(permissionId: Hex): Promise ``` ### Parameters #### permissionId Type: `Hex` The permission ID (hash) to revoke. This is the `id` field returned from `grantPermissions()`. ### Returns `Promise` - The revocation response. ```typescript interface RevokePermissionApiResponse { /** Whether the revocation was successful */ success: boolean; /** Transaction hash if on-chain revocation was needed */ transactionHash?: Hex; } ``` ### Behavior 1. Sends a revocation request to the JAW relay 2. Signs the revocation with the smart account 3. The permission is invalidated and can no longer be used 4. Returns confirmation of the revocation ### Example ```typescript import { Account } from '@jaw.id/core'; const account = await Account.get({ chainId: 1, apiKey: 'your-api-key', }); // Revoke a permission by its ID const response = await account.revokePermission( '0x1234567890abcdef...' // Permission ID from grantPermissions() ); if (response.success) { console.log('Permission revoked successfully'); } else { console.log('Revocation failed'); } ``` ### Related * [account.grantPermissions()](/account/grantPermissions) - Grant new permissions * [account.getPermission()](/account/getPermission) - Get permission details * [Subscription Payments Guide](/guides/subscription) - Learn about the permission system ## account.sendCalls() Source: https://docs.jaw.id/account/sendCalls ## account.sendCalls() Send multiple calls as a bundled user operation without waiting for receipt. **Type:** `instance async` ### Signature ```typescript async sendCalls( calls: TransactionCall[], options?: SendCallsOptions, paymasterUrlOverride?: string, paymasterContextOverride?: Record ): Promise ``` ### Parameters #### calls Type: `TransactionCall[]` Array of transaction calls to execute. ```typescript interface TransactionCall { /** Target contract address */ to: Address; /** Value to send in wei (bigint or hex string) */ value?: bigint | string; /** Call data */ data?: Hex; } ``` #### options (optional) Type: `SendCallsOptions` Optional settings for call execution. ```typescript interface SendCallsOptions { /** Permission ID to use for executing the calls through the permission manager */ permissionId?: Hex; } ``` #### paymasterUrlOverride (optional) Type: `string` Custom paymaster URL for gas sponsorship or ERC-20 token payment. Overrides the paymaster URL configured in `AccountConfig`. #### paymasterContextOverride (optional) Type: `Record` Custom paymaster context. For ERC-20 payment, include the token address: ```typescript { token: '0xUSDC_ADDRESS...' } ``` ### Returns `Promise` - The user operation ID and chain ID. ```typescript interface BundledTransactionResult { /** User operation hash */ id: Hex; /** Chain ID where the operation was submitted */ chainId: number; } ``` ### Behavior 1. Bundles all calls into a single user operation 2. Sends the user operation to the bundler 3. **Returns immediately** with the user operation ID 4. Does not wait for transaction inclusion For waiting until the transaction is mined, use [`sendTransaction()`](/account/sendTransaction). ### Example #### Getting an Account Instance Before calling instance methods, create an account using one of the factory methods: ```typescript import { Account } from '@jaw.id/core'; // Option 1: Restore existing session or login with passkey const account = await Account.get({ chainId: 1, apiKey: 'your-api-key' }); // Option 2: Create a new account with passkey const account = await Account.create( { chainId: 1, apiKey: 'your-api-key' }, { username: 'alice' } ); // Option 3: Import from cloud backup const account = await Account.import({ chainId: 1, apiKey: 'your-api-key' }); // Option 4: From a local account (server-side / embedded wallets) const account = await Account.fromLocalAccount( { chainId: 1, apiKey: 'your-api-key' }, localAccount ); ``` #### Batch Multiple Calls ```typescript import { encodeFunctionData } from 'viem'; // Multiple token transfers in one operation const transfers = recipients.map(({ address, amount }) => ({ to: USDC_ADDRESS, data: encodeFunctionData({ abi: erc20Abi, functionName: 'transfer', args: [address, amount], }), })); const { id } = await account.sendCalls(transfers); console.log('Batch transfer submitted:', id); ``` #### Execute with Permission (Delegated Execution) When a permission has been granted via `account.grantPermissions()`, you can execute calls using that permission. This allows delegated execution within the permission's constraints. ```typescript import { encodeFunctionData } from 'viem'; // First, get the permission ID from a previous grantPermissions call const permissionId = '0x1234...'; // The permission ID returned from grantPermissions const transferData = encodeFunctionData({ abi: erc20Abi, functionName: 'transfer', args: ['0x5678...', 1000000n], }); // Execute the transfer using the permission const { id } = await account.sendCalls( [{ to: USDC_ADDRESS, data: transferData }], { permissionId } ); console.log('Batch transfer submitted with permission:', id); ``` When using the `permissionId` option: * The calls are executed through the JustaPermissionManager contract * The permission's call and spend limits are enforced * The spender must have been granted appropriate permissions for the calls being made ### sendTransaction vs sendCalls \| | `sendTransaction()` | `sendCalls()` | \|---|---|---| \| Returns | Transaction hash | User operation ID | \| Waits | Yes, until mined | No, returns immediately | \| Use case | Need confirmation | Fire and forget | ### Related * [account.sendTransaction()](/account/sendTransaction) - Send and wait for receipt * [account.estimateGas()](/account/estimateGas) - Estimate gas before sending ## account.sendTransaction() Source: https://docs.jaw.id/account/sendTransaction ## account.sendTransaction() Send a transaction and wait for the receipt. **Type:** `instance async` ### Signature ```typescript async sendTransaction( calls: TransactionCall[], paymasterUrlOverride?: string, paymasterContextOverride?: Record ): Promise ``` ### Parameters #### calls Type: `TransactionCall[]` Array of transaction calls to execute. ```typescript interface TransactionCall { /** Target contract address */ to: Address; /** Value to send in wei (bigint or hex string) */ value?: bigint | string; /** Call data */ data?: Hex; } ``` #### paymasterUrlOverride (optional) Type: `string` Custom paymaster URL for gas sponsorship or ERC-20 token payment. Overrides the paymaster URL configured in `AccountConfig`. #### paymasterContextOverride (optional) Type: `Record` Custom paymaster context. For ERC-20 payment, include the token address: ```typescript { token: '0xUSDC_ADDRESS...' } ``` ### Returns `Promise` - The transaction hash after the transaction is included in a block. ### Value Format The `value` field must be in **wei** (the smallest unit of ETH): ```typescript import { parseEther } from 'viem'; // BigInt (wei) { to: '0x...', value: 1000000000000000000n } // 1 ETH in wei // Hex string (wei) { to: '0x...', value: '0x0de0b6b3a7640000' } // 1 ETH in wei // Using parseEther for convenience { to: '0x...', value: parseEther('1') } // 1 ETH { to: '0x...', value: parseEther('0.1') } // 0.1 ETH ``` ### Example #### Getting an Account Instance Before calling instance methods, create an account using one of the factory methods: ```typescript import { Account } from '@jaw.id/core'; // Option 1: Restore existing session or login with passkey const account = await Account.get({ chainId: 1, apiKey: 'your-api-key' }); // Option 2: Create a new account with passkey const account = await Account.create( { chainId: 1, apiKey: 'your-api-key' }, { username: 'alice' } ); // Option 3: Import from cloud backup const account = await Account.import({ chainId: 1, apiKey: 'your-api-key' }); // Option 4: From a local account (server-side / embedded wallets) const account = await Account.fromLocalAccount( { chainId: 1, apiKey: 'your-api-key' }, localAccount ); ``` #### Send ETH ```typescript import { parseEther } from 'viem'; // Send 0.1 ETH const hash = await account.sendTransaction([ { to: '0xRecipient...', value: parseEther('0.1') } ]); console.log('Transaction hash:', hash); ``` #### Contract Call ```typescript import { encodeFunctionData } from 'viem'; // Encode the function call const data = encodeFunctionData({ abi: erc20Abi, functionName: 'transfer', args: ['0xRecipient...', 1000000n], // 1 USDC (6 decimals) }); const hash = await account.sendTransaction([ { to: USDC_ADDRESS, data } ]); ``` ### Related * [account.sendCalls()](/account/sendCalls) - Send without waiting for receipt * [account.estimateGas()](/account/estimateGas) - Estimate gas before sending ## account.signMessage() Source: https://docs.jaw.id/account/signMessage ## account.signMessage() Sign a personal message (EIP-191). **Type:** `instance async` ### Signature ```typescript async signMessage(message: string): Promise ``` ### Parameters #### message Type: `string` The message to sign. ### Returns `Promise` - The signature as a hex string. ### Behavior 1. Creates an EIP-191 personal sign message 2. Signs with the smart account (passkey or local account) 3. Returns the signature wrapped for smart account validation ### Example Before calling instance methods, create an account using one of the factory methods: ```typescript import { Account } from '@jaw.id/core'; // Option 1: Restore existing session or login with passkey const account = await Account.get({ chainId: 1, apiKey: 'your-api-key' }); // Option 2: Create a new account with passkey const account = await Account.create( { chainId: 1, apiKey: 'your-api-key' }, { username: 'alice' } ); // Option 3: Import from cloud backup const account = await Account.import({ chainId: 1, apiKey: 'your-api-key' }); // Option 4: From a local account (server-side / embedded wallets) const account = await Account.fromLocalAccount( { chainId: 1, apiKey: 'your-api-key' }, localAccount ); ``` #### Basic Usage ```typescript const signature = await account.signMessage('Hello, World!'); console.log('Signature:', signature); ``` #### Sign-In with Ethereum (SIWE) ```typescript // Construct SIWE message const siweMessage = `myapp.com wants you to sign in with your Ethereum account: ${account.address} Sign in to MyApp URI: https://myapp.com Version: 1 Chain ID: 1 Nonce: ${generateNonce()} Issued At: ${new Date().toISOString()}`; const signature = await account.signMessage(siweMessage); // Send to backend for verification await fetch('/api/verify-siwe', { method: 'POST', body: JSON.stringify({ message: siweMessage, signature, address: account.address, }), }); ``` ### Related * [account.signTypedData()](/account/signTypedData) - Sign EIP-712 typed data * [account.sendTransaction()](/account/sendTransaction) - Send transactions * [Account Overview](/account) - High-level Account API ## account.signTypedData() Source: https://docs.jaw.id/account/signTypedData ## account.signTypedData() Sign EIP-712 typed data. **Type:** `instance async` ### Signature ```typescript async signTypedData( typedData: TypedDataDefinition ): Promise ``` ### Parameters #### typedData Type: `TypedDataDefinition` The EIP-712 typed data to sign, including domain, types, primary type, and message. ```typescript interface TypedDataDefinition { domain: { name?: string; version?: string; chainId?: number; verifyingContract?: Address; salt?: Hex; }; types: Record>; primaryType: string; message: Record; } ``` ### Returns `Promise` - The signature as a hex string. ### Behavior 1. Encodes the typed data according to EIP-712 2. Signs with the smart account (passkey or local account) 3. Returns the signature wrapped for smart account validation ### Example #### Getting an Account Instance Before calling instance methods, create an account using one of the factory methods: ```typescript import { Account } from '@jaw.id/core'; // Option 1: Restore existing session or login with passkey const account = await Account.get({ chainId: 1, apiKey: 'your-api-key' }); // Option 2: Create a new account with passkey const account = await Account.create( { chainId: 1, apiKey: 'your-api-key' }, { username: 'alice' } ); // Option 3: Import from cloud backup const account = await Account.import({ chainId: 1, apiKey: 'your-api-key' }); // Option 4: From a local account (server-side / embedded wallets) const account = await Account.fromLocalAccount( { chainId: 1, apiKey: 'your-api-key' }, localAccount ); ``` #### Basic Usage ```typescript const signature = await account.signTypedData({ domain: { name: 'MyApp', version: '1', chainId: 1, verifyingContract: '0x...', }, types: { Message: [ { name: 'content', type: 'string' }, { name: 'timestamp', type: 'uint256' }, ], }, primaryType: 'Message', message: { content: 'Hello, World!', timestamp: BigInt(Date.now()), }, }); ``` ### Related * [account.signMessage()](/account/signMessage) - Sign personal messages * [account.sendTransaction()](/account/sendTransaction) - Send transactions * [EIP-712 Specification](https://eips.ethereum.org/EIPS/eip-712) - Typed data standard