Six new clients (dependency-free EIP-1193 wrappers, precomputed
4-byte selectors, ABI tuple/string encoders inline):
- AereAgentBondClient — bondOf, isBonded, postBond, requestWithdraw,
withdraw, slash; oracle-only on slash
- AereAIReputationClient — scoreOf, statsOf, attest (delta -1/0/+1)
- AereInferNetClient — modelEpochCount, registerModel, commitEpoch;
EU AI Act Article 12 provider surface
- AereAgentMemoryVaultClient — grant, revoke, write, canReadNow,
permissionOf; user-owned namespace
- AereAttestationGatewayClient — publishSchema, setAttestor, attest,
revoke, isValidNow, subjectCurrentlyAttested
- AereCompliancePoolClient — deposit, withdraw, publishAssociationRoot,
setComplianceProvider; Privacy Pools surface
All exported from the package barrel. Zero TS errors.
85 lines
3.1 KiB
JavaScript
85 lines
3.1 KiB
JavaScript
// express-402-paid-endpoint.js
|
|
//
|
|
// Drop-in example: a paid `/v1/inference` endpoint that charges $0.0125
|
|
// in USDC.e per call via AERE402 settlement on Chain 2800.
|
|
//
|
|
// Run:
|
|
// yarn add express @aere/sdk-js ethers
|
|
// FACILITATOR=0x... PAYEE=0x... PROVIDER_PRIVATE_KEY=0x... node express-402-paid-endpoint.js
|
|
//
|
|
// Then the agent-side does:
|
|
// 1. curl http://localhost:3000/v1/inference
|
|
// → 402 with X-AERE402-Quote JSON header
|
|
// 2. agent EIP-712-signs the quote using its registered signing key
|
|
// 3. curl -H "X-AERE402-Sig: 0x.." -H "X-AERE402-AgentId: 1234" \
|
|
// -H "X-AERE402-Quote: <original-quote-json>" \
|
|
// http://localhost:3000/v1/inference
|
|
// → 200 with the actual inference output, X-AERE402-TxHash header set
|
|
|
|
const express = require('express');
|
|
const { ethers } = require('ethers');
|
|
const { createAere402Middleware } = require('@aere/sdk-js');
|
|
|
|
const FACILITATOR = process.env.FACILITATOR;
|
|
const USDC_E = process.env.USDC_E ?? '0x0000000000000000000000000000000000000000';
|
|
const PAYEE = process.env.PAYEE;
|
|
const PROVIDER_PK = process.env.PROVIDER_PRIVATE_KEY;
|
|
const RPC_URL = process.env.RPC_URL ?? 'https://rpc.aere.network';
|
|
const CHAIN_ID = parseInt(process.env.CHAIN_ID ?? '2800', 10);
|
|
|
|
if (!FACILITATOR || !PAYEE || !PROVIDER_PK) {
|
|
console.error('FACILITATOR, PAYEE, and PROVIDER_PRIVATE_KEY env vars required');
|
|
process.exit(1);
|
|
}
|
|
|
|
const provider = new ethers.JsonRpcProvider(RPC_URL);
|
|
const providerWallet = new ethers.Wallet(PROVIDER_PK, provider);
|
|
|
|
// Real `settle()` ABI from AERE402Facilitator. Pulled minimal — just what we call.
|
|
const FAC_ABI = [
|
|
'function settle(uint256 agentId, address token, address payee, uint256 amount, bytes32 resourceId, uint256 nonce, uint256 deadline, bytes signature) external',
|
|
];
|
|
const facContract = new ethers.Contract(FACILITATOR, FAC_ABI, providerWallet);
|
|
|
|
const charge = createAere402Middleware({
|
|
facilitator: FACILITATOR,
|
|
chainId: CHAIN_ID,
|
|
token: USDC_E,
|
|
payee: PAYEE,
|
|
pricer: () => 12500n, // $0.0125 in USDC.e (6 decimals)
|
|
submit: async (auth, signature) => {
|
|
const tx = await facContract.settle(
|
|
BigInt(auth.agentId),
|
|
auth.token,
|
|
auth.payee,
|
|
BigInt(auth.amount),
|
|
auth.resourceId,
|
|
BigInt(auth.nonce),
|
|
BigInt(auth.deadline),
|
|
signature,
|
|
);
|
|
const rcpt = await tx.wait();
|
|
return rcpt.hash;
|
|
},
|
|
});
|
|
|
|
const app = express();
|
|
|
|
app.get('/v1/inference', charge, (req, res) => {
|
|
// The middleware paid us — we can read req.aere402 for receipt info.
|
|
const { txHash, auth } = req.aere402;
|
|
console.log(`paid call: agent=${auth.agentId} amount=${auth.amount} tx=${txHash}`);
|
|
res.json({
|
|
output: 'Pretend this is an LLM completion.',
|
|
aere402: { txHash, amountCharged: auth.amount, token: auth.token },
|
|
});
|
|
});
|
|
|
|
const PORT = parseInt(process.env.PORT ?? '3000', 10);
|
|
app.listen(PORT, () => {
|
|
console.log(`paid endpoint running at http://localhost:${PORT}/v1/inference`);
|
|
console.log(`facilitator: ${FACILITATOR}`);
|
|
console.log(`payee: ${PAYEE}`);
|
|
console.log(`provider wallet: ${providerWallet.address}`);
|
|
});
|