Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: TX builder #267

Open
scarmuega opened this issue Jul 13, 2023 · 5 comments
Open

feat: TX builder #267

scarmuega opened this issue Jul 13, 2023 · 5 comments
Labels
enhancement New feature or request

Comments

@scarmuega
Copy link
Member

Problem:

  • Creating Cardano transactions is hard. Inputs, outputs, witnesses, datums, redeemers, hashes, etc, need to be carefully arranged to obtain a well-formed transaction that can be submitted to the chain. The end result has to be encoded into CBOR, which adds an extra layer of complexity.
  • Pallas already has structs representing all of the ledger primitives for the different eras in Cardano. These primitives provide an decoding / encoding mechanism from / to CBOR, which reduces complexity, but the structs still need to be carefully arranged to respect all of the business invariants of the ledger.

Proposal:

  • Create a new Pallas crate name pallas-tx-builder providing an ergonomic and idiomatic library for crafting transactions.
  • The only responsibility of this library is to provide high-level functions to compose low-level primitive structs from the pallas-primitives crate.
  • The end result could be a fully-defined, valid transaction or a partially defined transaction. This will depend on how the lib consumer decides to operate.
  • There should be no kind of IO operations in the crate. All of the data should be provided by the lib consumer as arguments. For example, input UTxO required to balance the transaction should be provided by the lib consumer.
  • The main entry-point for tx creation should use the common builder pattern.

Examples of some high-level functions that the lib could / should provide:

  • specify basic output to an address with some ADA
  • specify an output to an address and some native assets
  • specify outputs containing datums
  • specify reference inputs
  • specify inputs from tx hash / index
  • construct datums using native Rust types
  • allow minting
  • sign tx with a private key
  • attach redeemers to txs
  • attach spending validators
  • add metadata from key / value using native Rust types
  • compose partial txs into a single one
  • add collateral from specific input
  • balance the tx by creating a change output back to a specific addr
  • balance the collateral by creating a collateral return
  • encode as CBOR

The above list is just a preliminary reference, final feature is not limited to just those functions.

The following are things that should NOT be part of the library:

  • fetch utxos from some data provider
  • submit the transaction to a node
@scarmuega scarmuega added the enhancement New feature or request label Jul 13, 2023
@rvcas
Copy link
Member

rvcas commented Jul 14, 2023

for reference: #250

Totally fine if the above is thrown away btw. But perhaps a good reference for whoever picks this up.

@Quantumplation
Copy link
Collaborator

These may be covered by your list of examples, I'm tired and can't go through it lol. But, below is two examples of really common transaction types that we build at Sundae:

Simple token transfer tx

  • Take in one or more inputs from a server-controlled wallet
  • Take in one or more inputs (as needed) from a user wallet, with intelligent UTXO selection
  • Transfer {some token amount} from the server wallet to the users address
  • Transfer {some fee amount} from the users wallet to the server wallet
  • User covers the fee and minUTXO requirements for assets going to their wallet
  • Add one or more required signers
  • Attach some metadata

Transaction dependent on fee

  • When building scoop transactions, we need to know what the fee is, because we need to ensure that "sum of scooper fees from the input escrows, minus the tx fee, is paid to the "scooper lock contract"
  • This means we need the ability to run the tx builder logic inside of a "fixed point" closure to narrow in on the fee (usually converges in 2 or 3 iterations)

@Quantumplation
Copy link
Collaborator

Most tx builders use a "available inputs + change address" abstraction, for balancing the transaction; the first case above becomes a lot easier if you can have multiple labeled sources / change addresses; so you can specify "here's all the inputs from the Server, and all change should go back to X; and here's all the inputs from the User, and all change should go back to Y;" and then allow the user to explicitly transfer funds between these two pools.

@scarmuega
Copy link
Member Author

@Quantumplation nice feedback!

maybe create an abstraction representing a party which holds it's own UTxO set + change address. We could then support high-level operations such as transfer(from: party_a, to: party_b, assets) with all the balancing taken care of.

Is that what you had in mind?

@Quantumplation
Copy link
Collaborator

Yep, exactly! bonus points if you can extend that to include scripts, datums, etc.

I also had another thought: another common pattern is "I want to fit as many of these things as possible into the transaction", either processing escrows, or splitting assets into UTXOs with a specific size, etc; most transaction builders have good UX around grabbing as many inputs as we need, but no great experiences around the outputs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: In Progress
Development

No branches or pull requests

3 participants