kestrel.markets
Version:
A typed, token-efficient language + runtime for agentic trading: agents author bounded plans, the runtime fires them at the tick. CLI + typed library + MCP server.
42 lines (40 loc) • 1.57 kB
JavaScript
// src/cli/keypair.ts
var ED25519 = { name: "Ed25519" };
function subtle() {
const c = globalThis.crypto;
if (!c?.subtle) {
throw new Error("WebCrypto (crypto.subtle) unavailable — need node ≥18 or bun to use --keypair / JWT auth");
}
return c.subtle;
}
function b64url(bytes) {
return Buffer.from(bytes).toString("base64url");
}
async function generateAgentKeypair() {
const kp = await subtle().generateKey(ED25519, true, ["sign", "verify"]);
const priv = await subtle().exportKey("jwk", kp.privateKey);
const pub = await subtle().exportKey("jwk", kp.publicKey);
return {
publicJwk: { kty: "OKP", crv: "Ed25519", x: pub.x },
privateJwk: { kty: "OKP", crv: "Ed25519", x: priv.x, d: priv.d }
};
}
async function mintRequestJwt(input) {
const nowMs = input.now ?? Date.now();
const iat = Math.floor(nowMs / 1000);
const ttl = Math.min(Math.max(input.ttlSec ?? 120, 1), 300);
const claims = {
sub: input.subject,
aud: input.audience,
iat,
exp: iat + ttl,
jti: `jwt_${globalThis.crypto.randomUUID().replace(/-/g, "")}`
};
const key = await subtle().importKey("jwk", { ...input.privateJwk }, ED25519, false, ["sign"]);
const headerB64 = b64url(Buffer.from(JSON.stringify({ alg: "EdDSA", typ: "JWT" })));
const payloadB64 = b64url(Buffer.from(JSON.stringify(claims)));
const signingInput = `${headerB64}.${payloadB64}`;
const sig = await subtle().sign(ED25519, key, Buffer.from(signingInput));
return `${signingInput}.${b64url(new Uint8Array(sig))}`;
}
export { generateAgentKeypair, mintRequestJwt };