@majikah/majik-key 0.2.9 → 0.2.11
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 +1 -1
- package/dist/core/types.d.ts +6 -0
- package/dist/majik-key.d.ts +21 -3
- package/dist/majik-key.js +87 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -893,7 +893,7 @@ Secure messaging platform using Majik Keys
|
|
|
893
893
|
|
|
894
894
|
[Read more about Majik Message here](https://majikah.solutions/products/majik-message)
|
|
895
895
|
|
|
896
|
-
[](https://message.majikah.solutions)
|
|
897
897
|
|
|
898
898
|
> Click the image to try Majik Message live.
|
|
899
899
|
|
package/dist/core/types.d.ts
CHANGED
|
@@ -21,6 +21,12 @@ export interface MajikKeyJSON {
|
|
|
21
21
|
encryptedMlDsaSecretKey?: string;
|
|
22
22
|
mnemonicLanguage?: MnemonicLanguage;
|
|
23
23
|
}
|
|
24
|
+
export interface MajikKeyDangerousJSON extends MajikKeyJSON {
|
|
25
|
+
privateKeyBase64: string;
|
|
26
|
+
mlKemSecretKeyBase64: string;
|
|
27
|
+
edSecretKeyBase64: string;
|
|
28
|
+
mlDsaSecretKeyBase64: string;
|
|
29
|
+
}
|
|
24
30
|
export interface MajikKeyMetadata {
|
|
25
31
|
id: string;
|
|
26
32
|
fingerprint: string;
|
package/dist/majik-key.d.ts
CHANGED
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
* point, so ML-KEM keys can be deterministically re-derived and stored.
|
|
22
22
|
* No partial migration — either fully upgraded or not upgraded yet.
|
|
23
23
|
*/
|
|
24
|
-
import { MajikContact } from "@majikah/majik-contact";
|
|
24
|
+
import { MajikContact, MajikContactMeta } from "@majikah/majik-contact";
|
|
25
25
|
import { KDF_VERSION } from "./core/crypto/constants";
|
|
26
|
-
import type { MajikKeyJSON, MajikKeyMetadata, MnemonicJSON } from "./core/types";
|
|
26
|
+
import type { MajikKeyDangerousJSON, MajikKeyJSON, MajikKeyMetadata, MnemonicJSON } from "./core/types";
|
|
27
27
|
import { MajikMessageIdentity } from "./core/database/system/identity";
|
|
28
28
|
import { MajikUser } from "@thezelijah/majik-user";
|
|
29
29
|
import { MnemonicLanguage } from "./core/crypto/wordlist";
|
|
@@ -142,6 +142,20 @@ export declare class MajikKey {
|
|
|
142
142
|
get hasSigningKeys(): boolean;
|
|
143
143
|
static create(mnemonic: string, passphrase: string, label?: string, mnemonicLanguage?: MnemonicLanguage): Promise<MajikKey>;
|
|
144
144
|
static fromJSON(json: MajikKeyJSON | string): MajikKey;
|
|
145
|
+
/**
|
|
146
|
+
* Export a fully unlocked MajikKey with all raw private keys.
|
|
147
|
+
* ⚠️ DANGEROUS — output contains unencrypted private key material.
|
|
148
|
+
* Only use for server-side secrets injection.
|
|
149
|
+
* Never log, store in a database, or transmit over the network.
|
|
150
|
+
*/
|
|
151
|
+
toDangerousJSON(): MajikKeyDangerousJSON;
|
|
152
|
+
/**
|
|
153
|
+
* Reconstruct a fully unlocked MajikKey from a dangerous JSON export.
|
|
154
|
+
* ⚠️ DANGEROUS — input contains unencrypted private key material.
|
|
155
|
+
* Intended for server-side use only (e.g. TSA signing key loaded from Cloudflare Secrets).
|
|
156
|
+
* No KDF is involved — reconstruction is instant.
|
|
157
|
+
*/
|
|
158
|
+
static fromDangerousJSON(json: MajikKeyDangerousJSON | string): MajikKey;
|
|
145
159
|
toMnemonicJSON(mnemonic: string, passphrase?: string): MnemonicJSON;
|
|
146
160
|
static fromMnemonicJSON(mnemonicJson: MnemonicJSON | string, passphrase: string, label?: string): Promise<MajikKey>;
|
|
147
161
|
updateLabel(newLabel: string): this;
|
|
@@ -165,7 +179,11 @@ export declare class MajikKey {
|
|
|
165
179
|
toString(pretty?: boolean): string;
|
|
166
180
|
static generateMnemonic(strength?: 128 | 256, language?: MnemonicLanguage): Promise<string>;
|
|
167
181
|
static validateMnemonic(mnemonic: string): boolean;
|
|
168
|
-
|
|
182
|
+
/**
|
|
183
|
+
* Converts the MajikKey to a MajikContact.
|
|
184
|
+
* You can pass a custom metadata type if needed, e.g., toContact<MyMeta>()
|
|
185
|
+
*/
|
|
186
|
+
toContact<TMeta extends MajikContactMeta = MajikContactMeta>(initialMeta?: Partial<TMeta>): MajikContact<TMeta>;
|
|
169
187
|
toKeyIdentity(): MajikKeyIdentity;
|
|
170
188
|
toSerializedIdentity(): SerializedIdentity;
|
|
171
189
|
toMajikMessageIdentity(user: MajikUser, options?: {
|
package/dist/majik-key.js
CHANGED
|
@@ -198,7 +198,7 @@ export class MajikKey {
|
|
|
198
198
|
encryptedMlDsaSecretKeyBase64: arrayBufferToBase64(identity.encryptedMlDsaSecretKey),
|
|
199
199
|
edSecretKey: identity.edSecretKey,
|
|
200
200
|
mlDsaSecretKey: identity.mlDsaSecretKey,
|
|
201
|
-
mnemonicLanguage: mnemonicLanguage
|
|
201
|
+
mnemonicLanguage: mnemonicLanguage,
|
|
202
202
|
});
|
|
203
203
|
}
|
|
204
204
|
catch (err) {
|
|
@@ -271,6 +271,81 @@ export class MajikKey {
|
|
|
271
271
|
throw new MajikKeyError("Failed to parse MajikKey from JSON", err);
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* Export a fully unlocked MajikKey with all raw private keys.
|
|
276
|
+
* ⚠️ DANGEROUS — output contains unencrypted private key material.
|
|
277
|
+
* Only use for server-side secrets injection.
|
|
278
|
+
* Never log, store in a database, or transmit over the network.
|
|
279
|
+
*/
|
|
280
|
+
toDangerousJSON() {
|
|
281
|
+
if (this.isLocked)
|
|
282
|
+
throw new MajikKeyError("MajikKey must be unlocked to export dangerous JSON.");
|
|
283
|
+
if (!this._edSecretKey ||
|
|
284
|
+
!this._mlDsaSecretKey ||
|
|
285
|
+
!this._mlKemSecretKey ||
|
|
286
|
+
!this._privateKeyBase64)
|
|
287
|
+
throw new MajikKeyError("MajikKey is missing secret keys — re-import via importFromMnemonicBackup() first.");
|
|
288
|
+
return {
|
|
289
|
+
...this.toJSON(),
|
|
290
|
+
privateKeyBase64: this._privateKeyBase64,
|
|
291
|
+
mlKemSecretKeyBase64: arrayToBase64(this._mlKemSecretKey),
|
|
292
|
+
edSecretKeyBase64: arrayToBase64(this._edSecretKey),
|
|
293
|
+
mlDsaSecretKeyBase64: arrayToBase64(this._mlDsaSecretKey),
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Reconstruct a fully unlocked MajikKey from a dangerous JSON export.
|
|
298
|
+
* ⚠️ DANGEROUS — input contains unencrypted private key material.
|
|
299
|
+
* Intended for server-side use only (e.g. TSA signing key loaded from Cloudflare Secrets).
|
|
300
|
+
* No KDF is involved — reconstruction is instant.
|
|
301
|
+
*/
|
|
302
|
+
static fromDangerousJSON(json) {
|
|
303
|
+
try {
|
|
304
|
+
const parsed = typeof json === "string" ? JSON.parse(json) : json;
|
|
305
|
+
if (!parsed.id ||
|
|
306
|
+
!parsed.fingerprint ||
|
|
307
|
+
!parsed.publicKey ||
|
|
308
|
+
!parsed.privateKeyBase64 ||
|
|
309
|
+
!parsed.edPublicKey ||
|
|
310
|
+
!parsed.edSecretKeyBase64 ||
|
|
311
|
+
!parsed.mlDsaPublicKey ||
|
|
312
|
+
!parsed.mlDsaSecretKeyBase64 ||
|
|
313
|
+
!parsed.mlKemPublicKey ||
|
|
314
|
+
!parsed.mlKemSecretKeyBase64)
|
|
315
|
+
throw new MajikKeyError("Invalid MajikKeyDangerousJSON — missing required fields");
|
|
316
|
+
const privateKeyBytes = base64ToUint8Array(parsed.privateKeyBase64);
|
|
317
|
+
const edPublicKey = base64ToUint8Array(parsed.edPublicKey);
|
|
318
|
+
const edSecretKey = base64ToUint8Array(parsed.edSecretKeyBase64);
|
|
319
|
+
const mlDsaPublicKey = base64ToUint8Array(parsed.mlDsaPublicKey);
|
|
320
|
+
const mlDsaSecretKey = base64ToUint8Array(parsed.mlDsaSecretKeyBase64);
|
|
321
|
+
const mlKemPublicKey = base64ToUint8Array(parsed.mlKemPublicKey);
|
|
322
|
+
const mlKemSecretKey = base64ToUint8Array(parsed.mlKemSecretKeyBase64);
|
|
323
|
+
return new MajikKey({
|
|
324
|
+
id: parsed.id,
|
|
325
|
+
fingerprint: parsed.fingerprint,
|
|
326
|
+
publicKey: { raw: base64ToUint8Array(parsed.publicKey) },
|
|
327
|
+
publicKeyBase64: parsed.publicKey,
|
|
328
|
+
privateKey: { raw: privateKeyBytes },
|
|
329
|
+
privateKeyBase64: parsed.privateKeyBase64,
|
|
330
|
+
encryptedPrivateKey: new ArrayBuffer(0),
|
|
331
|
+
encryptedPrivateKeyBase64: parsed.encryptedPrivateKey,
|
|
332
|
+
salt: parsed.salt,
|
|
333
|
+
backup: parsed.backup,
|
|
334
|
+
kdfVersion: parsed?.kdfVersion || KDF_VERSION.ARGON2ID,
|
|
335
|
+
mlKemPublicKey,
|
|
336
|
+
mlKemSecretKey,
|
|
337
|
+
edPublicKey,
|
|
338
|
+
edSecretKey,
|
|
339
|
+
mlDsaPublicKey,
|
|
340
|
+
mlDsaSecretKey,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
catch (err) {
|
|
344
|
+
if (err instanceof MajikKeyError)
|
|
345
|
+
throw err;
|
|
346
|
+
throw new MajikKeyError("Failed to reconstruct MajikKey from dangerous JSON", err);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
274
349
|
// ── MnemonicJSON ─────────────────────────────────────────────────────────────
|
|
275
350
|
toMnemonicJSON(mnemonic, passphrase) {
|
|
276
351
|
if (this.isLocked)
|
|
@@ -512,13 +587,22 @@ export class MajikKey {
|
|
|
512
587
|
return false;
|
|
513
588
|
}
|
|
514
589
|
}
|
|
515
|
-
|
|
590
|
+
/**
|
|
591
|
+
* Converts the MajikKey to a MajikContact.
|
|
592
|
+
* You can pass a custom metadata type if needed, e.g., toContact<MyMeta>()
|
|
593
|
+
*/
|
|
594
|
+
toContact(initialMeta) {
|
|
516
595
|
const mlKeyBase64 = arrayToBase64(this.mlKemPublicKey);
|
|
596
|
+
// We construct the base metadata and merge with any provided initialMeta
|
|
597
|
+
const meta = {
|
|
598
|
+
label: this._label,
|
|
599
|
+
...initialMeta,
|
|
600
|
+
};
|
|
517
601
|
return new MajikContact({
|
|
518
602
|
id: this._id,
|
|
519
603
|
publicKey: this._publicKey,
|
|
520
604
|
fingerprint: this._fingerprint,
|
|
521
|
-
meta:
|
|
605
|
+
meta: meta,
|
|
522
606
|
mlKey: mlKeyBase64,
|
|
523
607
|
edPublicKeyBase64: this._edPublicKey
|
|
524
608
|
? arrayToBase64(this._edPublicKey)
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@majikah/majik-key",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"description": "A post-quantum ready seed phrase account library for the Majikah ecosystem. Manages deterministic X25519 and ML-KEM-768 identities with Argon2id protection and seamless legacy account migration.",
|
|
5
|
-
"version": "0.2.
|
|
5
|
+
"version": "0.2.11",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"author": "Zelijah",
|
|
8
8
|
"main": "./dist/index.js",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"test:watch": "vitest"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@majikah/majik-contact": "^0.0.
|
|
53
|
+
"@majikah/majik-contact": "^0.0.6",
|
|
54
54
|
"@noble/hashes": "^2.2.0",
|
|
55
55
|
"@noble/post-quantum": "^0.6.1",
|
|
56
56
|
"@scure/bip39": "^2.2.0",
|