Please describe your proposed solution.
Problem
Cardano-transaction-library (CTL) is a Swiss knife framework for Cardano offchain development created at MLabs. To appeal to a wider audience, a few shortcomings have to be addressed.
Wide dependency tree, use of WebAssembly
There are a number of WebAssembly dependencies we use that bloat CTL-produced front-end bundles for end users: it’s not possible to tree-shake WebAssembly binaries using JavaScript bundlers.
cardano-serialization-library (CSL) is a dependency of CTL. CSL’s code is partially autogenerated using https://github.com/dcSpark/cddl-codegen, which reads Cardano CDDL and emits rust code. Rust code then gets compiled to WebAssembly, and the build artefacts can be consumed as an NPM package: https://www.npmjs.com/package/@emurgo/cardano-serialization-lib-browser
At the moment of writing, the WASM binary in this package is 2.03 MB
cardano-message-signing (CMS) is a library that implements CIP-0008 message signing spec and is consumable from the browser as an NPM package:
<https://www.npmjs.com/package/@emurgo/cardano-message-signing-browser>
The WebAssembly blob is of 372KB in size.
cardano-message-signing is used for Cip30Mock implementation, that is only needed for testing.
uplc-apply-args (<https://github.com/mlabs-haskell/uplc-apply-args>) is a custom solution we use for applying PlutusData arguments to parameterized Plutus Scripts.
The WebAssembly blob is of 177KB in size.
Solution
Wide dependency tree, use of WebAssembly
We will re-implement parts of functionality in TypeScript or JavaScript and move the rest to optional dependencies.
cardano-serialization-library contains some functionality that we don’t actually need.
We use CSL for two purposes:
- Conversion between domain types and their CBOR representations
- Min-ada fee estimation using MinOutputAdaCalculator
We want to build a lightweight JS-only re-implementation of the part of CSL responsible for CBOR (de) serialisation of Cardano domain types. This part will have the same interface as CSL so that we can plug it into CTL without much refactoring.
There are ~130 semantically nontrivial CSL domain types we use.
Among them:
- 6 address-related types
- 3 numeric types: BigInt, Int, BigNum - we use arithmetic from CSL only for BigNum
We can allow ourselves to differ from CSL by lifting some requirements that are not relevant to us:
- We will only produce code for the latest era specification (no backwards compatibility is needed because we only deal with transactions from the current era)
- We will not guarantee that roundtrip property is preserved - serialize(deserialize(tx)) may differ from tx - again, because we don’t deal with deserialization a lot.
We have considered three approaches to implementing Cardano domain-type serialization:
- Code generation from CDDL to JS, similar to how <https://github.com/dcSpark/cddl-codegen> does that - requires writing a code generator from CDDL to JS / TS
- pros: automatic deriving of code from specification is a principled approach to software development. High correctness guarantees.
- cons: We have a limited set of data types and there is no potential for reuse
- cons: New versions of CDDL specs are proposed rarely and are always announced in advance
- cons: we estimate the development time to be >3 months (longest)
- cons: Even cddl-codegen does not allow to generate 100% of the code: https://github.com/dcSpark/cddl-codegen/blob/master/GENERATING_SERIALIZATION_LIB.md - because address data layout is not specified in CDDL, and there are a few technical limitations. High risks
- Manual implementation means writing the encoders/decoders by hand
- pros: straightforward approach that does not involve many risks
- cons: will require manual changes in the future
- cons: we estimate the development time to be slightly less than 3 months
- Adapting serialization code from cardano-js-sdk:
- pros: the (en/de)coder code is already there, no need to write it
- pros: lowest development cost
- cons: a fork is required, because serialization-related types are tightly coupled with the rest of the library
We decided to adapt serialization code from @cardano-sdk/core by stripping the unneeded parts and maintaining it as a separate project (proposed name “cardano-data-lite”, may be changed in the future).
MinOutputAdaCalculator is another CSL API we will have to re-implement. It is just a piece of arithmetics code that is trivial to rewrite:
<https://github.com/Emurgo/cardano-serialization-lib/blob/5c58e5ee75b0d6262840287ba06c9f9d1caf1037/rust/src/utils.rs#L1403>
cardano-message-signing (CMS)
We believe that, since most users would not need the CMS library in the browser context, it is possible to re-organize the CTL structure to make it an optional dependency for clients’ projects.
uplc-apply-args
We have evaluated the feasibility of implementing it in pure JavaScript, and, unfortunately, the scope of the functionality is too wide for us to fit it into a single Catalyst proposal. We will move it to a separate package for now, and free most of the users who do not need this functionality from having to deal with WebAssembly.
Market
Our target audience is Cardano dApp developers who use or may use CTL in the future, including current clients of MLabs.
Features
- New reusable library with a CSL-like interface that implements cardano domain types serialization and deserialization in pure JavaScript
- Dependency footprint reduction of CTL
Related work
Previous Catalyst proposals for Cardano Transaction Library development:
- Catalyst Fund8: <https://cardano.ideascale.com/c/idea/396607>
- Catalyst Fund9: <https://cardano.ideascale.com/c/idea/64398>
- Catalyst Fund10: <https://cardano.ideascale.com/c/idea/101478>