Hyperliquid Perps

Perps Demo

Explore RHEA cross-chain Perps via @rhea-finance/zcash-wallet-adapter/perps with MCA signing and local agent keys — no MetaMask required.

Connect Noir Wallet to resolve MCA identity and master address. Market read-only APIs work without a wallet.

Multi-chain Account & Agent

MCA authorization via client.authorization.connect() — resolves master from chainsig, restores/creates agent, approves once through MCA. No MetaMask required.

Usage example
import { PerpsClient } from '@rhea-finance/zcash-wallet-adapter/perps';

const client = new PerpsClient({ network: 'mainnet' });

try {
  const markets = await client.markets.list({ includeDexes: [] });
  const btc = await client.markets.resolve('BTC');
  console.log(markets.length, btc.coin, btc.context.markPx);
} finally {
  client.destroy();
}
Usage example
import { getNoirWallet } from '@noir-wallet/sdk';

const status = await getNoirWallet()?.zcash.checkLendingMcaAccount();
const identityKey =
  status?.publicKey ?? (await lending.getIdentityKey());

const sdk = await lending.loadSdk();
const mcaId =
  (await sdk.getMcaByWallet({ chain: 'zcash', identityKey })) ??
  status?.mcaId ??
  null;
Usage example
import { PerpsClient } from '@rhea-finance/zcash-wallet-adapter/perps';

const client = new PerpsClient({
  network: 'mainnet',
  mca: {
    mcaId,
    signerWallet: { chain: 'zcash', identityKey },
    nearRpcUrls: [process.env.NEXT_PUBLIC_NEAR_RPC_URL!],
    agentStore: protectedAgentStorage,

    resolveMasterAddress: ({ mcaId, derivationPath }) =>
      deriveMcaMappedEvmAddress(mcaId, derivationPath),

    signTypedData: (request) =>
      signHyperliquidAccountTypedData({
        mode: 'mca',
        mca: request.mcaId,
        signerWallet: request.signerWallet,
        typedData: request.typedData,
        onWalletSigned: request.onWalletSigned,
        onSignatureRequestSubmitted: request.onSignatureRequestSubmitted,
      }).then((result) => result.signatureParts),
  },
});

try {
  const session = await client.authorization.connect({
    onWalletSigned: () => console.log('wallet signed'),
    onSignatureRequestSubmitted: () => console.log('submitted to relayer'),
  });

  console.log(session.masterAddress, session.agent.address);
  await client.trading.placeMarketOrder({
    coin: 'BTC',
    side: 'buy',
    size: '0.001',
    slippageBps: 100,
  });
} finally {
  client.destroy();
}
Network
mainnet
Shielded
MCA Identity Key
MCA ID

Not connected — Get MCA, resolve master, then Connect Authorization

WebSocket Stream

Subscribe to mids feed. Unsubscribe on toggle off or page leave.

Usage example
const off = client.stream.subscribeMids((msg) => {
  console.log(msg.data.BTC);
});
// off() on cleanup; client.destroy() on unmount
Advanced — optional EVM-only mode

Not the default multi-chain path. SDK documents this for standalone EVM apps only.

Usage example
// Optional EVM-only mode — NOT the default MCA flow
import { PerpsClient } from '@rhea-finance/zcash-wallet-adapter/perps';
import { Wallet } from 'ethers';

const masterWallet = new Wallet(process.env.HL_MASTER_PRIVATE_KEY!);
const client = new PerpsClient({
  network: 'mainnet',
  userAddress: masterWallet.address,
  typedDataSigner: masterWallet,
  signer: masterWallet,
});

Markets

getRegistry

Usage example
const registry = await client.markets.getRegistry();
console.log(registry.byCoin['BTC']);

list

Usage example
// [] = main dex only; omit includeDexes for all HIP-3 dexes
const markets = await client.markets.list({ includeDexes: [] });

resolve

Usage example
const market = await client.markets.resolve('BTC');
console.log(market.assetId, market.context.markPx);

getOrderBook

Usage example
const book = await client.markets.getOrderBook('BTC');

getCandles

Usage example
const candles = await client.markets.getCandles(
  'BTC',
  '1h',
  Date.now() - 24 * 60 * 60 * 1000,
  Date.now(),
);

getFundingHistory

