Wires the chipnet-validated DeviantAdjustableFeeCapped covenant (snapshot
0259) into the wallet end-to-end, following Parameters/Artemision/
SESSION_PROMPT_adjustable-fee-wallet-integration.md.
**Type + planner (core)**
- `TokenTierA.adjustableFee?: { maxFeeBps, founderPubKeyHex }` — immutable
identity only; the live feeBps lives on chain in the reservoir NFT's
commitment (cached values would go stale on updateFee).
- `GenesisIntent.adjustableFee?: {...}` — when present, prepareGenesis()
uses ADJUSTABLE_FEE_CAPPED_ARTIFACT with the 5-arg constructor
(category, rateSats, maxFeeBps, founderPubKey(33), founderLB(25))
instead of DeviantOpenMintFT's 4-arg constructor. Validates 0<=start<=
cap<=500 and pubkey format.
- Genesis executor grows an optional `nftOverride: { capability, commitment }`.
Adjustable-fee assets pass { mutable, bytes(startingFeeBps) } so the
reservoir NFT can be rotated by updateFee later; fixed-fee assets stay
{ minting, '' } as before.
- Embedded artifact: contracts/dist/DeviantAdjustableFeeCapped.json copied
to src/verify/artifacts/ + exported as ADJUSTABLE_FEE_CAPPED_ARTIFACT.
**ScriptNum codec**
- src/token/scriptNum.ts — pure encode/decode for the ScriptNum used by
CashScript's bytes(int); hex wrappers (feeBpsToCommitmentHex /
commitmentHexToFeeBps) match the reservoir NFT's commitment field
byte-for-byte. 10/10 unit tests cross-check against the exact values
the chipnet test produced on-chain (feeBps 100→"64", 300→"2c01", 500→"f401").
**updateFee flow (shell)**
- shells/app/src/core/updateFee.ts — executeUpdateFee() reconstructs the
covenant from the stored descriptor, fetches the mutable reservoir
UTXO, builds an updateFee(newFeeBps, sig) tx, and broadcasts. Errors
bucketed via UpdateFeeError (not-adjustable / fee-out-of-range /
not-founder / no-reservoir / no-bch / broadcast-failed).
**Artemision wizard**
- New "Fee mode" segmented control on step 4 (MBA path): Fixed 🔒 vs
Adjustable ✎. Adjustable shows both sliders as the honest two-knob
(starting feeRate + immutable maxFeeRate cap); Fixed shows one slider
and the copy states the fee is baked into bytecode forever.
- Session's compressed pubkey derived via secp256k1 for the constructor's
founderPubKey arg. Review-wall lists fee-mode + which covenant deploys.
**AssetDetail founder actions**
- Modify founder-fee row is now live for adjustable-fee assets: click →
modal with current-fee readback, cap display, decimal input (validated
0..cap), Broadcast. On success rotates the on-chain commitment,
refreshes the local registry's cached founderFeeBps, and shows the
txid + confirmation banner. Fixed-fee assets keep the disabled row +
explainer pointing at the Artemision Adjustable option.
**Not in scope (deferred)**
- claim.ts / swap.ts LIVE fee read from the reservoir commitment — for
now claims still use the cached founderFeeBps (stale after an update).
The next slice adds a live-fee lookup pre-quote.
- Portable descriptor v1 emit/parse for adjustableFee (Route B pattern).
- Live end-to-end chipnet drive of the new wallet flow (unit tests +
chipnet-adjustable-fee-test.mjs cover the covenant + codec).
10/10 scriptNum tests + 607/607 full suite pass. Core tsc + shell tsc
clean. Deployed to deviant.x.