L1: Private Key Authentication
The highest level of authentication is via an account’s Polygon private key.
The private key remains in control of a user’s funds and all trading is non-custodial.
The operator never has control over users’ funds.
Private key authentication is required for:
- Placing an order (for signing the order)
- Creating or revoking API keys
L1 Header
| Header | Required? | Description |
|---|---|---|
POLY_ADDRESS | yes | Polygon address |
POLY_SIGNATURE | yes | CLOB EIP 712 signature |
POLY_TIMESTAMP | yes | Current UNIX timestamp |
POLY_NONCE | yes | Nonce. Default 0 |
The POLY_SIGNATURE is generated by signing the following EIP-712 struct.
Implementations exist in:
Signing Example
python
domain = {
"name": "ClobAuthDomain",
"version": "1",
"chainId": chainId, # Polygon Chain ID 137
}
types = {
"ClobAuth": [
{"name": "address", "type": "address"},
{"name": "timestamp", "type": "string"},
{"name": "nonce", "type": "uint256"},
{"name": "message", "type": "string"},
]
}
value = {
"address": signingAddress, # The signing address
"timestamp": ts, # The CLOB API server timestamp
"nonce": nonce, # The nonce used
"message": "This message attests that I control the given wallet",
}
sig = await signer._signTypedData(domain, types, value)typescript
const domain = {
name: "ClobAuthDomain",
version: "1",
chainId: chainId, // Polygon Chain ID 137
};
const types = {
ClobAuth: [
{ name: "address", type: "address" },
{ name: "timestamp", type: "string" },
{ name: "nonce", type: "uint256" },
{ name: "message", type: "string" },
],
};
const value = {
address: signingAddress, // The Signing address
timestamp: ts, // The CLOB API server timestamp
nonce: nonce, // The nonce used
message: "This message attests that I control the given wallet", // Static message
};
const sig = await signer._signTypedData(domain, types, value);