Skip to content

cardano-wasm: add stake-key witnessing (signWithStakeKey / alsoSignWithStakeKey)#1240

Merged
palas merged 4 commits into
masterfrom
add-stake-signing-primitives
Jul 3, 2026
Merged

cardano-wasm: add stake-key witnessing (signWithStakeKey / alsoSignWithStakeKey)#1240
palas merged 4 commits into
masterfrom
add-stake-signing-primitives

Conversation

@palas

@palas palas commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Context

After #1239 fixed certificate deserialisation, stake registration works end to end, but delegation and
unregistration transactions still can't be completed: they need a witness from the stake credential, and the only
signing methods: UnsignedTx.signWithPaymentKey and SignedTx.alsoSignWithPaymentKey, reject stake signing keys
(stake_sk…). Those transactions therefore go out missing a required witness and are rejected on submit.

This PR adds stake-key witnessing to the cardano-wasm API:

  • UnsignedTx.signWithStakeKey(signingKey)
  • SignedTx.alsoSignWithStakeKey(signingKey)

A vkey witness is key-agnostic (the ledger matches the vkey hash against the required-signer set), so the new methods
mirror the payment-key ones exactly and only differ in decoding a stake signing key and building a WitnessStakeKey.
Signing is not era-specific, so there are no era variants. Only non-extended stake_sk keys are accepted, matching the
payment path (addr_sk only).

The API method list has a single source (Cardano.Wasm.Api.Info) that generates both the *.d.ts and the runtime JS API,
so most of the diff is that one edit plus its regenerated golden .d.ts. The JS bridge, the WASI bridge, and the
cardano-wasi wasm export list are updated to match.

How to trust this PR

  • The witness construction lives in cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs (signWithStakeKeyImpl /
    alsoSignWithStakeKeyImpl): a line-for-line mirror of the payment versions, with WitnessStakeKey instead of
    WitnessPaymentKey.
  • New test in cardano-wasm/npm-wrapper/api.test.js builds a delegation transaction, signs it with the payment key and
    then alsoSignWithStakeKey.
  • To run:
    • cabal test cardano-wasm:cardano-wasm-golden: verifies the generated TypeScript declarations.
    • npm install && npm run build && npm test in cardano-wasm/npm-wrapper: exercises the new methods through the built wasm.

Checklist

  • Commit sequence broadly makes sense and commits have useful messages
  • New tests are added if needed and existing tests are updated. See Running
    tests
    for more details
  • Self-reviewed the diff
  • Changelog fragment added in .changes/

…thStakeKey)

Delegation and (de)registration transactions require a witness from the
stake credential, but the only signing methods (signWithPaymentKey /
alsoSignWithPaymentKey) accepted payment signing keys and rejected
stake_sk keys, so those transactions were missing a required witness and
were rejected on submit.

Add signWithStakeKey (on UnsignedTx) and alsoSignWithStakeKey (on
SignedTx), mirroring the payment-key methods but decoding a stake
signing
key and attaching a WitnessStakeKey vkey witness. Signing is not
era-specific, so no era variants are needed. Extended stake keys
(stake_xsk) are not accepted, consistent with the payment path
(addr_sk only).

- Api.Tx: signWithStakeKeyImpl / alsoSignWithStakeKeyImpl
- JS bridge (Bridge.hs) and WASI bridge (Api/Tx.hs, Conversion.hs)
  exports + stake signing-key decoders
- cardano-wasi wasm --export list
- Api.Info entries (drive the generated .d.ts and the runtime JS API)
- regenerated unsigned-tx.d.ts / signed-tx.d.ts golden files
- api.test.js: delegation tx signed with payment + stake key, asserting
  two vkey witnesses
- js-test/basic-test.golden: new methods on UnsignedTx / SignedTx
@palas palas self-assigned this Jul 1, 2026
@palas palas requested review from Jimbo4350 and erikd as code owners July 1, 2026 00:57
Copilot AI review requested due to automatic review settings July 1, 2026 00:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the cardano-wasm public API to support stake-key witnessing, enabling end-to-end construction and submission of stake delegation and stake (de)registration transactions that require a witness from the stake credential.

