Paxeer Docs logo

Signing

Learn how to implement message and typed data signing on Paxeer using EIP-191 and EIP-712 standards with viem and ethers examples.

Signing

Signing on Paxeer works through standard EVM libraries and wallet standards. The methods available depend on which wallet the user has connected.

Wallet Signing Support

MethodStandardPaxeer Global WalletMetaMaskWalletConnect wallets
personal_signEIP-191SupportedSupportedWallet-dependent
eth_signTypedData_v4EIP-712SupportedSupportedWallet-dependent
eth_signLegacyNot recommendedSupportedWallet-dependent
Transaction signing-SupportedSupportedSupported

Do not assume all wallets support all methods. Always handle rejection gracefully.

Personal Sign

viem
import { createWalletClient, custom } from 'viem';
import { sei } from 'viem/chains';

const client = createWalletClient({
  chain: sei,
  transport: custom(window.ethereum),
});

const [account] = await client.getAddresses();

const signature = await client.signMessage({
  account,
  message: 'Hello Paxeer',
});
ethers
import { ethers } from 'ethers';

const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();

const signature = await signer.signMessage('Hello Paxeer');

EIP-712 Typed Data

viem
const [account] = await client.getAddresses();

const signature = await client.signTypedData({
  account,
  domain: {
    name: 'My App',
    version: '1',
    chainId: 1329, // Paxeer mainnet
    verifyingContract: '0xContractAddress',
  },
  types: {
    Order: [
      { name: 'maker', type: 'address' },
      { name: 'amount', type: 'uint256' },
      { name: 'expiry', type: 'uint256' },
    ],
  },
  primaryType: 'Order',
  message: {
    maker: account,
    amount: 1000000n,
    expiry: BigInt(Math.floor(Date.now() / 1000) + 3600),
  },
});
ethers
import { ethers } from 'ethers';

const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();

const domain = {
  name: 'My App',
  version: '1',
  chainId: 1329,
  verifyingContract: '0xContractAddress',
};

const types = {
  Order: [
    { name: 'maker', type: 'address' },
    { name: 'amount', type: 'uint256' },
    { name: 'expiry', type: 'uint256' },
  ],
};

const value = {
  maker: await signer.getAddress(),
  amount: 1000000n,
  expiry: BigInt(Math.floor(Date.now() / 1000) + 3600),
};

const signature = await signer.signTypedData(domain, types, value);

Verifying Signatures

viem
import { verifyMessage, verifyTypedData } from 'viem';

// Verify personal sign
const valid = await verifyMessage({
  address: '0xSignerAddress',
  message: 'Hello Paxeer',
  signature,
});

// Verify EIP-712
const validTyped = await verifyTypedData({
  address: '0xSignerAddress',
  domain,
  types,
  primaryType: 'Order',
  message: value,
  signature,
});

EIP-1271 Contract Signatures

Smart contract wallets on Paxeer can validate signatures via EIP-1271 (isValidSignature). Use viem's verifyMessage with a contract address - it automatically uses EIP-1271 when the address is a contract.

viem
const valid = await verifyMessage({
  address: '0xSmartContractWallet',
  message: 'Hello Paxeer',
  signature,
});
// viem calls isValidSignature if the address is a contract