Skip to content

Commit dfc6d57

Browse files
committed
Merge master into develop-port, keeping develop-port versions
2 parents 3eb98ea + 2d6dbbe commit dfc6d57

File tree

3 files changed

+27
-31
lines changed

3 files changed

+27
-31
lines changed

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77
## Table of Contents
88

99
- [Unreleased](#unreleased)
10+
- [1.0.11 - 2025-11-23](#1011---2025-11-23)
1011
- [1.0.10 - 2025-10-30](#1010---2025-10-30)
1112
- [1.0.9 - 2025-09-30](#109---2025-09-30)
1213
- [1.0.8 - 2025-08-13](#108---2025-08-13)
@@ -45,6 +46,27 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4546
### Security
4647
- (Notify of any improvements related to security vulnerabilities or potential risks.)
4748

49+
---
50+
## [1.0.11] - 2025-11-23
51+
52+
### Changed
53+
- Converted `LivePolicy` fee model from asynchronous to synchronous implementation
54+
- Replaced `default_http_client()` (async) with `default_sync_http_client()` (sync) in `LivePolicy`
55+
- **`Transaction.fee()` can now be called from both synchronous and asynchronous functions without any special handling**
56+
- Removed unused `asyncio` and `inspect` imports from `transaction.py`
57+
- Simplified `Transaction.fee()` implementation by removing async helper methods
58+
59+
### Fixed
60+
- Updated all `LivePolicy` tests to use synchronous mocks instead of `AsyncMock`
61+
- Fixed `test_transaction_fee_with_default_rate` to use explicit fee model for deterministic testing
62+
- Removed `asyncio.run()` calls from `LivePolicy` test suite
63+
64+
### Notes
65+
- This change is transparent to users - `tx.fee()` works seamlessly in both sync and async contexts without any API changes
66+
- You can call `tx.fee()` inside `async def` functions or regular `def` functions - it works the same way
67+
- All existing code and documentation remain compatible with no modifications required
68+
69+
---
4870
## [1.0.10] - 2025-10-30
4971

5072
### Changed

bsv/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
TRANSACTION_SEQUENCE: int = int(os.getenv('BSV_PY_SDK_TRANSACTION_SEQUENCE') or 0xffffffff)
88
TRANSACTION_VERSION: int = int(os.getenv('BSV_PY_SDK_TRANSACTION_VERSION') or 1)
99
TRANSACTION_LOCKTIME: int = int(os.getenv('BSV_PY_SDK_TRANSACTION_LOCKTIME') or 0)
10-
TRANSACTION_FEE_RATE: int = int(os.getenv('BSV_PY_SDK_TRANSACTION_FEE_RATE') or 10) # satoshi per kilobyte
10+
TRANSACTION_FEE_RATE: int = int(os.getenv('BSV_PY_SDK_TRANSACTION_FEE_RATE') or 100) # satoshi per kilobyte
1111
BIP32_DERIVATION_PATH = os.getenv('BSV_PY_SDK_BIP32_DERIVATION_PATH') or "m/"
1212
BIP39_ENTROPY_BIT_LENGTH: int = int(os.getenv('BSV_PY_SDK_BIP39_ENTROPY_BIT_LENGTH') or 128)
1313
BIP44_DERIVATION_PATH = os.getenv('BSV_PY_SDK_BIP44_DERIVATION_PATH') or "m/44'/236'/0'"

bsv/transaction.py

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import asyncio
2-
import inspect
31
import math
42
from contextlib import suppress
53
from typing import List, Optional, Union, Dict, Any
@@ -175,29 +173,10 @@ def estimated_byte_length(self) -> int:
175173

176174
estimated_size = estimated_byte_length
177175

178-
# Private helper method for handling asynchronous fee resolution and application
179-
async def _resolve_and_apply_fee(self, fee_estimate, change_distribution):
180-
"""
181-
A helper method to resolve and apply the transaction fee asynchronously.
182-
183-
:param fee_estimate: An awaitable object that resolves to the estimated fee
184-
:param change_distribution: The method of distributing change ('equal' or 'random')
185-
:return: The resolved fee value (int) or None in case of an error
186-
"""
187-
try:
188-
# Resolve the fee asynchronously
189-
resolved_fee = await fee_estimate
190-
# Apply the resolved fee to the transaction
191-
self._apply_fee_amount(resolved_fee, change_distribution)
192-
return resolved_fee
193-
except Exception as e:
194-
# Handle any errors and return None on failure
195-
return None
196-
197176
def fee(self, model_or_fee=None, change_distribution='equal'):
198177
"""
199178
Computes the transaction fee and adjusts the change outputs accordingly.
200-
This method can be called synchronously, even if it internally uses asynchronous operations.
179+
This method can be called synchronously or from async contexts.
201180
202181
:param model_or_fee: A fee model or a fee amount. If not provided, it defaults to an instance
203182
of `LivePolicy` that fetches the latest mining fees.
@@ -214,15 +193,10 @@ def fee(self, model_or_fee=None, change_distribution='equal'):
214193
self._apply_fee_amount(model_or_fee, change_distribution)
215194
return model_or_fee
216195

217-
# If the fee estimation requires asynchronous computation
196+
# Compute the fee using the fee model
218197
fee_estimate = model_or_fee.compute_fee(self)
219-
220-
if inspect.isawaitable(fee_estimate):
221-
# Execute the asynchronous task synchronously and get the result
222-
resolved_fee = asyncio.run(self._resolve_and_apply_fee(fee_estimate, change_distribution))
223-
return resolved_fee
224-
225-
# Apply the fee directly if it is computed synchronously
198+
199+
# Apply the fee directly
226200
self._apply_fee_amount(fee_estimate, change_distribution)
227201
return fee_estimate
228202

0 commit comments

Comments
 (0)