Skip to content

Commit c908b56

Browse files
OttoAllmendingerllm-git
andcommitted
feat(abstract-utxo): use correct script hash for testnet LTC addresses
Fix the cross-chain recovery address conversion to properly handle testnet Litecoin addresses by using the correct script hash value. Previously, the code was using Bitcoin mainnet's script hash for both mainnet and testnet Litecoin addresses, which caused incorrect conversions for testnet. Also added a check to skip processing for non-Litecoin coins and expanded tests to verify both mainnet and testnet address conversions. Issue: BTC-2891 Co-authored-by: llm-git <llm-git@ttll.de>
1 parent 0006da4 commit c908b56

2 files changed

Lines changed: 19 additions & 4 deletions

File tree

modules/abstract-utxo/src/recovery/crossChainRecovery.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ export async function isWalletAddress(wallet: IWallet | WalletV1, address: strin
123123
* @returns The address in legacy 3... format, or the original address if it's not a P2SH address
124124
*/
125125
export function convertLtcAddressToLegacyFormat(address: string, coinName: UtxoCoinName): string {
126+
if (coinName !== 'ltc' && coinName !== 'tltc') {
127+
return address;
128+
}
129+
126130
const network = getNetworkFromCoinName(coinName);
127131
try {
128132
// Try to decode as bech32 - these don't need conversion
@@ -137,7 +141,8 @@ export function convertLtcAddressToLegacyFormat(address: string, coinName: UtxoC
137141
// Only convert P2SH addresses (scriptHash), not P2PKH (pubKeyHash)
138142
if (decoded.version === network.scriptHash) {
139143
// Convert to legacy format using Bitcoin's scriptHash (0x05)
140-
const legacyScriptHash = utxolib.networks.bitcoin.scriptHash;
144+
const legacyScriptHash =
145+
coinName === 'ltc' ? utxolib.networks.bitcoin.scriptHash : utxolib.networks.testnet.scriptHash;
141146
return utxolib.address.toBase58Check(decoded.hash, legacyScriptHash, network);
142147
}
143148
// P2PKH or other - return unchanged

modules/abstract-utxo/test/unit/recovery/crossChainRecovery.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import nock = require('nock');
55
import * as utxolib from '@bitgo/utxo-lib';
66
import { Triple } from '@bitgo/sdk-core';
77
import { getSeed } from '@bitgo/sdk-test';
8+
import { address as wasmAddress } from '@bitgo/wasm-utxo';
89
import * as sinon from 'sinon';
910

1011
import {
@@ -318,15 +319,24 @@ describe(`Cross-Chain Recovery getWallet`, async function () {
318319
});
319320

320321
describe('convertLtcAddressToLegacyFormat', function () {
322+
const scriptPubKey = Buffer.from('a9149f0bf51fab4d33ab21977e1b89f776f64161ef4287', 'hex');
321323
it('should convert M... P2SH address to 3... legacy format', function () {
322324
// These two addresses represent the same underlying script hash:
323325
// - MNQ7zkgMsaV67rsjA3JuP59RC5wxRXpwgE is the LTC format (scriptHash 0x32)
324326
// - 3GBygsGPvTdfKMbq4AKZZRu1sPMWPEsBfd is the BTC format (scriptHash 0x05)
325-
const ltcAddress = 'MNQ7zkgMsaV67rsjA3JuP59RC5wxRXpwgE';
326-
const expectedLegacyAddress = '3GBygsGPvTdfKMbq4AKZZRu1sPMWPEsBfd';
327+
// const ltcAddress = 'MNQ7zkgMsaV67rsjA3JuP59RC5wxRXpwgE';
328+
const ltcAddress = wasmAddress.fromOutputScriptWithCoin(scriptPubKey, 'ltc');
329+
const tltcAddress = wasmAddress.fromOutputScriptWithCoin(scriptPubKey, 'tltc');
330+
assert.strictEqual(ltcAddress, 'MNQ7zkgMsaV67rsjA3JuP59RC5wxRXpwgE');
331+
assert.strictEqual(tltcAddress, 'Qb6wsd4fZ2C6fKzRMPyTG5KiE81W6QCxhU');
327332

328333
const legacyAddress = convertLtcAddressToLegacyFormat(ltcAddress, 'ltc');
329-
assert.strictEqual(legacyAddress, expectedLegacyAddress);
334+
const expectedLtcLegacyAddress = '3GBygsGPvTdfKMbq4AKZZRu1sPMWPEsBfd';
335+
assert.strictEqual(legacyAddress, expectedLtcLegacyAddress);
336+
337+
const expectedTltcLegacyAddress = '2N7kBkcCRXv91X9ENjHwSBNtH5jZg8yye6r';
338+
const tltcLegacyAddress = convertLtcAddressToLegacyFormat(tltcAddress, 'tltc');
339+
assert.strictEqual(tltcLegacyAddress, expectedTltcLegacyAddress);
330340
});
331341

332342
it('should convert MD68PsdheKxcYsrVLyZRXgoSDLnB1MdVtE to legacy format', function () {

0 commit comments

Comments
 (0)