Skip to content

Commit

Permalink
Merge pull request #1591 from Plutonomicon/develop
Browse files Browse the repository at this point in the history
Merge develop to master
  • Loading branch information
klntsky authored Jan 25, 2024
2 parents 205f25b + e23ff27 commit 9b24f11
Show file tree
Hide file tree
Showing 447 changed files with 42,373 additions and 20,707 deletions.
5 changes: 3 additions & 2 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ Closes # .
### Pre-review checklist

- [ ] All code has been formatted using our config (`make format`)
- [ ] Any new API features or modification of existing behavior is covered as defined in our [test plan](https://github.com/Plutonomicon/cardano-transaction-lib/blob/develop/doc/test-plan.md)
- [ ] The changelog has been updated under the `## Unreleased` header, using the appropriate sub-headings (`### Added`, `### Removed`, `### Fixed`), and the links to the appropriate issues/PRs have been included
- [ ] Any new API features or modification of existing behavior are covered with tests
- [ ] The template (`templates/ctl-scaffold`) has been [updated](https://github.com/Plutonomicon/cardano-transaction-lib/blob/develop/doc/development.md#maintaining-the-template)
- [ ] The changelog has been updated under the `## Unreleased` header, using the appropriate sub-headings (`### Added`, `### Changed`, `### Removed`, `### Fixed`), and the links to the appropriate issues/PRs have been included
6 changes: 2 additions & 4 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ jobs:
- name: Install and Build
run: |
npm install -g spago
npm install -g [email protected]
npm install -g purescript-docs-search
spago docs --no-search
purescript-docs-search build-index --package-name cardano-transaction-lib
npm install -g [email protected]
spago docs
- name: Deploy
uses: JamesIves/[email protected]
with:
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ output.js
.idea/
test-data/chrome-user-data
test-data/preview
test-data/preprod
test-data/mainnet
test-data/keys
tmp
node_modules
plutip-server/dist-newstyle/
plutip-server/dist/
plutip-server/.stack-work/
6 changes: 6 additions & 0 deletions .mlc_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
"ignorePatterns": [
{
"pattern": "^https://gerowallet.io"
},
{
"pattern": "^https://singularitynet.io"
},
{
"pattern": "^https://iohk.io"
}
],
"aliveStatusCodes": [
Expand Down
245 changes: 222 additions & 23 deletions CHANGELOG.md

Large diffs are not rendered by default.

67 changes: 56 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,20 +1,61 @@
SHELL := bash
.ONESHELL:
.PHONY: run-dev run-build check-format format query-testnet-tip clean check-explicit-exports
.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
.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)
ps-entrypoint := Ctl.Examples.ByUrl # points to one of the example PureScript modules in examples/
ps-bundle = spago bundle-module -m ${ps-entrypoint} --to output.js
js-sources := $(shell fd --no-ignore-parent -ejs -ecjs)

### 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
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

create-bundle-entrypoint:
@mkdir -p dist/
@echo 'import("../output/${ps-entrypoint}/index.js").then(m => m.${ps-entrypoint-function}());' > ./dist/entrypoint.js

delete-bundle-entrypoint:
@rm -f ./dist/entrypoint.js

run-dev:
@${ps-bundle} && BROWSER_RUNTIME=1 webpack-dev-server --progress
create-html-entrypoint:
@mkdir -p dist/
@cat << EOF > dist/index.html
<!DOCTYPE html>
<html>
<body><script type="module" src="./index.js"></script></body>
</html>
EOF

run-build:
@${ps-bundle} && BROWSER_RUNTIME=1 webpack --mode=production
esbuild-bundle: spago-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
BROWSER_RUNTIME=1 node esbuild/serve.js ./dist/entrypoint.js dist/index.js dist/ ${serve-port}

webpack-bundle: spago-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
BROWSER_RUNTIME=1 webpack-dev-server --progress \
--port ${serve-port} \
-o dist/ --env entry=./dist/entrypoint.js

.ONESHELL:
check-explicit-exports:
Expand All @@ -34,8 +75,8 @@ check-whitespace:
check-format: check-explicit-exports check-examples-imports check-whitespace
@purs-tidy check ${ps-sources}
@nixpkgs-fmt --check ${nix-sources}
@prettier --loglevel warn -c ${js-sources}
@eslint --quiet ${js-sources}
@prettier --log-level warn -c ${js-sources}
@eslint --quiet ${js-sources} --parser-options 'sourceType: module'

format:
@purs-tidy format-in-place ${ps-sources}
Expand All @@ -50,6 +91,10 @@ query-preview-testnet-tip:
CARDANO_NODE_SOCKET_PATH=${preview-node-ipc}/node.socket cardano-cli query tip \
--testnet-magic 2

query-preprod-testnet-tip:
CARDANO_NODE_SOCKET_PATH=${preprod-node-ipc}/node.socket cardano-cli query tip \
--testnet-magic 1

run-ci-actions:
nix build -L .#checks.x86_64-linux.formatting-check
nix build -L .#checks.x86_64-linux.template-deps-json
Expand All @@ -61,7 +106,6 @@ run-ci-actions:
nix build -L .#checks.x86_64-linux.ctl-staking-test
nix build -L .#checks.x86_64-linux.examples-imports-check


clean:
@ rm -r .psc-ide-port || true
@ rm -rf .psci_modules || true
Expand All @@ -70,3 +114,4 @@ clean:
@ rm -rf .spago2nix || true
@ rm -rf node_modules || true
@ rm -rf output || true
@ rm -rf dist || true
47 changes: 38 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
- [Architecture](#architecture)
- [Additional resources/tools:](#additional-resourcestools)
- [Available support channels info](#available-support-channels-info)
- [Funding acknowledgements](#funding-acknowledgements)
- [Use in production](#use-in-production)

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

Expand All @@ -36,18 +38,24 @@ Please explore our documentation to discover how to use CTL, how to set up its r
- [CTL's runtime dependencies](./doc/runtime.md)
- [Blockfrost support](./doc/blockfrost.md)
- [Getting started writing CTL contracts](./doc/getting-started.md)
- [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)
- [Testing overview](./doc/testing.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)
- [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)
- [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).
Expand All @@ -62,7 +70,7 @@ Support is planned for the following light wallets:
- [x] [Lode](https://lodewallet.io/)
- [x] [Eternl (formerly CCvault)](https://eternl.io/)
- [x] [NuFi](https://nu.fi/)
- [ ] [Lace](https://www.lace.io/)
- [x] [Lace](https://www.lace.io/)
- [ ] [Typhon](https://typhonwallet.io/)
- [ ] [Yoroi](https://yoroi-wallet.com/)

Expand All @@ -73,8 +81,8 @@ Support is planned for the following light wallets:
- [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
- [ ] **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**)
- [ ] **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**)
- [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

Expand All @@ -84,12 +92,10 @@ CTL is directly inspired by the Plutus Application Backend (PAB). Unlike PAB, ho
- 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
- We [will support](https://cardano.ideascale.com/c/idea/420791) an alternative [BlockFrost](https://blockfrost.io/) backend as well in the future
3. How do we query for datums (i.e. the datums themselves and not just their hashes)?
- `Kupo` solves this problem
4. How do we get wallet data?
- 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
5. How closely should we follow Plutus' `Contract` API?
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
Expand All @@ -109,3 +115,26 @@ You can find help, more information and ongoing discusion about the project here

- [Plutonomicon Discord](https://discord.gg/JhbexnV9Pc)
- #ctl channel at MLabs' Slack

## Funding acknowledgements

CTL is being developed by MLabs. The following companies/funds have contributed significant resources to development:

- [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)
- [MLabs](https://mlabs.city/)
- [Indigo Protocol](https://indigoprotocol.io/)
- [Equine](https://www.equine.gg/)
- [Liqwid Labs](https://liqwid.finance/)
- [PlayerMint](https://www.playermint.com/)
- Ardana

## Use in production

- [Indigo Protocol](https://indigoprotocol.io/)
- [Liqwid](https://liqwid.finance/)
- [Clarity](https://clarity.community/)
- [PlayerMint](https://www.playermint.com/)
- [SingularityNet](https://singularitynet.io/)
8 changes: 4 additions & 4 deletions doc/babbage-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This document is a reference/explainer for the new CTL APIs introduced for Babba
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Reference Inputs

[Reference inputs](https://cips.cardano.org/cips/cip31/#referenceinputs) allow looking at an output without spending it in Plutus 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:

Expand All @@ -28,7 +28,7 @@ There are two ways to use an input as a reference in the constraints API:

## Reference Scripts

[Reference Scripts](https://developers.cardano.org/docs/governance/cardano-improvement-proposals/cip-0033/) allows the use of scripts without attaching them to the transaction (and using a reference instead).
[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).

Expand All @@ -40,14 +40,14 @@ Then, `mustSpendScriptOutputUsingScriptRef` (or its variants) can be used to use

## Inline Data

[CIP-32](https://developers.cardano.org/docs/governance/cardano-improvement-proposals/cip-0032/) introduces the inline data feature that allows storing datum values directly in transaction outputs, instead of just the hashes.
[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/cips/cip40/) 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.
[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.
22 changes: 17 additions & 5 deletions doc/balancing.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
- [Configuring balancing process](#configuring-balancing-process)
- [Balancer constraints](#balancer-constraints)
- [Concurrent spending](#concurrent-spending)
- [Balancing a Tx for other wallet](#balancing-a-tx-for-other-wallet)
- [Synchronization](#synchronization)
- [Balancing process limitations](#balancing-process-limitations)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
Expand All @@ -16,17 +18,27 @@ Transaction balancing in Cardano is the process of finding a set of inputs and o

CTL allows tweaking the default balancer behavior by letting the user impose constraints on the UTxO set that is used in the process (`balanceTxWithConstraints`):

- providing additional UTxOs to use: `mustUseUtxosAtAddresses` / `mustUseUtxosAtAddress` / `mustUseAdditionalUtxos`
- overriding change address: `mustSendChangeToAddress`
- prevent certain UTxOs from being spent: `mustNotSpendUtxosWithOutRefs` / `mustNotSpendUtxoWithOutRef`
- distribute token outputs equally between change UTxOs: `mustGenChangeOutsWithMaxTokenQuantity`
- Using arbitrary address as user's own (for transaction balancing): `mustUseUtxosAtAddresses` / `mustUseUtxosAtAddress`
- Providing additional UTxOs to use: `mustUseAdditionalUtxos`
- Bypassing wallet's collateral selection and selecting collateral UTxOs from a given set: `mustUseCollateralUtxos`
- Overriding change address: `mustSendChangeToAddress`
- Preventing certain UTxOs from being spent: `mustNotSpendUtxosWithOutRefs` / `mustNotSpendUtxoWithOutRef`
- Distributing token outputs equally between change UTxOs: `mustGenChangeOutsWithMaxTokenQuantity`

## Concurrent spending

Attempting to spend UTxOs concurrently leads to some of the transactions being rejected. To ensure that no concurrent spending is happening, CTL uses it's own UTxO locking machinery. `balanceTxs` and `balanceTxsWithConstraints` functions can be used to construct multiple transactions at once, ensuring that the sets of inputs do not intersect.
Attempting to spend UTxOs concurrently leads to some of the transactions being rejected. To ensure that no concurrent spending is happening, CTL uses it's own UTxO locking machinery. `balanceTxs` or `balanceTxsWithConstraints` can be used to construct multiple transactions at once, ensuring that the sets of inputs do not intersect.

Obviously, the number of available UTxOs must be greater than the number of transactions. CTL will throw an exception if it's not the case.

## Balancing a Tx for other wallet

Setting `mustUseUtxosAtAddress`, `mustSendChangeToAddress` and `mustUseCollateralUtxos` at the same time allows to build a transaction without any connection to the current wallet. For example, it's possible to balance it on server-side and send to the user to sign, or balance a Tx on one user's side while leaving fees at the expense of some other user.

## 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).

## Balancing process limitations

It may be surprising at first, but balancing a transaction on Cardano is generally undecidable.
Expand Down
Loading

0 comments on commit 9b24f11

Please sign in to comment.