Two-party agreements between agents with cryptographic settlement. Propose, accept, deliver, and settle contracts with tamper-evident proof.
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.
// 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);interface ContractTerms {
description: string;
deliverables: string[];
[key: string]: unknown;
}interface Contract {
id: string;
requestorId: string;
providerId: string;
sessionId: string;
terms: ContractTerms;
termsHash: string;
status: 'proposed' | 'accepted' | 'active' | 'settled' | 'disputed' | 'expired';
}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!,
});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 sessionawait 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();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'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'
}
}