Changes:

  • Added UnsignedTx.signWithStakeKey and SignedTx.alsoSignWithStakeKey across the core implementation and both JS/WASI bridges.
  • Updated the API method metadata source (Cardano.Wasm.Api.Info) and regenerated the corresponding TypeScript declaration goldens.
  • Added a JS integration test that builds a delegation transaction and signs it with both payment and stake keys, plus updated wasm export list and changelog fragment.

Reviewed changes

Copilot reviewed 9 out of 11 changed files in this pull request and generated no comments.

Show a summary per file
File Description
cardano-wasm/src-wasm/Cardano/Wasm/Internal/JavaScript/Bridge.hs Adds stake signing-key decoding and JS exports/wrappers for signWithStakeKey / alsoSignWithStakeKey.
cardano-wasm/src-wasi/Cardano/Wasi/Internal/Conversion.hs Adds WASI conversion helper to parse stake signing keys from C strings.
cardano-wasm/src-wasi/Cardano/Wasi/Internal/Api/Tx.hs Exposes WASI C-callable functions for stake-key signing and wires them to the core impl.
cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs Implements signWithStakeKeyImpl / alsoSignWithStakeKeyImpl mirroring the payment-key flow with WitnessStakeKey.
cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs Registers the new API methods so runtime JS API and *.d.ts generation include them.
cardano-wasm/npm-wrapper/api.test.js Adds an integration test covering delegation tx signing with both payment and stake keys.
cardano-wasm/lib-wrapper/unsigned-tx.d.ts Regenerated declaration to include signWithStakeKey.
cardano-wasm/lib-wrapper/signed-tx.d.ts Regenerated declaration to include alsoSignWithStakeKey.
cardano-wasm/js-test/basic-test.golden Updates golden output to include the new methods in the JS API surface.
cardano-wasm/cardano-wasm.cabal Adds wasm export symbols for the new stake-key signing functions.
.changes/20260701_001339_cardano-wasm_pablo.lamela_add_stake_signing_primitives.yml Adds Herald changelog fragment documenting the new cardano-wasm feature.

@carbolymer carbolymer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻

Comment thread cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs Outdated
Comment thread cardano-wasm/src-wasi/Cardano/Wasi/Internal/Conversion.hs Outdated
Comment thread cardano-wasm/npm-wrapper/api.test.js

@Jimbo4350 Jimbo4350 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

palas added 3 commits July 3, 2026 00:28
Address review feedback: signWith{Payment,Stake}KeyImpl and
alsoSignWith{Payment,Stake}KeyImpl were near-verbatim copies differing
only in the witness constructor. Extract signWithKeyImpl /
alsoSignWithKeyImpl taking a ShelleyWitnessSigningKey, so each public
function reduces to a one-liner and the witnessing logic has a single
source of truth.
Address review feedback: stringToStakeSigningKey was byte-for-byte
identical to stringToSigningKey, differing only in the return type.
Since deserialiseFromBech32 is already polymorphic over
SerialiseAsBech32, generalise stringToSigningKey to any key role and
drop the duplicate. Call sites pin the role via <*>, so type inference
resolves it. Future key types (DRep, committee, ...) now work without
adding another copy.
Address review feedback: the existing delegation test only exercised
alsoSignWithStakeKey (stake as a second signer). Add a test that signs
with the stake key first and then alsoSignWithPaymentKey, covering the
standalone signWithStakeKey path. Witnesses live in a set, so the
resulting transaction is byte-for-byte identical to the payment-first
variant, as the test asserts.
@palas palas added this pull request to the merge queue Jul 3, 2026
Merged via the queue into master with commit df798c9 Jul 3, 2026
30 of 31 checks passed
@palas palas deleted the add-stake-signing-primitives branch July 3, 2026 01:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants