From 91c24b20f715a0d91095a9e87bd89b1832c4c0fe Mon Sep 17 00:00:00 2001 From: M1 Date: Wed, 18 Mar 2026 23:18:49 +0400 Subject: [PATCH] fix: convert zpub to Ltub before LTC HD derivation --- apps/pay/package.json | 9 +++++---- apps/pay/src/address.ts | 12 +++++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/apps/pay/package.json b/apps/pay/package.json index c0e8a02..e4cde23 100644 --- a/apps/pay/package.json +++ b/apps/pay/package.json @@ -6,14 +6,15 @@ "start": "bun run src/index.ts" }, "dependencies": { - "@sinclair/typebox": "^0.34.0", - "elysia": "^1.4.27", - "postgres": "^3.4.8", "@dashevo/dashcore-lib": "^0.25.0", + "@sinclair/typebox": "^0.34.0", "bitcore-lib": "^10.10.7", "bitcore-lib-cash": "^10.10.5", "bitcore-lib-doge": "^10.9.0", - "bitcore-lib-ltc": "^10.10.5" + "bitcore-lib-ltc": "^10.10.5", + "bs58check": "^4.0.0", + "elysia": "^1.4.27", + "postgres": "^3.4.8" }, "devDependencies": { "@types/bun": "^1.3.10", diff --git a/apps/pay/src/address.ts b/apps/pay/src/address.ts index 7e0af7c..7ba2bef 100644 --- a/apps/pay/src/address.ts +++ b/apps/pay/src/address.ts @@ -82,7 +82,17 @@ export function deriveAddressSafe(coin: string, index: number): string { return addr.replace(/^bitcoincash:/, "ecash:"); } if (coin === "ltc") { - const hd = new bitcoreLtc.HDPublicKey(xpub); + // zpub uses BIP84 version bytes — convert to Ltub so bitcore-lib-ltc can parse it + let key = xpub; + if (xpub.startsWith("zpub") || xpub.startsWith("Zpub")) { + // Decode base58check, swap version bytes to Ltub (0x019da462), re-encode + const bs58check = await import("bs58check"); + const decoded = bs58check.default.decode(xpub); + // Replace first 4 bytes with Ltub version: 0x019da462 + decoded[0] = 0x01; decoded[1] = 0x9d; decoded[2] = 0xa4; decoded[3] = 0x62; + key = bs58check.default.encode(decoded); + } + const hd = new bitcoreLtc.HDPublicKey(key); return hd.deriveChild(0).deriveChild(index).publicKey.toAddress().toString(); } if (coin === "doge") {