Skip to content

feat: add transaction part builders for inputs, collateral and outputs - #854

Merged
twwu123 merged 6 commits into
mainfrom
feat/tx-parts-inputs-outputs
Oct 30, 2026
Merged

twwu123 merged 6 commits into
mainfrom
feat/tx-parts-inputs-outputs

Conversation

@lisicky

@lisicky lisicky commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

What

Adds builders for transaction parts: one call per input, collateral or output, taking everything that part needs at once. They return plain, immutable values shaped after TransactionPrototype, so they can later be assembled into one.

The code lives in its own directory, packages/mesh-transaction/src/tx-builder/, separate from MeshTxBuilder. It is not yet exported from the package root, and nothing existing changes.

Contents

packages/mesh-transaction/src/tx-builder/parts/:

  • spend.pubKey, spend.native, spend.plutus: an input with its witness.
    • Scripts can be attached or held in a reference output ({ reference }).
    • Redeemer data is accepted as Mesh Data or any BuilderData format.
    • The datum of a Plutus spend is "inline", "none" (Plutus V3 only) or { data }. When omitted, it is worked out from the spent UTxO.
  • referenceInput, collateral, collateralReturn.
  • output:
    • Value is given as Mesh Asset[] or as bigint quantities by unit.
    • The datum is inline, by hash, by hash with the datum published in the witness set (embed), or a known hash only.
    • A Plutus or native script can be attached as a reference script.
  • Inputs are given by reference or in full. Any input, including a script's reference output, can be an out ref or a full UTxO. A full UTxO is checked straight away and spares a lookup later. Parts copy what they are given and are deeply frozen.
  • Arguments are validated where the part is built, so a mistake fails at the line that made it rather than when the transaction is assembled:
    • out refs, addresses, values, asset units, datum hashes, scripts and execution units are checked for shape;
    • the witness must match how the UTxO is locked: a key, or the script with that hash;
    • the datum choice must fit the UTxO (inline vs hash vs none, hash equality);
    • a reference output must hold a script of the right kind and version.
  • Errors are typed. A TxPartError carries a code, the part kind and the part's label.
  • label? on every part, echoed in its errors.
  • unresolved(part) lists what a part leaves to be filled in before assembly: the contents of an input given by reference only, a reference script's hash/size/version, the datum of a spent output, execution units, an output's minimum lovelace, the total collateral. An empty list means the part is complete.
  • Redeemers carry no index. The index depends on where the item ends up once the transaction is sorted, so it is assigned once, at assembly, from what the redeemer belongs to.

Validation

npm run build:mesh
cd packages/mesh-transaction && npx jest test/tx-builder
  • 32 new tests:
    • every builder and every validation error;
    • unresolved for each kind of part;
    • a round trip: parts put into a minimal TransactionPrototype, encoded with transactionPrototypeToHex and decoded with transactionPrototypeFromHex, so their fragments survive real CBOR.
  • Full mesh-transaction suite (NODE_OPTIONS=--experimental-vm-modules npx jest): 185 tests pass. script-tx-fetcher and script-tx-fail fail to load under that flag on main too.

@twwu123
twwu123 added this pull request to stack #865 October 29, 2026 22:51
@twwu123
twwu123 merged commit 82cc3da into main Oct 30, 2026
1 check passed
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.

2 participants