This example demonstrates best practices for handling transaction lifecycles in the TRUF.NETWORK Python SDK using wait_for_tx() to avoid race conditions and ensure reliable sequential operations.
By default, SDK methods return success when transactions are submitted to the mempool, NOT when they're executed on-chain. This can cause race conditions in sequential workflows:
# ⚠️ DANGEROUS: Race condition possible
client.deploy_stream(stream_id, STREAM_TYPE_PRIMITIVE) # Returns immediately
client.insert_record(stream_id, record) # May fail if deployment not completeUse wait_for_tx() to wait for on-chain confirmation:
# ✅ SAFE: Wait for confirmation
tx_hash = client.deploy_stream(stream_id, STREAM_TYPE_PRIMITIVE)
client.wait_for_tx(tx_hash) # Wait for confirmation
client.insert_record(stream_id, record) # Now guaranteed to succeed- Python 3.8+ and the TRUF.NETWORK Python SDK installed
- Private key for transaction signing
- Network access to TRUF.NETWORK mainnet or local node
-
Install the SDK (if not already installed):
pip install https://github.com/trufnetwork/sdk-py/releases/download/v0.3.2/trufnetwork_sdk_py-0.3.2-py3-none-manylinux_2_28_x86_64.whl
-
Update the private key in
main.py:# Replace this placeholder with your actual private key private_key = "YOUR_PRIVATE_KEY_HERE"
-
Run the example:
python main.py
If you want to test against a local node instead of mainnet:
-
Start a local node (see Local Node Setup)
-
Update the endpoint in
main.py:endpoint = "http://localhost:8484" # Local node
- Uses
deploy_stream()+wait_for_tx()to wait for on-chain confirmation - Proper error handling with try/catch blocks
- Shows transaction hash and confirmation process
- Shows how
insert_record()has built-in confirmation - Demonstrates inserting multiple records safely
- Error handling for failed insertions
- Retrieves and displays inserted records
- Shows how to use date ranges for queries
- Confirms data integrity after operations
- Uses
destroy_stream()+wait_for_tx()to wait for confirmation - Verifies destruction by testing failed operations
- Demonstrates proper cleanup patterns
# The safe pattern for all lifecycle operations
tx_hash = client.deploy_stream(stream_id, STREAM_TYPE_PRIMITIVE)
client.wait_for_tx(tx_hash) # Wait for confirmation
tx_hash = client.destroy_stream(stream_id)
client.wait_for_tx(tx_hash) # Wait for confirmationtry:
tx_hash = client.deploy_stream(stream_id, STREAM_TYPE_PRIMITIVE)
client.wait_for_tx(tx_hash)
print("✅ Stream deployed successfully")
except Exception as e:
print(f"❌ Deployment failed: {e}")- Use
wait_for_tx()for lifecycle operations (deploy/destroy) - Wait for confirmation before dependent operations
- Test sequential workflows to catch timing issues
- Verify operations completed before proceeding
When you run the example successfully, you should see:
🔄 Transaction Lifecycle Best Practices Demo
==================================================
Stream ID: st_generated_stream_id
Endpoint: https://gateway.mainnet.truf.network
Data Provider: 0x...
📋 EXAMPLE 1: Safe Stream Deployment
----------------------------------------
📝 Deploying stream...
Deployment submitted: 0xabc123...
⏳ Waiting for deployment to be mined...
✅ Stream deployed and confirmed on-chain
📋 EXAMPLE 2: Record Insertion
----------------------------------------
📝 Inserting record 1...
✅ Record 1 inserted: 123.45
📝 Inserting record 2...
✅ Record 2 inserted: 456.78
📝 Inserting record 3...
✅ Record 3 inserted: 789.01
📋 EXAMPLE 3: Verify Records After Insertion
----------------------------------------
✅ Retrieved 3 records from stream:
Record 1: 123.45 (Time: 2025-09-04 18:30:00)
Record 2: 456.78 (Time: 2025-09-04 18:30:01)
Record 3: 789.01 (Time: 2025-09-04 18:30:02)
📋 EXAMPLE 4: Safe Stream Destruction with Verification
------------------------------------------------------
🗑️ Destroying stream...
Destruction submitted: 0xdef456...
⏳ Waiting for destruction to be mined...
✅ Stream destroyed and confirmed on-chain
🧪 Testing insertion after destruction...
✅ PERFECT: Insertion failed as expected after destruction
Error: stream not found...
🧪 Testing record retrieval after destruction...
✅ PERFECT: Record retrieval failed as expected
Error: stream not found...
📚 KEY TAKEAWAYS:
============================================================
✅ Use wait_for_tx() for DeployStream and DestroyStream
✅ insert_record() has built-in confirmation for data integrity
✅ Always use try/catch blocks for proper error handling
✅ Verify operations completed before proceeding with dependent actions
⚠️ Async operations can cause race conditions in sequential workflows
-
"Stream not found" during insertion
- Cause: Race condition - deployment not complete
- Solution: Use
wait_for_tx()afterdeploy_stream()
-
"Permission denied" errors
- Cause: Account lacks
system:network_writerrole - Solution: Contact TRUF.NETWORK team for role assignment
- Cause: Account lacks
-
Network connection errors
- Cause: Endpoint unreachable or invalid private key
- Solution: Check endpoint URL and private key validity
- Mainnet:
https://gateway.mainnet.truf.network - Local Node:
http://localhost:8484(after starting local node)
After understanding transaction lifecycles:
- Explore the Complex Example for advanced stream management
- Read the API Reference for complete method documentation
- Check out Custom Procedures for advanced functionality