88 * adapted for Aptos key types. Supports encrypting Ed25519, Secp256k1, and Secp256r1
99 * private keys with a password or key file using modern cryptography:
1010 *
11- * - KDF: Argon2id (default), scrypt , or PBKDF2-HMAC-SHA256
11+ * - KDF: scrypt (default), Argon2id (requires optional `hash-wasm` peer dependency) , or PBKDF2-HMAC-SHA256
1212 * - Cipher: AES-256-GCM (authenticated encryption)
1313 *
1414 * AES-256-GCM provides both confidentiality and integrity in a single operation,
@@ -24,7 +24,6 @@ import { sha256 } from "@noble/hashes/sha256";
2424import { scrypt as nobleScrypt } from "@noble/hashes/scrypt" ;
2525import { pbkdf2 as noblePbkdf2 } from "@noble/hashes/pbkdf2" ;
2626import { randomBytes , bytesToHex , hexToBytes } from "@noble/hashes/utils" ;
27- import { argon2id as hashWasmArgon2id } from "hash-wasm" ;
2827import { Ed25519PrivateKey } from "./ed25519" ;
2928import { Secp256k1PrivateKey } from "./secp256k1" ;
3029import { Secp256r1PrivateKey } from "./secp256r1" ;
@@ -106,8 +105,8 @@ export type KeystoreKdfParams = Argon2idKdfParams | ScryptKdfParams | Pbkdf2KdfP
106105 * "cipher": "aes-256-gcm",
107106 * "cipherparams": { "iv": "...", "tag": "..." },
108107 * "ciphertext": "...",
109- * "kdf": "argon2id ",
110- * "kdfparams": { "iterations ": 3 , "parallelism ": 4 , "memorySize ": 65536 , "dklen": 32, "salt": "..." }
108+ * "kdf": "scrypt ",
109+ * "kdfparams": { "n ": 131072 , "r ": 8 , "p ": 1 , "dklen": 32, "salt": "..." }
111110 * }
112111 * }
113112 * ```
@@ -145,7 +144,7 @@ export interface AptosKeyStore {
145144 * Options for customizing keystore encryption.
146145 */
147146export interface KeystoreEncryptOptions {
148- /** KDF to use. Defaults to "argon2id". */
147+ /** KDF to use. Defaults to "scrypt". Use " argon2id" for stronger protection (requires `hash-wasm` peer dependency) . */
149148 kdf ?: KeystoreKdf ;
150149 /** Argon2id iterations (time cost). Defaults to 3. */
151150 argon2Iterations ?: number ;
@@ -181,12 +180,22 @@ function passwordToBytes(password: string | Uint8Array): Uint8Array {
181180 return password ;
182181}
183182
183+ async function loadArgon2id ( ) : Promise < typeof import ( "hash-wasm" ) . argon2id > {
184+ try {
185+ const mod = await import ( "hash-wasm" ) ;
186+ return mod . argon2id ;
187+ } catch {
188+ throw new Error ( 'Argon2id KDF requires the "hash-wasm" package. Install it with: npm install hash-wasm' ) ;
189+ }
190+ }
191+
184192async function deriveKey ( password : Uint8Array , kdf : KeystoreKdf , kdfparams : KeystoreKdfParams ) : Promise < Uint8Array > {
185193 const salt = hexToBytes ( kdfparams . salt ) ;
186194
187195 if ( kdf === "argon2id" ) {
196+ const argon2id = await loadArgon2id ( ) ;
188197 const params = kdfparams as Argon2idKdfParams ;
189- return hashWasmArgon2id ( {
198+ return argon2id ( {
190199 password,
191200 salt,
192201 iterations : params . iterations ,
@@ -290,7 +299,9 @@ function createPrivateKey(bytes: Uint8Array, keyType: PrivateKeyVariants): Keyst
290299 * Supports all Aptos private key types (Ed25519, Secp256k1, Secp256r1).
291300 * The password can be a string (passphrase) or raw bytes (e.g., contents of a key file).
292301 *
293- * Uses AES-256-GCM authenticated encryption with Argon2id key derivation by default.
302+ * Uses AES-256-GCM authenticated encryption with scrypt key derivation by default.
303+ * For stronger password protection, use `kdf: "argon2id"` (requires the optional
304+ * `hash-wasm` peer dependency: `npm install hash-wasm`).
294305 *
295306 * @param args.privateKey - The private key to encrypt.
296307 * @param args.password - Password string or key-file bytes used to derive the encryption key.
@@ -301,12 +312,19 @@ function createPrivateKey(bytes: Uint8Array, keyType: PrivateKeyVariants): Keyst
301312 * ```typescript
302313 * import { Ed25519PrivateKey, encryptKeystore } from "@aptos-labs/ts-sdk";
303314 *
315+ * // Default (scrypt) — no extra dependencies
304316 * const privateKey = Ed25519PrivateKey.generate();
305317 * const keystore = await encryptKeystore({
306318 * privateKey,
307319 * password: "my-secure-password",
308320 * });
309- * console.log(JSON.stringify(keystore, null, 2));
321+ *
322+ * // Argon2id — requires: npm install hash-wasm
323+ * const keystoreArgon2 = await encryptKeystore({
324+ * privateKey,
325+ * password: "my-secure-password",
326+ * options: { kdf: "argon2id" },
327+ * });
310328 * ```
311329 */
312330export async function encryptKeystore ( args : {
@@ -316,7 +334,7 @@ export async function encryptKeystore(args: {
316334} ) : Promise < AptosKeyStore > {
317335 const { privateKey, password, options = { } } = args ;
318336 const {
319- kdf = "argon2id " ,
337+ kdf = "scrypt " ,
320338 argon2Iterations = 3 ,
321339 argon2Parallelism = 4 ,
322340 argon2MemorySize = 65536 ,
0 commit comments