p2party 0.14.2 → 0.14.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +230 -30
- package/docs/getting-started.md +15 -0
- package/docs/protocol-v4-security.md +40 -0
- package/docs/references.md +28 -8
- package/docs/session-api.md +10 -2
- package/lib/api/signalingServerApi.d.ts +13 -2
- package/lib/api/webrtc/applyIceConfiguration.d.ts +9 -0
- package/lib/api/webrtc/dataChannelHandler.d.ts +10 -0
- package/lib/api/webrtc/deleteRoomData.d.ts +13 -0
- package/lib/api/webrtc/disconnectFromAllRoomsQuery.d.ts +2 -1
- package/lib/api/webrtc/disconnectFromRoomQuery.d.ts +2 -1
- package/lib/api/webrtc/disconnectQuery.d.ts +2 -1
- package/lib/api/webrtc/iceRepair.d.ts +3 -1
- package/lib/api/webrtc/index.d.ts +2 -1
- package/lib/api/webrtc/interfaces.d.ts +37 -0
- package/lib/api/webrtc/negotiationLock.d.ts +24 -0
- package/lib/api/webrtc/pendingOffer.d.ts +29 -0
- package/lib/api/webrtc/rebindDeadline.d.ts +61 -0
- package/lib/api/webrtc/remoteTransportChange.d.ts +142 -0
- package/lib/api/webrtc/retiredRemoteTransports.d.ts +70 -0
- package/lib/api/webrtc/roomEdgeBudget.d.ts +10 -0
- package/lib/api/webrtc/setDescriptionQuery.d.ts +8 -1
- package/lib/api/webrtc/settleOnClose.d.ts +36 -0
- package/lib/blindRendezvous/admissionInput.d.ts +11 -0
- package/lib/blindRendezvous/admissionPolicy.d.ts +217 -0
- package/lib/blindRendezvous/canonicalSchema.d.ts +139 -0
- package/lib/blindRendezvous/carrierEnvelope.d.ts +105 -0
- package/lib/blindRendezvous/coreReduce.d.ts +199 -0
- package/lib/blindRendezvous/derivations.d.ts +381 -0
- package/lib/blindRendezvous/identityHelloAdmission.d.ts +89 -0
- package/lib/blindRendezvous/identityHelloAdmissionPersistence.d.ts +133 -0
- package/lib/blindRendezvous/identityHelloHistoricalEvidence.d.ts +52 -0
- package/lib/blindRendezvous/identityHelloOpen.d.ts +167 -0
- package/lib/blindRendezvous/identityHelloTrial.d.ts +271 -0
- package/lib/blindRendezvous/localAdmissibleProject.d.ts +101 -0
- package/lib/blindRendezvous/localPresenceKeyBinding.d.ts +108 -0
- package/lib/blindRendezvous/localStableIdentityCustody.d.ts +46 -0
- package/lib/blindRendezvous/normativeKernel.d.ts +222 -0
- package/lib/blindRendezvous/operation.d.ts +137 -0
- package/lib/blindRendezvous/operationPayload.d.ts +134 -0
- package/lib/blindRendezvous/pairBootstrapSuite.d.ts +93 -0
- package/lib/blindRendezvous/pairCrypto.d.ts +122 -0
- package/lib/blindRendezvous/pairLedger.d.ts +154 -0
- package/lib/blindRendezvous/pairOpenBudget.d.ts +67 -0
- package/lib/blindRendezvous/pairOpenReservation.d.ts +157 -0
- package/lib/blindRendezvous/pairPlaintext.d.ts +240 -0
- package/lib/blindRendezvous/pairStepEnvelope.d.ts +60 -0
- package/lib/blindRendezvous/plannerState.d.ts +61 -0
- package/lib/blindRendezvous/projections.d.ts +71 -0
- package/lib/blindRendezvous/publicWindow.d.ts +330 -0
- package/lib/blindRendezvous/retainedOperationStore.d.ts +187 -0
- package/lib/blindRendezvous/roomInviteV2.d.ts +92 -0
- package/lib/blindRendezvous/roomPolicyV4.d.ts +90 -0
- package/lib/blindRendezvous/schemas.d.ts +221 -0
- package/lib/blindRendezvous/storeDescriptor.d.ts +160 -0
- package/lib/cryptography/aeadWasm.d.ts +18 -0
- package/lib/cryptography/byteInput.d.ts +12 -0
- package/lib/cryptography/carrierAead.d.ts +23 -0
- package/lib/cryptography/chacha20poly1305.d.ts +7 -0
- package/lib/cryptography/fips202.d.ts +10 -0
- package/lib/cryptography/hpke.d.ts +84 -0
- package/lib/cryptography/hpkeSuite.d.ts +39 -0
- package/lib/cryptography/hybridKem.d.ts +42 -0
- package/lib/cryptography/hybridKemSuite.d.ts +22 -0
- package/lib/cryptography/interfaces.d.ts +3 -0
- package/lib/cryptography/mlkem.d.ts +27 -1
- package/lib/cryptography/mnemonic.d.ts +65 -1
- package/lib/cryptography/ownedEd25519KeyMaterial.d.ts +27 -0
- package/lib/cryptography/webCryptoSha256.d.ts +20 -0
- package/lib/cryptography/x25519.d.ts +18 -0
- package/lib/cryptography/xchacha20poly1305.d.ts +7 -0
- package/lib/db/api.d.ts +6 -3
- package/lib/db/identityEd25519ClientBoundary.d.ts +13 -0
- package/lib/db/src/getDB.d.ts +2 -2
- package/lib/db/types.d.ts +52 -4
- package/lib/db.worker.js +1 -1
- package/lib/handlers/coverChannelRegistry.d.ts +22 -0
- package/lib/handlers/edgeTeardownFollowUp.d.ts +35 -0
- package/lib/handlers/handleChallenge.d.ts +2 -1
- package/lib/handlers/handleConnectToPeer.d.ts +1 -1
- package/lib/handlers/handleHandshake.d.ts +2 -6
- package/lib/handlers/handleSendMessage.d.ts +60 -7
- package/lib/handlers/handleWebSocketMessage.d.ts +1 -1
- package/lib/handlers/handshakeCore.d.ts +2 -7
- package/lib/handlers/handshakeFrame.d.ts +25 -0
- package/lib/handlers/ratchetGateWait.d.ts +13 -0
- package/lib/handlers/reconcile.d.ts +24 -0
- package/lib/handlers/requestRoom.d.ts +30 -0
- package/lib/handlers/roomResponse.d.ts +53 -0
- package/lib/index.d.ts +99 -12
- package/lib/index.js +1 -1
- package/lib/index.min.js +1 -1
- package/lib/index.mjs +1 -1
- package/lib/libcrypto.provenance.json +5 -5
- package/lib/libcrypto.wasm +0 -0
- package/lib/middleware/roomListenerMiddleware.d.ts +4 -1
- package/lib/reducers/commonSlice.d.ts +3 -2
- package/lib/reducers/keyPairSlice.d.ts +3 -6
- package/lib/reducers/roomSlice.d.ts +81 -5
- package/lib/reducers/signalingServerSlice.d.ts +3 -2
- package/lib/session.d.ts +6 -3
- package/lib/session.js +1 -1
- package/lib/session.mjs +1 -1
- package/lib/store.d.ts +4 -2
- package/lib/utils/constants.d.ts +12 -0
- package/lib/utils/correlationId.d.ts +4 -0
- package/lib/utils/identityRestore.d.ts +108 -0
- package/lib/utils/interfaces.d.ts +25 -6
- package/lib/utils/roomConnectAdmission.d.ts +15 -0
- package/lib/utils/roomLeaveCoordinator.d.ts +38 -0
- package/lib/utils/roomRequestCoordinator.d.ts +104 -0
- package/lib/utils/roomRosterReconciler.d.ts +83 -0
- package/lib/utils/sdpFingerprint.d.ts +6 -0
- package/lib/utils/signalingAttemptLifecycle.d.ts +33 -0
- package/lib/utils/signalingAuth.d.ts +21 -2
- package/lib/utils/signalingBounds.d.ts +6 -0
- package/lib/utils/signalingFrame.d.ts +21 -0
- package/lib/utils/signalingHeartbeatWatchdog.d.ts +45 -0
- package/lib/utils/signalingIngressQueue.d.ts +49 -0
- package/lib/utils/signalingPeerRequestDebouncer.d.ts +13 -0
- package/lib/utils/signalingRoomLifecycle.d.ts +7 -0
- package/lib/utils/signalingRoomOperationLifecycle.d.ts +14 -0
- package/lib/utils/signalingServerBoundary.d.ts +11 -0
- package/lib/utils/terminalSettlement.d.ts +53 -0
- package/lib/utils/transportIdentity.d.ts +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pair-bootstrap HPKE and established-flight AEAD (Section 4.11).
|
|
3
|
+
*
|
|
4
|
+
* This module owns only cryptographic sealing/opening and exact transcript
|
|
5
|
+
* binding. It deliberately does not own one-use routing-tag consumption,
|
|
6
|
+
* predecessor/dependency state, identity/admission decisions, persistence, or
|
|
7
|
+
* SDP dispatch. Those effectful gates consume this module's authenticated
|
|
8
|
+
* output and must commit their state before exposing it to WebRTC.
|
|
9
|
+
*/
|
|
10
|
+
import type { LibCrypto } from "../cryptography/libcrypto";
|
|
11
|
+
import type { RoomPqMode } from "../roomPolicy";
|
|
12
|
+
import type { OperationPayloadClassV1 } from "./operation";
|
|
13
|
+
import type { PairBootstrapInfoV1, PairFlightSlotV1, PairOuterBindingV1, PairOuterPrebindingV1, PairPlaintextV1 } from "./pairPlaintext";
|
|
14
|
+
import type { PairStepEnvelopeV1 } from "./pairStepEnvelope";
|
|
15
|
+
export declare class PairCryptoError extends Error {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
constructor(message: string);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A bootstrap plaintext authenticated under one HPKE info value but carrying
|
|
21
|
+
* another identity-flight kind. Recipients may classify this exact
|
|
22
|
+
* peer-authenticated protocol fault without parsing an error message.
|
|
23
|
+
*/
|
|
24
|
+
export declare class PairBootstrapPlaintextKindError extends PairCryptoError {
|
|
25
|
+
readonly name = "PairBootstrapPlaintextKindError";
|
|
26
|
+
constructor();
|
|
27
|
+
}
|
|
28
|
+
export type PairBootstrapOuterFieldsV1 = Omit<PairOuterPrebindingV1, "bootstrapHeaderHash" | "nonce">;
|
|
29
|
+
export interface PairBootstrapSealOptionsV1 {
|
|
30
|
+
readonly module: LibCrypto;
|
|
31
|
+
readonly recipientHybridKemPublicKey: Uint8Array;
|
|
32
|
+
/** RoomRoot for HELLO or the validated HelloRoot for ACCEPT. */
|
|
33
|
+
readonly psk: Uint8Array;
|
|
34
|
+
readonly bootstrapInfo: PairBootstrapInfoV1;
|
|
35
|
+
readonly outerFields: PairBootstrapOuterFieldsV1;
|
|
36
|
+
readonly roomPqMode: RoomPqMode;
|
|
37
|
+
/**
|
|
38
|
+
* Called only after the HPKE header, one-use tag, and exact outer binding
|
|
39
|
+
* exist, allowing the stable identity signature to cover that binding.
|
|
40
|
+
*/
|
|
41
|
+
readonly createSignedPlaintext: (binding: PairOuterBindingV1) => PairPlaintextV1 | Promise<PairPlaintextV1>;
|
|
42
|
+
}
|
|
43
|
+
export interface PairBootstrapSealResultV1 {
|
|
44
|
+
readonly envelope: PairStepEnvelopeV1;
|
|
45
|
+
readonly binding: PairOuterBindingV1;
|
|
46
|
+
readonly plaintext: PairPlaintextV1;
|
|
47
|
+
/**
|
|
48
|
+
* HelloRoot or AcceptRoot. The caller owns these bytes and must wipe them
|
|
49
|
+
* after deriving/persisting the next protected state.
|
|
50
|
+
*/
|
|
51
|
+
readonly bootstrapRoot: Uint8Array;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Seal one HELLO or ACCEPT. Normal encapsulation always uses the hybrid KEM's
|
|
55
|
+
* CSPRNG path; deterministic conformance hooks are intentionally unreachable
|
|
56
|
+
* from this protocol API.
|
|
57
|
+
*/
|
|
58
|
+
export declare const sealPairBootstrapV1: (options: PairBootstrapSealOptionsV1) => Promise<PairBootstrapSealResultV1>;
|
|
59
|
+
export interface PairBootstrapOpenOptionsV1 {
|
|
60
|
+
readonly module: LibCrypto;
|
|
61
|
+
readonly recipientHybridKemSecretKey: Uint8Array;
|
|
62
|
+
readonly psk: Uint8Array;
|
|
63
|
+
readonly bootstrapInfo: PairBootstrapInfoV1;
|
|
64
|
+
readonly prebinding: PairOuterPrebindingV1;
|
|
65
|
+
readonly envelope: PairStepEnvelopeV1;
|
|
66
|
+
readonly operationPayloadClass: OperationPayloadClassV1;
|
|
67
|
+
readonly roomPqMode: RoomPqMode;
|
|
68
|
+
/**
|
|
69
|
+
* The trusted pair-state layer verifies the stable transcript signature,
|
|
70
|
+
* identity/commitment binding, exact presences, and state-owned slot before
|
|
71
|
+
* the bootstrap root is released.
|
|
72
|
+
*/
|
|
73
|
+
readonly validateAuthenticatedPlaintext: (binding: PairOuterBindingV1, plaintext: PairPlaintextV1) => void | Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
export interface PairBootstrapOpenResultV1 {
|
|
76
|
+
readonly binding: PairOuterBindingV1;
|
|
77
|
+
readonly plaintext: PairPlaintextV1;
|
|
78
|
+
readonly bootstrapRoot: Uint8Array;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Try one budgeted HELLO/ACCEPT receiver key and expected info candidate.
|
|
82
|
+
*
|
|
83
|
+
* A routing-tag or HPKE authentication mismatch is `null` (not this
|
|
84
|
+
* candidate). Authenticated noncanonical/invalid pair plaintext throws and
|
|
85
|
+
* must be accounted as a rejected pair attempt by the caller.
|
|
86
|
+
*/
|
|
87
|
+
export declare const openPairBootstrapV1: (options: PairBootstrapOpenOptionsV1) => Promise<PairBootstrapOpenResultV1 | null>;
|
|
88
|
+
export interface SealPairStepOptionsV1 {
|
|
89
|
+
readonly module: LibCrypto;
|
|
90
|
+
/** EstablishedPairRoot before promotion, one-use PqSlotSecret afterwards. */
|
|
91
|
+
readonly baseSecret: Uint8Array;
|
|
92
|
+
readonly expectedSlot: PairFlightSlotV1;
|
|
93
|
+
readonly prebinding: PairOuterPrebindingV1;
|
|
94
|
+
readonly plaintext: PairPlaintextV1;
|
|
95
|
+
readonly roomPqMode: RoomPqMode;
|
|
96
|
+
}
|
|
97
|
+
export interface SealPairStepResultV1 {
|
|
98
|
+
readonly envelope: PairStepEnvelopeV1;
|
|
99
|
+
readonly binding: PairOuterBindingV1;
|
|
100
|
+
readonly plaintext: PairPlaintextV1;
|
|
101
|
+
}
|
|
102
|
+
/** Seal one non-HPKE pair flight under the exact suite-1 DRY construction. */
|
|
103
|
+
export declare const sealPairStepV1: (options: SealPairStepOptionsV1) => Promise<SealPairStepResultV1>;
|
|
104
|
+
export interface OpenPairStepOptionsV1 {
|
|
105
|
+
readonly module: LibCrypto;
|
|
106
|
+
readonly baseSecret: Uint8Array;
|
|
107
|
+
/** One member of the closed candidate-slot set selected by pair state. */
|
|
108
|
+
readonly expectedSlot: PairFlightSlotV1;
|
|
109
|
+
readonly prebinding: PairOuterPrebindingV1;
|
|
110
|
+
readonly envelope: PairStepEnvelopeV1;
|
|
111
|
+
readonly operationPayloadClass: OperationPayloadClassV1;
|
|
112
|
+
readonly roomPqMode: RoomPqMode;
|
|
113
|
+
}
|
|
114
|
+
export interface OpenPairStepResultV1 {
|
|
115
|
+
readonly binding: PairOuterBindingV1;
|
|
116
|
+
readonly plaintext: PairPlaintextV1;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Try one state-selected established-flight slot. A tag/authentication
|
|
120
|
+
* mismatch is `null`; authenticated slot/body/padding disagreement throws.
|
|
121
|
+
*/
|
|
122
|
+
export declare const openPairStepV1: (options: OpenPairStepOptionsV1) => Promise<OpenPairStepResultV1 | null>;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure accepted-slot ledger for pair-private operations.
|
|
3
|
+
*
|
|
4
|
+
* This boundary starts only after pair opening has authenticated an operation
|
|
5
|
+
* and checked its state-derived inner slot. Invalid tag/AEAD trials therefore
|
|
6
|
+
* never consume a slot or routing tag here. Persistence, budgets, pair-machine
|
|
7
|
+
* state, WebRTC effects, and response publication remain outside this module.
|
|
8
|
+
*
|
|
9
|
+
* The coordinate deliberately excludes `kind`: two authenticated kinds at
|
|
10
|
+
* the same edge/endpoint/direction/sequence coordinate are a fork. Consumed
|
|
11
|
+
* routing tags and retained fork-stall evidence are projections of entries,
|
|
12
|
+
* never separately mutable state. The pair machine separately owns overall
|
|
13
|
+
* edge status, including non-fork failures and causal expiry.
|
|
14
|
+
*/
|
|
15
|
+
import type { PairAuthorChainPrefixEvidenceV1 } from "./coreReduce";
|
|
16
|
+
import type { PairStepKindV1 } from "./pairPlaintext";
|
|
17
|
+
declare const pairAcceptedSlotLedgerBrand: unique symbol;
|
|
18
|
+
/** Process-local immutable ledger handle. Persist only its canonical snapshot. */
|
|
19
|
+
export interface PairAcceptedSlotLedgerV1 {
|
|
20
|
+
readonly [pairAcceptedSlotLedgerBrand]: true;
|
|
21
|
+
}
|
|
22
|
+
export interface PairAcceptedSlotCoordinateV1 {
|
|
23
|
+
readonly pairEdgeId: Uint8Array;
|
|
24
|
+
readonly endpointPresenceOperationIds: readonly [Uint8Array, Uint8Array];
|
|
25
|
+
readonly direction: 0 | 1;
|
|
26
|
+
readonly pairSequence: bigint;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Structural input for the post-authentication boundary.
|
|
30
|
+
*
|
|
31
|
+
* Production pair ingress must construct this only from its opaque successful
|
|
32
|
+
* open result. This ledger owns and validates the shape but does not itself
|
|
33
|
+
* prove pair AEAD, signatures, bindings, or operation-ID derivation.
|
|
34
|
+
*/
|
|
35
|
+
export interface PairSlotAcceptanceCandidateV1 {
|
|
36
|
+
readonly coordinate: PairAcceptedSlotCoordinateV1;
|
|
37
|
+
readonly kind: PairStepKindV1;
|
|
38
|
+
readonly acceptedOperationId: Uint8Array;
|
|
39
|
+
readonly exactOperationBytes: Uint8Array;
|
|
40
|
+
readonly acceptedLogicalWindow: bigint;
|
|
41
|
+
readonly retainThroughLogicalWindow: bigint;
|
|
42
|
+
readonly routingTag: Uint8Array;
|
|
43
|
+
readonly authorChainPrefix: readonly PairAuthorChainPrefixEvidenceV1[];
|
|
44
|
+
readonly cachedExactResponse: Uint8Array | null;
|
|
45
|
+
}
|
|
46
|
+
export interface PairAcceptedSlotEntryV1 extends PairSlotAcceptanceCandidateV1 {
|
|
47
|
+
readonly version: 1;
|
|
48
|
+
/**
|
|
49
|
+
* A null cached response is durable only for a locally denied
|
|
50
|
+
* IDENTITY_HELLO or terminal PAIR_CHECKPOINT. The former still reserves its
|
|
51
|
+
* authenticated slot so a later conflicting HELLO cannot win by arrival.
|
|
52
|
+
*/
|
|
53
|
+
readonly cachedExactResponse: Uint8Array | null;
|
|
54
|
+
/**
|
|
55
|
+
* Bytewise-lowest two distinct authenticated IDs observed at this
|
|
56
|
+
* coordinate. These are a bounded fork-evidence index; the validated outer
|
|
57
|
+
* operation store remains the SSOT for the referenced signed bytes.
|
|
58
|
+
*/
|
|
59
|
+
readonly forkProofOperationIds: readonly [Uint8Array, Uint8Array] | null;
|
|
60
|
+
}
|
|
61
|
+
/** Durable, deeply owned structural representation. */
|
|
62
|
+
export interface PairAcceptedSlotLedgerSnapshotV1 {
|
|
63
|
+
readonly version: 1;
|
|
64
|
+
readonly entries: readonly PairAcceptedSlotEntryV1[];
|
|
65
|
+
}
|
|
66
|
+
export type PairAcceptedSlotTransitionV1 = {
|
|
67
|
+
readonly result: "accepted";
|
|
68
|
+
readonly ledger: PairAcceptedSlotLedgerV1;
|
|
69
|
+
} | {
|
|
70
|
+
readonly result: "replay";
|
|
71
|
+
/** Exact cached bytes are freshly owned by this result. */
|
|
72
|
+
readonly cachedExactResponse: Uint8Array | null;
|
|
73
|
+
/** Replay is a no-op and preserves handle identity. */
|
|
74
|
+
readonly ledger: PairAcceptedSlotLedgerV1;
|
|
75
|
+
} | {
|
|
76
|
+
readonly result: "fork";
|
|
77
|
+
readonly forkProofOperationIds: readonly [Uint8Array, Uint8Array];
|
|
78
|
+
readonly ledger: PairAcceptedSlotLedgerV1;
|
|
79
|
+
} | {
|
|
80
|
+
readonly result: "edge-stalled";
|
|
81
|
+
readonly ledger: PairAcceptedSlotLedgerV1;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Read-only classification at the authenticated pair-slot boundary.
|
|
85
|
+
*
|
|
86
|
+
* `unoccupied` is deliberately not called `accepted`: no durable entry or
|
|
87
|
+
* fork proof exists until `recordAcceptedPairSlotV1` succeeds.
|
|
88
|
+
*/
|
|
89
|
+
export type AuthenticatedPairSlotPreviewV1 = {
|
|
90
|
+
readonly result: "unoccupied";
|
|
91
|
+
} | {
|
|
92
|
+
readonly result: "replay";
|
|
93
|
+
/** Exact cached bytes are freshly owned by this result. */
|
|
94
|
+
readonly cachedExactResponse: Uint8Array | null;
|
|
95
|
+
} | {
|
|
96
|
+
readonly result: "fork";
|
|
97
|
+
readonly forkProofOperationIds: readonly [Uint8Array, Uint8Array];
|
|
98
|
+
} | {
|
|
99
|
+
readonly result: "edge-stalled";
|
|
100
|
+
};
|
|
101
|
+
export declare class PairLedgerError extends Error {
|
|
102
|
+
readonly name = "PairLedgerError";
|
|
103
|
+
constructor(message: string);
|
|
104
|
+
}
|
|
105
|
+
/** Create the unique empty ledger value. */
|
|
106
|
+
export declare const createEmptyPairAcceptedSlotLedgerV1: () => PairAcceptedSlotLedgerV1;
|
|
107
|
+
/** Deep-copy the complete state for the durable transaction adapter. */
|
|
108
|
+
export declare const snapshotPairAcceptedSlotLedgerV1: (ledger: PairAcceptedSlotLedgerV1) => PairAcceptedSlotLedgerSnapshotV1;
|
|
109
|
+
/** Canonical durable bytes for one genuine process-local ledger. */
|
|
110
|
+
export declare const encodePairAcceptedSlotLedgerV1: (ledger: PairAcceptedSlotLedgerV1) => Uint8Array;
|
|
111
|
+
/**
|
|
112
|
+
* Strict structural reconstruction boundary.
|
|
113
|
+
*
|
|
114
|
+
* This restores ledger shape and invariants, not cryptographic provenance.
|
|
115
|
+
* The durable pair transaction must revalidate exact accepted operation bytes
|
|
116
|
+
* and pair state before using a restored ledger for protocol effects.
|
|
117
|
+
*/
|
|
118
|
+
export declare const restorePairAcceptedSlotLedgerV1: (snapshotValue: unknown) => PairAcceptedSlotLedgerV1;
|
|
119
|
+
/**
|
|
120
|
+
* Strict canonical durable-byte reconstruction.
|
|
121
|
+
*
|
|
122
|
+
* This restores structural ledger invariants only. The trusted pair
|
|
123
|
+
* transaction must still revalidate the retained signed operation bytes
|
|
124
|
+
* before the restored handle can authorize protocol effects.
|
|
125
|
+
*/
|
|
126
|
+
export declare const decodePairAcceptedSlotLedgerV1: (encoded: Uint8Array) => PairAcceptedSlotLedgerV1;
|
|
127
|
+
/**
|
|
128
|
+
* Classify one fully authenticated candidate without creating any durable
|
|
129
|
+
* entry, fork proof, consumed-tag projection, or replacement ledger handle.
|
|
130
|
+
*
|
|
131
|
+
* A new IDENTITY_HELLO may be previewed with a null cached response so the
|
|
132
|
+
* caller can run admission and construct that response. The subsequent record
|
|
133
|
+
* call revalidates the candidate and requires the exact response atomically.
|
|
134
|
+
*/
|
|
135
|
+
export declare const previewAuthenticatedPairSlotV1: (ledger: PairAcceptedSlotLedgerV1, candidateValue: PairSlotAcceptanceCandidateV1) => AuthenticatedPairSlotPreviewV1;
|
|
136
|
+
export declare const recordAcceptedPairSlotV1: (ledger: PairAcceptedSlotLedgerV1, candidateValue: PairSlotAcceptanceCandidateV1) => PairAcceptedSlotTransitionV1;
|
|
137
|
+
/**
|
|
138
|
+
* Persist a stable-signature-valid HELLO that current local policy denies.
|
|
139
|
+
*
|
|
140
|
+
* Denial sends no sensitive response, so an exact replay remains a null
|
|
141
|
+
* response. Reserving the authenticated slot is nevertheless load-bearing:
|
|
142
|
+
* a later byte-different HELLO at the same coordinate is a fork rather than
|
|
143
|
+
* an arrival-order winner. Only the trusted admission transaction may call
|
|
144
|
+
* this after its sole policy kernel returns deny.
|
|
145
|
+
*/
|
|
146
|
+
export declare const recordDeniedIdentityHelloSlotV1: (ledger: PairAcceptedSlotLedgerV1, candidateValue: PairSlotAcceptanceCandidateV1) => PairAcceptedSlotTransitionV1;
|
|
147
|
+
/** True exactly while retained fork evidence stalls this edge. */
|
|
148
|
+
export declare const pairEdgeIsStalledV1: (ledger: PairAcceptedSlotLedgerV1, pairEdgeId: Uint8Array) => boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Canonical unique routing-tag projection. There is intentionally no
|
|
151
|
+
* separately persisted consumed-tag collection.
|
|
152
|
+
*/
|
|
153
|
+
export declare const consumedPairRoutingTagsV1: (ledger: PairAcceptedSlotLedgerV1) => readonly Uint8Array[];
|
|
154
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure durable pair-open work-budget reducer.
|
|
3
|
+
*
|
|
4
|
+
* The effectful transaction layer derives one charge from a genuine active
|
|
5
|
+
* PAIR_STEP, calls this reducer, compare-and-swaps the returned row together
|
|
6
|
+
* with the exact Core/pair-state revisions, and only then mints a one-use
|
|
7
|
+
* cryptographic trial capability. This module deliberately cannot authorize
|
|
8
|
+
* crypto work by itself.
|
|
9
|
+
*/
|
|
10
|
+
export interface PairOpenBudgetCoordinateV1 {
|
|
11
|
+
readonly localRoomId: string;
|
|
12
|
+
readonly localPresenceOperationId: Uint8Array;
|
|
13
|
+
readonly budgetLogicalWindow: bigint;
|
|
14
|
+
}
|
|
15
|
+
export interface PairOpenBudgetSnapshotV1 {
|
|
16
|
+
readonly version: 1;
|
|
17
|
+
readonly coordinate: PairOpenBudgetCoordinateV1;
|
|
18
|
+
readonly budgetRevision: bigint;
|
|
19
|
+
readonly reservedTrialCount: number;
|
|
20
|
+
readonly reservedEnvelopeBytes: bigint;
|
|
21
|
+
readonly saturated: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Higher layers derive this from an opaque active-operation handle. In
|
|
25
|
+
* particular, `completeEnvelopeBytes` is the exact validated fixed payload
|
|
26
|
+
* length and is never a transport- or caller-reported estimate.
|
|
27
|
+
*/
|
|
28
|
+
export interface PairOpenBudgetChargeV1 {
|
|
29
|
+
readonly localRoomId: string;
|
|
30
|
+
readonly localPresenceOperationId: Uint8Array;
|
|
31
|
+
readonly capturedReferenceWindow: bigint;
|
|
32
|
+
readonly completeEnvelopeBytes: number;
|
|
33
|
+
}
|
|
34
|
+
export interface PairOpenBudgetLimitsV1 {
|
|
35
|
+
readonly maxPairOpenTrialsPerPresenceWindow: number;
|
|
36
|
+
readonly maxPairOpenBytesPerPresenceWindow: number;
|
|
37
|
+
}
|
|
38
|
+
export type PairOpenBudgetTransitionV1 = {
|
|
39
|
+
readonly result: "prepared";
|
|
40
|
+
/** Must be durably committed before any cryptographic work begins. */
|
|
41
|
+
readonly next: PairOpenBudgetSnapshotV1;
|
|
42
|
+
} | {
|
|
43
|
+
readonly result: "saturated";
|
|
44
|
+
/**
|
|
45
|
+
* Non-null on the first saturation (or a new-window reset) and must be
|
|
46
|
+
* committed. Null means the persisted row was already sticky-saturated.
|
|
47
|
+
*/
|
|
48
|
+
readonly next: PairOpenBudgetSnapshotV1 | null;
|
|
49
|
+
};
|
|
50
|
+
export declare class PairOpenBudgetError extends Error {
|
|
51
|
+
readonly name = "PairOpenBudgetError";
|
|
52
|
+
constructor(message: string);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Apply one actual expensive-trial charge.
|
|
56
|
+
*
|
|
57
|
+
* Equal/older captured windows reuse the durable counters. Only a strictly
|
|
58
|
+
* newer captured Core reference window resets them, and reset plus charge is
|
|
59
|
+
* represented by one replacement row. Repeating crypto work repeats charge.
|
|
60
|
+
*/
|
|
61
|
+
export declare const reducePairOpenBudgetV1: (previousValue: PairOpenBudgetSnapshotV1 | null, chargeValue: PairOpenBudgetChargeV1, limitsValue: PairOpenBudgetLimitsV1) => PairOpenBudgetTransitionV1;
|
|
62
|
+
/** Strictly own and validate one row read from durable storage. */
|
|
63
|
+
export declare const validatePairOpenBudgetSnapshotV1: (value: unknown) => PairOpenBudgetSnapshotV1;
|
|
64
|
+
/** Canonical durable bytes after complete structural and reachability checks. */
|
|
65
|
+
export declare const encodePairOpenBudgetSnapshotV1: (value: unknown) => Uint8Array;
|
|
66
|
+
/** Strictly restore and own one canonical durable budget row. */
|
|
67
|
+
export declare const decodePairOpenBudgetSnapshotV1: (bytes: Uint8Array) => PairOpenBudgetSnapshotV1;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Effectful pair-open budget reservation boundary.
|
|
3
|
+
*
|
|
4
|
+
* The pure reducer in pairOpenBudget.ts describes the next durable row. This
|
|
5
|
+
* module is the only bridge from that structural transition to permission for
|
|
6
|
+
* one expensive identity-HELLO open: it derives every coordinate and fence
|
|
7
|
+
* from opaque provenance, commits the exact row with one storage CAS, and only
|
|
8
|
+
* then mints an object-identity capability.
|
|
9
|
+
*
|
|
10
|
+
* The storage adapter treats canonical rows as opaque bytes. An IndexedDB
|
|
11
|
+
* implementation performs compare + optional replacement in one readwrite
|
|
12
|
+
* transaction over the Core, receiver-key, and budget stores and resolves
|
|
13
|
+
* "committed" only after `transaction.oncomplete`. No cryptography or other
|
|
14
|
+
* promise is awaited while that transaction is live.
|
|
15
|
+
*/
|
|
16
|
+
import type { ActivePairOperationCandidateV1 } from "./coreReduce";
|
|
17
|
+
import type { ExpectedIdentityHelloTrialV1 } from "./identityHelloTrial";
|
|
18
|
+
import type { PairOpenBudgetLimitsV1 } from "./pairOpenBudget";
|
|
19
|
+
/** Storage subject shared by the Core, receiver-key, and budget lookups. */
|
|
20
|
+
export interface PairOpenBudgetSubjectV1 {
|
|
21
|
+
readonly localRoomId: string;
|
|
22
|
+
readonly localPresenceOperationId: Uint8Array;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Exact durable budget-row state. `absent` is distinct from malformed, empty,
|
|
26
|
+
* or deleted-and-recreated bytes.
|
|
27
|
+
*/
|
|
28
|
+
export type ExactPairOpenBudgetRowV1 = {
|
|
29
|
+
readonly kind: "absent";
|
|
30
|
+
} | {
|
|
31
|
+
readonly kind: "present";
|
|
32
|
+
readonly exactBytes: Uint8Array;
|
|
33
|
+
};
|
|
34
|
+
export interface PairOpenReservationCasRequestV1 {
|
|
35
|
+
readonly subject: PairOpenBudgetSubjectV1;
|
|
36
|
+
/** Exact canonical Core bytes, not only `operationsDigest` or a revision. */
|
|
37
|
+
readonly expectedExactCoreStateBytes: Uint8Array;
|
|
38
|
+
/**
|
|
39
|
+
* Exact canonical HELLO-time Core bytes identifying the complete retained
|
|
40
|
+
* historical evidence view. This may intentionally differ from the current
|
|
41
|
+
* Core fence for a delayed HELLO.
|
|
42
|
+
*
|
|
43
|
+
* The durable row selected by this fence owns the exact presence operations
|
|
44
|
+
* and author prefixes for every observed presence in that Core view. An
|
|
45
|
+
* adapter must conflict if the row or any of that complete evidence is no
|
|
46
|
+
* longer retained.
|
|
47
|
+
*/
|
|
48
|
+
readonly expectedExactEvidenceCoreStateBytes: Uint8Array;
|
|
49
|
+
/**
|
|
50
|
+
* Exact revision at the subject's receiver-key row. Revisions must never be
|
|
51
|
+
* reused after replacement or retirement, so deletion cannot create ABA.
|
|
52
|
+
*/
|
|
53
|
+
readonly expectedReceiverKeyRecordRevision: bigint;
|
|
54
|
+
/** Exact prior bytes (or exact absence), never revision-only equality. */
|
|
55
|
+
readonly expectedBudgetRow: ExactPairOpenBudgetRowV1;
|
|
56
|
+
readonly budgetMutation: {
|
|
57
|
+
/** A sticky saturated row is still fenced, but needs no rewrite. */
|
|
58
|
+
readonly kind: "keep";
|
|
59
|
+
} | {
|
|
60
|
+
/** Canonical prepared or newly saturated replacement bytes. */
|
|
61
|
+
readonly kind: "replace";
|
|
62
|
+
readonly exactNextBytes: Uint8Array;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export type PairOpenReservationCasResultV1 = {
|
|
66
|
+
readonly status: "committed";
|
|
67
|
+
/**
|
|
68
|
+
* Exact row visible at commit. For `keep`, this is the prior row; for
|
|
69
|
+
* `replace`, this is the replacement. The service verifies this echo.
|
|
70
|
+
*/
|
|
71
|
+
readonly exactBudgetRowBytes: Uint8Array;
|
|
72
|
+
} | {
|
|
73
|
+
readonly status: "conflict";
|
|
74
|
+
/**
|
|
75
|
+
* Adapters compare in this order: current Core, historical evidence
|
|
76
|
+
* view, receiver key, then budget row. The first mismatch determines
|
|
77
|
+
* this closed result.
|
|
78
|
+
*/
|
|
79
|
+
readonly fence: "core" | "historical-evidence" | "receiver-key" | "budget";
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Minimal byte-store port. Implementations own all input before retaining it
|
|
83
|
+
* and return fresh bytes; this module additionally snapshots every boundary.
|
|
84
|
+
*/
|
|
85
|
+
export interface PairOpenReservationStorePortV1 {
|
|
86
|
+
/**
|
|
87
|
+
* Read the one current budget row for this room/presence subject. This read
|
|
88
|
+
* need not share a transaction with the later CAS: the exact returned bytes
|
|
89
|
+
* become the CAS fence.
|
|
90
|
+
*/
|
|
91
|
+
readExactBudgetRow(subject: PairOpenBudgetSubjectV1): Promise<ExactPairOpenBudgetRowV1>;
|
|
92
|
+
/**
|
|
93
|
+
* In one atomic transaction, compare exact current Core bytes, the complete
|
|
94
|
+
* exact historical-evidence view, receiver-key record revision, and exact
|
|
95
|
+
* budget row/absence, then apply the requested mutation.
|
|
96
|
+
*
|
|
97
|
+
* If physical budget keys include `budgetLogicalWindow`, a replacement that
|
|
98
|
+
* advances the window deletes the old key and writes the new key in this
|
|
99
|
+
* same transaction.
|
|
100
|
+
*/
|
|
101
|
+
compareAndSwap(request: PairOpenReservationCasRequestV1): Promise<PairOpenReservationCasResultV1>;
|
|
102
|
+
}
|
|
103
|
+
declare const reservedIdentityHelloOpenBrand: unique symbol;
|
|
104
|
+
/**
|
|
105
|
+
* One process-local permission for one already charged HELLO open.
|
|
106
|
+
*
|
|
107
|
+
* It intentionally exposes no structural fields. Spread, structured clone,
|
|
108
|
+
* persistence, or a type assertion cannot reproduce its WeakMap provenance.
|
|
109
|
+
*/
|
|
110
|
+
export interface ReservedIdentityHelloOpenV1 {
|
|
111
|
+
readonly [reservedIdentityHelloOpenBrand]: true;
|
|
112
|
+
}
|
|
113
|
+
export type ReserveIdentityHelloOpenResultV1 = {
|
|
114
|
+
readonly kind: "reserved";
|
|
115
|
+
readonly capability: ReservedIdentityHelloOpenV1;
|
|
116
|
+
} | {
|
|
117
|
+
readonly kind: "saturated";
|
|
118
|
+
readonly condition: "pair-control-DoS/stalled";
|
|
119
|
+
} | {
|
|
120
|
+
readonly kind: "retry";
|
|
121
|
+
readonly reason: "budget-conflict";
|
|
122
|
+
} | {
|
|
123
|
+
readonly kind: "stale";
|
|
124
|
+
readonly reason: "core-changed" | "historical-evidence-changed" | "receiver-key-changed";
|
|
125
|
+
};
|
|
126
|
+
export interface PairOpenReservationServiceV1 {
|
|
127
|
+
/**
|
|
128
|
+
* Perform one read/reduce/CAS attempt. Budget contention is returned to the
|
|
129
|
+
* deterministic pair scheduler; this method never spins or reorders trials.
|
|
130
|
+
*/
|
|
131
|
+
reserveIdentityHelloOpen(candidate: ActivePairOperationCandidateV1, trial: ExpectedIdentityHelloTrialV1): Promise<ReserveIdentityHelloOpenResultV1>;
|
|
132
|
+
}
|
|
133
|
+
export declare class PairOpenReservationError extends Error {
|
|
134
|
+
readonly name = "PairOpenReservationError";
|
|
135
|
+
constructor(message: string);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Create the trusted effectful boundary around one concrete storage adapter.
|
|
139
|
+
*
|
|
140
|
+
* The adapter and validated local resource policy are captured once; callers
|
|
141
|
+
* cannot supply a transition, charge, coordinate, fence, or commit result per
|
|
142
|
+
* trial.
|
|
143
|
+
*/
|
|
144
|
+
export declare const createPairOpenReservationServiceV1: (port: PairOpenReservationStorePortV1, limits: PairOpenBudgetLimitsV1) => PairOpenReservationServiceV1;
|
|
145
|
+
/**
|
|
146
|
+
* Consume one exact reservation before any trial-secret transfer or KEM work.
|
|
147
|
+
*
|
|
148
|
+
* Deletion is synchronous and precedes return, so reentrancy and a second
|
|
149
|
+
* attempt cannot reuse the capability. The returned value is the opaque
|
|
150
|
+
* candidate privately stored at reservation time; the gated trial-secret
|
|
151
|
+
* transfer compares it to the candidate sealed inside the trial. No
|
|
152
|
+
* structural transition or secret-bearing snapshot is returned.
|
|
153
|
+
*
|
|
154
|
+
* @internal
|
|
155
|
+
*/
|
|
156
|
+
export declare const consumeReservedIdentityHelloOpenV1: (capability: ReservedIdentityHelloOpenV1, trial: ExpectedIdentityHelloTrialV1) => ActivePairOperationCandidateV1;
|
|
157
|
+
export {};
|