@unicitylabs/nostr-js-sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +290 -0
  2. package/dist/browser/index.js +8444 -0
  3. package/dist/browser/index.js.map +1 -0
  4. package/dist/browser/index.min.js +12 -0
  5. package/dist/browser/index.min.js.map +1 -0
  6. package/dist/browser/index.umd.js +8524 -0
  7. package/dist/browser/index.umd.js.map +1 -0
  8. package/dist/browser/index.umd.min.js +12 -0
  9. package/dist/browser/index.umd.min.js.map +1 -0
  10. package/dist/cjs/NostrKeyManager.js +265 -0
  11. package/dist/cjs/NostrKeyManager.js.map +1 -0
  12. package/dist/cjs/client/NostrClient.js +518 -0
  13. package/dist/cjs/client/NostrClient.js.map +1 -0
  14. package/dist/cjs/client/NostrEventListener.js +31 -0
  15. package/dist/cjs/client/NostrEventListener.js.map +1 -0
  16. package/dist/cjs/client/WebSocketAdapter.js +90 -0
  17. package/dist/cjs/client/WebSocketAdapter.js.map +1 -0
  18. package/dist/cjs/client/index.js +18 -0
  19. package/dist/cjs/client/index.js.map +1 -0
  20. package/dist/cjs/crypto/bech32.js +201 -0
  21. package/dist/cjs/crypto/bech32.js.map +1 -0
  22. package/dist/cjs/crypto/index.js +49 -0
  23. package/dist/cjs/crypto/index.js.map +1 -0
  24. package/dist/cjs/crypto/nip04.js +327 -0
  25. package/dist/cjs/crypto/nip04.js.map +1 -0
  26. package/dist/cjs/crypto/schnorr.js +101 -0
  27. package/dist/cjs/crypto/schnorr.js.map +1 -0
  28. package/dist/cjs/index.js +57 -0
  29. package/dist/cjs/index.js.map +1 -0
  30. package/dist/cjs/nametag/NametagBinding.js +196 -0
  31. package/dist/cjs/nametag/NametagBinding.js.map +1 -0
  32. package/dist/cjs/nametag/NametagUtils.js +156 -0
  33. package/dist/cjs/nametag/NametagUtils.js.map +1 -0
  34. package/dist/cjs/nametag/index.js +47 -0
  35. package/dist/cjs/nametag/index.js.map +1 -0
  36. package/dist/cjs/protocol/Event.js +209 -0
  37. package/dist/cjs/protocol/Event.js.map +1 -0
  38. package/dist/cjs/protocol/EventKinds.js +126 -0
  39. package/dist/cjs/protocol/EventKinds.js.map +1 -0
  40. package/dist/cjs/protocol/Filter.js +202 -0
  41. package/dist/cjs/protocol/Filter.js.map +1 -0
  42. package/dist/cjs/protocol/index.js +50 -0
  43. package/dist/cjs/protocol/index.js.map +1 -0
  44. package/dist/cjs/token/TokenTransferProtocol.js +196 -0
  45. package/dist/cjs/token/TokenTransferProtocol.js.map +1 -0
  46. package/dist/cjs/token/index.js +45 -0
  47. package/dist/cjs/token/index.js.map +1 -0
  48. package/dist/esm/NostrKeyManager.js +228 -0
  49. package/dist/esm/NostrKeyManager.js.map +1 -0
  50. package/dist/esm/client/NostrClient.js +481 -0
  51. package/dist/esm/client/NostrClient.js.map +1 -0
  52. package/dist/esm/client/NostrEventListener.js +27 -0
  53. package/dist/esm/client/NostrEventListener.js.map +1 -0
  54. package/dist/esm/client/WebSocketAdapter.js +52 -0
  55. package/dist/esm/client/WebSocketAdapter.js.map +1 -0
  56. package/dist/esm/client/index.js +7 -0
  57. package/dist/esm/client/index.js.map +1 -0
  58. package/dist/esm/crypto/bech32.js +193 -0
  59. package/dist/esm/crypto/bech32.js.map +1 -0
  60. package/dist/esm/crypto/index.js +10 -0
  61. package/dist/esm/crypto/index.js.map +1 -0
  62. package/dist/esm/crypto/nip04.js +286 -0
  63. package/dist/esm/crypto/nip04.js.map +1 -0
  64. package/dist/esm/crypto/schnorr.js +93 -0
  65. package/dist/esm/crypto/schnorr.js.map +1 -0
  66. package/dist/esm/index.js +32 -0
  67. package/dist/esm/index.js.map +1 -0
  68. package/dist/esm/nametag/NametagBinding.js +155 -0
  69. package/dist/esm/nametag/NametagBinding.js.map +1 -0
  70. package/dist/esm/nametag/NametagUtils.js +149 -0
  71. package/dist/esm/nametag/NametagUtils.js.map +1 -0
  72. package/dist/esm/nametag/index.js +8 -0
  73. package/dist/esm/nametag/index.js.map +1 -0
  74. package/dist/esm/protocol/Event.js +172 -0
  75. package/dist/esm/protocol/Event.js.map +1 -0
  76. package/dist/esm/protocol/EventKinds.js +119 -0
  77. package/dist/esm/protocol/EventKinds.js.map +1 -0
  78. package/dist/esm/protocol/Filter.js +197 -0
  79. package/dist/esm/protocol/Filter.js.map +1 -0
  80. package/dist/esm/protocol/index.js +8 -0
  81. package/dist/esm/protocol/index.js.map +1 -0
  82. package/dist/esm/token/TokenTransferProtocol.js +154 -0
  83. package/dist/esm/token/TokenTransferProtocol.js.map +1 -0
  84. package/dist/esm/token/index.js +6 -0
  85. package/dist/esm/token/index.js.map +1 -0
  86. package/dist/types/NostrKeyManager.d.ts +150 -0
  87. package/dist/types/NostrKeyManager.d.ts.map +1 -0
  88. package/dist/types/client/NostrClient.d.ts +154 -0
  89. package/dist/types/client/NostrClient.d.ts.map +1 -0
  90. package/dist/types/client/NostrEventListener.d.ts +40 -0
  91. package/dist/types/client/NostrEventListener.d.ts.map +1 -0
  92. package/dist/types/client/WebSocketAdapter.d.ts +55 -0
  93. package/dist/types/client/WebSocketAdapter.d.ts.map +1 -0
  94. package/dist/types/client/index.d.ts +9 -0
  95. package/dist/types/client/index.d.ts.map +1 -0
  96. package/dist/types/crypto/bech32.d.ts +51 -0
  97. package/dist/types/crypto/bech32.d.ts.map +1 -0
  98. package/dist/types/crypto/index.d.ts +10 -0
  99. package/dist/types/crypto/index.d.ts.map +1 -0
  100. package/dist/types/crypto/nip04.d.ts +56 -0
  101. package/dist/types/crypto/nip04.d.ts.map +1 -0
  102. package/dist/types/crypto/schnorr.d.ts +47 -0
  103. package/dist/types/crypto/schnorr.d.ts.map +1 -0
  104. package/dist/types/index.d.ts +31 -0
  105. package/dist/types/index.d.ts.map +1 -0
  106. package/dist/types/nametag/NametagBinding.d.ts +68 -0
  107. package/dist/types/nametag/NametagBinding.d.ts.map +1 -0
  108. package/dist/types/nametag/NametagUtils.d.ts +44 -0
  109. package/dist/types/nametag/NametagUtils.d.ts.map +1 -0
  110. package/dist/types/nametag/index.d.ts +8 -0
  111. package/dist/types/nametag/index.d.ts.map +1 -0
  112. package/dist/types/protocol/Event.d.ts +112 -0
  113. package/dist/types/protocol/Event.d.ts.map +1 -0
  114. package/dist/types/protocol/EventKinds.d.ts +62 -0
  115. package/dist/types/protocol/EventKinds.d.ts.map +1 -0
  116. package/dist/types/protocol/Filter.d.ts +146 -0
  117. package/dist/types/protocol/Filter.d.ts.map +1 -0
  118. package/dist/types/protocol/index.d.ts +10 -0
  119. package/dist/types/protocol/index.d.ts.map +1 -0
  120. package/dist/types/token/TokenTransferProtocol.d.ts +67 -0
  121. package/dist/types/token/TokenTransferProtocol.d.ts.map +1 -0
  122. package/dist/types/token/index.d.ts +6 -0
  123. package/dist/types/token/index.d.ts.map +1 -0
  124. package/package.json +89 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Bech32 encoding/decoding for NIP-19 key formats (npub, nsec).
