Skip to content

Commit

Permalink
Merge branch 'develop' into dshuiski/balancer-constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
errfrom committed Aug 22, 2024
2 parents 3455bff + 3cc3a1b commit 4328687
Show file tree
Hide file tree
Showing 485 changed files with 36,523 additions and 37,805 deletions.
24 changes: 0 additions & 24 deletions .eslintrc.json

This file was deleted.

1 change: 1 addition & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
run: |
npm install -g spago
npm install -g [email protected]
rm -rf package.json # remove package.json so that we are no more in an ESM module. A hack to make 'spago docs' work
spago docs
- name: Deploy
uses: JamesIves/[email protected]
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ node_modules
plutip-server/dist-newstyle/
plutip-server/dist/
plutip-server/.stack-work/
nixos.qcow2
3 changes: 3 additions & 0 deletions .mlc_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
{
"pattern": "^https://gerowallet.io"
},
{
"pattern": "^https://stackoverflow.com"
},
{
"pattern": "^https://singularitynet.io"
},
Expand Down
303 changes: 274 additions & 29 deletions CHANGELOG.md

Large diffs are not rendered by default.

36 changes: 22 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
SHELL := bash
.ONESHELL:
.PHONY: esbuild-bundle esbuild-serve webpack-bundle webpack-serve check-format format query-testnet-tip clean check-explicit-exports spago-build create-bundle-entrypoint create-html-entrypoint delete-bundle-entrypoint
.PHONY: esbuild-bundle esbuild-serve webpack-bundle webpack-serve check-format \
format query-preview-testnet-tip query-preprod-testnet-tip \
clean check-explicit-exports build create-bundle-entrypoint \
create-html-entrypoint delete-bundle-entrypoint
.SHELLFLAGS := -eu -o pipefail -c

ps-sources := $(shell fd --no-ignore-parent -epurs)
nix-sources := $(shell fd --no-ignore-parent -enix --exclude='spago*')
js-sources := $(shell fd --no-ignore-parent -ejs -ecjs)
purs-args := "--stash --censor-lib --censor-codes=UserDefinedWarning,ImplicitImport,ImplicitQualifiedImport,ImplicitQualifiedImportReExport"

### Bundler setup

# The main Purescript module
ps-entrypoint := Ctl.Examples.ByUrl
# The entry point function in the main PureScript module
ps-entrypoint-function := main
# Whether to bundle for the browser
# Whether to bundle for the browser ("1") or the node ("")
# NOTE: bundling for the node is not necessary, see https://github.com/Plutonomicon/cardano-transaction-lib/blob/develop/doc/using-from-js.md
browser-runtime := 1 # Use "1" for true and "" for false

preview-node-ipc = $(shell docker volume inspect store_node-preview-ipc | jq -r '.[0].Mountpoint')
preprod-node-ipc = $(shell docker volume inspect store_node-preprod-ipc | jq -r '.[0].Mountpoint')
serve-port := 4008

spago-build:
@spago build
build:
@spago build --purs-args ${purs-args}

create-bundle-entrypoint:
@mkdir -p dist/
Expand All @@ -39,20 +44,20 @@ create-html-entrypoint:
</html>
EOF

esbuild-bundle: spago-build create-bundle-entrypoint
esbuild-bundle: build create-bundle-entrypoint
@mkdir -p dist/
BROWSER_RUNTIME=${browser-runtime} node esbuild/bundle.js ./dist/entrypoint.js dist/index.js
@make delete-bundle-entrypoint

esbuild-serve: spago-build create-bundle-entrypoint create-html-entrypoint
esbuild-serve: build create-bundle-entrypoint create-html-entrypoint
BROWSER_RUNTIME=1 node esbuild/serve.js ./dist/entrypoint.js dist/index.js dist/ ${serve-port}

webpack-bundle: spago-build create-bundle-entrypoint
webpack-bundle: build create-bundle-entrypoint
BROWSER_RUNTIME=${browser-runtime} webpack --mode=production \
-o dist/ --env entry=./dist/entrypoint.js
@make delete-bundle-entrypoint

webpack-serve: spago-build create-bundle-entrypoint create-html-entrypoint
webpack-serve: build create-bundle-entrypoint create-html-entrypoint
BROWSER_RUNTIME=1 webpack-dev-server --progress \
--port ${serve-port} \
-o dist/ --env entry=./dist/entrypoint.js
Expand All @@ -61,6 +66,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 All @@ -76,7 +82,7 @@ check-format: check-explicit-exports check-examples-imports check-whitespace
@purs-tidy check ${ps-sources}
@nixpkgs-fmt --check ${nix-sources}
@prettier --log-level warn -c ${js-sources}
@eslint --quiet ${js-sources} --parser-options 'sourceType: module'
@eslint --quiet ${js-sources}

