Skip to content

Authentication Examples

For comprehensive implementation examples across all languages and frameworks, see EIP-712 Signing Implementation.

Quick Integration Examples

Minimal integration examples. See EIP-712 guide for complete implementation details.

JavaScript/TypeScript with viem

// Minimal WebSocket auth example
import { createWalletClient, http, parseSignature } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
 
const account = privateKeyToAccount('0x...');
const client = createWalletClient({
  account,
  transport: http()
});
 
// Sign WebSocket authentication
const authSignature = await client.signTypedData({
  domain: {
    name: "Synthetix",
    version: "1",
    chainId: BigInt(1)
  },
  types: {
    AuthMessage: [
      { name: "subAccountId", type: "uint256" },
      { name: "timestamp", type: "uint256" },
      { name: "action", type: "string" }
    ]
  },
  primaryType: "AuthMessage",
  message: {
    subAccountId: BigInt("123456789"),
    timestamp: BigInt(Math.floor(Date.now() / 1000)),
    action: "websocket_auth"
  }
});
 
const { v, r, s } = parseSignature(authSignature);

Python with eth_account

from eth_account.messages import encode_structured_data
from eth_account import Account
import time
 
# Minimal order signing example
account = Account.from_key('0x...')
 
typed_data = {
    "types": {
        "EIP712Domain": [
            {"name": "name", "type": "string"},
            {"name": "version", "type": "string"},
            {"name": "chainId", "type": "uint256"}
        ],
        "NewOrderRequest": [
            {"name": "subAccountId", "type": "uint64"},
            {"name": "symbol", "type": "string"},
            {"name": "side", "type": "string"},
            {"name": "quantity", "type": "string"},
            {"name": "price", "type": "string"},
            {"name": "orderType", "type": "string"},
            {"name": "reduceOnly", "type": "bool"},
            {"name": "nonce", "type": "uint256"},
            {"name": "expiresAfter", "type": "uint256"}
        ]
    },
    "primaryType": "NewOrderRequest",
    "domain": {
        "name": "Synthetix",
        "version": "1",
        "chainId": 1
    },
    "message": {
        "subAccountId": 123456789,
        "symbol": "BTC-USDT",
        "side": "buy",
        "quantity": "0.1",
        "price": "50000",
        "orderType": "limitGtc",
        "triggerPrice": "",
        "isTriggerMarket": False,
        "reduceOnly": False,
        "nonce": int(time.time() * 1000),
        "expiresAfter": 0
    }
}
 
encoded = encode_structured_data(typed_data)
signed = account.sign_message(encoded)

Go with go-ethereum

// Minimal auth example
import (
    "time"
    "github.com/ethereum/go-ethereum/common/math"
    "github.com/ethereum/go-ethereum/signer/core/apitypes"
)
 
domain := apitypes.TypedDataDomain{
    Name:    "Synthetix",
    Version: "1",
    ChainId: math.NewHexOrDecimal256(1),
}
 
types := apitypes.Types{
    "EIP712Domain": {
        {"name", "string"},
        {"version", "string"},
        {"chainId", "uint256"},
    },
    "AuthMessage": {
        {"subAccountId", "uint256"},
        {"timestamp", "uint256"},
        {"action", "string"},
    },
}
 
message := apitypes.TypedDataMessage{
    "subAccountId": math.NewHexOrDecimal256(123456789),
    "timestamp":    math.NewHexOrDecimal256(time.Now().Unix()),
    "action":       "websocket_auth",
}
 
typedData := apitypes.TypedData{
    Types:       types,
    PrimaryType: "AuthMessage",
    Domain:      domain,
    Message:     message,
}
 
// Sign with your private key...

Integration Patterns

React Hook Pattern

// Custom hook for Synthetix signing
export const useSynthetixSigner = (privateKey: string) => {
  const signer = useMemo(() => new SynthetixSigner(privateKey), [privateKey]);
 
  const signOrder = useCallback(async (orderData) => {
    return await signer.signPlaceOrder(orderData);
  }, [signer]);
 
  const signAuth = useCallback(async (subAccountId: string) => {
    return await signer.signWebSocketAuth(subAccountId);
  }, [signer]);
 
  return { signOrder, signAuth };
};

Error Handling Pattern

try {
  const signature = await signer.signPlaceOrder(orderData);
  // Use signature in API call
} catch (error) {
  if (error.message.includes('subAccountId')) {
    console.error('Missing required subAccountId field');
  } else if (error.message.includes('orderType')) {
    console.error('Order type must be JSON stringified');
  } else {
    console.error('Signature failed:', error.message);
  }
}

For Complete Examples