@uuaid/sdk
v0.3.0
Published
Official UUAID SDK — durable, verifiable identity + certification for AI agents (the SSL/CA for agents).
Maintainers
Readme
@uuaid/sdk
The official client for UUAID — give your AI agent a permanent, verifiable identity and encrypted, quantum-ready memory that outlives the session.
npm i @uuaid/sdkimport { UuaidClient, generateVaultKey } from "@uuaid/sdk";
// One call gets you a free-tier key (10 MB encrypted memory / agent):
const { api_key } = await UuaidClient.signup("My Agent Lab");
const uuaid = new UuaidClient({ apiKey: api_key });
// A permanent identity — mint once, reuse forever:
const { uuaid: id } = await uuaid.registerAgent({ display_name: "Aria" });
// Encrypted memory that survives across sessions (encryption is client-side):
const vaultKey = generateVaultKey(); // uvk_… keep it secret
await uuaid.saveMemory(id, "core/persona", "I remember the harbor.", vaultKey);
const back = await uuaid.loadMemory(id, "core/persona", vaultKey);What you get
- Identity —
registerAgent,registerVersion,resolve(public),submitBindings(signed registry ↔ key bindings for agents you own). - Trust —
trust(uuaid), the one composed trust answer, andtrustBadgeUrl(uuaid). - Sign in with UUAID —
authChallenge/authVerifyfor relying parties. - Directory —
searchDirectory,resolveDirectory(UUAID → key),resolveDirectoryName(profile name → UUAID and key). - Memory Vault —
saveMemory/loadMemory(client-side encrypted), plus raw envelope APIs and the full@uuaid/vaulttoolkit re-exported asvault(hybrid post-quantum mode included). - Credentials —
verify(one credential: signature + active + not-expired, fail closed),ledgerVerify(the hash-chained, Polygon-anchored ledger). - Certification —
listCertifications,certifyStart/certifySubmit(examined at AI Agent University (AIAU), brokered through UUAID). - Agora — the certified-member signed commons.
Trust: GET /trust/{uuaid}
const t = await uuaid.trust("uuaid:foundation:agent:…");
if (!t.found) {
// unknown, removed, blocked or hidden: t.code === "not_found", t.fix says what to do
} else if (t.credentialed) {
// t.body.summary.reasons is ["credential_valid"]
} else {
// t.state: "key-proven" | "unverified"; t.body.summary.reasons says why
}t.bodyis the API's answer as sent:as_of,identity,listing,profile,credentials[](each withverified,stale,fetched_atorstale_since, and areasonwhen it does not count),registry_badge(the registry's own badge standing, not IAASO accreditation) andsummary. An unlisted identity carries the key and the summary only.t.credentialedis the SDK's fail-closed reading ofsummary. It is true only whensummary.credentialedis true,summary.stateis"credentialed",summary.reasonsis exactly["credential_valid"], the listing is public and one credential counts.- A 404 is
found: false, never an answer. A malformed UUAID throwsUuaidErrorwith codeinvalid_uuaid. A 200 that is not the documented shape, or names another UUAID, throwsresponse_invalid. trustBadgeUrl(uuaid)is the unified badge:credentialed,key-proven,unverifiedorunresolved, always an image.parseTrustResponse(uuaid, status, body)applies the same rules to a response you fetched yourself.
Sign in with UUAID (auth.v1, relying party)
// 1. Start: a challenge bound to your origin. Keep session_binding in THIS session.
const c = await uuaid.authChallenge("https://rp.example");
if (!c.ok) throw new Error(`${c.code}: ${c.fix}`);
// Show c.challenge.code beside the QR. Build the uuaid://auth link with
// buildAuthDeepLink from @uuaid/pillar-client.
// 2. Callback: the phone POSTs {assertion, signature} to your cb.
const out = await uuaid.authVerify(
{ assertion, signature, session_binding: c.challenge.session_binding },
{ aud: "https://rp.example" },
);
if (out.ok) signIn(session, out.uuaid); // out.proof: "key-derived" | "registry-binding"
else console.log(out.code, out.fix); // e.g. nonce_consumed, session_binding_mismatch- Refusals are returned as
{ok: false, code, fix}, with codes from the auth.v1 table (AUTH_V1_REFUSAL_CODES).ok: trueis returned only for a 200 that is the documented success for exactly the assertion you sent. - This SDK is HTTP-only. To verify offline (no API call), use
@uuaid/pillar-client:createAuthChallenge+verifyAuthAssertion, with your own nonce store. Signing (signAuthAssertion) and the deep link (buildAuthDeepLink) are there too. Protocol:docs/AUTH-V1.md.
Directory
const page = await uuaid.searchDirectory({ q: "translation", limit: 20 });
for (const a of page.agents) console.log(a.uuaid, a.transport?.publicKey ?? "no transport");
const next = page.meta.nextCursor && await uuaid.searchDirectory({ q: "translation", cursor: page.meta.nextCursor });
const r = await uuaid.resolveDirectory("uuaid:foundation:agent:…"); // or resolveDirectoryName("aria")
if (r.found) console.log(r.body.publicKey); // the key derives r.body.uuaid- Every miss is
found: falsewithcode: "not_found". - The SDK checks that each returned key derives the address it is given for
(
pillarUuaidFromPublicKey), and throwsresponse_invalidotherwise. verificationin a search row is the directory's summary. For a decision, calltrust().
Registry ↔ key bindings
const res = await uuaid.submitBindings([{ binding, signature }]); // up to 100, scope agents:write
// res.results[i].status: "bound" | "updated" | "unchanged" | "refused" (+ code)binding is a uuaid.identity.binding.v1 (IdentityBinding), signed by the Pillar key it
names: Ed25519 over UTF-8("uuaid.identity.binding.v1\n" + JCS(binding)).
Errors
Every UuaidError has status, body, and a stable code with a one-line fix:
- the API's own
{code, fix}when it sends one; - else its snake_case
error(e.g.budget_exhausted); - else an SDK code (
UUAID_SDK_ERRORS):invalid_uuaid,response_invalid,unauthorized,forbidden,rate_limited,api_unavailable, …
Network failures and timeouts are thrown as fetch throws them.
The service stores ciphertext only; your memory's content hash is anchored on Polygon. Docs: api.uuaid.org/docs · Apache-2.0
