beam-protocol-sdk 0.3.0 → 0.5.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.
Files changed (49) hide show
  1. package/dist/bip39-wordlist.d.ts +2 -0
  2. package/dist/bip39-wordlist.d.ts.map +1 -0
  3. package/dist/bip39-wordlist.js +2052 -0
  4. package/dist/bip39-wordlist.js.map +1 -0
  5. package/dist/client.d.ts +80 -0
  6. package/dist/client.d.ts.map +1 -0
  7. package/dist/client.js +295 -0
  8. package/dist/client.js.map +1 -0
  9. package/dist/did.d.ts +85 -0
  10. package/dist/did.d.ts.map +1 -0
  11. package/dist/did.js +254 -0
  12. package/dist/did.js.map +1 -0
  13. package/dist/directory.d.ts +28 -0
  14. package/dist/directory.d.ts.map +1 -0
  15. package/dist/directory.js +215 -0
  16. package/dist/directory.js.map +1 -0
  17. package/dist/frames.d.ts +29 -0
  18. package/dist/frames.d.ts.map +1 -0
  19. package/dist/frames.js +133 -0
  20. package/dist/frames.js.map +1 -0
  21. package/dist/identity.d.ts +20 -0
  22. package/dist/identity.d.ts.map +1 -0
  23. package/dist/identity.js +81 -0
  24. package/dist/identity.js.map +1 -0
  25. package/dist/index.d.ts +9 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +7 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/key-management.d.ts +54 -0
  30. package/dist/key-management.d.ts.map +1 -0
  31. package/dist/key-management.js +172 -0
  32. package/dist/key-management.js.map +1 -0
  33. package/dist/types.d.ts +124 -0
  34. package/dist/types.d.ts.map +1 -0
  35. package/dist/types.js +2 -0
  36. package/dist/types.js.map +1 -0
  37. package/package.json +25 -5
  38. package/src/client.ts +0 -383
  39. package/src/directory.ts +0 -91
  40. package/src/frames.ts +0 -161
  41. package/src/identity.ts +0 -85
  42. package/src/index.ts +0 -25
  43. package/src/types.ts +0 -71
  44. package/tests/client.test.ts +0 -217
  45. package/tests/directory.test.ts +0 -202
  46. package/tests/frames.test.ts +0 -213
  47. package/tests/identity.test.ts +0 -130
  48. package/tsconfig.json +0 -19
  49. package/vitest.config.ts +0 -8
