Skip to main content

Overview

Integrate Zenland escrows into your marketplace, platform, or dApp.

Read: Free

Query escrow states and data

Write: Gas

Create/manage escrows (or use NYKNYC)

Index: Events

Build real-time dashboards

Installation

NPM Package

npm install @zenland/contracts

Contract ABIs

import {
  EscrowFactory__factory,
  EscrowImplementation__factory,
  AgentRegistry__factory,
} from '@zenland/contracts';

Direct Import

// ABIs are also available at
const factoryAbi = await fetch('https://zen.land/abi/EscrowFactory.json');

Common Patterns

1. Predict Escrow Address

Before creating, predict the escrow address:
import { ethers } from 'ethers';

const factory = new ethers.Contract(FACTORY_ADDRESS, factoryAbi, provider);

const { predictedAddress, creationFee, assignmentFee } = 
  await factory.quoteCreateEscrow(
    userSalt,
    sellerAddress,
    agentAddress,
    tokenAddress,
    amount,
    buyerProtectionTime
  );

console.log(`Escrow will deploy to: ${predictedAddress}`);
console.log(`Total fees: ${creationFee + assignmentFee}`);

2. Create an Escrow

// First: approve token spending
const token = new ethers.Contract(tokenAddress, erc20Abi, signer);
const totalAmount = amount + creationFee;
await token.approve(FACTORY_ADDRESS, totalAmount);

// Then: create escrow
const tx = await factory.createEscrow(
  userSalt,
  sellerAddress,
  agentAddress,    // or ethers.ZeroAddress for locked
  tokenAddress,
  amount,
  buyerProtectionTime,
  termsHash,
  1,               // version
  predictedAddress // safety check
);

const receipt = await tx.wait();
console.log(`Escrow created: ${receipt.logs[0].args.escrow}`);

3. Read Escrow State

const escrow = new ethers.Contract(
  escrowAddress,
  escrowImplAbi,
  provider
);

const state = await escrow.state();
const amount = await escrow.amount();
const buyer = await escrow.buyer();
const seller = await escrow.seller();

const states = ['PENDING', 'ACTIVE', 'FULFILLED', 'RELEASED', 
                'REFUNDED', 'DISPUTED', 'AGENT_INVITED', 
                'SPLIT', 'AGENT_RESOLVED'];
console.log(`State: ${states[state]}`);

4. Execute Actions

// As buyer: release funds
await escrow.connect(buyerSigner).release();

// As seller: mark fulfilled
await escrow.connect(sellerSigner).markFulfilled();

// As seller: refund
await escrow.connect(sellerSigner).sellerRefund();

Indexing Events

Using Ethers.js

// Listen to all escrow creations
factory.on('EscrowCreated', (escrow, buyer, seller, agent, token, amount, fee) => {
  console.log(`New escrow: ${escrow}`);
});

// Listen to specific escrow events
escrow.on('Released', (buyer, amount) => {
  console.log(`Released ${amount} to seller`);
});

Using The Graph

We’re working on a subgraph. Check back soon!

Using Ponder

// ponder.config.ts
export default {
  contracts: {
    EscrowFactory: {
      abi: factoryAbi,
      address: FACTORY_ADDRESS,
      startBlock: START_BLOCK,
    },
  },
};

// handlers/Factory.ts
import { ponder } from '@ponder/core';

ponder.on('EscrowFactory:EscrowCreated', async ({ event, context }) => {
  await context.db.Escrow.create({
    id: event.args.escrow,
    buyer: event.args.buyer,
    seller: event.args.seller,
    amount: event.args.amount,
    state: 'PENDING',
  });
});

Gas Optimization

For Your Users

Use Permit (EIP-2612)

Combine approval + creation in one transaction.

Batch Reads

Use multicall for reading multiple escrows.

For Your Backend

// Use staticCall for simulations
const wouldSucceed = await factory.createEscrow.staticCall(...args);

// Estimate gas before sending
const gasEstimate = await factory.createEscrow.estimateGas(...args);

Account Abstraction (ERC-4337)

Want to sponsor gas for your users?
// Using a paymaster (e.g., Pimlico, StackUp)
const userOperation = await bundler.buildUserOp({
  target: FACTORY_ADDRESS,
  data: factory.interface.encodeFunctionData('createEscrow', args),
});

// Sponsor the operation
userOperation.paymasterAndData = YOUR_PAYMASTER_DATA;

await bundler.sendUserOperation(userOperation);

Contact Us

Want integration support? Reach out!

API Reference

Full API Reference

See complete function signatures →