add TransactionPrototype type and CST encoder/decoder - #837
Open
lisicky wants to merge 1 commit into
Open
Conversation
A backend-agnostic representation of a fully-resolved Cardano transaction, typed against the Conway CDDL, plus converters in both directions: - mesh-common: the TransactionPrototype types - mesh-core-cst: prototype <-> Transaction (decoder enables round-trip tests) - mesh-core-csl: serializeTxPrototype via js_tx_prototype_to_hex Also fixes a pre-existing bug in utils/certificate.ts, shared with the v1 builder: StakeVoteRegistrationAndDelegation emitted CDDL certificate 10 instead of 13, dropping the deposit that getTotalDeposit() still charged.
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.
What
TransactionPrototype— a universal layer representing a raw transaction that is already in aserialization-friendly state, plus converters between it and CBOR.
This is groundwork for the new tx builder. The intended shape is: the builder does its work
(coin selection, witness collection, fee calculation) and at the end assembles a
TransactionPrototype, which is what it hands to the serializer. The prototype itself holds nobuilder logic — every value in it is already decided.
Why it lives in
mesh-commonmesh-core-cstandmesh-core-cslare two backends behind oneIMeshTxSerializer. Both needthe same shape, so the type cannot live in either of them. The file has no runtime imports, so
this adds no dependency edge.
Contents
mesh-common— the types. Typed against the Conway CDDL(
IntersectMBO/cardano-ledger,eras/conway/impl/cddl/data/conway.cddl), not against anybackend's own field widths.
mesh-core-cst/tx-prototype-to-cbor— prototype →Transaction.mesh-core-cst/tx-prototype-from-cbor—Transaction→ prototype. Exists mainly so theencoder can be round-trip tested;
decode(encode(x)) === xcatches silent field drops thatper-field assertions miss.
mesh-core-csl/tx-prototype—serializeTxPrototypeviajs_tx_prototype_to_hex.135 tests.
bigintis used (notnumber | bigint) for every field whose CDDL range exceedsNumber.MAX_SAFE_INTEGER, so a plain numeric literal is a compile error rather than a silentprecision loss.
Two CDDL points
Plutus scripts are split per version.
transaction_witness_setkeys 3/6/7 andauxiliary_data_mapkeys 2/3/4 are separate fields because a script's language version is notrecoverable from its bytes — the map key is what records it. A single version-less list cannot
round-trip a V2/V3 script.
transactionPrototypeToHextakes ataggedSetsoption. CDDL accepts both#6.258-taggedsets and plain arrays, but the choice is transaction-wide and changes the tx hash.
@cardano-sdk/coredecides it from a module-global read at serialization time (defaultfalse,flipped to
trueas a side effect of constructing aCardanoSDKSerializer). The option pinsthat global for the duration of the call and restores it, so output neither depends on nor leaks
ambient state.
Unrelated fix included
utils/certificate.ts— shared with the v1MeshTxBuilder— handledStakeVoteRegistrationAndDelegationby emittingnewStakeVoteDelegationCert(CDDL certificate10) instead of
newStakeVoteRegistrationDelegationCert(13). The two produced identicalCBOR and the deposit was dropped, while
getTotalDeposit()still charged it: the balance assumeda deposit the certificate never declared, and the stake credential was never registered.
There is no public builder method that reaches this today, so exposure is low. Not covered by any
test on the v1 path — the new tests exercise it through
certificatePrototypeToCardano.Known limitations
prefer_alonzo_formatandPlutusListPrototype.definite_encodingare not honoured —@cardano-sdk/coreexposes no control for either. Documented at their declarations.PARAMETER_CHANGE_ACTION; it throws rather than return ahalf-correct protocol-parameter update.
transaction_outputhas two legal encodings (Alonzo array / Babbage map) and the type does notexpress the choice — CST derives it from content. Stable for anything encoded here; only
byte-exact re-encoding of a third-party transaction is affected.
update, genesis-key and MIR certificates, PPUd/extra_entropy/protocol_version) are absent from the type by design.