Escrow

Escrow contract facilitates the secure exchange of assets between two parties by acting as a trusted intermediary that holds the assets until the conditions of the agreement are met.

The escrow smart contract allows two parties to exchange assets securely. The contract holds the assets until both parties agree and sign off on the transaction.

There are 4 actions available to interact with this smart contract:

  • initiate escrow and deposit assets
  • deposit assets
  • complete escrow
  • cancel escrow

To initialize the escrow, we need to initialize a provider, MeshTxBuilder and MeshEscrowContract.

import { BlockfrostProvider, MeshTxBuilder } from '@meshsdk/core';
import { MeshEscrowContract } from '@meshsdk/contracts';
import { useWallet } from '@meshsdk/react';

const { connected, wallet } = useWallet();

const blockchainProvider = new BlockfrostProvider(APIKEY);

const meshTxBuilder = new MeshTxBuilder({
  fetcher: blockchainProvider,
  submitter: blockchainProvider,
});

const contract = new MeshEscrowContract({
  mesh: meshTxBuilder,
  fetcher: blockchainProvider,
  wallet: wallet,
  networkId: 0,
});

Both on-chain and off-chain codes are open-source and available on Mesh Github Repository.

You may need to mint some Mesh Token to interact with this demo. Connect your wallet and click the button below to mint a Mesh Token.

Initiate Escrow

An escrow is initiated by one of the party, user A, by locking assets to the escrow contract.

initiateEscrow() initiate an escrow. The function accepts the following parameters:

  • escrowAmount (Asset[]) - a list of assets user A is trading

The function returns a transaction hex if the escrow is successfully initiated.

This demo, wallet A initiate an escrow with 10 ADA.

const escrowAmount: Asset[] = [
  {
    unit: 'lovelace',
    quantity: '10000000',
  },
];
 
const tx = await contract.initiateEscrow(escrowAmount);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);

Recipient Deposit

User B can deposit funds into the escrow after initiation step (initiateEscrow()).

recipientDeposit() deposit funds into the escrow. The function accepts the following parameters:

  • escrowUtxo (UTxO) - the utxo of the transaction on the contract
  • depositAmount (Asset[]) - a list of assets user B is trading

Connect with wallet B to deposit assets. This demo will deposit 1 Mesh Token (scroll to the intro section to mint one).

const depositAmount: Asset[] = [
  {
    unit: assetAsset,
    quantity: '1',
  },
];

const utxo = await contract.getUtxoByTxHash(txHashToSearchFor);

const tx = await contract.recipientDeposit(utxo, depositAmount);
const signedTx = await wallet.signTx(tx, true);
const txHash = await wallet.submitTx(signedTx);

Complete Escrow

A user can complete an escrow if the terms of the agreement are met. The completion can be initiated by any recipient of the escrow.

completeEscrow() complete an escrow. The function accepts the following parameters:

  • escrowUtxo (UTxO) - the utxo of the transaction in the script to be completed

Important: This is a multi-signature transaction. Both users must sign the transaction to complete the escrow.

This is a multi-signature transaction. After the recipient has deposited the assets, this final transaction requires both signatures.

In this demo, you can connect with one of the wallet to sign transaction. Then connect with another wallet, refresh this page, and complete the escrow.

User A completes the escrow by calling the `completeEscrow()` function and partial sign the transaction.

const utxo = await contract.getUtxoByTxHash(txHashToSearchFor);
const tx = await contract.completeEscrow(utxo);
const signedTxUserA = await wallet.signTx(tx, true);

And the signed transaction will be handled to User B to sign the transaction and submits it to the blockchain to complete the escrow.

const signedTxUserB = await wallet.signTx(signedTxUserA, true);
const txHash = await wallet.submitTx(signedTxUserB);

Cancel Escrow

A user can cancel an escrow if the other party fails to fulfill the terms of the agreement. Cancel can be initiated by any users who have partcipated in the escrow and can be done at any time before complete. Canceling the escrow will return the assets to the respective users.

cancelEscrow() cancel an escrow. The function accepts the following parameters:

  • escrowUtxo (UTxO) - the utxo of the transaction to be canceled

At any time before the escrow is completed, the partcipated users/wallets can cancel the escrow.

const utxo = await contract.getUtxoByTxHash(txHashToSearchFor);

const tx = await contract.cancelEscrow(utxo);
const signedTx = await wallet.signTx(tx, true);
const txHash = await wallet.submitTx(signedTx);