is pipeline sits before escrow and payment layers. It answers "Should this trade exist?" before ERC-8183 (escrow state machine) or x402 (payment rail) are invoked. This prevents unnecessary state changes and payment authorizations for invalid counterparties.
Implementation Details
The following TypeScript implementation demonstrates the pipeline structure. Note the use of distinct interfaces and error handling to ensure robustness in production environments.
Filter 1: Behavioral Risk Assessment
This filter queries on-chain settlement history to compute a risk score. It uses a rolling window to ensure relevance and weights metrics by notional value to prioritize significant trades.
interface SettlementProfile {
address: string;
windowSize: number; // Days
totalSwaps: number;
onTimeRate: number; // Weighted by notional
timeoutRate: number;
disputeRate: number;
}
interface RiskThresholds {
minSwaps: number;
minOnTimeRate: number;
maxTimeoutRate: number;
}
class BehavioralRiskEngine {
async evaluate(profile: SettlementProfile, thresholds: RiskThresholds): Promise<ValidationResult> {
// Low-cost check: Reject addresses with insufficient history
if (profile.totalSwaps < thresholds.minSwaps) {
return { status: 'REJECT', reason: 'Insufficient settlement history' };
}
// High-signal check: On-time rate is the primary predictor
if (profile.onTimeRate < thresholds.minOnTimeRate) {
return { status: 'REJECT', reason: 'On-time rate below policy threshold' };
}
// Secondary check: Timeout and dispute rates indicate reliability
if (profile.timeoutRate > thresholds.maxTimeoutRate) {
return { status: 'REJECT', reason: 'Excessive timeout rate detected' };
}
return { status: 'PASS', riskScore: this.calculateRiskScore(profile) };
}
private calculateRiskScore(profile: SettlementProfile): number {
// Composite score favoring volume and timeliness
const volumeWeight = Math.min(profile.totalSwaps / 100, 1.0);
const reliabilityWeight = profile.onTimeRate * (1 - profile.disputeRate);
return volumeWeight * reliabilityWeight;
}
}
Filter 2: Structural Commitment Verification
This filter validates that the counterparty has made a binding commitment via a sealed-bid RFQ mechanism. The protocol enforces this; the agent merely verifies the state. This prevents griefing where a maker withdraws after market movements.
interface RfqCommitment {
rfqId: string;
makerAddress: string;
bondAmount: bigint;
isBinding: boolean;
withdrawalPenalty: bigint;
}
class RfqBondValidator {
async verifyCommitment(commitment: RfqCommitment): Promise<ValidationResult> {
// Protocol-enforced check: Bid must be binding upon acceptance
if (!commitment.isBinding) {
return { status: 'REJECT', reason: 'RFQ bid is not binding' };
}
// Economic check: Bond must exist to deter withdrawal
if (commitment.bondAmount === 0n) {
return { status: 'REJECT', reason: 'No bond posted for RFQ commitment' };
}
return { status: 'PASS', commitmentVerified: true };
}
}
Filter 3: Policy-Driven Attestation Tiers
Identity verification is layered. Agents can require specific attestation tiers based on trade size or instrument class. This allows flexibility: retail agents may accept anonymous counterparties, while institutional agents require verified attestations.
enum AttestationTier {
ANONYMOUS = 0,
ATTESTED = 1,
VERIFIED = 2
}
interface AttestationRecord {
address: string;
tier: AttestationTier;
provider: string;
hashReference: string;
}
interface AgentPolicy {
minTierForNotional: (notional: bigint) => AttestationTier;
}
class AttestationPolicyChecker {
async checkCompliance(
record: AttestationRecord,
policy: AgentPolicy,
notional: bigint
): Promise<ValidationResult> {
const requiredTier = policy.minTierForNotional(notional);
// Policy check: Counterparty tier must meet or exceed requirement
if (record.tier < requiredTier) {
return {
status: 'REJECT',
reason: `Attestation tier ${record.tier} insufficient for notional ${notional}. Required: ${requiredTier}`
};
}
return { status: 'PASS', tierVerified: record.tier };
}
}
Filter 4: Cryptographic Safety Net
The final filter validates the Hash Time-Locked Contract (HTLC) parameters. This is the cryptographic floor ensuring atomicity. Even if previous filters pass, the HTLC guarantees that either both legs settle or both refund.
interface HtlcParams {
timelockSeconds: number;
hashAlgorithm: string;
hashLock: string;
refundAddress: string;
}
class HtlcSafetyValidator {
async validateParams(params: HtlcParams): Promise<ValidationResult> {
// Safety check: Timelock must be sufficient for settlement
if (params.timelockSeconds < 3600) { // Minimum 1 hour
return { status: 'REJECT', reason: 'Timelock duration too short for safe settlement' };
}
// Security check: Hash algorithm must be secure
if (params.hashAlgorithm !== 'sha256') {
return { status: 'REJECT', reason: 'Unsupported hash algorithm' };
}
return { status: 'PASS', htlcValid: true };
}
}
Unified Pipeline Orchestration
The agent orchestrates these filters in a single workflow. This abstraction allows the agent to treat counterparty validation as a single tool call, simplifying integration.
interface ValidationPipeline {
behavioral: BehavioralRiskEngine;
rfq: RfqBondValidator;
attestation: AttestationPolicyChecker;
htlc: HtlcSafetyValidator;
}
class CounterpartyValidator {
constructor(private pipeline: ValidationPipeline) {}
async validate(
address: string,
notional: bigint,
profile: SettlementProfile,
commitment: RfqCommitment,
attestation: AttestationRecord,
htlcParams: HtlcParams,
policy: AgentPolicy
): Promise<ValidationResult> {
// Stage 1: Behavioral Risk
const stage1 = await this.pipeline.behavioral.evaluate(profile, {
minSwaps: 10,
minOnTimeRate: 0.95,
maxTimeoutRate: 0.05
});
if (stage1.status === 'REJECT') return stage1;
// Stage 2: RFQ Commitment
const stage2 = await this.pipeline.rfq.verifyCommitment(commitment);
if (stage2.status === 'REJECT') return stage2;
// Stage 3: Attestation Policy
const stage3 = await this.pipeline.attestation.checkCompliance(attestation, policy, notional);
if (stage3.status === 'REJECT') return stage3;
// Stage 4: HTLC Safety
const stage4 = await this.pipeline.htlc.validateParams(htlcParams);
if (stage4.status === 'REJECT') return stage4;
return { status: 'PASS', allStagesVerified: true };
}
}
Pitfall Guide
Developers implementing agent counterparty validation often encounter specific failure modes. The following pitfalls highlight common mistakes and provide production-tested fixes.
-
Crypto-First Fallacy
- Explanation: Validating HTLC parameters before checking settlement history or RFQ commitments. This wastes gas and latency on counterparties that would be rejected by cheaper filters.
- Fix: Enforce strict pipeline ordering. HTLC validation must always be the final stage.
-
Static Threshold Trap
- Explanation: Hardcoding risk thresholds (e.g., "reject if on-time rate < 95%") without considering market conditions or trade size. This can lead to false rejections during volatile periods or insufficient risk control for large trades.
- Fix: Implement dynamic thresholds based on notional size and market volatility. Use confidence intervals for statistical metrics.
-
Attestation Blindness
- Explanation: Assuming that a higher attestation tier (e.g., Tier 2) implies lower risk. Attestation verifies identity, not behavior. A verified entity can still have a poor settlement history.
- Fix: Treat attestation as a policy gate, not a risk score. Always combine attestation checks with behavioral analysis.
-
The "Median" Counterparty Trap
- Explanation: Failing to handle counterparties with moderate history (e.g., 30 swaps, 92% on-time). Strict thresholds may reject these, while loose thresholds may accept risky actors.
- Fix: Implement an "Inspect" state for median cases. Escalate to agent decision logic or require additional bonds for borderline counterparties.
-
Cross-Chain Fragmentation
- Explanation: Relying on settlement history from a single chain when the agent trades across multiple networks. An address may have a clean history on Ethereum but poor behavior on SUI.
- Fix: Use a unified directory that aggregates history across chains or require chain-specific validation for each trade leg.
-
RFQ Bond Misinterpretation
- Explanation: Assuming the RFQ bond covers all risks. The bond prevents withdrawal but does not guarantee settlement quality or timeliness.
- Fix: Combine RFQ verification with behavioral checks. The bond is a structural guarantee, not a comprehensive risk mitigation.
-
Ignoring Tooling Abstraction
- Explanation: Building raw API calls for each filter instead of using standardized tool interfaces. This increases complexity and reduces agent interoperability.
- Fix: Integrate with MCP servers or standardized tooling that abstracts the pipeline into a single
quote or validate call.
Production Bundle
Action Checklist
Decision Matrix
| Scenario | Recommended Approach | Why | Cost Impact |
|---|
| Retail Agent Trading Small Notional | Tier 0 Attestation, Low History Threshold | Minimizes friction for small trades; behavioral history is sufficient. | Low |
| Institutional Agent Trading Large Notional | Tier 2 Attestation, High History Threshold | Requires verified identity and proven track record for risk mitigation. | Medium |
| New Counterparty with No History | Escalate to Agent Decision, Require Higher Bond | Lack of history increases risk; bond provides economic deterrent. | Medium |
| Cross-Chain Trade | Chain-Specific Validation, Unified Directory | Ensures accurate risk assessment across different network behaviors. | High |
| High Volatility Market | Dynamic Thresholds, Shorter Timelocks | Adapts to market conditions; reduces exposure to rapid price swings. | Low |
Configuration Template
{
"agentPolicy": {
"behavioralThresholds": {
"minSwaps": 10,
"minOnTimeRate": 0.95,
"maxTimeoutRate": 0.05,
"windowDays": 30
},
"attestationPolicy": {
"tiers": {
"0": { "maxNotional": "1000" },
"1": { "maxNotional": "10000" },
"2": { "maxNotional": "unlimited" }
}
},
"htlcParameters": {
"minTimelockSeconds": 3600,
"hashAlgorithm": "sha256"
},
"escalation": {
"medianCounterparty": "ESCALATE_TO_AGENT",
"confidenceInterval": 0.95
}
}
}
Quick Start Guide
- Install SDK: Add the counterparty validation SDK to your agent project via npm or package manager.
- Configure Policy: Define your risk thresholds and attestation requirements in the configuration file.
- Initialize Pipeline: Instantiate the
CounterpartyValidator with the configured policy and pipeline engines.
- Execute Validation: Call the
validate method with counterparty data before executing any trade.
- Handle Result: Proceed with trade execution if status is
PASS; otherwise, log rejection reason and abort.
This pipeline provides a robust, scalable foundation for autonomous counterparty trust, enabling agents to trade safely and efficiently in decentralized markets. By prioritizing behavioral data, structural commitments, and cryptographic guarantees, developers can build agents that operate with the precision and reliability required for production environments.