@concordia-protocol/sdk
v0.0.1-alpha.12
Published
TypeScript reference implementation of the Concordia Protocol -- signed agreement primitives for autonomous agents
Readme
@concordia-protocol/sdk
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.
Install
npm install @concordia-protocol/sdkRequires Node.js 20 or newer. The package ships ESM and CommonJS builds plus
TypeScript types, so both import and require work.
Quickstart
Generate a key pair, sign an authority predicate, and verify it. The built-in
urn:concordia:predicate-type:authority_gate:v1 profile is registered when the
module loads, so no profile registration call is needed.
import { generateKeyPair, signPredicate, verifyPredicate, verify } from '@concordia-protocol/sdk';
const keyPair = generateKeyPair();
const signed = signPredicate(
{
predicate_id: 'urn:concordia:predicate:quickstart_authority',
type: 'urn:concordia:predicate-type:authority_gate:v1',
authority: 'urn:concordia:authority:procurement',
issuer: 'did:web:issuer.example#key-1',
subject: 'did:web:buyer.example#agent',
condition: { result: 'satisfied' },
issued_at: '2026-05-14T00:00:00Z',
expires_at: '2126-06-14T00:00:00Z',
references: [],
algorithm: 'EdDSA',
status: 'active',
signature: '',
},
keyPair,
);
const semanticResult = verifyPredicate(signed);
console.log(semanticResult.valid); // true
const publicKey = keyPair.publicKeyBytes();
const signatureOnly = verify(signed.toDict(), signed.signature, publicKey);
console.log(signatureOnly); // trueverifyPredicate checks the predicate schema, built-in type profile, signature,
lifecycle, subject binding, and references. The low-level verify() call checks
only the Ed25519 signature over canonical JSON using the public key. It is the
portable path for a third party that has an artifact, its signature, and the
issuer public key; it needs no process-local predicate profile registration.
Predicate ids must start with urn:concordia:predicate:. Built-in predicate
types use full URNs such as urn:concordia:predicate-type:authority_gate:v1;
bare shorthand such as authority_gate is not accepted.
Low-Level Object Signing
You can also sign and verify any Concordia object directly. 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)); // falsesign 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.
Canonical JSON
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)); // trueWhat this SDK provides
The public API surface (see src/index.ts) covers:
- Canonical JSON:
canonicalizeJcsandcanonicalizePredicateplus the strict parserparseJsonStrictand thecheckNoSpecialFloatsguard. - Ed25519 signing:
generateKeyPair/KeyPair,sign/verifyover an object,signJson/verifyJsonover a JSON string, and thetoBase64Url/fromBase64Urlhelpers. - Core types: the
SessionState,MessageType,TermType,OutcomeStatus, and related enumerations, plusTerm,AgentIdentity,BehaviorRecord, and their serialization helpers. - Negotiation session: the
Sessionstate machine (PROPOSED -> ACTIVE -> AGREED / REJECTED / EXPIRED -> DORMANT) with a strict transition table, signature-verified message application, hash-chain transcript helpers (computeHash,validateChain,GENESIS_HASH), andcomputeConcession. - Signed predicates:
signPredicate/verifyPredicate,validatePredicateForWrite, the type-profile registry, andvalidateReferencewith its size bounds. - Mandate credentials: the
MandateandDelegationLinkmodels,signMandate/signDelegation, constraint and temporal validation, delegation-scope composition, and the fullverifyMandateover all five checks. - Reputation attestation:
generateAttestation(behavioral signals only, never the raw deal terms),generateReceiptSummary,computeTranscriptHash, and the temporal-validity checks. - Schema validation:
validateMessage,validateApprovalReceipt, andvalidateFulfillmentAttestation(each returning a CPython-jsonschema-identical ordered error list), plus the fullverifyApprovalReceipthuman-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.
Parity with the Python SDK
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).
License
Apache-2.0. Copyright 2026 Erik Newton.
