@agether/sdk 1.5.5 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +48 -222
- package/dist/index.d.mts +9 -16
- package/dist/index.d.ts +9 -16
- package/dist/index.js +44 -218
- package/dist/index.mjs +44 -218
- package/package.json +6 -2
- package/dist/MorphoClient-AV27HBOF.mjs +0 -6
- package/dist/X402Client-PY4FOTQC.mjs +0 -6
- package/dist/chunk-OMCWZ3VN.mjs +0 -840
- package/dist/chunk-PTXYOTCG.mjs +0 -257
- package/dist/cli.d.mts +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.mjs +0 -680
package/dist/index.js
CHANGED
|
@@ -1094,23 +1094,19 @@ var MorphoClient = class {
|
|
|
1094
1094
|
var import_axios2 = __toESM(require("axios"));
|
|
1095
1095
|
|
|
1096
1096
|
// src/clients/X402Client.ts
|
|
1097
|
-
var
|
|
1098
|
-
var
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
"eip155:84532": { name: "USD Coin", version: "2", address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e" },
|
|
1102
|
-
"eip155:42161": { name: "USD Coin", version: "2", address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831" },
|
|
1103
|
-
"eip155:10": { name: "USD Coin", version: "2", address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85" }
|
|
1104
|
-
};
|
|
1105
|
-
function chainIdFromNetwork(network) {
|
|
1106
|
-
const m = network.match(/^eip155:(\d+)$/);
|
|
1107
|
-
return m ? Number(m[1]) : 1;
|
|
1108
|
-
}
|
|
1097
|
+
var import_fetch = require("@x402/fetch");
|
|
1098
|
+
var import_client = require("@x402/core/client");
|
|
1099
|
+
var import_client2 = require("@x402/evm/exact/client");
|
|
1100
|
+
var import_accounts = require("viem/accounts");
|
|
1109
1101
|
var X402Client = class {
|
|
1110
1102
|
constructor(config) {
|
|
1111
1103
|
this.config = config;
|
|
1112
|
-
const
|
|
1113
|
-
|
|
1104
|
+
const privateKey = config.privateKey.startsWith("0x") ? config.privateKey : `0x${config.privateKey}`;
|
|
1105
|
+
const signer = (0, import_accounts.privateKeyToAccount)(privateKey);
|
|
1106
|
+
this.address = signer.address;
|
|
1107
|
+
const client = new import_client.x402Client();
|
|
1108
|
+
(0, import_client2.registerExactEvmScheme)(client, { signer });
|
|
1109
|
+
this.paidFetch = (0, import_fetch.wrapFetchWithPayment)(fetch, client);
|
|
1114
1110
|
}
|
|
1115
1111
|
async get(url, opts) {
|
|
1116
1112
|
return this.request(url, { ...opts, method: "GET" });
|
|
@@ -1124,13 +1120,13 @@ var X402Client = class {
|
|
|
1124
1120
|
});
|
|
1125
1121
|
}
|
|
1126
1122
|
getAddress() {
|
|
1127
|
-
return this.
|
|
1123
|
+
return this.address;
|
|
1128
1124
|
}
|
|
1129
|
-
// ──────────── Core request / 402
|
|
1125
|
+
// ──────────── Core request — @x402/fetch handles 402 automatically ────────────
|
|
1130
1126
|
async request(url, options) {
|
|
1131
1127
|
try {
|
|
1132
|
-
console.log(
|
|
1133
|
-
const response = await
|
|
1128
|
+
console.log(` [x402] ${options?.method || "GET"} ${url}`);
|
|
1129
|
+
const response = await this.paidFetch(url, {
|
|
1134
1130
|
...options,
|
|
1135
1131
|
headers: {
|
|
1136
1132
|
...options?.headers,
|
|
@@ -1139,45 +1135,13 @@ var X402Client = class {
|
|
|
1139
1135
|
});
|
|
1140
1136
|
if (response.ok) {
|
|
1141
1137
|
const data = await response.json();
|
|
1142
|
-
|
|
1143
|
-
}
|
|
1144
|
-
if (response.status !== 402) {
|
|
1145
|
-
return { success: false, error: `HTTP ${response.status}: ${await response.text()}` };
|
|
1146
|
-
}
|
|
1147
|
-
console.log(" [2/4] 402 received \u2014 parsing payment requirements\u2026");
|
|
1148
|
-
const parsed = await this.parsePaymentRequired(response);
|
|
1149
|
-
if (!parsed) {
|
|
1150
|
-
return { success: false, error: "Could not parse payment requirements from 402 response" };
|
|
1151
|
-
}
|
|
1152
|
-
const { requirements, resource } = parsed;
|
|
1153
|
-
console.log(` scheme : ${requirements.scheme}`);
|
|
1154
|
-
console.log(` network : ${requirements.network}`);
|
|
1155
|
-
console.log(` amount : ${requirements.amount} (atomic)`);
|
|
1156
|
-
console.log(` asset : ${requirements.asset}`);
|
|
1157
|
-
console.log(` payTo : ${requirements.payTo}`);
|
|
1158
|
-
console.log(" [3/4] Signing EIP-3009 transferWithAuthorization\u2026");
|
|
1159
|
-
const paymentPayload = await this.buildPaymentPayload(requirements, resource, url);
|
|
1160
|
-
const paymentB64 = Buffer.from(JSON.stringify(paymentPayload)).toString("base64");
|
|
1161
|
-
await this.riskCheck(paymentPayload, requirements);
|
|
1162
|
-
console.log(" [4/4] Retrying with PAYMENT-SIGNATURE header\u2026");
|
|
1163
|
-
const paidResponse = await fetch(url, {
|
|
1164
|
-
...options,
|
|
1165
|
-
headers: {
|
|
1166
|
-
...options?.headers,
|
|
1167
|
-
"X-Agent-Id": this.config.agentId || "",
|
|
1168
|
-
// v2 header
|
|
1169
|
-
"PAYMENT-SIGNATURE": paymentB64,
|
|
1170
|
-
// v1 compat header (some servers still use this)
|
|
1171
|
-
"X-PAYMENT": paymentB64
|
|
1172
|
-
}
|
|
1173
|
-
});
|
|
1174
|
-
if (paidResponse.ok) {
|
|
1175
|
-
const data = await paidResponse.json();
|
|
1176
|
-
const settlementHeader = paidResponse.headers.get("PAYMENT-RESPONSE") || paidResponse.headers.get("X-PAYMENT-RESPONSE");
|
|
1138
|
+
const paymentResponse = response.headers.get("PAYMENT-RESPONSE");
|
|
1177
1139
|
let txHash;
|
|
1178
|
-
if (
|
|
1140
|
+
if (paymentResponse) {
|
|
1179
1141
|
try {
|
|
1180
|
-
const settlement = JSON.parse(
|
|
1142
|
+
const settlement = JSON.parse(
|
|
1143
|
+
Buffer.from(paymentResponse, "base64").toString("utf-8")
|
|
1144
|
+
);
|
|
1181
1145
|
txHash = settlement.transaction;
|
|
1182
1146
|
} catch {
|
|
1183
1147
|
}
|
|
@@ -1185,164 +1149,26 @@ var X402Client = class {
|
|
|
1185
1149
|
return {
|
|
1186
1150
|
success: true,
|
|
1187
1151
|
data,
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1152
|
+
...txHash ? {
|
|
1153
|
+
paymentInfo: {
|
|
1154
|
+
amount: "",
|
|
1155
|
+
asset: "USDC",
|
|
1156
|
+
network: "eip155:8453",
|
|
1157
|
+
txHash
|
|
1158
|
+
}
|
|
1159
|
+
} : {}
|
|
1194
1160
|
};
|
|
1195
1161
|
}
|
|
1196
|
-
const errBody = await
|
|
1197
|
-
return {
|
|
1162
|
+
const errBody = await response.text();
|
|
1163
|
+
return {
|
|
1164
|
+
success: false,
|
|
1165
|
+
error: `HTTP ${response.status}: ${errBody}`
|
|
1166
|
+
};
|
|
1198
1167
|
} catch (error) {
|
|
1199
|
-
return {
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
async parsePaymentRequired(response) {
|
|
1204
|
-
const prHeader = response.headers.get("PAYMENT-REQUIRED") || response.headers.get("x-payment-required");
|
|
1205
|
-
if (prHeader) {
|
|
1206
|
-
try {
|
|
1207
|
-
const decoded = JSON.parse(Buffer.from(prHeader, "base64").toString("utf-8"));
|
|
1208
|
-
if (decoded.accepts?.length) {
|
|
1209
|
-
return { requirements: decoded.accepts[0], resource: decoded.resource };
|
|
1210
|
-
}
|
|
1211
|
-
} catch {
|
|
1212
|
-
}
|
|
1213
|
-
}
|
|
1214
|
-
try {
|
|
1215
|
-
const body = await response.json();
|
|
1216
|
-
if (body.accepts && Array.isArray(body.accepts) && body.accepts.length > 0) {
|
|
1217
|
-
return { requirements: body.accepts[0], resource: body.resource };
|
|
1218
|
-
}
|
|
1219
|
-
if (body.paymentRequirements) {
|
|
1220
|
-
const pr = Array.isArray(body.paymentRequirements) ? body.paymentRequirements[0] : body.paymentRequirements;
|
|
1221
|
-
return { requirements: pr, resource: body.resource };
|
|
1222
|
-
}
|
|
1223
|
-
if (body.scheme && body.network) {
|
|
1224
|
-
return { requirements: body, resource: body.resource };
|
|
1225
|
-
}
|
|
1226
|
-
} catch {
|
|
1227
|
-
}
|
|
1228
|
-
const wwwAuth = response.headers.get("WWW-Authenticate");
|
|
1229
|
-
if (wwwAuth) {
|
|
1230
|
-
const m = wwwAuth.match(/x402[^"]*"([^"]+)"/);
|
|
1231
|
-
if (m) {
|
|
1232
|
-
try {
|
|
1233
|
-
const decoded = JSON.parse(Buffer.from(m[1], "base64").toString("utf-8"));
|
|
1234
|
-
const reqs = Array.isArray(decoded) ? decoded[0] : decoded;
|
|
1235
|
-
return { requirements: reqs };
|
|
1236
|
-
} catch {
|
|
1237
|
-
}
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
return null;
|
|
1241
|
-
}
|
|
1242
|
-
// ──────────── Build x402 v2 PaymentPayload with EIP-3009 ────────────
|
|
1243
|
-
//
|
|
1244
|
-
// If an AgentAccount is configured, we use it as the `from` address
|
|
1245
|
-
// (smart wallet pays directly). The AgentAccount implements EIP-1271
|
|
1246
|
-
// so USDC's transferWithAuthorization will call isValidSignature()
|
|
1247
|
-
// to verify the owner's ECDSA signature. The facilitator detects
|
|
1248
|
-
// the >65-byte or smart-wallet case and uses the bytes overload.
|
|
1249
|
-
async buildPaymentPayload(reqs, resource, url) {
|
|
1250
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
1251
|
-
const validAfter = String(now - 60);
|
|
1252
|
-
const validBefore = String(now + (reqs.maxTimeoutSeconds || 300));
|
|
1253
|
-
const nonce = import_ethers3.ethers.hexlify(import_ethers3.ethers.randomBytes(32));
|
|
1254
|
-
const chainId = chainIdFromNetwork(reqs.network);
|
|
1255
|
-
const usdcDomain = USDC_DOMAINS[reqs.network] || USDC_DOMAINS["eip155:1"];
|
|
1256
|
-
const payerAddress = this.config.accountAddress || this.wallet.address;
|
|
1257
|
-
const isSmartWallet = !!this.config.accountAddress;
|
|
1258
|
-
const domain = {
|
|
1259
|
-
name: usdcDomain.name,
|
|
1260
|
-
version: usdcDomain.version,
|
|
1261
|
-
chainId,
|
|
1262
|
-
verifyingContract: reqs.asset || usdcDomain.address
|
|
1263
|
-
};
|
|
1264
|
-
const types = {
|
|
1265
|
-
TransferWithAuthorization: [
|
|
1266
|
-
{ name: "from", type: "address" },
|
|
1267
|
-
{ name: "to", type: "address" },
|
|
1268
|
-
{ name: "value", type: "uint256" },
|
|
1269
|
-
{ name: "validAfter", type: "uint256" },
|
|
1270
|
-
{ name: "validBefore", type: "uint256" },
|
|
1271
|
-
{ name: "nonce", type: "bytes32" }
|
|
1272
|
-
]
|
|
1273
|
-
};
|
|
1274
|
-
const value = {
|
|
1275
|
-
from: payerAddress,
|
|
1276
|
-
// AgentAccount or EOA
|
|
1277
|
-
to: reqs.payTo,
|
|
1278
|
-
value: reqs.amount,
|
|
1279
|
-
validAfter,
|
|
1280
|
-
validBefore,
|
|
1281
|
-
nonce
|
|
1282
|
-
};
|
|
1283
|
-
let signature = await this.wallet.signTypedData(domain, types, value);
|
|
1284
|
-
if (isSmartWallet) {
|
|
1285
|
-
signature = signature + "00";
|
|
1286
|
-
}
|
|
1287
|
-
if (isSmartWallet) {
|
|
1288
|
-
console.log(` \u2713 Signed for AgentAccount ${payerAddress.slice(0, 10)}\u2026 (EIP-1271, chain=${chainId})`);
|
|
1289
|
-
} else {
|
|
1290
|
-
console.log(` \u2713 Signed (from=${payerAddress.slice(0, 10)}\u2026, chain=${chainId})`);
|
|
1291
|
-
}
|
|
1292
|
-
return {
|
|
1293
|
-
x402Version: 2,
|
|
1294
|
-
resource: resource || { url, description: "", mimeType: "application/json" },
|
|
1295
|
-
accepted: {
|
|
1296
|
-
scheme: reqs.scheme,
|
|
1297
|
-
network: reqs.network,
|
|
1298
|
-
amount: reqs.amount,
|
|
1299
|
-
asset: reqs.asset,
|
|
1300
|
-
payTo: reqs.payTo,
|
|
1301
|
-
maxTimeoutSeconds: reqs.maxTimeoutSeconds,
|
|
1302
|
-
extra: reqs.extra || {}
|
|
1303
|
-
},
|
|
1304
|
-
payload: {
|
|
1305
|
-
signature,
|
|
1306
|
-
authorization: {
|
|
1307
|
-
from: payerAddress,
|
|
1308
|
-
// AgentAccount address — facilitator checks balance here
|
|
1309
|
-
to: reqs.payTo,
|
|
1310
|
-
value: reqs.amount,
|
|
1311
|
-
validAfter,
|
|
1312
|
-
validBefore,
|
|
1313
|
-
nonce
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
};
|
|
1317
|
-
}
|
|
1318
|
-
// ──────────── Risk check via our backend ────────────
|
|
1319
|
-
async riskCheck(paymentPayload, reqs) {
|
|
1320
|
-
try {
|
|
1321
|
-
const verifyUrl = `${this.config.backendUrl}/x402/verify`;
|
|
1322
|
-
const resp = await fetch(verifyUrl, {
|
|
1323
|
-
method: "POST",
|
|
1324
|
-
headers: {
|
|
1325
|
-
"Content-Type": "application/json",
|
|
1326
|
-
"X-Agent-Id": this.config.agentId || "",
|
|
1327
|
-
...this.config.accountAddress ? { "X-Agent-Account": this.config.accountAddress } : {}
|
|
1328
|
-
},
|
|
1329
|
-
body: JSON.stringify({
|
|
1330
|
-
x402Version: 2,
|
|
1331
|
-
paymentPayload,
|
|
1332
|
-
paymentRequirements: reqs
|
|
1333
|
-
}),
|
|
1334
|
-
signal: AbortSignal.timeout(5e3)
|
|
1335
|
-
});
|
|
1336
|
-
if (resp.ok) {
|
|
1337
|
-
const result = await resp.json();
|
|
1338
|
-
const decision = resp.headers.get("X-Risk-Decision") || (result.isValid ? "allow" : "unknown");
|
|
1339
|
-
const score = resp.headers.get("X-Risk-Score") || "?";
|
|
1340
|
-
console.log(` \u2713 Risk check: ${decision} (score=${score})`);
|
|
1341
|
-
} else {
|
|
1342
|
-
console.log(` \u26A0 Risk check failed (HTTP ${resp.status}) \u2014 continuing anyway`);
|
|
1343
|
-
}
|
|
1344
|
-
} catch {
|
|
1345
|
-
console.log(" \u26A0 Risk check unavailable \u2014 continuing");
|
|
1168
|
+
return {
|
|
1169
|
+
success: false,
|
|
1170
|
+
error: `Request failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1171
|
+
};
|
|
1346
1172
|
}
|
|
1347
1173
|
}
|
|
1348
1174
|
};
|
|
@@ -1438,7 +1264,7 @@ var ScoringClient = class {
|
|
|
1438
1264
|
};
|
|
1439
1265
|
|
|
1440
1266
|
// src/clients/AgentIdentityClient.ts
|
|
1441
|
-
var
|
|
1267
|
+
var import_ethers3 = require("ethers");
|
|
1442
1268
|
var ERC8004_IDENTITY_ABI = [
|
|
1443
1269
|
// Registration
|
|
1444
1270
|
"function register() returns (uint256)",
|
|
@@ -1480,8 +1306,8 @@ var AgentIdentityClient = class {
|
|
|
1480
1306
|
this.signer = options.signer;
|
|
1481
1307
|
const identityAddr = options.config.contracts?.identityRegistry || ERC8004_SEPOLIA.identityRegistry;
|
|
1482
1308
|
const reputationAddr = options.config.contracts?.reputationRegistry || ERC8004_SEPOLIA.reputationRegistry;
|
|
1483
|
-
this.identityRegistry = new
|
|
1484
|
-
this.reputationRegistry = new
|
|
1309
|
+
this.identityRegistry = new import_ethers3.ethers.Contract(identityAddr, ERC8004_IDENTITY_ABI, this.signer);
|
|
1310
|
+
this.reputationRegistry = new import_ethers3.ethers.Contract(reputationAddr, ERC8004_REPUTATION_ABI, this.signer);
|
|
1485
1311
|
}
|
|
1486
1312
|
// ============ Identity Functions ============
|
|
1487
1313
|
/**
|
|
@@ -1548,7 +1374,7 @@ var AgentIdentityClient = class {
|
|
|
1548
1374
|
async registerWithMetadata(agentURI, metadata) {
|
|
1549
1375
|
const metadataEntries = metadata.map((m) => ({
|
|
1550
1376
|
key: m.key,
|
|
1551
|
-
value:
|
|
1377
|
+
value: import_ethers3.ethers.toUtf8Bytes(m.value)
|
|
1552
1378
|
}));
|
|
1553
1379
|
const tx = await this.identityRegistry["register(string,tuple(string,bytes)[])"](
|
|
1554
1380
|
agentURI,
|
|
@@ -1585,7 +1411,7 @@ var AgentIdentityClient = class {
|
|
|
1585
1411
|
const tx = await this.identityRegistry.setMetadata(
|
|
1586
1412
|
agentId,
|
|
1587
1413
|
key,
|
|
1588
|
-
|
|
1414
|
+
import_ethers3.ethers.toUtf8Bytes(value)
|
|
1589
1415
|
);
|
|
1590
1416
|
const receipt = await tx.wait();
|
|
1591
1417
|
return receipt.hash;
|
|
@@ -1595,7 +1421,7 @@ var AgentIdentityClient = class {
|
|
|
1595
1421
|
*/
|
|
1596
1422
|
async getMetadata(agentId, key) {
|
|
1597
1423
|
const value = await this.identityRegistry.getMetadata(agentId, key);
|
|
1598
|
-
return
|
|
1424
|
+
return import_ethers3.ethers.toUtf8String(value);
|
|
1599
1425
|
}
|
|
1600
1426
|
/**
|
|
1601
1427
|
* Transfer agent to new owner
|
|
@@ -1629,8 +1455,8 @@ var AgentIdentityClient = class {
|
|
|
1629
1455
|
* Give feedback to an agent
|
|
1630
1456
|
*/
|
|
1631
1457
|
async giveFeedback(input) {
|
|
1632
|
-
const feedbackHash =
|
|
1633
|
-
|
|
1458
|
+
const feedbackHash = import_ethers3.ethers.keccak256(
|
|
1459
|
+
import_ethers3.ethers.AbiCoder.defaultAbiCoder().encode(
|
|
1634
1460
|
["uint256", "int128", "uint256"],
|
|
1635
1461
|
[input.agentId, input.value, Date.now()]
|
|
1636
1462
|
)
|
package/dist/index.mjs
CHANGED
|
@@ -1030,23 +1030,19 @@ var MorphoClient = class {
|
|
|
1030
1030
|
import axios2 from "axios";
|
|
1031
1031
|
|
|
1032
1032
|
// src/clients/X402Client.ts
|
|
1033
|
-
import {
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
"eip155:84532": { name: "USD Coin", version: "2", address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e" },
|
|
1038
|
-
"eip155:42161": { name: "USD Coin", version: "2", address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831" },
|
|
1039
|
-
"eip155:10": { name: "USD Coin", version: "2", address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85" }
|
|
1040
|
-
};
|
|
1041
|
-
function chainIdFromNetwork(network) {
|
|
1042
|
-
const m = network.match(/^eip155:(\d+)$/);
|
|
1043
|
-
return m ? Number(m[1]) : 1;
|
|
1044
|
-
}
|
|
1033
|
+
import { wrapFetchWithPayment } from "@x402/fetch";
|
|
1034
|
+
import { x402Client } from "@x402/core/client";
|
|
1035
|
+
import { registerExactEvmScheme } from "@x402/evm/exact/client";
|
|
1036
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
1045
1037
|
var X402Client = class {
|
|
1046
1038
|
constructor(config) {
|
|
1047
1039
|
this.config = config;
|
|
1048
|
-
const
|
|
1049
|
-
|
|
1040
|
+
const privateKey = config.privateKey.startsWith("0x") ? config.privateKey : `0x${config.privateKey}`;
|
|
1041
|
+
const signer = privateKeyToAccount(privateKey);
|
|
1042
|
+
this.address = signer.address;
|
|
1043
|
+
const client = new x402Client();
|
|
1044
|
+
registerExactEvmScheme(client, { signer });
|
|
1045
|
+
this.paidFetch = wrapFetchWithPayment(fetch, client);
|
|
1050
1046
|
}
|
|
1051
1047
|
async get(url, opts) {
|
|
1052
1048
|
return this.request(url, { ...opts, method: "GET" });
|
|
@@ -1060,13 +1056,13 @@ var X402Client = class {
|
|
|
1060
1056
|
});
|
|
1061
1057
|
}
|
|
1062
1058
|
getAddress() {
|
|
1063
|
-
return this.
|
|
1059
|
+
return this.address;
|
|
1064
1060
|
}
|
|
1065
|
-
// ──────────── Core request / 402
|
|
1061
|
+
// ──────────── Core request — @x402/fetch handles 402 automatically ────────────
|
|
1066
1062
|
async request(url, options) {
|
|
1067
1063
|
try {
|
|
1068
|
-
console.log(
|
|
1069
|
-
const response = await
|
|
1064
|
+
console.log(` [x402] ${options?.method || "GET"} ${url}`);
|
|
1065
|
+
const response = await this.paidFetch(url, {
|
|
1070
1066
|
...options,
|
|
1071
1067
|
headers: {
|
|
1072
1068
|
...options?.headers,
|
|
@@ -1075,45 +1071,13 @@ var X402Client = class {
|
|
|
1075
1071
|
});
|
|
1076
1072
|
if (response.ok) {
|
|
1077
1073
|
const data = await response.json();
|
|
1078
|
-
|
|
1079
|
-
}
|
|
1080
|
-
if (response.status !== 402) {
|
|
1081
|
-
return { success: false, error: `HTTP ${response.status}: ${await response.text()}` };
|
|
1082
|
-
}
|
|
1083
|
-
console.log(" [2/4] 402 received \u2014 parsing payment requirements\u2026");
|
|
1084
|
-
const parsed = await this.parsePaymentRequired(response);
|
|
1085
|
-
if (!parsed) {
|
|
1086
|
-
return { success: false, error: "Could not parse payment requirements from 402 response" };
|
|
1087
|
-
}
|
|
1088
|
-
const { requirements, resource } = parsed;
|
|
1089
|
-
console.log(` scheme : ${requirements.scheme}`);
|
|
1090
|
-
console.log(` network : ${requirements.network}`);
|
|
1091
|
-
console.log(` amount : ${requirements.amount} (atomic)`);
|
|
1092
|
-
console.log(` asset : ${requirements.asset}`);
|
|
1093
|
-
console.log(` payTo : ${requirements.payTo}`);
|
|
1094
|
-
console.log(" [3/4] Signing EIP-3009 transferWithAuthorization\u2026");
|
|
1095
|
-
const paymentPayload = await this.buildPaymentPayload(requirements, resource, url);
|
|
1096
|
-
const paymentB64 = Buffer.from(JSON.stringify(paymentPayload)).toString("base64");
|
|
1097
|
-
await this.riskCheck(paymentPayload, requirements);
|
|
1098
|
-
console.log(" [4/4] Retrying with PAYMENT-SIGNATURE header\u2026");
|
|
1099
|
-
const paidResponse = await fetch(url, {
|
|
1100
|
-
...options,
|
|
1101
|
-
headers: {
|
|
1102
|
-
...options?.headers,
|
|
1103
|
-
"X-Agent-Id": this.config.agentId || "",
|
|
1104
|
-
// v2 header
|
|
1105
|
-
"PAYMENT-SIGNATURE": paymentB64,
|
|
1106
|
-
// v1 compat header (some servers still use this)
|
|
1107
|
-
"X-PAYMENT": paymentB64
|
|
1108
|
-
}
|
|
1109
|
-
});
|
|
1110
|
-
if (paidResponse.ok) {
|
|
1111
|
-
const data = await paidResponse.json();
|
|
1112
|
-
const settlementHeader = paidResponse.headers.get("PAYMENT-RESPONSE") || paidResponse.headers.get("X-PAYMENT-RESPONSE");
|
|
1074
|
+
const paymentResponse = response.headers.get("PAYMENT-RESPONSE");
|
|
1113
1075
|
let txHash;
|
|
1114
|
-
if (
|
|
1076
|
+
if (paymentResponse) {
|
|
1115
1077
|
try {
|
|
1116
|
-
const settlement = JSON.parse(
|
|
1078
|
+
const settlement = JSON.parse(
|
|
1079
|
+
Buffer.from(paymentResponse, "base64").toString("utf-8")
|
|
1080
|
+
);
|
|
1117
1081
|
txHash = settlement.transaction;
|
|
1118
1082
|
} catch {
|
|
1119
1083
|
}
|
|
@@ -1121,164 +1085,26 @@ var X402Client = class {
|
|
|
1121
1085
|
return {
|
|
1122
1086
|
success: true,
|
|
1123
1087
|
data,
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1088
|
+
...txHash ? {
|
|
1089
|
+
paymentInfo: {
|
|
1090
|
+
amount: "",
|
|
1091
|
+
asset: "USDC",
|
|
1092
|
+
network: "eip155:8453",
|
|
1093
|
+
txHash
|
|
1094
|
+
}
|
|
1095
|
+
} : {}
|
|
1130
1096
|
};
|
|
1131
1097
|
}
|
|
1132
|
-
const errBody = await
|
|
1133
|
-
return {
|
|
1098
|
+
const errBody = await response.text();
|
|
1099
|
+
return {
|
|
1100
|
+
success: false,
|
|
1101
|
+
error: `HTTP ${response.status}: ${errBody}`
|
|
1102
|
+
};
|
|
1134
1103
|
} catch (error) {
|
|
1135
|
-
return {
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
async parsePaymentRequired(response) {
|
|
1140
|
-
const prHeader = response.headers.get("PAYMENT-REQUIRED") || response.headers.get("x-payment-required");
|
|
1141
|
-
if (prHeader) {
|
|
1142
|
-
try {
|
|
1143
|
-
const decoded = JSON.parse(Buffer.from(prHeader, "base64").toString("utf-8"));
|
|
1144
|
-
if (decoded.accepts?.length) {
|
|
1145
|
-
return { requirements: decoded.accepts[0], resource: decoded.resource };
|
|
1146
|
-
}
|
|
1147
|
-
} catch {
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
|
-
try {
|
|
1151
|
-
const body = await response.json();
|
|
1152
|
-
if (body.accepts && Array.isArray(body.accepts) && body.accepts.length > 0) {
|
|
1153
|
-
return { requirements: body.accepts[0], resource: body.resource };
|
|
1154
|
-
}
|
|
1155
|
-
if (body.paymentRequirements) {
|
|
1156
|
-
const pr = Array.isArray(body.paymentRequirements) ? body.paymentRequirements[0] : body.paymentRequirements;
|
|
1157
|
-
return { requirements: pr, resource: body.resource };
|
|
1158
|
-
}
|
|
1159
|
-
if (body.scheme && body.network) {
|
|
1160
|
-
return { requirements: body, resource: body.resource };
|
|
1161
|
-
}
|
|
1162
|
-
} catch {
|
|
1163
|
-
}
|
|
1164
|
-
const wwwAuth = response.headers.get("WWW-Authenticate");
|
|
1165
|
-
if (wwwAuth) {
|
|
1166
|
-
const m = wwwAuth.match(/x402[^"]*"([^"]+)"/);
|
|
1167
|
-
if (m) {
|
|
1168
|
-
try {
|
|
1169
|
-
const decoded = JSON.parse(Buffer.from(m[1], "base64").toString("utf-8"));
|
|
1170
|
-
const reqs = Array.isArray(decoded) ? decoded[0] : decoded;
|
|
1171
|
-
return { requirements: reqs };
|
|
1172
|
-
} catch {
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
return null;
|
|
1177
|
-
}
|
|
1178
|
-
// ──────────── Build x402 v2 PaymentPayload with EIP-3009 ────────────
|
|
1179
|
-
//
|
|
1180
|
-
// If an AgentAccount is configured, we use it as the `from` address
|
|
1181
|
-
// (smart wallet pays directly). The AgentAccount implements EIP-1271
|
|
1182
|
-
// so USDC's transferWithAuthorization will call isValidSignature()
|
|
1183
|
-
// to verify the owner's ECDSA signature. The facilitator detects
|
|
1184
|
-
// the >65-byte or smart-wallet case and uses the bytes overload.
|
|
1185
|
-
async buildPaymentPayload(reqs, resource, url) {
|
|
1186
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
1187
|
-
const validAfter = String(now - 60);
|
|
1188
|
-
const validBefore = String(now + (reqs.maxTimeoutSeconds || 300));
|
|
1189
|
-
const nonce = ethers3.hexlify(ethers3.randomBytes(32));
|
|
1190
|
-
const chainId = chainIdFromNetwork(reqs.network);
|
|
1191
|
-
const usdcDomain = USDC_DOMAINS[reqs.network] || USDC_DOMAINS["eip155:1"];
|
|
1192
|
-
const payerAddress = this.config.accountAddress || this.wallet.address;
|
|
1193
|
-
const isSmartWallet = !!this.config.accountAddress;
|
|
1194
|
-
const domain = {
|
|
1195
|
-
name: usdcDomain.name,
|
|
1196
|
-
version: usdcDomain.version,
|
|
1197
|
-
chainId,
|
|
1198
|
-
verifyingContract: reqs.asset || usdcDomain.address
|
|
1199
|
-
};
|
|
1200
|
-
const types = {
|
|
1201
|
-
TransferWithAuthorization: [
|
|
1202
|
-
{ name: "from", type: "address" },
|
|
1203
|
-
{ name: "to", type: "address" },
|
|
1204
|
-
{ name: "value", type: "uint256" },
|
|
1205
|
-
{ name: "validAfter", type: "uint256" },
|
|
1206
|
-
{ name: "validBefore", type: "uint256" },
|
|
1207
|
-
{ name: "nonce", type: "bytes32" }
|
|
1208
|
-
]
|
|
1209
|
-
};
|
|
1210
|
-
const value = {
|
|
1211
|
-
from: payerAddress,
|
|
1212
|
-
// AgentAccount or EOA
|
|
1213
|
-
to: reqs.payTo,
|
|
1214
|
-
value: reqs.amount,
|
|
1215
|
-
validAfter,
|
|
1216
|
-
validBefore,
|
|
1217
|
-
nonce
|
|
1218
|
-
};
|
|
1219
|
-
let signature = await this.wallet.signTypedData(domain, types, value);
|
|
1220
|
-
if (isSmartWallet) {
|
|
1221
|
-
signature = signature + "00";
|
|
1222
|
-
}
|
|
1223
|
-
if (isSmartWallet) {
|
|
1224
|
-
console.log(` \u2713 Signed for AgentAccount ${payerAddress.slice(0, 10)}\u2026 (EIP-1271, chain=${chainId})`);
|
|
1225
|
-
} else {
|
|
1226
|
-
console.log(` \u2713 Signed (from=${payerAddress.slice(0, 10)}\u2026, chain=${chainId})`);
|
|
1227
|
-
}
|
|
1228
|
-
return {
|
|
1229
|
-
x402Version: 2,
|
|
1230
|
-
resource: resource || { url, description: "", mimeType: "application/json" },
|
|
1231
|
-
accepted: {
|
|
1232
|
-
scheme: reqs.scheme,
|
|
1233
|
-
network: reqs.network,
|
|
1234
|
-
amount: reqs.amount,
|
|
1235
|
-
asset: reqs.asset,
|
|
1236
|
-
payTo: reqs.payTo,
|
|
1237
|
-
maxTimeoutSeconds: reqs.maxTimeoutSeconds,
|
|
1238
|
-
extra: reqs.extra || {}
|
|
1239
|
-
},
|
|
1240
|
-
payload: {
|
|
1241
|
-
signature,
|
|
1242
|
-
authorization: {
|
|
1243
|
-
from: payerAddress,
|
|
1244
|
-
// AgentAccount address — facilitator checks balance here
|
|
1245
|
-
to: reqs.payTo,
|
|
1246
|
-
value: reqs.amount,
|
|
1247
|
-
validAfter,
|
|
1248
|
-
validBefore,
|
|
1249
|
-
nonce
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
};
|
|
1253
|
-
}
|
|
1254
|
-
// ──────────── Risk check via our backend ────────────
|
|
1255
|
-
async riskCheck(paymentPayload, reqs) {
|
|
1256
|
-
try {
|
|
1257
|
-
const verifyUrl = `${this.config.backendUrl}/x402/verify`;
|
|
1258
|
-
const resp = await fetch(verifyUrl, {
|
|
1259
|
-
method: "POST",
|
|
1260
|
-
headers: {
|
|
1261
|
-
"Content-Type": "application/json",
|
|
1262
|
-
"X-Agent-Id": this.config.agentId || "",
|
|
1263
|
-
...this.config.accountAddress ? { "X-Agent-Account": this.config.accountAddress } : {}
|
|
1264
|
-
},
|
|
1265
|
-
body: JSON.stringify({
|
|
1266
|
-
x402Version: 2,
|
|
1267
|
-
paymentPayload,
|
|
1268
|
-
paymentRequirements: reqs
|
|
1269
|
-
}),
|
|
1270
|
-
signal: AbortSignal.timeout(5e3)
|
|
1271
|
-
});
|
|
1272
|
-
if (resp.ok) {
|
|
1273
|
-
const result = await resp.json();
|
|
1274
|
-
const decision = resp.headers.get("X-Risk-Decision") || (result.isValid ? "allow" : "unknown");
|
|
1275
|
-
const score = resp.headers.get("X-Risk-Score") || "?";
|
|
1276
|
-
console.log(` \u2713 Risk check: ${decision} (score=${score})`);
|
|
1277
|
-
} else {
|
|
1278
|
-
console.log(` \u26A0 Risk check failed (HTTP ${resp.status}) \u2014 continuing anyway`);
|
|
1279
|
-
}
|
|
1280
|
-
} catch {
|
|
1281
|
-
console.log(" \u26A0 Risk check unavailable \u2014 continuing");
|
|
1104
|
+
return {
|
|
1105
|
+
success: false,
|
|
1106
|
+
error: `Request failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1107
|
+
};
|
|
1282
1108
|
}
|
|
1283
1109
|
}
|
|
1284
1110
|
};
|
|
@@ -1374,7 +1200,7 @@ var ScoringClient = class {
|
|
|
1374
1200
|
};
|
|
1375
1201
|
|
|
1376
1202
|
// src/clients/AgentIdentityClient.ts
|
|
1377
|
-
import { ethers as
|
|
1203
|
+
import { ethers as ethers3 } from "ethers";
|
|
1378
1204
|
var ERC8004_IDENTITY_ABI = [
|
|
1379
1205
|
// Registration
|
|
1380
1206
|
"function register() returns (uint256)",
|
|
@@ -1416,8 +1242,8 @@ var AgentIdentityClient = class {
|
|
|
1416
1242
|
this.signer = options.signer;
|
|
1417
1243
|
const identityAddr = options.config.contracts?.identityRegistry || ERC8004_SEPOLIA.identityRegistry;
|
|
1418
1244
|
const reputationAddr = options.config.contracts?.reputationRegistry || ERC8004_SEPOLIA.reputationRegistry;
|
|
1419
|
-
this.identityRegistry = new
|
|
1420
|
-
this.reputationRegistry = new
|
|
1245
|
+
this.identityRegistry = new ethers3.Contract(identityAddr, ERC8004_IDENTITY_ABI, this.signer);
|
|
1246
|
+
this.reputationRegistry = new ethers3.Contract(reputationAddr, ERC8004_REPUTATION_ABI, this.signer);
|
|
1421
1247
|
}
|
|
1422
1248
|
// ============ Identity Functions ============
|
|
1423
1249
|
/**
|
|
@@ -1484,7 +1310,7 @@ var AgentIdentityClient = class {
|
|
|
1484
1310
|
async registerWithMetadata(agentURI, metadata) {
|
|
1485
1311
|
const metadataEntries = metadata.map((m) => ({
|
|
1486
1312
|
key: m.key,
|
|
1487
|
-
value:
|
|
1313
|
+
value: ethers3.toUtf8Bytes(m.value)
|
|
1488
1314
|
}));
|
|
1489
1315
|
const tx = await this.identityRegistry["register(string,tuple(string,bytes)[])"](
|
|
1490
1316
|
agentURI,
|
|
@@ -1521,7 +1347,7 @@ var AgentIdentityClient = class {
|
|
|
1521
1347
|
const tx = await this.identityRegistry.setMetadata(
|
|
1522
1348
|
agentId,
|
|
1523
1349
|
key,
|
|
1524
|
-
|
|
1350
|
+
ethers3.toUtf8Bytes(value)
|
|
1525
1351
|
);
|
|
1526
1352
|
const receipt = await tx.wait();
|
|
1527
1353
|
return receipt.hash;
|
|
@@ -1531,7 +1357,7 @@ var AgentIdentityClient = class {
|
|
|
1531
1357
|
*/
|
|
1532
1358
|
async getMetadata(agentId, key) {
|
|
1533
1359
|
const value = await this.identityRegistry.getMetadata(agentId, key);
|
|
1534
|
-
return
|
|
1360
|
+
return ethers3.toUtf8String(value);
|
|
1535
1361
|
}
|
|
1536
1362
|
/**
|
|
1537
1363
|
* Transfer agent to new owner
|
|
@@ -1565,8 +1391,8 @@ var AgentIdentityClient = class {
|
|
|
1565
1391
|
* Give feedback to an agent
|
|
1566
1392
|
*/
|
|
1567
1393
|
async giveFeedback(input) {
|
|
1568
|
-
const feedbackHash =
|
|
1569
|
-
|
|
1394
|
+
const feedbackHash = ethers3.keccak256(
|
|
1395
|
+
ethers3.AbiCoder.defaultAbiCoder().encode(
|
|
1570
1396
|
["uint256", "int128", "uint256"],
|
|
1571
1397
|
[input.agentId, input.value, Date.now()]
|
|
1572
1398
|
)
|