Integration Guide

Integrate Términa Escrow into your application using our TypeScript SDK or direct smart contract calls. This guide covers everything you need to get started.

Quick Start

The fastest way to integrate escrow functionality into your app:

1. Install Dependencies

npm install casper-js-sdk
# or
yarn add casper-js-sdk

2. Initialize the SDK

import { CasperClient, Keys, DeployUtil } from 'casper-js-sdk';

// Connect to Casper network
const client = new CasperClient('https://rpc.testnet.casperlabs.io/rpc');

// Load your keys
const keys = Keys.Ed25519.loadKeyPairFromPrivateFile('./secret_key.pem');

3. Create an Escrow

// Deploy escrow contract with invoice details
const deploy = DeployUtil.makeDeploy(
  new DeployUtil.DeployParams(
    keys.publicKey,
    'casper-test',
    1,
    1800000 // 30 min TTL
  ),
  DeployUtil.ExecutableDeployItem.newModuleBytes(
    escrowWasm,
    RuntimeArgs.fromMap({
      invoice_id: CLValueBuilder.string('INV-001'),
      description: CLValueBuilder.string('Web development'),
      amount: CLValueBuilder.u512(100_000_000_000), // 100 CSPR
      payer: CLValueBuilder.key(payerPublicKey),
      arbiter: CLValueBuilder.option(Some(arbiterPublicKey))
    })
  ),
  DeployUtil.standardPayment(50_000_000_000) // 50 CSPR gas
);

// Sign and send
const signedDeploy = DeployUtil.signDeploy(deploy, keys);
const result = await client.putDeploy(signedDeploy);
console.log('Deploy hash:', result);

API Reference

The escrow contract exposes the following entry points. All methods require proper authentication and state validation.

MethodParametersCallerGas (CSPR)
initEscrowConfigIssuer~50
acceptnonePayer~1
fundamount (attached)Payer~1 + amount
releasenonePayer~1
cancelnoneIssuer/Payer~1
disputereason: StringIssuer/Payer~1
resolve_disputerelease_to_issuer: boolArbiter~1

Calling Contract Methods

After deployment, interact with the escrow using stored contract calls:

Accept Escrow (Payer)

const deploy = DeployUtil.makeDeploy(
  deployParams,
  DeployUtil.ExecutableDeployItem.newStoredContractByHash(
    escrowContractHash,
    'accept',
    RuntimeArgs.fromMap({})
  ),
  DeployUtil.standardPayment(1_000_000_000) // 1 CSPR
);

Fund Escrow (Payer)

const deploy = DeployUtil.makeDeploy(
  deployParams,
  DeployUtil.ExecutableDeployItem.newStoredContractByHash(
    escrowContractHash,
    'fund',
    RuntimeArgs.fromMap({
      amount: CLValueBuilder.u512(100_000_000_000) // 100 CSPR
    })
  ),
  DeployUtil.standardPayment(101_000_000_000) // amount + gas
);

Release Funds (Payer)

const deploy = DeployUtil.makeDeploy(
  deployParams,
  DeployUtil.ExecutableDeployItem.newStoredContractByHash(
    escrowContractHash,
    'release',
    RuntimeArgs.fromMap({})
  ),
  DeployUtil.standardPayment(1_000_000_000) // 1 CSPR
);

Querying State

Read escrow data using the Casper RPC:

// Get current state
const stateRootHash = await client.nodeClient.getStateRootHash();
const state = await client.nodeClient.getBlockState(
  stateRootHash,
  `hash-${escrowContractHash}`,
  ['state']
);
console.log('Escrow state:', state);

// Get invoice details
const invoice = await client.nodeClient.getBlockState(
  stateRootHash,
  `hash-${escrowContractHash}`,
  ['invoice']
);
console.log('Invoice:', invoice);

Listening to Events

Subscribe to escrow events using the Casper Event Stream:

import { EventStream, EventName } from 'casper-js-sdk';

const eventStream = new EventStream(
  'https://events.testnet.casperlabs.io/events/main'
);

eventStream.subscribe(EventName.DeployProcessed, (event) => {
  const deploy = event.body.DeployProcessed;

  // Filter for your escrow contract
  if (deploy.execution_result.Success) {
    const transforms = deploy.execution_result.Success.effect.transforms;
    // Parse event data from transforms
    console.log('Escrow event:', transforms);
  }
});

eventStream.start();

Error Handling

The contract returns specific error codes for different failure scenarios:

CodeErrorDescription
1NotPayerCaller is not the designated payer
2NotIssuerCaller is not the designated issuer
3NotArbiterCaller is not the designated arbiter
4InvalidStateAction not allowed in current state
5InsufficientFundsDeposit less than invoice amount
6NoArbiterNo arbiter set for dispute resolution

Testnet Resources