Getting Started
What is JAW?
The JAW SDK is a TypeScript library for building identity-first smart accounts on EVM chains: passkey-authenticated, programmable, and extensible through delegated permissions.
Smart wallets are blockchain accounts controlled by smart contracts instead of private keys. This enables powerful features like:
- Gasless transactions - Users don't need ETH to pay for gas
- Batch operations - Execute multiple actions in a single transaction
- Programmable permissions - Grant limited access to third parties
Passkeys replace seed phrases and passwords with biometric authentication (Face ID, fingerprint, or device PIN). Your users get:
- No seed phrases to lose or steal
- Phishing-resistant authentication
- Cross-device sync via iCloud/Google
Installation
npm
npm install @jaw.id/wagmi wagmi @tanstack/react-queryQuick Start
1. Configure Wagmi
Create your wagmi config with the JAW connector:
// config.ts
import { createConfig, http } from 'wagmi';
import { mainnet, base } from 'wagmi/chains';
import { jaw } from '@jaw.id/wagmi';
export const config = createConfig({
chains: [mainnet, base],
connectors: [
jaw({
apiKey: 'your-api-key',
appName: 'My DApp',
appLogoUrl: 'https://my-dapp.com/logo.png',
}),
],
transports: {
[mainnet.id]: http(),
[base.id]: http(),
},
});2. Set Up Providers
Wrap your app with the required providers:
// App.tsx
import { WagmiProvider } from 'wagmi';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { config } from './config';
const queryClient = new QueryClient();
function App({ children }: { children: React.ReactNode }) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
</WagmiProvider>
);
}3. Connect & Interact
import { useAccount, useSendTransaction } from 'wagmi';
import { useConnect, useDisconnect } from '@jaw.id/wagmi';
import { parseEther } from 'viem';
import { config } from './config';
function WalletButton() {
const { address, isConnected } = useAccount();
const { mutate: connect, isPending } = useConnect();
const { mutate: disconnect } = useDisconnect();
const { sendTransaction } = useSendTransaction();
if (isConnected) {
return (
<div>
<p>Connected: {address}</p>
<button onClick={() => sendTransaction({
to: '0x...',
value: parseEther('0.01')
})}>
Send ETH
</button>
<button onClick={() => disconnect({})}>
Disconnect
</button>
</div>
);
}
return (
<button
onClick={() => connect({ connector: config.connectors[0] })}
disabled={isPending}
>
{isPending ? 'Connecting...' : 'Connect Wallet'}
</button>
);
}When users click "Connect Wallet", a popup appears for passkey authentication.
Using the Provider Directly
For non-React applications or advanced use cases, you can use the provider API directly:
import { JAW } from '@jaw.id/core';
const jaw = JAW.create({
apiKey: 'your-api-key',
appName: 'My DApp',
});
// EIP-1193 compatible provider
const accounts = await jaw.provider.request({
method: 'wallet_connect',
});See the Provider API Reference for all available methods.
Next Steps
- Configuration - All configuration options
- Wagmi Integration - Full wagmi hooks reference
- Guides - Tutorials for common use cases
- Supported Networks - Available chains