$ npm install @tetherto/wdk-secret-managerNote: This package is currently in beta. Please test thoroughly in development environments before using in production.
A small, security-focused utility for generating, encrypting, and managing wallet secrets. It provides:
crypto_secretboxThis module is part of the WDK (Wallet Development Kit) project, which empowers developers to build secure, non-custodial wallets with unified blockchain access, stateless architecture, and full user control.
For detailed documentation about the complete WDK ecosystem, visit https://docs.wallet.tether.io.
crypto_secretbox (XSalsa20-Poly1305)dispose()bare build for bare-wdk-runtimeInstall with npm:
npm install @tetherto/wdk-secret-manager
import WdkSecretManager from "@tetherto/wdk-secret-manager";
If you are using the bare runtime, import as usual; the bare export is provided for compatible bundlers/environments.
import WdkSecretManager from "@tetherto/wdk-secret-manager";
const passkey = "correct horse battery staple"; // minimum 12 characters
const salt = WdkSecretManager.generateSalt(); // 16-byte Buffer
// Optional: tune PBKDF2 iterations
const sm = new WdkSecretManager(passkey, salt, { iterations: 100_000 });
// Generates 16-byte entropy, converts to BIP-39 mnemonic, derives 64-byte seed,
// and encrypts both with the manager's settings
const { encryptedEntropy, encryptedSeed } = await sm.generateAndEncrypt();
// Decrypt later
const entropy = sm.decrypt(encryptedEntropy); // 16 bytes
const seed = sm.decrypt(encryptedSeed); // 64 bytes
// Accepts payloads between 16 and 64 bytes
const data = crypto.getRandomValues(new Uint8Array(32));
const payload = sm.encrypt(Buffer.from(data));
const out = sm.decrypt(payload);
import { pbkdf2Sync } from "crypto";
import b4a from "b4a";
const masterKey = b4a.from(
pbkdf2Sync(b4a.from(passkey), b4a.from(salt), 100_000, 32, "sha256")
);
const cipher = sm.encrypt(
Buffer.from("0123456789abcdef0123456789abcdef"),
masterKey
);
const plain = sm.decrypt(cipher, masterKey);
const entropy16 = sm.generateRandomBuffer(); // 16 bytes
const mnemonic = sm.entropyToMnemonic(entropy16); // 12 words
const entropyRoundTrip = sm.mnemonicToEntropy(mnemonic); // back to 16 bytes
// Wipes internal passkey/salt/iteration state from memory
sm.dispose();
| Class | Description | Methods |
|---|---|---|
WdkSecretManager | High-level manager for secret generation, encryption, and decryption. | constructor, generateSalt, generateAndEncrypt, encrypt, decrypt, entropyToMnemonic, mnemonicToEntropy, generateRandomBuffer, dispose |
The main class for generating and managing encrypted secrets.
new WdkSecretManager(passKey, salt, kdfParams?)
Parameters:
passKey (string | Buffer | Uint8Array): User passkey (min 12 characters/bytes)salt (Buffer): 16-byte salt used for key derivationkdfParams (object, optional):
iterations (number, optional): PBKDF2 iterations (default: 100_000)generateSalt(): Buffer
| Method | Description | Returns |
|---|---|---|
generateAndEncrypt(entropyOpt?, masterKeyOpt?) | Generates 16-byte entropy, derives mnemonic + 64-byte seed, encrypts both. | { encryptedSeed: Buffer, encryptedEntropy: Buffer } |
encrypt(data, masterKeyOpt?) | Encrypts 16–64 byte payload with header and MAC. | Buffer (payload) |
decrypt(payload, masterKeyOpt?) | Decrypts a payload produced by this manager. | Buffer (plaintext) |
generateRandomBuffer() | Returns 16 random bytes. | Buffer |
entropyToMnemonic(entropy) | Converts 16-byte entropy to 12-word mnemonic. | string |
mnemonicToEntropy(mnemonic) | Converts 12-word mnemonic to 16-byte entropy. | Buffer |
dispose() | Zeroizes internal state; instance becomes unusable. | void |
Header [version(1), kdf_alg(1), iterations(u32le), reserved(u32le=0), salt(16), nonce(24)] followed by cipher = secretbox( [len(1) | data(16..64)], nonce, key).
generateAndEncrypt(entropyOpt?, masterKeyOpt?)Generates 16-byte entropy, converts it to a BIP-39 12-word mnemonic, derives the 64-byte BIP-39 seed, and encrypts both values.
Parameters:
entropyOpt (Buffer | null, optional): If provided, must be exactly 16 bytes. When not provided, secure random entropy is generated.masterKeyOpt (Buffer | null, optional): A 32-byte key. If provided, PBKDF2 derivation is skipped and this key is used for encryption.Returns: { encryptedSeed: Buffer, encryptedEntropy: Buffer }
Example:
const { encryptedSeed, encryptedEntropy } = await sm.generateAndEncrypt();
const seed = sm.decrypt(encryptedSeed); // 64 bytes
const entropy = sm.decrypt(encryptedEntropy); // 16 bytes
encrypt(data, masterKeyOpt?)Encrypts a 16–64 byte payload using a versioned header and crypto_secretbox. The plaintext is prefixed with a single-byte length before encryption.
Parameters:
data (Buffer): Plaintext data. Must be between 16 and 64 bytes inclusive.masterKeyOpt (Buffer | null, optional): 32-byte master key. If omitted, a key is derived via PBKDF2-SHA256 from the manager's passkey + salt.Returns: Buffer - Encrypted payload with header and MAC.
Throws: on invalid input length, missing/invalid passkey or salt, or other validation errors.
Example:
const data = Buffer.from("0123456789abcdef0123456789abcdef"); // 32 bytes
const payload = sm.encrypt(data);
decrypt(payload, masterKeyOpt?)Decrypts a payload produced by this manager, validates the header, and returns the original plaintext.
Parameters:
payload (Buffer): Encrypted payload produced by encrypt.masterKeyOpt (Buffer | null, optional): 32-byte master key. If omitted, a key is derived via PBKDF2-SHA256 using the header's salt and iteration count.Returns: Buffer - Decrypted plaintext.
Throws: when authentication fails, payload is malformed, length prefix is out of bounds, or inputs are invalid.
Example:
const plain = sm.decrypt(payload);
generateRandomBuffer()Generates 16 bytes of cryptographically secure random data using libsodium.
Returns: Buffer
Example:
const entropy16 = sm.generateRandomBuffer();
entropyToMnemonic(entropy)Converts 16-byte entropy into a 12-word BIP-39 mnemonic.
Parameters:
entropy (Buffer): Exactly 16 bytes.Returns: string - 12-word mnemonic.
Throws: on invalid type or length.
Example:
const mnemonic = sm.entropyToMnemonic(entropy16);
mnemonicToEntropy(mnemonic)Converts a 12-word mnemonic into its original 16-byte entropy buffer.
Parameters:
mnemonic (string): Non-empty 12-word BIP-39 mnemonic.Returns: Buffer - 16-byte entropy.
Throws: on invalid/empty string or non-12-word mnemonics.
Example:
const entropy = sm.mnemonicToEntropy(mnemonic);
dispose()Securely wipes internal state (passkey, salt, iterations) from memory. The instance should not be used after calling this.
Returns: void
Example:
sm.dispose();
sodium-native and Node crypto for PBKDF2bare build; PBKDF2 provided by bare-cryptocrypto_secretbox provides authenticated encryptiondispose() after use to wipe sensitive state# Install dependencies
npm install
# Build TypeScript definitions
npm run build:types
# Lint code
npm run lint
# Fix linting issues
npm run lint:fix
# Run bare runtime tests
npm run test:bare
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
For support, please open an issue on the repository.