From ada472b476d76306f700544c59049a5946f1c3b3 Mon Sep 17 00:00:00 2001 From: ygd58 Date: Fri, 17 Apr 2026 07:28:22 +0200 Subject: [PATCH] examples: add x402 payment and agent policy examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #149 Adds an examples/ directory with three runnable examples: - x402-pay-request.js: make a paid HTTP request to an x402-enabled endpoint — shows the full 402->sign->retry flow via pay() - x402-discover-services.js: discover payable services in the OWS marketplace via discover() with optional keyword filtering - agent-with-policy.js: create a wallet, register a chain+expiry policy, and set up a policy-gated API key for an agent Also adds examples/README.md with prerequisites and usage instructions. --- examples/README.md | 24 +++++++++ examples/agent-with-policy.js | 78 ++++++++++++++++++++++++++++++ examples/x402-discover-services.js | 45 +++++++++++++++++ examples/x402-pay-request.js | 41 ++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 examples/README.md create mode 100644 examples/agent-with-policy.js create mode 100644 examples/x402-discover-services.js create mode 100644 examples/x402-pay-request.js diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 00000000..375435ca --- /dev/null +++ b/examples/README.md @@ -0,0 +1,24 @@ +# OWS Examples + +Runnable examples for common OWS use cases. + +## Prerequisites + + npm install -g @open-wallet-standard/core + ows wallet create --name my-wallet + +Get test USDC on Base Sepolia: https://faucet.circle.com + +## Examples + +| File | Description | +|---|---| +| [x402-pay-request.js](x402-pay-request.js) | Pay an x402-enabled API endpoint | +| [x402-discover-services.js](x402-discover-services.js) | Discover payable services in the marketplace | +| [agent-with-policy.js](agent-with-policy.js) | Create a policy-gated API key for an agent | + +## Running + + node examples/x402-pay-request.js + node examples/x402-discover-services.js + node examples/agent-with-policy.js diff --git a/examples/agent-with-policy.js b/examples/agent-with-policy.js new file mode 100644 index 00000000..3ec7017f --- /dev/null +++ b/examples/agent-with-policy.js @@ -0,0 +1,78 @@ +/** + * agent-with-policy.js + * + * Create a policy-gated API key for an agent. + * The agent can only sign on allowed chains and within expiry. + * + * Usage: + * node examples/agent-with-policy.js + */ + +import { createWallet, signMessage } from "@open-wallet-standard/core"; +import { writeFileSync, existsSync } from "fs"; +import { execSync } from "child_process"; + +const WALLET_NAME = "agent-treasury"; +const POLICY_ID = "base-agent-limits"; +const POLICY_FILE = "/tmp/base-agent-limits.json"; + +function createPolicyFile() { + const expiry = new Date(); + expiry.setFullYear(expiry.getFullYear() + 1); + + const policy = { + id: POLICY_ID, + name: "Base Agent Safety Limits", + version: 1, + created_at: new Date().toISOString(), + rules: [ + { type: "allowed_chains", chain_ids: ["eip155:8453", "eip155:84532"] }, + { type: "expires_at", timestamp: expiry.toISOString() } + ], + action: "deny" + }; + + writeFileSync(POLICY_FILE, JSON.stringify(policy, null, 2)); + console.log("Policy file written to:", POLICY_FILE); + return POLICY_FILE; +} + +async function main() { + console.log("Setting up policy-gated agent wallet..."); + console.log("-".repeat(50)); + + // Step 1: Create wallet + console.log("Step 1: Creating wallet:", WALLET_NAME); + const wallet = createWallet(WALLET_NAME); + console.log("EVM address :", wallet.accounts.find(a => a.chain === "evm")?.address); + console.log("SOL address :", wallet.accounts.find(a => a.chain === "solana")?.address); + + // Step 2: Create and register policy + console.log(""); + console.log("Step 2: Registering policy:", POLICY_ID); + createPolicyFile(); + execSync("ows policy create --file " + POLICY_FILE, { stdio: "inherit" }); + + // Step 3: Create API key with policy + console.log(""); + console.log("Step 3: Creating API key for agent..."); + console.log("Run the following command and store the token securely:"); + console.log(""); + console.log(" ows key create --name claude-agent --wallet " + WALLET_NAME + " --policy " + POLICY_ID); + console.log(""); + console.log("The agent token (ows_key_...) is shown once."); + console.log("Pass it to your agent as OWS_API_KEY environment variable."); + + // Step 4: Show what the agent can do + console.log(""); + console.log("-".repeat(50)); + console.log("Agent policy summary:"); + console.log(" Allowed chains : eip155:8453 (Base), eip155:84532 (Base Sepolia)"); + console.log(" Expiry : 1 year from now"); + console.log(" Access tier : agent (policy enforced, no passphrase)"); +} + +main().catch(err => { + console.error("Error:", err.message); + process.exit(1); +}); diff --git a/examples/x402-discover-services.js b/examples/x402-discover-services.js new file mode 100644 index 00000000..f6f5dfbc --- /dev/null +++ b/examples/x402-discover-services.js @@ -0,0 +1,45 @@ +/** + * x402-discover-services.js + * + * Discover x402-enabled payable services in the OWS marketplace. + * + * Usage: + * node examples/x402-discover-services.js + * node examples/x402-discover-services.js ai + */ + +import { discover } from "@open-wallet-standard/core"; + +const query = process.argv[2] || null; + +async function main() { + console.log("Discovering x402 services" + (query ? " matching: " + query : "") + "..."); + console.log("-".repeat(50)); + + try { + const result = await discover(query, 10, 0); + + console.log("Total services found:", result.total); + console.log("Showing:", result.services.length); + console.log(""); + + for (const svc of result.services) { + console.log("Name :", svc.name); + console.log("URL :", svc.url); + console.log("Price :", svc.price); + console.log("Network :", svc.network); + console.log("Tags :", svc.tags.join(", ") || "none"); + console.log("Desc :", svc.description); + console.log("-".repeat(50)); + } + + if (result.total > result.services.length) { + console.log("More services available — use offset to page through results."); + } + } catch (err) { + console.error("Error:", err.message); + process.exit(1); + } +} + +main(); diff --git a/examples/x402-pay-request.js b/examples/x402-pay-request.js new file mode 100644 index 00000000..cb470b13 --- /dev/null +++ b/examples/x402-pay-request.js @@ -0,0 +1,41 @@ +/** + * x402-pay-request.js + * + * Make a paid HTTP request to an x402-enabled API endpoint. + * OWS handles the 402 -> sign -> retry flow automatically. + * + * Usage: + * node examples/x402-pay-request.js + */ + +import { pay } from "@open-wallet-standard/core"; + +const WALLET_NAME = "my-wallet"; +const API_URL = "https://api.cdp.coinbase.com/platform/v1/price?ids=ethereum"; + +async function main() { + console.log("Making x402 payment request..."); + console.log("Wallet :", WALLET_NAME); + console.log("URL :", API_URL); + console.log("-".repeat(50)); + + try { + const result = await pay(WALLET_NAME, API_URL, "GET"); + + console.log("Status :", result.status); + console.log("Protocol:", result.protocol); + + if (result.payment) { + console.log("Payment :", result.payment.amount, result.payment.token, "on", result.payment.network); + } else { + console.log("Payment : none required"); + } + + console.log("Response:", result.body.slice(0, 200)); + } catch (err) { + console.error("Error:", err.message); + process.exit(1); + } +} + +main();