Skip to content

Add regtest address support to address_to_script_pubkey#166

Merged
mflaxman merged 1 commit intomainfrom
add-regtest-support
Mar 3, 2026
Merged

Add regtest address support to address_to_script_pubkey#166
mflaxman merged 1 commit intomainfrom
add-regtest-support

Conversation

@jimmysong
Copy link
Collaborator

@jimmysong jimmysong commented Mar 1, 2026

Summary

  • address_to_script_pubkey() now handles regtest bech32 addresses (bcrt1q for P2WPKH/P2WSH, bcrt1p for P2TR)
  • TxFetcher.get_url() raises a clear ValueError for regtest instead of an unhelpful KeyError
  • Added tests for regtest address roundtrips and TxFetcher error handling

Network parameter audit

Every function/method that takes network as a parameter was reviewed. Here is the full analysis:

Dict lookup (regtest key exists in dict)

File:Line Function How network is used Regtest?
bech32.py:172 encode_bech32_checksum() PREFIX.get(network) Yes — PREFIX has "regtest": "bcrt"
network.py:43 GenericMessage.__init__() Stored, not branched Yes
network.py:52 GenericMessage.parse() MAGIC[network] Yes — MAGIC has regtest
network.py:306 SimpleNode.__init__() PORT[network] Yes — PORT has regtest
hd.py:141 HDPrivateKey.from_seed() XPRV[network] Yes — XPRV has regtest
tx.py:53 TxFetcher.get_url() URL[network] Fixed — now raises clear ValueError
tx.py:62 TxFetcher.fetch() Calls get_url(network) Fixed via get_url
tx.py:97 TxFetcher.sendrawtransaction() Calls get_url(network) Fixed via get_url

Passthrough (stores or forwards network, no branching)

File:Line Function How network is used
cecc.py:368 PrivateKey.__init__() Stores self.network
pecc.py:538 PrivateKey.__init__() Stores self.network
cecc.py:215 S256Point.address() Forwards to p2pkh_script().address(network)
cecc.py:219 S256Point.p2wpkh_address() Forwards to p2wpkh_script().address(network)
cecc.py:223 S256Point.p2sh_p2wpkh_address() Forwards to p2wpkh_script().p2sh_address(network)
cecc.py:227 S256Point.p2tr_address() Forwards to p2tr_script().address(network)
pecc.py:339-351 Same 4 methods on S256Point Same as cecc.py
script.py:428 RedeemScript.address() Forwards to script_pubkey().address(network)
script.py:511 P2WPKHScriptPubKey.p2sh_address() Forwards to redeem_script().address(network)
script.py:579 WitnessScript.p2sh_address() Forwards to redeem_script().address(network)
tx.py:164-237 Tx.parse_hex/parse/parse_legacy/parse_segwit Stores self.network
tx.py:864-878 TxIn.fetch_tx/value/script_pubkey Forwards to TxFetcher.fetch(network)
psbt.py (6 methods) Various parse() methods Stores or forwards, uses path_network() as fallback
hd.py:273,695 raw_parse() Infers from xpub/xprv version bytes, override via param

Branching on network == "mainnet" (else = all non-mainnet including regtest)

File:Line Function Logic Regtest?
script.py:386 P2PKHScriptPubKey.address() mainnet → 0x00, else → 0x6f Yes — regtest uses 0x6f
script.py:405 P2SHScriptPubKey.address() mainnet → 0x05, else → 0xc4 Yes — regtest uses 0xc4
script.py:504 P2WPKHScriptPubKey.address() Calls encode_bech32_checksum(network) Yes
script.py:545 P2WSHScriptPubKey.address() Calls encode_bech32_checksum(network) Yes
script.py:572 P2TRScriptPubKey.address() Calls encode_bech32_checksum(network) Yes

All mainnet-vs-else branches are correct for regtest because regtest shares testnet's base58 version bytes, and bech32 functions use the PREFIX dict which already includes regtest.

Inherent protocol limitations (not bugs)

  • WIF parse (cecc.py:493, pecc.py:693): WIF prefix 0xEF is shared by testnet/signet/regtest — the format cannot distinguish them. pecc.py documents this explicitly.
  • path_network() (helper.py:360): BIP32 paths use coin 1' for all non-mainnet networks — cannot distinguish testnet/signet/regtest. PSBT callers allow explicit network override.

Test plan

  • Regtest P2WPKH address (bcrt1q..., len 44) parses and roundtrips
  • Regtest P2WSH address (bcrt1q..., len 64) parses and roundtrips
  • Regtest P2TR address (bcrt1p..., len 64) parses and roundtrips
  • TxFetcher.get_url("regtest") raises ValueError with clear message
  • All existing tests still pass

🤖 Generated with Claude Code

- Handle bcrt1q (P2WPKH len 44, P2WSH len 64) and bcrt1p (P2TR len 64)
  prefixes in address_to_script_pubkey()
- TxFetcher.get_url() now raises a clear ValueError for regtest instead
  of an unhelpful KeyError
- Add tests for regtest P2WPKH, P2WSH, and P2TR address roundtrips
- Add test for TxFetcher regtest error message

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jimmysong
Copy link
Collaborator Author

takes care of #162 and #163

@mflaxman mflaxman merged commit 5334f0b into main Mar 3, 2026
5 of 30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants