Skip to content

0xOsiris/mpp-agentkit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mpp-agentkit

AgentKit payment method for the Machine Payments Protocol (MPP).

method="agentkit" lets servers accept proof-of-humanness as payment. Agents sign a SIWE message, the server checks the AgentBook contract on-chain, and if the agent maps to a World ID-verified human, access is granted. No stablecoins, no gas — identity is the currency.

Install

cargo add mpp-agentkit

Or in Cargo.toml:

# Server + client (default)
mpp-agentkit = "0.1"

# Server only
mpp-agentkit = { version = "0.1", default-features = false, features = ["server"] }

# Client only
mpp-agentkit = { version = "0.1", default-features = false, features = ["client"] }

How it works

Agent                              Server                         AgentBook (on-chain)
  |                                  |                                |
  |-- GET /api/resource ------------>|                                |
  |                                  |  No credential                 |
  |<-- 402 + WWW-Authenticate ------|                                |
  |    method="agentkit"             |                                |
  |    request={ domain, nonce, ... }|                                |
  |                                  |                                |
  |  [Build SIWE message]           |                                |
  |  [Sign with wallet key]         |                                |
  |                                  |                                |
  |-- GET /api/resource ------------>|                                |
  |   Authorization: Payment {       |                                |
  |     payload: { message, sig }    |                                |
  |   }                              |                                |
  |                                  |  1. Verify SIWE signature      |
  |                                  |  2. lookupHuman(address) ----->|
  |                                  |  3. <-- humanId ---------------|
  |                                  |  4. AccessPolicy::evaluate()   |
  |                                  |  5. Return receipt             |
  |                                  |                                |
  |<-- 200 + Payment-Receipt -------|                                |
  |    { method: "agentkit",         |                                |
  |      reference: "<human_id>" }   |                                |

The library handles steps 1-3 (SIWE + AgentBook). Step 4 is yours via the AccessPolicy trait.

Server

Basic setup

use mpp::server::Mpp;
use mpp_agentkit::{AgentKitConfig, AgentKitMethod, AllowAll};

// Any registered agent gets access, no limits.
let method = AgentKitMethod::new(AgentKitConfig::default_mainnet(), AllowAll);
let mpp = Mpp::new(method, "api.example.com", "my-secret");

// In your handler:
// - No credential → mpp generates a 402 challenge
// - Valid credential → mpp calls AgentKitMethod::verify() → receipt

With a free trial quota

use mpp_agentkit::{AgentKitConfig, AgentKitMethod, FreeTrial, InMemoryUsageTracker};

// 10 uses per human, tracked in memory.
let policy = FreeTrial::new(InMemoryUsageTracker::new(), 10);
let method = AgentKitMethod::new(AgentKitConfig::default_mainnet(), policy);

Custom access policy

Implement AccessPolicy to define your own logic:

use mpp_agentkit::{AccessPolicy, VerifiedAgent, PolicyDecision};

#[derive(Clone)]
struct PremiumOnly {
    db: MyDatabase,
}

impl AccessPolicy for PremiumOnly {
    async fn evaluate(&self, agent: &VerifiedAgent) -> PolicyDecision {
        if self.db.is_premium(&agent.human_id_hex).await {
            PolicyDecision::Allow
        } else {
            PolicyDecision::Deny("Premium subscription required".into())
        }
    }
}

let method = AgentKitMethod::new(config, PremiumOnly { db });

The VerifiedAgent you receive is guaranteed to have:

  • address — recovered from a valid SIWE signature
  • human_id — non-zero value from AgentBook.lookupHuman()
  • chain_id — the chain used for the lookup

You decide what to do with it.

Mock mode

For local development without on-chain access:

let method = AgentKitMethod::new(config, AllowAll)
    .with_mock_mode(true);

In mock mode, AgentBook.lookupHuman() is skipped and the human ID is derived from keccak256(address). SIWE signature verification still runs.

Client

Agent setup

