@@ -12,7 +12,8 @@ import chalk from "chalk";
12
12
import yargs from "yargs" ;
13
13
import { $ } from "bun" ;
14
14
import { hideBin } from "yargs/helpers" ;
15
- import { Keypair , PublicKey } from "@solana/web3.js" ;
15
+ import { Connection , Keypair , PublicKey } from "@solana/web3.js" ;
16
+ import * as spl from "@solana/spl-token" ;
16
17
import fs from "fs" ;
17
18
import readline from "readline" ;
18
19
import { ChainContext , UniversalAddress , Wormhole , assertChain , canonicalAddress , chainToPlatform , chains , isNetwork , networks , platforms , signSendWait , toUniversal , type AccountAddress , type Chain , type ChainAddress , type ConfigOverrides , type Network , type Platform } from "@wormhole-foundation/sdk" ;
@@ -966,6 +967,9 @@ async function deploySolana<N extends Network, C extends SolanaChains>(
966
967
) : Promise < ChainAddress < C > > {
967
968
ensureNttRoot ( pwd ) ;
968
969
970
+ // TODO: if the binary is provided, we should not check addresses in the source tree. (so we should move around the control flow a bit)
971
+ // TODO: factor out some of this into separate functions to help readability of this function (maybe even move to a different file)
972
+
969
973
const wormhole = ch . config . contracts . coreBridge ;
970
974
if ( ! wormhole ) {
971
975
console . error ( "Core bridge not found" ) ;
@@ -1030,6 +1034,49 @@ async function deploySolana<N extends Network, C extends SolanaChains>(
1030
1034
fs . writeFileSync ( libRsPath , newLibRs ) ;
1031
1035
}
1032
1036
1037
+
1038
+ // First we check that the provided mint's mint authority is the program's token authority PDA when in burning mode.
1039
+ // This is checked in the program initialiser anyway, but we can save some
1040
+ // time by checking it here and failing early (not to mention better
1041
+ // diagnostics).
1042
+
1043
+ const emitter = NTT . pdas ( providedProgramId ) . emitterAccount ( ) . toBase58 ( ) ;
1044
+ const payerKeypair = Keypair . fromSecretKey ( new Uint8Array ( JSON . parse ( fs . readFileSync ( payer ) . toString ( ) ) ) ) ;
1045
+
1046
+ // can't do this yet.. need to init first.
1047
+ // const {ntt, addresses} = await nttFromManager(ch, providedProgramId);
1048
+ const ntt : SolanaNtt < N , C > = await ch . getProtocol ( "Ntt" , {
1049
+ ntt : {
1050
+ manager : providedProgramId ,
1051
+ token : token ,
1052
+ transceiver : { wormhole : emitter } ,
1053
+ }
1054
+ } ) as SolanaNtt < N , C > ;
1055
+
1056
+ // get the mint authority of 'token'
1057
+ const tokenMint = new PublicKey ( token ) ;
1058
+ // const tokenInfo = await ch.connection.getTokenInfo(tokenMint);
1059
+ const connection : Connection = await ch . getRpc ( ) ;
1060
+ const mintInfo = await connection . getAccountInfo ( tokenMint )
1061
+ if ( ! mintInfo ) {
1062
+ console . error ( `Mint ${ token } not found on ${ ch . chain } ${ ch . network } ` ) ;
1063
+ process . exit ( 1 ) ;
1064
+ }
1065
+ const mint = spl . unpackMint ( tokenMint , mintInfo , mintInfo . owner ) ;
1066
+
1067
+ if ( mode === "burning" ) {
1068
+ const expectedMintAuthority = ntt . pdas . tokenAuthority ( ) . toBase58 ( ) ;
1069
+ const actualMintAuthority : string | null = mint . mintAuthority ?. toBase58 ( ) ?? null ;
1070
+ if ( actualMintAuthority !== expectedMintAuthority ) {
1071
+ console . error ( `Mint authority mismatch for ${ token } ` ) ;
1072
+ console . error ( `Expected: ${ expectedMintAuthority } ` ) ;
1073
+ console . error ( `Actual: ${ actualMintAuthority } ` ) ;
1074
+ console . error ( `Set the mint authority to the program's token authority PDA with e.g.:` ) ;
1075
+ console . error ( `spl-token authorize ${ token } mint ${ expectedMintAuthority } ` ) ;
1076
+ process . exit ( 1 ) ;
1077
+ }
1078
+ }
1079
+
1033
1080
let binary : string ;
1034
1081
1035
1082
const skipDeploy = false ;
@@ -1086,20 +1133,6 @@ async function deploySolana<N extends Network, C extends SolanaChains>(
1086
1133
// wait 3 seconds
1087
1134
await new Promise ( ( resolve ) => setTimeout ( resolve , 3000 ) ) ;
1088
1135
1089
- const emitter = NTT . pdas ( providedProgramId ) . emitterAccount ( ) . toBase58 ( ) ;
1090
-
1091
- const payerKeypair = Keypair . fromSecretKey ( new Uint8Array ( JSON . parse ( fs . readFileSync ( payer ) . toString ( ) ) ) ) ;
1092
-
1093
- // can't do this yet.. need to init first.
1094
- // const {ntt, addresses} = await nttFromManager(ch, providedProgramId);
1095
- const ntt : SolanaNtt < N , C > = await ch . getProtocol ( "Ntt" , {
1096
- ntt : {
1097
- manager : providedProgramId ,
1098
- token : token ,
1099
- transceiver : { wormhole : emitter } ,
1100
- }
1101
- } ) as SolanaNtt < N , C > ;
1102
-
1103
1136
const tx = ntt . initialize (
1104
1137
toUniversal ( ch . chain , payerKeypair . publicKey . toBase58 ( ) ) ,
1105
1138
{
0 commit comments