0% found this document useful (0 votes)
20 views4 pages

Bitcoin Transection Handler

Uploaded by

ashamisha234
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views4 pages

Bitcoin Transection Handler

Uploaded by

ashamisha234
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

import logging

from typing import Dict, Optional, Union


from decimal import Decimal
from concurrent.futures import ThreadPoolExecutor
import time
from dataclasses import dataclass
from bitcoinlib.wallets import Wallet, wallet_delete_if_exists
from bitcoinlib.services.services import Service
from bitcoinlib.transactions import Transaction

# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

@dataclass
class TransactionResult:
"""Data class to store transaction results"""
success: bool
tx_id: Optional[str] = None
details: Optional[Dict] = None
error: Optional[str] = None

class BitcoinTransactionHandler:
"""Handles Bitcoin transactions with improved error handling and performance"""

def __init__(self, network: str = 'testnet'):


self.network = network
self.service = Service(network=network)
self._executor = ThreadPoolExecutor(max_workers=3)

def _satoshi_to_btc(self, satoshi: int) -> Decimal:


"""Convert satoshi to BTC"""
return Decimal(satoshi) / Decimal(100000000)

def _btc_to_satoshi(self, btc: Union[float, Decimal]) -> int:


"""Convert BTC to satoshi with proper rounding"""
return int(Decimal(str(btc)) * Decimal(100000000))

async def check_address_validity(self, address: str) -> bool:


"""Validate Bitcoin address format"""
try:
return self.service.address_valid(address)
except Exception as e:
logger.error(f"Address validation error: {e}")
return False

def _check_wallet_exists(self, wallet_name: str) -> bool:


"""Check if wallet exists and is accessible"""
try:
Wallet(wallet_name)
return True
except Exception:
return False

def get_wallet_balance(self, wallet_name: str) -> TransactionResult:


"""Get wallet balance with improved error handling"""
try:
wallet = Wallet(wallet_name)
balance_satoshi = wallet.balance()
balance_btc = self._satoshi_to_btc(balance_satoshi)

return TransactionResult(
success=True,
details={
'balance_satoshi': balance_satoshi,
'balance_btc': float(balance_btc),
'address': wallet.get_key().address
}
)
except Exception as e:
logger.error(f"Balance check failed: {e}")
return TransactionResult(success=False, error=str(e))

def create_transaction(
self,
sender_wallet_name: str,
recipient_address: str,
amount_btc: Union[float, Decimal],
fee_strategy: str = 'normal'
) -> TransactionResult:
"""
Create and send a Bitcoin transaction with improved handling and features

Args:
sender_wallet_name: Name of the sender's wallet
recipient_address: Recipient's Bitcoin address
amount_btc: Amount to send in BTC
fee_strategy: 'low', 'normal', or 'high' for fee calculation
"""
try:
# Input validation
if not self._check_wallet_exists(sender_wallet_name):
raise ValueError(f"Wallet '{sender_wallet_name}' not found")

# Convert amount to satoshi


amount_satoshi = self._btc_to_satoshi(amount_btc)

# Initialize wallet
wallet = Wallet(sender_wallet_name)
wallet.scan() # Update UTXO set

# Check balance
balance = wallet.balance()
if balance < amount_satoshi:
raise ValueError(
f"Insufficient funds. Required: {amount_btc} BTC, "
f"Available: {self._satoshi_to_btc(balance)} BTC"
)

# Create transaction with dynamic fee calculation


fee_multiplier = {
'low': 0.8,
'normal': 1.0,
'high': 1.2
}.get(fee_strategy, 1.0)
tx = wallet.send_to(
recipient_address,
amount_satoshi,
fee_per_kb=None, # Use dynamic fee estimation
min_confirms=1,
prioity=fee_strategy
)

# Wait for transaction to be accepted by network


confirmation_check = self._executor.submit(
self._wait_for_confirmation,
tx.txid,
max_attempts=3
)

tx_info = tx.info()

return TransactionResult(
success=True,
tx_id=tx.txid,
details={
'amount_btc': amount_btc,
'fee_strategy': fee_strategy,
'fee_satoshi': tx_info.get('fee', 0),
'confirmations': tx_info.get('confirmations', 0),
'timestamp': tx_info.get('timestamp'),
'status': tx_info.get('status'),
'hex': tx_info.get('hex')
}
)

except Exception as e:
logger.error(f"Transaction failed: {e}")
return TransactionResult(success=False, error=str(e))

def _wait_for_confirmation(self, txid: str, max_attempts: int = 3) -> bool:


"""Wait for transaction confirmation with timeout"""
attempt = 0
while attempt < max_attempts:
try:
tx_info = self.service.gettransaction(txid)
if tx_info.get('confirmations', 0) > 0:
return True
except Exception as e:
logger.warning(f"Confirmation check failed: {e}")

time.sleep(10) # Wait 10 seconds between checks


attempt += 1

return False

# Usage example
def main():
# Initialize handler
handler = BitcoinTransactionHandler(network='testnet')

# Transaction parameters
sender_wallet = 'TestWallet'
recipient = 'tb1qrecipientaddressfortestnet'
amount = 0.001

# Check balance first


balance_result = handler.get_wallet_balance(sender_wallet)
if not balance_result.success:
logger.error(f"Balance check failed: {balance_result.error}")
return

logger.info(f"Current balance: {balance_result.details}")

# Create transaction
tx_result = handler.create_transaction(
sender_wallet,
recipient,
amount,
fee_strategy='normal'
)

if tx_result.success:
logger.info(f"Transaction successful! Details: {tx_result.details}")
else:
logger.error(f"Transaction failed: {tx_result.error}")

if __name__ == "__main__":
main()

You might also like