The MultiParty Escrow (MPE) smart contract manages payment channels between clients —who act as senders, consumers, or service customers— and service providers, who serve as receivers or recipients.
We need to have a .env file at the src with the following content:
PORT = 3000
PROVIDER_PROJECT_ID = ""
PROVIDER_URL = ""
NETWORK = ""
CONFIG_FILE = ""Where CONFIG_FILE is the name of a file inside the project, with the following format:
{
// "token": "[policyId][hexaName]"
"token": "921e27e15e2552a40515564ba10a26ecb1fe1a34ac6ccb58c1ce132041474958",
"ref_script": {
"txHash": "d307d64e839f499a53f8a70bb98b21aacecb54ae441998947aabb6c13b36c0dd"
}
}Some scripts that run on test networks rely on a 24-word mnemonic which must be set on a .test-env file at src:
SEED=soda water ...Note: For safety, always use a mnemonic intended only for testing. Never use real or production mnemonics.
For the first time, run npm install inside the src folder to install all the dependencies.
To run the server, run npm run dev inside the src folder.
Note: Aiken must be installed. Check the aiken.toml file to match the correct compiler version.
Inside onchain, run aiken build.
Run bash parse-blueprint.sh to generate the contract types from the validator's blueprint.
To test the offchain operations, you can run the following commands from the src folder.
Open a channel A channel with 6 tokens will be created.
$> npm run test-openUpdate a channel A channel will be created and then updated, funding 3 tokens more and extending its expiration date.
$> npm run test-updateBuild a message A channel will be created with an initial amount of 6 tokens, and a message will be created and signed, indicating that the receiver can claim 3 tokens from the channel.
$> npm run test-build-msgClaim a channel A channel will be created with an initial deposit of 600 tokens. Then, a message authorizing the claim of 20 tokens will be signed, which will be used to make a claim. Another message will be signed authorizing the transfer of 60 tokens, followed by a final claim that will also close the channel.
$> npm run test-claimMulti Claim of channels Two channels will be created by the same sender, which we'll refer to as A and B, with initial deposits of 100 and 20 tokens, respectively.
Two messages will be created to claim 20 tokens from channel A and 10 tokens from channel B. Both claims will be executed, and channel B will be closed.
Finally, another message will be created to claim 60 tokens from channel A, which will also result in its closure.
$> npm run test-claimClose a channel
$> npm run test-closeTest combined operations First, a channel is created with an initial deposit of 6 tokens. Then, an update adds 3 more tokens to the channel. A message for 7 tokens is signed and later used to claim the channel. Finally, the channel is closed, returning the remaining tokens to the sender.
$> npm run test-allTo emulate this operations on testnet, complete the .test-env file at the src with:
SEED="decrease cash kangaroo ..."To reduce inputs, you can complete the CONFIG_FILE with:
{
// sender's address
"sender": "addr_test1...",
// receiver's address
"receiver": "addr_test1...",
// signer's pub key hash
"signer_pub_key": "0a0b..."
}Then run:
$> npm run cli-previewAnd input as appropiate.
To test the operations with jest, try:
$> npm run test- Make a directory where we are going to clone all the needed repositories:
mkdir escrow-tx3
cd escrow-tx3
git clone git@github.com:txpipe-shop/tx3-multiparty-escrow.git- Set up tx3 repository:
git clone git@github.com:tx3-lang/tx3.git
cd tx3
git checkout 4ee75495d57096610c142e4dd5e1d7de8f174790
git apply ../tx3-multiparty-escrow/tx3-setup-utils/tx3-changes.patch
cd ..- Set up trix:
git clone git@github.com:tx3-lang/trix.git
cd trix
git checkout e7bca06c51bf5607731f56ef8ba14df61aa91381
git apply ../tx3-multiparty-escrow/tx3-setup-utils/trix-changes.patch
cd ..- Set up dolos:
git clone git@github.com:txpipe/dolos.git
cd dolos
git checkout 16926bdca5d657643ce2ba3f1f2112f92a7261f8
git apply ../tx3-multiparty-escrow/tx3-setup-utils/dolos-changes.patch
cd ..- Complete the CONFIG_FILE with:
{
...
// sender's address
"sender": "addr_test1...",
// receiver's address
"receiver": "addr_test1...",
// signer's pub key hash
"signer_pub_key": "0a0b..."
}- Make sure to use node
v20.11.1:
cd tx3-multiparty-escrow
nvm use v20.11.1- Generate the blaze blueprint:
cd src
npm run generate-blaze-blueprint
cd ../..And fix the generated blueprint.ts by changing the imports section the following way:
/* eslint-disable */
// @ts-nocheck
import { Type } from "@blaze-cardano/data";
import { applyParamsToScript, cborToScript, Core } from "@blaze-cardano/sdk";- Run inside your
dolosfolder:
cd dolos
# Within the options this command shows, select the network to use
# Make sure you enable the trp server and the utxo-rpc endpoint (See the image below)
cargo run init
# To enable
cargo run daemonHere's what the init command looks like:

Note: Keep this terminal and don't close it.
- Generate the proto tx. Open a new terminal and run from the
tx3-multiparty-escrowfolder:
cd src/tx3-offchain
cargo run --manifest-path "../../../trix/Cargo.toml" --quiet --bin trix -- bindgen
cd ..Open a channel
Given an initial amount of AGIX to deposit, a groupID, to open a channel, try inside the src folder:
npm run tx3-open -- -a <initialDeposit> -g <groupId> [-s <sender>] [-r <receiver>] [-spk <signerPubKey>] [-e <expirationDate>]This will return the txHash of said transaction, its CBOR and the corresponding channelID. A default expiration date to one day from now will be set, but you can change that by adding the -e <expirationDate> parameter with the expiration date in POSIX time.
Update a channel
Given a channel ID an amount and an expiration date, you can obtain a CBOR to update a channel by running:
npm run npm run tx3-update -- -c <channelId> [-a <amount>] [-e <expirationDate>] [-s <sender>]The amount and the expiration date are optional fields, but if none of them is completed an error will arise. By using:
npm run tx3-update -- -c <channelId> -dA default amount of 1 AGIX and an expiration date to one week from now will be set.
Build a message
Given a nonce, an amount and a channel ID:
npm run sign -- -c <channelId> -n <nonce> -a <amount>Will return a message signed by the user specified with the seed phrase in the .test-env file.
Claim a channel
Given a channel ID a payload (or signed message) and an amount to claim, run the following:
npm run tx3-claim -- -c <channelId> -p <payload> -a <amount> -f <finalize> [-s <sender>] [-r <receiver>]The -f <finalize> parameter indicates whether the channel will be closed or not after the claiming action.
Close a channel
Given a channel ID from a channel, to close said channel, try:
npm run tx3-close -- -c <channelId> [-s <sender>]