Wallet-only auth
There are no passwords, no email confirmations and no admin accounts. The lowercased address of the wallet you connect is your user id everywhere in the system.
The model
A connected wallet is an identity claim, and Agex treats it as the whole account system. When
RainbowKit reports a connection, the frontend calls POST /api/user/profile with the
address. The backend upserts a row in profiles whose primary key is that
lowercased address, and returns the profile. Disconnecting the wallet signs you out.
toLowerCase() on write and on lookup. Mixed-case
checksummed addresses passed to an endpoint still resolve to the same profile.Sign-in flow
Connect
WalletProvider.jsxconfigures wagmi and RainbowKit with the Robinhood Chain and yourVITE_WALLETCONNECT_PROJECT_ID.Sync profile
AuthContext.jsxwatches the connected address and posts it to/api/user/profile.Hydrate
The response โ id, username, avatar, wallet โ is held in React context and consumed by Profile, Settings and Register.
Disconnect
Clearing the wallet clears the context. Nothing is persisted client-side beyond wagmi's own connection state.
What a profile stores
| Column | Notes |
|---|---|
id | Lowercased wallet address. Primary key and the value every other table references as user_id. |
wallet_address | The same address, kept as a readable field. |
username | Optional display name; editable from Profile. |
avatar_url | Optional profile image. |
role | Always user. The column survives for schema compatibility but nothing branches on it. |
Ownership of an agent
Agents record their deployer on deploy_wallet. A legacy created_by UUID
column is still written when a caller passes a UUID, but wallet deployments always use
deploy_wallet. Ownership decides three things:
GET /api/agents/mine/:userIdreturns only agents whosedeploy_walletmatches.PUT /api/agents/:tickerrejects edits from a wallet that does not own the agent.POST /api/agents/:ticker/reveal-keyonly decrypts the private key for the owner.
What was removed
Earlier versions of the codebase had an admin role, an agent approval queue and per-agent status
values such as pending_approval, suspended and bankrupt. All of
it is gone: there is no admin router, no ADMIN_WALLETS environment variable, no approval
gate before an agent goes live, and no status filtering anywhere in the trading engines or the UI.