npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

signer-test-sdk

v0.1.11

Published

Abstraxn Signer package for handling transaction signing and wallet interactions.

Readme

@abstraxn/signer

Abstraxn Signer SDK - A comprehensive React wallet SDK for seamless Web3 wallet integration with email OTP and Google OAuth authentication.

npm version License: MIT

📦 Installation

npm install @abstraxn/signer react

Requirements:

  • React 18.0.0 or higher
  • Node.js 16.0.0 or higher

🚀 Quick Start

1. Wrap Your App with AbstraxnProvider

import { AbstraxnProvider } from "@abstraxn/signer/react";
import App from "./App";

function Root() {
  return (
    <AbstraxnProvider
      config={{
        apiKey: "your-api-key-here",
        autoInit: true,
        autoConnect: false,
        ui: {
          theme: "light",
          logoName: "My App",
          welcomeMessage: "Welcome to My App",
        },
      }}
    >
      <App />
    </AbstraxnProvider>
  );
}

2. Use the ConnectButton Component

import { ConnectButton } from "@abstraxn/signer/react";

function App() {
  return (
    <div>
      <ConnectButton
        connectText="Connect Wallet"
        connectedText="Connected"
        showAddress={true}
      />
    </div>
  );
}

That's it! The ConnectButton will:

  • Show onboarding modal when disconnected
  • Show wallet management modal when connected
  • Handle all authentication flows automatically

✨ Features

  • 🔐 Multiple Auth Methods: Email OTP and Google OAuth
  • 💼 Wallet Management: Connect, disconnect, view wallet info
  • 🎨 Beautiful UI Components: Pre-built ConnectButton and WalletModal
  • 🌓 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

📚 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)
/>;

Props:

  • connectText?: string - Button text when disconnected (default: "Connect Wallet")
  • connectedText?: string - Button text when connected (default: "Connected")
  • showAddress?: boolean - Show shortened address when connected (default: false)
  • onClick?: (e: MouseEvent) => void - Custom click handler
  • All standard HTML button props are supported

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

The modal is automatically shown when clicking ConnectButton while connected. You can also use it directly:

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)} />
    </>
  );
}

OnboardingUI

The onboarding component for authentication. Usually used automatically by ConnectButton, but can be used directly:

import { OnboardingUI } from "@abstraxn/signer/react";

<OnboardingUI
  config={{
    theme: "dark",
    logoName: "My App",
  }}
  modal={true}
  onClose={() => {}}
/>;

🪝 Hooks

useAbstraxnWallet

Main hook that provides access to all wallet functionality:

import { useAbstraxnWallet } from "@abstraxn/signer/react";

function MyComponent() {
  const {
    // State
    isConnected,
    address,
    user,
    whoami,
    chainId,
    loading,
    error,

    // Methods
    connect,
    disconnect,
    showOnboarding,
    hideOnboarding,
    getAddress,
    getChainId,
    switchChain,
    signMessage,
    signTransaction,
    sendTransaction,
    signTransactionViaAPI,
    signAndSendTransaction,
    loginWithOTP,
    verifyOTP,
    loginWithGoogle,
    handleGoogleCallback,

    // Config
    uiConfig,
  } = useAbstraxnWallet();
}

Individual Hooks

For simpler use cases, you can use individual hooks:

import {
  useIsConnected,
  useAddress,
  useUser,
  useChainId,
  useLoading,
  useError,
} from "@abstraxn/signer/react";

function MyComponent() {
  const isConnected = useIsConnected();
  const address = useAddress();
  const user = useUser();
  const chainId = useChainId();
  const loading = useLoading();
  const error = useError();
}

Transaction Hooks

import { usePrepareTransaction } from "@abstraxn/signer/react";

function SendTransaction() {
  const { prepareTransaction } = usePrepareTransaction();

  const handleSend = async () => {
    // Prepare and sign transaction
    const result = await prepareTransaction(
      "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", // to
      "0.001", // amount in ETH
      "https://rpc-amoy.polygon.technology",
      80002
    );

    // gives signed transaction which user execute through its public client

    // 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);
  };
}

⚙️ Configuration

AbstraxnProviderConfig

interface AbstraxnProviderConfig {
  // Required
  apiKey: string;