Usage example
const funding = await client.markets.getFundingHistory(
  'BTC',
  Date.now() - 7 * 24 * 60 * 60 * 1000,
);

Account

getSnapshot

Requires master address

Usage example
const snapshot = await client.account.getSnapshot(masterAddress);

getDetails

Requires master address

Usage example
const details = await client.account.getDetails(masterAddress);

getOpenOrders

Requires master address

Usage example
const orders = await client.account.getOpenOrders(masterAddress);

getFills

Requires master address

Usage example
const fills = await client.account.getFills(masterAddress);

getFees

Requires master address

Usage example
const fees = await client.account.getFees(masterAddress);

getActiveAssetData

Requires master address

Usage example
const data = await client.account.getActiveAssetData(masterAddress, 'BTC');

getPortfolio

Requires master address

Usage example
const portfolio = await client.account.getPortfolio(masterAddress);

Agents

isApproved

Requires master address

Usage example
const ok = await client.agents.isApproved(agentAddress, masterAddress);

Trading

prepareTrading

Requires master address

Requires approved agent

Usage example
await client.trading.prepareTrading('BTC');

placeMarketOrder

Requires master address

Requires approved agent

Usage example
await client.trading.placeMarketOrder({
  coin: 'BTC',
  side: 'buy',
  size: '0.001',
  slippageBps: 100,
});

placeOrder

Requires master address

Requires approved agent

Usage example
await client.trading.placeOrder({
  coin: 'BTC',
  side: 'buy',
  price: '62000',
  size: '0.001',
});

closePosition

Requires master address

Requires approved agent

Usage example
await client.trading.closePosition({
  coin: 'BTC',
  size: '0.001',
  isLong: true,
  slippageBps: 200,
});

cancelOrder

Requires master address

Requires approved agent

Usage example
await client.trading.cancelOrder('BTC', orderId);

cancelAll

Requires master address

Requires approved agent

Usage example
const orders = await client.account.getOpenOrders(masterAddress);
await client.trading.cancelAll('BTC', orders);

updateLeverage

Requires master address

Requires approved agent

Usage example
await client.trading.updateLeverage('BTC', 10, 'cross');

adjustIsolatedMargin

Requires master address

Requires approved agent

Usage example
await client.trading.adjustIsolatedMargin('BTC', 100, true);

setAccountAbstraction

Requires master address

Requires approved agent

Usage example
await client.trading.setAccountAbstraction('unifiedAccount');

Funding

withdrawDirect

Requires master address

Usage example
await client.funding.withdrawDirect({
  amount: '25',
  destinationAddress: '0x...',
  signer: masterTypedDataSigner,
});

Lending Top-up

Borrow USDC from the Lending MCA and top up the Hyperliquid master account. The authorizer reuses the connected Noir wallet — no second wallet UI. Full execute() + authorize() wiring is in the setup snippet below.

Setup (execute + authorizer)
import type { LendingTopUpAuthorizer } from '@rhea-finance/zcash-wallet-adapter/perps';

const client = new PerpsClient({
  network: 'mainnet',
  userAddress: masterAddress,
  lendingTopUp: {
    baseUrl: `${indexerBaseUrl}/api/v1/perps/hyperliquid`,
    authorizer,
    pendingStore,
  },
});

const job = await client.lendingTopUp!.execute({
  accountMode: 'mca',
  mcaId,
  hyperliquidUserAddress: masterAddress,
  targetAddress: masterAddress,
  tokenId: 'usdc.token.near',
  amountBorrowRaw: '10000000',
  amountTokenRaw: '10000000',
  symbol: 'USDC',
  quote: { depositAddress, amountIn, amountOut, minAmountOut },
  onUpdate: (job) => console.log(job.status, job.progress),
});

getHistory

Requires master address

Usage example
const history = await client.lendingTopUp!.getHistory({
  hyperliquidUserAddress: masterAddress,
  page: 1,
  pageSize: 20,
});

getJob

Usage example
const job = await client.lendingTopUp!.getJob(jobId);

resumePendingJobs

Usage example
const results = await client.lendingTopUp!.resumePendingJobs();

Raw API

api.getPerpDexs

api.getLegalCheck

Requires master address

api.getReferralInfo

Requires master address

api.getExchangeStatus