Skip to content

Commit b2b16e8

Browse files
committed
update: Lane latest data
1 parent f8c075e commit b2b16e8

File tree

3 files changed

+280
-29
lines changed

3 files changed

+280
-29
lines changed

src/components/CCIP/Drawer/LaneDrawer.tsx

Lines changed: 102 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import "../Tables/Table.css"
33
import { Environment, LaneConfig, LaneFilter, Version } from "~/config/data/ccip/types.ts"
44
import { getNetwork, getTokenData } from "~/config/data/ccip/data.ts"
55
import { determineTokenMechanism } from "~/config/data/ccip/utils.ts"
6-
import { useState } from "react"
6+
import { useState, useEffect } from "react"
77
import LaneDetailsHero from "../ChainHero/LaneDetailsHero.tsx"
88
import { getExplorerAddressUrl, getTokenIconUrl, fallbackTokenIconUrl } from "~/features/utils/index.ts"
99
import TableSearchInput from "../Tables/TableSearchInput.tsx"
1010
import { Tooltip } from "~/features/common/Tooltip/Tooltip.tsx"
1111
import { ChainType, ExplorerInfo } from "@config/types.ts"
12+
import { RealtimeDataService } from "~/lib/ccip/services/realtime-data.ts"
13+
import type { TokenRateLimits } from "~/lib/ccip/types/index.ts"
1214

