Skip to content

Safe Signature Verifier

A TypeScript library for verifying Safe (formerly Gnosis Safe) signatures, supporting both standard messages and EIP-712 typed data verification.

Basic Usage

1. Initialize the Verifier

import { SafeSignatureVerifier, initializeSafeVerifier } from './safe';

// Using constructor
const verifier = new SafeSignatureVerifier({
  rpcUrl: 'https://arbitrum.drpc.org',
  chainId: 42161,
  safe: {
    version: '1.4.1',
    saltNonce: 555n,
  },
});

// Using initialization helper
const verifier2 = await initializeSafeVerifier({
  rpcUrl: 'https://arbitrum.drpc.org',
  chainId: 42161,
});

2. Verify Standard Messages

// Using instance methods
const isValid = await verifier.verifyMessage({
  message: 'Hello World',
  signature: '0x...', // Signature hex
  address: '0x...', // Optional safe address
});

// Using helper function
const isValid2 = await verifySafeMsg(
  'Hello World',
  '0x...', // Safe address
  '0x...', // Signature
);

3. Verify EIP-712 Typed Data

// Example typed data structure
const domain = {
  name: 'Ether Mail',
  version: '1',
  chainId: 42161,
  verifyingContract: '0x...',
};

const types = {
  Person: [
    { name: 'name', type: 'string' },
    { name: 'wallet', type: 'address' },
  ],
  Mail: [
    { name: 'from', type: 'Person' },
    { name: 'to', type: 'Person' },
    { name: 'contents', type: 'string' },
  ],
};

// Using instance method
const isValid = await verifier.verifyTypedData({
  domain,
  types,
  primaryType: 'Mail',
  message: {
    from: { name: 'Alice', wallet: '0x...' },
    to: { name: 'Bob', wallet: '0x...' },
    contents: 'Hello!',
  },
  signature: '0x...',
  address: '0x...', // Optional safe address
});

// Using helper function
const isValid2 = await verifySafeTypedData({
  domain,
  types,
  primaryType: 'Mail',
  message: {
    /*...*/
  },
  signature: '0x...',
  address: '0x...',
});

Configuration Options

interface SafeVerifierConfig {
  // RPC endpoint URL
  rpcUrl?: string;

  // Chain ID or Chain object
  chainId?: number | Chain;

  // Owner address or account
  ownerAddress?: Account | Address;

  // Safe configuration
  safe?: {
    version?: string;
    saltNonce?: bigint | number;
    factoryAddress?: Address;
    singletonAddress?: Address;
    fallbackHandler?: Address;
    entryPointAddress?: Address;
  };

  // Client configuration
  client?: {
    transport?: HttpTransport;
    initTimeout?: number;
    debug?: boolean;
  };
}

Advanced Usage

Custom Environment Variables

The verifier supports configuration through environment variables:

RELAYER_RPC_URL=https://your-rpc-url
RELAYER_CHAIN_ID=42161
RELAYER_SAFE_SALT=555
PRIVATE_HTTPS_RPC_URL=http://localhost:8545
PRIVATE_WSS_RPC_URL=ws://localhost:8545

Error Handling

try {
  const verifier = await initializeSafeVerifier();
  const isValid = await verifier.verifyMessage({
    message: 'Hello',
    signature: '0x...',
  });
} catch (error) {
  console.error('Verification failed:', error);
}

Logging

The verifier includes built-in logging with Winston:

// Configure logging level
process.env.ENV = 'local'; // Sets debug level
// or
process.env.ENV = 'production'; // Sets info level

// Logs will include metadata about operations

Key Features

  • Supports both standard message and EIP-712 typed data verification
  • Built-in support for Safe contracts
  • Configurable RPC endpoints and chain IDs
  • Comprehensive logging
  • TypeScript type safety
  • Environment variable configuration
  • Error handling and timeout management

Dependencies

  • viem: Ethereum interaction library
  • permissionless: Account abstraction utilities
  • winston: Logging framework
  • ox: Crypto utilities

This documentation is generated from the service README. For the most up-to-date information, refer to the original README