Follow the spel fork's `nssa → lee` refactor (chore/update-lez): the
`#[lez_program]` macro now emits `lee_core::…` paths, so the crate must be
referenced by its real name rather than the `nssa_core` alias.
- Cargo.toml: rename the `nssa_core`/`nssa` dep keys to `lee_core`/`lee` and
drop the now-redundant `package = "lee_core"`/`package = "lee"` aliases
(dep name == package name).
- Rust: `nssa_core::` → `lee_core::`, `nssa::` → `lee::` across programs,
modules, and tools.
- Docs: update the library reference in CLAUDE.md and README.md.
Also drop the dead `NSSA_WALLET_HOME_DIR` env var — superseded by
`LEE_WALLET_HOME_DIR`, which is the only wallet-home var any v0.2.x wallet
reads — from the test tooling (setup-amm-testnet.sh, custom-token.mjs,
run-basecamp-e2e.sh) and docs.
Closes#225
Add a `CreatePriceObservations` instruction that registers a TWAP
price-observations account for a pool over a time window, via a chained
call to the configured TWAP oracle program. The pool acts as the price
source: the AMM authorizes it with its pool PDA seed so the oracle ties
the feed to that pool.
The feed's initial tick is read from the pool's authoritative
`CurrentTickAccount` (validated against its pool-derived PDA) rather than
being supplied by the caller, so the feed cannot be seeded at a forged
price — mirroring what `RecordTick` does. The clock is verified to be the
canonical 1-block LEZ clock, and creation is rejected if the observations
account already exists.
To support the chained call, `AmmConfig` and the `Initialize` instruction
are extended with a `twap_oracle_program_id` that the instruction reads.
Add an admin authority to the AMM config so configuration can be changed
after initialization. AmmConfig gains an `authority` field, set by
Initialize, and a new UpdateConfig instruction lets that admin change
config values.
UpdateConfig is access-controlled: the authority account must equal the
stored config.authority and be passed authorized (signed). Both fields are
optional — token_program_id updates the chained-call token program, and
new_authority transfers admin control to a different account. Without this
gate any caller could repoint the AMM at a malicious token program.
Introduce a singleton AMM configuration account, a PDA derived from the
constant "CONFIG" seed, created once via a new `Initialize` instruction.
The config stores the Token Program ID the AMM issues every chained call
to, replacing the previous behavior of trusting the program owner of a
caller-supplied holding.
The config account's existence is the Program's initialization gate: the
chained-call instructions (new_definition, add_liquidity, remove_liquidity,
swap_exact_input, swap_exact_output) now take the config as their first
account, validate it against `compute_config_pda(self_program_id)`, and
read the Token Program ID from it on demand — rejecting calls until the
Program is initialized. Vaults and user holdings are asserted to match the
configured Token Program. sync_reserves is left ungated, as it cannot act
on a pool that could not have existed before initialization.
- amm_core: AmmConfig type, compute_config_pda/_seed, Initialize variant
- amm: initialize.rs + config threading through chained-call instructions
- guest: initialize instruction; config + self_program_id on gated calls
- tests: config fixtures, init-gate unit tests, end-to-end Initialize VM test