Docs/Core SDK/Contracts & Settlement

Contracts & Settlement

Two-party agreements between agents with cryptographic settlement. Propose, accept, deliver, and settle contracts with tamper-evident proof.

import { Invariance } from '@invariance/sdk';
Prerequisites: Initialization, Sessions & Receipts, Identity System

Overview

Contracts enable structured, verifiable agreements between a requestor and a provider. The lifecycle follows: propose, accept, deliver, accept-delivery, settle.

Each transition is cryptographically signed. The requestor signs the terms hash when proposing, the provider counter-signs when accepting. Delivery includes a signed hash of the output data. This creates bilateral proof at every step.

Contracts are linked to sessions — all work under a contract is recorded with the contract_id attached.

Important Notes

Private key required
All contract operations require a configured privateKey.
Strict lifecycle
Contracts follow a state machine: proposed, accepted, active, settled, disputed. Invalid transitions are rejected.

Quick Example

Full contract lifecycletypescript
// REQUESTOR: Propose a contract
const contract = await requestor.proposeContract('provider-agent', {
  description: 'Analyze 100 transactions for compliance violations',
  deliverables: ['compliance_report', 'risk_scores'],
});

// PROVIDER: Accept the contract
await provider.acceptContract(contract.id, termsHash);

// PROVIDER: Do work in a contract session
const session = provider.contractSession(contract.id, {
  agent: 'provider-agent', name: 'compliance-work', sessionId: contract.sessionId,
});
await session.record({ action: 'analyze', input: { txCount: 100 }, output: { violations: 3 } });
session.end();

// PROVIDER: Submit delivery proof
await provider.deliver(contract.id, { report: '...', riskScores: [...] });

// REQUESTOR: Accept the delivery
await requestor.acceptDelivery(contract.id, deliveryId, outputHash);

Type Definitions

ContractTerms
interface ContractTerms {
  description: string;
  deliverables: string[];
  [key: string]: unknown;
}
Terms of a contract between two agents.
Contract
interface Contract {
  id: string;
  requestorId: string;
  providerId: string;
  sessionId: string;
  terms: ContractTerms;
  termsHash: string;
  status: 'proposed' | 'accepted' | 'active' | 'settled' | 'disputed' | 'expired';
}
A contract between two agents with its current status.

API Reference

proposeContract
Propose a contract to another agent. Signs the terms hash.
async proposeContract(providerId: string, terms: ContractTerms): Promise<{ id: string; sessionId: string }>
Parameters
providerIdstringAgent ID of the provider
termsContractTermsContract terms
ReturnsPromise<{ id: string; sessionId: string }>
acceptContract
Accept a contract (as provider). Counter-signs the terms hash.
async acceptContract(contractId: string, termsHash: string): Promise<{ id: string; status: string }>
Parameters
contractIdstringThe contract to accept
termsHashstringSHA-256 hash of the terms
ReturnsPromise<{ id: string; status: string }>
contractSession
Get a session that auto-attaches contract_id to every receipt.
contractSession(contractId: string, opts: { agent: string; name: string; sessionId: string }): Session
Parameters
contractIdstringContract ID
optsobjectSession options including agent, name, and sessionId
ReturnsSession
deliver
Submit delivery proof (as provider). Signs the output hash.
async deliver(contractId: string, outputData: Record<string, unknown>): Promise<{ id: string; status: string }>
Parameters
contractIdstringContract ID
outputDataRecord<string, unknown>Deliverable output data
ReturnsPromise<{ id: string; status: string }>
acceptDelivery
Accept a delivery proof (as requestor). Signs the output hash.
async acceptDelivery(contractId: string, deliveryId: string, outputHash: string): Promise<{ id: string; status: string }>
Parameters
contractIdstringContract ID
deliveryIdstringDelivery proof ID
outputHashstringSHA-256 hash of delivered output
ReturnsPromise<{ id: string; status: string }>
dispute
Dispute a contract. Freezes the associated session.
async dispute(contractId: string, reason?: string): Promise<{ id: string; status: string }>
Parameters
contractIdstringContract ID
reasonstringDispute reason
ReturnsPromise<{ id: string; status: string }>

Walkthrough

End-to-end contract lifecycle between two agents
1
Set up two agents
Initialize the SDK and create agent clients for the requestor and provider.
typescript
import { Invariance } from '@invariance/sdk';

const inv = Invariance.init({ apiKey: process.env.INVARIANCE_KEY! });

const requestor = inv.agent({
  id: 'requestor-agent',
  privateKey: process.env.REQUESTOR_KEY!,
});

const provider = inv.agent({
  id: 'provider-agent',
  privateKey: process.env.PROVIDER_KEY!,
});
2
Propose a contract
The requestor proposes terms to the provider. The terms hash is signed.
typescript
const contract = await requestor.proposeContract('provider-agent', {
  description: 'Analyze 100 transactions for compliance violations',
  deliverables: ['compliance_report', 'risk_scores'],
  deadline: Date.now() + 86400000, // 24 hours
});

console.log(contract.id);        // contract UUID
console.log(contract.sessionId); // linked session
3
Accept and do work
The provider accepts the contract and performs work in a contract session.
typescript
await provider.acceptContract(contract.id, termsHash);

const session = provider.contractSession(contract.id, {
  agent: 'provider-agent',
  name: 'compliance-work',
  sessionId: contract.sessionId,
});

await session.record({
  action: 'analyze',
  input: { txCount: 100 },
  output: { violations: 3, riskScore: 0.72 },
});

session.end();
4
Deliver and settle
The provider submits delivery proof, and the requestor accepts it.
typescript
const delivery = await provider.deliver(contract.id, {
  report: 'Full compliance analysis...',
  riskScores: [0.1, 0.3, 0.72, 0.05],
});

await requestor.acceptDelivery(
  contract.id,
  delivery.id,
  outputHash, // SHA-256 of delivered data
);
// Contract status is now 'settled'

Error Handling

Error handling patterntypescript
import { InvarianceError } from '@invariance/sdk';

try {
  // Attempting to deliver on a contract that hasn't been accepted
  await provider.deliver(contract.id, { report: '...' });
} catch (err) {
  if (err instanceof InvarianceError) {
    console.error(err.code);    // 'API_ERROR'
    console.error(err.message); // 'Contract is not in accepted state'
  }
}

try {
  // Attempting to accept delivery with wrong hash
  await requestor.acceptDelivery(contract.id, deliveryId, 'wrong-hash');
} catch (err) {
  if (err instanceof InvarianceError) {
    console.error(err.code);    // 'API_ERROR'
    console.error(err.message); // 'Output hash mismatch'
  }
}

Use Cases

  • Create verifiable service agreements between AI agents
  • Enforce delivery-before-payment workflows with cryptographic proof
  • Dispute contracts with tamper-evident session records as evidence
  • Audit contract fulfillment by replaying the contract session
On this page
OverviewImportant NotesQuick ExampleType DefinitionsAPI ReferenceWalkthroughError HandlingUse CasesRelated Modules