---
title: Build a Hyperliquid Trading App with Builder Codes
description: >-
  Clone an MIT-licensed Next.js app that implements the full Hyperliquid builder
  code lifecycle. Walkthrough of agent wallets, EIP-712 signing, order
  placement, and Dwellir endpoint routing.
date: '2026-03-06'
tags: >-
  Hyperliquid, Builder Codes, Next.js, Web3 Development, Developer Tools, Open
  Source, Trading Infrastructure, DeFi
imageUrl: /posts/BuilderCodesDemo.webp
author: Elias Faltin
category: Hyperliquid
---

Builder codes have generated [$40M+ in revenue](https://www.dwellir.com/blog/hyperliquid-builder-codes) for Hyperliquid application developers. But most integration guides stop at isolated code snippets, leaving you to figure out the plumbing: wallet signing flows, session-scoped agent keys, deposit orchestration, and the chainId 1337 problem that breaks every major wallet provider.

We built an [open-source demo app](https://github.com/dwellir-public/hyperliquid-builder-codes-demo) that implements the complete builder code lifecycle in a single Next.js application. It is MIT-licensed, works on both testnet and mainnet, and covers every step from approval to order placement to revocation. Clone it, swap in your builder address, and start earning fees.

This post walks through the architecture, the implementation patterns that matter, and how to get it running.

## What the Demo Does

The app is a guided wizard that walks through 7 steps covering the full builder code lifecycle:

1. **Check approval status** - Read-only query to see if your wallet has approved the builder address
2. **Approve builder fee** - Sign an EIP-712 message authorizing a maximum fee rate
3. **Deposit USDC** - Transfer USDC from Arbitrum to Hyperliquid (skipped if you already have a balance)
4. **Activate agent** - Approve a temporary session key for order signing
5. **Place order** - Submit a market or limit order with the builder code attached
6. **Revoke approval** - Set the max fee to 0% to remove the builder's permission
7. **What's next** - Links to clone the repo, sign up at Dwellir, and explore docs

Each step includes live account balances, an L2 order book feed, candlestick charts, and human-readable transaction results. The wizard auto-skips completed steps on load, so returning users jump straight to where they left off.

![Builder Codes workflow wizard with sidebar account summary and the approve-builder step active.](https://www.dwellir.com/posts/builder-codes-demo-wizard-overview.webp)

Wizard overview shown in the screenshot:

- Left sidebar contains:
- account overview with USDC balance and account equity
- a builder approval status badge
- resource cards linking to the repo, Dwellir endpoints, CLI and skill, and documentation
- Top stepper shows the seven-step builder code flow from approval checks through order placement and revocation
- Main panel is currently on **Approve Builder Fee**
- The approve screen explains that the EIP-712 message must be signed by the main wallet and shows the approved fee state plus a continue button

The sidebar provides quick access to account balances, resource links, and builder fee status. The Dwellir L2 orderbook feed shows live bid/ask data directly in the interface:

![Compact Dwellir L2 orderbook widget with live bid, ask, mid price, and slippage estimate.](https://www.dwellir.com/posts/builder-codes-demo-orderbook.webp)

Orderbook widget contents:

| Field                      | Value shown                        |
| -------------------------- | ---------------------------------- |
| Status                     | LIVE                               |
| Bid                        | 2021.50                            |
| Ask                        | 2021.60                            |
| Mid                        | $2021.55                           |
| Indicative fill / slippage | IOC about $2082.2 with 3% slippage |

The screenshot shows the widget as a narrow strip embedded directly in the trading UI rather than a full separate orderbook page.

## Architecture: Solving the ChainId 1337 Problem

The trickiest part of building on Hyperliquid is not the builder code itself. It is getting wallet signatures to work.

Hyperliquid L1 actions (orders, cancels) use EIP-712 typed-data signatures with a domain `chainId` of **1337**. This does not match any real chain. MetaMask, WalletConnect, and other wallet providers reject the signature because the domain chain ID does not match the active network.

The official Hyperliquid app solves this with **agent keys**, and the demo uses the same approach:

1. The app generates a random private key in the browser using viem's `generatePrivateKey()`
2. The key is stored in `sessionStorage` (cleared when you close the tab)
3. You sign an `approveAgent` transaction via your wallet. This uses chainId 42161 (Arbitrum), which your wallet accepts
4. All subsequent orders are signed locally in JavaScript with the agent key. No wallet popup, no chain-ID validation problem

The agent key is scoped to your wallet address, authorized only for trading actions (it cannot withdraw funds), and lives only for the duration of your browser session.

This pattern separates two concerns: **authorization** (your real wallet, on a real chain) and **execution** (an ephemeral key, signing L1 actions locally). The demo implements both sides.

## Key Implementation Patterns

The following patterns come directly from the [demo repository](https://github.com/dwellir-public/hyperliquid-builder-codes-demo). Each one solves a specific integration challenge.

### Builder Fee Approval

Users must approve your builder fee before you can charge it. This is a one-time EIP-712 signature on Arbitrum:

```typescript
// src/components/ApproveBuilder.tsx
await walletClient.approveBuilderFee({
  builder: DWELLIR_BUILDER_ADDRESS,
  maxFeeRate: '0.0100%', // 1 basis point
});
```

The fee parameter uses a percentage string format. In the demo's constants, a helper converts the raw integer (tenths of basis points) to the SDK's expected format:

```typescript
// src/config/constants.ts
export const DEFAULT_BUILDER_FEE = 10; // 10 tenths-of-a-bps = 1 bps = 0.01%

export function feeToPercent(fee: number): string {
  return `${(fee / 100).toFixed(4)}%`;
}
```

The app polls the approval status using `maxBuilderFee()` via React Query, so the UI updates automatically once the transaction confirms:

```typescript
// src/hooks/useBuilderApproval.ts
const { data: maxFee } = useQuery({
  queryKey: ['maxBuilderFee', network, address, builder],
  queryFn: () => queryMaxBuilderFee(network, address, builder),
  refetchInterval: network === 'mainnet' ? 5_000 : 10_000,
});
```

### Agent Wallet Session Management

The agent wallet hook generates, stores, and manages ephemeral keys:

```typescript
// src/hooks/useAgentWallet.tsx
const approveAgent = async () => {
  const pk = generatePrivateKey();
  const account = privateKeyToAccount(pk);

  // Register with Hyperliquid via your real wallet (chainId 42161)
  await userWalletClient.approveAgent({
    agentAddress: account.address,
    agentName: 'DwellirBuilder',
  });

  // Store in sessionStorage for the tab's lifetime
  sessionStorage.setItem(`hl-agent-key-${userAddress}`, pk);
};
```

The key is shared across the app via React Context. Any component that needs to place or cancel orders consumes the agent wallet client, which signs L1 actions (chainId 1337) entirely in memory without touching the user's wallet.

![Activate Trading Session step asking the user to authorize a temporary signing key.](https://www.dwellir.com/posts/builder-codes-demo-agent-wallet-activation.webp)

Agent activation screen:

- Stepper is on **Step 3: Activate Agent**
- Main heading is **Activate Trading Session**
- The UI explains that a temporary signing key will place orders locally to avoid the wallet's chain-ID restriction on Hyperliquid L1 actions
- A generated agent address is displayed in the panel
- Primary button is in a waiting state: **Waiting for signature...**

This screenshot communicates that the app pauses for one wallet authorization before switching future order signing to a temporary session key.

### Order Placement with Builder Code

With the agent wallet active, placing an order with builder code attribution is a single call:

```typescript
// src/components/PlaceOrderStep.tsx
await agentWalletClient.order({
  orders: [{
    coin: selectedAsset,
    isBuy: side === 'buy',
    sz: size,
    limitPx: price,
    orderType: { limit: { tif: 'Gtc' } },
    reduceOnly: false,
  }],
  builder: {
    b: DWELLIR_BUILDER_ADDRESS,
    f: DEFAULT_BUILDER_FEE,
  },
});
```

The `builder` field is the entire integration point. The `b` parameter is your builder address, and `f` is the fee in tenths of basis points. The protocol enforces the caps: 10 bps max for perpetuals, 100 bps max for spot.

![Place Order screen with market, limit, and close tabs, a candlestick chart, amount fields, and a live orderbook strip.](https://www.dwellir.com/posts/builder-codes-demo-order-form.webp)

Order entry screen layout:

- Main panel is **Place Order**
- Tabs at the top switch between **Market**, **Limit**, and **Close**
- Large candlestick chart dominates the upper half of the panel
- Below the chart are amount and conversion fields for paying in USDC and receiving ETH
- A compact Dwellir L2 orderbook strip sits beneath the form
- Primary action button is **Place Market Long**

The screenshot shows the builder-code flow as a real trading interface rather than a minimal form.

After execution, the app shows the open position with entry price, PnL, and a close button:

![Close-position view showing an open ETH long with size, entry price, PnL, and a close button.](https://www.dwellir.com/posts/builder-codes-demo-order-confirmation.webp)

Open-position confirmation screen:

- The wizard remains on the **Place Order** step, but the **Close** tab is selected
- Sidebar account card now shows an open ETH position alongside balances
- Main table lists one open position:
- coin: ETH
- side: Long
- size: 0.005
- entry: about $2,021.60
- PnL: near flat at the captured moment
- Each row includes a **Close** action button

The point of the screenshot is to show the flow after execution: the app does not stop at submission, it surfaces the live position and close controls immediately.

### Dwellir Endpoint Routing

The demo optionally routes requests through Dwellir's optimized infrastructure when an API key is present:

```typescript
// src/config/constants.ts
const DWELLIR_API_KEY = process.env.NEXT_PUBLIC_DWELLIR_API_KEY;

const mainnetConfig = {
  infoUrl: DWELLIR_API_KEY
    ? `https://api-hyperliquid-mainnet-info.n.dwellir.com/${DWELLIR_API_KEY}/info`
    : 'https://api.hyperliquid.xyz/info',
  wsUrl: DWELLIR_API_KEY
    ? `wss://api-hyperliquid-mainnet-orderbook.n.dwellir.com/${DWELLIR_API_KEY}/ws`
    : 'wss://api.hyperliquid.xyz/ws',
};
```

This pattern lets the app work out of the box with public endpoints while giving production deployments access to higher rate limits, deeper order book data, and lower latency through Dwellir's managed infrastructure. No code changes required, just set an environment variable.

## Running It Yourself

### Prerequisites

- Node.js 18+
- A browser wallet (MetaMask recommended)
- A [WalletConnect](https://dashboard.reown.com) project ID (free)

### Quick Start

```bash
git clone https://github.com/dwellir-public/hyperliquid-builder-codes-demo.git
cd hyperliquid-builder-codes-demo
npm install
cp .env.local.example .env.local
```

Edit `.env.local` with your WalletConnect project ID:

```
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_project_id_here
```

Then start the dev server:

```bash
npm run dev
```

Open `http://localhost:3000`. The app defaults to **mainnet**. To experiment on testnet without risking real funds, change the default network in `src/components/Providers.tsx`:

```typescript
const [network, setNetwork] = useState<NetworkKey>("testnet"); // change "mainnet" → "testnet"
```

The codebase has full testnet support (endpoints, contract addresses, wallet chain switching), so everything works the same way — just against Hyperliquid's testnet environment.

### Customizing for Your Builder Address

Swap in your own builder address and fee rate in `src/config/constants.ts`:

```typescript
export const DWELLIR_BUILDER_ADDRESS = '0xYOUR_BUILDER_ADDRESS';
export const DEFAULT_BUILDER_FEE = 10; // Adjust fee rate (tenths of bps)
```

For production, add a Dwellir API key to route through managed infrastructure:

```
NEXT_PUBLIC_DWELLIR_API_KEY=your_dwellir_api_key
```

## Agent Tooling for Faster Development

If you use AI coding agents, two Dwellir tools make building on Hyperliquid significantly faster.

The [Hyperliquid agent skill](https://github.com/dwellir-public/hyperliquid-skills) gives agents like Claude Code, Cursor, and Windsurf procedural knowledge about Hyperliquid's API surface, including HyperEVM JSON-RPC, Info API queries, gRPC streaming, and order book WebSocket feeds. Install it with:

```bash
npx skills add dwellir-public/hyperliquid-skills
```

In our [benchmarks](https://www.dwellir.com/blog/hyperliquid-skill-benchmark), agents with the skill shipped Hyperliquid trading dashboards 70% faster at 57% lower cost compared to agents working without it.

The [Dwellir CLI](https://www.dwellir.com/blog/introducing-dwellir-agent-toolkit) gives agents and developers terminal access to endpoint discovery, API key management, and usage monitoring. An agent can provision Hyperliquid endpoints, create API keys, and check error logs without leaving the terminal.

Both tools pair well with this demo as a starting point. Point an agent at the cloned repo with the skill installed, and it has both the working reference implementation and the infrastructure knowledge to extend it.

## Start Building

The [builder codes demo](https://github.com/dwellir-public/hyperliquid-builder-codes-demo) is MIT-licensed and designed as a starting point. Fork it, swap in your builder address, and build the trading interface your users need. Whether that is a copy trading platform, a mobile-first frontend, or an automated strategy with builder fees attached, the core integration patterns are the same.

For production infrastructure with higher rate limits and deeper order book data, [sign up at the Dwellir dashboard](https://dashboard.dwellir.com/register). For dedicated node clusters, [contact us](https://www.dwellir.com/contact). Our Hyperliquid docs cover the full stack, including the [order book WebSocket used here](https://www.dwellir.com/docs/hyperliquid/websocket-api), [gRPC streaming](https://www.dwellir.com/docs/hyperliquid/grpc), [custom JSON-RPC](https://www.dwellir.com/docs/hyperliquid), [Hyperliquid / HyperEVM](https://www.dwellir.com/docs/hyperliquid), and [processed tick data](https://www.dwellir.com/docs/hyperliquid/tick-data).

---

*This demo is for educational purposes. It is a reference implementation, not a production trading interface. Building financial applications involves regulatory considerations that vary by jurisdiction. Use at your own risk.*
