JSPM

@polymarket/builder-relayer-client

0.0.9
    • ESM via JSPM
    • ES Module Entrypoint
    • Export Map
    • Keywords
    • License
    • Repository URL
    • TypeScript Types
    • README
    • Created
    • Published
    • Downloads 23969
    • Score
      100M100P100Q159726F

    Client for Polymarket relayers

    Package Exports

    • @polymarket/builder-relayer-client
    • @polymarket/builder-relayer-client/dist/builder/derive
    • @polymarket/builder-relayer-client/dist/builder/derive.js
    • @polymarket/builder-relayer-client/dist/config
    • @polymarket/builder-relayer-client/dist/config/index.js
    • @polymarket/builder-relayer-client/dist/index.js

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@polymarket/builder-relayer-client) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    builder-relayer-client

    TypeScript client library for interacting with Polymarket relayer infrastructure

    Installation

    pnpm install @polymarket/builder-relayer-client

    Quick Start

    Basic Setup

    import { createWalletClient, Hex, http } from "viem";
    import { privateKeyToAccount } from "viem/accounts";
    import { polygon } from "viem/chains";
    import { RelayClient, RelayerTxType } from "@polymarket/builder-relayer-client";
    
    const relayerUrl = process.env.POLYMARKET_RELAYER_URL;
    const chainId = parseInt(process.env.CHAIN_ID);
    
    const account = privateKeyToAccount(process.env.PRIVATE_KEY as Hex);
    const wallet = createWalletClient({
      account,
      chain: polygon,
      transport: http(process.env.RPC_URL)
    });
    
    // Initialize the client with SAFE transaction type (default)
    const client = new RelayClient(relayerUrl, chainId, wallet);
    
    // Or initialize with PROXY transaction type
    const proxyClient = new RelayClient(relayerUrl, chainId, wallet, undefined, RelayerTxType.PROXY);

    Transaction Types

    The client supports two transaction types via the RelayerTxType enum:

    • RelayerTxType.SAFE (default): Executes transactions through a Gnosis Safe
    • RelayerTxType.PROXY: Executes transactions for a Polymarket Proxy wallet

    The transaction type is specified as the last parameter when creating a RelayClient instance. All examples use the Transaction type - the client automatically converts transactions to the appropriate format (SafeTransaction or ProxyTransaction) based on the RelayerTxType you've configured.

    The client also supports Deposit Wallets, which use separate dedicated methods rather than the execute() flow. See Deposit Wallet below.

    With Local Builder Authentication

    import { BuilderApiKeyCreds, BuilderConfig } from "@polymarket/builder-signing-sdk";
    import { RelayerTxType } from "@polymarket/builder-relayer-client";
    
    const builderCreds: BuilderApiKeyCreds = {
      key: process.env.BUILDER_API_KEY,
      secret: process.env.BUILDER_SECRET,
      passphrase: process.env.BUILDER_PASS_PHRASE,
    };
    
    const builderConfig = new BuilderConfig({
      localBuilderCreds: builderCreds
    });
    
    // Initialize with SAFE transaction type (default)
    const client = new RelayClient(relayerUrl, chainId, wallet, builderConfig);
    
    // Or initialize with PROXY transaction type
    const proxyClient = new RelayClient(relayerUrl, chainId, wallet, builderConfig, RelayerTxType.PROXY);

    With Remote Builder Authentication

    import { BuilderConfig } from "@polymarket/builder-signing-sdk";
    import { RelayerTxType } from "@polymarket/builder-relayer-client";
    
    const builderConfig = new BuilderConfig(
      {
        remoteBuilderConfig: {
          url: "http://localhost:3000/sign",
          token: `${process.env.MY_AUTH_TOKEN}`
        }
      },
    );
    
    // Initialize with SAFE transaction type (default)
    const client = new RelayClient(relayerUrl, chainId, wallet, builderConfig);
    
    // Or initialize with PROXY transaction type
    const proxyClient = new RelayClient(relayerUrl, chainId, wallet, builderConfig, RelayerTxType.PROXY);

    Examples

    Execute ERC20 Approval Transaction

    import { encodeFunctionData, prepareEncodeFunctionData, maxUint256 } from "viem";
    import { Transaction, RelayerTxType } from "@polymarket/builder-relayer-client";
    
    const erc20Abi = [
      {
        "constant": false,
        "inputs": [
          {"name": "_spender", "type": "address"},
          {"name": "_value", "type": "uint256"}
        ],
        "name": "approve",
        "outputs": [{"name": "", "type": "bool"}],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
      }
    ];
    
    const erc20 = prepareEncodeFunctionData({
      abi: erc20Abi,
      functionName: "approve",
    });
    
    function createApprovalTransaction(
      tokenAddress: string,
      spenderAddress: string
    ): Transaction {
      const calldata = encodeFunctionData({
        ...erc20,
        args: [spenderAddress, maxUint256]
      });
      return {
        to: tokenAddress,
        data: calldata,
        value: "0"
      };
    }
    
    // Initialize client with SAFE transaction type (default)
    const safeClient = new RelayClient(relayerUrl, chainId, wallet, builderConfig);
    
    // Or initialize with PROXY transaction type
    const proxyClient = new RelayClient(relayerUrl, chainId, wallet, builderConfig, RelayerTxType.PROXY);
    
    // Execute the approval - works with both SAFE and PROXY
    const approvalTx = createApprovalTransaction(
      "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", // USDC
      "0x4d97dcd97ec945f40cf65f87097ace5ea0476045"  // CTF
    );
    
    // Using SAFE client
    const safeResponse = await safeClient.execute([approvalTx], "usdc approval on the CTF");
    const safeResult = await safeResponse.wait();
    console.log("Safe approval completed:", safeResult.transactionHash);
    
    // Using PROXY client
    const proxyResponse = await proxyClient.execute([approvalTx], "usdc approval on the CTF");
    const proxyResult = await proxyResponse.wait();
    console.log("Proxy approval completed:", proxyResult.transactionHash);

    Deploy Safe Contract

    Note: Safe deployment is only available for RelayerTxType.SAFE. Proxy wallets are deployed automatically on its first transaction.

    // Initialize client with SAFE transaction type (default)
    const client = new RelayClient(relayerUrl, chainId, wallet, builderConfig);
    
    const response = await client.deploy();
    const result = await response.wait();
    
    if (result) {
      console.log("Safe deployed successfully!");
      console.log("Transaction Hash:", result.transactionHash);
      console.log("Safe Address:", result.proxyAddress);
    } else {
      console.log("Safe deployment failed");
    }

    Redeem Positions

    CTF (ConditionalTokensFramework) Redeem

    import { encodeFunctionData, prepareEncodeFunctionData, zeroHash } from "viem";
    import { Transaction, RelayerTxType } from "@polymarket/builder-relayer-client";
    
    const ctfRedeemAbi = [
      {
        "constant": false,
        "inputs": [
          {"name": "collateralToken", "type": "address"},
          {"name": "parentCollectionId", "type": "bytes32"},
          {"name": "conditionId", "type": "bytes32"},
          {"name": "indexSets", "type": "uint256[]"}
        ],
        "name": "redeemPositions",
        "outputs": [],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
      }
    ];
    
    const ctf = prepareEncodeFunctionData({
      abi: ctfRedeemAbi,
      functionName: "redeemPositions",
    });
    
    function createCtfRedeemTransaction(
      ctfAddress: string,
      collateralToken: string,
      conditionId: string
    ): Transaction {
      const calldata = encodeFunctionData({
        ...ctf,
        args: [collateralToken, zeroHash, conditionId, [1, 2]]
      });
      return {
        to: ctfAddress,
        data: calldata,
        value: "0"
      };
    }
    
    // Initialize client with SAFE transaction type (default)
    const safeClient = new RelayClient(relayerUrl, chainId, wallet, builderConfig);
    
    // Or initialize with PROXY transaction type
    const proxyClient = new RelayClient(relayerUrl, chainId, wallet, builderConfig, RelayerTxType.PROXY);
    
    // Execute the redeem - works with both SAFE and PROXY
    const ctfAddress = "0x4d97dcd97ec945f40cf65f87097ace5ea0476045";
    const usdcAddress = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
    const conditionId = "0x..."; // Your condition ID
    
    const redeemTx = createCtfRedeemTransaction(ctfAddress, usdcAddress, conditionId);
    
    // Using SAFE client
    const safeResponse = await safeClient.execute([redeemTx], "redeem positions");
    const safeResult = await safeResponse.wait();
    console.log("Safe redeem completed:", safeResult.transactionHash);
    
    // Using PROXY client
    const proxyResponse = await proxyClient.execute([redeemTx], "redeem positions");
    const proxyResult = await proxyResponse.wait();
    console.log("Proxy redeem completed:", proxyResult.transactionHash);

    NegRisk Adapter Redeem

    import { encodeFunctionData, prepareEncodeFunctionData } from "viem";
    import { Transaction, RelayerTxType } from "@polymarket/builder-relayer-client";
    
    const nrAdapterRedeemAbi = [
      {
        "inputs": [
          {"internalType": "bytes32", "name": "_conditionId", "type": "bytes32"},
          {"internalType": "uint256[]", "name": "_amounts", "type": "uint256[]"}
        ],
        "name": "redeemPositions",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
      }
    ];
    
    const nrAdapter = prepareEncodeFunctionData({
      abi: nrAdapterRedeemAbi,
      functionName: "redeemPositions",
    });
    
    function createNrAdapterRedeemTransaction(
      adapterAddress: string,
      conditionId: string,
      redeemAmounts: bigint[] // [yesAmount, noAmount]
    ): Transaction {
      const calldata = encodeFunctionData({
        ...nrAdapter,
        args: [conditionId, redeemAmounts]
      });
      return {
        to: adapterAddress,
        data: calldata,
        value: "0"
      };
    }
    
    // Initialize client with SAFE transaction type (default)
    const safeClient = new RelayClient(relayerUrl, chainId, wallet, builderConfig);
    
    // Or initialize with PROXY transaction type
    const proxyClient = new RelayClient(relayerUrl, chainId, wallet, builderConfig, RelayerTxType.PROXY);
    
    // Execute the redeem - works with both SAFE and PROXY
    const negRiskAdapter = "0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296";
    const conditionId = "0x..."; // Your condition ID
    const redeemAmounts = [BigInt(111000000), BigInt(0)]; // [yes tokens, no tokens]
    
    const redeemTx = createNrAdapterRedeemTransaction(negRiskAdapter, conditionId, redeemAmounts);
    
    // Using SAFE client
    const safeResponse = await safeClient.execute([redeemTx], "redeem positions");
    const safeResult = await safeResponse.wait();
    console.log("Safe redeem completed:", safeResult.transactionHash);
    
    // Using PROXY client
    const proxyResponse = await proxyClient.execute([redeemTx], "redeem positions");
    const proxyResult = await proxyResponse.wait();
    console.log("Proxy redeem completed:", proxyResult.transactionHash);

    Deposit Wallet

    Deposit Wallets are UUPS-upgradeable smart contract wallets that support EIP-712 signed batch execution. Unlike Safe and Proxy wallets which use the execute() method, Deposit Wallets have dedicated methods.

    Derive Deposit Wallet Address

    You can predict the deposit wallet address before deployment using CREATE2:

    const client = new RelayClient(relayerUrl, chainId, wallet, builderConfig);
    
    const walletAddress = await client.deriveDepositWalletAddress();
    console.log("Expected deposit wallet address:", walletAddress);

    Or use the standalone function directly:

    import { deriveDepositWallet } from "@polymarket/builder-relayer-client";
    
    const walletAddress = deriveDepositWallet(ownerAddress, factoryAddress, implementationAddress);

    Deploy Deposit Wallet

    const client = new RelayClient(relayerUrl, chainId, wallet, builderConfig);
    
    const response = await client.deployDepositWallet();
    const result = await response.wait();
    
    if (result) {
      console.log("Deposit wallet deployed successfully!");
      console.log("Transaction Hash:", result.transactionHash);
    } else {
      console.log("Deposit wallet deployment failed");
    }

    Execute Deposit Wallet Batch

    Deposit wallet transactions use DepositWalletCall instead of Transaction. Each call has a target (instead of to), value, and data field. Batches require a walletAddress and a deadline (unix timestamp for signature expiry).

    import { encodeFunctionData, prepareEncodeFunctionData, maxUint256 } from "viem";
    import { DepositWalletCall } from "@polymarket/builder-relayer-client";
    
    const erc20Abi = [
      {
        "constant": false,
        "inputs": [
          {"name": "_spender", "type": "address"},
          {"name": "_value", "type": "uint256"}
        ],
        "name": "approve",
        "outputs": [{"name": "", "type": "bool"}],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
      }
    ];
    
    const erc20 = prepareEncodeFunctionData({
      abi: erc20Abi,
      functionName: "approve",
    });
    
    function createApproveCall(
      tokenAddress: string,
      spenderAddress: string
    ): DepositWalletCall {
      const calldata = encodeFunctionData({
        ...erc20,
        args: [spenderAddress, maxUint256]
      });
      return {
        target: tokenAddress,
        value: "0",
        data: calldata,
      };
    }
    
    const client = new RelayClient(relayerUrl, chainId, wallet, builderConfig);
    
    const walletAddress = await client.deriveDepositWalletAddress();
    
    const approveCall = createApproveCall(
      "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", // USDC
      "0x4d97dcd97ec945f40cf65f87097ace5ea0476045"  // CTF
    );
    
    // Deadline: 4 minutes from now
    const deadline = Math.floor(Date.now() / 1000 + 240).toString();
    
    const response = await client.executeDepositWalletBatch([approveCall], walletAddress, deadline);
    const result = await response.wait();
    console.log("Deposit wallet batch executed:", result.transactionHash);

    Check Deposit Wallet Deployment

    const walletAddress = await client.deriveDepositWalletAddress();
    const isDeployed = await client.getDeployed(walletAddress, "WALLET");
    console.log("Deposit wallet deployed:", isDeployed);