phase 4.5, 4.6, 3.6 close-out: stake delegation + multisig mint primitive

stake key + reward address (4.5):
- StakeKey::stake_address(network) — bech32 (`stake1...` mainnet,
  `stake_test1...` testnet) via pallas_addresses::StakeAddress::new
  (added to the fork in the same commit since the upstream tuple
  struct had no public constructor).
- StakeKey::xprv() — crate-internal accessor for signing.
- WalletInner now holds the stake_key alongside the payment_key.
- mcp tool wallet.stake.address surfaces the bech32.

stake delegation (4.6):
- new aldabra-core::stake module:
  - parse_pool_id(bech32) → Hash<28>
  - build_signed_stake_delegation(payment, stake, network, utxos,
    change_addr, pool_bech32, register_first, params) → signed cbor.
  - if register_first: prepends a StakeRegistration cert (consumes
    a 2 ADA deposit from inputs). otherwise just delegates.
  - signs with both payment_key (body witness) and stake_key (cert
    witness). reuses sign::add_witness for both — same body-hash
    ed25519 signing path regardless of CIP-1852 chain index.
- mcp tool wallet.stake.delegate: pool_id, register_first (defaults
  true). signs + submits.

3.6 close-out — wallet.mint.unsigned mcp tool:
- exposes the existing build_unsigned_mint with caller-supplied
  PolicySpec (json), so multi-sig / treasury flows can build through
  this wallet without it auto-signing. round-trip with
  wallet.sign_partial chain → wallet.submit_signed_tx.

depends on Sulkta-Coop/pallas@feat-aux-data which gained two more
patches in the same branch:
- StakeAddress::new public constructor.
- StagingTransaction::add_certificate / clear_certificates +
  Conway::build_conway_raw decode-and-plumb for certs (filling in the
  `certificates: None, // TODO` upstream).

mcp tools: 12 → 15 (wallet.stake.address, wallet.stake.delegate,
wallet.mint.unsigned).

79 → 84 unit tests. new coverage: stake address bech32 round-trip,
pool_id bech32 parse + reject-wrong-hrp, delegation tx with + without
registration (asserts cert count, witness count, cert variants).
fork tests grew: certificates_plumb_through_to_tx_body and
no_certificates_means_none.
This commit is contained in:
Sulkta 2026-05-04 12:41:10 -07:00
parent 640af23598
commit 49986d2864
7 changed files with 669 additions and 9 deletions

View file

@ -81,6 +81,7 @@ async fn run() -> Result<()> {
)?;
let payment_key =
aldabra_core::derive_payment_key(&root, cfg.account, cfg.index);
let stake_key = aldabra_core::derive_stake_key(&root, cfg.account);
tracing::info!(%address, "derived base address");
if bootstrap_only {
@ -95,6 +96,7 @@ async fn run() -> Result<()> {
address,
cfg.koios_base,
payment_key,
stake_key,
cfg.max_send_lovelace,
);
let server = service