Skip to content

Commit 7ec332d

Browse files
bingyuyapevan-gray
authored andcommitted
dashboard: solana ntt rate limit queries
Signed-off-by: bingyuyap <bingyu.yap.21@gmail.com>
1 parent 5c573ca commit 7ec332d

14 files changed

+482
-940
lines changed

common/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export * from './consts';
44
export * from './explorer';
55
export * from './solana';
66
export * from './utils';
7+
export * from './nttConsts';

common/src/nttConsts.ts

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { Chain, Network, chains } from '@wormhole-foundation/sdk-base';
2+
3+
// This data structure is used in dashboard
4+
export type NTTContract = {
5+
[key in Network]: { [tokenName: string]: { [key in Chain]?: string } };
6+
};
7+
8+
// This data structure is used in watchers
9+
export type NTTContractArray = {
10+
[key in Network]: { [key in Chain]?: string[] };
11+
};
12+
13+
function convertNTTManagerContractToNTTContractArray(
14+
nttManagerContract: NTTContract
15+
): NTTContractArray {
16+
const nttContract: NTTContractArray = {} as NTTContractArray;
17+
18+
for (const network in nttManagerContract) {
19+
nttContract[network as Network] = {};
20+
21+
for (const tokenName in nttManagerContract[network as Network]) {
22+
for (const chain in nttManagerContract[network as Network][tokenName]) {
23+
const tokenAddress = nttManagerContract[network as Network][tokenName][chain as Chain];
24+
25+
if (tokenAddress) {
26+
if (!nttContract[network as Network][chain as Chain]) {
27+
nttContract[network as Network][chain as Chain] = [];
28+
}
29+
nttContract[network as Network][chain as Chain]!.push(tokenAddress);
30+
}
31+
}
32+
}
33+
}
34+
35+
return nttContract;
36+
}
37+
38+
export const NTT_MANAGER_CONTRACT: NTTContract = {
39+
Mainnet: {
40+
USDC: {
41+
Ethereum: '0xeBdCe9a913d9400EE75ef31Ce8bd34462D01a1c1',
42+
Fantom: '0x68dB2f05Aa2d77DEf981fd2be32661340c9222FB',
43+
},
44+
},
45+
Testnet: {
46+
TEST_NTT: {
47+
Solana: 'nTTh3bZ5Aer6xboWZe39RDEft4MeVxSQ8D1EYAVLZw9',
48+
Sepolia: '0xB231aD95f2301bc82eA44c515001F0F746D637e0',
49+
ArbitrumSepolia: '0xEec94CD3083e067398256a79CcA7e740C5c8ef81',
50+
BaseSepolia: '0xB03b030b2f5B40819Df76467d67eD1C85Ff66fAD',
51+
OptimismSepolia: '0x7f430D4e7939D994C0955A01FC75D9DE33F12D11',
52+
},
53+
},
54+
Devnet: {},
55+
};
56+
57+
export const NTT_TRANSCEIVER_CONTRACT: NTTContract = {
58+
Mainnet: {
59+
USDC: {
60+
Ethereum: '0x55f7820357FA17A1ECb48E959D5E637bFF956d6F',
61+
Fantom: '0x8b47f02E7E20174C76Af910adc0Ad8A4B0342f4c',
62+
},
63+
},
64+
Testnet: {
65+
TEST_NTT: {
66+
Solana: '9WNzy7xYZyL2k6JnE9dWSp7VpYkvfRN3Rhd8wHv9J9mY',
67+
Sepolia: '0x1fDC902e30b188FD2BA976B421Cb179943F57896',
68+
ArbitrumSepolia: '0x0E24D17D7467467b39Bf64A9DFf88776Bd6c74d7',
69+
BaseSepolia: '0x1e072169541f1171e427Aa44B5fd8924BEE71b0e',
70+
OptimismSepolia: '0x41265eb2863bf0238081F6AeefeF73549C82C3DD',
71+
},
72+
},
73+
Devnet: {},
74+
};
75+
76+
export const NTT_TOKENS: NTTContract = {
77+
Mainnet: {
78+
USDC: {
79+
Ethereum: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
80+
Fantom: '0x2F733095B80A04b38b0D10cC884524a3d09b836a',
81+
},
82+
},
83+
Testnet: {
84+
TEST_NTT: {
85+
Solana: '87r5ZS91Q2pQbFTvvneqs7y7mbtegtqMt4LDAS4g23Ax',
86+
Sepolia: '0x1d30E78B7C7fbbcef87ae6e97B5389b2e470CA4a',
87+
ArbitrumSepolia: '0x84A1Cb660B19eB0063EE5FD377eC14AAe3364d74',
88+
BaseSepolia: '0x7f430D4e7939D994C0955A01FC75D9DE33F12D11',
89+
OptimismSepolia: '0x0e15979a7a1eFAEf20312CA45A59eb141bF7E340',
90+
},
91+
},
92+
Devnet: {},
93+
};
94+
95+
export const NTT_MANAGER_CONTRACT_ARRAY =
96+
convertNTTManagerContractToNTTContractArray(NTT_MANAGER_CONTRACT);
97+
98+
export function NTT_SUPPORTED_CHAINS(network: Network, token: string): Chain[] {
99+
const contractDetails = NTT_MANAGER_CONTRACT[network][token];
100+
if (!contractDetails) {
101+
return [];
102+
}
103+
104+
return chains.filter((chain) => chain in contractDetails);
105+
}

