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