Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
5eaad7a
feat: add end-to-end plan and execution flows across protocols
ggonzalez94 Feb 24, 2026
14b3134
Add Morpho lend execution and Across bridge execution support
ggonzalez94 Feb 24, 2026
2206ee6
Merge origin/main and preserve execution flows
ggonzalez94 Feb 24, 2026
ae26ad9
execution: unify action builders and drop --yes confirmation
ggonzalez94 Feb 25, 2026
27a2d1e
Simplify local signer UX and default sender behavior
ggonzalez94 Feb 25, 2026
7c56f42
execution: harden simulation, signing, and tx broadcast flows
ggonzalez94 Feb 25, 2026
db0f8d4
docs: document execution pre-sign guardrails and endpoint registry
ggonzalez94 Feb 25, 2026
a465c9a
docs: document execution guardrails and endpoint policy
ggonzalez94 Feb 25, 2026
2fb9753
feat(execution): add private-key override and drop actions status alias
ggonzalez94 Feb 25, 2026
bc55243
signer: simplify default key-path UX and error hints
ggonzalez94 Feb 25, 2026
462d217
refactor rpc handling into shared registry and remove taiko-specific …
ggonzalez94 Feb 25, 2026
925fbf9
docs: clarify rpc override scope and keep swap examples neutral
ggonzalez94 Feb 25, 2026
292a017
Merge branch 'chore/basic-execution-safety' into plan-and-execution-f…
ggonzalez94 Feb 25, 2026
3e77c00
feat!: standardize lend/rewards selector on --provider
ggonzalez94 Feb 25, 2026
5a9e993
Merge remote-tracking branch 'origin/main' into plan-and-execution-flows
ggonzalez94 Feb 25, 2026
e47723d
docs: add taiko hoodi alias notes after main merge
ggonzalez94 Feb 25, 2026
cd6df55
add lend positions by address with typed filters
ggonzalez94 Feb 26, 2026
9954c18
breaking: switch morpho yield opportunities to vaults
ggonzalez94 Feb 26, 2026
43c935a
feat(yield): add provider-backed yield history command
ggonzalez94 Feb 26, 2026
c0a2e57
refactor yield opportunities to objective metrics and backing assets
ggonzalez94 Feb 26, 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
19 changes: 19 additions & 0 deletions .github/workflows/nightly-execution-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: nightly-execution-smoke

on:
schedule:
- cron: "0 3 * * *"
workflow_dispatch:

jobs:
execution-smoke:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: execution smoke checks
run: bash scripts/nightly_execution_smoke.sh
66 changes: 45 additions & 21 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ go test -race ./...
go vet ./...

