@agether/sdk 1.5.5 → 1.6.1

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
@@ -827,7 +827,6 @@ var MorphoClient = class {
827
827
  */
828
828
  async repay(usdcAmount, tokenSymbol, marketParams) {
829
829
  const acctAddr = await this.getAccountAddress();
830
- const amount = ethers2.parseUnits(usdcAmount, 6);
831
830
  const morphoAddr = this.config.contracts.morphoBlue;
832
831
  const usdcAddr = this.config.contracts.usdc;
833
832
  let params;
@@ -839,14 +838,60 @@ var MorphoClient = class {
839
838
  const { params: p } = await this._findActiveMarket();
840
839
  params = p;
841
840
  }
841
+ let repayAssets;
842
+ let repayShares;
843
+ let approveAmount;
844
+ if (usdcAmount === "all") {
845
+ const markets = await this.getMarkets();
846
+ const mkt = markets.find(
847
+ (m) => m.collateralAsset?.address.toLowerCase() === params.collateralToken.toLowerCase()
848
+ );
849
+ if (mkt) {
850
+ const pos = await this.morphoBlue.position(mkt.uniqueKey, acctAddr);
851
+ repayShares = BigInt(pos.borrowShares);
852
+ repayAssets = 0n;
853
+ const onChainMkt = await this.morphoBlue.market(mkt.uniqueKey);
854
+ const totalBorrowAssets = BigInt(onChainMkt.totalBorrowAssets);
855
+ const totalBorrowShares = BigInt(onChainMkt.totalBorrowShares);
856
+ const estimated = totalBorrowShares > 0n ? repayShares * totalBorrowAssets / totalBorrowShares + 10n : 0n;
857
+ approveAmount = estimated > 0n ? estimated : ethers2.parseUnits("1", 6);
858
+ } else {
859
+ repayAssets = ethers2.parseUnits("999999", 6);
860
+ repayShares = 0n;
861
+ approveAmount = repayAssets;
862
+ }
863
+ } else {
864
+ repayAssets = ethers2.parseUnits(usdcAmount, 6);
865
+ repayShares = 0n;
866
+ approveAmount = repayAssets;
867
+ try {
868
+ const markets = await this.getMarkets();
869
+ const mkt = markets.find(
870
+ (m) => m.collateralAsset?.address.toLowerCase() === params.collateralToken.toLowerCase()
871
+ );
872
+ if (mkt) {
873
+ const pos = await this.morphoBlue.position(mkt.uniqueKey, acctAddr);
874
+ const onChainMkt = await this.morphoBlue.market(mkt.uniqueKey);
875
+ const totalBorrowAssets = BigInt(onChainMkt.totalBorrowAssets);
876
+ const totalBorrowShares = BigInt(onChainMkt.totalBorrowShares);
877
+ const currentDebt = totalBorrowShares > 0n ? BigInt(pos.borrowShares) * totalBorrowAssets / totalBorrowShares : 0n;
878
+ if (repayAssets >= currentDebt && BigInt(pos.borrowShares) > 0n) {
879
+ repayShares = BigInt(pos.borrowShares);
880
+ repayAssets = 0n;
881
+ approveAmount = currentDebt + 10n;
882
+ }
883
+ }
884
+ } catch {
885
+ }
886
+ }
842
887
  const targets = [usdcAddr, morphoAddr];
843
888
  const values = [0n, 0n];
844
889
  const datas = [
845
- erc20Iface.encodeFunctionData("approve", [morphoAddr, amount]),
890
+ erc20Iface.encodeFunctionData("approve", [morphoAddr, approveAmount]),
846
891
  morphoIface.encodeFunctionData("repay", [
847
892
  this._toTuple(params),
848
- amount,
849
- 0n,
893
+ repayAssets,
894
+ repayShares,
850
895
  acctAddr,
851
896
  "0x"
852
897
  ])
@@ -1030,23 +1075,19 @@ var MorphoClient = class {
1030
1075
  import axios2 from "axios";
1031
1076
 
1032
1077
  // src/clients/X402Client.ts
1033
- import { ethers as ethers3 } from "ethers";
1034
- var USDC_DOMAINS = {
1035
- "eip155:1": { name: "USD Coin", version: "2", address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" },
1036
- "eip155:8453": { name: "USD Coin", version: "2", address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" },
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
- }
1078
+ import { wrapFetchWithPayment } from "@x402/fetch";
1079
+ import { x402Client } from "@x402/core/client";
1080
+ import { registerExactEvmScheme } from "@x402/evm/exact/client";
1081
+ import { privateKeyToAccount } from "viem/accounts";
1045
1082
  var X402Client = class {
1046
1083
  constructor(config) {
1047
1084
  this.config = config;
1048
- const provider = new ethers3.JsonRpcProvider(config.rpcUrl);
1049
- this.wallet = new ethers3.Wallet(config.privateKey, provider);
1085
+ const privateKey = config.privateKey.startsWith("0x") ? config.privateKey : `0x${config.privateKey}`;
1086
+ const signer = privateKeyToAccount(privateKey);
1087
+ this.address = signer.address;
1088
+ const client = new x402Client();
1089
+ registerExactEvmScheme(client, { signer });
1090
+ this.paidFetch = wrapFetchWithPayment(fetch, client);
1050
1091
  }
1051
1092
  async get(url, opts) {
1052
1093
  return this.request(url, { ...opts, method: "GET" });
@@ -1060,13 +1101,13 @@ var X402Client = class {
1060
1101
  });
1061
1102
  }
1062
1103
  getAddress() {
1063
- return this.wallet.address;
1104
+ return this.address;
1064
1105
  }
1065
- // ──────────── Core request / 402-retry loop ────────────
1106
+ // ──────────── Core request — @x402/fetch handles 402 automatically ────────────
1066
1107
  async request(url, options) {
1067
1108
  try {
1068
- console.log(" [1/4] Calling resource server\u2026");
1069
- const response = await fetch(url, {
1109
+ console.log(` [x402] ${options?.method || "GET"} ${url}`);
1110
+ const response = await this.paidFetch(url, {
1070
1111
  ...options,
1071
1112
  headers: {
1072
1113
  ...options?.headers,
@@ -1075,45 +1116,13 @@ var X402Client = class {
1075
1116
  });
1076
1117
  if (response.ok) {
1077
1118
  const data = await response.json();
1078
- return { success: true, data };
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");
1119
+ const paymentResponse = response.headers.get("PAYMENT-RESPONSE");
1113
1120
  let txHash;
1114
- if (settlementHeader) {
1121
+ if (paymentResponse) {
1115
1122
  try {
1116
- const settlement = JSON.parse(Buffer.from(settlementHeader, "base64").toString("utf-8"));
1123
+ const settlement = JSON.parse(
1124
+ Buffer.from(paymentResponse, "base64").toString("utf-8")
1125
+ );
1117
1126
  txHash = settlement.transaction;
1118
1127
  } catch {
1119
1128
  }
@@ -1121,164 +1130,26 @@ var X402Client = class {
1121
1130
  return {
1122
1131
  success: true,
1123
1132
  data,
1124
- paymentInfo: {
1125
- amount: requirements.amount,
1126
- asset: requirements.extra?.name || "USDC",
1127
- network: requirements.network,
1128
- txHash
1129
- }
1133
+ ...txHash ? {
1134
+ paymentInfo: {
1135
+ amount: "",
1136
+ asset: "USDC",
1137
+ network: "eip155:8453",
1138
+ txHash
1139
+ }
1140
+ } : {}
1130
1141
  };
1131
1142
  }
1132
- const errBody = await paidResponse.text();
1133
- return { success: false, error: `Payment rejected (HTTP ${paidResponse.status}): ${errBody}` };
1143
+ const errBody = await response.text();
1144
+ return {
1145
+ success: false,
1146
+ error: `HTTP ${response.status}: ${errBody}`
1147
+ };
1134
1148
  } catch (error) {
1135
- return { success: false, error: `Request failed: ${error instanceof Error ? error.message : String(error)}` };
1136
- }
1137
- }
1138
- // ──────────── Parse 402 response ────────────
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");
1149
+ return {
1150
+ success: false,
1151
+ error: `Request failed: ${error instanceof Error ? error.message : String(error)}`
1152
+ };
1282
1153
  }
1283
1154
  }
1284
1155
  };
@@ -1374,7 +1245,7 @@ var ScoringClient = class {
1374
1245
  };
1375
1246
 
1376
1247
  // src/clients/AgentIdentityClient.ts
1377
- import { ethers as ethers4 } from "ethers";
1248
+ import { ethers as ethers3 } from "ethers";
1378
1249
  var ERC8004_IDENTITY_ABI = [
1379
1250
  // Registration
1380
1251
  "function register() returns (uint256)",
@@ -1416,8 +1287,8 @@ var AgentIdentityClient = class {
1416
1287
  this.signer = options.signer;
1417
1288
  const identityAddr = options.config.contracts?.identityRegistry || ERC8004_SEPOLIA.identityRegistry;
1418
1289
  const reputationAddr = options.config.contracts?.reputationRegistry || ERC8004_SEPOLIA.reputationRegistry;
1419
- this.identityRegistry = new ethers4.Contract(identityAddr, ERC8004_IDENTITY_ABI, this.signer);
1420
- this.reputationRegistry = new ethers4.Contract(reputationAddr, ERC8004_REPUTATION_ABI, this.signer);
1290
+ this.identityRegistry = new ethers3.Contract(identityAddr, ERC8004_IDENTITY_ABI, this.signer);
1291
+ this.reputationRegistry = new ethers3.Contract(reputationAddr, ERC8004_REPUTATION_ABI, this.signer);
1421
1292
  }
1422
1293
  // ============ Identity Functions ============
1423
1294
  /**
@@ -1484,7 +1355,7 @@ var AgentIdentityClient = class {
1484
1355
  async registerWithMetadata(agentURI, metadata) {
1485
1356
  const metadataEntries = metadata.map((m) => ({
1486
1357
  key: m.key,
1487
- value: ethers4.toUtf8Bytes(m.value)
1358
+ value: ethers3.toUtf8Bytes(m.value)
1488
1359
  }));
1489
1360
  const tx = await this.identityRegistry["register(string,tuple(string,bytes)[])"](
1490
1361
  agentURI,
@@ -1521,7 +1392,7 @@ var AgentIdentityClient = class {
1521
1392
  const tx = await this.identityRegistry.setMetadata(
1522
1393
  agentId,
1523
1394
  key,
1524
- ethers4.toUtf8Bytes(value)
1395
+ ethers3.toUtf8Bytes(value)
1525
1396
  );
1526
1397
  const receipt = await tx.wait();
1527
1398
  return receipt.hash;
@@ -1531,7 +1402,7 @@ var AgentIdentityClient = class {
1531
1402
  */
1532
1403
  async getMetadata(agentId, key) {
1533
1404
  const value = await this.identityRegistry.getMetadata(agentId, key);
1534
- return ethers4.toUtf8String(value);
1405
+ return ethers3.toUtf8String(value);
1535
1406
  }
1536
1407
  /**
1537
1408
  * Transfer agent to new owner
@@ -1565,8 +1436,8 @@ var AgentIdentityClient = class {
1565
1436
  * Give feedback to an agent
1566
1437
  */
1567
1438
  async giveFeedback(input) {
1568
- const feedbackHash = ethers4.keccak256(
1569
- ethers4.AbiCoder.defaultAbiCoder().encode(
1439
+ const feedbackHash = ethers3.keccak256(
1440
+ ethers3.AbiCoder.defaultAbiCoder().encode(
1570
1441
  ["uint256", "int128", "uint256"],
1571
1442
  [input.agentId, input.value, Date.now()]
1572
1443
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agether/sdk",
3
- "version": "1.5.5",
3
+ "version": "1.6.1",
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
- };