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

Remove defineplugin #1598

Merged
merged 14 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,37 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

### Removed

- **[IMPORTANT]** Removed use of conditional code rewriting based on `BROWSER_RUNTIME` env variable during bundling ([#1595](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1598)). This change simplifies the bundling process, but it requires a number of updates for all CTL-dependent projects:

* WebPack users should make this change to the webpack config:
```diff
plugins: [
- new webpack.DefinePlugin({
- BROWSER_RUNTIME: isBrowser
- }),
```
* Esbuild users should make this change:
```diff
const config = {
...
- define: {
- BROWSER_RUNTIME: isBrowser ? "true" : '""'
- },
```
* All users should update the runtime dependencies:
```diff
- "@emurgo/cardano-message-signing-browser": "1.0.1",
- "@emurgo/cardano-message-signing-nodejs": "1.0.1",
+ "@mlabs-haskell/cardano-message-signing": "1.0.1",
- "apply-args-browser": "0.0.1",
- "apply-args-nodejs": "0.0.1",
+ "@mlabs-haskell/uplc-apply-args": "1.0.0",
+ "isomorphic-ws": "^5.0.0",
- "ws": "8.4.0",
+ "ws": "^8.16.0",
+ "web-encoding": "^1.1.5",
```

- `ModifyTx` error: made conversion functions total and removed the need to handle it

## [v7.0.0]
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ js-sources := $(shell fd --no-ignore-parent -ejs -ecjs)
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')
Expand Down
14 changes: 3 additions & 11 deletions doc/ctl-as-dependency.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,17 @@ 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 -->

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

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

## Caveats

The following caveats alway applies when using CTL from your project:

1. Only bundling with Webpack is supported (this is due to our internal dependency on `cardano-serialization-lib` which uses WASM with top-level `await`; only Webpack is reliably capable of bundling this properly)
2. The environment variable `BROWSER_RUNTIME` determines which version of `cardano-serialization-lib` is loaded by CTL, so you must use it as well (i.e. set it to `1` for the browser; leave it unset for NodeJS)

## Using CTL's 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:

- `overlays.purescript` contains Purescript builders to compile Purescript sources, build bundles with Webpack (`bundlePursProject`), run unit tests using NodeJS (`runPursTest`), and run CTL contracts on a private testnet using Plutip (`runPlutipTest`).
- `overlays.purescript` contains Purescript builders to compile Purescript sources, build bundles with Webpack/esbuild (`bundlePursProject`), run unit tests using NodeJS (`runPursTest`), and run CTL contracts on a private testnet using Plutip (`runPlutipTest`).
- `overlays.runtime` contains various packages and other tools used in CTL's runtime, including `ogmios`, `kupo`, and `plutip-server`. It also defines `buildCtlRuntime` and `launchCtlRuntime` to help you quickly launch all runtime services (see the [runtime docs](./runtime.md))

We've split the overlays into two components to allow users to more easily choose which parts of CTL's Nix infrastructure they would like to directly consume. For example, some users do not require a pre-packaged runtime and would prefer to build it themselves with more control over its components (e.g. by directly using `ogmios` from their own `inputs`). Such users might still like to use our `purescript` overlay -- splitting the `overlays` allows us to support this. `overlays.runtime` also contains several haskell.nix packages which may cause issues with `hackage.nix` versions in your own project.
Expand Down Expand Up @@ -80,9 +72,9 @@ Make sure to perform **all** of the following steps, otherwise you **will** enco
- That is, avoid using the `~` or `^` prefixes (e.g use versions like `"1.6.51"` instead of `"^1.6.51"`)
- If you're using a `package-lock.json` (which is _highly_ recommended), you can update the lockfile with `npm i --package-lock-only`

4. **Update your webpack config**
4. **Update your webpack/esbuild config**

- Sometimes the WebPack configuration also comes with breaking changes. Common source of problems are changes to `resolve.fallback`, `plugins` and `experiments` fields of the WebPack config. Use `git diff old-revision new-revision webpack.config.js` in the root of a cloned CTL repo, or use `git blame`.
- Sometimes the WebPack or esbuild configuration also comes with breaking changes. Use `git diff old-revision new-revision webpack.config.cjs` in the root of a cloned CTL repo, or use `git blame`.

## See also

Expand Down
10 changes: 5 additions & 5 deletions doc/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ To **build** the project **without bundling and for a NodeJS environment**:
- `npm run staking-test` to run [Plutip](./plutip-testing.md)-powered tests for ADA staking functionality - [entry point](../test/Plutip/Staking.purs)
- `npm run blockfrost-test` for [Blockfrost-powered tests](./blockfrost.md) (does not require a runtime, but needs [some setup](./blockfrost.md#setting-up-a-blockfrost-powered-test-suite)) - [entry point](../test/Blockfrost/Contract.purs)
- `npm run blockfrost-local-test` for self-hosted [Blockfrost-powered tests](./blockfrost.md) (requires a [local Blockfrost runtime](./blockfrost.md#running-blockfrost-locally)) - [entry point](../test/Blockfrost/Contract.purs)
- `npm run e2e-test` for [tests with a headless browser](./e2e-testing.md) (requires a runtime and the tests served via HTTP: `npm run start-runtime` and `npm run webpack-serve` or `esbuild-serve`)
- `npm run e2e-test` for [tests with a headless browser](./e2e-testing.md) (requires a runtime and the tests served via HTTP: `npm run start-runtime` and `npm run e2e-serve` or `esbuild-serve`)

#### With Nix

Expand All @@ -100,14 +100,14 @@ Here and below, `<SYSTEM>` should be replaced with [one of the supported systems

To run or build/bundle the project for the browser:

- `npm run webpack-serve` will start a Webpack development server at `localhost:4008`, which is required for [E2E tests](./e2e-testing.md)
- `npm run {webpack|esbuild}-serve` will start a Webpack development server at `localhost:4008`, which is required for [E2E tests](./e2e-testing.md)
- `npm run {webpack|esbuild}-bundle` will output a bundled example module to `dist` (or `nix build -L .#ctl-example-bundle-web-{webpack|esbuild}` to build an example module using Nix into `./result/`)

By default, Webpack will build a [Purescript module](../examples/ByUrl.purs) that serves multiple example `Contract`s depending on URL (see [here](./e2e-testing.md#serving-the-contract-to-be-tested)). You can point Webpack to another Purescript entrypoint by changing the `ps-bundle` variable in the Makefile or in the `main` argument in the flake's `packages.ctl-examples-bundle-web`.
By default, the bundler will build a [Purescript module](../examples/ByUrl.purs) that serves multiple example `Contract`s depending on URL (see [here](./e2e-testing.md#serving-the-contract-to-be-tested)). You can point the bundler to another Purescript entrypoint by changing the `ps-bundle` variable in the Makefile or in the `main` argument in the flake's `packages.ctl-examples-bundle-web`.

You will also need a light wallet extension pre-configured to run a `Contract`.
You will also need a light wallet extension pre-configured for the correct Cardano network to run a `Contract`.

**Note**: The `BROWSER_RUNTIME` environment variable must be set to `1` in order to build/bundle the project properly for the browser (e.g. `BROWSER_RUNTIME=1 webpack ...`). For Node environments, leave this variable unset.
**Note**: The `BROWSER_RUNTIME` environment variable must be set to `1` in order to build/bundle the project properly for the browser (e.g. `BROWSER_RUNTIME=1 webpack ...`). For NodeJS environments, leave this variable unset.

**Note**: The `KUPO_HOST` environment variable must be set to the base URL of the Kupo service in order to successfully serve the project for the browser (by default, `KUPO_HOST=http://localhost:1442`).

Expand Down
4 changes: 3 additions & 1 deletion doc/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ Another thing to keep in mind is that due to [min-ada requirements](https://docs

CTL does not consume wallet collateral normally, but it still can happen.

In order to get the collateral UTxO, CTL uses the wallet and then marks the returned UTxO as locked internally. But some wallets (e.g. Gero) do not return the collateral the moment it is set, waiting for Tx confirmation first. In case a collateral is set right before the contract is started, CTL can accidentally spend the collateral, because we rely on CTL's own query layer to get a list of available UTxOs, and the wallet state may lag behind it, not returning the collateral to filter out at that moment.
In order to get the collateral UTxO, CTL uses the wallet and then marks the returned UTxO as "locked" internally. But some wallets (e.g. Gero) do not return the collateral the moment it is set, waiting for Tx confirmation first. In case a collateral is set right before the contract is started, CTL can accidentally spend the collateral, because we rely on CTL's own query layer to get a list of available UTxOs without consulting with the wallet [in some cases](./query-layers.md), and the wallet state may lag behind the backend state.

It is impossible to lose the collateral UTxO funds completely, though, because CTL always uses [CIP-40 collateral return](https://cips.cardano.org/cip/CIP-0040).

## Time-related

Expand Down
92 changes: 5 additions & 87 deletions doc/importing-scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

- [Exporting scripts from Plutus or Plutarch](#exporting-scripts-from-plutus-or-plutarch)
- [Using Plutonomy](#using-plutonomy)
- [Importing serialized scripts](#importing-serialized-scripts)
- [Serializing Plutus scripts](#serializing-plutus-scripts)
- [PlutusTx](#plutustx)
- [Plutarch](#plutarch)
- [plutarch-ctl-bridge](#plutarch-ctl-bridge)
- [Importing serialized scripts](#importing-serialized-scripts)

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

Expand All @@ -31,7 +31,6 @@ The output file should be a Cardano envelope:
- An example of a Plutus exporter can be found [here](https://github.com/Mr-Andersen/ctl-multisign-mre/blob/main/onchain/exporter/Main.hs).
- For Plutarch, see [the-plutus-scaffold](https://github.com/mlabs-haskell/the-plutus-scaffold)'s [exporter](https://github.com/mlabs-haskell/the-plutus-scaffold/tree/main/onchain/exporter).


### Using Plutonomy

It makes sense to use [Plutonomy](https://github.com/well-typed/plutonomy) (an optimizer for UPLC) in the exporter:
Expand All @@ -44,91 +43,6 @@ script = fromCompiledCode $
optimizeUPLCWith aggressiveOptimizerOptions $$(PlutusTx.compile [||policy||])
```

## Importing serialized scripts

To use your own scripts, compile them to any subdirectory in the root of your project (where `webpack.config.js` is located) and add a relative path to `webpack.config.js` under the `resolve.alias` section. In CTL, we have the `Scripts` alias for this purpose. Note the capitalization of `Scripts`: it is necessary to disambiguate it from local folders.

First, in your `webpack.config.js`, define an `alias` under `module.exports.resolve.alias` in order to `require` the compiled scripts from JS modules:

```javascript
const path = require("path");

module.exports = {
// ...
resolve: {
modules: [process.env.NODE_PATH],
extensions: [".js"],
fallback: {
// ...
},
alias: {
// You should update this path to the location of your compiled scripts,
// relative to `webpack.config.js`
Scripts: path.resolve(__dirname, "fixtures/scripts"),
},
},
};
```

You must also add the following to `module.exports.module.rules`:

```javascript
module.exports = {
// ...
module: {
rules: [
{
test: /\.plutus$/i,
type: "asset/source",
},
// ...
],
},
};
```

This enables inlining your serialized scripts in `.js` files, to then be loaded in Purescript via the FFI:

```javascript
// inline .plutus file as a string
exports.myscript = require("Scripts/myscript.plutus");
```

And on the purescript side, the script can be loaded like so:

```purescript
foreign import myscript :: String

parseValidator :: Contract Validator
parseValidator = liftMaybe (error "Error decoding myscript") do
envelope <- decodeTextEnvelope myscript
Validator <$> Contract.TextEnvelope.plutusScriptV1FromEnvelope envelope
myContract cfg = runContract_ cfg $ do
validator <- parseValidator
...
```

This way you avoid hardcoding your scripts directly to .purs files which could lead to synchronization issues should your scripts change.

**Note**: The `alias` method above will only work in the browser when bundling with Webpack. In order to load the scripts for both browser and NodeJS environments, you can use the `BROWSER_RUNTIME` environment variable like so:

```javascript
let script;
if (typeof BROWSER_RUNTIME != "undefined" && BROWSER_RUNTIME) {
script = require("Scripts/my-script.plutus");
} else {
const fs = require("fs");
const path = require("path");
script = fs.readFileSync(
path.resolve(__dirname, "../../fixtures/scripts/my-script.plutus"),
"utf8"
);
}
exports.myScript = script;
```

Note that the relative path passed to `path.resolve` for the NodeJS case starts from the `output` directory that the Purescript compiler produces.

## Serializing Plutus scripts

### PlutusTx
Expand Down Expand Up @@ -176,3 +90,7 @@ You can use [`ply`](https://github.com/mlabs-haskell/ply) and [`ply-ctl`](https:
### plutarch-ctl-bridge

You can use [`plutarch-ctl-bridge`](https://github.com/mlabs-haskell/plutarch-ctl-bridge) to generate Purescript types from your Haskell type definitions and typed script wrappers from parametrized Plutarch scripts. See [example module](https://github.com/mlabs-haskell/plutarch-ctl-bridge/blob/main/example/Main.hs).

## Importing serialized scripts

To use your own scripts, compile them to any subdirectory in the root of your project and either dynamically load them from file (NodeJS) or use your bundler to include them as fixtures into the bundle ([instructions for WebPack](https://webpack.js.org/guides/asset-modules/), [for esbuild](https://esbuild.github.io/content-types/#external-file)).
Loading