diff --git a/contracts/conditions.mdx b/contracts/conditions.mdx index 1abf2dc..fa60d6a 100644 --- a/contracts/conditions.mdx +++ b/contracts/conditions.mdx @@ -670,7 +670,7 @@ config.releaseCondition = businessHours.address; Deploy operators with conditions using the SDK. - + Interact with freeze and escrow conditions via the Client SDK. diff --git a/docs.json b/docs.json index 3140914..9ab727f 100644 --- a/docs.json +++ b/docs.json @@ -55,45 +55,24 @@ ] }, { - "group": "Client SDK", + "group": "Merchant", "pages": [ - "sdk/client/quickstart", - "sdk/client/payment-queries", - "sdk/client/refund-operations", - "sdk/client/escrow-management", - "sdk/client/subscriptions" - ] - }, - { - "group": "Merchant SDK", - "pages": [ - "sdk/merchant/quickstart", - "sdk/merchant/payment-operations", - "sdk/merchant/refund-handling", - "sdk/merchant/subscriptions" - ] - }, - { - "group": "Arbiter SDK", - "pages": [ - "sdk/arbiter/quickstart", - "sdk/arbiter/decision-submission", - "sdk/arbiter/registry", - "sdk/arbiter/batch-operations", - "sdk/arbiter/ai-integration", - "sdk/arbiter/subscriptions" + "sdk/merchant/getting-started", + "sdk/helpers/refundable" ] }, { - "group": "Resource Server", + "group": "Facilitator", "pages": [ - "sdk/helpers/refundable" + "sdk/facilitator/getting-started" ] }, { - "group": "Reference", + "group": "Coming Soon", "pages": [ - "sdk/limitations" + "sdk/merchant/quickstart", + "sdk/client/quickstart", + "sdk/arbiter/quickstart" ] } ] diff --git a/index.mdx b/index.mdx index d08f29b..dd471df 100644 --- a/index.mdx +++ b/index.mdx @@ -44,11 +44,11 @@ sequenceDiagram Request refunds, freeze suspicious payments, and track payment state. - + Release funds, process refunds, and manage escrow periods. - Resolve disputes, approve/deny refund requests, and integrate AI decision-making. + Resolve disputes and approve/deny refund requests. diff --git a/roadmap.mdx b/roadmap.mdx index 7264c5b..3da3270 100644 --- a/roadmap.mdx +++ b/roadmap.mdx @@ -53,7 +53,7 @@ icon: "map" ### Phase 1: MVP Examples (Completed) -- 7 examples (deploy-operator, merchant-server, merchant-cli, client-cli, arbiter-cli *(in progress)*, e2e-dispute, shared) +- 8 examples (deploy-operator, facilitator, server-express, server-hono, merchant-cli, client-cli, arbiter-cli, shared) - Full e2e dispute resolution flow ### Phase 2: Core SDK (Completed) diff --git a/sdk/arbiter/quickstart.mdx b/sdk/arbiter/quickstart.mdx index c58dd72..e4656f7 100644 --- a/sdk/arbiter/quickstart.mdx +++ b/sdk/arbiter/quickstart.mdx @@ -1,21 +1,21 @@ --- -title: "Arbiter Quickstart" -description: "Get started with the X402r Arbiter SDK for dispute resolution" +title: "Arbiter SDK" +description: "Dispute resolution SDK for reviewing cases and making decisions (experimental)" icon: "rocket" --- -The `@x402r/arbiter` package provides everything arbiters need to resolve disputes: reviewing cases, making decisions, executing refunds, and integrating AI for automated resolution. + +The Arbiter SDK is experimental. The dispute resolution system design is actively evolving. + -## Installation + +The `@x402r/arbiter` package is not yet published on npm. Install directly from the [GitHub repository](https://github.com/BackTrackCo/x402r-sdk). + -```bash -npm install @x402r/arbiter @x402r/core viem -``` +The `@x402r/arbiter` package provides methods for arbiters to resolve disputes: reviewing refund requests, approving or denying them, and executing refunds. ## Setup -Create viem clients as described in [Installation](/sdk/installation), then: - ```typescript import { X402rArbiter } from '@x402r/arbiter'; import { getNetworkConfig } from '@x402r/core'; @@ -31,119 +31,33 @@ const arbiter = new X402rArbiter({ }); ``` -## Review Pending Cases - -Get refund requests awaiting your decision: - -```typescript -// Get paginated refund requests for a receiver -const { keys, total } = await arbiter.getPendingRefundRequests( - 0n, // offset - 10n, // count - '0xReceiverAddress...' // optional: defaults to wallet account -); -console.log(`${total} cases to review, showing first ${keys.length}`); - -// Review each case -for (const key of keys) { - const request = await arbiter.getRefundRequestByKey(key); - console.log(`Amount: ${request.amount}, Status: ${request.status}`); -} -``` - -## Make a Decision +## Available Methods -Approve or deny refund requests: +The Arbiter SDK currently supports: -```typescript -// Approve a refund request -const { txHash: approveTx } = await arbiter.approveRefundRequest(paymentInfo, 0n); -console.log('Approved:', approveTx); +- **`approveRefundRequest()`** — Approve a pending refund request +- **`denyRefundRequest()`** — Deny a pending refund request +- **`executeRefundInEscrow()`** — Execute an approved refund to transfer funds back +- **`getPendingRefundRequests()`** — List refund requests awaiting decision +- **`getRefundRequestByKey()`** — Get details of a specific refund request +- **`registerArbiter()`** — Register in the on-chain ArbiterRegistry +- **`isArbiterRegistered()`** — Check registration status -// Deny a refund request -const { txHash: denyTx } = await arbiter.denyRefundRequest(paymentInfo, 0n); -console.log('Denied:', denyTx); -``` +## Try It Now -## Execute Approved Refunds +The easiest way to try arbiter features is with the **arbiter-cli** example, which provides a command-line interface for all arbiter operations: -After approving, execute the refund to transfer funds back to the payer: - -```typescript -// Approve the request first -await arbiter.approveRefundRequest(paymentInfo, 0n); - -// Execute the refund (defaults to paymentInfo.maxAmount if no amount specified) -const { txHash } = await arbiter.executeRefundInEscrow(paymentInfo); -console.log('Refund executed:', txHash); - -// Or specify a partial refund amount -const { txHash: partialTx } = await arbiter.executeRefundInEscrow( - paymentInfo, - BigInt('500000') // partial amount -); -``` - -## Batch Operations - -Process multiple cases efficiently: - -```typescript -// Approve multiple refunds -const results = await arbiter.batchApprove([ - { paymentInfo: paymentInfo1, nonce: 0n }, - { paymentInfo: paymentInfo2, nonce: 0n }, -]); -console.log(`Approved ${results.length} refunds`); - -// Deny multiple refunds -const denyResults = await arbiter.batchDeny([ - { paymentInfo: paymentInfo3, nonce: 0n }, -]); -``` - -## Register as an Arbiter - -Register yourself in the on-chain ArbiterRegistry: - -```typescript -// Register with your API endpoint -const { txHash } = await arbiter.registerArbiter('https://arbiter.example.com/api/disputes'); -console.log('Registered:', txHash); - -// Check registration -const isRegistered = await arbiter.isArbiterRegistered(account.address); -console.log('Is registered:', isRegistered); -``` - -## Watch for New Cases - -Subscribe to incoming refund requests: - -```typescript -const { unsubscribe } = arbiter.watchNewCases((event) => { - console.log('New case:', event); -}); - -// Watch for decisions (status updates) -const { unsubscribe: unsubDecisions } = arbiter.watchDecisions((event) => { - console.log('Decision made:', event); -}); -``` + + CLI tool for arbiters to review cases, make decisions, and manage registry. + ## Next Steps - - Learn all decision methods including executeRefundInEscrow. - - - Manage your arbiter registration and discover other arbiters. - - - Process multiple cases efficiently. + + See all working examples including the full payment flow. - - Automate with AI hooks. + + Deploy a PaymentOperator with arbiter support. diff --git a/sdk/client/quickstart.mdx b/sdk/client/quickstart.mdx index 635029a..fba6594 100644 --- a/sdk/client/quickstart.mdx +++ b/sdk/client/quickstart.mdx @@ -1,21 +1,21 @@ --- -title: "Client Quickstart" -description: "Get started with the X402r Client SDK for payer integrations" +title: "Client SDK" +description: "Payer-side SDK for refunds, freezes, and escrow management (experimental)" icon: "rocket" --- -The `@x402r/client` package provides everything payers need to interact with X402r payments: requesting refunds, freezing payments, and managing escrow. + +The Client SDK is experimental. APIs will change as the refund and dispute system design evolves. + -## Installation + +The `@x402r/client` package is not yet published on npm. Install directly from the [GitHub repository](https://github.com/BackTrackCo/x402r-sdk). + -```bash -npm install @x402r/client @x402r/core viem -``` +The `@x402r/client` package provides payer-side methods for interacting with X402r payments: requesting refunds, freezing payments, and querying escrow state. ## Setup -Create viem clients as described in [Installation](/sdk/installation), then: - ```typescript import { X402rClient } from '@x402r/client'; import { getNetworkConfig } from '@x402r/core'; @@ -31,97 +31,32 @@ const client = new X402rClient({ }); ``` -## Request a Refund - -Submit a refund request for a payment that is in escrow: - -```typescript -// Request refund for the first charge (nonce = 0n) -const { txHash } = await client.requestRefund( - paymentInfo, - BigInt('1000000'), // amount to refund (e.g., 1 USDC) - 0n // nonce: identifies which charge -); -console.log(`Refund requested: ${txHash}`); - -// Check refund status -const status = await client.getRefundStatus(paymentInfo, 0n); -console.log(`Refund status: ${status}`); -// 0 = Pending, 1 = Approved, 2 = Denied, 3 = Cancelled -``` - -## Check Escrow Period - -Query whether the payment is still within its escrow period: - -```typescript -const escrowPeriodAddress = '0x...'; // EscrowPeriod contract address - -// Check if still within escrow period -const inEscrow = await client.isDuringEscrowPeriod(paymentInfo, escrowPeriodAddress); -if (inEscrow) { - console.log('Still in escrow period - can request refund'); -} else { - console.log('Escrow period passed - funds can be released'); -} - -// Get when the payment was authorized -const authTime = await client.getAuthorizationTime(paymentInfo, escrowPeriodAddress); -console.log(`Authorized at: ${new Date(Number(authTime) * 1000)}`); -``` - -## Freeze a Payment +## Available Methods -Freeze a payment to prevent release while a dispute is resolved: +The Client SDK currently supports: -```typescript -const freezeAddress = '0x...'; // Freeze contract address +- **`requestRefund()`** — Submit a refund request for a payment in escrow +- **`getRefundStatus()`** — Check the status of a refund request +- **`freezePayment()`** — Freeze a payment to prevent release during a dispute +- **`isFrozen()`** — Check if a payment is frozen +- **`isDuringEscrowPeriod()`** — Check if a payment is still in its escrow window +- **`getAuthorizationTime()`** — Get when a payment was authorized -// Freeze the payment (only payer can do this) -const { txHash } = await client.freezePayment(paymentInfo, freezeAddress); -console.log(`Payment frozen: ${txHash}`); +## Try It Now -// Check if payment is frozen -const frozen = await client.isFrozen(paymentInfo, freezeAddress); -console.log(`Frozen: ${frozen}`); -``` +The easiest way to try client features is with the **client-cli** example, which provides a command-line interface for all client operations: -## Watch for Updates - -Subscribe to real-time events: - -```typescript -// Watch payment state changes (releases, refunds) -const { unsubscribe } = client.watchPaymentState( - paymentInfoHash, - (event) => { - console.log('Payment event:', event.eventName); - } -); - -// Watch for refund request updates -const { unsubscribe: unsubRefunds } = client.watchRefundRequests((event) => { - console.log('Refund event:', event.eventName); -}); - -// Later: stop watching -unsubscribe(); -unsubRefunds(); -``` + + CLI tool for payers to `pay`, `preview-fee`, request refunds, freeze payments, and check status. + ## Next Steps - - Learn about payment query methods (including stubbed methods pending subgraph). - - - Deep dive into refund workflows. - - - Manage freeze and escrow timing. + + See all working examples including the full payment flow. - - Real-time event watching. + + Deploy a PaymentOperator to test client operations against. diff --git a/sdk/concepts.mdx b/sdk/concepts.mdx index 712fd21..3b66c61 100644 --- a/sdk/concepts.mdx +++ b/sdk/concepts.mdx @@ -197,11 +197,8 @@ flowchart TB Deploy your own PaymentOperator with all supporting contracts. - - Build payer-side integrations. - - - Add refund support to your server. + + Working examples for merchants, clients, and arbiters. Understand the underlying contract architecture. diff --git a/sdk/deploy-operator.mdx b/sdk/deploy-operator.mdx index 91c9374..b02996f 100644 --- a/sdk/deploy-operator.mdx +++ b/sdk/deploy-operator.mdx @@ -144,11 +144,8 @@ Deployment requires gas fees. Ensure your wallet has ETH on the target network. ## Next Steps - - Use the operator address with the Client SDK. - - - Release funds and handle refunds. + + See working merchant and client examples. Mark payment options as refundable with your operator. diff --git a/sdk/examples.mdx b/sdk/examples.mdx index 1cc76ba..44df86f 100644 --- a/sdk/examples.mdx +++ b/sdk/examples.mdx @@ -9,26 +9,29 @@ The SDK includes working examples in the `x402r-sdk/` repository. Each is a stan ## Examples - - HTTP service implementing x402's facilitator protocol for escrow payments. Handles signature verification and on-chain settlement. + + Operator-agnostic HTTP service implementing x402's facilitator protocol for escrow payments. Handles signature verification and on-chain settlement. Deploy a complete marketplace operator with escrow, freeze, and arbiter support. - - HTTP server that accepts escrow payments via x402's standard `paymentMiddleware`. Delegates verify/settle to the facilitator service. + + Express merchant server using `EscrowServerScheme`, `HTTPFacilitatorClient`, and `refundable()` to accept escrow payments via x402 middleware. - - CLI tool for merchants to release payments, approve/deny refunds, and query state. + + Hono merchant server using `EscrowServerScheme`, `HTTPFacilitatorClient`, and `refundable()` to accept escrow payments via x402 middleware. - - CLI tool for payers to request refunds, freeze payments, and check status. + + CLI tool for merchants to release payments, approve/deny refunds, and query escrow state. - - CLI tool for arbiters to review cases, make decisions, and manage registry. This example is under active development. + + CLI tool for payers to `pay`, `preview-fee`, request refunds, freeze payments, and check status. - - Shared utilities used by the CLI examples (display helpers, PaymentInfo formatting). + + CLI tool for arbiters to review cases, make decisions, and manage registry. + + + Shared utilities used by the CLI examples: `parsePaymentInfo`, `shortAddress`, `formatUSDC`. @@ -41,24 +44,28 @@ All examples require a private key with Base Sepolia ETH and USDC. See [Base net The full payment flow requires the facilitator to be running before the merchant server: ```bash -# 1. Start the facilitator service -cd x402r-sdk/examples/facilitator -cp .env.example .env # Set PRIVATE_KEY + OPERATOR_ADDRESS -pnpm dev - -# 2. Start the merchant server (new terminal) -cd x402r-sdk/examples/merchant-server -cp .env.example .env # Set PRIVATE_KEY, OPERATOR_ADDRESS, FACILITATOR_URL -pnpm dev - -# 3. Make a payment (new terminal) -cd x402r-sdk/examples/client-cli -cp .env.example .env # Set PRIVATE_KEY -pnpm start pay --url http://localhost:3000/weather +# All commands run from the x402r-sdk/ root directory + +# 1. Set up environment files +cp examples/facilitator/basic/.env-local examples/facilitator/basic/.env +# Edit .env — set PRIVATE_KEY + +cp examples/servers/express/.env-local examples/servers/express/.env +# Edit .env — set ADDRESS, OPERATOR_ADDRESS, FACILITATOR_URL + +# 2. Start the facilitator (port 4022) +pnpm example:facilitator + +# 3. Start the merchant server (new terminal, port 4021) +pnpm example:server:express +# Or: pnpm example:server:hono + +# 4. Make a payment (new terminal) +pnpm example:client-cli pay --url http://localhost:4021/weather ``` -The facilitator must be running before the merchant server starts, as the merchant delegates payment verification and settlement to it. +The facilitator must be running before the merchant server (Express or Hono) starts, as the merchant delegates payment verification and settlement to it. ## deploy-operator @@ -83,9 +90,9 @@ const result = await deployMarketplaceOperator( See [Deploy an Operator](/sdk/deploy-operator) for the full guide. -## merchant-server +## Server Examples -Demonstrates a minimal HTTP server that uses x402's standard middleware: +Demonstrates minimal merchant servers (Express and Hono variants) that use `EscrowServerScheme`, `HTTPFacilitatorClient`, and `refundable()` via x402's standard middleware: 1. Returns 402 with `refundable()` payment options 2. Delegates payment verification to the facilitator via `HTTPFacilitatorClient` @@ -95,14 +102,14 @@ Demonstrates a minimal HTTP server that uses x402's standard middleware: ## Next Steps - - Build a payer integration. + + Deploy a PaymentOperator with escrow and freeze support. - - Build a merchant integration. + + Mark payment options as refundable with escrow configuration. - - Build an arbiter integration. + + Understand the payment lifecycle and key concepts. Browse all examples on GitHub. diff --git a/sdk/facilitator/getting-started.mdx b/sdk/facilitator/getting-started.mdx new file mode 100644 index 0000000..e30d702 --- /dev/null +++ b/sdk/facilitator/getting-started.mdx @@ -0,0 +1,174 @@ +--- +title: "Facilitator Quickstart" +description: "Run your own x402r facilitator service to verify and settle escrow payments" +icon: "server" +--- + + +The X402r SDK packages are not yet published on npm. Install directly from the [GitHub repository](https://github.com/BackTrackCo/x402r-sdk). See [Installation](/sdk/installation) for details. + + +A facilitator is a service that verifies payment signatures and settles escrow transactions on-chain. This guide walks you through running your own facilitator on Base Sepolia. + + +The full source code for this example is available on [GitHub](https://github.com/BackTrackCo/x402r-sdk/tree/main/examples/facilitator/basic). + + +## Prerequisites + +- Node.js 20+ +- A wallet private key with Base Sepolia ETH + + +Never commit private keys to source control. Use environment variables or a secrets manager. + + +## Setup + + + + ```bash + mkdir facilitator && cd facilitator + npm init -y + npm install @x402/core @x402/evm @x402r/evm express dotenv viem + ``` + + + + Create a `.env` file in the project root: + + ```bash + PRIVATE_KEY=0xYourPrivateKey + PORT=4022 + ``` + + + + Create `index.ts`: + + ```typescript + import "dotenv/config"; + import express from "express"; + import { x402Facilitator } from "@x402/core/facilitator"; + import { PaymentPayload, PaymentRequirements } from "@x402/core/types"; + import { toFacilitatorEvmSigner } from "@x402/evm"; + import { registerEscrowScheme } from "@x402r/evm/escrow/facilitator"; + import { createWalletClient, http, publicActions } from "viem"; + import { privateKeyToAccount } from "viem/accounts"; + import { baseSepolia } from "viem/chains"; + + if (!process.env.PRIVATE_KEY) { + console.error("PRIVATE_KEY environment variable is required"); + process.exit(1); + } + + const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`); + console.info(`Facilitator account: ${account.address}`); + + const viemClient = createWalletClient({ + account, + chain: baseSepolia, + transport: http(), + }).extend(publicActions); + + const evmSigner = toFacilitatorEvmSigner({ + address: account.address, + getCode: (args) => viemClient.getCode(args), + readContract: (args) => viemClient.readContract({ ...args, args: args.args || [] }), + verifyTypedData: (args) => viemClient.verifyTypedData(args as any), + writeContract: (args) => viemClient.writeContract({ ...args, args: args.args || [] }), + sendTransaction: (args) => viemClient.sendTransaction(args), + waitForTransactionReceipt: (args) => viemClient.waitForTransactionReceipt(args), + }); + + const facilitator = new x402Facilitator(); + + registerEscrowScheme(facilitator, { + signer: evmSigner, + networks: "eip155:84532", + }); + + const app = express(); + app.use(express.json()); + + app.post("/verify", async (req, res) => { + const { paymentPayload, paymentRequirements } = req.body as { + paymentPayload: PaymentPayload; + paymentRequirements: PaymentRequirements; + }; + const response = await facilitator.verify(paymentPayload, paymentRequirements); + res.json(response); + }); + + app.post("/settle", async (req, res) => { + const { paymentPayload, paymentRequirements } = req.body; + const response = await facilitator.settle( + paymentPayload as PaymentPayload, + paymentRequirements as PaymentRequirements, + ); + res.json(response); + }); + + app.get("/supported", async (req, res) => { + const response = facilitator.getSupported(); + res.json(response); + }); + + const PORT = process.env.PORT || "4022"; + app.listen(parseInt(PORT), () => { + console.log(`Facilitator listening on http://localhost:${PORT}`); + }); + ``` + + + + ```bash + npx tsx index.ts + ``` + + You should see: + ``` + Facilitator account: 0x... + Facilitator listening on http://localhost:4022 + ``` + + + + ```bash + curl http://localhost:4022/supported + ``` + + The response lists supported payment schemes and networks: + + ```json + { + "supportedSchemes": { + "escrow": { + "networks": ["eip155:84532"] + } + } + } + ``` + + + +## How it works + +- **`x402Facilitator`** is the core facilitator class from `@x402/core` that routes verify and settle requests to registered scheme handlers. +- **`registerEscrowScheme`** adds x402r escrow support to the facilitator, enabling it to verify escrow payment signatures and settle them on-chain. +- **`toFacilitatorEvmSigner`** adapts a viem wallet client into the signer interface the facilitator expects for on-chain interactions. +- The three endpoints (`/verify`, `/settle`, `/supported`) match the interface that `HTTPFacilitatorClient` on the merchant side expects. + +## Next Steps + + + + Set up a merchant server that uses your facilitator. + + + Understand the payment lifecycle and escrow flow. + + + Deploy a PaymentOperator contract for your merchant. + + diff --git a/sdk/helpers/refundable.mdx b/sdk/helpers/refundable.mdx index d75a539..16839b9 100644 --- a/sdk/helpers/refundable.mdx +++ b/sdk/helpers/refundable.mdx @@ -4,6 +4,10 @@ description: "Configure HTTP 402 responses with escrow-backed refundable payment icon: "wrench" --- + +The X402r SDK packages are not yet published on npm. Install directly from the [GitHub repository](https://github.com/BackTrackCo/x402r-sdk). See [Installation](/sdk/installation) for details. + + The `@x402r/helpers` package provides the `refundable()` function — a framework-agnostic helper that adds escrow configuration to x402 payment options. @@ -161,13 +165,10 @@ app.get('/api/resource', (req, res) => { Deploy a PaymentOperator to use with refundable(). - - Full merchant integration guide. + + See merchant server examples using refundable(). Understand the escrow scheme. - - Current SDK constraints. - diff --git a/sdk/installation.mdx b/sdk/installation.mdx index 230bc15..f63fbb3 100644 --- a/sdk/installation.mdx +++ b/sdk/installation.mdx @@ -4,6 +4,10 @@ description: "Install and configure the X402r SDK packages" icon: "download" --- + +The X402r SDK packages are not yet published on npm. Install directly from the [GitHub repository](https://github.com/BackTrackCo/x402r-sdk) using your package manager's Git URL support, or clone the repo and link locally. + + ## Install Packages Install only the packages you need for your use case: @@ -29,11 +33,6 @@ Install only the packages you need for your use case: npm install @x402r/helpers @x402r/core viem ``` - - ```bash - npm install @x402r/client @x402r/merchant @x402r/arbiter @x402r/helpers @x402r/core viem - ``` - ## Setup viem Clients @@ -63,37 +62,13 @@ Network identifiers use the [EIP-155](https://eips.ethereum.org/EIPS/eip-155) fo Never commit private keys to version control. Use environment variables or a secrets manager. -## Quick Verification - -Verify your setup by querying refund status for a payment: - -```typescript -import { X402rClient } from '@x402r/client'; - -const client = new X402rClient({ - publicClient, - operatorAddress: '0x...', // Your PaymentOperator address - refundRequestAddress: config.refundRequest, -}); - -// Check if a refund request exists for a payment -const hasRequest = await client.hasRefundRequest(paymentInfo, 0n); -console.log('Has refund request:', hasRequest); -``` - ## Next Steps Learn about payment states, escrow, and the refund lifecycle. - - Start building as a payer/client. - - - Integrate refunds into your server. - - - Build a dispute resolution system. + + Working examples for merchants, clients, and arbiters. diff --git a/sdk/merchant/getting-started.mdx b/sdk/merchant/getting-started.mdx new file mode 100644 index 0000000..a622666 --- /dev/null +++ b/sdk/merchant/getting-started.mdx @@ -0,0 +1,171 @@ +--- +title: "Merchant Server Quickstart" +description: "Accept escrow-backed refundable payments on your Express server in 5 minutes" +icon: "store" +--- + + +The X402r SDK packages are not yet published on npm. Install directly from the [GitHub repository](https://github.com/BackTrackCo/x402r-sdk). See [Installation](/sdk/installation) for details. + + +This guide walks you through setting up an Express server that accepts x402r escrow-backed payments. By the end, you'll have a paid API endpoint protected by the x402 payment middleware with refundable escrow support. + + +The full source code for this example is available on [GitHub](https://github.com/BackTrackCo/x402r-sdk/tree/main/examples/servers/express). + + +## Prerequisites + +- Node.js 20+ +- A deployed PaymentOperator contract ([Deploy Operator](/sdk/deploy-operator)) +- A running facilitator service ([Facilitator Quickstart](/sdk/facilitator/getting-started)) +- Base Sepolia ETH for testing + +## Setup + + + + ```bash + mkdir merchant-server && cd merchant-server + npm init -y + npm install express @x402/core @x402/express @x402r/evm @x402r/helpers dotenv + ``` + + + + Create a `.env` file in the project root: + + ```bash + ADDRESS=0xYourMerchantAddress + OPERATOR_ADDRESS=0xYourPaymentOperatorAddress + FACILITATOR_URL=http://localhost:4022 + ``` + + + + Create `index.ts`: + + ```typescript + import "dotenv/config"; + import express from "express"; + import { paymentMiddleware, x402ResourceServer } from "@x402/express"; + import { EscrowServerScheme } from "@x402r/evm/escrow/server"; + import { refundable } from "@x402r/helpers"; + import { HTTPFacilitatorClient } from "@x402/core/server"; + + const address = process.env.ADDRESS as `0x${string}`; + const operatorAddress = process.env.OPERATOR_ADDRESS as `0x${string}`; + if (!address || !operatorAddress) { + console.error("Missing required environment variables: ADDRESS, OPERATOR_ADDRESS"); + process.exit(1); + } + + const facilitatorUrl = process.env.FACILITATOR_URL; + if (!facilitatorUrl) { + console.error("FACILITATOR_URL environment variable is required"); + process.exit(1); + } + const facilitatorClient = new HTTPFacilitatorClient({ url: facilitatorUrl }); + + const app = express(); + + app.use( + paymentMiddleware( + { + "GET /weather": { + accepts: [ + refundable( + { + scheme: "escrow", + price: "$0.01", + network: "eip155:84532", + payTo: address, + }, + operatorAddress, + ), + ], + description: "Weather data", + mimeType: "application/json", + }, + }, + new x402ResourceServer(facilitatorClient).register( + "eip155:84532", + new EscrowServerScheme() as never, + ), + ), + ); + + app.get("/weather", (req, res) => { + res.send({ + report: { weather: "sunny", temperature: 70 }, + }); + }); + + app.listen(4021, () => { + console.log("Server listening at http://localhost:4021"); + }); + ``` + + + + ```bash + npx tsx index.ts + ``` + + You should see: + ``` + Server listening at http://localhost:4021 + ``` + + + + ```bash + curl http://localhost:4021/weather + ``` + + Without a valid payment header, the server responds with HTTP 402 and the escrow payment requirements: + + ```json + { + "x402Version": 2, + "accepts": [{ + "scheme": "escrow", + "price": "$0.01", + "network": "eip155:84532", + "payTo": "0x...", + "extra": { + "escrowAddress": "0x...", + "operatorAddress": "0x...", + "tokenCollector": "0x...", + "minFeeBps": 0, + "maxFeeBps": 1000 + } + }] + } + ``` + + + +## How it works + +- **`refundable()`** wraps a standard x402 payment option with escrow configuration (contract addresses, fee bounds) from the network config. +- **`EscrowServerScheme`** registers the escrow payment scheme with the x402 resource server so it can validate escrow-backed payments. +- **`paymentMiddleware`** intercepts requests, checks for a valid payment header, and returns 402 if no payment is provided. +- **`HTTPFacilitatorClient`** connects to the facilitator service that verifies and settles payments on-chain. + +## Next Steps + + + + Configure escrow options and fee bounds. + + + Release payments, handle refunds, and manage escrow. + + + Deploy your own PaymentOperator contract. + + + Run your own facilitator service. + + diff --git a/sdk/merchant/quickstart.mdx b/sdk/merchant/quickstart.mdx index fe672d7..8c3ac70 100644 --- a/sdk/merchant/quickstart.mdx +++ b/sdk/merchant/quickstart.mdx @@ -1,5 +1,5 @@ --- -title: "Merchant Quickstart" +title: "Merchant SDK" description: "Get started with the X402r Merchant SDK for server integrations" icon: "rocket" --- @@ -7,7 +7,7 @@ icon: "rocket" The `@x402r/merchant` package provides everything merchants need to handle X402r payments: releasing funds, charging, processing refunds, and managing escrow. -**Most merchants start here:** The [merchant-server example](/sdk/examples#merchant-server) shows how to accept escrow payments via HTTP middleware. This SDK (`@x402r/merchant`) is for post-payment lifecycle -- releasing funds, handling refund requests, and managing escrow. +**Most merchants start here:** The [server examples](/sdk/examples#server-examples) show how to accept escrow payments via HTTP middleware. This SDK (`@x402r/merchant`) is for post-payment lifecycle -- releasing funds, handling refund requests, and managing escrow. ## Installation diff --git a/sdk/overview.mdx b/sdk/overview.mdx index 83dcbba..83157a8 100644 --- a/sdk/overview.mdx +++ b/sdk/overview.mdx @@ -12,9 +12,9 @@ The X402r SDK provides a complete TypeScript implementation for integrating with ## Packages -The SDK is organized into five packages, each designed for a specific role in the payment ecosystem: +The SDK is organized into packages designed for specific roles in the payment ecosystem: - + Shared types, ABIs, network config, deploy utilities, and condition builders. @@ -24,35 +24,14 @@ The SDK is organized into five packages, each designed for a specific role in th SDK for merchants to release payments, charge, and handle refunds. - - SDK for arbiters to resolve disputes, manage registry, and automate decisions with AI. + + SDK for arbiters to resolve disputes and manage refund decisions. + + + Framework-agnostic helper to mark x402 payment options as refundable with escrow configuration. - - Framework-agnostic helper to mark x402 payment options as refundable with escrow configuration. - - -## Key Features - - - - Built on [viem](https://viem.sh) for fully typed interactions with X402r smart contracts. All ABIs are exported with complete TypeScript types. - - - Real-time event watching for payment state changes, refund requests, and freeze events across all packages. - - - Built-in hooks for integrating AI models into dispute resolution workflows with structured evaluation contexts. - - - `deployMarketplaceOperator()` deploys all necessary contracts (operator, escrow period, freeze, conditions) in a single call. - - - On-chain registry for arbiters to register, update metadata, and be discovered by merchants and clients. - - - ## Network Support | Network | Chain ID | Status | @@ -72,7 +51,7 @@ The SDK is organized into five packages, each designed for a specific role in th Deploy a PaymentOperator with one function call. - - Source code and examples. + + Working examples for merchants, clients, and arbiters.