@agether/sdk 2.17.1 → 2.17.3
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 +5 -84
- package/dist/index.d.mts +4 -38
- package/dist/index.d.ts +4 -38
- package/dist/index.js +5 -84
- package/dist/index.mjs +5 -84
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1885,7 +1885,7 @@ var init_MorphoClient = __esm({
|
|
|
1885
1885
|
*
|
|
1886
1886
|
* @returns Array of markets with yield analysis, sorted by net spread descending.
|
|
1887
1887
|
*/
|
|
1888
|
-
async getYieldSpread() {
|
|
1888
|
+
async getYieldSpread(minLiquidity = 0) {
|
|
1889
1889
|
const lstYields = await this._getLstYields();
|
|
1890
1890
|
if (Object.keys(lstYields).length === 0) {
|
|
1891
1891
|
console.warn("[agether] No LST yield data available \u2014 DeFi Llama may be unreachable");
|
|
@@ -1927,92 +1927,13 @@ var init_MorphoClient = __esm({
|
|
|
1927
1927
|
maxSafeLeverage: parseFloat(maxLeverage.toFixed(2)),
|
|
1928
1928
|
leveragedNetApy: parseFloat(leveragedNetApy.toFixed(2)),
|
|
1929
1929
|
liquidity: mkt.totalSupplyUsd - mkt.totalBorrowUsd,
|
|
1930
|
+
totalSupply: mkt.totalSupplyUsd,
|
|
1931
|
+
utilization: mkt.totalBorrowUsd > 0 ? mkt.totalBorrowUsd / mkt.totalSupplyUsd * 100 : 0,
|
|
1930
1932
|
marketId: mkt.marketId
|
|
1931
1933
|
});
|
|
1932
1934
|
}
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
/**
|
|
1936
|
-
* Execute a leverage loop: deposit collateral → borrow → swap to collateral → deposit again.
|
|
1937
|
-
* Repeats N times to achieve target leverage.
|
|
1938
|
-
*
|
|
1939
|
-
* Example: 1 wstETH at 3x leverage = deposit 1 → borrow → swap to ~0.77 wstETH → deposit →
|
|
1940
|
-
* borrow → swap to ~0.6 wstETH → deposit. Total exposure: ~2.37 wstETH, debt: ~1.37 ETH worth.
|
|
1941
|
-
*
|
|
1942
|
-
* @param collateralToken - LST token to deposit (e.g. 'wstETH')
|
|
1943
|
-
* @param amount - Initial deposit amount
|
|
1944
|
-
* @param targetLeverage - Target leverage multiplier (e.g. 2.0 for 2x)
|
|
1945
|
-
* @param loanToken - Token to borrow (default: inferred from market)
|
|
1946
|
-
* @param maxIterations - Max loop iterations (default: 5, safety cap)
|
|
1947
|
-
*/
|
|
1948
|
-
async leverageLoop(collateralToken, amount, targetLeverage, loanToken, maxIterations = 5) {
|
|
1949
|
-
if (targetLeverage < 1.1 || targetLeverage > 10) {
|
|
1950
|
-
throw new AgetherError(
|
|
1951
|
-
"Target leverage must be between 1.1x and 10x",
|
|
1952
|
-
"INVALID_LEVERAGE"
|
|
1953
|
-
);
|
|
1954
|
-
}
|
|
1955
|
-
const spreads = await this.getYieldSpread();
|
|
1956
|
-
const matchingMarket = spreads.find(
|
|
1957
|
-
(s) => s.collateralToken.toLowerCase() === collateralToken.toLowerCase() && (!loanToken || s.loanToken.toLowerCase() === loanToken.toLowerCase())
|
|
1958
|
-
);
|
|
1959
|
-
if (!matchingMarket) {
|
|
1960
|
-
throw new AgetherError(
|
|
1961
|
-
`No LST market found for ${collateralToken}`,
|
|
1962
|
-
"MARKET_NOT_FOUND"
|
|
1963
|
-
);
|
|
1964
|
-
}
|
|
1965
|
-
if (!matchingMarket) {
|
|
1966
|
-
throw new AgetherError(
|
|
1967
|
-
`No yield data available for ${collateralToken}. Ensure DeFi Llama API is reachable.`,
|
|
1968
|
-
"NO_YIELD_DATA"
|
|
1969
|
-
);
|
|
1970
|
-
}
|
|
1971
|
-
if (targetLeverage > matchingMarket.maxSafeLeverage) {
|
|
1972
|
-
throw new AgetherError(
|
|
1973
|
-
`Target leverage ${targetLeverage}x exceeds max safe leverage ${matchingMarket.maxSafeLeverage}x for ${collateralToken}. Max LLTV is ${(matchingMarket.lltv * 100).toFixed(0)}%.`,
|
|
1974
|
-
"LEVERAGE_TOO_HIGH"
|
|
1975
|
-
);
|
|
1976
|
-
}
|
|
1977
|
-
const initialAmount = parseFloat(amount);
|
|
1978
|
-
const iterations = [];
|
|
1979
|
-
let totalCollateral = initialAmount;
|
|
1980
|
-
let totalDebt = 0;
|
|
1981
|
-
let currentAmount = initialAmount;
|
|
1982
|
-
for (let i = 0; i < maxIterations; i++) {
|
|
1983
|
-
const currentLeverage = totalDebt > 0 ? totalCollateral / (totalCollateral - totalDebt) : 1;
|
|
1984
|
-
if (currentLeverage >= targetLeverage * 0.98) break;
|
|
1985
|
-
const borrowAmount = currentAmount * matchingMarket.lltv * 0.8;
|
|
1986
|
-
const swapOutput = borrowAmount * 0.997;
|
|
1987
|
-
iterations.push({
|
|
1988
|
-
iteration: i + 1,
|
|
1989
|
-
deposit: currentAmount,
|
|
1990
|
-
borrow: borrowAmount,
|
|
1991
|
-
swapOutput
|
|
1992
|
-
});
|
|
1993
|
-
totalDebt += borrowAmount;
|
|
1994
|
-
totalCollateral += swapOutput;
|
|
1995
|
-
currentAmount = swapOutput;
|
|
1996
|
-
}
|
|
1997
|
-
const finalLeverage = totalDebt > 0 ? totalCollateral / (totalCollateral - totalDebt) : 1;
|
|
1998
|
-
return {
|
|
1999
|
-
strategy: "leverage_loop",
|
|
2000
|
-
collateralToken: matchingMarket.collateralToken,
|
|
2001
|
-
loanToken: matchingMarket.loanToken,
|
|
2002
|
-
initialDeposit: amount,
|
|
2003
|
-
targetLeverage,
|
|
2004
|
-
achievedLeverage: parseFloat(finalLeverage.toFixed(2)),
|
|
2005
|
-
totalCollateral: parseFloat(totalCollateral.toFixed(6)),
|
|
2006
|
-
totalDebt: parseFloat(totalDebt.toFixed(6)),
|
|
2007
|
-
iterations,
|
|
2008
|
-
estimatedNetApy: parseFloat(
|
|
2009
|
-
(matchingMarket.collateralYield * finalLeverage - matchingMarket.borrowRate * (finalLeverage - 1)).toFixed(2)
|
|
2010
|
-
),
|
|
2011
|
-
healthFactor: parseFloat(
|
|
2012
|
-
(totalCollateral * matchingMarket.lltv / totalDebt).toFixed(2)
|
|
2013
|
-
),
|
|
2014
|
-
warning: "This is a simulation. Actual execution requires DEX swap integration. Real results may differ due to slippage and price movements."
|
|
2015
|
-
};
|
|
1935
|
+
const filtered = minLiquidity > 0 ? results.filter((r) => r.liquidity >= minLiquidity) : results;
|
|
1936
|
+
return filtered.sort((a, b) => b.liquidity - a.liquidity || b.netSpread - a.netSpread);
|
|
2016
1937
|
}
|
|
2017
1938
|
/**
|
|
2018
1939
|
* Withdraw collateral from Morpho Blue.
|
package/dist/index.d.mts
CHANGED
|
@@ -581,30 +581,10 @@ interface YieldSpreadResult {
|
|
|
581
581
|
maxSafeLeverage: number;
|
|
582
582
|
leveragedNetApy: number;
|
|
583
583
|
liquidity: number;
|
|
584
|
+
totalSupply: number;
|
|
585
|
+
utilization: number;
|
|
584
586
|
marketId: string;
|
|
585
587
|
}
|
|
586
|
-
/** Single iteration in a leverage loop. */
|
|
587
|
-
interface LeverageIteration {
|
|
588
|
-
iteration: number;
|
|
589
|
-
deposit: number;
|
|
590
|
-
borrow: number;
|
|
591
|
-
swapOutput: number;
|
|
592
|
-
}
|
|
593
|
-
/** Result of a leverage loop simulation. */
|
|
594
|
-
interface LeverageResult {
|
|
595
|
-
strategy: string;
|
|
596
|
-
collateralToken: string;
|
|
597
|
-
loanToken: string;
|
|
598
|
-
initialDeposit: string;
|
|
599
|
-
targetLeverage: number;
|
|
600
|
-
achievedLeverage: number;
|
|
601
|
-
totalCollateral: number;
|
|
602
|
-
totalDebt: number;
|
|
603
|
-
iterations: LeverageIteration[];
|
|
604
|
-
estimatedNetApy: number;
|
|
605
|
-
healthFactor: number;
|
|
606
|
-
warning: string;
|
|
607
|
-
}
|
|
608
588
|
declare class MorphoClient {
|
|
609
589
|
private _signer;
|
|
610
590
|
private provider;
|
|
@@ -954,21 +934,7 @@ declare class MorphoClient {
|
|
|
954
934
|
*
|
|
955
935
|
* @returns Array of markets with yield analysis, sorted by net spread descending.
|
|
956
936
|
*/
|
|
957
|
-
getYieldSpread(): Promise<YieldSpreadResult[]>;
|
|
958
|
-
/**
|
|
959
|
-
* Execute a leverage loop: deposit collateral → borrow → swap to collateral → deposit again.
|
|
960
|
-
* Repeats N times to achieve target leverage.
|
|
961
|
-
*
|
|
962
|
-
* Example: 1 wstETH at 3x leverage = deposit 1 → borrow → swap to ~0.77 wstETH → deposit →
|
|
963
|
-
* borrow → swap to ~0.6 wstETH → deposit. Total exposure: ~2.37 wstETH, debt: ~1.37 ETH worth.
|
|
964
|
-
*
|
|
965
|
-
* @param collateralToken - LST token to deposit (e.g. 'wstETH')
|
|
966
|
-
* @param amount - Initial deposit amount
|
|
967
|
-
* @param targetLeverage - Target leverage multiplier (e.g. 2.0 for 2x)
|
|
968
|
-
* @param loanToken - Token to borrow (default: inferred from market)
|
|
969
|
-
* @param maxIterations - Max loop iterations (default: 5, safety cap)
|
|
970
|
-
*/
|
|
971
|
-
leverageLoop(collateralToken: string, amount: string, targetLeverage: number, loanToken?: string, maxIterations?: number): Promise<LeverageResult>;
|
|
937
|
+
getYieldSpread(minLiquidity?: number): Promise<YieldSpreadResult[]>;
|
|
972
938
|
/**
|
|
973
939
|
* Withdraw collateral from Morpho Blue.
|
|
974
940
|
*
|
|
@@ -1669,4 +1635,4 @@ interface RetryOptions {
|
|
|
1669
1635
|
*/
|
|
1670
1636
|
declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
1671
1637
|
|
|
1672
|
-
export { ACCOUNT_FACTORY_ABI, AGENT_REPUTATION_ABI, AGETHER_4337_FACTORY_ABI, AGETHER_8004_SCORER_ABI, AGETHER_8004_VALIDATION_MODULE_ABI, AGETHER_HOOK_MULTIPLEXER_ABI, AgentIdentityClient, type AgentIdentityClientOptions, AgentNotApprovedError, AgetherClient, type AgetherClientOptions, type AgetherConfig, AgetherError, type AgetherSigner, type AgetherViemWallet, type BalancesResult, type BorrowResult, ChainId, type ContractAddresses, type DepositAndBorrowResult, type DepositResult, ENTRYPOINT_V07_ABI, ERC20_ABI, ERC8004_VALIDATION_MODULE_ABI, HOOK_MULTIPLEXER_ABI, IDENTITY_REGISTRY_ABI, InsufficientBalanceError,
|
|
1638
|
+
export { ACCOUNT_FACTORY_ABI, AGENT_REPUTATION_ABI, AGETHER_4337_FACTORY_ABI, AGETHER_8004_SCORER_ABI, AGETHER_8004_VALIDATION_MODULE_ABI, AGETHER_HOOK_MULTIPLEXER_ABI, AgentIdentityClient, type AgentIdentityClientOptions, AgentNotApprovedError, AgetherClient, type AgetherClientOptions, type AgetherConfig, AgetherError, type AgetherSigner, type AgetherViemWallet, type BalancesResult, type BorrowResult, ChainId, type ContractAddresses, type DepositAndBorrowResult, type DepositResult, ENTRYPOINT_V07_ABI, ERC20_ABI, ERC8004_VALIDATION_MODULE_ABI, HOOK_MULTIPLEXER_ABI, IDENTITY_REGISTRY_ABI, InsufficientBalanceError, MORPHO_BLUE_ABI, type MarketFilter, MorphoClient, type MorphoClientConfig, type MorphoMarketInfo, type MorphoMarketParams, type MorphoPosition, type PayFromYieldResult, type PaymentRequirements, type PositionResult, type RegisterResult, type RepayResult, type RetryOptions, SAFE7579_ACCOUNT_ABI, SAFE_AGENT_FACTORY_ABI, type ScoreAttestation, type ScoreResult, ScoringClient, type ScoringClientConfig, ScoringRejectedError, type SpendingTracker, type StatusResult, type SupplyAssetResult, type SupplyPositionResult, type TransactionResult, VALIDATION_REGISTRY_ABI, type WithdrawFromAccountResult, type WithdrawResult, type WithdrawSupplyResult, X402Client, type X402Config, type X402PaymentRequest, type X402PaymentResult, type X402Response, type YieldSpreadResult, bpsToRate, createConfig, formatAPR, formatAddress, formatHealthFactor, formatPercent, formatTimestamp, formatUSD, formatUnits, getContractAddresses, getDefaultConfig, getMorphoBlueAddress, getUSDCAddress, parseUnits, rateToBps, withRetry };
|
package/dist/index.d.ts
CHANGED
|
@@ -581,30 +581,10 @@ interface YieldSpreadResult {
|
|
|
581
581
|
maxSafeLeverage: number;
|
|
582
582
|
leveragedNetApy: number;
|
|
583
583
|
liquidity: number;
|
|
584
|
+
totalSupply: number;
|
|
585
|
+
utilization: number;
|
|
584
586
|
marketId: string;
|
|
585
587
|
}
|
|
586
|
-
/** Single iteration in a leverage loop. */
|
|
587
|
-
interface LeverageIteration {
|
|
588
|
-
iteration: number;
|
|
589
|
-
deposit: number;
|
|
590
|
-
borrow: number;
|
|
591
|
-
swapOutput: number;
|
|
592
|
-
}
|
|
593
|
-
/** Result of a leverage loop simulation. */
|
|
594
|
-
interface LeverageResult {
|
|
595
|
-
strategy: string;
|
|
596
|
-
collateralToken: string;
|
|
597
|
-
loanToken: string;
|
|
598
|
-
initialDeposit: string;
|
|
599
|
-
targetLeverage: number;
|
|
600
|
-
achievedLeverage: number;
|
|
601
|
-
totalCollateral: number;
|
|
602
|
-
totalDebt: number;
|
|
603
|
-
iterations: LeverageIteration[];
|
|
604
|
-
estimatedNetApy: number;
|
|
605
|
-
healthFactor: number;
|
|
606
|
-
warning: string;
|
|
607
|
-
}
|
|
608
588
|
declare class MorphoClient {
|
|
609
589
|
private _signer;
|
|
610
590
|
private provider;
|
|
@@ -954,21 +934,7 @@ declare class MorphoClient {
|
|
|
954
934
|
*
|
|
955
935
|
* @returns Array of markets with yield analysis, sorted by net spread descending.
|
|
956
936
|
*/
|
|
957
|
-
getYieldSpread(): Promise<YieldSpreadResult[]>;
|
|
958
|
-
/**
|
|
959
|
-
* Execute a leverage loop: deposit collateral → borrow → swap to collateral → deposit again.
|
|
960
|
-
* Repeats N times to achieve target leverage.
|
|
961
|
-
*
|
|
962
|
-
* Example: 1 wstETH at 3x leverage = deposit 1 → borrow → swap to ~0.77 wstETH → deposit →
|
|
963
|
-
* borrow → swap to ~0.6 wstETH → deposit. Total exposure: ~2.37 wstETH, debt: ~1.37 ETH worth.
|
|
964
|
-
*
|
|
965
|
-
* @param collateralToken - LST token to deposit (e.g. 'wstETH')
|
|
966
|
-
* @param amount - Initial deposit amount
|
|
967
|
-
* @param targetLeverage - Target leverage multiplier (e.g. 2.0 for 2x)
|
|
968
|
-
* @param loanToken - Token to borrow (default: inferred from market)
|
|
969
|
-
* @param maxIterations - Max loop iterations (default: 5, safety cap)
|
|
970
|
-
*/
|
|
971
|
-
leverageLoop(collateralToken: string, amount: string, targetLeverage: number, loanToken?: string, maxIterations?: number): Promise<LeverageResult>;
|
|
937
|
+
getYieldSpread(minLiquidity?: number): Promise<YieldSpreadResult[]>;
|
|
972
938
|
/**
|
|
973
939
|
* Withdraw collateral from Morpho Blue.
|
|
974
940
|
*
|
|
@@ -1669,4 +1635,4 @@ interface RetryOptions {
|
|
|
1669
1635
|
*/
|
|
1670
1636
|
declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
1671
1637
|
|
|
1672
|
-
export { ACCOUNT_FACTORY_ABI, AGENT_REPUTATION_ABI, AGETHER_4337_FACTORY_ABI, AGETHER_8004_SCORER_ABI, AGETHER_8004_VALIDATION_MODULE_ABI, AGETHER_HOOK_MULTIPLEXER_ABI, AgentIdentityClient, type AgentIdentityClientOptions, AgentNotApprovedError, AgetherClient, type AgetherClientOptions, type AgetherConfig, AgetherError, type AgetherSigner, type AgetherViemWallet, type BalancesResult, type BorrowResult, ChainId, type ContractAddresses, type DepositAndBorrowResult, type DepositResult, ENTRYPOINT_V07_ABI, ERC20_ABI, ERC8004_VALIDATION_MODULE_ABI, HOOK_MULTIPLEXER_ABI, IDENTITY_REGISTRY_ABI, InsufficientBalanceError,
|
|
1638
|
+
export { ACCOUNT_FACTORY_ABI, AGENT_REPUTATION_ABI, AGETHER_4337_FACTORY_ABI, AGETHER_8004_SCORER_ABI, AGETHER_8004_VALIDATION_MODULE_ABI, AGETHER_HOOK_MULTIPLEXER_ABI, AgentIdentityClient, type AgentIdentityClientOptions, AgentNotApprovedError, AgetherClient, type AgetherClientOptions, type AgetherConfig, AgetherError, type AgetherSigner, type AgetherViemWallet, type BalancesResult, type BorrowResult, ChainId, type ContractAddresses, type DepositAndBorrowResult, type DepositResult, ENTRYPOINT_V07_ABI, ERC20_ABI, ERC8004_VALIDATION_MODULE_ABI, HOOK_MULTIPLEXER_ABI, IDENTITY_REGISTRY_ABI, InsufficientBalanceError, MORPHO_BLUE_ABI, type MarketFilter, MorphoClient, type MorphoClientConfig, type MorphoMarketInfo, type MorphoMarketParams, type MorphoPosition, type PayFromYieldResult, type PaymentRequirements, type PositionResult, type RegisterResult, type RepayResult, type RetryOptions, SAFE7579_ACCOUNT_ABI, SAFE_AGENT_FACTORY_ABI, type ScoreAttestation, type ScoreResult, ScoringClient, type ScoringClientConfig, ScoringRejectedError, type SpendingTracker, type StatusResult, type SupplyAssetResult, type SupplyPositionResult, type TransactionResult, VALIDATION_REGISTRY_ABI, type WithdrawFromAccountResult, type WithdrawResult, type WithdrawSupplyResult, X402Client, type X402Config, type X402PaymentRequest, type X402PaymentResult, type X402Response, type YieldSpreadResult, bpsToRate, createConfig, formatAPR, formatAddress, formatHealthFactor, formatPercent, formatTimestamp, formatUSD, formatUnits, getContractAddresses, getDefaultConfig, getMorphoBlueAddress, getUSDCAddress, parseUnits, rateToBps, withRetry };
|
package/dist/index.js
CHANGED
|
@@ -2830,7 +2830,7 @@ var _MorphoClient = class _MorphoClient {
|
|
|
2830
2830
|
*
|
|
2831
2831
|
* @returns Array of markets with yield analysis, sorted by net spread descending.
|
|
2832
2832
|
*/
|
|
2833
|
-
async getYieldSpread() {
|
|
2833
|
+
async getYieldSpread(minLiquidity = 0) {
|
|
2834
2834
|
const lstYields = await this._getLstYields();
|
|
2835
2835
|
if (Object.keys(lstYields).length === 0) {
|
|
2836
2836
|
console.warn("[agether] No LST yield data available \u2014 DeFi Llama may be unreachable");
|
|
@@ -2872,92 +2872,13 @@ var _MorphoClient = class _MorphoClient {
|
|
|
2872
2872
|
maxSafeLeverage: parseFloat(maxLeverage.toFixed(2)),
|
|
2873
2873
|
leveragedNetApy: parseFloat(leveragedNetApy.toFixed(2)),
|
|
2874
2874
|
liquidity: mkt.totalSupplyUsd - mkt.totalBorrowUsd,
|
|
2875
|
+
totalSupply: mkt.totalSupplyUsd,
|
|
2876
|
+
utilization: mkt.totalBorrowUsd > 0 ? mkt.totalBorrowUsd / mkt.totalSupplyUsd * 100 : 0,
|
|
2875
2877
|
marketId: mkt.marketId
|
|
2876
2878
|
});
|
|
2877
2879
|
}
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
/**
|
|
2881
|
-
* Execute a leverage loop: deposit collateral → borrow → swap to collateral → deposit again.
|
|
2882
|
-
* Repeats N times to achieve target leverage.
|
|
2883
|
-
*
|
|
2884
|
-
* Example: 1 wstETH at 3x leverage = deposit 1 → borrow → swap to ~0.77 wstETH → deposit →
|
|
2885
|
-
* borrow → swap to ~0.6 wstETH → deposit. Total exposure: ~2.37 wstETH, debt: ~1.37 ETH worth.
|
|
2886
|
-
*
|
|
2887
|
-
* @param collateralToken - LST token to deposit (e.g. 'wstETH')
|
|
2888
|
-
* @param amount - Initial deposit amount
|
|
2889
|
-
* @param targetLeverage - Target leverage multiplier (e.g. 2.0 for 2x)
|
|
2890
|
-
* @param loanToken - Token to borrow (default: inferred from market)
|
|
2891
|
-
* @param maxIterations - Max loop iterations (default: 5, safety cap)
|
|
2892
|
-
*/
|
|
2893
|
-
async leverageLoop(collateralToken, amount, targetLeverage, loanToken, maxIterations = 5) {
|
|
2894
|
-
if (targetLeverage < 1.1 || targetLeverage > 10) {
|
|
2895
|
-
throw new AgetherError(
|
|
2896
|
-
"Target leverage must be between 1.1x and 10x",
|
|
2897
|
-
"INVALID_LEVERAGE"
|
|
2898
|
-
);
|
|
2899
|
-
}
|
|
2900
|
-
const spreads = await this.getYieldSpread();
|
|
2901
|
-
const matchingMarket = spreads.find(
|
|
2902
|
-
(s) => s.collateralToken.toLowerCase() === collateralToken.toLowerCase() && (!loanToken || s.loanToken.toLowerCase() === loanToken.toLowerCase())
|
|
2903
|
-
);
|
|
2904
|
-
if (!matchingMarket) {
|
|
2905
|
-
throw new AgetherError(
|
|
2906
|
-
`No LST market found for ${collateralToken}`,
|
|
2907
|
-
"MARKET_NOT_FOUND"
|
|
2908
|
-
);
|
|
2909
|
-
}
|
|
2910
|
-
if (!matchingMarket) {
|
|
2911
|
-
throw new AgetherError(
|
|
2912
|
-
`No yield data available for ${collateralToken}. Ensure DeFi Llama API is reachable.`,
|
|
2913
|
-
"NO_YIELD_DATA"
|
|
2914
|
-
);
|
|
2915
|
-
}
|
|
2916
|
-
if (targetLeverage > matchingMarket.maxSafeLeverage) {
|
|
2917
|
-
throw new AgetherError(
|
|
2918
|
-
`Target leverage ${targetLeverage}x exceeds max safe leverage ${matchingMarket.maxSafeLeverage}x for ${collateralToken}. Max LLTV is ${(matchingMarket.lltv * 100).toFixed(0)}%.`,
|
|
2919
|
-
"LEVERAGE_TOO_HIGH"
|
|
2920
|
-
);
|
|
2921
|
-
}
|
|
2922
|
-
const initialAmount = parseFloat(amount);
|
|
2923
|
-
const iterations = [];
|
|
2924
|
-
let totalCollateral = initialAmount;
|
|
2925
|
-
let totalDebt = 0;
|
|
2926
|
-
let currentAmount = initialAmount;
|
|
2927
|
-
for (let i = 0; i < maxIterations; i++) {
|
|
2928
|
-
const currentLeverage = totalDebt > 0 ? totalCollateral / (totalCollateral - totalDebt) : 1;
|
|
2929
|
-
if (currentLeverage >= targetLeverage * 0.98) break;
|
|
2930
|
-
const borrowAmount = currentAmount * matchingMarket.lltv * 0.8;
|
|
2931
|
-
const swapOutput = borrowAmount * 0.997;
|
|
2932
|
-
iterations.push({
|
|
2933
|
-
iteration: i + 1,
|
|
2934
|
-
deposit: currentAmount,
|
|
2935
|
-
borrow: borrowAmount,
|
|
2936
|
-
swapOutput
|
|
2937
|
-
});
|
|
2938
|
-
totalDebt += borrowAmount;
|
|
2939
|
-
totalCollateral += swapOutput;
|
|
2940
|
-
currentAmount = swapOutput;
|
|
2941
|
-
}
|
|
2942
|
-
const finalLeverage = totalDebt > 0 ? totalCollateral / (totalCollateral - totalDebt) : 1;
|
|
2943
|
-
return {
|
|
2944
|
-
strategy: "leverage_loop",
|
|
2945
|
-
collateralToken: matchingMarket.collateralToken,
|
|
2946
|
-
loanToken: matchingMarket.loanToken,
|
|
2947
|
-
initialDeposit: amount,
|
|
2948
|
-
targetLeverage,
|
|
2949
|
-
achievedLeverage: parseFloat(finalLeverage.toFixed(2)),
|
|
2950
|
-
totalCollateral: parseFloat(totalCollateral.toFixed(6)),
|
|
2951
|
-
totalDebt: parseFloat(totalDebt.toFixed(6)),
|
|
2952
|
-
iterations,
|
|
2953
|
-
estimatedNetApy: parseFloat(
|
|
2954
|
-
(matchingMarket.collateralYield * finalLeverage - matchingMarket.borrowRate * (finalLeverage - 1)).toFixed(2)
|
|
2955
|
-
),
|
|
2956
|
-
healthFactor: parseFloat(
|
|
2957
|
-
(totalCollateral * matchingMarket.lltv / totalDebt).toFixed(2)
|
|
2958
|
-
),
|
|
2959
|
-
warning: "This is a simulation. Actual execution requires DEX swap integration. Real results may differ due to slippage and price movements."
|
|
2960
|
-
};
|
|
2880
|
+
const filtered = minLiquidity > 0 ? results.filter((r) => r.liquidity >= minLiquidity) : results;
|
|
2881
|
+
return filtered.sort((a, b) => b.liquidity - a.liquidity || b.netSpread - a.netSpread);
|
|
2961
2882
|
}
|
|
2962
2883
|
/**
|
|
2963
2884
|
* Withdraw collateral from Morpho Blue.
|
package/dist/index.mjs
CHANGED
|
@@ -2754,7 +2754,7 @@ var _MorphoClient = class _MorphoClient {
|
|
|
2754
2754
|
*
|
|
2755
2755
|
* @returns Array of markets with yield analysis, sorted by net spread descending.
|
|
2756
2756
|
*/
|
|
2757
|
-
async getYieldSpread() {
|
|
2757
|
+
async getYieldSpread(minLiquidity = 0) {
|
|
2758
2758
|
const lstYields = await this._getLstYields();
|
|
2759
2759
|
if (Object.keys(lstYields).length === 0) {
|
|
2760
2760
|
console.warn("[agether] No LST yield data available \u2014 DeFi Llama may be unreachable");
|
|
@@ -2796,92 +2796,13 @@ var _MorphoClient = class _MorphoClient {
|
|
|
2796
2796
|
maxSafeLeverage: parseFloat(maxLeverage.toFixed(2)),
|
|
2797
2797
|
leveragedNetApy: parseFloat(leveragedNetApy.toFixed(2)),
|
|
2798
2798
|
liquidity: mkt.totalSupplyUsd - mkt.totalBorrowUsd,
|
|
2799
|
+
totalSupply: mkt.totalSupplyUsd,
|
|
2800
|
+
utilization: mkt.totalBorrowUsd > 0 ? mkt.totalBorrowUsd / mkt.totalSupplyUsd * 100 : 0,
|
|
2799
2801
|
marketId: mkt.marketId
|
|
2800
2802
|
});
|
|
2801
2803
|
}
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
/**
|
|
2805
|
-
* Execute a leverage loop: deposit collateral → borrow → swap to collateral → deposit again.
|
|
2806
|
-
* Repeats N times to achieve target leverage.
|
|
2807
|
-
*
|
|
2808
|
-
* Example: 1 wstETH at 3x leverage = deposit 1 → borrow → swap to ~0.77 wstETH → deposit →
|
|
2809
|
-
* borrow → swap to ~0.6 wstETH → deposit. Total exposure: ~2.37 wstETH, debt: ~1.37 ETH worth.
|
|
2810
|
-
*
|
|
2811
|
-
* @param collateralToken - LST token to deposit (e.g. 'wstETH')
|
|
2812
|
-
* @param amount - Initial deposit amount
|
|
2813
|
-
* @param targetLeverage - Target leverage multiplier (e.g. 2.0 for 2x)
|
|
2814
|
-
* @param loanToken - Token to borrow (default: inferred from market)
|
|
2815
|
-
* @param maxIterations - Max loop iterations (default: 5, safety cap)
|
|
2816
|
-
*/
|
|
2817
|
-
async leverageLoop(collateralToken, amount, targetLeverage, loanToken, maxIterations = 5) {
|
|
2818
|
-
if (targetLeverage < 1.1 || targetLeverage > 10) {
|
|
2819
|
-
throw new AgetherError(
|
|
2820
|
-
"Target leverage must be between 1.1x and 10x",
|
|
2821
|
-
"INVALID_LEVERAGE"
|
|
2822
|
-
);
|
|
2823
|
-
}
|
|
2824
|
-
const spreads = await this.getYieldSpread();
|
|
2825
|
-
const matchingMarket = spreads.find(
|
|
2826
|
-
(s) => s.collateralToken.toLowerCase() === collateralToken.toLowerCase() && (!loanToken || s.loanToken.toLowerCase() === loanToken.toLowerCase())
|
|
2827
|
-
);
|
|
2828
|
-
if (!matchingMarket) {
|
|
2829
|
-
throw new AgetherError(
|
|
2830
|
-
`No LST market found for ${collateralToken}`,
|
|
2831
|
-
"MARKET_NOT_FOUND"
|
|
2832
|
-
);
|
|
2833
|
-
}
|
|
2834
|
-
if (!matchingMarket) {
|
|
2835
|
-
throw new AgetherError(
|
|
2836
|
-
`No yield data available for ${collateralToken}. Ensure DeFi Llama API is reachable.`,
|
|
2837
|
-
"NO_YIELD_DATA"
|
|
2838
|
-
);
|
|
2839
|
-
}
|
|
2840
|
-
if (targetLeverage > matchingMarket.maxSafeLeverage) {
|
|
2841
|
-
throw new AgetherError(
|
|
2842
|
-
`Target leverage ${targetLeverage}x exceeds max safe leverage ${matchingMarket.maxSafeLeverage}x for ${collateralToken}. Max LLTV is ${(matchingMarket.lltv * 100).toFixed(0)}%.`,
|
|
2843
|
-
"LEVERAGE_TOO_HIGH"
|
|
2844
|
-
);
|
|
2845
|
-
}
|
|
2846
|
-
const initialAmount = parseFloat(amount);
|
|
2847
|
-
const iterations = [];
|
|
2848
|
-
let totalCollateral = initialAmount;
|
|
2849
|
-
let totalDebt = 0;
|
|
2850
|
-
let currentAmount = initialAmount;
|
|
2851
|
-
for (let i = 0; i < maxIterations; i++) {
|
|
2852
|
-
const currentLeverage = totalDebt > 0 ? totalCollateral / (totalCollateral - totalDebt) : 1;
|
|
2853
|
-
if (currentLeverage >= targetLeverage * 0.98) break;
|
|
2854
|
-
const borrowAmount = currentAmount * matchingMarket.lltv * 0.8;
|
|
2855
|
-
const swapOutput = borrowAmount * 0.997;
|
|
2856
|
-
iterations.push({
|
|
2857
|
-
iteration: i + 1,
|
|
2858
|
-
deposit: currentAmount,
|
|
2859
|
-
borrow: borrowAmount,
|
|
2860
|
-
swapOutput
|
|
2861
|
-
});
|
|
2862
|
-
totalDebt += borrowAmount;
|
|
2863
|
-
totalCollateral += swapOutput;
|
|
2864
|
-
currentAmount = swapOutput;
|
|
2865
|
-
}
|
|
2866
|
-
const finalLeverage = totalDebt > 0 ? totalCollateral / (totalCollateral - totalDebt) : 1;
|
|
2867
|
-
return {
|
|
2868
|
-
strategy: "leverage_loop",
|
|
2869
|
-
collateralToken: matchingMarket.collateralToken,
|
|
2870
|
-
loanToken: matchingMarket.loanToken,
|
|
2871
|
-
initialDeposit: amount,
|
|
2872
|
-
targetLeverage,
|
|
2873
|
-
achievedLeverage: parseFloat(finalLeverage.toFixed(2)),
|
|
2874
|
-
totalCollateral: parseFloat(totalCollateral.toFixed(6)),
|
|
2875
|
-
totalDebt: parseFloat(totalDebt.toFixed(6)),
|
|
2876
|
-
iterations,
|
|
2877
|
-
estimatedNetApy: parseFloat(
|
|
2878
|
-
(matchingMarket.collateralYield * finalLeverage - matchingMarket.borrowRate * (finalLeverage - 1)).toFixed(2)
|
|
2879
|
-
),
|
|
2880
|
-
healthFactor: parseFloat(
|
|
2881
|
-
(totalCollateral * matchingMarket.lltv / totalDebt).toFixed(2)
|
|
2882
|
-
),
|
|
2883
|
-
warning: "This is a simulation. Actual execution requires DEX swap integration. Real results may differ due to slippage and price movements."
|
|
2884
|
-
};
|
|
2804
|
+
const filtered = minLiquidity > 0 ? results.filter((r) => r.liquidity >= minLiquidity) : results;
|
|
2805
|
+
return filtered.sort((a, b) => b.liquidity - a.liquidity || b.netSpread - a.netSpread);
|
|
2885
2806
|
}
|
|
2886
2807
|
/**
|
|
2887
2808
|
* Withdraw collateral from Morpho Blue.
|