feat(statics): add Pearl to statics and utxo-lib networks#9347
Draft
manojkumar138 wants to merge 1 commit into
Draft
feat(statics): add Pearl to statics and utxo-lib networks#9347manojkumar138 wants to merge 1 commit into
manojkumar138 wants to merge 1 commit into
Conversation
manojkumar138
force-pushed
the
feat/prl/pr1-statics
branch
from
July 24, 2026 11:27
d507bc6 to
0f546d8
Compare
manojkumar138
force-pushed
the
feat/prl/pr1-statics
branch
4 times, most recently
from
July 24, 2026 11:53
e940684 to
563cbd8
Compare
Contributor
manojkumar138
force-pushed
the
feat/prl/pr1-statics
branch
6 times, most recently
from
July 25, 2026 17:01
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) <noreply@anthropic.com>
manojkumar138
force-pushed
the
feat/prl/pr1-statics
branch
from
July 25, 2026 20:12
96342d0 to
8317443
Compare
Contributor
Author
|
@claude review |
Contributor
|
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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