UNPKG

trellis

Version:

Agentic State Engine — event-sourced causal graph with branching, decision traces, and realtime sync for AI-native applications

166 lines (163 loc) 4.45 kB
import { __esm, __require } from "./chunk-2ESYSVXG.js"; // src/identity/identity.ts import { generateKeyPairSync, sign, verify, createPublicKey } from "crypto"; import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs"; import { join, dirname } from "path"; import { homedir } from "os"; function createIdentity(opts) { const { publicKey, privateKey } = generateKeyPairSync("ed25519"); const pubDer = publicKey.export({ type: "spki", format: "der" }); const privDer = privateKey.export({ type: "pkcs8", format: "der" }); const rawPub = pubDer.subarray(pubDer.length - 32); const did = deriveDid(rawPub); const entityId = `identity:${did}`; return { displayName: opts.displayName, email: opts.email, publicKey: pubDer.toString("base64"), privateKey: privDer.toString("base64"), did, entityId, createdAt: (/* @__PURE__ */ new Date()).toISOString() }; } function deriveDid(rawPublicKey) { const multicodec = Buffer.concat([ Buffer.from([237, 1]), Buffer.from(rawPublicKey) ]); const encoded = base58btcEncode(multicodec); return `did:key:z${encoded}`; } function signMessage(message, privateKeyBase64) { const privDer = Buffer.from(privateKeyBase64, "base64"); const privateKey = createPrivateKeyFromDer(privDer); const sig = sign(null, Buffer.from(message, "utf-8"), privateKey); return sig.toString("base64"); } function verifySignature(message, signatureBase64, publicKeyBase64) { const pubDer = Buffer.from(publicKeyBase64, "base64"); const publicKey = createPublicKey({ key: pubDer, format: "der", type: "spki" }); const sig = Buffer.from(signatureBase64, "base64"); return verify(null, Buffer.from(message, "utf-8"), publicKey, sig); } function saveIdentity(trellisDir, identity) { const filePath = join(trellisDir, IDENTITY_FILE); if (!existsSync(dirname(filePath))) { mkdirSync(dirname(filePath), { recursive: true }); } writeFileSync(filePath, JSON.stringify(identity, null, 2), "utf-8"); } function loadIdentity(trellisDir) { const filePath = join(trellisDir, IDENTITY_FILE); if (!existsSync(filePath)) return null; try { return JSON.parse(readFileSync(filePath, "utf-8")); } catch { return null; } } function hasIdentity(trellisDir) { return existsSync(join(trellisDir, IDENTITY_FILE)); } function toPublicIdentity(identity) { return { displayName: identity.displayName, email: identity.email, publicKey: identity.publicKey, did: identity.did, entityId: identity.entityId, createdAt: identity.createdAt }; } function personIdentityDir() { return join(homedir(), ".trellis"); } function personIdentityPath() { return join(personIdentityDir(), IDENTITY_FILE); } function savePersonIdentity(identity) { saveIdentity(personIdentityDir(), identity); } function loadPersonIdentity() { return loadIdentity(personIdentityDir()); } function hasPersonIdentity() { return existsSync(personIdentityPath()); } function ensurePersonIdentity(opts) { const existing = loadPersonIdentity(); if (existing) return existing; const identity = createIdentity({ displayName: opts?.displayName ?? "Anonymous", email: opts?.email }); savePersonIdentity(identity); return identity; } function resolveRepoIdentity(trellisDir) { return loadIdentity(trellisDir) ?? loadPersonIdentity(); } function createPrivateKeyFromDer(der) { const { createPrivateKey } = __require("crypto"); return createPrivateKey({ key: der, format: "der", type: "pkcs8" }); } function base58btcEncode(buf) { const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; let num = BigInt(0); for (const byte of buf) { num = num * 256n + BigInt(byte); } let encoded = ""; while (num > 0n) { const rem = Number(num % 58n); num = num / 58n; encoded = ALPHABET[rem] + encoded; } for (const byte of buf) { if (byte === 0) { encoded = "1" + encoded; } else { break; } } return encoded || "1"; } var IDENTITY_FILE; var init_identity = __esm({ "src/identity/identity.ts"() { "use strict"; IDENTITY_FILE = "identity.json"; } }); export { createIdentity, signMessage, verifySignature, saveIdentity, loadIdentity, hasIdentity, toPublicIdentity, savePersonIdentity, loadPersonIdentity, hasPersonIdentity, ensurePersonIdentity, resolveRepoIdentity, init_identity };