@openlv/session 0.0.1-beta.2
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/LICENSE +165 -0
- package/README.md +3 -0
- package/dist/base.d.ts +35 -0
- package/dist/base.js +172 -0
- package/dist/base.js.map +1 -0
- package/dist/connection.d.ts +57 -0
- package/dist/connection.js +757 -0
- package/dist/connection.js.map +1 -0
- package/dist/encryption/asymmetric.d.ts +22 -0
- package/dist/encryption/asymmetric.js +90 -0
- package/dist/encryption/asymmetric.js.map +1 -0
- package/dist/encryption/asymmetric.test.d.ts +1 -0
- package/dist/encryption/asymmetric.test.js +38 -0
- package/dist/encryption/asymmetric.test.js.map +1 -0
- package/dist/encryption/base64.d.ts +2 -0
- package/dist/encryption/base64.js +16 -0
- package/dist/encryption/base64.js.map +1 -0
- package/dist/encryption/base64.test.d.ts +1 -0
- package/dist/encryption/base64.test.js +21 -0
- package/dist/encryption/base64.test.js.map +1 -0
- package/dist/encryption/handshake.d.ts +10 -0
- package/dist/encryption/handshake.js +37 -0
- package/dist/encryption/handshake.js.map +1 -0
- package/dist/encryption/handshake.test.d.ts +1 -0
- package/dist/encryption/handshake.test.js +16 -0
- package/dist/encryption/handshake.test.js.map +1 -0
- package/dist/encryption/hash.d.ts +13 -0
- package/dist/encryption/hash.js +32 -0
- package/dist/encryption/hash.js.map +1 -0
- package/dist/encryption/index.d.ts +4 -0
- package/dist/encryption/index.js +5 -0
- package/dist/encryption/index.js.map +1 -0
- package/dist/encryption/random.d.ts +8 -0
- package/dist/encryption/random.js +21 -0
- package/dist/encryption/random.js.map +1 -0
- package/dist/events.d.ts +4 -0
- package/dist/events.js +2 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +1 -0
- package/dist/index.test.js +41 -0
- package/dist/index.test.js.map +1 -0
- package/dist/messages/index.d.ts +11 -0
- package/dist/messages/index.js +2 -0
- package/dist/messages/index.js.map +1 -0
- package/dist/provider.d.ts +11 -0
- package/dist/provider.js +285 -0
- package/dist/provider.js.map +1 -0
- package/dist/session/index.d.ts +41 -0
- package/dist/session/index.js +99 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/index.test.d.ts +1 -0
- package/dist/session/index.test.js +32 -0
- package/dist/session/index.test.js.map +1 -0
- package/dist/signaling/base.d.ts +14 -0
- package/dist/signaling/base.js +2 -0
- package/dist/signaling/base.js.map +1 -0
- package/dist/signaling/index.d.ts +28 -0
- package/dist/signaling/index.js +152 -0
- package/dist/signaling/index.js.map +1 -0
- package/dist/signaling/index.test.d.ts +1 -0
- package/dist/signaling/index.test.js +62 -0
- package/dist/signaling/index.test.js.map +1 -0
- package/dist/signaling/messages/index.d.ts +48 -0
- package/dist/signaling/messages/index.js +2 -0
- package/dist/signaling/messages/index.js.map +1 -0
- package/dist/signaling/mqtt/index.d.ts +5 -0
- package/dist/signaling/mqtt/index.js +49 -0
- package/dist/signaling/mqtt/index.js.map +1 -0
- package/dist/signaling/mqtt.d.ts +31 -0
- package/dist/signaling/mqtt.js +152 -0
- package/dist/signaling/mqtt.js.map +1 -0
- package/dist/signaling/ntfy/index.d.ts +25 -0
- package/dist/signaling/ntfy/index.js +92 -0
- package/dist/signaling/ntfy/index.js.map +1 -0
- package/dist/signaling/ntfy/url.d.ts +12 -0
- package/dist/signaling/ntfy/url.js +37 -0
- package/dist/signaling/ntfy/url.js.map +1 -0
- package/dist/signaling/ntfy/url.test.d.ts +1 -0
- package/dist/signaling/ntfy/url.test.js +54 -0
- package/dist/signaling/ntfy/url.test.js.map +1 -0
- package/dist/transport/index.d.ts +11 -0
- package/dist/transport/index.js +8 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/webrtc/index.d.ts +1 -0
- package/dist/transport/webrtc/index.js +70 -0
- package/dist/transport/webrtc/index.js.map +1 -0
- package/dist/types.d.ts +56 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/encryption.d.ts +86 -0
- package/dist/utils/encryption.js +243 -0
- package/dist/utils/encryption.js.map +1 -0
- package/dist/utils/log.d.ts +1 -0
- package/dist/utils/log.js +2 -0
- package/dist/utils/log.js.map +1 -0
- package/dist/utils/url.d.ts +3 -0
- package/dist/utils/url.js +66 -0
- package/dist/utils/url.js.map +1 -0
- package/dist/utils/url.test.d.ts +1 -0
- package/dist/utils/url.test.js +29 -0
- package/dist/utils/url.test.js.map +1 -0
- package/package.json +65 -0
package/dist/provider.js
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || ((receiver, state, kind, f) => {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
});
|
|
6
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || ((receiver, state, value, kind, f) => {
|
|
7
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
+
});
|
|
12
|
+
var _OpenLVProvider_conn, _OpenLVProvider_isConnected, _OpenLVProvider_accounts, _OpenLVProvider_chainId;
|
|
13
|
+
/* eslint-disable sonarjs/no-duplicate-string */
|
|
14
|
+
import { EventEmitter } from "eventemitter3";
|
|
15
|
+
export class OpenLVProvider extends EventEmitter {
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
_OpenLVProvider_conn.set(this, void 0);
|
|
19
|
+
_OpenLVProvider_isConnected.set(this, false);
|
|
20
|
+
_OpenLVProvider_accounts.set(this, []);
|
|
21
|
+
_OpenLVProvider_chainId.set(this, 1);
|
|
22
|
+
}
|
|
23
|
+
get connected() {
|
|
24
|
+
return __classPrivateFieldGet(this, _OpenLVProvider_isConnected, "f");
|
|
25
|
+
}
|
|
26
|
+
async init() {
|
|
27
|
+
__classPrivateFieldSet(this, _OpenLVProvider_conn, new OpenLVConnection(), "f");
|
|
28
|
+
// Set up connection handlers
|
|
29
|
+
__classPrivateFieldGet(this, _OpenLVProvider_conn, "f").onPhaseChange((phase) => {
|
|
30
|
+
console.log(`OpenLV Provider: Connection state changed to ${phase.state}`);
|
|
31
|
+
if (phase.state === "webrtc-connected") {
|
|
32
|
+
__classPrivateFieldSet(this, _OpenLVProvider_isConnected, true, "f");
|
|
33
|
+
this.emit("connect");
|
|
34
|
+
}
|
|
35
|
+
else if (phase.state === "key-exchange") {
|
|
36
|
+
__classPrivateFieldSet(this, _OpenLVProvider_isConnected, true, "f");
|
|
37
|
+
this.emit("connect");
|
|
38
|
+
}
|
|
39
|
+
else if (phase.state === "disconnected") {
|
|
40
|
+
__classPrivateFieldSet(this, _OpenLVProvider_isConnected, false, "f");
|
|
41
|
+
this.emit("disconnect");
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
// Set up message handler for incoming JSON-RPC messages
|
|
45
|
+
__classPrivateFieldGet(this, _OpenLVProvider_conn, "f").onMessage(async (message) => {
|
|
46
|
+
console.log("Provider: Received message:", message);
|
|
47
|
+
// **FIX: Always emit the message first**
|
|
48
|
+
this.emit("message", message);
|
|
49
|
+
// Handle responses to our requests (but don't interfere with request handlers)
|
|
50
|
+
if ("result" in message || "error" in message) {
|
|
51
|
+
const response = message;
|
|
52
|
+
console.log("Provider: Processing response:", response);
|
|
53
|
+
// Check for account changes and update internal state
|
|
54
|
+
if (response.result && Array.isArray(response.result)) {
|
|
55
|
+
const newAccounts = response.result;
|
|
56
|
+
console.log("Provider: Found accounts in response:", newAccounts);
|
|
57
|
+
// Update accounts but don't emit here - let the request handler do it
|
|
58
|
+
const oldAccounts = __classPrivateFieldGet(this, _OpenLVProvider_accounts, "f");
|
|
59
|
+
__classPrivateFieldSet(this, _OpenLVProvider_accounts, newAccounts, "f");
|
|
60
|
+
// Only emit if accounts actually changed
|
|
61
|
+
if (JSON.stringify(oldAccounts) !== JSON.stringify(newAccounts)) {
|
|
62
|
+
console.log("Provider: Emitting accountsChanged:", newAccounts);
|
|
63
|
+
this.emit("accountsChanged", newAccounts);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Return the response for request handlers
|
|
67
|
+
return response;
|
|
68
|
+
}
|
|
69
|
+
// For incoming requests, return a default response
|
|
70
|
+
return { status: "received" };
|
|
71
|
+
});
|
|
72
|
+
const { openLVUrl } = await __classPrivateFieldGet(this, _OpenLVProvider_conn, "f").initSession();
|
|
73
|
+
this.emit("display_uri", openLVUrl);
|
|
74
|
+
}
|
|
75
|
+
async connect(uri) {
|
|
76
|
+
__classPrivateFieldSet(this, _OpenLVProvider_conn, new OpenLVConnection(), "f");
|
|
77
|
+
// Set up connection handlers
|
|
78
|
+
__classPrivateFieldGet(this, _OpenLVProvider_conn, "f").onPhaseChange((phase) => {
|
|
79
|
+
console.log(`OpenLV Provider: Connection state changed to ${phase.state}`);
|
|
80
|
+
if (phase.state === "webrtc-connected") {
|
|
81
|
+
__classPrivateFieldSet(this, _OpenLVProvider_isConnected, true, "f");
|
|
82
|
+
this.emit("connect");
|
|
83
|
+
}
|
|
84
|
+
else if (phase.state === "key-exchange") {
|
|
85
|
+
__classPrivateFieldSet(this, _OpenLVProvider_isConnected, true, "f");
|
|
86
|
+
this.emit("connect");
|
|
87
|
+
}
|
|
88
|
+
else if (phase.state === "disconnected") {
|
|
89
|
+
__classPrivateFieldSet(this, _OpenLVProvider_isConnected, false, "f");
|
|
90
|
+
this.emit("disconnect");
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
// Set up message handler
|
|
94
|
+
__classPrivateFieldGet(this, _OpenLVProvider_conn, "f").onMessage(async (message) => {
|
|
95
|
+
console.log("Provider: Received message:", message);
|
|
96
|
+
// **FIX: Always emit the message first**
|
|
97
|
+
this.emit("message", message);
|
|
98
|
+
// Handle responses to our requests
|
|
99
|
+
if ("result" in message || "error" in message) {
|
|
100
|
+
const response = message;
|
|
101
|
+
// Check for account changes
|
|
102
|
+
if (response.result && Array.isArray(response.result)) {
|
|
103
|
+
const newAccounts = response.result;
|
|
104
|
+
if (JSON.stringify(newAccounts) !== JSON.stringify(__classPrivateFieldGet(this, _OpenLVProvider_accounts, "f"))) {
|
|
105
|
+
__classPrivateFieldSet(this, _OpenLVProvider_accounts, newAccounts, "f");
|
|
106
|
+
this.emit("accountsChanged", newAccounts);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return response;
|
|
110
|
+
}
|
|
111
|
+
// For incoming requests, return a default response
|
|
112
|
+
return { status: "received" };
|
|
113
|
+
});
|
|
114
|
+
await __classPrivateFieldGet(this, _OpenLVProvider_conn, "f").connectToSession(uri);
|
|
115
|
+
}
|
|
116
|
+
disconnect() {
|
|
117
|
+
__classPrivateFieldGet(this, _OpenLVProvider_conn, "f")?.disconnect();
|
|
118
|
+
__classPrivateFieldSet(this, _OpenLVProvider_isConnected, false, "f");
|
|
119
|
+
const oldAccounts = __classPrivateFieldGet(this, _OpenLVProvider_accounts, "f");
|
|
120
|
+
__classPrivateFieldSet(this, _OpenLVProvider_accounts, [], "f");
|
|
121
|
+
// Emit account change event if there were accounts
|
|
122
|
+
if (oldAccounts.length > 0) {
|
|
123
|
+
this.emit("accountsChanged", []);
|
|
124
|
+
}
|
|
125
|
+
this.emit("disconnect");
|
|
126
|
+
}
|
|
127
|
+
async request(params) {
|
|
128
|
+
if (!__classPrivateFieldGet(this, _OpenLVProvider_conn, "f")) {
|
|
129
|
+
throw new Error("Connection not established");
|
|
130
|
+
}
|
|
131
|
+
// Convert to JSON-RPC request format
|
|
132
|
+
const jsonRpcRequest = {
|
|
133
|
+
jsonrpc: "2.0",
|
|
134
|
+
id: Date.now(),
|
|
135
|
+
method: params.method,
|
|
136
|
+
params: params.params ? Array.from(params.params) : [],
|
|
137
|
+
};
|
|
138
|
+
console.log("Provider: Sending request:", jsonRpcRequest);
|
|
139
|
+
// Send the request
|
|
140
|
+
await __classPrivateFieldGet(this, _OpenLVProvider_conn, "f").sendMessage(jsonRpcRequest);
|
|
141
|
+
// For some methods, we can return immediately or simulate responses
|
|
142
|
+
switch (params.method) {
|
|
143
|
+
case "eth_requestAccounts":
|
|
144
|
+
// This will be handled by the wallet, so we need to wait for response
|
|
145
|
+
return new Promise((resolve, reject) => {
|
|
146
|
+
const timeout = setTimeout(() => {
|
|
147
|
+
this.removeListener("message", handleResponse);
|
|
148
|
+
console.log("Provider: Request timeout for eth_requestAccounts");
|
|
149
|
+
reject(new Error("Request timeout"));
|
|
150
|
+
}, 30000);
|
|
151
|
+
const handleResponse = (message) => {
|
|
152
|
+
console.log("Provider: Checking response for eth_requestAccounts:", message);
|
|
153
|
+
console.log("Provider: Request ID:", jsonRpcRequest.id, "Response ID:", message.id);
|
|
154
|
+
console.log("Provider: Response structure:", {
|
|
155
|
+
hasId: "id" in message,
|
|
156
|
+
hasResult: "result" in message,
|
|
157
|
+
hasError: "error" in message,
|
|
158
|
+
hasMethod: "method" in message,
|
|
159
|
+
resultType: typeof message.result,
|
|
160
|
+
isArray: Array.isArray(message.result),
|
|
161
|
+
resultLength: Array.isArray(message.result)
|
|
162
|
+
? message.result.length
|
|
163
|
+
: "N/A",
|
|
164
|
+
});
|
|
165
|
+
// Check if this is the response to our request
|
|
166
|
+
if (message.id === jsonRpcRequest.id) {
|
|
167
|
+
console.log("Provider: ID match - processing response");
|
|
168
|
+
if (message.error) {
|
|
169
|
+
console.log("Provider: Error in response:", message.error);
|
|
170
|
+
clearTimeout(timeout);
|
|
171
|
+
this.removeListener("message", handleResponse);
|
|
172
|
+
reject(new Error(message.error.message));
|
|
173
|
+
}
|
|
174
|
+
else if ("result" in message && Array.isArray(message.result)) {
|
|
175
|
+
// Validate that these are proper Ethereum addresses
|
|
176
|
+
const accounts = message.result;
|
|
177
|
+
const isValidAccounts = accounts.length > 0 &&
|
|
178
|
+
accounts.every((addr) => {
|
|
179
|
+
if (typeof addr !== "string")
|
|
180
|
+
return false;
|
|
181
|
+
if (!addr.startsWith("0x"))
|
|
182
|
+
return false;
|
|
183
|
+
if (addr.length !== 42)
|
|
184
|
+
return false;
|
|
185
|
+
// Basic hex validation
|
|
186
|
+
return /^0x[0-9a-fA-F]{40}$/.test(addr);
|
|
187
|
+
});
|
|
188
|
+
if (isValidAccounts) {
|
|
189
|
+
console.log("Provider: Valid account array found:", message.result);
|
|
190
|
+
clearTimeout(timeout);
|
|
191
|
+
this.removeListener("message", handleResponse);
|
|
192
|
+
__classPrivateFieldSet(this, _OpenLVProvider_accounts, message.result, "f");
|
|
193
|
+
console.log("Provider: Updated accounts:", __classPrivateFieldGet(this, _OpenLVProvider_accounts, "f"));
|
|
194
|
+
resolve(message.result);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
console.log("Provider: Invalid addresses in response:", message.result);
|
|
198
|
+
console.log("Provider: Address validation failed - ignoring this response");
|
|
199
|
+
// Don't resolve/reject yet - wait for a valid response
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else if ("result" in message) {
|
|
203
|
+
console.log("Provider: Non-array result found:", message.result);
|
|
204
|
+
// Don't resolve for non-array results like {status: 'processing'}
|
|
205
|
+
// Keep waiting for the actual account array
|
|
206
|
+
console.log("Provider: Waiting for account array response...");
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
console.log("Provider: Invalid response format - missing result");
|
|
210
|
+
console.log("Provider: Full message:", JSON.stringify(message, null, 2));
|
|
211
|
+
// Don't reject immediately - wallet might send another response
|
|
212
|
+
console.log("Provider: Continuing to wait for valid response...");
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
console.log("Provider: Message ID mismatch - ignoring");
|
|
217
|
+
console.log("Provider: Expected:", jsonRpcRequest.id, "Got:", message.id);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
this.on("message", handleResponse);
|
|
221
|
+
});
|
|
222
|
+
case "eth_accounts":
|
|
223
|
+
return __classPrivateFieldGet(this, _OpenLVProvider_accounts, "f");
|
|
224
|
+
case "eth_chainId":
|
|
225
|
+
return `0x${__classPrivateFieldGet(this, _OpenLVProvider_chainId, "f").toString(16)}`;
|
|
226
|
+
case "wallet_switchEthereumChain": {
|
|
227
|
+
// Handle chain switching
|
|
228
|
+
const chainIdParam = params.params?.[0]?.chainId;
|
|
229
|
+
if (chainIdParam) {
|
|
230
|
+
const newChainId = typeof chainIdParam === "string"
|
|
231
|
+
? parseInt(chainIdParam, 16)
|
|
232
|
+
: Number(chainIdParam);
|
|
233
|
+
if (newChainId !== __classPrivateFieldGet(this, _OpenLVProvider_chainId, "f")) {
|
|
234
|
+
__classPrivateFieldSet(this, _OpenLVProvider_chainId, newChainId, "f");
|
|
235
|
+
this.emit("chainChanged", chainIdParam);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// Continue with the default case to send the request
|
|
239
|
+
return new Promise((resolve, reject) => {
|
|
240
|
+
const timeout = setTimeout(() => {
|
|
241
|
+
this.removeListener("message", handleResponse);
|
|
242
|
+
reject(new Error("Request timeout"));
|
|
243
|
+
}, 10000);
|
|
244
|
+
const handleResponse = (message) => {
|
|
245
|
+
if (message.id === jsonRpcRequest.id) {
|
|
246
|
+
clearTimeout(timeout);
|
|
247
|
+
this.removeListener("message", handleResponse);
|
|
248
|
+
if (message.error) {
|
|
249
|
+
reject(new Error(message.error.message));
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
resolve(message.result);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
this.on("message", handleResponse);
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
default:
|
|
260
|
+
// For other methods, wait for response
|
|
261
|
+
return new Promise((resolve, reject) => {
|
|
262
|
+
const timeout = setTimeout(() => {
|
|
263
|
+
this.removeListener("message", handleResponse);
|
|
264
|
+
reject(new Error("Request timeout"));
|
|
265
|
+
}, 10000);
|
|
266
|
+
const handleResponse = (message) => {
|
|
267
|
+
console.log("Provider: Default handler - checking response:", message);
|
|
268
|
+
if (message.id === jsonRpcRequest.id) {
|
|
269
|
+
clearTimeout(timeout);
|
|
270
|
+
this.removeListener("message", handleResponse);
|
|
271
|
+
if (message.error) {
|
|
272
|
+
reject(new Error(message.error.message));
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
resolve(message.result);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
this.on("message", handleResponse);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
_OpenLVProvider_conn = new WeakMap(), _OpenLVProvider_isConnected = new WeakMap(), _OpenLVProvider_accounts = new WeakMap(), _OpenLVProvider_chainId = new WeakMap();
|
|
285
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { DecryptionKey, EncryptionKey } from "../encryption/index.js";
|
|
2
|
+
import { SignalLayerCreator } from "../signaling/base.js";
|
|
3
|
+
import { SignalingMode } from "../signaling/index.js";
|
|
4
|
+
type Hex<L> = string;
|
|
5
|
+
/**
|
|
6
|
+
* The parameters from the connection url
|
|
7
|
+
*/
|
|
8
|
+
export type SessionHandshakeParameters = {
|
|
9
|
+
sessionId: Hex<16>;
|
|
10
|
+
h: Hex<16>;
|
|
11
|
+
k: Hex<16>;
|
|
12
|
+
p: string;
|
|
13
|
+
s: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The parameters that describe a session
|
|
17
|
+
* these can be used to restart a session
|
|
18
|
+
*/
|
|
19
|
+
export type SessionConnectionParameters = SessionHandshakeParameters & {
|
|
20
|
+
relyingPublicKey: EncryptionKey;
|
|
21
|
+
encryptionKey: EncryptionKey;
|
|
22
|
+
decryptionKey: DecryptionKey;
|
|
23
|
+
};
|
|
24
|
+
export type SessionState = "create" | "handshake" | "signaling" | "encrypted" | "connected";
|
|
25
|
+
export type Session = {
|
|
26
|
+
getState(): {
|
|
27
|
+
state: SessionState;
|
|
28
|
+
signaling?: {
|
|
29
|
+
state: SignalingMode;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
getHandshakeParameters(): SessionHandshakeParameters;
|
|
33
|
+
connect(): Promise<void>;
|
|
34
|
+
};
|
|
35
|
+
export type SessionCreationParameters = Pick<SessionHandshakeParameters, "p" | "s">;
|
|
36
|
+
export type SessionParameters = SessionConnectionParameters | SessionHandshakeParameters | SessionCreationParameters;
|
|
37
|
+
export declare const createSession: (initParameters: SessionParameters, signalLayer: SignalLayerCreator) => Promise<Session>;
|
|
38
|
+
/**
|
|
39
|
+
* Connect to a session from its openlv:// URL
|
|
40
|
+
*/
|
|
41
|
+
export declare const connectSession: (connectionUrl: string) => Promise<Session>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { deriveSymmetricKey, generateHandshakeKey, } from "../encryption/handshake.js";
|
|
2
|
+
import { initHash } from "../encryption/hash.js";
|
|
3
|
+
import { initEncryptionKeys, parseEncryptionKey, } from "../encryption/index.js";
|
|
4
|
+
import { generateSessionId } from "../encryption/random.js";
|
|
5
|
+
import { mqtt } from "../signaling/mqtt/index.js";
|
|
6
|
+
import { ntfy } from "../signaling/ntfy/index.js";
|
|
7
|
+
import { decodeConnectionURL } from "../utils/url.js";
|
|
8
|
+
export const createSession = async (initParameters, signalLayer) => {
|
|
9
|
+
const sessionId = "sessionId" in initParameters
|
|
10
|
+
? initParameters.sessionId
|
|
11
|
+
: generateSessionId();
|
|
12
|
+
const { encryptionKey, decryptionKey } = await initEncryptionKeys(initParameters);
|
|
13
|
+
let relyingPublicKey;
|
|
14
|
+
const handshakeKey = "k" in initParameters
|
|
15
|
+
? await deriveSymmetricKey(initParameters.k)
|
|
16
|
+
: await generateHandshakeKey();
|
|
17
|
+
const { hash, isHost } = await initHash("h" in initParameters ? initParameters.h : undefined, encryptionKey);
|
|
18
|
+
const state = "handshake";
|
|
19
|
+
const protocol = initParameters.p;
|
|
20
|
+
const server = initParameters.s;
|
|
21
|
+
const signaling = await signalLayer({
|
|
22
|
+
topic: sessionId,
|
|
23
|
+
url: server,
|
|
24
|
+
});
|
|
25
|
+
const signal = await signaling({
|
|
26
|
+
h: hash,
|
|
27
|
+
canEncrypt() {
|
|
28
|
+
return relyingPublicKey !== undefined;
|
|
29
|
+
},
|
|
30
|
+
async encrypt(message) {
|
|
31
|
+
if (!relyingPublicKey) {
|
|
32
|
+
throw new Error("Relying party public key not found");
|
|
33
|
+
}
|
|
34
|
+
console.log("encrypting to " + relyingPublicKey.toString());
|
|
35
|
+
return await relyingPublicKey.encrypt(message);
|
|
36
|
+
},
|
|
37
|
+
async decrypt(message) {
|
|
38
|
+
if (!decryptionKey) {
|
|
39
|
+
throw new Error("Decryption key not found");
|
|
40
|
+
}
|
|
41
|
+
return await decryptionKey.decrypt(message);
|
|
42
|
+
},
|
|
43
|
+
publicKey: encryptionKey,
|
|
44
|
+
k: handshakeKey,
|
|
45
|
+
async rpDiscovered(rpKey) {
|
|
46
|
+
const role = isHost ? "host" : "client";
|
|
47
|
+
console.log("rpKey discovered by " + role, rpKey);
|
|
48
|
+
relyingPublicKey = await parseEncryptionKey(rpKey);
|
|
49
|
+
},
|
|
50
|
+
isHost,
|
|
51
|
+
});
|
|
52
|
+
// let transport: TransportLayer | undefined;
|
|
53
|
+
return {
|
|
54
|
+
connect: async () => {
|
|
55
|
+
console.log("connecting to session, isHost:", isHost);
|
|
56
|
+
// TODO: implement
|
|
57
|
+
console.log("connecting to session");
|
|
58
|
+
await signal.setup();
|
|
59
|
+
signal.subscribe((message) => {
|
|
60
|
+
console.log("Session: received message from signaling", message);
|
|
61
|
+
});
|
|
62
|
+
},
|
|
63
|
+
getState() {
|
|
64
|
+
return { state, signaling: signal.getState() };
|
|
65
|
+
},
|
|
66
|
+
getHandshakeParameters() {
|
|
67
|
+
return {
|
|
68
|
+
sessionId,
|
|
69
|
+
h: hash,
|
|
70
|
+
k: handshakeKey.toString(),
|
|
71
|
+
p: protocol,
|
|
72
|
+
s: server,
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
// getAsParameters() {
|
|
76
|
+
// return {
|
|
77
|
+
// ...initParameters,
|
|
78
|
+
// relyingPublicKey,
|
|
79
|
+
// encryptionKey,
|
|
80
|
+
// decryptionKey,
|
|
81
|
+
// };
|
|
82
|
+
// },
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Connect to a session from its openlv:// URL
|
|
87
|
+
*/
|
|
88
|
+
export const connectSession = async (connectionUrl) => {
|
|
89
|
+
const initParameters = decodeConnectionURL(connectionUrl);
|
|
90
|
+
const signaling = {
|
|
91
|
+
mqtt: mqtt,
|
|
92
|
+
ntfy: ntfy,
|
|
93
|
+
}[initParameters.p];
|
|
94
|
+
if (!signaling) {
|
|
95
|
+
throw new Error(`Invalid signaling protocol: ${initParameters.p}`);
|
|
96
|
+
}
|
|
97
|
+
return createSession(initParameters, signaling);
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAGL,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AA0DtD,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,cAAiC,EACjC,WAA+B,EACb,EAAE;IACpB,MAAM,SAAS,GACb,WAAW,IAAI,cAAc;QAC3B,CAAC,CAAC,cAAc,CAAC,SAAS;QAC1B,CAAC,CAAC,iBAAiB,EAAE,CAAC;IAC1B,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,GACpC,MAAM,kBAAkB,CAAC,cAAc,CAAC,CAAC;IAC3C,IAAI,gBAA2C,CAAC;IAChD,MAAM,YAAY,GAChB,GAAG,IAAI,cAAc;QACnB,CAAC,CAAC,MAAM,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC;QAC5C,CAAC,CAAC,MAAM,oBAAoB,EAAE,CAAC;IACnC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,QAAQ,CACrC,GAAG,IAAI,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EACpD,aAAa,CACd,CAAC;IACF,MAAM,KAAK,GAAiB,WAAW,CAAC;IACxC,MAAM,QAAQ,GAAG,cAAc,CAAC,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC;IAEhC,MAAM,SAAS,GAAmB,MAAM,WAAW,CAAC;QAClD,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE,MAAM;KACZ,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;QAC7B,CAAC,EAAE,IAAI;QACP,UAAU;YACR,OAAO,gBAAgB,KAAK,SAAS,CAAC;QACxC,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,OAAO;YACnB,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;YACxD,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAC;YAE5D,OAAO,MAAM,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACjD,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,OAAO;YACnB,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAC9C,CAAC;YAED,OAAO,MAAM,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9C,CAAC;QACD,SAAS,EAAE,aAAa;QACxB,CAAC,EAAE,YAAY;QACf,KAAK,CAAC,YAAY,CAAC,KAAK;YACtB,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;YAExC,OAAO,CAAC,GAAG,CAAC,sBAAsB,GAAG,IAAI,EAAE,KAAK,CAAC,CAAC;YAElD,gBAAgB,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACrD,CAAC;QACD,MAAM;KACP,CAAC,CAAC;IAEH,6CAA6C;IAE7C,OAAO;QACL,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,OAAO,CAAC,GAAG,CAAC,gCAAgC,EAAE,MAAM,CAAC,CAAC;YACtD,kBAAkB;YAClB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;YACrC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YAErB,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC3B,OAAO,CAAC,GAAG,CAAC,0CAA0C,EAAE,OAAO,CAAC,CAAC;YACnE,CAAC,CAAC,CAAC;QACL,CAAC;QACD,QAAQ;YACN,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QACjD,CAAC;QACD,sBAAsB;YACpB,OAAO;gBACL,SAAS;gBACT,CAAC,EAAE,IAAI;gBACP,CAAC,EAAE,YAAY,CAAC,QAAQ,EAAE;gBAC1B,CAAC,EAAE,QAAQ;gBACX,CAAC,EAAE,MAAM;aACV,CAAC;QACJ,CAAC;QACD,sBAAsB;QACtB,eAAe;QACf,6BAA6B;QAC7B,4BAA4B;QAC5B,yBAAyB;QACzB,yBAAyB;QACzB,SAAS;QACT,KAAK;KACN,CAAC;AACJ,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,aAAqB,EACH,EAAE;IACpB,MAAM,cAAc,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAE1D,MAAM,SAAS,GAAG;QAChB,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,IAAI;KACX,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAEpB,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,+BAA+B,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,aAAa,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;AAClD,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { ntfy } from "../signaling/ntfy/index.js";
|
|
3
|
+
import { decodeConnectionURL, encodeConnectionURL } from "../utils/url.js";
|
|
4
|
+
import { connectSession, createSession } from "./index.js";
|
|
5
|
+
describe("Session", () => {
|
|
6
|
+
test("Should be able to create a session", async () => {
|
|
7
|
+
const sessionA = await createSession({
|
|
8
|
+
sessionId: "mytestsession111",
|
|
9
|
+
p: "ntfy",
|
|
10
|
+
s: "https://ntfy.sh/",
|
|
11
|
+
}, ntfy);
|
|
12
|
+
expect(sessionA).toBeDefined();
|
|
13
|
+
console.log(sessionA.getState());
|
|
14
|
+
await sessionA.connect();
|
|
15
|
+
const handshakeParametersA = sessionA.getHandshakeParameters();
|
|
16
|
+
const encodedUrl = encodeConnectionURL(handshakeParametersA);
|
|
17
|
+
console.log(encodedUrl);
|
|
18
|
+
const decodedUrl = decodeConnectionURL(encodedUrl);
|
|
19
|
+
expect(decodedUrl).toEqual(handshakeParametersA);
|
|
20
|
+
//
|
|
21
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
22
|
+
console.log("Connecting to session B");
|
|
23
|
+
const sessionB = await connectSession(encodedUrl);
|
|
24
|
+
console.log(sessionB.getState());
|
|
25
|
+
await sessionB.connect();
|
|
26
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
27
|
+
//
|
|
28
|
+
console.log("A", sessionA.getState());
|
|
29
|
+
console.log("B", sessionB.getState());
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/session/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEhD,OAAO,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3D,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,IAAI,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAClC;YACE,SAAS,EAAE,kBAAkB;YAC7B,CAAC,EAAE,MAAM;YACT,CAAC,EAAE,kBAAkB;SACtB,EACD,IAAI,CACL,CAAC;QAEF,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEjC,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;QAEzB,MAAM,oBAAoB,GAAG,QAAQ,CAAC,sBAAsB,EAAE,CAAC;QAC/D,MAAM,UAAU,GAAG,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;QAE7D,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAExB,MAAM,UAAU,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAEnD,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAEjD,EAAE;QACF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAE1D,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QAEvC,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,UAAU,CAAC,CAAC;QAElD,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QACjC,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;QAEzB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAE1D,EAAE;QACF,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { MaybePromise } from 'viem';
|
|
2
|
+
import { SignalingLayer } from './index.js';
|
|
3
|
+
export type SignalBaseProperties = {
|
|
4
|
+
topic: string;
|
|
5
|
+
url: string;
|
|
6
|
+
};
|
|
7
|
+
export type SignalingBaseLayer = {
|
|
8
|
+
type: string;
|
|
9
|
+
setup: () => MaybePromise<void>;
|
|
10
|
+
teardown: () => MaybePromise<void>;
|
|
11
|
+
publish: (payload: string) => MaybePromise<void>;
|
|
12
|
+
subscribe: (handler: (payload: string) => void) => MaybePromise<void>;
|
|
13
|
+
};
|
|
14
|
+
export type SignalLayerCreator = (properties: SignalBaseProperties) => MaybePromise<SignalingLayer>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/signaling/base.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { MaybePromise } from 'viem';
|
|
2
|
+
import { SymmetricKey } from '../encryption/handshake.js';
|
|
3
|
+
import { EncryptionKey } from '../encryption/index.js';
|
|
4
|
+
import { SignalingBaseLayer } from './base.js';
|
|
5
|
+
export type SignalingProperties = {
|
|
6
|
+
isHost: boolean;
|
|
7
|
+
h: string;
|
|
8
|
+
k?: SymmetricKey;
|
|
9
|
+
rpDiscovered: (rpKey: string) => MaybePromise<void>;
|
|
10
|
+
decrypt: (message: string) => MaybePromise<string>;
|
|
11
|
+
encrypt: (message: string) => MaybePromise<string>;
|
|
12
|
+
publicKey: EncryptionKey;
|
|
13
|
+
canEncrypt: () => boolean;
|
|
14
|
+
};
|
|
15
|
+
export type SignalingLayer = (properties: SignalingProperties) => Promise<{
|
|
16
|
+
type: string;
|
|
17
|
+
send: (message: object) => MaybePromise<void>;
|
|
18
|
+
subscribe: (handler: (message: object) => void) => MaybePromise<void>;
|
|
19
|
+
setup: () => MaybePromise<void>;
|
|
20
|
+
teardown: () => MaybePromise<void>;
|
|
21
|
+
getState: () => {
|
|
22
|
+
state: SignalingMode;
|
|
23
|
+
};
|
|
24
|
+
}>;
|
|
25
|
+
export declare const XR_PREFIX = "x";
|
|
26
|
+
export declare const XR_H_PREFIX = "h";
|
|
27
|
+
export type SignalingMode = 'handshake-open' | 'handshaking' | 'handshake-closed' | 'xr-encrypted' | 'connecting' | 'disconnected';
|
|
28
|
+
export declare const createSignalingLayer: (init: SignalingBaseLayer) => SignalingLayer;
|