@peridot-agent/agent-kit 0.2.0 → 0.2.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/README.md +61 -1
- package/dist/adapters/langchain/index.cjs +228 -115
- package/dist/adapters/langchain/index.cjs.map +1 -1
- package/dist/adapters/langchain/index.d.cts +1 -1
- package/dist/adapters/langchain/index.d.ts +1 -1
- package/dist/adapters/langchain/index.js +196 -83
- package/dist/adapters/langchain/index.js.map +1 -1
- package/dist/adapters/mcp/server.cjs +228 -115
- package/dist/adapters/mcp/server.cjs.map +1 -1
- package/dist/adapters/mcp/server.js +196 -83
- package/dist/adapters/mcp/server.js.map +1 -1
- package/dist/adapters/vercel-ai/index.cjs +228 -115
- package/dist/adapters/vercel-ai/index.cjs.map +1 -1
- package/dist/adapters/vercel-ai/index.d.cts +1 -1
- package/dist/adapters/vercel-ai/index.d.ts +1 -1
- package/dist/adapters/vercel-ai/index.js +196 -83
- package/dist/adapters/vercel-ai/index.js.map +1 -1
- package/dist/index.cjs +228 -115
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +196 -83
- package/dist/index.js.map +1 -1
- package/dist/{types-Cg95um6s.d.cts → types-BP04EsT6.d.cts} +1 -8
- package/dist/{types-Cg95um6s.d.ts → types-BP04EsT6.d.ts} +1 -8
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as ToolDefinition, P as PeridotConfig, L as LiquidatablePositions, C as ComposeRequest, B as BiconomyResponse, a as TransactionStatus, M as MarketSummary, b as LeaderboardEntry, c as MarketRates, U as UserPosition, S as SimulateBorrowResult, A as AccountLiquidity, H as HubTransactionIntent, d as CrossChainIntent } from './types-
|
|
2
|
-
export { e as ComposeFlow, f as ToolCategory, g as TransactionCall, h as TransactionIntent } from './types-
|
|
1
|
+
import { T as ToolDefinition, P as PeridotConfig, L as LiquidatablePositions, C as ComposeRequest, B as BiconomyResponse, a as TransactionStatus, M as MarketSummary, b as LeaderboardEntry, c as MarketRates, U as UserPosition, S as SimulateBorrowResult, A as AccountLiquidity, H as HubTransactionIntent, d as CrossChainIntent } from './types-BP04EsT6.cjs';
|
|
2
|
+
export { e as ComposeFlow, f as ToolCategory, g as TransactionCall, h as TransactionIntent } from './types-BP04EsT6.cjs';
|
|
3
3
|
import { Address } from 'viem';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
|
|
@@ -517,10 +517,13 @@ declare function getMarketRates(input: GetMarketRatesInput, config: PeridotConfi
|
|
|
517
517
|
|
|
518
518
|
declare const getUserPositionSchema: z.ZodObject<{
|
|
519
519
|
address: z.ZodString;
|
|
520
|
+
chainId: z.ZodEffects<z.ZodDefault<z.ZodNumber>, number, number | undefined>;
|
|
520
521
|
}, "strip", z.ZodTypeAny, {
|
|
522
|
+
chainId: number;
|
|
521
523
|
address: string;
|
|
522
524
|
}, {
|
|
523
525
|
address: string;
|
|
526
|
+
chainId?: number | undefined;
|
|
524
527
|
}>;
|
|
525
528
|
type GetUserPositionInput = z.infer<typeof getUserPositionSchema>;
|
|
526
529
|
declare function getUserPosition(input: GetUserPositionInput, config: PeridotConfig): Promise<UserPosition>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as ToolDefinition, P as PeridotConfig, L as LiquidatablePositions, C as ComposeRequest, B as BiconomyResponse, a as TransactionStatus, M as MarketSummary, b as LeaderboardEntry, c as MarketRates, U as UserPosition, S as SimulateBorrowResult, A as AccountLiquidity, H as HubTransactionIntent, d as CrossChainIntent } from './types-
|
|
2
|
-
export { e as ComposeFlow, f as ToolCategory, g as TransactionCall, h as TransactionIntent } from './types-
|
|
1
|
+
import { T as ToolDefinition, P as PeridotConfig, L as LiquidatablePositions, C as ComposeRequest, B as BiconomyResponse, a as TransactionStatus, M as MarketSummary, b as LeaderboardEntry, c as MarketRates, U as UserPosition, S as SimulateBorrowResult, A as AccountLiquidity, H as HubTransactionIntent, d as CrossChainIntent } from './types-BP04EsT6.js';
|
|
2
|
+
export { e as ComposeFlow, f as ToolCategory, g as TransactionCall, h as TransactionIntent } from './types-BP04EsT6.js';
|
|
3
3
|
import { Address } from 'viem';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
|
|
@@ -517,10 +517,13 @@ declare function getMarketRates(input: GetMarketRatesInput, config: PeridotConfi
|
|
|
517
517
|
|
|
518
518
|
declare const getUserPositionSchema: z.ZodObject<{
|
|
519
519
|
address: z.ZodString;
|
|
520
|
+
chainId: z.ZodEffects<z.ZodDefault<z.ZodNumber>, number, number | undefined>;
|
|
520
521
|
}, "strip", z.ZodTypeAny, {
|
|
522
|
+
chainId: number;
|
|
521
523
|
address: string;
|
|
522
524
|
}, {
|
|
523
525
|
address: string;
|
|
526
|
+
chainId?: number | undefined;
|
|
524
527
|
}>;
|
|
525
528
|
type GetUserPositionInput = z.infer<typeof getUserPositionSchema>;
|
|
526
529
|
declare function getUserPosition(input: GetUserPositionInput, config: PeridotConfig): Promise<UserPosition>;
|
package/dist/index.js
CHANGED
|
@@ -409,6 +409,121 @@ async function listMarkets(input, config) {
|
|
|
409
409
|
|
|
410
410
|
// src/features/lending/read/get-portfolio.ts
|
|
411
411
|
import { z as z3 } from "zod";
|
|
412
|
+
init_constants();
|
|
413
|
+
|
|
414
|
+
// src/shared/on-chain-position.ts
|
|
415
|
+
import Decimal from "decimal.js";
|
|
416
|
+
import { createPublicClient, http } from "viem";
|
|
417
|
+
|
|
418
|
+
// src/shared/abis.ts
|
|
419
|
+
import { parseAbi } from "viem";
|
|
420
|
+
var PTOKEN_ABI = parseAbi([
|
|
421
|
+
"function mint(uint256 mintAmount) returns (uint256)",
|
|
422
|
+
"function redeem(uint256 redeemTokens) returns (uint256)",
|
|
423
|
+
"function redeemUnderlying(uint256 redeemAmount) returns (uint256)",
|
|
424
|
+
"function borrow(uint256 borrowAmount) returns (uint256)",
|
|
425
|
+
"function repayBorrow(uint256 repayAmount) returns (uint256)",
|
|
426
|
+
"function repayBorrowBehalf(address borrower, uint256 repayAmount) returns (uint256)",
|
|
427
|
+
"function liquidateBorrow(address borrower, uint256 repayAmount, address pTokenCollateral) returns (uint256)",
|
|
428
|
+
"function balanceOf(address owner) view returns (uint256)",
|
|
429
|
+
"function borrowBalanceStored(address account) view returns (uint256)",
|
|
430
|
+
"function supplyRatePerBlock() view returns (uint256)",
|
|
431
|
+
"function borrowRatePerBlock() view returns (uint256)",
|
|
432
|
+
"function exchangeRateStored() view returns (uint256)",
|
|
433
|
+
"function underlying() view returns (address)"
|
|
434
|
+
]);
|
|
435
|
+
var COMPTROLLER_ABI = parseAbi([
|
|
436
|
+
"function enterMarkets(address[] calldata pTokens) returns (uint256[] memory)",
|
|
437
|
+
"function exitMarket(address pTokenAddress) returns (uint256)",
|
|
438
|
+
"function getAccountLiquidity(address account) view returns (uint256 errorCode, uint256 liquidity, uint256 shortfall)",
|
|
439
|
+
"function getAllMarkets() view returns (address[] memory)",
|
|
440
|
+
"function markets(address pToken) view returns (bool isListed, uint256 collateralFactorMantissa, bool isComped)",
|
|
441
|
+
"function checkMembership(address account, address pToken) view returns (bool)"
|
|
442
|
+
]);
|
|
443
|
+
var ERC20_ABI = parseAbi([
|
|
444
|
+
"function approve(address spender, uint256 amount) returns (bool)",
|
|
445
|
+
"function allowance(address owner, address spender) view returns (uint256)",
|
|
446
|
+
"function balanceOf(address owner) view returns (uint256)",
|
|
447
|
+
"function transfer(address to, uint256 amount) returns (bool)"
|
|
448
|
+
]);
|
|
449
|
+
|
|
450
|
+
// src/shared/on-chain-position.ts
|
|
451
|
+
init_constants();
|
|
452
|
+
async function readOnChainPosition(address, chainId, config) {
|
|
453
|
+
const markets = PERIDOT_MARKETS[chainId];
|
|
454
|
+
if (!markets) {
|
|
455
|
+
throw new Error(`No markets configured for chain ${chainId}`);
|
|
456
|
+
}
|
|
457
|
+
const marketEntries = Object.entries(markets).filter(
|
|
458
|
+
(entry) => entry[1] !== void 0
|
|
459
|
+
);
|
|
460
|
+
if (marketEntries.length === 0) {
|
|
461
|
+
return { totalSuppliedUsd: 0, totalBorrowedUsd: 0, assets: [] };
|
|
462
|
+
}
|
|
463
|
+
const rpcUrl = config.rpcUrls?.[chainId] ?? DEFAULT_RPC_URLS[chainId];
|
|
464
|
+
if (!rpcUrl) {
|
|
465
|
+
throw new Error(
|
|
466
|
+
`No RPC URL available for chain ${chainId}. Provide one via config.rpcUrls[${chainId}].`
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
const viemClient = createPublicClient({ transport: http(rpcUrl) });
|
|
470
|
+
const apiClient = new PeridotApiClient(config);
|
|
471
|
+
const [metricsData, multicallResults] = await Promise.all([
|
|
472
|
+
apiClient.getMarketMetrics(),
|
|
473
|
+
viemClient.multicall({
|
|
474
|
+
contracts: marketEntries.flatMap(([, pTokenAddress]) => [
|
|
475
|
+
{
|
|
476
|
+
address: pTokenAddress,
|
|
477
|
+
abi: PTOKEN_ABI,
|
|
478
|
+
functionName: "balanceOf",
|
|
479
|
+
args: [address]
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
address: pTokenAddress,
|
|
483
|
+
abi: PTOKEN_ABI,
|
|
484
|
+
functionName: "exchangeRateStored"
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
address: pTokenAddress,
|
|
488
|
+
abi: PTOKEN_ABI,
|
|
489
|
+
functionName: "borrowBalanceStored",
|
|
490
|
+
args: [address]
|
|
491
|
+
}
|
|
492
|
+
]),
|
|
493
|
+
allowFailure: true
|
|
494
|
+
})
|
|
495
|
+
]);
|
|
496
|
+
const assets = [];
|
|
497
|
+
let totalSuppliedUsd = 0;
|
|
498
|
+
let totalBorrowedUsd = 0;
|
|
499
|
+
for (let i = 0; i < marketEntries.length; i++) {
|
|
500
|
+
const entry = marketEntries[i];
|
|
501
|
+
if (!entry) continue;
|
|
502
|
+
const [symbol] = entry;
|
|
503
|
+
const base = i * 3;
|
|
504
|
+
const balanceResult = multicallResults[base];
|
|
505
|
+
const exchangeRateResult = multicallResults[base + 1];
|
|
506
|
+
const borrowResult = multicallResults[base + 2];
|
|
507
|
+
if (!balanceResult || !exchangeRateResult || !borrowResult || balanceResult.status === "failure" || exchangeRateResult.status === "failure" || borrowResult.status === "failure") {
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
const cTokenBalance = balanceResult.result;
|
|
511
|
+
const exchangeRate = exchangeRateResult.result;
|
|
512
|
+
const borrowBalance = borrowResult.result;
|
|
513
|
+
const underlyingDecimals = ASSET_DECIMALS[symbol] ?? 18;
|
|
514
|
+
const priceUsd = metricsData[`${symbol}:${chainId}`]?.priceUsd ?? 0;
|
|
515
|
+
const suppliedTokens = new Decimal(cTokenBalance.toString()).mul(exchangeRate.toString()).div("1e18").div(new Decimal(10).pow(underlyingDecimals)).toNumber();
|
|
516
|
+
const borrowedTokens = new Decimal(borrowBalance.toString()).div(new Decimal(10).pow(underlyingDecimals)).toNumber();
|
|
517
|
+
const suppliedUsd = suppliedTokens * priceUsd;
|
|
518
|
+
const borrowedUsd = borrowedTokens * priceUsd;
|
|
519
|
+
if (suppliedUsd > 1e-3 || borrowedUsd > 1e-3) {
|
|
520
|
+
assets.push({ assetId: symbol, suppliedUsd, borrowedUsd, suppliedTokens, borrowedTokens, priceUsd });
|
|
521
|
+
totalSuppliedUsd += suppliedUsd;
|
|
522
|
+
totalBorrowedUsd += borrowedUsd;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
return { totalSuppliedUsd, totalBorrowedUsd, assets };
|
|
526
|
+
}
|
|
412
527
|
|
|
413
528
|
// src/shared/zod-utils.ts
|
|
414
529
|
import { z as z2 } from "zod";
|
|
@@ -464,26 +579,47 @@ var Cache = class {
|
|
|
464
579
|
// src/features/lending/read/get-portfolio.ts
|
|
465
580
|
var portfolioCache = new Cache(3e4);
|
|
466
581
|
var getPortfolioSchema = z3.object({
|
|
467
|
-
address: evmAddress.describe("The wallet address (0x...) to look up")
|
|
582
|
+
address: evmAddress.describe("The wallet address (0x...) to look up"),
|
|
583
|
+
chainId: z3.number().int().default(BSC_MAINNET_CHAIN_ID).refine(isHubChain, { message: "chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia)." }).describe("Hub chain ID to query. Defaults to BSC (56).")
|
|
468
584
|
});
|
|
469
585
|
async function getPortfolio(input, config) {
|
|
470
|
-
const key = input.address.toLowerCase()
|
|
586
|
+
const key = `${input.address.toLowerCase()}:${input.chainId}`;
|
|
471
587
|
return portfolioCache.getOrFetch(key, async () => {
|
|
472
|
-
const
|
|
473
|
-
const
|
|
588
|
+
const apiClient = new PeridotApiClient(config);
|
|
589
|
+
const [position, apyData] = await Promise.all([
|
|
590
|
+
readOnChainPosition(input.address, input.chainId, config),
|
|
591
|
+
apiClient.getMarketApy(input.chainId)
|
|
592
|
+
]);
|
|
593
|
+
const { totalSuppliedUsd, totalBorrowedUsd, assets } = position;
|
|
594
|
+
let netApy = 0;
|
|
595
|
+
if (totalSuppliedUsd > 0) {
|
|
596
|
+
let weighted = 0;
|
|
597
|
+
for (const asset of assets) {
|
|
598
|
+
const apyEntry = apyData[asset.assetId.toLowerCase()]?.[input.chainId];
|
|
599
|
+
if (apyEntry) {
|
|
600
|
+
weighted += asset.suppliedUsd * (apyEntry.totalSupplyApy ?? 0);
|
|
601
|
+
weighted -= asset.borrowedUsd * (apyEntry.netBorrowApy ?? 0);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
netApy = weighted / totalSuppliedUsd;
|
|
605
|
+
}
|
|
474
606
|
return {
|
|
475
607
|
address: input.address,
|
|
476
608
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
477
609
|
portfolio: {
|
|
478
|
-
currentValue:
|
|
479
|
-
totalSupplied:
|
|
480
|
-
totalBorrowed:
|
|
481
|
-
netApy
|
|
482
|
-
healthFactor:
|
|
610
|
+
currentValue: totalSuppliedUsd - totalBorrowedUsd,
|
|
611
|
+
totalSupplied: totalSuppliedUsd,
|
|
612
|
+
totalBorrowed: totalBorrowedUsd,
|
|
613
|
+
netApy,
|
|
614
|
+
healthFactor: totalBorrowedUsd > 0 ? totalSuppliedUsd / totalBorrowedUsd : null
|
|
483
615
|
},
|
|
484
|
-
assets:
|
|
485
|
-
|
|
486
|
-
|
|
616
|
+
assets: assets.map((a) => ({
|
|
617
|
+
assetId: a.assetId,
|
|
618
|
+
supplied: a.suppliedUsd,
|
|
619
|
+
borrowed: a.borrowedUsd,
|
|
620
|
+
net: a.suppliedUsd - a.borrowedUsd,
|
|
621
|
+
percentage: totalSuppliedUsd > 0 ? (a.suppliedUsd - a.borrowedUsd) / totalSuppliedUsd * 100 : 0
|
|
622
|
+
}))
|
|
487
623
|
};
|
|
488
624
|
});
|
|
489
625
|
}
|
|
@@ -565,39 +701,50 @@ async function getMarketRates(input, config) {
|
|
|
565
701
|
|
|
566
702
|
// src/features/lending/read/get-user-position.ts
|
|
567
703
|
import { z as z6 } from "zod";
|
|
704
|
+
init_constants();
|
|
568
705
|
var getUserPositionSchema = z6.object({
|
|
569
|
-
address: evmAddress.describe("The wallet address (0x...) to look up")
|
|
706
|
+
address: evmAddress.describe("The wallet address (0x...) to look up"),
|
|
707
|
+
chainId: z6.number().int().default(BSC_MAINNET_CHAIN_ID).refine(isHubChain, { message: "chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia)." }).describe("Hub chain ID to query. Defaults to BSC (56).")
|
|
570
708
|
});
|
|
571
709
|
async function getUserPosition(input, config) {
|
|
572
|
-
const
|
|
573
|
-
const
|
|
574
|
-
|
|
575
|
-
|
|
710
|
+
const apiClient = new PeridotApiClient(config);
|
|
711
|
+
const [position, apyData] = await Promise.all([
|
|
712
|
+
readOnChainPosition(input.address, input.chainId, config),
|
|
713
|
+
apiClient.getMarketApy(input.chainId)
|
|
714
|
+
]);
|
|
715
|
+
const { totalSuppliedUsd, totalBorrowedUsd, assets } = position;
|
|
716
|
+
const healthFactor = totalBorrowedUsd > 0 ? totalSuppliedUsd / totalBorrowedUsd : null;
|
|
717
|
+
let netApyPct = 0;
|
|
718
|
+
if (totalSuppliedUsd > 0) {
|
|
719
|
+
let weightedApy = 0;
|
|
720
|
+
for (const asset of assets) {
|
|
721
|
+
const apyEntry = apyData[asset.assetId.toLowerCase()]?.[input.chainId];
|
|
722
|
+
if (apyEntry) {
|
|
723
|
+
weightedApy += asset.suppliedUsd * (apyEntry.totalSupplyApy ?? 0);
|
|
724
|
+
weightedApy -= asset.borrowedUsd * (apyEntry.netBorrowApy ?? 0);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
netApyPct = weightedApy / totalSuppliedUsd;
|
|
728
|
+
}
|
|
576
729
|
return {
|
|
577
730
|
address: input.address,
|
|
578
|
-
totalSuppliedUsd
|
|
579
|
-
totalBorrowedUsd
|
|
580
|
-
netWorthUsd:
|
|
581
|
-
netApyPct
|
|
731
|
+
totalSuppliedUsd,
|
|
732
|
+
totalBorrowedUsd,
|
|
733
|
+
netWorthUsd: totalSuppliedUsd - totalBorrowedUsd,
|
|
734
|
+
netApyPct,
|
|
582
735
|
healthFactor,
|
|
583
736
|
assets: assets.map((a) => ({
|
|
584
737
|
assetId: a.assetId,
|
|
585
|
-
suppliedUsd: a.
|
|
586
|
-
borrowedUsd: a.
|
|
587
|
-
netUsd: a.
|
|
738
|
+
suppliedUsd: a.suppliedUsd,
|
|
739
|
+
borrowedUsd: a.borrowedUsd,
|
|
740
|
+
netUsd: a.suppliedUsd - a.borrowedUsd
|
|
588
741
|
})),
|
|
589
|
-
transactions: {
|
|
590
|
-
supplyCount: transactions.supplyCount,
|
|
591
|
-
borrowCount: transactions.borrowCount,
|
|
592
|
-
repayCount: transactions.repayCount,
|
|
593
|
-
redeemCount: transactions.redeemCount
|
|
594
|
-
},
|
|
595
742
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
596
743
|
};
|
|
597
744
|
}
|
|
598
745
|
|
|
599
746
|
// src/features/lending/read/simulate-borrow.ts
|
|
600
|
-
import
|
|
747
|
+
import Decimal2 from "decimal.js";
|
|
601
748
|
import { z as z7 } from "zod";
|
|
602
749
|
init_constants();
|
|
603
750
|
var simulateBorrowSchema = z7.object({
|
|
@@ -620,10 +767,10 @@ function classifyRisk(hf) {
|
|
|
620
767
|
return "liquidatable";
|
|
621
768
|
}
|
|
622
769
|
async function simulateBorrow(input, config) {
|
|
623
|
-
const
|
|
624
|
-
const [
|
|
625
|
-
|
|
626
|
-
|
|
770
|
+
const apiClient = new PeridotApiClient(config);
|
|
771
|
+
const [position, metricsData] = await Promise.all([
|
|
772
|
+
readOnChainPosition(input.address, input.chainId, config),
|
|
773
|
+
apiClient.getMarketMetrics()
|
|
627
774
|
]);
|
|
628
775
|
const assetUpper = input.asset.toUpperCase();
|
|
629
776
|
const metricKey = `${assetUpper}:${input.chainId}`;
|
|
@@ -635,12 +782,11 @@ async function simulateBorrow(input, config) {
|
|
|
635
782
|
if (isNaN(borrowAmountRaw) || borrowAmountRaw <= 0) {
|
|
636
783
|
throw new Error(`Invalid borrow amount: "${input.amount}"`);
|
|
637
784
|
}
|
|
638
|
-
const borrowAmount = new
|
|
785
|
+
const borrowAmount = new Decimal2(input.amount);
|
|
639
786
|
const borrowAmountUsd = borrowAmount.mul(metric.priceUsd).toNumber();
|
|
640
|
-
const {
|
|
641
|
-
const currentHF =
|
|
642
|
-
|
|
643
|
-
if (totalSupplied === 0) {
|
|
787
|
+
const { totalSuppliedUsd, totalBorrowedUsd } = position;
|
|
788
|
+
const currentHF = totalBorrowedUsd > 0 ? new Decimal2(totalSuppliedUsd).div(totalBorrowedUsd).toNumber() : null;
|
|
789
|
+
if (totalSuppliedUsd === 0) {
|
|
644
790
|
return {
|
|
645
791
|
currentHealthFactor: null,
|
|
646
792
|
projectedHealthFactor: null,
|
|
@@ -648,13 +794,14 @@ async function simulateBorrow(input, config) {
|
|
|
648
794
|
isSafe: false,
|
|
649
795
|
riskLevel: "liquidatable",
|
|
650
796
|
maxSafeBorrowUsd: 0,
|
|
651
|
-
warning: "
|
|
797
|
+
warning: "No supplied collateral found on-chain for this address. Supply assets and enable them as collateral before borrowing."
|
|
652
798
|
};
|
|
653
799
|
}
|
|
654
|
-
const
|
|
655
|
-
const
|
|
800
|
+
const projectedBorrowedUsd = new Decimal2(totalBorrowedUsd).add(borrowAmountUsd);
|
|
801
|
+
const projectedHF = new Decimal2(totalSuppliedUsd).div(projectedBorrowedUsd).toNumber();
|
|
802
|
+
const maxSafeBorrowUsd = Decimal2.max(
|
|
656
803
|
0,
|
|
657
|
-
new
|
|
804
|
+
new Decimal2(totalSuppliedUsd).div(RISK_THRESHOLDS.safe).sub(totalBorrowedUsd)
|
|
658
805
|
).toNumber();
|
|
659
806
|
const riskLevel = classifyRisk(projectedHF);
|
|
660
807
|
const isSafe = projectedHF >= RISK_THRESHOLDS.high;
|
|
@@ -678,43 +825,9 @@ async function simulateBorrow(input, config) {
|
|
|
678
825
|
}
|
|
679
826
|
|
|
680
827
|
// src/features/lending/read/get-account-liquidity.ts
|
|
681
|
-
import
|
|
828
|
+
import Decimal3 from "decimal.js";
|
|
682
829
|
import { z as z8 } from "zod";
|
|
683
|
-
import { createPublicClient, http } from "viem";
|
|
684
|
-
|
|
685
|
-
// src/shared/abis.ts
|
|
686
|
-
import { parseAbi } from "viem";
|
|
687
|
-
var PTOKEN_ABI = parseAbi([
|
|
688
|
-
"function mint(uint256 mintAmount) returns (uint256)",
|
|
689
|
-
"function redeem(uint256 redeemTokens) returns (uint256)",
|
|
690
|
-
"function redeemUnderlying(uint256 redeemAmount) returns (uint256)",
|
|
691
|
-
"function borrow(uint256 borrowAmount) returns (uint256)",
|
|
692
|
-
"function repayBorrow(uint256 repayAmount) returns (uint256)",
|
|
693
|
-
"function repayBorrowBehalf(address borrower, uint256 repayAmount) returns (uint256)",
|
|
694
|
-
"function liquidateBorrow(address borrower, uint256 repayAmount, address pTokenCollateral) returns (uint256)",
|
|
695
|
-
"function balanceOf(address owner) view returns (uint256)",
|
|
696
|
-
"function borrowBalanceStored(address account) view returns (uint256)",
|
|
697
|
-
"function supplyRatePerBlock() view returns (uint256)",
|
|
698
|
-
"function borrowRatePerBlock() view returns (uint256)",
|
|
699
|
-
"function exchangeRateStored() view returns (uint256)",
|
|
700
|
-
"function underlying() view returns (address)"
|
|
701
|
-
]);
|
|
702
|
-
var COMPTROLLER_ABI = parseAbi([
|
|
703
|
-
"function enterMarkets(address[] calldata pTokens) returns (uint256[] memory)",
|
|
704
|
-
"function exitMarket(address pTokenAddress) returns (uint256)",
|
|
705
|
-
"function getAccountLiquidity(address account) view returns (uint256 errorCode, uint256 liquidity, uint256 shortfall)",
|
|
706
|
-
"function getAllMarkets() view returns (address[] memory)",
|
|
707
|
-
"function markets(address pToken) view returns (bool isListed, uint256 collateralFactorMantissa, bool isComped)",
|
|
708
|
-
"function checkMembership(address account, address pToken) view returns (bool)"
|
|
709
|
-
]);
|
|
710
|
-
var ERC20_ABI = parseAbi([
|
|
711
|
-
"function approve(address spender, uint256 amount) returns (bool)",
|
|
712
|
-
"function allowance(address owner, address spender) view returns (uint256)",
|
|
713
|
-
"function balanceOf(address owner) view returns (uint256)",
|
|
714
|
-
"function transfer(address to, uint256 amount) returns (bool)"
|
|
715
|
-
]);
|
|
716
|
-
|
|
717
|
-
// src/features/lending/read/get-account-liquidity.ts
|
|
830
|
+
import { createPublicClient as createPublicClient2, http as http2 } from "viem";
|
|
718
831
|
init_constants();
|
|
719
832
|
var getAccountLiquiditySchema = z8.object({
|
|
720
833
|
address: evmAddress.describe("The wallet address to check"),
|
|
@@ -728,7 +841,7 @@ async function getAccountLiquidity(input, config) {
|
|
|
728
841
|
);
|
|
729
842
|
}
|
|
730
843
|
const controllerAddress = getControllerAddress(input.chainId);
|
|
731
|
-
const client =
|
|
844
|
+
const client = createPublicClient2({ transport: http2(rpcUrl) });
|
|
732
845
|
const [error, liquidity, shortfall] = await client.readContract({
|
|
733
846
|
address: controllerAddress,
|
|
734
847
|
abi: COMPTROLLER_ABI,
|
|
@@ -738,8 +851,8 @@ async function getAccountLiquidity(input, config) {
|
|
|
738
851
|
if (error !== 0n) {
|
|
739
852
|
throw new Error(`Comptroller getAccountLiquidity returned error code ${error.toString()}`);
|
|
740
853
|
}
|
|
741
|
-
const liquidityUsd = new
|
|
742
|
-
const shortfallUsd = new
|
|
854
|
+
const liquidityUsd = new Decimal3(liquidity.toString()).div("1e18").toNumber();
|
|
855
|
+
const shortfallUsd = new Decimal3(shortfall.toString()).div("1e18").toNumber();
|
|
743
856
|
return {
|
|
744
857
|
address: input.address,
|
|
745
858
|
chainId: input.chainId,
|