@varco/client 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +52 -0
  2. package/dist/client.d.ts +2 -0
  3. package/dist/client.js +302 -0
  4. package/dist/client.js.map +1 -0
  5. package/dist/consumer-client.d.ts +2 -0
  6. package/dist/consumer-client.js +19 -0
  7. package/dist/consumer-client.js.map +1 -0
  8. package/dist/domain-helpers.d.ts +12 -0
  9. package/dist/domain-helpers.js +83 -0
  10. package/dist/domain-helpers.js.map +1 -0
  11. package/dist/encoding.d.ts +4 -0
  12. package/dist/encoding.js +32 -0
  13. package/dist/encoding.js.map +1 -0
  14. package/dist/hass-like.d.ts +7 -0
  15. package/dist/hass-like.js +13 -0
  16. package/dist/hass-like.js.map +1 -0
  17. package/dist/identity.d.ts +11 -0
  18. package/dist/identity.js +96 -0
  19. package/dist/identity.js.map +1 -0
  20. package/dist/index.d.ts +9 -0
  21. package/dist/index.js +8 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/local-client.d.ts +2 -0
  24. package/dist/local-client.js +90 -0
  25. package/dist/local-client.js.map +1 -0
  26. package/dist/manifest-helpers.d.ts +94 -0
  27. package/dist/manifest-helpers.js +105 -0
  28. package/dist/manifest-helpers.js.map +1 -0
  29. package/dist/memory-storage.d.ts +7 -0
  30. package/dist/memory-storage.js +7 -0
  31. package/dist/memory-storage.js.map +1 -0
  32. package/dist/transport-noble.d.ts +34 -0
  33. package/dist/transport-noble.js +257 -0
  34. package/dist/transport-noble.js.map +1 -0
  35. package/dist/transport.d.ts +29 -0
  36. package/dist/transport.js +195 -0
  37. package/dist/transport.js.map +1 -0
  38. package/dist/types.d.ts +185 -0
  39. package/dist/types.js +2 -0
  40. package/dist/types.js.map +1 -0
  41. package/dist/varco-client.js +5139 -0
  42. package/package.json +54 -0