package/dist/frames.js ADDED
@@ -0,0 +1,133 @@
1
+ import { randomUUID, createPrivateKey, sign } from 'node:crypto';
2
+ import { BeamIdentity } from './identity.js';
3
+ export const MAX_FRAME_SIZE = 4 * 1024; // 4KB hard limit
4
+ export const REPLAY_WINDOW_MS = 5 * 60 * 1000; // 5 minutes
5
+ export function createIntentFrame(options, identity) {
6
+ const frame = {
7
+ v: '1',
8
+ intent: options.intent,
9
+ from: options.from,
10
+ to: options.to,
11
+ payload: options.payload ?? {},
12
+ nonce: randomUUID(),
13
+ timestamp: new Date().toISOString()
14
+ };
15
+ return signFrame(frame, identity.export().privateKeyBase64);
16
+ }
17
+ export function signFrame(frame, privateKeyBase64) {
18
+ const signedPayload = JSON.stringify({
19
+ type: 'intent',
20
+ from: frame.from,
21
+ to: frame.to,
22
+ intent: frame.intent,
23
+ payload: frame.payload,
24
+ timestamp: frame.timestamp,
25
+ nonce: frame.nonce,
26
+ });
27
+ const privateKey = createPrivateKey({
28
+ key: Buffer.from(privateKeyBase64, 'base64'),
29
+ format: 'der',
30
+ type: 'pkcs8',
31
+ });
32
+ frame.signature = sign(null, Buffer.from(signedPayload, 'utf8'), privateKey).toString('base64');
33
+ return frame;
34
+ }
35
+ export function createResultFrame(options, identity) {
36
+ const frame = {
37
+ v: '1',
38
+ success: options.success,
39
+ nonce: options.nonce,
40
+ timestamp: new Date().toISOString(),
41
+ ...(options.payload !== undefined && { payload: options.payload }),
42
+ ...(options.error !== undefined && { error: options.error }),
43
+ ...(options.errorCode !== undefined && { errorCode: options.errorCode }),
44
+ ...(options.latency !== undefined && { latency: options.latency })
45
+ };
46
+ frame.signature = identity.sign(canonicalizeFrame(frame));
47
+ return frame;
48
+ }
49
+ export function validateIntentFrame(frame, senderPublicKey) {
50
+ if (!frame || typeof frame !== 'object') {
51
+ return { valid: false, error: 'Frame must be an object' };
52
+ }
53
+ const f = frame;
54
+ if (f['v'] !== '1')
55
+ return { valid: false, error: 'Invalid protocol version' };
56
+ if (typeof f['intent'] !== 'string' || !f['intent'])
57
+ return { valid: false, error: 'Missing or empty intent' };
58
+ if (typeof f['from'] !== 'string' || !BeamIdentity.parseBeamId(f['from'])) {
59
+ return { valid: false, error: 'Invalid from Beam ID' };
60
+ }
61
+ if (typeof f['to'] !== 'string' || !BeamIdentity.parseBeamId(f['to'])) {
62
+ return { valid: false, error: 'Invalid to Beam ID' };
63
+ }
64
+ if (typeof f['nonce'] !== 'string' || !f['nonce'])
65
+ return { valid: false, error: 'Missing nonce' };
66
+ if (typeof f['timestamp'] !== 'string')
67
+ return { valid: false, error: 'Missing timestamp' };
68
+ if (!f['payload'] || typeof f['payload'] !== 'object' || Array.isArray(f['payload'])) {
69
+ return { valid: false, error: 'Payload must be an object' };
70
+ }
71
+ const size = Buffer.byteLength(JSON.stringify(frame), 'utf8');
72
+ if (size > MAX_FRAME_SIZE) {
73
+ return { valid: false, error: `Frame size ${size} exceeds limit of ${MAX_FRAME_SIZE} bytes` };
74
+ }
75
+ const frameTime = new Date(f['timestamp']).getTime();
76
+ if (isNaN(frameTime))
77
+ return { valid: false, error: 'Invalid timestamp format' };
78
+ if (Math.abs(Date.now() - frameTime) > REPLAY_WINDOW_MS) {
79
+ return { valid: false, error: 'Frame timestamp outside replay window (±5 minutes)' };
80
+ }
81
+ if (typeof f['signature'] !== 'string')
82
+ return { valid: false, error: 'Missing signature' };
83
+ const signedPayload = JSON.stringify({
84
+ type: 'intent',
85
+ from: f['from'],
86
+ to: f['to'],
87
+ intent: f['intent'],
88
+ payload: f['payload'],
89
+ timestamp: f['timestamp'],
90
+ nonce: f['nonce'],
91
+ });
92
+ if (!BeamIdentity.verify(signedPayload, f['signature'], senderPublicKey)) {
93
+ return { valid: false, error: 'Signature verification failed' };
94
+ }
95
+ return { valid: true };
96
+ }
97
+ export function validateResultFrame(frame, senderPublicKey) {
98
+ if (!frame || typeof frame !== 'object') {
99
+ return { valid: false, error: 'Frame must be an object' };
100
+ }
101
+ const f = frame;
102
+ if (f['v'] !== '1')
103
+ return { valid: false, error: 'Invalid protocol version' };
104
+ if (typeof f['success'] !== 'boolean')
105
+ return { valid: false, error: 'Missing success boolean' };
106
+ if (typeof f['nonce'] !== 'string' || !f['nonce'])
107
+ return { valid: false, error: 'Missing nonce' };
108
+ if (typeof f['timestamp'] !== 'string')
109
+ return { valid: false, error: 'Missing timestamp' };
110
+ if (typeof f['signature'] !== 'string')
111
+ return { valid: false, error: 'Missing signature' };
112
+ const { signature, ...unsigned } = f;
113
+ if (!BeamIdentity.verify(canonicalizeFrame(unsigned), signature, senderPublicKey)) {
114
+ return { valid: false, error: 'Signature verification failed' };
115
+ }
116
+ return { valid: true };
117
+ }
118
+ export function canonicalizeFrame(frame) {
119
+ return JSON.stringify(deepSortKeys(frame));
120
+ }
121
+ function deepSortKeys(value) {
122
+ if (Array.isArray(value))
123
+ return value.map(deepSortKeys);
124
+ if (value !== null && typeof value === 'object') {
125
+ const sorted = {};
126
+ for (const key of Object.keys(value).sort()) {
127
+ sorted[key] = deepSortKeys(value[key]);
128
+ }
129
+ return sorted;
130
+ }
131
+ return value;
132
+ }
133
+ //# sourceMappingURL=frames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frames.js","sourceRoot":"","sources":["../src/frames.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { BeamIdString, BeamIdentityConfig, BeamIdentityData } from './types.js';
2
+ export declare class BeamIdentity {
3
+ readonly beamId: BeamIdString;
4
+ readonly publicKeyBase64: string;
5
+ private readonly _privateKey;
6
+ private readonly _publicKey;
7
+ private constructor();
8
+ static generate(config: BeamIdentityConfig): BeamIdentity;
9
+ static fromData(data: BeamIdentityData): BeamIdentity;
10
+ export(): BeamIdentityData;
11
+ sign(data: string): string;
12
+ static verify(data: string, signatureBase64: string, publicKeyBase64: string): boolean;
13
+ static parseBeamId(beamId: string): {
14
+ agent: string;
15
+ org?: string;
16
+ kind: 'consumer' | 'organization';
17
+ } | null;
18
+ static generateNonce(): string;
19
+ }
20
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAMpF,qBAAa,YAAY;IACvB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAW;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAW;IAEtC,OAAO;IAOP,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY;IAezD,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY;IAcrD,MAAM,IAAI,gBAAgB;IAQ1B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAK1B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO;IAkBtF,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,GAAG,cAAc,CAAA;KAAE,GAAG,IAAI;IAc7G,MAAM,CAAC,aAAa,IAAI,MAAM;CAG/B"}
@@ -0,0 +1,81 @@
1
+ import { generateKeyPairSync, sign, verify, createPrivateKey, createPublicKey, randomUUID } from 'node:crypto';
2
+ const AGENT_RE = /^[a-z0-9_-]+$/;
3
+ const CONSUMER_BEAM_ID_RE = /^([a-z0-9_-]+)@beam\.directory$/;
4
+ const ORG_BEAM_ID_RE = /^([a-z0-9_-]+)@([a-z0-9_-]+)\.beam\.directory$/;
5
+ export class BeamIdentity {
6
+ beamId;
7
+ publicKeyBase64;
8
+ _privateKey;
9
+ _publicKey;
10
+ constructor(beamId, privateKey, publicKey) {
11
+ this.beamId = beamId;
12
+ this._privateKey = privateKey;
13
+ this._publicKey = publicKey;
14
+ this.publicKeyBase64 = publicKey.export({ type: 'spki', format: 'der' }).toString('base64');
15
+ }
16
+ static generate(config) {
17
+ if (!AGENT_RE.test(config.agentName)) {
18
+ throw new Error('agentName must match [a-z0-9_-]+');
19
+ }
20
+ if (config.orgName && !AGENT_RE.test(config.orgName)) {
21
+ throw new Error('orgName must match [a-z0-9_-]+');
22
+ }
23
+ const { privateKey, publicKey } = generateKeyPairSync('ed25519');
24
+ const beamId = config.orgName
25
+ ? `${config.agentName}@${config.orgName}.beam.directory`
26
+ : `${config.agentName}@beam.directory`;
27
+ return new BeamIdentity(beamId, privateKey, publicKey);
28
+ }
29
+ static fromData(data) {
30
+ const privateKey = createPrivateKey({
31
+ key: Buffer.from(data.privateKeyBase64, 'base64'),
32
+ format: 'der',
33
+ type: 'pkcs8'
34
+ });
35
+ const publicKey = createPublicKey({
36
+ key: Buffer.from(data.publicKeyBase64, 'base64'),
37
+ format: 'der',
38
+ type: 'spki'
39
+ });
40
+ return new BeamIdentity(data.beamId, privateKey, publicKey);
41
+ }
42
+ export() {
43
+ return {
44
+ beamId: this.beamId,
45
+ publicKeyBase64: this.publicKeyBase64,
46
+ privateKeyBase64: this._privateKey.export({ type: 'pkcs8', format: 'der' }).toString('base64')
47
+ };
48
+ }
49
+ sign(data) {
50
+ const signature = sign(null, Buffer.from(data, 'utf8'), this._privateKey);
51
+ return signature.toString('base64');
52
+ }
53
+ static verify(data, signatureBase64, publicKeyBase64) {
54
+ try {
55
+ const publicKey = createPublicKey({
56
+ key: Buffer.from(publicKeyBase64, 'base64'),
57
+ format: 'der',
58
+ type: 'spki'
59
+ });
60
+ return verify(null, Buffer.from(data, 'utf8'), publicKey, Buffer.from(signatureBase64, 'base64'));
61
+ }
62
+ catch {
63
+ return false;
64
+ }
65
+ }
66
+ static parseBeamId(beamId) {
67
+ const consumerMatch = beamId.match(CONSUMER_BEAM_ID_RE);
68
+ if (consumerMatch) {
69
+ return { agent: consumerMatch[1], kind: 'consumer' };
70
+ }
71
+ const orgMatch = beamId.match(ORG_BEAM_ID_RE);
72
+ if (orgMatch) {
73
+ return { agent: orgMatch[1], org: orgMatch[2], kind: 'organization' };
74
+ }
75
+ return null;
76
+ }
77
+ static generateNonce() {
78
+ return randomUUID();
79
+ }
80
+ }
81
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export { BeamIdentity } from './identity.js';
2
+ export { BeamDirectory, BeamDirectoryError } from './directory.js';
3
+ export { BeamClient, BeamThread } from './client.js';
4
+ export { BeamDID, BeamCredentialsClient, CredentialVerifier } from './did.js';
5
+ export { createIntentFrame, createResultFrame, signFrame, validateIntentFrame, validateResultFrame, canonicalizeFrame, MAX_FRAME_SIZE, REPLAY_WINDOW_MS } from './frames.js';
6
+ export type { AgentProfile, AgentRegistration, AgentRecord, AgentSearchQuery, BeamClientConfig, BeamIdentityConfig, BeamIdentityData, BeamIdString, BrowseFilters, BrowseResult, Delegation, DirectoryConfig, DirectoryStats, DomainVerification, IntentFrame, KeyRotationResult, Report, ResultFrame, VerificationTier, } from './types.js';
7
+ export type { DIDDocument, VerificationMethod, ServiceEndpoint, VerifiableCredential, CredentialSubject, Proof, } from './did.js';
8
+ export * from './key-management.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAC7E,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EACjB,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,UAAU,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,MAAM,EACN,WAAW,EACX,gBAAgB,GACjB,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,KAAK,GACN,MAAM,UAAU,CAAA;AACjB,cAAc,qBAAqB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { BeamIdentity } from './identity.js';
2
+ export { BeamDirectory, BeamDirectoryError } from './directory.js';
3
+ export { BeamClient, BeamThread } from './client.js';
4
+ export { BeamDID, BeamCredentialsClient, CredentialVerifier } from './did.js';
5
+ export { createIntentFrame, createResultFrame, signFrame, validateIntentFrame, validateResultFrame, canonicalizeFrame, MAX_FRAME_SIZE, REPLAY_WINDOW_MS } from './frames.js';
6
+ export * from './key-management.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAC7E,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EACjB,MAAM,aAAa,CAAA;AA8BpB,cAAc,qBAAqB,CAAA"}
@@ -0,0 +1,54 @@
1
+ export interface ExportedIdentity {
2
+ version: 1;
3
+ beamId: string;
4
+ publicKeyBase64: string;
5
+ /** Present only if not encrypted */
6
+ privateKeyBase64?: string;
7
+ /** Present only if encrypted */
8
+ encrypted?: {
9
+ ciphertext: string;
10
+ iv: string;
11
+ salt: string;
12
+ iterations: number;
13
+ };
14
+ }
15
+ export interface BeamIdentityData {
16
+ beamId: string;
17
+ publicKeyBase64: string;
18
+ privateKeyBase64: string;
19
+ }
20
+ /**
21
+ * Export a Beam identity as JSON. If password is provided, the private key
22
+ * is encrypted with AES-256-GCM (PBKDF2 key derivation).
23
+ */
24
+ export declare function exportIdentity(identity: BeamIdentityData, password?: string): Promise<string>;
25
+ /**
26
+ * Import a Beam identity from JSON. If the identity was encrypted,
27
+ * provide the same password used during export.
28
+ */
29
+ export declare function importIdentity(json: string, password?: string): Promise<BeamIdentityData>;
30
+ /**
31
+ * Extract the 32-byte Ed25519 seed from a private key and encode as
32
+ * a 12-word mnemonic. Only the first 128 bits (16 bytes) of the seed
33
+ * are encoded; remaining 16 bytes are derived via SHA-256 during recovery.
34
+ *
35
+ * NOTE: This is a simplified scheme (128-bit entropy → 12 words).
36
+ * The full 32-byte seed is NOT recoverable from just 12 words —
37
+ * we hash the 16-byte entropy to get the full seed deterministically.
38
+ */
39
+ export declare function generateRecoveryPhrase(identity: BeamIdentityData): string;
40
+ /**
41
+ * Recover a Beam identity from a 12-word recovery phrase.
42
+ * The entropy is expanded to a 32-byte seed via SHA-256.
43
+ */
44
+ export declare function recoverFromPhrase(phrase: string, beamId?: string): BeamIdentityData;
45
+ /**
46
+ * Generate a compact JSON string suitable for QR code encoding.
47
+ * Contains only the essential data to reconstruct the identity.
48
+ */
49
+ export declare function toQRData(identity: BeamIdentityData): string;
50
+ /**
51
+ * Parse a QR code data string back into a BeamIdentityData object.
52
+ */
53
+ export declare function fromQRData(data: string): BeamIdentityData;
54
+ //# sourceMappingURL=key-management.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-management.d.ts","sourceRoot":"","sources":["../src/key-management.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,CAAC,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;IACvB,oCAAoC;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gCAAgC;IAChC,SAAS,CAAC,EAAE;QACV,UAAU,EAAE,MAAM,CAAA;QAClB,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,UAAU,EAAE,MAAM,CAAA;KACnB,CAAA;CACF;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;CACzB;AA4BD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BnG;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA2B/F;AAID;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAsBzE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAuCnF;AAID;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAM3D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAOzD"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Consumer-friendly key management for Beam identities.
3
+ * Supports encrypted export/import, BIP-39 recovery phrases, and QR data.
4
+ */
5
+ import { createHash, generateKeyPairSync } from 'node:crypto';
6
+ import { BIP39_ENGLISH } from './bip39-wordlist.js';
7
+ // ─── Helpers ───────────────────────────────────────────────
8
+ const subtle = globalThis.crypto?.subtle;
9
+ async function deriveKey(password, salt) {
10
+ const enc = new TextEncoder();
11
+ const keyMaterial = await subtle.importKey('raw', enc.encode(password), 'PBKDF2', false, ['deriveKey']);
12
+ return subtle.deriveKey({ name: 'PBKDF2', salt, iterations: 600_000, hash: 'SHA-256' }, keyMaterial, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);
13
+ }
14
+ function toBase64(buf) {
15
+ return Buffer.from(buf).toString('base64');
16
+ }
17
+ function fromBase64(b64) {
18
+ return new Uint8Array(Buffer.from(b64, 'base64'));
19
+ }
20
+ // ─── Export / Import ───────────────────────────────────────
21
+ /**
22
+ * Export a Beam identity as JSON. If password is provided, the private key
23
+ * is encrypted with AES-256-GCM (PBKDF2 key derivation).
24
+ */
25
+ export async function exportIdentity(identity, password) {
26
+ if (!password) {
27
+ const doc = {
28
+ version: 1,
29
+ beamId: identity.beamId,
30
+ publicKeyBase64: identity.publicKeyBase64,
31
+ privateKeyBase64: identity.privateKeyBase64,
32
+ };
33
+ return JSON.stringify(doc, null, 2);
34
+ }
35
+ const salt = globalThis.crypto.getRandomValues(new Uint8Array(16));
36
+ const iv = globalThis.crypto.getRandomValues(new Uint8Array(12));
37
+ const key = await deriveKey(password, salt);
38
+ const plaintext = new TextEncoder().encode(identity.privateKeyBase64);
39
+ const ciphertext = await subtle.encrypt({ name: 'AES-GCM', iv }, key, plaintext);
40
+ const doc = {
41
+ version: 1,
42
+ beamId: identity.beamId,
43
+ publicKeyBase64: identity.publicKeyBase64,
44
+ encrypted: {
45
+ ciphertext: toBase64(ciphertext),
46
+ iv: toBase64(iv),
47
+ salt: toBase64(salt),
48
+ iterations: 600_000,
49
+ },
50
+ };
51
+ return JSON.stringify(doc, null, 2);
52
+ }
53
+ /**
54
+ * Import a Beam identity from JSON. If the identity was encrypted,
55
+ * provide the same password used during export.
56
+ */
57
+ export async function importIdentity(json, password) {
58
+ const doc = JSON.parse(json);
59
+ if (doc.privateKeyBase64 && !doc.encrypted) {
60
+ return {
61
+ beamId: doc.beamId,
62
+ publicKeyBase64: doc.publicKeyBase64,
63
+ privateKeyBase64: doc.privateKeyBase64,
64
+ };
65
+ }
66
+ if (!doc.encrypted)
67
+ throw new Error('Identity is encrypted but no encrypted block found');
68
+ if (!password)
69
+ throw new Error('Password required to decrypt identity');
70
+ const { ciphertext, iv, salt, iterations } = doc.encrypted;
71
+ const key = await deriveKey(password, fromBase64(salt));
72
+ const decrypted = await subtle.decrypt({ name: 'AES-GCM', iv: fromBase64(iv) }, key, fromBase64(ciphertext));
73
+ return {
74
+ beamId: doc.beamId,
75
+ publicKeyBase64: doc.publicKeyBase64,
76
+ privateKeyBase64: new TextDecoder().decode(decrypted),
77
+ };
78
+ }
79
+ // ─── Recovery Phrase (BIP-39 style) ────────────────────────
80
+ /**
81
+ * Extract the 32-byte Ed25519 seed from a private key and encode as
82
+ * a 12-word mnemonic. Only the first 128 bits (16 bytes) of the seed
83
+ * are encoded; remaining 16 bytes are derived via SHA-256 during recovery.
84
+ *
85
+ * NOTE: This is a simplified scheme (128-bit entropy → 12 words).
86
+ * The full 32-byte seed is NOT recoverable from just 12 words —
87
+ * we hash the 16-byte entropy to get the full seed deterministically.
88
+ */
89
+ export function generateRecoveryPhrase(identity) {
90
+ const privKeyDer = Buffer.from(identity.privateKeyBase64, 'base64');
91
+ // Ed25519 PKCS8 DER: last 32 bytes are the seed
92
+ const seed = privKeyDer.subarray(privKeyDer.length - 32);
93
+ // Take first 16 bytes (128 bits) → 12 words (11 bits each, 132 bits, 4 checksum)
94
+ const entropy = seed.subarray(0, 16);
95
+ const hash = createHash('sha256').update(entropy).digest();
96
+ const checksumBits = hash[0] >> 4; // 4 checksum bits for 128-bit entropy
97
+ // Build bit string
98
+ let bits = '';
99
+ for (const byte of entropy)
100
+ bits += byte.toString(2).padStart(8, '0');
101
+ bits += checksumBits.toString(2).padStart(4, '0');
102
+ const words = [];
103
+ for (let i = 0; i < 132; i += 11) {
104
+ const idx = parseInt(bits.slice(i, i + 11), 2);
105
+ words.push(BIP39_ENGLISH[idx]);
106
+ }
107
+ return words.join(' ');
108
+ }
109
+ /**
110
+ * Recover a Beam identity from a 12-word recovery phrase.
111
+ * The entropy is expanded to a 32-byte seed via SHA-256.
112
+ */
113
+ export function recoverFromPhrase(phrase, beamId) {
114
+ const words = phrase.trim().toLowerCase().split(/\s+/);
115
+ if (words.length !== 12)
116
+ throw new Error('Recovery phrase must be exactly 12 words');
117
+ // Words → 132 bits
118
+ let bits = '';
119
+ for (const word of words) {
120
+ const idx = BIP39_ENGLISH.indexOf(word);
121
+ if (idx === -1)
122
+ throw new Error(`Unknown word: ${word}`);
123
+ bits += idx.toString(2).padStart(11, '0');
124
+ }
125
+ // Extract 128-bit entropy (first 128 bits)
126
+ const entropyBits = bits.slice(0, 128);
127
+ const entropy = new Uint8Array(16);
128
+ for (let i = 0; i < 16; i++) {
129
+ entropy[i] = parseInt(entropyBits.slice(i * 8, i * 8 + 8), 2);
130
+ }
131
+ // Verify checksum
132
+ const hash = createHash('sha256').update(entropy).digest();
133
+ const expectedChecksum = (hash[0] >> 4).toString(2).padStart(4, '0');
134
+ const actualChecksum = bits.slice(128, 132);
135
+ if (expectedChecksum !== actualChecksum)
136
+ throw new Error('Invalid recovery phrase checksum');
137
+ // Expand entropy to 32-byte seed via SHA-256
138
+ const seed = createHash('sha256').update(entropy).digest();
139
+ // Create Ed25519 keypair from seed
140
+ const { privateKey, publicKey } = generateKeyPairSync('ed25519', { seed });
141
+ const privDer = privateKey.export({ format: 'der', type: 'pkcs8' });
142
+ const pubDer = publicKey.export({ format: 'der', type: 'spki' });
143
+ return {
144
+ beamId: beamId ?? `recovered-${Date.now()}@beam.directory`,
145
+ publicKeyBase64: Buffer.from(pubDer).toString('base64'),
146
+ privateKeyBase64: Buffer.from(privDer).toString('base64'),
147
+ };
148
+ }
149
+ // ─── QR Code Data ──────────────────────────────────────────
150
+ /**
151
+ * Generate a compact JSON string suitable for QR code encoding.
152
+ * Contains only the essential data to reconstruct the identity.
153
+ */
154
+ export function toQRData(identity) {
155
+ return JSON.stringify({
156
+ b: identity.beamId,
157
+ p: identity.publicKeyBase64,
158
+ s: identity.privateKeyBase64,
159
+ });
160
+ }
161
+ /**
162
+ * Parse a QR code data string back into a BeamIdentityData object.
163
+ */
164
+ export function fromQRData(data) {
165
+ const obj = JSON.parse(data);
166
+ return {
167
+ beamId: obj.b,
168
+ publicKeyBase64: obj.p,
169
+ privateKeyBase64: obj.s,
170
+ };
171
+ }
172
+ //# sourceMappingURL=key-management.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-management.js","sourceRoot":"","sources":["../src/key-management.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,124 @@
1
+ export type BeamIdString = `${string}@beam.directory` | `${string}@${string}.beam.directory`;
2
+ export type VerificationTier = 'basic' | 'verified' | 'business' | 'enterprise';
3
+ export interface BeamIdentityConfig {
4
+ agentName: string;
5
+ orgName?: string;
6
+ }
7
+ export interface BeamIdentityData {
8
+ beamId: BeamIdString;
9
+ publicKeyBase64: string;
10
+ privateKeyBase64: string;
11
+ }
12
+ export interface IntentFrame {
13
+ v: '1';
14
+ intent: string;
15
+ from: BeamIdString;
16
+ to: BeamIdString;
17
+ payload: Record<string, unknown>;
18
+ nonce: string;
19
+ timestamp: string;
20
+ signature?: string;
21
+ }
22
+ export interface ResultFrame {
23
+ v: '1';
24
+ success: boolean;
25
+ payload?: Record<string, unknown>;
26
+ error?: string;
27
+ errorCode?: string;
28
+ nonce: string;
29
+ timestamp: string;
30
+ latency?: number;
31
+ signature?: string;
32
+ }
33
+ export interface AgentRegistration {
34
+ beamId: BeamIdString;
35
+ displayName: string;
36
+ capabilities: string[];
37
+ publicKey: string;
38
+ org?: string;
39
+ }
40
+ export interface AgentRecord extends AgentRegistration {
41
+ did?: string;
42
+ trustScore: number;
43
+ verified: boolean;
44
+ createdAt: string;
45
+ lastSeen: string;
46
+ }
47
+ export interface AgentProfile extends AgentRecord {
48
+ description?: string;
49
+ logoUrl?: string;
50
+ website?: string;
51
+ verificationTier?: VerificationTier;
52
+ verificationStatus?: 'pending' | 'verified' | 'failed' | 'unverified';
53
+ domain?: string;
54
+ intentsHandled?: number;
55
+ }
56
+ export interface BrowseFilters {
57
+ capability?: string;
58
+ tier?: VerificationTier;
59
+ verified_only?: boolean;
60
+ }
61
+ export interface BrowseResult {
62
+ page: number;
63
+ pageSize: number;
64
+ total: number;
65
+ agents: AgentProfile[];
66
+ }
67
+ export interface DirectoryStats {
68
+ totalAgents: number;
69
+ verifiedAgents: number;
70
+ intentsProcessed: number;
71
+ consumerAgents?: number;
72
+ uptime?: number;
73
+ waitlistSize?: number;
74
+ version?: string;
75
+ }
76
+ export interface Delegation {
77
+ id?: string;
78
+ sourceBeamId: BeamIdString;
79
+ targetBeamId: BeamIdString;
80
+ scope: string;
81
+ expiresAt?: string;
82
+ createdAt?: string;
83
+ status?: string;
84
+ }
85
+ export interface Report {
86
+ id?: string;
87
+ reporterBeamId: BeamIdString;
88
+ targetBeamId: BeamIdString;
89
+ reason: string;
90
+ createdAt?: string;
91
+ status?: string;
92
+ }
93
+ export interface DomainVerification {
94
+ domain: string;
95
+ verified: boolean;
96
+ status?: string;
97
+ tier?: VerificationTier;
98
+ txtName?: string;
99
+ txtValue?: string;
100
+ expected?: string;
101
+ records?: string[];
102
+ checkedAt?: string;
103
+ }
104
+ export interface KeyRotationResult {
105
+ beamId: BeamIdString;
106
+ publicKey: string;
107
+ rotatedAt?: string;
108
+ previousKey?: string;
109
+ }
110
+ export interface DirectoryConfig {
111
+ baseUrl: string;
112
+ apiKey?: string;
113
+ }
114
+ export interface BeamClientConfig {
115
+ identity: BeamIdentityData;
116
+ directoryUrl: string;
117
+ }
118
+ export interface AgentSearchQuery {
119
+ org?: string;
120
+ capabilities?: string[];
121
+ minTrustScore?: number;
122
+ limit?: number;
123
+ }
124
+ //# sourceMappingURL=types.d.ts.map