btcaaron 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {btcaaron-0.2.0 → btcaaron-0.2.2}/PKG-INFO +82 -22
- btcaaron-0.2.2/README.md +212 -0
- {btcaaron-0.2.0 → btcaaron-0.2.2}/btcaaron/__init__.py +9 -2
- btcaaron-0.2.2/btcaaron/explain/__init__.py +8 -0
- btcaaron-0.2.2/btcaaron/explain/program.py +55 -0
- btcaaron-0.2.2/btcaaron/explain/transaction.py +53 -0
- {btcaaron-0.2.0 → btcaaron-0.2.2}/btcaaron/key.py +28 -2
- {btcaaron-0.2.0 → btcaaron-0.2.2}/btcaaron/legacy.py +106 -23
- btcaaron-0.2.2/btcaaron/network/__init__.py +16 -0
- btcaaron-0.2.2/btcaaron/network/blockstream.py +68 -0
- btcaaron-0.2.2/btcaaron/network/mempool.py +73 -0
- btcaaron-0.2.2/btcaaron/network/provider.py +51 -0
- btcaaron-0.2.2/btcaaron/network/utxo.py +90 -0
- btcaaron-0.2.2/btcaaron/psbt.py +734 -0
- btcaaron-0.2.2/btcaaron/script/__init__.py +7 -0
- btcaaron-0.2.2/btcaaron/script/script.py +103 -0
- btcaaron-0.2.2/btcaaron/spend/__init__.py +8 -0
- btcaaron-0.2.2/btcaaron/spend/builder.py +463 -0
- btcaaron-0.2.2/btcaaron/spend/transaction.py +177 -0
- btcaaron-0.2.2/btcaaron/tree/__init__.py +11 -0
- btcaaron-0.2.2/btcaaron/tree/builder.py +238 -0
- btcaaron-0.2.2/btcaaron/tree/leaf.py +49 -0
- btcaaron-0.2.2/btcaaron/tree/program.py +294 -0
- btcaaron-0.2.2/btcaaron/tree/tapmath.py +132 -0
- {btcaaron-0.2.0 → btcaaron-0.2.2}/btcaaron.egg-info/PKG-INFO +82 -22
- btcaaron-0.2.2/btcaaron.egg-info/SOURCES.txt +36 -0
- btcaaron-0.2.2/btcaaron.egg-info/entry_points.txt +2 -0
- btcaaron-0.2.2/btcaaron.egg-info/requires.txt +2 -0
- btcaaron-0.2.2/setup.py +50 -0
- {btcaaron-0.2.0 → btcaaron-0.2.2}/tests/test_btcaaron_v02.py +438 -1
- btcaaron-0.2.0/README.md +0 -157
- btcaaron-0.2.0/btcaaron.egg-info/SOURCES.txt +0 -16
- btcaaron-0.2.0/btcaaron.egg-info/requires.txt +0 -2
- btcaaron-0.2.0/setup.py +0 -27
- {btcaaron-0.2.0 → btcaaron-0.2.2}/btcaaron/btcaaron.py +0 -0
- {btcaaron-0.2.0 → btcaaron-0.2.2}/btcaaron/errors.py +0 -0
- {btcaaron-0.2.0 → btcaaron-0.2.2}/btcaaron.egg-info/dependency_links.txt +0 -0
- {btcaaron-0.2.0 → btcaaron-0.2.2}/btcaaron.egg-info/top_level.txt +0 -0
- {btcaaron-0.2.0 → btcaaron-0.2.2}/setup.cfg +0 -0
- {btcaaron-0.2.0 → btcaaron-0.2.2}/tests/test_btcaaron_v01.py +0 -0
- {btcaaron-0.2.0 → btcaaron-0.2.2}/tests/test_btcaaron_v01_cpfp.py +0 -0
- {btcaaron-0.2.0 → btcaaron-0.2.2}/tests/test_rawscript_tapmath.py +0 -0
|
@@ -1,44 +1,50 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: btcaaron
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A Bitcoin Testnet transaction toolkit supporting Legacy, SegWit, and Taproot
|
|
5
5
|
Home-page: https://x.com/aaron_recompile
|
|
6
6
|
Author: Aaron Zhang
|
|
7
7
|
Author-email: aaron.recompile@gmail.com
|
|
8
|
+
Keywords: bitcoin,taproot,tapscript,bip341,bip342,schnorr,p2tr,taptree,script-path,miniscript,psbt,regtest,testnet
|
|
8
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
9
13
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
14
|
Classifier: Operating System :: OS Independent
|
|
11
15
|
Classifier: Development Status :: 3 - Alpha
|
|
12
16
|
Classifier: Intended Audience :: Developers
|
|
13
17
|
Classifier: Topic :: Software Development :: Libraries
|
|
14
|
-
Classifier: Topic ::
|
|
15
|
-
Requires-Python: >=3.
|
|
18
|
+
Classifier: Topic :: Security :: Cryptography
|
|
19
|
+
Requires-Python: >=3.10,<3.13
|
|
16
20
|
Description-Content-Type: text/markdown
|
|
17
|
-
Requires-Dist: requests
|
|
18
|
-
Requires-Dist: bitcoin-utils
|
|
21
|
+
Requires-Dist: requests<3.0.0,>=2.25.0
|
|
22
|
+
Requires-Dist: bitcoin-utils<0.8.0,>=0.7.3
|
|
19
23
|
Dynamic: author
|
|
20
24
|
Dynamic: author-email
|
|
21
25
|
Dynamic: classifier
|
|
22
26
|
Dynamic: description
|
|
23
27
|
Dynamic: description-content-type
|
|
24
28
|
Dynamic: home-page
|
|
29
|
+
Dynamic: keywords
|
|
25
30
|
Dynamic: requires-dist
|
|
26
31
|
Dynamic: requires-python
|
|
27
32
|
Dynamic: summary
|
|
28
33
|
|
|
29
34
|
# btcaaron<img src="images/mark.png" width="52" alt="btcaaron mark" style="margin-left:4px;vertical-align:middle" />
|
|
30
35
|
|
|
36
|
+
[](https://opensats.org)
|
|
37
|
+
|
|
31
38
|
A pragmatic Bitcoin toolkit with a clear path toward full Taproot engineering.
|
|
32
39
|
|
|
33
40
|
Designed for reproducible testnet experiments, educational workflows, and script-path development.
|
|
34
41
|
|
|
35
|
-
|
|
42
|
+
If you find btcaaron useful, a GitHub star is appreciated.
|
|
36
43
|
|
|
37
|
-
|
|
38
|
-
Core utilities actively used in my Taproot engineering work and on-chain experiments.
|
|
44
|
+
## Current Status
|
|
39
45
|
|
|
40
|
-
**v0.2.
|
|
41
|
-
|
|
46
|
+
**v0.2.2 (alpha preview)** — Core Taproot spend-path workflows are implemented and testnet/regtest-verified.
|
|
47
|
+
Current focus is release hardening: broader validation coverage, documentation alignment, and contributor testing feedback.
|
|
42
48
|
|
|
43
49
|
## Features
|
|
44
50
|
|
|
@@ -52,7 +58,7 @@ Production-tested on testnet with real transactions:
|
|
|
52
58
|
- Broadcast to Blockstream / Mempool endpoints
|
|
53
59
|
- Developer helpers (`WIFKey`, `quick_transfer`)
|
|
54
60
|
|
|
55
|
-
### Available Now (v0.2.
|
|
61
|
+
### Available Now (v0.2.2 - Alpha Preview)
|
|
56
62
|
|
|
57
63
|
Testnet-verified with real transactions (23 tests, all passing):
|
|
58
64
|
|
|
@@ -64,19 +70,34 @@ Testnet-verified with real transactions (23 tests, all passing):
|
|
|
64
70
|
|
|
65
71
|
### Future (v0.3.x+)
|
|
66
72
|
|
|
67
|
-
- PSBT v2
|
|
73
|
+
- PSBT v2 hardening and broader interoperability validation
|
|
68
74
|
- Custom script templates
|
|
69
75
|
- Multi-input/output transactions
|
|
70
76
|
|
|
77
|
+
## Positioning (Quick Comparison)
|
|
78
|
+
|
|
79
|
+
> High-level developer-experience comparison only (not a full feature matrix).
|
|
80
|
+
|
|
81
|
+
| Library | Typical Use Case | Script-Path UX |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| `python-bitcoin-utils` | Low-level transaction/script construction and protocol experiments | Manual (build tree/witness/control-block flow yourself) |
|
|
84
|
+
| `btcaaron` | Fast Taproot prototyping, teaching workflows, and reproducible test scaffolds | Declarative (e.g., `.hashlock()`, `.multisig()`, `.timelock()`) |
|
|
85
|
+
| `BitcoinLib` | Wallet-oriented workflows, account management, and persistence layers | Mostly automated for common wallet flows |
|
|
86
|
+
| `embit` | Descriptor/PSBT flows and hardware-wallet-oriented integrations | Descriptor-oriented, standard-policy paths |
|
|
87
|
+
|
|
88
|
+
_Optional note_: `btcaaron` is designed as a pragmatic Taproot engineering layer on top of low-level primitives, prioritizing readability and reproducible testing workflows.
|
|
89
|
+
|
|
71
90
|
## Requirements
|
|
72
91
|
|
|
73
|
-
- Python
|
|
74
|
-
- Dependencies:
|
|
92
|
+
- Python `>=3.10,<3.13`
|
|
93
|
+
- Dependencies:
|
|
94
|
+
- `requests>=2.25.0,<3.0.0`
|
|
95
|
+
- `bitcoin-utils>=0.7.3,<0.8.0`
|
|
75
96
|
|
|
76
97
|
## Installation
|
|
77
98
|
|
|
78
99
|
```bash
|
|
79
|
-
pip install btcaaron
|
|
100
|
+
python -m pip install btcaaron
|
|
80
101
|
```
|
|
81
102
|
|
|
82
103
|
Or from source:
|
|
@@ -84,7 +105,17 @@ Or from source:
|
|
|
84
105
|
```bash
|
|
85
106
|
git clone https://github.com/aaron-recompile/btcaaron.git
|
|
86
107
|
cd btcaaron
|
|
87
|
-
pip install .
|
|
108
|
+
python -m pip install -e .
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### IDE environment tip (important)
|
|
112
|
+
|
|
113
|
+
Most IDE terminals run `python`/`python3` from the currently selected interpreter.
|
|
114
|
+
Install and run with the same interpreter to avoid mismatched environments:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
python -m pip install -e .
|
|
118
|
+
btcaaron-doctor
|
|
88
119
|
```
|
|
89
120
|
|
|
90
121
|
## Quick Start
|
|
@@ -105,7 +136,7 @@ if balance > 1000:
|
|
|
105
136
|
print("Broadcasted:", txid)
|
|
106
137
|
```
|
|
107
138
|
|
|
108
|
-
## v0.2.
|
|
139
|
+
## v0.2.2 API Example
|
|
109
140
|
|
|
110
141
|
*Taproot-native API — core features available now.*
|
|
111
142
|
|
|
@@ -124,6 +155,10 @@ program = (TapTree(internal_key=alice)
|
|
|
124
155
|
|
|
125
156
|
print(program.address) # tb1p...
|
|
126
157
|
|
|
158
|
+
# Fund commit address without leaving IDE (auto UTXO selection)
|
|
159
|
+
from btcaaron import fund_program
|
|
160
|
+
# txid = fund_program(wif, program, 10_000) # 打币到 program.address
|
|
161
|
+
|
|
127
162
|
tx = (program.spend("hash")
|
|
128
163
|
.from_utxo("abc123...", 0, sats=1200)
|
|
129
164
|
.to("tb1p...", 666)
|
|
@@ -146,11 +181,26 @@ python -m pytest tests/
|
|
|
146
181
|
Run specific test suites:
|
|
147
182
|
|
|
148
183
|
```bash
|
|
149
|
-
# v0.2.
|
|
150
|
-
python -m pytest tests/
|
|
184
|
+
# v0.2.2 comprehensive tests (pytest)
|
|
185
|
+
python -m pytest tests/test_btcaaron_v02.py -v
|
|
151
186
|
|
|
152
187
|
# v0.1.x example-based tests
|
|
153
|
-
python tests/
|
|
188
|
+
python tests/test_btcaaron_v01.py
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Environment Doctor
|
|
192
|
+
|
|
193
|
+
Use doctor before reporting install/runtime issues:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
btcaaron-doctor
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
If doctor fails, re-install with the same interpreter:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
python -m pip install -e .
|
|
203
|
+
btcaaron-doctor
|
|
154
204
|
```
|
|
155
205
|
|
|
156
206
|
## Project Structure
|
|
@@ -171,8 +221,18 @@ See [DESIGN.md](./DESIGN.md) for architecture details and development roadmap.
|
|
|
171
221
|
|
|
172
222
|
## Notes
|
|
173
223
|
|
|
174
|
-
- **
|
|
175
|
-
- **
|
|
224
|
+
- **Default safety posture**: testnet/regtest-first for everyday development and experiments.
|
|
225
|
+
- **Mainnet (experimental)**: available behind explicit guardrails in `Transaction.broadcast(...)`.
|
|
226
|
+
- **Mainnet guardrails**:
|
|
227
|
+
- default call blocks mainnet broadcast unless `allow_mainnet=True`
|
|
228
|
+
- `dry_run=True` is available for no-side-effect routing checks
|
|
229
|
+
- recommended smoke script: `python3 examples/core_test/scenarios/mainnet_readiness_smoke.py`
|
|
230
|
+
- **v0.2.2 Status**: Core Taproot spend-path flows are implemented and testnet-verified; ongoing work focuses on hardening, PSBT, and documentation.
|
|
231
|
+
|
|
232
|
+
## Acknowledgments
|
|
233
|
+
|
|
234
|
+
Development of btcaaron is supported by an [OpenSats](https://opensats.org) grant.
|
|
235
|
+
OpenSats supports open-source contributors working on Bitcoin and related freedom tech.
|
|
176
236
|
|
|
177
237
|
## Author
|
|
178
238
|
|
btcaaron-0.2.2/README.md
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# btcaaron<img src="images/mark.png" width="52" alt="btcaaron mark" style="margin-left:4px;vertical-align:middle" />
|
|
2
|
+
|
|
3
|
+
[](https://opensats.org)
|
|
4
|
+
|
|
5
|
+
A pragmatic Bitcoin toolkit with a clear path toward full Taproot engineering.
|
|
6
|
+
|
|
7
|
+
Designed for reproducible testnet experiments, educational workflows, and script-path development.
|
|
8
|
+
|
|
9
|
+
If you find btcaaron useful, a GitHub star is appreciated.
|
|
10
|
+
|
|
11
|
+
## Current Status
|
|
12
|
+
|
|
13
|
+
**v0.2.2 (alpha preview)** — Core Taproot spend-path workflows are implemented and testnet/regtest-verified.
|
|
14
|
+
Current focus is release hardening: broader validation coverage, documentation alignment, and contributor testing feedback.
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
### Available Now (v0.1.x)
|
|
19
|
+
|
|
20
|
+
Production-tested on testnet with real transactions:
|
|
21
|
+
|
|
22
|
+
- Generate Legacy / SegWit / Taproot addresses from WIF
|
|
23
|
+
- UTXO scanning and balance lookup via public APIs
|
|
24
|
+
- Build and sign standard transactions
|
|
25
|
+
- Broadcast to Blockstream / Mempool endpoints
|
|
26
|
+
- Developer helpers (`WIFKey`, `quick_transfer`)
|
|
27
|
+
|
|
28
|
+
### Available Now (v0.2.2 - Alpha Preview)
|
|
29
|
+
|
|
30
|
+
Testnet-verified with real transactions (23 tests, all passing):
|
|
31
|
+
|
|
32
|
+
- Declarative Taproot tree builder (`.hashlock()`, `.multisig()`, `.timelock()`, `.checksig()`)
|
|
33
|
+
- Script-path and key-path spend constructors
|
|
34
|
+
- Automatic witness construction and signature ordering
|
|
35
|
+
- All 5 spend paths verified: hashlock, multisig, checksig, CSV timelock, keypath
|
|
36
|
+
- Real transaction TXID reproduction tests
|
|
37
|
+
|
|
38
|
+
### Future (v0.3.x+)
|
|
39
|
+
|
|
40
|
+
- PSBT v2 hardening and broader interoperability validation
|
|
41
|
+
- Custom script templates
|
|
42
|
+
- Multi-input/output transactions
|
|
43
|
+
|
|
44
|
+
## Positioning (Quick Comparison)
|
|
45
|
+
|
|
46
|
+
> High-level developer-experience comparison only (not a full feature matrix).
|
|
47
|
+
|
|
48
|
+
| Library | Typical Use Case | Script-Path UX |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `python-bitcoin-utils` | Low-level transaction/script construction and protocol experiments | Manual (build tree/witness/control-block flow yourself) |
|
|
51
|
+
| `btcaaron` | Fast Taproot prototyping, teaching workflows, and reproducible test scaffolds | Declarative (e.g., `.hashlock()`, `.multisig()`, `.timelock()`) |
|
|
52
|
+
| `BitcoinLib` | Wallet-oriented workflows, account management, and persistence layers | Mostly automated for common wallet flows |
|
|
53
|
+
| `embit` | Descriptor/PSBT flows and hardware-wallet-oriented integrations | Descriptor-oriented, standard-policy paths |
|
|
54
|
+
|
|
55
|
+
_Optional note_: `btcaaron` is designed as a pragmatic Taproot engineering layer on top of low-level primitives, prioritizing readability and reproducible testing workflows.
|
|
56
|
+
|
|
57
|
+
## Requirements
|
|
58
|
+
|
|
59
|
+
- Python `>=3.10,<3.13`
|
|
60
|
+
- Dependencies:
|
|
61
|
+
- `requests>=2.25.0,<3.0.0`
|
|
62
|
+
- `bitcoin-utils>=0.7.3,<0.8.0`
|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
python -m pip install btcaaron
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Or from source:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
git clone https://github.com/aaron-recompile/btcaaron.git
|
|
74
|
+
cd btcaaron
|
|
75
|
+
python -m pip install -e .
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### IDE environment tip (important)
|
|
79
|
+
|
|
80
|
+
Most IDE terminals run `python`/`python3` from the currently selected interpreter.
|
|
81
|
+
Install and run with the same interpreter to avoid mismatched environments:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
python -m pip install -e .
|
|
85
|
+
btcaaron-doctor
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Quick Start
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from btcaaron import WIFKey, quick_transfer
|
|
92
|
+
|
|
93
|
+
wif = "your_testnet_wif"
|
|
94
|
+
|
|
95
|
+
key = WIFKey(wif)
|
|
96
|
+
print("Taproot:", key.get_taproot().address)
|
|
97
|
+
|
|
98
|
+
balance = key.get_taproot().get_balance()
|
|
99
|
+
print("Balance:", balance, "sats")
|
|
100
|
+
|
|
101
|
+
if balance > 1000:
|
|
102
|
+
txid = quick_transfer(wif, "taproot", "tb1q...", amount=500, fee=300)
|
|
103
|
+
print("Broadcasted:", txid)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## v0.2.2 API Example
|
|
107
|
+
|
|
108
|
+
*Taproot-native API — core features available now.*
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from btcaaron import Key, TapTree
|
|
112
|
+
|
|
113
|
+
alice = Key.from_wif("cRxebG...")
|
|
114
|
+
bob = Key.from_wif("cSNdLF...")
|
|
115
|
+
|
|
116
|
+
program = (TapTree(internal_key=alice)
|
|
117
|
+
.hashlock("secret", label="hash")
|
|
118
|
+
.multisig(2, [alice, bob], label="2of2")
|
|
119
|
+
.timelock(blocks=144, then=bob, label="csv")
|
|
120
|
+
.checksig(bob, label="backup")
|
|
121
|
+
).build()
|
|
122
|
+
|
|
123
|
+
print(program.address) # tb1p...
|
|
124
|
+
|
|
125
|
+
# Fund commit address without leaving IDE (auto UTXO selection)
|
|
126
|
+
from btcaaron import fund_program
|
|
127
|
+
# txid = fund_program(wif, program, 10_000) # 打币到 program.address
|
|
128
|
+
|
|
129
|
+
tx = (program.spend("hash")
|
|
130
|
+
.from_utxo("abc123...", 0, sats=1200)
|
|
131
|
+
.to("tb1p...", 666)
|
|
132
|
+
.unlock(preimage="secret")
|
|
133
|
+
.build())
|
|
134
|
+
|
|
135
|
+
tx.broadcast()
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Full specification in [DESIGN.md](./DESIGN.md).
|
|
139
|
+
|
|
140
|
+
## Testing
|
|
141
|
+
|
|
142
|
+
Run the test suite:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
python -m pytest tests/
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Run specific test suites:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# v0.2.2 comprehensive tests (pytest)
|
|
152
|
+
python -m pytest tests/test_btcaaron_v02.py -v
|
|
153
|
+
|
|
154
|
+
# v0.1.x example-based tests
|
|
155
|
+
python tests/test_btcaaron_v01.py
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Environment Doctor
|
|
159
|
+
|
|
160
|
+
Use doctor before reporting install/runtime issues:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
btcaaron-doctor
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
If doctor fails, re-install with the same interpreter:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
python -m pip install -e .
|
|
170
|
+
btcaaron-doctor
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Project Structure
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
btcaaron/
|
|
177
|
+
├── btcaaron/ # Core library
|
|
178
|
+
├── tests/ # Test suite
|
|
179
|
+
├── DESIGN.md # Architecture & roadmap
|
|
180
|
+
├── README.md
|
|
181
|
+
├── setup.py
|
|
182
|
+
└── LICENSE
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Development
|
|
186
|
+
|
|
187
|
+
See [DESIGN.md](./DESIGN.md) for architecture details and development roadmap.
|
|
188
|
+
|
|
189
|
+
## Notes
|
|
190
|
+
|
|
191
|
+
- **Default safety posture**: testnet/regtest-first for everyday development and experiments.
|
|
192
|
+
- **Mainnet (experimental)**: available behind explicit guardrails in `Transaction.broadcast(...)`.
|
|
193
|
+
- **Mainnet guardrails**:
|
|
194
|
+
- default call blocks mainnet broadcast unless `allow_mainnet=True`
|
|
195
|
+
- `dry_run=True` is available for no-side-effect routing checks
|
|
196
|
+
- recommended smoke script: `python3 examples/core_test/scenarios/mainnet_readiness_smoke.py`
|
|
197
|
+
- **v0.2.2 Status**: Core Taproot spend-path flows are implemented and testnet-verified; ongoing work focuses on hardening, PSBT, and documentation.
|
|
198
|
+
|
|
199
|
+
## Acknowledgments
|
|
200
|
+
|
|
201
|
+
Development of btcaaron is supported by an [OpenSats](https://opensats.org) grant.
|
|
202
|
+
OpenSats supports open-source contributors working on Bitcoin and related freedom tech.
|
|
203
|
+
|
|
204
|
+
## Author
|
|
205
|
+
|
|
206
|
+
**Aaron Zhang**
|
|
207
|
+
Reproducible Taproot experiments · Script engineering · Educational tooling
|
|
208
|
+
https://x.com/aaron_recompile
|
|
209
|
+
|
|
210
|
+
## License
|
|
211
|
+
|
|
212
|
+
MIT License
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
btcaaron - Taproot-focused Bitcoin Toolkit
|
|
3
3
|
|
|
4
4
|
v0.1.x API (legacy, still supported):
|
|
5
|
-
from btcaaron import WIFKey, quick_transfer
|
|
5
|
+
from btcaaron import WIFKey, quick_transfer, fund_program
|
|
6
6
|
|
|
7
7
|
v0.2.x API (new):
|
|
8
8
|
from btcaaron import Key, TapTree
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
__version__ = "0.2.
|
|
11
|
+
__version__ = "0.2.2"
|
|
12
12
|
|
|
13
13
|
# ══════════════════════════════════════════════════════════════════
|
|
14
14
|
# Legacy API (v0.1.x) - backward compatible
|
|
@@ -19,6 +19,7 @@ from .legacy import (
|
|
|
19
19
|
BTCTransaction,
|
|
20
20
|
wif_to_addresses,
|
|
21
21
|
quick_transfer,
|
|
22
|
+
fund_program,
|
|
22
23
|
)
|
|
23
24
|
|
|
24
25
|
# ══════════════════════════════════════════════════════════════════
|
|
@@ -28,6 +29,7 @@ from .key import Key
|
|
|
28
29
|
from .tree import TapTree, TaprootProgram, LeafDescriptor
|
|
29
30
|
from .spend import SpendBuilder, Transaction
|
|
30
31
|
from .script import Script, RawScript
|
|
32
|
+
from .psbt import Psbt, PsbtInput, PsbtV2, PsbtV2Input
|
|
31
33
|
from .errors import (
|
|
32
34
|
BtcAaronError,
|
|
33
35
|
BuildError,
|
|
@@ -45,6 +47,7 @@ __all__ = [
|
|
|
45
47
|
"BTCTransaction",
|
|
46
48
|
"wif_to_addresses",
|
|
47
49
|
"quick_transfer",
|
|
50
|
+
"fund_program",
|
|
48
51
|
|
|
49
52
|
# New API
|
|
50
53
|
"Key",
|
|
@@ -55,6 +58,10 @@ __all__ = [
|
|
|
55
58
|
"Transaction",
|
|
56
59
|
"Script",
|
|
57
60
|
"RawScript",
|
|
61
|
+
"Psbt",
|
|
62
|
+
"PsbtInput",
|
|
63
|
+
"PsbtV2",
|
|
64
|
+
"PsbtV2Input",
|
|
58
65
|
|
|
59
66
|
# Errors
|
|
60
67
|
"BtcAaronError",
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""
|
|
2
|
+
btcaaron.explain.program - Program explanation
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import List, Dict, Any, TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from ..tree.program import TaprootProgram
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class ProgramExplanation:
|
|
14
|
+
"""Structured explanation of a TaprootProgram."""
|
|
15
|
+
|
|
16
|
+
program: "TaprootProgram"
|
|
17
|
+
|
|
18
|
+
def to_text(self) -> str:
|
|
19
|
+
"""Generate human-readable text explanation."""
|
|
20
|
+
p = self.program
|
|
21
|
+
lines = [
|
|
22
|
+
"TaprootProgram",
|
|
23
|
+
f"├── Address: {p.address}",
|
|
24
|
+
f"├── Internal Key: {p.internal_key}",
|
|
25
|
+
f"└── Leaves ({p.num_leaves}):",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
for i, label in enumerate(p.leaves):
|
|
29
|
+
leaf = p.leaf(label)
|
|
30
|
+
prefix = " └──" if i == p.num_leaves - 1 else " ├──"
|
|
31
|
+
lines.append(f"{prefix} [{i}] \"{label}\": {leaf.script_type}")
|
|
32
|
+
|
|
33
|
+
return "\n".join(lines)
|
|
34
|
+
|
|
35
|
+
def to_markdown(self) -> str:
|
|
36
|
+
"""Generate Markdown explanation."""
|
|
37
|
+
return f"```\n{self.to_text()}\n```"
|
|
38
|
+
|
|
39
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
40
|
+
"""Generate dictionary representation."""
|
|
41
|
+
p = self.program
|
|
42
|
+
return {
|
|
43
|
+
"address": p.address,
|
|
44
|
+
"internal_key": p.internal_key,
|
|
45
|
+
"merkle_root": p.merkle_root,
|
|
46
|
+
"leaves": [
|
|
47
|
+
{
|
|
48
|
+
"label": leaf.label,
|
|
49
|
+
"index": leaf.index,
|
|
50
|
+
"script_type": leaf.script_type,
|
|
51
|
+
"script_hex": leaf.script_hex,
|
|
52
|
+
}
|
|
53
|
+
for leaf in [p.leaf(label) for label in p.leaves]
|
|
54
|
+
]
|
|
55
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
btcaaron.explain.transaction - Transaction explanation
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Dict, Any, TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from ..spend.transaction import Transaction
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class TransactionExplanation:
|
|
14
|
+
"""Structured explanation of a Transaction."""
|
|
15
|
+
|
|
16
|
+
tx: "Transaction"
|
|
17
|
+
|
|
18
|
+
def to_text(self) -> str:
|
|
19
|
+
"""Generate human-readable text explanation."""
|
|
20
|
+
t = self.tx
|
|
21
|
+
lines = [
|
|
22
|
+
"Transaction Details",
|
|
23
|
+
f"├── TXID: {t.txid}",
|
|
24
|
+
f"├── Size: {t.size} bytes",
|
|
25
|
+
f"├── Fee: {t.fee} sats ({t.fee_rate:.2f} sat/vB)",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
if t._leaf:
|
|
29
|
+
lines.append(f"├── Spend Path: Script Path, Leaf \"{t._leaf.label}\"")
|
|
30
|
+
else:
|
|
31
|
+
lines.append(f"├── Spend Path: Key Path")
|
|
32
|
+
|
|
33
|
+
lines.append(f"└── Outputs: {len(t._tx.outputs)}")
|
|
34
|
+
|
|
35
|
+
return "\n".join(lines)
|
|
36
|
+
|
|
37
|
+
def to_markdown(self) -> str:
|
|
38
|
+
"""Generate Markdown explanation."""
|
|
39
|
+
return f"```\n{self.to_text()}\n```"
|
|
40
|
+
|
|
41
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
42
|
+
"""Generate dictionary representation."""
|
|
43
|
+
t = self.tx
|
|
44
|
+
return {
|
|
45
|
+
"txid": t.txid,
|
|
46
|
+
"hex": t.hex,
|
|
47
|
+
"size": t.size,
|
|
48
|
+
"vsize": t.vsize,
|
|
49
|
+
"fee": t.fee,
|
|
50
|
+
"fee_rate": t.fee_rate,
|
|
51
|
+
"spend_type": "SCRIPT_PATH" if t._leaf else "KEY_PATH",
|
|
52
|
+
"leaf_label": t._leaf.label if t._leaf else None,
|
|
53
|
+
}
|
|
@@ -8,8 +8,33 @@ from typing import Optional
|
|
|
8
8
|
from bitcoinutils.setup import setup
|
|
9
9
|
from bitcoinutils.keys import PrivateKey
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
|
|
12
|
+
def _normalize_network(network: str) -> str:
|
|
13
|
+
"""
|
|
14
|
+
Normalize app-level network labels to bitcoinutils setup labels.
|
|
15
|
+
|
|
16
|
+
bitcoinutils distinguishes mainnet/testnet/regtest. For signet-family
|
|
17
|
+
networks we use testnet address/version rules.
|
|
18
|
+
"""
|
|
19
|
+
n = (network or "testnet").lower()
|
|
20
|
+
if n == "mainnet":
|
|
21
|
+
return "mainnet"
|
|
22
|
+
if n == "regtest":
|
|
23
|
+
return "regtest"
|
|
24
|
+
return "testnet"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def set_network(network: str) -> str:
|
|
28
|
+
"""
|
|
29
|
+
Set bitcoinutils global network context and return normalized value.
|
|
30
|
+
"""
|
|
31
|
+
normalized = _normalize_network(network)
|
|
32
|
+
setup(normalized)
|
|
33
|
+
return normalized
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# Default module context remains testnet-first.
|
|
37
|
+
set_network("testnet")
|
|
13
38
|
|
|
14
39
|
|
|
15
40
|
class Key:
|
|
@@ -79,6 +104,7 @@ class Key:
|
|
|
79
104
|
Returns:
|
|
80
105
|
Key instance
|
|
81
106
|
"""
|
|
107
|
+
set_network(network)
|
|
82
108
|
private_key = PrivateKey()
|
|
83
109
|
return cls(private_key)
|
|
84
110
|
|