@@ -1015,28 +1015,37 @@ yargs(hideBin(process.argv))
10151015 } )
10161016 . command ( "create-spl-multisig <multisigMemberPubkey...>" ,
10171017 "create a valid SPL Multisig (see https://github.com/wormhole-foundation/native-token-transfers/tree/main/solana#spl-multisig-support for more info)" ,
1018- ( yargs ) =>
1019- yargs
1020- . positional ( "multisigMemberPubkey" , {
1021- describe :
1022- "public keys of the members that can independently mint" ,
1023- type : "string" ,
1024- demandOption : true ,
1025- } )
1026- . option ( "path" , options . deploymentPath )
1027- . option ( "payer" , { ...options . payer , demandOption : true } )
1028- . example (
1029- "$0 solana create-spl-multisig Sol1234... --payer <SOLANA_KEYPAIR_PATH>" ,
1030- "Create multisig with Sol1234... having independent mint privilege alongside NTT token-authority"
1031- )
1032- . example (
1033- "$0 solana create-spl-multisig Sol1234... Sol3456... Sol5678... --payer <SOLANA_KEYPAIR_PATH>" ,
1034- "Create multisig with Sol1234..., Sol3456..., and Sol5678... having mint privileges alongside NTT token-authority"
1035- ) ,
1018+ ( yargs ) => yargs
1019+ . positional ( "multisigMemberPubkey" , {
1020+ describe : "public keys of the members that can independently mint" ,
1021+ type : "string" ,
1022+ demandOption : true ,
1023+ } )
1024+ . option ( "manager" , {
1025+ describe : "Manager address" ,
1026+ type : "string" ,
1027+ } )
1028+ . option ( "token" , {
1029+ describe : "Token address" ,
1030+ type : "string" ,
1031+ } )
1032+ . option ( "path" , options . deploymentPath )
1033+ . option ( "yes" , options . yes )
1034+ . option ( "payer" , { ...options . payer , demandOption : true } )
1035+ . example (
1036+ "$0 solana create-spl-multisig Sol1234... --token Sol3456... --manager Sol5678... --payer <SOLANA_KEYPAIR_PATH>" ,
1037+ "Create multisig with Sol1234... having independent mint privilege alongside NTT token-authority for undeployed program"
1038+ )
1039+ . example (
1040+ "$0 solana create-spl-multisig Sol1234... Sol3456... Sol5678... --payer <SOLANA_KEYPAIR_PATH>" ,
1041+ "Create multisig with Sol1234..., Sol3456..., and Sol5678... having mint privileges alongside NTT token-authority for deployed program"
1042+ ) ,
10361043 async ( argv ) => {
10371044 const path = argv [ "path" ] ;
10381045 const deployments : Config = loadConfig ( path ) ;
10391046 const chain : Chain = "Solana" ;
1047+ const manager = argv [ "manager" ] ;
1048+ const token = argv [ "token" ] ;
10401049 const network = deployments . network as Network ;
10411050
10421051 if ( ! fs . existsSync ( argv [ "payer" ] ) ) {
@@ -1049,44 +1058,101 @@ yargs(hideBin(process.argv))
10491058 )
10501059 ) ;
10511060
1052- if ( ! ( chain in deployments . chains ) ) {
1053- console . error ( `Chain ${ chain } not found in ${ path } ` ) ;
1061+ if ( ! token !== ! manager ) {
1062+ console . error (
1063+ "Please provide both --token and --manager for an undeployed program"
1064+ ) ;
10541065 process . exit ( 1 ) ;
10551066 }
1056- const chainConfig = deployments . chains [ chain ] ! ;
1057- const wh = new Wormhole ( network , [ solana . Platform , evm . Platform ] , overrides ) ;
1058- const ch = wh . getChain ( chain ) ;
1059- const connection = await ch . getRpc ( ) ;
1060- const [ , , ntt ] = await pullChainConfig (
1067+
1068+ const wh = new Wormhole (
10611069 network ,
1062- { chain , address : toUniversal ( chain , chainConfig . manager ) } ,
1070+ [ solana . Platform , evm . Platform ] ,
10631071 overrides
10641072 ) ;
1065- const solanaNtt = ntt as SolanaNtt < typeof network , SolanaChains > ;
1066- const tokenAuthority = NTT . pdas ( chainConfig . manager ) . tokenAuthority ( ) ;
1073+ const ch = wh . getChain ( chain ) ;
1074+ const connection : Connection = await ch . getRpc ( ) ;
1075+
1076+ let solanaNtt : SolanaNtt < typeof network , SolanaChains > | undefined ;
1077+ let managerKey : PublicKey ;
1078+ let major : number ;
1079+ let tokenProgram : PublicKey ;
1080+
1081+ // program deployed so fetch token and manager addresses from deployment
1082+ if ( ! token && ! manager ) {
1083+ if ( ! ( chain in deployments . chains ) ) {
1084+ console . error ( `Either provide --token and --manager flags, or ensure ${ path } contains a valid ${ chain } configuration` ) ;
1085+ process . exit ( 1 ) ;
1086+ }
1087+ const chainConfig = deployments . chains [ chain ] ! ;
1088+ const [ , , ntt ] = await pullChainConfig (
1089+ network ,
1090+ { chain, address : toUniversal ( chain , chainConfig . manager ) } ,
1091+ overrides
1092+ ) ;
1093+ solanaNtt = ntt as SolanaNtt < typeof network , SolanaChains > ;
1094+ managerKey = new PublicKey ( chainConfig . manager ) ;
1095+ major = Number ( solanaNtt . version . split ( "." ) [ 0 ] ) ;
1096+ tokenProgram = ( await solanaNtt . getConfig ( ) ) . tokenProgram ;
1097+ }
1098+ // default values as undeployed program
1099+ else {
1100+ // ensure mint is valid
1101+ const tokenMint = new PublicKey ( token ! ) ;
1102+ const mintInfo = await connection . getAccountInfo ( tokenMint ) ;
1103+ if ( ! mintInfo ) {
1104+ console . error (
1105+ `Mint ${ token } not found on ${ ch . chain } ${ ch . network } `
1106+ ) ;
1107+ process . exit ( 1 ) ;
1108+ }
1109+ spl . unpackMint ( tokenMint , mintInfo , mintInfo . owner ) ;
1110+
1111+ solanaNtt = undefined ;
1112+ managerKey = new PublicKey ( manager ! ) ;
1113+ major = - 1 ;
1114+ tokenProgram = mintInfo . owner ;
1115+ }
1116+
1117+ const tokenAuthority = NTT . pdas ( managerKey ) . tokenAuthority ( ) ;
10671118
10681119 // check if SPL-Multisig is supported for manager version
1069- const major = Number ( solanaNtt . version . split ( "." ) [ 0 ] ) ;
1070- if ( major < 3 ) {
1120+ // undeployed -- assume version compatible via warning
1121+ if ( major === - 1 && ! argv [ "yes" ] ) {
1122+ console . warn (
1123+ chalk . yellow (
1124+ "SPL Multisig token mint authority is only supported for versions >= 3.x.x"
1125+ )
1126+ ) ;
1127+ console . warn (
1128+ chalk . yellow (
1129+ "Ensure the program version you wish to deploy supports SPL Multisig token mint authority"
1130+ )
1131+ ) ;
1132+ await askForConfirmation ( ) ;
1133+ }
1134+ // unsupported version
1135+ else if ( major < 3 ) {
10711136 console . error (
10721137 "SPL Multisig token mint authority is only supported for versions >= 3.x.x"
10731138 ) ;
1074- console . error ( "Use 'ntt upgrade' to upgrade the NTT contract to a specific version." ) ;
1139+ console . error (
1140+ "Use 'ntt upgrade' to upgrade the NTT contract to a specific version."
1141+ ) ;
10751142 process . exit ( 1 ) ;
10761143 }
10771144
10781145 try {
10791146 // use same tokenProgram as token to create multisig
1080- const tokenProgram = ( await solanaNtt . getConfig ( ) ) . tokenProgram ;
10811147 const additionalMemberPubkeys = ( argv [ "multisigMemberPubkey" ] as any ) . map (
10821148 ( key : string ) => new PublicKey ( key )
10831149 ) ;
10841150 const multisig = await spl . createMultisig (
10851151 connection ,
10861152 payerKeypair ,
10871153 [
1088- tokenAuthority ,
1089- ...additionalMemberPubkeys ,
1154+ tokenAuthority ,
1155+ ...additionalMemberPubkeys ,
10901156 ] ,
10911157 1 ,
10921158 undefined ,
@@ -1326,18 +1392,18 @@ yargs(hideBin(process.argv))
13261392 try {
13271393 const latestBlockHash = await connection . getLatestBlockhash ( ) ;
13281394 const messageV0 = new TransactionMessage ( {
1329- payerKey : payerKeypair . publicKey ,
1330- instructions : [
1331- await NTT . createAcceptTokenAuthorityInstruction (
1332- solanaNtt . program ,
1333- await solanaNtt . getConfig ( ) ,
1334- {
1335- currentAuthority : payerKeypair . publicKey ,
1336- multisigTokenAuthority,
1337- }
1338- ) ,
1339- ] ,
1340- recentBlockhash : latestBlockHash . blockhash ,
1395+ payerKey : payerKeypair . publicKey ,
1396+ instructions : [
1397+ await NTT . createAcceptTokenAuthorityInstruction (
1398+ solanaNtt . program ,
1399+ await solanaNtt . getConfig ( ) ,
1400+ {
1401+ currentAuthority : payerKeypair . publicKey ,
1402+ multisigTokenAuthority,
1403+ }
1404+ ) ,
1405+ ] ,
1406+ recentBlockhash : latestBlockHash . blockhash ,
13411407 } ) . compileToV0Message ( luts ) ;
13421408 const vtx = new VersionedTransaction ( messageV0 ) ;
13431409 vtx . sign ( [ payerKeypair ] ) ;
0 commit comments