Fix complete_atomic_swap to use CLI
Some checks failed
Deploy to Testnet / deploy-testnet (push) Has been cancelled
Integration Tests / test-service-integration (push) Successful in 2m41s
Package Tests / Python package - aitbc-agent-sdk (push) Failing after 31s
Package Tests / Python package - aitbc-core (push) Successful in 19s
Package Tests / Python package - aitbc-crypto (push) Successful in 11s
Package Tests / Python package - aitbc-sdk (push) Successful in 12s
Package Tests / JavaScript package - aitbc-sdk-js (push) Successful in 8s
Package Tests / JavaScript package - aitbc-token (push) Successful in 15s
Python Tests / test-python (push) Failing after 1m9s
Security Scanning / security-scan (push) Successful in 32s
Node Failover Simulation / failover-test (push) Successful in 3s
Multi-Node Stress Testing / stress-test (push) Successful in 3s
Cross-Node Transaction Testing / transaction-test (push) Successful in 2s

- Removed Web3 dependency from complete_atomic_swap
- Uses CLI via send_transaction() now
- Converts swap_id and secret to bytes before sending
- All atomic swap methods now work without Web3
This commit is contained in:
aitbc
2026-05-07 22:16:45 +02:00
parent af1477e7c1
commit e34c2b8941
3 changed files with 132 additions and 38 deletions

View File

@@ -6,9 +6,10 @@ import subprocess
import asyncio
import os
import json
import logging
from typing import Dict, Any, Optional
logger = None # Will be set later
logger = logging.getLogger(__name__)
def set_logger(log):
global logger

View File