  // Optional Wallet Config
  authMethods?: ("otp" | "google")[]; // Default: ['otp', 'google']
  googleClientId?: string; // Required for Google auth
  defaultChainId?: number; // Default chain ID
  supportedChains?: Chain[]; // Supported chains
  autoConnect?: boolean; // Auto-connect on init (default: false)
  enableLogging?: boolean; // Enable debug logging (default: false)

  // Provider Config
  autoInit?: boolean; // Auto-initialize IndexedDB (default: true)
  autoShowOnboarding?: boolean; // Auto-show onboarding (default: false)

  // UI Configuration
  ui?: AbstraxnUIConfig;
}

AbstraxnUIConfig

interface AbstraxnUIConfig {
  // Theme & Branding
  theme?: "light" | "dark"; // Default: 'light'
  logo?: string; // Logo URL or HTML string
  logoName?: string; // Brand name (shown if logo not provided)
  welcomeMessage?: string; // Default: 'Welcome back!'
  tagline?: string; // Default: 'Web3 Experience Simplified'
  showTagline?: boolean; // Default: true

  // Footer
  showFooter?: boolean; // Default: true
  showTerms?: boolean; // Default: false

  // Modal Behavior
  modal?: boolean; // Show as modal (default: true)
  closeOnBackdropClick?: boolean; // Close on backdrop click (default: true)
  showCloseButton?: boolean; // Show close button (default: true)

  // Styling
  className?: string; // Custom CSS class
  style?: string | Partial<CSSStyleDeclaration>; // Custom styles
  customCSS?: string; // Custom CSS overrides

  // Colors
  colors?: {
    primary?: string;
    primaryHover?: string;
    background?: string;
    text?: string;
    border?: string;
    error?: string;
    success?: string;
  };

  // Labels
  labels?: {
    emailLabel?: string;
    emailPlaceholder?: string;
    otpLabel?: string;
    otpPlaceholder?: string;
    emailButton?: string;
    otpButton?: string;
    googleButton?: string;
    connectButton?: string;
    disconnectButton?: string;
  };

  // Auth Methods
  authMethods?: ("otp" | "google")[]; // Which auth methods to show
}

📖 Complete Examples

Example 1: Basic Integration

import { AbstraxnProvider, ConnectButton } from "@abstraxn/signer/react";

function App() {
  return (
    <AbstraxnProvider
      config={{
        apiKey: "your-api-key-here",
        autoInit: true,
        ui: {
          theme: "light",
          logoName: "My DApp",
        },
      }}
    >
      <div>
        <h1>My DApp</h1>
        <ConnectButton />
      </div>
    </AbstraxnProvider>
  );
}

Example 2: Custom Wallet UI

import {
  useAbstraxnWallet,
  useIsConnected,
  useAddress,
  WalletModal,
} from "@abstraxn/signer/react";
import { useState } from "react";

function CustomWalletButton() {
  const { connect, disconnect } = useAbstraxnWallet();
  const isConnected = useIsConnected();
  const address = useAddress();
  const [showModal, setShowModal] = useState(false);

  if (!isConnected) {
    return <button onClick={connect}>Connect Wallet</button>;
  }

  return (
    <>
      <button onClick={() => setShowModal(true)}>
        {address?.slice(0, 6)}...{address?.slice(-4)}
      </button>
      <WalletModal isOpen={showModal} onClose={() => setShowModal(false)} />
    </>
  );
}

Example 3: Send Transaction

import { useSignAndSendTransaction, useAddress } from "@abstraxn/signer/react";
import { useState } from "react";

