@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.js CHANGED
@@ -891,7 +891,6 @@ var MorphoClient = class {
891
891
  */
892
892
  async repay(usdcAmount, tokenSymbol, marketParams) {
893
893
  const acctAddr = await this.getAccountAddress();
894
- const amount = import_ethers2.ethers.parseUnits(usdcAmount, 6);
895
894
  const morphoAddr = this.config.contracts.morphoBlue;
896
895
  const usdcAddr = this.config.contracts.usdc;
897
896
  let params;
@@ -903,14 +902,60 @@ var MorphoClient = class {
903
902
  const { params: p } = await this._findActiveMarket();
904
903
  params = p;
905
904
  }
905
+ let repayAssets;
906
+ let repayShares;
907
+ let approveAmount;
908
+ if (usdcAmount === "all") {
909
+ const markets = await this.getMarkets();
910
+ const mkt = markets.find(
911
+ (m) => m.collateralAsset?.address.toLowerCase() === params.collateralToken.toLowerCase()
912
+ );
913
+ if (mkt) {
914
+ const pos = await this.morphoBlue.position(mkt.uniqueKey, acctAddr);
915
+ repayShares = BigInt(pos.borrowShares);
916
+ repayAssets = 0n;
917
+ const onChainMkt = await this.morphoBlue.market(mkt.uniqueKey);
918
+ const totalBorrowAssets = BigInt(onChainMkt.totalBorrowAssets);
919
+ const totalBorrowShares = BigInt(onChainMkt.totalBorrowShares);
920
+ const estimated = totalBorrowShares > 0n ? repayShares * totalBorrowAssets / totalBorrowShares + 10n : 0n;
921
+ approveAmount = estimated > 0n ? estimated : import_ethers2.ethers.parseUnits("1", 6);
922
+ } else {
923
+ repayAssets = import_ethers2.ethers.parseUnits("999999", 6);
924
+ repayShares = 0n;
925
+ approveAmount = repayAssets;
926
+ }
927
+ } else {
928
+ repayAssets = import_ethers2.ethers.parseUnits(usdcAmount, 6);
929
+ repayShares = 0n;
930
+ approveAmount = repayAssets;
931
+ try {
932
+ const markets = await this.getMarkets();
933
+ const mkt = markets.find(
934
+ (m) => m.collateralAsset?.address.toLowerCase() === params.collateralToken.toLowerCase()
935
+ );
936
+ if (mkt) {
937
+ const pos = await this.morphoBlue.position(mkt.uniqueKey, acctAddr);
938
+ const onChainMkt = await this.morphoBlue.market(mkt.uniqueKey);
939
+ const totalBorrowAssets = BigInt(onChainMkt.totalBorrowAssets);
940
+ const totalBorrowShares = BigInt(onChainMkt.totalBorrowShares);
941
+ const currentDebt = totalBorrowShares > 0n ? BigInt(pos.borrowShares) * totalBorrowAssets / totalBorrowShares : 0n;
942
+ if (repayAssets >= currentDebt && BigInt(pos.borrowShares) > 0n) {
943
+ repayShares = BigInt(pos.borrowShares);
944
+ repayAssets = 0n;
945
+ approveAmount = currentDebt + 10n;
946
+ }
947
+ }
948
+ } catch {
949
+ }
950
+ }
906
951
  const targets = [usdcAddr, morphoAddr];
907
952
  const values = [0n, 0n];
908
953
  const datas = [
909
- erc20Iface.encodeFunctionData("approve", [morphoAddr, amount]),
954
+ erc20Iface.encodeFunctionData("approve", [morphoAddr, approveAmount]),
910
955
  morphoIface.encodeFunctionData("repay", [
911
956
  this._toTuple(params),
912
- amount,
913
- 0n,
957
+ repayAssets,
958
+ repayShares,
914
959
  acctAddr,
915
960
  "0x"
916
961
  ])
@@ -1094,23 +1139,19 @@ var MorphoClient = class {
1094
1139
  var import_axios2 = __toESM(require("axios"));
1095
1140
 
1096
1141
  // src/clients/X402Client.ts
1097
- var import_ethers3 = require("ethers");
1098
- var USDC_DOMAINS = {
1099
- "eip155:1": { name: "USD Coin", version: "2", address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" },
1100
- "eip155:8453": { name: "USD Coin", version: "2", address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" },
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
- }
1142
+ var import_fetch = require("@x402/fetch");
1143
+ var import_client = require("@x402/core/client");
1144
+ var import_client2 = require("@x402/evm/exact/client");
1145
+ var import_accounts = require("viem/accounts");
1109
1146
  var X402Client = class {
1110
1147
  constructor(config) {
1111
1148
  this.config = config;
1112
- const provider = new import_ethers3.ethers.JsonRpcProvider(config.rpcUrl);
1113
- this.wallet = new import_ethers3.ethers.Wallet(config.privateKey, provider);
1149
+ const privateKey = config.privateKey.startsWith("0x") ? config.privateKey : `0x${config.privateKey}`;
1150
+ const signer = (0, import_accounts.privateKeyToAccount)(privateKey);
1151
+ this.address = signer.address;
1152
+ const client = new import_client.x402Client();
1153
+ (0, import_client2.registerExactEvmScheme)(client, { signer });
1154
+ this.paidFetch = (0, import_fetch.wrapFetchWithPayment)(fetch, client);
1114
1155
  }
1115
1156
  async get(url, opts) {
1116
1157
  return this.request(url, { ...opts, method: "GET" });
@@ -1124,13 +1165,13 @@ var X402Client = class {
1124
1165
  });
1125
1166
  }
1126
1167
  getAddress() {
1127
- return this.wallet.address;
1168
+ return this.address;
1128
1169
  }
1129
- // ──────────── Core request / 402-retry loop ────────────
1170
+ // ──────────── Core request — @x402/fetch handles 402 automatically ────────────
1130
1171
  async request(url, options) {
1131
1172
  try {
1132
- console.log(" [1/4] Calling resource server\u2026");
1133
- const response = await fetch(url, {
1173
+ console.log(` [x402] ${options?.method || "GET"} ${url}`);
1174
+ const response = await this.paidFetch(url, {
1134
1175
  ...options,
1135
1176
  headers: {
1136
1177
  ...options?.headers,
@@ -1139,45 +1180,13 @@ var X402Client = class {
1139
1180
  });
1140
1181
  if (response.ok) {
1141
1182
  const data = await response.json();
1142
- return { success: true, data };
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");
1183
+ const paymentResponse = response.headers.get("PAYMENT-RESPONSE");
1177
1184
  let txHash;
1178
- if (settlementHeader) {
1185
+ if (paymentResponse) {
1179
1186
  try {
1180
- const settlement = JSON.parse(Buffer.from(settlementHeader, "base64").toString("utf-8"));
1187
+ const settlement = JSON.parse(
1188
+ Buffer.from(paymentResponse, "base64").toString("utf-8")
1189
+ );
1181
1190
  txHash = settlement.transaction;
1182
1191
  } catch {
1183
1192
  }
@@ -1185,164 +1194,26 @@ var X402Client = class {
1185
1194
  return {
1186
1195
  success: true,
1187
1196
  data,
1188
- paymentInfo: {
1189
- amount: requirements.amount,
1190
- asset: requirements.extra?.name || "USDC",
1191
- network: requirements.network,
1192
- txHash
1193
- }
1197
+ ...txHash ? {
1198
+ paymentInfo: {
1199
+ amount: "",
1200
+ asset: "USDC",
1201
+ network: "eip155:8453",
1202
+ txHash
1203
+ }
1204
+ } : {}
1194
1205
  };
1195
1206
  }
1196
- const errBody = await paidResponse.text();
1197
- return { success: false, error: `Payment rejected (HTTP ${paidResponse.status}): ${errBody}` };
1207
+ const errBody = await response.text();
1208
+ return {
1209
+ success: false,
1210
+ error: `HTTP ${response.status}: ${errBody}`
1211
+ };
1198
1212
  } catch (error) {
1199
- return { success: false, error: `Request failed: ${error instanceof Error ? error.message : String(error)}` };
1200
- }
1201
- }
1202
- // ──────────── Parse 402 response ────────────
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");
1213
+ return {
1214
+ success: false,
1215
+ error: `Request failed: ${error instanceof Error ? error.message : String(error)}`
1216
+ };
1346
1217
  }
1347
1218
  }
1348
1219
  };
@@ -1438,7 +1309,7 @@ var ScoringClient = class {
1438
1309
  };
1439
1310
 
1440
1311
  // src/clients/AgentIdentityClient.ts
1441
- var import_ethers4 = require("ethers");
1312
+ var import_ethers3 = require("ethers");
1442
1313
  var ERC8004_IDENTITY_ABI = [
1443
1314
  // Registration
1444
1315
  "function register() returns (uint256)",
@@ -1480,8 +1351,8 @@ var AgentIdentityClient = class {
1480
1351
  this.signer = options.signer;
1481
1352
  const identityAddr = options.config.contracts?.identityRegistry || ERC8004_SEPOLIA.identityRegistry;
1482
1353
  const reputationAddr = options.config.contracts?.reputationRegistry || ERC8004_SEPOLIA.reputationRegistry;
1483
- this.identityRegistry = new import_ethers4.ethers.Contract(identityAddr, ERC8004_IDENTITY_ABI, this.signer);
1484
- this.reputationRegistry = new import_ethers4.ethers.Contract(reputationAddr, ERC8004_REPUTATION_ABI, this.signer);
1354
+ this.identityRegistry = new import_ethers3.ethers.Contract(identityAddr, ERC8004_IDENTITY_ABI, this.signer);
1355
+ this.reputationRegistry = new import_ethers3.ethers.Contract(reputationAddr, ERC8004_REPUTATION_ABI, this.signer);
1485
1356
  }
1486
1357
  // ============ Identity Functions ============
1487
1358
  /**
@@ -1548,7 +1419,7 @@ var AgentIdentityClient = class {
1548
1419
  async registerWithMetadata(agentURI, metadata) {
1549
1420
  const metadataEntries = metadata.map((m) => ({
1550
1421
  key: m.key,
1551
- value: import_ethers4.ethers.toUtf8Bytes(m.value)
1422
+ value: import_ethers3.ethers.toUtf8Bytes(m.value)
1552
1423
  }));
1553
1424
  const tx = await this.identityRegistry["register(string,tuple(string,bytes)[])"](
1554
1425
  agentURI,
@@ -1585,7 +1456,7 @@ var AgentIdentityClient = class {
1585
1456
  const tx = await this.identityRegistry.setMetadata(
1586
1457
  agentId,
1587
1458
  key,
1588
- import_ethers4.ethers.toUtf8Bytes(value)
1459
+ import_ethers3.ethers.toUtf8Bytes(value)
1589
1460
  );
1590
1461
  const receipt = await tx.wait();
1591
1462
  return receipt.hash;
@@ -1595,7 +1466,7 @@ var AgentIdentityClient = class {
1595
1466
  */
1596
1467
  async getMetadata(agentId, key) {
1597
1468
  const value = await this.identityRegistry.getMetadata(agentId, key);
1598
- return import_ethers4.ethers.toUtf8String(value);
1469
+ return import_ethers3.ethers.toUtf8String(value);
1599
1470
  }
1600
1471
  /**
1601
1472
  * Transfer agent to new owner
@@ -1629,8 +1500,8 @@ var AgentIdentityClient = class {
1629
1500
  * Give feedback to an agent
1630
1501
  */
1631
1502
  async giveFeedback(input) {
1632
- const feedbackHash = import_ethers4.ethers.keccak256(
1633
- import_ethers4.ethers.AbiCoder.defaultAbiCoder().encode(
1503
+ const feedbackHash = import_ethers3.ethers.keccak256(
1504
+ import_ethers3.ethers.AbiCoder.defaultAbiCoder().encode(
1634
1505
  ["uint256", "int128", "uint256"],
1635
1506
  [input.agentId, input.value, Date.now()]
1636
1507
  )