Context Verification
Verify the authenticity and integrity of BB-MCP contexts using blockchain records. Learn how to validate contexts, check signatures, and ensure data hasn't been tampered with.
How Verification Works
BB-MCP uses cryptographic signatures and blockchain records for verification
What Gets Verified
- Authenticity: Context came from claimed agent
- Integrity: Data hasn't been modified
- Timestamp: Context created at claimed time
- Non-repudiation: Agent cannot deny creating it
Verification Levels
Full Verification
Signature + Blockchain + Hash validation
Signature Only
Cryptographic signature validation
Blockchain Only
Hash presence on blockchain
Basic Verification
Verify a context using its transaction hash or context ID
Python SDK
import bb_mcp
client = bb_mcp.Client(api_key="your_api_key")
# Method 1: Verify by transaction hash
verification = client.verify_context(
transaction_hash="0x1a2b3c4d5e6f7890abcdef..."
)
if verification.verified:
print("✅ Context verified successfully!")
print(f"Agent ID: {verification.agent_id}")
print(f"Block Number: {verification.block_number}")
print(f"Confirmations: {verification.confirmations}")
print(f"Verified at: {verification.block_timestamp}")
else:
print("❌ Verification failed")
print(f"Reason: {verification.error_reason}")
# Method 2: Verify by context ID
verification = client.verify_context(
context_id="ctx_1234567890abcdef"
)
# Method 3: Verify with local context data
context_data = {
"agent_id": "my-agent",
"timestamp": "2024-01-15T10:30:00Z",
"context_data": {"task": "classification", "result": "positive"},
"metadata": {"version": "1.0"}
}
verification = client.verify_context(
transaction_hash="0x1a2b3c4d5e6f7890...",
context=context_data # Compares local data with blockchain record
)
JavaScript SDK
import { BBMCPClient } from '@quietstack/bb-mcp';
const client = new BBMCPClient({ apiKey: 'your_api_key' });
// Method 1: Verify by transaction hash
try {
const verification = await client.verify({
transaction_hash: '0x1a2b3c4d5e6f7890abcdef...'
});
if (verification.verified) {
console.log('✅ Context verified successfully!');
console.log(`Agent ID: ${verification.agent_id}`);
console.log(`Block Number: ${verification.block_number}`);
console.log(`Confirmations: ${verification.confirmations}`);
} else {
console.log('❌ Verification failed');
}
} catch (error) {
console.error('Verification error:', error.message);
}
// Method 2: Verify with context validation
const verification = await client.verify({
transaction_hash: '0x1a2b3c4d5e6f7890...',
context: {
agent_id: 'my-agent',
timestamp: '2024-01-15T10:30:00Z',
context_data: { task: 'classification', result: 'positive' },
metadata: { version: '1.0' }
}
});
// Check specific verification aspects
console.log(`Signature valid: ${verification.signature_valid}`);
console.log(`Hash matches: ${verification.hash_matches}`);
console.log(`On blockchain: ${verification.block_number > 0}`);
Batch Verification
Verify multiple contexts efficiently in a single request
Python Implementation
# Verify multiple contexts at once
transaction_hashes = [
"0x1a2b3c4d5e6f7890...",
"0x9876543210fedcba...",
"0xabcdef1234567890..."
]
# Batch verify (more efficient than individual calls)
verifications = client.verify_contexts_batch(transaction_hashes)
# Process results
for i, verification in enumerate(verifications):
tx_hash = transaction_hashes[i]
if verification.verified:
print(f"✅ {tx_hash[:10]}... verified (Block: {verification.block_number})")
else:
print(f"❌ {tx_hash[:10]}... failed ({verification.error_reason})")
# Summary statistics
total = len(verifications)
verified = sum(1 for v in verifications if v.verified)
print(f"\nVerification Summary: {verified}/{total} contexts verified ({verified/total*100:.1f}%)")
# Filter for different verification statuses
confirmed = [v for v in verifications if v.verified and v.confirmations >= 12]
pending = [v for v in verifications if v.verified and v.confirmations < 12]
failed = [v for v in verifications if not v.verified]
print(f"Confirmed: {len(confirmed)}, Pending: {len(pending)}, Failed: {len(failed)}")
JavaScript Implementation
// Verify multiple contexts concurrently
const transactionHashes = [
'0x1a2b3c4d5e6f7890...',
'0x9876543210fedcba...',
'0xabcdef1234567890...'
];
// Method 1: Batch API call (recommended)
const verifications = await client.verifyBatch(transactionHashes);
// Process results
verifications.forEach((verification, index) => {
const txHash = transactionHashes[index];
if (verification.verified) {
console.log(`✅ ${txHash.substring(0, 10)}... verified (Block: ${verification.block_number})`);
} else {
console.log(`❌ ${txHash.substring(0, 10)}... failed (${verification.error_reason})`);
}
});
// Method 2: Concurrent individual calls
const verifyPromises = transactionHashes.map(hash =>
client.verify({ transaction_hash: hash })
);
const results = await Promise.allSettled(verifyPromises);
// Handle mixed success/failure
results.forEach((result, index) => {
const txHash = transactionHashes[index];
if (result.status === 'fulfilled' && result.value.verified) {
console.log(`✅ ${txHash.substring(0, 10)}... verified`);
} else {
const reason = result.status === 'rejected'
? result.reason.message
: result.value.error_reason;
console.log(`❌ ${txHash.substring(0, 10)}... failed: ${reason}`);
}
});
Verification Response Format
Understanding the verification response structure
Successful Verification
{
"verified": true,
"transaction_hash": "0x1a2b3c4d5e6f7890abcdef123456789012345678",
"block_number": 123456789,
"block_timestamp": "2024-01-15T10:30:05Z",
"confirmations": 15,
"agent_id": "my-classification-agent",
"context_hash": "0xabcdef1234567890fedcba0987654321abcdef12",
"signature_valid": true,
"hash_matches": true,
"verification_time": "2024-01-15T11:45:23Z",
"network": "polygon",
"gas_used": 42000,
"verification_details": {
"signature_algorithm": "ECDSA",
"hash_algorithm": "SHA-256",
"public_key": "0x04a1b2c3d4e5f6...",
"signature": "0x789abc..."
}
}
Failed Verification
{
"verified": false,
"transaction_hash": "0x1a2b3c4d5e6f7890abcdef123456789012345678",
"error_reason": "SIGNATURE_INVALID",
"error_details": "Digital signature does not match expected value",
"context_hash": "0xabcdef1234567890fedcba0987654321abcdef12",
"signature_valid": false,
"hash_matches": true, // Hash found on blockchain but signature invalid
"verification_time": "2024-01-15T11:45:23Z",
"network": "polygon",
"block_number": 123456789, // May still be present if found
"possible_causes": [
"Context data was modified after signing",
"Incorrect agent private key used for signing",
"Corrupted signature during transmission"
]
}
Verification Status and Timing
Understanding confirmation times and blockchain finality
Confirmation Timeline
0-1 min
Transaction Pending
Submitted to mempool, waiting for inclusion
1-5 min
First Confirmation
Included in a block, basic verification possible
5-15 min
Confirmed
12+ confirmations, considered final on most networks
Network Comparison
Network | Block Time | Safe Confirmations | Finality Time |
---|---|---|---|
Polygon | ~2 seconds | 12 blocks | ~30 seconds |
Ethereum | ~12 seconds | 12 blocks | ~2.4 minutes |
Arbitrum | ~1 second | 20 blocks | ~20 seconds |
Base | ~2 seconds | 12 blocks | ~30 seconds |
Checking Confirmation Status
# Poll for confirmation status
import time
def wait_for_confirmation(client, transaction_hash, required_confirmations=12, timeout=300):
start_time = time.time()
while time.time() - start_time < timeout:
verification = client.verify_context(transaction_hash)
if not verification.verified:
print(f"❌ Verification failed: {verification.error_reason}")
return False
confirmations = verification.confirmations
print(f"Confirmations: {confirmations}/{required_confirmations}")
if confirmations >= required_confirmations:
print(f"✅ Context confirmed with {confirmations} confirmations")
return True
time.sleep(10) # Check every 10 seconds
print(f"⏰ Timeout waiting for confirmations")
return False
# Usage
result = client.contexts.create(context)
confirmed = wait_for_confirmation(client, result.transaction_hash)
if confirmed:
print("Ready to use verified context")
else:
print("Context not yet confirmed, but may still be valid")
Manual Verification
Verify contexts manually using blockchain explorers and cryptographic tools
Using Blockchain Explorers
Step 1: Look up Transaction
Use the transaction hash to find the transaction on a blockchain explorer
Step 2: Find Contract Event
Look for the ContextLogged event in the transaction logs
Event: ContextLogged(bytes32 indexed contextHash, string agentId, uint256 timestamp)
Step 3: Verify Hash
Compare the contextHash in the event with the hash of your context data
Cryptographic Verification
# Manual cryptographic verification
import hashlib
import json
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import ec
def verify_context_signature(context, signature, public_key_pem):
"""
Manually verify a BB-MCP context signature
"""
# 1. Serialize context (excluding signature and hash fields)
context_for_signing = {
"agent_id": context["agent_id"],
"timestamp": context["timestamp"],
"context_data": context["context_data"],
"metadata": context.get("metadata", {})
}
# 2. Create canonical JSON representation
context_json = json.dumps(context_for_signing, sort_keys=True, separators=(',', ':'))
# 3. Hash the context
context_bytes = context_json.encode('utf-8')
context_hash = hashlib.sha256(context_bytes).digest()
# 4. Load public key
public_key = serialization.load_pem_public_key(public_key_pem.encode())
# 5. Verify signature
try:
public_key.verify(
bytes.fromhex(signature),
context_hash,
ec.ECDSA(hashes.SHA256())
)
return True, context_hash.hex()
except Exception as e:
return False, str(e)
# Example usage
context = {
"agent_id": "my-agent",
"timestamp": "2024-01-15T10:30:00Z",
"context_data": {"task": "test"},
"signature": "3045022100..."
}
public_key_pem = """-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
-----END PUBLIC KEY-----"""
is_valid, result = verify_context_signature(context, context["signature"], public_key_pem)
print(f"Signature valid: {is_valid}")
print(f"Context hash: {result}")
Verification Best Practices
Guidelines for effective context verification
✅ Best Practices
- Always verify contexts before trusting them
- Check both signature and blockchain confirmation
- Use batch verification for multiple contexts
- Implement retry logic for pending transactions
- Cache verification results to avoid redundant checks
- Set appropriate confirmation requirements for your use case
⚠️ Common Pitfalls
- Accepting contexts without verification
- Not handling verification failures gracefully
- Assuming immediate blockchain finality
- Ignoring network-specific confirmation requirements
- Not validating context structure before verification
- Relying solely on client-side verification
Verification Tools & Resources
CLI Commands
bbmcp verify <tx_hash>
bbmcp verify-batch <file.txt>
bbmcp verify-context <context.json>