Files
salvium-rs/generate_wordlists_rs.mjs
T
Matt Hess 733ecd2681 Migrate all JS tests to Rust: 9-crate workspace, 703 tests, 0 JS remaining
Add root Cargo workspace with 9 crates: salvium-crypto (extended),
  salvium-types, salvium-consensus, salvium-wallet, salvium-tx,
  salvium-rpc, salvium-miner (extended), salvium-cli, salvium-multisig.

  New modules: chain_state, block_weight, alt_chain, validation,
  offline signing, stake lifecycle, wallet sync/query/encryption/utxo,
  randomx utilities, and full multisig crate with CARROT support.

  Delete 188 JS test/helper/debug files; archive integration test
  scripts to test/legacy-js/ for live testnet use. Testnet integration
  tests (transfer, stake, burn, convert, sweep) remain as #[ignore]-
  gated Rust tests runnable with --ignored against a live daemon.
2026-02-17 23:09:35 +00:00

81 lines
3.0 KiB
JavaScript

import { readFileSync, writeFileSync } from 'fs';
const langs = [
{ file: "english", varName: "ENGLISH" },
{ file: "spanish", varName: "SPANISH" },
{ file: "french", varName: "FRENCH" },
{ file: "german", varName: "GERMAN" },
{ file: "italian", varName: "ITALIAN" },
{ file: "portuguese", varName: "PORTUGUESE" },
{ file: "dutch", varName: "DUTCH" },
{ file: "russian", varName: "RUSSIAN" },
{ file: "japanese", varName: "JAPANESE" },
{ file: "chinese_simplified", varName: "CHINESE_SIMPLIFIED" },
{ file: "esperanto", varName: "ESPERANTO" },
{ file: "lojban", varName: "LOJBAN" },
];
for (const lang of langs) {
const content = readFileSync("src/wordlists/" + lang.file + ".js", "utf8");
const nameMatch = content.match(/export const name = '([^']*)'/);
lang.displayName = nameMatch[1];
const engMatch = content.match(/export const englishName = '([^']*)'/);
lang.englishName = engMatch[1];
const prefixMatch = content.match(/export const prefixLength = (\d+)/);
lang.prefixLength = parseInt(prefixMatch[1]);
const wordsMatch = content.match(/export const words = \[([\s\S]*?)\]/);
const rawWords = wordsMatch[1];
const words = [];
const re = /"([^"]*)"/g;
let m;
while ((m = re.exec(rawWords)) !== null) {
words.push(m[1]);
}
lang.words = words;
if (words.length !== 1626) {
console.error(`ERROR: ${lang.file} has ${words.length} words, expected 1626`);
process.exit(1);
}
}
let out = "";
out += "//! Mnemonic word lists for 12 languages.\n";
out += "//! Each list has exactly 1626 words, matching the CryptoNote/Salvium mnemonic scheme.\n";
out += "\n";
out += "pub struct WordList {\n";
out += " pub name: &'static str,\n";
out += " pub english_name: &'static str,\n";
out += " pub prefix_length: usize,\n";
out += " pub words: &'static [&'static str; 1626],\n";
out += "}\n\n";
out += "pub static ALL_LANGUAGES: [&WordList; 12] = [\n";
for (const lang of langs) {
out += " &" + lang.varName + ",\n";
}
out += "];\n\n";
for (const lang of langs) {
out += "pub static " + lang.varName + ": WordList = WordList {\n";
out += " name: \"" + lang.displayName + "\",\n";
out += " english_name: \"" + lang.englishName + "\",\n";
out += " prefix_length: " + lang.prefixLength + ",\n";
out += " words: &" + lang.varName + "_WORDS,\n";
out += "};\n\n";
out += "static " + lang.varName + "_WORDS: [&str; 1626] = [\n";
for (let i = 0; i < lang.words.length; i += 8) {
const chunk = lang.words.slice(i, i + 8);
// Escape backslashes and double quotes in words
const escaped = chunk.map(w => '"' + w.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"');
out += " " + escaped.join(", ") + ",\n";
}
out += "];\n\n";
}
writeFileSync("crates/salvium-types/src/wordlists.rs", out);
console.log("Done! Wrote crates/salvium-types/src/wordlists.rs");
for (const lang of langs) {
console.log(` ${lang.file}: ${lang.words.length} words, prefix=${lang.prefixLength}, name="${lang.displayName}"`);
}