Skip to content

ChiJian28/LEASH

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LEASH

Put your agent on a leash.

Onchain spend allowances for AI agents and automations on Monad testnet — fund a personal vault, attach hard caps, revoke instantly, and audit every action through a live ledger.

Tagline

Programmable onchain allowances so agents can spend for you without spending you.

Problem

Agents need wallets to act, but unlimited approvals and hot keys are a personal disaster.

  • You want an agent to pay, trade, or hit APIs.
  • You do not want infinite approve, shared private keys, or “trust me” offchain limits.
  • When something goes wrong, you need a hard stop and a verifiable trail — not a spreadsheet and a hope.

This is a problem I hit the moment agent + money touch the same wallet.

Solution

LEASH is a personal policy vault for agent spend:

  1. You create a vault and deposit USDC (owner-controlled custody).
  2. You open a session for a spender (agent wallet): total cap, optional period cap, expiry, optional allowlist, optional ERC-8004 agentId.
  3. The agent can only spend inside that policy; over-cap / bad recipient / expired → reverts onchain.
  4. You can revoke in one transaction.
  5. Everyone can read the story on the Envio activity ledger (not a mocked feed).

Hard limits live in Solidity. The UI is a command center, not the source of truth.

Architecture

LEASH technical architecture

Layer Name What it does
SURFACE Next.js command center — wallet UX, fund, sessions, ledger, spend simulator
ACCESS Wallet writes · thin Express/viem API · Envio GraphQL reads
CUSTODY LeashFactory + LeashVault — one vault per owner, deposit/withdraw
LEASH Sessions: caps, period, expiry, allowlist, canSpend, spend, revoke
PROOF Envio HyperIndex → live Activity feed · explorers for tx proof

Agent spend loop: preflight (canSpend) → onchain spend → events indexed → ledger updates.

Features

Feature Description
Personal vault One vault per owner via factory
Deposit / withdraw Owner moves USDC in and out
Agent sessions Cap, period cap, expiry, agentId, allowlist
Onchain enforcement spend only by spender; caps are hard
Preflight canSpend view + API + Policy lab UI
Spend simulator Demo agent spend without a real bot
Instant revoke Owner cuts the leash in one tx
Live ledger Envio-indexed Vault / Session / Activity
Command-center UI Dark operational design (not a generic template)

Demo

https://youtu.be/3S0eR4LAb9M

Tech Stack

Layer Stack
Chain Monad testnet (10143)
Contracts Solidity 0.8 · Foundry · OpenZeppelin
Indexer Envio HyperIndex (hosted GraphQL)
API Node · Express · viem
Frontend Next.js 15 · TypeScript · Tailwind CSS
Wallet Wagmi · viem · RainbowKit
Data / state TanStack Query · Axios · Zustand
Motion Framer Motion (landing atmosphere)

Smart Contracts

There is no separate “ToolRegistry.” The onchain surface is a factory + personal vault.

Contract Role
LeashFactory createVault / createVaultFor · vaultOf(owner) · one vault per owner
LeashVault deposit · withdraw · createSession · spend · revoke · canSpend · allowlist

Address

Network Contract Address
Monad testnet LeashFactory 0x5BA28C60b1A49C809c9A455cca1436bff86a49e0
Monad testnet USDC (x402 guide) 0x534b2f3A21130d7a60830c2Df862319e593943A3

Vaults are created per user by the factory (clone / deploy pattern via createVault). Look up yours with vaultOf(owner) or the app overview after connecting.

Explorer

Indexer (GraphQL)

https://indexer.dev.hyperindex.xyz/25cb989/v1/graphql

Example:

{
  _meta { isReady progressBlock eventsProcessed }
  Vault(limit: 5) { address owner depositCount sessionCount }
  Activity(order_by: { timestamp: desc }, limit: 10) { kind txHash amount }
}

Repository Structure

LEASH/
├── architecture.svg          # System architecture diagram
├── README.md
├── backend/                  # Contracts + thin API
│   ├── src/                  # LeashFactory, LeashVault, mocks
│   ├── test/                 # Foundry tests (10/10)
│   ├── script/               # Deploy scripts
│   ├── abi/                  # Exported ABIs
│   ├── deployments/          # chainId → addresses (e.g. 10143.json)
│   └── api/                  # Express + viem read/preflight API
├── indexer/                  # Envio HyperIndex project
│   ├── config.yaml
│   ├── schema.graphql
│   └── src/handlers/         # Vault + factory event handlers
└── frontend/                 # Next.js command center
    ├── DESIGN.md             # UI design system
    └── src/
        ├── app/              # Routes: /, /app, fund, sessions, ledger, policy-lab
        ├── components/       # UI + LEASH domain + motion
        ├── hooks/            # vault / sessions / ledger
        └── lib/              # wagmi, envio, api, abis

Quick Start

Prerequisites

  • Node.js 22+
  • Foundry (forge, cast)
  • Monad testnet MON (gas) + testnet USDC for deposits
  • WalletConnect project id (optional for WalletConnect; injected wallets work)

1. Contracts (optional local verify)

cd backend
forge test -vv

Deploy (see backend/script/deploy.sh + backend/.env.example).
Already deployed factory address is in backend/deployments/10143.json.

2. API (policy preflight)

cd backend/api
cp ../.env.example .env   # set LEASH_FACTORY_ADDRESS, RPC_URL, etc.
npm install
npm run dev               # default http://localhost:8787

3. Indexer

Hosted indexer is already running (URL above). For local Envio:

cd indexer
pnpm install
pnpm codegen
# see indexer/README.md for dev / cloud deploy

4. Frontend

cd frontend
cp .env.example .env.local
# set NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID if needed
# GraphQL + factory defaults match testnet deploy
npm install
npm run dev               # http://localhost:3000
Env (frontend) Purpose
NEXT_PUBLIC_LEASH_FACTORY Factory address
NEXT_PUBLIC_USDC Testnet USDC
NEXT_PUBLIC_ENVIO_GRAPHQL_URL Envio GraphQL endpoint
NEXT_PUBLIC_API_URL Backend API (policy lab)
NEXT_PUBLIC_RPC_URL Monad RPC
NEXT_PUBLIC_CHAIN_ID 10143

Security notes

  • Owner controls deposit, withdraw, create session, revoke.
  • Spender can only spend within an active session policy.
  • Backend API is read / preflight only — it does not hold private keys.
  • Never commit .env / .env.local (see root .gitignore).

License

Hackathon project (BuildAnything Spark · Monad). See individual package folders for dependency licenses.

About

Onchain spend allowances for AI agents. Set hard spending caps, expiry, and revoke access with smart contract enforcement on Monad.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors