Please note:
- shodown is called “Project X” below :-)
- we can have a single trading wallet per user (in order to reduce friction)
Master Account
-
A trader’s main Hyperliquid account (holds the funds).
-
Has an EVM-style address and a private key (wallet).
-
Can:
- Hold collateral
- Trade
- Create & fund subaccounts
- Approve API / trading wallets
Subaccounts (per competition)
- Separate “buckets” under a master account.
- Each has its own address and PnL / positions.
- No private key: subaccounts are controlled by signatures from the master (or its API wallets).
- To trade on a subaccount, you send a signed action with a
vaultAddress = subaccountAddress.
Trading Wallet / API Wallet
-
A separate keypair the trader creates on Hyperliquid.
-
Has no withdraw rights, only trading rights for the master + its subaccounts.
-
In Project X:
- One API wallet per competition.
- The private key is imported into the Project X web client (browser) and stored encrypted locally.
- All orders are signed client-side with this key and then relayed to Hyperliquid by our backend.
- Our backend enforces that this wallet only trades the registered competition subaccount.
-
On Hyperliquid (outside Project X)
- Trader has a funded master account.
- Trader creates a subaccount (e.g. “Project X – Season 1”).
- Trader transfers in the exact starting balance required by the competition (e.g. 1,000 USDC).
-
Optional: create trading wallet for the competition
In order to reduce friction the same trading wallet could be used across multiple competitions
- Trader goes to Hyperliquid’s API / Agent wallet page.
- Creates a new API wallet dedicated to this competition.
- Copies the trading wallet private key (shown once).
-
Link everything in Project X
-
Trader logs into Project X and:
-
Links master account
- Signs a simple message to prove ownership of their HL master address.
-
Selects competition subaccount
- Project X fetches the trader’s subaccounts, trader picks one for this competition.
- Project X verifies that its equity matches the required starting balance and stores it as
startEquity.
-
Imports trading wallet
-
In the Project X web client, trader pastes the API wallet private key.
-
The client:
- Derives the public address (sanity check).
- Encrypts the private key with a passphrase and stores it locally (e.g. IndexedDB).
-
The private key is never sent to the Project X backend.
-
-
-
Result: For this competition we now have:
masterAddresssubAccountAddresstradingWalletAddress(API wallet, private key known only to the browser)startEquity
-
Trader opens the Project X trading page for the competition:
- TradingView-based chart showing data from the competition subaccount.
- Order ticket (side, size, leverage, type, etc.).
-
On page load:
- The Project X web client detects an encrypted trading key in local storage.
- Trader enters their passphrase once to “unlock trading”.
- The client decrypts the API wallet private key into memory.
-
When trader submits an order:
-
Client builds a Hyperliquid
actionobject:type: "order", with the desired orders.
-
Client chooses a
nonce(typicallyDate.now()in ms). -
Client signs
(action + nonce)locally with the API wallet private key and setsvaultAddress = competitionSubaccountAddressin the signature. -
Client sends to Project X backend:
{ "competitionId": "...", "action": { ... }, "nonce": 1734567890123, "signature": { "...": "...", "vaultAddress": "0xCOMPETITION_SUBACCOUNT" }, "signer": "0xTRADING_WALLET" }
-
-
Project X backend:
-
Authenticates the user.
-
Looks up their
competitionId → subAccountAddress → tradingWalletAddress. -
Verifies:
signature.vaultAddressmatches the registered subaccount.signermatches the registered trading wallet for this competition.
-
Applies our own risk/competition rules (max size, allowed markets, etc.).
-
Forwards the body as-is to
https://api.hyperliquid.xyz/exchange. -
Hyperliquid validates the signature and nonce, then executes the order on the subaccount.
-
-
The UI updates:
- Project X backend reads positions/orders from Hyperliquid’s info API for
user = subAccountAddress. - Returns updated state to the client (open positions, orders, PnL).
- TradingView chart overlays entries/exits, etc.
- Project X backend reads positions/orders from Hyperliquid’s info API for
Non-custodial properties:
- Funds stay on Hyperliquid (subaccount).
- Trading wallet keys live only in the trader’s browser.
- Project X backend never holds withdrawal-capable keys.
-
Live data ingestion
-
Project X periodically (or via streams) queries Hyperliquid info API for each competition subaccount:
- current equity, positions, PnL, fills since competition start.
-
For each competition entry, we compute:
currentEquity,PnL = currentEquity - startEquity,PnL%, volume, etc.
-
We store aggregated stats in our own DB (per user & competition).
-
-
Leaderboard logic
- A scoring function (e.g.
score = PnL%or something more advanced) is applied. - Leaderboard table is updated continuously from these stats.
- Only trades on the competition subaccount count; main account and other subaccounts are ignored.
- A scoring function (e.g.
-
Trader UI
-
Trader opens the Project X leaderboard page.
-
Sees:
- Their rank, PnL%, volume, streaks, achievements.
- Overall competition rankings.
-
Optional: animated badges, XP, levels, etc. – all derived from the same per-subaccount trading data.
-
Again, all competition metrics are computed from:
startEquity(snapshot when they joined),- live data for
user = competitionSubaccountAddressfrom Hyperliquid.
That’s the gist:
- Master account holds funds and owns subaccounts.
- Subaccounts are per-competition trading sandboxes.
- Trading wallets (API wallets) sign orders but can’t withdraw, and their keys live only in the Project X web client.
- Project X glues this together into: onboarding, a trading UI, and a live gamified leaderboard.