Skip to content

Commit e940684

Browse files
manojkumar138claude
andcommitted
feat(statics): add Pearl (PRL) to statics and utxo-lib networks
Pearl is a Taproot-only UTXO chain (btcd fork) using BIP-340 Schnorr signatures and BIP-341 script-path spending with a NUMS internal key. - Add CoinFamily.PRL and UnderlyingAsset.PRL to base.ts - Add Pearl/PearlTestnet network classes (bech32m HRP: prl/tprl) - Add prl/tprl coin entries to utxo.ts with MULTISIG + BULK_TRANSACTION - Add pearl/pearlTest to utxo-lib networks with Taproot + SegWit support - Add isPearl() helper and update supportsTaproot()/supportsSegwit() TICKET: CECHO-1780 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8b1ee36 commit e940684

11 files changed

Lines changed: 134 additions & 67 deletions

File tree

modules/abstract-utxo/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
"@bitgo/utxo-descriptors": "^1.3.4",
6868
"@bitgo/utxo-lib": "^11.24.1",
6969
"@bitgo/utxo-ord": "^1.32.4",
70-
"@bitgo/wasm-utxo": "^4.21.1",
70+
"@bitgo/wasm-utxo": "^4.27.0",
7171
"@types/lodash": "^4.14.121",
7272
"@types/superagent": "4.1.15",
7373
"bignumber.js": "^9.0.2",

