Search projects, hackathons, sponsors and tech

    ← All projects

    casium

    Scoped AI rental agent with Sui-enforced permissions and private document sharing.

    Demo

    About

    Cassiuum is a scoped AI rental agent that finds suitable properties and submits applications within limits set by the renter. Sui enforces the agent’s permissions, while World verifies that each agent represents a unique human and prevents duplicate applications. Sensitive documents remain encrypted on Walrus and are shared only with authorized landlords.

    How it's made

    Casium is a scoped rental-application agent: a renter authorizes an agent to apply for apartments, but the agent is constrained by both human identity and on-chain permissions. The core idea is: **World limits who the agent represents. Sui limits what the agent can do.** I built it as a pnpm/TypeScript monorepo with three main apps: - **Next.js 16 + React 19 frontend** for renter, provider, landlord, and agent-operator views. - **Hono provider API** that owns listings, application reservations, duplicate-human checks, packet registration, receipt verification, and Postgres persistence via Drizzle. - **Node.js deterministic agent service** that reads a renter mandate, evaluates listings, reserves an application slot with the provider, then submits the application on Sui. The on-chain core is a **Sui Move package deployed to testnet**. It defines `RentalMandate`, `OwnerCap`, `AgentCap`, `RentalListing`, and `ApplicationReceipt`. A renter creates a `RentalMandate` with limits like max rent, municipality allowlist, bedroom count, expiration, and remaining application count. The agent receives an `AgentCap`, but Move still checks that the transaction sender matches the mandate’s authorized `agent_sui`, the listing is eligible, the mandate is not revoked/expired, and the agent has remaining application allowance. For **World AgentKit**, the provider verifies the agent’s EVM identity before accepting a reservation. The app supports both a mock mode for deterministic local testing and real AgentKit verification using `@worldcoin/agentkit` helpers. The important part is that raw World human IDs are immediately SHA-256 hashed, and the provider enforces one application per verified human per listing. We also bind the AgentKit-verified EVM address back to the Sui mandate’s `agent_evm` field, so a random verified agent cannot use someone else’s mandate. For documents, we used **Walrus** as the storage layer and **Seal** as the access-control layer. The renter’s browser generates a synthetic application packet, encrypts it client-side, uploads only ciphertext to Walrus, and registers the `walrusBlobId` plus packet hash with the provider. Walrus is abstracted behind one adapter interface with mock, HTTP, and CLI modes; the live HTTP adapter was smoke-tested against Walrus testnet with byte-identical download verification. Seal handles landlord-gated decryption. The packet identity is derived from: ```text bcs(mandate_id) || bcs(listing_id) ``` That was a deliberate design choice because the renter encrypts before the eventual `ApplicationReceipt` exists, but we still wanted the ciphertext scoped to exactly one mandate and one listing. We upgraded the Sui package to add `seal_approve_packet`, which Seal key servers dry-run before releasing keys. The Move policy checks landlord sender, packet identity, receipt status, access expiry, mandate match, and revoked state. The hackiest-but-important part was stitching together multiple identity domains safely. The agent has a Sui address for transactions and an EVM address for AgentKit. Sui cannot directly verify the AgentKit EVM signature inside the Move call, so the provider becomes the cross-chain enforcement point: it sees the AgentKit-verified EVM signer, reads the Sui mandate, checks the mandate’s expected EVM/Sui agent addresses, then only returns a reservation hint if everything matches.