brawny
Block-driven Ethereum job and transaction execution framework, inspired by eth-brownie.
Brownie-style ergonomics: brawny mirrors Brownie's developer experience with familiar patterns—accounts, Contract(), chain, history, and an interactive console. If you've used Brownie, you'll feel right at home.
Installation (Local Development)
# Clone and install the framework
git clone https://github.com/yearn/brawny.git
cd brawny
pip install -e .
Quick Start
# Create a new keeper project
mkdir my-keeper && cd my-keeper
brawny init
# Install your project (brawny is already installed from above)
pip install -e .
# Configure
cp .env.example .env
# Edit .env: set RPC_URL and BRAWNY_KEYSTORE_PASSWORD_WORKER
# Import a signer key (will prompt for password)
brawny accounts import --name worker --private-key 0xYOUR_PRIVATE_KEY
# Run
brawny start
See docs/quickstart.md for a longer walkthrough.
Project Structure
After brawny init, your project looks like:
my-keeper/
├── my_keeper/ # Your Python package
│ └── __init__.py
├── jobs/
│ ├── __init__.py
│ └── _examples.py # Reference implementations (not registered)
├── interfaces/ # Place ABI JSON files here
├── monitoring/ # Prometheus + Grafana stack
│ ├── docker-compose.yml
│ └── grafana/...
├── pyproject.toml
├── config.yaml
├── .env.example
├── .gitignore
└── AGENTS.md # AI agent guide for writing jobs
The AGENTS.md file contains a comprehensive guide for AI agents to generate correct, idiomatic jobs.
Minimal Job Example
Create jobs/harvester.py:
from brawny import Job, job, Contract, trigger, intent, block
@job(signer="worker")
class HarvestJob(Job):
name = "Harvest Example"
check_interval_blocks = 50
vault_address = "0xYourVault"
def check(self):
vault = Contract(self.vault_address)
pending = vault.pendingRewards()
if pending > 1_000_000_000_000_000_000:
return trigger(
reason="Harvest pending rewards",
data={"pending": pending},
idempotency_parts=[block.number // 50],
)
return None
def build_intent(self, trig):
vault = Contract(self.vault_address)
return intent(
signer_address=self._signer_name,
to_address=self.vault_address,
data=vault.harvest.encode_input(),
min_confirmations=2,
)
def alert_triggered(self, ctx):
return f"Harvest triggered: {ctx.trigger.data['pending'] / 1e18:.4f}"
def alert_confirmed(self, ctx):
return f"Harvest confirmed: {ctx.tx.hash}"
Docs
docs/quickstart.mddocs/cli.mddocs/job-lifecycle.mddocs/alerts.md
Metadata
Release files for brawny 0.1.51
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| brawny-0.1.51.tar.gz | 322.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| brawny-0.1.51-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 711.8 kB
Release files / brawny-0.1.51.tar.gz
| Download URL | brawny-0.1.51.tar.gz |
|---|---|
| Size | 322.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f9d2064609978436ae6d13705c8e0d29051f2bd8c974c5657eed9b4b762fc8d2
|
|
BLAKE2b-256 checksum How to use checksums |
93d6be084cf14df45601210ba39e3bb301ce145fb07e9df8c0b4e9c0c0572f37
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.11
|
Release files / brawny-0.1.51-py3-none-any.whl
| Download URL | brawny-0.1.51-py3-none-any.whl |
|---|---|
| Size | 389.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
56411cd62508f14eef48d05a79987c1c7989a598f15f2b5bbadacb99c7e539a9
|
|
BLAKE2b-256 checksum How to use checksums |
714450d291df2ce8dddb0a8298bb686ddf85d2e4a26d73a35341bb8fb747583e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.11
|