跳转到主要内容
Polymarket 的 Relayer Client 为你的用户提供免 gas 交易功能。用户无需持有 POL 来支付 gas 费,Polymarket 的基础设施会支付所有交易费用。这创造了一种无缝体验,用户只需要 USDC.e 就能交易。

工作原理

relayer 充当交易赞助者:
  1. 你的应用创建一笔交易
  2. 用户用私钥签名
  3. 你的应用将交易发送到 Polymarket 的 relayer
  4. relayer 将交易提交到链上并支付 gas 费
  5. 交易从用户钱包执行
免 gas 交易需要 Builder Program 会员资格。你需要 Builder API 凭证来向 relayer 进行身份验证。

覆盖范围

Polymarket 为通过 relayer 路由的所有操作支付 gas:
操作说明
Wallet deployment为新用户部署 Safe 或 Proxy 钱包
Token approvals授权合约使用 USDC.e 或结果代币
CTF operations拆分、合并和兑换仓位
Transfers在地址之间转移代币

前置要求

使用 relayer 之前,你需要:
要求来源
Builder API 凭证Builder Profile
用户的私钥或签名器你的钱包集成
USDC.e 余额用于交易(不是用于 gas)

安装

npm install @polymarket/builder-relayer-client @polymarket/builder-signing-sdk

客户端设置

使用你的签名配置初始化 relayer 客户端:
当你的后端安全地处理所有交易时,使用本地签名。
import { createWalletClient, http, Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { polygon } from "viem/chains";
import { RelayClient } from "@polymarket/builder-relayer-client";
import { BuilderConfig } from "@polymarket/builder-signing-sdk";

const account = privateKeyToAccount(process.env.PRIVATE_KEY as Hex);
const wallet = createWalletClient({
  account,
  chain: polygon,
  transport: http(process.env.RPC_URL),
});

const builderConfig = new BuilderConfig({
  localBuilderCreds: {
    key: process.env.POLY_BUILDER_API_KEY!,
    secret: process.env.POLY_BUILDER_SECRET!,
    passphrase: process.env.POLY_BUILDER_PASSPHRASE!,
  },
});

const client = new RelayClient(
  "https://relayer-v2.polymarket.com/",
  137,
  wallet,
  builderConfig,
);
永远不要在客户端代码中暴露 Builder API 凭证。使用环境变量或密钥管理器。

Relayer 身份验证 Header

所有发送到 relayer 的请求必须包含这些身份验证 header:
Header说明
POLY_BUILDER_API_KEY你的 Builder API key
POLY_BUILDER_TIMESTAMPUnix 时间戳
POLY_BUILDER_PASSPHRASE你的 Builder passphrase
POLY_BUILDER_SIGNATUREHMAC-SHA256 签名
当你通过 BuilderConfig 提供凭证时,SDK 会自动处理 header 生成。

钱包类型

初始化客户端时选择钱包类型:
类型部署方式最适用于
Safe在首次交易前调用 deploy()大多数 builder 集成
Proxy首次交易时自动部署Magic Link 用户
import { RelayClient, RelayerTxType } from "@polymarket/builder-relayer-client";

const client = new RelayClient(
  "https://relayer-v2.polymarket.com/",
  137,
  wallet,
  builderConfig,
  RelayerTxType.SAFE,
);

// Deploy before first transaction
const response = await client.deploy();
const result = await response.wait();
console.log("Safe Address:", result?.proxyAddress);

执行交易

使用 execute 方法通过 relayer 发送交易:
interface Transaction {
  to: string; // Target contract address
  data: string; // Encoded function call
  value: string; // POL to send (usually "0")
}

const response = await client.execute(transactions, "Description");
const result = await response.wait();

代币授权

授权合约使用代币:
import { encodeFunctionData, maxUint256 } from "viem";

const USDC = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
const CTF = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045";

const approveTx = {
  to: USDC,
  data: encodeFunctionData({
    abi: [
      {
        name: "approve",
        type: "function",
        inputs: [
          { name: "spender", type: "address" },
          { name: "amount", type: "uint256" },
        ],
        outputs: [{ type: "bool" }],
      },
    ],
    functionName: "approve",
    args: [CTF, maxUint256],
  }),
  value: "0",
};

const response = await client.execute([approveTx], "Approve USDC.e for CTF");
await response.wait();

兑换仓位

市场判定后,将获胜代币兑换为 USDC.e:
import { encodeFunctionData } from "viem";

const redeemTx = {
  to: CTF_ADDRESS,
  data: encodeFunctionData({
    abi: [
      {
        name: "redeemPositions",
        type: "function",
        inputs: [
          { name: "collateralToken", type: "address" },
          { name: "parentCollectionId", type: "bytes32" },
          { name: "conditionId", type: "bytes32" },
          { name: "indexSets", type: "uint256[]" },
        ],
        outputs: [],
      },
    ],
    functionName: "redeemPositions",
    args: [collateralToken, parentCollectionId, conditionId, indexSets],
  }),
  value: "0",
};

const response = await client.execute([redeemTx], "Redeem positions");
await response.wait();

批量交易

在单次调用中原子性地执行多个操作:
const approveTx = {
  to: USDC,
  data: encodeFunctionData({
    abi: erc20Abi,
    functionName: "approve",
    args: [CTF, maxUint256],
  }),
  value: "0",
};

const transferTx = {
  to: USDC,
  data: encodeFunctionData({
    abi: erc20Abi,
    functionName: "transfer",
    args: [recipientAddress, parseUnits("50", 6)],
  }),
  value: "0",
};

// Both execute atomically
const response = await client.execute(
  [approveTx, transferTx],
  "Approve and transfer",
);
await response.wait();
批量处理可以减少延迟,并确保所有交易要么全部成功,要么全部失败。

交易状态

通过这些状态跟踪交易进度:
状态终态说明
STATE_NEWrelayer 已收到交易
STATE_EXECUTED已提交到链上
STATE_MINED已打包进区块
STATE_CONFIRMED成功确认
STATE_FAILED永久失败
STATE_INVALID被拒绝为无效

合约地址

所有 Polymarket 智能合约地址详见合约地址

资源

下一步