A human-first commerce agent that spends through Rain, earns merchant incentives on Monad, returns value to the user on Base, and builds verifiable onchain reputation.
Winner of 1st Prize: $5,000 cash prize and a Michelin Star Dinner with the Rain Founders.
The agent works for the human, not the highest bidder.
Net Human Cost = Money Spent - Confirmed Money Returned to the Human
For eligible offers, the matcher minimizes Net Human Cost before considering quality, agent earnings, or secondary preferences. A pending or failed user payout does not count as money returned.
npm install
npm run demoOpen http://localhost:5176. The split-screen workspace shows Shopify discovery, live merchant attention bids, deterministic human-first recommendation, human approval, Rain settlement, and the 60/40 incentive split.
The unified demo uses the live discovery and auction backend. Its post-approval transaction hashes, wallet balances, payout messages, and reputation update are presentation fixtures; use the component-specific commands below for real sandbox or Monad evidence.
User Intent
→ Offer Discovery
→ Human-First Matching
→ Deterministic Guardrails
→ Agent Capacity
→ Rain Scoped Card
→ Authorization and Settlement
→ Merchant Pays Agent USDC on Monad
→ User Cashback Bridges to USDC on Base
→ Monad Reputation Event
→ Updated Delegated Capacity
Rain executes and enforces the card purchase. The agent never pays the merchant from its Monad wallet. After Rain settlement validation, the selected merchant pays the agent's incentive in Monad USDC. Monad is the canonical agent identity, payment-evidence, and reputation layer. A bridge or relayer handles the user's cashback from Monad to Base; Rain does not perform that cross-chain step.
flowchart TD
Human[Human buyer] -->|shopping prompt| DemoUI[ui-demo/app.js]
DemoUI -->|POST /api/discover| DemoServer[cli/serve-demo.ts]
subgraph Discovery[Discovery and matching]
DemoServer --> Intent[parseDiscoveryIntent]
Intent --> UCP[Shopify UCP searchCatalog]
UCP --> Eligible[Budget and availability filter]
Eligible --> Score[Intent relevance and merchant diversity]
Score --> Auction[createAuctionSession]
Auction --> Split[Bid accounting: 60% cashback / 40% agent]
Split --> Rank[Rank by Net Human Cost, then relevance]
end
Rank -->|sessionId, bids, recommendedProductId| DemoUI
DemoUI -->|GET /api/bids| DemoServer
DemoUI --> Approval{Human approval}
Approval -->|reject| Denied[Stop transaction]
Approval -->|approve or override| Selected[Selected eligible offer]
subgraph Execution[Fail-closed commerce orchestrator]
Selected --> Identity[ERC-8004 identity]
Identity --> Guardrails[Budget, MCC, domain policy]
Guardrails --> Capacity[Reputation-based capacity]
Capacity --> Rain[Rain scoped card authorize and settle]
Rain --> Incentive[x402 merchant incentive on Monad]
Incentive --> Vault[CashbackCreditVault 60/40 settlement]
Vault --> Receipt[Privacy-safe commerce receipt]
Receipt --> Reputation[ERC-8004 feedback and next capacity]
end
Guardrails -->|deny| Blocked[Block all downstream stages]
Capacity -->|deny| Blocked
Rain -->|fail| Blocked
Incentive -->|fail| Blocked
Key implementation boundaries:
| Boundary | Owner | Contract |
|---|---|---|
| Demo HTTP | cli/serve-demo.ts |
Serves ui-demo and exposes discovery, bid polling, and health routes |
| Intent and offers | Discovery modules | Parses constraints, queries Shopify UCP, filters ineligible offers, and creates auction sessions |
| Recommendation | Auction module | Minimizes Net Human Cost before relevance or agent share; merchant bid size cannot override human value |
| Incentive accounting | Auction module | Splits each ad bid in integer cents: 60% user cashback and 40% agent reward |
| Orchestration | src/orchestrator |
Executes the eight-stage trace idempotently and blocks downstream work after denial or failure |
| Durable evidence | src/receipts, src/reputation, src/onchain |
Builds receipts, derives reputation, and anchors privacy-safe hashes on Monad |
- scope.md defines what the hackathon build must do.
- build.md defines the product story and implementation sequence.
- docs/demo-script.md contains the exact judge narration and demo values.
- docs/ui-spec.md defines the continuous eight-stage demo interface.
- data/demo-catalog.json is the loader-ready source for demo intents, offers, expected decisions, and the 60/40 revenue split.
- hack.md tracks ownership and progress.
- docs/dheeraj-agent-context.md is the complete coding-agent handoff for Dheeraj's branch.
v1scope.md and v2scope.md preserve the earlier design progression. If they conflict with the canonical scope amendment, scope.md wins.
| Scenario | Expected result | What it proves |
|---|---|---|
laptop-shared-value |
Scholar Systems at $1,330 Net Human Cost |
A disclosed reward can improve the human outcome |
laptop-human-first |
Degree Devices with $0 reward |
Commission cannot outweigh lower human cost |
laptop-hard-budget-denial |
DENY |
A reward cannot override a hard budget |
hotel-tonight |
Union Square Stay at $257 Net Human Cost |
The same matcher works across commerce categories |
Purchase: $1,420
Merchant reward: $150 USDC on Monad
User cashback: $90 USDC on Base
Agent share: $60 USDC on Monad
Net Human Cost: $1,330
The cashback reduces realized Net Human Cost only after the Base payout is confirmed.
main, dev, and dheeraj/dev are normalized to the same validated implementation. The current build includes:
- Unified ACP-style buyer and merchant demo at
http://localhost:5176 - Live Shopify UCP discovery with budget filtering
- Deterministic Net Human Cost recommendation with human override
- Merchant ad bids capped at 3% of purchase price
- Conserved 60/40 split: 60% user cashback and 40% agent reward
- Eight-stage fail-closed orchestrator and transaction workspace
- Rain sandbox, Monad testnet, receipt, reputation, and capacity evidence modules
Implementation ownership and remaining milestones are tracked in hack.md.
Phase X binds one selected offer to a settled Rain transaction and an exact merchant-to-Wa1 Monad USDC incentive. It then calculates the cashback split and coordinates bridge and Base payout adapters through a resumable state machine.
npm run phaseX:test # safety, accounting, retry, receipt, and evidence tests
npm run phaseX:demo # simulated bridge/Base payout; no funds moveImplemented guarantees:
- Rain settlement must verify before incentive processing.
- The Monad USDC transfer must match merchant, Wa1, token, and amount.
- Bridge and payout retries use stable idempotency keys.
- Cashback is not realized until Base payout confirmation.
- Refunds/reversals cancel untouched flows or require reconciliation after funds move.
- Receipt evidence links Rain, Monad incentive, bridge, and Base payout references.
The bridge and payout interfaces are deliberately provider-neutral. A live Monad-to-Base provider and the authoritative Rain-user Base destination source must be selected before real cashback can move.
Rain sandbox supports Base as a payment-route rail but does not support Monad, does not expose a Base wallet for a userId, and does not move real funds. Across supports Monad and Base on mainnet, but its testnet deployment does not list Monad testnet.
For the hackathon, cashback therefore uses CashbackCreditVault on Monad testnet:
Operator authorizes winning commerce evidence
→ selected merchant deposits Monad USDC
→ vault pays Wa1's agent share
→ vault escrows the user's cashback credit
→ operator consumes credit once against a Rain intent hash
→ backend idempotently funds Rain sandbox collateral
→ backend issues a scoped cashback card
npm run cashback:compile
npm run cashback:test
npm run cashback:deploy # requires the original local Wa1 private wallet fileThe production path can replace this adapter with Across or Circle CCTP from Monad mainnet to Base mainnet while preserving the Phase X receipt/state machine.
Deployed Monad testnet vault:
CashbackCreditVault: 0x25195a6e7c8d6a112f03057c088e4f390adc3732
USDC: 0x534b2f3A21130d7a60830c2Df862319e593943A3
Operator: 0xD321df9DAd14b63f93732041d9c752f9E68aaB2D
Public deployment evidence is stored in data/cashback-deployment.json.
The first live testnet redemption completed successfully:
1.0 USDCmerchant incentive settled into the vault.0.4 USDCwas paid to Wa1.0.6 USDCcashback credit was consumed once for a Rain intent.- Rain funded
60¢of sandbox collateral and issued an active card with a strict60¢authorization ceiling.
Public transaction and Rain references are stored in data/cashback-demo.json.
The receipt pipeline normalizes identity, intent, offer, policy, Rain, Monad incentive, vault, bridge, and payout evidence into one strict privacy-safe receipt.
npm testReceipts derive effective spend, confirmed cashback, and Net Human Cost; callers cannot supply those values independently. Every lifecycle update creates a revision linked to the previous receipt hash. Duplicate creates and transitions replay idempotently, while conflicting evidence fails closed.
The reputation indexer processes current receipt revisions without double-counting prior outcomes and exposes objective reputation dimensions rather than one opaque credit score.
npm testMetrics include verified settlements and volume, effective spend, earnings, cashback, refunds, reversals, declines, policy violations, categories, counterparties, and transparent basis-point rates. Monad publication uses ERC-8004 giveFeedback with a privacy-safe data URI and evidence hash; no raw PII or card data is published.
The discovery pipeline converts a natural-language shopping request into structured budget and shipping constraints, searches Shopify's live UCP catalog, and ranks eligible merchants by projected human outcome.
npm test
npm run demo # unified buyer/merchant demo at http://localhost:5176Merchant incentives are simulated binding offers for the hackathon UI and are labeled projected until payment verification. Each bid is typically 1–3% of purchase price in the current auction implementation, capped at 3%, and split into 60% user cashback plus 40% agent reward. Ranking minimizes projected Net Human Cost before relevance and agent share. Checkout issues an amount/MCC/expiry-scoped Rain card and executes real sandbox authorization and settlement without hiding Rain's 1.2x ceiling.
The capacity evaluator turns receipt-derived reputation evidence into deterministic, bounded, time-limited delegated authority.
npm testThe evaluator uses transparent $100/$250/$500 tiers, then applies refund/reversal penalties, policy caps, reconciliation freezes, user and policy limits, and current exposure. It emits a replaceable x401-shaped authorization envelope without inventing unsupported protocol behavior.
The economics pipeline converts a projected discovery incentive into a settlement-gated x402 v2 exact payment from the mapped Wm merchant wallet to Wa1 on Monad.
npm testThe claim pipeline verifies the Rain settlement first, signs a deterministic ERC-3009 authorization, calls the Monad facilitator's /verify and /settle endpoints, and stores the resulting transaction evidence idempotently. Its settled evidence plugs directly into commerce receipts; cashback remains unrealized until the separate Phase X/vault path confirms user value.
The essential receipt and capacity results can be anchored on Monad without publishing private commerce data.
npm testDeployed on Monad testnet:
CommerceReceiptRegistry:0x16710d3fc7b8ae28427b76a476641ff367283b19AgentCapacityRegistry:0xf9a01c8d1943f4f27307525901332f960477e8cd
Public deployment transactions and the first live receipt and capacity writes are recorded under data/.
The orchestrator composes the completed modules into one fail-closed transaction trace:
Identity → Intent → Offer → Guardrails → Capacity → Rain → Incentive → Reputation
npm test
npm run app # http://localhost:5175The workspace runs explicit demo adapters so no live funds move from the UI. It provides success and hard-denial scenarios with eight inspectable stages. The server rejects malformed, oversized, non-JSON, and path-traversal requests; blocks sensitive response fields; applies strict security headers; and returns idempotent results for repeated intents.
This integration proves the spending rail works in Rain's sandbox before policy, matching, payments, or UI are added.
Fund collateral (sandbox balance)
↓
Issue scoped / agentic virtual card (amount, expiry, MCC)
↓
Authorize → Settle → Read transaction
↓
Decline (e.g. casino MCC 7995) + refund / reversal
Important distinction:
- Collateral = sandbox money pool on your contract (not a personal bank deposit).
- Scoped card = temporary agent spending envelope drawn against that collateral, with hard limits.
No real money moves. All calls hit https://api-dev.raincards.xyz/v1.
npm install
cp .env.example .envFill .env with your workshop credentials:
| Variable | Meaning |
|---|---|
RAIN_API_KEY |
Api-Key header |
RAIN_TEAM_ID |
Team scope |
RAIN_USER_ID |
Cardholder for scoped cards |
RAIN_CONTRACT_ID |
Collateral contract to fund |
RAIN_API_BASE |
Defaults to sandbox URL |
Never commit .env.
Runs the full Rain checklist end-to-end:
npm testExpected: the overall verification reports PASS.
Rain applies a 1.2× ceiling on amountInUSDCents. For a hard product max H, submit:
submitAmount = floor(H / 1.2)
Example: hard $300 (30000) → submit 25000 → Rain auth ceiling 30000.
src/rain/ Reusable Rain client
client.ts HTTP + Api-Key
collateral.ts Fund sandbox collateral
cards.ts Issue scoped cards (+ session encryption)
transactions.ts Authorize / settle / refund / reverse / read
limits.ts 1.2x ceiling helpers
session.ts SessionId RSA + AES decrypt
index.ts RainClient facade
Other components plug into RainClient instead of calling Rain HTTP directly.
Rain sandbox docs: https://rain-sandbox-trial.mintlify.site
Local EVM wallets for agent earnings and merchant x402 payers on Monad testnet.
npm run wallets -- create # generate Wa1 + Wm1–Wm4 (once)
npm run wallets -- list
npm run wallets -- balances
npm run wallets -- fund-helpFund test USDC (Circle) + MON gas:
- https://faucet.circle.com — USDC → Monad Testnet → paste address → Send 1 USDC
- https://faucet.monad.xyz — paste address → Get Testnet MON
Secrets stay in .wallets.monad.json and .env (gitignored). Public addresses are in data/wallets.public.json.
Gives each wallet an on-chain agent identity on Monad testnet, with declared capabilities and a tracked history of registrations + USDC transfers.
Important distinction:
- ERC-8004 on Monad = identity + reputation registries (who the agent is).
- x402 facilitator (e.g. molandak) = payment settlement rail — separate from 8004.
npm test
npm run ui # http://localhost:5173 profile UIUI shows each profile: agent ID, wallet, capabilities, history refs (explorer links).
Registries (Monad testnet):
- Identity:
0x8004A818BFB912233c491871b3d84c89A494BD9e - Reputation:
0x8004B663056A597Dffe9eCcC1965A193B7388713