./defi providers list --results-only
./defi lend markets --protocol aave --chain 1 --asset USDC --results-only
./defi lend markets --provider aave --chain 1 --asset USDC --results-only
./defi lend positions --provider aave --chain 1 --address 0x000000000000000000000000000000000000dEaD --type all --limit 3 --results-only
./defi yield opportunities --chain 1 --asset USDC --providers aave,morpho --limit 5 --results-only
./defi lend markets --protocol kamino --chain solana --asset USDC --results-only
./defi swap quote --chain solana --from-asset USDC --to-asset SOL --amount 1000000 --results-only
```

## Folder structure
Expand All @@ -34,11 +33,13 @@ cmd/
internal/
app/runner.go # command wiring, provider routing, cache flow
providers/ # external adapters
aave/ morpho/ kamino/ # direct GraphQL/REST lending + yield
defillama/ # chain/protocol market data + bridge analytics
across/ lifi/ bungee/ # bridge quotes
oneinch/ uniswap/ jupiter/ fibrous/ bungee/ # swap quotes
aave/ morpho/ # direct GraphQL lending + yield
defillama/ # market/yield normalization + fallback + bridge analytics
across/ lifi/ # bridge quotes + lifi execution planning
oneinch/ uniswap/ taikoswap/ # swap quotes + uniswap-v3-compatible execution planning (taikoswap today)
types.go # provider interfaces
execution/ # action persistence + planner helpers + signer abstraction + tx execution
registry/ # canonical execution endpoints/contracts/ABI fragments + default chain RPC map
config/ # defaults + file/env/flags precedence
cache/ # sqlite cache + file lock
id/ # CAIP parsing + amount normalization
Expand All @@ -50,6 +51,7 @@ internal/
httpx/ # shared HTTP client/retry behavior

.github/workflows/ci.yml # CI (test/vet/build)
.github/workflows/nightly-execution-smoke.yml # nightly execution planning drift checks
.github/workflows/release.yml # tagged release pipeline (GoReleaser)
scripts/install.sh # macOS/Linux installer from GitHub Releases
.goreleaser.yml # cross-platform release artifact config
Expand All @@ -64,29 +66,52 @@ README.md # user-facing usage + caveats

- Error output always returns a full envelope, even with `--results-only` or `--select`.
- Config precedence is `flags > env > config file > defaults`.
- `yield --providers` expects provider names (`aave,morpho,kamino`), not protocol categories.
- Lending routes by `--protocol` to direct adapters only (`aave`, `morpho`, `kamino`).
- `yield --providers` expects provider names (`defillama,aave,morpho`), not protocol categories.
- Lending routes by `--provider` use direct protocol adapters (`aave`, `morpho`, `kamino`).
- `lend positions` currently supports `--provider aave|morpho`; `kamino` does not expose positions yet.
- `lend positions --type all` intentionally returns non-overlapping intents (`supply`, `borrow`, `collateral`) for automation-friendly filtering.
- Most commands do not require provider API keys.
- Key-gated routes: `swap quote --provider 1inch` (`DEFI_1INCH_API_KEY`), `swap quote --provider uniswap` (`DEFI_UNISWAP_API_KEY`), `chains assets`, and `bridge list` / `bridge details` via DefiLlama (`DEFI_DEFILLAMA_API_KEY`). `swap quote --provider jupiter` supports `DEFI_JUPITER_API_KEY` optionally (higher limits). `swap quote --provider fibrous` is keyless. Bungee Auto-mode quotes (`bridge quote --provider bungee`, `swap quote --provider bungee`) are keyless by default; optional dedicated-backend mode requires both `DEFI_BUNGEE_API_KEY` and `DEFI_BUNGEE_AFFILIATE`.
- Key-gated routes: `swap quote --provider 1inch` (`DEFI_1INCH_API_KEY`), `swap quote --provider uniswap` (`DEFI_UNISWAP_API_KEY`), `chains assets`, and `bridge list` / `bridge details` via DefiLlama (`DEFI_DEFILLAMA_API_KEY`).
- Multi-provider command paths require explicit selector choice via `--provider`; no implicit defaults.
- TaikoSwap quote/planning does not require an API key; execution uses local signer inputs (`--private-key` override, `DEFI_PRIVATE_KEY{,_FILE}`, or keystore envs) and also auto-discovers `~/.config/defi/key.hex` (or `$XDG_CONFIG_HOME/defi/key.hex`) when present.
- `swap quote` (on-chain quote providers) and execution `plan`/`run` commands support optional `--rpc-url` overrides (`swap`, `bridge`, `approvals`, `lend`, `rewards`); `submit`/`status` use stored action step RPC URLs.
- Swap execution planning validates sender/recipient inputs as EVM hex addresses before building calldata.
- Metadata ownership is split by intent:
- `internal/registry`: canonical execution endpoints/contracts/ABIs and default chain RPC map (used when no `--rpc-url` is provided).
- `internal/providers/*/client.go`: provider quote/read API base URLs.
- `internal/id/id.go`: bootstrap token symbol/address registry for deterministic asset parsing.
- Execution commands currently available:
- `swap plan|run|submit|status`
- `bridge plan|run|submit|status` (Across, LiFi)
- `approvals plan|run|submit|status`
- `lend supply|withdraw|borrow|repay plan|run|submit|status` (Aave, Morpho)
- `rewards claim|compound plan|run|submit|status` (Aave)
- `actions list|show`
- Execution builder architecture is intentionally split:
- `swap`/`bridge` action construction is provider capability based (`BuildSwapAction` / `BuildBridgeAction`) because route payloads are provider-specific.
- `lend`/`rewards`/`approvals` action construction uses internal planners for deterministic contract-call composition.
- All execution `run` / `submit` commands can broadcast transactions.
- Execution pre-sign checks enforce bounded ERC-20 approvals by default; `--allow-max-approval` opts into larger approvals when required.
- Bridge execution pre-sign checks validate provider settlement metadata/endpoints by default; `--unsafe-provider-tx` bypasses these guardrails.
- LiFi bridge quote/plan/run support optional `--from-amount-for-gas` (source token base units reserved for destination native gas top-up).
- Bridge execution status for Across/LiFi waits for destination settlement (`/deposit/status` or `/status`) before marking bridge steps complete.
- Rewards `--assets` expects comma-separated on-chain addresses used by Aave incentives contracts.
- Aave execution has default pool-address-provider coverage for chain IDs `1`, `10`, `137`, `8453`, `42161`, and `43114`; override with `--pool-address` / `--pool-address-provider` otherwise.
- Morpho lend execution requires `--market-id` (Morpho market unique key bytes32).
- Key requirements are command + provider specific; `providers list` is metadata only and should remain callable without provider keys.
- Prefer env vars for provider keys in docs/examples; keep config file usage optional and focused on non-secret defaults.
- `--chain` supports CAIP-2, numeric chain IDs, and aliases; aliases include `mantle`, `megaeth`/`mega eth`/`mega-eth`, `ink`, `scroll`, `berachain`, `gnosis`/`xdai`, `linea`, `sonic`, `blast`, `fraxtal`, `world-chain`, `celo`, `taiko`/`taiko alethia`, `zksync`, `hyperevm`/`hyper evm`/`hyper-evm`, `monad`, and `citrea`.
- `--chain` supports CAIP-2, numeric chain IDs, and aliases; aliases include `mantle`, `megaeth`/`mega eth`/`mega-eth`, `ink`, `scroll`, `berachain`, `gnosis`/`xdai`, `linea`, `sonic`, `blast`, `fraxtal`, `world-chain`, `celo`, `taiko`/`taiko alethia`, `taiko hoodi`/`hoodi`, `zksync`, `hyperevm`/`hyper evm`/`hyper-evm`, `monad`, and `citrea`.
- Bungee Auto quote calls use deterministic placeholder sender/receiver addresses for quote-only mode (`0x000...001`).
- Swap quote type defaults to `exact-input`; `exact-output` currently routes through Uniswap only (`--type exact-output` with `--amount-out` or `--amount-out-decimal`).
- Uniswap quote calls use a deterministic placeholder `swapper` for quote-only mode (`0x000...001`) and default to provider auto slippage unless `swap quote --slippage-pct` is provided.
- Uniswap quote calls require a real `swapper` address via `swap quote --from-address` and default to provider auto slippage unless `swap quote --slippage-pct` is provided.
- MegaETH bootstrap symbol parsing currently supports `MEGA`, `WETH`, and `USDT` (`USDT` maps to the chain's `USDT0` contract address on `eip155:4326`). Official Mega token list currently has no Ethereum L1 `MEGA` token entry.
- Symbol parsing depends on the local bootstrap token registry; on chains without registry entries use token address or CAIP-19.
- APY values are percentage points (`2.3` means `2.3%`), not ratios.
- Morpho can emit extreme APYs in tiny markets; use `--min-tvl-usd` in ranking/filters.
- `lend`/`yield` rows expose retrieval-first ID metadata: `provider`, `provider_native_id`, and `provider_native_id_kind`; IDs are provider-scoped and not guaranteed to be on-chain addresses.
- Bridge quotes now include `fee_breakdown` with provider-reported components (`lp_fee`, `relayer_fee`, `gas_fee`) and amount-delta consistency checks.
- Kamino direct routes currently support Solana mainnet only.
- Solana devnet/testnet aliases and custom Solana CAIP-2 references are intentionally unsupported; use Solana mainnet only.
- Fresh cache hits (`age <= ttl`) skip provider calls; once TTL expires, the CLI re-fetches providers and only serves stale data within `max_stale` on temporary provider failures.
- Cache locking uses sqlite WAL + busy timeout + lock/backoff retries to reduce `database is locked` contention under parallel runs.
- Cache initialization is best-effort; if cache path init fails (permissions/path issues), commands continue with cache disabled.
- Across may omit native USD fee fields for some routes; when missing and the input asset is a known stable token, `estimated_fee_usd` falls back to a token-denominated approximation while exact token-unit fees remain in `fee_breakdown`.
- Metadata commands (`version`, `schema`, `providers list`) bypass cache initialization.
- Execution commands (`swap|bridge|approvals|lend|rewards ... plan|run|submit|status`, `actions list|show`) bypass cache initialization.
- For `lend`/`yield`, unresolved symbols are treated as symbol filters; on chains without bootstrap token entries, prefer token address or CAIP-19 for deterministic matching.
- Amounts used for swaps/bridges are base units; keep both base and decimal forms consistent.
- Release artifacts are built on `v*` tags via `.github/workflows/release.yml` and `.goreleaser.yml`.
- Mintlify production docs should use the `docs-live` branch; the release workflow force-syncs `docs-live` to each `v*` tag.
Expand Down Expand Up @@ -126,10 +151,9 @@ README.md # user-facing usage + caveats
- Keep `CHANGELOG.md` in a simple release-notes format with `## [Unreleased]` at the top.
- Add user-facing changes under `Unreleased` using sections in this order: `Added`, `Changed`, `Fixed`, `Docs`, `Security`.
- Keep entries concise and action-oriented (what changed for users, not internal refactors unless user impact exists).
- Record only the net user-facing outcome in `Unreleased`; omit intermediate implementation steps and fixes for regressions that never shipped in a release.
- Do not add changelog entries for README-only or `AGENTS.md`-only edits.
- On release, move `Unreleased` items into `## [vX.Y.Z] - YYYY-MM-DD` and update compare links at the bottom.
- If a section has no updates while editing, use `- None yet.` to keep structure stable.
- Keep README/AGENTS focused on current behavior; track version-to-version deltas in CHANGELOG/release notes instead of adding temporary in-progress migration notes.

## Maintenance note

Expand Down
63 changes: 59 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,71 @@ Format:
## [Unreleased]

### Added
- None yet.
- Added TaikoSwap provider support for `swap quote` using on-chain quoter contract calls (no API key required).
- Added swap execution workflow commands: `swap plan`, `swap run`, `swap submit`, and `swap status`.
- Added bridge execution workflow commands: `bridge plan`, `bridge run`, `bridge submit`, and `bridge status` (Across and LiFi providers).
- Added approvals workflow commands: `approvals plan`, `approvals run`, `approvals submit`, and `approvals status`.
- Added lend execution workflow commands under `lend supply|withdraw|borrow|repay ... plan|run|submit|status` (Aave and Morpho).
- Added rewards execution workflow commands under `rewards claim|compound ... plan|run|submit|status` (Aave).
- Added action persistence and inspection commands: `actions list` and `actions show`.
- Added local signer support for execution with env/file/keystore key sources.
- Added Taiko Hoodi chain alias and token registry entries (`USDC`, `USDT`, `WETH`) for deterministic asset parsing.
- Added planner unit tests for approvals, Aave lend/rewards flows, and LiFi bridge action building.
- Added centralized execution registry data in `internal/registry` for endpoint, contract, and ABI references.
- Added nightly execution-planning smoke workflow (`nightly-execution-smoke.yml`) and script.
- Added `lend positions` to query account-level lending positions by address for Aave and Morpho with `--type all|supply|borrow|collateral`.
- Added `yield history` to query historical yield-provider series with `--metrics apy_total,tvl_usd`, `--interval hour|day`, `--window`/`--from`/`--to`, and optional `--opportunity-ids`.

### Changed
- None yet.
- BREAKING: Morpho `yield opportunities` now returns vault-level opportunities (`provider_native_id_kind=vault_address`) sourced from Morpho vault/vault-v2 data instead of Morpho market IDs.
- BREAKING: `yield opportunities` removed subjective fields (`risk_level`, `risk_reasons`, `score`) and removed the `--max-risk` flag.
- BREAKING: `yield opportunities --sort` now supports only objective keys (`apy_total|tvl_usd|liquidity_usd`) and defaults to `apy_total`.
- `yield opportunities` now returns `backing_assets` with full per-opportunity backing composition.
- Yield liquidity/TVL sourcing is now provider-native and consistent: Aave (`size.usd`, `borrowInfo.availableLiquidity.usd`), Morpho vaults (`totalAssetsUsd`, vault liquidity fields), and Kamino (`totalSupplyUsd`, `max(totalSupplyUsd-totalBorrowUsd,0)`).
- BREAKING: Lend and rewards commands now use `--provider` as the selector flag; `--protocol` has been removed.
- `providers list` now includes TaikoSwap execution capabilities (`swap.plan`, `swap.execute`) alongside quote metadata.
- `providers list` now includes LiFi bridge execution capabilities (`bridge.plan`, `bridge.execute`).
- `providers list` now includes Across bridge execution capabilities (`bridge.plan`, `bridge.execute`).
- `providers list` now includes Morpho lend execution capabilities (`lend.plan`, `lend.execute`).
- Added execution-specific exit codes (`20`-`24`) for plan/simulation/policy/timeout/signer failures.
- Added execution config/env support for action store paths.
- Execution command cache/action-store policy now covers `swap|bridge|approvals|lend|rewards ... plan|run|submit|status`.
- Removed implicit defaults for multi-provider command paths; `--provider` must be set explicitly where applicable.
- Added bridge gas-top-up request support via `--from-amount-for-gas` for LiFi quote/plan/run flows.
- Bridge execution now tracks LiFi destination settlement status before finalizing bridge steps.
- Bridge execution now tracks Across destination settlement status before finalizing bridge steps.
- Aave execution registry defaults now include PoolAddressesProvider mappings for Base, Arbitrum, Optimism, Polygon, and Avalanche in addition to Ethereum.
- Execution `run`/`submit` commands now propagate command timeout/cancel context through on-chain execution.
- Morpho lend execution now requires explicit `--market-id` to avoid ambiguous market selection.
- Execution `run`/`submit` commands no longer require `--yes`; command intent now gates execution.
- Unified execution action-construction dispatch under a shared ActionBuilder registry while preserving existing command semantics.
- Execution commands now use `--from-address` as the single signer-address guard; `--confirm-address` has been removed.
- Execution `run` commands now default sender to signer address when `--from-address` is omitted.
- Execution `run`/`submit` commands now support `--private-key` as a one-off local signer override (highest precedence).
- Local signer `--key-source auto` now discovers `${XDG_CONFIG_HOME:-~/.config}/defi/key.hex` when present.
- Missing local-signer key errors now include a simple default key-file hint (`~/.config/defi/key.hex`, with `XDG_CONFIG_HOME` override note).
- Local signer key/keystore file loading no longer hard-fails on non-`0600` file permissions.
- Execution endpoint defaults for Across/LiFi settlement polling and Morpho GraphQL planning are now centralized in `internal/registry`.
- Default chain RPC metadata is now centralized in `internal/registry/rpc.go`; execution/quote flows use shared chain defaults when `--rpc-url` is not provided.
- Execution pre-sign validation now enforces bounded ERC-20 approvals by default and validates TaikoSwap router/selector invariants before signing.
- Execution `run`/`submit` commands now expose `--allow-max-approval` and `--unsafe-provider-tx` overrides for advanced/provider-specific flows.
- `swap quote` (on-chain providers) and `swap plan`/`swap run` now support `--rpc-url` to override chain default RPCs per invocation.
- Swap execution planning now validates sender/recipient fields as EVM addresses before route planning.
- Uniswap `swap quote` now requires a real `--from-address` swapper input instead of using a deterministic placeholder address.
- `lend positions` now emits non-overlapping type rows for automation: `supply` (non-collateral), `collateral` (posted collateral), and `borrow` (debt).
- `providers list` for Aave/Morpho/Kamino now advertises `yield.history` capability metadata.

### Fixed
- None yet.
- Improved bridge execution error messaging to clearly distinguish quote-only providers from execution-capable providers.

### Docs
- None yet.
- Documented bridge/lend/rewards/approvals execution flows, signer env inputs, command behavior, and exit codes in `README.md`.
- Updated `AGENTS.md` with expanded execution command coverage and caveats.
- Updated `docs/act-execution-design.md` implementation status to reflect the shipped Phase 2 surface.
- Clarified execution builder architecture split (provider-backed route builders for swap/bridge vs internal planners for lend/rewards/approvals) in `AGENTS.md` and execution design docs.
- Added `lend positions` usage and caveats to `README.md`, `AGENTS.md`, and Mintlify lending command reference.
- Documented `yield history` usage, flags, and provider caveats across README and Mintlify yield/lending references.
- Updated yield docs/reference examples to remove risk-based flags and document `backing_assets` plus objective `tvl_usd`/`liquidity_usd` semantics.

### Security
- None yet.
Expand Down
Loading
Loading