1315
function LaneDrawer({
1416
lane,
@@ -26,6 +28,9 @@ function LaneDrawer({
2628
inOutbound: LaneFilter
2729
}) {
2830
const [search, setSearch] = useState("")
31+
const [rateLimits, setRateLimits] = useState<Record<string, TokenRateLimits>>({})
32+
const [isLoadingRateLimits, setIsLoadingRateLimits] = useState(true)
33+
2934
const destinationNetworkDetails = getNetwork({
3035
filter: environment,
3136
chain: destinationNetwork.key,
@@ -36,6 +41,27 @@ function LaneDrawer({
3641
chain: sourceNetwork.key,
3742
})
3843

44+
// Fetch rate limits data
45+
useEffect(() => {
46+
const fetchRateLimits = async () => {
47+
setIsLoadingRateLimits(true)
48+
const realtimeService = new RealtimeDataService()
49+
50+
// Determine source and destination based on inOutbound filter
51+
const source = inOutbound === LaneFilter.Outbound ? sourceNetwork.key : destinationNetwork.key
52+
const destination = inOutbound === LaneFilter.Outbound ? destinationNetwork.key : sourceNetwork.key
53+
54+
const response = await realtimeService.getLaneSupportedTokens(source, destination, environment)
55+
56+
if (response?.data) {
57+
setRateLimits(response.data)
58+
}
59+
setIsLoadingRateLimits(false)
60+
}
61+
62+
fetchRateLimits()
63+
}, [sourceNetwork.key, destinationNetwork.key, environment, inOutbound])
64+
3965
return (
4066
<>
4167
<h2 className="ccip-table__drawer-heading">Lane Details</h2>
@@ -184,10 +210,29 @@ function LaneDrawer({
184210
if (!Object.keys(data).length) return null
185211
const logo = getTokenIconUrl(token)
186212

187-
// TODO: Fetch rate limits from API for both inbound and outbound
188-
// Token pause detection requires rate limiter data from API
189-
// A token is paused when rate limit capacity is 0
190-
const tokenPaused = false
213+
// Get rate limit data for this token
214+
const tokenRateLimits = rateLimits[token]
215+
const realtimeService = new RealtimeDataService()
216+
217+
// Determine direction based on inOutbound filter
218+
const direction = inOutbound === LaneFilter.Outbound ? "out" : "in"
219+
220+
// Get standard and FTF rate limits
221+
const allLimits = tokenRateLimits
222+
? realtimeService.getAllRateLimitsForDirection(tokenRateLimits, direction)
223+
: { standard: null, ftf: null }
224+
225+
// Token is paused if standard rate limit capacity is 0
226+
const tokenPaused = allLimits.standard?.capacity === "0"
227+
228+
// Format rate limit values
229+
const formatRateLimit = (value: string | null) => {
230+
if (!value || value === "0") return "0"
231+
// Convert from wei to tokens (divide by 1e18)
232+
const numValue = BigInt(value)
233+
const formatted = Number(numValue) / 1e18
234+
return formatted.toLocaleString(undefined, { maximumFractionDigits: 2 })
235+
}
191236

192237
return (
193238
<tr key={index} className={tokenPaused ? "ccip-table__row--paused" : ""}>
@@ -235,23 +280,64 @@ function LaneDrawer({
235280
</td>
236281

237282
<td>
238-
{/* TODO: Fetch rate limits from API for both inbound and outbound
239-
GET /api/ccip/v1/lanes/by-internal-id/{source}/{destination}/supported-tokens?environment={environment}
240-
Response will contain both standard and custom rate limits per token */}
241-
Disabled
283+
{isLoadingRateLimits
284+
? "Loading..."
285+
: allLimits.standard
286+
? allLimits.standard.isEnabled
287+
? formatRateLimit(allLimits.standard.capacity)
288+
: "Disabled"
289+
: (
290+
<span style={{ display: "inline-flex", alignItems: "center", gap: "4px" }}>
291+
Unavailable
292+
<Tooltip
293+
label=""
294+
tip="Rate limit data is currently unavailable. You can find the Token Pool rate limit by reading the Token Pool contract directly on the relevant blockchain."
295+
style={{
296+
display: "inline-block",
297+
verticalAlign: "middle",
298+
}}
299+
/>
300+
</span>
301+
)}
242302
</td>
243303
<td className="rate-tooltip-cell">
244-
{/* TODO: Fetch rate limits from API for both inbound and outbound
245-
Display refill rate from standard.in/out or custom.in/out based on inOutbound filter */}
246-
Disabled
304+
{isLoadingRateLimits
305+
? "Loading..."
306+
: allLimits.standard
307+
? allLimits.standard.isEnabled
308+
? formatRateLimit(allLimits.standard.rate)
309+
: "Disabled"
310+
: "N/A"}
247311
</td>
248312
<td>
249-
{/* Placeholder for FTF Rate limit capacity - data not yet available */}
250-
TBC
313+
{isLoadingRateLimits
314+
? "Loading..."
315+
: allLimits.ftf
316+
? allLimits.ftf.isEnabled
317+
? formatRateLimit(allLimits.ftf.capacity)
318+
: "Disabled"
319+
: (
320+
<span style={{ display: "inline-flex", alignItems: "center", gap: "4px" }}>
321+
Unavailable
322+
<Tooltip
323+
label=""
324+
tip="Rate limit data is currently unavailable. You can find the Token Pool rate limit by reading the Token Pool contract directly on the relevant blockchain."
325+
style={{
326+
display: "inline-block",
327+
verticalAlign: "middle",
328+
}}
329+
/>
330+
</span>
331+
)}
251332
</td>
252333
<td>
253-
{/* Placeholder for FTF Rate limit refill rate - data not yet available */}
254-
TBC
334+
{isLoadingRateLimits
335+
? "Loading..."
336+
: allLimits.ftf
337+
? allLimits.ftf.isEnabled
338+
? formatRateLimit(allLimits.ftf.rate)
339+
: "Disabled"
340+
: "N/A"}
255341
</td>
256342
</tr>
257343
)

src/components/CCIP/Drawer/TokenDrawer.tsx

Lines changed: 88 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ import {
1313
getTokenData,
1414
LaneConfig,
1515
} from "~/config/data/ccip/index.ts"
16-
import { useState } from "react"
16+
import { useState, useEffect } from "react"
1717
import { ChainType, ExplorerInfo, SupportedChain } from "~/config/index.ts"
1818
import LaneDrawer from "../Drawer/LaneDrawer.tsx"
1919
import TableSearchInput from "../Tables/TableSearchInput.tsx"
2020
import Tabs from "../Tables/Tabs.tsx"
2121
import { Tooltip } from "~/features/common/Tooltip/Tooltip.tsx"
22+
import { RealtimeDataService } from "~/lib/ccip/services/realtime-data.ts"
23+
import type { TokenRateLimits } from "~/lib/ccip/types/index.ts"
2224

2325
function TokenDrawer({
2426
token,
@@ -54,6 +56,7 @@ function TokenDrawer({
5456
}) {
5557
const [search, setSearch] = useState("")
5658
const [inOutbound, setInOutbound] = useState<LaneFilter>(LaneFilter.Outbound)
59+
const [rateLimits, setRateLimits] = useState<Record<string, Record<string, TokenRateLimits>>>({})
5760

5861
type LaneRow = {
5962
networkDetails: {
@@ -65,6 +68,29 @@ function TokenDrawer({
6568
destinationPoolType: PoolType
6669
}
6770

71+
// Fetch rate limits for all lanes
72+
useEffect(() => {
73+
const fetchAllRateLimits = async () => {
74+
const realtimeService = new RealtimeDataService()
75+
const newRateLimits: Record<string, Record<string, TokenRateLimits>> = {}
76+
77+
for (const destinationChain of Object.keys(destinationLanes)) {
78+
const source = inOutbound === LaneFilter.Outbound ? network.key : destinationChain
79+
const destination = inOutbound === LaneFilter.Outbound ? destinationChain : network.key
80+
const laneKey = `${source}-${destination}`
81+
82+
const response = await realtimeService.getLaneSupportedTokens(source, destination, environment)
83+
if (response?.data) {
84+
newRateLimits[laneKey] = response.data
85+
}
86+
}
87+
88+
setRateLimits(newRateLimits)
89+
}
90+
91+
fetchAllRateLimits()
92+
}, [network.key, destinationLanes, environment, inOutbound])
93+
6894
const laneRows: LaneRow[] = Object.keys(destinationLanes)
6995
.map((destinationChain) => {
7096
const networkDetails = getNetwork({
@@ -186,6 +212,8 @@ function TokenDrawer({
186212
}}
187213
/>
188214
</th>
215+
<th>FTF Rate limit capacity</th>
216+
<th>FTF Rate limit refill rate</th>
189217
<th>
190218
Mechanism
191219
<Tooltip
@@ -213,10 +241,33 @@ function TokenDrawer({
213241
.map(({ networkDetails, laneData, destinationChain, destinationPoolType }) => {
214242
if (!laneData || !networkDetails) return null
215243

216-
// TODO: Fetch rate limits from API for both inbound and outbound
217-
// Token pause detection requires rate limiter data from API
218-
// A token is paused when rate limit capacity is 0
219-
const tokenPaused = false
244+
// Get rate limit data for this lane
245+
const source = inOutbound === LaneFilter.Outbound ? network.key : destinationChain
246+
const destination = inOutbound === LaneFilter.Outbound ? destinationChain : network.key
247+
const laneKey = `${source}-${destination}`
248+
const laneRateLimits = rateLimits[laneKey]
249+
const tokenRateLimits = laneRateLimits?.[token.id]
250+
251+
const realtimeService = new RealtimeDataService()
252+
const direction = inOutbound === LaneFilter.Outbound ? "out" : "in"
253+
254+
// Get standard and FTF rate limits
255+
const allLimits = tokenRateLimits
256+
? realtimeService.getAllRateLimitsForDirection(tokenRateLimits, direction)
257+
: { standard: null, ftf: null }
258+
259+
// Token is paused if standard rate limit capacity is 0
260+
const tokenPaused = allLimits.standard?.capacity === "0"
261+
262+
// Format rate limit values
263+
const formatRateLimit = (value: string | null) => {
264+
if (!value || value === "0") return "0"
265+
const numValue = BigInt(value)
266+
const formatted = Number(numValue) / 1e18
267+
return formatted.toLocaleString(undefined, { maximumFractionDigits: 2 })
268+
}
269+
270+
const isLoading = !laneRateLimits
220271

221272
return (
222273
<tr key={networkDetails.name} className={tokenPaused ? "ccip-table__row--paused" : ""}>
@@ -257,15 +308,40 @@ function TokenDrawer({
257308
</button>
258309
</td>
259310
<td>
260-
{/* TODO: Fetch rate limits from API for both inbound and outbound
261-
GET /api/ccip/v1/lanes/by-internal-id/{source}/{destination}/supported-tokens?environment={environment}
262-
Response will contain both standard and custom rate limits per token */}
263-
Disabled
311+
{isLoading
312+
? "Loading..."
313+
: allLimits.standard
314+
? allLimits.standard.isEnabled
315+
? formatRateLimit(allLimits.standard.capacity)
316+
: "Disabled"
317+
: "N/A"}
318+
</td>
319+
<td>
320+
{isLoading
321+
? "Loading..."
322+
: allLimits.standard
323+
? allLimits.standard.isEnabled
324+
? formatRateLimit(allLimits.standard.rate)
325+
: "Disabled"
326+
: "N/A"}
327+
</td>
328+
<td>
329+
{isLoading
330+
? "Loading..."
331+
: allLimits.ftf
332+
? allLimits.ftf.isEnabled
333+
? formatRateLimit(allLimits.ftf.capacity)
334+
: "Disabled"
335+
: "N/A"}
264336
</td>
265337
<td>
266-
{/* TODO: Fetch rate limits from API for both inbound and outbound
267-
Display refill rate from standard.in/out or custom.in/out based on inOutbound filter */}
268-
Disabled
338+
{isLoading
339+
? "Loading..."
340+
: allLimits.ftf
341+
? allLimits.ftf.isEnabled
342+
? formatRateLimit(allLimits.ftf.rate)
343+
: "Disabled"
344+
: "N/A"}
269345
</td>
270346
<td>
271347
{inOutbound === LaneFilter.Outbound

0 commit comments

Comments
 (0)