1
- import React , { ReactElement , memo } from 'react' ;
1
+ import React , { ReactElement , useEffect , useState } from 'react' ;
2
2
3
- import { Chains , chainMetadata } from '@hyperlane-xyz/sdk' ;
4
- import { isNumeric } from '@hyperlane-xyz/utils' ;
5
-
6
- import ArbitrumBlack from '../logos/black/Arbitrum.js' ;
7
- import AvalancheBlack from '../logos/black/Avalanche.js' ;
8
- import BaseBlack from '../logos/black/Base.js' ;
9
- import BscBlack from '../logos/black/Bsc.js' ;
10
- import CeloBlack from '../logos/black/Celo.js' ;
11
- import EthereumBlack from '../logos/black/Ethereum.js' ;
12
- import GnosisBlack from '../logos/black/Gnosis.js' ;
13
- import InevmBlack from '../logos/black/Inevm.js' ;
14
- import InjectiveBlack from '../logos/black/Injective.js' ;
15
- import MantaBlack from '../logos/black/Manta.js' ;
16
- import MoonbeamBlack from '../logos/black/Moonbeam.js' ;
17
- import NautilusBlack from '../logos/black/Nautilus.js' ;
18
- import NeutronBlack from '../logos/black/Neutron.js' ;
19
- import OptimismBlack from '../logos/black/Optimism.js' ;
20
- import PlumeBlack from '../logos/black/Plume.js' ;
21
- import PolygonBlack from '../logos/black/Polygon.js' ;
22
- import PolygonzkevmBlack from '../logos/black/Polygonzkevm.js' ;
23
- import ScrollBlack from '../logos/black/Scroll.js' ;
24
- import SolanaBlack from '../logos/black/Solana.js' ;
25
- import VictionBlack from '../logos/black/Viction.js' ;
26
- import ArbitrumColor from '../logos/color/Arbitrum.js' ;
27
- import AvalancheColor from '../logos/color/Avalanche.js' ;
28
- import BaseColor from '../logos/color/Base.js' ;
29
- import BscColor from '../logos/color/Bsc.js' ;
30
- import CeloColor from '../logos/color/Celo.js' ;
31
- import EthereumColor from '../logos/color/Ethereum.js' ;
32
- import GnosisColor from '../logos/color/Gnosis.js' ;
33
- import InevmColor from '../logos/color/Inevm.js' ;
34
- import InjectiveColor from '../logos/color/Injective.js' ;
35
- import MantaColor from '../logos/color/Manta.js' ;
36
- import MoonbeamColor from '../logos/color/Moonbeam.js' ;
37
- import NautilusColor from '../logos/color/Nautilus.js' ;
38
- import NeutronColor from '../logos/color/Neutron.js' ;
39
- import OptimismColor from '../logos/color/Optimism.js' ;
40
- import PlumeColor from '../logos/color/Plume.js' ;
41
- import PolygonColor from '../logos/color/Polygon.js' ;
42
- import PolygonzkevmColor from '../logos/color/Polygonzkevm.js' ;
43
- import ScrollColor from '../logos/color/Scroll.js' ;
44
- import SolanaColor from '../logos/color/Solana.js' ;
45
- import VictionColor from '../logos/color/Viction.js' ;
3
+ import { IRegistry } from '@hyperlane-xyz/registry' ;
46
4
47
5
import { Circle } from './Circle.js' ;
48
6
import { QuestionMarkIcon } from './QuestionMark.js' ;
49
7
50
8
type SvgIcon = ( props : { width : number ; height : number ; title ?: string } ) => ReactElement ;
51
9
52
- // Keep up to date as new chains are added or
53
- // icon will fallback to default (question mark)
54
- const CHAIN_TO_LOGO : Record < string | number , { black : SvgIcon ; color : SvgIcon } > = {
55
- [ chainMetadata [ Chains . alfajores ] . chainId ] : { black : CeloBlack , color : CeloColor } ,
56
- [ chainMetadata [ Chains . arbitrum ] . chainId ] : { black : ArbitrumBlack , color : ArbitrumColor } ,
57
- [ chainMetadata [ Chains . avalanche ] . chainId ] : { black : AvalancheBlack , color : AvalancheColor } ,
58
- [ chainMetadata [ Chains . base ] . chainId ] : { black : BaseBlack , color : BaseColor } ,
59
- [ chainMetadata [ Chains . bsc ] . chainId ] : { black : BscBlack , color : BscColor } ,
60
- [ chainMetadata [ Chains . bsctestnet ] . chainId ] : { black : BscBlack , color : BscColor } ,
61
- [ chainMetadata [ Chains . celo ] . chainId ] : { black : CeloBlack , color : CeloColor } ,
62
- [ chainMetadata [ Chains . chiado ] . chainId ] : { black : GnosisBlack , color : GnosisColor } ,
63
- [ chainMetadata [ Chains . ethereum ] . chainId ] : { black : EthereumBlack , color : EthereumColor } ,
64
- [ chainMetadata [ Chains . fuji ] . chainId ] : { black : AvalancheBlack , color : AvalancheColor } ,
65
- [ chainMetadata [ Chains . gnosis ] . chainId ] : { black : GnosisBlack , color : GnosisColor } ,
66
- [ chainMetadata [ Chains . inevm ] . chainId ] : { black : InevmBlack , color : InevmColor } ,
67
- [ chainMetadata [ Chains . injective ] . chainId ] : { black : InjectiveBlack , color : InjectiveColor } ,
68
- [ chainMetadata [ Chains . mantapacific ] . chainId ] : { black : MantaBlack , color : MantaColor } ,
69
- [ chainMetadata [ Chains . moonbeam ] . chainId ] : { black : MoonbeamBlack , color : MoonbeamColor } ,
70
- [ chainMetadata [ Chains . mumbai ] . chainId ] : { black : PolygonBlack , color : PolygonColor } ,
71
- [ chainMetadata [ Chains . nautilus ] . chainId ] : { black : NautilusBlack , color : NautilusColor } ,
72
- [ chainMetadata [ Chains . neutron ] . chainId ] : { black : NeutronBlack , color : NeutronColor } ,
73
- [ chainMetadata [ Chains . optimism ] . chainId ] : { black : OptimismBlack , color : OptimismColor } ,
74
- [ chainMetadata [ Chains . plumetestnet ] . chainId ] : { black : PlumeBlack , color : PlumeColor } ,
75
- [ chainMetadata [ Chains . polygon ] . chainId ] : { black : PolygonBlack , color : PolygonColor } ,
76
- [ chainMetadata [ Chains . polygonzkevm ] . chainId ] : {
77
- black : PolygonzkevmBlack ,
78
- color : PolygonzkevmColor ,
79
- } ,
80
- [ chainMetadata [ Chains . scroll ] . chainId ] : { black : ScrollBlack , color : ScrollColor } ,
81
- [ chainMetadata [ Chains . scrollsepolia ] . chainId ] : { black : ScrollBlack , color : ScrollColor } ,
82
- [ chainMetadata [ Chains . sepolia ] . chainId ] : { black : EthereumBlack , color : EthereumColor } ,
83
- [ chainMetadata [ Chains . solana ] . chainId ] : { black : SolanaBlack , color : SolanaColor } ,
84
- [ chainMetadata [ Chains . solanadevnet ] . chainId ] : { black : SolanaBlack , color : SolanaColor } ,
85
- [ chainMetadata [ Chains . viction ] . chainId ] : { black : VictionBlack , color : VictionColor } ,
86
- } ;
87
-
88
10
export interface ChainLogoProps {
89
- chainId ?: number | string ;
90
- chainName ?: string ;
11
+ chainName : string ;
12
+ registry : IRegistry ;
91
13
size ?: number ;
92
- color ?: boolean ;
93
14
background ?: boolean ;
94
- icon ?: SvgIcon ; // Override the default set used above. Necessary for PI chain logos.
15
+ Icon ?: SvgIcon ; // Optional override for the logo in the registry
95
16
}
96
17
97
- function _ChainLogo ( {
98
- chainId,
18
+ export function ChainLogo ( {
99
19
chainName,
20
+ registry,
100
21
size = 32 ,
101
- color = true ,
102
22
background = false ,
103
- icon ,
23
+ Icon ,
104
24
} : ChainLogoProps ) {
105
- const colorType = color ? 'color' : 'black ';
106
- const title = chainName || chainId ?. toString ( ) || 'Unknown' ;
25
+ const title = chainName || 'Unknown ';
26
+ const bgColorSeed = title . charCodeAt ( 0 ) ;
107
27
const iconSize = Math . floor ( size / 1.9 ) ;
108
- const ImageNode = icon ?? ( chainId ? CHAIN_TO_LOGO [ chainId ] ?. [ colorType ] : null ) ;
109
- const bgColorSeed = chainId && isNumeric ( chainId ) ? parseInt ( chainId . toString ( ) , 10 ) : 0 ;
110
28
111
- if ( ! ImageNode ) {
29
+ const [ svgLogo , setSvgLogo ] = useState ( '' ) ;
30
+ useEffect ( ( ) => {
31
+ if ( ! chainName || svgLogo || Icon ) return ;
32
+ registry
33
+ . getChainLogoUri ( chainName )
34
+ . then ( ( uri ) => uri && setSvgLogo ( uri ) )
35
+ . catch ( ( err ) => console . error ( err ) ) ;
36
+ } , [ chainName , registry , svgLogo , Icon ] ) ;
37
+
38
+ if ( ! svgLogo ) {
112
39
return (
113
40
< Circle size = { size } title = { title } bgColorSeed = { bgColorSeed } >
114
41
{ chainName ? (
@@ -123,12 +50,18 @@ function _ChainLogo({
123
50
if ( background ) {
124
51
return (
125
52
< Circle size = { size } title = { title } classes = "htw-bg-gray-100" >
126
- < ImageNode width = { iconSize } height = { iconSize } />
53
+ { Icon ? (
54
+ < Icon width = { iconSize } height = { iconSize } title = { title } />
55
+ ) : (
56
+ < img src = { svgLogo } alt = { title } width = { iconSize } height = { iconSize } />
57
+ ) }
127
58
</ Circle >
128
59
) ;
129
60
} else {
130
- return < ImageNode width = { size } height = { size } title = { title } /> ;
61
+ return Icon ? (
62
+ < Icon width = { size } height = { size } title = { title } />
63
+ ) : (
64
+ < img src = { svgLogo } alt = { title } width = { size } height = { size } />
65
+ ) ;
131
66
}
132
67
}
133
-
134
- export const ChainLogo = memo ( _ChainLogo ) ;
0 commit comments