agentbnb 8.4.7 → 9.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -17
- package/dist/{card-BN643ZOY.js → card-6KL6L4GF.js} +2 -2
- package/dist/{card-HYTD2BJQ.js → card-NKQFB3HD.js} +3 -3
- package/dist/{chunk-UNXCKETK.js → chunk-27VHBFUP.js} +11 -9
- package/dist/{chunk-CFHCG5FE.js → chunk-2GWOFP24.js} +1 -1
- package/dist/{chunk-PQIP7EXY.js → chunk-3466S65P.js} +6 -2
- package/dist/{chunk-SME5LJTE.js → chunk-4FK45WJI.js} +4 -4
- package/dist/chunk-5CC6O6SO.js +152 -0
- package/dist/{chunk-MZSVVG55.js → chunk-5PV5YCSN.js} +1 -1
- package/dist/{chunk-5SIGMKOD.js → chunk-77HAL2ZL.js} +14 -5
- package/dist/{chunk-EKLVNIIY.js → chunk-AZEGOADG.js} +5 -5
- package/dist/{chunk-NQANA6WH.js → chunk-BNS76U6K.js} +2 -2
- package/dist/{chunk-JDAFLPR7.js → chunk-BOBND3QV.js} +5 -5
- package/dist/{chunk-VRPLSK34.js → chunk-D4IJQ3TK.js} +1 -1
- package/dist/{chunk-4NFJ3VYZ.js → chunk-DYJ7YGBM.js} +6 -2
- package/dist/{chunk-PIPCGRCR.js → chunk-ELFGYC22.js} +1 -1
- package/dist/{chunk-WTHMHNKC.js → chunk-J4RFJVXI.js} +1 -1
- package/dist/{chunk-IMLFBU3H.js → chunk-LLL3KYEM.js} +8 -8
- package/dist/{chunk-VAAEBCMU.js → chunk-N3TXLBGK.js} +2 -2
- package/dist/{chunk-COA2D7QM.js → chunk-NLQCHO7N.js} +2 -2
- package/dist/{chunk-WK2QSO4E.js → chunk-NZTLBAML.js} +7 -141
- package/dist/{chunk-HU46M4JA.js → chunk-P3FDT7G5.js} +4 -4
- package/dist/{chunk-ZU2TP7CN.js → chunk-PG3CLSAH.js} +1 -1
- package/dist/chunk-PMVHKTFG.js +199 -0
- package/dist/{chunk-OPRCWXD5.js → chunk-SLZBE2I5.js} +198 -5
- package/dist/{chunk-AZKVGC5T.js → chunk-TLT6F35V.js} +1 -1
- package/dist/{chunk-2PP5MQPD.js → chunk-UIPGGNRC.js} +4 -4
- package/dist/{chunk-NX27AFPA.js → chunk-UR3MISL2.js} +1 -1
- package/dist/{chunk-I7KWA7OB.js → chunk-UVCNMRPS.js} +4 -0
- package/dist/{chunk-RF4A5X5U.js → chunk-W5J3PEQ6.js} +6 -4
- package/dist/{chunk-YKMBFQC2.js → chunk-W6LOCBWQ.js} +2 -2
- package/dist/{chunk-U6LP4KWN.js → chunk-YDGXKH2T.js} +1 -1
- package/dist/{chunk-GIEJVKZZ.js → chunk-YNBZLXYS.js} +1 -1
- package/dist/cli/index.js +75 -61
- package/dist/{client-UQBGCIPA.js → client-YB3IYO3S.js} +3 -3
- package/dist/conduct-4NPMP4GL.js +25 -0
- package/dist/{conduct-TE4YAXKR.js → conduct-5FTKINWU.js} +16 -16
- package/dist/{conductor-mode-2F5OP7Q4.js → conductor-mode-NRSVP2AU.js} +157 -7
- package/dist/{conductor-mode-TLIQMU4A.js → conductor-mode-ZWC5BZUL.js} +167 -15
- package/dist/did-action-MQLDT4RF.js +50 -0
- package/dist/{execute-VRTABQ6F.js → execute-DNRNU3HM.js} +5 -5
- package/dist/execute-JTPFFEH6.js +20 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +405 -32
- package/dist/{openclaw-setup-5ZWWRVF3.js → openclaw-setup-HVEVSKXQ.js} +14 -13
- package/dist/{openclaw-skills-6ZWQJ5V6.js → openclaw-skills-QLC4D6DZ.js} +12 -2
- package/dist/{process-guard-TNSUNHSR.js → process-guard-QDBIOLY4.js} +1 -1
- package/dist/{publish-capability-GNH5FHKG.js → publish-capability-FOCHYNYE.js} +4 -4
- package/dist/{reliability-metrics-G7LPUYJD.js → reliability-metrics-JSOY3PNW.js} +1 -1
- package/dist/{reliability-metrics-RRUKJ4ME.js → reliability-metrics-KKUFFVB6.js} +3 -3
- package/dist/{request-XWEOIVB3.js → request-WX3VLXBT.js} +14 -14
- package/dist/{serve-skill-UD7TLSRN.js → serve-skill-C7JU24CF.js} +14 -13
- package/dist/{server-XWTGBJHV.js → server-F4WXNK5B.js} +15 -13
- package/dist/{service-coordinator-RN7GOLLC.js → service-coordinator-2NFUCXYX.js} +197 -27
- package/dist/skills/agentbnb/bootstrap.js +186 -20
- package/dist/{store-4Z446745.js → store-S22F3I7G.js} +3 -3
- package/dist/vc-action-SUD7TMN2.js +75 -0
- package/dist/websocket-client-5CRE36Z5.js +7 -0
- package/dist/{websocket-client-SNDF3B6N.js → websocket-client-WHEHIYIZ.js} +1 -1
- package/package.json +1 -1
- package/skills/agentbnb/SKILL.md +46 -1
- package/dist/conduct-2RD45QKB.js +0 -25
- package/dist/execute-6EJSVBFB.js +0 -19
- package/dist/websocket-client-3U27WJUU.js +0 -7
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createPendingRequest
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5PV5YCSN.js";
|
|
4
4
|
import {
|
|
5
5
|
getAutonomyTier,
|
|
6
6
|
insertAuditEvent
|
|
7
7
|
} from "./chunk-G5WKW3ED.js";
|
|
8
8
|
import {
|
|
9
9
|
resolveTargetCapability
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-UIPGGNRC.js";
|
|
11
11
|
import {
|
|
12
12
|
fetchRemoteCards
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-ELFGYC22.js";
|
|
14
14
|
import {
|
|
15
15
|
holdEscrow,
|
|
16
16
|
releaseEscrow,
|
|
17
17
|
searchCards,
|
|
18
18
|
settleEscrow
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-P3FDT7G5.js";
|
|
20
20
|
import {
|
|
21
21
|
RelayClient
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-UR3MISL2.js";
|
|
23
23
|
import {
|
|
24
24
|
requestCapability,
|
|
25
25
|
requestViaRelay
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-W6LOCBWQ.js";
|
|
27
27
|
import {
|
|
28
28
|
findPeer
|
|
29
29
|
} from "./chunk-3YQ73ZM6.js";
|
|
30
30
|
import {
|
|
31
31
|
resolveCanonicalIdentity
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-J4RFJVXI.js";
|
|
33
33
|
import {
|
|
34
34
|
AgentBnBError
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-UVCNMRPS.js";
|
|
36
36
|
|
|
37
37
|
// src/gateway/relay-dispatch.ts
|
|
38
38
|
import { randomUUID } from "crypto";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
insertCard
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NLQCHO7N.js";
|
|
4
4
|
import {
|
|
5
5
|
CapabilityCardSchema
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-UVCNMRPS.js";
|
|
7
7
|
|
|
8
8
|
// src/skills/publish-capability.ts
|
|
9
9
|
import { randomUUID } from "crypto";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureAgentsTable,
|
|
3
3
|
resolveCanonicalIdentity
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-J4RFJVXI.js";
|
|
5
5
|
import {
|
|
6
6
|
AgentBnBError,
|
|
7
7
|
AnyCardSchema,
|
|
8
8
|
CapabilityCardSchema
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-UVCNMRPS.js";
|
|
10
10
|
|
|
11
11
|
// src/registry/store.ts
|
|
12
12
|
import Database from "better-sqlite3";
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
deriveAgentId
|
|
3
|
+
} from "./chunk-5CC6O6SO.js";
|
|
1
4
|
import {
|
|
2
5
|
bootstrapAgent,
|
|
3
6
|
getBalance,
|
|
@@ -7,151 +10,17 @@ import {
|
|
|
7
10
|
openCreditDb,
|
|
8
11
|
releaseEscrow,
|
|
9
12
|
settleEscrow
|
|
10
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-P3FDT7G5.js";
|
|
11
14
|
import {
|
|
12
|
-
generateKeyPair,
|
|
13
|
-
loadKeyPair,
|
|
14
|
-
saveKeyPair,
|
|
15
15
|
signEscrowReceipt,
|
|
16
16
|
verifyEscrowReceipt
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-YNBZLXYS.js";
|
|
18
18
|
import {
|
|
19
19
|
lookupAgent
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-J4RFJVXI.js";
|
|
21
21
|
import {
|
|
22
22
|
AgentBnBError
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
|
|
25
|
-
// src/identity/identity.ts
|
|
26
|
-
import { z } from "zod";
|
|
27
|
-
import { createHash, createPrivateKey, createPublicKey } from "crypto";
|
|
28
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
29
|
-
import { join } from "path";
|
|
30
|
-
var AgentIdentitySchema = z.object({
|
|
31
|
-
/** Deterministic ID derived from public key: sha256(hex).slice(0, 16). */
|
|
32
|
-
agent_id: z.string().min(1),
|
|
33
|
-
/** Human-readable owner name (from config or init). */
|
|
34
|
-
owner: z.string().min(1),
|
|
35
|
-
/** Hex-encoded Ed25519 public key. */
|
|
36
|
-
public_key: z.string().min(1),
|
|
37
|
-
/** ISO 8601 timestamp of identity creation. */
|
|
38
|
-
created_at: z.string().datetime(),
|
|
39
|
-
/** Optional guarantor info if linked to a human. */
|
|
40
|
-
guarantor: z.object({
|
|
41
|
-
github_login: z.string().min(1),
|
|
42
|
-
verified_at: z.string().datetime()
|
|
43
|
-
}).optional()
|
|
44
|
-
});
|
|
45
|
-
var AgentCertificateSchema = z.object({
|
|
46
|
-
identity: AgentIdentitySchema,
|
|
47
|
-
/** ISO 8601 timestamp of certificate issuance. */
|
|
48
|
-
issued_at: z.string().datetime(),
|
|
49
|
-
/** ISO 8601 timestamp of certificate expiry. */
|
|
50
|
-
expires_at: z.string().datetime(),
|
|
51
|
-
/** Hex-encoded public key of the issuer (same as identity for self-signed). */
|
|
52
|
-
issuer_public_key: z.string().min(1),
|
|
53
|
-
/** Base64url Ed25519 signature over { identity, issued_at, expires_at, issuer_public_key }. */
|
|
54
|
-
signature: z.string().min(1)
|
|
55
|
-
});
|
|
56
|
-
var IDENTITY_FILENAME = "identity.json";
|
|
57
|
-
var PRIVATE_KEY_FILENAME = "private.key";
|
|
58
|
-
var PUBLIC_KEY_FILENAME = "public.key";
|
|
59
|
-
function derivePublicKeyFromPrivate(privateKey) {
|
|
60
|
-
const privateKeyObject = createPrivateKey({ key: privateKey, format: "der", type: "pkcs8" });
|
|
61
|
-
const publicKeyObject = createPublicKey(privateKeyObject);
|
|
62
|
-
const publicKey = publicKeyObject.export({ format: "der", type: "spki" });
|
|
63
|
-
return Buffer.from(publicKey);
|
|
64
|
-
}
|
|
65
|
-
function buildIdentityFromPublicKey(publicKey, owner, createdAt) {
|
|
66
|
-
const publicKeyHex = publicKey.toString("hex");
|
|
67
|
-
return {
|
|
68
|
-
agent_id: deriveAgentId(publicKeyHex),
|
|
69
|
-
owner,
|
|
70
|
-
public_key: publicKeyHex,
|
|
71
|
-
created_at: createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
function generateFreshIdentity(configDir, owner) {
|
|
75
|
-
const keys = generateKeyPair();
|
|
76
|
-
saveKeyPair(configDir, keys);
|
|
77
|
-
const identity = buildIdentityFromPublicKey(keys.publicKey, owner);
|
|
78
|
-
saveIdentity(configDir, identity);
|
|
79
|
-
return { identity, keys, status: "generated" };
|
|
80
|
-
}
|
|
81
|
-
function deriveAgentId(publicKeyHex) {
|
|
82
|
-
return createHash("sha256").update(publicKeyHex, "hex").digest("hex").slice(0, 16);
|
|
83
|
-
}
|
|
84
|
-
function loadIdentity(configDir) {
|
|
85
|
-
const filePath = join(configDir, IDENTITY_FILENAME);
|
|
86
|
-
if (!existsSync(filePath)) return null;
|
|
87
|
-
try {
|
|
88
|
-
const raw = readFileSync(filePath, "utf-8");
|
|
89
|
-
return AgentIdentitySchema.parse(JSON.parse(raw));
|
|
90
|
-
} catch {
|
|
91
|
-
return null;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
function saveIdentity(configDir, identity) {
|
|
95
|
-
if (!existsSync(configDir)) {
|
|
96
|
-
mkdirSync(configDir, { recursive: true });
|
|
97
|
-
}
|
|
98
|
-
const filePath = join(configDir, IDENTITY_FILENAME);
|
|
99
|
-
writeFileSync(filePath, JSON.stringify(identity, null, 2), "utf-8");
|
|
100
|
-
}
|
|
101
|
-
function loadOrRepairIdentity(configDir, ownerHint) {
|
|
102
|
-
if (!existsSync(configDir)) {
|
|
103
|
-
mkdirSync(configDir, { recursive: true });
|
|
104
|
-
}
|
|
105
|
-
const identityPath = join(configDir, IDENTITY_FILENAME);
|
|
106
|
-
const privateKeyPath = join(configDir, PRIVATE_KEY_FILENAME);
|
|
107
|
-
const publicKeyPath = join(configDir, PUBLIC_KEY_FILENAME);
|
|
108
|
-
const hasIdentity = existsSync(identityPath);
|
|
109
|
-
const hasPrivateKey = existsSync(privateKeyPath);
|
|
110
|
-
const hasPublicKey = existsSync(publicKeyPath);
|
|
111
|
-
if (!hasIdentity || !hasPrivateKey || !hasPublicKey) {
|
|
112
|
-
return generateFreshIdentity(configDir, ownerHint ?? "agent");
|
|
113
|
-
}
|
|
114
|
-
let keys;
|
|
115
|
-
try {
|
|
116
|
-
keys = loadKeyPair(configDir);
|
|
117
|
-
} catch {
|
|
118
|
-
return generateFreshIdentity(configDir, ownerHint ?? "agent");
|
|
119
|
-
}
|
|
120
|
-
let derivedPublicKey;
|
|
121
|
-
try {
|
|
122
|
-
derivedPublicKey = derivePublicKeyFromPrivate(keys.privateKey);
|
|
123
|
-
} catch {
|
|
124
|
-
return generateFreshIdentity(configDir, ownerHint ?? "agent");
|
|
125
|
-
}
|
|
126
|
-
let keypairRepaired = false;
|
|
127
|
-
if (!keys.publicKey.equals(derivedPublicKey)) {
|
|
128
|
-
keypairRepaired = true;
|
|
129
|
-
keys = { privateKey: keys.privateKey, publicKey: derivedPublicKey };
|
|
130
|
-
saveKeyPair(configDir, keys);
|
|
131
|
-
}
|
|
132
|
-
const loadedIdentity = loadIdentity(configDir);
|
|
133
|
-
const expectedAgentId = deriveAgentId(derivedPublicKey.toString("hex"));
|
|
134
|
-
const expectedPublicKeyHex = derivedPublicKey.toString("hex");
|
|
135
|
-
const identityMismatch = !loadedIdentity || loadedIdentity.public_key !== expectedPublicKeyHex || loadedIdentity.agent_id !== expectedAgentId;
|
|
136
|
-
if (identityMismatch) {
|
|
137
|
-
const repairedIdentity = buildIdentityFromPublicKey(
|
|
138
|
-
derivedPublicKey,
|
|
139
|
-
loadedIdentity?.owner ?? ownerHint ?? "agent",
|
|
140
|
-
loadedIdentity?.created_at
|
|
141
|
-
);
|
|
142
|
-
saveIdentity(configDir, repairedIdentity);
|
|
143
|
-
return { identity: repairedIdentity, keys, status: "repaired" };
|
|
144
|
-
}
|
|
145
|
-
if (ownerHint && loadedIdentity.owner !== ownerHint) {
|
|
146
|
-
const updatedIdentity = { ...loadedIdentity, owner: ownerHint };
|
|
147
|
-
saveIdentity(configDir, updatedIdentity);
|
|
148
|
-
return { identity: updatedIdentity, keys, status: "repaired" };
|
|
149
|
-
}
|
|
150
|
-
return { identity: loadedIdentity, keys, status: keypairRepaired ? "repaired" : "existing" };
|
|
151
|
-
}
|
|
152
|
-
function ensureIdentity(configDir, owner) {
|
|
153
|
-
return loadOrRepairIdentity(configDir, owner).identity;
|
|
154
|
-
}
|
|
23
|
+
} from "./chunk-UVCNMRPS.js";
|
|
155
24
|
|
|
156
25
|
// src/credit/local-credit-ledger.ts
|
|
157
26
|
var LocalCreditLedger = class {
|
|
@@ -583,9 +452,6 @@ function createLedger(opts) {
|
|
|
583
452
|
}
|
|
584
453
|
|
|
585
454
|
export {
|
|
586
|
-
deriveAgentId,
|
|
587
|
-
loadOrRepairIdentity,
|
|
588
|
-
ensureIdentity,
|
|
589
455
|
identityAuthPlugin,
|
|
590
456
|
createLedger
|
|
591
457
|
};
|
|
@@ -3,16 +3,16 @@ import {
|
|
|
3
3
|
ensureReliabilityTable,
|
|
4
4
|
migrateCreditOwnerData,
|
|
5
5
|
recordSuccessfulHire
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-YDGXKH2T.js";
|
|
7
7
|
import {
|
|
8
8
|
getFeedbackForProvider
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-NLQCHO7N.js";
|
|
10
10
|
import {
|
|
11
11
|
ensureAgentsTable
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-J4RFJVXI.js";
|
|
13
13
|
import {
|
|
14
14
|
AgentBnBError
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-UVCNMRPS.js";
|
|
16
16
|
|
|
17
17
|
// src/credit/ledger.ts
|
|
18
18
|
import Database from "better-sqlite3";
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentBnBError
|
|
3
|
+
} from "./chunk-UVCNMRPS.js";
|
|
4
|
+
|
|
5
|
+
// src/auth/ucan.ts
|
|
6
|
+
import { randomUUID } from "crypto";
|
|
7
|
+
import { sign, verify, createPrivateKey, createPublicKey } from "crypto";
|
|
8
|
+
|
|
9
|
+
// src/auth/canonical-json.ts
|
|
10
|
+
function escapeString(s) {
|
|
11
|
+
let result = '"';
|
|
12
|
+
for (let i = 0; i < s.length; i++) {
|
|
13
|
+
const ch = s.charCodeAt(i);
|
|
14
|
+
if (ch === 8) {
|
|
15
|
+
result += "\\b";
|
|
16
|
+
} else if (ch === 9) {
|
|
17
|
+
result += "\\t";
|
|
18
|
+
} else if (ch === 10) {
|
|
19
|
+
result += "\\n";
|
|
20
|
+
} else if (ch === 12) {
|
|
21
|
+
result += "\\f";
|
|
22
|
+
} else if (ch === 13) {
|
|
23
|
+
result += "\\r";
|
|
24
|
+
} else if (ch === 34) {
|
|
25
|
+
result += '\\"';
|
|
26
|
+
} else if (ch === 92) {
|
|
27
|
+
result += "\\\\";
|
|
28
|
+
} else if (ch < 32) {
|
|
29
|
+
result += "\\u" + ch.toString(16).padStart(4, "0");
|
|
30
|
+
} else {
|
|
31
|
+
result += s[i];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
result += '"';
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
function serializeNumber(n) {
|
|
38
|
+
if (!Number.isFinite(n)) {
|
|
39
|
+
throw new AgentBnBError(
|
|
40
|
+
`Cannot canonicalize non-finite number: ${String(n)}`,
|
|
41
|
+
"CANONICAL_JSON_ERROR"
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
if (Object.is(n, -0)) {
|
|
45
|
+
return "0";
|
|
46
|
+
}
|
|
47
|
+
return JSON.stringify(n);
|
|
48
|
+
}
|
|
49
|
+
function canonicalize(value) {
|
|
50
|
+
return serializeValue(value);
|
|
51
|
+
}
|
|
52
|
+
function serializeValue(value) {
|
|
53
|
+
if (value === null) {
|
|
54
|
+
return "null";
|
|
55
|
+
}
|
|
56
|
+
switch (typeof value) {
|
|
57
|
+
case "boolean":
|
|
58
|
+
return value ? "true" : "false";
|
|
59
|
+
case "number":
|
|
60
|
+
return serializeNumber(value);
|
|
61
|
+
case "string":
|
|
62
|
+
return escapeString(value);
|
|
63
|
+
case "bigint":
|
|
64
|
+
throw new AgentBnBError(
|
|
65
|
+
"Cannot canonicalize BigInt values",
|
|
66
|
+
"CANONICAL_JSON_ERROR"
|
|
67
|
+
);
|
|
68
|
+
case "symbol":
|
|
69
|
+
throw new AgentBnBError(
|
|
70
|
+
"Cannot canonicalize Symbol values",
|
|
71
|
+
"CANONICAL_JSON_ERROR"
|
|
72
|
+
);
|
|
73
|
+
case "function":
|
|
74
|
+
throw new AgentBnBError(
|
|
75
|
+
"Cannot canonicalize function values",
|
|
76
|
+
"CANONICAL_JSON_ERROR"
|
|
77
|
+
);
|
|
78
|
+
case "undefined":
|
|
79
|
+
throw new AgentBnBError(
|
|
80
|
+
"Cannot canonicalize undefined at top level",
|
|
81
|
+
"CANONICAL_JSON_ERROR"
|
|
82
|
+
);
|
|
83
|
+
case "object": {
|
|
84
|
+
if (Array.isArray(value)) {
|
|
85
|
+
return serializeArray(value);
|
|
86
|
+
}
|
|
87
|
+
return serializeObject(value);
|
|
88
|
+
}
|
|
89
|
+
default:
|
|
90
|
+
throw new AgentBnBError(
|
|
91
|
+
`Cannot canonicalize unknown type: ${typeof value}`,
|
|
92
|
+
"CANONICAL_JSON_ERROR"
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function serializeArray(arr) {
|
|
97
|
+
const elements = arr.map((item) => serializeValue(item));
|
|
98
|
+
return "[" + elements.join(",") + "]";
|
|
99
|
+
}
|
|
100
|
+
function serializeObject(obj) {
|
|
101
|
+
const keys = Object.keys(obj).sort();
|
|
102
|
+
const entries = [];
|
|
103
|
+
for (const key of keys) {
|
|
104
|
+
const val = obj[key];
|
|
105
|
+
if (val === void 0) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
entries.push(escapeString(key) + ":" + serializeValue(val));
|
|
109
|
+
}
|
|
110
|
+
return "{" + entries.join(",") + "}";
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// src/auth/ucan.ts
|
|
114
|
+
var UCAN_HEADER = {
|
|
115
|
+
alg: "EdDSA",
|
|
116
|
+
typ: "JWT",
|
|
117
|
+
ucv: "0.10.0"
|
|
118
|
+
};
|
|
119
|
+
function toBase64Url(data) {
|
|
120
|
+
const buf = typeof data === "string" ? Buffer.from(data, "utf-8") : data;
|
|
121
|
+
return buf.toString("base64url");
|
|
122
|
+
}
|
|
123
|
+
function fromBase64Url(encoded) {
|
|
124
|
+
return Buffer.from(encoded, "base64url").toString("utf-8");
|
|
125
|
+
}
|
|
126
|
+
function createUCAN(opts) {
|
|
127
|
+
const payload = {
|
|
128
|
+
iss: opts.issuerDid,
|
|
129
|
+
aud: opts.audienceDid,
|
|
130
|
+
exp: opts.expiresAt,
|
|
131
|
+
nnc: randomUUID(),
|
|
132
|
+
att: opts.attenuations,
|
|
133
|
+
prf: opts.proofs ?? []
|
|
134
|
+
};
|
|
135
|
+
if (opts.notBefore !== void 0) {
|
|
136
|
+
payload.nbf = opts.notBefore;
|
|
137
|
+
}
|
|
138
|
+
if (opts.facts !== void 0) {
|
|
139
|
+
payload.fct = opts.facts;
|
|
140
|
+
}
|
|
141
|
+
const headerEncoded = toBase64Url(canonicalize(UCAN_HEADER));
|
|
142
|
+
const payloadEncoded = toBase64Url(canonicalize(payload));
|
|
143
|
+
const signingInput = `${headerEncoded}.${payloadEncoded}`;
|
|
144
|
+
const keyObject = createPrivateKey({ key: opts.signerKey, format: "der", type: "pkcs8" });
|
|
145
|
+
const sig = sign(null, Buffer.from(signingInput, "utf-8"), keyObject);
|
|
146
|
+
const signatureEncoded = sig.toString("base64url");
|
|
147
|
+
return `${signingInput}.${signatureEncoded}`;
|
|
148
|
+
}
|
|
149
|
+
function verifyUCAN(token, issuerPublicKey) {
|
|
150
|
+
try {
|
|
151
|
+
const parts = token.split(".");
|
|
152
|
+
if (parts.length !== 3) {
|
|
153
|
+
return { valid: false, reason: "Invalid token format: expected 3 parts" };
|
|
154
|
+
}
|
|
155
|
+
const signingInput = `${parts[0]}.${parts[1]}`;
|
|
156
|
+
const signatureBuffer = Buffer.from(parts[2], "base64url");
|
|
157
|
+
const keyObject = createPublicKey({ key: issuerPublicKey, format: "der", type: "spki" });
|
|
158
|
+
const isValid = verify(null, Buffer.from(signingInput, "utf-8"), keyObject, signatureBuffer);
|
|
159
|
+
if (!isValid) {
|
|
160
|
+
return { valid: false, reason: "Signature verification failed" };
|
|
161
|
+
}
|
|
162
|
+
return { valid: true };
|
|
163
|
+
} catch (err) {
|
|
164
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
165
|
+
return { valid: false, reason: `Verification error: ${message}` };
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function decodeUCAN(token) {
|
|
169
|
+
const parts = token.split(".");
|
|
170
|
+
if (parts.length !== 3) {
|
|
171
|
+
throw new AgentBnBError(
|
|
172
|
+
`Invalid UCAN token format: expected 3 dot-separated parts, got ${parts.length}`,
|
|
173
|
+
"UCAN_INVALID"
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
let header;
|
|
177
|
+
let payload;
|
|
178
|
+
try {
|
|
179
|
+
header = JSON.parse(fromBase64Url(parts[0]));
|
|
180
|
+
} catch {
|
|
181
|
+
throw new AgentBnBError("Invalid UCAN token: failed to decode header", "UCAN_INVALID");
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
payload = JSON.parse(fromBase64Url(parts[1]));
|
|
185
|
+
} catch {
|
|
186
|
+
throw new AgentBnBError("Invalid UCAN token: failed to decode payload", "UCAN_INVALID");
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
header,
|
|
190
|
+
payload,
|
|
191
|
+
signature: parts[2]
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export {
|
|
196
|
+
createUCAN,
|
|
197
|
+
verifyUCAN,
|
|
198
|
+
decodeUCAN
|
|
199
|
+
};
|