function SendTransaction() {
  const { signAndSendTransaction } = useSignAndSendTransaction();
  const address = useAddress();
  const [to, setTo] = useState("");
  const [amount, setAmount] = useState("0.001");
  const [loading, setLoading] = useState(false);
  const [txHash, setTxHash] = useState<string | null>(null);

  const handleSend = async () => {
    if (!address) return;

    setLoading(true);
    try {
      // First, prepare the transaction
      const rpcUrl = "https://rpc-amoy.polygon.technology";

      // Create unsigned transaction (you can use viem or other libraries)
      const unsignedTx = "..."; // Your unsigned transaction

      // Sign and send
      const result = await signAndSendTransaction(unsignedTx, address, rpcUrl);

      setTxHash(result.hash);
      console.log("Transaction sent:", result.hash);
    } catch (error) {
      console.error("Transaction failed:", error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <input
        type="text"
        placeholder="Recipient address"
        value={to}
        onChange={(e) => setTo(e.target.value)}
      />
      <input
        type="text"
        placeholder="Amount"
        value={amount}
        onChange={(e) => setAmount(e.target.value)}
      />
      <button onClick={handleSend} disabled={loading}>
        {loading ? "Sending..." : "Send"}
      </button>
      {txHash && (
        <p>
          Transaction:
          <a href={`https://amoy.polygonscan.com/tx/${txHash}`} target="_blank">
            {txHash}
          </a>
        </p>
      )}
    </div>
  );
}

Example 4: Dark Theme

<AbstraxnProvider
  config={{
    apiKey: "your-api-key-here",
    ui: {
      theme: "dark",
      logoName: "My DApp",
      welcomeMessage: "Welcome to My DApp",
      colors: {
        primary: "#9333ea",
        primaryHover: "#7e22ce",
      },
    },
  }}
>
  <App />
</AbstraxnProvider>

Example 5: Next.js Integration

// app/layout.tsx or pages/_app.tsx
import { AbstraxnProvider } from "@abstraxn/signer/react";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <AbstraxnProvider
          config={{
            apiKey: process.env.NEXT_PUBLIC_ABSTRAXN_API_KEY!,
            autoInit: true,
            ui: {
              theme: "light",
            },
          }}
        >
          {children}
        </AbstraxnProvider>
      </body>
    </html>
  );
}

🔐 Authentication Flow

Email OTP Flow

  1. User enters email address
  2. SDK sends OTP to email
  3. User enters OTP code
  4. SDK verifies OTP and authenticates user
  5. Wallet is connected automatically

Google OAuth Flow

  1. User clicks "Continue with Google"
  2. SDK redirects to Google OAuth
  3. User authenticates with Google
  4. Google redirects back to your app
  5. SDK handles callback and connects wallet

Both flows are handled automatically by the ConnectButton component.

🎨 Theming

The SDK supports both light and dark themes. The theme is applied to:

  • OnboardingUI component
  • WalletModal component
  • All UI elements
<AbstraxnProvider
  config={{
    apiKey: "your-api-key",
    ui: {
      theme: "dark", // or 'light'
    },
  }}
>
  <App />
</AbstraxnProvider>

📱 Responsive Design

All components are fully responsive and work on:

  • Desktop
  • Tablet
  • Mobile devices

The WalletModal automatically adapts to screen size and appears as a bottom sheet on mobile devices.

🔒 Security

  • IndexedDB Storage: Keys are stored securely in browser IndexedDB
  • 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

🐛 Error Handling

import { useAbstraxnWallet, useError } from "@abstraxn/signer/react";

function MyComponent() {
  const { connect } = useAbstraxnWallet();
  const error = useError();

  const handleConnect = async () => {
    try {
      await connect();
    } catch (err) {
      console.error("Connection failed:", err);
      // Handle error
    }
  };

  return (
    <div>
      <button onClick={handleConnect}>Connect</button>
      {error && <div className="error">Error: {error.message}</div>}
    </div>
  );
}

📚 API Reference

AbstraxnWallet Methods

  • connect(): Connect wallet
  • disconnect(): Disconnect wallet
  • getAddress(): Get wallet address
  • getChainId(): Get current chain ID
  • switchChain(chainId): Switch blockchain network
  • getUserInfo(): Get user information
  • getWhoami(): Get whoami information
  • signMessage(message): Sign arbitrary message
  • signTransaction(tx): Sign transaction
  • sendTransaction(tx): Sign and send transaction
  • signTransactionViaAPI(tx): Sign transaction via API

Events

The wallet emits the following events:

  • connect: Wallet connected
  • disconnect: Wallet disconnected
  • accountChanged: Account changed
  • chainChanged: Chain changed

🤝 Support

For issues, questions, or contributions, please visit our GitHub repository.

📝 License

MIT


Made with ❤️ by Abstraxn