Regents Mobile, built by Regents Labs, is the iPhone wallet for Regent users. The live path is the wallet: open a wallet, add funds, send, receive, cash out, and review history with Base USDC as the happy path.
The app also keeps "My agents": the list of agents a person funds. An agent is added by pasting its Base wallet address or by giving it a pairing code, and every listed agent shows its live Base USDC balance.
Important
The wallet is the live path and moves real money on Base. Funding an agent is a wallet send that the person reviews and signs on the phone.
client surfaces
ios mobile app, wallet, action signing ◀ this repository
regents-cli operator control surface
regents-techtree-hermes-plugin Hermes mission-control tab
│
▼
platform
ash-platform Phoenix, LiveView, Ash: web, API, product domains
│
▼
services and chain
siwa-server agent request signing, nonce and replay state
media-web hosted card images and video
fly-sentinel operator health checks
regent-contracts canonical Solidity, ABIs, deployment records
autolaunch-contracts frozen Autolaunch V1 Solidity
shared libraries and standalone tools
elixir-utils SIWA, ENS, XMTP, cache, Credo checks
design-system tokens and regent_ui components
python-cli offline Techtree skill-tree inspection
videocontrol video project and timeline workflows
- Open a mobile wallet after signing in.
- Add USDC on Base, with Apple Pay shown when it is available for the user and region.
- Send funds to another wallet or fund one of your agents.
- Keep a list of your agents: add one by wallet address or pair it with a code, and see its Base USDC balance.
- Pay or decline the USDC your paired agents ask for, from the Requests tab or straight from the notification.
- Receive funds by copying the Base and Ethereum wallet address.
- Cash out supported balances through the Coinbase cash-out flow.
- Review wallet history and failed transaction support details.
- Check $REGENT staking and reward actions from the Earn tab.
Base USDC is the primary route for agent funding. Other balances may appear in the wallet detail view, but Base USDC remains the recommended path.
The agents list is owned by the phone backend under server/. Pasting a wallet address lists an agent straight away. A pairing code (single-use, ten minutes) lets an agent that can run commands prove it holds its wallet key: it sends a signed request to POST /agent/pair, the backend checks the signature with the SIWA server for the regents-mobile audience and records the verified address as waiting. The pairing screen shows the exact instructions to paste to the agent, then asks the person to confirm the address the agent signed in with; only a confirmed address is listed as paired. If balances cannot be read, the list still loads and says so.
Funding an agent opens the wallet send flow prefilled with Base USDC and the agent's address. Balances shown in the list are live Base USDC reads.
A paired agent can ask its person for Base USDC. The request shows up in the Requests tab and arrives as a notification with Pay and Decline buttons. Pay sends the USDC from the phone wallet after the wallet's own confirmation.
How an agent asks:
- Send a signed request to
POST /agent/payment-requests. It is signed the same way as/agent/pair: a SIWA receipt for theregents-mobileaudience, every proof header once, and a JSON body of at most 4 KiB. - The body is
{"to": "0x…", "amount": "5.00", "note": "What it is for"}.tois the Base address that receives the money, usually the agent's own wallet.amountis USDC above zero with at most 6 decimals.noteis 1 to 140 characters and is shown to the person as the agent's own words. - Only a wallet someone has paired can ask. An unpaired wallet gets a 403 telling it to pair first. Each person who paired the wallet gets their own request, and the response lists the request ids.
How an agent reads the answer:
- Send a signed
GET /agent/payment-requests/{id}. With no body, it signs no content digest. - It returns
{id, status, txHash}.statusiswaiting,paidordeclined, andtxHashis the Base transaction of the latest payment. Only the wallet that asked can read a request.
A signed request to /agent/* carries no query string. The header names and what is signed come from the shared SIWA signing contract: server/src/siwa/ holds generated copies of elixir-utils' siwa/contract/contract.json and fixtures.json at the commit server/siwa-contract.lock.json pins. npm run siwa:contract in server/ writes the copies from the elixir-utils checkout beside this one, npm run siwa:contract -- --check compares them with that commit, and npm test fails when a copy is not the pinned file or the backend stops taking the contract's fixtures as the contract says.
A request is marked paid only when Base shows a successful transaction with a USDC transfer from the person's own phone wallet to to for exactly the amount asked. The server asks Coinbase which wallet is signed in as that person, so nobody can mark a request paid with someone else's payment. Each transaction counts for one request only, so one payment never marks two requests paid. Requests never expire. Each person keeps their newest 100. A declined request can still be paid later, and the Pay button works whatever the status.
Install dependencies:
npm install
cd server && npm installRun the local backend in one terminal:
cd server
npm run devRun the Expo app in another terminal:
npm run startUse npm run ios for an iOS simulator build, npm run android for Android, and npm run web for the web target when needed.
Note
Signing in and using the wallet touches production data and real balances. What stays on
the device: the user's keys and anything the OS keychain holds. What leaves it: calls to
the Regent platform API, the local mobile backend under server/, and the funding and
cash-out providers the flows use. Backend secrets never belong in the app bundle.
When you add a native module (for example npx expo install expo-blur), the iOS
dev client must be rebuilt so CocoaPods links it. Run pod install with a UTF-8
locale — otherwise CocoaPods crashes on some Ruby versions with an
Encoding::CompatibilityError / ASCII-8BIT error before it does any work:
cd ios && LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 pod installThen rebuild the dev client (npm run ios, or drive xcodebuild against a
simulator directly if expo run:ios routes to a physical-device signing path).
One command must pass before a change is proposed:
npm run check:appIt runs the Expo lint pass, the app test suite, and the component tests. The local backend has its own suite:
| Command | What it does |
|---|---|
npm run check:app |
Lint, app tests, and component tests together. |
npm run test:app |
The app test suite on its own. |
npm run test:components |
The Jest component tests on their own. |
cd server && npm test |
The local mobile backend suite. |
npm run check:advisory |
expo-doctor. Advisory, not required. |
eas.json defines development, preview, and production EAS build profiles.
Start with AGENTS.md, repo.yaml, and layer2.md before editing. The app uses Expo Router under app/, shared UI under components/, wallet and mobile API helpers under hooks/ and utils/, and the local mobile backend under server/ (agents list in server/src/mobileAgents.ts, routes in server/src/routes/mobileAgents.ts).
The in-repo API source of truth is api-contract.openapiv3.yaml. mobile-services-contract.openapiv3.yaml currently documents that there are no separate shipped shared mobile service routes.
Warning
Mobile wallet opening and wallet actions are production-data work. Keep value movement user-signed, keep backend secrets out of the app, and verify Base USDC flows before treating a change as complete.
| Repository | What it is | What it deliberately does not do |
|---|---|---|
ash-platform |
The Phoenix, LiveView, and Ash application: public web pages, the HTTP API, product domains, human identity, billing, and the Techtree and Autolaunch product areas. | It does not hold Solidity source or user signing keys; wallet actions remain browser-signed. |
autolaunch-contracts |
A clean-room Solidity implementation of the founder-frozen Autolaunch V1 system, controlled by its own SPEC.md. |
It authorises no deployment, signature, or value movement; the older Autolaunch code in regent-contracts is historical reference only. |
design-system |
The shared Regent visual language: the style guide, design tokens, logos, fonts, and the regent_ui Phoenix component library. |
Shared components never own product workflow state, authorisation decisions, money movement, or product database behaviour. |
elixir-utils |
A collection of standalone Elixir libraries used across the family: SIWA, ENS, XMTP, a cache, agentbook helpers, and the in-house credo_ash lint checks. |
Each package is a library only; none of them runs a service or holds product behaviour. |
fly-sentinel |
A small Phoenix service that reports Fly.io observability and operator preview checks. | It observes and reports; it does not deploy, scale, or change any other application. |
media-web |
A standalone Phoenix service that serves hosted Regents card images and video files from media.regents.sh. |
It only serves bytes over HTTP; it holds no identity, database, or product logic. |
python-cli |
The installable regents-techtree Python package, whose shipped surface is a deterministic offline inspection of one champion/challenger skill-tree pair. |
It does not evaluate or execute an agent, and it makes no network calls once its locked dependencies are installed. |
regent-contracts |
The canonical home for Regent Solidity source, Foundry tests, deployment scripts, verified deployment records, ABIs, and the chain-contract manifest. | It holds no HTTP or CLI contracts, Ash resources, workflow logic, UI, or projection workers. |
regents-cli |
The operator control surface: the regents command line tool, its generated bindings, and its local runtime. |
It drives the platform over published contracts and owns no product database or on-chain authority. |
regents-techtree-hermes-plugin |
The Hermes plugin that presents Techtree mission control across Forge, Techtree Verify, and Uplift. | It is presentation only: no second task store, no private Verify database, no identity model, no payment system, and no Hermes runtime of its own. |
siwa-server |
The shared Sign-In With Anything service for signed agent requests, nonce and replay state, and internal keyring endpoints. | It owns no product data or product authorization policy. |
videocontrol |
A separate product: video project workflows, timeline editing, preview rendering, and Codex plugin media control. | It shares the house style but no runtime, database, or contract with the Regent platform. |
Apache 2.0 — see LICENSE.