@@ -0,0 +1,257 @@
1
+ // WebCrypto-free twin of RelayTransport for runtimes without crypto.subtle
2
+ // (e.g. Pebble PKJS). Same wire behaviour, primitives from @noble/*.
3
+ import { gcm } from "@noble/ciphers/aes.js";
4
+ import { ed25519 } from "@noble/curves/ed25519";
5
+ import { p256 } from "@noble/curves/p256.js";
6
+ import { hkdf } from "@noble/hashes/hkdf.js";
7
+ import { sha256 } from "@noble/hashes/sha2";
8
+ import { b64urlDecode, b64urlEncode, canonicalJson } from "./encoding.js";
9
+ import { closeError, envelopeLane } from "./transport.js";
10
+ // Pure-JS UTF-8: PKJS has no TextEncoder/TextDecoder.
11
+ function utf8Encode(value) {
12
+ const out = [];
13
+ for (let i = 0; i < value.length; i += 1) {
14
+ const code = value.codePointAt(i);
15
+ if (code > 0xffff)
16
+ i += 1;
17
+ if (code < 0x80)
18
+ out.push(code);
19
+ else if (code < 0x800)
20
+ out.push(0xc0 | (code >> 6), 0x80 | (code & 0x3f));
21
+ else if (code < 0x10000)
22
+ out.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));
23
+ else
24
+ out.push(0xf0 | (code >> 18), 0x80 | ((code >> 12) & 0x3f), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));
25
+ }
26
+ return Uint8Array.from(out);
27
+ }
28
+ function utf8Decode(bytes) {
29
+ let out = "";
30
+ let i = 0;
31
+ while (i < bytes.length) {
32
+ const b = bytes[i];
33
+ let code;
34
+ if (b < 0x80) {
35
+ code = b;
36
+ i += 1;
37
+ }
38
+ else if (b < 0xe0) {
39
+ code = ((b & 0x1f) << 6) | (bytes[i + 1] & 0x3f);
40
+ i += 2;
41
+ }
42
+ else if (b < 0xf0) {
43
+ code = ((b & 0x0f) << 12) | ((bytes[i + 1] & 0x3f) << 6) | (bytes[i + 2] & 0x3f);
44
+ i += 3;
45
+ }
46
+ else {
47
+ code = ((b & 0x07) << 18) | ((bytes[i + 1] & 0x3f) << 12) | ((bytes[i + 2] & 0x3f) << 6) | (bytes[i + 3] & 0x3f);
48
+ i += 4;
49
+ }
50
+ out += String.fromCodePoint(code);
51
+ }
52
+ return out;
53
+ }
54
+ // DER SubjectPublicKeyInfo header for a P-256 uncompressed point.
55
+ const SPKI_P256_PREFIX = Uint8Array.from([
56
+ 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01,
57
+ 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00,
58
+ ]);
59
+ function spkiWrap(rawPoint) {
60
+ const out = new Uint8Array(SPKI_P256_PREFIX.length + rawPoint.length);
61
+ out.set(SPKI_P256_PREFIX);
62
+ out.set(rawPoint, SPKI_P256_PREFIX.length);
63
+ return out;
64
+ }
65
+ function spkiUnwrap(spki) {
66
+ if (spki.length < 91 || spki[spki.length - 65] !== 0x04)
67
+ throw new Error("Bad server public key");
68
+ return spki.slice(spki.length - 65);
69
+ }
70
+ function defaultRandomBytes(n) {
71
+ const cryptoLike = globalThis.crypto;
72
+ if (!cryptoLike?.getRandomValues)
73
+ throw new Error("No secure randomness available: pass a randomBytes option");
74
+ const out = new Uint8Array(n);
75
+ cryptoLike.getRandomValues(out);
76
+ return out;
77
+ }
78
+ function wsUrl(base, authorityId) {
79
+ const clean = base.replace(/\/$/, "");
80
+ return `${clean}/consumer/${encodeURIComponent(authorityId)}`;
81
+ }
82
+ function nonce(value) {
83
+ const out = new Uint8Array(12);
84
+ new DataView(out.buffer).setUint32(8, value, false);
85
+ return out;
86
+ }
87
+ function deriveSessionKeys(privateKey, serverPoint, authorityId) {
88
+ // X coordinate only: matches WebCrypto ECDH deriveBits(256).
89
+ const shared = p256.getSharedSecret(privateKey, serverPoint).slice(1);
90
+ const salt = b64urlDecode(authorityId);
91
+ return {
92
+ send: hkdf(sha256, shared, salt, utf8Encode("varco-session-c2s-v1"), 32),
93
+ recv: hkdf(sha256, shared, salt, utf8Encode("varco-session-s2c-v1"), 32),
94
+ channelBinding: b64urlEncode(hkdf(sha256, shared, salt, utf8Encode("varco-channel-binding-v1"), 32)),
95
+ };
96
+ }
97
+ export class NobleRelayTransport {
98
+ bridgeUrl;
99
+ authorityId;
100
+ ws = null;
101
+ keys = null;
102
+ sendNonce = 0;
103
+ recvNonce = 0;
104
+ pending = new Map();
105
+ eventHandler = null;
106
+ closeHandler = null;
107
+ ready = null;
108
+ closed = false;
109
+ requestTimeoutMs;
110
+ randomBytes;
111
+ constructor(bridgeUrl, authorityId, options = {}) {
112
+ this.bridgeUrl = bridgeUrl;
113
+ this.authorityId = authorityId;
114
+ this.requestTimeoutMs = options.requestTimeoutMs ?? 30_000;
115
+ this.randomBytes = options.randomBytes ?? defaultRandomBytes;
116
+ }
117
+ onEvent(handler) { this.eventHandler = handler; }
118
+ onClose(handler) { this.closeHandler = handler; }
119
+ async channelBinding() {
120
+ await this.ensureConnected();
121
+ return this.keys.channelBinding;
122
+ }
123
+ async request(message) {
124
+ await this.ensureConnected();
125
+ const requestId = message.request_id ?? b64urlEncode(this.randomBytes(8));
126
+ const withId = { ...message, request_id: requestId };
127
+ const encrypted = this.encrypt(withId);
128
+ this.ws?.send(JSON.stringify(encrypted));
129
+ return new Promise((resolve, reject) => {
130
+ const timer = setTimeout(() => {
131
+ this.pending.delete(requestId);
132
+ reject(new Error(`Varco request timed out: ${String(message.type)}`));
133
+ }, this.requestTimeoutMs);
134
+ this.pending.set(requestId, { resolve, reject, timer });
135
+ });
136
+ }
137
+ async close() {
138
+ this.closed = true;
139
+ this.ws?.close();
140
+ this.failPending(new Error("Varco transport closed"));
141
+ }
142
+ failPending(err) {
143
+ for (const entry of this.pending.values()) {
144
+ clearTimeout(entry.timer);
145
+ entry.reject(err);
146
+ }
147
+ this.pending.clear();
148
+ }
149
+ async ensureConnected() {
150
+ if (this.closed)
151
+ throw new Error("Varco transport closed");
152
+ if (!this.ready)
153
+ this.ready = this.connect();
154
+ await this.ready;
155
+ }
156
+ generatePrivateKey() {
157
+ // p256.utils.randomSecretKey needs global crypto; sample from the injected
158
+ // source instead, rejecting out-of-range scalars.
159
+ for (;;) {
160
+ const candidate = this.randomBytes(32);
161
+ if (p256.utils.isValidSecretKey(candidate))
162
+ return candidate;
163
+ }
164
+ }
165
+ async connect() {
166
+ const privateKey = this.generatePrivateKey();
167
+ const clientPub = b64urlEncode(spkiWrap(p256.getPublicKey(privateKey, false)));
168
+ const ws = new WebSocket(wsUrl(this.bridgeUrl, this.authorityId));
169
+ this.ws = ws;
170
+ await new Promise((resolve, reject) => {
171
+ ws.onopen = () => ws.send(JSON.stringify({ type: "client_hello", client_pub: clientPub }));
172
+ ws.onerror = () => reject(new Error("Varco WebSocket failed"));
173
+ ws.onclose = () => reject(new Error("Varco WebSocket closed during handshake"));
174
+ ws.onmessage = (event) => {
175
+ try {
176
+ const outer = JSON.parse(String(event.data));
177
+ const payload = outer.payload ?? outer;
178
+ if (payload.type === "server_hello") {
179
+ const serverPubBytes = b64urlDecode(payload.server_pub);
180
+ const transcript = new Uint8Array(utf8Encode("varco-server-hello-v1\0").length + b64urlDecode(clientPub).length + 1 + serverPubBytes.length);
181
+ let offset = 0;
182
+ const prefix = utf8Encode("varco-server-hello-v1\0");
183
+ transcript.set(prefix, offset);
184
+ offset += prefix.length;
185
+ const clientBytes = b64urlDecode(clientPub);
186
+ transcript.set(clientBytes, offset);
187
+ offset += clientBytes.length;
188
+ transcript[offset] = 0;
189
+ offset += 1;
190
+ transcript.set(serverPubBytes, offset);
191
+ if (!ed25519.verify(b64urlDecode(payload.signature), transcript, b64urlDecode(this.authorityId)))
192
+ throw new Error("Bad authority signature");
193
+ this.keys = deriveSessionKeys(privateKey, spkiUnwrap(serverPubBytes), this.authorityId);
194
+ ws.onmessage = (messageEvent) => {
195
+ this.handleMessage(String(messageEvent.data)).catch((err) => {
196
+ this.failPending(err instanceof Error ? err : new Error(String(err)));
197
+ ws.close();
198
+ });
199
+ };
200
+ ws.onclose = (closeEvent) => {
201
+ const code = closeEvent?.code;
202
+ const wasClosed = this.closed;
203
+ this.closed = true;
204
+ this.failPending(closeError(code));
205
+ if (!wasClosed && code !== 4405)
206
+ this.closeHandler?.();
207
+ };
208
+ resolve();
209
+ }
210
+ }
211
+ catch (err) {
212
+ reject(err);
213
+ }
214
+ };
215
+ });
216
+ }
217
+ encrypt(payload) {
218
+ if (!this.keys)
219
+ throw new Error("Varco session is not ready");
220
+ const n = nonce(this.sendNonce++);
221
+ const body = gcm(this.keys.send, n).encrypt(utf8Encode(canonicalJson(payload)));
222
+ const envelope = { type: "ciphertext", nonce: b64urlEncode(n), body: b64urlEncode(body) };
223
+ const lane = envelopeLane(payload.type);
224
+ if (lane)
225
+ envelope.lane = lane;
226
+ return envelope;
227
+ }
228
+ decrypt(envelope) {
229
+ if (!this.keys)
230
+ throw new Error("Varco session is not ready");
231
+ const n = b64urlDecode(envelope.nonce);
232
+ const expected = nonce(this.recvNonce++);
233
+ if (n.some((value, index) => value !== expected[index]))
234
+ throw new Error("Unexpected nonce");
235
+ const plaintext = gcm(this.keys.recv, n).decrypt(b64urlDecode(envelope.body));
236
+ return JSON.parse(utf8Decode(plaintext));
237
+ }
238
+ async handleMessage(data) {
239
+ const outer = JSON.parse(data);
240
+ if (outer.type === "relay_disabled")
241
+ throw new Error("Bridge is signaling-only: P2P required but unavailable");
242
+ const payload = this.decrypt(outer.payload ?? outer);
243
+ const requestId = payload.request_id;
244
+ if (requestId && this.pending.has(requestId)) {
245
+ const pending = this.pending.get(requestId);
246
+ this.pending.delete(requestId);
247
+ clearTimeout(pending.timer);
248
+ if (payload.type === "error")
249
+ pending.reject(Object.assign(new Error(payload.message), { code: payload.code }));
250
+ else
251
+ pending.resolve(payload);
252
+ return;
253
+ }
254
+ this.eventHandler?.(payload);
255
+ }
256
+ }
257
+ //# sourceMappingURL=transport-noble.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-noble.js","sourceRoot":"","sources":["../src/transport-noble.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { VarcoTransport } from "./types.js";
2
+ export declare function envelopeLane(payloadType: unknown): "signaling" | null;
3
+ export declare function closeError(code: number | undefined): Error;
4
+ export declare class RelayTransport implements VarcoTransport {
5
+ private bridgeUrl;
6
+ private authorityId;
7
+ private requestTimeoutMs;
8
+ private ws;
9
+ private keys;
10
+ private sendNonce;
11
+ private recvNonce;
12
+ private pending;
13
+ private eventHandler;
14
+ private closeHandler;
15
+ private ready;
16
+ private closed;
17
+ constructor(bridgeUrl: string, authorityId: string, requestTimeoutMs?: number);
18
+ onEvent(handler: (event: any) => void): void;
19
+ onClose(handler: () => void): void;
20
+ channelBinding(): Promise<string>;
21
+ request(message: Record<string, unknown>): Promise<any>;
22
+ close(): Promise<void>;
23
+ private failPending;
24
+ private ensureConnected;
25
+ private connect;
26
+ private encrypt;
27
+ private decrypt;
28
+ private handleMessage;
29
+ }
@@ -0,0 +1,195 @@
1
+ import { ed25519 } from "@noble/curves/ed25519";
2
+ import { b64urlDecode, b64urlEncode, canonicalJson, utf8 } from "./encoding.js";
3
+ import { randomId } from "./identity.js";
4
+ function bufferSource(bytes) {
5
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
6
+ }
7
+ function wsUrl(base, authorityId) {
8
+ const clean = base.replace(/\/$/, "");
9
+ return `${clean}/consumer/${encodeURIComponent(authorityId)}`;
10
+ }
11
+ async function importServerPublic(spki) {
12
+ return crypto.subtle.importKey("spki", bufferSource(b64urlDecode(spki)), { name: "ECDH", namedCurve: "P-256" }, false, []);
13
+ }
14
+ async function exportPublic(key) {
15
+ return b64urlEncode(new Uint8Array(await crypto.subtle.exportKey("spki", key)));
16
+ }
17
+ async function deriveHkdf(material, authorityId, info, usage) {
18
+ return crypto.subtle.deriveKey({ name: "HKDF", hash: "SHA-256", salt: bufferSource(b64urlDecode(authorityId)), info: bufferSource(utf8(info)) }, material, { name: "AES-GCM", length: 256 }, false, usage);
19
+ }
20
+ async function deriveSessionKeys(privateKey, publicKey, authorityId) {
21
+ const bits = await crypto.subtle.deriveBits({ name: "ECDH", public: publicKey }, privateKey, 256);
22
+ const material = await crypto.subtle.importKey("raw", bits, "HKDF", false, ["deriveKey", "deriveBits"]);
23
+ const send = await deriveHkdf(material, authorityId, "varco-session-c2s-v1", ["encrypt"]);
24
+ const recv = await deriveHkdf(material, authorityId, "varco-session-s2c-v1", ["decrypt"]);
25
+ const bindingBits = await crypto.subtle.deriveBits({ name: "HKDF", hash: "SHA-256", salt: bufferSource(b64urlDecode(authorityId)), info: bufferSource(utf8("varco-channel-binding-v1")) }, material, 256);
26
+ return { send, recv, channelBinding: b64urlEncode(new Uint8Array(bindingBits)) };
27
+ }
28
+ // Message types relayed even by a signaling-only bridge: pairing, session
29
+ // auth, and WebRTC negotiation. The lane tag is envelope metadata the bridge
30
+ // can see; it carries no plaintext and grants no permissions.
31
+ const SIGNALING_TYPES = new Set(["access_request", "authenticate", "webrtc_offer", "webrtc_ice"]);
32
+ const SIGNALING_ONLY_ERROR = "Bridge is signaling-only: P2P required but unavailable";
33
+ export function envelopeLane(payloadType) {
34
+ return SIGNALING_TYPES.has(String(payloadType)) ? "signaling" : null;
35
+ }
36
+ export function closeError(code) {
37
+ return new Error(code === 4405 ? SIGNALING_ONLY_ERROR : "Varco transport closed");
38
+ }
39
+ function nonce(value) {
40
+ const out = new Uint8Array(12);
41
+ new DataView(out.buffer).setUint32(8, value, false);
42
+ return out;
43
+ }
44
+ export class RelayTransport {
45
+ bridgeUrl;
46
+ authorityId;
47
+ requestTimeoutMs;
48
+ ws = null;
49
+ keys = null;
50
+ sendNonce = 0;
51
+ recvNonce = 0;
52
+ pending = new Map();
53
+ eventHandler = null;
54
+ closeHandler = null;
55
+ ready = null;
56
+ closed = false;
57
+ constructor(bridgeUrl, authorityId, requestTimeoutMs = 30_000) {
58
+ this.bridgeUrl = bridgeUrl;
59
+ this.authorityId = authorityId;
60
+ this.requestTimeoutMs = requestTimeoutMs;
61
+ }
62
+ onEvent(handler) { this.eventHandler = handler; }
63
+ onClose(handler) { this.closeHandler = handler; }
64
+ async channelBinding() {
65
+ await this.ensureConnected();
66
+ return this.keys.channelBinding;
67
+ }
68
+ async request(message) {
69
+ await this.ensureConnected();
70
+ const requestId = message.request_id ?? randomId(8);
71
+ const withId = { ...message, request_id: requestId };
72
+ const encrypted = await this.encrypt(withId);
73
+ this.ws?.send(JSON.stringify(encrypted));
74
+ return new Promise((resolve, reject) => {
75
+ const timer = setTimeout(() => {
76
+ this.pending.delete(requestId);
77
+ reject(new Error(`Varco request timed out: ${String(message.type)}`));
78
+ }, this.requestTimeoutMs);
79
+ this.pending.set(requestId, { resolve, reject, timer });
80
+ });
81
+ }
82
+ async close() {
83
+ this.closed = true;
84
+ this.ws?.close();
85
+ this.failPending(new Error("Varco transport closed"));
86
+ }
87
+ failPending(err) {
88
+ for (const entry of this.pending.values()) {
89
+ clearTimeout(entry.timer);
90
+ entry.reject(err);
91
+ }
92
+ this.pending.clear();
93
+ }
94
+ async ensureConnected() {
95
+ if (this.closed)
96
+ throw new Error("Varco transport closed");
97
+ if (!this.ready)
98
+ this.ready = this.connect();
99
+ await this.ready;
100
+ }
101
+ async connect() {
102
+ const ecdh = await crypto.subtle.generateKey({ name: "ECDH", namedCurve: "P-256" }, true, ["deriveBits"]);
103
+ const clientPub = await exportPublic(ecdh.publicKey);
104
+ const ws = new WebSocket(wsUrl(this.bridgeUrl, this.authorityId));
105
+ this.ws = ws;
106
+ await new Promise((resolve, reject) => {
107
+ ws.onopen = () => ws.send(JSON.stringify({ type: "client_hello", client_pub: clientPub }));
108
+ ws.onerror = () => reject(new Error("Varco WebSocket failed"));
109
+ ws.onclose = () => reject(new Error("Varco WebSocket closed during handshake"));
110
+ ws.onmessage = async (event) => {
111
+ try {
112
+ const outer = JSON.parse(String(event.data));
113
+ const payload = outer.payload ?? outer;
114
+ if (payload.type === "server_hello") {
115
+ const serverPubBytes = b64urlDecode(payload.server_pub);
116
+ const transcript = new Uint8Array(utf8("varco-server-hello-v1\0").length + b64urlDecode(clientPub).length + 1 + serverPubBytes.length);
117
+ let offset = 0;
118
+ const prefix = utf8("varco-server-hello-v1\0");
119
+ transcript.set(prefix, offset);
120
+ offset += prefix.length;
121
+ const clientBytes = b64urlDecode(clientPub);
122
+ transcript.set(clientBytes, offset);
123
+ offset += clientBytes.length;
124
+ transcript[offset] = 0;
125
+ offset += 1;
126
+ transcript.set(serverPubBytes, offset);
127
+ if (!ed25519.verify(b64urlDecode(payload.signature), transcript, b64urlDecode(this.authorityId)))
128
+ throw new Error("Bad authority signature");
129
+ this.keys = await deriveSessionKeys(ecdh.privateKey, await importServerPublic(payload.server_pub), this.authorityId);
130
+ ws.onmessage = (messageEvent) => {
131
+ this.handleMessage(String(messageEvent.data)).catch((err) => {
132
+ this.failPending(err instanceof Error ? err : new Error(String(err)));
133
+ ws.close();
134
+ });
135
+ };
136
+ ws.onclose = (closeEvent) => {
137
+ const code = closeEvent?.code;
138
+ const wasClosed = this.closed;
139
+ this.closed = true;
140
+ this.failPending(closeError(code));
141
+ // Signaling-only rejection (4405) and explicit close() are final;
142
+ // anything else is a network drop the owner may want to recover from.
143
+ if (!wasClosed && code !== 4405)
144
+ this.closeHandler?.();
145
+ };
146
+ resolve();
147
+ }
148
+ }
149
+ catch (err) {
150
+ reject(err);
151
+ }
152
+ };
153
+ });
154
+ }
155
+ async encrypt(payload) {
156
+ if (!this.keys)
157
+ throw new Error("Varco session is not ready");
158
+ const n = nonce(this.sendNonce++);
159
+ const body = new Uint8Array(await crypto.subtle.encrypt({ name: "AES-GCM", iv: bufferSource(n) }, this.keys.send, bufferSource(utf8(canonicalJson(payload)))));
160
+ const envelope = { type: "ciphertext", nonce: b64urlEncode(n), body: b64urlEncode(body) };
161
+ const lane = envelopeLane(payload.type);
162
+ if (lane)
163
+ envelope.lane = lane;
164
+ return envelope;
165
+ }
166
+ async decrypt(envelope) {
167
+ if (!this.keys)
168
+ throw new Error("Varco session is not ready");
169
+ const n = b64urlDecode(envelope.nonce);
170
+ const expected = nonce(this.recvNonce++);
171
+ if (n.some((value, index) => value !== expected[index]))
172
+ throw new Error("Unexpected nonce");
173
+ const plaintext = await crypto.subtle.decrypt({ name: "AES-GCM", iv: bufferSource(n) }, this.keys.recv, bufferSource(b64urlDecode(envelope.body)));
174
+ return JSON.parse(new TextDecoder().decode(plaintext));
175
+ }
176
+ async handleMessage(data) {
177
+ const outer = JSON.parse(data);
178
+ if (outer.type === "relay_disabled")
179
+ throw new Error(SIGNALING_ONLY_ERROR);
180
+ const payload = await this.decrypt(outer.payload ?? outer);
181
+ const requestId = payload.request_id;
182
+ if (requestId && this.pending.has(requestId)) {
183
+ const pending = this.pending.get(requestId);
184
+ this.pending.delete(requestId);
185
+ clearTimeout(pending.timer);
186
+ if (payload.type === "error")
187
+ pending.reject(Object.assign(new Error(payload.message), { code: payload.code }));
188
+ else
189
+ pending.resolve(payload);
190
+ return;
191
+ }
192
+ this.eventHandler?.(payload);
193
+ }
194
+ }
195
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}