3
+ * Implements the Bech32 specification for Nostr key encoding.
4
+ */
5
+ const CHARSET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
6
+ const GENERATOR = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
7
+ /**
8
+ * Compute the Bech32 polymod checksum
9
+ */
10
+ function polymod(values) {
11
+ let chk = 1;
12
+ for (const v of values) {
13
+ const top = chk >> 25;
14
+ chk = ((chk & 0x1ffffff) << 5) ^ v;
15
+ for (let i = 0; i < 5; i++) {
16
+ if ((top >> i) & 1) {
17
+ chk ^= GENERATOR[i];
18
+ }
19
+ }
20
+ }
21
+ return chk;
22
+ }
23
+ /**
24
+ * Expand the human-readable part for checksum computation
25
+ */
26
+ function hrpExpand(hrp) {
27
+ const result = [];
28
+ for (let i = 0; i < hrp.length; i++) {
29
+ result.push(hrp.charCodeAt(i) >> 5);
30
+ }
31
+ result.push(0);
32
+ for (let i = 0; i < hrp.length; i++) {
33
+ result.push(hrp.charCodeAt(i) & 31);
34
+ }
35
+ return result;
36
+ }
37
+ /**
38
+ * Verify the Bech32 checksum
39
+ */
40
+ function verifyChecksum(hrp, data) {
41
+ return polymod(hrpExpand(hrp).concat(data)) === 1;
42
+ }
43
+ /**
44
+ * Create the Bech32 checksum
45
+ */
46
+ function createChecksum(hrp, data) {
47
+ const values = hrpExpand(hrp).concat(data).concat([0, 0, 0, 0, 0, 0]);
48
+ const mod = polymod(values) ^ 1;
49
+ const result = [];
50
+ for (let i = 0; i < 6; i++) {
51
+ result.push((mod >> (5 * (5 - i))) & 31);
52
+ }
53
+ return result;
54
+ }
55
+ /**
56
+ * Convert bits between different widths
57
+ */
58
+ function convertBits(data, fromBits, toBits, pad) {
59
+ let acc = 0;
60
+ let bits = 0;
61
+ const result = [];
62
+ const maxv = (1 << toBits) - 1;
63
+ for (const value of data) {
64
+ if (value < 0 || value >> fromBits !== 0) {
65
+ return null;
66
+ }
67
+ acc = (acc << fromBits) | value;
68
+ bits += fromBits;
69
+ while (bits >= toBits) {
70
+ bits -= toBits;
71
+ result.push((acc >> bits) & maxv);
72
+ }
73
+ }
74
+ if (pad) {
75
+ if (bits > 0) {
76
+ result.push((acc << (toBits - bits)) & maxv);
77
+ }
78
+ }
79
+ else if (bits >= fromBits || ((acc << (toBits - bits)) & maxv) !== 0) {
80
+ return null;
81
+ }
82
+ return result;
83
+ }
84
+ /**
85
+ * Encode data with Bech32 checksum
86
+ * @param hrp Human-readable part (e.g., "npub", "nsec")
87
+ * @param data Data bytes to encode
88
+ * @returns Bech32-encoded string
89
+ */
90
+ export function encode(hrp, data) {
91
+ const values = convertBits(Array.from(data), 8, 5, true);
92
+ if (values === null) {
93
+ throw new Error('Failed to convert bits for Bech32 encoding');
94
+ }
95
+ const checksum = createChecksum(hrp, values);
96
+ const combined = values.concat(checksum);
97
+ let result = hrp + '1';
98
+ for (const v of combined) {
99
+ result += CHARSET.charAt(v);
100
+ }
101
+ return result;
102
+ }
103
+ /**
104
+ * Decode a Bech32-encoded string
105
+ * @param bech32String The Bech32 string to decode
106
+ * @returns Decoded data with human-readable part
107
+ */
108
+ export function decode(bech32String) {
109
+ const str = bech32String.toLowerCase();
110
+ // Find separator
111
+ const pos = str.lastIndexOf('1');
112
+ if (pos < 1 || pos + 7 > str.length || str.length > 90) {
113
+ throw new Error('Invalid Bech32 string');
114
+ }
115
+ const hrp = str.slice(0, pos);
116
+ const dataChars = str.slice(pos + 1);
117
+ // Decode data characters
118
+ const data = [];
119
+ for (const char of dataChars) {
120
+ const idx = CHARSET.indexOf(char);
121
+ if (idx === -1) {
122
+ throw new Error(`Invalid character '${char}' in Bech32 string`);
123
+ }
124
+ data.push(idx);
125
+ }
126
+ // Verify checksum
127
+ if (!verifyChecksum(hrp, data)) {
128
+ throw new Error('Invalid Bech32 checksum');
129
+ }
130
+ // Remove checksum and convert bits
131
+ const dataWithoutChecksum = data.slice(0, -6);
132
+ const converted = convertBits(dataWithoutChecksum, 5, 8, false);
133
+ if (converted === null) {
134
+ throw new Error('Failed to convert bits in Bech32 decoding');
135
+ }
136
+ return {
137
+ hrp,
138
+ data: new Uint8Array(converted),
139
+ };
140
+ }
141
+ /**
142
+ * Encode a public key as npub
143
+ * @param publicKey 32-byte public key
144
+ * @returns npub-encoded string
145
+ */
146
+ export function encodeNpub(publicKey) {
147
+ if (publicKey.length !== 32) {
148
+ throw new Error('Public key must be 32 bytes');
149
+ }
150
+ return encode('npub', publicKey);
151
+ }
152
+ /**
153
+ * Decode an npub string to public key bytes
154
+ * @param npub npub-encoded string
155
+ * @returns 32-byte public key
156
+ */
157
+ export function decodeNpub(npub) {
158
+ const decoded = decode(npub);
159
+ if (decoded.hrp !== 'npub') {
160
+ throw new Error(`Expected 'npub' prefix, got '${decoded.hrp}'`);
161
+ }
162
+ if (decoded.data.length !== 32) {
163
+ throw new Error(`Expected 32 bytes, got ${decoded.data.length}`);
164
+ }
165
+ return decoded.data;
166
+ }
167
+ /**
168
+ * Encode a private key as nsec
169
+ * @param privateKey 32-byte private key
170
+ * @returns nsec-encoded string
171
+ */
172
+ export function encodeNsec(privateKey) {
173
+ if (privateKey.length !== 32) {
174
+ throw new Error('Private key must be 32 bytes');
175
+ }
176
+ return encode('nsec', privateKey);
177
+ }
178
+ /**
179
+ * Decode an nsec string to private key bytes
180
+ * @param nsec nsec-encoded string
181
+ * @returns 32-byte private key
182
+ */
183
+ export function decodeNsec(nsec) {
184
+ const decoded = decode(nsec);
185
+ if (decoded.hrp !== 'nsec') {
186
+ throw new Error(`Expected 'nsec' prefix, got '${decoded.hrp}'`);
187
+ }
188
+ if (decoded.data.length !== 32) {
189
+ throw new Error(`Expected 32 bytes, got ${decoded.data.length}`);
190
+ }
191
+ return decoded.data;
192
+ }
193
+ //# sourceMappingURL=bech32.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bech32.js","sourceRoot":"","sources":["../../../src/crypto/bech32.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,OAAO,GAAG,kCAAkC,CAAC;AACnD,MAAM,SAAS,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAY/E;;GAEG;AACH,SAAS,OAAO,CAAC,MAAgB;IAC/B,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC;QACtB,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnB,GAAG,IAAI,SAAS,CAAC,CAAC,CAAE,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,GAAW;IAC5B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,GAAW,EAAE,IAAc;IACjD,OAAO,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,GAAW,EAAE,IAAc;IACjD,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAClB,IAA2B,EAC3B,QAAgB,EAChB,MAAc,EACd,GAAY;IAEZ,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IAE/B,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QACzB,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,GAAG,GAAG,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,KAAK,CAAC;QAChC,IAAI,IAAI,QAAQ,CAAC;QACjB,OAAO,IAAI,IAAI,MAAM,EAAE,CAAC;YACtB,IAAI,IAAI,MAAM,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,IAAI,GAAG,EAAE,CAAC;QACR,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;SAAM,IAAI,IAAI,IAAI,QAAQ,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,GAAW,EAAE,IAAgB;IAClD,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;IACzD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEzC,IAAI,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC;IACvB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,YAAoB;IACzC,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;IAEvC,iBAAiB;IACjB,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9B,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAErC,yBAAyB;IACzB,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,oBAAoB,CAAC,CAAC;QAClE,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC;IAED,kBAAkB;IAClB,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAED,mCAAmC;IACnC,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,WAAW,CAAC,mBAAmB,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;IAChE,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO;QACL,GAAG;QACH,IAAI,EAAE,IAAI,UAAU,CAAC,SAAS,CAAC;KAChC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,SAAqB;IAC9C,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,OAAO,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,gCAAgC,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,0BAA0B,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,UAAsB;IAC/C,IAAI,UAAU,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,OAAO,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,gCAAgC,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,0BAA0B,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC;AACtB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Crypto module - Cryptographic utilities for Nostr protocol
3
+ */
4
+ export * from './bech32.js';
5
+ export * as Bech32 from './bech32.js';
6
+ export * from './schnorr.js';
7
+ export * as SchnorrSigner from './schnorr.js';
8
+ export * from './nip04.js';
9
+ export * as NIP04 from './nip04.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/crypto/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,aAAa,CAAC;AAC5B,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,OAAO,KAAK,aAAa,MAAM,cAAc,CAAC;AAC9C,cAAc,YAAY,CAAC;AAC3B,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC"}
@@ -0,0 +1,286 @@
1
+ /**
2
+ * NIP-04 Encryption implementation.
3
+ * AES-256-CBC encryption with ECDH key agreement and optional GZIP compression.
4
+ * Works in both Node.js and browser environments.
5
+ */
6
+ import { secp256k1 } from '@noble/curves/secp256k1';
7
+ import { sha256 } from '@noble/hashes/sha256';
8
+ import { bytesToHex, hexToBytes, randomBytes } from '@noble/hashes/utils';
9
+ /** Compression threshold in bytes */
10
+ const COMPRESSION_THRESHOLD = 1024;
11
+ /** Prefix for compressed messages */
12
+ const COMPRESSION_PREFIX = 'gz:';
13
+ /**
14
+ * Convert a Uint8Array to base64 string (browser and Node.js compatible)
15
+ */
16
+ function toBase64(bytes) {
17
+ if (typeof Buffer !== 'undefined') {
18
+ return Buffer.from(bytes).toString('base64');
19
+ }
20
+ // Browser environment
21
+ let binary = '';
22
+ for (let i = 0; i < bytes.length; i++) {
23
+ binary += String.fromCharCode(bytes[i]);
24
+ }
25
+ return btoa(binary);
26
+ }
27
+ /**
28
+ * Convert a base64 string to Uint8Array (browser and Node.js compatible)
29
+ */
30
+ function fromBase64(base64) {
31
+ if (typeof Buffer !== 'undefined') {
32
+ return new Uint8Array(Buffer.from(base64, 'base64'));
33
+ }
34
+ // Browser environment
35
+ const binary = atob(base64);
36
+ const bytes = new Uint8Array(binary.length);
37
+ for (let i = 0; i < binary.length; i++) {
38
+ bytes[i] = binary.charCodeAt(i);
39
+ }
40
+ return bytes;
41
+ }
42
+ /**
43
+ * Convert Uint8Array to a standard ArrayBuffer view for Web Crypto API compatibility
44
+ */
45
+ function toBufferSource(data) {
46
+ // Create a new ArrayBuffer to ensure compatibility with Web Crypto API
47
+ const buffer = new ArrayBuffer(data.length);
48
+ new Uint8Array(buffer).set(data);
49
+ return buffer;
50
+ }
51
+ /**
52
+ * GZIP compress data (browser and Node.js compatible)
53
+ */
54
+ async function compress(data) {
55
+ // Check for Node.js environment first
56
+ if (typeof process !== 'undefined' && process.versions?.node) {
57
+ // Node.js environment - use native zlib
58
+ const { gzipSync } = await import('zlib');
59
+ return new Uint8Array(gzipSync(Buffer.from(data)));
60
+ }
61
+ else if (typeof CompressionStream !== 'undefined') {
62
+ // Browser with Compression Streams API
63
+ const stream = new CompressionStream('gzip');
64
+ const writer = stream.writable.getWriter();
65
+ writer.write(toBufferSource(data));
66
+ writer.close();
67
+ const chunks = [];
68
+ const reader = stream.readable.getReader();
69
+ while (true) {
70
+ const { done, value } = await reader.read();
71
+ if (done)
72
+ break;
73
+ chunks.push(value);
74
+ }
75
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
76
+ const result = new Uint8Array(totalLength);
77
+ let offset = 0;
78
+ for (const chunk of chunks) {
79
+ result.set(chunk, offset);
80
+ offset += chunk.length;
81
+ }
82
+ return result;
83
+ }
84
+ throw new Error('GZIP compression not supported in this environment');
85
+ }
86
+ /**
87
+ * GZIP decompress data (browser and Node.js compatible)
88
+ */
89
+ async function decompress(data) {
90
+ // Check for Node.js environment first
91
+ if (typeof process !== 'undefined' && process.versions?.node) {
92
+ // Node.js environment - use native zlib
93
+ const { gunzipSync } = await import('zlib');
94
+ return new Uint8Array(gunzipSync(Buffer.from(data)));
95
+ }
96
+ else if (typeof DecompressionStream !== 'undefined') {
97
+ // Browser with Compression Streams API
98
+ const stream = new DecompressionStream('gzip');
99
+ const writer = stream.writable.getWriter();
100
+ writer.write(toBufferSource(data));
101
+ writer.close();
102
+ const chunks = [];
103
+ const reader = stream.readable.getReader();
104
+ while (true) {
105
+ const { done, value } = await reader.read();
106
+ if (done)
107
+ break;
108
+ chunks.push(value);
109
+ }
110
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
111
+ const result = new Uint8Array(totalLength);
112
+ let offset = 0;
113
+ for (const chunk of chunks) {
114
+ result.set(chunk, offset);
115
+ offset += chunk.length;
116
+ }
117
+ return result;
118
+ }
119
+ throw new Error('GZIP decompression not supported in this environment');
120
+ }
121
+ /**
122
+ * Import an AES-256-CBC key for encryption/decryption
123
+ */
124
+ async function importKey(keyBytes) {
125
+ const crypto = globalThis.crypto;
126
+ return crypto.subtle.importKey('raw', toBufferSource(keyBytes), { name: 'AES-CBC' }, false, [
127
+ 'encrypt',
128
+ 'decrypt',
129
+ ]);
130
+ }
131
+ /**
132
+ * AES-256-CBC encrypt
133
+ */
134
+ async function aesEncrypt(plaintext, key, iv) {
135
+ const crypto = globalThis.crypto;
136
+ const cryptoKey = await importKey(key);
137
+ const ciphertext = await crypto.subtle.encrypt({ name: 'AES-CBC', iv: toBufferSource(iv) }, cryptoKey, toBufferSource(plaintext));
138
+ return new Uint8Array(ciphertext);
139
+ }
140
+ /**
141
+ * AES-256-CBC decrypt
142
+ */
143
+ async function aesDecrypt(ciphertext, key, iv) {
144
+ const crypto = globalThis.crypto;
145
+ const cryptoKey = await importKey(key);
146
+ const plaintext = await crypto.subtle.decrypt({ name: 'AES-CBC', iv: toBufferSource(iv) }, cryptoKey, toBufferSource(ciphertext));
147
+ return new Uint8Array(plaintext);
148
+ }
149
+ /**
150
+ * Derive a shared secret using ECDH (NIP-04 compatible).
151
+ * Returns SHA-256(sharedPoint.x) as the shared secret.
152
+ * @param myPrivateKey 32-byte private key
153
+ * @param theirPublicKey 32-byte x-only public key
154
+ * @returns 32-byte shared secret
155
+ */
156
+ export function deriveSharedSecret(myPrivateKey, theirPublicKey) {
157
+ if (myPrivateKey.length !== 32) {
158
+ throw new Error('Private key must be 32 bytes');
159
+ }
160
+ if (theirPublicKey.length !== 32) {
161
+ throw new Error('Public key must be 32 bytes');
162
+ }
163
+ // Reconstruct the full public key point from x-coordinate (assume even y)
164
+ // For secp256k1, we need to prefix with 02 for even y
165
+ const fullPublicKey = new Uint8Array(33);
166
+ fullPublicKey[0] = 0x02;
167
+ fullPublicKey.set(theirPublicKey, 1);
168
+ // Compute ECDH shared point
169
+ const sharedPoint = secp256k1.getSharedSecret(myPrivateKey, fullPublicKey);
170
+ // Extract x-coordinate (skip the 0x04 prefix byte, take next 32 bytes)
171
+ const sharedX = sharedPoint.slice(1, 33);
172
+ // Return SHA-256 of the x-coordinate
173
+ return sha256(sharedX);
174
+ }
175
+ /**
176
+ * Derive a shared secret from hex-encoded keys
177
+ * @param myPrivateKeyHex Hex-encoded private key
178
+ * @param theirPublicKeyHex Hex-encoded public key
179
+ * @returns Hex-encoded shared secret
180
+ */
181
+ export function deriveSharedSecretHex(myPrivateKeyHex, theirPublicKeyHex) {
182
+ const myPrivateKey = hexToBytes(myPrivateKeyHex);
183
+ const theirPublicKey = hexToBytes(theirPublicKeyHex);
184
+ return bytesToHex(deriveSharedSecret(myPrivateKey, theirPublicKey));
185
+ }
186
+ /**
187
+ * Encrypt a message using NIP-04 encryption.
188
+ * Format: "base64(ciphertext)?iv=base64(iv)"
189
+ * If message > 1KB, automatically compresses with GZIP: "gz:base64(compressed)?iv=base64(iv)"
190
+ * @param message Message to encrypt
191
+ * @param myPrivateKey 32-byte private key
192
+ * @param theirPublicKey 32-byte x-only public key
193
+ * @returns Encrypted content string
194
+ */
195
+ export async function encrypt(message, myPrivateKey, theirPublicKey) {
196
+ const encoder = new TextEncoder();
197
+ let plaintext = encoder.encode(message);
198
+ // Check if compression is needed
199
+ let useCompression = false;
200
+ let plaintextToEncrypt = plaintext;
201
+ if (plaintext.length > COMPRESSION_THRESHOLD) {
202
+ const compressed = await compress(plaintext);
203
+ // Only use compression if it actually reduces size
204
+ if (compressed.length < plaintext.length) {
205
+ plaintextToEncrypt = new Uint8Array(compressed);
206
+ useCompression = true;
207
+ }
208
+ }
209
+ // Derive shared secret
210
+ const sharedSecret = deriveSharedSecret(myPrivateKey, theirPublicKey);
211
+ // Generate random IV
212
+ const iv = randomBytes(16);
213
+ // Encrypt
214
+ const ciphertext = await aesEncrypt(plaintextToEncrypt, sharedSecret, iv);
215
+ // Format output
216
+ const ciphertextBase64 = toBase64(ciphertext);
217
+ const ivBase64 = toBase64(iv);
218
+ if (useCompression) {
219
+ return `${COMPRESSION_PREFIX}${ciphertextBase64}?iv=${ivBase64}`;
220
+ }
221
+ return `${ciphertextBase64}?iv=${ivBase64}`;
222
+ }
223
+ /**
224
+ * Encrypt a message using hex-encoded keys
225
+ * @param message Message to encrypt
226
+ * @param myPrivateKeyHex Hex-encoded private key
227
+ * @param theirPublicKeyHex Hex-encoded public key
228
+ * @returns Encrypted content string
229
+ */
230
+ export async function encryptHex(message, myPrivateKeyHex, theirPublicKeyHex) {
231
+ const myPrivateKey = hexToBytes(myPrivateKeyHex);
232
+ const theirPublicKey = hexToBytes(theirPublicKeyHex);
233
+ return encrypt(message, myPrivateKey, theirPublicKey);
234
+ }
235
+ /**
236
+ * Decrypt a NIP-04 encrypted message.
237
+ * Automatically decompresses if the message was compressed.
238
+ * @param encryptedContent Encrypted content string
239
+ * @param myPrivateKey 32-byte private key
240
+ * @param theirPublicKey 32-byte x-only public key
241
+ * @returns Decrypted message
242
+ */
243
+ export async function decrypt(encryptedContent, myPrivateKey, theirPublicKey) {
244
+ // Check for compression prefix
245
+ let content = encryptedContent;
246
+ let isCompressed = false;
247
+ if (content.startsWith(COMPRESSION_PREFIX)) {
248
+ content = content.slice(COMPRESSION_PREFIX.length);
249
+ isCompressed = true;
250
+ }
251
+ // Parse format: "base64(ciphertext)?iv=base64(iv)"
252
+ const parts = content.split('?iv=');
253
+ if (parts.length !== 2) {
254
+ throw new Error('Invalid encrypted content format');
255
+ }
256
+ const ciphertextBase64 = parts[0];
257
+ const ivBase64 = parts[1];
258
+ const ciphertext = fromBase64(ciphertextBase64);
259
+ const iv = fromBase64(ivBase64);
260
+ if (iv.length !== 16) {
261
+ throw new Error('Invalid IV length');
262
+ }
263
+ // Derive shared secret
264
+ const sharedSecret = deriveSharedSecret(myPrivateKey, theirPublicKey);
265
+ // Decrypt
266
+ let plaintext = await aesDecrypt(ciphertext, sharedSecret, iv);
267
+ // Decompress if needed
268
+ if (isCompressed) {
269
+ plaintext = await decompress(plaintext);
270
+ }
271
+ const decoder = new TextDecoder();
272
+ return decoder.decode(plaintext);
273
+ }
274
+ /**
275
+ * Decrypt a message using hex-encoded keys
276
+ * @param encryptedContent Encrypted content string
277
+ * @param myPrivateKeyHex Hex-encoded private key
278
+ * @param theirPublicKeyHex Hex-encoded public key
279
+ * @returns Decrypted message
280
+ */
281
+ export async function decryptHex(encryptedContent, myPrivateKeyHex, theirPublicKeyHex) {
282
+ const myPrivateKey = hexToBytes(myPrivateKeyHex);
283
+ const theirPublicKey = hexToBytes(theirPublicKeyHex);
284
+ return decrypt(encryptedContent, myPrivateKey, theirPublicKey);
285
+ }
286
+ //# sourceMappingURL=nip04.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nip04.js","sourceRoot":"","sources":["../../../src/crypto/nip04.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * BIP-340 Schnorr signature implementation using secp256k1.
3
+ * Uses @noble/curves for cryptographic operations.
4
+ */
5
+ import { schnorr } from '@noble/curves/secp256k1';
6
+ import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
7
+ /**
8
+ * Get the x-only public key from a private key (BIP-340)
9
+ * @param privateKey 32-byte private key
10
+ * @returns 32-byte x-only public key
11
+ */
12
+ export function getPublicKey(privateKey) {
13
+ if (privateKey.length !== 32) {
14
+ throw new Error('Private key must be 32 bytes');
15
+ }
16
+ return schnorr.getPublicKey(privateKey);
17
+ }
18
+ /**
19
+ * Get the x-only public key from a hex-encoded private key
20
+ * @param privateKeyHex Hex-encoded private key
21
+ * @returns Hex-encoded x-only public key
22
+ */
23
+ export function getPublicKeyHex(privateKeyHex) {
24
+ const privateKey = hexToBytes(privateKeyHex);
25
+ const publicKey = getPublicKey(privateKey);
26
+ return bytesToHex(publicKey);
27
+ }
28
+ /**
29
+ * Sign a message using BIP-340 Schnorr signature
30
+ * @param message 32-byte message hash to sign
31
+ * @param privateKey 32-byte private key
32
+ * @returns 64-byte Schnorr signature (R.x || s)
33
+ */
34
+ export function sign(message, privateKey) {
35
+ if (message.length !== 32) {
36
+ throw new Error('Message must be 32 bytes');
37
+ }
38
+ if (privateKey.length !== 32) {
39
+ throw new Error('Private key must be 32 bytes');
40
+ }
41
+ return schnorr.sign(message, privateKey);
42
+ }
43
+ /**
44
+ * Sign a message and return hex-encoded signature
45
+ * @param message 32-byte message hash to sign
46
+ * @param privateKey 32-byte private key
47
+ * @returns Hex-encoded 64-byte Schnorr signature
48
+ */
49
+ export function signHex(message, privateKey) {
50
+ return bytesToHex(sign(message, privateKey));
51
+ }
52
+ /**
53
+ * Verify a BIP-340 Schnorr signature
54
+ * @param signature 64-byte Schnorr signature
55
+ * @param message 32-byte message hash
56
+ * @param publicKey 32-byte x-only public key
57
+ * @returns true if the signature is valid
58
+ */
59
+ export function verify(signature, message, publicKey) {
60
+ if (signature.length !== 64) {
61
+ return false;
62
+ }
63
+ if (message.length !== 32) {
64
+ return false;
65
+ }
66
+ if (publicKey.length !== 32) {
67
+ return false;
68
+ }
69
+ try {
70
+ return schnorr.verify(signature, message, publicKey);
71
+ }
72
+ catch {
73
+ return false;
74
+ }
75
+ }
76
+ /**
77
+ * Verify a hex-encoded Schnorr signature
78
+ * @param signatureHex Hex-encoded 64-byte signature
79
+ * @param message 32-byte message hash
80
+ * @param publicKeyHex Hex-encoded 32-byte public key
81
+ * @returns true if the signature is valid
82
+ */
83
+ export function verifyHex(signatureHex, message, publicKeyHex) {
84
+ try {
85
+ const signature = hexToBytes(signatureHex);
86
+ const publicKey = hexToBytes(publicKeyHex);
87
+ return verify(signature, message, publicKey);
88
+ }
89
+ catch {
90
+ return false;
91
+ }
92
+ }
93
+ //# sourceMappingURL=schnorr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schnorr.js","sourceRoot":"","sources":["../../../src/crypto/schnorr.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,UAAsB;IACjD,IAAI,UAAU,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,aAAqB;IACnD,MAAM,UAAU,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IAC3C,OAAO,UAAU,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,IAAI,CAAC,OAAmB,EAAE,UAAsB;IAC9D,IAAI,OAAO,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,OAAmB,EAAE,UAAsB;IACjE,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,MAAM,CACpB,SAAqB,EACrB,OAAmB,EACnB,SAAqB;IAErB,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,OAAO,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACvB,YAAoB,EACpB,OAAmB,EACnB,YAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;QAC3C,OAAO,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Unicity Nostr SDK
3
+ *
4
+ * A TypeScript SDK for Nostr protocol with Unicity extensions.
5
+ * Works in both Node.js and browser environments.
6
+ *
7
+ * Features:
8
+ * - BIP-340 Schnorr signatures
9
+ * - NIP-04 encrypted direct messages with GZIP compression
10
+ * - Multi-relay WebSocket connections with auto-reconnection
11
+ * - Token transfers over Nostr
12
+ * - Privacy-preserving nametag bindings
13
+ *
14
+ * @packageDocumentation
15
+ */
16
+ // Core key management
17
+ export { NostrKeyManager } from './NostrKeyManager.js';
18
+ // Crypto utilities
19
+ export * from './crypto/index.js';
20
+ export { Bech32, SchnorrSigner, NIP04, } from './crypto/index.js';
21
+ // Protocol types and classes
22
+ export * from './protocol/index.js';
23
+ export { EventKinds } from './protocol/index.js';
24
+ // Client
25
+ export * from './client/index.js';
26
+ // Nametag utilities
27
+ export * from './nametag/index.js';
28
+ export { NametagUtils, NametagBinding } from './nametag/index.js';
29
+ // Token transfer
30
+ export * from './token/index.js';
31
+ export { TokenTransferProtocol } from './token/index.js';
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,sBAAsB;AACtB,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,mBAAmB;AACnB,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,MAAM,EACN,aAAa,EACb,KAAK,GACN,MAAM,mBAAmB,CAAC;AAE3B,6BAA6B;AAC7B,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,SAAS;AACT,cAAc,mBAAmB,CAAC;AAElC,oBAAoB;AACpB,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAElE,iBAAiB;AACjB,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC"}