Skip to content
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
ca0d937
Fixing pytest
F1r3Hydr4nt Nov 19, 2025
a9be91c
Modifications to get to zero failures
F1r3Hydr4nt Nov 19, 2025
8c2fdad
BRC-100 compatibility implemented and tested, 215 failures remaing
F1r3Hydr4nt Nov 20, 2025
184c3e5
ZERO failing tests, complaints about Permissions, Certificates, Chain…
F1r3Hydr4nt Nov 20, 2025
fb4f924
No failing tests
F1r3Hydr4nt Nov 20, 2025
c17c051
No failures
F1r3Hydr4nt Nov 20, 2025
4d7256f
More tests unskipped, need discussion
F1r3Hydr4nt Nov 21, 2025
c4e77e5
MISSING_FUNCTIONALITY_MODULES.md
F1r3Hydr4nt Nov 21, 2025
62bed1d
Full comparison
F1r3Hydr4nt Nov 21, 2025
dbeac2a
Started on coverage, no warnings, 59%
F1r3Hydr4nt Nov 27, 2025
7d74b61
Added coverage now at 64%
F1r3Hydr4nt Nov 27, 2025
d35a4bd
65.68%
F1r3Hydr4nt Nov 28, 2025
d8f5f22
Added brc29 implementation
F1r3Hydr4nt Nov 28, 2025
3f0ade3
67.95%
F1r3Hydr4nt Nov 28, 2025
89f8c03
>70%
F1r3Hydr4nt Nov 28, 2025
903520c
Removing helper files
F1r3Hydr4nt Nov 28, 2025
6d2ff88
Skipped tests improvement
F1r3Hydr4nt Dec 1, 2025
bff4d64
Saving to new branch
F1r3Hydr4nt Dec 1, 2025
cff6142
Saving for day
F1r3Hydr4nt Dec 1, 2025
c0771b5
pytest -x --cov --cov-report=html --cov-report=term 793
F1r3Hydr4nt Dec 2, 2025
40c4bc9
Utils down to go
F1r3Hydr4nt Dec 2, 2025
004fdb1
No failures!
F1r3Hydr4nt Dec 2, 2025
e8c1e70
71%
F1r3Hydr4nt Dec 2, 2025
8058852
All tests passing again
F1r3Hydr4nt Dec 3, 2025
b8c1e45
Removing inter files
F1r3Hydr4nt Dec 3, 2025
037d97e
All tests passing
F1r3Hydr4nt Dec 3, 2025
eff3b05
All tests passing
F1r3Hydr4nt Dec 3, 2025
9c6ea4a
Passing again
F1r3Hydr4nt Dec 3, 2025
a80b6db
More unskipped
F1r3Hydr4nt Dec 3, 2025
fce0a93
Really good comparison result
F1r3Hydr4nt Dec 3, 2025
df6c95a
Go parity, needs better testing
F1r3Hydr4nt Dec 3, 2025
17cf901
Cleanup
F1r3Hydr4nt Dec 3, 2025
d7f4d38
Fixing GH CodeQL issues
F1r3Hydr4nt Dec 3, 2025
4cd65bd
Potential fix for code scanning alert no. 1: Information exposure thr…
F1r3Hydr4nt Dec 3, 2025
f093aeb
Potential fix for code scanning alert no. 4: Information exposure thr…
F1r3Hydr4nt Dec 3, 2025
6a2bb4d
Update src/bsv_wallet_toolbox/storage/provider.py
F1r3Hydr4nt Dec 3, 2025
3210823
Update src/bsv_wallet_toolbox/signer/methods.py
F1r3Hydr4nt Dec 3, 2025
d10d7f3
Update src/bsv_wallet_toolbox/utils/validation.py
F1r3Hydr4nt Dec 3, 2025
716c571
Update src/bsv_wallet_toolbox/storage/provider.py
F1r3Hydr4nt Dec 3, 2025
f11f6ae
Small fixes to circumnavigate Github changes
F1r3Hydr4nt Dec 4, 2025
c12f25b
Update src/bsv_wallet_toolbox/utils/validation.py
F1r3Hydr4nt Dec 4, 2025
b56f671
Addressed code smell and pagination negative offset concerns
F1r3Hydr4nt Dec 4, 2025
3e11012
Update src/bsv_wallet_toolbox/utils/validation.py
F1r3Hydr4nt Dec 4, 2025
48ff14e
Update src/bsv_wallet_toolbox/storage/provider.py
F1r3Hydr4nt Dec 4, 2025
92172a2
Update src/bsv_wallet_toolbox/services/services.py
F1r3Hydr4nt Dec 4, 2025
3d61059
Update src/bsv_wallet_toolbox/signer/methods.py
F1r3Hydr4nt Dec 4, 2025
6009991
import examples from Go examples (WIP)
jo7ueb Dec 4, 2025
a1b413c
Merge branch 'master' into develop
jo7ueb Dec 4, 2025
d137a82
resolve conflict
jo7ueb Dec 4, 2025
bdb8acf
fix for failing test
jo7ueb Dec 4, 2025
ea9fa46
Apply suggestions from code review
F1r3Hydr4nt Dec 4, 2025
3590986
no_send_with_change var rename
F1r3Hydr4nt Dec 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions examples/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Example entrypoint package for py-wallet-toolbox.