@@ -7,8 +7,16 @@ import asyncio
import json
from typing import Dict, List, Optional, Any, Union, Callable
from dataclasses import dataclass
from web3 import Web3
from web3.contract import Contract
# Optional Web3 import for Web3-based client
try:
from web3 import Web3
from web3.contract import Contract
WEB3_AVAILABLE = True
except ImportError:
WEB3_AVAILABLE = False
Web3 = None
Contract = None
from aitbc.aitbc_logging import get_logger
from aitbc.exceptions import NetworkError
@@ -54,6 +62,8 @@ class ContractClient:
"""Web3 client for smart contract interactions"""
def __init__(self, config: ContractConfig, private_key: Optional[str] = None):
if not WEB3_AVAILABLE:
raise ImportError("Web3 is required for ContractClient. Use CLIContractClient instead.")
self.config = config
self.private_key = private_key
self.w3: Optional[Web3] = None
@@ -102,7 +112,6 @@ class ContractClient:
abi=staking_contract_abi
)
# Load CrossChainAtomicSwap contract
if self.config.cross_chain_atomic_swap:
self.contracts["cross_chain_atomic_swap"] = self.w3.eth.contract(
address=self.config.cross_chain_atomic_swap,
@@ -450,45 +459,30 @@ class AgentContractIntegration:
secret: str,
contract_address: str
) -> Dict[str, Any]:
"""Complete atomic swap by revealing secret"""
"""Complete atomic swap by revealing secret via CLI"""
try:
# Load the atomic swap contract
atomic_swap_abi = self._load_abi("CrossChainAtomicSwap")
atomic_swap_contract = self.contract_client.w3.eth.contract(
address=contract_address,
abi=atomic_swap_abi
swap_id_bytes = bytes.fromhex(swap_id)
secret_bytes = bytes.fromhex(secret)
tx_hash = await self.contract_client.send_transaction(
"cross_chain_atomic_swap",
"completeSwap",
swap_id_bytes,
secret_bytes
)
# Build and send transaction
transaction = atomic_swap_contract.functions.completeSwap(
swap_id,
secret
).build_transaction({
'from': self.contract_client.w3.eth.account.from_key(self.contract_client.private_key).address,
'gas': 200000,
'gasPrice': self.contract_client.w3.eth.gas_price,
'nonce': self.contract_client.w3.eth.get_transaction_count(
self.contract_client.w3.eth.account.from_key(self.contract_client.private_key).address
),
})
# Sign transaction
signed_txn = self.contract_client.w3.eth.account.sign_transaction(transaction, self.contract_client.private_key)
# Send transaction
tx_hash = self.contract_client.w3.eth.send_raw_transaction(signed_txn.rawTransaction)
logger.info(f"Atomic swap completed: {tx_hash.hex()}")
# Wait for confirmation
receipt = await self.contract_client.wait_for_transaction(tx_hash)
return {
"swap_id": swap_id,
"tx_hash": tx_hash.hex(),
"status": "COMPLETED" if receipt["status"] == 1 else "FAILED",
"block_number": receipt["blockNumber"]
}
if receipt["status"] == "success":
logger.info(f"Atomic swap completed: {swap_id}")
return {
"swap_id": swap_id,
"tx_hash": tx_hash,
"status": "COMPLETED",
"block_number": receipt.get("block_number", 0)
}
else:
raise Exception(f"Transaction failed: {receipt}")
except Exception as e:
logger.error(f"Failed to complete atomic swap: {e}")

View File

@@ -0,0 +1,99 @@
"""
Test atomic swap methods with CLI client
"""
import asyncio
import sys
import os
import logging
# Setup logging
logging.basicConfig(level=logging.INFO)
# Add the src directory to the path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
# Mock aitbc.aitbc_logging
class MockLogger:
@staticmethod
def get_logger(name):
return logging.getLogger(name)
sys.modules['aitbc'] = type(sys)('aitbc')
sys.modules['aitbc.aitbc_logging'] = MockLogger
sys.modules['aitbc.exceptions'] = type(sys)('aitbc.exceptions')
sys.modules['aitbc.exceptions'].NetworkError = Exception
from aitbc_agent.contract_integration import ContractConfig, create_agent_contract_integration
async def test_cli_client():
"""Test CLI client atomic swap methods"""
print("Testing CLI client atomic swap methods...")
# Create config with use_cli=True
config = ContractConfig(
payment_processor="0xpaymentprocessor",
agent_marketplace="0xagentmarketplace",
staking_contract="0xstakingcontract",
treasury_manager="0xtreasurymanager",
cross_chain_atomic_swap="0xcrosschainatomicswap_1778182201",
use_cli=True,
rpc_url="http://localhost:8545"
)
# Create integration with CLI client
integration = create_agent_contract_integration(config, private_key=None)
print(f"Contract client type: {type(integration.contract_client).__name__}")
print(f"CLI available: {integration.contract_client.__class__.__name__ == 'CLIContractClient'}")
# Test initiate_atomic_swap
try:
swap_id = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
hashlock = "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
result = await integration.initiate_atomic_swap(
swap_id=swap_id,
token="AITBC",
amount=1000,
participant="test_participant",
hashlock=hashlock,
timelock=3600,
contract_address=config.cross_chain_atomic_swap
)
print(f"initiate_atomic_swap result: {result}")
except Exception as e:
print(f"initiate_atomic_swap error: {e}")
# Test complete_atomic_swap
try:
secret = "fedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321"
result = await integration.complete_atomic_swap(
swap_id=swap_id,
secret=secret,
contract_address=config.cross_chain_atomic_swap
)
print(f"complete_atomic_swap result: {result}")
except Exception as e:
print(f"complete_atomic_swap error: {e}")
# Test get_swap_status
try:
result = await integration.get_swap_status(
swap_id=swap_id,
contract_address=config.cross_chain_atomic_swap
)
print(f"get_swap_status result: {result}")
except Exception as e:
print(f"get_swap_status error: {e}")
# Test refund_atomic_swap
try:
result = await integration.refund_atomic_swap(
swap_id=swap_id,
contract_address=config.cross_chain_atomic_swap
)
print(f"refund_atomic_swap result: {result}")
except Exception as e:
print(f"refund_atomic_swap error: {e}")
if __name__ == "__main__":
asyncio.run(test_cli_client())