@private.me/xbind 1.2.0
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/AGENTS.md +778 -0
- package/LICENSE.md +27 -0
- package/README.md +400 -0
- package/dist-standalone/_deps/crypto/base64.d.ts +29 -0
- package/dist-standalone/_deps/crypto/base64.js +97 -0
- package/dist-standalone/_deps/crypto/cjs/base64.js +103 -0
- package/dist-standalone/_deps/crypto/cjs/errors.js +119 -0
- package/dist-standalone/_deps/crypto/cjs/hmac.js +71 -0
- package/dist-standalone/_deps/crypto/cjs/index.js +86 -0
- package/dist-standalone/_deps/crypto/cjs/padding.js +57 -0
- package/dist-standalone/_deps/crypto/cjs/share-header.js +68 -0
- package/dist-standalone/_deps/crypto/cjs/shares.js +152 -0
- package/dist-standalone/_deps/crypto/cjs/tlv.js +199 -0
- package/dist-standalone/_deps/crypto/cjs/uuid.js +61 -0
- package/dist-standalone/_deps/crypto/cjs/verify.js +24 -0
- package/dist-standalone/_deps/crypto/cjs/xorida.js +221 -0
- package/dist-standalone/_deps/crypto/errors.d.ts +51 -0
- package/dist-standalone/_deps/crypto/errors.js +109 -0
- package/dist-standalone/_deps/crypto/hmac.d.ts +39 -0
- package/dist-standalone/_deps/crypto/hmac.js +66 -0
- package/dist-standalone/_deps/crypto/index.d.ts +20 -0
- package/dist-standalone/_deps/crypto/index.js +45 -0
- package/dist-standalone/_deps/crypto/padding.d.ts +19 -0
- package/dist-standalone/_deps/crypto/padding.js +53 -0
- package/dist-standalone/_deps/crypto/share-header.d.ts +44 -0
- package/dist-standalone/_deps/crypto/share-header.js +63 -0
- package/dist-standalone/_deps/crypto/shares.d.ts +27 -0
- package/dist-standalone/_deps/crypto/shares.js +148 -0
- package/dist-standalone/_deps/crypto/tlv.d.ts +26 -0
- package/dist-standalone/_deps/crypto/tlv.js +195 -0
- package/dist-standalone/_deps/crypto/uuid.d.ts +22 -0
- package/dist-standalone/_deps/crypto/uuid.js +56 -0
- package/dist-standalone/_deps/crypto/verify.d.ts +15 -0
- package/dist-standalone/_deps/crypto/verify.js +15 -0
- package/dist-standalone/_deps/crypto/xorida.d.ts +44 -0
- package/dist-standalone/_deps/crypto/xorida.js +215 -0
- package/dist-standalone/_deps/mldsa-wasm/LICENSE +24 -0
- package/dist-standalone/_deps/mldsa-wasm/dist/mldsa.js +1920 -0
- package/dist-standalone/_deps/mldsa-wasm/package.json +46 -0
- package/dist-standalone/_deps/mldsa-wasm/types/mldsa.d.ts +30 -0
- package/dist-standalone/_deps/shared/cjs/errors.js +582 -0
- package/dist-standalone/_deps/shared/cjs/index.js +492 -0
- package/dist-standalone/_deps/shared/cjs/package.json +1 -0
- package/dist-standalone/_deps/shared/cjs/types.js +403 -0
- package/dist-standalone/_deps/shared/errors.d.ts +48 -0
- package/dist-standalone/_deps/shared/errors.d.ts.map +1 -0
- package/dist-standalone/_deps/shared/errors.js +192 -0
- package/dist-standalone/_deps/shared/errors.js.map +1 -0
- package/dist-standalone/_deps/shared/index.d.ts +4 -0
- package/dist-standalone/_deps/shared/index.d.ts.map +1 -0
- package/dist-standalone/_deps/shared/index.js +78 -0
- package/dist-standalone/_deps/shared/index.js.map +1 -0
- package/dist-standalone/_deps/shared/types.d.ts +1097 -0
- package/dist-standalone/_deps/shared/types.d.ts.map +1 -0
- package/dist-standalone/_deps/shared/types.js +89 -0
- package/dist-standalone/_deps/shared/types.js.map +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/errors.d.ts +115 -0
- package/dist-standalone/_deps/ux-helpers/cjs/errors.d.ts.map +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/errors.js +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/errors.js.map +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/index.d.ts +13 -0
- package/dist-standalone/_deps/ux-helpers/cjs/index.d.ts.map +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/index.js +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/index.js.map +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/package.json +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/pagination.d.ts +39 -0
- package/dist-standalone/_deps/ux-helpers/cjs/pagination.d.ts.map +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/pagination.js +83 -0
- package/dist-standalone/_deps/ux-helpers/cjs/pagination.js.map +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/progress.d.ts +99 -0
- package/dist-standalone/_deps/ux-helpers/cjs/progress.d.ts.map +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/progress.js +143 -0
- package/dist-standalone/_deps/ux-helpers/cjs/progress.js.map +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/search.d.ts +32 -0
- package/dist-standalone/_deps/ux-helpers/cjs/search.d.ts.map +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/search.js +119 -0
- package/dist-standalone/_deps/ux-helpers/cjs/search.js.map +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/types.d.ts +109 -0
- package/dist-standalone/_deps/ux-helpers/cjs/types.d.ts.map +1 -0
- package/dist-standalone/_deps/ux-helpers/cjs/types.js +8 -0
- package/dist-standalone/_deps/ux-helpers/cjs/types.js.map +1 -0
- package/dist-standalone/_deps/ux-helpers/errors.d.ts +115 -0
- package/dist-standalone/_deps/ux-helpers/errors.d.ts.map +1 -0
- package/dist-standalone/_deps/ux-helpers/errors.js +253 -0
- package/dist-standalone/_deps/ux-helpers/errors.js.map +1 -0
- package/dist-standalone/_deps/ux-helpers/index.d.ts +13 -0
- package/dist-standalone/_deps/ux-helpers/index.d.ts.map +1 -0
- package/dist-standalone/_deps/ux-helpers/index.js +16 -0
- package/dist-standalone/_deps/ux-helpers/index.js.map +1 -0
- package/dist-standalone/_deps/ux-helpers/pagination.d.ts +39 -0
- package/dist-standalone/_deps/ux-helpers/pagination.d.ts.map +1 -0
- package/dist-standalone/_deps/ux-helpers/pagination.js +79 -0
- package/dist-standalone/_deps/ux-helpers/pagination.js.map +1 -0
- package/dist-standalone/_deps/ux-helpers/progress.d.ts +99 -0
- package/dist-standalone/_deps/ux-helpers/progress.d.ts.map +1 -0
- package/dist-standalone/_deps/ux-helpers/progress.js +138 -0
- package/dist-standalone/_deps/ux-helpers/progress.js.map +1 -0
- package/dist-standalone/_deps/ux-helpers/search.d.ts +32 -0
- package/dist-standalone/_deps/ux-helpers/search.d.ts.map +1 -0
- package/dist-standalone/_deps/ux-helpers/search.js +116 -0
- package/dist-standalone/_deps/ux-helpers/search.js.map +1 -0
- package/dist-standalone/_deps/ux-helpers/types.d.ts +109 -0
- package/dist-standalone/_deps/ux-helpers/types.d.ts.map +1 -0
- package/dist-standalone/_deps/ux-helpers/types.js +7 -0
- package/dist-standalone/_deps/ux-helpers/types.js.map +1 -0
- package/dist-standalone/_deps/xchange/auto-accept.d.ts +127 -0
- package/dist-standalone/_deps/xchange/auto-accept.js +1 -0
- package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -0
- package/dist-standalone/_deps/xchange/cjs/errors.js +1 -0
- package/dist-standalone/_deps/xchange/cjs/index.js +1 -0
- package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -0
- package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -0
- package/dist-standalone/_deps/xchange/cjs/package.json +1 -0
- package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -0
- package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -0
- package/dist-standalone/_deps/xchange/errors.d.ts +69 -0
- package/dist-standalone/_deps/xchange/errors.js +1 -0
- package/dist-standalone/_deps/xchange/index.d.ts +15 -0
- package/dist-standalone/_deps/xchange/index.js +1 -0
- package/dist-standalone/_deps/xchange/invite-client.d.ts +178 -0
- package/dist-standalone/_deps/xchange/invite-client.js +1 -0
- package/dist-standalone/_deps/xchange/lazy-init.d.ts +176 -0
- package/dist-standalone/_deps/xchange/lazy-init.js +1 -0
- package/dist-standalone/_deps/xchange/trust-integration.d.ts +102 -0
- package/dist-standalone/_deps/xchange/trust-integration.js +1 -0
- package/dist-standalone/_deps/xchange/xchange.d.ts +60 -0
- package/dist-standalone/_deps/xchange/xchange.js +1 -0
- package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -0
- package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -0
- package/dist-standalone/_deps/xregistry/cjs/index.js +1 -0
- package/dist-standalone/_deps/xregistry/cjs/package.json +1 -0
- package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -0
- package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -0
- package/dist-standalone/_deps/xregistry/cjs/types.js +1 -0
- package/dist-standalone/_deps/xregistry/discovery.d.ts +126 -0
- package/dist-standalone/_deps/xregistry/discovery.d.ts.map +1 -0
- package/dist-standalone/_deps/xregistry/discovery.js +1 -0
- package/dist-standalone/_deps/xregistry/discovery.js.map +1 -0
- package/dist-standalone/_deps/xregistry/errors.d.ts +41 -0
- package/dist-standalone/_deps/xregistry/errors.d.ts.map +1 -0
- package/dist-standalone/_deps/xregistry/errors.js +1 -0
- package/dist-standalone/_deps/xregistry/errors.js.map +1 -0
- package/dist-standalone/_deps/xregistry/index.d.ts +8 -0
- package/dist-standalone/_deps/xregistry/index.d.ts.map +1 -0
- package/dist-standalone/_deps/xregistry/index.js +1 -0
- package/dist-standalone/_deps/xregistry/index.js.map +1 -0
- package/dist-standalone/_deps/xregistry/registry.d.ts +85 -0
- package/dist-standalone/_deps/xregistry/registry.d.ts.map +1 -0
- package/dist-standalone/_deps/xregistry/registry.js +1 -0
- package/dist-standalone/_deps/xregistry/registry.js.map +1 -0
- package/dist-standalone/_deps/xregistry/schema.d.ts +81 -0
- package/dist-standalone/_deps/xregistry/schema.d.ts.map +1 -0
- package/dist-standalone/_deps/xregistry/schema.js +1 -0
- package/dist-standalone/_deps/xregistry/schema.js.map +1 -0
- package/dist-standalone/_deps/xregistry/types.d.ts +95 -0
- package/dist-standalone/_deps/xregistry/types.d.ts.map +1 -0
- package/dist-standalone/_deps/xregistry/types.js +1 -0
- package/dist-standalone/_deps/xregistry/types.js.map +1 -0
- package/dist-standalone/agent-call.d.ts +286 -0
- package/dist-standalone/agent-call.js +642 -0
- package/dist-standalone/agent-sdk.d.ts +207 -0
- package/dist-standalone/agent-sdk.js +328 -0
- package/dist-standalone/agent.d.ts +670 -0
- package/dist-standalone/agent.js +1529 -0
- package/dist-standalone/approval.d.ts +145 -0
- package/dist-standalone/approval.js +193 -0
- package/dist-standalone/auth.d.ts +75 -0
- package/dist-standalone/auth.js +219 -0
- package/dist-standalone/auto-accept.d.ts +102 -0
- package/dist-standalone/auto-accept.js +229 -0
- package/dist-standalone/backup-config.d.ts +150 -0
- package/dist-standalone/backup-config.js +201 -0
- package/dist-standalone/checkpoint.d.ts +125 -0
- package/dist-standalone/checkpoint.js +186 -0
- package/dist-standalone/cjs/agent-call.js +651 -0
- package/dist-standalone/cjs/agent-sdk.js +332 -0
- package/dist-standalone/cjs/agent.js +1566 -0
- package/dist-standalone/cjs/approval.js +199 -0
- package/dist-standalone/cjs/auth.js +225 -0
- package/dist-standalone/cjs/auto-accept.js +233 -0
- package/dist-standalone/cjs/backup-config.js +207 -0
- package/dist-standalone/cjs/checkpoint.js +193 -0
- package/dist-standalone/cjs/cli/init.js +487 -0
- package/dist-standalone/cjs/connect.js +312 -0
- package/dist-standalone/cjs/did-document.js +101 -0
- package/dist-standalone/cjs/did-privateme.js +130 -0
- package/dist-standalone/cjs/did-web.js +201 -0
- package/dist-standalone/cjs/discovery.js +462 -0
- package/dist-standalone/cjs/dual-mode.js +251 -0
- package/dist-standalone/cjs/email-templates.js +313 -0
- package/dist-standalone/cjs/email-transport.js +239 -0
- package/dist-standalone/cjs/envelope.js +510 -0
- package/dist-standalone/cjs/errors.js +562 -0
- package/dist-standalone/cjs/gateway-state.js +55 -0
- package/dist-standalone/cjs/gateway-transport.js +120 -0
- package/dist-standalone/cjs/guardrails.js +223 -0
- package/dist-standalone/cjs/http-compat.js +272 -0
- package/dist-standalone/cjs/identity.js +541 -0
- package/dist-standalone/cjs/index.js +224 -0
- package/dist-standalone/cjs/invitation.js +421 -0
- package/dist-standalone/cjs/invite.js +328 -0
- package/dist-standalone/cjs/key-agreement.js +246 -0
- package/dist-standalone/cjs/lazy-init.js +300 -0
- package/dist-standalone/cjs/mdns-discovery.js +202 -0
- package/dist-standalone/cjs/nonce-store.js +66 -0
- package/dist-standalone/cjs/package.json +3 -0
- package/dist-standalone/cjs/pairing-manager.js +223 -0
- package/dist-standalone/cjs/policy.js +320 -0
- package/dist-standalone/cjs/redis-nonce-store.js +76 -0
- package/dist-standalone/cjs/registry-middleware.js +50 -0
- package/dist-standalone/cjs/retry-transport.js +102 -0
- package/dist-standalone/cjs/security-policy.js +204 -0
- package/dist-standalone/cjs/split-channel.js +177 -0
- package/dist-standalone/cjs/subscription-proof.js +230 -0
- package/dist-standalone/cjs/succession.js +148 -0
- package/dist-standalone/cjs/transport.js +63 -0
- package/dist-standalone/cjs/trust-registry.js +742 -0
- package/dist-standalone/cjs/verify.js +25 -0
- package/dist-standalone/cjs/xfetch.js +252 -0
- package/dist-standalone/cli/init.d.ts +63 -0
- package/dist-standalone/cli/init.js +450 -0
- package/dist-standalone/connect.d.ts +143 -0
- package/dist-standalone/connect.js +274 -0
- package/dist-standalone/did-document.d.ts +65 -0
- package/dist-standalone/did-document.js +96 -0
- package/dist-standalone/did-privateme.d.ts +70 -0
- package/dist-standalone/did-privateme.js +121 -0
- package/dist-standalone/did-web.d.ts +73 -0
- package/dist-standalone/did-web.js +196 -0
- package/dist-standalone/discovery.d.ts +176 -0
- package/dist-standalone/discovery.js +458 -0
- package/dist-standalone/dual-mode.d.ts +145 -0
- package/dist-standalone/dual-mode.js +247 -0
- package/dist-standalone/email-templates.d.ts +41 -0
- package/dist-standalone/email-templates.js +309 -0
- package/dist-standalone/email-transport.d.ts +139 -0
- package/dist-standalone/email-transport.js +232 -0
- package/dist-standalone/envelope.d.ts +288 -0
- package/dist-standalone/envelope.js +497 -0
- package/dist-standalone/errors.d.ts +74 -0
- package/dist-standalone/errors.js +548 -0
- package/dist-standalone/gateway-state.d.ts +32 -0
- package/dist-standalone/gateway-state.js +51 -0
- package/dist-standalone/gateway-transport.d.ts +59 -0
- package/dist-standalone/gateway-transport.js +116 -0
- package/dist-standalone/guardrails.d.ts +136 -0
- package/dist-standalone/guardrails.js +216 -0
- package/dist-standalone/http-compat.d.ts +150 -0
- package/dist-standalone/http-compat.js +267 -0
- package/dist-standalone/identity.d.ts +176 -0
- package/dist-standalone/identity.js +516 -0
- package/dist-standalone/index.d.ts +83 -0
- package/dist-standalone/index.js +51 -0
- package/dist-standalone/invitation.d.ts +211 -0
- package/dist-standalone/invitation.js +415 -0
- package/dist-standalone/invite.d.ts +192 -0
- package/dist-standalone/invite.js +324 -0
- package/dist-standalone/key-agreement.d.ts +122 -0
- package/dist-standalone/key-agreement.js +236 -0
- package/dist-standalone/lazy-init.d.ts +167 -0
- package/dist-standalone/lazy-init.js +295 -0
- package/dist-standalone/mdns-discovery.d.ts +117 -0
- package/dist-standalone/mdns-discovery.js +195 -0
- package/dist-standalone/nonce-store.d.ts +39 -0
- package/dist-standalone/nonce-store.js +62 -0
- package/dist-standalone/package.json +11 -0
- package/dist-standalone/pairing-manager.d.ts +147 -0
- package/dist-standalone/pairing-manager.js +219 -0
- package/dist-standalone/policy.d.ts +150 -0
- package/dist-standalone/policy.js +315 -0
- package/dist-standalone/redis-nonce-store.d.ts +93 -0
- package/dist-standalone/redis-nonce-store.js +72 -0
- package/dist-standalone/registry-middleware.d.ts +38 -0
- package/dist-standalone/registry-middleware.js +47 -0
- package/dist-standalone/retry-transport.d.ts +76 -0
- package/dist-standalone/retry-transport.js +98 -0
- package/dist-standalone/security-policy.d.ts +146 -0
- package/dist-standalone/security-policy.js +198 -0
- package/dist-standalone/split-channel.d.ts +69 -0
- package/dist-standalone/split-channel.js +171 -0
- package/dist-standalone/subscription-proof.d.ts +103 -0
- package/dist-standalone/subscription-proof.js +224 -0
- package/dist-standalone/succession.d.ts +57 -0
- package/dist-standalone/succession.js +142 -0
- package/dist-standalone/transport.d.ts +50 -0
- package/dist-standalone/transport.js +59 -0
- package/dist-standalone/trust-registry.d.ts +286 -0
- package/dist-standalone/trust-registry.js +702 -0
- package/dist-standalone/verify.d.ts +16 -0
- package/dist-standalone/verify.js +16 -0
- package/dist-standalone/xfetch.d.ts +129 -0
- package/dist-standalone/xfetch.js +247 -0
- package/llms.txt +800 -0
- package/package.json +79 -0
- package/share1.dat +0 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module email-transport
|
|
3
|
+
* Email-based transport adapter for xBind agent invitations.
|
|
4
|
+
*
|
|
5
|
+
* Enables viral growth through email-based connection discovery:
|
|
6
|
+
* - Agent A sends email invite to Agent B
|
|
7
|
+
* - Email contains one-click acceptance link
|
|
8
|
+
* - Agent B clicks link, connection established
|
|
9
|
+
* - No manual DID exchange required
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { EmailTransport } from '@private.me/xbind/email-transport';
|
|
14
|
+
*
|
|
15
|
+
* const transport = new EmailTransport({
|
|
16
|
+
* smtpHost: process.env.SMTP_HOST,
|
|
17
|
+
* smtpPort: 587,
|
|
18
|
+
* smtpUser: process.env.SMTP_USER,
|
|
19
|
+
* smtpPass: process.env.SMTP_PASS,
|
|
20
|
+
* fromEmail: 'noreply@private.me',
|
|
21
|
+
* acceptBaseUrl: 'https://private.me/xbind/accept'
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* const agent = await Agent.create({
|
|
25
|
+
* name: 'payment-processor',
|
|
26
|
+
* transport
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* await agent.invite({
|
|
30
|
+
* to: 'fulfillment@acme.com',
|
|
31
|
+
* message: 'Connect our systems'
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
import { Result } from '@private.me/shared';
|
|
36
|
+
import type { XailTransportAdapter, TransportError, EnvelopeHandler } from './transport.js';
|
|
37
|
+
/**
|
|
38
|
+
* Email transport configuration.
|
|
39
|
+
*/
|
|
40
|
+
export interface EmailTransportConfig {
|
|
41
|
+
/** SMTP server hostname */
|
|
42
|
+
smtpHost: string;
|
|
43
|
+
/** SMTP server port (typically 587 for TLS) */
|
|
44
|
+
smtpPort: number;
|
|
45
|
+
/** SMTP authentication username */
|
|
46
|
+
smtpUser: string;
|
|
47
|
+
/** SMTP authentication password */
|
|
48
|
+
smtpPass: string;
|
|
49
|
+
/** Sender email address (e.g., noreply@private.me) */
|
|
50
|
+
fromEmail: string;
|
|
51
|
+
/** Sender display name (e.g., Private.Me) */
|
|
52
|
+
fromName: string;
|
|
53
|
+
/** Base URL for acceptance links (e.g., https://private.me/xbind/accept) */
|
|
54
|
+
acceptBaseUrl: string;
|
|
55
|
+
/** Rate limit: max invites per hour per agent (default: 10) */
|
|
56
|
+
rateLimit?: number;
|
|
57
|
+
/** Token expiration in hours (default: 48) */
|
|
58
|
+
tokenExpiryHours?: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Email-based transport adapter for xBind invitations.
|
|
62
|
+
*
|
|
63
|
+
* Sends invitation emails with branded templates and one-click acceptance links.
|
|
64
|
+
* Enforces rate limiting and token expiration for security.
|
|
65
|
+
*
|
|
66
|
+
* Note: Email transport is one-way (sending only). onReceive() is not supported.
|
|
67
|
+
*/
|
|
68
|
+
export declare class EmailTransport implements XailTransportAdapter {
|
|
69
|
+
private config;
|
|
70
|
+
private transporter;
|
|
71
|
+
private rateLimits;
|
|
72
|
+
/**
|
|
73
|
+
* Create email transport adapter.
|
|
74
|
+
*
|
|
75
|
+
* @param config - SMTP and email configuration
|
|
76
|
+
*/
|
|
77
|
+
constructor(config: EmailTransportConfig);
|
|
78
|
+
/**
|
|
79
|
+
* Send invitation email.
|
|
80
|
+
*
|
|
81
|
+
* @param envelope - Transport envelope
|
|
82
|
+
* @param recipientDid - Recipient DID (email address for email transport)
|
|
83
|
+
* @returns Result with void on success
|
|
84
|
+
*/
|
|
85
|
+
send(envelope: any, recipientDid: string): Promise<Result<void, TransportError>>;
|
|
86
|
+
/**
|
|
87
|
+
* Validate email address format.
|
|
88
|
+
*
|
|
89
|
+
* @param email - Email address to validate
|
|
90
|
+
* @returns True if valid
|
|
91
|
+
*/
|
|
92
|
+
private isValidEmail;
|
|
93
|
+
/**
|
|
94
|
+
* Check if agent has exceeded rate limit.
|
|
95
|
+
*
|
|
96
|
+
* @param agentDid - Agent DID
|
|
97
|
+
* @returns Result indicating if rate limit is OK
|
|
98
|
+
*/
|
|
99
|
+
private checkRateLimit;
|
|
100
|
+
/**
|
|
101
|
+
* Increment rate limit counter for agent.
|
|
102
|
+
*
|
|
103
|
+
* @param agentDid - Agent DID
|
|
104
|
+
*/
|
|
105
|
+
private incrementRateLimit;
|
|
106
|
+
/**
|
|
107
|
+
* Generate secure invitation token.
|
|
108
|
+
*
|
|
109
|
+
* Token contains: sender DID, sender public key, timestamp, expiry.
|
|
110
|
+
* Encoded as base64url for URL safety.
|
|
111
|
+
*
|
|
112
|
+
* @param envelope - Message envelope
|
|
113
|
+
* @returns Invitation token
|
|
114
|
+
*/
|
|
115
|
+
private generateInviteToken;
|
|
116
|
+
/**
|
|
117
|
+
* Verify connection to SMTP server.
|
|
118
|
+
*
|
|
119
|
+
* @returns Result indicating if SMTP connection is OK
|
|
120
|
+
*/
|
|
121
|
+
verify(): Promise<Result<void, TransportError>>;
|
|
122
|
+
/**
|
|
123
|
+
* Close SMTP connection.
|
|
124
|
+
*/
|
|
125
|
+
close(): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Register handler for incoming envelopes.
|
|
128
|
+
*
|
|
129
|
+
* Note: Email transport is one-way (sending only).
|
|
130
|
+
* This method exists for interface compliance but is a no-op.
|
|
131
|
+
*
|
|
132
|
+
* @param handler - Envelope handler (unused)
|
|
133
|
+
*/
|
|
134
|
+
onReceive(handler: EnvelopeHandler): void;
|
|
135
|
+
/**
|
|
136
|
+
* Shut down the transport (close SMTP connection).
|
|
137
|
+
*/
|
|
138
|
+
dispose(): void;
|
|
139
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module email-transport
|
|
3
|
+
* Email-based transport adapter for xBind agent invitations.
|
|
4
|
+
*
|
|
5
|
+
* Enables viral growth through email-based connection discovery:
|
|
6
|
+
* - Agent A sends email invite to Agent B
|
|
7
|
+
* - Email contains one-click acceptance link
|
|
8
|
+
* - Agent B clicks link, connection established
|
|
9
|
+
* - No manual DID exchange required
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { EmailTransport } from '@private.me/xbind/email-transport';
|
|
14
|
+
*
|
|
15
|
+
* const transport = new EmailTransport({
|
|
16
|
+
* smtpHost: process.env.SMTP_HOST,
|
|
17
|
+
* smtpPort: 587,
|
|
18
|
+
* smtpUser: process.env.SMTP_USER,
|
|
19
|
+
* smtpPass: process.env.SMTP_PASS,
|
|
20
|
+
* fromEmail: 'noreply@private.me',
|
|
21
|
+
* acceptBaseUrl: 'https://private.me/xbind/accept'
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* const agent = await Agent.create({
|
|
25
|
+
* name: 'payment-processor',
|
|
26
|
+
* transport
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* await agent.invite({
|
|
30
|
+
* to: 'fulfillment@acme.com',
|
|
31
|
+
* message: 'Connect our systems'
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
import { ok, err } from"./_deps/shared/index.js";
|
|
36
|
+
import { renderInviteEmail } from './email-templates.js';
|
|
37
|
+
import nodemailer from 'nodemailer';
|
|
38
|
+
/**
|
|
39
|
+
* Email-based transport adapter for xBind invitations.
|
|
40
|
+
*
|
|
41
|
+
* Sends invitation emails with branded templates and one-click acceptance links.
|
|
42
|
+
* Enforces rate limiting and token expiration for security.
|
|
43
|
+
*
|
|
44
|
+
* Note: Email transport is one-way (sending only). onReceive() is not supported.
|
|
45
|
+
*/
|
|
46
|
+
export class EmailTransport {
|
|
47
|
+
config;
|
|
48
|
+
transporter;
|
|
49
|
+
rateLimits;
|
|
50
|
+
/**
|
|
51
|
+
* Create email transport adapter.
|
|
52
|
+
*
|
|
53
|
+
* @param config - SMTP and email configuration
|
|
54
|
+
*/
|
|
55
|
+
constructor(config) {
|
|
56
|
+
this.config = {
|
|
57
|
+
...config,
|
|
58
|
+
rateLimit: config.rateLimit ?? 10,
|
|
59
|
+
tokenExpiryHours: config.tokenExpiryHours ?? 48,
|
|
60
|
+
};
|
|
61
|
+
// Create nodemailer transporter
|
|
62
|
+
this.transporter = nodemailer.createTransport({
|
|
63
|
+
host: this.config.smtpHost,
|
|
64
|
+
port: this.config.smtpPort,
|
|
65
|
+
secure: false, // TLS on port 587
|
|
66
|
+
auth: {
|
|
67
|
+
user: this.config.smtpUser,
|
|
68
|
+
pass: this.config.smtpPass,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
this.rateLimits = new Map();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Send invitation email.
|
|
75
|
+
*
|
|
76
|
+
* @param envelope - Transport envelope
|
|
77
|
+
* @param recipientDid - Recipient DID (email address for email transport)
|
|
78
|
+
* @returns Result with void on success
|
|
79
|
+
*/
|
|
80
|
+
async send(envelope, recipientDid) {
|
|
81
|
+
// Extract invitation data from envelope
|
|
82
|
+
const { from, to, payload } = envelope;
|
|
83
|
+
// Validate email address
|
|
84
|
+
if (!this.isValidEmail(to)) {
|
|
85
|
+
return err('SEND_FAILED');
|
|
86
|
+
}
|
|
87
|
+
// Check rate limit
|
|
88
|
+
const rateLimitCheck = this.checkRateLimit(from);
|
|
89
|
+
if (!rateLimitCheck.ok) {
|
|
90
|
+
return err('SEND_FAILED');
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
// Generate secure invitation token
|
|
94
|
+
const token = await this.generateInviteToken(envelope);
|
|
95
|
+
// Construct acceptance URL
|
|
96
|
+
const acceptUrl = `${this.config.acceptBaseUrl}/${token}`;
|
|
97
|
+
// Render branded email template
|
|
98
|
+
const html = renderInviteEmail({
|
|
99
|
+
agentName: payload.agentName || from,
|
|
100
|
+
did: from,
|
|
101
|
+
acceptUrl,
|
|
102
|
+
message: payload.message,
|
|
103
|
+
});
|
|
104
|
+
// Send email via SMTP
|
|
105
|
+
await this.transporter.sendMail({
|
|
106
|
+
from: `"${this.config.fromName}" <${this.config.fromEmail}>`,
|
|
107
|
+
to,
|
|
108
|
+
subject: `${payload.agentName || 'Agent'} wants to connect`,
|
|
109
|
+
html,
|
|
110
|
+
});
|
|
111
|
+
// Update rate limit counter
|
|
112
|
+
this.incrementRateLimit(from);
|
|
113
|
+
return ok(undefined);
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
return err('NETWORK_ERROR');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Validate email address format.
|
|
121
|
+
*
|
|
122
|
+
* @param email - Email address to validate
|
|
123
|
+
* @returns True if valid
|
|
124
|
+
*/
|
|
125
|
+
isValidEmail(email) {
|
|
126
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
127
|
+
return emailRegex.test(email);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Check if agent has exceeded rate limit.
|
|
131
|
+
*
|
|
132
|
+
* @param agentDid - Agent DID
|
|
133
|
+
* @returns Result indicating if rate limit is OK
|
|
134
|
+
*/
|
|
135
|
+
checkRateLimit(agentDid) {
|
|
136
|
+
const now = Date.now();
|
|
137
|
+
const entry = this.rateLimits.get(agentDid);
|
|
138
|
+
if (!entry) {
|
|
139
|
+
return ok(undefined);
|
|
140
|
+
}
|
|
141
|
+
// Reset if hour has passed
|
|
142
|
+
if (now >= entry.resetAt) {
|
|
143
|
+
this.rateLimits.delete(agentDid);
|
|
144
|
+
return ok(undefined);
|
|
145
|
+
}
|
|
146
|
+
// Check if limit exceeded
|
|
147
|
+
if (entry.count >= this.config.rateLimit) {
|
|
148
|
+
return err(undefined);
|
|
149
|
+
}
|
|
150
|
+
return ok(undefined);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Increment rate limit counter for agent.
|
|
154
|
+
*
|
|
155
|
+
* @param agentDid - Agent DID
|
|
156
|
+
*/
|
|
157
|
+
incrementRateLimit(agentDid) {
|
|
158
|
+
const now = Date.now();
|
|
159
|
+
const entry = this.rateLimits.get(agentDid);
|
|
160
|
+
if (!entry) {
|
|
161
|
+
this.rateLimits.set(agentDid, {
|
|
162
|
+
count: 1,
|
|
163
|
+
resetAt: now + (60 * 60 * 1000), // 1 hour
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
entry.count += 1;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Generate secure invitation token.
|
|
172
|
+
*
|
|
173
|
+
* Token contains: sender DID, sender public key, timestamp, expiry.
|
|
174
|
+
* Encoded as base64url for URL safety.
|
|
175
|
+
*
|
|
176
|
+
* @param envelope - Message envelope
|
|
177
|
+
* @returns Invitation token
|
|
178
|
+
*/
|
|
179
|
+
async generateInviteToken(envelope) {
|
|
180
|
+
const tokenData = {
|
|
181
|
+
from: envelope.from,
|
|
182
|
+
publicKey: envelope.payload.publicKey,
|
|
183
|
+
endpoint: envelope.payload.endpoint,
|
|
184
|
+
timestamp: Date.now(),
|
|
185
|
+
expiresAt: Date.now() + (this.config.tokenExpiryHours * 60 * 60 * 1000),
|
|
186
|
+
};
|
|
187
|
+
// Encode as base64url
|
|
188
|
+
const json = JSON.stringify(tokenData);
|
|
189
|
+
const base64 = Buffer.from(json).toString('base64')
|
|
190
|
+
.replace(/\+/g, '-')
|
|
191
|
+
.replace(/\//g, '_')
|
|
192
|
+
.replace(/=/g, '');
|
|
193
|
+
return base64;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Verify connection to SMTP server.
|
|
197
|
+
*
|
|
198
|
+
* @returns Result indicating if SMTP connection is OK
|
|
199
|
+
*/
|
|
200
|
+
async verify() {
|
|
201
|
+
try {
|
|
202
|
+
await this.transporter.verify();
|
|
203
|
+
return ok(undefined);
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
return err('NETWORK_ERROR');
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Close SMTP connection.
|
|
211
|
+
*/
|
|
212
|
+
async close() {
|
|
213
|
+
this.transporter.close();
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Register handler for incoming envelopes.
|
|
217
|
+
*
|
|
218
|
+
* Note: Email transport is one-way (sending only).
|
|
219
|
+
* This method exists for interface compliance but is a no-op.
|
|
220
|
+
*
|
|
221
|
+
* @param handler - Envelope handler (unused)
|
|
222
|
+
*/
|
|
223
|
+
onReceive(handler) {
|
|
224
|
+
// Email transport is one-way - no incoming messages
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Shut down the transport (close SMTP connection).
|
|
228
|
+
*/
|
|
229
|
+
dispose() {
|
|
230
|
+
this.transporter.close();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import type { Result } from '@private.me/shared';
|
|
2
|
+
/** Envelope v1 format matching xail.io/sdk specification. */
|
|
3
|
+
export interface TransportEnvelope {
|
|
4
|
+
readonly v: 1;
|
|
5
|
+
readonly alg: 'Ed25519';
|
|
6
|
+
readonly sender: string;
|
|
7
|
+
readonly recipient: string;
|
|
8
|
+
readonly timestamp: number;
|
|
9
|
+
readonly nonce: string;
|
|
10
|
+
readonly scope: string;
|
|
11
|
+
readonly payload: string;
|
|
12
|
+
readonly signature: string;
|
|
13
|
+
/** Base64-encoded ephemeral X25519 public key for forward secrecy. */
|
|
14
|
+
readonly ephemeralPub?: string;
|
|
15
|
+
/** Share index for split-channel delivery (0-based). */
|
|
16
|
+
readonly shareIndex?: number;
|
|
17
|
+
/** Total shares for split-channel delivery. */
|
|
18
|
+
readonly shareTotal?: number;
|
|
19
|
+
/** Threshold for split-channel reconstruction. */
|
|
20
|
+
readonly shareThreshold?: number;
|
|
21
|
+
/** UUID linking all shares of a split-channel message. */
|
|
22
|
+
readonly shareGroupId?: string;
|
|
23
|
+
/** Base64-encoded HMAC key for split-channel integrity. */
|
|
24
|
+
readonly shareHmacKey?: string;
|
|
25
|
+
/** Base64-encoded HMAC signature for split-channel integrity. */
|
|
26
|
+
readonly shareHmacSig?: string;
|
|
27
|
+
/** Protocol identifier for viral exposure: "PRIVATE.ME/xBind/v3" */
|
|
28
|
+
readonly protocol?: string;
|
|
29
|
+
/** Documentation URL for the protocol */
|
|
30
|
+
readonly documentationUrl?: string;
|
|
31
|
+
}
|
|
32
|
+
/** Envelope v2 format with hybrid post-quantum KEM. */
|
|
33
|
+
export interface TransportEnvelopeV2 {
|
|
34
|
+
readonly v: 2;
|
|
35
|
+
readonly alg: 'Ed25519';
|
|
36
|
+
readonly kem: 'X25519-MLKEM768';
|
|
37
|
+
readonly sender: string;
|
|
38
|
+
readonly recipient: string;
|
|
39
|
+
readonly timestamp: number;
|
|
40
|
+
readonly nonce: string;
|
|
41
|
+
readonly scope: string;
|
|
42
|
+
readonly payload: string;
|
|
43
|
+
readonly signature: string;
|
|
44
|
+
/** Base64-encoded ephemeral X25519 public key (32B). */
|
|
45
|
+
readonly ephemeralPub: string;
|
|
46
|
+
/** Base64-encoded ML-KEM-768 ciphertext (1088B). */
|
|
47
|
+
readonly kemCiphertext: string;
|
|
48
|
+
/** Share index for split-channel delivery (0-based). */
|
|
49
|
+
readonly shareIndex?: number;
|
|
50
|
+
/** Total shares for split-channel delivery. */
|
|
51
|
+
readonly shareTotal?: number;
|
|
52
|
+
/** Threshold for split-channel reconstruction. */
|
|
53
|
+
readonly shareThreshold?: number;
|
|
54
|
+
/** UUID linking all shares of a split-channel message. */
|
|
55
|
+
readonly shareGroupId?: string;
|
|
56
|
+
/** Base64-encoded HMAC key for split-channel integrity. */
|
|
57
|
+
readonly shareHmacKey?: string;
|
|
58
|
+
/** Base64-encoded HMAC signature for split-channel integrity. */
|
|
59
|
+
readonly shareHmacSig?: string;
|
|
60
|
+
/** Protocol identifier for viral exposure: "PRIVATE.ME/xBind/v3" */
|
|
61
|
+
readonly protocol?: string;
|
|
62
|
+
/** Documentation URL for the protocol */
|
|
63
|
+
readonly documentationUrl?: string;
|
|
64
|
+
}
|
|
65
|
+
/** Envelope v3 format with hybrid KEM + dual PQ signatures. */
|
|
66
|
+
export interface TransportEnvelopeV3 {
|
|
67
|
+
readonly v: 3;
|
|
68
|
+
readonly alg: 'Ed25519';
|
|
69
|
+
/** Signature scheme: dual Ed25519 + ML-DSA-65. */
|
|
70
|
+
readonly sig: 'Ed25519+MLDSA65';
|
|
71
|
+
readonly kem: 'X25519-MLKEM768';
|
|
72
|
+
readonly sender: string;
|
|
73
|
+
readonly recipient: string;
|
|
74
|
+
readonly timestamp: number;
|
|
75
|
+
readonly nonce: string;
|
|
76
|
+
readonly scope: string;
|
|
77
|
+
readonly payload: string;
|
|
78
|
+
/** Base64-encoded Ed25519 signature (64B). */
|
|
79
|
+
readonly signature: string;
|
|
80
|
+
/** Base64-encoded ML-DSA-65 signature (3309B). */
|
|
81
|
+
readonly pqSignature: string;
|
|
82
|
+
/** Base64-encoded ephemeral X25519 public key (32B). */
|
|
83
|
+
readonly ephemeralPub: string;
|
|
84
|
+
/** Base64-encoded ML-KEM-768 ciphertext (1088B). */
|
|
85
|
+
readonly kemCiphertext: string;
|
|
86
|
+
/** Share index for split-channel delivery (0-based). */
|
|
87
|
+
readonly shareIndex?: number;
|
|
88
|
+
/** Total shares for split-channel delivery. */
|
|
89
|
+
readonly shareTotal?: number;
|
|
90
|
+
/** Threshold for split-channel reconstruction. */
|
|
91
|
+
readonly shareThreshold?: number;
|
|
92
|
+
/** UUID linking all shares of a split-channel message. */
|
|
93
|
+
readonly shareGroupId?: string;
|
|
94
|
+
/** Base64-encoded HMAC key for split-channel integrity. */
|
|
95
|
+
readonly shareHmacKey?: string;
|
|
96
|
+
/** Base64-encoded HMAC signature for split-channel integrity. */
|
|
97
|
+
readonly shareHmacSig?: string;
|
|
98
|
+
/** Protocol identifier for viral exposure: "PRIVATE.ME/xBind/v3" */
|
|
99
|
+
readonly protocol?: string;
|
|
100
|
+
/** Documentation URL for the protocol */
|
|
101
|
+
readonly documentationUrl?: string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Xchange mode envelope (wire format v:4).
|
|
105
|
+
*
|
|
106
|
+
* Opt-in performance mode activated via `xchange: true`. Single security
|
|
107
|
+
* layer (information-theoretic XorIDA split) + Ed25519 authentication.
|
|
108
|
+
* ~180x faster than V3 split-channel. No per-share encryption, no KEM.
|
|
109
|
+
*/
|
|
110
|
+
export interface TransportEnvelopeV4 {
|
|
111
|
+
readonly v: 4;
|
|
112
|
+
readonly alg: 'Ed25519';
|
|
113
|
+
/** Key transport method: Xchange (random key bundled + split). */
|
|
114
|
+
readonly kem: 'Xchange';
|
|
115
|
+
readonly sender: string;
|
|
116
|
+
readonly recipient: string;
|
|
117
|
+
readonly timestamp: number;
|
|
118
|
+
readonly nonce: string;
|
|
119
|
+
readonly scope: string;
|
|
120
|
+
/** Base64-encoded XorIDA share (NOT encrypted — the split IS the security). */
|
|
121
|
+
readonly payload: string;
|
|
122
|
+
/** Base64-encoded Ed25519 signature (64B) — sender auth only. */
|
|
123
|
+
readonly signature: string;
|
|
124
|
+
/** Share index for split-channel delivery (0-based). */
|
|
125
|
+
readonly shareIndex: number;
|
|
126
|
+
/** Total shares for split-channel delivery. */
|
|
127
|
+
readonly shareTotal: number;
|
|
128
|
+
/** Threshold for split-channel reconstruction. */
|
|
129
|
+
readonly shareThreshold: number;
|
|
130
|
+
/** UUID linking all shares of a split-channel message. */
|
|
131
|
+
readonly shareGroupId: string;
|
|
132
|
+
/** Base64-encoded HMAC key for split-channel integrity. */
|
|
133
|
+
readonly shareHmacKey: string;
|
|
134
|
+
/** Base64-encoded HMAC signature for split-channel integrity. */
|
|
135
|
+
readonly shareHmacSig: string;
|
|
136
|
+
/** Protocol identifier for viral exposure: "PRIVATE.ME/xBind/v3" */
|
|
137
|
+
readonly protocol?: string;
|
|
138
|
+
/** Documentation URL for the protocol */
|
|
139
|
+
readonly documentationUrl?: string;
|
|
140
|
+
}
|
|
141
|
+
/** Union of all supported envelope versions. */
|
|
142
|
+
export type AnyTransportEnvelope = TransportEnvelope | TransportEnvelopeV2 | TransportEnvelopeV3 | TransportEnvelopeV4;
|
|
143
|
+
/** Options for creating an envelope. */
|
|
144
|
+
export interface CreateEnvelopeOptions {
|
|
145
|
+
readonly senderDid: string;
|
|
146
|
+
readonly recipientDid: string;
|
|
147
|
+
readonly scope: string;
|
|
148
|
+
readonly plaintext: Uint8Array;
|
|
149
|
+
readonly privateKey: CryptoKey;
|
|
150
|
+
readonly sharedKey: CryptoKey;
|
|
151
|
+
/** Raw ephemeral X25519 public key to include for forward secrecy. */
|
|
152
|
+
readonly ephemeralPublicKey?: Uint8Array;
|
|
153
|
+
/** Split-channel share metadata. */
|
|
154
|
+
readonly shareIndex?: number;
|
|
155
|
+
readonly shareTotal?: number;
|
|
156
|
+
readonly shareThreshold?: number;
|
|
157
|
+
readonly shareGroupId?: string;
|
|
158
|
+
readonly shareHmacKey?: string;
|
|
159
|
+
readonly shareHmacSig?: string;
|
|
160
|
+
}
|
|
161
|
+
/** Options for creating a v2 hybrid-KEM envelope. */
|
|
162
|
+
export interface CreateEnvelopeV2Options {
|
|
163
|
+
readonly senderDid: string;
|
|
164
|
+
readonly recipientDid: string;
|
|
165
|
+
readonly scope: string;
|
|
166
|
+
readonly plaintext: Uint8Array;
|
|
167
|
+
readonly privateKey: CryptoKey;
|
|
168
|
+
readonly sharedKey: CryptoKey;
|
|
169
|
+
/** Raw ephemeral X25519 public key (32B). */
|
|
170
|
+
readonly ephemeralPublicKey: Uint8Array;
|
|
171
|
+
/** ML-KEM-768 ciphertext (1088B). */
|
|
172
|
+
readonly kemCiphertext: Uint8Array;
|
|
173
|
+
/** Split-channel share metadata. */
|
|
174
|
+
readonly shareIndex?: number;
|
|
175
|
+
readonly shareTotal?: number;
|
|
176
|
+
readonly shareThreshold?: number;
|
|
177
|
+
readonly shareGroupId?: string;
|
|
178
|
+
readonly shareHmacKey?: string;
|
|
179
|
+
readonly shareHmacSig?: string;
|
|
180
|
+
}
|
|
181
|
+
/** Options for creating a v3 hybrid-KEM + dual-sig envelope. */
|
|
182
|
+
export interface CreateEnvelopeV3Options {
|
|
183
|
+
readonly senderDid: string;
|
|
184
|
+
readonly recipientDid: string;
|
|
185
|
+
readonly scope: string;
|
|
186
|
+
readonly plaintext: Uint8Array;
|
|
187
|
+
readonly privateKey: CryptoKey;
|
|
188
|
+
readonly sharedKey: CryptoKey;
|
|
189
|
+
/** Raw ephemeral X25519 public key (32B). */
|
|
190
|
+
readonly ephemeralPublicKey: Uint8Array;
|
|
191
|
+
/** ML-KEM-768 ciphertext (1088B). */
|
|
192
|
+
readonly kemCiphertext: Uint8Array;
|
|
193
|
+
/** ML-DSA-65 secret key (4032B) for post-quantum signature. */
|
|
194
|
+
readonly mlDsaSecretKey: Uint8Array;
|
|
195
|
+
/** Split-channel share metadata. */
|
|
196
|
+
readonly shareIndex?: number;
|
|
197
|
+
readonly shareTotal?: number;
|
|
198
|
+
readonly shareThreshold?: number;
|
|
199
|
+
readonly shareGroupId?: string;
|
|
200
|
+
readonly shareHmacKey?: string;
|
|
201
|
+
readonly shareHmacSig?: string;
|
|
202
|
+
}
|
|
203
|
+
/** Options for creating a Xchange mode envelope (no encryption — share IS the payload). */
|
|
204
|
+
export interface CreateEnvelopeV4Options {
|
|
205
|
+
readonly senderDid: string;
|
|
206
|
+
readonly recipientDid: string;
|
|
207
|
+
readonly scope: string;
|
|
208
|
+
/** Raw share data (already an XorIDA share — NOT encrypted). */
|
|
209
|
+
readonly shareData: Uint8Array;
|
|
210
|
+
readonly privateKey: CryptoKey;
|
|
211
|
+
/** Split-channel share metadata (all REQUIRED for v4). */
|
|
212
|
+
readonly shareIndex: number;
|
|
213
|
+
readonly shareTotal: number;
|
|
214
|
+
readonly shareThreshold: number;
|
|
215
|
+
readonly shareGroupId: string;
|
|
216
|
+
readonly shareHmacKey: string;
|
|
217
|
+
readonly shareHmacSig: string;
|
|
218
|
+
}
|
|
219
|
+
/** Options for creating a signed (unencrypted) envelope. */
|
|
220
|
+
export interface CreateSignedEnvelopeOptions {
|
|
221
|
+
readonly senderDid: string;
|
|
222
|
+
readonly recipientDid: string;
|
|
223
|
+
readonly scope: string;
|
|
224
|
+
readonly plaintext: Uint8Array;
|
|
225
|
+
readonly privateKey: CryptoKey;
|
|
226
|
+
}
|
|
227
|
+
/** Envelope error codes. */
|
|
228
|
+
export type EnvelopeError = 'INVALID_VERSION' | 'INVALID_ALG' | 'INVALID_KEM' | 'INVALID_DID' | 'INVALID_NONCE' | 'INVALID_FIELDS' | 'ENCRYPT_FAILED' | 'DECRYPT_FAILED' | 'SIGN_FAILED' | 'PQ_SIGN_FAILED' | 'VERIFY_FAILED' | 'PARSE_FAILED';
|
|
229
|
+
/**
|
|
230
|
+
* Create a signed, encrypted TransportEnvelope.
|
|
231
|
+
*
|
|
232
|
+
* Encrypt-then-sign: AES-256-GCM encrypts payload, Ed25519 signs ciphertext.
|
|
233
|
+
*/
|
|
234
|
+
export declare function createEnvelope(opts: CreateEnvelopeOptions): Promise<Result<TransportEnvelope, EnvelopeError>>;
|
|
235
|
+
/**
|
|
236
|
+
* Create a signed, encrypted TransportEnvelopeV2 with hybrid KEM.
|
|
237
|
+
*
|
|
238
|
+
* Same encrypt-then-sign as v1, but includes ML-KEM-768 ciphertext.
|
|
239
|
+
*/
|
|
240
|
+
export declare function createEnvelopeV2(opts: CreateEnvelopeV2Options): Promise<Result<TransportEnvelopeV2, EnvelopeError>>;
|
|
241
|
+
/**
|
|
242
|
+
* Create a signed, encrypted TransportEnvelopeV3 with hybrid KEM + dual signatures.
|
|
243
|
+
*
|
|
244
|
+
* Encrypt-then-sign: AES-256-GCM encrypts payload, Ed25519 AND ML-DSA-65 sign ciphertext.
|
|
245
|
+
* Both signatures must verify for the envelope to be accepted.
|
|
246
|
+
*/
|
|
247
|
+
export declare function createEnvelopeV3(opts: CreateEnvelopeV3Options): Promise<Result<TransportEnvelopeV3, EnvelopeError>>;
|
|
248
|
+
/**
|
|
249
|
+
* Create a signed Xchange mode envelope (v4 wire format).
|
|
250
|
+
*
|
|
251
|
+
* Opt-in performance mode. No encryption — the share IS the payload.
|
|
252
|
+
* Ed25519 signs the raw share data for sender authentication.
|
|
253
|
+
* The XorIDA split provides confidentiality (information-theoretic).
|
|
254
|
+
*/
|
|
255
|
+
export declare function createEnvelopeV4(opts: CreateEnvelopeV4Options): Promise<Result<TransportEnvelopeV4, EnvelopeError>>;
|
|
256
|
+
/**
|
|
257
|
+
* Decrypt the payload from a v1, v2, or v3 TransportEnvelope.
|
|
258
|
+
* Caller must verify signature before calling this.
|
|
259
|
+
*/
|
|
260
|
+
export declare function decryptPayload(envelope: AnyTransportEnvelope, sharedKey: CryptoKey): Promise<Result<Uint8Array, EnvelopeError>>;
|
|
261
|
+
/** Serialize envelope to UTF-8 bytes. */
|
|
262
|
+
export declare function serializeEnvelope(envelope: AnyTransportEnvelope): Uint8Array;
|
|
263
|
+
/** Deserialize bytes to a validated v1 or v2 TransportEnvelope. */
|
|
264
|
+
export declare function deserializeEnvelope(bytes: Uint8Array): Result<AnyTransportEnvelope, EnvelopeError>;
|
|
265
|
+
/** Validate a parsed object is a valid v1 or v2 TransportEnvelope. */
|
|
266
|
+
export declare function validateEnvelope(obj: unknown): Result<AnyTransportEnvelope, EnvelopeError>;
|
|
267
|
+
/** Generate an AES-256-GCM key for envelope encryption. */
|
|
268
|
+
export declare function generateSharedKey(): Promise<CryptoKey>;
|
|
269
|
+
/**
|
|
270
|
+
* Create a signed but unencrypted TransportEnvelope.
|
|
271
|
+
*
|
|
272
|
+
* Payload is base64-encoded plaintext (NOT encrypted).
|
|
273
|
+
* Signature covers the raw plaintext bytes.
|
|
274
|
+
* Use for public announcements, audit logs, or telemetry where
|
|
275
|
+
* confidentiality is not required but integrity is.
|
|
276
|
+
*
|
|
277
|
+
* @param opts - Sender, recipient, scope, plaintext, and signing key.
|
|
278
|
+
* @returns Signed envelope or error.
|
|
279
|
+
*/
|
|
280
|
+
export declare function createSignedEnvelope(opts: CreateSignedEnvelopeOptions): Promise<Result<TransportEnvelope, EnvelopeError>>;
|
|
281
|
+
/**
|
|
282
|
+
* Verify signature on a signed (unencrypted) envelope and return plaintext.
|
|
283
|
+
*
|
|
284
|
+
* @param envelope - The signed envelope to verify.
|
|
285
|
+
* @param senderPublicKey - The sender's Ed25519 public key.
|
|
286
|
+
* @returns Plaintext bytes if signature is valid, error otherwise.
|
|
287
|
+
*/
|
|
288
|
+
export declare function openSignedEnvelope(envelope: TransportEnvelope, senderPublicKey: CryptoKey): Promise<Result<Uint8Array, EnvelopeError>>;
|