Skip to main content
Every step the wallet API returns carries an EIP-1193 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 with 0x. Smart-account (ERC-1271) and longer signatures are refused: sign with the wallet’s own key.
  • Switch the wallet to the action’s chainId first when it is set. personal_sign steps have chainId: null.
  • Sign before expiresAtMs when the action has it. A later signature fails the action with SIGNATURE_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.
Use a library’s typed-data signer by parsing params[1] with JSON.parse. Some libraries (ethers) want EIP712Domain removed from types first. viem and eth-account accept it as is.

Before you show a request

A malicious or buggy server could ask for the wrong thing. Before the wallet prompts, check:
  1. params[0] (or from) is the connected address.
  2. The typed data’s domain.chainId matches the action’s chainId, and both are a chain you expect for its venue (table).
  3. domain.name and primaryType are one of the pairs on this page.
  4. 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.
  5. For transactions (only Predict.fun approvals), every call is an approve or setApprovalForAll on BNB Chain USDT or one of Predict.fun’s outcome-token contracts, and every value is 0x0.

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.
  • eth_signTypedData_v4, chain 0x89
  • Domain { name: "ClobAuthDomain", version: "1", chainId: 137 }, no verifying contract
  • primaryType: "ClobAuth" with address, timestamp (unix seconds, as a string), nonce, and message: "This message attests that I control the given wallet"
  • Shown as Connect this wallet to Polymarket (no gas)
Asked only when the trading wallet isn’t approved yet.
  • eth_signTypedData_v4, chain 0x89
  • Domain { name: "DepositWallet", version: "1", chainId: 137, verifyingContract: <trading wallet> }
  • primaryType: "Batch": Batch(address wallet, uint256 nonce, uint256 deadline, Call[] calls) with Call(address target, uint256 value, bytes data)
  • The calls approve Polymarket’s contracts to use the trading wallet’s pUSD and outcome tokens. deadline is 10 minutes out
  • Shown as Approve your trading wallet (no gas)
The trading wallet is a smart wallet owned by the user’s address and controlled only by the user’s key.The batch holds only the approvals the wallet is missing. Every pUSD 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.
  • eth_signTypedData_v4, chain 0x89
  • An ERC-7739 TypedDataSign that wraps the Polymarket order, so the trading wallet can validate it:
    • Domain: { name: "Polymarket CTF Exchange", version: "2" | "3", chainId: 137, verifyingContract: <exchange> }. Version 3 is for markets on Polymarket’s newer exchange
    • primaryType: "TypedDataSign", message { contents: <Order>, name: "DepositWallet", version: "1", chainId: 137, verifyingContract: <trading wallet>, salt }
    • Order carries salt, maker, signer, tokenId, makerAmount, takerAmount, side, signatureType, timestamp, metadata, builder. maker is the trading wallet
  • Shown as Confirm this Polymarket order. Sign within about 60 seconds
A first order on a new wallet can ask for all three in one action.

Predict.fun

Asked only for approvals the wallet is missing.
  • wallet_sendCalls, chain 0x38, one call per approval (up to 12): an unlimited ERC-20 approve of USDT and ERC-1155 setApprovalForAll of outcome tokens, both to Predict.fun’s exchange contracts
  • fallbackRequests holds the same calls as separate eth_sendTransactions, for wallets without wallet_sendCalls
  • The user pays BNB gas once (about 70,000 gas per approval). With too little BNB, setup asks for nothing and ends done with next: "fund" and venueDetail.reason; an order fails with this wallet needs about … BNB …
  • Shown as Approve Predict.fun trading on BNB Chain: N approvals in one confirmation (pays BNB gas)
After you answer, the step is working while the approvals confirm, up to about 5 minutes.
  • personal_sign of 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
  • eth_signTypedData_v4, chain 0x38
  • 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
  • Order carries salt, maker, signer, taker, tokenId, makerAmount, takerAmount, expiration, nonce, feeRateBps, side, signatureType. maker and signer are the wallet; feeRateBps is 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.
  • eth_signTypedData_v4, chain 0xa4b1
  • Domain { name: "HyperliquidSignTransaction", version: "1", chainId: 42161, verifyingContract: 0x0000000000000000000000000000000000000000 }
  • primaryType: "HyperliquidTransaction:ApproveAgent" with hyperliquidChain ("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
Hyperliquid agents can place and cancel orders only. They can’t withdraw or transfer funds, and the user can revoke the agent on Hyperliquid at any time.
Asked right after the agent approval, only where a Hyperliquid builder fee is configured.
  • Same domain, primaryType: "HyperliquidTransaction:ApproveBuilderFee" with hyperliquidChain, maxFeeRate (a percent string, for example "0.01%"), builder, nonce
  • Shown as Approve the Hyperliquid builder fee on your trades (no gas)
  • See fees
Asked when spot USDC is short but the wallet’s perps account can cover the gap.
  • Same domain, primaryType: "HyperliquidTransaction:UsdClassTransfer" with hyperliquidChain, 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)
  • eth_signTypedData_v4, chain 0xa4b1
  • Domain { name: "Kairos", version: "1", chainId: 42161 }, no verifying contract
  • primaryType: "PlaceOrder" with wallet, 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, chain 0x89 (Polygon), even when the orders are on Predict.fun or Hyperliquid
  • Domain { name: "Kairos", version: "1", chainId: 137 }, no verifying contract
  • primaryType: "CancelOrders" with wallet, orders ("all", or the order ids joined by commas), action (the action id), expiresAt
  • Shown as Confirm cancelling these orders. Sign within 5 minutes
One cancel signature covers every venue.

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").