All checks were successful
check / check (push) Successful in 22s
Add a 'Show private key' button on the address detail view that opens a dedicated password-prompt screen with a clear warning about key sensitivity. After correct password entry, the derived private key is displayed in a read-only well with a copy button. - Add getPrivateKeyForAddress() to wallet.js - Add showPrivateKey view with password verification - Add clipboard policy section to README explaining why we never auto-clear the clipboard - Register new view in helpers.js VIEWS array and wire up in index.js Closes #19
69 lines
1.8 KiB
JavaScript
69 lines
1.8 KiB
JavaScript
// Wallet operations: mnemonic generation, HD derivation, signing.
|
|
// All crypto delegated to ethers.js.
|
|
|
|
const { Mnemonic, HDNodeWallet, Wallet } = require("ethers");
|
|
const { DEBUG, DEBUG_MNEMONIC, BIP44_ETH_PATH } = require("./constants");
|
|
|
|
function generateMnemonic() {
|
|
if (DEBUG) return DEBUG_MNEMONIC;
|
|
const m = Mnemonic.fromEntropy(
|
|
globalThis.crypto.getRandomValues(new Uint8Array(16)),
|
|
);
|
|
return m.phrase;
|
|
}
|
|
|
|
function deriveAddressFromXpub(xpub, index) {
|
|
const node = HDNodeWallet.fromExtendedKey(xpub);
|
|
return node.deriveChild(index).address;
|
|
}
|
|
|
|
function hdWalletFromMnemonic(mnemonic) {
|
|
const node = HDNodeWallet.fromPhrase(mnemonic, "", BIP44_ETH_PATH);
|
|
const xpub = node.neuter().extendedKey;
|
|
const firstAddress = node.deriveChild(0).address;
|
|
return { xpub, firstAddress };
|
|
}
|
|
|
|
function addressFromPrivateKey(key) {
|
|
const w = new Wallet(key);
|
|
return w.address;
|
|
}
|
|
|
|
function getSignerForAddress(walletData, addrIndex, decryptedSecret) {
|
|
if (walletData.type === "hd") {
|
|
const node = HDNodeWallet.fromPhrase(
|
|
decryptedSecret,
|
|
"",
|
|
BIP44_ETH_PATH,
|
|
);
|
|
return node.deriveChild(addrIndex);
|
|
}
|
|
return new Wallet(decryptedSecret);
|
|
}
|
|
|
|
function getPrivateKeyForAddress(walletData, addrIndex, decryptedSecret) {
|
|
if (walletData.type === "hd") {
|
|
const node = HDNodeWallet.fromPhrase(
|
|
decryptedSecret,
|
|
"",
|
|
BIP44_ETH_PATH,
|
|
);
|
|
return node.deriveChild(addrIndex).privateKey;
|
|
}
|
|
return decryptedSecret;
|
|
}
|
|
|
|
function isValidMnemonic(mnemonic) {
|
|
return Mnemonic.isValidMnemonic(mnemonic);
|
|
}
|
|
|
|
module.exports = {
|
|
generateMnemonic,
|
|
deriveAddressFromXpub,
|
|
hdWalletFromMnemonic,
|
|
addressFromPrivateKey,
|
|
getSignerForAddress,
|
|
getPrivateKeyForAddress,
|
|
isValidMnemonic,
|
|
};
|