@majikah/majik-key 0.4.0 → 0.5.0

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.
@@ -326,6 +326,32 @@ export declare class MajikKey {
326
326
  getMlKemSecretKey(): Uint8Array;
327
327
  getEdSecretKey(): Uint8Array;
328
328
  getMlDsaSecretKey(): Uint8Array;
329
+ /**
330
+ * Executes an operation against an already-unlocked MajikKey and
331
+ * automatically locks the key when the operation completes.
332
+ *
333
+ * The key is always locked after the operation, including when the
334
+ * operation throws or rejects.
335
+ *
336
+ * @param key - An already-unlocked MajikKey instance.
337
+ * @param operation - Synchronous or asynchronous operation to execute.
338
+ * @returns The result returned by the operation.
339
+ *
340
+ * @throws {MajikKeyError} If the key is locked.
341
+ * @throws {MajikKeyError} If `operation` is not a function.
342
+ *
343
+ * @example
344
+ * ```ts
345
+ * await key.unlock(passphrase);
346
+ *
347
+ * const signature = await MajikKey.withAutoLock(key, async (key) => {
348
+ * return sign(key.getEdSecretKey(), message);
349
+ * });
350
+ *
351
+ * // key.isLocked === true
352
+ * ```
353
+ */
354
+ static withAutoLock<T>(key: MajikKey, operation: (key: MajikKey) => T | Promise<T>): Promise<T>;
329
355
  toJSON(): MajikKeyJSON;
330
356
  toString(pretty?: boolean): string;
331
357
  static generateMnemonic(strength?: 128 | 256, language?: MnemonicLanguage): Promise<string>;
package/dist/majik-key.js CHANGED
@@ -8,7 +8,7 @@ import { aesGcmDecrypt, aesGcmEncrypt, deriveKeyFromPassphraseArgon2, deriveKeyF
8
8
  import { EncryptionEngine } from "./core/crypto/encryption-engine";
9
9
  import { MajikContact } from "@majikah/majik-contact";
10
10
  import { arrayBufferToBase64, arrayToBase64, base64ToArrayBuffer, concatUint8Arrays, utf8ToBase64, base64ToUtf8, seedStringToArray, seedArrayToString, base64ToUint8Array, } from "./core/utils";
11
- import { KDF_VERSION, MAJIK_MNEMONIC_SALT, } from "./core/crypto/constants";
11
+ import { KDF_VERSION, MAJIK_MNEMONIC_SALT } from "./core/crypto/constants";
12
12
  import { MajikKeyValidator } from "./core/validator";
13
13
  import { MajikKeyError } from "./core/error";
14
14
  import { MajikMessageIdentity } from "./core/database/system/identity";
@@ -706,6 +706,48 @@ export class MajikKey {
706
706
  throw new MajikKeyError("No ML-DSA secret key — re-import via importFromMnemonicBackup() for full migration.");
707
707
  return this._mlDsaSecretKey;
708
708
  }
709
+ /**
710
+ * Executes an operation against an already-unlocked MajikKey and
711
+ * automatically locks the key when the operation completes.
712
+ *
713
+ * The key is always locked after the operation, including when the
714
+ * operation throws or rejects.
715
+ *
716
+ * @param key - An already-unlocked MajikKey instance.
717
+ * @param operation - Synchronous or asynchronous operation to execute.
718
+ * @returns The result returned by the operation.
719
+ *
720
+ * @throws {MajikKeyError} If the key is locked.
721
+ * @throws {MajikKeyError} If `operation` is not a function.
722
+ *
723
+ * @example
724
+ * ```ts
725
+ * await key.unlock(passphrase);
726
+ *
727
+ * const signature = await MajikKey.withAutoLock(key, async (key) => {
728
+ * return sign(key.getEdSecretKey(), message);
729
+ * });
730
+ *
731
+ * // key.isLocked === true
732
+ * ```
733
+ */
734
+ static async withAutoLock(key, operation) {
735
+ if (!(key instanceof MajikKey)) {
736
+ throw new MajikKeyError("A valid MajikKey instance is required");
737
+ }
738
+ if (key.isLocked) {
739
+ throw new MajikKeyError("MajikKey must be unlocked before calling withAutoLock()");
740
+ }
741
+ if (typeof operation !== "function") {
742
+ throw new MajikKeyError("Operation must be a function");
743
+ }
744
+ try {
745
+ return await operation(key);
746
+ }
747
+ finally {
748
+ key.lock();
749
+ }
750
+ }
709
751
  // ── SERIALIZATION ────────────────────────────────────────────────────────────
710
752
  toJSON() {
711
753
  return {
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.4.0",
5
+ "version": "0.5.0",
6
6
  "license": "Apache-2.0",
7
7
  "author": "Zelijah",
8
8
  "main": "./dist/index.js",
@@ -56,11 +56,11 @@
56
56
  },
57
57
  "dependencies": {
58
58
  "@majikah/majik-contact": "^0.0.6",
59
- "@noble/curves": "^2.3.0",
60
- "@noble/hashes": "^2.3.0",
61
- "@noble/post-quantum": "^0.7.0",
62
- "@scure/bip32": "^2.3.0",
63
- "@scure/bip39": "^2.3.0",
59
+ "@noble/curves": "^2.4.0",
60
+ "@noble/hashes": "^2.4.0",
61
+ "@noble/post-quantum": "^0.7.1",
62
+ "@scure/bip32": "^2.4.0",
63
+ "@scure/bip39": "^2.4.0",
64
64
  "@stablelib/aes": "^2.0.1",
65
65
  "@stablelib/ed25519": "^2.1.0",
66
66
  "@stablelib/gcm": "^2.0.1",
@@ -72,16 +72,16 @@
72
72
  "hash-wasm": "^4.12.0"
73
73
  },
74
74
  "devDependencies": {
75
- "@scure/btc-signer": "^2.3.0",
76
- "@solana/kit": "^7.1.0",
75
+ "@scure/btc-signer": "^2.4.1",
76
+ "@solana/kit": "^8.3.0",
77
77
  "@types/ed2curve": "^0.2.4",
78
- "@types/node": "^26.2.0",
78
+ "@types/node": "^26.6.2",
79
79
  "typescript": "^7.0.2",
80
- "vitest": "^4.1.10"
80
+ "vitest": "^5.0.1"
81
81
  },
82
82
  "peerDependencies": {
83
- "@scure/btc-signer": "^2.2.0",
84
- "@solana/kit": "^7.0.0"
83
+ "@scure/btc-signer": "^2.4.1",
84
+ "@solana/kit": "^8.3.0"
85
85
  },
86
86
  "peerDependenciesMeta": {
87
87
  "@solana/kit": {