nostr-websocket-utils 0.3.17 → 0.3.18
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 +2 -2
- package/dist/browser/nostr-websocket-utils.min.js +2 -2
- package/dist/browser/nostr-websocket-utils.min.js.map +7 -1
- package/dist/browser/report.html +1 -1
- package/dist/cjs/nips/index.d.ts +2 -0
- package/dist/cjs/nips/index.d.ts.map +1 -1
- package/dist/cjs/nips/index.js +5 -1
- package/dist/cjs/nips/index.js.map +1 -1
- package/dist/cjs/nips/nip-26.d.ts.map +1 -1
- package/dist/cjs/nips/nip-26.js +3 -7
- package/dist/cjs/nips/nip-26.js.map +1 -1
- package/dist/cjs/nips/nip-44.d.ts +69 -0
- package/dist/cjs/nips/nip-44.d.ts.map +1 -0
- package/dist/cjs/nips/nip-44.js +143 -0
- package/dist/cjs/nips/nip-44.js.map +1 -0
- package/dist/cjs/nips/nip-46.d.ts +112 -0
- package/dist/cjs/nips/nip-46.d.ts.map +1 -0
- package/dist/cjs/nips/nip-46.js +123 -0
- package/dist/cjs/nips/nip-46.js.map +1 -0
- package/dist/nips/index.d.ts +2 -0
- package/dist/nips/index.d.ts.map +1 -1
- package/dist/nips/index.js +5 -1
- package/dist/nips/index.js.map +1 -1
- package/dist/nips/nip-26.d.ts.map +1 -1
- package/dist/nips/nip-26.js +4 -8
- package/dist/nips/nip-26.js.map +1 -1
- package/dist/nips/nip-44.d.ts +69 -0
- package/dist/nips/nip-44.d.ts.map +1 -0
- package/dist/nips/nip-44.js +134 -0
- package/dist/nips/nip-44.js.map +1 -0
- package/dist/nips/nip-46.d.ts +112 -0
- package/dist/nips/nip-46.d.ts.map +1 -0
- package/dist/nips/nip-46.js +119 -0
- package/dist/nips/nip-46.js.map +1 -0
- package/package.json +5 -9
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file NIP-44: Versioned Encrypted Payloads
|
|
4
|
+
* @module nips/nip-44
|
|
5
|
+
* @see https://github.com/nostr-protocol/nips/blob/master/44.md
|
|
6
|
+
*
|
|
7
|
+
* NIP-44 replaces NIP-04 with a modern encryption scheme using
|
|
8
|
+
* ChaCha20 + HMAC-SHA256. This module provides DM-level helpers
|
|
9
|
+
* that parallel the NIP-04 module (nip-04.ts).
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ENCRYPTED_DM_KIND_44 = void 0;
|
|
13
|
+
exports.getConversationKey = getConversationKey;
|
|
14
|
+
exports.encryptNip44 = encryptNip44;
|
|
15
|
+
exports.decryptNip44 = decryptNip44;
|
|
16
|
+
exports.createEncryptedDM44 = createEncryptedDM44;
|
|
17
|
+
exports.decryptDM44 = decryptDM44;
|
|
18
|
+
exports.validateEncryptedDM44 = validateEncryptedDM44;
|
|
19
|
+
const nostr_crypto_utils_1 = require("nostr-crypto-utils");
|
|
20
|
+
/**
|
|
21
|
+
* Kind value for NIP-44 encrypted direct messages (gift-wrapped DMs use kind 14,
|
|
22
|
+
* but for parity with NIP-04 kind 4 usage, callers may choose their own kind).
|
|
23
|
+
* NIP-44 itself is a payload format, not a kind — the kind depends on the use case.
|
|
24
|
+
* We default to kind 44 as a convenience constant; callers should override as needed.
|
|
25
|
+
*/
|
|
26
|
+
exports.ENCRYPTED_DM_KIND_44 = 44;
|
|
27
|
+
/**
|
|
28
|
+
* Creates a NIP-44 conversation key from a sender's private key and recipient's public key.
|
|
29
|
+
* This key is symmetric and reusable for all messages in the conversation.
|
|
30
|
+
* @param senderPrivkeyHex - Sender's private key in hex
|
|
31
|
+
* @param recipientPubkeyHex - Recipient's public key in hex
|
|
32
|
+
* @returns Conversation key as Uint8Array
|
|
33
|
+
*/
|
|
34
|
+
function getConversationKey(senderPrivkeyHex, recipientPubkeyHex) {
|
|
35
|
+
const privkeyBytes = (0, nostr_crypto_utils_1.hexToBytes)(senderPrivkeyHex);
|
|
36
|
+
return nostr_crypto_utils_1.nip44.getConversationKey(privkeyBytes, recipientPubkeyHex);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Encrypts a message using NIP-44
|
|
40
|
+
* @param plaintext - Message content to encrypt
|
|
41
|
+
* @param senderPrivkeyHex - Sender's private key in hex
|
|
42
|
+
* @param recipientPubkeyHex - Recipient's public key in hex
|
|
43
|
+
* @returns Encrypted payload string (base64)
|
|
44
|
+
*/
|
|
45
|
+
function encryptNip44(plaintext, senderPrivkeyHex, recipientPubkeyHex) {
|
|
46
|
+
const conversationKey = getConversationKey(senderPrivkeyHex, recipientPubkeyHex);
|
|
47
|
+
return nostr_crypto_utils_1.nip44.encrypt(plaintext, conversationKey);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Decrypts a NIP-44 encrypted payload
|
|
51
|
+
* @param payload - Encrypted payload string (base64)
|
|
52
|
+
* @param recipientPrivkeyHex - Recipient's private key in hex
|
|
53
|
+
* @param senderPubkeyHex - Sender's public key in hex
|
|
54
|
+
* @returns Decrypted plaintext
|
|
55
|
+
*/
|
|
56
|
+
function decryptNip44(payload, recipientPrivkeyHex, senderPubkeyHex) {
|
|
57
|
+
const conversationKey = getConversationKey(recipientPrivkeyHex, senderPubkeyHex);
|
|
58
|
+
return nostr_crypto_utils_1.nip44.decrypt(payload, conversationKey);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Creates an encrypted direct message event using NIP-44
|
|
62
|
+
* @param content - Message content to encrypt
|
|
63
|
+
* @param recipientPubkey - Recipient's public key (hex)
|
|
64
|
+
* @param senderPrivkey - Sender's private key (hex)
|
|
65
|
+
* @param tags - Additional tags for the event
|
|
66
|
+
* @param kind - Event kind (defaults to ENCRYPTED_DM_KIND_44)
|
|
67
|
+
* @returns Encrypted message event as NostrWSMessage
|
|
68
|
+
*/
|
|
69
|
+
function createEncryptedDM44(content, recipientPubkey, senderPrivkey, tags = [], kind = exports.ENCRYPTED_DM_KIND_44) {
|
|
70
|
+
try {
|
|
71
|
+
const encryptedContent = encryptNip44(content, senderPrivkey, recipientPubkey);
|
|
72
|
+
const senderPubkey = (0, nostr_crypto_utils_1.getPublicKeySync)(senderPrivkey);
|
|
73
|
+
return ['EVENT', {
|
|
74
|
+
kind,
|
|
75
|
+
pubkey: senderPubkey,
|
|
76
|
+
content: encryptedContent,
|
|
77
|
+
tags: [
|
|
78
|
+
['p', recipientPubkey],
|
|
79
|
+
...tags
|
|
80
|
+
]
|
|
81
|
+
}];
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
85
|
+
throw new Error(`Failed to create NIP-44 encrypted DM: ${errorMessage}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Decrypts a received direct message event encrypted with NIP-44
|
|
90
|
+
* @param message - Received message
|
|
91
|
+
* @param recipientPrivkey - Recipient's private key (hex)
|
|
92
|
+
* @param senderPubkey - Sender's public key (hex)
|
|
93
|
+
* @param logger - Logger instance
|
|
94
|
+
* @returns Decrypted message content
|
|
95
|
+
*/
|
|
96
|
+
function decryptDM44(message, recipientPrivkey, senderPubkey, logger) {
|
|
97
|
+
try {
|
|
98
|
+
if (!Array.isArray(message) || message[0] !== 'EVENT') {
|
|
99
|
+
throw new Error('Invalid message format');
|
|
100
|
+
}
|
|
101
|
+
const event = message[1];
|
|
102
|
+
return decryptNip44(event.content, recipientPrivkey, senderPubkey);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
106
|
+
logger.error('Failed to decrypt NIP-44 DM:', errorMessage);
|
|
107
|
+
throw new Error(`Failed to decrypt NIP-44 DM: ${errorMessage}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Validates a NIP-44 encrypted DM event format
|
|
112
|
+
* @param message - Message to validate
|
|
113
|
+
* @param logger - Logger instance
|
|
114
|
+
* @returns True if message follows NIP-44 encrypted DM format
|
|
115
|
+
*/
|
|
116
|
+
function validateEncryptedDM44(message, logger) {
|
|
117
|
+
try {
|
|
118
|
+
if (!Array.isArray(message) || message[0] !== 'EVENT') {
|
|
119
|
+
logger.debug('Invalid message format');
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
const event = message[1];
|
|
123
|
+
if (!event.content || typeof event.content !== 'string') {
|
|
124
|
+
logger.debug('Missing or invalid content');
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
if (!Array.isArray(event.tags)) {
|
|
128
|
+
logger.debug('Missing tags array');
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
const recipientTag = event.tags.find((tag) => Array.isArray(tag) && tag[0] === 'p' && tag[1]);
|
|
132
|
+
if (!recipientTag) {
|
|
133
|
+
logger.debug('Missing recipient tag');
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
logger.error('Error validating NIP-44 encrypted DM:', error);
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=nip-44.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nip-44.js","sourceRoot":"","sources":["../../../src/nips/nip-44.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file NIP-46: Nostr Connect / Remote Signing Transport
|
|
3
|
+
* @module nips/nip-46
|
|
4
|
+
* @see https://github.com/nostr-protocol/nips/blob/master/46.md
|
|
5
|
+
*
|
|
6
|
+
* nostr-crypto-utils provides the NIP-46 protocol layer (crypto, encoding,
|
|
7
|
+
* message formatting) but has no I/O. This module adds the WebSocket relay
|
|
8
|
+
* transport on top — subscribing for kind 24133 responses, publishing
|
|
9
|
+
* wrapped requests, and correlating request/response pairs.
|
|
10
|
+
*/
|
|
11
|
+
import { nip46 } from 'nostr-crypto-utils';
|
|
12
|
+
import type { Nip46Session, Nip46Request, Nip46Response, SignedNostrEvent, BunkerURI } from 'nostr-crypto-utils';
|
|
13
|
+
import { NostrWSClient } from '../core/client.js';
|
|
14
|
+
import type { NostrWSMessage } from '../types/messages.js';
|
|
15
|
+
/**
|
|
16
|
+
* Options for creating a NIP-46 transport
|
|
17
|
+
*/
|
|
18
|
+
export interface Nip46TransportOptions {
|
|
19
|
+
/** Timeout for waiting for a response (ms). Defaults to 60000 (60s). */
|
|
20
|
+
timeout?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Result of sending a NIP-46 request
|
|
24
|
+
*/
|
|
25
|
+
export interface Nip46TransportResult {
|
|
26
|
+
/** The JSON-RPC response from the remote signer */
|
|
27
|
+
response: Nip46Response;
|
|
28
|
+
/** The raw kind 24133 event that carried the response */
|
|
29
|
+
rawEvent: SignedNostrEvent;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A thin transport layer that bridges nostr-crypto-utils NIP-46 protocol
|
|
33
|
+
* with the WebSocket relay infrastructure in this library.
|
|
34
|
+
*
|
|
35
|
+
* Usage:
|
|
36
|
+
* ```ts
|
|
37
|
+
* const client = new NostrWSClient(['wss://relay.example.com']);
|
|
38
|
+
* await client.connect();
|
|
39
|
+
*
|
|
40
|
+
* const session = nip46.createSession(remotePubkey);
|
|
41
|
+
* const transport = new Nip46Transport(client, session);
|
|
42
|
+
*
|
|
43
|
+
* // Send a connect request
|
|
44
|
+
* const connectReq = nip46.connectRequest(remotePubkey, secret);
|
|
45
|
+
* const result = await transport.sendRequest(connectReq);
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare class Nip46Transport {
|
|
49
|
+
private client;
|
|
50
|
+
private session;
|
|
51
|
+
private timeout;
|
|
52
|
+
constructor(client: NostrWSClient, session: Nip46Session, options?: Nip46TransportOptions);
|
|
53
|
+
/**
|
|
54
|
+
* Subscribe for NIP-46 response events addressed to our ephemeral pubkey.
|
|
55
|
+
* This sends a REQ message to the relay with the appropriate filter.
|
|
56
|
+
* @param subscriptionId - Subscription ID for the REQ message
|
|
57
|
+
* @param since - Optional since timestamp for the filter
|
|
58
|
+
* @returns The subscription message that was sent
|
|
59
|
+
*/
|
|
60
|
+
subscribe(subscriptionId: string, since?: number): Promise<NostrWSMessage>;
|
|
61
|
+
/**
|
|
62
|
+
* Wrap and publish a NIP-46 request as a kind 24133 event.
|
|
63
|
+
* @param request - NIP-46 JSON-RPC request
|
|
64
|
+
* @returns The signed kind 24133 event that was published
|
|
65
|
+
*/
|
|
66
|
+
publishRequest(request: Nip46Request): Promise<SignedNostrEvent>;
|
|
67
|
+
/**
|
|
68
|
+
* Attempt to unwrap a kind 24133 event into a NIP-46 request or response.
|
|
69
|
+
* Returns null if the event is not kind 24133 or decryption fails.
|
|
70
|
+
* @param event - A signed Nostr event
|
|
71
|
+
* @returns Decrypted NIP-46 payload, or null on failure
|
|
72
|
+
*/
|
|
73
|
+
unwrapEvent(event: SignedNostrEvent): Nip46Request | Nip46Response | null;
|
|
74
|
+
/**
|
|
75
|
+
* Get the NIP-46 response filter for this session.
|
|
76
|
+
* Useful for manual subscription management.
|
|
77
|
+
* @param since - Optional since timestamp
|
|
78
|
+
* @returns Filter object for kind 24133 events tagged to our pubkey
|
|
79
|
+
*/
|
|
80
|
+
getResponseFilter(since?: number): {
|
|
81
|
+
kinds: number[];
|
|
82
|
+
'#p': string[];
|
|
83
|
+
since?: number;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Get the current session (read-only info).
|
|
87
|
+
* @returns The session's client and remote pubkeys
|
|
88
|
+
*/
|
|
89
|
+
getSessionInfo(): {
|
|
90
|
+
clientPubkey: string;
|
|
91
|
+
remotePubkey: string;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** Parse a bunker:// URI */
|
|
95
|
+
export declare const parseBunkerURI: (uri: string) => BunkerURI;
|
|
96
|
+
/** Create a bunker:// URI */
|
|
97
|
+
export declare const createBunkerURI: (remotePubkey: string, relays: string[], secret?: string) => string;
|
|
98
|
+
/** Validate a bunker:// URI */
|
|
99
|
+
export declare const validateBunkerURI: typeof nip46.validateBunkerURI;
|
|
100
|
+
/** Create a new NIP-46 session */
|
|
101
|
+
export declare const createNip46Session: typeof nip46.createSession;
|
|
102
|
+
/** Restore a NIP-46 session */
|
|
103
|
+
export declare const restoreNip46Session: typeof nip46.restoreSession;
|
|
104
|
+
/** Create a 'connect' request */
|
|
105
|
+
export declare const connectRequest: typeof nip46.connectRequest;
|
|
106
|
+
/** Create a 'ping' request */
|
|
107
|
+
export declare const pingRequest: typeof nip46.pingRequest;
|
|
108
|
+
/** Create a 'get_public_key' request */
|
|
109
|
+
export declare const getPublicKeyRequest: typeof nip46.getPublicKeyRequest;
|
|
110
|
+
/** Create a 'sign_event' request */
|
|
111
|
+
export declare const signEventRequest: typeof nip46.signEventRequest;
|
|
112
|
+
//# sourceMappingURL=nip-46.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nip-46.d.ts","sourceRoot":"","sources":["../../../src/nips/nip-46.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,SAAS,EACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAK3D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,mDAAmD;IACnD,QAAQ,EAAE,aAAa,CAAC;IACxB,yDAAyD;IACzD,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,OAAO,CAAS;gBAGtB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,qBAA0B;IAOrC;;;;;;OAMG;IACG,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAWhF;;;;OAIG;IACG,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAatE;;;;;OAKG;IACH,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,GAAG,aAAa,GAAG,IAAI;IAUzE;;;;;OAKG;IACH,iBAAiB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAItF;;;OAGG;IACH,cAAc,IAAI;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE;CAGjE;AAKD,4BAA4B;AAC5B,eAAO,MAAM,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAgC,CAAC;AAE/E,6BAA6B;AAC7B,eAAO,MAAM,eAAe,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,MAA8B,CAAC;AAE1H,+BAA+B;AAC/B,eAAO,MAAM,iBAAiB,EAAE,OAAO,KAAK,CAAC,iBAA2C,CAAC;AAEzF,kCAAkC;AAClC,eAAO,MAAM,kBAAkB,EAAE,OAAO,KAAK,CAAC,aAAmC,CAAC;AAElF,+BAA+B;AAC/B,eAAO,MAAM,mBAAmB,EAAE,OAAO,KAAK,CAAC,cAAqC,CAAC;AAErF,iCAAiC;AACjC,eAAO,MAAM,cAAc,EAAE,OAAO,KAAK,CAAC,cAAqC,CAAC;AAEhF,8BAA8B;AAC9B,eAAO,MAAM,WAAW,EAAE,OAAO,KAAK,CAAC,WAA+B,CAAC;AAEvE,wCAAwC;AACxC,eAAO,MAAM,mBAAmB,EAAE,OAAO,KAAK,CAAC,mBAA+C,CAAC;AAE/F,oCAAoC;AACpC,eAAO,MAAM,gBAAgB,EAAE,OAAO,KAAK,CAAC,gBAAyC,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file NIP-46: Nostr Connect / Remote Signing Transport
|
|
4
|
+
* @module nips/nip-46
|
|
5
|
+
* @see https://github.com/nostr-protocol/nips/blob/master/46.md
|
|
6
|
+
*
|
|
7
|
+
* nostr-crypto-utils provides the NIP-46 protocol layer (crypto, encoding,
|
|
8
|
+
* message formatting) but has no I/O. This module adds the WebSocket relay
|
|
9
|
+
* transport on top — subscribing for kind 24133 responses, publishing
|
|
10
|
+
* wrapped requests, and correlating request/response pairs.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.signEventRequest = exports.getPublicKeyRequest = exports.pingRequest = exports.connectRequest = exports.restoreNip46Session = exports.createNip46Session = exports.validateBunkerURI = exports.createBunkerURI = exports.parseBunkerURI = exports.Nip46Transport = void 0;
|
|
14
|
+
const nostr_crypto_utils_1 = require("nostr-crypto-utils");
|
|
15
|
+
const logger_js_1 = require("../utils/logger.js");
|
|
16
|
+
const logger = (0, logger_js_1.getLogger)('NIP-46');
|
|
17
|
+
/**
|
|
18
|
+
* A thin transport layer that bridges nostr-crypto-utils NIP-46 protocol
|
|
19
|
+
* with the WebSocket relay infrastructure in this library.
|
|
20
|
+
*
|
|
21
|
+
* Usage:
|
|
22
|
+
* ```ts
|
|
23
|
+
* const client = new NostrWSClient(['wss://relay.example.com']);
|
|
24
|
+
* await client.connect();
|
|
25
|
+
*
|
|
26
|
+
* const session = nip46.createSession(remotePubkey);
|
|
27
|
+
* const transport = new Nip46Transport(client, session);
|
|
28
|
+
*
|
|
29
|
+
* // Send a connect request
|
|
30
|
+
* const connectReq = nip46.connectRequest(remotePubkey, secret);
|
|
31
|
+
* const result = await transport.sendRequest(connectReq);
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
class Nip46Transport {
|
|
35
|
+
constructor(client, session, options = {}) {
|
|
36
|
+
this.client = client;
|
|
37
|
+
this.session = session;
|
|
38
|
+
this.timeout = options.timeout ?? 60000;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Subscribe for NIP-46 response events addressed to our ephemeral pubkey.
|
|
42
|
+
* This sends a REQ message to the relay with the appropriate filter.
|
|
43
|
+
* @param subscriptionId - Subscription ID for the REQ message
|
|
44
|
+
* @param since - Optional since timestamp for the filter
|
|
45
|
+
* @returns The subscription message that was sent
|
|
46
|
+
*/
|
|
47
|
+
async subscribe(subscriptionId, since) {
|
|
48
|
+
const filter = nostr_crypto_utils_1.nip46.createResponseFilter(this.session.clientPubkey, since);
|
|
49
|
+
const message = ['REQ', {
|
|
50
|
+
subscription_id: subscriptionId,
|
|
51
|
+
filters: [filter]
|
|
52
|
+
}];
|
|
53
|
+
await this.client.sendMessage(message);
|
|
54
|
+
logger.debug({ subscriptionId, filter }, 'Subscribed for NIP-46 responses');
|
|
55
|
+
return message;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Wrap and publish a NIP-46 request as a kind 24133 event.
|
|
59
|
+
* @param request - NIP-46 JSON-RPC request
|
|
60
|
+
* @returns The signed kind 24133 event that was published
|
|
61
|
+
*/
|
|
62
|
+
async publishRequest(request) {
|
|
63
|
+
const event = await nostr_crypto_utils_1.nip46.wrapEvent(request, this.session, this.session.remotePubkey);
|
|
64
|
+
const message = ['EVENT', event];
|
|
65
|
+
await this.client.sendMessage(message);
|
|
66
|
+
logger.debug({ requestId: request.id, method: request.method }, 'Published NIP-46 request');
|
|
67
|
+
return event;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Attempt to unwrap a kind 24133 event into a NIP-46 request or response.
|
|
71
|
+
* Returns null if the event is not kind 24133 or decryption fails.
|
|
72
|
+
* @param event - A signed Nostr event
|
|
73
|
+
* @returns Decrypted NIP-46 payload, or null on failure
|
|
74
|
+
*/
|
|
75
|
+
unwrapEvent(event) {
|
|
76
|
+
try {
|
|
77
|
+
return nostr_crypto_utils_1.nip46.unwrapEvent(event, this.session);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
81
|
+
logger.debug({ error: errorMessage }, 'Failed to unwrap NIP-46 event');
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get the NIP-46 response filter for this session.
|
|
87
|
+
* Useful for manual subscription management.
|
|
88
|
+
* @param since - Optional since timestamp
|
|
89
|
+
* @returns Filter object for kind 24133 events tagged to our pubkey
|
|
90
|
+
*/
|
|
91
|
+
getResponseFilter(since) {
|
|
92
|
+
return nostr_crypto_utils_1.nip46.createResponseFilter(this.session.clientPubkey, since);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get the current session (read-only info).
|
|
96
|
+
* @returns The session's client and remote pubkeys
|
|
97
|
+
*/
|
|
98
|
+
getSessionInfo() {
|
|
99
|
+
return nostr_crypto_utils_1.nip46.getSessionInfo(this.session);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.Nip46Transport = Nip46Transport;
|
|
103
|
+
// ─── Convenience re-exports from nostr-crypto-utils ─────────────────────────
|
|
104
|
+
// These let consumers access NIP-46 protocol helpers without a separate import.
|
|
105
|
+
/** Parse a bunker:// URI */
|
|
106
|
+
exports.parseBunkerURI = nostr_crypto_utils_1.nip46.parseBunkerURI;
|
|
107
|
+
/** Create a bunker:// URI */
|
|
108
|
+
exports.createBunkerURI = nostr_crypto_utils_1.nip46.createBunkerURI;
|
|
109
|
+
/** Validate a bunker:// URI */
|
|
110
|
+
exports.validateBunkerURI = nostr_crypto_utils_1.nip46.validateBunkerURI;
|
|
111
|
+
/** Create a new NIP-46 session */
|
|
112
|
+
exports.createNip46Session = nostr_crypto_utils_1.nip46.createSession;
|
|
113
|
+
/** Restore a NIP-46 session */
|
|
114
|
+
exports.restoreNip46Session = nostr_crypto_utils_1.nip46.restoreSession;
|
|
115
|
+
/** Create a 'connect' request */
|
|
116
|
+
exports.connectRequest = nostr_crypto_utils_1.nip46.connectRequest;
|
|
117
|
+
/** Create a 'ping' request */
|
|
118
|
+
exports.pingRequest = nostr_crypto_utils_1.nip46.pingRequest;
|
|
119
|
+
/** Create a 'get_public_key' request */
|
|
120
|
+
exports.getPublicKeyRequest = nostr_crypto_utils_1.nip46.getPublicKeyRequest;
|
|
121
|
+
/** Create a 'sign_event' request */
|
|
122
|
+
exports.signEventRequest = nostr_crypto_utils_1.nip46.signEventRequest;
|
|
123
|
+
//# sourceMappingURL=nip-46.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nip-46.js","sourceRoot":"","sources":["../../../src/nips/nip-46.ts"],"names":[],"mappings":"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"}
|
package/dist/nips/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
export * from './nip-01.js';
|
|
6
6
|
export * from './nip-02.js';
|
|
7
7
|
export * from './nip-04.js';
|
|
8
|
+
export * from './nip-44.js';
|
|
8
9
|
export * from './nip-05.js';
|
|
9
10
|
export * from './nip-09.js';
|
|
10
11
|
export * from './nip-19.js';
|
|
@@ -17,4 +18,5 @@ export * from './nip-15.js';
|
|
|
17
18
|
export * from './nip-22.js';
|
|
18
19
|
export * from './nip-28.js';
|
|
19
20
|
export * from './nip-33.js';
|
|
21
|
+
export * from './nip-46.js';
|
|
20
22
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/nips/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nips/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nips/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC"}
|
package/dist/nips/index.js
CHANGED
|
@@ -6,8 +6,10 @@
|
|
|
6
6
|
export * from './nip-01.js';
|
|
7
7
|
// Contact List and Petnames
|
|
8
8
|
export * from './nip-02.js';
|
|
9
|
-
// Encrypted Direct Messages
|
|
9
|
+
// Encrypted Direct Messages (NIP-04)
|
|
10
10
|
export * from './nip-04.js';
|
|
11
|
+
// Versioned Encrypted Payloads (NIP-44)
|
|
12
|
+
export * from './nip-44.js';
|
|
11
13
|
// DNS Identity Verification
|
|
12
14
|
export * from './nip-05.js';
|
|
13
15
|
// Event Deletion
|
|
@@ -32,4 +34,6 @@ export * from './nip-22.js';
|
|
|
32
34
|
export * from './nip-28.js';
|
|
33
35
|
// Parameterized Replaceable Events
|
|
34
36
|
export * from './nip-33.js';
|
|
37
|
+
// Nostr Connect / Remote Signing Transport (NIP-46)
|
|
38
|
+
export * from './nip-46.js';
|
|
35
39
|
//# sourceMappingURL=index.js.map
|
package/dist/nips/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nips/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,sBAAsB;AACtB,cAAc,aAAa,CAAC;AAE5B,4BAA4B;AAC5B,cAAc,aAAa,CAAC;AAE5B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nips/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,sBAAsB;AACtB,cAAc,aAAa,CAAC;AAE5B,4BAA4B;AAC5B,cAAc,aAAa,CAAC;AAE5B,qCAAqC;AACrC,cAAc,aAAa,CAAC;AAE5B,wCAAwC;AACxC,cAAc,aAAa,CAAC;AAE5B,4BAA4B;AAC5B,cAAc,aAAa,CAAC;AAE5B,iBAAiB;AACjB,cAAc,aAAa,CAAC;AAE5B,0BAA0B;AAC1B,cAAc,aAAa,CAAC;AAE5B,0BAA0B;AAC1B,cAAc,aAAa,CAAC;AAE5B,6BAA6B;AAC7B,cAAc,aAAa,CAAC;AAE5B,kBAAkB;AAClB,cAAc,aAAa,CAAC;AAE5B,gBAAgB;AAChB,cAAc,aAAa,CAAC;AAE5B,kBAAkB;AAClB,cAAc,aAAa,CAAC;AAE5B,8BAA8B;AAC9B,cAAc,aAAa,CAAC;AAE5B,0BAA0B;AAC1B,cAAc,aAAa,CAAC;AAE5B,cAAc;AACd,cAAc,aAAa,CAAC;AAE5B,mCAAmC;AACnC,cAAc,aAAa,CAAC;AAE5B,oDAAoD;AACpD,cAAc,aAAa,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nip-26.d.ts","sourceRoot":"","sources":["../../src/nips/nip-26.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD;;;;;;;GAOG;AACH,UAAU,oBAAoB;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,oBAAoB,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"nip-26.d.ts","sourceRoot":"","sources":["../../src/nips/nip-26.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD;;;;;;;GAOG;AACH,UAAU,oBAAoB;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,oBAAoB,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,OAAO,CAAC,CAuBlB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,GAAG,UAAU,CAYtF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAyBtE;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAuChF"}
|
package/dist/nips/nip-26.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @module nips/nip-26
|
|
4
4
|
*/
|
|
5
5
|
import { getLogger } from '../utils/logger.js';
|
|
6
|
-
import {
|
|
6
|
+
import { finalizeEvent, verifySignature } from 'nostr-crypto-utils';
|
|
7
7
|
const logger = getLogger('NIP-26');
|
|
8
8
|
/**
|
|
9
9
|
* Create a delegation token
|
|
@@ -15,17 +15,13 @@ export async function createDelegation(delegatorPrivkey, delegateePubkey, condit
|
|
|
15
15
|
.sort()
|
|
16
16
|
.join('&');
|
|
17
17
|
const message = `nostr:delegation:${delegateePubkey}:${conditionsString}`;
|
|
18
|
-
//
|
|
19
|
-
const
|
|
20
|
-
id: '', // This will be set by signEvent
|
|
18
|
+
// Use finalizeEvent for one-step create+sign
|
|
19
|
+
const signedEvent = await finalizeEvent({
|
|
21
20
|
pubkey: delegateePubkey,
|
|
22
|
-
created_at: Math.floor(Date.now() / 1000),
|
|
23
21
|
kind: 0, // Using kind 0 for delegation events
|
|
24
22
|
tags: [],
|
|
25
23
|
content: message,
|
|
26
|
-
|
|
27
|
-
};
|
|
28
|
-
const signedEvent = await signEvent(event, delegatorPrivkey);
|
|
24
|
+
}, delegatorPrivkey);
|
|
29
25
|
return signedEvent.sig;
|
|
30
26
|
}
|
|
31
27
|
catch (error) {
|
package/dist/nips/nip-26.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nip-26.js","sourceRoot":"","sources":["../../src/nips/nip-26.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"nip-26.js","sourceRoot":"","sources":["../../src/nips/nip-26.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file NIP-44: Versioned Encrypted Payloads
|
|
3
|
+
* @module nips/nip-44
|
|
4
|
+
* @see https://github.com/nostr-protocol/nips/blob/master/44.md
|
|
5
|
+
*
|
|
6
|
+
* NIP-44 replaces NIP-04 with a modern encryption scheme using
|
|
7
|
+
* ChaCha20 + HMAC-SHA256. This module provides DM-level helpers
|
|
8
|
+
* that parallel the NIP-04 module (nip-04.ts).
|
|
9
|
+
*/
|
|
10
|
+
import type { NostrWSMessage } from '../types/messages.js';
|
|
11
|
+
import type { Logger } from '../types/logger.js';
|
|
12
|
+
/**
|
|
13
|
+
* Kind value for NIP-44 encrypted direct messages (gift-wrapped DMs use kind 14,
|
|
14
|
+
* but for parity with NIP-04 kind 4 usage, callers may choose their own kind).
|
|
15
|
+
* NIP-44 itself is a payload format, not a kind — the kind depends on the use case.
|
|
16
|
+
* We default to kind 44 as a convenience constant; callers should override as needed.
|
|
17
|
+
*/
|
|
18
|
+
export declare const ENCRYPTED_DM_KIND_44 = 44;
|
|
19
|
+
/**
|
|
20
|
+
* Creates a NIP-44 conversation key from a sender's private key and recipient's public key.
|
|
21
|
+
* This key is symmetric and reusable for all messages in the conversation.
|
|
22
|
+
* @param senderPrivkeyHex - Sender's private key in hex
|
|
23
|
+
* @param recipientPubkeyHex - Recipient's public key in hex
|
|
24
|
+
* @returns Conversation key as Uint8Array
|
|
25
|
+
*/
|
|
26
|
+
export declare function getConversationKey(senderPrivkeyHex: string, recipientPubkeyHex: string): Uint8Array;
|
|
27
|
+
/**
|
|
28
|
+
* Encrypts a message using NIP-44
|
|
29
|
+
* @param plaintext - Message content to encrypt
|
|
30
|
+
* @param senderPrivkeyHex - Sender's private key in hex
|
|
31
|
+
* @param recipientPubkeyHex - Recipient's public key in hex
|
|
32
|
+
* @returns Encrypted payload string (base64)
|
|
33
|
+
*/
|
|
34
|
+
export declare function encryptNip44(plaintext: string, senderPrivkeyHex: string, recipientPubkeyHex: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Decrypts a NIP-44 encrypted payload
|
|
37
|
+
* @param payload - Encrypted payload string (base64)
|
|
38
|
+
* @param recipientPrivkeyHex - Recipient's private key in hex
|
|
39
|
+
* @param senderPubkeyHex - Sender's public key in hex
|
|
40
|
+
* @returns Decrypted plaintext
|
|
41
|
+
*/
|
|
42
|
+
export declare function decryptNip44(payload: string, recipientPrivkeyHex: string, senderPubkeyHex: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Creates an encrypted direct message event using NIP-44
|
|
45
|
+
* @param content - Message content to encrypt
|
|
46
|
+
* @param recipientPubkey - Recipient's public key (hex)
|
|
47
|
+
* @param senderPrivkey - Sender's private key (hex)
|
|
48
|
+
* @param tags - Additional tags for the event
|
|
49
|
+
* @param kind - Event kind (defaults to ENCRYPTED_DM_KIND_44)
|
|
50
|
+
* @returns Encrypted message event as NostrWSMessage
|
|
51
|
+
*/
|
|
52
|
+
export declare function createEncryptedDM44(content: string, recipientPubkey: string, senderPrivkey: string, tags?: string[][], kind?: number): NostrWSMessage;
|
|
53
|
+
/**
|
|
54
|
+
* Decrypts a received direct message event encrypted with NIP-44
|
|
55
|
+
* @param message - Received message
|
|
56
|
+
* @param recipientPrivkey - Recipient's private key (hex)
|
|
57
|
+
* @param senderPubkey - Sender's public key (hex)
|
|
58
|
+
* @param logger - Logger instance
|
|
59
|
+
* @returns Decrypted message content
|
|
60
|
+
*/
|
|
61
|
+
export declare function decryptDM44(message: NostrWSMessage, recipientPrivkey: string, senderPubkey: string, logger: Logger): string;
|
|
62
|
+
/**
|
|
63
|
+
* Validates a NIP-44 encrypted DM event format
|
|
64
|
+
* @param message - Message to validate
|
|
65
|
+
* @param logger - Logger instance
|
|
66
|
+
* @returns True if message follows NIP-44 encrypted DM format
|
|
67
|
+
*/
|
|
68
|
+
export declare function validateEncryptedDM44(message: NostrWSMessage, logger: Logger): boolean;
|
|
69
|
+
//# sourceMappingURL=nip-44.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nip-44.d.ts","sourceRoot":"","sources":["../../src/nips/nip-44.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,gBAAgB,EAAE,MAAM,EACxB,kBAAkB,EAAE,MAAM,GACzB,UAAU,CAGZ;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EACxB,kBAAkB,EAAE,MAAM,GACzB,MAAM,CAGR;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,mBAAmB,EAAE,MAAM,EAC3B,eAAe,EAAE,MAAM,GACtB,MAAM,CAGR;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,MAAM,EACrB,IAAI,GAAE,MAAM,EAAE,EAAO,EACrB,IAAI,GAAE,MAA6B,GAClC,cAAc,CAiBhB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,cAAc,EACvB,gBAAgB,EAAE,MAAM,EACxB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,MAAM,CAaR;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,MAAM,GACb,OAAO,CAiCT"}
|