modules/statics/src/base.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ export enum CoinFamily {
110110
OPETH = 'opeth',
111111
OSMO = 'osmo',
112112
PLUME = 'plume',
113+
PEARL = 'pearl',
113114
RBTC = 'rbtc',
114115
SCROLLETH = 'scrolleth', // Scroll L2
115116
SGB = 'sgb',
@@ -1684,6 +1685,7 @@ export enum UnderlyingAsset {
16841685
PRDX = 'prdx',
16851686
PRINTS = 'prints',
16861687
PRISM = 'prism',
1688+
PEARL = 'pearl',
16871689
PRO = 'pro',
16881690
PROM = 'prom',
16891691
PROS = 'pros',

modules/statics/src/networks.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,6 +1431,20 @@ class ZCashTestnet extends Testnet implements UtxoNetwork {
14311431
explorerUrl = 'https://testnet.zcashexplorer.app/transactions/';
14321432
}
14331433

1434+
class Pearl extends Mainnet implements UtxoNetwork {
1435+
name = 'Pearl';
1436+
family = CoinFamily.PEARL;
1437+
utxolibName = 'pearl';
1438+
explorerUrl = undefined;
1439+
}
1440+
1441+
class PearlTestnet extends Testnet implements UtxoNetwork {
1442+
name = 'PearlTestnet';
1443+
family = CoinFamily.PEARL;
1444+
utxolibName = 'pearlTest';
1445+
explorerUrl = undefined;
1446+
}
1447+
14341448
class Near extends Mainnet implements AccountNetwork {
14351449
name = 'Near';
14361450
family = CoinFamily.NEAR;
@@ -2953,6 +2967,7 @@ export const Networks = {
29532967
plume: Object.freeze(new Plume()),
29542968
polygon: Object.freeze(new Polygon()),
29552969
polyx: Object.freeze(new Polymesh()),
2970+
pearl: Object.freeze(new Pearl()),
29562971
phrs: Object.freeze(new Pharos()),
29572972
ctc: Object.freeze(new Creditcoin()),
29582973
hypeevm: Object.freeze(new HypeEVM()),
@@ -3087,6 +3102,7 @@ export const Networks = {
30873102
mantra: Object.freeze(new MantraTestnet()),
30883103
polygon: Object.freeze(new PolygonTestnet()),
30893104
polyx: Object.freeze(new PolymeshTestnet()),
3105+
pearl: Object.freeze(new PearlTestnet()),
30903106
phrs: Object.freeze(new PharosTestnet()),
30913107
ctc: Object.freeze(new CreditcoinTestnet()),
30923108
hypeevm: Object.freeze(new HypeEVMTestnet()),

modules/statics/src/utxo.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,12 @@ const DOGE_FEATURES = [
143143
const DASH_FEATURES = [...UtxoCoin.DEFAULT_FEATURES, CoinFeature.CUSTODY_BITGO_FRANKFURT, CoinFeature.BULK_TRANSACTION];
144144
const TDASH_FEATURES = [...UtxoCoin.DEFAULT_FEATURES, CoinFeature.BULK_TRANSACTION];
145145
const ZEC_FEATURES = [...UtxoCoin.DEFAULT_FEATURES, CoinFeature.BULK_TRANSACTION, CoinFeature.CUSTODY_BITGO_FRANKFURT];
146+
const PEARL_FEATURES = [
147+
...UtxoCoin.DEFAULT_FEATURES,
148+
CoinFeature.MULTISIG,
149+
CoinFeature.BULK_TRANSACTION,
150+
CoinFeature.DISTRIBUTED_CUSTODY,
151+
];
146152
export const utxoCoins: Readonly<BaseCoin>[] = [
147153
utxo(
148154
'8d6e08d5-399f-414f-8430-6ceca1798cbf',
@@ -320,6 +326,28 @@ export const utxoCoins: Readonly<BaseCoin>[] = [
320326
BaseUnit.ZEC,
321327
ZEC_FEATURES
322328
),
329+
utxo(
330+
'4518a5b9-00d3-476e-bc40-d3f87eb82250',
331+
'pearl',
332+
'Pearl',
333+
Networks.main.pearl,
334+
UnderlyingAsset.PEARL,
335+
BaseUnit.BTC,
336+
PEARL_FEATURES,
337+
'',
338+
'PEARL'
339+
),
340+
utxo(
341+
'5d88723a-7e86-43c7-9fb1-f4cee7abc48f',
342+
'tpearl',
343+
'Testnet Pearl',
344+
Networks.test.pearl,
345+
UnderlyingAsset.PEARL,
346+
BaseUnit.BTC,
347+
PEARL_FEATURES,
348+
'',
349+
'TPEARL'
350+
),
323351
utxo(
324352
'c93a9160-458f-4a31-bea0-4a93ae8b1d2d',
325353
'doge',

modules/utxo-bin/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"@bitgo/unspents": "^0.51.7",
3232
"@bitgo/utxo-core": "^1.39.4",
3333
"@bitgo/utxo-lib": "^11.24.1",
34-
"@bitgo/wasm-utxo": "^4.21.1",
34+
"@bitgo/wasm-utxo": "^4.27.0",
3535
"@noble/curves": "1.8.1",
3636
"archy": "^1.0.0",
3737
"bech32": "^2.0.0",

modules/utxo-core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
"@bitgo/secp256k1": "^1.11.0",
8282
"@bitgo/unspents": "^0.51.7",
8383
"@bitgo/utxo-lib": "^11.24.1",
84-
"@bitgo/wasm-utxo": "^4.21.1",
84+
"@bitgo/wasm-utxo": "^4.27.0",
8585
"bip174": "npm:@bitgo-forks/bip174@3.1.0-master.4",
8686
"fast-sha256": "^1.3.0"
8787
},

modules/utxo-descriptors/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,6 @@
6060
},
6161
"dependencies": {
6262
"@bitgo/utxo-core": "^1.39.4",
63-
"@bitgo/wasm-utxo": "^4.21.1"
63+
"@bitgo/wasm-utxo": "^4.27.0"
6464
}
6565
}

modules/utxo-lib/src/networks.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const coins = {
3333
ZEC: 'zec',
3434
DASH: 'dash',
3535
DOGE: 'doge',
36+
PEARL: 'pearl',
3637
} as const;
3738

3839
export type NetworkName =
@@ -56,7 +57,9 @@ export type NetworkName =
5657
| 'litecoin'
5758
| 'litecoinTest'
5859
| 'zcash'
59-
| 'zcashTest';
60+
| 'zcashTest'
61+
| 'pearl'
62+
| 'pearlTest';
6063

6164
export type Network = {
6265
messagePrefix: string;
@@ -345,6 +348,26 @@ export const networks: Record<NetworkName, Network> = {
345348
wif: 0xef,
346349
coin: coins.ZEC,
347350
},
351+
352+
// https://github.com/pearl-research-labs/pearl/blob/main/chaincfg/params.go
353+
pearl: {
354+
messagePrefix: '\x18Pearl Signed Message:\n',
355+
bech32: 'prl',
356+
bip32: getDefaultBip32Mainnet(),
357+
pubKeyHash: 0x00,
358+
scriptHash: 0x05,
359+
wif: 0x80,
360+
coin: coins.PEARL,
361+
},
362+
pearlTest: {
363+
messagePrefix: '\x18Pearl Signed Message:\n',
364+
bech32: 'tprl',
365+
bip32: getDefaultBip32Testnet(),
366+
pubKeyHash: 0x6f,
367+
scriptHash: 0xc4,
368+
wif: 0xef,
369+
coin: coins.PEARL,
370+
},
348371
};
349372

350373
/**
@@ -409,6 +432,10 @@ export function getMainnet(network: Network): Network {
409432
case networks.dogecoin:
410433
case networks.dogecoinTest:
411434
return networks.dogecoin;
435+
436+
case networks.pearl:
437+
case networks.pearlTest:
438+
return networks.pearl;
412439
}
413440
throw new TypeError(`invalid network`);
414441
}
@@ -529,6 +556,14 @@ export function isDogecoin(network: Network): boolean {
529556
return getMainnet(network) === networks.dogecoin;
530557
}
531558

559+
/**
560+
* @param {Network} network
561+
* @returns {boolean} true iff network is pearl or pearlTest
562+
*/
563+
export function isPearl(network: Network): boolean {
564+
return getMainnet(network) === networks.pearl;
565+
}
566+
532567
/**
533568
* @param {Network} network
534569
* @returns {boolean} true iff network is litecoin or litecoinTest
@@ -554,9 +589,11 @@ export function isValidNetwork(network: unknown): network is Network {
554589
}
555590

556591
export function supportsSegwit(network: Network): boolean {
557-
return ([networks.bitcoin, networks.litecoin, networks.bitcoingold] as Network[]).includes(getMainnet(network));
592+
return ([networks.bitcoin, networks.litecoin, networks.bitcoingold, networks.pearl] as Network[]).includes(
593+
getMainnet(network)
594+
);
558595
}
559596

560597
export function supportsTaproot(network: Network): boolean {
561-
return getMainnet(network) === networks.bitcoin;
598+
return ([networks.bitcoin, networks.pearl] as Network[]).includes(getMainnet(network));
562599
}

modules/utxo-ord/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"directory": "modules/utxo-ord"
4646
},
4747
"dependencies": {
48-
"@bitgo/wasm-utxo": "^4.21.1"
48+
"@bitgo/wasm-utxo": "^4.27.0"
4949
},
5050
"devDependencies": {
5151
"@bitgo/utxo-lib": "^11.24.1"

modules/utxo-staking/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"@bitgo/babylonlabs-io-btc-staking-ts": "^3.5.1",
6464
"@bitgo/utxo-core": "^1.39.4",
6565
"@bitgo/utxo-lib": "^11.24.1",
66-
"@bitgo/wasm-utxo": "^4.21.1",
66+
"@bitgo/wasm-utxo": "^4.27.0",
6767
"bip174": "npm:@bitgo-forks/bip174@3.1.0-master.4",
6868
"bip322-js": "^2.0.0",
6969
"bitcoinjs-lib": "^6.1.7",

0 commit comments

Comments
 (0)