Skip to content

BootNodeDev/cajero

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

El Cajero

A self-serve Slack bot for distributing gas and test tokens to developers from a Safe multisig on Base. Supports ETH and USDC on Base, Ethereum mainnet, and Arbitrum — non-Base requests are bridged automatically via Uniswap.

How It Works

1. Developer runs: /cajero request 0.01 ETH vitalik.eth testing --network eth
2. Bot checks allowlist
3. Bot resolves ENS name to 0x address (if applicable)
4. For Base: proposes a direct Safe transaction
   For ETH/Arb: fetches a cross-chain quote from Uniswap and proposes a bridge transaction
5. Bot auto-executes the Safe transaction (if threshold = 1)
6. Bot posts confirmation with BaseScan link

Features

  • Multi-chain: fund recipients on Base, Ethereum, or Arbitrum
  • Uniswap bridge: cross-chain requests use Uniswap's routing API from the Base Safe
  • ENS + raw address support for recipients
  • Safe auto-execution when threshold is met (no manual signing required)
  • Allowlist restricts usage to specific Slack users
  • Rate limiting at one pending request per user
  • Amount caps per token (configurable)

Commands

/cajero request <amount> <token> <recipient> <reason> [--network base|eth|arb] [--project name]
  Request funds. Default network is Base.
  ETH and Arb requests are bridged via Uniswap.
  Recipient can be an ENS name or 0x address.

/cajero status
  Show your pending requests.

/cajero balance
  Show the Safe's ETH and USDC balance on Base.

/cajero expenses [project-name]
  Show spending totals by project and network.

Examples

/cajero request 0.01 ETH vitalik.eth testing bridge
/cajero request 0.01 ETH 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 gas --network eth
/cajero request 50 USDC 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 hackathon --network arb --project bridge-v2
/cajero balance

Setup

1. Create a Slack App

  1. Go to api.slack.com/apps > Create New App > From scratch
  2. Name it El Cajero, pick your workspace

Enable Socket Mode:

  • Settings > Socket Mode > Enable
  • This generates an App-Level Token (xapp-...) with connections:write scope

Add Bot Token Scopes:

  • Features > OAuth & Permissions > Bot Token Scopes:
    • commands
    • chat:write
    • chat:write.public

Create Slash Command:

  • Features > Slash Commands > Create:
    • Command: /cajero
    • Description: Request test funds from the team Safe
    • Usage hint: request <amount> <token> <recipient> <reason> [--network base|eth|arb]

Enable Interactivity:

  • Features > Interactivity & Shortcuts > Toggle On

Install to Workspace:

  • Settings > Install App > Install to Workspace
  • Copy the Bot User OAuth Token (xoxb-...)
  • Copy the Signing Secret from Basic Information

2. Create a Safe on Base

  1. Go to app.safe.global > Create new Safe on Base
  2. Note the Safe address
  3. Run the bot once to see the bot wallet address in the startup log
  4. Add the bot wallet as a Safe owner (Settings > Owners > Add new owner)
  5. Set threshold to 1 for auto-execution

Fund the Safe with ETH and/or USDC on Base. For cross-chain requests, Uniswap will route from those Base funds.

3. Environment Variables

cp .env.example .env

Fill in all values. See .env.example for descriptions.

4. Run

npm install
npm run dev      # Development (with hot reload)
npm run build    # Production build
npm start        # Run production build

Project Structure

cajero/
  src/
    index.ts                # Slack app, command routing, execution monitor
    config.ts               # Env validation, constants
    handlers/
      requestFunds.ts       # /cajero request handler
    uniswap/
      bridge.ts             # Uniswap cross-chain bridge quotes
    ens/
      resolve.ts            # ENS name resolution (mainnet provider)
    safe/
      proposeTx.ts          # Safe propose + auto-execute (direct + bridge)
    db/
      store.ts              # SQLite: requests table

Architecture

Slack (/cajero request)
  |
  v
Allowlist check --> reject if not allowed
  |
  v
ENS resolution (mainnet) --> resolve name or validate 0x address
  |
  v
Network = base?
  |-- Yes --> Safe SDK: direct ETH/USDC transfer on Base
  |-- No  --> Uniswap API: cross-chain bridge quote
                  |
                  v
              Safe SDK: propose bridge tx (approve + Universal Router call)
  |
  v
Execution monitor --> poll for on-chain confirmation (Base)

Safety

  • Only allowlisted Slack user IDs can use the bot
  • Hard caps per request (MAX_AMOUNT_ETH / MAX_AMOUNT_USDC)
  • Max 1 pending request per user at a time
  • Addresses validated with ethers.isAddress() or ENS resolution
  • Private keys never logged to Slack or console
  • All requests logged to SQLite

Deployment

Railway

  1. Connect your GitHub repo
  2. Set environment variables in the dashboard
  3. Build command: npm run build
  4. Start command: npm start

Render

  1. Create a new Background Worker
  2. Build command: npm install && npm run build
  3. Start command: npm start
  4. Add environment variables in the dashboard

The bot uses Socket Mode (WebSocket), so no public URL or port is needed.

About

A self-serve internal tool for distributing gas and test ERC20 tokens to developers for building and testing across supported networks

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors