Mnemonic Backup

sealMnemonic() and openMnemonic() — a portable, password-protected backup of one account's BIP-39 seed phrase, encrypted under the workspace password and bound to its account.

sealMnemonic() and openMnemonic() turn one account's BIP-39 seed phrase into a portable, encrypted backup and read it back. The backup is a RecoveryEnvelope — a small plain-data record you can serialize, store anywhere, and move between machines. It is sealed under the workspace password, and it is bound to the account it came from, so a blob cannot be opened under a different account.

import.ts
import { sealMnemonic, openMnemonic } from "wative-core";
import type { RecoveryEnvelope } from "wative-core";

sealMnemonic

sealMnemonic(
  accountSlug: Slug,
  mnemonic: string,
  workspacePassword: string,
  opts?: { kdf?: Argon2Backend },
): RecoveryEnvelope
ParameterTypeNotes
accountSlugSlugThe slug of the account this phrase belongs to. Bound into the envelope, so the backup can only be opened for this account.
mnemonicstringA valid BIP-39 English mnemonic. Validated and normalized before sealing; a non-BIP-39 input throws INVALID_MNEMONIC.
workspacePasswordstringThe password the envelope is encrypted under.
opts.kdfArgon2BackendOptional Argon2 backend. Omit for the pure-JS default. See Key Derivation.

Returns a RecoveryEnvelope. The phrase is normalized (Unicode NFKD, lowercased) before sealing, so the same phrase produces a byte-identical envelope across operating systems.

openMnemonic

openMnemonic(
  envelope: RecoveryEnvelope,
  workspacePassword: string,
  opts?: { expectedSlug?: Slug; kdf?: Argon2Backend },
): string
ParameterTypeNotes
envelopeRecoveryEnvelopeThe sealed backup.
workspacePasswordstringThe password the envelope was sealed under.
opts.expectedSlugSlugOptional. The account you mean to restore. When given, the envelope is refused unless it belongs to that account. Pass it whenever the expected account is known.
opts.kdfArgon2BackendOptional Argon2 backend; must match the one used to seal. Omit for the pure-JS default.

Returns the decrypted BIP-39 phrase as a string.

RecoveryEnvelope

interface RecoveryEnvelope {
  readonly accountSlug: Slug;
  readonly sealedMnemonic: Uint8Array; // workspace-password-sealed
  readonly createdAt: number;          // epoch milliseconds
}

The record is plain data — safe to JSON-serialize (encode sealedMnemonic as you would any Uint8Array) and store independently of the workspace.

Round-trip

backup-restore.ts
import { sealMnemonic, openMnemonic } from "wative-core";

// Back up one account's phrase under the workspace password.
const envelope = sealMnemonic(acc.slug, acc.dumpMnemonic(), "wsp-pwd");

// …later, on any machine, restore it — naming the account you expect.
const phrase = openMnemonic(envelope, "wsp-pwd", { expectedSlug: acc.slug });

Account binding

The envelope is cryptographically bound to its accountSlug, so a backup relabelled to another account's name fails to open. Passing expectedSlug adds a second check that refuses an envelope whose whole record was swapped for another account's — restore treasury and you cannot be handed petty-cash instead. Planting a chosen phrase still requires the workspace password.

Failure modes

CodeWhen
INVALID_MNEMONICsealMnemonic given a phrase that is not valid BIP-39 English.
PARAMETER_ERRORopenMnemonic given a malformed envelope, an unknown option, or an expectedSlug that does not match the envelope.
DECRYPT_FAILEDopenMnemonic given the wrong workspace password, or a tampered envelope.

Last updated on