@@ -14,7 +14,12 @@ import {
1414} from '@lifi/sdk' ;
1515import bs58 from 'bs58' ;
1616import type { ChainMetadata } from '@hyperlane-xyz/sdk' ;
17- import { ProtocolType , assert , ensure0x } from '@hyperlane-xyz/utils' ;
17+ import {
18+ ProtocolType ,
19+ assert ,
20+ ensure0x ,
21+ isEVMLike ,
22+ } from '@hyperlane-xyz/utils' ;
1823import type { Logger } from 'pino' ;
1924import { type Chain , createWalletClient , http } from 'viem' ;
2025import { privateKeyToAccount } from 'viem/accounts' ;
@@ -142,10 +147,8 @@ export class LiFiBridge implements IExternalBridge {
142147 const metadataByDomainId = new Map < number , ChainMetadata > ( ) ;
143148 for ( const metadata of Object . values ( config . chainMetadata ) ) {
144149 metadataByDomainId . set ( metadata . domainId , metadata ) ;
145- if ( metadata . chainId !== undefined ) {
146- if ( metadata . protocol === ProtocolType . Ethereum ) {
147- this . chainMetadataByChainId . set ( Number ( metadata . chainId ) , metadata ) ;
148- }
150+ if ( metadata . chainId !== undefined && isEVMLike ( metadata . protocol ) ) {
151+ this . chainMetadataByChainId . set ( Number ( metadata . chainId ) , metadata ) ;
149152 }
150153 }
151154 // Also key by LiFi chain IDs so both Hyperlane domains and LiFi IDs
@@ -185,11 +188,24 @@ export class LiFiBridge implements IExternalBridge {
185188 * Iterates metadata to find matching chainId and returns first HTTP RPC URL.
186189 */
187190 private getRpcUrlForChainId ( chainId : number ) : string | undefined {
188- return this . chainMetadataByChainId . get ( chainId ) ?. rpcUrls ?. [ 0 ] ?. http ;
191+ return this . getMetadataForChainId ( chainId ) ?. rpcUrls ?. [ 0 ] ?. http ;
189192 }
190193
191194 private getProtocolTypeForChainId ( chainId : number ) : ProtocolType | undefined {
192- return this . chainMetadataByChainId . get ( chainId ) ?. protocol ;
195+ return this . getMetadataForChainId ( chainId ) ?. protocol ;
196+ }
197+
198+ private getMetadataForChainId ( chainId : number ) : ChainMetadata | undefined {
199+ const directMetadata = this . chainMetadataByChainId . get ( chainId ) ;
200+ if ( directMetadata ) {
201+ return directMetadata ;
202+ }
203+
204+ const matches = Object . values ( this . config . chainMetadata ?? { } ) . filter (
205+ ( metadata ) =>
206+ metadata . chainId !== undefined && Number ( metadata . chainId ) === chainId ,
207+ ) ;
208+ return matches . length === 1 ? matches [ 0 ] : undefined ;
193209 }
194210
195211 private addressesEqual ( a : string , b : string , chainId : number ) : boolean {
@@ -202,68 +218,63 @@ export class LiFiBridge implements IExternalBridge {
202218 }
203219
204220 /**
205- * Configure LiFi SDK providers from the given private keys.
206- * Sets up wallet/signer for each protocol type present in the keys map.
221+ * Configure the LiFi SDK provider for the route source protocol.
207222 */
208- private configureLiFiProviders (
209- privateKeys : Partial < Record < ProtocolType , string > > ,
223+ private configureLiFiProvider (
224+ protocol : ProtocolType ,
225+ key : string ,
210226 fromChain : number ,
211227 fromRpcUrl : string | undefined ,
212228 ) : void {
213229 const providers : Parameters < typeof lifiConfig . setProviders > [ 0 ] = [ ] ;
214- for ( const [ protocol , key ] of Object . entries ( privateKeys ) ) {
215- switch ( protocol ) {
216- case ProtocolType . Ethereum : {
217- const account = privateKeyToAccount ( ensure0x ( key ) as `0x${string } `) ;
218- const chain = getViemChain ( fromChain , fromRpcUrl ) ;
219- const walletClient = createWalletClient ( {
220- account,
221- chain,
222- transport : http ( fromRpcUrl ) ,
223- } ) ;
224- providers . push (
225- EVM ( {
226- getWalletClient : async ( ) => walletClient ,
227- switchChain : async ( requiredChainId : number ) => {
228- const switchRpcUrl = this . getRpcUrlForChainId ( requiredChainId ) ;
229- const requiredChain = getViemChain (
230- requiredChainId ,
231- switchRpcUrl ,
232- ) ;
233- return createWalletClient ( {
234- account,
235- chain : requiredChain ,
236- transport : http ( switchRpcUrl ) ,
237- } ) ;
238- } ,
239- } ) ,
240- ) ;
241- break ;
242- }
243- case ProtocolType . Sealevel : {
244- const base58Key = toBase58SolanaKey ( key ) ;
245- providers . push (
246- Solana ( {
247- getWalletAdapter : async ( ) => new KeypairWalletAdapter ( base58Key ) ,
248- } ) ,
249- ) ;
250- break ;
251- }
252- default :
253- throw new Error (
254- `Unsupported protocol type '${ protocol } ' for LiFi provider` ,
255- ) ;
230+ switch ( protocol ) {
231+ case ProtocolType . Ethereum : {
232+ const account = privateKeyToAccount ( ensure0x ( key ) as `0x${string } `) ;
233+ const chain = getViemChain ( fromChain , fromRpcUrl ) ;
234+ const walletClient = createWalletClient ( {
235+ account,
236+ chain,
237+ transport : http ( fromRpcUrl ) ,
238+ } ) ;
239+ providers . push (
240+ EVM ( {
241+ getWalletClient : async ( ) => walletClient ,
242+ switchChain : async ( requiredChainId : number ) => {
243+ const switchRpcUrl = this . getRpcUrlForChainId ( requiredChainId ) ;
244+ const requiredChain = getViemChain ( requiredChainId , switchRpcUrl ) ;
245+ return createWalletClient ( {
246+ account,
247+ chain : requiredChain ,
248+ transport : http ( switchRpcUrl ) ,
249+ } ) ;
250+ } ,
251+ } ) ,
252+ ) ;
253+ break ;
256254 }
255+ case ProtocolType . Sealevel : {
256+ const base58Key = toBase58SolanaKey ( key ) ;
257+ providers . push (
258+ Solana ( {
259+ getWalletAdapter : async ( ) => new KeypairWalletAdapter ( base58Key ) ,
260+ } ) ,
261+ ) ;
262+ break ;
263+ }
264+ default :
265+ throw new Error (
266+ `Unsupported protocol type '${ protocol } ' for LiFi provider` ,
267+ ) ;
257268 }
258269
259270 lifiConfig . setProviders ( providers ) ;
260271
261272 this . logger . debug (
262273 {
263274 fromChain,
264- protocols : Object . keys ( privateKeys ) ,
275+ protocol ,
265276 } ,
266- 'Configured LiFi providers for route execution' ,
277+ 'Configured LiFi provider for route execution' ,
267278 ) ;
268279 }
269280
@@ -497,9 +508,10 @@ export class LiFiBridge implements IExternalBridge {
497508 const fromChain = route . fromChainId ;
498509 const toChain = route . toChainId ;
499510 const fromProtocol = this . getProtocolTypeForChainId ( fromChain ) ;
511+ const sourceProtocol = fromProtocol ?? ProtocolType . Ethereum ;
500512 assert (
501- privateKeys [ fromProtocol ?? ProtocolType . Ethereum ] ,
502- `Missing private key for source chain protocol ${ fromProtocol ?? ProtocolType . Ethereum } ` ,
513+ privateKeys [ sourceProtocol ] ,
514+ `Missing private key for source chain protocol ${ sourceProtocol } ` ,
503515 ) ;
504516
505517 this . logger . info (
@@ -527,14 +539,11 @@ export class LiFiBridge implements IExternalBridge {
527539 let executedRoute ! : RouteExtended ;
528540
529541 try {
530- this . configureLiFiProviders ( privateKeys , fromChain , fromRpcUrl ) ;
531-
532- this . logger . debug (
533- {
534- fromChain,
535- protocols : Object . keys ( privateKeys ) ,
536- } ,
537- 'Configured LiFi providers for route execution' ,
542+ this . configureLiFiProvider (
543+ sourceProtocol ,
544+ privateKeys [ sourceProtocol ] ! ,
545+ fromChain ,
546+ fromRpcUrl ,
538547 ) ;
539548
540549 // Execute route with update callbacks
0 commit comments