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
12 changes: 12 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copy to .env and fill in. Never commit .env.
#
# RPCs
RPC_BASE_SEPOLIA=https://sepolia.base.org
RPC_OP_SEPOLIA=https://sepolia.optimism.io
RPC_LUX_TESTNET=https://api.lux-test.network/ext/bc/C/rpc

# Deployer key — testnet only, NEVER mainnet keys here
DEPLOYER_PRIVATE_KEY=0x0000000000000000000000000000000000000000000000000000000000000000

# Etherscan / Basescan multichain key (used for verification)
ETHERSCAN_API_KEY=replace-me
48 changes: 48 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI

on:
push:
branches: [master, main]
pull_request:

jobs:
forge:
name: forge test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: foundry-rs/foundry-toolchain@v1
with:
version: stable

- name: Install OZ + forge-std
run: |
forge install foundry-rs/forge-std --shallow
forge install OpenZeppelin/openzeppelin-contracts@v5.0.2 --shallow

- run: forge build --sizes
- run: forge test -vv

pytest:
name: pytest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install package + test deps
run: |
python -m pip install --upgrade pip
python -m pip install -e '.[dev]'

- name: Collect tests (must succeed)
run: pytest tests/ --collect-only -q

- name: Run tests
run: pytest tests/ -v
56 changes: 56 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Publish to PyPI

on:
push:
tags:
- "v*"
workflow_dispatch:

# OIDC trusted-publishing requires id-token: write at the job level.
permissions:
contents: read

jobs:
build:
name: Build sdist + wheel
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install build deps
run: |
python -m pip install --upgrade pip
python -m pip install build

- name: Build
run: python -m build

- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/

publish:
name: Publish to PyPI
needs: build
runs-on: ubuntu-latest
# Restrict to tag pushes — manual dispatch builds but does not publish
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
environment:
name: pypi
url: https://pypi.org/p/switchboard-agent
permissions:
id-token: write # OIDC trusted publishing
steps:
- uses: actions/download-artifact@v4
with:
name: dist
path: dist/

- name: Publish to PyPI (OIDC)
uses: pypa/gh-action-pypi-publish@release/v1
# No password / token — uses OIDC trusted-publishing config on PyPI side.
38 changes: 38 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Foundry
out/
cache/
broadcast/
lib/

# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
*.egg-info/
*.egg
.pytest_cache/
.tox/
.coverage
htmlcov/
.venv/
venv/
env/

# Env / secrets
.env
.env.*
!.env.example

# Editors / OS
.vscode/
.idea/
.DS_Store
*.swp
58 changes: 58 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
.PHONY: install build test clean fmt deploy-base-sepolia deploy-op-sepolia deploy-lux-testnet verify-base-sepolia

# ── Setup ──────────────────────────────────────────────────────────────────

install:
forge install

build:
forge build

clean:
forge clean

fmt:
forge fmt

test:
forge test -vv

# ── Deploy ─────────────────────────────────────────────────────────────────
# Each target loads .env, then runs the Deploy script with --broadcast --verify.
# Override RPC with RPC_<CHAIN>_OVERRIDE=... if you need a private endpoint.

deploy-base-sepolia:
@test -f .env || (echo ".env not found — copy .env.example" && exit 1)
. ./.env && forge script script/Deploy.s.sol:Deploy \
--rpc-url $$RPC_BASE_SEPOLIA \
--broadcast \
--verify \
--etherscan-api-key $$ETHERSCAN_API_KEY \
-vvv

deploy-op-sepolia:
@test -f .env || (echo ".env not found — copy .env.example" && exit 1)
. ./.env && forge script script/Deploy.s.sol:Deploy \
--rpc-url $$RPC_OP_SEPOLIA \
--broadcast \
--verify \
--etherscan-api-key $$ETHERSCAN_API_KEY \
-vvv

deploy-lux-testnet:
@test -f .env || (echo ".env not found — copy .env.example" && exit 1)
. ./.env && forge script script/Deploy.s.sol:Deploy \
--rpc-url $$RPC_LUX_TESTNET \
--broadcast \
--legacy \
-vvv

# ── Verify (re-run if --verify failed during deploy) ───────────────────────

verify-base-sepolia:
@test -n "$(ADDRESS)" || (echo "usage: make verify-base-sepolia ADDRESS=0x..." && exit 1)
. ./.env && forge verify-contract \
--chain-id 84532 \
--etherscan-api-key $$ETHERSCAN_API_KEY \
--constructor-args $$(cast abi-encode "constructor(uint256)" 84532) \
$(ADDRESS) contracts/AgentEscrow.sol:AgentEscrow
31 changes: 27 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,35 @@ Open issues with [`good first issue`](https://github.com/kcolbchain/switchboard/
## Install

```bash
pip install -e .
# optional, for ZAP binary wire:
pip install 'luxfi-zap @ git+https://github.com/luxfi/zap@main#subdirectory=python'
pip install switchboard-agent # PyPI distribution name
# import name stays `switchboard`:
# from switchboard.x402_middleware import X402Middleware

# Optional extras:
pip install 'switchboard-agent[fastapi]' # FastAPI middleware deps
pip install 'switchboard-agent[flask]' # Flask middleware deps
pip install 'switchboard-agent[zap]' # ZAP binary wire (luxfi/zap)
pip install 'switchboard-agent[all]' # everything
```

Python 3.11+. Tests: `pytest tests/`.
Python 3.11+. Tests: `pytest tests/`. Solidity tests: `forge test` (see [Foundry setup](#foundry--on-chain-deployment) below).

### Foundry / on-chain deployment

`AgentEscrow.sol` ships with a Foundry scaffold for testnet deploys:

```bash
forge install # pulls OpenZeppelin + forge-std
forge build
forge test -vv

# Copy .env.example → .env, then:
make deploy-base-sepolia # 84532
make deploy-op-sepolia # 11155420
make deploy-lux-testnet # 96368
```

Deployed addresses go into `switchboard/registry.json` (chainId-keyed).

---

Expand Down
Loading