@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/signaling/ntfy/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* URL format supports the ?auth= parameter
|
|
3
|
+
* example: https://ntfy.sh/?auth=mytoken
|
|
4
|
+
* example: http://authtoken123@myserver.example.com/
|
|
5
|
+
*
|
|
6
|
+
* The same goes for apprise ntfy urls
|
|
7
|
+
* example: ntfy://{token}@{host}/
|
|
8
|
+
* example: ntfy://{user}:{password}@{host}/
|
|
9
|
+
* https variant: ntfys://{user}:{password}@{host}/
|
|
10
|
+
*/
|
|
11
|
+
export const parseNtfyUrl = (url) => {
|
|
12
|
+
const regex = /^(?<protocol>https?|ntfys?):\/\/(?:(?:(?<user>[^:@]+):)?(?<password>[^@]+)?@)?(?<host>[^/?]+)\/?(?<parameters>.*)$/;
|
|
13
|
+
const match = url.match(regex);
|
|
14
|
+
if (!match) {
|
|
15
|
+
throw new Error(`Invalid NTFY URL: ${url}`);
|
|
16
|
+
}
|
|
17
|
+
const { protocol: protocolType, user, password, host, parameters } = match.groups || {};
|
|
18
|
+
// Determine protocol
|
|
19
|
+
let protocol;
|
|
20
|
+
if (['http', 'ntfy'].includes(protocolType)) {
|
|
21
|
+
protocol = 'http';
|
|
22
|
+
}
|
|
23
|
+
else if (['https', 'ntfys'].includes(protocolType)) {
|
|
24
|
+
protocol = 'https';
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
throw new Error(`Invalid NTFY URL: ${url}`);
|
|
28
|
+
}
|
|
29
|
+
const credentials = user ? { user, password } : password ? { token: password } : undefined;
|
|
30
|
+
return {
|
|
31
|
+
host,
|
|
32
|
+
protocol,
|
|
33
|
+
credentials,
|
|
34
|
+
parameters: parameters ? parameters : undefined,
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url.js","sourceRoot":"","sources":["../../../src/signaling/ntfy/url.ts"],"names":[],"mappings":"AAYA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAW,EAAW,EAAE;IACjD,MAAM,KAAK,GACP,oHAAoH,CAAC;IACzH,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;IAExF,qBAAqB;IACrB,IAAI,QAA0B,CAAC;IAE/B,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC1C,QAAQ,GAAG,MAAM,CAAC;IACtB,CAAC;SAAM,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACnD,QAAQ,GAAG,OAAO,CAAC;IACvB,CAAC;SAAM,CAAC;QACJ,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAE3F,OAAO;QACH,IAAI;QACJ,QAAQ;QACR,WAAW;QACX,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;KAClD,CAAC;AACN,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { parseNtfyUrl } from './url.js';
|
|
3
|
+
const testCases = [
|
|
4
|
+
{
|
|
5
|
+
url: 'https://ntfy.sh/?auth=mytoken1',
|
|
6
|
+
expected: {
|
|
7
|
+
host: 'ntfy.sh',
|
|
8
|
+
protocol: 'https',
|
|
9
|
+
parameters: '?auth=mytoken1',
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
url: 'http://ntfy.sh/?auth=mytoken2',
|
|
14
|
+
expected: {
|
|
15
|
+
host: 'ntfy.sh',
|
|
16
|
+
protocol: 'http',
|
|
17
|
+
parameters: '?auth=mytoken2',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
url: 'ntfy://mytoken@example.com',
|
|
22
|
+
expected: {
|
|
23
|
+
host: 'example.com',
|
|
24
|
+
protocol: 'http',
|
|
25
|
+
credentials: { token: 'mytoken' },
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
url: 'ntfys://myuser:mypassword@ntfy.sh/',
|
|
30
|
+
expected: {
|
|
31
|
+
host: 'ntfy.sh',
|
|
32
|
+
protocol: 'https',
|
|
33
|
+
credentials: { user: 'myuser', password: 'mypassword' },
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
url: 'ntfy://mytoken@ntfy.sh/?auth=mytoken',
|
|
38
|
+
expected: {
|
|
39
|
+
host: 'ntfy.sh',
|
|
40
|
+
protocol: 'http',
|
|
41
|
+
credentials: { token: 'mytoken' },
|
|
42
|
+
parameters: '?auth=mytoken',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
describe('should parse NTFY URL', () => {
|
|
47
|
+
testCases.forEach((testCase) => {
|
|
48
|
+
it(`should parse NTFY URL ${testCase.url}`, () => {
|
|
49
|
+
const result = parseNtfyUrl(testCase.url);
|
|
50
|
+
expect(result).toEqual(testCase.expected);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=url.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url.test.js","sourceRoot":"","sources":["../../../src/signaling/ntfy/url.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,SAAS,GAAG;IACd;QACI,GAAG,EAAE,gCAAgC;QACrC,QAAQ,EAAE;YACN,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,OAAO;YACjB,UAAU,EAAE,gBAAgB;SAC/B;KACJ;IACD;QACI,GAAG,EAAE,+BAA+B;QACpC,QAAQ,EAAE;YACN,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,MAAM;YAChB,UAAU,EAAE,gBAAgB;SAC/B;KACJ;IACD;QACI,GAAG,EAAE,4BAA4B;QACjC,QAAQ,EAAE;YACN,IAAI,EAAE,aAAa;YACnB,QAAQ,EAAE,MAAM;YAChB,WAAW,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;SACpC;KACJ;IACD;QACI,GAAG,EAAE,oCAAoC;QACzC,QAAQ,EAAE;YACN,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,OAAO;YACjB,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE;SAC1D;KACJ;IACD;QACI,GAAG,EAAE,sCAAsC;QAC3C,QAAQ,EAAE;YACN,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,MAAM;YAChB,WAAW,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;YACjC,UAAU,EAAE,eAAe;SAC9B;KACJ;CACJ,CAAC;AAEF,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACnC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;QAC3B,EAAE,CAAC,yBAAyB,QAAQ,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE;YAC7C,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MaybePromise } from 'viem';
|
|
2
|
+
export type TransportInit = {
|
|
3
|
+
type: string;
|
|
4
|
+
setup: () => MaybePromise<void>;
|
|
5
|
+
teardown: () => MaybePromise<void>;
|
|
6
|
+
};
|
|
7
|
+
export type TransportLayer = {
|
|
8
|
+
type: string;
|
|
9
|
+
foo: 'bar';
|
|
10
|
+
};
|
|
11
|
+
export declare const createTransportLayerBase: (init: TransportInit) => TransportLayer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/transport/index.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,IAAmB,EAAkB,EAAE;IAC5E,EAAE;IAEF,OAAO;QACH,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,GAAG,EAAE,KAAK;KACb,CAAC;AACN,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const webrtc: () => import("../index.js").TransportLayer;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { createTransportLayerBase } from '../index.js';
|
|
2
|
+
export const webrtc = () => {
|
|
3
|
+
return createTransportLayerBase({
|
|
4
|
+
type: 'webrtc',
|
|
5
|
+
setup() {
|
|
6
|
+
//
|
|
7
|
+
// const iceServers = [
|
|
8
|
+
// { urls: 'stun:stun.l.google.com:19302' },
|
|
9
|
+
// { urls: 'stun:stun1.l.google.com:19302' },
|
|
10
|
+
// { urls: 'stun:stun.services.mozilla.com:3478' },
|
|
11
|
+
// {
|
|
12
|
+
// urls: ['turn:openrelay.metered.ca:80', 'turn:openrelay.metered.ca:443'],
|
|
13
|
+
// username: 'openrelayproject',
|
|
14
|
+
// credential: 'openrelayproject',
|
|
15
|
+
// },
|
|
16
|
+
// ];
|
|
17
|
+
// this.peerConnection = new RTCPeerConnection({
|
|
18
|
+
// iceServers,
|
|
19
|
+
// iceCandidatePoolSize: 10,
|
|
20
|
+
// iceTransportPolicy: 'all',
|
|
21
|
+
// bundlePolicy: 'max-bundle',
|
|
22
|
+
// rtcpMuxPolicy: 'require',
|
|
23
|
+
// });
|
|
24
|
+
// // Connection state handlers
|
|
25
|
+
// this.peerConnection.onconnectionstatechange = () => {
|
|
26
|
+
// const state = this.peerConnection!.connectionState;
|
|
27
|
+
// console.log('WebRTC connection state:', state);
|
|
28
|
+
// if (state === 'connected') {
|
|
29
|
+
// this.updateConnectionState('webrtc-connected', 'Direct P2P connection established');
|
|
30
|
+
// } else if (state === 'failed') {
|
|
31
|
+
// this.retryWebRTC();
|
|
32
|
+
// } else if (state === 'connecting') {
|
|
33
|
+
// this.updateConnectionState('webrtc-negotiating', 'Establishing P2P connection...');
|
|
34
|
+
// }
|
|
35
|
+
// };
|
|
36
|
+
// // ICE candidate handler
|
|
37
|
+
// this.peerConnection.onicecandidate = async (event) => {
|
|
38
|
+
// if (event.candidate && this.peerPublicKey) {
|
|
39
|
+
// const encryptedCandidate = await EncryptionUtils.encryptMessage(
|
|
40
|
+
// event.candidate,
|
|
41
|
+
// this.peerPublicKey,
|
|
42
|
+
// this.privateKey!,
|
|
43
|
+
// this.publicKey!
|
|
44
|
+
// );
|
|
45
|
+
// await this.signaling.publish({
|
|
46
|
+
// type: 'ice-candidate',
|
|
47
|
+
// payload: encryptedCandidate,
|
|
48
|
+
// sessionId: this.sessionId!,
|
|
49
|
+
// timestamp: Date.now(),
|
|
50
|
+
// senderId: this.peerId,
|
|
51
|
+
// });
|
|
52
|
+
// }
|
|
53
|
+
// };
|
|
54
|
+
// // Data channel setup
|
|
55
|
+
// if (this.isInitiator) {
|
|
56
|
+
// this.dataChannel = this.peerConnection.createDataChannel('openlv-data');
|
|
57
|
+
// this.setupDataChannel();
|
|
58
|
+
// } else {
|
|
59
|
+
// this.peerConnection.ondatachannel = (event) => {
|
|
60
|
+
// this.dataChannel = event.channel;
|
|
61
|
+
// this.setupDataChannel();
|
|
62
|
+
// };
|
|
63
|
+
// }
|
|
64
|
+
},
|
|
65
|
+
teardown() {
|
|
66
|
+
//
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/transport/webrtc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEvD,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,EAAE;IACvB,OAAO,wBAAwB,CAAC;QAC5B,IAAI,EAAE,QAAQ;QACd,KAAK;YACD,EAAE;YACF,uBAAuB;YACvB,gDAAgD;YAChD,iDAAiD;YACjD,uDAAuD;YACvD,QAAQ;YACR,mFAAmF;YACnF,wCAAwC;YACxC,0CAA0C;YAC1C,SAAS;YACT,KAAK;YACL,gDAAgD;YAChD,kBAAkB;YAClB,gCAAgC;YAChC,iCAAiC;YACjC,kCAAkC;YAClC,gCAAgC;YAChC,MAAM;YACN,+BAA+B;YAC/B,wDAAwD;YACxD,0DAA0D;YAC1D,sDAAsD;YACtD,mCAAmC;YACnC,+FAA+F;YAC/F,uCAAuC;YACvC,8BAA8B;YAC9B,2CAA2C;YAC3C,8FAA8F;YAC9F,QAAQ;YACR,KAAK;YACL,2BAA2B;YAC3B,0DAA0D;YAC1D,mDAAmD;YACnD,2EAA2E;YAC3E,+BAA+B;YAC/B,kCAAkC;YAClC,gCAAgC;YAChC,8BAA8B;YAC9B,aAAa;YACb,yCAAyC;YACzC,qCAAqC;YACrC,2CAA2C;YAC3C,0CAA0C;YAC1C,qCAAqC;YACrC,qCAAqC;YACrC,cAAc;YACd,QAAQ;YACR,KAAK;YACL,wBAAwB;YACxB,0BAA0B;YAC1B,+EAA+E;YAC/E,+BAA+B;YAC/B,WAAW;YACX,uDAAuD;YACvD,4CAA4C;YAC5C,mCAAmC;YACnC,SAAS;YACT,IAAI;QACR,CAAC;QACD,QAAQ;YACJ,EAAE;QACN,CAAC;KACJ,CAAC,CAAC;AACP,CAAC,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open Lavatory Protocol Types
|
|
3
|
+
* Includes JSON-RPC types for Ethereum wallet connectivity
|
|
4
|
+
*/
|
|
5
|
+
export type ConnectionState = "disconnected" | "mqtt-connecting" | "mqtt-connected" | "pairing" | "key-exchange" | "webrtc-negotiating" | "webrtc-connected";
|
|
6
|
+
export type ConnectionPhase = {
|
|
7
|
+
state: ConnectionState;
|
|
8
|
+
description: string;
|
|
9
|
+
timestamp: number;
|
|
10
|
+
};
|
|
11
|
+
export type SessionConfig = {
|
|
12
|
+
mqttUrl?: string;
|
|
13
|
+
protocol?: "mqtt" | "waku" | "nostr";
|
|
14
|
+
};
|
|
15
|
+
export interface JsonRpcRequest {
|
|
16
|
+
jsonrpc: "2.0";
|
|
17
|
+
id: string | number;
|
|
18
|
+
method: string;
|
|
19
|
+
params?: any[];
|
|
20
|
+
}
|
|
21
|
+
export interface JsonRpcResponse {
|
|
22
|
+
jsonrpc: "2.0";
|
|
23
|
+
id: string | number;
|
|
24
|
+
result?: any;
|
|
25
|
+
error?: JsonRpcError;
|
|
26
|
+
}
|
|
27
|
+
export interface JsonRpcError {
|
|
28
|
+
code: number;
|
|
29
|
+
message: string;
|
|
30
|
+
data?: any;
|
|
31
|
+
}
|
|
32
|
+
export type EthereumMethod = "eth_requestAccounts" | "eth_accounts" | "eth_chainId" | "eth_getBalance" | "eth_blockNumber" | "eth_sendTransaction" | "eth_signTransaction" | "eth_sign" | "personal_sign" | "eth_signTypedData" | "eth_signTypedData_v3" | "eth_signTypedData_v4" | "wallet_switchEthereumChain" | "wallet_addEthereumChain";
|
|
33
|
+
export interface EthereumRequest extends JsonRpcRequest {
|
|
34
|
+
method: EthereumMethod;
|
|
35
|
+
}
|
|
36
|
+
export type EthereumResponse = JsonRpcResponse;
|
|
37
|
+
export interface WalletInfo {
|
|
38
|
+
name: string;
|
|
39
|
+
version: string;
|
|
40
|
+
icon?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface DAppInfo {
|
|
43
|
+
name: string;
|
|
44
|
+
url: string;
|
|
45
|
+
icon?: string;
|
|
46
|
+
}
|
|
47
|
+
export type MessageHandler = (request: JsonRpcRequest) => Promise<any> | any;
|
|
48
|
+
export type PhaseHandler = (phase: ConnectionPhase) => void;
|
|
49
|
+
export type ErrorHandler = (error: Error) => void;
|
|
50
|
+
export interface ConnectionEvents {
|
|
51
|
+
onPhaseChange?: PhaseHandler;
|
|
52
|
+
onMessage?: MessageHandler;
|
|
53
|
+
onError?: ErrorHandler;
|
|
54
|
+
onConnect?: () => void;
|
|
55
|
+
onDisconnect?: () => void;
|
|
56
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encryption utilities for Open Lavatory Protocol
|
|
3
|
+
* Implements ECDH key exchange with P-256 curve and ECIES encryption
|
|
4
|
+
*/
|
|
5
|
+
export declare class EncryptionUtils {
|
|
6
|
+
/**
|
|
7
|
+
* URL-safe alphabet for session ID generation
|
|
8
|
+
*/
|
|
9
|
+
private static readonly URL_SAFE_ALPHABET;
|
|
10
|
+
/**
|
|
11
|
+
* Generate a cryptographically secure URL-safe random string
|
|
12
|
+
*/
|
|
13
|
+
static generateUrlSafeRandomString(length: number): string;
|
|
14
|
+
/**
|
|
15
|
+
* Generate a 16-character URL-safe session ID
|
|
16
|
+
*/
|
|
17
|
+
static generateSessionId(): string;
|
|
18
|
+
/**
|
|
19
|
+
* Generate a 32-byte random shared key and return as hex
|
|
20
|
+
*/
|
|
21
|
+
static generateSharedKey(): string;
|
|
22
|
+
/**
|
|
23
|
+
* Convert hex string to Uint8Array
|
|
24
|
+
*/
|
|
25
|
+
static hexToBytes(hex: string): Uint8Array;
|
|
26
|
+
/**
|
|
27
|
+
* Convert Uint8Array to hex string
|
|
28
|
+
*/
|
|
29
|
+
static bytesToHex(bytes: Uint8Array): string;
|
|
30
|
+
/**
|
|
31
|
+
* Generate an ECDH keypair using P-256 curve
|
|
32
|
+
*/
|
|
33
|
+
static generateKeyPair(): Promise<{
|
|
34
|
+
privateKey: CryptoKey;
|
|
35
|
+
publicKey: CryptoKey;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Export public key to raw format (65 bytes uncompressed)
|
|
39
|
+
*/
|
|
40
|
+
static exportPublicKey(publicKey: CryptoKey): Promise<ArrayBuffer>;
|
|
41
|
+
/**
|
|
42
|
+
* Import public key from raw format
|
|
43
|
+
*/
|
|
44
|
+
static importPublicKey(keyData: ArrayBuffer): Promise<CryptoKey>;
|
|
45
|
+
/**
|
|
46
|
+
* Compute SHA-256 hash of public key and return first 8 bytes as hex
|
|
47
|
+
*/
|
|
48
|
+
static computePublicKeyHash(publicKey: CryptoKey): Promise<string>;
|
|
49
|
+
/**
|
|
50
|
+
* Compute SHA-256 hash of raw public key data
|
|
51
|
+
*/
|
|
52
|
+
static computePublicKeyHashFromRaw(publicKeyData: Uint8Array): Promise<string>;
|
|
53
|
+
/**
|
|
54
|
+
* Derive shared AES-GCM key from ECDH key exchange
|
|
55
|
+
*/
|
|
56
|
+
static deriveSharedKey(privateKey: CryptoKey, peerPublicKey: CryptoKey): Promise<CryptoKey>;
|
|
57
|
+
/**
|
|
58
|
+
* Encrypt message using ECIES scheme
|
|
59
|
+
* Format: ephemeral_pubkey || iv || encrypted_data || auth_tag
|
|
60
|
+
*/
|
|
61
|
+
static encryptMessage(message: any, recipientPublicKey: CryptoKey, senderPrivateKey: CryptoKey, senderPublicKey: CryptoKey): Promise<string>;
|
|
62
|
+
/**
|
|
63
|
+
* Decrypt message using ECIES scheme
|
|
64
|
+
*/
|
|
65
|
+
static decryptMessage(encryptedMessage: string, recipientPrivateKey: CryptoKey): Promise<any>;
|
|
66
|
+
/**
|
|
67
|
+
* Convert public key to base64 string for transmission
|
|
68
|
+
*/
|
|
69
|
+
static publicKeyToBase64(publicKey: CryptoKey): Promise<string>;
|
|
70
|
+
/**
|
|
71
|
+
* Convert base64 string back to public key
|
|
72
|
+
*/
|
|
73
|
+
static publicKeyFromBase64(base64Key: string): Promise<CryptoKey>;
|
|
74
|
+
/**
|
|
75
|
+
* Derive symmetric key from hex-encoded shared secret (for initial handshake)
|
|
76
|
+
*/
|
|
77
|
+
static deriveSymmetricKey(sharedSecretHex: string): Promise<CryptoKey>;
|
|
78
|
+
/**
|
|
79
|
+
* Encrypt message using symmetric key (for initial handshake)
|
|
80
|
+
*/
|
|
81
|
+
static encryptSymmetric(message: any, sharedKey: CryptoKey): Promise<string>;
|
|
82
|
+
/**
|
|
83
|
+
* Decrypt message using symmetric key (for initial handshake)
|
|
84
|
+
*/
|
|
85
|
+
static decryptSymmetric(encryptedMessage: string, sharedKey: CryptoKey): Promise<any>;
|
|
86
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encryption utilities for Open Lavatory Protocol
|
|
3
|
+
* Implements ECDH key exchange with P-256 curve and ECIES encryption
|
|
4
|
+
*/
|
|
5
|
+
export class EncryptionUtils {
|
|
6
|
+
/**
|
|
7
|
+
* Generate a cryptographically secure URL-safe random string
|
|
8
|
+
*/
|
|
9
|
+
static generateUrlSafeRandomString(length) {
|
|
10
|
+
const array = new Uint8Array(length);
|
|
11
|
+
crypto.getRandomValues(array);
|
|
12
|
+
return Array.from(array)
|
|
13
|
+
.map((byte) => EncryptionUtils.URL_SAFE_ALPHABET[byte % EncryptionUtils.URL_SAFE_ALPHABET.length])
|
|
14
|
+
.join("");
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Generate a 16-character URL-safe session ID
|
|
18
|
+
*/
|
|
19
|
+
static generateSessionId() {
|
|
20
|
+
return EncryptionUtils.generateUrlSafeRandomString(16);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Generate a 32-byte random shared key and return as hex
|
|
24
|
+
*/
|
|
25
|
+
static generateSharedKey() {
|
|
26
|
+
const array = new Uint8Array(32);
|
|
27
|
+
crypto.getRandomValues(array);
|
|
28
|
+
return Array.from(array)
|
|
29
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
30
|
+
.join("");
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Convert hex string to Uint8Array
|
|
34
|
+
*/
|
|
35
|
+
static hexToBytes(hex) {
|
|
36
|
+
if (hex.length % 2 !== 0) {
|
|
37
|
+
throw new Error("Hex string must have even length");
|
|
38
|
+
}
|
|
39
|
+
const array = new Uint8Array(hex.length / 2);
|
|
40
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
41
|
+
array[i / 2] = parseInt(hex.substr(i, 2), 16);
|
|
42
|
+
}
|
|
43
|
+
return array;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Convert Uint8Array to hex string
|
|
47
|
+
*/
|
|
48
|
+
static bytesToHex(bytes) {
|
|
49
|
+
return Array.from(bytes)
|
|
50
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
51
|
+
.join("");
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Generate an ECDH keypair using P-256 curve
|
|
55
|
+
*/
|
|
56
|
+
static async generateKeyPair() {
|
|
57
|
+
return await crypto.subtle.generateKey({
|
|
58
|
+
name: "ECDH",
|
|
59
|
+
namedCurve: "P-256",
|
|
60
|
+
}, true, ["deriveKey"]);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Export public key to raw format (65 bytes uncompressed)
|
|
64
|
+
*/
|
|
65
|
+
static async exportPublicKey(publicKey) {
|
|
66
|
+
return await crypto.subtle.exportKey("raw", publicKey);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Import public key from raw format
|
|
70
|
+
*/
|
|
71
|
+
static async importPublicKey(keyData) {
|
|
72
|
+
return await crypto.subtle.importKey("raw", keyData, {
|
|
73
|
+
name: "ECDH",
|
|
74
|
+
namedCurve: "P-256",
|
|
75
|
+
}, false, []);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Compute SHA-256 hash of public key and return first 8 bytes as hex
|
|
79
|
+
*/
|
|
80
|
+
static async computePublicKeyHash(publicKey) {
|
|
81
|
+
const exportedKey = await EncryptionUtils.exportPublicKey(publicKey);
|
|
82
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", exportedKey);
|
|
83
|
+
const hashArray = new Uint8Array(hashBuffer);
|
|
84
|
+
const shortHash = hashArray.slice(0, 8); // First 8 bytes
|
|
85
|
+
return Array.from(shortHash)
|
|
86
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
87
|
+
.join("");
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Compute SHA-256 hash of raw public key data
|
|
91
|
+
*/
|
|
92
|
+
static async computePublicKeyHashFromRaw(publicKeyData) {
|
|
93
|
+
// @ts-expect-error
|
|
94
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", publicKeyData);
|
|
95
|
+
const hashArray = new Uint8Array(hashBuffer);
|
|
96
|
+
const shortHash = hashArray.slice(0, 8); // First 8 bytes
|
|
97
|
+
return Array.from(shortHash)
|
|
98
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
99
|
+
.join("");
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Derive shared AES-GCM key from ECDH key exchange
|
|
103
|
+
*/
|
|
104
|
+
static async deriveSharedKey(privateKey, peerPublicKey) {
|
|
105
|
+
const sharedSecret = await crypto.subtle.deriveKey({
|
|
106
|
+
name: "ECDH",
|
|
107
|
+
public: peerPublicKey,
|
|
108
|
+
}, privateKey, {
|
|
109
|
+
name: "AES-GCM",
|
|
110
|
+
length: 256,
|
|
111
|
+
}, false, ["encrypt", "decrypt"]);
|
|
112
|
+
return sharedSecret;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Encrypt message using ECIES scheme
|
|
116
|
+
* Format: ephemeral_pubkey || iv || encrypted_data || auth_tag
|
|
117
|
+
*/
|
|
118
|
+
static async encryptMessage(message, recipientPublicKey, senderPrivateKey, senderPublicKey) {
|
|
119
|
+
const sharedKey = await EncryptionUtils.deriveSharedKey(senderPrivateKey, recipientPublicKey);
|
|
120
|
+
const encoder = new TextEncoder();
|
|
121
|
+
const data = encoder.encode(JSON.stringify(message));
|
|
122
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
123
|
+
const encrypted = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, sharedKey, data);
|
|
124
|
+
// Get ephemeral public key for ECIES
|
|
125
|
+
const ephemeralPublicKey = await EncryptionUtils.exportPublicKey(senderPublicKey);
|
|
126
|
+
// Combine ephemeral public key, IV and encrypted data
|
|
127
|
+
const combined = new Uint8Array(ephemeralPublicKey.byteLength + iv.length + encrypted.byteLength);
|
|
128
|
+
combined.set(new Uint8Array(ephemeralPublicKey));
|
|
129
|
+
combined.set(iv, ephemeralPublicKey.byteLength);
|
|
130
|
+
combined.set(new Uint8Array(encrypted), ephemeralPublicKey.byteLength + iv.length);
|
|
131
|
+
// Return as base64
|
|
132
|
+
return btoa(String.fromCharCode.apply(null, Array.from(combined)));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Decrypt message using ECIES scheme
|
|
136
|
+
*/
|
|
137
|
+
static async decryptMessage(encryptedMessage, recipientPrivateKey) {
|
|
138
|
+
try {
|
|
139
|
+
// Decode from base64
|
|
140
|
+
const combined = new Uint8Array(atob(encryptedMessage)
|
|
141
|
+
.split("")
|
|
142
|
+
.map((char) => char.charCodeAt(0)));
|
|
143
|
+
// Extract ephemeral public key, IV and encrypted data
|
|
144
|
+
const ephemeralPublicKey = combined.slice(0, 65); // P-256 uncompressed key is 65 bytes
|
|
145
|
+
const iv = combined.slice(65, 77); // 12 bytes
|
|
146
|
+
const encrypted = combined.slice(77);
|
|
147
|
+
// Import ephemeral public key
|
|
148
|
+
const senderPublicKey = await EncryptionUtils.importPublicKey(ephemeralPublicKey.buffer);
|
|
149
|
+
// Derive shared key
|
|
150
|
+
const sharedKey = await EncryptionUtils.deriveSharedKey(recipientPrivateKey, senderPublicKey);
|
|
151
|
+
const decrypted = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, sharedKey, encrypted);
|
|
152
|
+
const decoder = new TextDecoder();
|
|
153
|
+
const messageStr = decoder.decode(decrypted);
|
|
154
|
+
return JSON.parse(messageStr);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
console.error("Failed to decrypt message:", error);
|
|
158
|
+
throw new Error("Message decryption failed");
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Convert public key to base64 string for transmission
|
|
163
|
+
*/
|
|
164
|
+
static async publicKeyToBase64(publicKey) {
|
|
165
|
+
const exportedKey = await EncryptionUtils.exportPublicKey(publicKey);
|
|
166
|
+
return btoa(String.fromCharCode.apply(null, Array.from(new Uint8Array(exportedKey))));
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Convert base64 string back to public key
|
|
170
|
+
*/
|
|
171
|
+
static async publicKeyFromBase64(base64Key) {
|
|
172
|
+
const keyData = new Uint8Array(atob(base64Key)
|
|
173
|
+
.split("")
|
|
174
|
+
.map((char) => char.charCodeAt(0)));
|
|
175
|
+
return await EncryptionUtils.importPublicKey(keyData.buffer);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Derive symmetric key from hex-encoded shared secret (for initial handshake)
|
|
179
|
+
*/
|
|
180
|
+
static async deriveSymmetricKey(sharedSecretHex) {
|
|
181
|
+
const sharedSecretBytes = EncryptionUtils.hexToBytes(sharedSecretHex);
|
|
182
|
+
// @ts-expect-error
|
|
183
|
+
const sharedSecretBytesBufferSource = sharedSecretBytes;
|
|
184
|
+
const keyMaterial = await crypto.subtle.importKey("raw", sharedSecretBytesBufferSource, "PBKDF2", false, ["deriveKey"]);
|
|
185
|
+
const encoder = new TextEncoder();
|
|
186
|
+
return await crypto.subtle.deriveKey({
|
|
187
|
+
name: "PBKDF2",
|
|
188
|
+
salt: encoder.encode("openlv-salt"), // Fixed salt for deterministic key
|
|
189
|
+
iterations: 100000,
|
|
190
|
+
hash: "SHA-256",
|
|
191
|
+
}, keyMaterial, {
|
|
192
|
+
name: "AES-GCM",
|
|
193
|
+
length: 256,
|
|
194
|
+
}, false, ["encrypt", "decrypt"]);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Encrypt message using symmetric key (for initial handshake)
|
|
198
|
+
*/
|
|
199
|
+
static async encryptSymmetric(message, sharedKey) {
|
|
200
|
+
const encoder = new TextEncoder();
|
|
201
|
+
const data = encoder.encode(JSON.stringify(message));
|
|
202
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
203
|
+
const encrypted = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, sharedKey, data);
|
|
204
|
+
// Combine IV and encrypted data
|
|
205
|
+
const combined = new Uint8Array(iv.length + encrypted.byteLength);
|
|
206
|
+
combined.set(iv);
|
|
207
|
+
combined.set(new Uint8Array(encrypted), iv.length);
|
|
208
|
+
// Return as base64
|
|
209
|
+
return btoa(String.fromCharCode.apply(null, Array.from(combined)));
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Decrypt message using symmetric key (for initial handshake)
|
|
213
|
+
*/
|
|
214
|
+
static async decryptSymmetric(encryptedMessage, sharedKey) {
|
|
215
|
+
try {
|
|
216
|
+
// Decode from base64
|
|
217
|
+
const combined = new Uint8Array(atob(encryptedMessage)
|
|
218
|
+
.split("")
|
|
219
|
+
.map((char) => char.charCodeAt(0)));
|
|
220
|
+
// Extract IV and encrypted data
|
|
221
|
+
const iv = combined.slice(0, 12); // 12 bytes
|
|
222
|
+
const encrypted = combined.slice(12);
|
|
223
|
+
const decrypted = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, sharedKey, encrypted);
|
|
224
|
+
const decoder = new TextDecoder();
|
|
225
|
+
const messageStr = decoder.decode(decrypted);
|
|
226
|
+
return JSON.parse(messageStr);
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
console.error("Failed to decrypt symmetric message:", error);
|
|
230
|
+
throw new Error("Symmetric message decryption failed");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* URL-safe alphabet for session ID generation
|
|
236
|
+
*/
|
|
237
|
+
Object.defineProperty(EncryptionUtils, "URL_SAFE_ALPHABET", {
|
|
238
|
+
enumerable: true,
|
|
239
|
+
configurable: true,
|
|
240
|
+
writable: true,
|
|
241
|
+
value: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
|
|
242
|
+
});
|
|
243
|
+
//# sourceMappingURL=encryption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../src/utils/encryption.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const log: (...x: Parameters<typeof console.log>) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/utils/log.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,CAAiC,EAAE,EAAE,CAC1D,OAAO,CAAC,GAAG,CACT,eAAe,EACf,kCAAkC,EAClC,qCAAqC,EACrC,GAAG,CAAC,CACL,CAAC"}
|