/// HD address derivation using bitcore-lib family. /// Derives child addresses at m/0/{index} (external receive chain). // @ts-ignore import bitcore from "bitcore-lib"; import bs58check from "bs58check"; // @ts-ignore import bitcoreCash from "bitcore-lib-cash"; // @ts-ignore import bitcoreLtc from "bitcore-lib-ltc"; // @ts-ignore import bitcoreDoge from "bitcore-lib-doge"; // @ts-ignore import dashcore from "@dashevo/dashcore-lib"; function getXpub(coin: string): string { const key = `XPUB_${coin.toUpperCase()}`; const val = process.env[key]; if (!val) throw new Error(`Missing env var: ${key}`); return val; } export function derive(coin: string, index: number): string { const xpub = getXpub(coin === "xec" ? "xec" : coin); if (coin === "btc") { const hd = new bitcore.HDPublicKey(xpub); return hd.deriveChild(0).deriveChild(index).publicKey.toAddress().toString(); } if (coin === "bch") { const hd = new bitcoreCash.HDPublicKey(xpub); return hd.deriveChild(0).deriveChild(index).publicKey.toAddress().toCashAddress(); } if (coin === "xec") { const hd = new bitcoreCash.HDPublicKey(xpub); const addr = hd.deriveChild(0).deriveChild(index).publicKey.toAddress().toCashAddress(); return addr.replace(/^bitcoincash:/, "ecash:"); } if (coin === "ltc") { // Remap zpub/Ltub/Mtub to standard xpub version bytes for bitcore-lib-ltc const decoded = Buffer.from(bs58check.decode(xpub)); decoded[0] = 0x04; decoded[1] = 0x88; decoded[2] = 0xb2; decoded[3] = 0x1e; const normalized = bs58check.encode(decoded); const hd = new bitcoreLtc.HDPublicKey(normalized); const pubkey = hd.deriveChild(0).deriveChild(index).publicKey; return new bitcoreLtc.Address(pubkey, bitcoreLtc.Networks.mainnet, bitcoreLtc.Address.PayToWitnessPublicKeyHash).toString(); } if (coin === "doge") { const hd = new bitcoreDoge.HDPublicKey(xpub); return hd.deriveChild(0).deriveChild(index).publicKey.toAddress().toString(); } if (coin === "dash") { const hd = new dashcore.HDPublicKey(xpub); return hd.deriveChild(0).deriveChild(index).publicKey.toAddress().toString(); } throw new Error(`Unsupported coin: ${coin}`); }