dashboard/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
"@types/react": "^18.0.15",
1919
"@types/react-dom": "^18.0.6",
2020
"axios": "^0.27.2",
21-
"ethers": "^6.11.1",
2221
"numeral": "^2.0.6",
2322
"react": "^18.2.0",
2423
"react-dom": "^18.2.0",

dashboard/src/components/NTTMetrics.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ function NTTMetrics() {
1212
src="https://lookerstudio.google.com/embed/reporting/0f20bce5-d442-4f39-8cc4-ced8bb73042a/page/kSKuD"
1313
hasTabs
1414
/>
15+
<NTTRateLimits />
1516
</>
1617
);
1718
}

dashboard/src/components/NTTRateLimits.tsx

+48-13
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,40 @@ import { chainIdToName } from '@wormhole-foundation/wormhole-monitor-common';
1919
const rateLimitColumnHelper = createColumnHelper<RateLimit>();
2020

2121
const rateLimitColumns = [
22+
rateLimitColumnHelper.accessor('tokenName', {
23+
id: 'tokenName',
24+
header: () => 'Token',
25+
cell: (info) => (
26+
<>
27+
{info.row.getCanExpand() && !info.row.original.srcChain ? (
28+
<IconButton
29+
size="small"
30+
sx={{ ml: -1 }}
31+
{...{
32+
onClick: info.row.getToggleExpandedHandler(),
33+
}}
34+
>
35+
{info.row.getIsExpanded() ? (
36+
<KeyboardArrowDown fontSize="inherit" />
37+
) : (
38+
<KeyboardArrowRight fontSize="inherit" />
39+
)}
40+
</IconButton>
41+
) : null}{' '}
42+
{info.row.original.srcChain
43+
? info.row.original.destChain
44+
? null
45+
: null
46+
: info.row.original.tokenName}
47+
</>
48+
),
49+
}),
2250
rateLimitColumnHelper.accessor((row) => row.srcChain, {
2351
id: 'srcChain',
2452
header: () => 'Chain',
2553
cell: (info) => (
2654
<>
27-
{info.row.getCanExpand() ? (
55+
{info.row.getCanExpand() && info.row.original.srcChain ? (
2856
<IconButton
2957
size="small"
3058
sx={{ ml: -1 }}
@@ -38,32 +66,38 @@ const rateLimitColumns = [
3866
<KeyboardArrowRight fontSize="inherit" />
3967
)}
4068
</IconButton>
41-
) : null}{' '}
42-
{info.row.original.destChain ? (
43-
<Box sx={{ pl: 3 }}>
44-
{chainIdToName(info.row.original.destChain)} ({info.row.original.destChain})
45-
</Box>
4669
) : (
47-
`${chainIdToName(info.row.original.srcChain)} (${info.row.original.srcChain})`
48-
)}
70+
<Box sx={{ width: 20, display: 'inline-block' }} />
71+
)}{' '}
72+
{info.row.original.srcChain
73+
? info.row.original.destChain
74+
? `${chainIdToName(info.row.original.destChain)}(${info.row.original.destChain})`
75+
: `${chainIdToName(info.row.original.srcChain)}(${info.row.original.srcChain})`
76+
: null}
4977
</>
5078
),
5179
}),
5280
rateLimitColumnHelper.accessor('amount', {
5381
header: () => <Box order="1">Outbound Capacity</Box>,
5482
cell: (info) => (
5583
<Box textAlign="right">
56-
{info.row.original.destChain ? null : `$${info.row.original.amount.toLocaleString()}`}
84+
{info.row.original.srcChain
85+
? info.row.original.destChain
86+
? null
87+
: `${info.row.original.amount?.toLocaleString()}`
88+
: null}
5789
</Box>
5890
),
5991
}),
6092
rateLimitColumnHelper.accessor('totalInboundCapacity', {
6193
header: () => <Box order="1">Inbound Capacity</Box>,
6294
cell: (info) => (
6395
<Box textAlign="right">
64-
{info.row.original.destChain
65-
? `$${info.row.original.amount.toLocaleString()}`
66-
: `$${info.row.original.totalInboundCapacity?.toLocaleString()}`}
96+
{info.row.original.srcChain
97+
? info.row.original.destChain
98+
? info.row.original.amount?.toLocaleString()
99+
: `${info.row.original.totalInboundCapacity?.toLocaleString()}`
100+
: null}
67101
</Box>
68102
),
69103
}),
@@ -83,7 +117,8 @@ export function NTTRateLimits() {
83117
sorting: rateLimitSorting,
84118
},
85119
getSubRows: (row) => row.inboundCapacity,
86-
getRowId: (rateLimit) => `${rateLimit.srcChain.toString()}-${rateLimit.destChain || ''}`,
120+
getRowId: (rateLimit) =>
121+
`${rateLimit.tokenName.toString()}-${rateLimit.srcChain || ''}-${rateLimit.destChain || ''}`,
87122
getCoreRowModel: getCoreRowModel(),
88123
getSortedRowModel: getSortedRowModel(),
89124
getExpandedRowModel: getExpandedRowModel(),

