From e3c8f7423ab4cedf8ed044eb5dea13838ca3193b Mon Sep 17 00:00:00 2001 From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2026 02:22:40 +0000 Subject: [PATCH] docs(sdk): update delivery protection docs for v2 OrConditions and PaymentIndexRecorder Generated-By: mintlify-agent --- sdk/delivery-arbiter.mdx | 6 +++- sdk/delivery-protection.mdx | 7 ++-- sdk/deploy-operator.mdx | 71 +++++++++++++++++++++++++++++++------ sdk/overview.mdx | 2 +- 4 files changed, 71 insertions(+), 15 deletions(-) diff --git a/sdk/delivery-arbiter.mdx b/sdk/delivery-arbiter.mdx index 66b3290..6ac4f48 100644 --- a/sdk/delivery-arbiter.mdx +++ b/sdk/delivery-arbiter.mdx @@ -76,7 +76,9 @@ app.post('/verify', async (req, res) => { await arbiter.payment.release(paymentInfo, amounts.capturableAmount) res.json({ verdict: 'PASS' }) } else { - // Do nothing. Funds auto-refund after escrow expires. + // Arbiter can refund immediately without waiting for escrow expiry. + const amounts = await arbiter.payment.getAmounts(paymentInfo) + await arbiter.refund.refundInEscrow(paymentInfo, amounts.capturableAmount) res.json({ verdict: 'FAIL' }) } }) @@ -108,6 +110,8 @@ async function evaluate(responseBody: string): Promise { ### 5. What Happens on Failure +With delivery protection v2, the arbiter can call `refundInEscrow()` immediately on a FAIL verdict. You do not need to wait for escrow expiry. The receiver (merchant) can also trigger a voluntary refund at any time. + If your service goes down, no payments get evaluated and funds stay in escrow until timeout. The escrow period protects payers, but add uptime monitoring and alerting. diff --git a/sdk/delivery-protection.mdx b/sdk/delivery-protection.mdx index a466e2d..e4867e1 100644 --- a/sdk/delivery-protection.mdx +++ b/sdk/delivery-protection.mdx @@ -4,16 +4,17 @@ description: "Automated quality verification for every transaction." icon: "shield-check" --- -In the delivery protection model, the arbiter evaluates every transaction automatically. Only the arbiter can release funds. If the arbiter does not release, funds auto-refund to the payer after escrow expires. +In the delivery protection model, the arbiter evaluates every transaction automatically. The arbiter or a satisfied payer can release funds. If the arbiter issues a FAIL verdict, it can trigger an immediate refund without waiting for escrow expiry. If nobody acts, funds auto-refund to the payer after escrow expires. This is different from the [marketplace model](/sdk/overview) where the merchant releases funds and the arbiter only gets involved when a payer files a dispute. | | Marketplace | Delivery Protection | |---|---|---| -| Who releases funds | Merchant (after escrow) | Arbiter only | +| Who releases funds | Merchant (after escrow) | Arbiter or payer | +| Refund during escrow | Receiver or arbiter | Escrow expiry, receiver, or arbiter | | Dispute process | Payer files refund request | No disputes needed | | Arbiter involvement | Only on disputes | Every transaction | -| Contracts needed | Operator + EscrowPeriod + RefundRequest + Evidence + Freeze | Operator + EscrowPeriod + StaticAddressCondition | +| Contracts deployed | ~8 (Operator, EscrowPeriod, RefundRequest, Evidence, Freeze, etc.) | 6 (Operator, EscrowPeriod, SAC, 2x OrCondition, RecorderCombinator) | | Deploy preset | `deployMarketplaceOperator()` | `deployDeliveryProtectionOperator()` | Use this when every response needs automated quality checks: AI content verification, garbage detection, schema validation. diff --git a/sdk/deploy-operator.mdx b/sdk/deploy-operator.mdx index ca8f7a1..8c19e62 100644 --- a/sdk/deploy-operator.mdx +++ b/sdk/deploy-operator.mdx @@ -117,7 +117,7 @@ Deployment requires gas fees. Ensure your wallet has ETH on the target network. ## Delivery Protection Operator -For automated quality verification (AI garbage detection, schema validation), use the simpler delivery protection preset. No RefundRequest, Evidence, or Freeze contracts. The arbiter is the only address that can release funds. +For automated quality verification (AI garbage detection, schema validation), use the delivery protection preset. No RefundRequest, Evidence, or Freeze contracts. The arbiter or payer can release funds, and the arbiter can issue immediate refunds without waiting for escrow expiry. ```typescript import { deployDeliveryProtectionOperator } from '@x402r/core' @@ -136,23 +136,74 @@ const deployment = await deployDeliveryProtectionOperator( console.log('Operator:', deployment.operatorAddress) console.log('EscrowPeriod:', deployment.escrowPeriodAddress) console.log('ArbiterCondition:', deployment.arbiterConditionAddress) +console.log('ReleaseCondition:', deployment.releaseConditionAddress) +console.log('AuthorizeRecorder:', deployment.authorizeRecorderAddress) ``` | Option | Type | Description | |--------|------|-------------| | `chainId` | `number` | Target chain | -| `arbiter` | `Address` | Only address that can call `release()` | +| `arbiter` | `Address` | Arbiter address for release and refund decisions | | `feeRecipient` | `Address` | Receives protocol fees | | `escrowPeriodSeconds` | `bigint` | Verification window before auto-refund | +| `authorizedCodehash` | `Hex` | Override the default `recorderCombinatorCodehash`. Optional | +| `paymentIndexRecorderAddress` | `Address` | Override the default PaymentIndexRecorder. Pass `zeroAddress` to skip on-chain payment indexing. Optional | +| `allowArbiterRefund` | `boolean` | Allow arbiter to refund immediately during escrow. Default: `true` | - - | Slot | Contract | Purpose | - |------|----------|---------| - | `RELEASE_CONDITION` | StaticAddressCondition(arbiter) | Only arbiter can release | - | `AUTHORIZE_RECORDER` | EscrowPeriod | Records authorization time | - | `REFUND_IN_ESCROW_CONDITION` | EscrowPeriod | Anyone can refund after escrow expires | - | `REFUND_POST_ESCROW_CONDITION` | Receiver | Receiver can refund post-escrow | - + + + ```typescript + interface DeliveryProtectionOperatorDeployment { + operatorAddress: Address + escrowPeriodAddress: Address + arbiterConditionAddress: Address + releaseConditionAddress: Address // OrCondition([arbiter, payer]) + refundInEscrowConditionAddress: Address // OrCondition([escrowPeriod, receiver, arbiter]) + authorizeRecorderAddress: Address // RecorderCombinator([escrowPeriod, paymentIndexRecorder]) + paymentIndexRecorderAddress: Address + operatorConfig: OperatorConfig + deployments: DeployResult[] + summary: { + newCount: number + existingCount: number + txHashes: `0x${string}`[] + } + } + ``` + + Deploys 6 contracts by default: EscrowPeriod, StaticAddressCondition(arbiter), OrCondition(release), OrCondition(refund), RecorderCombinator, and the Operator. If you pass `paymentIndexRecorderAddress: zeroAddress`, the RecorderCombinator is skipped (5 contracts). + + Redeploying with the same parameters is idempotent (CREATE3). It detects existing contracts and skips them. + + + + Compute addresses without deploying: + + ```typescript + import { previewDeliveryProtectionOperator } from '@x402r/core' + + const preview = await previewDeliveryProtectionOperator(publicClient, { + chainId: 84532, + arbiter: '0xArbiterServiceAddress', + feeRecipient: account.address, + escrowPeriodSeconds: 300n, + }) + + console.log('Operator will be at:', preview.operatorAddress) + console.log('EscrowPeriod will be at:', preview.escrowPeriodAddress) + console.log('AuthorizeRecorder will be at:', preview.authorizeRecorderAddress) + ``` + + + + | Slot | Contract | Purpose | + |------|----------|---------| + | `RELEASE_CONDITION` | OrCondition([SAC(arbiter), PayerCondition]) | Arbiter or satisfied payer can release | + | `AUTHORIZE_RECORDER` | RecorderCombinator([EscrowPeriod, PaymentIndexRecorder]) | Records authorization time and indexes payments on-chain | + | `REFUND_IN_ESCROW_CONDITION` | OrCondition([EscrowPeriod, ReceiverCondition, SAC(arbiter)]) | Escrow expiry, receiver voluntary refund, or arbiter immediate refund | + | `REFUND_POST_ESCROW_CONDITION` | ReceiverCondition | Only receiver after escrow | + + ## Next Steps diff --git a/sdk/overview.mdx b/sdk/overview.mdx index 4b43e59..14a0e90 100644 --- a/sdk/overview.mdx +++ b/sdk/overview.mdx @@ -16,7 +16,7 @@ Three roles interact with the protocol: **Marketplace** (`deployMarketplaceOperator`): The merchant releases funds after escrow. If the payer contests, they file a refund request and an arbiter resolves it. Use this for general commerce where most transactions are uncontested. -**Delivery Protection** (`deployDeliveryProtectionOperator`): The arbiter evaluates every transaction automatically and is the only address that can release funds. If the arbiter does not release, funds auto-refund after escrow. Use this for AI content verification, schema validation, or automated quality checks. +**Delivery Protection** (`deployDeliveryProtectionOperator`): The arbiter evaluates every transaction automatically. The arbiter or a satisfied payer can release funds. On a FAIL verdict, the arbiter can trigger an immediate refund. If nobody acts, funds auto-refund after escrow. Use this for AI content verification, schema validation, or automated quality checks. ### Packages