From ef00330d4df669e6efbc27ae0fd15a8c183561fa Mon Sep 17 00:00:00 2001 From: "tuddman@users.noreply.github.com" Date: Wed, 27 May 2026 13:01:09 +0200 Subject: [PATCH] chore(release): aspens 0.5.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Minor bump (not patch) because the tech-debt sweep landed since 0.4.3 removed several public items. Per the Versioning section in README.md, source-breaking changes to `aspens::*` move the minor number, not the patch. Breaking removals (full list in CHANGELOG): - The 7 legacy `privkey: String` wrappers across send_order / cancel_order / deposit / withdraw / balance / auth. - The legacy two-chain `balance::balance` + its `call_get_*` privkey-derived helpers and `balance_table`. - The `chain_client::derive_associated_token_account` re-export. - `aspens::grpc` is now `#[doc(hidden)]` (still resolvable, no longer in the documented public API). Everything else under 0.5.0 in the changelog is additive or non-breaking — new tests, the `aspens-cliutil` crate, supply-chain CI, file splits, lean-signing fixes, docstring corrections. All gates green locally: - cargo build --workspace - cargo test --workspace --all-features - cargo test -p aspens --no-default-features --features evm,solana - cargo clippy --workspace --all-targets --all-features -- -D warnings - cargo deny --workspace check - RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --all-features - cargo fmt --all -- --check --- CHANGELOG.md | 204 +++++++++++++++++++++++++++++++-------------------- Cargo.lock | 10 +-- Cargo.toml | 2 +- 3 files changed, 131 insertions(+), 85 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66efcd9..04fe1d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,100 +9,145 @@ change before 1.0. ## [Unreleased] -### Changed -- Split `commands/trading/gasless.rs` (810 LOC) into - `gasless/{mod.rs, evm.rs, solana.rs}` — the EVM and Solana - `build_*` branches each live next door to the dispatcher now - instead of all sharing one file. -- Split `commands/trading/send_order.rs` (855 LOC) — the proto - `Display` impls and CLI-formatting helpers moved to a sibling - `send_order/display.rs`; signing / RPC dispatch stays in `mod.rs`. -- Introduced a `GaslessBuildArgs` struct used by both gasless - branches; retires four `#[allow(clippy::too_many_arguments)]` - attributes (was 8, now 4). The 4 remaining allows are on the - public top-level `send_order` API and `derive_order_id` — - documented with comments explaining why those argument lists - stay flat (consensus recipe / public API surface). -- Production-path `.unwrap()` calls now `.expect("...")` with a - descriptive message: - - `executor::BlockingExecutor::new` (tokio runtime build) - - `solana::{sysvar_rent_id, sysvar_instructions_id, - ata_program_id, ed25519_program_id}` (well-known program / - sysvar pubkeys — parse failure would mean a catastrophic - solana-sdk regression, but the panic message now says so) -- The other ~140 `.unwrap()` calls in the lib were audited and - found to be inside `#[cfg(test)]` modules or doc-test examples, - where the test framework already prints clear failures. No - changes to test code. - -### Removed (breaking, pre-1.0) -- Retired the legacy `privkey: String` wrappers around the - curve-agnostic trading API. The `_with_wallet` (and `_with_wallets`) - family is the only public shape now. Specifically deleted: - - `commands::trading::send_order::send_order` - - `commands::trading::cancel_order::call_cancel_order` - - `commands::trading::cancel_order::call_cancel_order_from_config` - - `commands::trading::deposit::call_deposit_from_config` - - `commands::trading::withdraw::call_withdraw_from_config` - - `commands::trading::balance::balance_from_config` - - `commands::auth::authenticate_with_signature` -- Deleted the legacy two-chain pretty-printer - `commands::trading::balance::balance` plus its private-key-derived - helpers (`call_get_balance`, `call_get_locked_balance`, - `call_get_erc20_balance`, `call_get_native_balance`) and the - `balance_table` helper. The address-based variants - (`call_get_*_for_address`) and `format_balance` are kept — they're - used by `aspens-admin`. -- Removed the `chain_client::derive_associated_token_account` - re-export. The function still lives at +## [0.5.0] — 2026-05-27 + +A tech-debt sweep that retired legacy public API and tightened the +crate's surface. Bumped to a minor release because of the source- +breaking removals listed below — patch-compatible per the +**Versioning** section in `README.md` would require keeping those +items. + +### Breaking — removed public items + +- **Legacy `privkey: String` wrappers retired.** The `_with_wallet` + (and `_with_wallets`) family is now the only public shape: + - `commands::trading::send_order::send_order` → use + `send_order_with_wallet` / `send_order_with_wallets`. + - `commands::trading::cancel_order::call_cancel_order` and + `call_cancel_order_from_config` → use the `_with_wallet` + variants. + - `commands::trading::deposit::call_deposit_from_config` → use + `call_deposit_from_config_with_wallet`. + - `commands::trading::withdraw::call_withdraw_from_config` → use + `call_withdraw_from_config_with_wallet`. + - `commands::trading::balance::balance_from_config` → use + `balance_from_config_with_wallets` (multi-wallet, curve-aware). + - `commands::auth::authenticate_with_signature` → use + `authenticate_with_wallet`. +- **Legacy two-chain balance helpers deleted.** + `commands::trading::balance::balance` and its private-key-derived + primitives (`call_get_balance`, `call_get_locked_balance`, + `call_get_erc20_balance`, `call_get_native_balance`, + `balance_table`) were unused inside the workspace and have been + removed. The address-based variants (`call_get_*_for_address`) and + `format_balance` are kept — they're used by `aspens-admin`. +- **`chain_client::derive_associated_token_account` re-export + removed.** The canonical location is `aspens::solana::derive_associated_token_account`. +- **`aspens::grpc` marked `#[doc(hidden)]`.** The gRPC channel + helpers it exposes are internal — not part of the stable public + API. + +### Added + +- New `aspens-cliutil` workspace crate (`publish = false`) holding the + canonical `format_error(err, context, &BinaryContext)` and + `resolve_token_amount` shared by `aspens-cli`, `aspens-repl`, and + `aspens-admin`. Retires ~680 lines of triplicated CLI scaffolding; + binaries now keep a thin local wrapper that picks up the right + `BinaryContext` (binary name + privkey env var) and delegate. +- New `aspens::evm::rpc` submodule containing the `#[sol(rpc)]`-enabled + `MidribV2` + `IERC20` bindings (gated on the `client` feature). The + stateless `aspens::evm::MidribV2` struct-only bindings stay put for + lean-signing consumers. +- **Supply-chain CI**: `deny.toml` at the workspace root and a new + `.github/workflows/security-audit.yml` that runs + `EmbarkStudios/cargo-deny-action` over `advisories ∪ bans ∪ + licenses ∪ sources` on every PR plus a daily cron. +- **New CI jobs**: `cargo build -p aspens --examples` (catches example + bitrot) and a `build-lean-signing` job that exercises + `--no-default-features --features evm,solana` so the lean-signing + build path is gated on every PR. +- **Signing-primitive tests**: round-trip sign-with-`Wallet` → + recover-with-`Signature` test in `aspens::evm` that mirrors the + arborter's on-chain verifier (`arborter/app/onchain/src/verify.rs`) + exactly; plus EIP-191 length-prefix coverage across byte counts. +- **Trading-command tests**: 10 new tests in `commands::trading::balance` + covering `format_balance_with_decimals`, `format_balance`, and + `select_wallet_for_chain` (multi-curve wallet routing). +- **Build-script tests**: `aspens/build.rs`'s attestation path-rewrite + logic extracted to a shared `aspens/build_attestation_paths.rs` + and covered by 6 unit tests including an on-disk regression guard. +- New top-level docs: `CHANGELOG.md` (Keep-a-Changelog) and a + **Versioning** section in `README.md`. ### Changed + +- Binaries (`aspens-cli`, `aspens-repl`, `aspens-admin`) now declare + their `aspens` features explicitly with + `default-features = false, features = ["client", "trader", "evm", + "solana", "formatting"]` (+ `"admin"` for the admin binary). Changes + to the library's default features no longer silently affect + binaries. All three binaries also gained `publish = false` — + they're not on crates.io. +- `commands/trading/gasless.rs` (810 LOC) split into + `gasless/{mod.rs, evm.rs, solana.rs}`; EVM and Solana + `build_gasless_authorization` branches now sit next door to the + dispatcher. `GaslessBuildArgs` retires 4 of the 8 + `#[allow(clippy::too_many_arguments)]` attributes. +- `commands/trading/send_order.rs` (855 LOC) split into + `send_order/{mod.rs, display.rs}` so the proto `Display` impls and + CLI-formatting helpers live separately from signing / RPC dispatch. +- Production-path `.unwrap()` → `.expect("...")` with descriptive + messages: `BlockingExecutor::new` (tokio runtime build) and the + four well-known Solana sysvar / program IDs + (`sysvar_rent_id`, `sysvar_instructions_id`, `ata_program_id`, + `ed25519_program_id`). The remaining ~140 unwraps in the lib were + audited and confirmed test-only. +- `AspensClient` `RwLock.unwrap()` (8 sites) → + `.expect("AspensClient ... lock poisoned")` so a poisoned lock + surfaces with a clear message instead of a generic panic. +- `chain_curve`, `load_trader_wallet_for_chain`, and + `load_trader_wallet_for_network` are now gated behind the + `client` feature. They take proto types that were already + `client`-only — gating them makes the documented lean-signing build + (`--no-default-features --features evm,solana`) actually work. +- Examples moved from `examples/` to `aspens/examples/` so Cargo + picks them up natively. Declared with `required-features = ["client"]` + so lean-signing builds skip them automatically. Run with + `cargo run -p aspens --example `. +- CI workflow reads the Rust toolchain from `rust-toolchain.toml` + via `actions-rust-lang/setup-rust-toolchain@v1` instead of pinning + `stable` per job. Local and CI builds now use the same compiler. - `aspens-repl` and the `quickstart` example now use the curve-aware `_with_wallet` API directly. The REPL constructs an EVM `Wallet` from `TRADER_PRIVKEY` via a new `load_trader_wallet_or_complain` helper; the example re-builds a `Wallet` inside each `async move` block since `Wallet` is intentionally not `Clone` (Solana keypairs). -- Binaries (`aspens-cli`, `aspens-repl`, `aspens-admin`) now declare the - `aspens` library features they depend on explicitly - (`client`, `evm`, `solana`, `formatting`, plus `admin` for the admin - binary) and turn off default-feature inheritance. Changes to the - `aspens` crate's default features no longer silently affect binaries. -- Binaries (`aspens-cli`, `aspens-repl`, `aspens-admin`) now declare the - `aspens` library features they depend on explicitly - (`client`, `evm`, `solana`, `formatting`, plus `admin` for the admin - binary) and turn off default-feature inheritance. Changes to the - `aspens` crate's default features no longer silently affect binaries. -- Internal helpers in `AspensClient` that take `RwLock` guards now - `expect("AspensClient ... lock poisoned")` instead of `unwrap()`, so a - poisoned lock surfaces with a clear message instead of a generic panic. -- `chain_curve`, `load_trader_wallet_for_chain`, and - `load_trader_wallet_for_network` are now gated behind the `client` - feature. They depend on the proto-generated `Chain` / - `GetConfigResponse` types in `commands::config`, which are themselves - `client`-only — gating these helpers makes the lean-signing build - (`--no-default-features --features evm,solana`) work. -- `aspens::grpc` is marked `#[doc(hidden)]`. The gRPC channel helpers it - exposes are internal — not part of the stable public API. -- Examples moved from `examples/` to `aspens/examples/` so Cargo picks - them up automatically (`cargo run -p aspens --example `). -- CI workflow now reads the Rust toolchain from `rust-toolchain.toml` - instead of pinning `stable` per job. Local and CI builds now use the - same compiler version. -- CI now builds examples (`cargo build -p aspens --examples`) and runs - a lean-signing job (`aspens --no-default-features --features - evm,solana`) so example bitrot and accidental `client`-feature - coupling are caught on every PR. +- `aspens/Cargo.toml`: corrected the misleading comment claiming + `trader` / `admin` features don't gate deps — both gate `commands::*` + modules in `commands/mod.rs`. ### Fixed -- `justfile`: `test-anvil` and `test-testnet` recipes now call - `python3 scripts/ammit.py` directly. The previous `./scripts/ammit.sh` + +- `decimals.md`: audited end-to-end and corrected four real + discrepancies — diagram referenced a nonexistent + `normalize_decimals` (real function is `gasless::normalize`); the + BID/ASK paragraph misattributed normalization to `send_order.rs` + as the "arborter-side mirror" (it's `gasless::resolve_order`, + SDK-side); Example 3 (`buy-market`) claimed market orders execute + but they're rejected at `gasless::resolve_order`; reference section + now marks `convert_to_pair_decimals` as private and adds + `gasless::normalize`. +- `justfile`: `test-anvil` and `test-testnet` recipes now invoke + `python3 scripts/ammit.py`. The previous `./scripts/ammit.sh` invocations referred to a script that no longer exists. - `aspens/examples/transaction_hash_example.rs`: updated `SendOrderResponse` initializer to include the `current_orderbook` and `order_id` fields added in the 0.4.x proto sync. ### Removed + - `scripts/ammit-multi-token.sh` deleted. `scripts/ammit.py` is the single supported AMMIT entry point. @@ -159,6 +204,7 @@ Pre-0.4.1 history is recorded in git only. The 0.4.x line introduced Solana support, the Wallet enum, and feature gates (`evm`, `solana`, `client`) for lean-signing consumers. -[Unreleased]: https://github.com/aspensprotocol/sdk/compare/0.4.3...HEAD +[Unreleased]: https://github.com/aspensprotocol/sdk/compare/0.5.0...HEAD +[0.5.0]: https://github.com/aspensprotocol/sdk/compare/0.4.3...0.5.0 [0.4.3]: https://github.com/aspensprotocol/sdk/releases/tag/0.4.3 [0.4.2]: https://github.com/aspensprotocol/sdk/releases/tag/0.4.2 diff --git a/Cargo.lock b/Cargo.lock index c73103b..dd1b88c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1084,7 +1084,7 @@ dependencies = [ [[package]] name = "aspens" -version = "0.4.3" +version = "0.5.0" dependencies = [ "alloy", "alloy-chains", @@ -1122,7 +1122,7 @@ dependencies = [ [[package]] name = "aspens-admin" -version = "0.4.3" +version = "0.5.0" dependencies = [ "alloy", "aspens", @@ -1142,7 +1142,7 @@ dependencies = [ [[package]] name = "aspens-cli" -version = "0.4.3" +version = "0.5.0" dependencies = [ "alloy", "alloy-chains", @@ -1162,7 +1162,7 @@ dependencies = [ [[package]] name = "aspens-cliutil" -version = "0.4.3" +version = "0.5.0" dependencies = [ "aspens", "eyre", @@ -1170,7 +1170,7 @@ dependencies = [ [[package]] name = "aspens-repl" -version = "0.4.3" +version = "0.5.0" dependencies = [ "alloy", "alloy-chains", diff --git a/Cargo.toml b/Cargo.toml index 69eca2d..1072608 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ members = [ ] [workspace.package] -version = "0.4.3" +version = "0.5.0" edition = "2021" license = "MIT" repository = "https://github.com/aspensprotocol/sdk"