Guides

Vault and procedures

Vault records, locations, and the SLIP10 / BIP39 / Ed25519 procedures that keep private keys in Rust.

A vault is a named group of binary records inside a client. Records are written from JavaScript with insert, or produced by the procedures, which keep key material on the Rust side.

import { KeyringSession, Location } from "tauri-plugin-keyring-store-api";

const session = await KeyringSession.load("/vault-a", "");
const vault = (await session.createClient("c1")).getVault("SECRETS");

await vault.insert("blob.bin", [0xde, 0xad]);
await vault.remove(Location.generic("SECRETS", "blob.bin"));

await session.unload();

There is no get for vault records: like in Stronghold, a vault secret can be written and used by a procedure, but not read back by the webview. Use the store for data the frontend needs to read.

Locations

A Location names one record in one vault:

const named = Location.generic("WALLET", "seed.bin");
const numbered = Location.counter("WALLET", 0);

A counter is stored under the text of its number: Location.counter("WALLET", 7) and Location.generic("WALLET", "7") are the same record. Do not mix counters and numeric record names in one vault.

vault.remove(location) deletes the record in the vault named by the location, not the vault the KeyringVault was opened for. Removing a missing record is not an error.

Procedures

Need the crypto Cargo feature (default). Each runs in Rust, reads and writes vault records, and returns only public data.

MethodWrites to outputResolves to
generateSLIP10Seed(output, sizeBytes?)SLIP10 master key from sizeBytes random bytes (16..=64, default 32)empty array
deriveSLIP10(chain, "Seed" | "Key", source, output)child key derived along chain32-byte chain code
recoverBIP39(mnemonic, output, passphrase?)master key of an existing English mnemonicempty array
generateBIP39(output, passphrase?)master key of a new 24-word mnemonicthe mnemonic as UTF-8 bytes
getEd25519PublicKey(privateKey)—32-byte public key
signEd25519(privateKey, msg)—64-byte signature of the UTF-8 of msg

Keys are stored as SLIP10 extended keys (65 bytes). getEd25519PublicKey and signEd25519 also accept a record that holds a raw 32-byte Ed25519 secret key.

Derivation

Every segment of chain is hardened (Ed25519 SLIP10 supports only hardened derivation). With "Seed" the source record holds seed bytes; with "Key" it holds an extended key written by another procedure.

const master = Location.generic("PRIMARY", "master");
await vault.generateSLIP10Seed(master);

const account0 = Location.generic("PRIMARY", "m/44'/0'/0'");
await vault.deriveSLIP10([44, 0, 0], "Key", master, account0);

const publicKey = await vault.getEd25519PublicKey(account0);
const signature = await vault.signEd25519(account0, "message");

Mnemonics

generateBIP39 returns the 24 words once so the user can write them down. Show them, do not store them in the webview or in logs. To restore, pass the words to recoverBIP39 with the same passphrase.

const words = new TextDecoder().decode(await vault.generateBIP39(master, "optional passphrase"));
// later, on another device:
await vault.recoverBIP39(words, master, "optional passphrase");

An invalid mnemonic fails with crypto procedure error: BIP39 recover: invalid mnemonic; the error never names the wrong word.

Not supported

PublicKey with type X25519 rejects with X25519 public key extraction is not implemented.