Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
cab80a6
feat(bridge-sdk): scaffold aleo-bridge-sdk with error taxonomy and ex…
iamalwaysuncomfortable Sep 16, 2026
a4f8a38
feat(bridge-sdk): vendor keccak-256 and base58 primitives
iamalwaysuncomfortable Sep 16, 2026
3d68bb4
feat(bridge-sdk): wire encoders — bech32m, hyperlane limbs, xReserve …
iamalwaysuncomfortable Sep 16, 2026
fb78ab8
feat(bridge-sdk): pinned veil registry (7 chains, 19 assets, 22 route…
iamalwaysuncomfortable Sep 16, 2026
ece5668
feat(bridge-sdk): status enum, plan/receipt/progress and result datac…
iamalwaysuncomfortable Sep 16, 2026
de45ad8
fix(bridge-sdk): derive Progress.error for failed transfers and expor…
iamalwaysuncomfortable Sep 16, 2026
4550d94
feat(bridge-sdk): AleoCall verb ladder with checkpointable delegate a…
iamalwaysuncomfortable Sep 16, 2026
8e12bcc
fix(bridge-sdk): narrow duplicate-broadcast detection and document co…
iamalwaysuncomfortable Sep 16, 2026
c3e18e9
feat(bridge-sdk): Aleo-origin Hyperlane transfer_remote, IGP quote an…
iamalwaysuncomfortable Sep 16, 2026
8180a5b
fix(bridge-sdk): stop test_import_without_optional_extras leaking rei…
iamalwaysuncomfortable Sep 16, 2026
f64ae42
feat(bridge-sdk): xReserve burn and private_mint builders, Circle att…
iamalwaysuncomfortable Sep 16, 2026
b83f625
fix(bridge-sdk): wrap Circle transport and JSON failures in Attestati…
iamalwaysuncomfortable Sep 17, 2026
340e238
feat(bridge-sdk): Sealance freeze-list Merkle tree and exclusion proofs
iamalwaysuncomfortable Sep 17, 2026
ecefb1f
feat(bridge-sdk): shield/unshield for ARC-20 and ARC-22 assets with r…
iamalwaysuncomfortable Sep 17, 2026
eff3201
fix(bridge-sdk): reject mismatched recipient on ARC-20 unshield
iamalwaysuncomfortable Sep 17, 2026
8b3d726
feat(bridge-sdk): Bridge client with from_env/from_profile/status, Al…
iamalwaysuncomfortable Sep 17, 2026
77992bd
fix(bridge-sdk): read the USDCx freeze list from usdcx_freezelist.ale…
iamalwaysuncomfortable Sep 17, 2026
2bfd6b7
fix(bridge-sdk): mapping_value returns None for a missing program
iamalwaysuncomfortable Sep 17, 2026
326175d
test(bridge-sdk): gated read-only live checks (IGP quotes, mailbox an…
iamalwaysuncomfortable Sep 17, 2026
a7a45d3
feat(bridge-sdk): version-1 checkpoint allowlist and FileCheckpointStore
iamalwaysuncomfortable Sep 17, 2026
75052af
feat(bridge-sdk): Ethereum connection with three signer forms and fak…
iamalwaysuncomfortable Sep 17, 2026
41ecd18
feat(bridge-sdk): EvmCall step runner with pre-poll checkpoints, EVM …
iamalwaysuncomfortable Sep 17, 2026
794a7d1
fix(bridge-sdk): AleoCall.__repr__ no longer leaks record/nonce literals
iamalwaysuncomfortable Sep 17, 2026
56fad46
fix(bridge-sdk): Receipt.replace copies its dicts; to_progress raises…
iamalwaysuncomfortable Sep 17, 2026
2d85e45
fix(bridge-sdk): freeze-list root check is fatal when unreadable
iamalwaysuncomfortable Sep 17, 2026
157978c
fix(bridge-sdk): profile creation is exclusive (O_EXCL); home dir mod…
iamalwaysuncomfortable Sep 17, 2026
87b1676
fix(bridge-sdk): xreserve.burn validates mode before touching chain s…
iamalwaysuncomfortable Sep 17, 2026
4fdc2d8
fix(bridge-sdk): triaged minors from the plan-1 review
iamalwaysuncomfortable Sep 17, 2026
6afbadf
test(bridge-sdk): prove eth.py fee arithmetic, legacy gasPrice path, …
iamalwaysuncomfortable Sep 17, 2026
f92e13c
feat(bridge-sdk): eth.quote_transfer_remote with native/collateral fe…
iamalwaysuncomfortable Sep 17, 2026
748f75b
feat(bridge): eth.transfer_remote with approval reset, DispatchId mes…
iamalwaysuncomfortable Sep 17, 2026
0f8acfc
feat(bridge): eth.quote_deposit_usdc with hook data, wrapper-program …
iamalwaysuncomfortable Sep 17, 2026
b672919
fix(bridge-sdk): validate Hyperlane route metadata before contract ca…
iamalwaysuncomfortable Sep 17, 2026
c8687fb
fix(bridge-sdk): validate xReserve route metadata before contract calls
iamalwaysuncomfortable Sep 17, 2026
cfe3100
feat(bridge): eth.deposit_usdc with DepositedToRemote re-verification…
iamalwaysuncomfortable Sep 17, 2026
5729f46
feat(bridge-sdk): eth.source_status for approval and confirming branc…
iamalwaysuncomfortable Sep 17, 2026
075655b
feat(bridge-sdk): eth.recover_source log-scan recovery for Hyperlane …
iamalwaysuncomfortable Sep 17, 2026
f3f8c9d
feat(bridge-sdk): Bridge.eth, bare Web3 wrapping, EVM env vars in fro…
iamalwaysuncomfortable Sep 17, 2026
ed308c6
test(bridge-sdk): live Ethereum read checks and gated Sepolia USDC le…
iamalwaysuncomfortable Sep 17, 2026
c33f2a3
docs(bridge-sdk): document bridge.eth in the README Ethereum section
iamalwaysuncomfortable Sep 17, 2026
1b67563
fix(bridge-sdk): recover_source required semantics, chain-checked sta…
iamalwaysuncomfortable Sep 17, 2026
361ff91
feat(bridge-sdk): sealevel TransferRemote instruction data with veil'…
iamalwaysuncomfortable Sep 17, 2026
58ac424
test(bridge-sdk): leg-1 state files follow the rehearsal convention; …
iamalwaysuncomfortable Sep 17, 2026
1afbb69
feat(bridge-sdk): decode sealevel IGP accounts and quote the lamport …
iamalwaysuncomfortable Sep 17, 2026
4103b93
feat(bridge-sdk): sealevel route metadata, pure PDA derivation, and t…
iamalwaysuncomfortable Sep 17, 2026
6b6553a
feat(bridge-sdk): Solana sync JSON-RPC transport and connection (rpc_…
iamalwaysuncomfortable Sep 17, 2026
68e19e0
fix(bridge-sdk): DispatchId must come from the route's mailbox; xRese…
iamalwaysuncomfortable Sep 17, 2026
87a1adb
fix(bridge-sdk): a checkpoint-store failure after broadcast never los…
iamalwaysuncomfortable Sep 17, 2026
a3d3c5d
feat(bridge-sdk): plan-driven transfer_remote/deposit_usdc and quote …
iamalwaysuncomfortable Sep 17, 2026
a1aa976
fix(bridge-sdk): bounded, chunked and wrapped recovery log scans
iamalwaysuncomfortable Sep 17, 2026
d8bfde1
fix(bridge-sdk): native fee decimals, validated mailbox lookup, match…
iamalwaysuncomfortable Sep 17, 2026
73591c6
docs(bridge-sdk): note BRIDGE_LIVE_ETHEREUM_RPC_URL is an ordinary fr…
iamalwaysuncomfortable Sep 17, 2026
a8ef703
refactor(bridge-sdk): promote _plan_for to _plan.build_plan with a ch…
iamalwaysuncomfortable Sep 17, 2026
4cf603e
feat(bridge-sdk): SolModule quote — IGP payment, network fee, rent an…
iamalwaysuncomfortable Sep 17, 2026
9249dce
feat(bridge-sdk): SolCall — partial sign, fee-payer signature, broadc…
iamalwaysuncomfortable Sep 17, 2026
3a77bc0
feat(bridge-sdk): Solana SOURCE_CONFIRMING status refresh with blockh…
iamalwaysuncomfortable Sep 17, 2026
448351e
feat(bridge-sdk): wire the Solana connection into Bridge (sol propert…
iamalwaysuncomfortable Sep 17, 2026
7a7c2aa
fix(bridge-sdk): SolCall polling — EXPIRED only without a status; log…
iamalwaysuncomfortable Sep 17, 2026
f34e3a1
test(bridge-sdk): gated live Solana reads (IGP decode, leg 11 quote) …
iamalwaysuncomfortable Sep 17, 2026
38fc1db
feat(bridge): pure prepare() planner with veil step lists and route r…
iamalwaysuncomfortable Sep 17, 2026
ebee929
feat(bridge-sdk): quote() dispatch over protocol modules + duck-typed…
iamalwaysuncomfortable Sep 17, 2026
02391c7
fix(bridge-sdk): never lose a broadcast id, and verify the node echoe…
iamalwaysuncomfortable Sep 17, 2026
f6ce2c1
fix(bridge-sdk): a call is single-use once it has broadcast
iamalwaysuncomfortable Sep 17, 2026
6c86e0d
fix(bridge-sdk): a Solana status row with no confirmation level is pr…
iamalwaysuncomfortable Sep 17, 2026
9f67ee3
fix(bridge-sdk): coerce solana= like ethereum=, and derive the status…
iamalwaysuncomfortable Sep 17, 2026
02ebe97
fix(bridge-sdk): close Solana transports properly and never raise fro…
iamalwaysuncomfortable Sep 17, 2026
19797dc
fix(bridge-sdk): keep the key out of tracebacks, re-resolve the route…
iamalwaysuncomfortable Sep 17, 2026
df5d34a
docs(bridge-sdk): document the Solana env aliases; drop two dead decl…
iamalwaysuncomfortable Sep 17, 2026
43d0934
fix(bridge-sdk): name the missing recipient, and validate log_scan_ch…
iamalwaysuncomfortable Sep 17, 2026
8231783
feat(bridge-sdk): execute() with prove->checkpoint->broadcast Aleo le…
iamalwaysuncomfortable Sep 17, 2026
fa8553d
fix(bridge-sdk): arm the single-use guard on an echoed-hash mismatch;…
iamalwaysuncomfortable Sep 17, 2026
5b7e954
feat(bridge-sdk): get_status() branch table incl. nullifier-first inb…
iamalwaysuncomfortable Sep 17, 2026
682a199
fix(bridge-sdk): save-then-delete checkpoints, gate Aleo legs on the …
iamalwaysuncomfortable Sep 18, 2026
f33edd7
feat(bridge-sdk): wait() with caller boundaries, until, transient-err…
iamalwaysuncomfortable Sep 18, 2026
cfc4479
fix(bridge-sdk): stop _message_id aliasing source tx hashes and stop …
iamalwaysuncomfortable Sep 18, 2026
2b46d1c
feat(bridge-sdk): recover() rebuilds progress from checkpoints withou…
iamalwaysuncomfortable Sep 18, 2026
5b5ca47
fix(bridge-sdk): let get_status see a failing destination-balance read
iamalwaysuncomfortable Sep 18, 2026
ec0038a
feat(bridge-sdk): resume() and complete() - idempotent rebroadcast, p…
iamalwaysuncomfortable Sep 18, 2026
cef3230
fix(bridge-sdk): recover() rejects malformed deliveryVerification and…
iamalwaysuncomfortable Sep 18, 2026
7f15242
feat(bridge-sdk): Bridge lifecycle methods, pending(), and additive p…
iamalwaysuncomfortable Sep 18, 2026
644f6de
fix(bridge-sdk): resume requires the checkpointed xReserve hook; comp…
iamalwaysuncomfortable Sep 18, 2026
7e646e4
feat(bridge-sdk): agent tools over the lifecycle verbs with confirm-g…
iamalwaysuncomfortable Sep 18, 2026
d841db4
fix(bridge-sdk): pending() is offline; Bridge.wait forwards the retry…
iamalwaysuncomfortable Sep 18, 2026
a7d69f1
fix(bridge-sdk): agent tools return checkpoints from reads, redact re…
iamalwaysuncomfortable Sep 18, 2026
59a88b4
feat(bridge-sdk): MCP stdio server over the agent tools
iamalwaysuncomfortable Sep 18, 2026
a5ea78e
feat(bridge-sdk): generate AGENTS.md from docstrings; python -m aleo_…
iamalwaysuncomfortable Sep 18, 2026
b87883a
test(bridge-sdk): live harness config/helpers ported from veil, with …
iamalwaysuncomfortable Sep 18, 2026
a2df678
feat(bridge-sdk): live cases + rehearse CLI over the public lifecycle…
iamalwaysuncomfortable Sep 18, 2026
681a107
docs(bridge-sdk): README section for the live tests
iamalwaysuncomfortable Sep 18, 2026
ef6c270
fix(bridge-sdk): veil parity for the live cases — source confirmation…
iamalwaysuncomfortable Sep 18, 2026
33aadd6
test(bridge-sdk): live lifecycle suite over every route, back and forth
iamalwaysuncomfortable Sep 18, 2026
07ed2a2
docs(bridge-sdk): live-test commands, and PyNaCl is a base dependency
iamalwaysuncomfortable Sep 18, 2026
f4361a2
docs(bridge-sdk): rewrite README for the full lifecycle SDK, agent/MC…
iamalwaysuncomfortable Sep 18, 2026
fa05da5
ci: add build-bridge and release-bridge jobs for aleo-bridge-sdk
iamalwaysuncomfortable Sep 18, 2026
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
79 changes: 73 additions & 6 deletions .github/workflows/sdk-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
- 'sdk/**'
- 'sdk-abi/**'
- 'shield-swap-sdk/**'
- 'bridge-sdk/**'
- '.github/workflows/sdk-wheels.yml'
- '.github/workflows/sdk.yml'
branches:
Expand All @@ -18,6 +19,7 @@ on:
- 'sdk/**'
- 'sdk-abi/**'
- 'shield-swap-sdk/**'
- 'bridge-sdk/**'
- '.github/workflows/sdk-wheels.yml'
- '.github/workflows/sdk.yml'
workflow_dispatch:
Expand Down Expand Up @@ -271,17 +273,62 @@ jobs:
name: shield-swap-wheels-universal
path: shield-swap-sdk/dist

# aleo-bridge-sdk is pure Python (hatchling): one universal wheel + sdist.
# Tested against the built aleo-sdk wheel; installed WITH every extra for the
# suite and WITHOUT extras for the import smoke — an Aleo-only install must
# import (extras raise MissingExtraError at the point of use, never at import).
# Only the hermetic suite runs here (`-m "not live"`): no key, no live RPC.
build-bridge:
name: bridge-build
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- uses: actions/download-artifact@v4
with:
name: wheels-linux-x86_64
path: sdk-dist
- name: Build wheel + sdist
run: |
pip install build
python -m build bridge-sdk --outdir bridge-sdk/dist
- name: Test against the built aleo-sdk wheel (all extras, hermetic only)
run: |
pip install sdk-dist/aleo_sdk-*.whl
pip install "$(ls bridge-sdk/dist/*.whl)[evm,solana,mcp]" pytest pytest-asyncio
cd bridge-sdk && python -m pytest -q -m "not live"
- name: AGENTS.md up to date
run: python bridge-sdk/codegen/gen_context.py --check
- name: Smoke test wheel with extras
run: |
cd "$RUNNER_TEMP"
python -c "import aleo_bridge, aleo_bridge.eth, aleo_bridge.sol, aleo_bridge.mcp; print('aleo-bridge-sdk', aleo_bridge.__version__)"
python -m aleo_bridge | head -1
- name: Smoke test wheel WITHOUT extras
run: |
pip uninstall -y aleo-bridge-sdk web3 eth-account solders solana mcp
pip install "$(ls bridge-sdk/dist/*.whl)"
python -c "import aleo_bridge; from aleo_bridge import Bridge, Ethereum, Solana, DEFAULT_REGISTRY; print(len(DEFAULT_REGISTRY.routes(include_unavailable=True, environment=None)), 'routes')"
- name: Upload wheel
uses: actions/upload-artifact@v4
with:
name: bridge-wheels-universal
path: bridge-sdk/dist

# Publishing uses PyPI trusted publishing (OIDC) — no token secret. Each
# package has its own job because a pending publisher must be unique per
# (repo, workflow, environment): the job's environment name must exactly
# match the publisher registered on PyPI for that project. All three gate
# on every build job, and they release strictly in dependency order:
# abi -> sdk -> shield-swap (shield-swap-sdk requires aleo-sdk on PyPI).
# match the publisher registered on PyPI for that project. All gate on
# every build job, and they release strictly in dependency order:
# abi -> sdk -> shield-swap / bridge (both require aleo-sdk on PyPI).
release-abi:
name: Release aleo-contract-abi-generator
runs-on: ubuntu-latest
if: "startsWith(github.ref, 'refs/tags/')"
needs: [build, sdist, build-abi, sdist-abi, build-shield-swap]
needs: [build, sdist, build-abi, sdist-abi, build-shield-swap, build-bridge]
environment: pypi-abi
permissions:
id-token: write
Expand All @@ -301,7 +348,7 @@ jobs:
name: Release aleo-sdk
runs-on: ubuntu-latest
if: "startsWith(github.ref, 'refs/tags/')"
needs: [build, sdist, build-abi, sdist-abi, build-shield-swap, release-abi]
needs: [build, sdist, build-abi, sdist-abi, build-shield-swap, build-bridge, release-abi]
environment: pypi
permissions:
id-token: write
Expand All @@ -321,7 +368,7 @@ jobs:
name: Release shield-swap-sdk
runs-on: ubuntu-latest
if: "startsWith(github.ref, 'refs/tags/')"
needs: [build, sdist, build-abi, sdist-abi, build-shield-swap, release-sdk]
needs: [build, sdist, build-abi, sdist-abi, build-shield-swap, build-bridge, release-sdk]
environment: pypi-shield-swap
permissions:
id-token: write
Expand All @@ -336,3 +383,23 @@ jobs:
with:
packages-dir: dist
skip-existing: true

release-bridge:
name: Release aleo-bridge-sdk
runs-on: ubuntu-latest
if: "startsWith(github.ref, 'refs/tags/')"
needs: [build, sdist, build-abi, sdist-abi, build-shield-swap, build-bridge, release-sdk]
environment: pypi-bridge
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
pattern: 'bridge-wheels-*'
merge-multiple: true
path: dist
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist
skip-existing: true
5 changes: 5 additions & 0 deletions bridge-sdk/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.venv/
dist/
__pycache__/
.pytest_cache/
*.egg-info/
Loading
Loading