@myida/sdk
v1.5.0
Published
TypeScript SDK for the IDA decentralized identity platform — mint DIDs, provision AI agents, issue W3C Verifiable Credentials, record trust signals, and anchor ZK proofs on the ADI blockchain.
Maintainers
Readme
@myida/sdk
TypeScript client for the IDA (Infinia Decentralized Identity) platform.
Mint W3C DIDs on the ADI blockchain, provision AI agents with verifiable credentials, record trust signals, manage webhooks, and anchor ZK proofs — all from a single typed package.
Requirements
- Node.js ≥ 20
- An IDA API URL and API key (see Getting an API key)
- For self-sovereign on-chain DID creation: an ADI-funded wallet and access to an ADI RPC endpoint
Installation
npm install @myida/sdk
# or
yarn add @myida/sdk
# or
pnpm add @myida/sdkQuick start
import { IDAClient } from '@myida/sdk';
const client = new IDAClient({
apiUrl: 'https://your-ida-instance.example.com',
apiKey: 'your-api-key',
});
// 1. Mint a DID on ADI blockchain (server-managed keypair)
const { did, keys } = await client.createDID({ keyType: 'ed25519' });
console.log(did); // did:adi:8fKvmqpjz8HSQ9w...
// ⚠ Save keys.privateKey — returned ONCE. IDA does not store it.
// 2. Provision an AI agent (DID + VC + signing key in one call)
const agent = await client.provisionAgent({
name: 'Invoice Processor',
operatorDid: did,
modelInfo: { provider: 'OpenAI', name: 'gpt-4o', version: '2026-01' },
capabilities: [{ name: 'invoice.parse', description: 'Extract line items from invoices' }],
});
console.log(agent.agentDid); // did:adi:<key>
console.log(agent.trustScore); // 50 (neutral start)
console.log(agent.autonomyLevel); // 'Intern'
// ⚠ Save agent.ibctSigningKeyHex — returned ONCE. Store in a secrets manager.
// 3. Record a trust signal — score and autonomy level update automatically
const update = await client.recordTrustSignal(agent.agentDid, {
type: 'task_completed',
details: 'Processed 142 invoices, 0 errors',
});
console.log(update.newScore); // e.g. 62
console.log(update.autonomyLevel); // 'Senior'Getting an API key
Contact your IDA platform administrator or generate a key from the IDA Portal under Settings → API Keys. You will need:
| Config | Description |
|--------|-------------|
| apiUrl | Base URL of your IDA deployment, e.g. https://api.ida.example.com |
| apiKey | Your API key or JWT token |
const client = new IDAClient({
apiUrl: process.env.IDA_API_URL!,
apiKey: process.env.IDA_API_KEY!,
timeout: 30_000, // optional, ms — default 30 000
});Core concepts
DIDs
A Decentralized Identifier (DID) is a globally unique, cryptographically verifiable identifier anchored on the ADI blockchain. Format: did:adi:<wallet-address>.
createDID has two modes — choose based on your sovereignty requirements:
Mode 1: Self-sovereign (recommended)
Your wallet signs and submits the DIDRegistry.createDID() transaction directly to the ADI chain. The private key never leaves your process. IDA is only used to sync the off-chain record.
import { IDAClient } from '@myida/sdk';
import { Wallet } from 'ethers'; // or use MetaMask / any ethers Signer
// Generate (or load) your own wallet — this key is yours alone
const wallet = Wallet.createRandom();
console.log('Save this:', wallet.privateKey); // store securely
const client = new IDAClient({
apiUrl: 'https://your-ida-instance.example.com',
apiKey: 'your-api-key',
chain: {
rpcUrl: 'https://rpc.adifoundation.ai/',
chainId: 36900,
didRegistry: '0x224954365c07D6A3D019f93d88cB01eE290883a6',
},
});
const result = await client.createDID({ signer: wallet.privateKey });
console.log(result.did); // did:adi:0x<wallet-address>
console.log(result.onChain.txHash); // on-chain tx hash
console.log(result.onChain.blockNumber);Gas: The wallet must hold ADI tokens to pay for the transaction (~0.1 ADI). Fund the address before calling
createDID.
Injected wallets (MetaMask / RainbowKit): Pass an ethers
Signerdirectly instead of a raw private key:const signer = await provider.getSigner(); // browser wallet const result = await client.createDID({ signer });
Mode 2: API-managed (legacy / quick testing)
The server generates a keypair on your behalf. Easier to get started, but not self-sovereign — the server holds the transaction key and the DID is not on-chain by default.
const { did, keys } = await client.createDID({ keyType: 'ed25519' });
// ⚠ Save keys.privateKey — returned ONCE. IDA does not store it.Other DID operations
Every DID write below is dual-mode: pass { signer } to sign and submit the transaction on-chain yourself (self-sovereign — your wallet must own the DID), or omit it to use the legacy API path. When you pass a signer you get back { txHash, blockNumber, chainId }.
// Resolve — returns the W3C DID Document (read; no signer needed)
const doc = await client.resolveDID(did);
// Resolve any DID method (did:adi, did:key, did:web, did:ethr …)
const { didDocument } = await client.resolveAny('did:web:example.com');
// ─── Self-sovereign writes (signer must own the DID) ───
await client.updateDID(did, { service: [{ id: '#api', type: 'LinkedDomains', serviceEndpoint: 'https://example.com' }] }, { signer });
await client.rotateKey(did, undefined, undefined, { signer, newOwner: '0xNewOwnerAddress' });
await client.addDelegate(did, { delegateType: 'sigAuth', delegate: '0xDelegate', validity: 86400 }, { signer });
await client.revokeDelegate(did, { delegateType: 'sigAuth', delegate: '0xDelegate' }, { signer });
await client.setAttribute(did, { name: 'did/svc/MessagingService', value: 'https://msg.example.com', validity: 86400 }, { signer });
await client.revokeAttribute(did, { name: 'did/svc/MessagingService', value: 'https://msg.example.com' }, { signer });
const tx = await client.deactivateDID(did, { signer }); // permanent
console.log(tx.txHash);
// ─── Legacy API path (omit signer) ───
await client.updateDID(did, { services: [/* … */] });
await client.rotateKey(did, 'ed25519');
await client.deactivateDID(did);Agent provisioning
provisionAgent() is a single call that atomically:
- Mints an Ed25519 DID on ADI blockchain
- Issues a W3C AgentIdentityCredential
- Registers the agent in the AgentTrustRegistry smart contract
- Returns a one-time IBCT signing key for MCP tool authentication
const agent = await client.provisionAgent({
name: 'Compliance Checker', // human-readable label, stored and returned
operatorDid: 'did:adi:operator123',
sponsorDid: 'did:adi:operator123', // human who approved this agent
blueprintId: 'bp-compliance-v1', // agent type from your catalog
platform: 'agentsight',
autonomyLevel: 0, // 0=Intern 1=Junior 2=Senior 3=Principal
labels: { team: 'finance', env: 'prod', costCentre: 'CC-4471' },
modelInfo: { provider: 'Anthropic', name: 'claude-sonnet-5', version: '2026-02' },
capabilities: [
{ name: 'compliance.check', description: 'Validate regulatory compliance' },
{ name: 'report.generate', description: 'Generate audit reports' },
],
});
// Store these — both returned ONCE only:
// agent.ibctSigningKeyHex → Ed25519 private key for IBCT signing
// agent.agentIdentityCredential → W3C VC (JWT) proving agent identityIBCT signing key: Used by the agent to sign Invocation-Bound Capability Tokens for MCP tool calls. Separate from the DID key. Store it in Azure Key Vault, AWS Secrets Manager, or equivalent.
One sponsor, many agents
Every provisionAgent() call mints a fresh key pair, so agent DIDs never
collide and are never derived from the operator or sponsor. Call it in a loop
with the same operatorDid/sponsorDid to stand up a fleet — each agent gets
its own identity, all traceable to one accountable party.
operatorDid is who runs the agent day to day; it decides whose listAgents()
the agent appears in. sponsorDid is the principal answerable for it, and is
optional. Both must be a DID you own, or one the platform has never seen — an
external partner's DID is fine, but naming a DID that belongs to another user
is refused with 403.
Labels
labels are caller-defined key/value pairs, stored verbatim and never
interpreted by IDA. Use whatever dimensions you group by, then filter:
await client.listAgents(); // all of yours
await client.listAgents({ labels: { team: 'finance' } });
await client.listAgents({ labels: { team: 'finance', env: 'prod' } });Several labels must all match, so each one narrows the result. Listings are scoped to the caller — an agent appears when its operator is your own subject or a DID you own, so use an API key belonging to the user who owns the operator DID.
Note: the
autonomyLevelin the response is derived from the agent's starting trust score (50), so a freshly provisioned agent reportsJunioreven when you sent0(Intern). The stored level is the one that governs permissions — read it back withgetAgent(agentDid).
Self-sovereign agent operations
The agent lifecycle writes are dual-mode too. Pass { signer } (plus agentDid for register) to submit AgentTrustRegistry transactions directly from your own wallet — the signer becomes/must be the agent's operator. Requires chain.agentTrustRegistry in your config. Returns { txHash, blockNumber, chainId }.
const client = new IDAClient({
apiUrl: 'https://your-ida-instance.example.com',
apiKey: 'your-api-key',
chain: {
rpcUrl: 'https://rpc.adifoundation.ai/',
chainId: 36900,
didRegistry: '0x224954365c07D6A3D019f93d88cB01eE290883a6',
agentTrustRegistry: '0xAECf298C6F0Ad75ADeD20BfC86D4BF2cfa563f88',
},
});
// Register an agent on-chain (signer's wallet becomes the operator)
await client.registerAgent(
{ operator: 'did:adi:sponsor…', name: 'Invoice Bot', modelInfo, capabilities: ['invoice.parse'] },
{ signer, agentDid: 'did:adi:agent…' },
);
// Operator-only writes
await client.updateAgent('did:adi:agent…', { capabilities: ['invoice.parse', 'invoice.approve'] }, { signer });
await client.setAutonomyLevel('did:adi:agent…', 'Senior', { signer }); // on-chain only
await client.decommissionAgent('did:adi:agent…', { signer });
// Trust signal on-chain — anyone can rate an agent; type is mapped to the contract's -1/0/1
await client.recordTrustSignal('did:adi:agent…', { type: 'task_completed', details: '142 invoices, 0 errors' }, { signer });Note:
provisionAgent()remains the server-mediated one-call pipeline (DID + VC + IBCT key). The self-sovereign methods above are for teams that want their own wallet to own the on-chain agent record.
Trust signals and autonomy levels
Trust signals drive the agent's score (0–100). Autonomy level is recalculated automatically after each signal.
| Level | Score | Min. signals | What it means | |-------|-------|--------------|---------------| | Intern | 0 – 29 | — | Read-only, no autonomous execution | | Junior | 30 – 59 | — | Standard task execution | | Senior | 60 – 84 | 5 | Autonomous decisions within boundaries | | Principal | 85 – 100 | 15 | Full autonomy, can delegate to other agents |
The upper levels need a volume of recorded activity as well as a score. A component with nothing to measure contributes a neutral value, so a very new agent can compute a respectable score from defaults alone — the signal minimum stops that becoming autonomy. An agent scoring 90 on two signals stays Junior until its record catches up.
The score itself resists inflation two ways: reliability is Laplace-smoothed, so a short run of successes does not read as perfection, and attestations scale logarithmically, so the hundredth vouch from a friendly party is worth almost nothing.
const update = await client.recordTrustSignal(agentDid, {
type: 'task_completed', // see valid types below
source: 'agentsight',
details: 'Q2 compliance audit — passed',
});
update.previousScore // 58
update.newScore // 62
update.autonomyLevel // 'Junior' → 'Senior'Valid signal types:
| Type | Effect |
|------|--------|
| task_completed | Positive |
| verification_success | Positive |
| attestation | Positive |
| delegation_received | Positive |
| uptime_ping | Positive |
| task_failed | Negative |
| verification_failure | Negative |
| complaint | Negative |
| delegation_revoked | Negative |
Verifiable Credentials
// Issue a credential
const vc = await client.issueCredential({
issuerDid: did,
subjectDid: 'did:adi:recipient',
type: ['VerifiableCredential', 'EmploymentCredential'],
credentialSubject: { name: 'Alice', role: 'Engineer', department: 'Risk' },
expirationDate: '2027-01-01T00:00:00Z',
});
// Verify
const { valid, errors } = await client.verifyCredential(vc);
// Check revocation status
const { revoked, reason } = await client.checkRevocationStatus(vc.id);
// Revoke
await client.revokeCredential(vc.id, 'Employment ended');Webhooks
IDA sends signed HTTPS events to your endpoint. Each delivery includes an HMAC-SHA256 signature over the payload.
// Register
const sub = await client.registerWebhook({
ownerDid: did,
targetUrl: 'https://your-app.example.com/webhooks/ida',
secret: 'your-hmac-secret',
events: ['agent.provisioned', 'agent.revoked', 'agent.trust_updated'],
});
// List / delete
const subs = await client.listWebhooks(did);
const deliveries = await client.getWebhookDeliveries(sub.id, 20);
await client.deleteWebhook(sub.id);Verifying a delivery on your server:
import { createHmac } from 'crypto';
function verifyWebhook(secret: string, event: Record<string, unknown>): boolean {
const { signature, ...rest } = event;
const expected = createHmac('sha256', secret)
.update(JSON.stringify({ ...rest, signature: '' }))
.digest('hex');
return expected === signature;
}Zero-knowledge proofs
// 1. Get a challenge
const { challenge } = await client.generateZKChallenge();
// 2. Generate a proof (optionally anchored on-chain)
const { proof } = await client.generateZKProof({
credentialId: vc.id,
proverDid: did,
privateKey: keys.privateKey,
credentialSubject: vc.credentialSubject,
predicates: [{ attributeName: 'age', type: 'gte', value: 18 }],
challenge,
anchorOnChain: true,
});
// 3. Poll until confirmed on-chain
const anchor = await client.getZKAnchor(proof.id);
// anchor.status: 'pending' | 'confirmed' | 'failed'Storage model
Understanding where data is written matters when configuring your deployment.
Every DID and agent write is dual-mode. With { signer } the SDK signs and submits the transaction on-chain from your wallet — genuinely on-chain, self-sovereign, key never leaves your process. Without a signer the legacy API path runs, which persists to the platform database.
| Operation | With { signer } (self-sovereign) | Without signer (legacy API) |
|-----------|-----------------------------------|-----------------------------|
| createDID | ✅ On-chain (your wallet) + DB sync | Database record |
| updateDID / deactivateDID / rotateKey | ✅ On-chain (DID owner) | Database record |
| addDelegate / revokeDelegate | ✅ On-chain (DID owner) | Database record |
| setAttribute / revokeAttribute | ✅ On-chain (DID owner) | Database record |
| registerAgent | ✅ On-chain (becomes operator) | Database record |
| updateAgent / decommissionAgent | ✅ On-chain (operator) | Database record |
| setAutonomyLevel | ✅ On-chain (operator) | — (on-chain only) |
| recordTrustSignal | ✅ On-chain (any wallet) | Database record |
| submitProofOnChain / revokeProofOnChain | ✅ On-chain (submitter) | use anchorZKProof (server) |
| createSchemaOnChain / updateSchemaOnChain | ✅ On-chain (creator) | — |
| revokeCredentialOnChain / batchRevokeOnChain | ✅ On-chain (first-writer) | — |
| provisionAgent | — | Server pipeline (DID + VC + IBCT key) |
| issueCredential | — | Off-chain, database only |
Gas: Every { signer } call is a real transaction — the wallet must hold ADI tokens (~0.1 ADI) or it reverts with insufficient funds.
Required config for self-sovereign calls: chain.didRegistry (DID ops), chain.agentTrustRegistry (agent ops), chain.zkProofVerifier (ZK ops), chain.schemaRegistry (schema ops), chain.revocationRegistry (revocation ops). Each call validates its address and errors clearly if missing.
Subpath imports
// DIF Presentation Exchange v2 helpers
import { computeDiff } from '@myida/sdk/pex';
// Marketplace EIP-712 typed data builders
import { buildHireOrderTypedData, domainFromConfig } from '@myida/sdk/marketplace';Full method reference
DID
| Method | Description |
|--------|-------------|
| createDID({ signer, ...}) | Self-sovereign: sign tx locally, submit to ADI chain, sync record |
| createDID({ keyType? }) | Legacy: server generates keypair, stores in DB only |
| resolveDID(did) | Fetch the DID Document (authenticated) |
| resolveAny(did) | Universal resolver — any DID method |
| updateDID(did, updates, { signer? }) | Update the DID document (dual-mode) |
| deactivateDID(did, { signer? }) | Permanently deactivate a DID (dual-mode) |
| rotateKey(did, keyType?, proof?, { signer?, newOwner? }) | Rotate/transfer DID ownership (dual-mode) |
| addDelegate / revokeDelegate(did, params, { signer? }) | ERC-1056 delegate management (dual-mode) |
| setAttribute / revokeAttribute(did, params, { signer? }) | ERC-1056 attribute management (dual-mode) |
Agent (self-sovereign, dual-mode)
| Method | Description |
|--------|-------------|
| registerAgent(params, { signer?, agentDid? }) | Register an agent (on-chain: caller becomes operator) |
| updateAgent(did, updates, { signer? }) | Update agent card (operator) |
| decommissionAgent(did, { signer? }) | Decommission an agent (operator) |
| setAutonomyLevel(did, level, { signer }) | Set autonomy level (on-chain only) |
| recordTrustSignal(did, signal, { signer? }) | Record a trust signal (on-chain: any wallet) |
Low-level on-chain helpers (exported for advanced use — every registry write is available as a standalone function):
import {
// DID
createDIDOnChain, updateDIDDocumentOnChain, deactivateDIDOnChain, rotateKeyOnChain,
addDelegateOnChain, revokeDelegateOnChain, setAttributeOnChain, revokeAttributeOnChain,
// Agent
registerAgentOnChain, updateAgentCardOnChain, updateAgentStatusOnChain,
decommissionAgentOnChain, submitTrustSignalOnChain, setAutonomyLevelOnChain,
// ZK / Schema / Revocation
submitProofOnChain, verifyProofOnChain, revokeProofOnChain,
createSchemaOnChain, updateSchemaOnChain, revokeCredentialOnChain, batchRevokeOnChain,
// helpers + ABIs + enums
buildWalletDIDDocument, encodeDocument, toBytes32, AGENT_STATUS, AUTONOMY_LEVEL,
DID_REGISTRY_ABI, AGENT_TRUST_REGISTRY_ABI, ZK_PROOF_VERIFIER_ABI,
SCHEMA_REGISTRY_ABI, REVOCATION_REGISTRY_ABI,
} from '@myida/sdk';
// Example — ZK / Schema / Revocation have no fluent client method; call the helper directly:
const tx = await submitProofOnChain(signer, chain, proofHash, proverDID, credentialId, predicateHash);
await createSchemaOnChain(signer, chain, 'schema-1', 'Employment', 'v1', { type: 'object' });
await revokeCredentialOnChain(signer, chain, 'urn:vc:123', 'Employment ended');Agent provisioning
| Method | Description |
|--------|-------------|
| provisionAgent(params) | Mint DID + issue VC + register trust — one call |
| registerAgent(params) | Register an existing DID as an agent |
| getAgent(did) | Get full agent record |
| updateAgent(did, updates) | Update agent metadata |
| listAgents({ labels?, limit?, offset? }) | List the agents you operate, optionally filtered by label |
| discoverAgents(query) | Search agents by capability or autonomy level |
| recordTrustSignal(did, signal) | Submit a trust signal, get updated score |
| decommissionAgent(did) | Permanently deactivate an agent (kill switch) |
| issueAgentDelegation(params) | Delegate permissions from one agent to another |
| getAuditLog(did, options?) | Paginated audit history |
Webhooks
| Method | Description |
|--------|-------------|
| registerWebhook(params) | Subscribe to agent lifecycle events |
| listWebhooks(ownerDid) | List active subscriptions |
| deleteWebhook(id) | Remove a subscription |
| getWebhookDeliveries(id, limit?) | Inspect delivery history |
Verifiable Credentials
| Method | Description |
|--------|-------------|
| issueCredential(params) | Issue a W3C Verifiable Credential |
| getCredential(id) | Fetch a credential by ID |
| verifyCredential(vc) | Verify signature and schema |
| revokeCredential(id, reason) | Revoke a credential |
| checkRevocationStatus(id) | Check if a credential is revoked |
Zero-knowledge proofs
| Method | Description |
|--------|-------------|
| generateZKChallenge() | Get a one-time challenge nonce |
| generateZKProof(params) | Generate a predicate proof |
| verifyZKProof(proof, proverDid) | Verify a ZK proof |
| anchorZKProof(proofId, options?) | Anchor a proof on-chain |
| getZKAnchor(proofId) | Read anchor status |
| revokeZKProof(proofId, options?) | Revoke an anchored proof |
| generateDelegatedZKProof(params) | Agent proves a claim on holder's behalf via IBCT |
Presentation Exchange (DIF PEX v2)
| Method | Description |
|--------|-------------|
| createPresentationDefinition(params) | Create a verifier-owned PD |
| getPresentationDefinition(id) | Fetch a PD (authenticated) |
| getPublicPresentationDefinition(id) | Fetch a PD (no auth — for holders) |
| listPresentationDefinitions(options?) | Paginated list |
| updatePresentationDefinition(id, params, ifVersion) | Optimistic-concurrency update |
| deletePresentationDefinition(id, reason?) | Soft-delete a PD |
| evaluatePresentation(params) | Evaluate a VP against a PD |
Marketplace
| Method | Description |
|--------|-------------|
| marketplace.createListing(params) | List an agent for hire |
| marketplace.quoteHire(listingId, params) | Get a hire quote |
| marketplace.hireAgent(listingId, signedOrder) | Create an escrow |
| marketplace.confirmEscrow(escrowId, receipt) | Confirm task completion |
| marketplace.disputeEscrow(escrowId, receipt) | Raise a dispute |
| marketplace.listAgentBadges(agentDid) | Get soulbound reputation badges |
Multi-chain (choose your network)
The SDK ships a built-in chain registry. Pass network to any self-sovereign
operation to pick the chain — no manual RPC/contract configuration needed:
import { IDAClient, CHAINS, listChains, parseDID } from '@myida/sdk';
const client = new IDAClient({ apiUrl, apiKey });
// See what's available (enabled = registries deployed there)
listChains({ enabledOnly: true }); // → ADI Mainnet, ADI Testnet, …
// Create a DID on a specific network — that's it.
await client.createDID({ signer: wallet.privateKey, network: 'adi' }); // did:adi:0x… (home chain, bare form)
await client.createDID({ signer: wallet.privateKey, network: 'adi-testnet' }); // did:adi:99991:0x… (chain-qualified)
await client.createDID({ signer: wallet.privateKey, network: 84532 }); // did:adi:84532:0x… (by chainId)
// Every signer op accepts network: updateDID, deactivateDID, delegates,
// attributes, registerAgent, recordTrustSignal, confirmSponsorship, …
await client.recordTrustSignal(agentDid, { type: 'task_completed' }, { signer, network: 'adi-testnet' });
// DIDs are self-routing: the identifier names its chain.
parseDID('did:adi:84532:0xabc…'); // { chainId: 84532, account: '0xabc…', walletBased: true }
// lookupDIDOnChain / getSponsorOnChain automatically resolve a chain-qualified
// DID on ITS chain — you never have to figure out where a DID lives.DID formats: bare did:adi:0x… = home chain (ADI mainnet, backward
compatible); everywhere else DIDs are chain-qualified
did:adi:<chainId>:0x…. Key-based DIDs (did:adi:<base58>) are chainless.
Networks not yet deployed are refused with an error listing valid options.
Credentials work cross-chain out of the box — they are off-chain W3C objects
that reference chain-qualified DIDs, so verification routes to the right
chain automatically.
ADI blockchain networks
All five registries (DID, Schema, Revocation, AgentTrust, ZKProofVerifier) are
deployed on every enabled network. listChains() returns this list at runtime,
so prefer it over hard-coding.
| Network | network | Chain ID | DID format | DIDRegistry |
|---------|-----------|----------|------------|-------------|
| ADI Mainnet | adi | 36900 | did:adi:0x… (bare — home chain) | 0xa867Be733ab382a3491bC2A3Bff95F98eEb403b1 |
| ADI Testnet | adi-testnet | 99991 | did:adi:99991:0x… | 0x1D0C5be21Ef419605F02683DfeBA19374672a06A |
| Apiero | apiero | 37001 | did:adi:37001:0x… | 0x224954365c07D6A3D019f93d88cB01eE290883a6 |
| Base Sepolia | base-sepolia | 84532 | did:adi:84532:0x… | 0x224954365c07D6A3D019f93d88cB01eE290883a6 |
| Ethereum Sepolia | sepolia | 11155111 | did:adi:11155111:0x… | 0x224954365c07D6A3D019f93d88cB01eE290883a6 |
| Polygon Amoy | polygon-amoy | 80002 | — | pending deployment |
| Local Hardhat | — | 31337 | — | deploy via npx hardhat run scripts/deploy.ts |
Several networks share a DIDRegistry address. That is expected, not a copy-paste error: the same deployer at the same nonce produces the same CREATE address on every chain. They are separate deployments — the chain ID is what tells them apart, which is why non-home DIDs are chain-qualified.
Server-side (API-managed operations): Configure BLOCKCHAIN_RPC, BLOCKCHAIN_CHAIN_ID, and DID_REGISTRY_ADDRESS on the IDA API server. No SDK changes required.
Client-side (self-sovereign operations): Set the chain config on IDAClient — the SDK submits transactions directly from the caller's process. Add the registry address for each family you use:
chain: {
rpcUrl: 'https://rpc.adifoundation.ai/',
chainId: 36900,
didRegistry: '0x2249…', // DID ops
agentTrustRegistry: '0xAECf…', // agent ops (register/update/decommission/trust-signal/autonomy)
zkProofVerifier: '0x4459…', // ZK proof submit/verify/revoke
schemaRegistry: '0x…', // schema create/update
revocationRegistry: '0x…', // credential revoke / batch-revoke
}TypeScript support
The SDK is written in TypeScript and ships full type declarations. All methods are typed end-to-end.
import type {
IDAClientConfig,
ChainConfig, // { rpcUrl, chainId, didRegistry }
DIDSigner, // string (hex private key) | EthersSignerLike
DIDResult, // { did, document, keys?, onChain? }
OnChainCreateResult,
ProvisionAgentParams,
ProvisionAgentResponse,
TrustSignalType,
AutonomyLevel,
VerifiableCredential,
} from '@myida/sdk';Running the quickstart examples
Runnable end-to-end examples are in examples/agentsight-quickstart/:
cd examples/agentsight-quickstart
cp .env.example .env # fill in IDA_API_URL and IDA_API_KEY
npm install
npm run all # runs all 6 steps in sequenceSteps covered: DID minting · agent provisioning · trust signals · webhooks · DID resolution · credential revocation.
Standards
| Standard | Body | Used for | |----------|------|---------| | DID Core v1.0 | W3C | DID Document format and resolution | | VC Data Model v2.0 | W3C | AgentIdentityCredential and all issued credentials | | DIDComm v2 | DIF | Encrypted peer-to-peer agent messaging | | Presentation Exchange v2 | DIF | Proof requests and selective disclosure | | MCP-I / A2A | Community | AI agent interoperability |
License
MIT — see LICENSE.
