> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nacrelabs.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Changelog

> Recent updates to Nacre Protocol, wPRL, and the testnet bridge.

<Update label="May 29, 2026" description="Weekly release">
  ## New features

  **Sweep transactions surfaced in the explorer.** NacreScan now links each
  mint intent to the Pearl sweep transaction that moved your deposit from the
  Hot Reserve into the protocol's Cold Reserve. The detail view also exposes
  the recipient Solana pubkey and the final wPRL mint signature, so you can
  follow the full PRL → wPRL path on-chain from one place. See the
  [NacreScan explorer](https://testnet.wrapped-pearl.com/explorer).

  **Friendlier mint state names.** Mint intent states have been renamed to
  match what's actually happening: `pending → sweeping`, `quorum_reached →
    minting`, `finalized → minted`. The status pill, lifecycle timeline, and
  wrap-pending page all use the new labels. Redeem-side names are unchanged.

  **Fresh testnet redeploy.** All four Anchor programs were redeployed to
  Solana devnet under new program IDs, and a fresh wPRL Token-2022 mint was
  created. The authoritative list is on the
  [protocol addresses page](/protocol/addresses) — if you have anything
  pinned locally, please refresh.

  ## Updates

  **Self-healing bridge.** The signature aggregator now distinguishes
  retryable upstream conditions (network blips, 5xx, 429, sweeps that just
  haven't crossed the confirmation gate yet) from terminal failures.
  Transient errors land in a `BackingOff` state with exponential backoff
  and recover automatically when the next block lands or the upstream
  recovers, instead of getting permanently stuck and requiring operator
  intervention. Existing stuck proposals from before this change are
  re-classified and resume on their own.

  **First-time wrap reliability.** The wrap flow now bundles the
  `init_user_setting` instruction into the same transaction as
  `create_hot_reserve` when a depositor's `UserSetting` account doesn't
  exist yet. Previously, a brand-new user's first deposit could succeed on
  the Pearl side but fail to mint with `AccountNotInitialized`. First wraps
  now Just Work.

  **Stale-bucket guard.** If you previously generated a deposit address
  that's no longer sweepable (for example, one registered before this
  week's redeploy), the wrap flow now detects the mismatch up front and
  shows a clear "recover + re-wrap" message instead of letting you deposit
  to a dead address.

  **Phantom-compatible recovery-key signing.** The canonical message that
  backs the Hot Reserve emergency-recovery-key derivation is now formatted
  to round-trip cleanly through Phantom and other Wallet-Standard wallets.
  Re-signing the canonical message reproduces the same recovery key, as
  designed.

  ## Bug fixes

  **Validator attestations no longer 401.** A misconfiguration in the
  testnet validator's Privy wiring caused every mint and redeem
  attestation to fail authorization. Validators are now correctly
  configured, and the aggregator additionally accepts a corrected
  signature from a previously-misconfigured validator without an operator
  reset.

  **Explorer reads from the browser.** The NacreScan read API now sends the
  correct CORS headers, so the bridge frontend can fetch `/intents` directly
  instead of timing out silently.
</Update>

<Update label="May 28, 2026" description="wPRL mint carries on-chain name + ticker">
  ## Updates

  **The wPRL Token-2022 mint now ships with native on-chain metadata.**
  Bootstrap creates the mint with the Token-2022 `MetadataPointer`
  extension (self-pointing) and a `TokenMetadata` extension storing
  `name = "Wrapped Pearl"`, `symbol = "wPRL"`, and an empty `uri` (logo +
  extended manifest can be slotted in later via a metadata update). The
  metadata `update_authority` is the admin multisig, so name / symbol /
  URI can be refreshed under the same 3-of-5 quorum that governs other
  protocol parameters. Phantom, Solscan, and Solana Explorer surface the
  new metadata directly — wPRL is no longer rendered as `Unknown`.

  The mint authority chain is unchanged: bootstrap holds it
  transiently while writing metadata, then rotates it to the
  `MINT_AUTHORITY_SEED` PDA via `SetAuthority` before any
  `twp_initialize` call, so the on-chain
  `mint_authority == MINT_AUTHORITY PDA` invariant continues to hold. The
  existing TransferFeeConfig extension and its authorities are
  untouched.

  Applies to fresh deploys only; mints created before this change can't
  retroactively grow extension space and would need a rotation. See
  `ARCHITECTURE.md §7.5`.
</Update>

<Update label="May 24, 2026" description="User-emergency key derives from a Solana signature">
  ## Updates

  **The Hot Reserve emergency-recovery key is now derived from a Solana
  signature**, not from the depositor's public key. Under the previous
  derivation, HKDF over the depositor's Solana *pubkey* produced the
  secp256k1 secret backing the Hot Reserve script-path leaf — meaning
  any third party who could see the deposit on-chain could compute the
  same secret and, after the 7-day CSV timeout, race the legitimate
  depositor for the deposit. The new derivation takes a 64-byte ed25519
  signature (the IKM) the user produces with their Solana wallet via
  `signMessage` over a canonical 62-byte payload. Only the holder of the
  Solana *secret* key can produce the signature, so only they can
  reproduce the emergency secret. ed25519 is deterministic (RFC 8032),
  so re-signing yields the same key on demand — no backup required.

  The on-chain protocol is also now derivation-agnostic for the
  user-emergency x-only: `mint_deposit` consumes whatever 32-byte x-only
  the user committed on `HotReserveBucket.script_path_spend_public_key`
  at `create_hot_reserve`, rather than re-deriving it from the depositor
  pubkey. To close the cross-user theft surface that the old
  depositor-pubkey-bound derivation prevented implicitly,
  `create_hot_reserve` now also inits a `HotReserveAddressIndex`
  uniqueness PDA seeded by the deposit address — a second bucket trying
  to claim the same address reverts, so the validator's `script_pubkey
    → owner` mapping is unambiguous. `recover_hot_reserve` closes both
  PDAs back to the owner.

  Wire format on the attestation side is unchanged (the bucket field
  already existed); the v1 HKDF domain tag has been retired and
  `tests/vectors/` was regenerated under the v2 tag. The Nacre app
  surfaces the derived emergency secret with a "save your recovery key"
  affordance, though the user can always re-derive it by signing the
  canonical message again. See `ARCHITECTURE.md §6.2 / §7.5 / §9.6 /
    §10.1 / §10.3`.
</Update>

<Update label="May 24, 2026" description="Hot-reserve key rotation: soft cutover">
  ## Updates

  **Hot-reserve key rotations no longer brick in-flight deposits.**
  Previously, executing `UpdatePrivyWalletPubkeys` immediately replaced
  the on-chain `hot_reserve_internal_key_secp256k1`, which silently
  invalidated every existing Hot Reserve deposit address — including
  addresses where PRL had been deposited but the bridge hadn't yet
  attested or minted. Affected deposits could only be recovered via the
  Pearl-side 7-day script-path timelock.

  `ProtocolConfig` now carries a bounded ring (`MAX_PREVIOUS_HOT_RESERVE_KEYS = 3`) of rotated-out internal keys plus a configurable
  `hot_reserve_rotation_grace_slots` window. On rotation, the outgoing key
  is parked in the ring with `expires_at_slot = now + grace_slots`. The
  on-chain `mint_deposit` handler accepts deposits derived from either
  the current key or any non-expired ring entry. Default grace window is
  \~8 days at 400ms slots — strictly longer than the Pearl-side
  `HOT_RESERVE_CSV_BLOCKS` so a user mid-deposit at rotation can't end
  up outside both windows simultaneously. See `ARCHITECTURE.md §7.2`.
</Update>

<Update label="May 24, 2026" description="Toolchain upgrade">
  ## Updates

  **Anchor 1.0.2 / Solana 4.0.0.** The four on-chain programs now build
  against Anchor 1.0.2 and the Solana 4.0 (platform-tools v1.52) toolchain.
  The on-chain `.so` artifacts are rebuilt; clients should re-fetch the IDLs
  from `target/idl/`.

  **`claim_cold_reserve_utxo` wire format.** The instruction now takes the
  claim outpoint (`claim_txid_be: [u8; 32]`, `claim_vout: u32`) as explicit
  arguments alongside the existing attestation bytes. The on-chain handler
  rejects if they don't match the validator-quorum-signed attestation —
  no new authority surface, the args are only there so the IDL resolver
  can statically recognize the `claim` PDA seeds.
</Update>

<Update label="May 24, 2026" description="Testnet redeploy">
  ## New features

  **Solana devnet bridge fully wired.** The testnet's full Solana side is now live: all 4 Anchor programs (`nacre_two_way_peg`, `nacre_liquidity_management`, `nacre_layer_ca`, `nacre_protocol_config`) deployed, wPRL Token-2022 mint created, Privy quorum provisioned, ALT staged. Authoritative addresses now live on the [protocol addresses page](/protocol/addresses); a machine-readable snapshot is at `infra/devnet/solana-devnet.json`.

  **Dynamic Hot Reserve discovery.** Validators now learn which Hot Reserve script\_pubkeys to watch from the on-chain `HotReserveBucketCreated` event stream (and seed via `getProgramAccounts` at boot), instead of needing a per-depositor terraform reapply. The frontend's "Generate deposit address" flow registers the bucket on-chain; the validator picks it up live.

  ## Updates

  **Two-way-peg program no longer uses `sol_big_mod_exp`.** The on-chain BIP-341 derivation (`verify_hot_reserve_address` / `verify_cold_reserve_address`) was calling a syscall that's feature-gated and inactive on every public Solana cluster, which prevented deploying anywhere real. Replaced with a `sol_secp256k1_recover` trick that produces an identical `lift_x` result via a syscall that IS universally active. \~25k CU per call instead of >1M for a pure-Rust modexp fallback.

  **Split-signer mode is now the testnet default.** The aggregator runs with `NACRE_SIGNER=split` so Hot Reserve sweeps (script-tree taproot, which Privy can't sign) work in-process, while Cold Reserve + Solana attestations route through real Privy.

  **Explorer tab + unified read API.** The bridge web app gained a `/explorer` master/detail table — live polling of every mint and redeem intent across both chains, with a per-intent lifecycle timeline and copy-buttons on every on-chain reference. The new wrap/burn waiting pages route through the same NacreScan `/intents` endpoint, so the consumer surface is one Lambda + one schema for both the live deposit tracker and the historical view. State machine consolidated to seven reachable values (`confirming → pending → quorum_reached → finalized` for mints, `escrowed → quorum_reached → attested → cleaned` for redeems, plus `expired` for the cancellation path); the SQS aggregator hop was removed and every transition is now derived directly from on-chain observation.
</Update>

<Update label="May 22, 2026" description="Weekly release">
  ## New features

  **Testnet bridge is live.** The Nacre testnet bridge is now hosted at
  [testnet.wrapped-pearl.com](https://testnet.wrapped-pearl.com). Connect a
  Solana wallet, send PRL on Pearl signet, and receive wPRL on Solana devnet
  end-to-end through the full validator pipeline. See the
  [quickstart](/quickstart) to walk through a mint.

  **Wallet Standard support.** The testnet bridge now uses the Solana Wallet
  Standard for wallet connection. Phantom, Backpack, Solflare, and any other
  Wallet-Standard-compatible Solana wallet work out of the box — no extra
  account creation step.

  **NacreScan explorer.** A read-only explorer for bridge activity is now
  online. NacreScan ingests confirmed Pearl deposits and Solana mint/burn
  events and exposes them through a public read API, so you can track a
  transfer from PRL deposit to wPRL mint (and back) without running your
  own indexer.

  **`CONFIRMING` state for in-flight deposits.** Deposits that have landed
  on Pearl but not yet reached the protocol confirmation depth are now
  surfaced as `CONFIRMING` in the explorer, with the current depth and the
  target depth. You can see your transfer the moment Pearl includes it,
  instead of waiting for the full confirmation window.

  ## Updates

  **Smaller, cheaper mint transactions.** The two-way-peg program now
  credits bridge fees directly to a single protocol treasury account, and
  attestation payloads have been trimmed to the fields the on-chain
  verifier actually needs. The `mint_deposit` transaction drops from
  2,132 bytes to 1,080 bytes — comfortably under Solana's 1,232-byte
  packet limit — which removes the previous occasional "transaction too
  large" failures on mint.

  **Attestation format v2.** `ATTESTATION_VERSION` has been bumped from
  `1` to `2`. Four informational fields were removed from
  `DepositAttestation` and two from `RedemptionAttestation`. If you parse
  attestations off-chain, regenerate your bindings before interacting with
  the new program build. The on-chain interface and user flows for mint,
  burn, and recover are unchanged. See the
  [wPRL overview](/wprl/overview) for the current flow.

  **Bridge home page polish.** The bridge app now ships with a proper page
  title, description, and social-share preview, so links shared in Discord,
  Telegram, and X render with the Wrapped Pearl branding.
</Update>