This allows running examples as modules, e.g.:

python -m examples.from_go.wallet_examples.create_data_tx.create_data_tx
"""


1 change: 1 addition & 0 deletions examples/from_go/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
examples-config.yaml
151 changes: 151 additions & 0 deletions examples/from_go/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
## Python Wallet Toolbox Examples (Go-port set)

This `examples/from_go` directory contains Python ports of the examples from the Go wallet toolbox.
All examples are intended to be executed **with this directory as the current working directory**.

### 1. Virtual environment and dependencies

```bash
cd toolbox/py-wallet-toolbox/examples/from_go

python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate

pip install -r requirements.txt

# Make this directory importable as the root for examples
```

`requirements.txt` contains the libraries required to run the examples, plus the toolbox package itself via `-e ../..`.

### 2. How to run examples (script mode as default)

All examples are expected to be run **from `examples/from_go`**.

#### 2-1. Run as scripts (recommended)

```bash
cd toolbox/py-wallet-toolbox/examples/from_go
source .venv/bin/activate

# Example: create a data transaction (OP_RETURN)
python wallet_examples/create_data_tx/create_data_tx.py

# Example: check wallet balance
python wallet_examples/get_balance/get_balance.py

# Example: show faucet receive address
python wallet_examples/show_address_for_tx_from_faucet/show_address_for_tx_from_faucet.py
```

> Note: You can also run them as modules, e.g. `python -m wallet_examples.create_data_tx`,
> but for day-to-day usage the simple “run the script file” pattern above is usually enough.

Every script uses `from internal import setup, show` to share common setup and logging helpers from `internal/`.

---

### 3. Recommended execution order (scenario-based)

There are many samples under `wallet_examples/`.
If you want a guided path, **start with the following order**:

> Assumption: You have already done
> `cd toolbox/py-wallet-toolbox/examples/from_go` and activated `.venv`.

#### 3-1. Get test funds from a faucet

1. **Show faucet address**

```bash
python wallet_examples/show_address_for_tx_from_faucet/show_address_for_tx_from_faucet.py
```

- Copy the address printed to the console.
- Use a testnet faucet (e.g. a public web faucet for BSV testnet) to **manually send** coins to that address.

2. **Internalize the faucet transaction into the wallet**

```bash
python wallet_examples/internalize_tx_from_faucet/internalize_tx_from_faucet.py
```

- Before running, edit the script and set `TX_ID` at the top to the transaction ID of the faucet payment
(as seen in your block explorer).

#### 3-2. Inspect balance and UTXOs

3. **Check balance**

```bash
python wallet_examples/get_balance/get_balance.py
```

4. **List UTXOs (outputs)**

```bash
python wallet_examples/list_outputs/list_outputs.py
```

5. **Inspect action history**

```bash
python wallet_examples/list_actions/list_actions.py
python wallet_examples/list_failed_actions/list_failed_actions.py
```

#### 3-3. Create and broadcast transactions

6. **Create a data transaction (OP_RETURN)**

```bash
python wallet_examples/create_data_tx/create_data_tx.py
```

- This requires that the wallet already has funds (from the faucet step).
- You can change `DATA_TO_EMBED` in the script to embed arbitrary text.

7. **Create a P2PKH payment**

```bash
# Edit the script first: set RECIPIENT_ADDRESS and SATOSHIS_TO_SEND
python wallet_examples/create_p2pkh_tx/create_p2pkh_tx.py
```

- Set `RECIPIENT_ADDRESS` to the destination address and `SATOSHIS_TO_SEND` to the amount you want to send.

#### 3-4. Encryption / decryption samples

8. **Encrypt / Decrypt**

```bash
# Encryption sample
python wallet_examples/encrypt/encrypt.py

# Decryption sample
# -> First, take the ciphertext produced by the encrypt example
# and paste it into the CIPHERTEXT variable in decrypt.py
python wallet_examples/decrypt/decrypt.py
```

#### 3-5. Advanced samples (optional)

9. **Internalize a wallet payment (BRC-29 style)**

```bash
# Fill in ATOMIC_BEEF_HEX / PREFIX / SUFFIX / IDENTITY_KEY
# according to your actual BRC-29 payment flow before running
python wallet_examples/internalize_wallet_payment/internalize_wallet_payment.py
```

10. **Batch send using NoSend + SendWith**

```bash
python wallet_examples/no_send_send_with/no_send_send_with.py
```

- This demonstrates creating multiple transactions with the `noSend` option
and then broadcasting them together with `sendWith`.
- You will again need sufficient wallet balance for all the mints and redeems.


8 changes: 8 additions & 0 deletions examples/from_go/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Go-port examples for py-wallet-toolbox.

These can be executed as Python modules, for example:

python -m examples.from_go.wallet_examples.show_address_for_tx_from_faucet.show_address_for_tx_from_faucet
"""


