
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
@tetherto/wdk-secret-manager
Advanced tools
Note: 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.
FAQs
A package to encrypt mnemonic and seed buffer
We found that @tetherto/wdk-secret-manager demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.