format:
@purs-tidy format-in-place ${ps-sources}
Expand All @@ -95,17 +101,19 @@ query-preprod-testnet-tip:
CARDANO_NODE_SOCKET_PATH=${preprod-node-ipc}/node.socket cardano-cli query tip \
--testnet-magic 1

run-ci-actions:
run-ci-actions: run-template-checks
nix build -L .#checks.x86_64-linux.formatting-check
nix build -L .#checks.x86_64-linux.template-deps-json
nix build -L .#checks.x86_64-linux.template-dhall-diff
nix build -L .#checks.x86_64-linux.template-version
nix build -L .#checks.x86_64-linux.ctl-unit-test
nix build -L .#checks.x86_64-linux.ctl-e2e-test
nix build -L .#checks.x86_64-linux.ctl-plutip-test
nix build -L .#checks.x86_64-linux.ctl-local-testnet-test
nix build -L .#checks.x86_64-linux.ctl-staking-test
nix build -L .#checks.x86_64-linux.examples-imports-check

run-template-checks:
nix build -L .#checks.x86_64-linux.template-deps-json
nix build -L .#checks.x86_64-linux.template-dhall-diff
nix build -L .#checks.x86_64-linux.template-version

clean:
@ rm -r .psc-ide-port || true
@ rm -rf .psci_modules || true
Expand Down
65 changes: 13 additions & 52 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 @@ -11,17 +12,14 @@
[docs badge]: https://img.shields.io/badge/docs-PureScript%20code%20documentation-%2377F
[docs link]: https://plutonomicon.github.io/cardano-transaction-lib/

**cardano-transaction-lib** (CTL) is a Purescript library for building smart contract transactions on Cardano. It aims to port the functionality and interface of Plutus off-chain code to the browser environment and NodeJS.
**cardano-transaction-lib** (CTL) is a Purescript framework for building smart contract transactions on Cardano. It belongs to the the same category of tools as Lucid, Mesh.js, Atlas, Plutus Application Backend (PAB).

**Table of Contents**

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- 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,65 +39,26 @@ 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 Cardano testnets](./doc/cardano-testnet-testing.md)
- [End-to-end dApp testing with headless browsers](./doc/e2e-testing.md)
- [Assertion utilities for testing](./doc/test-utils.md)
- [Using a directory with private keys to run tests](./doc/keydir.md)
- [Transaction balancing](./doc/balancing.md)
- [Transaction chaining](./doc/tx-chaining.md)
- [Ada staking support](./doc/staking.md)
- [Key management](./doc/key-management.md)
- [SECP256k1 support (CIP-49)](./doc/secp256k1-support.md)
- [Custom query layers](./doc/custom-query-layers.md)
- [Going to production with CTL](./doc/production.md)
- [FAQs](./doc/faq.md)
- [Feature overview video](./doc/video-intro.md)
- [Comparison with other frameworks (Lucid)](./doc/comparisons.md)
- [Development workflows for CTL](./doc/development.md)

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 All @@ -118,17 +77,19 @@ You can find help, more information and ongoing discusion about the project here

## Funding acknowledgements

CTL is being developed by MLabs. The following companies/funds have contributed significant resources to development:
CTL is being developed by MLabs. The following companies/funds have contributed significant resources (development time or funding):

