Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
27 changes: 18 additions & 9 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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...');
Expand All @@ -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.');
Expand Down
26 changes: 21 additions & 5 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -60,22 +65,33 @@ 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}`,
});
console.log(`Registered! TokenId: ${registration.tokenId}`);
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();
Expand Down