From 0fe0c6a8f914b2075dee8d5cc289bbf96546fc2d Mon Sep 17 00:00:00 2001 From: RF31 Date: Tue, 9 Jun 2026 21:40:30 +0200 Subject: [PATCH] fix: update to @azeth/sdk 0.2.22 + @azeth/provider 0.2.21 APIs - bump @azeth/sdk ^0.2.22, @azeth/provider ^0.2.21 - publishService now requires name/description/entityType (RegisterParams) - x402 routes use PaymentOption shape: accepts { scheme, price, network (CAIP-2), payTo } - createX402StackFromEnv is async and takes a payTo override (smart account) - getWeightedReputation returns { weightedValue, totalWeight, opinionCount } - submitOpinion takes SimpleOpinion { serviceTokenId, rating (-100..100), tag1 }; handle the $1 net-payment gate gracefully - README: MCP server now exposes 34 tools Co-Authored-By: Claude Fable 5 --- README.md | 4 ++-- package.json | 4 ++-- src/client.ts | 27 ++++++++++++++++++--------- src/server.ts | 26 +++++++++++++++++++++----- 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 00371ec..2096b92 100644 --- a/README.md +++ b/README.md @@ -86,14 +86,14 @@ This template includes a pre-configured `.claude/settings.json`. Just add your p ```bash # In Claude Code echo '{ "AZETH_PRIVATE_KEY": "0x..." }' > .env -# Now Claude has access to 32 Azeth tools +# Now Claude has access to 34 Azeth tools ``` Ask Claude: *"Create me a smart account and register as a weather data service"* ## Links -- [MCP Server](https://www.npmjs.com/package/@azeth/mcp-server) — 32 tools for AI agents +- [MCP Server](https://www.npmjs.com/package/@azeth/mcp-server) — 34 tools for AI agents - [SDK](https://www.npmjs.com/package/@azeth/sdk) — TypeScript SDK - [Provider](https://www.npmjs.com/package/@azeth/provider) — x402 middleware for Hono - [Website](https://azeth.ai) diff --git a/package.json b/package.json index afc4c52..6abc928 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,8 @@ "start:server": "node dist/server.js" }, "dependencies": { - "@azeth/sdk": "^0.2.0", - "@azeth/provider": "^0.2.0", + "@azeth/sdk": "^0.2.22", + "@azeth/provider": "^0.2.21", "hono": "^4.7.0", "@hono/node-server": "^1.13.0", "dotenv": "^16.4.0" diff --git a/src/client.ts b/src/client.ts index 04a1b97..9ff87ae 100644 --- a/src/client.ts +++ b/src/client.ts @@ -62,8 +62,10 @@ async function main() { // 4. Check reputation before trusting console.log('\nChecking provider reputation...'); const reputation = await agent.getWeightedReputation(service.tokenId); - console.log(` Score: ${reputation.compositeScore}/100`); - console.log(` Interactions: ${reputation.totalInteractions}`); + // weightedValue is 18-decimal fixed point on a -100..100 scale, weighted by USD paid + const score = reputation.opinionCount > 0n ? Number(reputation.weightedValue) / 1e18 : 0; + console.log(` Weighted score: ${score.toFixed(1)} (range -100..100)`); + console.log(` Opinions: ${reputation.opinionCount}`); // 5. Pay for the service via x402 console.log('\nPaying for weather data via x402...'); @@ -74,14 +76,21 @@ async function main() { console.log(` Response time: ${responseTimeMs}ms`); // 6. Rate the provider on-chain + // Opinions are payment-gated: the ReputationModule requires >= $1 net USD paid + // to the provider before accepting a rating (anti-Sybil protection). console.log('\nRating provider on-chain...'); - await agent.submitOpinion({ - serviceTokenId: service.tokenId, - success: true, - responseTimeMs, - qualityScore: 85, - }); - console.log(' Opinion submitted! Provider reputation updated.'); + try { + await agent.submitOpinion({ + serviceTokenId: service.tokenId, + rating: 85, // -100 to 100 + tag1: 'quality', + endpoint: service.endpoint, + }); + console.log(' Opinion submitted! Provider reputation updated.'); + } catch (err) { + console.log(` Opinion not accepted yet: ${err instanceof Error ? err.message : String(err)}`); + console.log(' Ratings unlock after >= $1 total net payment to the provider.'); + } console.log('\n--- Complete ---'); console.log('The provider now has a better reputation score.'); diff --git a/src/server.ts b/src/server.ts index 362ecaa..7253bfb 100644 --- a/src/server.ts +++ b/src/server.ts @@ -18,7 +18,12 @@ import 'dotenv/config'; import { Hono } from 'hono'; import { serve } from '@hono/node-server'; import { AzethKit } from '@azeth/sdk'; -import { createX402StackFromEnv, paymentMiddlewareFromHTTPServer } from '@azeth/provider'; +import { + CAIP2_NETWORKS, + createX402StackFromEnv, + paymentMiddlewareFromHTTPServer, + type RoutesConfig, +} from '@azeth/provider'; const PORT = 3402; // A play on HTTP 402 @@ -60,6 +65,9 @@ async function main() { // 3. Publish service on trust registry so other agents can discover us console.log('\nPublishing service on trust registry...'); const registration = await agent.publishService({ + name: 'WeatherOracle', + description: 'Real-time weather data for AI agents', + entityType: 'service', capabilities: ['weather-data', 'climate-analysis'], endpoint: `http://localhost:${PORT}`, }); @@ -67,15 +75,23 @@ async function main() { console.log('Other agents can now discover this service via azeth_discover_services.'); // 4. Set up x402 payment middleware - const routes = { + // Payments go to the smart account (not the EOA) so consumers can rate this service. + const payTo = agent.smartAccount ?? (await agent.resolveSmartAccount()); + + const routes: RoutesConfig = { 'GET /api/weather/:city': { - price: '$0.001', - network: 'base-sepolia', + accepts: { + scheme: 'exact', + price: '$0.001', + network: CAIP2_NETWORKS[chain], + payTo, + }, description: 'Weather data for a city', + mimeType: 'application/json', }, }; - const x402 = createX402StackFromEnv(routes); + const x402 = await createX402StackFromEnv(routes, { payTo }); // 5. Create Hono app with x402 paywall const app = new Hono();