diff --git a/modules/abstract-utxo/src/address/fixedScript.ts b/modules/abstract-utxo/src/address/fixedScript.ts index 7aa8d5aaac..03f23e90bf 100644 --- a/modules/abstract-utxo/src/address/fixedScript.ts +++ b/modules/abstract-utxo/src/address/fixedScript.ts @@ -13,11 +13,12 @@ import { Triple, } from '@bitgo/sdk-core'; import { bitgo } from '@bitgo/utxo-lib'; -import * as wasmUtxo from '@bitgo/wasm-utxo'; +import { fixedScriptWallet } from '@bitgo/wasm-utxo'; import { getNetworkFromCoinName, UtxoCoinName } from '../names'; -type ScriptType2Of3 = bitgo.outputScripts.ScriptType2Of3; +type ScriptType2Of3 = fixedScriptWallet.OutputScriptType; +type ChainCode = fixedScriptWallet.ChainCode; export interface FixedScriptAddressCoinSpecific { outputScript?: string; @@ -39,14 +40,13 @@ interface GenerateFixedScriptAddressOptions extends GenerateAddressOptions { } function supportsAddressType(coinName: UtxoCoinName, addressType: ScriptType2Of3): boolean { - const network = getNetworkFromCoinName(coinName); - return bitgo.outputScripts.isSupportedScriptType(network, addressType); + return fixedScriptWallet.supportsScriptType(coinName, addressType); } export function generateAddressWithChainAndIndex( coinName: UtxoCoinName, - keychains: bitgo.RootWalletKeys | Triple, - chain: bitgo.ChainCode, + keychains: fixedScriptWallet.RootWalletKeys | bitgo.RootWalletKeys | Triple, + chain: ChainCode, index: number, format: CreateAddressFormat | undefined ): string { @@ -54,7 +54,7 @@ export function generateAddressWithChainAndIndex( // 'base58' -> 'default', 'cashaddr' -> 'cashaddr' const wasmFormat = format === 'base58' ? 'default' : format; const network = getNetworkFromCoinName(coinName); - return wasmUtxo.fixedScriptWallet.address(keychains, chain, index, network, wasmFormat); + return fixedScriptWallet.address(keychains, chain, index, network, wasmFormat); } /** @@ -77,14 +77,14 @@ export function generateAddress(coinName: UtxoCoinName, params: GenerateFixedScr const { keychains, chain, segwit = false, bech32 = false } = params as GenerateFixedScriptAddressOptions; - let derivationChain = bitgo.getExternalChainCode('p2sh'); - if (_.isNumber(chain) && _.isInteger(chain) && bitgo.isChainCode(chain)) { + let derivationChain: ChainCode = fixedScriptWallet.ChainCode.value('p2sh', 'external'); + if (_.isNumber(chain) && _.isInteger(chain) && fixedScriptWallet.ChainCode.is(chain)) { derivationChain = chain; } function convertFlagsToAddressType(): ScriptType2Of3 { - if (bitgo.isChainCode(chain)) { - return bitgo.scriptTypeForChain(chain); + if (fixedScriptWallet.ChainCode.is(chain)) { + return fixedScriptWallet.ChainCode.scriptType(chain); } if (_.isBoolean(segwit) && segwit) { return 'p2shP2wsh'; @@ -97,7 +97,7 @@ export function generateAddress(coinName: UtxoCoinName, params: GenerateFixedScr const addressType = params.addressType || convertFlagsToAddressType(); - if (addressType !== bitgo.scriptTypeForChain(derivationChain)) { + if (addressType !== fixedScriptWallet.ChainCode.scriptType(derivationChain)) { throw new AddressTypeChainMismatchError(addressType, derivationChain); } diff --git a/modules/abstract-utxo/test/unit/coins.ts b/modules/abstract-utxo/test/unit/coins.ts index 2e52f88134..0040eee4d8 100644 --- a/modules/abstract-utxo/test/unit/coins.ts +++ b/modules/abstract-utxo/test/unit/coins.ts @@ -2,14 +2,19 @@ import * as assert from 'assert'; import * as utxolib from '@bitgo/utxo-lib'; -import { getMainnetCoinName, utxoCoinsMainnet, utxoCoinsTestnet } from '../../src/names'; +import { getMainnetCoinName, getNetworkFromCoinName, utxoCoinsMainnet, utxoCoinsTestnet } from '../../src/names'; import { getUtxoCoinForNetwork, utxoCoins } from './util'; describe('utxoCoins', function () { it('has expected chain/network values for items', function () { assert.deepStrictEqual( - utxoCoins.map((c) => [c.getChain(), c.getFamily(), c.getFullName(), utxolib.getNetworkName(c.network)]), + utxoCoins.map((c) => [ + c.getChain(), + c.getFamily(), + c.getFullName(), + utxolib.getNetworkName(getNetworkFromCoinName(c.name)), + ]), [ ['btc', 'btc', 'Bitcoin', 'bitcoin'], ['tbtc', 'btc', 'Testnet Bitcoin', 'testnet'], diff --git a/modules/abstract-utxo/test/unit/descriptorAddress.ts b/modules/abstract-utxo/test/unit/descriptorAddress.ts index 6f53adb389..feee8c8346 100644 --- a/modules/abstract-utxo/test/unit/descriptorAddress.ts +++ b/modules/abstract-utxo/test/unit/descriptorAddress.ts @@ -1,17 +1,16 @@ import * as assert from 'node:assert'; import * as utxolib from '@bitgo/utxo-lib'; +import { address as wasmAddress, CoinName } from '@bitgo/wasm-utxo'; import { IWallet, WalletCoinSpecific } from '@bitgo/sdk-core'; import { descriptor as utxod } from '../../src'; import { getUtxoCoin } from './util'; -export function getDescriptorAddress(d: string, index: number, network: utxolib.Network): string { - const derivedScript = Buffer.from( - utxod.Descriptor.fromString(d, 'derivable').atDerivationIndex(index).scriptPubkey() - ); - return utxolib.address.fromOutputScript(derivedScript, network); +export function getDescriptorAddress(d: string, index: number, coinName: CoinName): string { + const derivedScript = utxod.Descriptor.fromString(d, 'derivable').atDerivationIndex(index).scriptPubkey(); + return wasmAddress.fromOutputScriptWithCoin(derivedScript, coinName); } describe('descriptor wallets', function () { @@ -40,9 +39,9 @@ describe('descriptor wallets', function () { const descFoo = getNamedDescriptor2Of2('foo', xpubs[0], xpubs[1]); const descBar = getNamedDescriptor2Of2('bar', xpubs[1], xpubs[0]); - const addressFoo0 = getDescriptorAddress(descFoo.value, 0, coin.network); - const addressFoo1 = getDescriptorAddress(descFoo.value, 1, coin.network); - const addressBar0 = getDescriptorAddress(descBar.value, 0, coin.network); + const addressFoo0 = getDescriptorAddress(descFoo.value, 0, coin.name); + const addressFoo1 = getDescriptorAddress(descFoo.value, 1, coin.name); + const addressBar0 = getDescriptorAddress(descBar.value, 0, coin.name); it('has expected values', function () { assert.deepStrictEqual( diff --git a/modules/abstract-utxo/test/unit/prebuildAndSign.ts b/modules/abstract-utxo/test/unit/prebuildAndSign.ts index aacbe59961..e41f8f0005 100644 --- a/modules/abstract-utxo/test/unit/prebuildAndSign.ts +++ b/modules/abstract-utxo/test/unit/prebuildAndSign.ts @@ -6,6 +6,7 @@ import { common, HalfSignedUtxoTransaction, Wallet } from '@bitgo/sdk-core'; import { getSeed } from '@bitgo/sdk-test'; import { AbstractUtxoCoin, getReplayProtectionAddresses } from '../../src'; +import { getMainnetCoinName } from '../../src/names'; import { defaultBitGo, encryptKeychain, getDefaultWalletKeys, getUtxoWallet, keychainsBase58, utxoCoins } from './util'; @@ -295,7 +296,7 @@ function run(coin: AbstractUtxoCoin, inputScripts: ScriptType[], txFormat: TxFor } utxoCoins - .filter((coin) => utxolib.getMainnet(coin.network) !== utxolib.networks.bitcoinsv) + .filter((coin) => getMainnetCoinName(coin.name) !== 'bsv') .forEach((coin) => { scriptTypes // Don't iterate over p2shP2pk - in no scenario would a wallet spend two p2shP2pk inputs as these diff --git a/modules/abstract-utxo/test/unit/recovery/backupKeyRecovery.ts b/modules/abstract-utxo/test/unit/recovery/backupKeyRecovery.ts index 7bdabf4069..6043a5faf8 100644 --- a/modules/abstract-utxo/test/unit/recovery/backupKeyRecovery.ts +++ b/modules/abstract-utxo/test/unit/recovery/backupKeyRecovery.ts @@ -8,7 +8,7 @@ import { BIP32Interface } from '@bitgo/utxo-lib'; import * as utxolib from '@bitgo/utxo-lib'; import { Config, krsProviders, Triple } from '@bitgo/sdk-core'; import { Dimensions } from '@bitgo/unspents'; -import { fixedScriptWallet } from '@bitgo/wasm-utxo'; +import { address as wasmAddress, fixedScriptWallet } from '@bitgo/wasm-utxo'; import { AbstractUtxoCoin, @@ -17,6 +17,7 @@ import { CoingeckoApi, FormattedOfflineVaultTxInfo, } from '../../../src'; +import { getCoinName } from '../../../src/names'; import { defaultBitGo, encryptKeychain, @@ -319,7 +320,9 @@ function run( it((params.hasKrsOutput ? 'has' : 'has no') + ' key recovery service output', function () { const outs = recoveryTx instanceof utxolib.bitgo.UtxoPsbt ? recoveryTx.getUnsignedTx().outs : recoveryTx.outs; outs.length.should.eql(1); - const outputAddresses = outs.map((o) => utxolib.address.fromOutputScript(o.script, recoveryTx.network)); + const outputAddresses = outs.map((o) => + wasmAddress.fromOutputScriptWithCoin(o.script, getCoinName(recoveryTx.network)) + ); outputAddresses .includes(keyRecoveryServiceAddress) .should.eql(!!params.hasKrsOutput && params.krsProvider === 'keyternal'); diff --git a/modules/abstract-utxo/test/unit/recovery/crossChainRecovery.ts b/modules/abstract-utxo/test/unit/recovery/crossChainRecovery.ts index f44ec6d461..c778307020 100644 --- a/modules/abstract-utxo/test/unit/recovery/crossChainRecovery.ts +++ b/modules/abstract-utxo/test/unit/recovery/crossChainRecovery.ts @@ -16,6 +16,7 @@ import { generateAddress, convertLtcAddressToLegacyFormat, } from '../../../src'; +import { isMainnetCoin, isTestnetCoin } from '../../../src/names'; import { getFixture, keychainsBase58, @@ -265,8 +266,8 @@ utxoCoins.forEach((coin) => { (otherCoin) => coin !== otherCoin && isSupportedCrossChainRecovery(coin, otherCoin) && - ((utxolib.isMainnet(coin.network) && utxolib.isMainnet(otherCoin.network)) || - (utxolib.isTestnet(coin.network) && utxolib.isTestnet(otherCoin.network))) + ((isMainnetCoin(coin.name) && isMainnetCoin(otherCoin.name)) || + (isTestnetCoin(coin.name) && isTestnetCoin(otherCoin.name))) ) .forEach((otherCoin) => { if (coin.amountType === 'bigint') { diff --git a/modules/abstract-utxo/test/unit/recovery/mock.ts b/modules/abstract-utxo/test/unit/recovery/mock.ts index 3922ed9e26..96344177c0 100644 --- a/modules/abstract-utxo/test/unit/recovery/mock.ts +++ b/modules/abstract-utxo/test/unit/recovery/mock.ts @@ -1,6 +1,7 @@ import { bitgo } from '@bitgo/utxo-lib'; import { AddressInfo, TransactionIO } from '@bitgo/blockapis'; import * as utxolib from '@bitgo/utxo-lib'; +import { address as wasmAddress, AddressFormat } from '@bitgo/wasm-utxo'; import { AbstractUtxoCoin, RecoveryProvider } from '../../../src'; import { Bch } from '../../../src/impl/bch'; @@ -51,7 +52,7 @@ export class MockRecoveryProvider implements RecoveryProvider { } export class MockCrossChainRecoveryProvider implements RecoveryProvider { private addressVersion: 'cashaddr' | 'base58'; - private addressFormat: utxolib.addressFormat.AddressFormat; + private addressFormat: AddressFormat; constructor( public coin: AbstractUtxoCoin, public unspents: Unspent[], @@ -65,7 +66,7 @@ export class MockCrossChainRecoveryProvider imp async getUnspentsForAddresses(addresses: string[]): Promise { return this.tx.outs.map((o, vout: number) => { - let address = utxolib.addressFormat.fromOutputScriptWithFormat(o.script, this.addressFormat, this.coin.network); + let address = wasmAddress.fromOutputScriptWithCoin(o.script, this.coin.name, this.addressFormat); if (address.includes(':')) { [, address] = address.split(':'); } @@ -91,7 +92,7 @@ export class MockCrossChainRecoveryProvider imp }; }), outputs: this.tx.outs.map((o) => { - let address = utxolib.addressFormat.fromOutputScriptWithFormat(o.script, this.addressFormat, this.coin.network); + let address = wasmAddress.fromOutputScriptWithCoin(o.script, this.coin.name, this.addressFormat); if (address.includes(':')) { [, address] = address.split(':'); } diff --git a/modules/abstract-utxo/test/unit/transaction.ts b/modules/abstract-utxo/test/unit/transaction.ts index 20536661fc..30b0ac3e74 100644 --- a/modules/abstract-utxo/test/unit/transaction.ts +++ b/modules/abstract-utxo/test/unit/transaction.ts @@ -5,6 +5,7 @@ import * as _ from 'lodash'; import * as utxolib from '@bitgo/utxo-lib'; import nock = require('nock'); import { BIP32Interface, bitgo, testutil } from '@bitgo/utxo-lib'; +import { address as wasmAddress } from '@bitgo/wasm-utxo'; import { common, FullySignedTransaction, @@ -507,7 +508,7 @@ function run( : getUnspents(); const prevOutputs = unspents.map( (u): utxolib.TxOutput => ({ - script: utxolib.address.toOutputScript(u.address, coin.network), + script: Buffer.from(wasmAddress.toOutputScriptWithCoin(u.address, coin.name)), value: u.value, }) ); diff --git a/modules/abstract-utxo/test/unit/transaction/fixedScript/parsePsbt.ts b/modules/abstract-utxo/test/unit/transaction/fixedScript/parsePsbt.ts index 818e0471e7..9e527c2e8e 100644 --- a/modules/abstract-utxo/test/unit/transaction/fixedScript/parsePsbt.ts +++ b/modules/abstract-utxo/test/unit/transaction/fixedScript/parsePsbt.ts @@ -3,7 +3,7 @@ import assert from 'node:assert/strict'; import * as sinon from 'sinon'; import * as utxolib from '@bitgo/utxo-lib'; import { Wallet, VerificationOptions, ITransactionRecipient, Triple } from '@bitgo/sdk-core'; -import { fixedScriptWallet } from '@bitgo/wasm-utxo'; +import { address as wasmAddress, fixedScriptWallet } from '@bitgo/wasm-utxo'; import { parseTransaction } from '../../../../src/transaction/fixedScript/parseTransaction'; import { ParsedTransaction } from '../../../../src/transaction/types'; @@ -63,7 +63,7 @@ function getChangeInfoFromPsbt(psbt: utxolib.bitgo.UtxoPsbt): ChangeAddressInfo[ const path = derivations[0].path; const { chain, index } = utxolib.bitgo.getChainAndIndexFromPath(path); return { - address: utxolib.address.fromOutputScript(psbt.txOutputs[i].script, psbt.network), + address: wasmAddress.fromOutputScriptWithCoin(psbt.txOutputs[i].script, getCoinName(psbt.network)), chain, index, }; diff --git a/modules/abstract-utxo/test/unit/txFormat.ts b/modules/abstract-utxo/test/unit/txFormat.ts index f0e79fdc65..57bbe60459 100644 --- a/modules/abstract-utxo/test/unit/txFormat.ts +++ b/modules/abstract-utxo/test/unit/txFormat.ts @@ -1,9 +1,9 @@ import * as assert from 'assert'; -import * as utxolib from '@bitgo/utxo-lib'; import { Wallet } from '@bitgo/sdk-core'; import { AbstractUtxoCoin, ErrorDeprecatedTxFormat, TxFormat } from '../../src'; +import { getMainnetCoinName, isMainnetCoin, isTestnetCoin } from '../../src/names'; import { utxoCoins, defaultBitGo } from './util'; @@ -106,14 +106,14 @@ describe('txFormat', function () { // All testnet wallets default to PSBT-lite runTest({ description: 'should always return psbt-lite for testnet', - coinFilter: (coin) => utxolib.isTestnet(coin.network), + coinFilter: (coin) => isTestnetCoin(coin.name), expectedTxFormat: 'psbt-lite', }); // DistributedCustody wallets default to PSBT (mainnet only, testnet already covered) runTest({ description: 'should return psbt for distributedCustody wallets on mainnet', - coinFilter: (coin) => utxolib.isMainnet(coin.network), + coinFilter: (coin) => isMainnetCoin(coin.name), walletFilter: (w) => w.options.subType === 'distributedCustody', expectedTxFormat: 'psbt', }); @@ -121,7 +121,7 @@ describe('txFormat', function () { // MuSig2 wallets default to PSBT (mainnet only, testnet already covered) runTest({ description: 'should return psbt for wallets with musigKp flag on mainnet', - coinFilter: (coin) => utxolib.isMainnet(coin.network), + coinFilter: (coin) => isMainnetCoin(coin.name), walletFilter: (w) => Boolean(w.options.walletFlags?.some((f) => f.name === 'musigKp' && f.value === 'true')), expectedTxFormat: 'psbt', }); @@ -129,8 +129,7 @@ describe('txFormat', function () { // Mainnet Bitcoin hot wallets default to PSBT runTest({ description: 'should return psbt for mainnet bitcoin hot wallets', - coinFilter: (coin) => - utxolib.isMainnet(coin.network) && utxolib.getMainnet(coin.network) === utxolib.networks.bitcoin, + coinFilter: (coin) => isMainnetCoin(coin.name) && getMainnetCoinName(coin.name) === 'btc', walletFilter: (w) => w.options.type === 'hot', expectedTxFormat: 'psbt', }); @@ -138,7 +137,7 @@ describe('txFormat', function () { // Other mainnet wallets do NOT default to PSBT runTest({ description: 'should return undefined for other mainnet wallets', - coinFilter: (coin) => utxolib.isMainnet(coin.network), + coinFilter: (coin) => isMainnetCoin(coin.name), walletFilter: (w) => { const isHotBitcoin = w.options.type === 'hot'; // This will be bitcoin hot wallets const isDistributedCustody = w.options.subType === 'distributedCustody'; @@ -152,7 +151,7 @@ describe('txFormat', function () { // Test explicitly requested formats runTest({ description: 'should respect explicitly requested legacy format on mainnet', - coinFilter: (coin) => utxolib.isMainnet(coin.network), + coinFilter: (coin) => isMainnetCoin(coin.name), expectedTxFormat: 'legacy', requestedTxFormat: 'legacy', }); @@ -172,7 +171,7 @@ describe('txFormat', function () { // Test that legacy format is prohibited on testnet it('should throw ErrorDeprecatedTxFormat when legacy format is requested on testnet', function () { for (const coin of utxoCoins) { - if (!utxolib.isTestnet(coin.network)) { + if (!isTestnetCoin(coin.name)) { continue; } diff --git a/modules/abstract-utxo/test/unit/util/nockIndexerAPI.ts b/modules/abstract-utxo/test/unit/util/nockIndexerAPI.ts index 0ebf5754ca..f818b2f3cf 100644 --- a/modules/abstract-utxo/test/unit/util/nockIndexerAPI.ts +++ b/modules/abstract-utxo/test/unit/util/nockIndexerAPI.ts @@ -1,5 +1,6 @@ import nock = require('nock'); import * as utxolib from '@bitgo/utxo-lib'; +import { address as wasmAddress } from '@bitgo/wasm-utxo'; import { AbstractUtxoCoin } from '../../../src'; @@ -19,7 +20,7 @@ export function nockBitGoPublicTransaction ({ address: u.address })), - outputs: tx.outs.map((o) => ({ address: utxolib.address.fromOutputScript(o.script, coin.network) })), + outputs: tx.outs.map((o) => ({ address: wasmAddress.fromOutputScriptWithCoin(o.script, coin.name) })), }; return nockBitGo().get(`/api/v2/${coin.getChain()}/public/tx/${tx.getId()}`).reply(200, payload); } @@ -33,7 +34,7 @@ export function nockBitGoPublicAddressUnspents ({ id: `${txid}:${vout}`, - address: utxolib.address.fromOutputScript(o.script, coin.network), + address: wasmAddress.fromOutputScriptWithCoin(o.script, coin.name), value: Number(o.value), valueString: coin.amountType === 'bigint' ? o.value.toString() : undefined, }) diff --git a/modules/abstract-utxo/test/unit/util/transaction.ts b/modules/abstract-utxo/test/unit/util/transaction.ts index 7ca5fa150b..e976cf37cf 100644 --- a/modules/abstract-utxo/test/unit/util/transaction.ts +++ b/modules/abstract-utxo/test/unit/util/transaction.ts @@ -1,4 +1,7 @@ import * as utxolib from '@bitgo/utxo-lib'; +import { address as wasmAddress } from '@bitgo/wasm-utxo'; + +import { getCoinName } from '../../../src/names'; const { isWalletUnspent, signInputWithUnspent } = utxolib.bitgo; type RootWalletKeys = utxolib.bitgo.RootWalletKeys; type Unspent = utxolib.bitgo.Unspent; @@ -22,7 +25,7 @@ function toTxOutput( network: utxolib.Network ): utxolib.TxOutput { return { - script: utxolib.address.toOutputScript(u.address, network), + script: Buffer.from(wasmAddress.toOutputScriptWithCoin(u.address, getCoinName(network))), value: u.value, }; } diff --git a/modules/abstract-utxo/test/unit/util/unspents.ts b/modules/abstract-utxo/test/unit/util/unspents.ts index 674e61c4c7..e974a9ba1c 100644 --- a/modules/abstract-utxo/test/unit/util/unspents.ts +++ b/modules/abstract-utxo/test/unit/util/unspents.ts @@ -36,7 +36,10 @@ export function getWalletAddress( if (utxolib.isTestnet(network)) { return wasmUtxo.fixedScriptWallet.address(walletKeys, chain, index, network); } - return utxolib.address.fromOutputScript(getOutputScript(walletKeys, chain, index).scriptPubKey, network); + return wasmUtxo.address.fromOutputScriptWithCoin( + getOutputScript(walletKeys, chain, index).scriptPubKey, + getCoinName(network) + ); } function mockOutputIdForAddress(address: string) {