sealbridge 0.2.2 → 0.3.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.ja.md +492 -30
- package/README.md +522 -109
- package/dist/cli/dist/accept.d.ts +13 -0
- package/dist/cli/dist/accept.js +115 -0
- package/dist/cli/dist/accept.js.map +1 -0
- package/dist/cli/dist/approval-summary.d.ts +1 -1
- package/dist/cli/dist/board.d.ts +10 -9
- package/dist/cli/dist/board.js +62 -31
- package/dist/cli/dist/board.js.map +1 -1
- package/dist/cli/dist/command-identity.d.ts +6 -0
- package/dist/cli/dist/command-identity.js +13 -0
- package/dist/cli/dist/command-identity.js.map +1 -0
- package/dist/cli/dist/config.d.ts +3 -0
- package/dist/cli/dist/config.js +29 -0
- package/dist/cli/dist/config.js.map +1 -0
- package/dist/cli/dist/connections.d.ts +15 -0
- package/dist/cli/dist/connections.js +191 -0
- package/dist/cli/dist/connections.js.map +1 -0
- package/dist/cli/dist/contacts.d.ts +4 -3
- package/dist/cli/dist/contacts.js +39 -28
- package/dist/cli/dist/contacts.js.map +1 -1
- package/dist/cli/dist/doctor.d.ts +9 -0
- package/dist/cli/dist/doctor.js +46 -5
- package/dist/cli/dist/doctor.js.map +1 -1
- package/dist/cli/dist/error-messages.js +22 -0
- package/dist/cli/dist/error-messages.js.map +1 -1
- package/dist/cli/dist/index.js +44 -6
- package/dist/cli/dist/index.js.map +1 -1
- package/dist/cli/dist/invite-output.d.ts +14 -0
- package/dist/cli/dist/invite-output.js +66 -0
- package/dist/cli/dist/invite-output.js.map +1 -0
- package/dist/cli/dist/invite-share.d.ts +6 -3
- package/dist/cli/dist/invite-share.js +40 -15
- package/dist/cli/dist/invite-share.js.map +1 -1
- package/dist/cli/dist/invites-migrate.d.ts +3 -0
- package/dist/cli/dist/invites-migrate.js +33 -0
- package/dist/cli/dist/invites-migrate.js.map +1 -0
- package/dist/cli/dist/mcp.d.ts +7 -5
- package/dist/cli/dist/mcp.js +23 -18
- package/dist/cli/dist/mcp.js.map +1 -1
- package/dist/cli/dist/network.d.ts +11 -1
- package/dist/cli/dist/network.js +150 -87
- package/dist/cli/dist/network.js.map +1 -1
- package/dist/cli/dist/pending.d.ts +8 -0
- package/dist/cli/dist/pending.js +50 -0
- package/dist/cli/dist/pending.js.map +1 -0
- package/dist/cli/dist/public-settings.d.ts +5 -4
- package/dist/cli/dist/public-settings.js +13 -15
- package/dist/cli/dist/public-settings.js.map +1 -1
- package/dist/cli/dist/receipt.d.ts +1 -1
- package/dist/cli/dist/relay-auth.d.ts +3 -0
- package/dist/cli/dist/relay-auth.js +23 -0
- package/dist/cli/dist/relay-auth.js.map +1 -0
- package/dist/cli/dist/requests.d.ts +10 -0
- package/dist/cli/dist/requests.js +91 -0
- package/dist/cli/dist/requests.js.map +1 -0
- package/dist/cli/dist/sdk.d.ts +10 -0
- package/dist/cli/dist/sdk.js +7 -0
- package/dist/cli/dist/sdk.js.map +1 -0
- package/dist/cli/dist/setup-files.d.ts +24 -0
- package/dist/cli/dist/setup-files.js +190 -0
- package/dist/cli/dist/setup-files.js.map +1 -0
- package/dist/cli/dist/setup-hosts.d.ts +29 -0
- package/dist/cli/dist/setup-hosts.js +75 -0
- package/dist/cli/dist/setup-hosts.js.map +1 -0
- package/dist/cli/dist/setup.d.ts +61 -0
- package/dist/cli/dist/setup.js +243 -0
- package/dist/cli/dist/setup.js.map +1 -0
- package/dist/cli/dist/task-input.d.ts +1 -1
- package/dist/cli/dist/wake-hook.d.ts +1 -1
- package/dist/cli/dist/worker-json.d.ts +4 -0
- package/dist/cli/dist/worker-json.js +87 -0
- package/dist/cli/dist/worker-json.js.map +1 -0
- package/dist/examples/two-owner-demo/dist/run-demo.d.ts +13 -13
- package/dist/package.json +1 -1
- package/dist/packages/adapters/dist/command.d.ts +2 -2
- package/dist/packages/adapters/dist/credential-proxy.d.ts +2 -2
- package/dist/packages/adapters/dist/index.d.ts +1 -1
- package/dist/packages/adapters/dist/mcp.d.ts +2 -2
- package/dist/packages/adapters/dist/openai.d.ts +2 -2
- package/dist/packages/adapters/dist/sandbox.d.ts +2 -2
- package/dist/packages/core/dist/connection.d.ts +58 -0
- package/dist/packages/core/dist/connection.js +132 -0
- package/dist/packages/core/dist/connection.js.map +1 -0
- package/dist/packages/core/dist/delivery-status.d.ts +22 -0
- package/dist/packages/core/dist/delivery-status.js +53 -0
- package/dist/packages/core/dist/delivery-status.js.map +1 -0
- package/dist/packages/core/dist/discovery.d.ts +7 -6
- package/dist/packages/core/dist/discovery.js +19 -20
- package/dist/packages/core/dist/discovery.js.map +1 -1
- package/dist/packages/core/dist/edge.d.ts +1 -0
- package/dist/packages/core/dist/edge.js +1 -0
- package/dist/packages/core/dist/edge.js.map +1 -1
- package/dist/packages/core/dist/index.d.ts +3 -0
- package/dist/packages/core/dist/index.js +3 -0
- package/dist/packages/core/dist/index.js.map +1 -1
- package/dist/packages/core/dist/protocol.d.ts +24 -0
- package/dist/packages/core/dist/protocol.js +54 -0
- package/dist/packages/core/dist/protocol.js.map +1 -0
- package/dist/packages/core/dist/receipts.d.ts +1 -0
- package/dist/packages/core/dist/receipts.js +1 -1
- package/dist/packages/core/dist/receipts.js.map +1 -1
- package/dist/packages/core/dist/schema.d.ts +1 -0
- package/dist/packages/core/dist/schema.js +13 -2
- package/dist/packages/core/dist/schema.js.map +1 -1
- package/dist/packages/ledger/dist/index.d.ts +1 -1
- package/dist/packages/relay/dist/admission.d.ts +14 -0
- package/dist/packages/relay/dist/admission.js +70 -0
- package/dist/packages/relay/dist/admission.js.map +1 -0
- package/dist/packages/relay/dist/fetch.d.ts +8 -2
- package/dist/packages/relay/dist/fetch.js +41 -12
- package/dist/packages/relay/dist/fetch.js.map +1 -1
- package/dist/packages/relay/dist/index.d.ts +23 -12
- package/dist/packages/relay/dist/index.js +130 -78
- package/dist/packages/relay/dist/index.js.map +1 -1
- package/dist/packages/relay/dist/journal.d.ts +1 -1
- package/dist/packages/relay/dist/notifications.d.ts +1 -1
- package/dist/packages/relay/dist/retry.d.ts +23 -0
- package/dist/packages/relay/dist/retry.js +43 -1
- package/dist/packages/relay/dist/retry.js.map +1 -1
- package/dist/packages/relay/dist/ssrf.d.ts +3 -2
- package/dist/packages/relay/dist/ssrf.js.map +1 -1
- package/dist/packages/relay/dist/worker.js +1 -1
- package/dist/packages/relay/dist/worker.js.map +1 -1
- package/dist/packages/runtime/dist/a2a.d.ts +1 -1
- package/dist/packages/runtime/dist/a2a.js +1 -1
- package/dist/packages/runtime/dist/adapter.d.ts +2 -2
- package/dist/packages/runtime/dist/application-config.d.ts +20 -0
- package/dist/packages/runtime/dist/application-config.js +218 -0
- package/dist/packages/runtime/dist/application-config.js.map +1 -0
- package/dist/packages/runtime/dist/approval-providers.d.ts +24 -3
- package/dist/packages/runtime/dist/approval-providers.js +79 -3
- package/dist/packages/runtime/dist/approval-providers.js.map +1 -1
- package/dist/packages/runtime/dist/connection-admission-review.d.ts +39 -0
- package/dist/packages/runtime/dist/connection-admission-review.js +86 -0
- package/dist/packages/runtime/dist/connection-admission-review.js.map +1 -0
- package/dist/packages/runtime/dist/connection-persistence.d.ts +35 -0
- package/dist/packages/runtime/dist/connection-persistence.js +181 -0
- package/dist/packages/runtime/dist/connection-persistence.js.map +1 -0
- package/dist/packages/runtime/dist/connection-records.d.ts +167 -0
- package/dist/packages/runtime/dist/connection-records.js +132 -0
- package/dist/packages/runtime/dist/connection-records.js.map +1 -0
- package/dist/packages/runtime/dist/connection-router.d.ts +45 -0
- package/dist/packages/runtime/dist/connection-router.js +130 -0
- package/dist/packages/runtime/dist/connection-router.js.map +1 -0
- package/dist/packages/runtime/dist/connection-service.d.ts +159 -0
- package/dist/packages/runtime/dist/connection-service.js +239 -0
- package/dist/packages/runtime/dist/connection-service.js.map +1 -0
- package/dist/packages/runtime/dist/connection-transport.d.ts +14 -0
- package/dist/packages/runtime/dist/connection-transport.js +89 -0
- package/dist/packages/runtime/dist/connection-transport.js.map +1 -0
- package/dist/packages/runtime/dist/delivery-records.d.ts +180 -0
- package/dist/packages/runtime/dist/delivery-records.js +205 -0
- package/dist/packages/runtime/dist/delivery-records.js.map +1 -0
- package/dist/packages/runtime/dist/delivery-status-router.d.ts +27 -0
- package/dist/packages/runtime/dist/delivery-status-router.js +150 -0
- package/dist/packages/runtime/dist/delivery-status-router.js.map +1 -0
- package/dist/packages/runtime/dist/delivery-status.d.ts +43 -0
- package/dist/packages/runtime/dist/delivery-status.js +193 -0
- package/dist/packages/runtime/dist/delivery-status.js.map +1 -0
- package/dist/packages/runtime/dist/delivery-store.d.ts +125 -0
- package/dist/packages/runtime/dist/delivery-store.js +1047 -0
- package/dist/packages/runtime/dist/delivery-store.js.map +1 -0
- package/dist/packages/runtime/dist/gateway.d.ts +4 -3
- package/dist/packages/runtime/dist/gateway.js.map +1 -1
- package/dist/packages/runtime/dist/held-request-review.d.ts +49 -0
- package/dist/packages/runtime/dist/held-request-review.js +122 -0
- package/dist/packages/runtime/dist/held-request-review.js.map +1 -0
- package/dist/packages/runtime/dist/held-request-store.d.ts +112 -0
- package/dist/packages/runtime/dist/held-request-store.js +290 -0
- package/dist/packages/runtime/dist/held-request-store.js.map +1 -0
- package/dist/packages/runtime/dist/idempotency-store.d.ts +53 -0
- package/dist/packages/runtime/dist/idempotency-store.js +331 -0
- package/dist/packages/runtime/dist/idempotency-store.js.map +1 -0
- package/dist/packages/runtime/dist/inbox.d.ts +1 -1
- package/dist/packages/runtime/dist/index.d.ts +27 -1
- package/dist/packages/runtime/dist/index.js +26 -0
- package/dist/packages/runtime/dist/index.js.map +1 -1
- package/dist/packages/runtime/dist/invite-store.d.ts +76 -0
- package/dist/packages/runtime/dist/invite-store.js +337 -0
- package/dist/packages/runtime/dist/invite-store.js.map +1 -0
- package/dist/packages/runtime/dist/key-store.d.ts +77 -0
- package/dist/packages/runtime/dist/key-store.js +226 -0
- package/dist/packages/runtime/dist/key-store.js.map +1 -0
- package/dist/packages/runtime/dist/local-identity.d.ts +33 -0
- package/dist/packages/runtime/dist/local-identity.js +279 -0
- package/dist/packages/runtime/dist/local-identity.js.map +1 -0
- package/dist/packages/runtime/dist/mcp-rpc.d.ts +19 -0
- package/dist/packages/runtime/dist/mcp-rpc.js +175 -0
- package/dist/packages/runtime/dist/mcp-rpc.js.map +1 -0
- package/dist/packages/runtime/dist/mcp-server.d.ts +46 -19
- package/dist/packages/runtime/dist/mcp-server.js +427 -184
- package/dist/packages/runtime/dist/mcp-server.js.map +1 -1
- package/dist/packages/runtime/dist/mcp-tool-catalog.d.ts +1 -1
- package/dist/packages/runtime/dist/mcp-tool-catalog.js +172 -13
- package/dist/packages/runtime/dist/mcp-tool-catalog.js.map +1 -1
- package/dist/packages/runtime/dist/mcp.d.ts +2 -2
- package/dist/packages/runtime/dist/message-status.d.ts +32 -0
- package/dist/packages/runtime/dist/message-status.js +29 -0
- package/dist/packages/runtime/dist/message-status.js.map +1 -0
- package/dist/packages/runtime/dist/outbox.d.ts +91 -0
- package/dist/packages/runtime/dist/outbox.js +462 -0
- package/dist/packages/runtime/dist/outbox.js.map +1 -0
- package/dist/packages/runtime/dist/policy.d.ts +1 -1
- package/dist/packages/runtime/dist/protocol-peer-store.d.ts +40 -0
- package/dist/packages/runtime/dist/protocol-peer-store.js +176 -0
- package/dist/packages/runtime/dist/protocol-peer-store.js.map +1 -0
- package/dist/packages/runtime/dist/protocol-release.d.ts +26 -0
- package/dist/packages/runtime/dist/protocol-release.js +76 -0
- package/dist/packages/runtime/dist/protocol-release.js.map +1 -0
- package/dist/packages/runtime/dist/quota.d.ts +1 -1
- package/dist/packages/runtime/dist/relay-selection.d.ts +20 -0
- package/dist/packages/runtime/dist/relay-selection.js +34 -0
- package/dist/packages/runtime/dist/relay-selection.js.map +1 -0
- package/dist/packages/runtime/dist/requester-pending-store.d.ts +59 -0
- package/dist/packages/runtime/dist/requester-pending-store.js +266 -0
- package/dist/packages/runtime/dist/requester-pending-store.js.map +1 -0
- package/dist/packages/runtime/dist/secret-store.d.ts +19 -0
- package/dist/packages/runtime/dist/secret-store.js +51 -0
- package/dist/packages/runtime/dist/secret-store.js.map +1 -0
- package/dist/packages/runtime/dist/session-audit.d.ts +29 -7
- package/dist/packages/runtime/dist/session-audit.js +149 -29
- package/dist/packages/runtime/dist/session-audit.js.map +1 -1
- package/dist/packages/runtime/dist/session.d.ts +101 -9
- package/dist/packages/runtime/dist/session.js +696 -96
- package/dist/packages/runtime/dist/session.js.map +1 -1
- package/dist/packages/runtime/dist/task-journal.d.ts +18 -3
- package/dist/packages/runtime/dist/task-journal.js +271 -18
- package/dist/packages/runtime/dist/task-journal.js.map +1 -1
- package/dist/packages/runtime/dist/verifier.d.ts +3 -2
- package/dist/packages/runtime/dist/verifier.js +1 -0
- package/dist/packages/runtime/dist/verifier.js.map +1 -1
- package/dist/packages/runtime/dist/worker-trust-store.d.ts +111 -0
- package/dist/packages/runtime/dist/worker-trust-store.js +592 -0
- package/dist/packages/runtime/dist/worker-trust-store.js.map +1 -0
- package/dist/packages/sandbox/dist/container.d.ts +1 -1
- package/dist/packages/sandbox/dist/index.d.ts +1 -1
- package/dist/spec/README.ja.md +21 -1
- package/dist/spec/README.md +20 -1
- package/dist/spec/agent-card.schema.json +11 -1
- package/dist/spec/delivery-status.schema.json +106 -0
- package/dist/spec/examples/protocol-versions/sample-agent-card.json +35 -0
- package/dist/spec/examples/sample-delivery-status.json +21 -0
- package/dist/spec/examples/sample-task-manifest.0.1.0.json +173 -0
- package/dist/spec/examples/sample-task-manifest.0.2.0.json +173 -0
- package/dist/spec/task-manifest.0.1.0.schema.json +422 -0
- package/dist/spec/task-manifest.0.2.0.schema.json +422 -0
- package/dist/spec/task-manifest.schema.json +9 -418
- package/docs/sdk.ja.md +133 -0
- package/docs/sdk.md +138 -0
- package/package.json +15 -3
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import type { ConnectionAccepted, ConnectionAck, ConnectionRequest, KeyPair, RevocationList, Signed, SignedAgentCard, SignedEnvelope } from '../../core/dist/index.js';
|
|
2
|
+
import type { ConnectionTransport } from './connection-transport.js';
|
|
3
|
+
/** Content-free offer metadata. Bodies belong to the injected held-content port. */
|
|
4
|
+
export interface ConnectionOffer {
|
|
5
|
+
requestId: string;
|
|
6
|
+
requestDigest: string;
|
|
7
|
+
fromOwnerDid: string;
|
|
8
|
+
toOwnerDid: string;
|
|
9
|
+
peerAgentDid?: string;
|
|
10
|
+
/** Derived locally from a verified peer card; never an identity selector. */
|
|
11
|
+
peerDisplayName?: string;
|
|
12
|
+
relayUrl: string;
|
|
13
|
+
createdAt: string;
|
|
14
|
+
expiresAt: string;
|
|
15
|
+
inviteDigest?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ConnectionConsent {
|
|
18
|
+
type: 'ConnectionConsent';
|
|
19
|
+
v: 1;
|
|
20
|
+
ownerDid: string;
|
|
21
|
+
requestDigest: string;
|
|
22
|
+
decidedAt: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ConnectionOutboxEntry {
|
|
25
|
+
id: string;
|
|
26
|
+
requestId: string;
|
|
27
|
+
relayUrl: string;
|
|
28
|
+
deliveryDeadline: string;
|
|
29
|
+
envelope: SignedEnvelope;
|
|
30
|
+
}
|
|
31
|
+
export interface ConnectionAcceptanceCommit {
|
|
32
|
+
offer: ConnectionOffer;
|
|
33
|
+
accepted: Signed<ConnectionAccepted>;
|
|
34
|
+
outbox: ConnectionOutboxEntry;
|
|
35
|
+
consent: Signed<ConnectionConsent> | {
|
|
36
|
+
inviteDigest: string;
|
|
37
|
+
};
|
|
38
|
+
now: number;
|
|
39
|
+
}
|
|
40
|
+
export interface ConnectionRedemptionCommit extends ConnectionAcceptanceCommit {
|
|
41
|
+
inviteDigest: string;
|
|
42
|
+
requesterOwnerDid: string;
|
|
43
|
+
tokenExpiresAt: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* All mutations are durable and atomic, scoped to the selected local owner DID.
|
|
47
|
+
* Implementations serialize concurrent writers and enforce these preconditions under lock:
|
|
48
|
+
* - record operations reject conflicting request IDs and blocked/withdrawn/tombstoned offers;
|
|
49
|
+
* repeated incoming requests return their retained decision without creating a new offer;
|
|
50
|
+
* - accept checks the recorded incoming digest, deadline and current owner decision,
|
|
51
|
+
* retaining signed local consent with the connection and acceptance/outbox;
|
|
52
|
+
* - redeem binds first owner + limited connection + acceptance/outbox in one write;
|
|
53
|
+
* same means the exact original offer is still connected, inactive means a same-owner
|
|
54
|
+
* reuse has no matching active offer, and other writes no authority;
|
|
55
|
+
* - apply checks the exact outgoing digest, owners, deadline, invite digest and consent,
|
|
56
|
+
* then writes limited connection + ACK outbox before returning; duplicates requeue the
|
|
57
|
+
* original ACK, including after markSent, without changing consent or connection state;
|
|
58
|
+
* - disconnect/block/withdraw supersede duplicates; retained decisions prevent restoration;
|
|
59
|
+
* - acknowledge checks the acceptance digest, request ID and both owners against the outbox,
|
|
60
|
+
* durably marks receipt, and treats duplicate/unknown ACKs as no-ops.
|
|
61
|
+
* No connection operation creates trusted authority or task execution permission.
|
|
62
|
+
*/
|
|
63
|
+
export interface ConnectionPersistencePort {
|
|
64
|
+
outgoing(requestId: string): Promise<ConnectionOffer | undefined>;
|
|
65
|
+
incoming(requestId: string): Promise<ConnectionOffer | undefined>;
|
|
66
|
+
recordOutgoing(offer: ConnectionOffer, consent: Signed<ConnectionConsent>, outbox: ConnectionOutboxEntry, now: number): Promise<void>;
|
|
67
|
+
recordIncoming(offer: ConnectionOffer, now: number): Promise<'pending' | 'accepted'>;
|
|
68
|
+
accept(commit: ConnectionAcceptanceCommit): Promise<void>;
|
|
69
|
+
redeem(commit: ConnectionRedemptionCommit): Promise<'first' | 'same' | 'other' | 'inactive'>;
|
|
70
|
+
applyAccepted(commit: {
|
|
71
|
+
offer: ConnectionOffer;
|
|
72
|
+
accepted: Signed<ConnectionAccepted>;
|
|
73
|
+
acknowledgement: Signed<ConnectionAck>;
|
|
74
|
+
outbox: ConnectionOutboxEntry;
|
|
75
|
+
now: number;
|
|
76
|
+
}): Promise<void>;
|
|
77
|
+
acknowledge(ack: Signed<ConnectionAck>, requestId: string, now: number): Promise<void>;
|
|
78
|
+
listOutbox(now: number): Promise<ConnectionOutboxEntry[]>;
|
|
79
|
+
/** Retain sent notifications until application ACK (ACK notifications need no further ACK). */
|
|
80
|
+
markSent(id: string, now: number): Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
export interface ConnectionHumanReviewProvider {
|
|
83
|
+
readonly kind: 'human';
|
|
84
|
+
review(context: {
|
|
85
|
+
reason: 'outgoing' | 'incoming' | 'confirm-invite';
|
|
86
|
+
localOwnerDid: string;
|
|
87
|
+
peerOwnerDid: string;
|
|
88
|
+
requestDigest: string;
|
|
89
|
+
request: Signed<ConnectionRequest>;
|
|
90
|
+
}): Promise<boolean>;
|
|
91
|
+
}
|
|
92
|
+
export interface ConnectionInspectionPort {
|
|
93
|
+
/** Persist the encrypted original, capped at min(offer deadline, first receivedAt + 24h).
|
|
94
|
+
* Duplicate holds retain the original deadline; expired content cannot be renewed. */
|
|
95
|
+
hold(envelope: SignedEnvelope, context: {
|
|
96
|
+
contentDigest: string;
|
|
97
|
+
expiresAt: string;
|
|
98
|
+
receivedAt: string;
|
|
99
|
+
}): Promise<void>;
|
|
100
|
+
/** Complete means the returned digest identifies this immutable held content. */
|
|
101
|
+
inspect(contentDigest: string): Promise<{
|
|
102
|
+
status: 'complete' | 'unavailable' | 'error';
|
|
103
|
+
contentDigest: string;
|
|
104
|
+
}>;
|
|
105
|
+
discard(contentDigest: string): Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
export interface ConnectionServiceOptions {
|
|
108
|
+
owner: KeyPair;
|
|
109
|
+
agentCard: SignedAgentCard;
|
|
110
|
+
relayUrl: string;
|
|
111
|
+
persistence: ConnectionPersistencePort;
|
|
112
|
+
transport: ConnectionTransport;
|
|
113
|
+
humanReview?: ConnectionHumanReviewProvider;
|
|
114
|
+
inspection?: ConnectionInspectionPort;
|
|
115
|
+
revocations?: RevocationList;
|
|
116
|
+
allowPrivateRelay?: boolean;
|
|
117
|
+
now?: () => number;
|
|
118
|
+
id?: () => string;
|
|
119
|
+
}
|
|
120
|
+
export type ConnectionServiceResult = {
|
|
121
|
+
requestId: string;
|
|
122
|
+
status: 'pending' | 'connected' | 'acknowledged';
|
|
123
|
+
code?: 'PENDING_OWNER_APPROVAL' | 'CONNECTION_DELIVERY_PENDING';
|
|
124
|
+
retryable?: false;
|
|
125
|
+
};
|
|
126
|
+
/** Signed connection exchange; task execution remains a separate owner decision. */
|
|
127
|
+
export declare class ConnectionService {
|
|
128
|
+
private readonly options;
|
|
129
|
+
private readonly now;
|
|
130
|
+
private readonly id;
|
|
131
|
+
constructor(options: ConnectionServiceOptions);
|
|
132
|
+
setAgentCard(card: SignedAgentCard): void;
|
|
133
|
+
private iso;
|
|
134
|
+
private review;
|
|
135
|
+
private invite;
|
|
136
|
+
private offer;
|
|
137
|
+
private outbox;
|
|
138
|
+
request(input: {
|
|
139
|
+
toOwnerDid: string;
|
|
140
|
+
peerAgentCard?: SignedAgentCard;
|
|
141
|
+
message?: string;
|
|
142
|
+
expiresAt?: string;
|
|
143
|
+
inviteToken?: string;
|
|
144
|
+
originProposalDigest?: string;
|
|
145
|
+
deferDelivery?: boolean;
|
|
146
|
+
}): Promise<ConnectionServiceResult>;
|
|
147
|
+
private checkRequest;
|
|
148
|
+
/** Validate an attached request before the task path mutates invitation or intake state. */
|
|
149
|
+
validateRequest(envelope: SignedEnvelope): void;
|
|
150
|
+
private inspect;
|
|
151
|
+
private accept;
|
|
152
|
+
/** Caller acknowledges relay delivery only after this resolves. No task mailbox is involved. */
|
|
153
|
+
receive(envelope: SignedEnvelope): Promise<ConnectionServiceResult>;
|
|
154
|
+
approve(envelope: SignedEnvelope): Promise<ConnectionServiceResult>;
|
|
155
|
+
/** Retries only retained control notifications, each bounded by its original offer deadline. */
|
|
156
|
+
flushOutbox(): Promise<boolean>;
|
|
157
|
+
}
|
|
158
|
+
/** Both owners derive the same ID, with the smaller DID as the base. */
|
|
159
|
+
export declare function connectionIdFor(left: string, right: string): string;
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { assertConnectionRequestCurrent, CONNECTION_OFFER_LIFETIME_MS, DEFAULT_CLOCK_SKEW_MS, digest, parseAndVerifyInviteToken, signConnectionAccepted, signConnectionAck, signConnectionRequest, signPayload, validateRelayEndpointUrl, verifyConnectionRequest, verifySignedAgentCard, } from '../../core/dist/index.js';
|
|
4
|
+
import { openConnectionFrame, retryConnectionEnvelope, sealConnectionFrame } from './connection-transport.js';
|
|
5
|
+
/** Signed connection exchange; task execution remains a separate owner decision. */
|
|
6
|
+
export class ConnectionService {
|
|
7
|
+
options;
|
|
8
|
+
now;
|
|
9
|
+
id;
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.options = options;
|
|
12
|
+
this.now = options.now ?? Date.now;
|
|
13
|
+
this.id = options.id ?? randomUUID;
|
|
14
|
+
validateRelayEndpointUrl(options.relayUrl, options);
|
|
15
|
+
if (!verifySignedAgentCard(options.agentCard, this.now()) ||
|
|
16
|
+
options.agentCard.payload.ownerDid !== options.owner.did ||
|
|
17
|
+
options.agentCard.payload.relayEndpoint !== options.relayUrl)
|
|
18
|
+
throw new Error('INVALID_AGENT_CARD');
|
|
19
|
+
}
|
|
20
|
+
setAgentCard(card) {
|
|
21
|
+
if (!verifySignedAgentCard(card, this.now()) || card.payload.ownerDid !== this.options.owner.did ||
|
|
22
|
+
card.payload.relayEndpoint !== this.options.relayUrl)
|
|
23
|
+
throw new Error('INVALID_AGENT_CARD');
|
|
24
|
+
this.options.agentCard = card;
|
|
25
|
+
}
|
|
26
|
+
iso() { return new Date(this.now()).toISOString(); }
|
|
27
|
+
async review(reason, request) {
|
|
28
|
+
const provider = this.options.humanReview;
|
|
29
|
+
if (!provider || provider.kind !== 'human')
|
|
30
|
+
throw new Error('APPROVAL_CHANNEL_UNAVAILABLE');
|
|
31
|
+
const p = request.payload;
|
|
32
|
+
const requestDigest = digest(request);
|
|
33
|
+
const approved = await provider.review({ reason, localOwnerDid: this.options.owner.did,
|
|
34
|
+
peerOwnerDid: p.fromOwnerDid === this.options.owner.did ? p.toOwnerDid : p.fromOwnerDid,
|
|
35
|
+
requestDigest, request: structuredClone(request) });
|
|
36
|
+
if (approved !== true)
|
|
37
|
+
throw new Error('APPROVAL_REJECTED');
|
|
38
|
+
assertConnectionRequestCurrent(p, this.now());
|
|
39
|
+
return signPayload({ type: 'ConnectionConsent', v: 1, ownerDid: this.options.owner.did,
|
|
40
|
+
requestDigest, decidedAt: this.iso() }, this.options.owner, this.iso());
|
|
41
|
+
}
|
|
42
|
+
invite(token, expectedOwner, expectedAgent) {
|
|
43
|
+
const now = this.now();
|
|
44
|
+
// Historical verification permits revocation to precede expiry, as in current admission.
|
|
45
|
+
const invite = parseAndVerifyInviteToken(token, now, { allowPrivateRelay: this.options.allowPrivateRelay, allowExpired: true });
|
|
46
|
+
if (invite.ownerDid !== expectedOwner || (expectedAgent && invite.agentDid !== expectedAgent) ||
|
|
47
|
+
invite.relayUrl !== this.options.relayUrl)
|
|
48
|
+
throw new Error('INVITE_WORKER_MISMATCH');
|
|
49
|
+
this.options.revocations?.assertNotRevoked('invite', digest(invite));
|
|
50
|
+
this.options.revocations?.assertNotRevoked('invite', token);
|
|
51
|
+
if (Math.min(Date.parse(invite.expiresAt), Date.parse(invite.agentCard.payload.expiresAt)) <= now)
|
|
52
|
+
throw new Error('INVITE_EXPIRED');
|
|
53
|
+
return invite;
|
|
54
|
+
}
|
|
55
|
+
offer(request, outgoing = false, peerCard) {
|
|
56
|
+
const p = request.payload;
|
|
57
|
+
return { requestId: p.requestId, requestDigest: digest(request), fromOwnerDid: p.fromOwnerDid,
|
|
58
|
+
toOwnerDid: p.toOwnerDid,
|
|
59
|
+
...(!outgoing ? { peerAgentDid: p.agentCard.payload.agentDid } : peerCard ? { peerAgentDid: peerCard.payload.agentDid } : {}),
|
|
60
|
+
...(!outgoing ? { peerDisplayName: p.agentCard.payload.name } : peerCard ? { peerDisplayName: peerCard.payload.name } : {}),
|
|
61
|
+
relayUrl: this.options.relayUrl, createdAt: p.createdAt, expiresAt: p.expiresAt,
|
|
62
|
+
...(p.inviteDigest ? { inviteDigest: p.inviteDigest } : {}) };
|
|
63
|
+
}
|
|
64
|
+
outbox(frame, deadline) {
|
|
65
|
+
return { id: frame.event.payload.type === 'ConnectionRequest' ? frame.requestId : frame.event.payload.eventId,
|
|
66
|
+
requestId: frame.requestId, relayUrl: this.options.relayUrl, deliveryDeadline: deadline,
|
|
67
|
+
envelope: sealConnectionFrame(frame, this.options.owner, this.now(), this.id()) };
|
|
68
|
+
}
|
|
69
|
+
async request(input) {
|
|
70
|
+
const invite = input.inviteToken === undefined ? undefined : this.invite(input.inviteToken, input.toOwnerDid);
|
|
71
|
+
const peerCard = invite?.agentCard ?? input.peerAgentCard;
|
|
72
|
+
if (input.peerAgentCard && (!verifySignedAgentCard(input.peerAgentCard, this.now()) ||
|
|
73
|
+
input.peerAgentCard.payload.ownerDid !== input.toOwnerDid ||
|
|
74
|
+
input.peerAgentCard.payload.relayEndpoint !== this.options.relayUrl ||
|
|
75
|
+
(invite && input.peerAgentCard.payload.agentDid !== invite.agentDid)))
|
|
76
|
+
throw new Error('INVALID_AGENT_CARD');
|
|
77
|
+
const now = this.now();
|
|
78
|
+
const request = signConnectionRequest({ type: 'ConnectionRequest', v: 1, protocolVersion: '0.2.0',
|
|
79
|
+
requestId: this.id(), fromOwnerDid: this.options.owner.did, toOwnerDid: input.toOwnerDid,
|
|
80
|
+
agentCard: this.options.agentCard, message: input.message ?? '', createdAt: new Date(now).toISOString(),
|
|
81
|
+
expiresAt: input.expiresAt ?? new Date(now + CONNECTION_OFFER_LIFETIME_MS).toISOString(),
|
|
82
|
+
...(invite ? { inviteDigest: digest(invite) } : {}),
|
|
83
|
+
...(input.originProposalDigest === undefined ? {} : { originProposalDigest: input.originProposalDigest }),
|
|
84
|
+
}, this.options.owner);
|
|
85
|
+
const consent = await this.review(invite ? 'confirm-invite' : 'outgoing', request);
|
|
86
|
+
const offer = this.offer(request, true, peerCard);
|
|
87
|
+
const outbox = this.outbox({ requestId: offer.requestId, event: request,
|
|
88
|
+
...(input.inviteToken === undefined ? {} : { inviteToken: input.inviteToken }) }, offer.expiresAt);
|
|
89
|
+
await this.options.persistence.recordOutgoing(offer, consent, outbox, this.now());
|
|
90
|
+
const delivered = input.deferDelivery ? true : await this.flushOutbox();
|
|
91
|
+
return { requestId: offer.requestId, status: 'pending', ...(!delivered ? { code: 'CONNECTION_DELIVERY_PENDING' } : {}) };
|
|
92
|
+
}
|
|
93
|
+
checkRequest(frame) {
|
|
94
|
+
const request = frame.event;
|
|
95
|
+
if (!verifyConnectionRequest(request) || request.payload.toOwnerDid !== this.options.owner.did ||
|
|
96
|
+
request.payload.agentCard.payload.relayEndpoint !== this.options.relayUrl)
|
|
97
|
+
throw new Error('INVALID_CONNECTION_REQUEST');
|
|
98
|
+
assertConnectionRequestCurrent(request.payload, this.now());
|
|
99
|
+
if (!verifySignedAgentCard(request.payload.agentCard, this.now()))
|
|
100
|
+
throw new Error('INVALID_AGENT_CARD');
|
|
101
|
+
if (request.payload.inviteDigest && !frame.inviteToken)
|
|
102
|
+
throw new Error('INVALID_CONNECTION_REQUEST');
|
|
103
|
+
if (frame.inviteToken !== undefined) {
|
|
104
|
+
const invite = this.invite(frame.inviteToken, this.options.owner.did, this.options.agentCard.payload.agentDid);
|
|
105
|
+
if (digest(invite) !== request.payload.inviteDigest)
|
|
106
|
+
throw new Error('INVALID_CONNECTION_REQUEST');
|
|
107
|
+
}
|
|
108
|
+
return request;
|
|
109
|
+
}
|
|
110
|
+
/** Validate an attached request before the task path mutates invitation or intake state. */
|
|
111
|
+
validateRequest(envelope) {
|
|
112
|
+
const frame = openConnectionFrame(envelope, this.options.owner);
|
|
113
|
+
if (frame.event.payload.type !== 'ConnectionRequest')
|
|
114
|
+
throw new Error('INVALID_CONNECTION_REQUEST');
|
|
115
|
+
this.checkRequest(frame);
|
|
116
|
+
}
|
|
117
|
+
async inspect(envelope, request) {
|
|
118
|
+
const port = this.options.inspection;
|
|
119
|
+
if (!port)
|
|
120
|
+
return false;
|
|
121
|
+
const contentDigest = digest(request), now = this.now();
|
|
122
|
+
await port.hold(envelope, { contentDigest, receivedAt: new Date(now).toISOString(),
|
|
123
|
+
expiresAt: new Date(Math.min(Date.parse(request.payload.expiresAt), now + 24 * 60 * 60 * 1000)).toISOString() });
|
|
124
|
+
let completion;
|
|
125
|
+
try {
|
|
126
|
+
completion = await port.inspect(contentDigest);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
return completion?.status === 'complete' && completion.contentDigest === contentDigest;
|
|
132
|
+
}
|
|
133
|
+
async accept(request, consent, token) {
|
|
134
|
+
const offer = this.offer(request);
|
|
135
|
+
assertConnectionRequestCurrent(request.payload, this.now());
|
|
136
|
+
const accepted = signConnectionAccepted({ type: 'ConnectionAccepted', v: 1, protocolVersion: '0.2.0',
|
|
137
|
+
eventId: this.id(), connectionId: connectionIdFor(this.options.owner.did, offer.fromOwnerDid), requestId: offer.requestId, requestDigest: offer.requestDigest,
|
|
138
|
+
fromOwnerDid: this.options.owner.did, toOwnerDid: offer.fromOwnerDid, acceptedAt: this.iso(), trust: 'limited',
|
|
139
|
+
...(offer.inviteDigest ? { inviteDigest: offer.inviteDigest } : {}) }, this.options.owner);
|
|
140
|
+
const commit = { offer, accepted, consent, now: this.now(),
|
|
141
|
+
outbox: this.outbox({ requestId: offer.requestId, event: accepted }, offer.expiresAt) };
|
|
142
|
+
if (token !== undefined) {
|
|
143
|
+
const invite = this.invite(token, this.options.owner.did, this.options.agentCard.payload.agentDid);
|
|
144
|
+
const outcome = await this.options.persistence.redeem({ ...commit, inviteDigest: digest(invite),
|
|
145
|
+
requesterOwnerDid: offer.fromOwnerDid,
|
|
146
|
+
tokenExpiresAt: new Date(Math.min(Date.parse(invite.expiresAt), Date.parse(invite.agentCard.payload.expiresAt))).toISOString() });
|
|
147
|
+
if (outcome === 'other' || outcome === 'inactive')
|
|
148
|
+
return 'pending';
|
|
149
|
+
}
|
|
150
|
+
else
|
|
151
|
+
await this.options.persistence.accept(commit);
|
|
152
|
+
await this.options.inspection?.discard(offer.requestDigest);
|
|
153
|
+
return 'connected';
|
|
154
|
+
}
|
|
155
|
+
/** Caller acknowledges relay delivery only after this resolves. No task mailbox is involved. */
|
|
156
|
+
async receive(envelope) {
|
|
157
|
+
const frame = openConnectionFrame(envelope, this.options.owner), p = frame.event.payload;
|
|
158
|
+
if (p.type === 'ConnectionRequest') {
|
|
159
|
+
const request = this.checkRequest(frame);
|
|
160
|
+
const complete = await this.inspect(envelope, request);
|
|
161
|
+
// Without durable held content, leave relay delivery unacknowledged.
|
|
162
|
+
if (!this.options.inspection)
|
|
163
|
+
throw new Error('INSPECTION_UNAVAILABLE');
|
|
164
|
+
const decision = await this.options.persistence.recordIncoming(this.offer(request), this.now());
|
|
165
|
+
if (decision === 'accepted') {
|
|
166
|
+
await this.options.inspection.discard(digest(request));
|
|
167
|
+
const delivered = await this.flushOutbox();
|
|
168
|
+
return { requestId: frame.requestId, status: 'connected', ...(!delivered ? { code: 'CONNECTION_DELIVERY_PENDING' } : {}) };
|
|
169
|
+
}
|
|
170
|
+
if (complete && frame.inviteToken !== undefined) {
|
|
171
|
+
const status = await this.accept(request, { inviteDigest: p.inviteDigest }, frame.inviteToken);
|
|
172
|
+
if (status === 'connected') {
|
|
173
|
+
const delivered = await this.flushOutbox();
|
|
174
|
+
return { requestId: frame.requestId, status, ...(!delivered ? { code: 'CONNECTION_DELIVERY_PENDING' } : {}) };
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return { requestId: frame.requestId, status: 'pending', code: 'PENDING_OWNER_APPROVAL', retryable: false };
|
|
178
|
+
}
|
|
179
|
+
if (p.type === 'ConnectionAccepted') {
|
|
180
|
+
const offer = await this.options.persistence.outgoing(frame.requestId);
|
|
181
|
+
if (!offer || offer.fromOwnerDid !== this.options.owner.did || offer.toOwnerDid !== p.fromOwnerDid ||
|
|
182
|
+
offer.requestDigest !== p.requestDigest || offer.inviteDigest !== p.inviteDigest)
|
|
183
|
+
throw new Error('CONNECTION_NOT_PENDING');
|
|
184
|
+
if (Date.parse(offer.expiresAt) <= this.now())
|
|
185
|
+
throw new Error('CONNECTION_REQUEST_EXPIRED');
|
|
186
|
+
if (Date.parse(p.acceptedAt) < Date.parse(offer.createdAt) || Date.parse(p.acceptedAt) >= Date.parse(offer.expiresAt) ||
|
|
187
|
+
Date.parse(p.acceptedAt) > this.now() + DEFAULT_CLOCK_SKEW_MS)
|
|
188
|
+
throw new Error('INVALID_CONNECTION_ACCEPTED');
|
|
189
|
+
const acknowledgement = signConnectionAck({ type: 'ConnectionAck', v: 1, eventId: this.id(),
|
|
190
|
+
acceptedDigest: digest(frame.event), fromOwnerDid: this.options.owner.did, toOwnerDid: p.fromOwnerDid,
|
|
191
|
+
receivedAt: this.iso() }, this.options.owner);
|
|
192
|
+
await this.options.persistence.applyAccepted({ offer, accepted: frame.event,
|
|
193
|
+
acknowledgement, outbox: this.outbox({ requestId: frame.requestId, event: acknowledgement }, offer.expiresAt), now: this.now() });
|
|
194
|
+
const delivered = await this.flushOutbox();
|
|
195
|
+
return { requestId: frame.requestId, status: 'connected', ...(!delivered ? { code: 'CONNECTION_DELIVERY_PENDING' } : {}) };
|
|
196
|
+
}
|
|
197
|
+
if (Date.parse(p.receivedAt) > this.now() + DEFAULT_CLOCK_SKEW_MS)
|
|
198
|
+
throw new Error('INVALID_CONNECTION_ACK');
|
|
199
|
+
await this.options.persistence.acknowledge(frame.event, frame.requestId, this.now());
|
|
200
|
+
return { requestId: frame.requestId, status: 'acknowledged' };
|
|
201
|
+
}
|
|
202
|
+
async approve(envelope) {
|
|
203
|
+
const frame = openConnectionFrame(envelope, this.options.owner);
|
|
204
|
+
const request = this.checkRequest(frame), offer = await this.options.persistence.incoming(frame.requestId);
|
|
205
|
+
if (!offer || offer.requestDigest !== digest(request))
|
|
206
|
+
throw new Error('CONNECTION_NOT_PENDING');
|
|
207
|
+
if (!await this.inspect(envelope, request))
|
|
208
|
+
throw new Error('INSPECTION_INCOMPLETE');
|
|
209
|
+
const consent = await this.review('incoming', request);
|
|
210
|
+
// Explicit review retains first-use invitation binding; an already-bound invite
|
|
211
|
+
// can still receive separate owner consent without changing that binding.
|
|
212
|
+
const status = frame.inviteToken === undefined ? 'pending' : await this.accept(request, consent, frame.inviteToken);
|
|
213
|
+
if (status !== 'connected')
|
|
214
|
+
await this.accept(request, consent);
|
|
215
|
+
const delivered = await this.flushOutbox();
|
|
216
|
+
return { requestId: frame.requestId, status: 'connected', ...(!delivered ? { code: 'CONNECTION_DELIVERY_PENDING' } : {}) };
|
|
217
|
+
}
|
|
218
|
+
/** Retries only retained control notifications, each bounded by its original offer deadline. */
|
|
219
|
+
async flushOutbox() {
|
|
220
|
+
let delivered = true;
|
|
221
|
+
for (const entry of await this.options.persistence.listOutbox(this.now())) {
|
|
222
|
+
if (Date.parse(entry.deliveryDeadline) <= this.now())
|
|
223
|
+
continue;
|
|
224
|
+
try {
|
|
225
|
+
await this.options.transport.send(entry.relayUrl, retryConnectionEnvelope(entry.envelope, this.options.owner, this.now()));
|
|
226
|
+
await this.options.persistence.markSent(entry.id, this.now());
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
delivered = false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return delivered;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/** Both owners derive the same ID, with the smaller DID as the base. */
|
|
236
|
+
export function connectionIdFor(left, right) {
|
|
237
|
+
return 'connection_' + digest([left, right].sort()).slice(7);
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=connection-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-service.js","sourceRoot":"","sources":["../src/connection-service.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,8BAA8B,EAAE,4BAA4B,EAAE,qBAAqB,EACnF,MAAM,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,iBAAiB,EAC5E,qBAAqB,EAAE,WAAW,EAAE,wBAAwB,EAAE,uBAAuB,EACrF,qBAAqB,GACtB,MAAM,WAAW,CAAC;AAKnB,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAoH9G,oFAAoF;AACpF,MAAM,OAAO,iBAAiB;IAGC;IAFZ,GAAG,CAAe;IAClB,EAAE,CAAe;IAClC,YAA6B,OAAiC;QAAjC,YAAO,GAAP,OAAO,CAA0B;QAC5D,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;QACnC,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,UAAU,CAAC;QACnC,wBAAwB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACpD,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;YACrD,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,KAAK,CAAC,GAAG;YACxD,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,aAAa,KAAK,OAAO,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC1G,CAAC;IACD,YAAY,CAAC,IAAqB;QAChC,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG;YAC5F,IAAI,CAAC,OAAO,CAAC,aAAa,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAChG,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAChC,CAAC;IACO,GAAG,KAAa,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAC5D,KAAK,CAAC,MAAM,CAAC,MAAkD,EAAE,OAAkC;QACzG,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;QAC1C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC5F,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;QAC1B,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG;YACpF,YAAY,EAAE,CAAC,CAAC,YAAY,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;YACvF,aAAa,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACtD,IAAI,QAAQ,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC5D,8BAA8B,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC9C,OAAO,WAAW,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG;YACpF,aAAa,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5E,CAAC;IACO,MAAM,CAAC,KAAa,EAAE,aAAqB,EAAE,aAAsB;QACzE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,yFAAyF;QACzF,MAAM,MAAM,GAAG,yBAAyB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;QAChI,IAAI,MAAM,CAAC,QAAQ,KAAK,aAAa,IAAI,CAAC,aAAa,IAAI,MAAM,CAAC,QAAQ,KAAK,aAAa,CAAC;YACzF,MAAM,CAAC,QAAQ,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACzF,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC5D,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,GAAG;YAC/F,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACpC,OAAO,MAAM,CAAC;IAChB,CAAC;IACO,KAAK,CAAC,OAAkC,EAAE,QAAQ,GAAG,KAAK,EAAE,QAA0B;QAC5F,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;QAC1B,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY;YAC3F,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7H,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3H,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS;YAC/E,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAClE,CAAC;IACO,MAAM,CAAC,KAAsB,EAAE,QAAgB;QACrD,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,mBAAmB,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO;YAC3G,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,EAAE,QAAQ;YACvF,QAAQ,EAAE,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IACtF,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,KAEb;QACC,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAC9G,MAAM,QAAQ,GAAG,MAAM,EAAE,SAAS,IAAI,KAAK,CAAC,aAAa,CAAC;QAC1D,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,CAAC,qBAAqB,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;YAC/E,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,KAAK,KAAK,CAAC,UAAU;YACzD,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,aAAa,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ;YACnE,CAAC,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACjH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,qBAAqB,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE,CAAC,EAAE,eAAe,EAAE,OAAO;YAC/F,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU;YACxF,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;YACvG,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,GAAG,GAAG,4BAA4B,CAAC,CAAC,WAAW,EAAE;YACxF,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnD,GAAG,CAAC,KAAK,CAAC,oBAAoB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,KAAK,CAAC,oBAAoB,EAAE,CAAC;SAC1G,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACvB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACnF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO;YACrE,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QACrG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAClF,MAAM,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QACxE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,6BAA6B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC3H,CAAC;IACO,YAAY,CAAC,KAAsB;QACzC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAkC,CAAC;QACzD,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,UAAU,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG;YAC1F,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,aAAa,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ;YAC3E,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,8BAA8B,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACzG,IAAI,OAAO,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,WAAW;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QACtG,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC/G,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,YAAY;gBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QACrG,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,4FAA4F;IAC5F,eAAe,CAAC,QAAwB;QACtC,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChE,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,mBAAmB;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QACpG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IACO,KAAK,CAAC,OAAO,CAAC,QAAwB,EAAE,OAAkC;QAChF,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACxD,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,UAAU,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;YAChF,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACnH,IAAI,UAAU,CAAC;QACf,IAAI,CAAC;YAAC,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,KAAK,CAAC;QAAC,CAAC;QAC/E,OAAO,UAAU,EAAE,MAAM,KAAK,UAAU,IAAI,UAAU,CAAC,aAAa,KAAK,aAAa,CAAC;IACzF,CAAC;IACO,KAAK,CAAC,MAAM,CAAC,OAAkC,EAAE,OAA8C,EAAE,KAAc;QACrH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClC,8BAA8B,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,sBAAsB,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,EAAE,CAAC,EAAE,eAAe,EAAE,OAAO;YAClG,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa;YAC7J,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,CAAC,YAAY,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS;YAC9G,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7F,MAAM,MAAM,GAA+B,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;YACpF,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1F,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACnG,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC;gBAC7F,iBAAiB,EAAE,KAAK,CAAC,YAAY;gBACrC,cAAc,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YACpI,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,UAAU;gBAAE,OAAO,SAAS,CAAC;QACtE,CAAC;;YAAM,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC5D,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,gGAAgG;IAChG,KAAK,CAAC,OAAO,CAAC,QAAwB;QACpC,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;QACzF,IAAI,CAAC,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACzC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACvD,qEAAqE;YACrE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU;gBAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACxE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAChG,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;gBAC5B,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;gBACvD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC3C,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,6BAA6B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;YAC7H,CAAC;YACD,IAAI,QAAQ,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;gBAChD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,YAAa,EAAE,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;gBAChG,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;oBAC3B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;oBAC3C,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,6BAA6B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;gBAChH,CAAC;YACH,CAAC;YACD,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,wBAAwB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QAC7G,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACvE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,UAAU,KAAK,CAAC,CAAC,YAAY;gBAC9F,KAAK,CAAC,aAAa,KAAK,CAAC,CAAC,aAAa,IAAI,KAAK,CAAC,YAAY,KAAK,CAAC,CAAC,YAAY;gBAClF,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;YAC5C,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC7F,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC;gBACjH,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,qBAAqB;gBAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAClH,MAAM,eAAe,GAAG,iBAAiB,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzF,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC,YAAY;gBACrG,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAChD,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAmC;gBACvG,eAAe,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACpI,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3C,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,6BAA6B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAC7H,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,qBAAqB;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC7G,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,KAA8B,EAAE,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC9G,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IAChE,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,QAAwB;QACpC,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC3G,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,aAAa,KAAK,MAAM,CAAC,OAAO,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACjG,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACrF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACvD,gFAAgF;QAChF,0EAA0E;QAC1E,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QACpH,IAAI,MAAM,KAAK,WAAW;YAAE,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC3C,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,6BAA6B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC7H,CAAC;IACD,gGAAgG;IAChG,KAAK,CAAC,WAAW;QACf,IAAI,SAAS,GAAG,IAAI,CAAC;QACrB,KAAK,MAAM,KAAK,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;YAC1E,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE;gBAAE,SAAS;YAC/D,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,uBAAuB,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAC3H,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAChE,CAAC;YAAC,MAAM,CAAC;gBAAC,SAAS,GAAG,KAAK,CAAC;YAAC,CAAC;QAChC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;CACF;AAED,wEAAwE;AACxE,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,KAAa;IACzD,OAAO,aAAa,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ConnectionControl, KeyPair, Signed, SignedEnvelope } from '../../core/dist/index.js';
|
|
2
|
+
export interface ConnectionFrame {
|
|
3
|
+
requestId: string;
|
|
4
|
+
event: Signed<ConnectionControl>;
|
|
5
|
+
inviteToken?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ConnectionTransport {
|
|
8
|
+
send(relayUrl: string, envelope: SignedEnvelope): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
/** Owner-addressed control frames use a routing namespace independent of task sessions. */
|
|
11
|
+
export declare function sealConnectionFrame(frame: ConnectionFrame, owner: KeyPair, now: number, envelopeId?: string): SignedEnvelope;
|
|
12
|
+
export declare function openConnectionFrame(envelope: SignedEnvelope, owner: KeyPair): ConnectionFrame;
|
|
13
|
+
/** Retry the same signed notification with a fresh relay envelope ID. Inner consent stays unchanged. */
|
|
14
|
+
export declare function retryConnectionEnvelope(envelope: SignedEnvelope, owner: KeyPair, now: number): SignedEnvelope;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { canonicalize, connectionEventName, connectionRoutingId, encryptEnvelopePayload, isConnectionEvent, openEnvelope, signPayload, verifySigned, verifyConnectionRequest, verifyConnectionAccepted, verifyConnectionAck, } from '../../core/dist/index.js';
|
|
4
|
+
function validEvent(event) {
|
|
5
|
+
switch (event?.payload?.type) {
|
|
6
|
+
case 'ConnectionRequest': return verifyConnectionRequest(event);
|
|
7
|
+
case 'ConnectionAccepted': return verifyConnectionAccepted(event);
|
|
8
|
+
case 'ConnectionAck': return verifyConnectionAck(event);
|
|
9
|
+
default: return false;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function validateFrame(frame) {
|
|
13
|
+
if (!validEvent(frame.event)) {
|
|
14
|
+
const type = frame.event?.payload?.type;
|
|
15
|
+
throw new Error(type === 'ConnectionRequest' ? 'INVALID_CONNECTION_REQUEST'
|
|
16
|
+
: type === 'ConnectionAccepted' ? 'INVALID_CONNECTION_ACCEPTED'
|
|
17
|
+
: type === 'ConnectionAck' ? 'INVALID_CONNECTION_ACK' : 'INVALID_CONNECTION_CONTROL');
|
|
18
|
+
}
|
|
19
|
+
connectionRoutingId(frame.requestId);
|
|
20
|
+
const p = frame.event.payload;
|
|
21
|
+
if (p.type !== 'ConnectionAck' && p.requestId !== frame.requestId)
|
|
22
|
+
throw new Error('INVALID_CONNECTION_CONTROL');
|
|
23
|
+
if (frame.inviteToken !== undefined && (p.type !== 'ConnectionRequest' ||
|
|
24
|
+
typeof frame.inviteToken !== 'string' || frame.inviteToken.length > 68 * 1024 || !p.inviteDigest))
|
|
25
|
+
throw new Error('INVALID_CONNECTION_REQUEST');
|
|
26
|
+
}
|
|
27
|
+
/** Owner-addressed control frames use a routing namespace independent of task sessions. */
|
|
28
|
+
export function sealConnectionFrame(frame, owner, now, envelopeId = randomUUID()) {
|
|
29
|
+
validateFrame(frame);
|
|
30
|
+
const p = frame.event.payload;
|
|
31
|
+
if (p.fromOwnerDid !== owner.did)
|
|
32
|
+
throw new Error('INVALID_CONNECTION_CONTROL');
|
|
33
|
+
const header = {
|
|
34
|
+
taskId: connectionRoutingId(frame.requestId), seq: 0, eventType: connectionEventName(p),
|
|
35
|
+
senderDid: owner.did, recipientDid: p.toOwnerDid,
|
|
36
|
+
};
|
|
37
|
+
const body = p.type === 'ConnectionRequest'
|
|
38
|
+
? { request: frame.event, ...(frame.inviteToken === undefined ? {} : { inviteToken: frame.inviteToken }) }
|
|
39
|
+
: frame.event;
|
|
40
|
+
return signPayload({
|
|
41
|
+
type: 'SignedEnvelope', envelopeId, ...header,
|
|
42
|
+
payload: encryptEnvelopePayload(body, header),
|
|
43
|
+
}, owner, new Date(now).toISOString());
|
|
44
|
+
}
|
|
45
|
+
export function openConnectionFrame(envelope, owner) {
|
|
46
|
+
try {
|
|
47
|
+
const h = envelope.payload;
|
|
48
|
+
if (!isConnectionEvent(h.eventType) || h.type !== 'SignedEnvelope' || h.seq !== 0 ||
|
|
49
|
+
h.recipientDid !== owner.did || !h.taskId.startsWith('conn_') || !h.envelopeId ||
|
|
50
|
+
!verifySigned(envelope, h.senderDid) ||
|
|
51
|
+
Object.keys(envelope).sort().join() !== 'payload,signature' ||
|
|
52
|
+
Object.keys(envelope.signature).sort().join() !== 'canonicalization,payloadDigest,signature,signedAt,signerDid' ||
|
|
53
|
+
Object.keys(h).sort().join() !== 'envelopeId,eventType,payload,recipientDid,senderDid,seq,taskId,type' ||
|
|
54
|
+
Buffer.byteLength(canonicalize(envelope)) > 256 * 1024)
|
|
55
|
+
throw new Error();
|
|
56
|
+
const body = openEnvelope(envelope, owner);
|
|
57
|
+
let event, inviteToken;
|
|
58
|
+
if (h.eventType === 'CONNECTION_REQUEST') {
|
|
59
|
+
const b = body;
|
|
60
|
+
if (!b || Object.keys(b).some((k) => k !== 'request' && k !== 'inviteToken'))
|
|
61
|
+
throw new Error();
|
|
62
|
+
event = b.request;
|
|
63
|
+
inviteToken = b.inviteToken;
|
|
64
|
+
}
|
|
65
|
+
else
|
|
66
|
+
event = body;
|
|
67
|
+
const frame = { requestId: h.taskId.slice(5), event,
|
|
68
|
+
...(inviteToken === undefined ? {} : { inviteToken }) };
|
|
69
|
+
validateFrame(frame);
|
|
70
|
+
if (connectionEventName(event.payload) !== h.eventType || event.payload.fromOwnerDid !== h.senderDid ||
|
|
71
|
+
event.payload.toOwnerDid !== h.recipientDid)
|
|
72
|
+
throw new Error();
|
|
73
|
+
return frame;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
if (error instanceof Error && ['UNENCRYPTED_ENVELOPE_REJECTED', 'INVALID_CONNECTION_REQUEST',
|
|
77
|
+
'INVALID_CONNECTION_ACCEPTED', 'INVALID_CONNECTION_ACK'].includes(error.message))
|
|
78
|
+
throw error;
|
|
79
|
+
throw new Error('INVALID_CONNECTION_CONTROL');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Retry the same signed notification with a fresh relay envelope ID. Inner consent stays unchanged. */
|
|
83
|
+
export function retryConnectionEnvelope(envelope, owner, now) {
|
|
84
|
+
if (envelope.payload.senderDid !== owner.did || !isConnectionEvent(envelope.payload.eventType) ||
|
|
85
|
+
!verifySigned(envelope, owner.did))
|
|
86
|
+
throw new Error('INVALID_CONNECTION_CONTROL');
|
|
87
|
+
return signPayload({ ...envelope.payload, envelopeId: randomUUID() }, owner, new Date(now).toISOString());
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=connection-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-transport.js","sourceRoot":"","sources":["../src/connection-transport.ts"],"names":[],"mappings":"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"}
|