@agether/sdk 2.14.0 → 2.14.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/cli.js CHANGED
@@ -514,7 +514,7 @@ var init_MorphoClient = __esm({
514
514
  const resolved = await this._resolveToken(loanTokenSymbolOrAddress);
515
515
  loanAddr = resolved.address.toLowerCase();
516
516
  } catch {
517
- loanAddr = loanTokenSymbolOrAddress.toLowerCase();
517
+ loanAddr = void 0;
518
518
  }
519
519
  }
520
520
  }
@@ -522,6 +522,7 @@ var init_MorphoClient = __esm({
522
522
  for (const m of this._discoveredMarkets ?? []) {
523
523
  if (m.collateralAsset.address.toLowerCase() !== colAddr) continue;
524
524
  if (loanAddr && m.loanAsset.address.toLowerCase() !== loanAddr) continue;
525
+ if (!loanAddr && loanTokenSymbolOrAddress && m.loanAsset.symbol.toUpperCase() !== loanTokenSymbolOrAddress.toUpperCase()) continue;
525
526
  return {
526
527
  loanToken: m.loanAsset.address,
527
528
  collateralToken: m.collateralAsset.address,
@@ -532,9 +533,22 @@ var init_MorphoClient = __esm({
532
533
  }
533
534
  if (!collateralSymbolOrAddress.startsWith("0x")) {
534
535
  const searched = await this.searchMarkets(collateralSymbolOrAddress, { asCollateral: true });
535
- for (const m of searched) {
536
+ const allResults = [...searched];
537
+ if (loanTokenSymbolOrAddress && !loanTokenSymbolOrAddress.startsWith("0x")) {
538
+ const loanSearched = await this.searchMarkets(loanTokenSymbolOrAddress, { asLoanToken: true });
539
+ const seen = new Set(allResults.map((r) => r.marketId));
540
+ for (const m of loanSearched) {
541
+ if (!seen.has(m.marketId)) allResults.push(m);
542
+ }
543
+ }
544
+ for (const m of allResults) {
545
+ if (colAddr.startsWith("0x") && m.collateralAddress.toLowerCase() !== colAddr) {
546
+ if (m.collateralToken.toUpperCase() !== collateralSymbolOrAddress.toUpperCase()) continue;
547
+ } else if (m.collateralToken.toUpperCase() !== collateralSymbolOrAddress.toUpperCase()) {
548
+ continue;
549
+ }
536
550
  if (loanAddr && m.loanAddress.toLowerCase() !== loanAddr) continue;
537
- if (loanTokenSymbolOrAddress && !loanTokenSymbolOrAddress.startsWith("0x") && m.loanToken.toUpperCase() !== loanTokenSymbolOrAddress.toUpperCase()) continue;
551
+ if (!loanAddr && loanTokenSymbolOrAddress && m.loanToken.toUpperCase() !== loanTokenSymbolOrAddress.toUpperCase()) continue;
538
552
  return this.getMarketParams(m.marketId);
539
553
  }
540
554
  }
@@ -568,26 +582,54 @@ var init_MorphoClient = __esm({
568
582
  };
569
583
  }
570
584
  /**
571
- * Full status: positions across all discovered markets.
585
+ * Full status: positions across all markets the user has interacted with.
586
+ *
587
+ * Uses Morpho GraphQL `marketPositions` to find ALL positions (not limited
588
+ * to the top-500 markets), then reads onchain data for accurate debt.
572
589
  */
573
590
  async getStatus() {
574
591
  const acctAddr = await this.getAccountAddress();
575
- const markets = await this.getMarkets();
592
+ const chainId = this.config.chainId;
576
593
  const positions = [];
577
594
  let totalDebtFloat = 0;
578
- for (const m of markets) {
579
- if (!m.collateralAsset || m.collateralAsset.address === import_ethers.ethers.ZeroAddress) continue;
580
- try {
581
- const pos = await this.morphoBlue.position(m.uniqueKey, acctAddr);
582
- if (pos.collateral === 0n && pos.borrowShares === 0n && pos.supplyShares === 0n) continue;
595
+ try {
596
+ const posQuery = `{
597
+ marketPositions(
598
+ where: {
599
+ userAddress_in: ["${acctAddr}"]
600
+ chainId_in: [${chainId}]
601
+ }
602
+ first: 100
603
+ ) {
604
+ items {
605
+ supplyShares
606
+ borrowShares
607
+ collateral
608
+ market {
609
+ uniqueKey
610
+ loanAsset { symbol address decimals }
611
+ collateralAsset { symbol address decimals }
612
+ }
613
+ }
614
+ }
615
+ }`;
616
+ const resp = await import_axios.default.post(MORPHO_API_URL, { query: posQuery }, { timeout: 15e3 });
617
+ const items = resp.data?.data?.marketPositions?.items ?? [];
618
+ for (const item of items) {
619
+ const supplyShares = BigInt(item.supplyShares ?? "0");
620
+ const borrowShares = BigInt(item.borrowShares ?? "0");
621
+ const collateral = BigInt(item.collateral ?? "0");
622
+ if (collateral === 0n && borrowShares === 0n && supplyShares === 0n) continue;
623
+ const m = item.market;
624
+ if (!m?.collateralAsset || !m?.loanAsset) continue;
583
625
  const loanDecimals = m.loanAsset.decimals;
584
626
  let debt = 0n;
585
- if (pos.borrowShares > 0n) {
627
+ if (borrowShares > 0n) {
586
628
  try {
587
629
  const mkt = await this.morphoBlue.market(m.uniqueKey);
588
630
  const totalBorrowShares = BigInt(mkt.totalBorrowShares);
589
631
  const totalBorrowAssets = BigInt(mkt.totalBorrowAssets);
590
- debt = totalBorrowShares > 0n ? (BigInt(pos.borrowShares) * totalBorrowAssets + totalBorrowShares - 1n) / totalBorrowShares : 0n;
632
+ debt = totalBorrowShares > 0n ? (borrowShares * totalBorrowAssets + totalBorrowShares - 1n) / totalBorrowShares : 0n;
591
633
  totalDebtFloat += parseFloat(import_ethers.ethers.formatUnits(debt, loanDecimals));
592
634
  } catch (e) {
593
635
  console.warn(`[agether] debt calc failed for market ${m.uniqueKey}:`, e instanceof Error ? e.message : e);
@@ -597,14 +639,46 @@ var init_MorphoClient = __esm({
597
639
  marketId: m.uniqueKey,
598
640
  collateralToken: m.collateralAsset.symbol,
599
641
  loanToken: m.loanAsset.symbol,
600
- collateral: import_ethers.ethers.formatUnits(pos.collateral, m.collateralAsset.decimals),
601
- borrowShares: pos.borrowShares.toString(),
602
- supplyShares: pos.supplyShares.toString(),
642
+ collateral: import_ethers.ethers.formatUnits(collateral, m.collateralAsset.decimals),
643
+ borrowShares: borrowShares.toString(),
644
+ supplyShares: supplyShares.toString(),
603
645
  debt: import_ethers.ethers.formatUnits(debt, loanDecimals)
604
646
  });
605
- } catch (e) {
606
- console.warn(`[agether] position read failed for market:`, e instanceof Error ? e.message : e);
607
- continue;
647
+ }
648
+ } catch (e) {
649
+ console.warn("[agether] marketPositions API failed, falling back to market scan:", e instanceof Error ? e.message : e);
650
+ const markets = await this.getMarkets();
651
+ for (const m of markets) {
652
+ if (!m.collateralAsset || m.collateralAsset.address === import_ethers.ethers.ZeroAddress) continue;
653
+ try {
654
+ const pos = await this.morphoBlue.position(m.uniqueKey, acctAddr);
655
+ if (pos.collateral === 0n && pos.borrowShares === 0n && pos.supplyShares === 0n) continue;
656
+ const loanDecimals = m.loanAsset.decimals;
657
+ let debt = 0n;
658
+ if (pos.borrowShares > 0n) {
659
+ try {
660
+ const mkt = await this.morphoBlue.market(m.uniqueKey);
661
+ const totalBorrowShares = BigInt(mkt.totalBorrowShares);
662
+ const totalBorrowAssets = BigInt(mkt.totalBorrowAssets);
663
+ debt = totalBorrowShares > 0n ? (BigInt(pos.borrowShares) * totalBorrowAssets + totalBorrowShares - 1n) / totalBorrowShares : 0n;
664
+ totalDebtFloat += parseFloat(import_ethers.ethers.formatUnits(debt, loanDecimals));
665
+ } catch (e2) {
666
+ console.warn(`[agether] debt calc failed:`, e2 instanceof Error ? e2.message : e2);
667
+ }
668
+ }
669
+ positions.push({
670
+ marketId: m.uniqueKey,
671
+ collateralToken: m.collateralAsset.symbol,
672
+ loanToken: m.loanAsset.symbol,
673
+ collateral: import_ethers.ethers.formatUnits(pos.collateral, m.collateralAsset.decimals),
674
+ borrowShares: pos.borrowShares.toString(),
675
+ supplyShares: pos.supplyShares.toString(),
676
+ debt: import_ethers.ethers.formatUnits(debt, loanDecimals)
677
+ });
678
+ } catch (e2) {
679
+ console.warn(`[agether] position read failed:`, e2 instanceof Error ? e2.message : e2);
680
+ continue;
681
+ }
608
682
  }
609
683
  }
610
684
  return {
@@ -1891,6 +1965,46 @@ var init_MorphoClient = __esm({
1891
1965
  /** Find the first market where the agent has collateral deposited. */
1892
1966
  async _findActiveMarket() {
1893
1967
  const acctAddr = await this.getAccountAddress();
1968
+ const chainId = this.config.chainId;
1969
+ try {
1970
+ const posQuery = `{
1971
+ marketPositions(
1972
+ where: { userAddress_in: ["${acctAddr}"], chainId_in: [${chainId}] }
1973
+ first: 50
1974
+ ) {
1975
+ items {
1976
+ collateral
1977
+ market {
1978
+ uniqueKey
1979
+ oracleAddress
1980
+ irmAddress
1981
+ lltv
1982
+ loanAsset { address symbol decimals }
1983
+ collateralAsset { address symbol decimals }
1984
+ }
1985
+ }
1986
+ }
1987
+ }`;
1988
+ const resp = await import_axios.default.post(MORPHO_API_URL, { query: posQuery }, { timeout: 1e4 });
1989
+ const items = resp.data?.data?.marketPositions?.items ?? [];
1990
+ for (const item of items) {
1991
+ if (BigInt(item.collateral ?? "0") > 0n && item.market?.collateralAsset) {
1992
+ const m = item.market;
1993
+ return {
1994
+ params: {
1995
+ loanToken: m.loanAsset.address,
1996
+ collateralToken: m.collateralAsset.address,
1997
+ oracle: m.oracleAddress,
1998
+ irm: m.irmAddress,
1999
+ lltv: BigInt(m.lltv)
2000
+ },
2001
+ symbol: m.collateralAsset.symbol
2002
+ };
2003
+ }
2004
+ }
2005
+ } catch (e) {
2006
+ console.warn("[agether] _findActiveMarket GraphQL failed, falling back:", e instanceof Error ? e.message : e);
2007
+ }
1894
2008
  const markets = await this.getMarkets();
1895
2009
  for (const m of markets) {
1896
2010
  if (!m.collateralAsset || m.collateralAsset.address === import_ethers.ethers.ZeroAddress) continue;
@@ -1919,6 +2033,46 @@ var init_MorphoClient = __esm({
1919
2033
  /** Find the first market where the agent has a supply (lending) position. */
1920
2034
  async _findActiveSupplyMarket() {
1921
2035
  const acctAddr = await this.getAccountAddress();
2036
+ const chainId = this.config.chainId;
2037
+ try {
2038
+ const posQuery = `{
2039
+ marketPositions(
2040
+ where: { userAddress_in: ["${acctAddr}"], chainId_in: [${chainId}] }
2041
+ first: 50
2042
+ ) {
2043
+ items {
2044
+ supplyShares
2045
+ market {
2046
+ uniqueKey
2047
+ oracleAddress
2048
+ irmAddress
2049
+ lltv
2050
+ loanAsset { address symbol decimals }
2051
+ collateralAsset { address symbol decimals }
2052
+ }
2053
+ }
2054
+ }
2055
+ }`;
2056
+ const resp = await import_axios.default.post(MORPHO_API_URL, { query: posQuery }, { timeout: 1e4 });
2057
+ const items = resp.data?.data?.marketPositions?.items ?? [];
2058
+ for (const item of items) {
2059
+ if (BigInt(item.supplyShares ?? "0") > 0n && item.market?.collateralAsset) {
2060
+ const m = item.market;
2061
+ return {
2062
+ params: {
2063
+ loanToken: m.loanAsset.address,
2064
+ collateralToken: m.collateralAsset.address,
2065
+ oracle: m.oracleAddress,
2066
+ irm: m.irmAddress,
2067
+ lltv: BigInt(m.lltv)
2068
+ },
2069
+ symbol: m.collateralAsset.symbol
2070
+ };
2071
+ }
2072
+ }
2073
+ } catch (e) {
2074
+ console.warn("[agether] _findActiveSupplyMarket GraphQL failed, falling back:", e instanceof Error ? e.message : e);
2075
+ }
1922
2076
  const markets = await this.getMarkets();
1923
2077
  for (const m of markets) {
1924
2078
  if (!m.collateralAsset || m.collateralAsset.address === import_ethers.ethers.ZeroAddress) continue;
package/dist/index.d.mts CHANGED
@@ -575,7 +575,10 @@ declare class MorphoClient {
575
575
  /** Read onchain position for a specific market. */
576
576
  getPosition(marketId: string): Promise<MorphoPosition>;
577
577
  /**
578
- * Full status: positions across all discovered markets.
578
+ * Full status: positions across all markets the user has interacted with.
579
+ *
580
+ * Uses Morpho GraphQL `marketPositions` to find ALL positions (not limited
581
+ * to the top-500 markets), then reads onchain data for accurate debt.
579
582
  */
580
583
  getStatus(): Promise<StatusResult>;
581
584
  /**
package/dist/index.d.ts CHANGED
@@ -575,7 +575,10 @@ declare class MorphoClient {
575
575
  /** Read onchain position for a specific market. */
576
576
  getPosition(marketId: string): Promise<MorphoPosition>;
577
577
  /**
578
- * Full status: positions across all discovered markets.
578
+ * Full status: positions across all markets the user has interacted with.
579
+ *
580
+ * Uses Morpho GraphQL `marketPositions` to find ALL positions (not limited
581
+ * to the top-500 markets), then reads onchain data for accurate debt.
579
582
  */
580
583
  getStatus(): Promise<StatusResult>;
581
584
  /**
package/dist/index.js CHANGED
@@ -1261,7 +1261,7 @@ var MorphoClient = class {
1261
1261
  const resolved = await this._resolveToken(loanTokenSymbolOrAddress);
1262
1262
  loanAddr = resolved.address.toLowerCase();
1263
1263
  } catch {
1264
- loanAddr = loanTokenSymbolOrAddress.toLowerCase();
1264
+ loanAddr = void 0;
1265
1265
  }
1266
1266
  }
1267
1267
  }
@@ -1269,6 +1269,7 @@ var MorphoClient = class {
1269
1269
  for (const m of this._discoveredMarkets ?? []) {
1270
1270
  if (m.collateralAsset.address.toLowerCase() !== colAddr) continue;
1271
1271
  if (loanAddr && m.loanAsset.address.toLowerCase() !== loanAddr) continue;
1272
+ if (!loanAddr && loanTokenSymbolOrAddress && m.loanAsset.symbol.toUpperCase() !== loanTokenSymbolOrAddress.toUpperCase()) continue;
1272
1273
  return {
1273
1274
  loanToken: m.loanAsset.address,
1274
1275
  collateralToken: m.collateralAsset.address,
@@ -1279,9 +1280,22 @@ var MorphoClient = class {
1279
1280
  }
1280
1281
  if (!collateralSymbolOrAddress.startsWith("0x")) {
1281
1282
  const searched = await this.searchMarkets(collateralSymbolOrAddress, { asCollateral: true });
1282
- for (const m of searched) {
1283
+ const allResults = [...searched];
1284
+ if (loanTokenSymbolOrAddress && !loanTokenSymbolOrAddress.startsWith("0x")) {
1285
+ const loanSearched = await this.searchMarkets(loanTokenSymbolOrAddress, { asLoanToken: true });
1286
+ const seen = new Set(allResults.map((r) => r.marketId));
1287
+ for (const m of loanSearched) {
1288
+ if (!seen.has(m.marketId)) allResults.push(m);
1289
+ }
1290
+ }
1291
+ for (const m of allResults) {
1292
+ if (colAddr.startsWith("0x") && m.collateralAddress.toLowerCase() !== colAddr) {
1293
+ if (m.collateralToken.toUpperCase() !== collateralSymbolOrAddress.toUpperCase()) continue;
1294
+ } else if (m.collateralToken.toUpperCase() !== collateralSymbolOrAddress.toUpperCase()) {
1295
+ continue;
1296
+ }
1283
1297
  if (loanAddr && m.loanAddress.toLowerCase() !== loanAddr) continue;
1284
- if (loanTokenSymbolOrAddress && !loanTokenSymbolOrAddress.startsWith("0x") && m.loanToken.toUpperCase() !== loanTokenSymbolOrAddress.toUpperCase()) continue;
1298
+ if (!loanAddr && loanTokenSymbolOrAddress && m.loanToken.toUpperCase() !== loanTokenSymbolOrAddress.toUpperCase()) continue;
1285
1299
  return this.getMarketParams(m.marketId);
1286
1300
  }
1287
1301
  }
@@ -1315,26 +1329,54 @@ var MorphoClient = class {
1315
1329
  };
1316
1330
  }
1317
1331
  /**
1318
- * Full status: positions across all discovered markets.
1332
+ * Full status: positions across all markets the user has interacted with.
1333
+ *
1334
+ * Uses Morpho GraphQL `marketPositions` to find ALL positions (not limited
1335
+ * to the top-500 markets), then reads onchain data for accurate debt.
1319
1336
  */
1320
1337
  async getStatus() {
1321
1338
  const acctAddr = await this.getAccountAddress();
1322
- const markets = await this.getMarkets();
1339
+ const chainId = this.config.chainId;
1323
1340
  const positions = [];
1324
1341
  let totalDebtFloat = 0;
1325
- for (const m of markets) {
1326
- if (!m.collateralAsset || m.collateralAsset.address === import_ethers2.ethers.ZeroAddress) continue;
1327
- try {
1328
- const pos = await this.morphoBlue.position(m.uniqueKey, acctAddr);
1329
- if (pos.collateral === 0n && pos.borrowShares === 0n && pos.supplyShares === 0n) continue;
1342
+ try {
1343
+ const posQuery = `{
1344
+ marketPositions(
1345
+ where: {
1346
+ userAddress_in: ["${acctAddr}"]
1347
+ chainId_in: [${chainId}]
1348
+ }
1349
+ first: 100
1350
+ ) {
1351
+ items {
1352
+ supplyShares
1353
+ borrowShares
1354
+ collateral
1355
+ market {
1356
+ uniqueKey
1357
+ loanAsset { symbol address decimals }
1358
+ collateralAsset { symbol address decimals }
1359
+ }
1360
+ }
1361
+ }
1362
+ }`;
1363
+ const resp = await import_axios.default.post(MORPHO_API_URL, { query: posQuery }, { timeout: 15e3 });
1364
+ const items = resp.data?.data?.marketPositions?.items ?? [];
1365
+ for (const item of items) {
1366
+ const supplyShares = BigInt(item.supplyShares ?? "0");
1367
+ const borrowShares = BigInt(item.borrowShares ?? "0");
1368
+ const collateral = BigInt(item.collateral ?? "0");
1369
+ if (collateral === 0n && borrowShares === 0n && supplyShares === 0n) continue;
1370
+ const m = item.market;
1371
+ if (!m?.collateralAsset || !m?.loanAsset) continue;
1330
1372
  const loanDecimals = m.loanAsset.decimals;
1331
1373
  let debt = 0n;
1332
- if (pos.borrowShares > 0n) {
1374
+ if (borrowShares > 0n) {
1333
1375
  try {
1334
1376
  const mkt = await this.morphoBlue.market(m.uniqueKey);
1335
1377
  const totalBorrowShares = BigInt(mkt.totalBorrowShares);
1336
1378
  const totalBorrowAssets = BigInt(mkt.totalBorrowAssets);
1337
- debt = totalBorrowShares > 0n ? (BigInt(pos.borrowShares) * totalBorrowAssets + totalBorrowShares - 1n) / totalBorrowShares : 0n;
1379
+ debt = totalBorrowShares > 0n ? (borrowShares * totalBorrowAssets + totalBorrowShares - 1n) / totalBorrowShares : 0n;
1338
1380
  totalDebtFloat += parseFloat(import_ethers2.ethers.formatUnits(debt, loanDecimals));
1339
1381
  } catch (e) {
1340
1382
  console.warn(`[agether] debt calc failed for market ${m.uniqueKey}:`, e instanceof Error ? e.message : e);
@@ -1344,14 +1386,46 @@ var MorphoClient = class {
1344
1386
  marketId: m.uniqueKey,
1345
1387
  collateralToken: m.collateralAsset.symbol,
1346
1388
  loanToken: m.loanAsset.symbol,
1347
- collateral: import_ethers2.ethers.formatUnits(pos.collateral, m.collateralAsset.decimals),
1348
- borrowShares: pos.borrowShares.toString(),
1349
- supplyShares: pos.supplyShares.toString(),
1389
+ collateral: import_ethers2.ethers.formatUnits(collateral, m.collateralAsset.decimals),
1390
+ borrowShares: borrowShares.toString(),
1391
+ supplyShares: supplyShares.toString(),
1350
1392
  debt: import_ethers2.ethers.formatUnits(debt, loanDecimals)
1351
1393
  });
1352
- } catch (e) {
1353
- console.warn(`[agether] position read failed for market:`, e instanceof Error ? e.message : e);
1354
- continue;
1394
+ }
1395
+ } catch (e) {
1396
+ console.warn("[agether] marketPositions API failed, falling back to market scan:", e instanceof Error ? e.message : e);
1397
+ const markets = await this.getMarkets();
1398
+ for (const m of markets) {
1399
+ if (!m.collateralAsset || m.collateralAsset.address === import_ethers2.ethers.ZeroAddress) continue;
1400
+ try {
1401
+ const pos = await this.morphoBlue.position(m.uniqueKey, acctAddr);
1402
+ if (pos.collateral === 0n && pos.borrowShares === 0n && pos.supplyShares === 0n) continue;
1403
+ const loanDecimals = m.loanAsset.decimals;
1404
+ let debt = 0n;
1405
+ if (pos.borrowShares > 0n) {
1406
+ try {
1407
+ const mkt = await this.morphoBlue.market(m.uniqueKey);
1408
+ const totalBorrowShares = BigInt(mkt.totalBorrowShares);
1409
+ const totalBorrowAssets = BigInt(mkt.totalBorrowAssets);
1410
+ debt = totalBorrowShares > 0n ? (BigInt(pos.borrowShares) * totalBorrowAssets + totalBorrowShares - 1n) / totalBorrowShares : 0n;
1411
+ totalDebtFloat += parseFloat(import_ethers2.ethers.formatUnits(debt, loanDecimals));
1412
+ } catch (e2) {
1413
+ console.warn(`[agether] debt calc failed:`, e2 instanceof Error ? e2.message : e2);
1414
+ }
1415
+ }
1416
+ positions.push({
1417
+ marketId: m.uniqueKey,
1418
+ collateralToken: m.collateralAsset.symbol,
1419
+ loanToken: m.loanAsset.symbol,
1420
+ collateral: import_ethers2.ethers.formatUnits(pos.collateral, m.collateralAsset.decimals),
1421
+ borrowShares: pos.borrowShares.toString(),
1422
+ supplyShares: pos.supplyShares.toString(),
1423
+ debt: import_ethers2.ethers.formatUnits(debt, loanDecimals)
1424
+ });
1425
+ } catch (e2) {
1426
+ console.warn(`[agether] position read failed:`, e2 instanceof Error ? e2.message : e2);
1427
+ continue;
1428
+ }
1355
1429
  }
1356
1430
  }
1357
1431
  return {
@@ -2638,6 +2712,46 @@ var MorphoClient = class {
2638
2712
  /** Find the first market where the agent has collateral deposited. */
2639
2713
  async _findActiveMarket() {
2640
2714
  const acctAddr = await this.getAccountAddress();
2715
+ const chainId = this.config.chainId;
2716
+ try {
2717
+ const posQuery = `{
2718
+ marketPositions(
2719
+ where: { userAddress_in: ["${acctAddr}"], chainId_in: [${chainId}] }
2720
+ first: 50
2721
+ ) {
2722
+ items {
2723
+ collateral
2724
+ market {
2725
+ uniqueKey
2726
+ oracleAddress
2727
+ irmAddress
2728
+ lltv
2729
+ loanAsset { address symbol decimals }
2730
+ collateralAsset { address symbol decimals }
2731
+ }
2732
+ }
2733
+ }
2734
+ }`;
2735
+ const resp = await import_axios.default.post(MORPHO_API_URL, { query: posQuery }, { timeout: 1e4 });
2736
+ const items = resp.data?.data?.marketPositions?.items ?? [];
2737
+ for (const item of items) {
2738
+ if (BigInt(item.collateral ?? "0") > 0n && item.market?.collateralAsset) {
2739
+ const m = item.market;
2740
+ return {
2741
+ params: {
2742
+ loanToken: m.loanAsset.address,
2743
+ collateralToken: m.collateralAsset.address,
2744
+ oracle: m.oracleAddress,
2745
+ irm: m.irmAddress,
2746
+ lltv: BigInt(m.lltv)
2747
+ },
2748
+ symbol: m.collateralAsset.symbol
2749
+ };
2750
+ }
2751
+ }
2752
+ } catch (e) {
2753
+ console.warn("[agether] _findActiveMarket GraphQL failed, falling back:", e instanceof Error ? e.message : e);
2754
+ }
2641
2755
  const markets = await this.getMarkets();
2642
2756
  for (const m of markets) {
2643
2757
  if (!m.collateralAsset || m.collateralAsset.address === import_ethers2.ethers.ZeroAddress) continue;
@@ -2666,6 +2780,46 @@ var MorphoClient = class {
2666
2780
  /** Find the first market where the agent has a supply (lending) position. */
2667
2781
  async _findActiveSupplyMarket() {
2668
2782
  const acctAddr = await this.getAccountAddress();
2783
+ const chainId = this.config.chainId;
2784
+ try {
2785
+ const posQuery = `{
2786
+ marketPositions(
2787
+ where: { userAddress_in: ["${acctAddr}"], chainId_in: [${chainId}] }
2788
+ first: 50
2789
+ ) {
2790
+ items {
2791
+ supplyShares
2792
+ market {
2793
+ uniqueKey
2794
+ oracleAddress
2795
+ irmAddress
2796
+ lltv
2797
+ loanAsset { address symbol decimals }
2798
+ collateralAsset { address symbol decimals }
2799
+ }
2800
+ }
2801
+ }
2802
+ }`;
2803
+ const resp = await import_axios.default.post(MORPHO_API_URL, { query: posQuery }, { timeout: 1e4 });
2804
+ const items = resp.data?.data?.marketPositions?.items ?? [];
2805
+ for (const item of items) {
2806
+ if (BigInt(item.supplyShares ?? "0") > 0n && item.market?.collateralAsset) {
2807
+ const m = item.market;
2808
+ return {
2809
+ params: {
2810
+ loanToken: m.loanAsset.address,
2811
+ collateralToken: m.collateralAsset.address,
2812
+ oracle: m.oracleAddress,
2813
+ irm: m.irmAddress,
2814
+ lltv: BigInt(m.lltv)
2815
+ },
2816
+ symbol: m.collateralAsset.symbol
2817
+ };
2818
+ }
2819
+ }
2820
+ } catch (e) {
2821
+ console.warn("[agether] _findActiveSupplyMarket GraphQL failed, falling back:", e instanceof Error ? e.message : e);
2822
+ }
2669
2823
  const markets = await this.getMarkets();
2670
2824
  for (const m of markets) {
2671
2825
  if (!m.collateralAsset || m.collateralAsset.address === import_ethers2.ethers.ZeroAddress) continue;
package/dist/index.mjs CHANGED
@@ -1186,7 +1186,7 @@ var MorphoClient = class {
1186
1186
  const resolved = await this._resolveToken(loanTokenSymbolOrAddress);
1187
1187
  loanAddr = resolved.address.toLowerCase();
1188
1188
  } catch {
1189
- loanAddr = loanTokenSymbolOrAddress.toLowerCase();
1189
+ loanAddr = void 0;
1190
1190
  }
1191
1191
  }
1192
1192
  }
@@ -1194,6 +1194,7 @@ var MorphoClient = class {
1194
1194
  for (const m of this._discoveredMarkets ?? []) {
1195
1195
  if (m.collateralAsset.address.toLowerCase() !== colAddr) continue;
1196
1196
  if (loanAddr && m.loanAsset.address.toLowerCase() !== loanAddr) continue;
1197
+ if (!loanAddr && loanTokenSymbolOrAddress && m.loanAsset.symbol.toUpperCase() !== loanTokenSymbolOrAddress.toUpperCase()) continue;
1197
1198
  return {
1198
1199
  loanToken: m.loanAsset.address,
1199
1200
  collateralToken: m.collateralAsset.address,
@@ -1204,9 +1205,22 @@ var MorphoClient = class {
1204
1205
  }
1205
1206
  if (!collateralSymbolOrAddress.startsWith("0x")) {
1206
1207
  const searched = await this.searchMarkets(collateralSymbolOrAddress, { asCollateral: true });
1207
- for (const m of searched) {
1208
+ const allResults = [...searched];
1209
+ if (loanTokenSymbolOrAddress && !loanTokenSymbolOrAddress.startsWith("0x")) {
1210
+ const loanSearched = await this.searchMarkets(loanTokenSymbolOrAddress, { asLoanToken: true });
1211
+ const seen = new Set(allResults.map((r) => r.marketId));
1212
+ for (const m of loanSearched) {
1213
+ if (!seen.has(m.marketId)) allResults.push(m);
1214
+ }
1215
+ }
1216
+ for (const m of allResults) {
1217
+ if (colAddr.startsWith("0x") && m.collateralAddress.toLowerCase() !== colAddr) {
1218
+ if (m.collateralToken.toUpperCase() !== collateralSymbolOrAddress.toUpperCase()) continue;
1219
+ } else if (m.collateralToken.toUpperCase() !== collateralSymbolOrAddress.toUpperCase()) {
1220
+ continue;
1221
+ }
1208
1222
  if (loanAddr && m.loanAddress.toLowerCase() !== loanAddr) continue;
1209
- if (loanTokenSymbolOrAddress && !loanTokenSymbolOrAddress.startsWith("0x") && m.loanToken.toUpperCase() !== loanTokenSymbolOrAddress.toUpperCase()) continue;
1223
+ if (!loanAddr && loanTokenSymbolOrAddress && m.loanToken.toUpperCase() !== loanTokenSymbolOrAddress.toUpperCase()) continue;
1210
1224
  return this.getMarketParams(m.marketId);
1211
1225
  }
1212
1226
  }
@@ -1240,26 +1254,54 @@ var MorphoClient = class {
1240
1254
  };
1241
1255
  }
1242
1256
  /**
1243
- * Full status: positions across all discovered markets.
1257
+ * Full status: positions across all markets the user has interacted with.
1258
+ *
1259
+ * Uses Morpho GraphQL `marketPositions` to find ALL positions (not limited
1260
+ * to the top-500 markets), then reads onchain data for accurate debt.
1244
1261
  */
1245
1262
  async getStatus() {
1246
1263
  const acctAddr = await this.getAccountAddress();
1247
- const markets = await this.getMarkets();
1264
+ const chainId = this.config.chainId;
1248
1265
  const positions = [];
1249
1266
  let totalDebtFloat = 0;
1250
- for (const m of markets) {
1251
- if (!m.collateralAsset || m.collateralAsset.address === ethers2.ZeroAddress) continue;
1252
- try {
1253
- const pos = await this.morphoBlue.position(m.uniqueKey, acctAddr);
1254
- if (pos.collateral === 0n && pos.borrowShares === 0n && pos.supplyShares === 0n) continue;
1267
+ try {
1268
+ const posQuery = `{
1269
+ marketPositions(
1270
+ where: {
1271
+ userAddress_in: ["${acctAddr}"]
1272
+ chainId_in: [${chainId}]
1273
+ }
1274
+ first: 100
1275
+ ) {
1276
+ items {
1277
+ supplyShares
1278
+ borrowShares
1279
+ collateral
1280
+ market {
1281
+ uniqueKey
1282
+ loanAsset { symbol address decimals }
1283
+ collateralAsset { symbol address decimals }
1284
+ }
1285
+ }
1286
+ }
1287
+ }`;
1288
+ const resp = await axios.post(MORPHO_API_URL, { query: posQuery }, { timeout: 15e3 });
1289
+ const items = resp.data?.data?.marketPositions?.items ?? [];
1290
+ for (const item of items) {
1291
+ const supplyShares = BigInt(item.supplyShares ?? "0");
1292
+ const borrowShares = BigInt(item.borrowShares ?? "0");
1293
+ const collateral = BigInt(item.collateral ?? "0");
1294
+ if (collateral === 0n && borrowShares === 0n && supplyShares === 0n) continue;
1295
+ const m = item.market;
1296
+ if (!m?.collateralAsset || !m?.loanAsset) continue;
1255
1297
  const loanDecimals = m.loanAsset.decimals;
1256
1298
  let debt = 0n;
1257
- if (pos.borrowShares > 0n) {
1299
+ if (borrowShares > 0n) {
1258
1300
  try {
1259
1301
  const mkt = await this.morphoBlue.market(m.uniqueKey);
1260
1302
  const totalBorrowShares = BigInt(mkt.totalBorrowShares);
1261
1303
  const totalBorrowAssets = BigInt(mkt.totalBorrowAssets);
1262
- debt = totalBorrowShares > 0n ? (BigInt(pos.borrowShares) * totalBorrowAssets + totalBorrowShares - 1n) / totalBorrowShares : 0n;
1304
+ debt = totalBorrowShares > 0n ? (borrowShares * totalBorrowAssets + totalBorrowShares - 1n) / totalBorrowShares : 0n;
1263
1305
  totalDebtFloat += parseFloat(ethers2.formatUnits(debt, loanDecimals));
1264
1306
  } catch (e) {
1265
1307
  console.warn(`[agether] debt calc failed for market ${m.uniqueKey}:`, e instanceof Error ? e.message : e);
@@ -1269,14 +1311,46 @@ var MorphoClient = class {
1269
1311
  marketId: m.uniqueKey,
1270
1312
  collateralToken: m.collateralAsset.symbol,
1271
1313
  loanToken: m.loanAsset.symbol,
1272
- collateral: ethers2.formatUnits(pos.collateral, m.collateralAsset.decimals),
1273
- borrowShares: pos.borrowShares.toString(),
1274
- supplyShares: pos.supplyShares.toString(),
1314
+ collateral: ethers2.formatUnits(collateral, m.collateralAsset.decimals),
1315
+ borrowShares: borrowShares.toString(),
1316
+ supplyShares: supplyShares.toString(),
1275
1317
  debt: ethers2.formatUnits(debt, loanDecimals)
1276
1318
  });
1277
- } catch (e) {
1278
- console.warn(`[agether] position read failed for market:`, e instanceof Error ? e.message : e);
1279
- continue;
1319
+ }
1320
+ } catch (e) {
1321
+ console.warn("[agether] marketPositions API failed, falling back to market scan:", e instanceof Error ? e.message : e);
1322
+ const markets = await this.getMarkets();
1323
+ for (const m of markets) {
1324
+ if (!m.collateralAsset || m.collateralAsset.address === ethers2.ZeroAddress) continue;
1325
+ try {
1326
+ const pos = await this.morphoBlue.position(m.uniqueKey, acctAddr);
1327
+ if (pos.collateral === 0n && pos.borrowShares === 0n && pos.supplyShares === 0n) continue;
1328
+ const loanDecimals = m.loanAsset.decimals;
1329
+ let debt = 0n;
1330
+ if (pos.borrowShares > 0n) {
1331
+ try {
1332
+ const mkt = await this.morphoBlue.market(m.uniqueKey);
1333
+ const totalBorrowShares = BigInt(mkt.totalBorrowShares);
1334
+ const totalBorrowAssets = BigInt(mkt.totalBorrowAssets);
1335
+ debt = totalBorrowShares > 0n ? (BigInt(pos.borrowShares) * totalBorrowAssets + totalBorrowShares - 1n) / totalBorrowShares : 0n;
1336
+ totalDebtFloat += parseFloat(ethers2.formatUnits(debt, loanDecimals));
1337
+ } catch (e2) {
1338
+ console.warn(`[agether] debt calc failed:`, e2 instanceof Error ? e2.message : e2);
1339
+ }
1340
+ }
1341
+ positions.push({
1342
+ marketId: m.uniqueKey,
1343
+ collateralToken: m.collateralAsset.symbol,
1344
+ loanToken: m.loanAsset.symbol,
1345
+ collateral: ethers2.formatUnits(pos.collateral, m.collateralAsset.decimals),
1346
+ borrowShares: pos.borrowShares.toString(),
1347
+ supplyShares: pos.supplyShares.toString(),
1348
+ debt: ethers2.formatUnits(debt, loanDecimals)
1349
+ });
1350
+ } catch (e2) {
1351
+ console.warn(`[agether] position read failed:`, e2 instanceof Error ? e2.message : e2);
1352
+ continue;
1353
+ }
1280
1354
  }
1281
1355
  }
1282
1356
  return {
@@ -2563,6 +2637,46 @@ var MorphoClient = class {
2563
2637
  /** Find the first market where the agent has collateral deposited. */
2564
2638
  async _findActiveMarket() {
2565
2639
  const acctAddr = await this.getAccountAddress();
2640
+ const chainId = this.config.chainId;
2641
+ try {
2642
+ const posQuery = `{
2643
+ marketPositions(
2644
+ where: { userAddress_in: ["${acctAddr}"], chainId_in: [${chainId}] }
2645
+ first: 50
2646
+ ) {
2647
+ items {
2648
+ collateral
2649
+ market {
2650
+ uniqueKey
2651
+ oracleAddress
2652
+ irmAddress
2653
+ lltv
2654
+ loanAsset { address symbol decimals }
2655
+ collateralAsset { address symbol decimals }
2656
+ }
2657
+ }
2658
+ }
2659
+ }`;
2660
+ const resp = await axios.post(MORPHO_API_URL, { query: posQuery }, { timeout: 1e4 });
2661
+ const items = resp.data?.data?.marketPositions?.items ?? [];
2662
+ for (const item of items) {
2663
+ if (BigInt(item.collateral ?? "0") > 0n && item.market?.collateralAsset) {
2664
+ const m = item.market;
2665
+ return {
2666
+ params: {
2667
+ loanToken: m.loanAsset.address,
2668
+ collateralToken: m.collateralAsset.address,
2669
+ oracle: m.oracleAddress,
2670
+ irm: m.irmAddress,
2671
+ lltv: BigInt(m.lltv)
2672
+ },
2673
+ symbol: m.collateralAsset.symbol
2674
+ };
2675
+ }
2676
+ }
2677
+ } catch (e) {
2678
+ console.warn("[agether] _findActiveMarket GraphQL failed, falling back:", e instanceof Error ? e.message : e);
2679
+ }
2566
2680
  const markets = await this.getMarkets();
2567
2681
  for (const m of markets) {
2568
2682
  if (!m.collateralAsset || m.collateralAsset.address === ethers2.ZeroAddress) continue;
@@ -2591,6 +2705,46 @@ var MorphoClient = class {
2591
2705
  /** Find the first market where the agent has a supply (lending) position. */
2592
2706
  async _findActiveSupplyMarket() {
2593
2707
  const acctAddr = await this.getAccountAddress();
2708
+ const chainId = this.config.chainId;
2709
+ try {
2710
+ const posQuery = `{
2711
+ marketPositions(
2712
+ where: { userAddress_in: ["${acctAddr}"], chainId_in: [${chainId}] }
2713
+ first: 50
2714
+ ) {
2715
+ items {
2716
+ supplyShares
2717
+ market {
2718
+ uniqueKey
2719
+ oracleAddress
2720
+ irmAddress
2721
+ lltv
2722
+ loanAsset { address symbol decimals }
2723
+ collateralAsset { address symbol decimals }
2724
+ }
2725
+ }
2726
+ }
2727
+ }`;
2728
+ const resp = await axios.post(MORPHO_API_URL, { query: posQuery }, { timeout: 1e4 });
2729
+ const items = resp.data?.data?.marketPositions?.items ?? [];
2730
+ for (const item of items) {
2731
+ if (BigInt(item.supplyShares ?? "0") > 0n && item.market?.collateralAsset) {
2732
+ const m = item.market;
2733
+ return {
2734
+ params: {
2735
+ loanToken: m.loanAsset.address,
2736
+ collateralToken: m.collateralAsset.address,
2737
+ oracle: m.oracleAddress,
2738
+ irm: m.irmAddress,
2739
+ lltv: BigInt(m.lltv)
2740
+ },
2741
+ symbol: m.collateralAsset.symbol
2742
+ };
2743
+ }
2744
+ }
2745
+ } catch (e) {
2746
+ console.warn("[agether] _findActiveSupplyMarket GraphQL failed, falling back:", e instanceof Error ? e.message : e);
2747
+ }
2594
2748
  const markets = await this.getMarkets();
2595
2749
  for (const m of markets) {
2596
2750
  if (!m.collateralAsset || m.collateralAsset.address === ethers2.ZeroAddress) continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agether/sdk",
3
- "version": "2.14.0",
3
+ "version": "2.14.1",
4
4
  "description": "TypeScript SDK for Agether - autonomous credit for AI agents on Ethereum & Base",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",