Skip to content

Commit

Permalink
Merge pull request #1590 from Plutonomicon/klntsky/ps-csl
Browse files Browse the repository at this point in the history
Transition to purescript-cardano-serialization-lib
  • Loading branch information
klntsky committed May 5, 2024
2 parents eccf270 + 5de12f9 commit f8d2c52
Show file tree
Hide file tree
Showing 366 changed files with 6,686 additions and 22,198 deletions.
87 changes: 87 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,48 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]

In this version, we've refactored CTL and split it into multiple reusable sub-packages, most notably:

- this package
- `purescript-cardano-types` - (`Cardano.Types.*`) - domain types for Cardano ledger
- `purescript-cardano-serialization-lib` - (`Cardano.Serialization.Lib.*`) - PureScript wrapper for CSL
- `purescript-plutus-types` - (`Cardano.Plutus.*`) - Plutus-style domain types used only for `ToData`/`FromData` instances.

See the [cardano-purescript repo](https://github.com/klntsky/cardano-purescript) for a complete list of new packages.

These packages maintain their own public API, so the interfaces you should use are not necessarily namespaced under `Contract.*` anymore. E.g. `Cardano.Types.*` from `purescript-cardano-types` is public.

Starting from this version, CTL does not use Plutus-domain types anymore. This change comes with some downsides (e.g. the need to provide NetworkId in `Address`es), but the benefit of not caring about conversions for basic functionality will hopefully be more noticeable. The only case when a conversion is needed is when the developer wants to use [`purescript-plutus-types`](https://github.com/mlabs-haskell/purescript-plutus-types), which is a package that offers `PlutusData` encodings compatible with Plutus. Its main purpose is to be used when there is a need to apply arguments to parametrized scripts.

### Added

- New purescript dependencies:
- [`purescript-bytearrays`](https://github.com/mlabs-haskell/purescript-bytearrays)
- [`purescript-cardano-hd-wallet`](https://github.com/mlabs-haskell/purescript-cardano-hd-wallet)
- [`purescript-cardano-message-signing`](https://github.com/mlabs-haskell/purescript-cardano-message-signing)
- [`purescript-cardano-plutus-data-schema`](https://github.com/mlabs-haskell/purescript-cardano-plutus-data-schema)
- [`purescript-cardano-serialization-lib`](https://github.com/mlabs-haskell/purescript-cardano-serialization-lib)
- [`purescript-cardano-types`](https://github.com/mlabs-haskell/purescript-cardano-types)
- `Contract.Address.mkAddress` - a helper that automatically uses the correct `NetworkId` to construct an `Address`.
- Sharing wallets between Plutip tests - see [the docs for this feature](./doc/plutip-testing.md#sharing-wallet-state-between-tests) ([#1585](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1585))
- `runPlutipTestPlan` is a new function that executes a `ContractTestPlan`.
- `sameWallets` is a new function that creates a `ContractTestPlan` from a `UtxoDistribution` and a `TestPlanM` of the same wallets running different `Contract`s.
- new `onClusterStartup` hook that allows to get cluster startup parameters (private keys, `cardano-node` socket and config paths). See [`Test.Ctl.Plutip.Contract.ClusterParameters`](./test/Plutip/Contract/ClusterParameters.purs). ([#1610](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1610))


### Changed

- Replaced custom CIP-30 wrapper code with [`purescript-cip30-typesafe`](https://github.com/mlabs-haskell/purescript-cip30-typesafe/) - ([#1583](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1583))
- Renamings for better conformity with CSL:
- `TokenName` renamed to `AssetName`
- `NonAdaAsset` renamed to `MultiAsset`
- `CurrencySymbol` renamed to `ScriptHash`
- `Coin` now wraps BigNum instead of BigInt (in line with CSL)
- `NoOutputDatum` variant has been removed from `OutputDatum`: instead, it was made optional via `Maybe` in `TransactionOutput`
- `TransactionMetadatum` constructor naming change, in PS and in JSON encoding: `MetadataMap` -> `Map`, `MetadataList` -> `List`
- `Contract.PlutusData.Redeemer` has been renamed to `RedeemerDatum` (to resolve naming conflict with `cardano-ledger`-style redeemer)
- `Contract.PlutusData.Datum` has been deprecated, use `Cardano.Types.PlutusData`
- `plutusScriptV1FromEnvelope`, `plutusScriptV2FromEnvelope` have been replaced with `plutusScriptFromEnvelope` (the script is tagged with its language anyway)

### Fixed
- Plutip cluster's Kupo instances don't share the same working folder anymore - ([#1570](https://github.com/Plutonomicon/cardano-transaction-lib/issues/1570))
Expand Down Expand Up @@ -111,8 +143,63 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
+ "ws": "^8.16.0",
+ "web-encoding": "^1.1.5",
```
- NPM runtime dependencies:

```diff
"bip39": "^3.1.0",
- "blakejs": "1.2.1",
"bufferutil": "4.0.5",
- "jssha": "3.2.0",
"puppeteer-core": "^15.3.2",
"reconnecting-webs
```

- `Contract.Address` utilities to work with `Address` - use `mkAddress` and machinery from `Cardano.Types.Address`
- `Contract.RewardAddress` - use `Cardano.Types.RewardAddress`
- `Contract.Transaction`:
- Removed newtypes for `Transaction`:
- `BalancedSignedTransaction`
- `FinalizedTransaction`
- `Contract.Scripts`:
- `MintingPolicy` type. It was not used anywhere except of `mintingPolicy` lookup. Use `plutusMintingPolicy` and `nativeMintingPolicy` lookups instead.
- `Contract.ScriptLookups`:
- synonyms for lookup functions that use `Maybe` have been removed: `mintingPolicyM`, `ownPaymentPubKeyHashM`, `ownStakePubKeyHashM`, `unspentOutputsM`, `validatorM`
- `Contract.Credential` renamings:
- `PubKeyCredential` -> `PubKeyHashCredential`
- `ScriptCredential` -> `ScriptHashCredential`
- `ModifyTx` error: made conversion functions total and removed the need to handle it
- `Contract.CborBytes` utils:
- `cborBytesToByteArray`
- `cborBytesFromByteArray`
- `cborBytesFromAscii`
- `cborBytesToIntArray`
- `cborBytesFromIntArray`
- `cborBytesFromIntArrayUnsafe`
- `cborBytesToHex`
- `cborByteLength`
- `hexToCborBytes`
- `hexToCborBytesUnsafe`
- `rawBytesAsCborBytes`
- `ToData`/`FromData` Instances for `purescript-noble-secp256k1` types (PS does not allow orphans)
- `ToMetadata`/`FromMetadata` instance for `BigInt`: it was partial and unsafe
- `Cardano.Types.BigNum.toInt'` method
- `Contract.Address`:
- `scriptHashAddress` - use `Contract.Address.mkAddress`
- `payPubKeyHashBaseAddress` - use `Contract.Address.mkAddress`
- `payPubKeyHashEnterpriseAddress` - use `Contract.Address.mkAddress`
- `Contract.Value`:
- `flattenNonAdaAssets` - use `Cardano.Types.Value.flatten`.
- `Contract.PlutusData`:
- `Datum`: removed, use `Cardano.Types.PlutusData`
- `unitDatum`
- `Contract.TextEnvelope`:
- `plutusScriptV1FromEnvelope` - use `plutusScriptFromEnvelope`
- `Contract.Hashing`
- `Contract.Transaction`:
- `TransactionOutputWithRefScript` - use `Cardano.Types.TransactionOutput`. It comes with refscript included.
- `getTxFinalFee`
- `Contract.Numeric.NatRatio` - the module was not used in the library.
- `Contract.AssocMap` - use `Cardano.Plutus.Types.Map` from [`purescript-plutus-types`](https://github.com/mlabs-haskell/purescript-plutus-types)

## [v7.0.0]

Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ webpack-serve: spago-build create-bundle-entrypoint create-html-entrypoint
check-explicit-exports:
@if grep -rn '(\.\.)' ${ps-sources}; then
echo "Use explicit imports/exports ^"
echo "Run ./scripts/import-fixer.sh to autofix some of these"
exit 1
else
echo "All imports/exports are explicit"
Expand Down
57 changes: 7 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# cardano-transaction-lib
# cardano-transaction-lib [![cardano-purescript](https://img.shields.io/badge/cardano--purescript?logo=cardano&logoColor=white&label=cardano-purescript&labelColor=blue&color=blue)](https://github.com/klntsky/cardano-purescript)


[![Hercules-ci][herc badge]][herc link]
[![Cachix Cache][cachix badge]][cachix link]
Expand All @@ -19,9 +20,6 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Documentation](#documentation)
- [Light wallet support](#light-wallet-support)
- [Roadmap](#roadmap)
- [Architecture](#architecture)
- [Additional resources/tools:](#additional-resourcestools)
- [Available support channels info](#available-support-channels-info)
- [Funding acknowledgements](#funding-acknowledgements)
Expand All @@ -31,7 +29,7 @@

## Documentation

Please explore our documentation to discover how to use CTL, how to set up its runtime, and how it compares to Plutus/PAB:
Please explore our documentation to discover how to use CTL, how to set up its runtime, and how it compares to other tools:

- [Super quick start](./doc/getting-started.md#setting-up-a-new-project)
- [Adding CTL as a dependency](./doc/ctl-as-dependency.md)
Expand All @@ -41,12 +39,11 @@ Please explore our documentation to discover how to use CTL, how to set up its r
- [Managing contract environment](./doc/contract-environment.md)
- [Using CTL from JS](./doc/using-from-js.md)
- [Importing Plutus Scripts](./doc/importing-scripts.md)
- [Migrating from Plutus to CTL](./doc/plutus-comparison.md)
- [Migrating from Plutus Application Backend to CTL](./doc/plutus-comparison.md)
- [Overview of testing approaches](./doc/testing.md)
- [Testing contracts with Plutip](./doc/plutip-testing.md)
- [End-to-end testing with headless browsers](./doc/e2e-testing.md)
- [Utilities for testing](./doc/test-utils.md)
- [CIP-25 NFT standard support](./doc/cip-25-nfts.md)
- [Testing on local testnets with Plutip](./doc/plutip-testing.md)
- [End-to-end dApp testing with headless browsers](./doc/e2e-testing.md)
- [Assertion utilities for testing](./doc/test-utils.md)
- [Transaction balancing](./doc/balancing.md)
- [Transaction chaining](./doc/tx-chaining.md)
- [Ada staking support](./doc/staking.md)
Expand All @@ -60,46 +57,6 @@ Please explore our documentation to discover how to use CTL, how to set up its r

You can also access [PureScript documentation for CTL and its dependencies](https://plutonomicon.github.io/cardano-transaction-lib/) for the most recent `develop` version, or [generate it yourself](./doc/development.md#generating-ps-documentation).

### Light wallet support

Support is planned for the following light wallets:

- [x] [Nami](https://namiwallet.io/)
- [x] [Gero](https://gerowallet.io/)
- [x] [Flint](https://flint-wallet.com/)
- [x] [Lode](https://lodewallet.io/)
- [x] [Eternl (formerly CCvault)](https://eternl.io/)
- [x] [NuFi](https://nu.fi/)
- [x] [Lace](https://www.lace.io/)
- [ ] [Typhon](https://typhonwallet.io/)
- [ ] [Yoroi](https://yoroi-wallet.com/)

## Roadmap

- [x] **Stage 1** Build a simple transaction in the browser that works with at least one light wallet (Nami)
- [x] **Stage 2** Once we can construct a simple user-to-user transaction, we will try to use the library to submit the tx with nami
- [x] **Stage 3** Once we have a simple working transaction, we will seek to build a Plutus smart contract transaction with datum from scratch
- [x] **Stage 4** Once we can construct Plutus smart contract transactions, we will seek to build a library/DSL/interface such that transactions can be built using constraints and lookups - as close as possible to a cut-and-paste solution from Plutus' `Contract` monad code in Haskell (but with no guarantee that code changes are not necessary)
- [x] **Stage 4.1** Investigate supporting compatibility with the Vasil hardfork and improvements to our initial `Contract` API
- [x] **Stage 5** Once we have a basic `Contract`-style API, we will further refine its public interface, expand wallet support (see [below](#light-wallet-support)), expose a test interface (**DONE** - see [here](doc/plutip-testing.md)), provide a more ergonomic JS/TS API, support stake validators (**DONE**), and support CIP workflows on the public testnet (**In progress**)
- [x] **Stage 6** Once CTL's `Contract` interface has been stabilized, we will add support for even more wallets and attempt to deprecate CTL's currently required Haskell server (**DONE**)

## Architecture

CTL is directly inspired by the Plutus Application Backend (PAB). Unlike PAB, however, CTL is a library and not a standalone process. Over the course of CTL's development, several questions have been raised as to how best create PAB-as-a-library:

1. How do we get the transaction in the right format?
- This is handled by `cardano-serialization-lib`, a Rust library available as WASM
2. How do we query the chain?
- This has been solved using Ogmios & Kupo
- Thanks to [Catalyst](https://cardano.ideascale.com/c/idea/420791), we now support an alternative [BlockFrost](https://blockfrost.io/) backend as well
3. How do we get wallet data?
- This is done via browser-based light wallet integration in the browser based on CIP-30
4. How closely should we follow Plutus' `Contract` API?
- CTL's `Contract` model is **significantly** less restrictive than Plutus' and allows for arbitrary effects within the `Contract` monad
- Certain features cannot be directly translated into Purescript from Haskell due to differences between the two languages
- Some of the Plutus conventions do not make sense for us, due to differences between on-chain and off-chain

## Additional resources/tools:

- [`cardano-serialization-lib`](https://github.com/Emurgo/cardano-serialization-lib/)
Expand Down
7 changes: 0 additions & 7 deletions doc/cip-25-nfts.md

This file was deleted.

25 changes: 22 additions & 3 deletions doc/comparisons.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This document highlights key differences between CTL and other Cardano offchain
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Plutus Application Backend](#plutus-application-backend)
- [Lucid](#lucid)
- [Wallet support](#wallet-support)
- [Query layer differences](#query-layer-differences)
Expand All @@ -16,11 +17,29 @@ This document highlights key differences between CTL and other Cardano offchain

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Plutus Application Backend

CTL is directly inspired by the Plutus Application Backend (PAB). Unlike PAB, however, CTL is a library and not a standalone process. Over the course of CTL's development, several questions have been raised as to how best create PAB-as-a-library:

1. How do we get the transaction in the right format?
- This is handled by `cardano-serialization-lib`, a Rust library available as WASM
2. How do we query the chain?
- This has been solved using Ogmios & Kupo
- Thanks to [Catalyst](https://cardano.ideascale.com/c/idea/420791), we now support an alternative [BlockFrost](https://blockfrost.io/) backend as well ([docs](./blockfrost.md))
3. How do we get wallet data?
- This is done via browser-based light wallet integration in the browser based on CIP-30 ([`purescript-cip30-typesafe`](https://github.com/mlabs-haskell/purescript-cip30-typesafe))
4. How closely should we follow Plutus' `Contract` API?
- CTL's `Contract` model is **significantly** less restrictive than Plutus' and allows for arbitrary effects within the `Contract` monad
- Certain features cannot be directly translated into Purescript from Haskell due to differences between the two languages
- Some of the Plutus conventions do not make sense for us, due to differences between on-chain and off-chain
- Our API scope is a lot more extensive, as we provide support for wallet interactions, staking operations, and more support for balancer tweaking.

For a more in-depth explanation of the differences between PAB and CTL (with code examples), refer to [`plutus-comparison.md`](./plutus-comparison.md).

## Lucid

### Wallet support

- Lucid supports any CIP-30 compatible wallet. CTL supports a pre-defined list of wallets (however, the list can be extended easily).
- Both CTL and Lucid support using [seed phrases and private keys](./key-management.md).
- Lucid allows to use any address without a private key for querying - CTL does not allow that, but it's still possible to build transactions for other wallets to sign via [other means](./balancing.md).

Expand All @@ -43,7 +62,7 @@ Lucid, on the other hand, provides a way to get a UTxO that contains a specified
### Supported backends

- Both CTL and Lucid support [Blockfrost](./blockfrost.md) and [Kupo+Ogmios](./runtime.md)
- Lucid supports [Maestro](https://www.gomaestro.org/)
- Lucid also supports [Maestro](https://www.gomaestro.org/)
- Both CTL and Lucid allow for custom backends - Lucid via `Provider` interface implementation, and CTL via a custom `QueryHandle`.

### Staking support
Expand All @@ -58,7 +77,7 @@ Additionally, CTL supports [testing with real wallets](./e2e-testing.md) via hea

### API design

Lucid aims for simplicity, while CTL allows more fine-grained control over transaction building process.
Lucid aims for simplicity, while CTL allows more fine-grained control over transaction building process without losing the benefits of declarativeness.

- CTL uses [`cardano-serialization-lib`](https://github.com/Emurgo/cardano-serialization-lib/), while Lucid uses a fork of [`cardano-multiplatform-lib`](https://github.com/berry-pool/cardano-multiplatform-lib). Lucid allows to use CML's `TxBuilder` or [call CML directly](https://lucid.spacebudz.io/docs/advanced/cml/), while CTL allows to alter the transaction arbitrarily as PureScript data type either before or after balancing. In CTL, CSL types and method wrappers are a part of the internal interface, but technically they can be used as well.
- Plutus Data conversion is handled via a [schema-enabled API](https://lucid.spacebudz.io/docs/advanced/type-casting/) in Lucid. CTL allows for automatic `ToData` / `FromData` deriving for some types, via `HasPlutusSchema`.
4 changes: 2 additions & 2 deletions doc/ctl-as-dependency.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ CTL can be imported as an additional dependency into a Purescript project built
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Using CTL's overlays](#using-ctls-overlays)
- [Using CTL's Nix overlays](#using-ctls-nix-overlays)
- [Upgrading CTL](#upgrading-ctl)
- [See also](#see-also)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Using CTL's overlays
## Using CTL's Nix overlays

CTL exposes two `overlay`s from its flake. You can use these in the Nix setup of your own project to use the same setup as we do, e.g. the same packages and PS builders:

Expand Down
1 change: 1 addition & 0 deletions doc/e2e-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ The tests can set up using CLI arguments, environment variables, or both. CLI ar
| Test timeout | `--test-timeout` | `E2E_TEST_TIMEOUT` |
| Browser binary path or name | `--browser` | `E2E_BROWSER` |
| Don't use headless mode | `--no-headless` | `E2E_NO_HEADLESS` |
| Pass browser logs to the shell console | `--pass-browser-logs` | `E2E_PASS_BROWSER_LOGS` |
| Path to the user settings archive | `--settings-archive` | `E2E_SETTINGS_ARCHIVE` |
| URL of settings archive asset | `--settings-archive-url` | `E2E_SETTINGS_ARCHIVE_URL` |
| Path to the user data directory | `--chrome-user-data` | `E2E_CHROME_USER_DATA` |
Expand Down

0 comments on commit f8d2c52

Please sign in to comment.