@gearbox-protocol/ui-kit 3.5.1 → 3.5.2
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/cjs/components/pool-apy-tooltip/pool-apy-tooltip.cjs +1 -1
- package/dist/esm/components/pool-apy-tooltip/pool-apy-tooltip.js +75 -69
- package/dist/types/components/composites/pool-table/pool-table-backend-contract.types.d.ts +168 -17
- package/dist/types/components/pool-apy-tooltip/pool-apy-tooltip.d.ts +2 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),v=require("@fortawesome/free-solid-svg-icons"),_=require("@gearbox-protocol/static"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),v=require("@fortawesome/free-solid-svg-icons"),_=require("@gearbox-protocol/static"),f=require("../compound-apy/compound-apy.cjs"),w=require("../icons/fa-icon.cjs"),P=require("../points-icon/points-icon.cjs"),N=require("../skeleton/skeleton.cjs");require("react");require("@gearbox-protocol/sdk");const u=require("../../utils/cn.cjs");require("sonner");const n=require("../../utils/format-money.cjs");require("@gearbox-protocol/sdk/common-utils");require("luxon");require("../../utils/z-index.cjs");const q=require("../token-icon/token-icon.cjs"),k=require("../tooltip/simple-tooltip.cjs");require("../tooltip/tooltip.cjs");const t=require("../typed-intl/index.cjs"),l=require("../vertical-indicator/vertical-indicator.cjs"),j=require("../vertical-list/vertical-list.cjs"),S={supplyAPY:"components.apyParts.supplyAPY",tokenYield:"components.apyParts.tokenYield"},F={supplyAPY:"components.apyParts.supplyAPY.tip",tokenYield:"components.apyParts.tokenYield.tip"},h={deposit:void 0,"cross-chain-deposit":"components.apyParts.points.condition.crossDeposit",holding:void 0};function L({children:c}){return e.jsx("div",{className:"w-[110px] grid grid-cols-2 items-end text-end",children:c})}function M({children:c,totalAPY:g,baseAPY:p,extraAPY:m,points:a,apy7DAgo:o,externalAPY:r,tokensList:T,className:x}){if(!(g!==void 0||p&&p.length>0||m&&m.length>0||a&&a.length>0))return e.jsx("span",{className:x,children:c});const I=!o||!!o.totalAPYLoading||!!o.loading7DAgo,y=!!o,d=(s,i)=>y?e.jsxs(L,{children:[e.jsx("span",{children:s}),e.jsx("span",{children:e.jsx(N.Skeleton,{width:30,height:14,loading:I,children:i})})]}):s,b=e.jsxs("div",{className:u.cn("w-[370px] max-w-[calc(100vw-32px)] p-6","bg-popover","border border-border","rounded-lg","shadow-[0_4px_28px_4px_rgba(0,0,0,0.15)]","text-left font-normal"),children:[e.jsxs(j.VerticalList,{children:[y&&e.jsx(l.VerticalIndicator,{size:"sm",label:e.jsx("span",{className:"uppercase text-muted-foreground text-xs",children:e.jsx(t.FormattedMessageTyped,{messageId:"components.apyParts.title"})}),value:e.jsx("span",{className:"text-muted-foreground text-xs",children:d("1D","7D")})}),p?.map((s,i)=>e.jsx(l.VerticalIndicator,{size:"sm",label:e.jsx(t.FormattedMessageTyped,{messageId:S[s.type]}),description:e.jsx(t.FormattedMessageTyped,{messageId:F[s.type]}),value:d(n.percentTemplate(s.apy),n.percentTemplate(o?.baseAPY?.[i]?.apy||0))},`base-${s.type}-${s.apy}`)),m?.map(s=>{const i=T?.[s.rewardToken];return e.jsx(l.VerticalIndicator,{size:"sm",label:e.jsxs("span",{className:"inline-flex items-center",children:[e.jsx(t.FormattedMessageTyped,{messageId:"components.apyParts.extraAPY",values:{symbol:s.rewardTokenSymbol}}),e.jsx("span",{className:"ml-1 inline-flex",children:e.jsx(q.TokenIcon,{symbol:f.getRewardTokenSymbol(i,s.rewardTokenSymbol),size:14})})]}),description:e.jsx(t.FormattedMessageTyped,{messageId:"components.apyParts.extraAPY.tip"}),value:d(n.percentTemplate(s.apy),n.percentTemplate(s.apy))},`extra-${s.rewardToken}-${s.apy}`)})]}),e.jsx("div",{className:"my-5 border-t border-border"}),e.jsx(j.VerticalList,{children:e.jsx(l.VerticalIndicator,{size:"sm",label:e.jsx("span",{className:"font-bold",children:e.jsx(t.FormattedMessageTyped,{messageId:"components.apyParts.totalAPY"})}),value:d(n.percentTemplate(g||0),n.percentTemplate(o?.totalAPY||0))})}),r&&e.jsx("div",{className:u.cn("mt-5 px-8 pt-[18px] pb-4","rounded-[10px]","text-[13px] leading-[120%] text-center","border border-dashed border-gray-40"),children:(()=>{const s=e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"text-gray-90 mr-1.5",children:e.jsx(_.IconLighting,{size:14,style:{verticalAlign:"top"}})}),e.jsxs("span",{className:"font-bold",children:["+",n.percentTemplate(r.apy)]})]});return r.tooltip?e.jsx(t.FormattedMessageTyped,{messageId:r.tooltip,values:{name:r.name,value:s}}):e.jsxs("span",{className:"inline-flex flex-wrap items-center justify-center gap-x-1",children:[e.jsx("span",{children:r.name}),s]})})()}),a&&a.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"relative my-2.5 mx-6 border-t-2 border-border",children:e.jsx("div",{className:u.cn("absolute -top-[10px] left-0","w-5 h-5","flex items-center justify-center","rounded-full","bg-gray-20"),children:e.jsx(w.FaIcon,{icon:v.faPlus,className:"size-2.5 text-white"})})}),e.jsx("div",{className:"h-6"}),e.jsx(j.VerticalList,{children:a.map(s=>e.jsx(l.VerticalIndicator,{size:"sm",label:e.jsxs("span",{className:"inline-flex items-center",children:[e.jsx(t.FormattedMessageTyped,{messageId:"components.apyParts.points",values:{symbol:s.name}}),s.reward&&e.jsx("span",{className:"ml-2 inline-flex",children:e.jsx(P.PointsIcon,{reward:{name:s.reward.name||s.name,type:s.reward.type||s.name.toLowerCase()},size:16})})]}),description:e.jsxs("div",{children:[e.jsx("div",{children:`Per ${[...s.reward?.duration?[s.reward.duration]:[],...s.tokenTitle?[`1 ${s.tokenTitle}`]:[]].join(" per ")}`}),s.reward?.condition&&h[s.reward.condition]&&e.jsx("span",{className:"text-warning",children:e.jsx(t.FormattedMessageTyped,{messageId:h[s.reward.condition]})})]}),value:s.amount},`points-${s.name}-${s.amount}`))})]})]});return e.jsx(k.SimpleTooltip,{placement:"bottom",triangle:!1,type:"modal-tooltip",minWidth:"100%",maxWidth:"100%",title:e.jsx("span",{className:x,children:c}),triggerClassName:x,children:b})}exports.PoolAPYTooltip=M;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsx as e, jsxs as
|
|
2
|
-
import { faPlus as
|
|
1
|
+
import { jsx as e, jsxs as n, Fragment as b } from "react/jsx-runtime";
|
|
2
|
+
import { faPlus as P } from "@fortawesome/free-solid-svg-icons";
|
|
3
3
|
import { IconLighting as T } from "@gearbox-protocol/static";
|
|
4
4
|
import { getRewardTokenSymbol as k } from "../compound-apy/compound-apy.js";
|
|
5
5
|
import { FaIcon as S } from "../icons/fa-icon.js";
|
|
@@ -7,22 +7,22 @@ import { PointsIcon as _ } from "../points-icon/points-icon.js";
|
|
|
7
7
|
import { Skeleton as z } from "../skeleton/skeleton.js";
|
|
8
8
|
import "react";
|
|
9
9
|
import "@gearbox-protocol/sdk";
|
|
10
|
-
import { cn as
|
|
10
|
+
import { cn as u } from "../../utils/cn.js";
|
|
11
11
|
import "sonner";
|
|
12
12
|
import { percentTemplate as r } from "../../utils/format-money.js";
|
|
13
13
|
import "@gearbox-protocol/sdk/common-utils";
|
|
14
14
|
import "luxon";
|
|
15
15
|
import "../../utils/z-index.js";
|
|
16
16
|
import { TokenIcon as C } from "../token-icon/token-icon.js";
|
|
17
|
-
import { SimpleTooltip as
|
|
17
|
+
import { SimpleTooltip as L } from "../tooltip/simple-tooltip.js";
|
|
18
18
|
import "../tooltip/tooltip.js";
|
|
19
|
-
import { FormattedMessageTyped as
|
|
20
|
-
import { VerticalIndicator as
|
|
21
|
-
import { VerticalList as
|
|
22
|
-
const
|
|
19
|
+
import { FormattedMessageTyped as o } from "../typed-intl/index.js";
|
|
20
|
+
import { VerticalIndicator as d } from "../vertical-indicator/vertical-indicator.js";
|
|
21
|
+
import { VerticalList as y } from "../vertical-list/vertical-list.js";
|
|
22
|
+
const $ = {
|
|
23
23
|
supplyAPY: "components.apyParts.supplyAPY",
|
|
24
24
|
tokenYield: "components.apyParts.tokenYield"
|
|
25
|
-
},
|
|
25
|
+
}, O = {
|
|
26
26
|
supplyAPY: "components.apyParts.supplyAPY.tip",
|
|
27
27
|
tokenYield: "components.apyParts.tokenYield.tip"
|
|
28
28
|
}, v = {
|
|
@@ -30,29 +30,29 @@ const A = {
|
|
|
30
30
|
"cross-chain-deposit": "components.apyParts.points.condition.crossDeposit",
|
|
31
31
|
holding: void 0
|
|
32
32
|
};
|
|
33
|
-
function
|
|
34
|
-
return /* @__PURE__ */ e("div", { className: "w-[110px] grid grid-cols-2 items-end text-end", children:
|
|
33
|
+
function Y({ children: m }) {
|
|
34
|
+
return /* @__PURE__ */ e("div", { className: "w-[110px] grid grid-cols-2 items-end text-end", children: m });
|
|
35
35
|
}
|
|
36
|
-
function
|
|
37
|
-
children:
|
|
36
|
+
function oe({
|
|
37
|
+
children: m,
|
|
38
38
|
totalAPY: f,
|
|
39
39
|
baseAPY: c,
|
|
40
40
|
extraAPY: h,
|
|
41
|
-
points:
|
|
41
|
+
points: i,
|
|
42
42
|
apy7DAgo: a,
|
|
43
|
-
externalAPY:
|
|
43
|
+
externalAPY: s,
|
|
44
44
|
tokensList: w,
|
|
45
45
|
className: g
|
|
46
46
|
}) {
|
|
47
|
-
if (!(f !== void 0 || c && c.length > 0 || h && h.length > 0 ||
|
|
48
|
-
return /* @__PURE__ */ e("span", { className: g, children:
|
|
49
|
-
const I = !a || !!a.totalAPYLoading || !!a.loading7DAgo, x = !!a, p = (t,
|
|
47
|
+
if (!(f !== void 0 || c && c.length > 0 || h && h.length > 0 || i && i.length > 0))
|
|
48
|
+
return /* @__PURE__ */ e("span", { className: g, children: m });
|
|
49
|
+
const I = !a || !!a.totalAPYLoading || !!a.loading7DAgo, x = !!a, p = (t, l) => x ? /* @__PURE__ */ n(Y, { children: [
|
|
50
50
|
/* @__PURE__ */ e("span", { children: t }),
|
|
51
|
-
/* @__PURE__ */ e("span", { children: /* @__PURE__ */ e(z, { width: 30, height: 14, loading: I, children:
|
|
52
|
-
] }) : t,
|
|
51
|
+
/* @__PURE__ */ e("span", { children: /* @__PURE__ */ e(z, { width: 30, height: 14, loading: I, children: l }) })
|
|
52
|
+
] }) : t, N = /* @__PURE__ */ n(
|
|
53
53
|
"div",
|
|
54
54
|
{
|
|
55
|
-
className:
|
|
55
|
+
className: u(
|
|
56
56
|
"w-[370px] max-w-[calc(100vw-32px)] p-6",
|
|
57
57
|
"bg-popover",
|
|
58
58
|
"border border-border",
|
|
@@ -61,13 +61,13 @@ function ne({
|
|
|
61
61
|
"text-left font-normal"
|
|
62
62
|
),
|
|
63
63
|
children: [
|
|
64
|
-
/* @__PURE__ */
|
|
64
|
+
/* @__PURE__ */ n(y, { children: [
|
|
65
65
|
x && /* @__PURE__ */ e(
|
|
66
|
-
|
|
66
|
+
d,
|
|
67
67
|
{
|
|
68
68
|
size: "sm",
|
|
69
69
|
label: /* @__PURE__ */ e("span", { className: "uppercase text-muted-foreground text-xs", children: /* @__PURE__ */ e(
|
|
70
|
-
|
|
70
|
+
o,
|
|
71
71
|
{
|
|
72
72
|
messageId: "components.apyParts.title"
|
|
73
73
|
}
|
|
@@ -75,33 +75,33 @@ function ne({
|
|
|
75
75
|
value: /* @__PURE__ */ e("span", { className: "text-muted-foreground text-xs", children: p("1D", "7D") })
|
|
76
76
|
}
|
|
77
77
|
),
|
|
78
|
-
c?.map((t,
|
|
79
|
-
|
|
78
|
+
c?.map((t, l) => /* @__PURE__ */ e(
|
|
79
|
+
d,
|
|
80
80
|
{
|
|
81
81
|
size: "sm",
|
|
82
|
-
label: /* @__PURE__ */ e(
|
|
82
|
+
label: /* @__PURE__ */ e(o, { messageId: $[t.type] }),
|
|
83
83
|
description: /* @__PURE__ */ e(
|
|
84
|
-
|
|
84
|
+
o,
|
|
85
85
|
{
|
|
86
|
-
messageId:
|
|
86
|
+
messageId: O[t.type]
|
|
87
87
|
}
|
|
88
88
|
),
|
|
89
89
|
value: p(
|
|
90
90
|
r(t.apy),
|
|
91
|
-
r(a?.baseAPY?.[
|
|
91
|
+
r(a?.baseAPY?.[l]?.apy || 0)
|
|
92
92
|
)
|
|
93
93
|
},
|
|
94
94
|
`base-${t.type}-${t.apy}`
|
|
95
95
|
)),
|
|
96
96
|
h?.map((t) => {
|
|
97
|
-
const
|
|
97
|
+
const l = w?.[t.rewardToken];
|
|
98
98
|
return /* @__PURE__ */ e(
|
|
99
|
-
|
|
99
|
+
d,
|
|
100
100
|
{
|
|
101
101
|
size: "sm",
|
|
102
|
-
label: /* @__PURE__ */
|
|
102
|
+
label: /* @__PURE__ */ n("span", { className: "inline-flex items-center", children: [
|
|
103
103
|
/* @__PURE__ */ e(
|
|
104
|
-
|
|
104
|
+
o,
|
|
105
105
|
{
|
|
106
106
|
messageId: "components.apyParts.extraAPY",
|
|
107
107
|
values: { symbol: t.rewardTokenSymbol }
|
|
@@ -110,13 +110,13 @@ function ne({
|
|
|
110
110
|
/* @__PURE__ */ e("span", { className: "ml-1 inline-flex", children: /* @__PURE__ */ e(
|
|
111
111
|
C,
|
|
112
112
|
{
|
|
113
|
-
symbol: k(
|
|
113
|
+
symbol: k(l, t.rewardTokenSymbol),
|
|
114
114
|
size: 14
|
|
115
115
|
}
|
|
116
116
|
) })
|
|
117
117
|
] }),
|
|
118
118
|
description: /* @__PURE__ */ e(
|
|
119
|
-
|
|
119
|
+
o,
|
|
120
120
|
{
|
|
121
121
|
messageId: "components.apyParts.extraAPY.tip"
|
|
122
122
|
}
|
|
@@ -131,12 +131,12 @@ function ne({
|
|
|
131
131
|
})
|
|
132
132
|
] }),
|
|
133
133
|
/* @__PURE__ */ e("div", { className: "my-5 border-t border-border" }),
|
|
134
|
-
/* @__PURE__ */ e(
|
|
135
|
-
|
|
134
|
+
/* @__PURE__ */ e(y, { children: /* @__PURE__ */ e(
|
|
135
|
+
d,
|
|
136
136
|
{
|
|
137
137
|
size: "sm",
|
|
138
138
|
label: /* @__PURE__ */ e("span", { className: "font-bold", children: /* @__PURE__ */ e(
|
|
139
|
-
|
|
139
|
+
o,
|
|
140
140
|
{
|
|
141
141
|
messageId: "components.apyParts.totalAPY"
|
|
142
142
|
}
|
|
@@ -147,55 +147,61 @@ function ne({
|
|
|
147
147
|
)
|
|
148
148
|
}
|
|
149
149
|
) }),
|
|
150
|
-
|
|
150
|
+
s && /* @__PURE__ */ e(
|
|
151
151
|
"div",
|
|
152
152
|
{
|
|
153
|
-
className:
|
|
153
|
+
className: u(
|
|
154
154
|
"mt-5 px-8 pt-[18px] pb-4",
|
|
155
155
|
"rounded-[10px]",
|
|
156
156
|
"text-[13px] leading-[120%] text-center",
|
|
157
157
|
"border border-dashed border-gray-40"
|
|
158
158
|
),
|
|
159
|
-
children:
|
|
160
|
-
n,
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
159
|
+
children: (() => {
|
|
160
|
+
const t = /* @__PURE__ */ n(b, { children: [
|
|
161
|
+
/* @__PURE__ */ e("span", { className: "text-gray-90 mr-1.5", children: /* @__PURE__ */ e(T, { size: 14, style: { verticalAlign: "top" } }) }),
|
|
162
|
+
/* @__PURE__ */ n("span", { className: "font-bold", children: [
|
|
163
|
+
"+",
|
|
164
|
+
r(s.apy)
|
|
165
|
+
] })
|
|
166
|
+
] });
|
|
167
|
+
return s.tooltip ? /* @__PURE__ */ e(
|
|
168
|
+
o,
|
|
169
|
+
{
|
|
170
|
+
messageId: s.tooltip,
|
|
171
|
+
values: {
|
|
172
|
+
name: s.name,
|
|
173
|
+
value: t
|
|
174
|
+
}
|
|
172
175
|
}
|
|
173
|
-
|
|
174
|
-
|
|
176
|
+
) : /* @__PURE__ */ n("span", { className: "inline-flex flex-wrap items-center justify-center gap-x-1", children: [
|
|
177
|
+
/* @__PURE__ */ e("span", { children: s.name }),
|
|
178
|
+
t
|
|
179
|
+
] });
|
|
180
|
+
})()
|
|
175
181
|
}
|
|
176
182
|
),
|
|
177
|
-
|
|
183
|
+
i && i.length > 0 && /* @__PURE__ */ n(b, { children: [
|
|
178
184
|
/* @__PURE__ */ e("div", { className: "relative my-2.5 mx-6 border-t-2 border-border", children: /* @__PURE__ */ e(
|
|
179
185
|
"div",
|
|
180
186
|
{
|
|
181
|
-
className:
|
|
187
|
+
className: u(
|
|
182
188
|
"absolute -top-[10px] left-0",
|
|
183
189
|
"w-5 h-5",
|
|
184
190
|
"flex items-center justify-center",
|
|
185
191
|
"rounded-full",
|
|
186
192
|
"bg-gray-20"
|
|
187
193
|
),
|
|
188
|
-
children: /* @__PURE__ */ e(S, { icon:
|
|
194
|
+
children: /* @__PURE__ */ e(S, { icon: P, className: "size-2.5 text-white" })
|
|
189
195
|
}
|
|
190
196
|
) }),
|
|
191
197
|
/* @__PURE__ */ e("div", { className: "h-6" }),
|
|
192
|
-
/* @__PURE__ */ e(
|
|
193
|
-
|
|
198
|
+
/* @__PURE__ */ e(y, { children: i.map((t) => /* @__PURE__ */ e(
|
|
199
|
+
d,
|
|
194
200
|
{
|
|
195
201
|
size: "sm",
|
|
196
|
-
label: /* @__PURE__ */
|
|
202
|
+
label: /* @__PURE__ */ n("span", { className: "inline-flex items-center", children: [
|
|
197
203
|
/* @__PURE__ */ e(
|
|
198
|
-
|
|
204
|
+
o,
|
|
199
205
|
{
|
|
200
206
|
messageId: "components.apyParts.points",
|
|
201
207
|
values: { symbol: t.name }
|
|
@@ -212,13 +218,13 @@ function ne({
|
|
|
212
218
|
}
|
|
213
219
|
) })
|
|
214
220
|
] }),
|
|
215
|
-
description: /* @__PURE__ */
|
|
221
|
+
description: /* @__PURE__ */ n("div", { children: [
|
|
216
222
|
/* @__PURE__ */ e("div", { children: `Per ${[
|
|
217
223
|
...t.reward?.duration ? [t.reward.duration] : [],
|
|
218
224
|
...t.tokenTitle ? [`1 ${t.tokenTitle}`] : []
|
|
219
225
|
].join(" per ")}` }),
|
|
220
226
|
t.reward?.condition && v[t.reward.condition] && /* @__PURE__ */ e("span", { className: "text-warning", children: /* @__PURE__ */ e(
|
|
221
|
-
|
|
227
|
+
o,
|
|
222
228
|
{
|
|
223
229
|
messageId: v[t.reward.condition]
|
|
224
230
|
}
|
|
@@ -233,19 +239,19 @@ function ne({
|
|
|
233
239
|
}
|
|
234
240
|
);
|
|
235
241
|
return /* @__PURE__ */ e(
|
|
236
|
-
|
|
242
|
+
L,
|
|
237
243
|
{
|
|
238
244
|
placement: "bottom",
|
|
239
245
|
triangle: !1,
|
|
240
246
|
type: "modal-tooltip",
|
|
241
247
|
minWidth: "100%",
|
|
242
248
|
maxWidth: "100%",
|
|
243
|
-
title: /* @__PURE__ */ e("span", { className: g, children:
|
|
249
|
+
title: /* @__PURE__ */ e("span", { className: g, children: m }),
|
|
244
250
|
triggerClassName: g,
|
|
245
|
-
children:
|
|
251
|
+
children: N
|
|
246
252
|
}
|
|
247
253
|
);
|
|
248
254
|
}
|
|
249
255
|
export {
|
|
250
|
-
|
|
256
|
+
oe as PoolAPYTooltip
|
|
251
257
|
};
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* ==================================
|
|
4
4
|
*
|
|
5
5
|
* Self-contained type definitions for the pool-list endpoint response.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* locally (e.g. SDK + `tokensList` on each row).
|
|
6
|
+
* Consumers (`@gearbox-protocol/ui-kit`, `charts`, `client-v3`) map these fields
|
|
7
|
+
* into the `PoolTable` component and resolve token metadata (icons, decimals, titles)
|
|
8
|
+
* locally (e.g. SDK + `tokensList` on each row in the app layer).
|
|
9
9
|
*
|
|
10
10
|
* Copy this file into your backend repo — it has **zero npm dependencies**.
|
|
11
11
|
*
|
|
@@ -19,6 +19,72 @@
|
|
|
19
19
|
* The client converts them back via `BigInt(value)`.
|
|
20
20
|
* - `Address` → `0x`-prefixed hex string, lower-case preferred.
|
|
21
21
|
*
|
|
22
|
+
* ## Unit conventions (critical — do not mix)
|
|
23
|
+
*
|
|
24
|
+
* - **`depositAPY`**, **`PoolApyDTO.totalAPY`**, **`PoolBaseApyDTO.apy`**, **`PoolExtraRewardApyDTO.apy`**:
|
|
25
|
+
* **percent** (e.g. `5.2` means 5.2%).
|
|
26
|
+
* - **`borrowAPY`**: **basis points** (`10_000` = 100%). The Borrow APY column uses the same
|
|
27
|
+
* formatter as elsewhere in the app.
|
|
28
|
+
* - **`utilization`**: **percent** in the `0–100` range (not 0–1).
|
|
29
|
+
* - **`expectedLiquidity`**, **`totalBorrowed`**, **`userBalance`**: raw amounts in **underlying /
|
|
30
|
+
* pool token units** (see field docs). Serialize as decimal strings in JSON.
|
|
31
|
+
* - **`*InUSD` fields**: plain `number` (USD).
|
|
32
|
+
*
|
|
33
|
+
* ## Mapping guide — gearbox-backend PR #84 → this contract
|
|
34
|
+
*
|
|
35
|
+
* The PR introduces `PoolOpportunity`, `MarketInfo`, `MarketMetrics`, `YieldBreakdown`, and
|
|
36
|
+
* discriminated `Incentive` (tokens | points). **The HTTP response shape stays
|
|
37
|
+
* {@link PoolTableListResponse}** so existing frontends do not need rewrites. On the server,
|
|
38
|
+
* **project** PR #84 types into the DTOs below.
|
|
39
|
+
*
|
|
40
|
+
* ### `PoolTableRowDTO` from `PoolOpportunity` + optional wallet snapshot
|
|
41
|
+
*
|
|
42
|
+
* - **`pool`**: Build {@link PoolDTO} from `MarketInfo` + latest `MarketMetrics` (and
|
|
43
|
+
* `PoolOpportunity.collaterals` for addresses). See {@link PoolDTO} block comments.
|
|
44
|
+
* - **`apy`**: Build {@link PoolApyDTO} from `PoolOpportunity.yield` (`YieldBreakdown`) and
|
|
45
|
+
* token incentives inside `yield.incentives`. See {@link PoolApyDTO}.
|
|
46
|
+
* - **`points`**: Map each **active** points incentive to {@link PoolApyPointDTO}.
|
|
47
|
+
* Source: `yield.incentives` where `incentive.type === "points"` (or your PR #84 equivalent).
|
|
48
|
+
* Use `[]` or omit when none.
|
|
49
|
+
* - **`chainId`**: Same as `MarketInfo.chainId` / row pool identity (required for table context).
|
|
50
|
+
* - **`href`**: Optional deep link; app may still build locally.
|
|
51
|
+
*
|
|
52
|
+
* ### `PoolDTO` from `MarketInfo` + `MarketMetrics` + `PoolOpportunity`
|
|
53
|
+
*
|
|
54
|
+
* | Contract field | Suggested PR #84 source |
|
|
55
|
+
* | --- | --- |
|
|
56
|
+
* | `address` | `MarketInfo.address` (pool contract) |
|
|
57
|
+
* | `underlyingToken` | `MarketInfo.underlyingAsset` |
|
|
58
|
+
* | `name` | `MarketInfo.name` |
|
|
59
|
+
* | `version` | `MarketInfo.version` (semver-like int as in PR) |
|
|
60
|
+
* | `network` | Derive human label from `chainId` (e.g. "Arbitrum") — **not** necessarily in PR types |
|
|
61
|
+
* | `chainId` | `MarketInfo.chainId` |
|
|
62
|
+
* | `marketConfigurator` | `MarketInfo.marketConfiguratorAddress` |
|
|
63
|
+
* | `expectedLiquidity` | `MarketMetrics.expected` (underlying units → bigint / JSON string) |
|
|
64
|
+
* | `expectedLiquidityInUSD` | `MarketMetrics.expectedUSD` |
|
|
65
|
+
* | `totalBorrowed` | `MarketMetrics.borrowed` |
|
|
66
|
+
* | `totalBorrowedInUSD` | `MarketMetrics.borrowedUSD` |
|
|
67
|
+
* | `utilization` | e.g. `(borrowed / expected) * 100` when `expected > 0`, else `0` — **percent 0–100** |
|
|
68
|
+
* | `depositAPY` | **Percent**: if PR stores annualized rate as fraction (e.g. `0.052`), multiply by `100`. If already percent, pass through. Align with `YieldBreakdown.base` / supply side. |
|
|
69
|
+
* | `borrowAPY` | **Basis points**: if PR `MarketMetrics.baseInterestRate` is a fraction, use `* 10_000`. If already bps, pass through. |
|
|
70
|
+
* | `collateralTokens` | `PoolOpportunity.collaterals.map(c => c.token.address)` (or active subset you expose) |
|
|
71
|
+
* | `userBalanceInUSD` | From `UserPoolPosition` / wallet-aware layer when `wallet` query present |
|
|
72
|
+
* | `userBalance` | Same — position size in pool/deposit token units |
|
|
73
|
+
* | `poolTokenSymbol` | Diesel / pool share symbol if distinct from underlying (app-specific) |
|
|
74
|
+
* | `hasPoints` | `true` if any points incentive is active, e.g. `yield.incentives.some(i => i.type === "points" && i.isActive)` |
|
|
75
|
+
*
|
|
76
|
+
* ### `PoolApyDTO` from `YieldBreakdown` + incentives
|
|
77
|
+
*
|
|
78
|
+
* - **`totalAPY`**: `YieldBreakdown.totalApy` (must be **percent**, consistent with UI).
|
|
79
|
+
* - **`baseAPY`**: At minimum `[{ type: "supplyAPY", apy: YieldBreakdown.base }]`. Add `{ type: "tokenYield", apy }` entries if your model splits organic yield further.
|
|
80
|
+
* - **`extraAPY`**: For each **token** incentive in `YieldBreakdown.incentives` with `type === "tokens"`, map to {@link PoolExtraRewardApyDTO} (see that interface).
|
|
81
|
+
* - **`externalAPY`**: Optional — only if you expose an external protocol boost; shape is {@link PoolExternalApyDTO}.
|
|
82
|
+
* - **`apy7DAgo`**: Optional — requires a **stored snapshot** (e.g. `MarketDetailResponse.metrics7DAgo` in PR #84). Build {@link PoolApy7DaysAgoDTO} the same way as current `apy` for that snapshot. Omit if unavailable.
|
|
83
|
+
*
|
|
84
|
+
* ### `PoolApyPointDTO` from points `Incentive`
|
|
85
|
+
*
|
|
86
|
+
* Map each points program to one row. Align with UI `PoolAPYPointsTip`: `amount`, `name`, `tokenTitle`, `fullTip`, `reward.*`.
|
|
87
|
+
*
|
|
22
88
|
* @packageDocumentation
|
|
23
89
|
*/
|
|
24
90
|
type Address = `0x${string}`;
|
|
@@ -29,11 +95,24 @@ type Address = `0x${string}`;
|
|
|
29
95
|
* "rows": [ … ]
|
|
30
96
|
* }
|
|
31
97
|
* ```
|
|
98
|
+
*
|
|
99
|
+
* **PR #84:** Keep this envelope. Populate `rows` by mapping each internal `PoolOpportunity`
|
|
100
|
+
* (plus metrics and optional user position) into {@link PoolTableRowDTO} — do not replace
|
|
101
|
+
* with a raw `PoolOpportunity[]` at the root if you want zero frontend changes.
|
|
32
102
|
*/
|
|
33
103
|
export interface PoolTableListResponse {
|
|
34
104
|
/** One entry per pool visible in the table. */
|
|
35
105
|
rows: PoolTableRowDTO[];
|
|
36
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* One table row. Apps pass this (with `tokensList` filled client-side) into `PoolTable`.
|
|
109
|
+
*
|
|
110
|
+
* **PR #84 assembly:**
|
|
111
|
+
* - **`pool`**: {@link PoolDTO} from `MarketInfo` + `MarketMetrics` + collateral list on `PoolOpportunity`.
|
|
112
|
+
* - **`apy`**: {@link PoolApyDTO} from `PoolOpportunity.yield` (`YieldBreakdown`); split token vs points as documented on {@link PoolApyDTO} and {@link PoolApyPointDTO}.
|
|
113
|
+
* - **`points`**: derived from **points** incentives only (not duplicated inside `apy.extraAPY`).
|
|
114
|
+
* - **`chainId`**: must match the pool’s chain.
|
|
115
|
+
*/
|
|
37
116
|
export interface PoolTableRowDTO {
|
|
38
117
|
pool: PoolDTO;
|
|
39
118
|
/** Supply / deposit APY breakdown (column + tooltip). */
|
|
@@ -44,55 +123,102 @@ export interface PoolTableRowDTO {
|
|
|
44
123
|
/** Deep-link to pool detail page (client can also build this locally). */
|
|
45
124
|
href?: string;
|
|
46
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Flat pool fields for columns (supply, borrowed, utilization, borrow APY, collateral icons, etc.).
|
|
128
|
+
*
|
|
129
|
+
* **PR #84:** Compose from `MarketInfo` + `MarketMetrics` + `PoolOpportunity.collaterals`.
|
|
130
|
+
* See the file-level mapping table for field-by-field sources.
|
|
131
|
+
*/
|
|
47
132
|
export interface PoolDTO {
|
|
133
|
+
/** **PR #84:** `MarketInfo.address`. */
|
|
48
134
|
address: Address;
|
|
135
|
+
/** **PR #84:** `MarketInfo.underlyingAsset`. */
|
|
49
136
|
underlyingToken: Address;
|
|
50
|
-
/** Display name, e.g. "USDC v3". */
|
|
137
|
+
/** Display name, e.g. "USDC v3". **PR #84:** `MarketInfo.name`. */
|
|
51
138
|
name?: string;
|
|
52
|
-
/** Semver-like integer: 300 = v3, 310 = v3.1, etc. */
|
|
139
|
+
/** Semver-like integer: 300 = v3, 310 = v3.1, etc. **PR #84:** `MarketInfo.version`. */
|
|
53
140
|
version?: number;
|
|
54
|
-
/** Human-readable network label, e.g. "Mainnet", "Arbitrum". */
|
|
141
|
+
/** Human-readable network label, e.g. "Mainnet", "Arbitrum". Derive from `chainId` if not in PR types. */
|
|
55
142
|
network?: string;
|
|
143
|
+
/** **PR #84:** `MarketInfo.chainId`. */
|
|
56
144
|
chainId?: number;
|
|
57
|
-
/** Market configurator address (
|
|
145
|
+
/** Market configurator address (curator badge). **PR #84:** `MarketInfo.marketConfiguratorAddress`. */
|
|
58
146
|
marketConfigurator?: Address;
|
|
59
|
-
/**
|
|
147
|
+
/**
|
|
148
|
+
* Total supplied liquidity in underlying token (bigint → string in JSON).
|
|
149
|
+
* **PR #84:** `MarketMetrics.expected` in underlying units.
|
|
150
|
+
*/
|
|
60
151
|
expectedLiquidity?: bigint;
|
|
61
|
-
/** Same value converted to USD. */
|
|
152
|
+
/** Same value converted to USD. **PR #84:** `MarketMetrics.expectedUSD`. */
|
|
62
153
|
expectedLiquidityInUSD?: number;
|
|
63
|
-
/**
|
|
154
|
+
/**
|
|
155
|
+
* Total borrowed in underlying token (bigint → string in JSON).
|
|
156
|
+
* **PR #84:** `MarketMetrics.borrowed`.
|
|
157
|
+
*/
|
|
64
158
|
totalBorrowed?: bigint;
|
|
65
|
-
/** Same value converted to USD. */
|
|
159
|
+
/** Same value converted to USD. **PR #84:** `MarketMetrics.borrowedUSD`. */
|
|
66
160
|
totalBorrowedInUSD?: number;
|
|
67
|
-
/**
|
|
161
|
+
/**
|
|
162
|
+
* Utilization ratio, 0–100 (percent).
|
|
163
|
+
* **PR #84:** e.g. `(borrowed / expected) * 100` with safe zero handling.
|
|
164
|
+
*/
|
|
68
165
|
utilization?: number;
|
|
69
|
-
/**
|
|
166
|
+
/**
|
|
167
|
+
* Base deposit APY, already in **percent** (e.g. `5.2` = 5.2%).
|
|
168
|
+
* **PR #84:** Align with supply-side APY; convert from fractional rate if needed (`* 100`).
|
|
169
|
+
*/
|
|
70
170
|
depositAPY?: number;
|
|
71
171
|
/**
|
|
72
172
|
* Borrow rate for the "Borrow APY" column.
|
|
73
173
|
* Unit: **basis points** (10 000 = 100%).
|
|
174
|
+
* **PR #84:** Map from `MarketMetrics.baseInterestRate`; convert fraction → bps (`* 10_000`) if applicable.
|
|
74
175
|
*/
|
|
75
176
|
borrowAPY?: number;
|
|
76
177
|
/**
|
|
77
178
|
* Active collateral token addresses for the "Collateral" column.
|
|
78
179
|
* Token symbols/decimals for display are resolved on the client (no server-side
|
|
79
180
|
* token dictionary in this response).
|
|
181
|
+
* **PR #84:** `PoolOpportunity.collaterals.map(c => c.token.address)` (or your filtered list).
|
|
80
182
|
*/
|
|
81
183
|
collateralTokens?: Address[];
|
|
82
|
-
/**
|
|
184
|
+
/**
|
|
185
|
+
* User's pool position value in USD ("Your Balance" column).
|
|
186
|
+
* **PR #84:** When wallet is requested, from `UserPoolPosition` / similar (e.g. `depositSizeUsd`).
|
|
187
|
+
*/
|
|
83
188
|
userBalanceInUSD?: number;
|
|
84
|
-
/**
|
|
189
|
+
/**
|
|
190
|
+
* User's position amount in pool/deposit token (bigint → string).
|
|
191
|
+
* **PR #84:** e.g. `UserPoolPosition.depositSize` in token units.
|
|
192
|
+
*/
|
|
85
193
|
userBalance?: bigint;
|
|
86
194
|
/** Pool deposit token symbol, e.g. `"edgeUSDC"`. */
|
|
87
195
|
poolTokenSymbol?: string;
|
|
88
|
-
/**
|
|
196
|
+
/**
|
|
197
|
+
* `true` when the pool has active points/rewards (shows indicator icon).
|
|
198
|
+
* **PR #84:** e.g. any active `type === "points"` incentive in `yield.incentives`.
|
|
199
|
+
*/
|
|
89
200
|
hasPoints?: boolean;
|
|
90
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Supply APY breakdown for {@link CompoundAPY} / tooltip. All APY numbers here are **percent**.
|
|
204
|
+
*
|
|
205
|
+
* **PR #84:** Build from `PoolOpportunity.yield` (`YieldBreakdown`):
|
|
206
|
+
* - `totalAPY` ← `totalApy`
|
|
207
|
+
* - `baseAPY` ← at least one `supplyAPY` row from `base`; add `tokenYield` rows if split
|
|
208
|
+
* - `extraAPY` ← token incentives only (see {@link PoolExtraRewardApyDTO})
|
|
209
|
+
* - `apy7DAgo` ← optional second snapshot if you persist `metrics7DAgo` / historical yield
|
|
210
|
+
*/
|
|
91
211
|
export interface PoolApyDTO {
|
|
92
|
-
/** Total combined supply APY in percent (`8.33` = 8.33%). */
|
|
212
|
+
/** Total combined supply APY in percent (`8.33` = 8.33%). **PR #84:** `YieldBreakdown.totalApy`. */
|
|
93
213
|
totalAPY: number;
|
|
214
|
+
/** **PR #84:** From `YieldBreakdown.base` (+ optional extra base rows). */
|
|
94
215
|
baseAPY: PoolBaseApyDTO[];
|
|
216
|
+
/**
|
|
217
|
+
* Token reward APY lines (not points — points go to {@link PoolTableRowDTO.points}).
|
|
218
|
+
* **PR #84:** `yield.incentives` filtered to `type === "tokens"`.
|
|
219
|
+
*/
|
|
95
220
|
extraAPY: PoolExtraRewardApyDTO[];
|
|
221
|
+
/** Optional external boost (e.g. third-party protocol). */
|
|
96
222
|
externalAPY?: PoolExternalApyDTO;
|
|
97
223
|
/** Snapshot from 7 days ago (for 1D / 7D comparison in tooltip). */
|
|
98
224
|
apy7DAgo?: PoolApy7DaysAgoDTO;
|
|
@@ -102,6 +228,14 @@ export interface PoolBaseApyDTO {
|
|
|
102
228
|
/** Already in percent. */
|
|
103
229
|
apy: number;
|
|
104
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* One line in "extra APY" (liquidity mining, etc.). **Percent** for `apy`.
|
|
233
|
+
*
|
|
234
|
+
* **PR #84 (token incentive):**
|
|
235
|
+
* - `apy` ← `TokenReward.apy` (or incentive-level APY if that’s where you store it)
|
|
236
|
+
* - `rewardToken` ← `TokenReward.rewardToken.address` (hex string)
|
|
237
|
+
* - `rewardTokenSymbol` ← `TokenReward.rewardToken.symbol`
|
|
238
|
+
*/
|
|
105
239
|
export interface PoolExtraRewardApyDTO {
|
|
106
240
|
/** Extra reward APY in percent. */
|
|
107
241
|
apy: number;
|
|
@@ -116,12 +250,29 @@ export interface PoolExternalApyDTO {
|
|
|
116
250
|
/** Source name, e.g. "Curve". */
|
|
117
251
|
name: string;
|
|
118
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* Historical snapshot for tooltip 1D / 7D columns. Same units as {@link PoolApyDTO}.
|
|
255
|
+
*
|
|
256
|
+
* **PR #84:** Fill from your stored 7d metrics / APY snapshot when available; omit otherwise.
|
|
257
|
+
*/
|
|
119
258
|
export interface PoolApy7DaysAgoDTO {
|
|
120
259
|
totalAPY?: number;
|
|
121
260
|
baseAPY?: PoolBaseApyDTO[];
|
|
122
261
|
extraAPY?: PoolExtraRewardApyDTO[];
|
|
123
262
|
externalAPY?: PoolExternalApyDTO;
|
|
124
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* One points program row for the APY tooltip. Matches UI `PoolAPYPointsTip` shape.
|
|
266
|
+
*
|
|
267
|
+
* **PR #84:** Map from a **points** `Incentive` / `PointsIncentive` (discriminated union):
|
|
268
|
+
* - `amount` — formatted string for display, e.g. `"2.5x"` from `PointsReward.multiplier`
|
|
269
|
+
* - `name` — `PointsReward.name` or program title
|
|
270
|
+
* - `tokenTitle` — optional; helps icon copy (e.g. underlying symbol)
|
|
271
|
+
* - `fullTip` — **pre-formatted** human-readable tooltip body (UI-ready)
|
|
272
|
+
* - `reward.duration` — human string (e.g. from `startsAt` / `endsAt`) or omit
|
|
273
|
+
* - `reward.condition` — e.g. `"deposit" | "cross-chain-deposit" | "holding"` if your model has it
|
|
274
|
+
* - `reward.name` / `reward.type` — for points icon / labeling in the UI
|
|
275
|
+
*/
|
|
125
276
|
export interface PoolApyPointDTO {
|
|
126
277
|
/** Formatted amount string, e.g. "2.5x". */
|
|
127
278
|
amount: string;
|
|
@@ -18,7 +18,8 @@ interface ExternalAPYData {
|
|
|
18
18
|
totalValue: number;
|
|
19
19
|
apy: number;
|
|
20
20
|
name: string;
|
|
21
|
-
|
|
21
|
+
/** When omitted, the block renders a plain name + APY line (no i18n id). */
|
|
22
|
+
tooltip?: LocaleKeys;
|
|
22
23
|
}
|
|
23
24
|
interface APY7DAgoData {
|
|
24
25
|
totalAPY?: number;
|