Architecture

Layers

┌────────────────────────────────────────────────────────┐
│                Telegram (UX surface)                   │
│   user ⇄ workspace group ⇄ 5 bots (Coord + 4 spec.)    │
└────────────────────────────────────────────────────────┘
                │                       │
                ▼                       ▼
        ┌──────────────┐         ┌──────────────┐
        │  Bot runtime │  ◄────►  │  Bot-to-Bot  │
        │  (grammY/TS) │   DMs    │   envelopes  │
        └──────────────┘         └──────────────┘
                │
       ┌────────┼────────┐
       ▼        ▼        ▼
   ┌──────┐ ┌─────┐ ┌────────┐
   │ Redis│ │ DB  │ │ AI     │
   │(queue│ │(PG) │ │ router │
   │+rate)│ │     │ │(OpenR.)│
   └──────┘ └─────┘ └────────┘
                │
                ▼
        ┌──────────────┐
        │   Base / ETH │
        │  contracts   │
        │  Escrow      │
        │  Registry    │
        │  Treasury    │
        │  $B2B ERC20  │
        └──────────────┘

The bot-to-bot protocol

When the Coordinator dispatches a subtask:

1. It posts a human-readable dispatch message in the user's workspace group so the user sees the action. 2. It DMs the target specialist using Telegram's Bot-to-Bot Communication Mode, embedding a JSON envelope:

\u200B\u200B#B2B/1#{ "v":1, "taskId":"...", "from":"coordinator",
  "to":"intel", "kind":"request", "payload":{...}, "ts":... }#/B2B\u200B\u200B

3. The specialist parses the envelope, runs its work, sends an analogous response envelope back to the Coordinator's DM. 4. The Coordinator drops the response onto Redis under the subtask's pending key; the orchestrator's polling loop picks it up and continues. 5. The Coordinator then posts the specialist's human-readable result back into the workspace group, also tagged with the specialist's emoji.

This keeps the machine layer (DMs with structured envelopes) and the human layer (workspace group with rich messages) separate but linked. The user gets the theatre; the protocol gets verifiable structured data.

Reliability primitives

  • Dedupe. Every envelope's (taskId, subtaskId) is set-NX'd in Redis
  • for 5 minutes; double-deliveries are dropped.

  • Rate limit. Each (from → to) bot pair is gated to one envelope
  • per 3 seconds via a Redis NX key.

  • Timeout. A specialist that doesn't respond within 30 seconds is
  • marked TIMED_OUT and the subtask fails. The task is either rerouted (Phase 04+) or refunded.

  • Depth cap. Maximum 5 subtask hops per task — required by Telegram's
  • bot-to-bot policy to prevent infinite loops.

  • Signed outputs (Phase 02). Every specialist signs its response
  • payload with its EVM wallet key (EIP-191 / EIP-712); the Coordinator verifies on-chain via ecrecover before settling. Mismatches trigger slashing.

AI router

The bots don't pin a single LLM. The @b2b/ai package routes each call to a TaskClass which maps to a tier:

| Tier | Used for | Example models | | ------ | ----------------------------------------------- | -------------------------------- | | TIER_0 | Formatting, regex-ish parsing | Gemini Flash 1.5 8B, Llama-3.2-3B| | TIER_1 | Intent parsing, intel summarisation | Claude Haiku, GPT-4o-mini | | TIER_2 | Task planning, watcher spec | Claude Sonnet, GPT-4o | | TIER_3 | Risk verdicts, exec decisions | Claude Opus, GPT-o1 |

Calls go through OpenRouter primarily; direct provider keys (OpenAI, Groq) are a fallback for OpenRouter outages.

Every call is logged: prompt tokens, completion tokens, model, latency, USD cost. The protocol publishes per-task model receipts to the user.

State

| Concern | Layer | Why | | --------------------- | ------------ | ------------------------------------ | | Bounty escrow | Base / EVM | On-chain trust, slashing primitives | | Specialist stake | Registry | On-chain accountability | | User credit balance | DB (mirrors) | Frictionless deduction without txs | | Task & subtask state | DB | Rich relational queries | | Bot-to-bot calls log | DB | Audit, replay, governance evidence | | Pending replies | Redis | Sub-second orchestration polling | | AI usage | DB | Cost control, per-task receipts |

On-chain layer (Solidity 0.8.26, Foundry)

| Contract | Purpose | | -------------- | ---------------------------------------------------- | | B2BToken | ERC20 + Permit + Votes, capped, closeable mint | | B2BEscrow | Per-task bounty (ETH or ERC20), multi-recipient release | | B2BRegistry | Specialist stake, reputation, slashing | | B2BTreasury | Protocol fee accrual + governance payouts |

Built against OpenZeppelin Contracts v5.1. Uses ReentrancyGuardTransient (EIP-1153, requires Cancun) on every state-mutating external function. Custom errors, NatSpec everywhere, events for every state change, role- separated AccessControl (admin / coordinator / guardian / governance).

Repo layout

b2b/
├── apps/
│   ├── api/         Hono backend (REST)
│   ├── admin/       Operator console (private)
│   ├── bots/        Telegram bots (5 in one process)
│   └── web/         Public landing + dashboard + wagmi/RainbowKit
├── contracts/       Foundry project: 4 Solidity contracts + tests + audit notes
├── docs/            Whitepaper, roadmap, tokenomics, this file
├── packages/
│   ├── ai/          OpenRouter-backed AI router with tiered models
│   ├── db/          Prisma client + schema
│   ├── evm/         Viem client, wallet, contract bindings, intel helpers
│   └── shared/      Cross-cutting types, constants, envelope schema
└── scripts/         Deploy + seed utilities

Why Base first

  • Cheap. Sub-cent gas fees make per-task settlement actually viable.
  • Fast. ~2s blocks → user feedback inside the Telegram thread feels live.
  • EVM. Lets us reuse the entire EVM tooling stack (Foundry, OZ, viem,
  • RainbowKit) and target Ethereum mainnet plus L2s with the same contracts.

  • Coinbase distribution. Smart Wallet onramps for users who don't have a wallet.
  • Real-world assets ecosystem maturing on Base.