dashboard/src/hooks/useRateLimits.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useState, useEffect } from 'react';
33
import { RateLimit, getRateLimits } from '../utils/nttHelpers';
44
import { Network } from '../contexts/NetworkContext';
55

6-
const REFRESH_INTERVAL = 60_000; // 1 minute
6+
const REFRESH_INTERVAL = 120_000; // 2 minutes
77

88
export function useRateLimits(network: Network) {
99
const [rateLimits, setRateLimits] = useState<RateLimit[]>([]);
@@ -14,6 +14,8 @@ export function useRateLimits(network: Network) {
1414
const fetchRateLimits = async () => {
1515
if (cancelled) return;
1616
const limits = await getRateLimits(network);
17+
limits.sort((a, b) => a.tokenName.localeCompare(b.tokenName));
18+
if (cancelled) return;
1719
setRateLimits(limits);
1820
};
1921

dashboard/src/utils/consts.ts

-43
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import terraIcon from '../images/terra.svg';
3737
import terra2Icon from '../images/terra2.svg';
3838
import wormchainIcon from '../images/wormchain.svg';
3939
import xplaIcon from '../images/xpla.svg';
40-
import { Chain, Network } from '@wormhole-foundation/sdk-base';
4140

4241
export const WORMCHAIN_URL = 'https://tncnt-eu-wormchain-main-01.rpc.p2p.world';
4342
export const TESTNET_WORMCHAIN_URL = `https://corsproxy.io/?${encodeURIComponent(
@@ -176,45 +175,3 @@ export const GUARDIAN_SET_3 = [
176175
name: 'Staking Facilities',
177176
},
178177
];
179-
180-
export const SUPPORTED_EVM_CHAINS: Record<string, Chain[]> = {
181-
Testnet: ['Sepolia', 'ArbitrumSepolia', 'BaseSepolia', 'OptimismSepolia'],
182-
Mainnet: [],
183-
Devnet: [],
184-
};
185-
186-
export const NTT_TOKENS: { [key in Network]: { [key in Chain]?: string } } = {
187-
Mainnet: {},
188-
Testnet: {
189-
Solana: '87r5ZS91Q2pQbFTvvneqs7y7mbtegtqMt4LDAS4g23Ax',
190-
Sepolia: '0x1d30E78B7C7fbbcef87ae6e97B5389b2e470CA4a',
191-
ArbitrumSepolia: '0x84A1Cb660B19eB0063EE5FD377eC14AAe3364d74',
192-
BaseSepolia: '0x7f430D4e7939D994C0955A01FC75D9DE33F12D11',
193-
OptimismSepolia: '0x0e15979a7a1eFAEf20312CA45A59eb141bF7E340',
194-
},
195-
Devnet: {},
196-
};
197-
198-
export const NTT_MANAGER_CONTRACT: { [key in Network]: { [key in Chain]?: string } } = {
199-
Mainnet: {},
200-
Testnet: {
201-
Solana: 'nTTh3bZ5Aer6xboWZe39RDEft4MeVxSQ8D1EYAVLZw9',
202-
Sepolia: '0xB231aD95f2301bc82eA44c515001F0F746D637e0',
203-
ArbitrumSepolia: '0xEec94CD3083e067398256a79CcA7e740C5c8ef81',
204-
BaseSepolia: '0xB03b030b2f5B40819Df76467d67eD1C85Ff66fAD',
205-
OptimismSepolia: '0x7f430D4e7939D994C0955A01FC75D9DE33F12D11',
206-
},
207-
Devnet: {},
208-
};
209-
210-
export const NTT_TRANSCEIVER_CONTRACT: { [key in Network]: { [key in Chain]?: string } } = {
211-
Mainnet: {},
212-
Testnet: {
213-
Solana: '9WNzy7xYZyL2k6JnE9dWSp7VpYkvfRN3Rhd8wHv9J9mY',
214-
Sepolia: '0x1fDC902e30b188FD2BA976B421Cb179943F57896',
215-
ArbitrumSepolia: '0x0E24D17D7467467b39Bf64A9DFf88776Bd6c74d7',
216-
BaseSepolia: '0x1e072169541f1171e427Aa44B5fd8924BEE71b0e',
217-
OptimismSepolia: '0x41265eb2863bf0238081F6AeefeF73549C82C3DD',
218-
},
219-
Devnet: {},
220-
};

0 commit comments

Comments
 (0)