@moonwell-fi/moonwell-sdk
Version:
TypeScript Interface for Moonwell
127 lines (110 loc) • 3.49 kB
text/typescript
import type { Address } from "viem";
import type { MoonwellClient } from "../../../client/createMoonwellClient.js";
import type { Chain, Environment } from "../../../environments/index.js";
import { fetchAccountMarketPortfolioFromIndexer } from "./lunarIndexerTransform.js";
export type AccountMarketPosition = {
chainId: number;
marketId: string;
marketKey: string;
supplyShares: string;
borrowShares: string;
collateral: string;
};
export type AccountPortfolioSnapshot = {
timestamp: number;
markets: AccountMarketPosition[];
};
export type GetAccountMarketPortfolioParameters = {
accountAddress: Address;
chainId?: number;
marketId?: string;
startTime: number;
endTime: number;
granularity?: "1h" | "6h" | "1d";
network?: Chain;
};
export type GetAccountMarketPortfolioReturnType = Promise<{
account: string;
positions: AccountPortfolioSnapshot[];
}>;
export async function getAccountMarketPortfolio(
client: MoonwellClient,
args: GetAccountMarketPortfolioParameters,
): GetAccountMarketPortfolioReturnType {
// Determine which environment to use
let environment: Environment | undefined;
// Get all environments as an array
const environments = Object.values(client.environments);
if (args.chainId) {
environment = environments.find((env) => env.chainId === args.chainId);
} else if (args.network && typeof args.network === "string") {
const envValue = (client.environments as any)[args.network];
if (envValue) {
environment = envValue;
}
} else {
// Default to first environment with lunar indexer
environment = environments.find((env) => env.lunarIndexerUrl);
}
if (!environment) {
throw new Error("Environment not found");
}
const lunarIndexerUrl = environment.lunarIndexerUrl;
if (!lunarIndexerUrl) {
throw new Error(
"Lunar Indexer URL not configured for this environment. Account market portfolio requires lunar-indexer.",
);
}
// Build options object with only defined values
const options: {
chainId?: number;
marketId?: string;
startTime?: number;
endTime?: number;
granularity?: "1h" | "6h" | "1d";
} = {
startTime: args.startTime,
endTime: args.endTime,
};
if (args.chainId !== undefined) {
options.chainId = args.chainId;
}
if (args.marketId !== undefined) {
options.marketId = args.marketId;
}
if (args.granularity !== undefined) {
options.granularity = args.granularity;
}
const response = await fetchAccountMarketPortfolioFromIndexer(
lunarIndexerUrl,
args.accountAddress,
options,
);
// Transform positions to include marketKey
const { morphoMarkets } = environment.config;
const positions: AccountPortfolioSnapshot[] = response.positions.map(
(position) => ({
timestamp: position.timestamp,
markets: position.markets.map((market) => {
// Find the market key from environment config
const marketKey = Object.keys(morphoMarkets).find(
(key) =>
morphoMarkets[key].id.toLowerCase() ===
market.marketId.toLowerCase(),
);
return {
chainId: market.chainId,
marketId: market.marketId,
marketKey: marketKey || market.marketId,
supplyShares: market.supplyShares,
borrowShares: market.borrowShares,
collateral: market.collateral,
};
}),
}),
);
return {
account: response.account,
positions,
};
}