cardano-wasm: add stake-key witnessing (signWithStakeKey / alsoSignWithStakeKey)#1240
Merged
Conversation
…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
Contributor
There was a problem hiding this comment.
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.signWithStakeKeyandSignedTx.alsoSignWithStakeKeyacross 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
reviewed
Jul 2, 2026
carbolymer
approved these changes
Jul 2, 2026
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.signWithPaymentKeyandSignedTx.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-wasmAPI: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_skkeys are accepted, matching thepayment path (
addr_skonly).The API method list has a single source (
Cardano.Wasm.Api.Info) that generates both the*.d.tsand 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 thecardano-wasiwasm export list are updated to match.How to trust this PR
cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs(signWithStakeKeyImpl/alsoSignWithStakeKeyImpl): a line-for-line mirror of the payment versions, withWitnessStakeKeyinstead ofWitnessPaymentKey.cardano-wasm/npm-wrapper/api.test.jsbuilds a delegation transaction, signs it with the payment key andthen
alsoSignWithStakeKey.cabal test cardano-wasm:cardano-wasm-golden: verifies the generated TypeScript declarations.npm install && npm run build && npm testincardano-wasm/npm-wrapper: exercises the new methods through the built wasm.Checklist
tests for more details
.changes/