diff --git a/packages/panoptic-sdk/README.md b/packages/panoptic-sdk/README.md index a3e9e58..05271cc 100644 --- a/packages/panoptic-sdk/README.md +++ b/packages/panoptic-sdk/README.md @@ -39,7 +39,7 @@ Typescript SDK for Panoptic - [x] `getPanopticPoolData` - [x] `getPanopticCollateralData` - [x] `getPanopticCollateralPositionData` - - [ ] `getPanopticPositionData` + - [x] `getPanopticPositionData` - Wallet Actions diff --git a/packages/panoptic-sdk/src/decorator/publicActions.ts b/packages/panoptic-sdk/src/decorator/publicActions.ts index e69de29..c8a1f9a 100644 --- a/packages/panoptic-sdk/src/decorator/publicActions.ts +++ b/packages/panoptic-sdk/src/decorator/publicActions.ts @@ -0,0 +1,36 @@ +import type { Chain, Client, Transport } from "viem"; +import { + type GetPanopticCollateralDataParameters, + getPanopticCollateralData, +} from "../publicActions/getPanopticCollateralData.js"; +import { + type GetPanopticCollateralPositionDataParameters, + getPanopticCollateralPositionData, +} from "../publicActions/getPanopticCollateralPositionData.js"; +import { + type GetPanopticPoolDataParameters, + getPanopticPoolData, +} from "../publicActions/getPanopticPoolData.js"; +import { + type GetPanopticPositionDataParameters, + getPanopticPositionData, +} from "../publicActions/getPanopticPositionData.js"; + +export const publicActionPanoptic = < + TChain extends Chain | undefined = Chain | undefined, +>( + client: Client, +) => ({ + getPanopticCollateralData: (args: GetPanopticCollateralDataParameters) => + getPanopticCollateralData(client, args), + + getPanopticCollateralPositionData: ( + args: GetPanopticCollateralPositionDataParameters, + ) => getPanopticCollateralPositionData(client, args), + + getPanopticPoolData: (args: GetPanopticPoolDataParameters) => + getPanopticPoolData(client, args), + + getPanopticPositionData: (args: GetPanopticPositionDataParameters) => + getPanopticPositionData(client, args), +}); diff --git a/packages/panoptic-sdk/src/index.ts b/packages/panoptic-sdk/src/index.ts index e69de29..fed6a61 100644 --- a/packages/panoptic-sdk/src/index.ts +++ b/packages/panoptic-sdk/src/index.ts @@ -0,0 +1,26 @@ +export type { + PanopticCollateral, + PanopticCollateralData, + PanopticCollateralParamters, + PanopticCollateralPositionData, + PanopticFactory, + PanopticPool, + PanopticPoolData, + PanopticPosition, + PanopticPositionData, + PanopticSemiFungiblePositionManager, +} from "./types/index.js"; + +export { getPanopticCollateralData } from "./publicActions/getPanopticCollateralData.js"; +export { getPanopticCollateralPositionData } from "./publicActions/getPanopticCollateralPositionData.js"; +export { getPanopticPoolData } from "./publicActions/getPanopticPoolData.js"; +export { getPanopticPositionData } from "./publicActions/getPanopticPositionData.js"; + +export { publicActionPanoptic } from "./decorator/publicActions.js"; + +export { + semiFungiblePositionManagerABI, + panopticFactoryABI, + panopticPoolABI, + collateralTrackerABI, +} from "./generated.js"; diff --git a/packages/panoptic-sdk/src/publicActions/getPanopticPositionData.ts b/packages/panoptic-sdk/src/publicActions/getPanopticPositionData.ts index e69de29..b99291f 100644 --- a/packages/panoptic-sdk/src/publicActions/getPanopticPositionData.ts +++ b/packages/panoptic-sdk/src/publicActions/getPanopticPositionData.ts @@ -0,0 +1,77 @@ +import { createFraction } from "reverse-mirage"; +import type { UniswapV3Tick } from "uniswap-v3-sdk"; +import type { Chain, Client, ReadContractParameters, Transport } from "viem"; +import { readContract } from "viem/actions"; +import { panopticPoolABI } from "../generated.js"; +import type { + PanopticPosition, + PanopticPositionData, +} from "../types/PanopticPosition.js"; +import { getPanoptionLegData } from "./getPanoptionLegData.js"; + +export type GetPanopticPositionDataParameters = Omit< + ReadContractParameters, + "address" | "abi" | "functionName" | "args" +> & { + panopticPosition: PanopticPosition; + tick: UniswapV3Tick; +}; + +export type GetPanopticPositionDataReturnType = PanopticPositionData; + +export const getPanopticPositionData = ( + client: Client, + { panopticPosition, tick, ...request }: GetPanopticPositionDataParameters, +): Promise => + Promise.all([ + readContract(client, { + abi: panopticPoolABI, + functionName: "optionPositionBalance", + address: panopticPosition.pool.address, + args: [panopticPosition.address, panopticPosition.id], + ...request, + }), + panopticPosition.legs[0] + ? getPanoptionLegData(client, { + leg: panopticPosition.legs[0], + address: panopticPosition.address, + pool: panopticPosition.pool, + tick, + ...request, + }) + : undefined, + panopticPosition.legs[1] + ? getPanoptionLegData(client, { + leg: panopticPosition.legs[1], + address: panopticPosition.address, + pool: panopticPosition.pool, + tick, + ...request, + }) + : undefined, + panopticPosition.legs[2] + ? getPanoptionLegData(client, { + leg: panopticPosition.legs[2], + address: panopticPosition.address, + pool: panopticPosition.pool, + tick, + ...request, + }) + : undefined, + panopticPosition.legs[3] + ? getPanoptionLegData(client, { + leg: panopticPosition.legs[3], + address: panopticPosition.address, + pool: panopticPosition.pool, + tick, + ...request, + }) + : undefined, + ] as const).then(([optionsBalance, leg0, leg1, leg2, leg3]) => ({ + type: "panopticPositionData", + amount: optionsBalance[0], + token0Utilization: createFraction(optionsBalance[1], 2n ** 64n), + token1Utilization: createFraction(optionsBalance[2], 2n ** 64n), + token: panopticPosition, + legData: [leg0, leg1, leg2, leg3], + })); diff --git a/packages/panoptic-sdk/src/publicActions/getPanoptionLegData.ts b/packages/panoptic-sdk/src/publicActions/getPanoptionLegData.ts new file mode 100644 index 0000000..c8e4f03 --- /dev/null +++ b/packages/panoptic-sdk/src/publicActions/getPanoptionLegData.ts @@ -0,0 +1,86 @@ +import type { UniswapV3Tick } from "uniswap-v3-sdk"; +import type { + Address, + Chain, + Client, + ReadContractParameters, + Transport, +} from "viem"; +import { readContract } from "viem/actions"; +import { + panopticPoolABI, + semiFungiblePositionManagerABI, +} from "../generated.js"; +import type { PanopticPool } from "../types/PanopticPool.js"; +import type { + PanoptionLeg, + PanoptionLegData, +} from "../types/PanopticPosition.js"; +import type {} from "./getPanopticPositionData.js"; + +export type GetPanoptionLegDataParameters = Omit< + ReadContractParameters, + "address" | "abi" | "functionName" | "args" +> & { + leg: PanoptionLeg; + address: Address; + pool: PanopticPool; + tick: UniswapV3Tick; +}; + +export type GetPanoptionLegDataReturnType = PanoptionLegData; + +export const getPanoptionLegData = ( + client: Client, + { leg, pool, address, tick, ...request }: GetPanoptionLegDataParameters, +): Promise => + Promise.all([ + readContract(client, { + abi: semiFungiblePositionManagerABI, + functionName: "getAccountLiquidity", + address: pool.factory.semiFungiblePositionManager.address, + args: [ + pool.uniswapPool.address, + address, + leg.tokenType === "token0" ? 0n : 1n, + leg.tickLower.tick, + leg.tickUpper.tick, + ], + ...request, + }), + readContract(client, { + abi: semiFungiblePositionManagerABI, + functionName: "getAccountPremium", + address: pool.factory.semiFungiblePositionManager.address, + args: [ + pool.uniswapPool.address, + address, + leg.tokenType === "token0" ? 0n : 1n, + leg.tickLower.tick, + leg.tickUpper.tick, + tick.tick, + leg.position === "short" ? 0n : 1n, + ], + ...request, + }), + readContract(client, { + abi: semiFungiblePositionManagerABI, + functionName: "getAccountFeesBase", + address: pool.factory.semiFungiblePositionManager.address, + args: [ + pool.uniswapPool.address, + address, + leg.tokenType === "token0" ? 0n : 1n, + leg.tickLower.tick, + leg.tickUpper.tick, + ], + ...request, + }), + ] as const).then(([legLiquidity, legPremium, legFeesBase]) => ({ + liquidityAdded: legLiquidity && 2n ** 128n - 1n, + liquidityRemoved: legLiquidity >> 128n, + accountPremium0: legPremium[0], + accountPremium1: legPremium[1], + baseFee0: legFeesBase[0], + baseFee1: legFeesBase[1], + })); diff --git a/packages/panoptic-sdk/src/types/PanopticFactory.ts b/packages/panoptic-sdk/src/types/PanopticFactory.ts index 8a46889..c09aed3 100644 --- a/packages/panoptic-sdk/src/types/PanopticFactory.ts +++ b/packages/panoptic-sdk/src/types/PanopticFactory.ts @@ -1,12 +1,14 @@ import type { WETH } from "reverse-mirage"; import type { UniswapV3Factory } from "uniswap-v3-sdk"; import type { Address } from "viem/accounts"; +import type { PanopticSemiFungiblePositionManager } from "./PanopticSemiFungiblePositionManager.js"; export type PanopticFactory = { type: "panopticFactory"; address: Address; owner: Address; uniswapFactory: UniswapV3Factory; + semiFungiblePositionManager: PanopticSemiFungiblePositionManager; weth: WETH; blockCreated: bigint; }; diff --git a/packages/panoptic-sdk/src/types/PanopticPosition.ts b/packages/panoptic-sdk/src/types/PanopticPosition.ts index 6571327..8a4f00a 100644 --- a/packages/panoptic-sdk/src/types/PanopticPosition.ts +++ b/packages/panoptic-sdk/src/types/PanopticPosition.ts @@ -19,15 +19,17 @@ export type PanopticPosition = BaseERC1155<"panopticPosition"> & { legs: Tuple; }; -export type PanopticPositionData = ERC1155Data & { +export type PanoptionLegData = { liquidityAdded: bigint; liquidityRemoved: bigint; - accountPremiumOwed0: bigint; - accountPremiumOwed1: bigint; - accountPremiumGross0: bigint; - accountPremiumGross1: bigint; + accountPremium0: bigint; + accountPremium1: bigint; baseFee0: bigint; baseFee1: bigint; +}; + +export type PanopticPositionData = ERC1155Data & { token0Utilization: Fraction; token1Utilization: Fraction; + legData: Tuple; }; diff --git a/wagmi.config.ts b/wagmi.config.ts index fd92efb..9ccee53 100644 --- a/wagmi.config.ts +++ b/wagmi.config.ts @@ -9,10 +9,10 @@ export default defineConfig([ foundry({ project: "lib/panoptic-v1-core/", include: [ - "SemiFuniblePositionManager.sol/**", + "SemiFungiblePositionManager.sol/**", "PanopticFactory.sol/**", "PanopticPool.sol/**", - "CollateralTracker.sol/**" + "CollateralTracker.sol/**", ], }), ],