@agether/sdk 1.5.4 → 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/index.mjs CHANGED
@@ -489,26 +489,48 @@ var MorphoClient = class {
489
489
  tx: txHash
490
490
  };
491
491
  }
492
- /** Get ETH / USDC balances for EOA and AgentAccount. */
492
+ /** Get ETH / USDC / collateral balances for EOA and AgentAccount. */
493
493
  async getBalances() {
494
494
  const eoaAddr = this.wallet.address;
495
495
  const usdc = new Contract2(this.config.contracts.usdc, ERC20_ABI, this.provider);
496
496
  const ethBal = await this.provider.getBalance(eoaAddr);
497
497
  const usdcBal = await usdc.balanceOf(eoaAddr);
498
+ const eoaCollateral = {};
499
+ for (const [symbol, info] of Object.entries(BASE_COLLATERALS)) {
500
+ try {
501
+ const token = new Contract2(info.address, ERC20_ABI, this.provider);
502
+ const bal = await token.balanceOf(eoaAddr);
503
+ eoaCollateral[symbol] = ethers2.formatUnits(bal, info.decimals);
504
+ } catch {
505
+ eoaCollateral[symbol] = "0";
506
+ }
507
+ }
498
508
  const result = {
499
509
  agentId: this.agentId || "?",
500
510
  address: eoaAddr,
501
511
  eth: ethers2.formatEther(ethBal),
502
- usdc: ethers2.formatUnits(usdcBal, 6)
512
+ usdc: ethers2.formatUnits(usdcBal, 6),
513
+ collateral: eoaCollateral
503
514
  };
504
515
  try {
505
516
  const acctAddr = await this.getAccountAddress();
506
517
  const acctEth = await this.provider.getBalance(acctAddr);
507
518
  const acctUsdc = await usdc.balanceOf(acctAddr);
519
+ const acctCollateral = {};
520
+ for (const [symbol, info] of Object.entries(BASE_COLLATERALS)) {
521
+ try {
522
+ const token = new Contract2(info.address, ERC20_ABI, this.provider);
523
+ const bal = await token.balanceOf(acctAddr);
524
+ acctCollateral[symbol] = ethers2.formatUnits(bal, info.decimals);
525
+ } catch {
526
+ acctCollateral[symbol] = "0";
527
+ }
528
+ }
508
529
  result.agentAccount = {
509
530
  address: acctAddr,
510
531
  eth: ethers2.formatEther(acctEth),
511
- usdc: ethers2.formatUnits(acctUsdc, 6)
532
+ usdc: ethers2.formatUnits(acctUsdc, 6),
533
+ collateral: acctCollateral
512
534
  };
513
535
  } catch {
514
536
  }
@@ -1008,23 +1030,19 @@ var MorphoClient = class {
1008
1030
  import axios2 from "axios";
1009
1031
 
1010
1032
  // src/clients/X402Client.ts
1011
- import { ethers as ethers3 } from "ethers";
1012
- var USDC_DOMAINS = {
1013
- "eip155:1": { name: "USD Coin", version: "2", address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" },
1014
- "eip155:8453": { name: "USD Coin", version: "2", address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" },
1015
- "eip155:84532": { name: "USD Coin", version: "2", address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e" },
1016
- "eip155:42161": { name: "USD Coin", version: "2", address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831" },
1017
- "eip155:10": { name: "USD Coin", version: "2", address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85" }
1018
- };
1019
- function chainIdFromNetwork(network) {
1020
- const m = network.match(/^eip155:(\d+)$/);
1021
- return m ? Number(m[1]) : 1;
1022
- }
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";
1023
1037
  var X402Client = class {
1024
1038
  constructor(config) {
1025
1039
  this.config = config;
1026
- const provider = new ethers3.JsonRpcProvider(config.rpcUrl);
1027
- this.wallet = new ethers3.Wallet(config.privateKey, provider);
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);
1028
1046
  }
1029
1047
  async get(url, opts) {
1030
1048
  return this.request(url, { ...opts, method: "GET" });
@@ -1038,13 +1056,13 @@ var X402Client = class {
1038
1056
  });
1039
1057
  }
1040
1058
  getAddress() {
1041
- return this.wallet.address;
1059
+ return this.address;
1042
1060
  }
1043
- // ──────────── Core request / 402-retry loop ────────────
1061
+ // ──────────── Core request — @x402/fetch handles 402 automatically ────────────
1044
1062
  async request(url, options) {
1045
1063
  try {
1046
- console.log(" [1/4] Calling resource server\u2026");
1047
- const response = await fetch(url, {
1064
+ console.log(` [x402] ${options?.method || "GET"} ${url}`);
1065
+ const response = await this.paidFetch(url, {
1048
1066
  ...options,
1049
1067
  headers: {
1050
1068
  ...options?.headers,
@@ -1053,45 +1071,13 @@ var X402Client = class {
1053
1071
  });
1054
1072
  if (response.ok) {
1055
1073
  const data = await response.json();
1056
- return { success: true, data };
1057
- }
1058
- if (response.status !== 402) {
1059
- return { success: false, error: `HTTP ${response.status}: ${await response.text()}` };
1060
- }
1061
- console.log(" [2/4] 402 received \u2014 parsing payment requirements\u2026");
1062
- const parsed = await this.parsePaymentRequired(response);
1063
- if (!parsed) {
1064
- return { success: false, error: "Could not parse payment requirements from 402 response" };
1065
- }
1066
- const { requirements, resource } = parsed;
1067
- console.log(` scheme : ${requirements.scheme}`);
1068
- console.log(` network : ${requirements.network}`);
1069
- console.log(` amount : ${requirements.amount} (atomic)`);
1070
- console.log(` asset : ${requirements.asset}`);
1071
- console.log(` payTo : ${requirements.payTo}`);
1072
- console.log(" [3/4] Signing EIP-3009 transferWithAuthorization\u2026");
1073
- const paymentPayload = await this.buildPaymentPayload(requirements, resource, url);
1074
- const paymentB64 = Buffer.from(JSON.stringify(paymentPayload)).toString("base64");
1075
- await this.riskCheck(paymentPayload, requirements);
1076
- console.log(" [4/4] Retrying with PAYMENT-SIGNATURE header\u2026");
1077
- const paidResponse = await fetch(url, {
1078
- ...options,
1079
- headers: {
1080
- ...options?.headers,
1081
- "X-Agent-Id": this.config.agentId || "",
1082
- // v2 header
1083
- "PAYMENT-SIGNATURE": paymentB64,
1084
- // v1 compat header (some servers still use this)
1085
- "X-PAYMENT": paymentB64
1086
- }
1087
- });
1088
- if (paidResponse.ok) {
1089
- const data = await paidResponse.json();
1090
- const settlementHeader = paidResponse.headers.get("PAYMENT-RESPONSE") || paidResponse.headers.get("X-PAYMENT-RESPONSE");
1074
+ const paymentResponse = response.headers.get("PAYMENT-RESPONSE");
1091
1075
  let txHash;
1092
- if (settlementHeader) {
1076
+ if (paymentResponse) {
1093
1077
  try {
1094
- const settlement = JSON.parse(Buffer.from(settlementHeader, "base64").toString("utf-8"));
1078
+ const settlement = JSON.parse(
1079
+ Buffer.from(paymentResponse, "base64").toString("utf-8")
1080
+ );
1095
1081
  txHash = settlement.transaction;
1096
1082
  } catch {
1097
1083
  }
@@ -1099,164 +1085,26 @@ var X402Client = class {
1099
1085
  return {
1100
1086
  success: true,
1101
1087
  data,
1102
- paymentInfo: {
1103
- amount: requirements.amount,
1104
- asset: requirements.extra?.name || "USDC",
1105
- network: requirements.network,
1106
- txHash
1107
- }
1088
+ ...txHash ? {
1089
+ paymentInfo: {
1090
+ amount: "",
1091
+ asset: "USDC",
1092
+ network: "eip155:8453",
1093
+ txHash
1094
+ }
1095
+ } : {}
1108
1096
  };
1109
1097
  }
1110
- const errBody = await paidResponse.text();
1111
- return { success: false, error: `Payment rejected (HTTP ${paidResponse.status}): ${errBody}` };
1098
+ const errBody = await response.text();
1099
+ return {
1100
+ success: false,
1101
+ error: `HTTP ${response.status}: ${errBody}`
1102
+ };
1112
1103
  } catch (error) {
1113
- return { success: false, error: `Request failed: ${error instanceof Error ? error.message : String(error)}` };
1114
- }
1115
- }
1116
- // ──────────── Parse 402 response ────────────
1117
- async parsePaymentRequired(response) {
1118
- const prHeader = response.headers.get("PAYMENT-REQUIRED") || response.headers.get("x-payment-required");
1119
- if (prHeader) {
1120
- try {
1121
- const decoded = JSON.parse(Buffer.from(prHeader, "base64").toString("utf-8"));
1122
- if (decoded.accepts?.length) {
1123
- return { requirements: decoded.accepts[0], resource: decoded.resource };
1124
- }
1125
- } catch {
1126
- }
1127
- }
1128
- try {
1129
- const body = await response.json();
1130
- if (body.accepts && Array.isArray(body.accepts) && body.accepts.length > 0) {
1131
- return { requirements: body.accepts[0], resource: body.resource };
1132
- }
1133
- if (body.paymentRequirements) {
1134
- const pr = Array.isArray(body.paymentRequirements) ? body.paymentRequirements[0] : body.paymentRequirements;
1135
- return { requirements: pr, resource: body.resource };
1136
- }
1137
- if (body.scheme && body.network) {
1138
- return { requirements: body, resource: body.resource };
1139
- }
1140
- } catch {
1141
- }
1142
- const wwwAuth = response.headers.get("WWW-Authenticate");
1143
- if (wwwAuth) {
1144
- const m = wwwAuth.match(/x402[^"]*"([^"]+)"/);
1145
- if (m) {
1146
- try {
1147
- const decoded = JSON.parse(Buffer.from(m[1], "base64").toString("utf-8"));
1148
- const reqs = Array.isArray(decoded) ? decoded[0] : decoded;
1149
- return { requirements: reqs };
1150
- } catch {
1151
- }
1152
- }
1153
- }
1154
- return null;
1155
- }
1156
- // ──────────── Build x402 v2 PaymentPayload with EIP-3009 ────────────
1157
- //
1158
- // If an AgentAccount is configured, we use it as the `from` address
1159
- // (smart wallet pays directly). The AgentAccount implements EIP-1271
1160
- // so USDC's transferWithAuthorization will call isValidSignature()
1161
- // to verify the owner's ECDSA signature. The facilitator detects
1162
- // the >65-byte or smart-wallet case and uses the bytes overload.
1163
- async buildPaymentPayload(reqs, resource, url) {
1164
- const now = Math.floor(Date.now() / 1e3);
1165
- const validAfter = String(now - 60);
1166
- const validBefore = String(now + (reqs.maxTimeoutSeconds || 300));
1167
- const nonce = ethers3.hexlify(ethers3.randomBytes(32));
1168
- const chainId = chainIdFromNetwork(reqs.network);
1169
- const usdcDomain = USDC_DOMAINS[reqs.network] || USDC_DOMAINS["eip155:1"];
1170
- const payerAddress = this.config.accountAddress || this.wallet.address;
1171
- const isSmartWallet = !!this.config.accountAddress;
1172
- const domain = {
1173
- name: usdcDomain.name,
1174
- version: usdcDomain.version,
1175
- chainId,
1176
- verifyingContract: reqs.asset || usdcDomain.address
1177
- };
1178
- const types = {
1179
- TransferWithAuthorization: [
1180
- { name: "from", type: "address" },
1181
- { name: "to", type: "address" },
1182
- { name: "value", type: "uint256" },
1183
- { name: "validAfter", type: "uint256" },
1184
- { name: "validBefore", type: "uint256" },
1185
- { name: "nonce", type: "bytes32" }
1186
- ]
1187
- };
1188
- const value = {
1189
- from: payerAddress,
1190
- // AgentAccount or EOA
1191
- to: reqs.payTo,
1192
- value: reqs.amount,
1193
- validAfter,
1194
- validBefore,
1195
- nonce
1196
- };
1197
- let signature = await this.wallet.signTypedData(domain, types, value);
1198
- if (isSmartWallet) {
1199
- signature = signature + "00";
1200
- }
1201
- if (isSmartWallet) {
1202
- console.log(` \u2713 Signed for AgentAccount ${payerAddress.slice(0, 10)}\u2026 (EIP-1271, chain=${chainId})`);
1203
- } else {
1204
- console.log(` \u2713 Signed (from=${payerAddress.slice(0, 10)}\u2026, chain=${chainId})`);
1205
- }
1206
- return {
1207
- x402Version: 2,
1208
- resource: resource || { url, description: "", mimeType: "application/json" },
1209
- accepted: {
1210
- scheme: reqs.scheme,
1211
- network: reqs.network,
1212
- amount: reqs.amount,
1213
- asset: reqs.asset,
1214
- payTo: reqs.payTo,
1215
- maxTimeoutSeconds: reqs.maxTimeoutSeconds,
1216
- extra: reqs.extra || {}
1217
- },
1218
- payload: {
1219
- signature,
1220
- authorization: {
1221
- from: payerAddress,
1222
- // AgentAccount address — facilitator checks balance here
1223
- to: reqs.payTo,
1224
- value: reqs.amount,
1225
- validAfter,
1226
- validBefore,
1227
- nonce
1228
- }
1229
- }
1230
- };
1231
- }
1232
- // ──────────── Risk check via our backend ────────────
1233
- async riskCheck(paymentPayload, reqs) {
1234
- try {
1235
- const verifyUrl = `${this.config.backendUrl}/x402/verify`;
1236
- const resp = await fetch(verifyUrl, {
1237
- method: "POST",
1238
- headers: {
1239
- "Content-Type": "application/json",
1240
- "X-Agent-Id": this.config.agentId || "",
1241
- ...this.config.accountAddress ? { "X-Agent-Account": this.config.accountAddress } : {}
1242
- },
1243
- body: JSON.stringify({
1244
- x402Version: 2,
1245
- paymentPayload,
1246
- paymentRequirements: reqs
1247
- }),
1248
- signal: AbortSignal.timeout(5e3)
1249
- });
1250
- if (resp.ok) {
1251
- const result = await resp.json();
1252
- const decision = resp.headers.get("X-Risk-Decision") || (result.isValid ? "allow" : "unknown");
1253
- const score = resp.headers.get("X-Risk-Score") || "?";
1254
- console.log(` \u2713 Risk check: ${decision} (score=${score})`);
1255
- } else {
1256
- console.log(` \u26A0 Risk check failed (HTTP ${resp.status}) \u2014 continuing anyway`);
1257
- }
1258
- } catch {
1259
- 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
+ };
1260
1108
  }
1261
1109
  }
1262
1110
  };
@@ -1352,7 +1200,7 @@ var ScoringClient = class {
1352
1200
  };
1353
1201
 
1354
1202
  // src/clients/AgentIdentityClient.ts
1355
- import { ethers as ethers4 } from "ethers";
1203
+ import { ethers as ethers3 } from "ethers";
1356
1204
  var ERC8004_IDENTITY_ABI = [
1357
1205
  // Registration
1358
1206
  "function register() returns (uint256)",
@@ -1394,8 +1242,8 @@ var AgentIdentityClient = class {
1394
1242
  this.signer = options.signer;
1395
1243
  const identityAddr = options.config.contracts?.identityRegistry || ERC8004_SEPOLIA.identityRegistry;
1396
1244
  const reputationAddr = options.config.contracts?.reputationRegistry || ERC8004_SEPOLIA.reputationRegistry;
1397
- this.identityRegistry = new ethers4.Contract(identityAddr, ERC8004_IDENTITY_ABI, this.signer);
1398
- this.reputationRegistry = new ethers4.Contract(reputationAddr, ERC8004_REPUTATION_ABI, this.signer);
1245
+ this.identityRegistry = new ethers3.Contract(identityAddr, ERC8004_IDENTITY_ABI, this.signer);
1246
+ this.reputationRegistry = new ethers3.Contract(reputationAddr, ERC8004_REPUTATION_ABI, this.signer);
1399
1247
  }
1400
1248
  // ============ Identity Functions ============
1401
1249
  /**
@@ -1462,7 +1310,7 @@ var AgentIdentityClient = class {
1462
1310
  async registerWithMetadata(agentURI, metadata) {
1463
1311
  const metadataEntries = metadata.map((m) => ({
1464
1312
  key: m.key,
1465
- value: ethers4.toUtf8Bytes(m.value)
1313
+ value: ethers3.toUtf8Bytes(m.value)
1466
1314
  }));
1467
1315
  const tx = await this.identityRegistry["register(string,tuple(string,bytes)[])"](
1468
1316
  agentURI,
@@ -1499,7 +1347,7 @@ var AgentIdentityClient = class {
1499
1347
  const tx = await this.identityRegistry.setMetadata(
1500
1348
  agentId,
1501
1349
  key,
1502
- ethers4.toUtf8Bytes(value)
1350
+ ethers3.toUtf8Bytes(value)
1503
1351
  );
1504
1352
  const receipt = await tx.wait();
1505
1353
  return receipt.hash;
@@ -1509,7 +1357,7 @@ var AgentIdentityClient = class {
1509
1357
  */
1510
1358
  async getMetadata(agentId, key) {
1511
1359
  const value = await this.identityRegistry.getMetadata(agentId, key);
1512
- return ethers4.toUtf8String(value);
1360
+ return ethers3.toUtf8String(value);
1513
1361
  }
1514
1362
  /**
1515
1363
  * Transfer agent to new owner
@@ -1543,8 +1391,8 @@ var AgentIdentityClient = class {
1543
1391
  * Give feedback to an agent
1544
1392
  */
1545
1393
  async giveFeedback(input) {
1546
- const feedbackHash = ethers4.keccak256(
1547
- ethers4.AbiCoder.defaultAbiCoder().encode(
1394
+ const feedbackHash = ethers3.keccak256(
1395
+ ethers3.AbiCoder.defaultAbiCoder().encode(
1548
1396
  ["uint256", "int128", "uint256"],
1549
1397
  [input.agentId, input.value, Date.now()]
1550
1398
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agether/sdk",
3
- "version": "1.5.4",
3
+ "version": "1.6.0",
4
4
  "description": "TypeScript SDK for Agether - autonomous credit for AI agents on Base",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -28,8 +28,12 @@
28
28
  "clean": "rm -rf dist"
29
29
  },
30
30
  "dependencies": {
31
+ "@x402/core": "^2.3.1",
32
+ "@x402/evm": "^2.3.1",
33
+ "@x402/fetch": "^2.3.0",
31
34
  "axios": "^1.6.0",
32
- "ethers": "^6.9.0"
35
+ "ethers": "^6.9.0",
36
+ "viem": "^2.46.2"
33
37
  },
34
38
  "devDependencies": {
35
39
  "@types/node": "^20.10.0",
@@ -1,6 +0,0 @@
1
- import {
2
- MorphoClient
3
- } from "./chunk-OMCWZ3VN.mjs";
4
- export {
5
- MorphoClient
6
- };
@@ -1,6 +0,0 @@
1
- import {
2
- X402Client
3
- } from "./chunk-PTXYOTCG.mjs";
4
- export {
5
- X402Client
6
- };