@ajna-inc/kanon
v0.6.3
Published
Credo (Aries TS) plugin that uses the Kanon AnonCreds VDR — drop-in for any EVM chain. Works with @credo-ts/anoncreds and @hyperledger/anoncreds-shared unmodified.
Maintainers
Readme
Credo plugin for the Kanon AnonCreds VDR — runs on any EVM chain (Hyperledger Besu, Ethereum, L2s, private rollups). Drops into Credo agents unmodified, no changes to @credo-ts/anoncreds or anoncreds-rs.
Credo-ts 0.6.x build. This package (
0.6.x) targets@credo-ts/core ^0.6.1and uses the 0.6 KMS API + the split@credo-ts/didcommmodule. If you're still on Credo-ts 0.5.x, install@ajna-inc/kanon@^0.5instead.
What's inside:
did:kanonregistrar + resolverKanonAnonCredsRegistry— AnonCreds VDR backed by the Kanon contracts- Wrapped
AnonCredsVerifierService— afterverifyProofsucceeds, ANDs an on-chainAnonCredsStatusRegistry.isRevoked(credDefId, credIdHash)check KanonIssuanceTracker— subscribes toDidCommCredentialStateChangedand writes an on-chain issuance record when issuance finalises- Chore-hiding helpers —
buildKanonSchema,buildKanonCredentialAttributes,buildKanonProofRequestso schema authors and verifier authors never typekanonCredIdby hand
Install
pnpm add @ajna-inc/kanon@^0.6 ethers(@ajna-inc/kanon-sdk is pulled in transitively from npm.)
Peer dependencies
@credo-ts/core^0.6.1@credo-ts/anoncreds^0.6.1@credo-ts/didcomm^0.6.1
Usage
import { Agent, DidsModule } from '@credo-ts/core'
import { AnonCredsModule } from '@credo-ts/anoncreds'
import {
KanonModule,
KanonAnonCredsRegistry,
KanonDidRegistrar,
KanonDidResolver,
buildKanonSchema,
} from '@ajna-inc/kanon'
const agent = new Agent({
config: { /* … */ },
modules: {
anoncreds: new AnonCredsModule({
registries: [new KanonAnonCredsRegistry()],
}),
dids: new DidsModule({
registrars: [new KanonDidRegistrar()],
resolvers: [new KanonDidResolver()],
}),
// KanonModule MUST come AFTER AnonCredsModule so its
// AnonCredsVerifierService override (on-chain status check) wins.
kanon: new KanonModule({
rpcUrl: process.env.KANON_RPC_URL!,
privateKey: process.env.KANON_PRIVATE_KEY!,
// Either pass the on-chain address book (single contract for all 7
// registries — recommended) …
addressBook: process.env.KANON_ADDRESS_BOOK,
// … or pass a deployment inline / by file / by chainId:
// deployment: { chainId, addresses: { … } }
// deploymentPath: './deployments/1947.json'
// chainId: 1947
issuerOrgId: process.env.KANON_ISSUER_ORG_ID!, // 0x<64 hex> bytes32
}),
},
})
// 1. Mint the issuer DID (once per org).
const { didState } = await agent.dids.create({
method: 'kanon',
scope: 'org',
orgId: process.env.KANON_ISSUER_ORG_ID!,
})
const issuerDid = didState.did!
// 2. Register a schema on the kanon VDR. buildKanonSchema prepends the
// canonical `kanonCredId` attribute so revocation works.
await agent.modules.anoncreds.registerSchema({
schema: buildKanonSchema({
name: 'DriverLicense',
version: '1.0',
attrNames: ['fullName', 'dateOfBirth', 'licenseNumber'],
issuerId: issuerDid,
}),
options: { supportRevocation: false },
})What ships under the hood
kanonCredIdattribute injection inbuildKanonSchema/buildKanonCredentialAttributes/buildKanonProofRequest- Canonical hash via
@ajna-inc/kanon-sdk/anoncreds(single source of truth) - On-chain calls via the SDK's contract bindings — Kanon ABIs, addresses, deployment loader all come from one place
Mode B (optional ZK)
Mode B (Groth16 SNARK presentations for unlinkability) is implemented in the SDK at @ajna-inc/kanon-sdk/zk. Not auto-wired into this plugin yet — see the Kanon site for the integration plan.
License
Apache-2.0.
