Txmanifest - portable format for wallets to call SimplicityHL contracts without custom code

I am not sure why I find it hard to describe the need for something like this. I think a lot of users of SimplicityHL think about writing the .simf file and that’s the end of it. Creating the contract is probably the most mentally challenging part, but there is a fair amount of (tedious) work in creating the wallet that interacts with the contract.

Currently, simplicity contracts basically require their custom wallets to be developed. My goal for txmanifest is to create a standardized, descriptive format that wallets can implement for building transactions interacting with simplicity inputs and are able to generate addresses.

The file itself can grow quite complex, so I’ve created a book to guide users through learning it, and that’s my recommended learning path: Introduction - The tx-manifest Cookbook

At the same time, I’ve created an ELIP and I’ll be editing it as I test out more and more use cases with it.

I’ll keep adding to this thread to keep everyone up to date. I’d love some feedback.

2 Likes

I’ve pushed a new version. There are a lot of changes so I’ve started a changelog.

[0.2.0] - 2026-08-20

Breaking: a manifest that sets utxo_type.confidential no longer parses.
Confidentiality is now declared per output.

Added

  • Blinding factors can be declared. An output or an input may carry a
    blinding block of asset_bf / value_bf. Each is a 32-byte scalar written
    as a decimal, a 0x string, a params.X / instance.X reference, or
    arithmetic over one (params.RT_FACTOR + 1). On an output it pins what the
    builder would otherwise pick at random; on a covenant input it states the
    factors the spent UTXO was created with. Needed by any covenant that verifies
    its own UTXOs as Pedersen commitments, because Elements’ blind_last chooses
    every factor itself.
  • Confidential covenant outputs. confidential: true on a utxo_type
    destination blinds the output, using the wallet’s change blinding key.
  • Confidential covenant inputs. Their prevout is rebuilt from the asset,
    the amount and the declared factors — a taproot sighash and Simplicity’s
    inputUTXOsHash both cover only a spent output’s asset, value and
    scriptPubKey, so the reconstruction is exact and needs no network access.
  • allow_change on an action: none, lbtc_only or any, bounding which
    surpluses may become a change output the manifest never declared.
  • A parameter interface for utxo_type: params on the type and args at
    each site, which closes the type’s scope so its address derivation reads only
    what it declares.
  • script_hash param compute, deriving sha256(scriptPubKey) from an
    address so a covenant’s committed hash and the address paid to cannot drift.
  • On-chain amounts. A pinned outpoint reads its amount and asset from the
    chain, outranking anything the manifest or an operator supplies.
  • simplicity_hl.unstable_features for opting into SimplicityHL imports
    and enums.

Changed

  • A reissuance now writes the spent token’s asset blinding factor as its
    issuance_blinding_nonce, which is the value Elements rebuilds the token’s
    generator from. Previously a constant placeholder.
  • Pinning an output’s asset_bf to the value an input of the same asset already
    carries is refused with an explanation. The surjection proof would have a zero
    shift to prove; secp reports only CannotProveSurjection.

Removed

  • utxo_type.confidential (breaking). It answered per address a question
    that is per output: one covenant address can hold a blinded reissuance token
    beside an explicit collateral UTXO. Use confidential on the output. Every
    example set it to false, and the builder only ever read it to warn.

Nice, awesome to see that v0.2.0 supports re-issuance tokens!

I know I’ve discussed this elsewhere many times, but I’d love to see support for tx manifests to describe not just how to push a known contract instance forward, but how to discover contract instances purely from chain data, and re-derive their state. Such functionality, I think, could allow for building a tx manifest indexer server. Such a server could be given multiple different tx manifests along with their SimplicityHL source files (and possibly their SimplicityHL compiler version) and each manifest’s initial block height, and the indexer could scan every block and transaction from a connected liquid node and index all found instances. This could replace the lending indexer, and eliminate the need for creating a new indexer for each simplicity contract.