feat(statics): add Pearl to statics and utxo-lib networks#9347
feat(statics): add Pearl to statics and utxo-lib networks#9347manojkumar138 wants to merge 1 commit into
Conversation
d507bc6 to
0f546d8
Compare
e940684 to
563cbd8
Compare
4df9ece to
96342d0
Compare
Add Pearl mainnet/testnet coin definitions to @bitgo/statics and network params to @bitgo/utxo-lib. Pearl is a Taproot-only UTXO chain (btcd fork) using BIP-340 Schnorr signatures and BIP-341 script-path spending. Bump @bitgo/wasm-utxo to ^4.27.0, which adds pearl/tpearl coin support. TICKET: CECHO-1780 Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
96342d0 to
8317443
Compare
|
@claude review |
|
Claude finished @manojkumar138's task —— View job Code Review - Pearl (PEARL) Integration✅ Completed Reviews1. Base Configuration (
2. Network Classes (
3. UTXO Coin Definitions (
4. UTXO-lib Network Configuration (
5. Test Fixtures and Validation ✅
🎯 Key Validation Points ✅
📊 Review SummaryStatus: ✅ APPROVED The Pearl (PEARL) cryptocurrency integration is well-implemented and complete. The implementation properly follows BitGo's established patterns and includes:
The integration correctly implements Pearl as a Taproot-enabled UTXO coin with bech32m addressing (prl/tprl prefixes) and includes all necessary features for BitGo wallet functionality. No issues identified. Ready for merge. |
There was a problem hiding this comment.
Pull request overview
This PR introduces Pearl (pearl / tpearl) as a recognized UTXO network across BitGoJS’ statics + UTXO stack (statics, utxo-lib, utxo-core, utxo-bin, abstract-utxo tests), including Taproot-only wallet script-type enforcement to match @bitgo/wasm-utxo behavior.
Changes:
- Adds Pearl network definitions (mainnet/testnet) and detection helpers in
@bitgo/utxo-lib, including Taproot-only script-type gating inoutputScripts.isSupportedScriptType. - Registers Pearl coin metadata in
@bitgo/statics(family/asset/network/utxo coin entries + expectedColdFeatures). - Updates dust threshold logic, CLI network parsing order, tests, and extensive address/PSBT fixtures; bumps
@bitgo/wasm-utxoto^4.27.0across affected modules.
Reviewed changes
Copilot reviewed 92 out of 93 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| yarn.lock | Bumps @bitgo/wasm-utxo and updates transitive lock entries. |
| modules/utxo-staking/package.json | Bumps @bitgo/wasm-utxo to ^4.27.0. |
| modules/utxo-ord/package.json | Bumps @bitgo/wasm-utxo to ^4.27.0. |
| modules/utxo-descriptors/package.json | Bumps @bitgo/wasm-utxo to ^4.27.0. |
| modules/utxo-core/package.json | Bumps @bitgo/wasm-utxo to ^4.27.0. |
| modules/utxo-bin/package.json | Bumps @bitgo/wasm-utxo to ^4.27.0. |
| modules/abstract-utxo/package.json | Bumps @bitgo/wasm-utxo to ^4.27.0. |
| modules/statics/src/base.ts | Adds CoinFamily.PEARL and UnderlyingAsset.PEARL. |
| modules/statics/src/networks.ts | Adds Pearl mainnet/testnet network objects to Networks. |
| modules/statics/src/utxo.ts | Adds pearl/tpearl UTXO coin entries and feature set. |
| modules/statics/test/unit/fixtures/expectedColdFeatures.ts | Adds pearl/tpearl to expected cold-feature fixtures. |
| modules/utxo-lib/src/networks.ts | Adds pearl/tpearl networks, NetworkName union updates, and helpers (isPearl, segwit/taproot support). |
| modules/utxo-lib/src/bitgo/outputScripts.ts | Enforces Taproot-only script type support for Pearl via isSupportedScriptType. |
| modules/utxo-lib/src/bitgo/transaction.ts | Enables transaction/PSBT factory support for networks.pearl. |
| modules/utxo-core/src/dustThreshold.ts | Treats Pearl like BTC-group for dust relay limit and spend size. |
| modules/utxo-core/test/dustThreshold.ts | Adds Pearl expected dust-threshold test vectors. |
| modules/utxo-bin/src/args/parseNetwork.ts | Adds Pearl to the CLI network ordering (mainnet group). |
| modules/utxo-lib/test/networks.ts | Extends network property-sharing groups and feature expectation table for Pearl. |
| modules/utxo-lib/test/bitgo/outputScripts.ts | Adds expected script types for Pearl (p2tr, p2trMusig2). |
| modules/utxo-lib/test/integration_local_rpc/parse.ts | Skips Pearl in regtest fixture suite until generator supports it. |
| modules/utxo-lib/test/fixtures_thirdparty/parse.ts | Excludes Pearl from third-party fixture parsing. |
| modules/utxo-lib/test/fixtures_thirdparty/download.ts | Excludes Pearl from third-party fixture downloads. |
| modules/utxo-lib/test/bitgo/psbt/Psbt.ts | Skips a p2ms-only extraction suite for Pearl. |
| modules/utxo-lib/test/bitgo/psbt/SignVerifyLegacy.ts | Skips legacy PSBT signing suite for taproot-only Pearl. |
| modules/utxo-lib/test/address/fixtures/pearl.json | Adds Pearl address vectors. |
| modules/utxo-lib/test/address/fixtures/tpearl.json | Adds Pearl testnet address vectors. |
| modules/utxo-lib/test/bitgo/fixtures/psbt/psbt.pearl.unsigned.json | Adds Pearl PSBT fixture (unsigned). |
| modules/utxo-lib/test/bitgo/fixtures/psbt/psbt.pearl.halfsigned.json | Adds Pearl PSBT fixture (half-signed). |
| modules/utxo-lib/test/bitgo/fixtures/psbt/psbt-lite.pearl.unsigned.json | Adds Pearl “lite” PSBT fixture (unsigned). |
| modules/utxo-lib/test/bitgo/fixtures/psbt/psbt-lite.pearl.halfsigned.json | Adds Pearl “lite” PSBT fixture (half-signed). |
| modules/abstract-utxo/test/unit/coins.ts | Documents Pearl networks as lacking coin classes yet (undefined). |
| modules/abstract-utxo/test/unit/util/utxoCoins.ts | Adds hasUtxoCoinForNetwork predicate for tests. |
| modules/abstract-utxo/test/unit/transaction/fixedScript/parsePsbt.ts | Filters AcidTest suite by hasUtxoCoinForNetwork. |
| modules/utxo-bin/test/fixtures/formatAddress/pearl_p2pkh_default_1LCVrCgbT26Ui1QyrhaGvvhrkVdDRAXxtt.txt | Adds Pearl formatAddress fixture (p2pkh). |
| modules/utxo-bin/test/fixtures/formatAddress/pearl_p2wkh_default_prl1q62tshlryz9lrjlw9edaf4l5l3v3deg03gw29k2.txt | Adds Pearl formatAddress fixture (p2wkh). |
| modules/utxo-bin/test/fixtures/formatAddress/pearl_p2tr_default_prl1p8gv9m64s539mycj4m29wu8thy5n3y6u36xs58wq3yezrmqygwfns2yff0j.txt | Adds Pearl formatAddress fixture (p2tr). |
| modules/utxo-bin/test/fixtures/formatAddress/pearl_p2trMusig2_default_prl1p5xqvqger0zdpcq6s3jznfz352exhk356p9hml6c69matmggrve9sq7apju.txt | Adds Pearl formatAddress fixture (p2trMusig2). |
| modules/utxo-bin/test/fixtures/formatAddress/tpearl_p2pkh_default_mziT9FmaG3XjV7tbaGYekqvBcVDvGnY3EZ.txt | Adds tpearl formatAddress fixture (p2pkh). |
| modules/utxo-bin/test/fixtures/formatAddress/tpearl_p2wkh_default_tprl1q62tshlryz9lrjlw9edaf4l5l3v3deg03lufv9q.txt | Adds tpearl formatAddress fixture (p2wkh). |
| modules/utxo-bin/test/fixtures/formatAddress/tpearl_p2tr_default_tprl1p8gv9m64s539mycj4m29wu8thy5n3y6u36xs58wq3yezrmqygwfnsptdhs8.txt | Adds tpearl formatAddress fixture (p2tr). |
| modules/utxo-bin/test/fixtures/formatAddress/tpearl_p2trMusig2_default_tprl1p5xqvqger0zdpcq6s3jznfz352exhk356p9hml6c69matmggrve9st3eldf.txt | Adds tpearl formatAddress fixture (p2trMusig2). |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2pkh_default_1LCVrCgbT26Ui1QyrhaGvvhrkVdDRAXxtt.txt | Updates network candidate list to include Pearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2pkh_default_1LCVrCgbT26Ui1QyrhaGvvhrkVdDRAXxtt.all.txt | Updates converted network list to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2sh_default_361UWADXqgPsdf8L5Jga6GNPauMuBtT1eW.txt | Updates network candidate list to include Pearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2sh_default_361UWADXqgPsdf8L5Jga6GNPauMuBtT1eW.all.txt | Updates converted network list to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2shP2wsh_default_33qtbAwm4ooBtMQenssbqDE1J4gSMMBRnb.txt | Updates network candidate list to include Pearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2shP2wsh_default_33qtbAwm4ooBtMQenssbqDE1J4gSMMBRnb.all.txt | Updates converted network list to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2tr_default_bc1p8gv9m64s539mycj4m29wu8thy5n3y6u36xs58wq3yezrmqygwfnsjhucex.all.txt | Adds Pearl/tpearl conversions for taproot addresses. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2trMusig2_default_bc1p5xqvqger0zdpcq6s3jznfz352exhk356p9hml6c69matmggrve9scdgsyg.all.txt | Adds Pearl/tpearl conversions for taproot-musig2 addresses. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2wkh_default_bc1q62tshlryz9lrjlw9edaf4l5l3v3deg034uw28c.all.txt | Adds Pearl/tpearl conversions for segwit v0 addresses. |
| modules/utxo-bin/test/fixtures/formatAddress/bitcoin_p2wsh_default_bc1qeu6xmet5wqslj2w0wac0hx5gj6dupmp869cajrkt3kw6ud3kkecsdzf7hn.all.txt | Adds Pearl/tpearl conversions for segwit v0 scripts. |
| modules/utxo-bin/test/fixtures/formatAddress/testnet_p2pkh_default_mziT9FmaG3XjV7tbaGYekqvBcVDvGnY3EZ.txt | Updates candidate network lists to include tpearl where prefixes collide. |
| modules/utxo-bin/test/fixtures/formatAddress/testnet_p2sh*_default_2M*.txt | Updates candidate network lists to include tpearl where prefixes collide. |
| modules/utxo-bin/test/fixtures/formatAddress/cash_*.all.txt | Updates converted network list to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/sv_* | Updates network candidate lists to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/bch_* | Updates network candidate lists to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/btg_* | Updates network candidate lists to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/doge_* | Updates network candidate lists to include tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/ecash_* | Updates network candidate lists to include Pearl/tpearl. |
| modules/utxo-bin/test/fixtures/formatAddress/litecoinTest_* | Updates network candidate lists to include tpearl. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const PEARL_FEATURES = [ | ||
| ...UtxoCoin.DEFAULT_FEATURES, | ||
| CoinFeature.MULTISIG, | ||
| CoinFeature.BULK_TRANSACTION, | ||
| CoinFeature.DISTRIBUTED_CUSTODY, | ||
| ]; |
Summary
Defines Pearl's coin identity and network parameters in
@bitgo/staticsand@bitgo/utxo-lib, and teaches the surrounding UTXO modules that Pearl exists.No SDK coin class yet — that follows in PR 2. This PR only makes Pearl a known network.
Chain Type
UTXO — Taproot-only (BIP-340 Schnorr signatures, BIP-341 script-path spending with a NUMS internal key). Pearl is a btcd fork.
Taproot-only is the load-bearing detail in this PR.
@bitgo/wasm-utxo— already merged and authoritative — supports onlyp2trLegacyandp2trMusig2for Pearl:utxo-lib is made to agree, so BitGoJS never advertises wallet script types the chain layer rejects.
Coin Codes & Tickers
pearlPEARLpearltpearlTPEARLtpearlNames match
@bitgo/wasm-utxo(coinNames: [..., "pearl", "tpearl"]) and indexer-utxo (CoinSymbol.pearl/CoinSymbol.tpearl).The testnet network is keyed
tpearlrather than the usual<name>Test. This is deliberate: wasm-utxo'sNetworkNameisUtxolibName | CoinName, and its legacyUtxolibNameunion is frozen for pre-existing coins — Pearl was added only toCoinName. Bothpearlandtpearlare validCoinNames that pass throughtoCoinName()unchanged, so the naming keeps utxo-lib'sNetworkNameassignable to wasm-utxo's without needing an upstream release.Network Parameters
prltprlm/86'/808276'/0'm/86'/1'/0'pubKeyHash/scriptHash/wif0x00/0x05/0x800x6f/0xc4/0xefMainnet reuses Bitcoin's base58 version bytes, so a Bitcoin base58 address is also a structurally valid Pearl address. That is expected and shows up in the utxo-bin fixtures below. In practice Pearl wallets are bech32m-only.
Changes
@bitgo/staticssrc/base.tsCoinFamily.PEARL,UnderlyingAsset.PEARLsrc/networks.tsPearl/PearlTestnetclasses +Networks.main/Networks.testentriessrc/utxo.tspearl/tpearlcoin entries with explicitPEARL/TPEARLsuffixes andMULTISIG+BULK_TRANSACTION+DISTRIBUTED_CUSTODYfeaturestest/unit/fixtures/expectedColdFeatures.tsjustMultiSig@bitgo/utxo-libsrc/networks.tspearl/tpearlnetwork objects,coins.PEARL,NetworkNameunion,getMainnet(),isPearl(),supportsSegwit(),supportsTaproot()src/bitgo/outputScripts.tsisSupportedScriptType()— Taproot-only guardsrc/bitgo/transaction.tspearladded to the six Bitcoin-like factory switchesThe Pearl block sits between
litecoinTestandzcashin thenetworksobject because a test asserts mainnets are ordered alphabetically.isSupportedScriptTypeneeded an explicit guard rather than a derived answer. It hardcodesp2sh→ always true and derives the rest fromsupportsSegwit/supportsTaproot, so no combination of those two flags can express "Taproot-only".supportsSegwit/supportsTaprootboth staytrue— those describe chain capability, and Pearl does have both activated; script-type support is the wallet-policy question and now lives where that question is asked.transaction.ts— Pearl joinsbitcoin/bitcoincash/bitcoinsv/bitcoingold/dogecoin/ecashincreateTransactionFromBuffer,createPsbtFromBuffer,createPsbtFromTransaction,createPsbtForNetwork,createTransactionBuilderForNetwork, andcreateTransactionBuilderFromTransaction. Without this,createPsbtForNetworkthrewunsupported network.Deliberately not touched:
getDefaultTransactionVersion,setTransactionBuilderDefaults,setPsbtDefaults(Pearl falls todefault→ version 1, correct for a btcd fork), and theSIGHASH_FORKIDswitches inUtxoPsbt.ts/UtxoTransaction.ts/signature.ts(Pearl has no forkid, andgetDefaultSigHash's default already yieldsSIGHASH_DEFAULTfor p2tr).@bitgo/utxo-coresrc/dustThreshold.ts— Pearl added togetDustRelayLimit(3000 sat/kB) andgetSpendSize(Bitcoin group).Not an assumption: btcd's
GetDustThresholdis3 * totalSizewheretotalSize = SerializeSize + 41 + 107/WitnessScaleFactor. Applying a 3000 sat/kB rate to that same spend size is arithmetically identical, so Pearl slots into the existing Bitcoin path rather than needing its own branch. Yields 546 sats for a 34-byte non-witness output and 306 sats for a Taproot output — same as BTC.@bitgo/utxo-binsrc/args/parseNetwork.ts— Pearl added to the hardcodednetworkOrderarray, which otherwise threwunknown network. Production code, not a test.Dependency bump
@bitgo/wasm-utxo^4.21.1→^4.27.0acrossabstract-utxo,utxo-bin,utxo-core,utxo-descriptors,utxo-ord,utxo-staking. 4.27.0 is the first release carryingpearl/tpearl; the older pin made utxo-lib's widenedNetworkNameunassignable.Test fixtures and suites
utxo-lib/test/networks.tsisPearladded to shared pubkey/script/WIF prefix groups andbech32Coinsutxo-lib/test/bitgo/outputScripts.ts['p2tr', 'p2trMusig2']utxo-lib/test/address/fixtures/{pearl,tpearl}.jsonutxo-lib/test/bitgo/fixtures/psbt/psbt{,-lite}.pearl.*.jsonutxo-bin/test/fixtures/formatAddress/*abstract-utxo/test/unit/coins.ts['pearl', undefined]/['tpearl', undefined]— no coin class until PR 2abstract-utxo/test/unit/util/utxoCoins.tshasUtxoCoinForNetworkpredicateabstract-utxo/test/unit/transaction/fixedScript/parsePsbt.tsThe 50 updated utxo-bin fixtures are purely additive —
pearl/tpearlappended to candidate-network lists, because Pearl mainnet shares Bitcoin's base58 prefixes. No existing value changed.Pearl is excluded from three suites that cannot apply to it:
fixtures_thirdparty/{parse,download}.ts— these pullsighash.json/tx_valid.jsonfrom each coin's upstream C++ tree. Pearl is a Go btcd fork with no such vectors.integration_local_rpc/parse.ts— needs pre-generated regtest fixtures; the generator has no Pearl node support.psbt/Psbt.ts(extractP2msOnlyHalfSignedTx) andpsbt/SignVerifyLegacy.ts— P2MS-only by definition, and the legacy suite's fixed output set assumes several legacy-signable inputs where Pearl contributes one.Verification
All eight affected modules, zero failures:
staticsutxo-libutxo-coreabstract-utxoutxo-binutxo-descriptorsutxo-ordutxo-stakingutxo-descriptors,utxo-ord,utxo-staking,blockapis, andunspentspass untouched. All modules build clean; prettier and eslint clean. Address and PSBT fixtures confirmed deterministic (deleted, regenerated, byte-identical).Dependencies
Already merged upstream:
Follow-ups
abstract-utxoPrl/Tprlclasses +sdk-coin-pearl. Since Pearl is Taproot-only, those classes will need to expose onlyp2tr/p2trMusig2rather than inheritingAbstractUtxoCoin's defaults.coinFactory+bitgomodule registration.integration_local_rpc/generate.Related
🤖 Generated with Claude Code