use mpp::client::Fetch;
use mpp_agentkit::AgentKitProvider;
use alloy::signers::local::PrivateKeySigner;

let signer = PrivateKeySigner::random();
let provider = AgentKitProvider::new(signer, 480); // 480 = World Chain

// Automatic 402 handling:
let response = reqwest::Client::new()
    .get("https://api.example.com/resource")
    .send_with_payment(&provider)
    .await?;

// The provider automatically:
// 1. Detects the 402 + method="agentkit" challenge
// 2. Extracts AgentKitRequest from ChargeRequest.method_details
// 3. Builds a SIWE message with the challenge nonce/domain
// 4. Signs with the agent's wallet
// 5. Retries the request with the credential

With MultiProvider (agentkit + tempo fallback)

use mpp::client::MultiProvider;

let provider = MultiProvider::new()
    .with(AgentKitProvider::new(signer.clone(), 480))
    .with(TempoProvider::new(signer, rpc_url)?);

// Prefers agentkit (free) when available, falls back to tempo (paid).

Architecture

mpp-agentkit/
  src/
    lib.rs                    Re-exports, feature gates
    types.rs                  AgentKitRequest, AgentKitPayload, AgentKitConfig
    contracts.rs              IAgentBook sol! bindings

    server/
      method.rs               AgentKitMethod<P: AccessPolicy> → ChargeMethod
      verify.rs               SIWE verification + AgentBook lookup
      policies/
        allow_all.rs          AllowAll policy
        free_trial.rs         FreeTrial<U: UsageTracker> policy
        usage.rs              UsageTracker trait + InMemoryUsageTracker

    client/
      provider.rs             AgentKitProvider<S: Signer> → PaymentProvider

Responsibility split

Layer Owns
mpp crate 402 formatting, HMAC challenge binding, credential parsing, receipt formatting
mpp-agentkit SIWE verification, AgentBook lookup, AccessPolicy dispatch
Your server Route definitions, challenge construction, policy implementation

Types

AgentKitRequest (in the 402 challenge)

pub struct AgentKitRequest {
    pub domain: String,         // Domain for SIWE message binding
    pub chain_id: u64,          // EIP-155 chain ID for AgentBook lookup
    pub nonce: String,          // Server-generated nonce (min 8 chars)
    pub max_uses: Option<u64>,  // Informational: per-human quota
}

Nested in ChargeRequest.method_details in the 402 challenge.

AgentKitPayload (in the credential)

pub struct AgentKitPayload {
    pub message: String,    // Full SIWE message (EIP-4361)
    pub signature: String,  // Hex-encoded 65-byte EIP-191 signature
}

VerifiedAgent (after verification)

pub struct VerifiedAgent {
    pub address: Address,          // Recovered from SIWE
    pub human_id: FixedBytes<32>,  // From AgentBook (nullifier hash)
    pub human_id_hex: String,      // Hex-encoded for storage keys
    pub chain_id: u64,             // Chain used for lookup
}

AccessPolicy trait

pub trait AccessPolicy: Clone + Send + Sync + 'static {
    fn evaluate(&self, agent: &VerifiedAgent) -> impl Future<Output = PolicyDecision> + Send;
    fn on_access(&self, _agent: &VerifiedAgent) -> impl Future<Output = ()> + Send { async {} }
}

pub enum PolicyDecision {
    Allow,
    Deny(String),
}

AgentBook contracts

Chain Address
World Chain (480) 0xA23aB2712eA7BBa896930544C7d6636a96b944dA
Base mainnet (8453) 0xE1D1D3526A6FAa37eb36bD10B933C1b77f4561a4
Base Sepolia (84532) 0xA23aB2712eA7BBa896930544C7d6636a96b944dA

Features

Feature Default Description
server yes Server-side verification. Pulls in siwe for EIP-191 recovery.
client yes Client-side SIWE signing. Only needs alloy signers.

License

MIT OR Apache-2.0

About

World Agent Kit Library for the Machine Payments Protocol

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages