| name | orchestration |
| description | How an AI agent plans, builds, and deploys a complete Hyperliquid application. The three-phase build system for HyperEVM dApps and HyperCore integrations. Use when building any full application on Hyperliquid. |
dApp Orchestration on Hyperliquid
What You Probably Got Wrong
"I'll just deploy to mainnet immediately." Never skip testnet. HyperEVM testnet (chain ID 998) and HyperCore testnet API are available. Test there first. Mainnet mistakes cost real HYPE and USDC.
"I'll handle HyperCore and HyperEVM separately." Plan both layers from the start. If your app uses HyperEVM contracts AND HyperCore API, coordinate them from day one. Late integration always reveals architectural problems.
"Secrets in env are fine." AI agents are the #1 source of leaked credentials. Before committing anything, verify no private keys or API credentials are in the codebase.
The Three-Phase Build System
| Phase | Environment | What Happens |
|---|
| Phase 1 | Local + testnet | Contracts on testnet, HyperCore testnet API. Iterate fast. |
| Phase 2 | Mainnet contracts + local UI | Deploy to mainnet. Test with real state. Polish UI. |
| Phase 3 | Production | Deploy frontend. Final QA. Monitor. |
Phase 1: Build and Test Locally
1.1 HyperEVM Contracts
anvil --fork-url https://rpc.hyperliquid.xyz/evm --chain-id 999
Contract development flow:
- Write contracts in
src/ (Foundry) or contracts/ (Hardhat)
- Write deploy scripts
- Write tests (≥90% coverage of custom logic)
- Run security checklist (
security/SKILL.md)
- Deploy to testnet
forge create src/MyVault.sol:MyVault \
--rpc-url https://rpc.hyperliquid-testnet.xyz/evm \
--private-key $PRIVATE_KEY \
--broadcast
forge test -vvv
forge test --fuzz-runs 1000
1.2 HyperCore API Integration
Test against the testnet API, never mainnet:
HYPERLIQUID_API_URL=https://api.hyperliquid-testnet.xyz
PRIVATE_KEY=0x...
import os
from hyperliquid.info import Info
from hyperliquid.exchange import Exchange
from hyperliquid.utils import constants
from eth_account import Account
def get_clients():
wallet = Account.from_key(os.environ['PRIVATE_KEY'])
api_url = os.environ.get('HYPERLIQUID_API_URL', constants.MAINNET_API_URL)
return Info(api_url), Exchange(wallet, api_url)
const isTestnet = process.env.HYPERLIQUID_TESTNET === 'true';
const client = new HyperliquidClient({ testnet: isTestnet });
Validate Phase 1:
1.3 Frontend (Local)
const CHAIN_CONFIG = process.env.NODE_ENV === 'development'
? {
chainId: 998,
rpcUrl: 'https://rpc.hyperliquid-testnet.xyz/evm',
}
: {
chainId: 999,
rpcUrl: 'https://rpc.hyperliquid.xyz/evm',
};
Use ONE loading state per button. Each button has its own isLoading / isPending state. Never share.
Four-state flow (MANDATORY for token interactions):
- Not connected → Connect Wallet button
- Wrong network → Switch to HyperEVM button
- Needs approval → Approve button
- Ready → Action button
const needsApproval = !allowance || allowance < amount;
const wrongNetwork = chain?.id !== 999;
const notConnected = !address;
{notConnected ? (
<ConnectButton />
) : wrongNetwork ? (
<button onClick={() => switchChain({ id: 999 })} disabled={isSwitching}>
{isSwitching ? "Switching..." : "Switch to HyperEVM"}
</button>
) : needsApproval ? (
<button onClick={handleApprove} disabled={isApproving}>
{isApproving ? "Approving..." : "Approve"}
</button>
) : (
<button onClick={handleDeposit} disabled={isDepositing}>
{isDepositing ? "Depositing..." : "Deposit"}
</button>
)}
🚨 NEVER COMMIT SECRETS TO GIT
Before touching Phase 2 (real mainnet), read this carefully.
This applies to ALL credentials:
- Wallet private keys (HyperEVM + HyperCore signing key)
- Agent wallet private keys
- RPC URLs with embedded API keys
- Any API credentials
.env
.env.*
*.key
*.pem
secrets/
__pycache__/
Pre-commit check:
grep -rn "0x[a-fA-F0-9]\{64\}" src/ contracts/ --include="*.ts" --include="*.py" --include="*.sol"
grep -rn "alchemyapi.io\|infura.io" src/ contracts/
Phase 2: Deploy to Mainnet
HyperEVM Contract Deployment
forge create src/MyVault.sol:MyVault \
--rpc-url https://rpc.hyperliquid.xyz/evm \
--private-key $PRIVATE_KEY \
--broadcast \
--verify \
--verifier blockscout \
--verifier-url https://explorer.hyperliquid.xyz/api
export CONTRACT_ADDRESS=0x...
Post-deployment checklist:
HyperCore Integration: Switch to Mainnet
import os
API_URL = os.environ.get('HYPERLIQUID_API_URL',
'https://api.hyperliquid.xyz')
info = Info(API_URL)
meta = info.meta()
print(f"Connected to: {API_URL}")
print(f"Universe has {len(meta['universe'])} perp markets")
Start with tiny amounts. First real mainnet test: the smallest allowed order. Verify everything before scaling.
Frontend Update
const wagmiConfig = createConfig({
chains: [hyperliquid],
transports: {
[hyperliquid.id]: http(process.env.NEXT_PUBLIC_HL_RPC_URL || 'https://rpc.hyperliquid.xyz/evm'),
},
});
Design rule: Make the UI actually good. No placeholder styling, no LLM-default purple gradients.
Phase 3: Production Deploy
Pre-Deploy Checklist
Frontend Deployment
Vercel (recommended for Hyperliquid dApps):
cd packages/nextjs
vercel --prod
IPFS (decentralized alternative):
yarn build
Production QA
Before going live, fetch qa/SKILL.md and give it to a separate reviewer agent.
Key HyperEVM-specific QA items:
Monitoring Post-Launch
HyperEVM Contract Monitoring
const unwatch = publicClient.watchContractEvent({
address: contractAddress,
abi: vaultAbi,
eventName: 'Deposit',
onLogs: (logs) => {
for (const log of logs) {
console.log(`Deposit: ${log.args.amount} from ${log.args.user}`);
}
},
});
HyperCore Position Monitoring
import asyncio
import websockets
import json
async def monitor_fills(address):
async with websockets.connect('wss://api.hyperliquid.xyz/ws') as ws:
await ws.send(json.dumps({
"method": "subscribe",
"subscription": {"type": "userFills", "user": address}
}))
async for message in ws:
data = json.loads(message)
if data.get('channel') == 'userFills':
for fill in data['data']:
print(f"Fill: {fill['coin']} {fill['side']} {fill['sz']} @ {fill['px']}")
Key Directories for Foundry + Next.js Projects
my-project/
├── src/ # Solidity contracts
├── script/ # Deploy scripts
├── test/ # Foundry tests
├── lib/ # Dependencies (OpenZeppelin, etc.)
├── foundry.toml # Chain configs
├── frontend/
│ ├── app/ # Pages
│ ├── components/ # React components
│ ├── lib/
│ │ ├── chains.ts # HyperEVM chain definitions
│ │ ├── wagmi.ts # wagmi config
│ │ └── hypercore.ts # HyperCore API helpers
│ └── .env.local # NEVER COMMIT THIS
└── .gitignore # Includes .env*