@sunhex/protocol 1.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Abdelhakim Sahifa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # @sunhex/protocol SDK
2
+
3
+ The official SunHex Quantum Protocol SDK for decentralized, stateless identity resolution.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @sunhex/protocol
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ### 1. Local Resolution (Edge-native)
14
+ Resolution happens entirely on your machine. No data ever touches the SunHex servers.
15
+
16
+ ```javascript
17
+ import { SunHex } from '@sunhex/protocol';
18
+
19
+ const sunhex = new SunHex();
20
+
21
+ // Resolve a Quantum Fragment
22
+ const identity = await sunhex.resolveLocal(
23
+ "01A7F2D...", // The Fragment
24
+ "1234" // User Private PIN
25
+ );
26
+
27
+ console.log(identity.firstName); // "Abdelhakim"
28
+ ```
29
+
30
+ ### 2. Crystallization (Fragment Generation)
31
+ Securely pack and encrypt biological data into a stateless code.
32
+
33
+ ```javascript
34
+ const fragment = await sunhex.crystallizeLocal({
35
+ firstName: "Jane",
36
+ lastName: "Doe",
37
+ countryCode: "US",
38
+ birthYear: 1995,
39
+ birthMonth: 5,
40
+ birthDay: 12,
41
+ gender: "Female"
42
+ }, "pin_secret_99");
43
+
44
+ console.log(fragment); // "02F9A12..."
45
+ ```
46
+
47
+ ## Security Mandate
48
+ This SDK uses the **Web Crypto API** to ensure hardware-accelerated, secure operations:
49
+ - **Encryption**: AES-256-GCM (Authenticated Encryption)
50
+ - **Key Derivation**: PBKDF2-SHA256 (100,000 Iterations)
51
+ - **Serialization**: Compact bit-packing binary protocol.
52
+
53
+ ## Vision
54
+ SunHex aims to eliminate "Identity Honeypots" by giving users total sovereignty over their biological data. We don't store—we compute.
55
+
56
+ ---
57
+ Developed by [Abdelhakim Sahifa](https://github.com/abdelhakim-sahifa).
58
+
59
+ Repository [SunHex-sdk](https://github.com/abdelhakim-sahifa/sunhex-sdk).
60
+
61
+ Documentation [Documentation](https://sunhex.vercel.app/docs).
62
+
63
+
package/dist/index.cjs ADDED
@@ -0,0 +1,460 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Crypto: () => crypto_exports,
24
+ Protocol: () => protocol_exports,
25
+ SunHex: () => SunHex,
26
+ sunhex: () => sunhex
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+
30
+ // src/crypto.ts
31
+ var crypto_exports = {};
32
+ __export(crypto_exports, {
33
+ decrypt: () => decrypt,
34
+ deriveKey: () => deriveKey,
35
+ encrypt: () => encrypt,
36
+ hexToUint8Array: () => hexToUint8Array,
37
+ uint8ArrayToHex: () => uint8ArrayToHex
38
+ });
39
+ var ITERATIONS = 1e5;
40
+ async function deriveKey(pin, salt) {
41
+ const encoder = new TextEncoder();
42
+ const passwordKey = await crypto.subtle.importKey(
43
+ "raw",
44
+ encoder.encode(pin),
45
+ "PBKDF2",
46
+ false,
47
+ ["deriveBits", "deriveKey"]
48
+ );
49
+ return await crypto.subtle.deriveKey(
50
+ {
51
+ name: "PBKDF2",
52
+ salt,
53
+ iterations: ITERATIONS,
54
+ hash: "SHA-256"
55
+ },
56
+ passwordKey,
57
+ { name: "AES-GCM", length: 256 },
58
+ false,
59
+ ["encrypt", "decrypt"]
60
+ );
61
+ }
62
+ async function encrypt(data, key) {
63
+ const iv = crypto.getRandomValues(new Uint8Array(12));
64
+ const encrypted = await crypto.subtle.encrypt(
65
+ { name: "AES-GCM", iv },
66
+ key,
67
+ data
68
+ );
69
+ return {
70
+ ciphertext: new Uint8Array(encrypted),
71
+ iv
72
+ };
73
+ }
74
+ async function decrypt(ciphertext, key, iv) {
75
+ const decrypted = await crypto.subtle.decrypt(
76
+ { name: "AES-GCM", iv },
77
+ key,
78
+ ciphertext
79
+ );
80
+ return new Uint8Array(decrypted);
81
+ }
82
+ function hexToUint8Array(hex) {
83
+ const bytes = new Uint8Array(hex.length / 2);
84
+ for (let i = 0; i < hex.length; i += 2) {
85
+ bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
86
+ }
87
+ return bytes;
88
+ }
89
+ function uint8ArrayToHex(bytes) {
90
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("").toUpperCase();
91
+ }
92
+
93
+ // src/protocol.ts
94
+ var protocol_exports = {};
95
+ __export(protocol_exports, {
96
+ pack: () => pack,
97
+ unpack: () => unpack
98
+ });
99
+
100
+ // src/constants.ts
101
+ var COUNTRY_CODES = {
102
+ "AF": "Afghanistan",
103
+ "AL": "Albania",
104
+ "DZ": "Algeria",
105
+ "AS": "American Samoa",
106
+ "AD": "Andorra",
107
+ "AO": "Angola",
108
+ "AI": "Anguilla",
109
+ "AQ": "Antarctica",
110
+ "AG": "Antigua and Barbuda",
111
+ "AR": "Argentina",
112
+ "AM": "Armenia",
113
+ "AW": "Aruba",
114
+ "AU": "Australia",
115
+ "AT": "Austria",
116
+ "AZ": "Azerbaijan",
117
+ "BS": "Bahamas",
118
+ "BH": "Bahrain",
119
+ "BD": "Bangladesh",
120
+ "BB": "Barbados",
121
+ "BY": "Belarus",
122
+ "BE": "Belgium",
123
+ "BZ": "Belize",
124
+ "BJ": "Benin",
125
+ "BM": "Bermuda",
126
+ "BT": "Bhutan",
127
+ "BO": "Bolivia",
128
+ "BA": "Bosnia and Herzegovina",
129
+ "BW": "Botswana",
130
+ "BR": "Brazil",
131
+ "IO": "British Indian Ocean Territory",
132
+ "BN": "Brunei Darussalam",
133
+ "BG": "Bulgaria",
134
+ "BF": "Burkina Faso",
135
+ "BI": "Burundi",
136
+ "KH": "Cambodia",
137
+ "CM": "Cameroon",
138
+ "CA": "Canada",
139
+ "CV": "Cape Verde",
140
+ "KY": "Cayman Islands",
141
+ "CF": "Central African Republic",
142
+ "TD": "Chad",
143
+ "CL": "Chile",
144
+ "CN": "China",
145
+ "CX": "Christmas Island",
146
+ "CC": "Cocos (Keeling) Islands",
147
+ "CO": "Colombia",
148
+ "KM": "Comoros",
149
+ "CG": "Congo",
150
+ "CD": "Congo, The Democratic Republic of the",
151
+ "CK": "Cook Islands",
152
+ "CR": "Costa Rica",
153
+ "CI": "Cote D'Ivoire",
154
+ "HR": "Croatia",
155
+ "CU": "Cuba",
156
+ "CY": "Cyprus",
157
+ "CZ": "Czech Republic",
158
+ "DK": "Denmark",
159
+ "DJ": "Djibouti",
160
+ "DM": "Dominica",
161
+ "DO": "Dominican Republic",
162
+ "EC": "Ecuador",
163
+ "EG": "Egypt",
164
+ "SV": "El Salvador",
165
+ "GQ": "Equatorial Guinea",
166
+ "ER": "Eritrea",
167
+ "EE": "Estonia",
168
+ "ET": "Ethiopia",
169
+ "FK": "Falkland Islands (Malvinas)",
170
+ "FO": "Faroe Islands",
171
+ "FJ": "Fiji",
172
+ "FI": "Finland",
173
+ "FR": "France",
174
+ "GF": "French Guiana",
175
+ "PF": "French Polynesia",
176
+ "TF": "French Southern Territories",
177
+ "GA": "Gabon",
178
+ "GM": "Gambia",
179
+ "GE": "Georgia",
180
+ "DE": "Germany",
181
+ "GH": "Ghana",
182
+ "GI": "Gibraltar",
183
+ "GR": "Greece",
184
+ "GL": "Greenland",
185
+ "GD": "Grenada",
186
+ "GP": "Guadeloupe",
187
+ "GU": "Guam",
188
+ "GT": "Guatemala",
189
+ "GN": "Guinea",
190
+ "GW": "Guinea-Bissau",
191
+ "GY": "Guyana",
192
+ "HT": "Haiti",
193
+ "HM": "Heard Island and Mcdonald Islands",
194
+ "VA": "Holy See (Vatican City State)",
195
+ "HN": "Honduras",
196
+ "HK": "Hong Kong",
197
+ "HU": "Hungary",
198
+ "IS": "Iceland",
199
+ "IN": "India",
200
+ "ID": "Indonesia",
201
+ "IR": "Iran, Islamic Republic of",
202
+ "IQ": "Iraq",
203
+ "IE": "Ireland",
204
+ "IL": "Israel",
205
+ "IT": "Italy",
206
+ "JM": "Jamaica",
207
+ "JP": "Japan",
208
+ "JO": "Jordan",
209
+ "KZ": "Kazakhstan",
210
+ "KE": "Kenya",
211
+ "KI": "Kiribati",
212
+ "KP": "Korea, Democratic People's Republic of",
213
+ "KR": "Korea, Republic of",
214
+ "KW": "Kuwait",
215
+ "KG": "Kyrgyzstan",
216
+ "LA": "Lao People's Democratic Republic",
217
+ "LV": "Latvia",
218
+ "LB": "Lebanon",
219
+ "LS": "Lesotho",
220
+ "LR": "Liberia",
221
+ "LY": "Libyan Arab Jamahiriya",
222
+ "LI": "Liechtenstein",
223
+ "LT": "Lithuania",
224
+ "LU": "Luxembourg",
225
+ "MO": "Macao",
226
+ "MK": "Macedonia, The Former Yugoslav Republic of",
227
+ "MG": "Madagascar",
228
+ "MW": "Malawi",
229
+ "MY": "Malaysia",
230
+ "MV": "Maldives",
231
+ "ML": "Mali",
232
+ "MT": "Malta",
233
+ "MH": "Marshall Islands",
234
+ "MQ": "Martinique",
235
+ "MR": "Mauritania",
236
+ "MU": "Mauritius",
237
+ "YT": "Mayotte",
238
+ "MX": "Mexico",
239
+ "FM": "Micronesia, Federated States of",
240
+ "MD": "Moldova, Republic of",
241
+ "MC": "Monaco",
242
+ "MN": "Mongolia",
243
+ "MS": "Montserrat",
244
+ "MA": "Morocco",
245
+ "MZ": "Mozambique",
246
+ "MM": "Myanmar",
247
+ "NA": "Namibia",
248
+ "NR": "Nauru",
249
+ "NP": "Nepal",
250
+ "NL": "Netherlands",
251
+ "AN": "Netherlands Antilles",
252
+ "NC": "New Caledonia",
253
+ "NZ": "New Zealand",
254
+ "NI": "Nicaragua",
255
+ "NE": "Niger",
256
+ "NG": "Nigeria",
257
+ "NU": "Niue",
258
+ "NF": "Norfolk Island",
259
+ "MP": "Northern Mariana Islands",
260
+ "NO": "Norway",
261
+ "OM": "Oman",
262
+ "PK": "Pakistan",
263
+ "PW": "Palau",
264
+ "PS": "Palestinian Territory, Occupied",
265
+ "PA": "Panama",
266
+ "PG": "Papua New Guinea",
267
+ "PY": "Paraguay",
268
+ "PE": "Peru",
269
+ "PH": "Philippines",
270
+ "PN": "Pitcairn",
271
+ "PL": "Poland",
272
+ "PT": "Portugal",
273
+ "PR": "Puerto Rico",
274
+ "QA": "Qatar",
275
+ "RE": "Reunion",
276
+ "RO": "Romania",
277
+ "RU": "Russian Federation",
278
+ "RW": "Rwanda",
279
+ "SH": "Saint Helena",
280
+ "KN": "Saint Kitts and Nevis",
281
+ "LC": "Saint Lucia",
282
+ "PM": "Saint Pierre and Miquelon",
283
+ "VC": "Saint Vincent and the Grenadines",
284
+ "WS": "Samoa",
285
+ "SM": "San Marino",
286
+ "ST": "Sao Tome and Principe",
287
+ "SA": "Saudi Arabia",
288
+ "SN": "Senegal",
289
+ "CS": "Serbia and Montenegro",
290
+ "SC": "Seychelles",
291
+ "SL": "Sierra Leone",
292
+ "SG": "Singapore",
293
+ "SK": "Slovakia",
294
+ "SI": "Slovenia",
295
+ "SB": "Solomon Islands",
296
+ "SO": "Somalia",
297
+ "ZA": "South Africa",
298
+ "GS": "South Georgia and the South Sandwich Islands",
299
+ "ES": "Spain",
300
+ "LK": "Sri Lanka",
301
+ "SD": "Sudan",
302
+ "SR": "Suriname",
303
+ "SJ": "Svalbard and Jan Mayen",
304
+ "SZ": "Swaziland",
305
+ "SE": "Sweden",
306
+ "CH": "Switzerland",
307
+ "SY": "Syrian Arab Republic",
308
+ "TW": "Taiwan, Province of China",
309
+ "TJ": "Tajikistan",
310
+ "TZ": "Tanzania, United Republic of",
311
+ "TH": "Thailand",
312
+ "TL": "Timor-Leste",
313
+ "TG": "Togo",
314
+ "TK": "Tokelau",
315
+ "TO": "Tonga",
316
+ "TT": "Trinidad and Tobago",
317
+ "TN": "Tunisia",
318
+ "TR": "Turkey",
319
+ "TM": "Turkmenistan",
320
+ "TC": "Turks and Caicos Islands",
321
+ "TV": "Tuvalu",
322
+ "UG": "Uganda",
323
+ "UA": "Ukraine",
324
+ "AE": "United Arab Emirates",
325
+ "GB": "United Kingdom",
326
+ "US": "United States",
327
+ "UM": "United States Minor Outlying Islands",
328
+ "UY": "Uruguay",
329
+ "UZ": "Uzbekistan",
330
+ "VU": "Vanuatu",
331
+ "VE": "Venezuela",
332
+ "VN": "Viet Nam",
333
+ "VG": "Virgin Islands, British",
334
+ "VI": "Virgin Islands, U.S.",
335
+ "WF": "Wallis and Futuna",
336
+ "EH": "Western Sahara",
337
+ "YE": "Yemen",
338
+ "ZM": "Zambia",
339
+ "ZW": "Zimbabwe"
340
+ };
341
+
342
+ // src/protocol.ts
343
+ var EPOCH = (/* @__PURE__ */ new Date("1900-01-01T00:00:00Z")).getTime();
344
+ var MS_PER_DAY = 24 * 60 * 60 * 1e3;
345
+ function pack(info) {
346
+ const encoder = new TextEncoder();
347
+ const fullName = `${info.firstName} ${info.lastName}`;
348
+ const nameBytes = encoder.encode(fullName);
349
+ const birthDate = (/* @__PURE__ */ new Date(`${info.birthYear}-${String(info.birthMonth).padStart(2, "0")}-${String(info.birthDay).padStart(2, "0")}T00:00:00Z`)).getTime();
350
+ const daysSinceEpoch = Math.floor((birthDate - EPOCH) / MS_PER_DAY);
351
+ const countryIndex = Object.keys(COUNTRY_CODES).indexOf(info.countryCode.toUpperCase());
352
+ const finalCountryIndex = countryIndex === -1 ? 0 : countryIndex;
353
+ const buffer = new Uint8Array(1 + 1 + 2 + 2 + 1 + nameBytes.length);
354
+ const view = new DataView(buffer.buffer);
355
+ let offset = 0;
356
+ view.setUint8(offset++, 1);
357
+ const genderMap = { "Male": 1, "Female": 2, "Other": 3 };
358
+ view.setUint8(offset++, genderMap[info.gender] || 0);
359
+ view.setUint16(offset, finalCountryIndex, false);
360
+ offset += 2;
361
+ view.setUint16(offset, daysSinceEpoch, false);
362
+ offset += 2;
363
+ view.setUint8(offset++, nameBytes.length);
364
+ buffer.set(nameBytes, offset);
365
+ return buffer;
366
+ }
367
+ function unpack(buffer) {
368
+ const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
369
+ const decoder = new TextDecoder();
370
+ let offset = 0;
371
+ const version = view.getUint8(offset++);
372
+ if (version !== 1) throw new Error(`Unsupported protocol version: ${version}`);
373
+ const genderVal = view.getUint8(offset++);
374
+ const genderRevMap = { 1: "Male", 2: "Female", 3: "Other" };
375
+ const gender = genderRevMap[genderVal] || "Other";
376
+ const countryIndex = view.getUint16(offset, false);
377
+ offset += 2;
378
+ const daysSinceEpoch = view.getUint16(offset, false);
379
+ offset += 2;
380
+ const nameLen = view.getUint8(offset++);
381
+ const nameBytes = buffer.slice(offset, offset + nameLen);
382
+ const fullName = decoder.decode(nameBytes);
383
+ const [firstName = "", ...lastNameParts] = fullName.split(" ");
384
+ const lastName = lastNameParts.join(" ");
385
+ const countryCode = Object.keys(COUNTRY_CODES)[countryIndex] || "??";
386
+ const birthDate = new Date(EPOCH + daysSinceEpoch * MS_PER_DAY);
387
+ return {
388
+ firstName,
389
+ lastName,
390
+ countryCode,
391
+ birthYear: birthDate.getUTCFullYear(),
392
+ birthMonth: birthDate.getUTCMonth() + 1,
393
+ birthDay: birthDate.getUTCDate(),
394
+ gender
395
+ };
396
+ }
397
+
398
+ // src/index.ts
399
+ var SunHex = class {
400
+ apiKey;
401
+ baseUrl;
402
+ constructor(config = {}) {
403
+ this.apiKey = config.apiKey;
404
+ this.baseUrl = config.baseUrl || "https://protocol.sunhex.com";
405
+ }
406
+ /**
407
+ * Resolve an identity fragment locally at the edge.
408
+ * Total privacy. No API calls.
409
+ */
410
+ async resolveLocal(fragment, pin) {
411
+ const fullBuffer = hexToUint8Array(fragment);
412
+ const version = fullBuffer[0];
413
+ if (version !== 2) throw new Error(`Incompatible protocol version: ${version}`);
414
+ const salt = fullBuffer.slice(1, 9);
415
+ const iv = fullBuffer.slice(9, 21);
416
+ const ciphertext = fullBuffer.slice(21);
417
+ const key = await deriveKey(pin, salt);
418
+ const decrypted = await decrypt(ciphertext, key, iv);
419
+ return unpack(decrypted);
420
+ }
421
+ /**
422
+ * Crystallize an identity fragment locally.
423
+ * Securely packs and encrypts biological data.
424
+ */
425
+ async crystallizeLocal(info, pin) {
426
+ const packed = pack(info);
427
+ const salt = crypto.getRandomValues(new Uint8Array(8));
428
+ const key = await deriveKey(pin, salt);
429
+ const { ciphertext, iv } = await encrypt(packed, key);
430
+ const finalBuffer = new Uint8Array(1 + 8 + 12 + ciphertext.length);
431
+ finalBuffer[0] = 2;
432
+ finalBuffer.set(salt, 1);
433
+ finalBuffer.set(iv, 9);
434
+ finalBuffer.set(ciphertext, 21);
435
+ return uint8ArrayToHex(finalBuffer);
436
+ }
437
+ /**
438
+ * Interact with the SunHex API Cluster (Optional).
439
+ */
440
+ async fetchMetadata(fragment) {
441
+ if (!this.apiKey) throw new Error("API Key required for cluster calls.");
442
+ const response = await fetch(`${this.baseUrl}/api/v1/metadata`, {
443
+ method: "POST",
444
+ headers: {
445
+ "Authorization": `Bearer ${this.apiKey}`,
446
+ "Content-Type": "application/json"
447
+ },
448
+ body: JSON.stringify({ fragment })
449
+ });
450
+ return response.json();
451
+ }
452
+ };
453
+ var sunhex = new SunHex();
454
+ // Annotate the CommonJS export names for ESM import in node:
455
+ 0 && (module.exports = {
456
+ Crypto,
457
+ Protocol,
458
+ SunHex,
459
+ sunhex
460
+ });
@@ -0,0 +1,74 @@
1
+ /**
2
+ * SunHex Quantum Protocol - Cryptographic Layer
3
+ */
4
+ declare function deriveKey(pin: string, salt: Uint8Array): Promise<CryptoKey>;
5
+ declare function encrypt(data: Uint8Array, key: CryptoKey): Promise<{
6
+ ciphertext: Uint8Array;
7
+ iv: Uint8Array;
8
+ }>;
9
+ declare function decrypt(ciphertext: Uint8Array, key: CryptoKey, iv: Uint8Array): Promise<Uint8Array>;
10
+ declare function hexToUint8Array(hex: string): Uint8Array;
11
+ declare function uint8ArrayToHex(bytes: Uint8Array): string;
12
+
13
+ declare const crypto_decrypt: typeof decrypt;
14
+ declare const crypto_deriveKey: typeof deriveKey;
15
+ declare const crypto_encrypt: typeof encrypt;
16
+ declare const crypto_hexToUint8Array: typeof hexToUint8Array;
17
+ declare const crypto_uint8ArrayToHex: typeof uint8ArrayToHex;
18
+ declare namespace crypto {
19
+ export { crypto_decrypt as decrypt, crypto_deriveKey as deriveKey, crypto_encrypt as encrypt, crypto_hexToUint8Array as hexToUint8Array, crypto_uint8ArrayToHex as uint8ArrayToHex };
20
+ }
21
+
22
+ /**
23
+ * SunHex Quantum Protocol - Serialization Layer
24
+ */
25
+ interface PersonalInfo {
26
+ firstName: string;
27
+ lastName: string;
28
+ countryCode: string;
29
+ birthYear: number;
30
+ birthMonth: number;
31
+ birthDay: number;
32
+ gender: "Male" | "Female" | "Other";
33
+ }
34
+ declare function pack(info: PersonalInfo): Uint8Array;
35
+ declare function unpack(buffer: Uint8Array): PersonalInfo;
36
+
37
+ type protocol_PersonalInfo = PersonalInfo;
38
+ declare const protocol_pack: typeof pack;
39
+ declare const protocol_unpack: typeof unpack;
40
+ declare namespace protocol {
41
+ export { type protocol_PersonalInfo as PersonalInfo, protocol_pack as pack, protocol_unpack as unpack };
42
+ }
43
+
44
+ /**
45
+ * SunHex Quantum Protocol SDK
46
+ * Official library for decentralized identity resolution.
47
+ */
48
+
49
+ interface SunHexConfig {
50
+ apiKey?: string;
51
+ baseUrl?: string;
52
+ }
53
+ declare class SunHex {
54
+ private apiKey?;
55
+ private baseUrl;
56
+ constructor(config?: SunHexConfig);
57
+ /**
58
+ * Resolve an identity fragment locally at the edge.
59
+ * Total privacy. No API calls.
60
+ */
61
+ resolveLocal(fragment: string, pin: string): Promise<PersonalInfo>;
62
+ /**
63
+ * Crystallize an identity fragment locally.
64
+ * Securely packs and encrypts biological data.
65
+ */
66
+ crystallizeLocal(info: PersonalInfo, pin: string): Promise<string>;
67
+ /**
68
+ * Interact with the SunHex API Cluster (Optional).
69
+ */
70
+ fetchMetadata(fragment: string): Promise<any>;
71
+ }
72
+ declare const sunhex: SunHex;
73
+
74
+ export { crypto as Crypto, type PersonalInfo, protocol as Protocol, SunHex, type SunHexConfig, sunhex };
@@ -0,0 +1,74 @@
1
+ /**
2
+ * SunHex Quantum Protocol - Cryptographic Layer
3
+ */
4
+ declare function deriveKey(pin: string, salt: Uint8Array): Promise<CryptoKey>;
5
+ declare function encrypt(data: Uint8Array, key: CryptoKey): Promise<{
6
+ ciphertext: Uint8Array;
7
+ iv: Uint8Array;
8
+ }>;
9
+ declare function decrypt(ciphertext: Uint8Array, key: CryptoKey, iv: Uint8Array): Promise<Uint8Array>;
10
+ declare function hexToUint8Array(hex: string): Uint8Array;
11
+ declare function uint8ArrayToHex(bytes: Uint8Array): string;
12
+
13
+ declare const crypto_decrypt: typeof decrypt;
14
+ declare const crypto_deriveKey: typeof deriveKey;
15
+ declare const crypto_encrypt: typeof encrypt;
16
+ declare const crypto_hexToUint8Array: typeof hexToUint8Array;
17
+ declare const crypto_uint8ArrayToHex: typeof uint8ArrayToHex;
18
+ declare namespace crypto {
19
+ export { crypto_decrypt as decrypt, crypto_deriveKey as deriveKey, crypto_encrypt as encrypt, crypto_hexToUint8Array as hexToUint8Array, crypto_uint8ArrayToHex as uint8ArrayToHex };
20
+ }
21
+
22
+ /**
23
+ * SunHex Quantum Protocol - Serialization Layer
24
+ */
25
+ interface PersonalInfo {
26
+ firstName: string;
27
+ lastName: string;
28
+ countryCode: string;
29
+ birthYear: number;
30
+ birthMonth: number;
31
+ birthDay: number;
32
+ gender: "Male" | "Female" | "Other";
33
+ }
34
+ declare function pack(info: PersonalInfo): Uint8Array;
35
+ declare function unpack(buffer: Uint8Array): PersonalInfo;
36
+
37
+ type protocol_PersonalInfo = PersonalInfo;
38
+ declare const protocol_pack: typeof pack;
39
+ declare const protocol_unpack: typeof unpack;
40
+ declare namespace protocol {
41
+ export { type protocol_PersonalInfo as PersonalInfo, protocol_pack as pack, protocol_unpack as unpack };
42
+ }
43
+
44
+ /**
45
+ * SunHex Quantum Protocol SDK
46
+ * Official library for decentralized identity resolution.
47
+ */
48
+
49
+ interface SunHexConfig {
50
+ apiKey?: string;
51
+ baseUrl?: string;
52
+ }
53
+ declare class SunHex {
54
+ private apiKey?;
55
+ private baseUrl;
56
+ constructor(config?: SunHexConfig);
57
+ /**
58
+ * Resolve an identity fragment locally at the edge.
59
+ * Total privacy. No API calls.
60
+ */
61
+ resolveLocal(fragment: string, pin: string): Promise<PersonalInfo>;
62
+ /**
63
+ * Crystallize an identity fragment locally.
64
+ * Securely packs and encrypts biological data.
65
+ */
66
+ crystallizeLocal(info: PersonalInfo, pin: string): Promise<string>;
67
+ /**
68
+ * Interact with the SunHex API Cluster (Optional).
69
+ */
70
+ fetchMetadata(fragment: string): Promise<any>;
71
+ }
72
+ declare const sunhex: SunHex;
73
+
74
+ export { crypto as Crypto, type PersonalInfo, protocol as Protocol, SunHex, type SunHexConfig, sunhex };
package/dist/index.js ADDED
@@ -0,0 +1,436 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // src/crypto.ts
8
+ var crypto_exports = {};
9
+ __export(crypto_exports, {
10
+ decrypt: () => decrypt,
11
+ deriveKey: () => deriveKey,
12
+ encrypt: () => encrypt,
13
+ hexToUint8Array: () => hexToUint8Array,
14
+ uint8ArrayToHex: () => uint8ArrayToHex
15
+ });
16
+ var ITERATIONS = 1e5;
17
+ async function deriveKey(pin, salt) {
18
+ const encoder = new TextEncoder();
19
+ const passwordKey = await crypto.subtle.importKey(
20
+ "raw",
21
+ encoder.encode(pin),
22
+ "PBKDF2",
23
+ false,
24
+ ["deriveBits", "deriveKey"]
25
+ );
26
+ return await crypto.subtle.deriveKey(
27
+ {
28
+ name: "PBKDF2",
29
+ salt,
30
+ iterations: ITERATIONS,
31
+ hash: "SHA-256"
32
+ },
33
+ passwordKey,
34
+ { name: "AES-GCM", length: 256 },
35
+ false,
36
+ ["encrypt", "decrypt"]
37
+ );
38
+ }
39
+ async function encrypt(data, key) {
40
+ const iv = crypto.getRandomValues(new Uint8Array(12));
41
+ const encrypted = await crypto.subtle.encrypt(
42
+ { name: "AES-GCM", iv },
43
+ key,
44
+ data
45
+ );
46
+ return {
47
+ ciphertext: new Uint8Array(encrypted),
48
+ iv
49
+ };
50
+ }
51
+ async function decrypt(ciphertext, key, iv) {
52
+ const decrypted = await crypto.subtle.decrypt(
53
+ { name: "AES-GCM", iv },
54
+ key,
55
+ ciphertext
56
+ );
57
+ return new Uint8Array(decrypted);
58
+ }
59
+ function hexToUint8Array(hex) {
60
+ const bytes = new Uint8Array(hex.length / 2);
61
+ for (let i = 0; i < hex.length; i += 2) {
62
+ bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
63
+ }
64
+ return bytes;
65
+ }
66
+ function uint8ArrayToHex(bytes) {
67
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("").toUpperCase();
68
+ }
69
+
70
+ // src/protocol.ts
71
+ var protocol_exports = {};
72
+ __export(protocol_exports, {
73
+ pack: () => pack,
74
+ unpack: () => unpack
75
+ });
76
+
77
+ // src/constants.ts
78
+ var COUNTRY_CODES = {
79
+ "AF": "Afghanistan",
80
+ "AL": "Albania",
81
+ "DZ": "Algeria",
82
+ "AS": "American Samoa",
83
+ "AD": "Andorra",
84
+ "AO": "Angola",
85
+ "AI": "Anguilla",
86
+ "AQ": "Antarctica",
87
+ "AG": "Antigua and Barbuda",
88
+ "AR": "Argentina",
89
+ "AM": "Armenia",
90
+ "AW": "Aruba",
91
+ "AU": "Australia",
92
+ "AT": "Austria",
93
+ "AZ": "Azerbaijan",
94
+ "BS": "Bahamas",
95
+ "BH": "Bahrain",
96
+ "BD": "Bangladesh",
97
+ "BB": "Barbados",
98
+ "BY": "Belarus",
99
+ "BE": "Belgium",
100
+ "BZ": "Belize",
101
+ "BJ": "Benin",
102
+ "BM": "Bermuda",
103
+ "BT": "Bhutan",
104
+ "BO": "Bolivia",
105
+ "BA": "Bosnia and Herzegovina",
106
+ "BW": "Botswana",
107
+ "BR": "Brazil",
108
+ "IO": "British Indian Ocean Territory",
109
+ "BN": "Brunei Darussalam",
110
+ "BG": "Bulgaria",
111
+ "BF": "Burkina Faso",
112
+ "BI": "Burundi",
113
+ "KH": "Cambodia",
114
+ "CM": "Cameroon",
115
+ "CA": "Canada",
116
+ "CV": "Cape Verde",
117
+ "KY": "Cayman Islands",
118
+ "CF": "Central African Republic",
119
+ "TD": "Chad",
120
+ "CL": "Chile",
121
+ "CN": "China",
122
+ "CX": "Christmas Island",
123
+ "CC": "Cocos (Keeling) Islands",
124
+ "CO": "Colombia",
125
+ "KM": "Comoros",
126
+ "CG": "Congo",
127
+ "CD": "Congo, The Democratic Republic of the",
128
+ "CK": "Cook Islands",
129
+ "CR": "Costa Rica",
130
+ "CI": "Cote D'Ivoire",
131
+ "HR": "Croatia",
132
+ "CU": "Cuba",
133
+ "CY": "Cyprus",
134
+ "CZ": "Czech Republic",
135
+ "DK": "Denmark",
136
+ "DJ": "Djibouti",
137
+ "DM": "Dominica",
138
+ "DO": "Dominican Republic",
139
+ "EC": "Ecuador",
140
+ "EG": "Egypt",
141
+ "SV": "El Salvador",
142
+ "GQ": "Equatorial Guinea",
143
+ "ER": "Eritrea",
144
+ "EE": "Estonia",
145
+ "ET": "Ethiopia",
146
+ "FK": "Falkland Islands (Malvinas)",
147
+ "FO": "Faroe Islands",
148
+ "FJ": "Fiji",
149
+ "FI": "Finland",
150
+ "FR": "France",
151
+ "GF": "French Guiana",
152
+ "PF": "French Polynesia",
153
+ "TF": "French Southern Territories",
154
+ "GA": "Gabon",
155
+ "GM": "Gambia",
156
+ "GE": "Georgia",
157
+ "DE": "Germany",
158
+ "GH": "Ghana",
159
+ "GI": "Gibraltar",
160
+ "GR": "Greece",
161
+ "GL": "Greenland",
162
+ "GD": "Grenada",
163
+ "GP": "Guadeloupe",
164
+ "GU": "Guam",
165
+ "GT": "Guatemala",
166
+ "GN": "Guinea",
167
+ "GW": "Guinea-Bissau",
168
+ "GY": "Guyana",
169
+ "HT": "Haiti",
170
+ "HM": "Heard Island and Mcdonald Islands",
171
+ "VA": "Holy See (Vatican City State)",
172
+ "HN": "Honduras",
173
+ "HK": "Hong Kong",
174
+ "HU": "Hungary",
175
+ "IS": "Iceland",
176
+ "IN": "India",
177
+ "ID": "Indonesia",
178
+ "IR": "Iran, Islamic Republic of",
179
+ "IQ": "Iraq",
180
+ "IE": "Ireland",
181
+ "IL": "Israel",
182
+ "IT": "Italy",
183
+ "JM": "Jamaica",
184
+ "JP": "Japan",
185
+ "JO": "Jordan",
186
+ "KZ": "Kazakhstan",
187
+ "KE": "Kenya",
188
+ "KI": "Kiribati",
189
+ "KP": "Korea, Democratic People's Republic of",
190
+ "KR": "Korea, Republic of",
191
+ "KW": "Kuwait",
192
+ "KG": "Kyrgyzstan",
193
+ "LA": "Lao People's Democratic Republic",
194
+ "LV": "Latvia",
195
+ "LB": "Lebanon",
196
+ "LS": "Lesotho",
197
+ "LR": "Liberia",
198
+ "LY": "Libyan Arab Jamahiriya",
199
+ "LI": "Liechtenstein",
200
+ "LT": "Lithuania",
201
+ "LU": "Luxembourg",
202
+ "MO": "Macao",
203
+ "MK": "Macedonia, The Former Yugoslav Republic of",
204
+ "MG": "Madagascar",
205
+ "MW": "Malawi",
206
+ "MY": "Malaysia",
207
+ "MV": "Maldives",
208
+ "ML": "Mali",
209
+ "MT": "Malta",
210
+ "MH": "Marshall Islands",
211
+ "MQ": "Martinique",
212
+ "MR": "Mauritania",
213
+ "MU": "Mauritius",
214
+ "YT": "Mayotte",
215
+ "MX": "Mexico",
216
+ "FM": "Micronesia, Federated States of",
217
+ "MD": "Moldova, Republic of",
218
+ "MC": "Monaco",
219
+ "MN": "Mongolia",
220
+ "MS": "Montserrat",
221
+ "MA": "Morocco",
222
+ "MZ": "Mozambique",
223
+ "MM": "Myanmar",
224
+ "NA": "Namibia",
225
+ "NR": "Nauru",
226
+ "NP": "Nepal",
227
+ "NL": "Netherlands",
228
+ "AN": "Netherlands Antilles",
229
+ "NC": "New Caledonia",
230
+ "NZ": "New Zealand",
231
+ "NI": "Nicaragua",
232
+ "NE": "Niger",
233
+ "NG": "Nigeria",
234
+ "NU": "Niue",
235
+ "NF": "Norfolk Island",
236
+ "MP": "Northern Mariana Islands",
237
+ "NO": "Norway",
238
+ "OM": "Oman",
239
+ "PK": "Pakistan",
240
+ "PW": "Palau",
241
+ "PS": "Palestinian Territory, Occupied",
242
+ "PA": "Panama",
243
+ "PG": "Papua New Guinea",
244
+ "PY": "Paraguay",
245
+ "PE": "Peru",
246
+ "PH": "Philippines",
247
+ "PN": "Pitcairn",
248
+ "PL": "Poland",
249
+ "PT": "Portugal",
250
+ "PR": "Puerto Rico",
251
+ "QA": "Qatar",
252
+ "RE": "Reunion",
253
+ "RO": "Romania",
254
+ "RU": "Russian Federation",
255
+ "RW": "Rwanda",
256
+ "SH": "Saint Helena",
257
+ "KN": "Saint Kitts and Nevis",
258
+ "LC": "Saint Lucia",
259
+ "PM": "Saint Pierre and Miquelon",
260
+ "VC": "Saint Vincent and the Grenadines",
261
+ "WS": "Samoa",
262
+ "SM": "San Marino",
263
+ "ST": "Sao Tome and Principe",
264
+ "SA": "Saudi Arabia",
265
+ "SN": "Senegal",
266
+ "CS": "Serbia and Montenegro",
267
+ "SC": "Seychelles",
268
+ "SL": "Sierra Leone",
269
+ "SG": "Singapore",
270
+ "SK": "Slovakia",
271
+ "SI": "Slovenia",
272
+ "SB": "Solomon Islands",
273
+ "SO": "Somalia",
274
+ "ZA": "South Africa",
275
+ "GS": "South Georgia and the South Sandwich Islands",
276
+ "ES": "Spain",
277
+ "LK": "Sri Lanka",
278
+ "SD": "Sudan",
279
+ "SR": "Suriname",
280
+ "SJ": "Svalbard and Jan Mayen",
281
+ "SZ": "Swaziland",
282
+ "SE": "Sweden",
283
+ "CH": "Switzerland",
284
+ "SY": "Syrian Arab Republic",
285
+ "TW": "Taiwan, Province of China",
286
+ "TJ": "Tajikistan",
287
+ "TZ": "Tanzania, United Republic of",
288
+ "TH": "Thailand",
289
+ "TL": "Timor-Leste",
290
+ "TG": "Togo",
291
+ "TK": "Tokelau",
292
+ "TO": "Tonga",
293
+ "TT": "Trinidad and Tobago",
294
+ "TN": "Tunisia",
295
+ "TR": "Turkey",
296
+ "TM": "Turkmenistan",
297
+ "TC": "Turks and Caicos Islands",
298
+ "TV": "Tuvalu",
299
+ "UG": "Uganda",
300
+ "UA": "Ukraine",
301
+ "AE": "United Arab Emirates",
302
+ "GB": "United Kingdom",
303
+ "US": "United States",
304
+ "UM": "United States Minor Outlying Islands",
305
+ "UY": "Uruguay",
306
+ "UZ": "Uzbekistan",
307
+ "VU": "Vanuatu",
308
+ "VE": "Venezuela",
309
+ "VN": "Viet Nam",
310
+ "VG": "Virgin Islands, British",
311
+ "VI": "Virgin Islands, U.S.",
312
+ "WF": "Wallis and Futuna",
313
+ "EH": "Western Sahara",
314
+ "YE": "Yemen",
315
+ "ZM": "Zambia",
316
+ "ZW": "Zimbabwe"
317
+ };
318
+
319
+ // src/protocol.ts
320
+ var EPOCH = (/* @__PURE__ */ new Date("1900-01-01T00:00:00Z")).getTime();
321
+ var MS_PER_DAY = 24 * 60 * 60 * 1e3;
322
+ function pack(info) {
323
+ const encoder = new TextEncoder();
324
+ const fullName = `${info.firstName} ${info.lastName}`;
325
+ const nameBytes = encoder.encode(fullName);
326
+ const birthDate = (/* @__PURE__ */ new Date(`${info.birthYear}-${String(info.birthMonth).padStart(2, "0")}-${String(info.birthDay).padStart(2, "0")}T00:00:00Z`)).getTime();
327
+ const daysSinceEpoch = Math.floor((birthDate - EPOCH) / MS_PER_DAY);
328
+ const countryIndex = Object.keys(COUNTRY_CODES).indexOf(info.countryCode.toUpperCase());
329
+ const finalCountryIndex = countryIndex === -1 ? 0 : countryIndex;
330
+ const buffer = new Uint8Array(1 + 1 + 2 + 2 + 1 + nameBytes.length);
331
+ const view = new DataView(buffer.buffer);
332
+ let offset = 0;
333
+ view.setUint8(offset++, 1);
334
+ const genderMap = { "Male": 1, "Female": 2, "Other": 3 };
335
+ view.setUint8(offset++, genderMap[info.gender] || 0);
336
+ view.setUint16(offset, finalCountryIndex, false);
337
+ offset += 2;
338
+ view.setUint16(offset, daysSinceEpoch, false);
339
+ offset += 2;
340
+ view.setUint8(offset++, nameBytes.length);
341
+ buffer.set(nameBytes, offset);
342
+ return buffer;
343
+ }
344
+ function unpack(buffer) {
345
+ const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
346
+ const decoder = new TextDecoder();
347
+ let offset = 0;
348
+ const version = view.getUint8(offset++);
349
+ if (version !== 1) throw new Error(`Unsupported protocol version: ${version}`);
350
+ const genderVal = view.getUint8(offset++);
351
+ const genderRevMap = { 1: "Male", 2: "Female", 3: "Other" };
352
+ const gender = genderRevMap[genderVal] || "Other";
353
+ const countryIndex = view.getUint16(offset, false);
354
+ offset += 2;
355
+ const daysSinceEpoch = view.getUint16(offset, false);
356
+ offset += 2;
357
+ const nameLen = view.getUint8(offset++);
358
+ const nameBytes = buffer.slice(offset, offset + nameLen);
359
+ const fullName = decoder.decode(nameBytes);
360
+ const [firstName = "", ...lastNameParts] = fullName.split(" ");
361
+ const lastName = lastNameParts.join(" ");
362
+ const countryCode = Object.keys(COUNTRY_CODES)[countryIndex] || "??";
363
+ const birthDate = new Date(EPOCH + daysSinceEpoch * MS_PER_DAY);
364
+ return {
365
+ firstName,
366
+ lastName,
367
+ countryCode,
368
+ birthYear: birthDate.getUTCFullYear(),
369
+ birthMonth: birthDate.getUTCMonth() + 1,
370
+ birthDay: birthDate.getUTCDate(),
371
+ gender
372
+ };
373
+ }
374
+
375
+ // src/index.ts
376
+ var SunHex = class {
377
+ apiKey;
378
+ baseUrl;
379
+ constructor(config = {}) {
380
+ this.apiKey = config.apiKey;
381
+ this.baseUrl = config.baseUrl || "https://protocol.sunhex.com";
382
+ }
383
+ /**
384
+ * Resolve an identity fragment locally at the edge.
385
+ * Total privacy. No API calls.
386
+ */
387
+ async resolveLocal(fragment, pin) {
388
+ const fullBuffer = hexToUint8Array(fragment);
389
+ const version = fullBuffer[0];
390
+ if (version !== 2) throw new Error(`Incompatible protocol version: ${version}`);
391
+ const salt = fullBuffer.slice(1, 9);
392
+ const iv = fullBuffer.slice(9, 21);
393
+ const ciphertext = fullBuffer.slice(21);
394
+ const key = await deriveKey(pin, salt);
395
+ const decrypted = await decrypt(ciphertext, key, iv);
396
+ return unpack(decrypted);
397
+ }
398
+ /**
399
+ * Crystallize an identity fragment locally.
400
+ * Securely packs and encrypts biological data.
401
+ */
402
+ async crystallizeLocal(info, pin) {
403
+ const packed = pack(info);
404
+ const salt = crypto.getRandomValues(new Uint8Array(8));
405
+ const key = await deriveKey(pin, salt);
406
+ const { ciphertext, iv } = await encrypt(packed, key);
407
+ const finalBuffer = new Uint8Array(1 + 8 + 12 + ciphertext.length);
408
+ finalBuffer[0] = 2;
409
+ finalBuffer.set(salt, 1);
410
+ finalBuffer.set(iv, 9);
411
+ finalBuffer.set(ciphertext, 21);
412
+ return uint8ArrayToHex(finalBuffer);
413
+ }
414
+ /**
415
+ * Interact with the SunHex API Cluster (Optional).
416
+ */
417
+ async fetchMetadata(fragment) {
418
+ if (!this.apiKey) throw new Error("API Key required for cluster calls.");
419
+ const response = await fetch(`${this.baseUrl}/api/v1/metadata`, {
420
+ method: "POST",
421
+ headers: {
422
+ "Authorization": `Bearer ${this.apiKey}`,
423
+ "Content-Type": "application/json"
424
+ },
425
+ body: JSON.stringify({ fragment })
426
+ });
427
+ return response.json();
428
+ }
429
+ };
430
+ var sunhex = new SunHex();
431
+ export {
432
+ crypto_exports as Crypto,
433
+ protocol_exports as Protocol,
434
+ SunHex,
435
+ sunhex
436
+ };
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@sunhex/protocol",
3
+ "version": "1.0.2",
4
+ "description": "The official SunHex Quantum Protocol SDK for decentralized identity.",
5
+ "main": "dist/index.cjs",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/abdelhakim-sahifa/sunhex-sdk.git"
14
+ },
15
+ "homepage": "https://github.com/abdelhakim-sahifa/sunhex-sdk#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/abdelhakim-sahifa/sunhex-sdk/issues"
18
+ },
19
+ "type": "module",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "import": "./dist/index.js",
24
+ "require": "./dist/index.cjs"
25
+ }
26
+ },
27
+ "scripts": {
28
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
29
+ "dev": "tsup src/index.ts --format cjs,esm --watch --dts",
30
+ "lint": "eslint src/**/*.ts",
31
+ "test": "jest",
32
+ "test:watch": "jest --watch",
33
+ "prepublishOnly": "npm run build && npm run test"
34
+ },
35
+ "keywords": [
36
+ "sunhex",
37
+ "identity",
38
+ "decentralized",
39
+ "crypto",
40
+ "quantum",
41
+ "aes-gcm",
42
+ "stateless"
43
+ ],
44
+ "author": "Abdelhakim-Sahifa",
45
+ "license": "MIT",
46
+ "devDependencies": {
47
+ "@eslint/js": "^9.39.2",
48
+ "@types/jest": "^30.0.0",
49
+ "@types/node": "^20.0.0",
50
+ "@typescript-eslint/eslint-plugin": "^8.53.1",
51
+ "@typescript-eslint/parser": "^8.53.1",
52
+ "eslint": "^9.39.2",
53
+ "jest": "^30.2.0",
54
+ "ts-jest": "^29.4.6",
55
+ "tsup": "^8.0.0",
56
+ "typescript": "^5.0.0",
57
+ "typescript-eslint": "^8.53.1"
58
+ },
59
+ "engines": {
60
+ "node": ">=18.0.0"
61
+ }
62
+ }