- [IOHK](https://iohk.io/en/about/)
- [Catalyst Fund8](https://cardano.ideascale.com/c/idea/396607)
- [Catalyst Fund9](https://cardano.ideascale.com/c/idea/420791)
- [Catalyst Fund10](https://cardano.ideascale.com/c/idea/101478)
- [Intersect MBO](https://docs.intersectmbo.org/intersect-community-grants/grant-projects)
- [MLabs](https://mlabs.city/)
- [Indigo Protocol](https://indigoprotocol.io/)
- [Equine](https://www.equine.gg/)
- [Liqwid Labs](https://liqwid.finance/)
- [PlayerMint](https://www.playermint.com/)
- [Fourier Labs](https://fourierlabs.io/)
- Ardana

## Use in production
Expand Down
31 changes: 6 additions & 25 deletions doc/babbage-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,29 @@ This document is a reference/explainer for the new CTL APIs introduced for Babba
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Reference Inputs](#reference-inputs)
- [Reference Scripts](#reference-scripts)
- [Reference Inputs & Reference Scripts](#reference-inputs--reference-scripts)
- [Inline Data](#inline-data)
- [Collateral Output](#collateral-output)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Reference Inputs
## Reference Inputs & Reference Scripts

[Reference inputs](https://cips.cardano.org/cip/CIP-0031#reference-inputs) allow looking at an output without spending it in Plutus scripts.

There are two ways to use an input as a reference in the constraints API:

1. via `mustReferenceOutput`, which allows Plutus scripts to access the information (e.g. datum, locked value) contained in the output.

[Usage example](../examples/PlutusV2/ReferenceInputs.purs)

2. by providing constraints which accept a value of the type `InputWithScriptRef` with the `RefInput` constructor. These allow scripts (validating or minting) to be reused by reference between multiple transactions without including them in those transactions, explained further in [Reference Scripts](#reference-scripts).

[Usage example](../examples/PlutusV2/ReferenceInputsAndScripts.purs)

## Reference Scripts

[Reference Scripts](https://cips.cardano.org/cip/CIP-0033) allows the use of scripts without attaching them to the transaction (and using a reference instead).

Reference scripts can be utilized in CTL by first creating a reference point for the script to be used later via `mustPayToScriptWithScriptRef` (or its variants).
Reference scripts can be utilized in CTL by first creating a UTxO containing the script to be used later.

This constraint utilises a new `ScriptRef` type that includes either a native script or a Plutus script.

Then, `mustSpendScriptOutputUsingScriptRef` (or its variants) can be used to use a reference script. It accepts a value of type `InputWithScriptRef` that specifies whether the UTxO with the reference script should be spent or referenced.

[Usage example](../examples/PlutusV2/ReferenceScripts.purs)
[Usage example](../examples/PlutusV2/ReferenceInputsAndScripts.purs)

## Inline Data

[CIP-32](https://cips.cardano.org/cip/CIP-0032) introduces the inline data feature that allows storing datum values directly in transaction outputs, instead of just the hashes.

In CTL, alternating between datum storage options can be achieved by specifying a `DatumPresence` value with constraints that accept it, like `mustPayToPubKeyWithDatum`.

[Usage example](../examples/PlutusV2/InlineDatum.purs)

## Collateral Output

[CIP-40](https://cips.cardano.org/cip/CIP-0040) introduces explicit collateral output. On validation failure, previously the entire collateral was consumed. Now, if excess collateral is supplied, even with native assets, the surplus can be returned on validation failure.

Collateral output is automatically added to transactions in CTL. To trigger a collateral return, the `mustNotBeValid` constraint should be explicitly specified, otherwise a script error would be detected earlier and the transaction will not be sent.

[Usage example](../examples/Lose7Ada.purs)
6 changes: 3 additions & 3 deletions doc/balancing.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Configuring balancing process](#configuring-balancing-process)
- [Configuring the balancing process](#configuring-the-balancing-process)
- [Balancer constraints](#balancer-constraints)
- [Concurrent spending](#concurrent-spending)
- [Balancing a Tx for other wallet](#balancing-a-tx-for-other-wallet)
Expand All @@ -10,7 +10,7 @@

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

# Configuring balancing process
# Configuring the balancing process

Transaction balancing in Cardano is the process of finding a set of inputs and outputs that that sum up to zero, covering all the required fees for the transaction to be valid.

Expand All @@ -37,7 +37,7 @@ Setting `mustUseUtxosAtAddress`, `mustSendChangeToAddress` and `mustUseCollatera

## Synchronization

Before balancing, CTL tries to synchronize the wallet state with the query layer, i.e. waits until all UTxOs that the wallet returns are visible in the query layer. Thus the situation when the query layer refuses to validate a Tx (either during ex-units evaluation or on Tx submission) is only possible due to a rollback or a synchronization timeout. Please see [our docs for query layer synchronization](./query-layers.md).
It's possible to make CTL try to synchronize the wallet state with the query layer, i.e. wait until all UTxOs that the wallet returns are visible in the query layer. Thus the situation when the query layer refuses to validate a Tx (either during ex-units evaluation or on Tx submission) is only possible due to a rollback or a synchronization timeout. Please see [our docs for query layer synchronization](./query-layers.md).

## Balancing process limitations

Expand Down
3 changes: 2 additions & 1 deletion doc/blockfrost.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Go to https://blockfrost.io to generate a new API key and specify it as `BLOCKFR

### Generating private keys

Follow https://developers.cardano.org/docs/stake-pool-course/handbook/keys-addresses/ to generate a private payment key (and, optionally, a stake key). You can use [this script](https://github.com/Plutonomicon/cardano-transaction-lib/blob/develop/scripts/generate-keys.sh) for convenience instead of following instructions in this section manually.
Follow [this guide](https://developers.cardano.org/docs/operate-a-stake-pool/generating-wallet-keys) to generate a private payment key (and, optionally, a stake key). You can use [this script](https://github.com/Plutonomicon/cardano-transaction-lib/blob/develop/scripts/generate-keys.sh) for convenience instead of following instructions in this section manually.

The generated keys should look like this:

Expand Down Expand Up @@ -210,4 +210,5 @@ This function is never used for constraints resolution, the only way to make it

## See also

- [key-directory test suite](./keydir.md) that is used under the hood by `executeContractTestsWithBlockfrost`. This test machinery can be used with any runtime backend, not just Blockfrost.
- [Testing utilities for CTL](./test-utils.md).
Loading

0 comments on commit 4328687

Please sign in to comment.