@@ -417,34 +417,109 @@ export class OFT extends OmniSDK implements IOApp {
417417 throw new TypeError ( `getCallerBpsCap() not implemented on Solana OFT SDK` )
418418 }
419419
420- public async sendConfigIsInitialized ( _eid : EndpointId ) : Promise < boolean > {
421- const deriver = new MessageLibPDADeriver ( UlnProgram . PROGRAM_ID )
422- const [ sendConfig ] = deriver . sendConfig ( _eid , new PublicKey ( this . point . address ) )
423- const accountInfo = await this . connection . getAccountInfo ( sendConfig )
424- return accountInfo != null
420+ public async sendConfigIsInitialized ( eid : EndpointId ) : Promise < boolean > {
421+ // This method should check the same conditions that initConfig checks
422+ // All components must be initialized: OFT store, send/receive libraries, and ULN config accounts
423+
424+ // Check OFT store exists
425+ const oftStoreInfo = await this . umi . rpc . getAccount ( this . umiPublicKey )
426+ if ( ! oftStoreInfo . exists ) {
427+ return false
428+ }
429+
430+ // Check OFT send/receive libraries are initialized
431+ const sendLibInitialized = await this . isSendLibraryInitialized ( eid )
432+ const receiveLibInitialized = await this . isReceiveLibraryInitialized ( eid )
433+
434+ if ( ! sendLibInitialized || ! receiveLibInitialized ) {
435+ return false
436+ }
437+
438+ // Check ULN config accounts using MessageLibPDADeriver (same as wire command)
439+ try {
440+ const deriver = new MessageLibPDADeriver ( UlnProgram . PROGRAM_ID )
441+ const [ sendConfig , receiveConfig ] = await Promise . all ( [
442+ deriver . sendConfig ( eid , new PublicKey ( this . point . address ) ) ,
443+ deriver . receiveConfig ( eid , new PublicKey ( this . point . address ) ) ,
444+ ] )
445+
446+ const [ sendConfigInfo , receiveConfigInfo ] = await Promise . all ( [
447+ this . connection . getAccountInfo ( sendConfig [ 0 ] ) ,
448+ this . connection . getAccountInfo ( receiveConfig [ 0 ] ) ,
449+ ] )
450+
451+ return sendConfigInfo != null && receiveConfigInfo != null
452+ } catch ( error ) {
453+ this . logger . debug ( `ULN config check failed for eid ${ eid } : ${ error } ` )
454+ return false
455+ }
425456 }
426457
427458 public async initConfig ( eid : EndpointId ) : Promise < OmniTransaction | undefined > {
459+ // Check if everything is already initialized - if so, no action needed
460+ if ( await this . sendConfigIsInitialized ( eid ) ) {
461+ return undefined
462+ }
463+
428464 const delegateAddress = await this . getDelegate ( )
429465 // delegate may be undefined if it has not yet been set. In this case, use admin, which must exist.
430466 const delegate = delegateAddress ? createNoopSigner ( publicKey ( delegateAddress ) ) : await this . _getAdmin ( )
467+ const oftStore = this . umiPublicKey
468+ const instructions : WrappedInstruction [ ] = [ ]
469+
470+ // Now check individual components to determine which instructions to add
471+ const oftStoreExists = ( await this . umi . rpc . getAccount ( oftStore ) ) . exists
472+ const sendLibInitialized = await this . isSendLibraryInitialized ( eid )
473+ const receiveLibInitialized = await this . isReceiveLibraryInitialized ( eid )
474+
475+ // Check ULN config accounts
476+ const deriver = new MessageLibPDADeriver ( UlnProgram . PROGRAM_ID )
477+ const [ sendConfig , receiveConfig ] = await Promise . all ( [
478+ deriver . sendConfig ( eid , new PublicKey ( this . point . address ) ) ,
479+ deriver . receiveConfig ( eid , new PublicKey ( this . point . address ) ) ,
480+ ] )
481+
482+ const [ sendConfigInfo , receiveConfigInfo ] = await Promise . all ( [
483+ this . connection . getAccountInfo ( sendConfig [ 0 ] ) ,
484+ this . connection . getAccountInfo ( receiveConfig [ 0 ] ) ,
485+ ] )
486+
487+ const ulnConfigExists = sendConfigInfo != null && receiveConfigInfo != null
488+
489+ // Add oft.initConfig if either OFT store OR ULN config accounts don't exist
490+ // This single instruction handles both the store creation and ULN config account initialization
491+ if ( ! oftStoreExists || ! ulnConfigExists ) {
492+ instructions . push (
493+ oft . initConfig (
494+ {
495+ admin : delegate ,
496+ oftStore,
497+ payer : delegate ,
498+ } ,
499+ eid ,
500+ {
501+ msgLib : fromWeb3JsPublicKey ( UlnProgram . PROGRAM_ID ) ,
502+ }
503+ )
504+ )
505+ }
506+
507+ // Add send/receive library initialization if needed
508+ if ( ! sendLibInitialized ) {
509+ instructions . push ( oft . initSendLibrary ( { admin : delegate , oftStore } , eid ) )
510+ }
511+
512+ if ( ! receiveLibInitialized ) {
513+ instructions . push ( oft . initReceiveLibrary ( { admin : delegate , oftStore } , eid ) )
514+ }
515+
516+ if ( instructions . length === 0 ) {
517+ return undefined
518+ }
519+
431520 return {
432- ...( await this . createTransaction (
433- this . _umiToWeb3Tx ( [
434- oft . initConfig (
435- {
436- admin : delegate ,
437- oftStore : this . umiPublicKey ,
438- payer : delegate ,
439- } ,
440- eid ,
441- {
442- msgLib : fromWeb3JsPublicKey ( UlnProgram . PROGRAM_ID ) ,
443- }
444- ) ,
445- ] )
446- ) ) ,
447- description : `oft.initConfig(${ eid } )` ,
521+ ...( await this . createTransaction ( this . _umiToWeb3Tx ( instructions ) ) ) ,
522+ description : `Initializing OFT config for eid ${ eid } (${ formatEid ( eid ) } )` ,
448523 }
449524 }
450525
0 commit comments