diff --git a/.github/workflows/test-bdk-ffi-latest.yaml b/.github/workflows/test-bdk-ffi-latest.yaml index 0899fdb..93bd24e 100644 --- a/.github/workflows/test-bdk-ffi-latest.yaml +++ b/.github/workflows/test-bdk-ffi-latest.yaml @@ -58,7 +58,7 @@ jobs: key: ${{ runner.os }}-${{ hashFiles('**/Cargo.toml','**/Cargo.lock') }} - name: "Generate bdk.py and binaries" - run: bash ./scripts/generate-linux.sh + run: bash ./scripts/generate-linux.sh --skip-submodule-update - name: "Build wheel" run: UV_PYTHON=${PYBIN}/python uv build --wheel --config-setting=--build-option=--plat-name=manylinux_2_28_x86_64 --verbose @@ -107,7 +107,7 @@ jobs: python-version: ${{ matrix.python }} - name: "Generate bdk.py and binaries" - run: bash ./scripts/generate-macos-arm64.sh + run: bash ./scripts/generate-macos-arm64.sh --skip-submodule-update - name: "Build wheel" # Specifying the plat-name argument is necessary to build a wheel with the correct name, @@ -157,7 +157,7 @@ jobs: python-version: ${{ matrix.python }} - name: "Generate bdk.py and binaries" - run: bash ./scripts/generate-macos-x86_64.sh + run: bash ./scripts/generate-macos-x86_64.sh --skip-submodule-update - name: "Build wheel" run: uv build --wheel --config-setting=--build-option=--plat-name=macosx_11_0_x86_64 --verbose @@ -206,7 +206,7 @@ jobs: python-version: ${{ matrix.python }} - name: "Generate bdk.py and binaries" - run: bash ./scripts/generate-windows.sh + run: bash ./scripts/generate-windows.sh --skip-submodule-update - name: "Build wheel" run: uv build --wheel --verbose diff --git a/README.md b/README.md index 80d952c..465e333 100644 --- a/README.md +++ b/README.md @@ -13,15 +13,19 @@ This repository uses the bdk-ffi repository as a git submodule. Here are useful ## Local Testing and Usage -1. Sync dependencies with `uv` -2. Run one of the build script +1. Run one of the build script (skip the submodule update if you are making local changes to the bdk-ffi submodule) +2. Sync dependencies with `uv` 3. Create the wheel 4. Install the library 5. Run the tests ```sh -uv sync +# If you made changes to the bdk-ffi submodule and wish to use those instead of the committed hash +bash scripts/generate-macos-arm64.sh --skip-submodule-update +# Otherwise bash scripts/generate-macos-arm64.sh + +uv sync uv build --wheel -v uv pip install ./dist/bdkpython-.whl --force-reinstall uv run python -m unittest --verbose diff --git a/bdk-ffi b/bdk-ffi index 2946cc1..a10d668 160000 --- a/bdk-ffi +++ b/bdk-ffi @@ -1 +1 @@ -Subproject commit 2946cc1b9ce4899bfc14620f5275ce7e4969ce3e +Subproject commit a10d6685f94141d8565cc4d20e44cffeab77d222 diff --git a/pyproject.toml b/pyproject.toml index 6dfe9ad..80e1310 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "bdkpython" -version = "2.4.0.dev0" +version = "3.0.0a0" description = "The Python language bindings for the Bitcoin Development Kit" readme = "README.md" requires-python = ">=3.10" diff --git a/scripts/generate-linux.sh b/scripts/generate-linux.sh index 92b95a6..a4e87ee 100644 --- a/scripts/generate-linux.sh +++ b/scripts/generate-linux.sh @@ -3,13 +3,18 @@ set -euo pipefail printf "\nSubmodule check...\n" -git submodule update --init -printf "Submodule is checked out at commit: $(git submodule status)\n\n" +if [[ "${1:-}" != "--skip-submodule-update" ]]; then + git submodule update --init + printf "Submodule is checked out at commit: $(git submodule status)\n\n" +else + printf "Skipping submodule update, using local changes.\n" + printf "Submodule is checked out at commit: $(git submodule status)\n\n" +fi cd ./bdk-ffi/bdk-ffi/ echo "Generating native binaries..." -cargo build --profile release-smaller +cargo build --locked --profile release-smaller echo "Generating bdk.py..." cargo run --bin uniffi-bindgen generate --library ./target/release-smaller/libbdkffi.so --language python --out-dir ../../src/bdkpython/ --no-format diff --git a/scripts/generate-macos-arm64.sh b/scripts/generate-macos-arm64.sh index 0cd2c5d..e47e8b8 100644 --- a/scripts/generate-macos-arm64.sh +++ b/scripts/generate-macos-arm64.sh @@ -3,15 +3,20 @@ set -euo pipefail printf "\nSubmodule check...\n" -git submodule update --init -printf "Submodule is checked out at commit: $(git submodule status)\n\n" +if [[ "${1:-}" != "--skip-submodule-update" ]]; then + git submodule update --init + printf "Submodule is checked out at commit: $(git submodule status)\n\n" +else + printf "Skipping submodule update, using local changes.\n" + printf "Submodule is checked out at commit: $(git submodule status)\n\n" +fi cd ./bdk-ffi/bdk-ffi/ rustup target add aarch64-apple-darwin echo "Generating native binaries..." -cargo build --profile release-smaller --target aarch64-apple-darwin +cargo build --locked --profile release-smaller --target aarch64-apple-darwin echo "Generating bdk.py..." cargo run --bin uniffi-bindgen generate --library ./target/aarch64-apple-darwin/release-smaller/libbdkffi.dylib --language python --out-dir ../../src/bdkpython/ --no-format diff --git a/scripts/generate-macos-x86_64.sh b/scripts/generate-macos-x86_64.sh index 161339b..7ef7833 100644 --- a/scripts/generate-macos-x86_64.sh +++ b/scripts/generate-macos-x86_64.sh @@ -3,15 +3,20 @@ set -euo pipefail printf "\nSubmodule check...\n" -git submodule update --init -printf "Submodule is checked out at commit: $(git submodule status)\n\n" +if [[ "${1:-}" != "--skip-submodule-update" ]]; then + git submodule update --init + printf "Submodule is checked out at commit: $(git submodule status)\n\n" +else + printf "Skipping submodule update, using local changes.\n" + printf "Submodule is checked out at commit: $(git submodule status)\n\n" +fi cd ./bdk-ffi/bdk-ffi/ rustup target add x86_64-apple-darwin echo "Generating native binaries..." -cargo build --profile release-smaller --target x86_64-apple-darwin +cargo build --locked --profile release-smaller --target x86_64-apple-darwin echo "Generating bdk.py..." cargo run --bin uniffi-bindgen generate --library ./target/x86_64-apple-darwin/release-smaller/libbdkffi.dylib --language python --out-dir ../../src/bdkpython/ --no-format diff --git a/scripts/generate-windows.sh b/scripts/generate-windows.sh index 467db78..cbb2738 100644 --- a/scripts/generate-windows.sh +++ b/scripts/generate-windows.sh @@ -3,15 +3,20 @@ set -euo pipefail printf "\nSubmodule check...\n" -git submodule update --init -printf "Submodule is checked out at commit: $(git submodule status)\n\n" +if [[ "${1:-}" != "--skip-submodule-update" ]]; then + git submodule update --init + printf "Submodule is checked out at commit: $(git submodule status)\n\n" +else + printf "Skipping submodule update, using local changes.\n" + printf "Submodule is checked out at commit: $(git submodule status)\n\n" +fi cd ./bdk-ffi/bdk-ffi/ rustup target add x86_64-pc-windows-msvc echo "Generating native binaries..." -cargo build --profile release-smaller --target x86_64-pc-windows-msvc +cargo build --locked --profile release-smaller --target x86_64-pc-windows-msvc echo "Generating bdk.py..." cargo run --bin uniffi-bindgen generate --library ./target/x86_64-pc-windows-msvc/release-smaller/bdkffi.dll --language python --out-dir ../../src/bdkpython/ --no-format diff --git a/tests/test_offline_custom_persist.py b/tests/test_offline_custom_persist.py index d40c220..49d3281 100644 --- a/tests/test_offline_custom_persist.py +++ b/tests/test_offline_custom_persist.py @@ -4,19 +4,42 @@ import unittest from typing import Any, Dict, List, Optional -import bdkpython as bdk +from bdkpython import NetworkKind +from bdkpython import Descriptor +from bdkpython import ChangeSet +from bdkpython import Persistence +from bdkpython import Wallet +from bdkpython import Persister +from bdkpython import UnconfirmedTx +from bdkpython import Transaction +from bdkpython import Network +from bdkpython import BlockHash +from bdkpython import ChainChange +from bdkpython import LocalChainChangeSet +from bdkpython import HashableOutPoint +from bdkpython import TxOut +from bdkpython import Anchor +from bdkpython import BlockId +from bdkpython import TxGraphChangeSet +from bdkpython import IndexerChangeSet +from bdkpython import Script +from bdkpython import Txid +from bdkpython import OutPoint +from bdkpython import ConfirmationBlockTime +from bdkpython import DescriptorId + initial_txs = [ "0200000000010101d7eb881ab8cac7d6adc6a7f9aa13e694813d95330c7299cee3623e5d14bd590000000000fdffffff02c5e6c1010000000016001407103a1cccf6a1ea654bee964a4020d20c41fb055c819725010000001600146337ec04bf42015e5d077b90cae05c06925c491a0247304402206aae2bf32da4c3b71cb95e6633c22f9f5a4a4f459975965c0c39b0ab439737b702200c4b16d2029383190965b07adeb87e6d634c68c70d2742f25e456874e8dc273a012103930326d6d72f8663340ce4341d0d3bdb1a1c0734d46e5df8a3003ab6bb50073b00000000", "02000000000101b0db431cffebeeeeec19ee8a09a2ae4755722ea73232dbb99b8e754eaad6ac300100000000fdffffff024ad24201000000001600146a7b71a68b261b0b7c79e5bb00f0f3d65d5ae4a285ae542401000000160014e43ff61232ca20061ef1d241e73f322a149a23d902473044022059f4b2fa8b9da34dbb57e491f3d5b8a47a623d7e6ebc1b6adfe6d2be744c9640022073cfc8311c49a8d48d69076466d32be591d3c0092b965828cfbcaca69fd409c90121027aa62d03db46272fa31bc1a6cb095bb66bc5409dd74b25e88e3099d84a17a3e469000000", ] -descriptor: bdk.Descriptor = bdk.Descriptor( +descriptor: Descriptor = Descriptor( "wpkh([44250c36/84'/1'/0']tpubDCrUjjHLB1fxk1oRveETjw62z8jsUuqx7JkBUW44VBszGmcY3Eun3apwVcE5X2bfF5MsM3uvuQDed6Do33ZN8GiWcnj2QPqVDspFT1AyZJ9/0/*)", - bdk.Network.REGTEST, + NetworkKind.TEST, ) -change_descriptor: bdk.Descriptor = bdk.Descriptor( +change_descriptor: Descriptor = Descriptor( "wpkh([44250c36/84'/1'/0']tpubDCrUjjHLB1fxk1oRveETjw62z8jsUuqx7JkBUW44VBszGmcY3Eun3apwVcE5X2bfF5MsM3uvuQDed6Do33ZN8GiWcnj2QPqVDspFT1AyZJ9/1/*)", - bdk.Network.REGTEST, + NetworkKind.TEST, ) @@ -25,42 +48,42 @@ class ChangeSetConverter: @staticmethod - def to_dict(changeset: bdk.ChangeSet) -> Dict: + def to_dict(changeset: ChangeSet) -> Dict: """ - Serialize a bdk.ChangeSet into a JSON string. + Serialize a ChangeSet into a JSON string. """ - def _serialize_descriptor(descriptor: Optional[bdk.Descriptor]) -> Optional[str]: + def _serialize_descriptor(descriptor: Optional[Descriptor]) -> Optional[str]: if descriptor is None: return None return str(descriptor) - def _serialize_blockhash(bh: Optional[bdk.BlockHash]) -> Optional[str]: + def _serialize_blockhash(bh: Optional[BlockHash]) -> Optional[str]: if bh is None: return None return bh.serialize().hex() - def _serialize_chainchange(cc: bdk.ChainChange) -> Dict[str, Any]: + def _serialize_chainchange(cc: ChainChange) -> Dict[str, Any]: return {"height": cc.height, "hash": _serialize_blockhash(cc.hash)} - def _serialize_local_chain(local_chain: bdk.LocalChainChangeSet) -> Dict[str, Any]: + def _serialize_local_chain(local_chain: LocalChainChangeSet) -> Dict[str, Any]: return {"changes": [_serialize_chainchange(cc) for cc in local_chain.changes]} - def _serialize_tx(tx: bdk.Transaction) -> str: + def _serialize_tx(tx: Transaction) -> str: return tx.serialize().hex() - def _serialize_outpoint(hop: bdk.HashableOutPoint) -> Dict[str, Any]: + def _serialize_outpoint(hop: HashableOutPoint) -> Dict[str, Any]: op = hop.outpoint() txid_hex = op.txid.serialize().hex() return {"txid": txid_hex, "vout": op.vout} - def _serialize_txout(txout: bdk.TxOut) -> Dict[str, Any]: - # TxOut.script_pubkey is a bdk.Script instance - script_obj: bdk.Script = txout.script_pubkey + def _serialize_txout(txout: TxOut) -> Dict[str, Any]: + # TxOut.script_pubkey is a Script instance + script_obj: Script = txout.script_pubkey script_bytes = script_obj.to_bytes() return {"value": txout.value, "script_pubkey": script_bytes.hex()} - def _serialize_tx_graph(tx_graph: bdk.TxGraphChangeSet) -> Dict[str, Any]: + def _serialize_tx_graph(tx_graph: TxGraphChangeSet) -> Dict[str, Any]: txs_list = [_serialize_tx(tx) for tx in tx_graph.txs] txouts_dict: Dict[str, Dict[str, Any]] = {} @@ -94,7 +117,7 @@ def sort_key(t): txid_hex = str(txid_obj) last_seen_dict[txid_hex] = timestamp first_seen_dict: Dict[str, int] = {} - for txid_obj, height in sorted(tx_graph.first_seen.items(), key=sort_key): + for txid_obj, timestamp in sorted(tx_graph.first_seen.items(), key=sort_key): try: txid_hex = txid_obj.serialize().hex() except AttributeError: @@ -102,7 +125,7 @@ def sort_key(t): first_seen_dict[txid_hex] = timestamp last_evicted_dict: Dict[str, int] = {} - for txid_obj, height in sorted(tx_graph.last_evicted.items(), key=sort_key): + for txid_obj, timestamp in sorted(tx_graph.last_evicted.items(), key=sort_key): try: txid_hex = txid_obj.serialize().hex() except AttributeError: @@ -118,7 +141,7 @@ def sort_key(t): "last_evicted": last_evicted_dict, } - def _serialize_indexer(indexer: bdk.IndexerChangeSet) -> Dict[str, Any]: + def _serialize_indexer(indexer: IndexerChangeSet) -> Dict[str, Any]: lr: Dict[str, int] = {} for did_obj, idx in sorted(indexer.last_revealed.items()): did_hex = did_obj.serialize().hex() @@ -142,139 +165,140 @@ def _serialize_indexer(indexer: bdk.IndexerChangeSet) -> Dict[str, Any]: return out @staticmethod - def from_dict(parsed_json: Dict) -> bdk.ChangeSet: + def from_dict(parsed_json: Dict) -> ChangeSet: """ - Deserialize a JSON string back into a bdk.ChangeSet. + Deserialize a JSON string back into a ChangeSet. """ def _deserialize_descriptor( - descriptor_str: Optional[str], network: Optional[bdk.Network] - ) -> Optional[bdk.Descriptor]: + descriptor_str: Optional[str], network: Optional[Network] + ) -> Optional[Descriptor]: if descriptor_str is None: return None - return bdk.Descriptor(descriptor_str, network) + nk = NetworkKind.MAIN if network == Network.BITCOIN else NetworkKind.TEST + return Descriptor(descriptor_str, nk) - def _deserialize_blockhash(hexstr: Optional[str]) -> Optional[bdk.BlockHash]: + def _deserialize_blockhash(hexstr: Optional[str]) -> Optional[BlockHash]: if hexstr is None: return None raw = binascii.unhexlify(hexstr) - return bdk.BlockHash.from_bytes(raw) + return BlockHash.from_bytes(raw) - def _deserialize_chainchange(data: Dict[str, Any]) -> bdk.ChainChange: + def _deserialize_chainchange(data: Dict[str, Any]) -> ChainChange: height = data["height"] hash_hex = data["hash"] bh = _deserialize_blockhash(hash_hex) - return bdk.ChainChange(height=height, hash=bh) + return ChainChange(height=height, hash=bh) - def _deserialize_local_chain(data: Dict[str, Any]) -> bdk.LocalChainChangeSet: + def _deserialize_local_chain(data: Dict[str, Any]) -> LocalChainChangeSet: changes_list = data.get("changes", []) - cc_objs: List[bdk.ChainChange] = [_deserialize_chainchange(cc) for cc in changes_list] - return bdk.LocalChainChangeSet(changes=cc_objs) + cc_objs: List[ChainChange] = [_deserialize_chainchange(cc) for cc in changes_list] + return LocalChainChangeSet(changes=cc_objs) - def _deserialize_tx(hexstr: str) -> bdk.Transaction: + def _deserialize_tx(hexstr: str) -> Transaction: raw = binascii.unhexlify(hexstr) - return bdk.Transaction(raw) + return Transaction(raw) - def _deserialize_outpoint(key_str: str) -> bdk.HashableOutPoint: + def _deserialize_outpoint(key_str: str) -> HashableOutPoint: obj = json.loads(key_str) txid_hex = obj["txid"] vout = obj["vout"] try: txid_bytes = binascii.unhexlify(txid_hex) - txid_obj = bdk.Txid.from_bytes(txid_bytes) + txid_obj = Txid.from_bytes(txid_bytes) except Exception: - txid_obj = bdk.Txid(txid_hex) - outpoint = bdk.OutPoint(txid=txid_obj, vout=vout) - return bdk.HashableOutPoint(outpoint=outpoint) + txid_obj = Txid(txid_hex) + outpoint = OutPoint(txid=txid_obj, vout=vout) + return HashableOutPoint(outpoint=outpoint) - def _deserialize_txout(data: Dict[str, Any]) -> bdk.TxOut: + def _deserialize_txout(data: Dict[str, Any]) -> TxOut: value = data["value"] script_hex = data["script_pubkey"] script_bytes = binascii.unhexlify(script_hex) - script_obj = bdk.Script(raw_output_script=script_bytes) - return bdk.TxOut(value=value, script_pubkey=script_obj) + script_obj = Script(raw_output_script=script_bytes) + return TxOut(value=value, script_pubkey=script_obj) - def _deserialize_tx_graph(data: Dict[str, Any]) -> bdk.TxGraphChangeSet: + def _deserialize_tx_graph(data: Dict[str, Any]) -> TxGraphChangeSet: tx_hex_list = data.get("txs", []) - tx_objs: List[bdk.Transaction] = [_deserialize_tx(h) for h in tx_hex_list] + tx_objs: List[Transaction] = [_deserialize_tx(h) for h in tx_hex_list] txouts_data = data.get("txouts", {}) - txouts_dict: Dict[bdk.HashableOutPoint, bdk.TxOut] = {} + txouts_dict: Dict[HashableOutPoint, TxOut] = {} for key_str, txout_data in sorted(txouts_data.items()): hop = _deserialize_outpoint(key_str) txout_obj = _deserialize_txout(txout_data) txouts_dict[hop] = txout_obj - anchors_list: List[bdk.Anchor] = [] + anchors_list: List[Anchor] = [] for anc in data.get("anchors", []): cbt_data = anc["confirmation_block_time"] block_id_data = cbt_data["block_id"] height = block_id_data["height"] hash_hex = block_id_data["hash"] bh = _deserialize_blockhash(hash_hex) - block_id_obj = bdk.BlockId(height=height, hash=bh) + block_id_obj = BlockId(height=height, hash=bh) confirmation_time = cbt_data["confirmation_time"] - cbt_obj = bdk.ConfirmationBlockTime( + cbt_obj = ConfirmationBlockTime( block_id=block_id_obj, confirmation_time=confirmation_time ) txid_hex = anc["txid"] try: txid_bytes = binascii.unhexlify(txid_hex) - txid_obj = bdk.Txid.from_bytes(txid_bytes) + txid_obj = Txid.from_bytes(txid_bytes) except Exception: - txid_obj = bdk.Txid(txid_hex) + txid_obj = Txid(txid_hex) - anchors_list.append(bdk.Anchor(confirmation_block_time=cbt_obj, txid=txid_obj)) + anchors_list.append(Anchor(confirmation_block_time=cbt_obj, txid=txid_obj)) last_seen_data = data.get("last_seen", {}) - last_seen_dict: Dict[bdk.Txid, int] = {} + last_seen_dict: Dict[Txid, int] = {} for txid_hex, timestamp in sorted(last_seen_data.items()): try: - txid_obj = bdk.Txid.from_bytes(binascii.unhexlify(txid_hex)) + txid_obj = Txid.from_bytes(binascii.unhexlify(txid_hex)) except Exception: - txid_obj = bdk.Txid(txid_hex) + txid_obj = Txid(txid_hex) last_seen_dict[txid_obj] = timestamp # Deserialize first_seen and last_evicted first_seen_data = data.get("first_seen", {}) - first_seen_dict: Dict[bdk.Txid, int] = {} + first_seen_dict: Dict[Txid, int] = {} for txid_hex, timestamp in sorted(first_seen_data.items()): try: - txid_obj = bdk.Txid.from_bytes(binascii.unhexlify(txid_hex)) + txid_obj = Txid.from_bytes(binascii.unhexlify(txid_hex)) except Exception: - txid_obj = bdk.Txid(txid_hex) + txid_obj = Txid(txid_hex) first_seen_dict[txid_obj] = timestamp last_evicted_data = data.get("last_evicted", {}) - last_evicted_dict: Dict[bdk.Txid, int] = {} + last_evicted_dict: Dict[Txid, int] = {} for txid_hex, timestamp in sorted(last_evicted_data.items()): try: - txid_obj = bdk.Txid.from_bytes(binascii.unhexlify(txid_hex)) + txid_obj = Txid.from_bytes(binascii.unhexlify(txid_hex)) except Exception: - txid_obj = bdk.Txid(txid_hex) + txid_obj = Txid(txid_hex) last_evicted_dict[txid_obj] = timestamp - return bdk.TxGraphChangeSet( + return TxGraphChangeSet( txs=tx_objs, txouts=txouts_dict, anchors=anchors_list, last_seen=last_seen_dict,first_seen=first_seen_dict,last_evicted=last_evicted_dict ) - def _deserialize_indexer(data: Dict[str, Any]) -> bdk.IndexerChangeSet: + def _deserialize_indexer(data: Dict[str, Any]) -> IndexerChangeSet: lr_data = data.get("last_revealed", {}) - lr_dict: Dict[bdk.DescriptorId, int] = {} + lr_dict: Dict[DescriptorId, int] = {} for did_hex, idx in sorted(lr_data.items()): did_bytes = binascii.unhexlify(did_hex) - did_obj = bdk.DescriptorId.from_bytes(did_bytes) + did_obj = DescriptorId.from_bytes(did_bytes) lr_dict[did_obj] = idx - return bdk.IndexerChangeSet(last_revealed=lr_dict) + return IndexerChangeSet(last_revealed=lr_dict) net = parsed_json.get("network") if net is None: network_obj = None else: - network_obj = getattr(bdk.Network, net) + network_obj = getattr(Network, net) descr = _deserialize_descriptor(parsed_json.get("descriptor"), network_obj) change_descr = _deserialize_descriptor(parsed_json.get("change_descriptor"), network_obj) @@ -282,37 +306,37 @@ def _deserialize_indexer(data: Dict[str, Any]) -> bdk.IndexerChangeSet: tx_graph_obj = _deserialize_tx_graph(parsed_json["tx_graph"]) indexer_obj = _deserialize_indexer(parsed_json["indexer"]) - changeset = bdk.ChangeSet.from_descriptor_and_network( + changeset = ChangeSet.from_descriptor_and_network( descriptor=descr, change_descriptor=change_descr, network=network_obj, ) - changeset = bdk.ChangeSet.from_merge( - changeset, bdk.ChangeSet.from_local_chain_changes(local_chain_changes=local_chain_obj) + changeset = ChangeSet.from_merge( + changeset, ChangeSet.from_local_chain_changes(local_chain_changes=local_chain_obj) ) - changeset = bdk.ChangeSet.from_merge( - changeset, bdk.ChangeSet.from_tx_graph_changeset(tx_graph_changeset=tx_graph_obj) + changeset = ChangeSet.from_merge( + changeset, ChangeSet.from_tx_graph_changeset(tx_graph_changeset=tx_graph_obj) ) - changeset = bdk.ChangeSet.from_merge( - changeset, bdk.ChangeSet.from_indexer_changeset(indexer_changes=indexer_obj) + changeset = ChangeSet.from_merge( + changeset, ChangeSet.from_indexer_changeset(indexer_changes=indexer_obj) ) return changeset -class MyPersistence(bdk.Persistence): +class MyPersistence(Persistence): def __init__(self): self.memory = [] - def merge_all(self) -> bdk.ChangeSet: - total_changeset = bdk.ChangeSet() + def merge_all(self) -> ChangeSet: + total_changeset = ChangeSet() for changeset_dict in self.memory: - total_changeset = bdk.ChangeSet.from_merge(total_changeset, changeset_dict) + total_changeset = ChangeSet.from_merge(total_changeset, changeset_dict) return total_changeset - def initialize(self) -> bdk.ChangeSet: + def initialize(self) -> ChangeSet: return self.merge_all() - def persist(self, changeset: bdk.ChangeSet): + def persist(self, changeset: ChangeSet): self.memory.append(changeset) @@ -321,12 +345,12 @@ class PersistenceTest(unittest.TestCase): def test_synced_transactions(self): myp = MyPersistence() - persister = bdk.Persister.custom(myp) + persister = Persister.custom(myp) - wallet: bdk.Wallet = bdk.Wallet(descriptor, change_descriptor, bdk.Network.REGTEST, persister) + wallet: Wallet = Wallet(descriptor, change_descriptor, Network.REGTEST, persister) wallet.apply_unconfirmed_txs( - [bdk.UnconfirmedTx(tx=bdk.Transaction(bytes.fromhex(tx)), last_seen=0) for tx in initial_txs] + [UnconfirmedTx(tx=Transaction(bytes.fromhex(tx)), last_seen=0) for tx in initial_txs] ) wallet.persist(persister=persister) @@ -334,9 +358,9 @@ def test_synced_transactions(self): # initialize new wallet with memory of myp myp2 = MyPersistence() myp2.memory = [ChangeSetConverter.from_dict(json.loads(serialized_persistence))] - persister2 = bdk.Persister.custom(myp2) + persister2 = Persister.custom(myp2) - wallet2 = bdk.Wallet.load( + wallet2 = Wallet.load( descriptor=descriptor, change_descriptor=change_descriptor, persister=persister2, @@ -360,8 +384,8 @@ def test_synced_transactions(self): assert wallet.balance().total.to_sat() == 50641167 d_myp = ChangeSetConverter.to_dict(myp.initialize()) d_myp2 = ChangeSetConverter.to_dict(myp2.initialize()) - print(d_myp) - print(d_myp2) + # print(d_myp) + # print(d_myp2) assert json.dumps(d_myp) == json.dumps(d_myp2) if __name__ == "__main__": diff --git a/tests/test_offline_descriptor.py b/tests/test_offline_descriptor.py index af64194..06ab65a 100644 --- a/tests/test_offline_descriptor.py +++ b/tests/test_offline_descriptor.py @@ -2,7 +2,7 @@ from bdkpython import Mnemonic from bdkpython import DescriptorSecretKey from bdkpython import KeychainKind -from bdkpython import Network +from bdkpython import NetworkKind import unittest @@ -10,8 +10,8 @@ class OfflineDescriptorTest(unittest.TestCase): def test_descriptor_bip86(self): mnemonic: Mnemonic = Mnemonic.from_string("space echo position wrist orient erupt relief museum myself grain wisdom tumble") - descriptor_secret_key: DescriptorSecretKey = DescriptorSecretKey(Network.TESTNET, mnemonic, None) - descriptor: Descriptor = Descriptor.new_bip86(descriptor_secret_key, KeychainKind.EXTERNAL, Network.TESTNET) + descriptor_secret_key: DescriptorSecretKey = DescriptorSecretKey(NetworkKind.TEST, mnemonic, None) + descriptor: Descriptor = Descriptor.new_bip86(descriptor_secret_key, KeychainKind.EXTERNAL, NetworkKind.TEST) self.assertEqual( "tr([be1eec8f/86'/1'/0']tpubDCTtszwSxPx3tATqDrsSyqScPNnUChwQAVAkanuDUCJQESGBbkt68nXXKRDifYSDbeMa2Xg2euKbXaU3YphvGWftDE7ozRKPriT6vAo3xsc/0/*)#m7puekcx", diff --git a/tests/test_offline_wallet.py b/tests/test_offline_wallet.py index 05c15f0..878b241 100644 --- a/tests/test_offline_wallet.py +++ b/tests/test_offline_wallet.py @@ -4,17 +4,18 @@ from bdkpython import Persister from bdkpython import AddressInfo from bdkpython import Network +from bdkpython import NetworkKind import unittest import os descriptor: Descriptor = Descriptor( "wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/1h/0/*)", - Network.TESTNET + NetworkKind.TEST ) change_descriptor: Descriptor = Descriptor( "wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/1h/1/*)", - Network.TESTNET + NetworkKind.TEST ) class OfflineWalletTest(unittest.TestCase): diff --git a/uv.lock b/uv.lock index 8ee6f03..506c19f 100644 --- a/uv.lock +++ b/uv.lock @@ -42,7 +42,7 @@ wheels = [ [[package]] name = "bdkpython" -version = "2.1.0.dev0" +version = "3.0.0a0" source = { editable = "." } [package.dev-dependencies]