@saw-protocol/widget
v1.0.8
Published
SAWP branded React widgets for dApp connections - The MetaMask-equivalent UI for agent wallets
Readme
@saw-protocol/widget
SAWP branded React widgets for dApp connections. This is the MetaMask-equivalent UI for agent wallets — a complete, reusable widget system that dApps can integrate to connect to SAWP wallets.
Features
- ConnectionModal — Beautiful branded modal for connection requests with permission display
- ConnectionStatus — Persistent status widget showing connection state at the top of your dApp
- Notification System — Toast notifications for connection events and transaction status
- React Context Provider — Easy state management across your application
- TypeScript Support — Fully typed for the best developer experience
Installation
npm install @saw-protocol/widgetQuick Start
Wrap your app with the SAWPProvider and add the widget components:
import {
SAWPProvider,
ConnectionModal,
ConnectionStatus,
NotificationContainer
} from '@saw-protocol/widget';
function App() {
return (
<SAWPProvider walletAddress="your-wallet-address">
<ConnectionStatus position="top-right" />
<ConnectionModal />
<NotificationContainer />
{/* Your app content */}
<YourApp />
</SAWPProvider>
);
}Components
SAWPProvider
The context provider that manages widget state and connection logic.
<SAWPProvider
walletAddress="your-wallet-public-key"
autoConnect={false}
>
{children}
</SAWPProvider>Props:
walletAddress(string, optional) — The wallet address to connect fromautoConnect(boolean, optional) — Whether to auto-restore previous connections
ConnectionModal
Displays connection requests with full permission details. Automatically appears when a connection is requested.
<ConnectionModal />Features:
- Shows dApp name, icon, and origin
- Lists all requested permissions with descriptions
- Security warning about trusted dApps
- Approve/Reject actions
ConnectionStatus
Persistent widget showing connection state. Stays visible at the edge of the screen.
<ConnectionStatus position="top-right" />Props:
position('top-right' | 'top-left' | 'top-center', default: 'top-right') — Where to position the widget
Features:
- Shows connected dApp name (truncated)
- Animated green pulse indicator when connected
- Dropdown with connection details and permissions
- One-click disconnect button
- Shows "Not Connected" state when disconnected
NotificationContainer
Displays toast notifications for connection events and errors.
<NotificationContainer />Features:
- Auto-dismisses after duration
- Different colors for info/success/warning/error
- Stacked notifications with staggered animation
- Click to dismiss
Hooks
useSAWPWidget
Hook for dApps to initiate connections and transactions.
import { useSAWPWidget } from '@saw-protocol/widget';
function MyDapp() {
const {
isConnected,
isConnecting,
requestConnection,
disconnect
} = useSAWPWidget();
const handleConnect = async () => {
try {
await requestConnection(
'my-dapp-id',
['transfer', 'swap', 'view'],
{ name: 'My DeFi App', url: window.location.origin }
);
} catch (err) {
console.error('Connection rejected:', err);
}
};
return (
<button onClick={handleConnect}>
{isConnected ? 'Connected' : 'Connect Wallet'}
</button>
);
}Complete Example
import React from 'react';
import {
SAWPProvider,
ConnectionModal,
ConnectionStatus,
NotificationContainer,
useSAWPWidget
} from '@saw-protocol/widget';
// Your dApp component
function MyDeFiApp() {
const { isConnected, requestConnection, disconnect } = useSAWPWidget();
const handleConnect = async () => {
await requestConnection(
'my-defi-app',
['transfer', 'swap', 'stake'],
{
name: 'My DeFi Protocol',
url: window.location.origin,
icon: 'https://myapp.com/icon.png'
}
);
};
return (
<div>
<h1>My DeFi App</h1>
{isConnected ? (
<div>
<p>Wallet connected!</p>
<button onClick={disconnect}>Disconnect</button>
</div>
) : (
<button onClick={handleConnect}>Connect SAWP Wallet</button>
)}
</div>
);
}
// App wrapper with SAWP widgets
function App() {
return (
<SAWPProvider walletAddress="your-wallet-address">
{/* Widget components */}
<ConnectionStatus position="top-right" />
<ConnectionModal />
<NotificationContainer />
{/* Your app */}
<MyDeFiApp />
</SAWPProvider>
);
}
export default App;Styling
The widgets come with built-in SAWP branding (purple/green dark theme). All styles are inline and scoped to components — no external CSS files required.
Default Theme Colors
- Primary:
#9945ff(purple) - Secondary:
#14f195(green) - Background:
#12121a(dark) - Surface:
#1a1a25(card backgrounds) - Border:
#2a2a3a(subtle borders)
Architecture
┌─────────────────────────────────────┐
│ Your dApp │
│ ┌───────────────────────────────┐ │
│ │ useSAWPWidget() hook │ │
│ │ - requestConnection() │ │
│ │ - requestTransaction() │ │
│ └───────────────────────────────┘ │
└─────────────────┬───────────────────┘
│
┌─────────────────▼───────────────────┐
│ SAWPProvider Context │
│ ┌───────────────────────────────┐ │
│ │ WalletConnector instance │ │
│ │ Connection state management │ │
│ │ Notification queue │ │
│ └───────────────────────────────┘ │
└─────────────────┬───────────────────┘
│
┌─────────────┼─────────────┐
│ │ │
┌───▼───┐ ┌─────▼──────┐ ┌────▼────┐
│Modal │ │Status │ │Notif. │
│Widget │ │Widget │ │Container│
└───────┘ └────────────┘ └─────────┘License
MIT
