Skip to content

Add P2TR (taproot) address generation to ku utility#426

Draft
Copilot wants to merge 7 commits intomainfrom
copilot/add-p2tr-address-support
Draft

Add P2TR (taproot) address generation to ku utility#426
Copilot wants to merge 7 commits intomainfrom
copilot/add-p2tr-address-support

Conversation

Copy link
Contributor

Copilot AI commented Dec 22, 2025

Plan: Add P2TR Address Generation to ku Utility

  • Understand the codebase structure and P2TR implementation
  • Modify ku_output_for_address() in pycoin/key/Key.py to add P2TR address generation
  • Create test cases for P2TR address generation
  • Verify the implementation with manual testing
  • Run existing tests to ensure no regressions
  • Address code review feedback
  • Run security scan
  • Remove unnecessary legacy field per maintainer feedback
  • Replace unit test with ku text test case
  • Fix failing JSON test files

Summary

Successfully implemented P2TR (Pay-to-Taproot) address generation in the ku utility as requested in issue #421.

Implementation Details

Modified Files:

  • pycoin/key/Key.py: Added P2TR address generation in ku_output_for_address() method
  • tests/cmds/test_cases/ku/p2tr_address.txt: Created dedicated P2TR test case following BIP 350 test vectors
  • Updated 21 ku command-line test fixture files with expected P2TR output (16 text + 5 JSON)
  • Removed unit test from tests/key_test.py per maintainer feedback

How It Works:

  1. Checks if the network supports taproot (for_p2tr method exists)
  2. Extracts the x-only public key (32 bytes) from the public pair
  3. Generates the P2TR address using network.address.for_p2tr(x_only)
  4. Outputs only address_taproot field (no legacy {SYMBOL}_address_taproot field)

Example Output:

$ ku 1 -n BTC
...
Bitcoin taproot address      : bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0

Testing & Verification

✅ Created dedicated ku text test case (tests/cmds/test_cases/ku/p2tr_address.txt)
✅ All ku functionality tests pass (83/83 ku tests)
✅ Verified against BIP 350 test vectors
✅ Tested with Bitcoin mainnet, Litecoin, and Bitcoin testnet3
✅ Works with both private and public-only keys
✅ No security vulnerabilities found (CodeQL scan clean)
✅ Code review feedback addressed:

  • Removed unnecessary legacy field
  • Replaced unit test with ku text test case
  • Fixed all JSON test files

Note: 2 unrelated tx tests remain failing (test_tx_ignored_locktime_txt, test_tx_pay_to_opcode_list_txt) - these are pre-existing failures unrelated to P2TR changes.

Original prompt

The ku utility in pycoin currently generates several Bitcoin address types (P2PKH, P2WPKH, P2SH-wrapped SegWit), but it does not generate P2TR (Pay-to-Taproot) addresses.

Issue #421: Feature request | generate bitcoin p2tr address in ku utility

The request is to add P2TR address generation support to the ku utility. The pycoin library already has P2TR support in the networks layer (AddressAPI.for_p2tr(), ContractAPI.for_p2tr()), but the Key class does not currently output P2TR addresses in its ku_output_for_address() method.

Solution:

  • Extend the ku_output_for_address() method in pycoin/key/Key.py to generate and output P2TR addresses when the network supports taproot
  • The P2TR address should be output alongside other address types like P2WPKH and P2SH-wrapped SegWit addresses
  • The implementation should follow the existing pattern used for other SegWit address types

Example output format should include:

address_taproot          : bc1p...
BTC_address_taproot      : bc1p...

This pull request was created from Copilot chat.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits December 22, 2025 15:41
Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
…ation

Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
Copilot AI changed the title [WIP] Add P2TR address generation to ku utility Add P2TR (taproot) address generation to ku utility Dec 22, 2025
Copilot AI requested a review from richardkiss December 22, 2025 15:52
address_taproot = self._network.address.for_p2tr(x_only)
if address_taproot:
yield ("address_taproot", address_taproot, "%s taproot address" % self._network.network_name)
yield ("%s_address_taproot" % self._network.symbol, address_taproot, "legacy")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot I don't think we need this one... it's just for "legacy".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in commit e36b11f. P2TR now only generates address_taproot without the legacy field.

"18fKPR8s1MQeckAsgya1sx6Z3WmFXd8wv8",
"1DVJQzgnyCahXdoXdJ3tjGA3hrYVgKpvgK")

def test_p2tr_address(self):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Can you instead just make this a new ku text test case, like the ones in tests/cmds/test_cases/ku/ ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in commit c037b48. Created tests/cmds/test_cases/ku/p2tr_address.txt and removed the unit test from tests/key_test.py.

@richardkiss
Copy link
Owner

@copilot tests are failing now too

Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
Copilot AI and others added 2 commits January 11, 2026 20:45
Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
Co-authored-by: richardkiss <5336+richardkiss@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 11, 2026

@copilot tests are failing now too

Fixed in commit 7c6df5e. Updated 5 JSON test files with the address_taproot field. All ku tests now pass (83/83). The 2 remaining failures (test_tx_ignored_locktime_txt, test_tx_pay_to_opcode_list_txt) are unrelated tx tests that were already failing.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • blockchain.info
    • Triggering command: /usr/bin/python3 python3 -m unittest tests.cmds.cmdline_test (dns block)
  • blockexplorer.com
    • Triggering command: /usr/bin/python3 python3 -m unittest tests.cmds.cmdline_test (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@richardkiss
Copy link
Owner

@copilot can you find a source that proves the p2tr test vector address is correct?

Copy link
Contributor Author

Copilot AI commented Jan 12, 2026

@copilot can you find a source that proves the p2tr test vector address is correct?

Yes, the P2TR test vector is proven correct by multiple authoritative sources:

  1. BIP 350 specification (https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki) - This address is an official test vector:

    • Address: bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0
    • Script: 512079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
  2. Already in pycoin's test suite - This exact test vector is in tests/bech32_test.py line 56, imported from BIP 350.

  3. SEC 2 v2.0 (https://www.secg.org/sec2-v2.pdf) - Section 2.7.1 defines the secp256k1 generator point G with x-coordinate 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798, which is the public key for secret exponent 1.

The address decodes correctly to witness version 1 (taproot) with the 32-byte x-only pubkey matching the generator point's x-coordinate.

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