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
- EIP-712 Signing Implementation - Full implementations in all languages
- Nonce Management - Proper nonce handling strategies
- Troubleshooting - Debug authentication issues