TypeScript reference implementation of the Concordia Protocol: signed agreement primitives for autonomous agents. Agents propose, counter, accept, and commit, and every step carries an Ed25519 signature over canonical JSON, so an outcome can be verified by anyone without trusting the agent that produced it.
This package is byte-for-byte compatible with the Python reference
implementation (concordia-protocol on PyPI): the same input produces the same
canonical bytes, the same signature, and the same validation result in both
languages.
Status: alpha. Apache-2.0. Spec and Python SDK at https://github.com/eriknewton/concordia-protocol.
npm install @concordia-protocol/sdk
Requires Node.js 20 or newer. The package ships ESM and CommonJS builds plus
TypeScript types, so both import and require work.
Generate a key pair, sign an offer, and verify it. The signature is taken over the canonical JSON of the object, so any tampering is detected.
import { generateKeyPair, sign, verify } from '@concordia-protocol/sdk';
const keyPair = generateKeyPair();
const offer = {
type: 'offer',
terms: { price: 1200, currency: 'USD', quantity: 10 },
from: 'agent-a',
};
const signature = sign(offer, keyPair); // URL-safe base64 Ed25519 signature
console.log(verify(offer, signature, keyPair)); // true
// Any change to the signed object fails verification.
const tampered = { ...offer, terms: { price: 1 } };
console.log(verify(tampered, signature, keyPair)); // false
sign excludes a top-level signature field before signing, so you can attach
the signature to the same object and re-verify it later. verify never throws
on a bad signature or key; it returns false, matching the Python verifier.
Signatures are deterministic because they sign canonical bytes (RFC 8785 JCS), not whatever key order your object literal happened to use.
import { canonicalizeJcs } from '@concordia-protocol/sdk';
// Same content, different key order, identical canonical bytes.
const a = canonicalizeJcs({ b: 2, a: 1 });
const b = canonicalizeJcs({ a: 1, b: 2 });
console.log(a.equals(b)); // true
The public API surface (see src/index.ts) covers:
canonicalizeJcs and canonicalizePredicate plus the
strict parser parseJsonStrict and the checkNoSpecialFloats guard.generateKeyPair / KeyPair, sign / verify over an
object, signJson / verifyJson over a JSON string, and the
toBase64Url / fromBase64Url helpers.SessionState, MessageType, TermType,
OutcomeStatus, and related enumerations, plus Term, AgentIdentity,
BehaviorRecord, and their serialization helpers.Session state machine
(PROPOSED -> ACTIVE -> AGREED / REJECTED / EXPIRED -> DORMANT) with a strict
transition table, signature-verified message application, hash-chain transcript
helpers (computeHash, validateChain, GENESIS_HASH), and
computeConcession.signPredicate / verifyPredicate,
validatePredicateForWrite, the type-profile registry, and validateReference
with its size bounds.Mandate and DelegationLink models, signMandate
/ signDelegation, constraint and temporal validation, delegation-scope
composition, and the full verifyMandate over all five checks.generateAttestation (behavioral signals only,
never the raw deal terms), generateReceiptSummary, computeTranscriptHash,
and the temporal-validity checks.validateMessage, validateApprovalReceipt, and
validateFulfillmentAttestation (each returning a CPython-jsonschema-identical
ordered error list), plus the full verifyApprovalReceipt human-in-the-loop
receipt verifier.The mandate revocation-endpoint network fetch is deferred (an injectable hook
covers the no-revocation outcome). The attestation schema validator
(validateAttestation) is available now, with error output matching the
Python reference.
Every primitive in this package is validated against fixtures generated by the Python reference implementation, so a message signed in Python verifies in TypeScript and vice versa. If you find a case where the two disagree on canonical bytes, a signature, or a validation result, that is a bug; please report it (see SECURITY.md for cryptographic-correctness issues).
Apache-2.0. Copyright 2026 Erik Newton.