Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions examples/tempo-payments-python/.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
E2B_API_KEY=your_e2b_api_key
# Your Tempo private key (from ~/.tempo/wallet/keys.toml, the "key" field)
# If not set, the example will copy your local keys.toml into the sandbox instead
TEMPO_PRIVATE_KEY=your_tempo_private_key
# Optional: set this after first build to skip rebuilding
# E2B_TEMPO_TEMPLATE_ID=
40 changes: 40 additions & 0 deletions examples/tempo-payments-python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# E2B + Tempo: Autonomous Agent Payments

This example shows how to run an AI agent inside an [E2B sandbox](https://e2b.dev) that can autonomously pay for API services using [Tempo's Machine Payments Protocol (MPP)](https://tempo.xyz).

The agent makes a paid web search request — Tempo handles the stablecoin payment automatically via HTTP 402 challenge-response.

## How it works

1. A custom sandbox template is built with Tempo CLI and pympp pre-installed
2. Your Tempo wallet keys are injected at runtime (never baked into the image)
3. The agent calls a paid API → Tempo handles the 402 payment → agent gets the response

## Setup & run

### 1. Install dependencies
```
poetry install
```

### 2. Set up Tempo wallet
```bash
curl -fsSL https://tempo.xyz/install | bash
tempo wallet login
tempo wallet fund
```

### 3. Set up `.env`
1. Copy `.env.template` to `.env`
2. Add your [E2B API key](https://e2b.dev/docs/getting-started/api-key)

### 4. Run the example
```
poetry run start
```

On first run, the template will be built automatically (~1-2 min). Subsequent runs use the cached template.

## Available services

100+ MPP-compatible services at [mpp.dev/services](https://mpp.dev/services) including web search, blockchain data, image generation, browser automation, and more.
73 changes: 73 additions & 0 deletions examples/tempo-payments-python/e2b_tempo/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import os
from pathlib import Path
from dotenv import load_dotenv
from e2b import Sandbox, Template

load_dotenv()

KEYS_TOML = Path.home() / ".tempo" / "wallet" / "keys.toml"


def build_template():
"""Build a custom sandbox template with Tempo pre-installed."""
template = (
Template()
.from_python_image("3.12")
.apt_install(["curl", "ca-certificates"])
.run_cmd("curl -fsSL https://tempo.xyz/install | bash")
.run_cmd("/home/user/.tempo/bin/tempo add request")
.pip_install(["pympp"])
)

info = Template.build(
template,
"e2b-tempo",
on_build_logs=lambda log: print(log.message, end=""),
)

print(f"\nTemplate built: {info.template_id}")
return info.template_id


def main():
template_id = os.environ.get("E2B_TEMPO_TEMPLATE_ID")
if not template_id:
print("No E2B_TEMPO_TEMPLATE_ID found, building template...")
template_id = build_template()

tempo_private_key = os.environ.get("TEMPO_PRIVATE_KEY")

sandbox = Sandbox.create(template=template_id)
print(f"Sandbox started: {sandbox.sandbox_id}")

try:
if tempo_private_key:
# Use private key directly via --private-key flag
key_flag = f"--private-key {tempo_private_key}"
elif KEYS_TOML.exists():
# Fallback: copy local keys.toml into the sandbox
keys_content = KEYS_TOML.read_text()
sandbox.files.write("/home/user/.tempo/wallet/keys.toml", keys_content)
key_flag = ""
else:
raise RuntimeError(
"Set TEMPO_PRIVATE_KEY in .env or run 'tempo wallet login' first"
)

# Make a paid API call from inside the sandbox
result = sandbox.commands.run(
'export PATH="$HOME/.tempo/bin:$PATH" && '
f"tempo request {key_flag} "
'-X POST --json \'{"query":"latest AI news"}\' '
"https://parallelmpp.dev/api/search"
)
print("Search results:", result.stdout)
except Exception as e:
print(f"Error: {e}")
finally:
sandbox.kill()
print("Sandbox destroyed.")


if __name__ == "__main__":
main()
19 changes: 19 additions & 0 deletions examples/tempo-payments-python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[tool.poetry]
name = "e2b-tempo"
version = "0.1.0"
description = "E2B sandbox with autonomous Tempo payments via MPP"
authors = ["Max Hager"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"
e2b = "^2.20.0"
pympp = "^0.6.0"
python-dotenv = "^1.0.1"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.scripts]
start = "e2b_tempo.main:main"