signer-test-sdk
v0.1.19
Published
Abstraxn Signer package for handling transaction signing and wallet interactions.
Maintainers
Readme
@abstraxn/signer
Abstraxn Signer SDK - A comprehensive React wallet SDK for seamless Web3 wallet integration with email OTP, social authentication (Google, Discord, X), passkey, and external wallet support.
📦 Installation
npm install @abstraxn/signer reactRequirements:
- React 18.0.0 or higher
- Node.js 16.0.0 or higher
🚀 Quick Start
1. Wrap Your App with AbstraxnProvider
import { AbstraxnProvider, type AbstraxnProviderConfig } from '@abstraxn/signer/react';
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
const providerConfig: AbstraxnProviderConfig = {
apiKey: 'your-api-key-here',
};
createRoot(document.getElementById('root')!).render(
<StrictMode>
<AbstraxnProvider config={providerConfig}>
<App />
</AbstraxnProvider>
</StrictMode>,
);2. Use the ConnectButton Component
import { ConnectButton } from "@abstraxn/signer/react";
function App() {
return (
<div>
<ConnectButton
connectText="Connect Wallet"
connectedText="Connected"
showAddress={true}
/>
</div>
);
}3. Or Use Hooks for Custom Integration
import { useAbstraxnWallet } from "@abstraxn/signer/react";
function HookConnectButton() {
const { showOnboarding, loading } = useAbstraxnWallet();
return (
<button
onClick={showOnboarding}
disabled={loading}
className="demo-connect-button"
>
{loading ? 'Connecting...' : 'Connect via Hook'}
</button>
);
}That's it! The SDK will handle all authentication flows automatically.
✨ Features
- 🔐 Multiple Auth Methods:
- Email OTP
- Social login (Google, Discord, X/Twitter)
- Passkey authentication
- External wallets (MetaMask, WalletConnect, Injected)
- 💼 Wallet Management: Connect, disconnect, view wallet info, export wallets
- 🎨 Beautiful UI Components: Pre-built ConnectButton, WalletModal, and OnboardingUI
- 🌓 Theme Support: Light and dark themes
- 🔄 Auto-Reconnect: Automatic session restoration
- 📱 Responsive Design: Works on all devices
- 🔒 Secure: IndexedDB key storage via Turnkey
- ⚡ TypeScript: Full TypeScript support
- 🌐 Multi-Chain: Support for multiple blockchain networks
⚙️ Configuration
Basic Configuration
const providerConfig: AbstraxnProviderConfig = {
apiKey: 'your-api-key-here',
};UI Configuration
Customize the authentication UI with these optional settings:
const providerConfig: AbstraxnProviderConfig = {
apiKey: 'your-api-key-here',
ui: {
onboardTitle: 'Sign In', // Optional (default: 'Sign In')
logo: 'https://your-logo-url.com/logo.png', // Optional (default: no logo)
theme: 'light', // Optional: 'light' | 'dark' (default: 'light')
showFooter: true, // Optional (default: true)
showCloseButton: true, // Optional (default: true)
closeOnBackdropClick: true, // Optional (default: true)
authMethods: ['otp', 'passkey', 'google', 'twitter', 'discord'], // Optional (default: ['otp', 'google'])
// Custom labels
labels: {
emailLabel: 'Enter Email', // Optional (default: 'Email Address')
emailPlaceholder: 'Enter your email', // Optional (default: 'Enter your email address')
otpLabel: 'OTP', // Optional (default: 'OTP Code')
otpPlaceholder: 'Enter your OTP', // Optional (default: 'Enter 6-digit code')
emailButton: 'Continue', // Optional (default: 'Continue')
otpButton: 'Verify', // Optional (default: 'Verify')
googleButton: 'Continue with Google', // Optional (default: 'Continue with Google')
},
// Custom colors
colors: {
primary: '#9333ea',
primaryHover: '#7e22ce',
},
// Custom CSS
customCSS: `
.onboarding-button-primary {
background-color: rgb(234, 51, 231);
}
.onboarding-card {
border-radius: 20px;
}
`,
},
};External Wallets Configuration
Enable support for external wallets like MetaMask and WalletConnect:
const providerConfig: AbstraxnProviderConfig = {
apiKey: 'your-api-key-here',
// Enable external wallets
externalWallets: {
enabled: true,
// Required for WalletConnect
walletConnectProjectId: 'your-walletconnect-project-id',
connectors: ['injected', 'metaMask', 'walletConnect'],
},
};Complete Configuration Example
const providerConfig: AbstraxnProviderConfig = {
apiKey: 'your-api-key-here',
ui: {
onboardTitle: 'Welcome',
theme: 'dark',
showFooter: true,
showCloseButton: true,
closeOnBackdropClick: true,
authMethods: ['otp', 'passkey', 'google', 'twitter', 'discord'],
labels: {
emailLabel: 'Email Address',
emailPlaceholder: 'Enter your email',
otpLabel: 'Verification Code',
otpPlaceholder: 'Enter code',
emailButton: 'Continue',
otpButton: 'Verify',
googleButton: 'Sign in with Google',
},
colors: {
primary: '#9333ea',
primaryHover: '#7e22ce',
},
},
externalWallets: {
enabled: true,
walletConnectProjectId: 'your-walletconnect-project-id',
connectors: ['injected', 'metaMask', 'walletConnect'],
},
};📚 Components
ConnectButton
A ready-to-use button component that handles wallet connection and displays wallet management modal.
import { ConnectButton } from "@abstraxn/signer/react";
<ConnectButton
connectText="Connect Wallet" // Text when disconnected
connectedText="Connected" // Text when connected
showAddress={true} // Show address when connected
onClick={() => {}} // Custom click handler (optional)
/>OnboardingUI
Direct authentication component that can be embedded anywhere in your app:
import { OnboardingUI } from "@abstraxn/signer/react";
function MyAuthPage() {
return (
<div>
<OnboardingUI />
</div>
);
}WalletModal
A beautiful wallet management modal that appears when the user clicks the ConnectButton while connected.
Features:
- User wallet information (address, email)
- Quick actions (Send, Receive, Buy)
- Asset display
- Navigation menu (Transactions, View Assets, Manage Wallet)
- Disconnect functionality
- Automatically uses theme from configuration
import { WalletModal } from "@abstraxn/signer/react";
import { useState } from "react";
function MyComponent() {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<button onClick={() => setIsOpen(true)}>Open Wallet</button>
<WalletModal isOpen={isOpen} onClose={() => setIsOpen(false)} />
</>
);
}🪝 Hooks
Core Hooks
import {
useAbstraxnWallet,
useIsConnected,
useAddress,
useWhoami
} from "@abstraxn/signer/react";
function MyComponent() {
const { showOnboarding, disconnect, loading } = useAbstraxnWallet();
const isConnected = useIsConnected(); // Check if wallet is connected
const address = useAddress(); // Get wallet address
const whoami = useWhoami(); // Get user information
}External Wallet Hooks
import { useExternalWalletInfo } from "@abstraxn/signer/react";
function ExternalWalletComponent() {
const {
chainId,
network,
formattedBalance,
switchChain,
isConnected: isExternalWalletConnected,
address: externalWalletAddress,
walletClient
} = useExternalWalletInfo();
}Transaction Hooks
Prepare and Sign Transactions
import { usePrepareTransaction, useAddress } from "@abstraxn/signer/react";
import { createPublicClient, http } from 'viem';
import { polygonAmoy } from 'viem/chains';
function SendTransaction() {
const { prepareTransaction } = usePrepareTransaction();
const address = useAddress();
const handleSend = async () => {
const toAddress = '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb';
const amount = '0.001';
const rpcUrl = 'https://rpc-amoy.polygon.technology';
// Prepare and sign transaction via API
const preparedTx = await prepareTransaction(
toAddress,
amount,
rpcUrl,
polygonAmoy.id
);
console.log('Prepared & Signed Transaction:', preparedTx);
// Create public client to send the signed transaction
const publicClient = createPublicClient({
chain: polygonAmoy,
transport: http(rpcUrl),
});
// Execute the signed transaction
const hash = await publicClient.sendRawTransaction({
serializedTransaction: preparedTx.signedTransaction as `0x${string}`,
});
console.log('Transaction hash:', hash);
};
return <button onClick={handleSend}>Send Transaction</button>;
}Wallet Export Hook
Export wallet private keys for backup or migration:
import { useExportWallet } from "@abstraxn/signer/react";
import { generateP256KeyPair } from "@turnkey/crypto";
function ExportWallet() {
const { exportWallet } = useExportWallet();
const handleExport = async () => {
// Generate key pair for encryption
const keyPair = await generateP256KeyPair();
const privateKey = keyPair.privateKey;
const publicKey = keyPair.publicKeyUncompressed;
// Export wallet (specify 'evm' or 'solana')
const exportedWallet = await exportWallet(publicKey, privateKey, 'evm');
console.log('Exported wallet:', exportedWallet);
};
return <button onClick={handleExport}>Export Wallet</button>;
}🔐 Authentication Methods
Email OTP
- User enters email address
- SDK sends OTP to email
- User enters OTP code
- SDK verifies OTP and authenticates user
- Wallet is connected automatically
Social Login
- Google: OAuth-based authentication
- Discord: OAuth-based authentication
- X (Twitter): OAuth-based authentication
Passkey
Modern passwordless authentication using WebAuthn
External Wallets
- MetaMask: Browser extension wallet
- WalletConnect: Connect mobile wallets via QR code
- Injected: Any injected Web3 wallet
📖 Complete Examples
Example 1: Basic Integration with Custom UI
import { AbstraxnProvider, ConnectButton } from "@abstraxn/signer/react";
function App() {
return (
<AbstraxnProvider
config={{
apiKey: "your-api-key-here",
ui: {
theme: "dark",
onboardTitle: "Welcome to My DApp",
authMethods: ['otp', 'google', 'passkey'],
colors: {
primary: '#9333ea',
primaryHover: '#7e22ce',
},
},
}}
>
<div>
<h1>My DApp</h1>
<ConnectButton />
</div>
</AbstraxnProvider>
);
}Example 2: With External Wallets
import { AbstraxnProvider, ConnectButton } from "@abstraxn/signer/react";
function App() {
return (
<AbstraxnProvider
config={{
apiKey: "your-api-key-here",
externalWallets: {
enabled: true,
connectors: ['injected', 'metaMask', 'walletConnect'],
},
walletConnectProjectId: 'your-walletconnect-project-id',
ui: {
theme: "light",
authMethods: ['otp', 'google', 'discord', 'twitter', 'passkey'],
},
}}
>
<div>
<h1>Multi-Wallet DApp</h1>
<ConnectButton showAddress={true} />
</div>
</AbstraxnProvider>
);
}Example 3: Custom Hook-Based UI
import {
useAbstraxnWallet,
useIsConnected,
useAddress,
useExternalWalletInfo,
} from "@abstraxn/signer/react";
function CustomWalletButton() {
const { showOnboarding, disconnect, loading } = useAbstraxnWallet();
const isConnected = useIsConnected();
const address = useAddress();
const {
isConnected: isExternalConnected,
address: externalAddress
} = useExternalWalletInfo();
if (!isConnected && !isExternalConnected) {
return (
<button onClick={showOnboarding} disabled={loading}>
{loading ? 'Connecting...' : 'Connect Wallet'}
</button>
);
}
const displayAddress = address || externalAddress;
return (
<div>
<p>Connected: {displayAddress?.slice(0, 6)}...{displayAddress?.slice(-4)}</p>
<button onClick={disconnect}>Disconnect</button>
</div>
);
}Example 4: Next.js Integration
// app/layout.tsx or pages/_app.tsx
import { AbstraxnProvider, type AbstraxnProviderConfig } from "@abstraxn/signer/react";
const config: AbstraxnProviderConfig = {
apiKey: process.env.NEXT_PUBLIC_ABSTRAXN_API_KEY!,
ui: {
theme: "light",
authMethods: ['otp', 'google', 'passkey'],
},
externalWallets: {
enabled: true,
connectors: ['injected', 'metaMask', 'walletConnect'],
},
walletConnectProjectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID!,
};
export default function RootLayout({ children }) {
return (
<html>
<body>
<AbstraxnProvider config={config}>
{children}
</AbstraxnProvider>
</body>
</html>
);
}🎨 Theming
The SDK supports both light and dark themes with full customization:
<AbstraxnProvider
config={{
apiKey: "your-api-key",
ui: {
theme: "dark", // 'light' | 'dark'
colors: {
primary: '#9333ea',
primaryHover: '#7e22ce',
background: '#1a1a1a',
text: '#ffffff',
},
customCSS: `
.onboarding-button-primary {
border-radius: 12px;
}
`,
},
}}
>
<App />
</AbstraxnProvider>🔒 Security
- IndexedDB Storage: Keys are stored securely in browser IndexedDB via Turnkey
- JWT Tokens: Secure token management with automatic refresh
- HTTPS Only: All API calls use HTTPS
- API Key Authentication: Secure API key-based authentication
- No Private Keys Exposed: All key management is handled internally
- Encrypted Exports: Wallet exports are encrypted using P256 key pairs
🐛 Error Handling
import { useAbstraxnWallet, useError } from "@abstraxn/signer/react";
function MyComponent() {
const { showOnboarding } = useAbstraxnWallet();
const error = useError();
const handleConnect = async () => {
try {
await showOnboarding();
} catch (err) {
console.error("Connection failed:", err);
}
};
return (
<div>
<button onClick={handleConnect}>Connect</button>
{error && <div className="error">Error: {error.message}</div>}
</div>
);
}📚 API Reference
Main Hooks
| Hook | Description |
|------|-------------|
| useAbstraxnWallet() | Main hook with all wallet functionality |
| useIsConnected() | Check if wallet is connected |
| useAddress() | Get wallet address |
| useWhoami() | Get user information |
| useExternalWalletInfo() | Get external wallet information |
| usePrepareTransaction() | Prepare and sign transactions |
| useExportWallet() | Export wallet private keys |
AbstraxnWallet Methods
showOnboarding(): Show authentication UIdisconnect(): Disconnect walletgetAddress(): Get wallet addressgetChainId(): Get current chain IDswitchChain(chainId): Switch blockchain networksignMessage(message): Sign arbitrary messagesignTransaction(tx): Sign transactionsendTransaction(tx): Sign and send transaction
📱 Responsive Design
All components are fully responsive and work on:
- Desktop
- Tablet
- Mobile devices
The modals automatically adapt to screen size and appear as bottom sheets on mobile devices.
🤝 Support
For issues, questions, or contributions, please visit our GitHub repository.
📝 License
MIT
Made with ❤️ by Abstraxn
