x402 solved the payment. BOND solves the deal.
A lightweight, open protocol for recurring agent-to-agent agreements on top of x402.
Two agents negotiate terms, both sign the schema, an EAS attestation records the mandate on-chain, and the mandate executor (e.g. PayAI) processes one x402 payment per period until the deal completes — or breaks.
| Layer | What it does |
|---|---|
| Recurring Deal Schema | Structured terms of an agent-to-agent recurring agreement — EIP-712-signed by both parties |
| Mandate | The on-chain (EAS) signed authorization derived from a sealed deal |
| Execution Model | How periodic x402 payments are triggered, validated, and recorded |
| Default Model | What happens when a party defaults — distinguishes willful default (trust penalty) from insufficient funds (circuit breaker, no penalty) |
BOND does not replace x402. Every BOND payment is a standard x402 transaction. BOND adds the layer that coordinates when those transactions happen and what they mean.
- x402 gave agents a way to pay per request. There's no permissionless way for two agents to commit to a recurring relationship with negotiated bulk pricing.
- MPP (Stripe/Tempo) solves recurring billing for the centralized world: merchants onboard, platforms enforce compliance, one company holds the state.
- BOND is the open-protocol equivalent: any two ERC-8004 agents, no whitelist, no merchant account, on-chain mandate state.
npm install @godman-protocols/bondimport {
verifyMandateRequest,
classifyDefault,
trustImpactFor,
type RecurringDealSchema,
type MandateModeHeaders,
} from '@godman-protocols/bond';
// 1. The mandate, signed by both agents and attested on-chain
const mandate: RecurringDealSchema = {
mandate_id: '0xABCD...',
buyer_did: 'did:ethr:0x1234...',
seller_did: 'did:ethr:0x5678...',
quantity_per_period: 5,
period_unit: 'week',
total_periods: 7,
amount_per_period: '0.40',
currency: 'USDC',
chain: 'base',
spot_price_per_unit: '0.12',
bulk_price_per_unit: '0.08',
mandate_start: 1714000000,
cancellation_notice_periods: 1,
buyer_signature: '0x...',
seller_signature: '0x...',
eas_attestation_uid: '0x...', // empty until on-chain attest lands
};
// 2. Seller presents an x402 request with mandate-mode headers
const headers: MandateModeHeaders = {
'X-Mandate-ID': mandate.mandate_id,
'X-Mandate-Period': 4,
'X-Mandate-Total-Periods': 7,
};
// 3. Executor validates before settling
const result = verifyMandateRequest({
mandate,
headers,
claimed_amount: '0.40',
claimed_currency: 'USDC',
claimed_chain: 'base',
now_seconds: Math.floor(Date.now() / 1000),
settled_periods: [1, 2, 3],
});
if (!result.ok) {
console.error(`Mandate rejected: ${result.reason}`);
} else {
// Execute the x402 payment, write the DRS receipt, increment settled period
}Per the spec, every BOND mandate request runs through four validations before execution:
| # | Check | Where |
|---|---|---|
| 1 | Is this mandate active on-chain? | EAS attestation lookup (caller hook) |
| 2 | Is this the correct period? | Local — verify.ts |
| 3 | Does the amount match the signed terms? | Local — verify.ts |
| 4 | Has the seller's DID signed this request? | Caller-supplied signature verifier |
verifyMandateRequest() runs the cheap deterministic checks first so a malformed request fails before any on-chain or cryptographic work happens.
import { classifyDefault, trustImpactFor } from '@godman-protocols/bond';
const reason = classifyDefault({
buyer_balance: '0.10',
amount_per_period: '0.40',
buyer_refused: false,
});
// → 'INSUFFICIENT_FUNDS' (no trust penalty, circuit breaker engaged)
const refusal = classifyDefault({
buyer_balance: '100.00',
amount_per_period: '0.40',
buyer_refused: true,
});
// → 'WILLFUL_DEFAULT' (bulk-deal trust ceiling reduced, spot x402 stays open)
const impact = trustImpactFor(refusal, 'did:ethr:0x1234');
// → { ceiling_multiplier: 0.5, spot_access_restricted: false, ... }The proportionality principle: a willful defaulter loses access to negotiated deals, not to the payment rails. This mirrors how credit scoring works in practice — you can still buy things with cash, you just can't get a mortgage.
| Protocol | Relation to BOND |
|---|---|
| SOUL | Source of buyer + seller DIDs in the mandate |
| PACT | Chamber 4 = deal-signing room. Trust registry = enforcement source |
| BOND | Recurring mandate standard (this package) |
| LAX | How buyers find sellers offering recurring access |
| SCORE | Trust score input for default-penalty calculation |
| AMF | How agents remember and reference active mandates |
| DRS | BOND receipts use DRS format: one receipt per period |
Each is useful standalone. Together they describe a complete agent interaction stack.
✅ In v0.1:
- Full
RecurringDealSchematype definitions - Mandate-mode x402 header conventions
- The four executor validation checks
- Default-reason classification + trust-impact mapping
- Period math helpers (window start, current period)
- EIP-712 typed-data structure for signing
❌ Deferred to v0.2:
- Live EAS attestation read/write helpers (BYO via the caller hook)
- Mandate amendment flow (re-sign vs. amendment-attestation)
- Partial-period delivery attestation format
- Multi-party mandates (A → B → C sub-contracting)
- Cross-chain mandates (negotiation on chain X, settlement on chain Y)
- Private mandates (ZK-attested with on-chain commitment)
v0.1 — Draft for review. The intent is to start a conversation, not present a finished system. Feedback on the architecture, the mandate format, and the enforcement model is genuinely welcome.
Issues: https://github.com/Godman-s/bond/issues
Apache-2.0 © SkinGem