timelock-sdk 0.0.19 → 0.0.21
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/abis.cjs +9 -1
- package/dist/abis.d.cts +3 -2
- package/dist/abis.d.ts +3 -2
- package/dist/abis.js +4 -1
- package/dist/client.cjs +695 -4
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +431 -53
- package/dist/client.d.ts +391 -13
- package/dist/client.js +667 -4
- package/dist/client.js.map +1 -0
- package/dist/{index-DyZhOGnP.d.ts → index-B7b3c8cu.d.cts} +151 -94
- package/dist/{index-CnaCnYLR.d.cts → index-CRhFaRiq.d.ts} +60 -3
- package/dist/numberUtils-CAMznXR5.js +220 -0
- package/dist/numberUtils-CAMznXR5.js.map +1 -0
- package/dist/numberUtils-DOUvJfQD.cjs +427 -0
- package/dist/numberUtils-DOUvJfQD.cjs.map +1 -0
- package/dist/optionsMarket-Br-bjuSA.cjs +2407 -0
- package/dist/optionsMarket-Br-bjuSA.cjs.map +1 -0
- package/dist/optionsMarket-DyBxHplR.js +2383 -0
- package/dist/optionsMarket-DyBxHplR.js.map +1 -0
- package/dist/package.cjs +32 -1
- package/dist/package.d.cts +2 -2
- package/dist/package.d.ts +2 -2
- package/dist/package.js +4 -1
- package/dist/{uniswapMathLens-SWLgAikn.d.ts → uniswapMathLens-B1MIL2yT.d.cts} +6 -1
- package/dist/{uniswapMathLens-CsZDhwII.d.cts → uniswapMathLens-MrB_VfJB.d.ts} +6 -1
- package/dist/uniswapV3Pool-Copswrde.js +1119 -1
- package/dist/uniswapV3Pool-Copswrde.js.map +1 -0
- package/dist/uniswapV3Pool-D9Vqrkmz.cjs +1131 -1
- package/dist/uniswapV3Pool-D9Vqrkmz.cjs.map +1 -0
- package/package.json +1 -1
- package/dist/numberUtils-B7BwWYfb.cjs +0 -1
- package/dist/numberUtils-DP-pDRRs.js +0 -1
- package/dist/optionsMarket-BsJTpwtl.js +0 -1
- package/dist/optionsMarket-BsK9z8z4.cjs +0 -1
package/dist/client.js
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import { lensAbi, optionsMarketAbi } from "./optionsMarket-DyBxHplR.js";
|
|
5
|
+
import { getErc20, getPriceAtTick, getTimelockLens, getTimelockMarket, getUniswapMathLens, roundTickDown, timelockLenses, token0ToToken1, token1ToToken0, uniswapMathLenses, wrapAmount, wrapPrice } from "./numberUtils-CAMznXR5.js";
|
|
6
|
+
import { singleOwnerVaultAbi, uniswapV3PoolAbi } from "./uniswapV3Pool-Copswrde.js";
|
|
7
|
+
import { encodeFunctionData, erc20Abi, maxUint256 } from "viem";
|
|
8
|
+
import React, { createContext, useContext, useMemo } from "react";
|
|
9
|
+
import { useAccount, useChainId, useClient, useReadContract, useWaitForTransactionReceipt, useWriteContract } from "wagmi";
|
|
10
|
+
import { GraphQLClient } from "graphql-request";
|
|
11
|
+
import gql from "graphql-tag";
|
|
12
|
+
import { waitForTransactionReceipt } from "viem/actions";
|
|
13
|
+
import { useQuery } from "@tanstack/react-query";
|
|
14
|
+
|
|
15
|
+
//#region src/generated/graphql.ts
|
|
16
|
+
const GetActiveUserOptionsDocument = gql`
|
|
2
17
|
query GetActiveUserOptions($user: String!) {
|
|
3
18
|
UserOption(
|
|
4
19
|
where: {ownerAddr: {_eq: $user}, fullyExercised: {_eq: false}}
|
|
@@ -29,7 +44,8 @@
|
|
|
29
44
|
fullyExercised
|
|
30
45
|
}
|
|
31
46
|
}
|
|
32
|
-
|
|
47
|
+
`;
|
|
48
|
+
const GetClosedUserOptionsDocument = gql`
|
|
33
49
|
query GetClosedUserOptions($user: String!) {
|
|
34
50
|
UserOption(
|
|
35
51
|
where: {ownerAddr: {_eq: $user}, fullyExercised: {_eq: true}}
|
|
@@ -60,7 +76,8 @@
|
|
|
60
76
|
fullyExercised
|
|
61
77
|
}
|
|
62
78
|
}
|
|
63
|
-
|
|
79
|
+
`;
|
|
80
|
+
const GetMarketDataDocument = gql`
|
|
64
81
|
query GetMarketData($marketAddr: String!) {
|
|
65
82
|
TimelockMarket(where: {id: {_eq: $marketAddr}}, limit: 1) {
|
|
66
83
|
id
|
|
@@ -80,4 +97,650 @@
|
|
|
80
97
|
payoutAssetName
|
|
81
98
|
}
|
|
82
99
|
}
|
|
83
|
-
`,I=(e,t,n,r)=>e();function L(e,t=I){return{GetActiveUserOptions(n,r,i){return t(t=>e.request({document:N,variables:n,requestHeaders:{...r,...t},signal:i}),`GetActiveUserOptions`,`query`,n)},GetClosedUserOptions(n,r,i){return t(t=>e.request({document:P,variables:n,requestHeaders:{...r,...t},signal:i}),`GetClosedUserOptions`,`query`,n)},GetMarketData(n,r,i){return t(t=>e.request({document:F,variables:n,requestHeaders:{...r,...t},signal:i}),`GetMarketData`,`query`,n)}}}const R=b(void 0),z=({children:e,marketData:t,envioGraphqlUrl:n})=>{let r=w(),i=c[r],a=d[r];return y.createElement(R.Provider,{value:{marketData:t||{},lensAddr:i,uniswapMathLensAddr:a,envioGraphqlUrl:n}},e)},B=()=>{let e=x(R);if(e===void 0)throw Error(`useCurrentMarket must be used within a TimelockMarketProvider`);return e.marketData},V=()=>{let e=x(R);if(e===void 0)throw Error(`useConfig must be used within a TimelockMarketProvider`);return{lensAddr:e.lensAddr,uniswapMathLensAddr:e.uniswapMathLensAddr,envioGraphqlUrl:e.envioGraphqlUrl,graphqlClient:e.envioGraphqlUrl?L(new k(e.envioGraphqlUrl)):void 0}},H=e=>{let{graphqlClient:t}=V(),{data:n}=M({queryKey:[`marketData`,e||`--`],queryFn:()=>t.GetMarketData({marketAddr:e.toLowerCase()}),select:e=>({...e.TimelockMarket[0],pool:e.TimelockMarket[0].pool,vault:e.TimelockMarket[0].vault,optionAsset:e.TimelockMarket[0].optionAsset,payoutAsset:e.TimelockMarket[0].payoutAsset,optionsCount:BigInt(e.TimelockMarket[0].optionsCount),tradersCount:BigInt(e.TimelockMarket[0].tradersCount)}),enabled:!!e&&!!t});return n||{}},U=e=>{let{vault:n}=H(e),r=T(),{data:i}=E({address:n,abi:m,functionName:`lowestTick`}),{writeContractAsync:a,data:o,isPending:s,error:c}=O(),{isLoading:l,isSuccess:u}=D({hash:o});return{exerciseOption:async(n,o)=>{if(!r)throw Error(`Wallet not connected`);if(i===void 0||!e)throw Error(`Lowest tick lower not available`);let s=await a({address:e,abi:t,functionName:`exerciseOption`,args:[n,o,0n,i]});return await j(r,{hash:s}),s},hash:o,isPending:s,isConfirming:l,isSuccess:u,error:c,isLoading:s||l}},W=()=>{let e=T(),t=S(()=>e?i(e):void 0,[e]);return{uniswapLens:S(()=>e?o(e):void 0,[e]),timelockLens:t}},G=(t,n,r=100)=>{let{timelockLens:i}=W(),{optionAssetDecimals:a}=H(t),{data:o,refetch:s}=E({address:i==null?void 0:i.address,abi:e,functionName:`getMaxPositionSizeAtCurrentTick`,args:[t,r],query:{enabled:!!t&&!!i},gas:100000000n}),{data:c,refetch:l}=E({address:i==null?void 0:i.address,abi:e,functionName:`getMaxPositionSize`,args:[t,n,r],query:{enabled:!!t&&!!i&&n!==void 0},gas:100000000n}),u=n===void 0?o:c,{maxCallSize:d,maxPutSize:p}=S(()=>u&&a?{maxCallSize:f(u[0],a),maxPutSize:f(u[1],a)}:{},[u,a]);return{maxCallSize:d,maxPutSize:p,refetch:()=>{s(),l()}}},K=t=>{let{timelockLens:n}=W(),r=T(),{data:i}=E({address:n==null?void 0:n.address,abi:e,functionName:`getPoolData`,args:t?[t]:void 0,query:{enabled:!!t&&!!r}});return i||{}},q=e=>{let{tickSpacing:t}=K(e),{data:n}=E({address:e,abi:h,functionName:`slot0`,args:[]}),r=n==null?void 0:n[1];return{exact:r,rounded:r&&t?Math.floor(r/t)*t:void 0}},J=e=>{let{timelockLens:r}=W(),{payoutAsset:i,vault:o,pool:c,optionAssetIsToken0:l}=H(e),{tickSpacing:u}=K(c),{exact:d}=q(c),f=T(),{address:p}=C(),{writeContractAsync:m,data:h,isPending:g,error:y}=O(),{isLoading:b,isSuccess:x}=D({hash:h}),S=async t=>{if(!f||!p)throw Error(`Wallet not connected`);if(!i||!e)throw Error(`Tokens not available`);await n(i,f).read.allowance([p,e])<t&&await j(f,{hash:await m({address:i,abi:_,functionName:`approve`,args:[e,v]})})};return{mintOption:async(n,i,c,p)=>{if(!f)throw Error(`Wallet not connected`);if(!r||!o||!e||!d||!u)throw Error(`Lowest tick lower not available`);p=s(p??d,u),(n===`CALL`&&l||n===`PUT`&&!l)&&(p+=u),await S(await a(e,f).read.calculatePremium([n===`CALL`?0:1,i,p,BigInt(c)]));let h=await m({address:e,abi:t,functionName:`mintOption`,args:[n===`CALL`?0:1,i,p,BigInt(c),BigInt(1e69),await r.read.getRefTick([o,p])]});return await j(f,{hash:h}),h},hash:h,isPending:g,isConfirming:b,isSuccess:x,error:y,isLoading:g||b}},ee=e=>{let{marketAddr:t,optionType:n,entryTick:r,positionSizeCurrent:i}=e,{pool:a,optionAssetIsToken0:o,payoutAssetDecimals:s}=H(t),{exact:c}=q(a),{displayPnl:d,unrealizedPayout:p}=S(()=>{if(o===void 0||c===void 0||!i||!s)return{};let e=o?l(i,c)-l(i,r):u(i,c)-u(i,r),t=f(n===`CALL`?e:-e,s);return{unrealizedPayout:f(t.scaled<0?0n:t.scaled,s),displayPnl:t}},[e,o,c,i]);return{displayPnl:d,unrealizedPayout:p}},te=(e,n,r,i)=>{let{pool:a,payoutAssetDecimals:o}=H(e),{tickSpacing:s}=K(a),c=q(a),l=S(()=>{if(!(c.rounded===void 0||s===void 0))return n===`CALL`?c.rounded+s:c.rounded},[c.rounded,s,n]),{data:u}=E({address:e,abi:t,functionName:`calculatePremium`,args:l===void 0?void 0:[n===`CALL`?0:1,r,l,BigInt(i)],query:{enabled:c.rounded!==void 0&&o!==void 0&&s!==void 0&&l!==void 0}});return S(()=>{if(!(u===void 0||o===void 0))return f(u,o)},[u,o])},Y=(e,t=!1)=>{let{graphqlClient:n}=V(),{data:r,...i}=M({queryKey:[`userTrades`,e||`--`,t],queryFn:()=>t?n==null?void 0:n.GetActiveUserOptions({user:e.toLowerCase()}):n==null?void 0:n.GetClosedUserOptions({user:e.toLowerCase()}),select:e=>{var t;return e==null||(t=e.UserOption)==null?void 0:t.map(e=>({...e,id:BigInt(e.id),marketAddr:e.marketAddr,optionType:e.optionType,createdAt:new Date(Number(e.createdAt)*1e3),expiresAt:new Date(Number(e.expiresAt)*1e3),premiumPaid:BigInt(e.premiumPaid),realizedPayout:BigInt(e.realizedPayout),liquiditiesAtOpen:e.liquiditiesAtOpen.map(e=>BigInt(e)),liquiditiesCurrent:e.liquiditiesCurrent.map(e=>BigInt(e)),positionSizeAtOpen:BigInt(e.positionSizeAtOpen),positionSizeCurrent:BigInt(e.positionSizeCurrent),strikePrice:BigInt(e.strikePrice),entryPrice:BigInt(e.entryPrice)}))},enabled:!!e&&!!n});return{data:S(()=>(r==null?void 0:r.sort((e,t)=>t.createdAt.getTime()-e.createdAt.getTime()))||[],[r]),...i}},ne=e=>Y(e,!0),re=e=>Y(e,!1),X=(e,t)=>{let{token0Decimals:n,token1Decimals:i}=K(t);return S(()=>e&&n&&i?p(r(e),n,i):void 0,[e,n,i])},Z=e=>{let t=q(e);return{currentPrice:X(t.exact,e),currentTick:t}},Q=e=>{let{data:t}=E({address:e,abi:m,functionName:`pool`});return{pool:t}},ie=e=>{let t=T(),{timelockLens:n}=W(),{pool:r}=Q(e),i=q(r),{writeContractAsync:a,data:o,isPending:s,error:c}=O(),{isLoading:l,isSuccess:u}=D({hash:o}),d=async(r,i,o)=>{if(!t)throw Error(`Wallet not connected`);if(!e||!n)throw Error(`Vault/lens not available`);let s=await a({address:e,abi:m,functionName:`burn`,args:[r,i,o,await n.read.getRefTick([e,r])]});return await j(t,{hash:s}),s};return{burnMultiple:async r=>{if(!t)throw Error(`Wallet not connected`);if(!i.exact)throw Error(`Current tick not available`);if(r.length===0)throw Error(`No positions to burn`);if(!n||!e)throw Error(`Vault/lens not available`);if(r.length===1)await d(r[0].tickLower,r[0].tickUpper,r[0].liquidity);else{let i=await n.read.batchGetRefTick([e,r.map(e=>e.tickLower)]);await j(t,{hash:await a({address:e,abi:m,functionName:`multicall`,args:[r.map((e,t)=>g({abi:m,functionName:`burn`,args:[e.tickLower,e.tickUpper,e.liquidity,i[t]]}))]})})}},burn:d,hash:o,isPending:s,isConfirming:l,isSuccess:u,error:c,isLoading:s||l}},ae=e=>{let{timelockLens:t}=W(),{pool:n}=Q(e),{token0Decimals:r,token1Decimals:i}=K(n),{currentPrice:a}=Z(n),{data:o=[],refetch:s}=M({queryKey:[`liquidityBlocks`,e],queryFn:()=>t.read.getAllBlocks([e]),enabled:!!e&&!!t}),{totalAmount0:c,totalAmount1:l,borrowedAmount0:u,borrowedAmount1:d}=S(()=>({totalAmount0:r?f(o.reduce((e,t)=>e+t.totalAmount0,0n),r):void 0,totalAmount1:i?f(o.reduce((e,t)=>e+t.totalAmount1,0n),i):void 0,borrowedAmount0:r?f(o.reduce((e,t)=>e+t.borrowedAmount0,0n),r):void 0,borrowedAmount1:i?f(o.reduce((e,t)=>e+t.borrowedAmount1,0n),i):void 0}),[o,r,i]);return{tvl1:S(()=>{if(!c||!l||!a||!i)return;let e=c.scaled*a.scaled/10n**18n,t=l.scaled;return f(e+t,i)},[c,l,a,i]),blocks:o,totalAmount0:c,totalAmount1:l,borrowedAmount0:u,borrowedAmount1:d,refetch:s}},$=async(e,t,n,r,i)=>{let a=Array(t.length).fill(i),o=await e.read.batchGetAmountsForLiquidityTicks([a,t,n,r]),s=0n,c=0n,l=[],u=[];for(let e of o[0])s+=e,l.push(e);for(let e of o[1])c+=e,u.push(e);return{totalAmount0:s,totalAmount1:c,amounts0:l,amounts1:u}},oe=e=>{let t=T(),{address:r}=C(),{pool:i}=Q(e),{timelockLens:a,uniswapLens:o}=W(),s=q(i),{token0:c,token1:l}=K(i),{writeContractAsync:u,data:d,isPending:f,error:p}=O(),{isLoading:h,isSuccess:y}=D({hash:d}),b=async i=>{if(!r||!t)throw Error(`Wallet not connected`);if(s.exact===void 0||!c||!l||!e||!o)throw Error(`Current tick not available`);let{totalAmount0:a,totalAmount1:d}=await $(o,i.map(e=>e.tickLower),i.map(e=>e.tickUpper),i.map(e=>e.liquidity),s.exact),[f,p]=await Promise.all([n(c,t).read.allowance([r,e]),n(l,t).read.allowance([r,e])]),m=[];if(f<=a){let n=await u({address:c,abi:_,functionName:`approve`,args:[e,v]});m.push(j(t,{hash:n}))}if(p<=d){let n=await u({address:l,abi:_,functionName:`approve`,args:[e,v]});m.push(j(t,{hash:n}))}m.length>0&&await Promise.all(m)},x=async(n,r,i)=>{if(!t)throw Error(`Wallet not connected`);if(!e||!a)throw Error(`Vault/lens not available`);await b([{tickLower:n,tickUpper:r,liquidity:i}]);let o=await u({address:e,abi:m,functionName:`mint`,args:[n,r,i,await a.read.getRefTick([e,n])]});return await j(t,{hash:o}),o};return{mintMultiple:async n=>{if(!t)throw Error(`Wallet not connected`);if(!s.exact)throw Error(`Current tick not available`);if(n.length===0)throw Error(`No positions to mint`);if(!a||!e)throw Error(`Vault/lens not available`);if(n.length===1)await x(n[0].tickLower,n[0].tickUpper,n[0].liquidity);else{await b(n);let r=await a.read.batchGetRefTick([e,n.map(e=>e.tickLower)]);await j(t,{hash:await u({address:e,abi:m,functionName:`multicall`,args:[n.map((e,t)=>g({abi:m,functionName:`mint`,args:[e.tickLower,e.tickUpper,e.liquidity,r[t]]}))]})})}},mint:x,hash:d,isPending:f,isConfirming:h,isSuccess:y,error:p,isLoading:f||h}},se=t=>{let{timelockLens:n}=W(),{pool:r}=Q(t),{token0Decimals:i,token1Decimals:a}=K(r),{data:o,refetch:s}=E({address:n==null?void 0:n.address,abi:e,functionName:`getVaultTVL`,args:[t],query:{enabled:!!t&&!!n}}),c=o&&i?f(o[0],i):void 0,l=o&&a?f(o[1],a):void 0,u=o&&i?f(o[2],i):void 0,d=o&&a?f(o[3],a):void 0;return{tvl0:o&&i?f(o[4],i):void 0,tvl1:o&&a?f(o[5],a):void 0,totalAmount0:c,totalAmount1:l,borrowedAmount0:u,borrowedAmount1:d,refetch:s}};export{z as TimelockMarketProvider,$ as batchGetAmountsFromLiquidity,ne as useActiveUserOptions,ie as useBurnLiquidity,re as useClosedUserOptions,B as useCurrentMarket,Z as useCurrentPrice,q as useCurrentTick,U as useExerciseOption,W as useLens,ae as useLiquidityBlocks,H as useMarketData,G as useMaxPositionSize,oe as useMintLiquidity,J as useMintOption,ee as useOptionPnl,te as useOptionPremium,K as usePoolData,X as usePriceAtTick,V as useTimelockConfig,Q as useVaultData,se as useVaultTVL};
|
|
100
|
+
`;
|
|
101
|
+
const defaultWrapper = (action, _operationName, _operationType, _variables) => action();
|
|
102
|
+
function getSdk(client, withWrapper = defaultWrapper) {
|
|
103
|
+
return {
|
|
104
|
+
GetActiveUserOptions(variables, requestHeaders, signal) {
|
|
105
|
+
return withWrapper((wrappedRequestHeaders) => client.request({
|
|
106
|
+
document: GetActiveUserOptionsDocument,
|
|
107
|
+
variables,
|
|
108
|
+
requestHeaders: {
|
|
109
|
+
...requestHeaders,
|
|
110
|
+
...wrappedRequestHeaders
|
|
111
|
+
},
|
|
112
|
+
signal
|
|
113
|
+
}), "GetActiveUserOptions", "query", variables);
|
|
114
|
+
},
|
|
115
|
+
GetClosedUserOptions(variables, requestHeaders, signal) {
|
|
116
|
+
return withWrapper((wrappedRequestHeaders) => client.request({
|
|
117
|
+
document: GetClosedUserOptionsDocument,
|
|
118
|
+
variables,
|
|
119
|
+
requestHeaders: {
|
|
120
|
+
...requestHeaders,
|
|
121
|
+
...wrappedRequestHeaders
|
|
122
|
+
},
|
|
123
|
+
signal
|
|
124
|
+
}), "GetClosedUserOptions", "query", variables);
|
|
125
|
+
},
|
|
126
|
+
GetMarketData(variables, requestHeaders, signal) {
|
|
127
|
+
return withWrapper((wrappedRequestHeaders) => client.request({
|
|
128
|
+
document: GetMarketDataDocument,
|
|
129
|
+
variables,
|
|
130
|
+
requestHeaders: {
|
|
131
|
+
...requestHeaders,
|
|
132
|
+
...wrappedRequestHeaders
|
|
133
|
+
},
|
|
134
|
+
signal
|
|
135
|
+
}), "GetMarketData", "query", variables);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/providers/TimelockMarketProvider.tsx
|
|
142
|
+
const TimelockMarketContext = createContext(void 0);
|
|
143
|
+
const TimelockMarketProvider = ({ children, marketData, envioGraphqlUrl }) => {
|
|
144
|
+
const chainId = useChainId();
|
|
145
|
+
const lensAddr = timelockLenses[chainId];
|
|
146
|
+
const uniswapMathLensAddr = uniswapMathLenses[chainId];
|
|
147
|
+
return /* @__PURE__ */ React.createElement(TimelockMarketContext.Provider, { value: {
|
|
148
|
+
marketData: marketData || {},
|
|
149
|
+
lensAddr,
|
|
150
|
+
uniswapMathLensAddr,
|
|
151
|
+
envioGraphqlUrl
|
|
152
|
+
} }, children);
|
|
153
|
+
};
|
|
154
|
+
const useCurrentMarket = () => {
|
|
155
|
+
const context = useContext(TimelockMarketContext);
|
|
156
|
+
if (context === void 0) throw new Error("useCurrentMarket must be used within a TimelockMarketProvider");
|
|
157
|
+
return context.marketData;
|
|
158
|
+
};
|
|
159
|
+
const useTimelockConfig = () => {
|
|
160
|
+
const context = useContext(TimelockMarketContext);
|
|
161
|
+
if (context === void 0) throw new Error("useConfig must be used within a TimelockMarketProvider");
|
|
162
|
+
return {
|
|
163
|
+
lensAddr: context.lensAddr,
|
|
164
|
+
uniswapMathLensAddr: context.uniswapMathLensAddr,
|
|
165
|
+
envioGraphqlUrl: context.envioGraphqlUrl,
|
|
166
|
+
graphqlClient: context.envioGraphqlUrl ? getSdk(new GraphQLClient(context.envioGraphqlUrl)) : void 0
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region src/hooks/market/useMarketData.ts
|
|
172
|
+
const useMarketData = (marketAddr) => {
|
|
173
|
+
const { graphqlClient } = useTimelockConfig();
|
|
174
|
+
const { data } = useQuery({
|
|
175
|
+
queryKey: ["marketData", marketAddr || "--"],
|
|
176
|
+
queryFn: () => graphqlClient.GetMarketData({ marketAddr: marketAddr.toLowerCase() }),
|
|
177
|
+
select: (data$1) => ({
|
|
178
|
+
...data$1.TimelockMarket[0],
|
|
179
|
+
pool: data$1.TimelockMarket[0].pool,
|
|
180
|
+
vault: data$1.TimelockMarket[0].vault,
|
|
181
|
+
optionAsset: data$1.TimelockMarket[0].optionAsset,
|
|
182
|
+
payoutAsset: data$1.TimelockMarket[0].payoutAsset,
|
|
183
|
+
optionsCount: BigInt(data$1.TimelockMarket[0].optionsCount),
|
|
184
|
+
tradersCount: BigInt(data$1.TimelockMarket[0].tradersCount)
|
|
185
|
+
}),
|
|
186
|
+
enabled: !!marketAddr && !!graphqlClient
|
|
187
|
+
});
|
|
188
|
+
return data || {};
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
//#endregion
|
|
192
|
+
//#region src/hooks/market/useExerciseOption.ts
|
|
193
|
+
const useExerciseOption = (marketAddr) => {
|
|
194
|
+
const { vault } = useMarketData(marketAddr);
|
|
195
|
+
const client = useClient();
|
|
196
|
+
const { data: lowestTick } = useReadContract({
|
|
197
|
+
address: vault,
|
|
198
|
+
abi: singleOwnerVaultAbi,
|
|
199
|
+
functionName: "lowestTick"
|
|
200
|
+
});
|
|
201
|
+
const { writeContractAsync, data: hash, isPending, error } = useWriteContract();
|
|
202
|
+
const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash });
|
|
203
|
+
const exerciseOption = async (optionId, liquidities) => {
|
|
204
|
+
if (!client) throw new Error("Wallet not connected");
|
|
205
|
+
if (lowestTick === void 0 || !marketAddr) throw new Error("Lowest tick lower not available");
|
|
206
|
+
const hash$1 = await writeContractAsync({
|
|
207
|
+
address: marketAddr,
|
|
208
|
+
abi: optionsMarketAbi,
|
|
209
|
+
functionName: "exerciseOption",
|
|
210
|
+
args: [
|
|
211
|
+
optionId,
|
|
212
|
+
liquidities,
|
|
213
|
+
0n,
|
|
214
|
+
lowestTick
|
|
215
|
+
]
|
|
216
|
+
});
|
|
217
|
+
await waitForTransactionReceipt(client, { hash: hash$1 });
|
|
218
|
+
return hash$1;
|
|
219
|
+
};
|
|
220
|
+
return {
|
|
221
|
+
exerciseOption,
|
|
222
|
+
hash,
|
|
223
|
+
isPending,
|
|
224
|
+
isConfirming,
|
|
225
|
+
isSuccess,
|
|
226
|
+
error,
|
|
227
|
+
isLoading: isPending || isConfirming
|
|
228
|
+
};
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
//#endregion
|
|
232
|
+
//#region src/hooks/useLens.ts
|
|
233
|
+
const useLens = () => {
|
|
234
|
+
const client = useClient();
|
|
235
|
+
const timelockLens = useMemo(() => client ? getTimelockLens(client) : void 0, [client]);
|
|
236
|
+
return {
|
|
237
|
+
uniswapLens: useMemo(() => client ? getUniswapMathLens(client) : void 0, [client]),
|
|
238
|
+
timelockLens
|
|
239
|
+
};
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/hooks/market/useMaxPositionSize.ts
|
|
244
|
+
const useMaxPositionSize = (marketAddr, strikeTick, maxBorrowableRange = 100) => {
|
|
245
|
+
const { timelockLens } = useLens();
|
|
246
|
+
const { optionAssetDecimals } = useMarketData(marketAddr);
|
|
247
|
+
const { data: data0, refetch: refetch0 } = useReadContract({
|
|
248
|
+
address: timelockLens === null || timelockLens === void 0 ? void 0 : timelockLens.address,
|
|
249
|
+
abi: lensAbi,
|
|
250
|
+
functionName: "getMaxPositionSizeAtCurrentTick",
|
|
251
|
+
args: [marketAddr, maxBorrowableRange],
|
|
252
|
+
query: { enabled: !!marketAddr && !!timelockLens },
|
|
253
|
+
gas: 100000000n
|
|
254
|
+
});
|
|
255
|
+
const { data: data1, refetch: refetch1 } = useReadContract({
|
|
256
|
+
address: timelockLens === null || timelockLens === void 0 ? void 0 : timelockLens.address,
|
|
257
|
+
abi: lensAbi,
|
|
258
|
+
functionName: "getMaxPositionSize",
|
|
259
|
+
args: [
|
|
260
|
+
marketAddr,
|
|
261
|
+
strikeTick,
|
|
262
|
+
maxBorrowableRange
|
|
263
|
+
],
|
|
264
|
+
query: { enabled: !!marketAddr && !!timelockLens && strikeTick !== void 0 },
|
|
265
|
+
gas: 100000000n
|
|
266
|
+
});
|
|
267
|
+
const data = strikeTick !== void 0 ? data1 : data0;
|
|
268
|
+
const { maxCallSize, maxPutSize } = useMemo(() => data && optionAssetDecimals ? {
|
|
269
|
+
maxCallSize: wrapAmount(data[0], optionAssetDecimals),
|
|
270
|
+
maxPutSize: wrapAmount(data[1], optionAssetDecimals)
|
|
271
|
+
} : {}, [data, optionAssetDecimals]);
|
|
272
|
+
const refetch = () => {
|
|
273
|
+
refetch0();
|
|
274
|
+
refetch1();
|
|
275
|
+
};
|
|
276
|
+
return {
|
|
277
|
+
maxCallSize,
|
|
278
|
+
maxPutSize,
|
|
279
|
+
refetch
|
|
280
|
+
};
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
//#endregion
|
|
284
|
+
//#region src/hooks/pool/usePoolData.ts
|
|
285
|
+
const usePoolData = (poolAddr) => {
|
|
286
|
+
const { timelockLens } = useLens();
|
|
287
|
+
const client = useClient();
|
|
288
|
+
const { data } = useReadContract({
|
|
289
|
+
address: timelockLens === null || timelockLens === void 0 ? void 0 : timelockLens.address,
|
|
290
|
+
abi: lensAbi,
|
|
291
|
+
functionName: "getPoolData",
|
|
292
|
+
args: poolAddr ? [poolAddr] : void 0,
|
|
293
|
+
query: { enabled: !!poolAddr && !!client }
|
|
294
|
+
});
|
|
295
|
+
return data || {};
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
//#endregion
|
|
299
|
+
//#region src/hooks/pool/useCurrentTick.ts
|
|
300
|
+
const useCurrentTick = (poolAddr) => {
|
|
301
|
+
const { tickSpacing } = usePoolData(poolAddr);
|
|
302
|
+
const { data } = useReadContract({
|
|
303
|
+
address: poolAddr,
|
|
304
|
+
abi: uniswapV3PoolAbi,
|
|
305
|
+
functionName: "slot0",
|
|
306
|
+
args: []
|
|
307
|
+
});
|
|
308
|
+
const exact = data === null || data === void 0 ? void 0 : data[1];
|
|
309
|
+
return {
|
|
310
|
+
exact,
|
|
311
|
+
rounded: exact && tickSpacing ? Math.floor(exact / tickSpacing) * tickSpacing : void 0
|
|
312
|
+
};
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
//#endregion
|
|
316
|
+
//#region src/hooks/market/useMintOption.ts
|
|
317
|
+
const useMintOption = (marketAddr) => {
|
|
318
|
+
const { timelockLens } = useLens();
|
|
319
|
+
const { payoutAsset, vault, pool, optionAssetIsToken0 } = useMarketData(marketAddr);
|
|
320
|
+
const { tickSpacing } = usePoolData(pool);
|
|
321
|
+
const { exact: currentTick } = useCurrentTick(pool);
|
|
322
|
+
const client = useClient();
|
|
323
|
+
const { address } = useAccount();
|
|
324
|
+
const { writeContractAsync, data: hash, isPending, error } = useWriteContract();
|
|
325
|
+
const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash });
|
|
326
|
+
const askForApproval = async (premiumAmount) => {
|
|
327
|
+
if (!client || !address) throw new Error("Wallet not connected");
|
|
328
|
+
if (!payoutAsset || !marketAddr) throw new Error("Tokens not available");
|
|
329
|
+
if (await getErc20(payoutAsset, client).read.allowance([address, marketAddr]) < premiumAmount) await waitForTransactionReceipt(client, { hash: await writeContractAsync({
|
|
330
|
+
address: payoutAsset,
|
|
331
|
+
abi: erc20Abi,
|
|
332
|
+
functionName: "approve",
|
|
333
|
+
args: [marketAddr, maxUint256]
|
|
334
|
+
}) });
|
|
335
|
+
};
|
|
336
|
+
const mintOption = async (optionType, amount, duration, strikeTick) => {
|
|
337
|
+
if (!client) throw new Error("Wallet not connected");
|
|
338
|
+
if (!timelockLens || !vault || !marketAddr || !currentTick || !tickSpacing) throw new Error("Lowest tick lower not available");
|
|
339
|
+
strikeTick = roundTickDown(strikeTick ?? currentTick, tickSpacing);
|
|
340
|
+
if (optionType === "CALL" && optionAssetIsToken0 || optionType === "PUT" && !optionAssetIsToken0) strikeTick += tickSpacing;
|
|
341
|
+
await askForApproval(await getTimelockMarket(marketAddr, client).read.calculatePremium([
|
|
342
|
+
optionType === "CALL" ? 0 : 1,
|
|
343
|
+
amount,
|
|
344
|
+
strikeTick,
|
|
345
|
+
BigInt(duration)
|
|
346
|
+
]));
|
|
347
|
+
const hash$1 = await writeContractAsync({
|
|
348
|
+
address: marketAddr,
|
|
349
|
+
abi: optionsMarketAbi,
|
|
350
|
+
functionName: "mintOption",
|
|
351
|
+
args: [
|
|
352
|
+
optionType === "CALL" ? 0 : 1,
|
|
353
|
+
amount,
|
|
354
|
+
strikeTick,
|
|
355
|
+
BigInt(duration),
|
|
356
|
+
BigInt(1e69),
|
|
357
|
+
await timelockLens.read.getRefTick([vault, strikeTick])
|
|
358
|
+
]
|
|
359
|
+
});
|
|
360
|
+
await waitForTransactionReceipt(client, { hash: hash$1 });
|
|
361
|
+
return hash$1;
|
|
362
|
+
};
|
|
363
|
+
return {
|
|
364
|
+
mintOption,
|
|
365
|
+
hash,
|
|
366
|
+
isPending,
|
|
367
|
+
isConfirming,
|
|
368
|
+
isSuccess,
|
|
369
|
+
error,
|
|
370
|
+
isLoading: isPending || isConfirming
|
|
371
|
+
};
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
//#endregion
|
|
375
|
+
//#region src/hooks/market/useOptionPnl.ts
|
|
376
|
+
const useOptionPnl = (optionData) => {
|
|
377
|
+
const { marketAddr, optionType, entryTick, positionSizeCurrent } = optionData;
|
|
378
|
+
const { pool, optionAssetIsToken0, payoutAssetDecimals } = useMarketData(marketAddr);
|
|
379
|
+
const { exact: currentTick } = useCurrentTick(pool);
|
|
380
|
+
const { displayPnl, unrealizedPayout } = useMemo(() => {
|
|
381
|
+
if (optionAssetIsToken0 === void 0 || currentTick === void 0 || !positionSizeCurrent || !payoutAssetDecimals) return {};
|
|
382
|
+
const delta = optionAssetIsToken0 ? token0ToToken1(positionSizeCurrent, currentTick) - token0ToToken1(positionSizeCurrent, entryTick) : token1ToToken0(positionSizeCurrent, currentTick) - token1ToToken0(positionSizeCurrent, entryTick);
|
|
383
|
+
const displayPnl$1 = wrapAmount(optionType === "CALL" ? delta : -delta, payoutAssetDecimals);
|
|
384
|
+
return {
|
|
385
|
+
unrealizedPayout: wrapAmount(displayPnl$1.scaled < 0 ? 0n : displayPnl$1.scaled, payoutAssetDecimals),
|
|
386
|
+
displayPnl: displayPnl$1
|
|
387
|
+
};
|
|
388
|
+
}, [
|
|
389
|
+
optionType,
|
|
390
|
+
optionAssetIsToken0,
|
|
391
|
+
entryTick,
|
|
392
|
+
currentTick,
|
|
393
|
+
positionSizeCurrent,
|
|
394
|
+
payoutAssetDecimals
|
|
395
|
+
]);
|
|
396
|
+
return {
|
|
397
|
+
displayPnl,
|
|
398
|
+
unrealizedPayout
|
|
399
|
+
};
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
//#endregion
|
|
403
|
+
//#region src/hooks/market/useOptionPremium.ts
|
|
404
|
+
const useOptionPremium = (marketAddr, optionType, optionAmount, duration) => {
|
|
405
|
+
const { pool, payoutAssetDecimals } = useMarketData(marketAddr);
|
|
406
|
+
const { tickSpacing } = usePoolData(pool);
|
|
407
|
+
const currentTick = useCurrentTick(pool);
|
|
408
|
+
const strikeTick = useMemo(() => {
|
|
409
|
+
if (currentTick.rounded === void 0 || tickSpacing === void 0) return;
|
|
410
|
+
return optionType === "CALL" ? currentTick.rounded + tickSpacing : currentTick.rounded;
|
|
411
|
+
}, [
|
|
412
|
+
currentTick.rounded,
|
|
413
|
+
tickSpacing,
|
|
414
|
+
optionType
|
|
415
|
+
]);
|
|
416
|
+
const { data: premiumData } = useReadContract({
|
|
417
|
+
address: marketAddr,
|
|
418
|
+
abi: optionsMarketAbi,
|
|
419
|
+
functionName: "calculatePremium",
|
|
420
|
+
args: strikeTick !== void 0 ? [
|
|
421
|
+
optionType === "CALL" ? 0 : 1,
|
|
422
|
+
optionAmount,
|
|
423
|
+
strikeTick,
|
|
424
|
+
BigInt(duration)
|
|
425
|
+
] : void 0,
|
|
426
|
+
query: { enabled: currentTick.rounded !== void 0 && payoutAssetDecimals !== void 0 && tickSpacing !== void 0 && strikeTick !== void 0 }
|
|
427
|
+
});
|
|
428
|
+
return useMemo(() => {
|
|
429
|
+
if (premiumData === void 0 || payoutAssetDecimals === void 0) return;
|
|
430
|
+
return wrapAmount(premiumData, payoutAssetDecimals);
|
|
431
|
+
}, [premiumData, payoutAssetDecimals]);
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
//#endregion
|
|
435
|
+
//#region src/hooks/market/useUserOptions.ts
|
|
436
|
+
const useUserOptions = (user, active = false) => {
|
|
437
|
+
const { graphqlClient } = useTimelockConfig();
|
|
438
|
+
const { data: options,...rest } = useQuery({
|
|
439
|
+
queryKey: [
|
|
440
|
+
"userTrades",
|
|
441
|
+
user || "--",
|
|
442
|
+
active
|
|
443
|
+
],
|
|
444
|
+
queryFn: () => active ? graphqlClient === null || graphqlClient === void 0 ? void 0 : graphqlClient.GetActiveUserOptions({ user: user.toLowerCase() }) : graphqlClient === null || graphqlClient === void 0 ? void 0 : graphqlClient.GetClosedUserOptions({ user: user.toLowerCase() }),
|
|
445
|
+
select: (data) => {
|
|
446
|
+
var _data$UserOption;
|
|
447
|
+
return data === null || data === void 0 || (_data$UserOption = data.UserOption) === null || _data$UserOption === void 0 ? void 0 : _data$UserOption.map((option) => ({
|
|
448
|
+
...option,
|
|
449
|
+
id: BigInt(option.id),
|
|
450
|
+
marketAddr: option.marketAddr,
|
|
451
|
+
optionType: option.optionType,
|
|
452
|
+
createdAt: /* @__PURE__ */ new Date(Number(option.createdAt) * 1e3),
|
|
453
|
+
expiresAt: /* @__PURE__ */ new Date(Number(option.expiresAt) * 1e3),
|
|
454
|
+
premiumPaid: BigInt(option.premiumPaid),
|
|
455
|
+
realizedPayout: BigInt(option.realizedPayout),
|
|
456
|
+
liquiditiesAtOpen: option.liquiditiesAtOpen.map((liquidity) => BigInt(liquidity)),
|
|
457
|
+
liquiditiesCurrent: option.liquiditiesCurrent.map((liquidity) => BigInt(liquidity)),
|
|
458
|
+
positionSizeAtOpen: BigInt(option.positionSizeAtOpen),
|
|
459
|
+
positionSizeCurrent: BigInt(option.positionSizeCurrent),
|
|
460
|
+
strikePrice: BigInt(option.strikePrice),
|
|
461
|
+
entryPrice: BigInt(option.entryPrice)
|
|
462
|
+
}));
|
|
463
|
+
},
|
|
464
|
+
enabled: !!user && !!graphqlClient
|
|
465
|
+
});
|
|
466
|
+
return {
|
|
467
|
+
data: useMemo(() => (options === null || options === void 0 ? void 0 : options.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())) || [], [options]),
|
|
468
|
+
...rest
|
|
469
|
+
};
|
|
470
|
+
};
|
|
471
|
+
const useActiveUserOptions = (user) => {
|
|
472
|
+
return useUserOptions(user, true);
|
|
473
|
+
};
|
|
474
|
+
const useClosedUserOptions = (user) => {
|
|
475
|
+
return useUserOptions(user, false);
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
//#endregion
|
|
479
|
+
//#region src/hooks/pool/usePriceAtTick.ts
|
|
480
|
+
const usePriceAtTick = (tick, poolAddr) => {
|
|
481
|
+
const { token0Decimals, token1Decimals } = usePoolData(poolAddr);
|
|
482
|
+
const priceBigInt = useMemo(() => tick ? getPriceAtTick(tick) : void 0, [tick]);
|
|
483
|
+
return useMemo(() => priceBigInt && token0Decimals && token1Decimals ? wrapPrice(priceBigInt, token0Decimals, token1Decimals) : void 0, [
|
|
484
|
+
priceBigInt,
|
|
485
|
+
token0Decimals,
|
|
486
|
+
token1Decimals
|
|
487
|
+
]);
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
//#endregion
|
|
491
|
+
//#region src/hooks/pool/useCurrentPrice.ts
|
|
492
|
+
const useCurrentPrice = (poolAddr) => {
|
|
493
|
+
const currentTick = useCurrentTick(poolAddr);
|
|
494
|
+
return {
|
|
495
|
+
currentPrice: usePriceAtTick(currentTick.exact, poolAddr),
|
|
496
|
+
currentTick
|
|
497
|
+
};
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
//#endregion
|
|
501
|
+
//#region src/hooks/vault/useVaultData.ts
|
|
502
|
+
const useVaultData = (vaultAddr) => {
|
|
503
|
+
const { data } = useReadContract({
|
|
504
|
+
address: vaultAddr,
|
|
505
|
+
abi: singleOwnerVaultAbi,
|
|
506
|
+
functionName: "pool"
|
|
507
|
+
});
|
|
508
|
+
return { pool: data };
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
//#endregion
|
|
512
|
+
//#region src/hooks/vault/useBurnLiquidity.ts
|
|
513
|
+
const useBurnLiquidity = (vaultAddr) => {
|
|
514
|
+
const client = useClient();
|
|
515
|
+
const { timelockLens } = useLens();
|
|
516
|
+
const { pool } = useVaultData(vaultAddr);
|
|
517
|
+
const currentTick = useCurrentTick(pool);
|
|
518
|
+
const { writeContractAsync, data: hash, isPending, error } = useWriteContract();
|
|
519
|
+
const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash });
|
|
520
|
+
const burn = async (tickLower, tickUpper, liquidity) => {
|
|
521
|
+
if (!client) throw new Error("Wallet not connected");
|
|
522
|
+
if (!vaultAddr || !timelockLens) throw new Error("Vault/lens not available");
|
|
523
|
+
const hash$1 = await writeContractAsync({
|
|
524
|
+
address: vaultAddr,
|
|
525
|
+
abi: singleOwnerVaultAbi,
|
|
526
|
+
functionName: "burn",
|
|
527
|
+
args: [
|
|
528
|
+
tickLower,
|
|
529
|
+
tickUpper,
|
|
530
|
+
liquidity,
|
|
531
|
+
await timelockLens.read.getRefTick([vaultAddr, tickLower])
|
|
532
|
+
]
|
|
533
|
+
});
|
|
534
|
+
await waitForTransactionReceipt(client, { hash: hash$1 });
|
|
535
|
+
return hash$1;
|
|
536
|
+
};
|
|
537
|
+
const burnMultiple = async (positions) => {
|
|
538
|
+
if (!client) throw new Error("Wallet not connected");
|
|
539
|
+
if (!currentTick.exact) throw new Error("Current tick not available");
|
|
540
|
+
if (positions.length === 0) throw new Error("No positions to burn");
|
|
541
|
+
if (!timelockLens || !vaultAddr) throw new Error("Vault/lens not available");
|
|
542
|
+
if (positions.length === 1) await burn(positions[0].tickLower, positions[0].tickUpper, positions[0].liquidity);
|
|
543
|
+
else {
|
|
544
|
+
const refTicks = await timelockLens.read.batchGetRefTick([vaultAddr, positions.map((position) => position.tickLower)]);
|
|
545
|
+
await waitForTransactionReceipt(client, { hash: await writeContractAsync({
|
|
546
|
+
address: vaultAddr,
|
|
547
|
+
abi: singleOwnerVaultAbi,
|
|
548
|
+
functionName: "multicall",
|
|
549
|
+
args: [positions.map((p, i) => encodeFunctionData({
|
|
550
|
+
abi: singleOwnerVaultAbi,
|
|
551
|
+
functionName: "burn",
|
|
552
|
+
args: [
|
|
553
|
+
p.tickLower,
|
|
554
|
+
p.tickUpper,
|
|
555
|
+
p.liquidity,
|
|
556
|
+
refTicks[i]
|
|
557
|
+
]
|
|
558
|
+
}))]
|
|
559
|
+
}) });
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
return {
|
|
563
|
+
burnMultiple,
|
|
564
|
+
burn,
|
|
565
|
+
hash,
|
|
566
|
+
isPending,
|
|
567
|
+
isConfirming,
|
|
568
|
+
isSuccess,
|
|
569
|
+
error,
|
|
570
|
+
isLoading: isPending || isConfirming
|
|
571
|
+
};
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
//#endregion
|
|
575
|
+
//#region src/hooks/vault/useLiquidityBlocks.ts
|
|
576
|
+
const useLiquidityBlocks = (vaultAddr) => {
|
|
577
|
+
const { timelockLens } = useLens();
|
|
578
|
+
const { data: blocks = [],...rest } = useReadContract({
|
|
579
|
+
address: timelockLens === null || timelockLens === void 0 ? void 0 : timelockLens.address,
|
|
580
|
+
abi: lensAbi,
|
|
581
|
+
functionName: "getAllBlocks",
|
|
582
|
+
args: [vaultAddr],
|
|
583
|
+
query: { enabled: !!vaultAddr && !!timelockLens }
|
|
584
|
+
});
|
|
585
|
+
return {
|
|
586
|
+
data: blocks,
|
|
587
|
+
...rest
|
|
588
|
+
};
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
//#endregion
|
|
592
|
+
//#region src/hooks/vault/useMintLiquidity.ts
|
|
593
|
+
const batchGetAmountsFromLiquidity = async (lens, tickLower, tickUpper, liquidity, currentTick) => {
|
|
594
|
+
const currentTicksArray = new Array(tickLower.length).fill(currentTick);
|
|
595
|
+
const amounts = await lens.read.batchGetAmountsForLiquidityTicks([
|
|
596
|
+
currentTicksArray,
|
|
597
|
+
tickLower,
|
|
598
|
+
tickUpper,
|
|
599
|
+
liquidity
|
|
600
|
+
]);
|
|
601
|
+
let totalAmount0 = 0n;
|
|
602
|
+
let totalAmount1 = 0n;
|
|
603
|
+
const amounts0 = [];
|
|
604
|
+
const amounts1 = [];
|
|
605
|
+
for (const scaled of amounts[0]) {
|
|
606
|
+
totalAmount0 += scaled;
|
|
607
|
+
amounts0.push(scaled);
|
|
608
|
+
}
|
|
609
|
+
for (const scaled of amounts[1]) {
|
|
610
|
+
totalAmount1 += scaled;
|
|
611
|
+
amounts1.push(scaled);
|
|
612
|
+
}
|
|
613
|
+
return {
|
|
614
|
+
totalAmount0,
|
|
615
|
+
totalAmount1,
|
|
616
|
+
amounts0,
|
|
617
|
+
amounts1
|
|
618
|
+
};
|
|
619
|
+
};
|
|
620
|
+
const useMintLiquidity = (vaultAddr) => {
|
|
621
|
+
const client = useClient();
|
|
622
|
+
const { address } = useAccount();
|
|
623
|
+
const { pool } = useVaultData(vaultAddr);
|
|
624
|
+
const { timelockLens, uniswapLens } = useLens();
|
|
625
|
+
const currentTick = useCurrentTick(pool);
|
|
626
|
+
const { token0, token1 } = usePoolData(pool);
|
|
627
|
+
const { writeContractAsync, data: hash, isPending, error } = useWriteContract();
|
|
628
|
+
const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash });
|
|
629
|
+
const askForApproval = async (params) => {
|
|
630
|
+
if (!address || !client) throw new Error("Wallet not connected");
|
|
631
|
+
if (currentTick.exact === void 0 || !token0 || !token1 || !vaultAddr || !uniswapLens) throw new Error("Current tick not available");
|
|
632
|
+
const { totalAmount0, totalAmount1 } = await batchGetAmountsFromLiquidity(uniswapLens, params.map((p) => p.tickLower), params.map((p) => p.tickUpper), params.map((p) => p.liquidity), currentTick.exact);
|
|
633
|
+
const [allowance0, allowance1] = await Promise.all([getErc20(token0, client).read.allowance([address, vaultAddr]), getErc20(token1, client).read.allowance([address, vaultAddr])]);
|
|
634
|
+
const approvalPromises = [];
|
|
635
|
+
if (allowance0 <= totalAmount0) {
|
|
636
|
+
const approvalHash = await writeContractAsync({
|
|
637
|
+
address: token0,
|
|
638
|
+
abi: erc20Abi,
|
|
639
|
+
functionName: "approve",
|
|
640
|
+
args: [vaultAddr, maxUint256]
|
|
641
|
+
});
|
|
642
|
+
approvalPromises.push(waitForTransactionReceipt(client, { hash: approvalHash }));
|
|
643
|
+
}
|
|
644
|
+
if (allowance1 <= totalAmount1) {
|
|
645
|
+
const approvalHash1 = await writeContractAsync({
|
|
646
|
+
address: token1,
|
|
647
|
+
abi: erc20Abi,
|
|
648
|
+
functionName: "approve",
|
|
649
|
+
args: [vaultAddr, maxUint256]
|
|
650
|
+
});
|
|
651
|
+
approvalPromises.push(waitForTransactionReceipt(client, { hash: approvalHash1 }));
|
|
652
|
+
}
|
|
653
|
+
if (approvalPromises.length > 0) await Promise.all(approvalPromises);
|
|
654
|
+
};
|
|
655
|
+
const mint = async (tickLower, tickUpper, liquidity) => {
|
|
656
|
+
if (!client) throw new Error("Wallet not connected");
|
|
657
|
+
if (!vaultAddr || !timelockLens) throw new Error("Vault/lens not available");
|
|
658
|
+
await askForApproval([{
|
|
659
|
+
tickLower,
|
|
660
|
+
tickUpper,
|
|
661
|
+
liquidity
|
|
662
|
+
}]);
|
|
663
|
+
const hash$1 = await writeContractAsync({
|
|
664
|
+
address: vaultAddr,
|
|
665
|
+
abi: singleOwnerVaultAbi,
|
|
666
|
+
functionName: "mint",
|
|
667
|
+
args: [
|
|
668
|
+
tickLower,
|
|
669
|
+
tickUpper,
|
|
670
|
+
liquidity,
|
|
671
|
+
await timelockLens.read.getRefTick([vaultAddr, tickLower])
|
|
672
|
+
]
|
|
673
|
+
});
|
|
674
|
+
await waitForTransactionReceipt(client, { hash: hash$1 });
|
|
675
|
+
return hash$1;
|
|
676
|
+
};
|
|
677
|
+
const mintMultiple = async (positions) => {
|
|
678
|
+
if (!client) throw new Error("Wallet not connected");
|
|
679
|
+
if (!currentTick.exact) throw new Error("Current tick not available");
|
|
680
|
+
if (positions.length === 0) throw new Error("No positions to mint");
|
|
681
|
+
if (!timelockLens || !vaultAddr) throw new Error("Vault/lens not available");
|
|
682
|
+
if (positions.length === 1) await mint(positions[0].tickLower, positions[0].tickUpper, positions[0].liquidity);
|
|
683
|
+
else {
|
|
684
|
+
await askForApproval(positions);
|
|
685
|
+
const refTicks = await timelockLens.read.batchGetRefTick([vaultAddr, positions.map((position) => position.tickLower)]);
|
|
686
|
+
await waitForTransactionReceipt(client, { hash: await writeContractAsync({
|
|
687
|
+
address: vaultAddr,
|
|
688
|
+
abi: singleOwnerVaultAbi,
|
|
689
|
+
functionName: "multicall",
|
|
690
|
+
args: [positions.map((p, i) => encodeFunctionData({
|
|
691
|
+
abi: singleOwnerVaultAbi,
|
|
692
|
+
functionName: "mint",
|
|
693
|
+
args: [
|
|
694
|
+
p.tickLower,
|
|
695
|
+
p.tickUpper,
|
|
696
|
+
p.liquidity,
|
|
697
|
+
refTicks[i]
|
|
698
|
+
]
|
|
699
|
+
}))]
|
|
700
|
+
}) });
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
return {
|
|
704
|
+
mintMultiple,
|
|
705
|
+
mint,
|
|
706
|
+
hash,
|
|
707
|
+
isPending,
|
|
708
|
+
isConfirming,
|
|
709
|
+
isSuccess,
|
|
710
|
+
error,
|
|
711
|
+
isLoading: isPending || isConfirming
|
|
712
|
+
};
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
//#endregion
|
|
716
|
+
//#region src/hooks/vault/useVaultTVL.ts
|
|
717
|
+
const useVaultTVL = (vaultAddr) => {
|
|
718
|
+
const { timelockLens } = useLens();
|
|
719
|
+
const { pool } = useVaultData(vaultAddr);
|
|
720
|
+
const { token0Decimals, token1Decimals } = usePoolData(pool);
|
|
721
|
+
const { data, refetch } = useReadContract({
|
|
722
|
+
address: timelockLens === null || timelockLens === void 0 ? void 0 : timelockLens.address,
|
|
723
|
+
abi: lensAbi,
|
|
724
|
+
functionName: "getVaultTVL",
|
|
725
|
+
args: [vaultAddr],
|
|
726
|
+
query: { enabled: !!vaultAddr && !!timelockLens }
|
|
727
|
+
});
|
|
728
|
+
const totalAmount0 = data && token0Decimals ? wrapAmount(data[0], token0Decimals) : void 0;
|
|
729
|
+
const totalAmount1 = data && token1Decimals ? wrapAmount(data[1], token1Decimals) : void 0;
|
|
730
|
+
const borrowedAmount0 = data && token0Decimals ? wrapAmount(data[2], token0Decimals) : void 0;
|
|
731
|
+
const borrowedAmount1 = data && token1Decimals ? wrapAmount(data[3], token1Decimals) : void 0;
|
|
732
|
+
return {
|
|
733
|
+
tvl0: data && token0Decimals ? wrapAmount(data[4], token0Decimals) : void 0,
|
|
734
|
+
tvl1: data && token1Decimals ? wrapAmount(data[5], token1Decimals) : void 0,
|
|
735
|
+
totalAmount0,
|
|
736
|
+
totalAmount1,
|
|
737
|
+
borrowedAmount0,
|
|
738
|
+
borrowedAmount1,
|
|
739
|
+
blocksCount: data === null || data === void 0 ? void 0 : data[6],
|
|
740
|
+
refetch
|
|
741
|
+
};
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
//#endregion
|
|
745
|
+
export { TimelockMarketProvider, batchGetAmountsFromLiquidity, useActiveUserOptions, useBurnLiquidity, useClosedUserOptions, useCurrentMarket, useCurrentPrice, useCurrentTick, useExerciseOption, useLens, useLiquidityBlocks, useMarketData, useMaxPositionSize, useMintLiquidity, useMintOption, useOptionPnl, useOptionPremium, usePoolData, usePriceAtTick, useTimelockConfig, useVaultData, useVaultTVL };
|
|
746
|
+
//# sourceMappingURL=client.js.map
|