8 changes: 8 additions & 0 deletions examples/from_go/internal/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Shared helpers for Go-port examples (setup, show, etc.).

This package is intended to be imported from modules under `examples.from_go`,
e.g. `from examples.from_go import internal` or
`from examples.from_go.internal import setup, show`.
"""


72 changes: 72 additions & 0 deletions examples/from_go/internal/services_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""Helpers for interacting with wallet services in the Go-port examples."""

from __future__ import annotations

from typing import Any

from bsv.merkle_path import MerklePath as PyMerklePath
from bsv.transaction.beef import BEEF_V2, Beef
from bsv.transaction.beef_builder import merge_bump, merge_raw_tx
from bsv.transaction.beef_serialize import to_binary_atomic
from bsv_wallet_toolbox.services import Services
from bsv_wallet_toolbox.utils.merkle_path_utils import convert_proof_to_merkle_path


def normalize_chain(network: str) -> str:
"""Map toolbox environment network names to Services chain names."""
normalized = (network or "").lower()
if normalized in {"main", "mainnet", "livenet"}:
return "main"
return "test"


def create_services(network: str) -> Services:
"""Create a Services instance for the provided toolbox environment network."""
chain = normalize_chain(network)
return Services(chain)


def build_atomic_beef_for_txid(services: Services, txid: str) -> bytes:
"""Fetch raw tx + merkle path for txid and return Atomic BEEF bytes."""
raw_hex = services.get_raw_tx(txid)
if not raw_hex:
raise RuntimeError(f"Failed to fetch raw transaction for txid '{txid}'")

beef = Beef(version=BEEF_V2)

merkle_result = services.get_merkle_path_for_transaction(txid)
merkle_path = _convert_merkle_result(txid, merkle_result)
bump_index = merge_bump(beef, merkle_path) if merkle_path else None

merge_raw_tx(beef, bytes.fromhex(raw_hex), bump_index)
return to_binary_atomic(beef, txid)


def _convert_merkle_result(txid: str, result: dict[str, Any]) -> PyMerklePath | None:
"""Convert services.get_merkle_path_for_transaction result into MerklePath."""
if not isinstance(result, dict):
return None

proof = result.get("merklePath") or {}
if not isinstance(proof, dict):
return None

# WhatsOnChain returns blockHeight/path which already matches py-sdk expectations
if "blockHeight" in proof and "path" in proof:
return PyMerklePath(proof["blockHeight"], proof["path"])

nodes = proof.get("nodes")
index = proof.get("index")
height = proof.get("height")

header = result.get("header")
if height is None and isinstance(header, dict):
height = header.get("height")

if nodes is None or index is None or height is None:
return None

tsc_proof = {"height": height, "index": index, "nodes": nodes}
mp_dict = convert_proof_to_merkle_path(txid, tsc_proof)
return PyMerklePath(mp_dict["blockHeight"], mp_dict["path"])

Loading