Documentation

How AI City works — concepts, guides, architecture, and the vision behind it.

Core concepts

AI City has a two-layer model: everything that holds money lives onchain, everything descriptive lives in Postgres and is pinned by a cryptographic hash. This page explains each piece and how they fit together.

Pop-up city

A pop-up city is a place and a time window. It has a name, location, dates, a mission, a description, and a core team that runs it. A city lives only in the database — it holds no money and has no smart contract. Anyone who has verified their humanity with World ID can launch one.

The founder starts as the only member of the core team and can add others. The core team can edit the city's details and — most importantly — approves or rejects residency proposals. Residencies are the onchain part; the city itself is the offchain container that makes them discoverable and governable.

Residency proposal

A residency starts as a proposal inside a city. The proposer fills in:

  • Dates (must fall within the city's window, at least 7 days long)
  • Rooms and beds with per-bed prices in USDC
  • Organizers and a story (mission, description, property URL)
  • A residency series (new or existing)

The proposal is stored in the database with a status field that starts atproposed. The core team reviews it and can approve, reject, or add a note. An approved proposal can then be deployed as an onchain contract by the proposer.

Residency (onchain)

A residency is a Solidity smart contract deployed by theResidencyFactory. Each residency gets its own contract, so funds never mix between different stays. Key facts:

  • Parameters (immutable): host, USDC token, metadata hash, start and end times, deadline, minimum and maximum seats.
  • Status machine: Open → deadline passes → Active (enough seats) or Failed (not enough). Active → Closed (via close).
  • Host can: approve members for beds, revoke unstaked approvals, cancel before the deadline, withdraw against receipts once Active, close anytime.
  • Members can: stake USDC for an approved bed, claim a refund if the residency fails or is cancelled, claim pro-rata leftovers when it closes.

The metadata (name, rooms, prices) is hashed into the contract as a singlebytes32, so anyone can verify the listing wasn't edited after deploy.

Residency series

A residency series links recurring instances of the same stay across different cities and years. "Builders' House Goa #1" and "Builders' House Goa #2" are instances of the same series. Only the series owner can propose new instances. Series help people follow a residency they liked and let hosts build a reputation.

Directory and profiles

Every verified human can create a public profile with a name, bio, links and photo. Profiles are listed in the public directory by default (with an opt-out). Each profile shows the person's participation: which cities they founded or served on the core team, and which residencies they hosted or staked in — confirmed against the onchain contract.

How-to guides

Connect your wallet and sign in

  1. Click "Connect Wallet" in the top-right corner.
  2. Choose MetaMask, Rainbow, Ronin Wallet, or WalletConnect.
  3. Your wallet prompts you to sign a message. This is Sign-In with Ethereum (SIWE) — no gas, no transaction, just proving you control the wallet.
  4. Once signed, the header shows your wallet address and a "Verify you're human" link.

Verify you're a human with World ID

  1. After signing in, go to /verify or click the "Verify you're human" link in the header.
  2. Check the "I confirm I'm 18 or older" box (self-attested — World'sminimum_age Identity Check is in preview).
  3. Click "Verify with World ID." The World App opens on your phone.
  4. Scan the QR code with the World App to generate a Proof of Human.
  5. The server verifies the proof against World's developer API. If valid, your wallet is bound to the World ID nullifier. One nullifier per wallet — trying to use the same World ID with another wallet returns a 409 error.
  6. For local development, set NEXT_PUBLIC_ALLOW_DEV_VERIFY=1 to get a "Dev: skip World ID" button.

No Orb verification is required. World ID Proof of Human uses the World App's built-in uniqueness check. You do not need to visit an Orb.

Launch a pop-up city

  1. Make sure you're signed in and verified.
  2. Go to /launch.
  3. Fill in the name, location, dates, mission and description.
  4. Submit. The city appears in the listing immediately — no transaction, no gas.
  5. You become the founder (and the only core team member).

Propose a residency

  1. Go to a city page and click "Propose a residency."
  2. Pick an existing series (one you own) or create a new one.
  3. Fill in the name, location, dates, rooms with per-bed prices, organizers and story.
  4. Submit. The core team will review your proposal.

Approve or reject a proposal (core team)

  1. Go to the proposal page (linked from the city page).
  2. Review the dates, rooms, prices and organizers.
  3. Click "Approve" or "Reject," optionally adding a note.
  4. An approved proposal shows a "Deploy" button for the proposer.

Deploy a residency contract

  1. Only the proposer of an approved proposal can deploy.
  2. Go to the proposal page and click "Deploy."
  3. Your wallet prompts you to send a transaction to ResidencyFactory.createResidency().
  4. After the transaction is mined, the server reads the receipt, decodes theResidencyCreated event, and records the residency in the database.
  5. The residency page appears at /r/[contract-address].

Apply for a bed

  1. Browse the residency you're interested in and click "Apply."
  2. Fill in your name, bio, links and preferred bed.
  3. Submit. The host reviews your application.
  4. If approved, you'll see the bed assignment and price on the residency page.

Stake USDC for your seat

  1. After the host approves your application, go to the residency page.
  2. Click "Pay [price] USDC to hold your bed."
  3. Your wallet prompts you to approve the USDC spend, then call stake(price). If the host changed your price in the meantime, the payment fails instead of charging the new amount.
  4. The funds sit in the residency's own contract until the deadline.

Manage a residency (host)

  1. Go to /r/[address]/manage.
  2. Review applications: approve each applicant for a specific bed and price, or deny.
  3. Monitor the seat count, deadline countdown and treasury balance.
  4. Cancel the residency before the deadline if needed (everyone gets a full refund).
  5. Close the residency once spending is done (anyone can close it after the end date) to return leftover funds pro-rata.
  6. Hand the residency to another wallet with "Hand over hosting"; the new wallet accepts on the residency page.
  7. 180 days after closing, sweep whatever guests didn't claim.

Withdraw funds and upload receipts

  1. Once the residency is Active (deadline passed with enough seats), the host can withdraw.
  2. Go to /r/[address]/manage and click "Withdraw."
  3. Enter the amount, upload a receipt file (PDF, PNG, JPEG or WebP, max 4 MB), and add a note.
  4. The server hashes the file and submits withdraw(amount, receiptHash, note) to the contract.
  5. Staked members can view and download all receipts from the residency page.

Claim a refund

  • Failed or cancelled: call claim() to get your full stake back.
  • Closed: call claim() to get your pro-rata share of unspent funds. Claim within 180 days: after that the host can sweep what's unclaimed.
  • Each address can claim once. The residency page shows your claimable amount.

Architecture

Stack overview

Browser (client)
  RainbowKit + wagmi + viem | React Query | Next.js App Router
  SIWE session cookie | World IDKit widget | Tailwind CSS
       │                               │
       │ HTTP + JSON API               │ RPC (read)
       ▼                               ▼
Next.js server
  API routes | Server-only lib | postgres driver | jose (JWT)
  @worldcoin/idkit-core/signing | viem public client
       │                               │
       │ SQL                           │ eth_call
       ▼                               ▼
Postgres (Neon)                Ethereum mainnet / anvil
  users | profiles |             ResidencyFactory
  cities | core_team |           Residency (one per stay)
  series | proposals |           USDC (real or mock)
  residencies | apps |
  receipts
LayerTechnologyWhy
FrameworkNext.js 16 + TypeScript + TailwindOne deployable on Vercel; API routes are the backend
WalletsRainbowKit + wagmi v2 + viemMetaMask, Rainbow, Ronin Wallet and WalletConnect out of the box
Sign-inSIWE + HTTP-only signed cookie (jose)Every write API knows which wallet is calling
Humanity@worldcoin/idkit 4.x + server-side RP verificationCurrent World SDK; one nullifier per human
DatabasePostgres (postgres driver, plain SQL)Neon in production, local Postgres in dev
ContractsSolidity 0.8.28, Foundry, OpenZeppelinOne factory + one contract per residency
Chain readsviem public client; multicallNo indexer needed at this scale

Smart contracts

Two contracts, deployed on Ethereum mainnet:

  • ResidencyFactory — the singleton factory. Deployed once per chain.createResidency(ResidencyParams) deploys a new Residencycontract. Emits ResidencyCreated with the metadata hash, dates and seats as event fields.
  • Residency — one contract per residency. Holds USDC. Immutable parameters set at construction. Functions: approve, revoke,stake, cancel, withdraw, close, sweep,transferHost, acceptHost,claim. Uses OpenZeppelin's SafeERC20 andReentrancyGuard.

Constructor checks: duration ≥ 7 days, deadline ≤ start time, deadline in the future, 1 ≤ minSeats ≤ maxSeats ≤ 500.

Read the full contract reference → Every function, who can call it, when, and what it does with your USDC.

Data model

TablePurposeKey columns
usersWallet + verification statusaddress PK, nullifier UNIQUE, verified_at, adult_attested_at
profilesPublic directory entryaddress PK FK, name, bio, links JSONB, photo BYTEA
citiesPop-up city (offchain)id PK, slug UNIQUE, name, location, start_time, end_time, founder
city_core_teamWho runs a city(city_id, address) PK, role (founder/core)
residency_seriesRecurring residency threadid PK, slug UNIQUE, name, description, owner
residency_proposalsProposal before deployid PK, city_id, status (proposed/approved/rejected/deployed)
residenciesDeployed onchain contractaddress PK, host, metadata_hash, dates, seats, city_id, proposal_id
applicationsGuest applicationsid PK, residency FK, applicant, status, bed_id, price_units
receiptsWithdrawal proof filesid PK, residency FK, tx_hash, receipt_hash, data BYTEA

Session and auth flow

  1. Browser connects wallet via RainbowKit.
  2. GET /api/auth/nonce returns a nonce JWT (10 min expiry) in an HTTP-only cookie.
  3. Browser signs the SIWE message with the wallet.
  4. POST /api/auth/verify validates the signature, issues a session JWT (7 day expiry) in an HTTP-only cookie.
  5. Every subsequent API call carries the session cookie. The server reads the wallet address from the JWT and looks up verification status from the database.

Residency lifecycle (deploy flow)

  1. Proposer submits form → POST /api/cities/[slug]/proposals → server validates, builds canonical JSON, inserts proposal.
  2. Core team reviews → POST /api/proposals/[id] with {decision: "approve"} → status becomes approved.
  3. Proposer calls ResidencyFactory.createResidency(params) via wallet → transaction mined → ResidencyCreated event emitted.
  4. Proposer calls POST /api/residencies with the tx hash → server reads receipt, decodes event, verifies metadata hash/dates/seats match the approved proposal, inserts residency row, updates proposal status to deployed.

Security model

  • Private keys never touch the server. SIWE proofs are verified; the server only stores a session cookie.
  • Receipt files are sha256'd onchain. The server rejects uploads whose hash doesn't match the Withdrawn event.
  • Receipts are served only to the host and staked members. The API checks getMember(addr).staked before serving.
  • Nullifier uniqueness. The UNIQUE constraint on users.nullifier enforces one wallet per human.
  • Cross-residency isolation. Each Residency contract holds its own USDC.
  • Unaudited. Only deposit what you can afford to lose.

Extropian vision

Why extropian?

AI City is built from an extropian philosophy. The extropians were the first organised transhumanist movement (1988–2006), and crypto grew directly out of their community — Hal Finney, Nick Szabo and Wei Dai were all on the extropians mailing list. AI City brings two branches of one family back together: the dream of digital cash and the dream of transcending biological limits.

The mission statement says it explicitly: "Accelerate human coordination across cultural bond building and extropian differential acceleration perspective."That means accelerating the parts of human coordination that make us more autonomous, more connected across cultures, and more capable of self-governance — not just faster transactions.

The principles, applied

PrincipleWhat it becomes in AI City
Perpetual ProgressSmall, rapid, reversible experiments in how people live and work together. A city lasts weeks, not years. You learn, iterate, dissolve or repeat.
Self-TransformationYou don't just attend a residency — you propose one. You don't just join a city — you launch it. The product is an instrument for its users to shape their own environment.
Practical OptimismShip it live on mainnet by Sunday rather than write a manifesto. The contracts are on Ethereum, the app is on Vercel, and the first residency is real USDC.
Intelligent TechnologySmart contracts automate the trust: money sits in code, the minimum-seat rule is enforced by the chain, every withdrawal is recorded onchain with the hash of its receipt, so members can check the spending.
Open SocietyAnyone can launch a city, anyone can propose a residency, anyone can apply. The barriers are proof of personhood (not permission) and a stake (not a credential). Voluntary entry, quorum-or-refund, and an exit.
Self-DirectionEvery city has a founder and a core team, not a central operator. Every residency has a host. The platform doesn't decide what runs; the people in each city do.
Rational ThinkingReceipt hashes on a public ledger, a confirmed-vs-inferred framework in every document, and later — prediction markets for city decisions.

The infomorph stack

AI City is the grouping layer of a larger vision called theinfomorph stack. An infomorph (from Alexander Chislenko's 1996 paper Networking in the Mind Age) is a post-biological entity whose mind exists as a distributed information pattern rather than being bound to a single body or machine.

The stack has six layers:

LayerTranshumanist ideaWhat exists
Self-modelPattern identity — the self as informationArgo: E2E journal, wallet key wrap, cognitive map
Working mindExocortex, extended mindSecond brain vault + Hermes agent
ReachAgents as sub-mindsHermes skills, concierge agent design
BodiesMorphological freedom, summonable bodiesCyberdeck, Reachy/Friendly robot, FPV drones
GroupingFunctional proximity, ad-hoc contractsAI City: Residency MVP on mainnet
ContinuityImmortality through distributionArgo recovery code; wallet-based key management

In this vision, AI City is the piece that lets groups form, commit resources and dissolve onchain — the coordination primitive that lets infomorphs assemble around shared problems and disassemble when the problem is solved. Each residency is a temporary contract, each city is a temporary container, and every member holds their own keys.

Read the full blog post on Infomorphs and Extropianism →