Adds ata_group_owned_owner_signing (Burn's missing GROUP variant) and two NewFungibleDefinition
private-initial-holder tests to Token. Removes two experimental PDA-external-seed Token tests
that had no real coverage purpose. Documents the root cause of the AMM privacy-test blocker
(a spel-framework guest-wrapper filter silently drops the clock account before either
transaction validator sees it) with full findings/matrix writeups, and reconciles table gaps
found while cross-checking each program's privacy tests against docs/findings.md.
Adds private-account tests for AMM's SwapExactInput/SwapExactOutput, AddLiquidity, and
RemoveLiquidity confirming the "Invalid account_identities length" circuit bug also fires
with real private accounts, not just the all-public control case, plus a distinct
RemoveLiquidity finding (destination must already exist). Also deduplicates the
shielded_token_transfer test helper and updates findings/matrix docs accordingly.
Documents the private-account primitives (private PDA vs public PDA, group-shared
accounts) and per-program privacy test results in docs/findings.md. Adds a
stablecoin test confirming WithdrawCollateral can't pay out to a brand-new private
destination, and folds in further ATA/token privacy test refinements.
Add Stablecoin privacy-preserving tests for WithdrawCollateral and RepayDebt
(personal and group-owned variants), plus a regression test confirming
OpenPosition is incompatible with the privacy circuit (chained-call
re-authorization). Close the last planned Token row (MintWithAuthority to a
private holding) and the ATA owner-signer gap for Transfer (personal and
group-owned), plus a defensive Create/group-owner test.
Extract shared privacy-test helpers (identity builders, GroupOwner
seal/unseal handshake) into integration_tests/src/lib.rs and use them
throughout token.rs, collapsing duplicated InputAccountIdentity/account
construction. Update docs/privacy-test-matrix.md with all new findings.
Validates the Q2 privacy features (shield/deshield, private-to-private transfers,
existing-account crediting, group-owned accounts, and private PDAs) against the
token and ata program flows, which previously ran almost entirely in public
context. Adds the key_protocol dependency for GMS-based group-account tests and
introduces a docs/privacy-test-matrix.md tracker mapping each program/instruction/
privacy-dimension combination to pass, fail, or not-expressible, with root-cause
findings for each gap (notably that private PDAs are structurally unsupported by
any program currently deriving addresses via for_public_pda).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add an optional mint authority to fungible tokens for controlled supply:
create with a designated minter, mint additional supply, rotate the
authority to a new key, or permanently revoke it to fix the supply.
The authority is stored inline on `TokenDefinition::Fungible` as
`authority: Option<AccountId>` (`Some(id)` = mintable by `id`, `None` =
fixed supply). Keeping it a plain `Option<AccountId>` rather than a custom
wrapper type leaves account state decodable by `spel inspect`; the
require/rotate/revoke guard logic lives inline in the handlers.
LEZ rejects a transaction that lists the same account id twice, so one
instruction cannot statically express both "the definition account is the
authority and signs" (self/PDA authority) and "a distinct rotated account
signs" (external authority) — they need opposite signer markers. Each
privileged operation is therefore split into a self and an external
variant:
- `Mint` / `SetAuthority` — the definition account is the signer.
- `MintWithAuthority` / `SetAuthorityWithAuthority` — a distinct authority
account is the signer; the definition account does not sign.
Creation via `NewFungibleDefinition { mint_authority, .. }`; an all-zero
authority id is rejected. The AMM's LP token uses self/PDA authority — its
stored authority is the LP definition PDA, minted only by the pool via
chained calls.
Covered by token unit tests and zkVM integration tests: creation with and
without an authority, self- and external-authority mint, rotation, and
external rotate/revoke. IDLs regenerated.
Bump the LEZ dependency from the `lez-core-v0.2.0` tag to `v0.2.0-rc6` across
the workspace and all guest manifests (still resolving via the renamed
`lee_core`/`lee` packages), and regenerate the lockfiles to match.
rc6 moved the clock program out of `nssa` into a separate system-programs crate
(gated behind the guest-building `artifacts` feature), so adapt the tests:
- Import `ClockAccountData` and `CLOCK_01_PROGRAM_ACCOUNT_ID` from `clock_core`
instead of `nssa`, and build clock data via `ClockAccountData::to_bytes()`
rather than hand-encoding the Borsh layout.
- `V03State::new()` no longer auto-creates the clock account, so AMM tests seed
the canonical 1-block clock explicitly before ops that read it.
- `advance_clock` now writes the clock account directly via
`force_insert_account` (the clock can no longer be ticked with a real
transaction), matching how upstream rc6 state-machine tests seed accounts.
- Add the `clock_core` dependency to integration_tests/benchmark.
Bump the LEZ dependency from the `v0.2.0-rc3` tags to the released
`lez-core-v0.2.0` tag across the workspace and all guest manifests. The crate
was renamed upstream, so `nssa_core`/`nssa` now resolve via the `lee_core`/`lee`
packages, and spel-framework points at the `refactor/lez-v020-compat` fork
branch for compatibility.
Adapt the integration tests to the new API surface:
- `NssaError` is now `LeeError` (error variants unchanged).
- Account inputs move from numeric mask vectors (`vec![2, 0, 0]`) to typed
`InputAccountIdentity` values (e.g. `PrivateUnauthorized { epk, view_tag,
npk, ssk, identifier }`).
- `ViewingPublicKey::from_scalar` → `from_seed(d, z)`; `AccountId::from(&npk)`
→ `AccountId::for_regular_private_account(&npk, 0)`; ephemeral-key/shared-
secret setup → `SharedSecretKey::encapsulate_deterministic(...)` with the
circuit filling the EPK.
Regenerate all guest Cargo.lock files and the workspace lockfile to match.