request. You pass it to the wallet as-is. This page lists every request the API can produce, so a wallet can show it clearly and check it before the user approves.
The four methods
Rules for signatures:
- Exactly 65 bytes (
r ‖ s ‖ v), hex with0x. Smart-account (ERC-1271) and longer signatures are refused: sign with the wallet’s own key. - Switch the wallet to the action’s
chainIdfirst when it is set.personal_signsteps havechainId: null. - Sign before
expiresAtMswhen the action has it. A later signature fails the action withSIGNATURE_EXPIRED; start a new one. - A signature from another address answers
400 signature is not from this wallet. The step stays open so the user can try again.
Before you show a request
A malicious or buggy server could ask for the wrong thing. Before the wallet prompts, check:params[0](orfrom) is the connected address.- The typed data’s
domain.chainIdmatches the action’schainId, and both are a chain you expect for itsvenue(table). domain.nameandprimaryTypeare one of the pairs on this page.- For orders, the message’s price, size and side match what the user asked for. On Polymarket and Predict.fun the price is
makerAmount / takerAmount(or the inverse for a sell). On Hyperliquid and cancels the terms are plain fields. - For transactions (only Predict.fun approvals), every call is an
approveorsetApprovalForAllon BNB Chain USDT or one of Predict.fun’s outcome-token contracts, and everyvalueis0x0.
Chains
If the wallet doesn’t know a chain, add it with
wallet_addEthereumChain and switch again. The SDK does this for you.
Polymarket
Nothing here costs gas.Setup 1: connect to Polymarket
Setup 1: connect to Polymarket
eth_signTypedData_v4, chain0x89- Domain
{ name: "ClobAuthDomain", version: "1", chainId: 137 }, no verifying contract primaryType: "ClobAuth"withaddress,timestamp(unix seconds, as a string),nonce, andmessage: "This message attests that I control the given wallet"- Shown as Connect this wallet to Polymarket (no gas)
Setup 2: approve the trading wallet
Setup 2: approve the trading wallet
Asked only when the trading wallet isn’t approved yet.
eth_signTypedData_v4, chain0x89- Domain
{ name: "DepositWallet", version: "1", chainId: 137, verifyingContract: <trading wallet> } primaryType: "Batch":Batch(address wallet, uint256 nonce, uint256 deadline, Call[] calls)withCall(address target, uint256 value, bytes data)- The calls approve Polymarket’s contracts to use the trading wallet’s pUSD and outcome tokens.
deadlineis 10 minutes out - Shown as Approve your trading wallet (no gas)
approve is unlimited. Each operator grant is setApprovalForAll(…, true).The Exchange V3, Router and Position Manager rows appear while Kairos has Polymarket Protocol V2 trading on.Outcome tokens are Polymarket’s Conditional Tokens
0x4D97DCd97eC945f40cF65F87097ACe5EA0476045. Position Manager 0x006F54F7f9A22e0000CC2AB60031000000ae9fEF holds Protocol V2 shares, Combo shares included. pUSD is 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB.The Router appears twice and only the first approval spends pUSD. If you never split Protocol V2 positions, that allowance is never used. A split or merge through on-chain intents carries its own approval, so it works whether or not this batch granted one.Order
Order
eth_signTypedData_v4, chain0x89- An ERC-7739
TypedDataSignthat wraps the Polymarket order, so the trading wallet can validate it:- Domain:
{ name: "Polymarket CTF Exchange", version: "2" | "3", chainId: 137, verifyingContract: <exchange> }. Version3is for markets on Polymarket’s newer exchange primaryType: "TypedDataSign", message{ contents: <Order>, name: "DepositWallet", version: "1", chainId: 137, verifyingContract: <trading wallet>, salt }Ordercarriessalt, maker, signer, tokenId, makerAmount, takerAmount, side, signatureType, timestamp, metadata, builder.makeris the trading wallet
- Domain:
- Shown as Confirm this Polymarket order. Sign within about 60 seconds
Predict.fun
Setup 1: approvals (pays BNB gas)
Setup 1: approvals (pays BNB gas)
Asked only for approvals the wallet is missing.
wallet_sendCalls, chain0x38, one call per approval (up to 12): an unlimited ERC-20approveof USDT and ERC-1155setApprovalForAllof outcome tokens, both to Predict.fun’s exchange contractsfallbackRequestsholds the same calls as separateeth_sendTransactions, for wallets withoutwallet_sendCalls- The user pays BNB gas once (about 70,000 gas per approval). With too little BNB, setup asks for nothing and ends
donewithnext: "fund"andvenueDetail.reason; an order fails withthis wallet needs about … BNB … - Shown as Approve Predict.fun trading on BNB Chain: N approvals in one confirmation (pays BNB gas)
working while the approvals confirm, up to about 5 minutes.Setup 2: sign in to Predict.fun
Setup 2: sign in to Predict.fun
personal_signof Predict.fun’s own login message,chainId: null- Shown as Sign in to Predict.fun (no gas)
- The session lasts about a day. An order asks for this again when less than an hour is left
Order
Order
eth_signTypedData_v4, chain0x38- Predict.fun’s own EIP-712 order: domain
{ name: "predict.fun CTF Exchange", version, chainId: 56, verifyingContract: <exchange> }. The exchange depends on whether the market is neg-risk and yield-bearing Ordercarriessalt, maker, signer, taker, tokenId, makerAmount, takerAmount, expiration, nonce, feeRateBps, side, signatureType.makerandsignerare the wallet;feeRateBpsis the market’s venue fee- Shown as Confirm this Predict.fun order. Sign within about 60 seconds
Hyperliquid
Hyperliquid’s user actions are EIP-712 messages on Arbitrum’s chain id. Nothing costs gas.Setup: approve the trading agent
Setup: approve the trading agent
eth_signTypedData_v4, chain0xa4b1- Domain
{ name: "HyperliquidSignTransaction", version: "1", chainId: 42161, verifyingContract: 0x0000000000000000000000000000000000000000 } primaryType: "HyperliquidTransaction:ApproveAgent"withhyperliquidChain("Mainnet"),agentAddress,agentName,nonce- Shown as Allow Kairos to place Hyperliquid trades for you (it cannot withdraw; no gas). If Hyperliquid dropped the agent while the account was empty, setup asks again with a note saying so
Setup: builder fee approval
Setup: builder fee approval
Asked right after the agent approval, only where a Hyperliquid builder fee is configured.
- Same domain,
primaryType: "HyperliquidTransaction:ApproveBuilderFee"withhyperliquidChain,maxFeeRate(a percent string, for example"0.01%"),builder,nonce - Shown as Approve the Hyperliquid builder fee on your trades (no gas)
- See fees
Order: move USDC from perps (only when needed)
Order: move USDC from perps (only when needed)
Asked when spot USDC is short but the wallet’s perps account can cover the gap.
- Same domain,
primaryType: "HyperliquidTransaction:UsdClassTransfer"withhyperliquidChain,amount(the shortfall including fees, rounded up to the cent),toPerp: false,nonce - Shown as Move X USDC from your Hyperliquid perps to spot for this order (no gas)
Order
Order
eth_signTypedData_v4, chain0xa4b1- Domain
{ name: "Kairos", version: "1", chainId: 42161 }, no verifying contract primaryType: "PlaceOrder"withwallet, market, outcome, side, price, size, timeInForce, postOnly, action, expiresAt. The terms are in plain text, so a wallet can show them directly- Kairos then places exactly that order on Hyperliquid with the approved agent
- Shown as Confirm this Hyperliquid order. Sign within 5 minutes
Cancel (every venue)
eth_signTypedData_v4, chain0x89(Polygon), even when the orders are on Predict.fun or Hyperliquid- Domain
{ name: "Kairos", version: "1", chainId: 137 }, no verifying contract primaryType: "CancelOrders"withwallet,orders("all", or the order ids joined by commas),action(the action id),expiresAt- Shown as Confirm cancelling these orders. Sign within 5 minutes
Sign-in
personal_sign of a Sign-In with Ethereum message, chainId: null. See the sign-in token.
Preview features
Trade plans, fee settlements and on-chain intents use the same methods. Their documents are listed on those pages:
Trade plans and on-chain intents check signatures more strictly: 65 bytes,
v of 0, 1, 27 or 28, and a low s value. Standard wallets already sign this way. On-chain intent documents carry chainId as a decimal string ("137").
