Portal de desarrolladores
Tema

Build Intent Orders on EVM#

Before submitting an intent order, you need to sign the signData object returned by the quote endpoint, then submit the signature together with signingScheme to the Create Intent Order endpoint. The signing method depends on your wallet type:

  • EOA wallet (a wallet controlled directly by a private key, e.g. MetaMask, a standard hot/cold wallet) → use signingScheme: "eip712"
  • Smart contract wallet (e.g. a Safe multisig, an AA wallet) → use signingScheme: "eip1271"; the signature must be generated using the OKX Intent SDK

1. Get the Data to Sign#

Call Get Intent Quote with mode=intent. The signData field in the response is the object you need to sign — it contains domain, types, and message (a standard EIP-712 TypedData structure).

typescript
const quote = await getIntentQuote({ mode: 'intent', /* ...other quote params */ });
const { signData } = quote.data[0];
// signData = { domain, types, message }

2. Option A: EIP-712 Signature (EOA Wallets)#

For a standard private-key wallet, sign signData directly with eth_signTypedData_v4 — no additional SDK is needed.

typescript
import { ethers } from 'ethers';
 
const wallet = new ethers.Wallet(PRIVATE_KEY);
 
// signData.types usually contains a primary type besides EIP712Domain (e.g. Order),
// ethers v5's _signTypedData requires EIP712Domain to be stripped out before passing it in
const { EIP712Domain, ...types } = signData.types;
 
const signature = await wallet._signTypedData(
  signData.domain,
  types,
  signData.message
);
 
// Submit the order
await createIntentOrder({
  ...orderParams,
  signingScheme: 'eip712',
  signature,
});

3. Option B: EIP-1271 Signature (Smart Contract Wallets)#

A smart contract wallet (e.g. Safe) has no private key — signature verification is implemented by the contract's own isValidSignature(hash, signature) method, so you cannot use a raw eth_signTypedData output directly. The signature needs to be assembled according to your contract wallet's own signature-collection rules; this logic please refer to OKX Intent SDK.

Additional Considerations for EIP-1271#

  • Verification depends on on-chain state: isValidSignature for EIP-1271 is a real on-chain read call, and its result depends on the contract's state at verification time (e.g. a Safe's owner set, threshold, or whether approveHash has been called). If the contract's state changes between quoting and submitting the order (owner change, threshold change), verification may fail — make sure the wallet's state is stable before submitting.
  • chainIndex must match the chain the contract is deployed on: a smart contract wallet may share the same address across chains but have different state on each (not every contract wallet is a counterfactual CREATE2 deployment with synchronized state) — the chainIndex used at order submission determines which chain the signature is verified against.
  • Gas and latency: EIP-1271 verification requires one extra RPC call compared to the purely offline verification of EIP-712. If you do client-side pre-validation, account for this call's latency and possible retries on failure.