Skip to content

Commit 9aa7510

Browse files
authored
Merge pull request #152 from m0-foundation/kurtis/add-set-mint-ix
Set portal mint instruction
2 parents de5b2ea + c168d0e commit 9aa7510

File tree

4 files changed

+110
-9
lines changed

4 files changed

+110
-9
lines changed

programs/portal/src/instructions/admin.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use anchor_lang::prelude::*;
2-
use anchor_spl::{token_2022::spl_token_2022::instruction::AuthorityType, token_interface};
2+
use anchor_spl::{
3+
token_2022::{spl_token_2022::instruction::AuthorityType, Token2022},
4+
token_interface,
5+
};
36

47
use crate::{
58
config::Config,
@@ -9,6 +12,7 @@ use crate::{
912
pending_token_authority::PendingTokenAuthority,
1013
queue::{inbox::InboxRateLimit, outbox::OutboxRateLimit, rate_limit::RateLimitState},
1114
registered_transceiver::RegisteredTransceiver,
15+
TOKEN_AUTHORITY_SEED,
1216
};
1317

1418
// * Transfer ownership
@@ -625,3 +629,38 @@ pub fn set_threshold(ctx: Context<SetThreshold>, threshold: u8) -> Result<()> {
625629
ctx.accounts.config.threshold = threshold;
626630
Ok(())
627631
}
632+
633+
// * Set Mint
634+
#[derive(Accounts)]
635+
pub struct SetMint<'info> {
636+
pub owner: Signer<'info>,
637+
638+
#[account(
639+
mut,
640+
has_one = owner,
641+
constraint = config.paused @ NTTError::NotPaused,
642+
)]
643+
pub config: Account<'info, Config>,
644+
645+
pub mint: InterfaceAccount<'info, token_interface::Mint>,
646+
647+
/// CHECK: This account is validated by its seeds
648+
#[account(
649+
seeds = [TOKEN_AUTHORITY_SEED],
650+
bump,
651+
)]
652+
pub token_authority: UncheckedAccount<'info>,
653+
654+
#[account(
655+
associated_token::mint = mint,
656+
associated_token::authority = token_authority,
657+
associated_token::token_program = Token2022::id(),
658+
)]
659+
pub custody: InterfaceAccount<'info, token_interface::TokenAccount>,
660+
}
661+
662+
pub fn set_mint(ctx: Context<SetMint>) -> Result<()> {
663+
ctx.accounts.config.mint = ctx.accounts.mint.key();
664+
ctx.accounts.config.custody = ctx.accounts.custody.key();
665+
Ok(())
666+
}

programs/portal/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ pub mod portal {
172172
instructions::claim_token_authority(ctx)
173173
}
174174

175+
pub fn set_mint(ctx: Context<SetMint>) -> Result<()> {
176+
instructions::set_mint(ctx)
177+
}
178+
175179
pub fn set_paused(ctx: Context<SetPaused>, pause: bool) -> Result<()> {
176180
instructions::set_paused(ctx, pause)
177181
}

services/cli/main.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import {
4545
} from '../../sdk/src';
4646
import { createInitializeConfidentialTransferMintInstruction } from './confidential-transfers';
4747
import { Program, BN } from '@coral-xyz/anchor';
48-
import { anchorProvider, keysFromEnv, NttManager } from './utils';
48+
import { anchorProvider, keysFromEnv, NttManager, updatePortalMint } from './utils';
4949
import { MerkleTree } from '../../sdk/src/merkle';
5050
import { bs58 } from '@coral-xyz/anchor/dist/cjs/utils/bytes';
5151
import { SolanaUnsignedTransaction } from '@wormhole-foundation/sdk-solana/dist/cjs';
@@ -78,7 +78,7 @@ async function main() {
7878
.command('print-addresses')
7979
.description('Print the addresses of all the relevant programs and accounts')
8080
.action(() => {
81-
const [mMint, wmMint, multisig] = keysFromEnv(['M_MINT_KEYPAIR', 'WM_MINT_KEYPAIR', 'M_MINT_MULTISIG_KEYPAIR']);
81+
const [mMint, wmMint] = keysFromEnv(['M_MINT_KEYPAIR', 'WM_MINT_KEYPAIR']);
8282
const [portalTokenAuthPda] = PublicKey.findProgramAddressSync([Buffer.from('token_authority')], PROGRAMS.portal);
8383
const [earnTokenAuthPda] = PublicKey.findProgramAddressSync([Buffer.from('token_authority')], PROGRAMS.earn);
8484
const [portalEmitter] = PublicKey.findProgramAddressSync([Buffer.from('emitter')], PROGRAMS.portal);
@@ -94,7 +94,6 @@ async function main() {
9494
'Earn Program': PROGRAMS.earn,
9595
'Swap Program': PROGRAMS.swap,
9696
'M Mint': mMint.publicKey,
97-
'M Mint Multisig': multisig.publicKey,
9897
'Portal Token Authority': portalTokenAuthPda,
9998
'Earn Token Authority': earnTokenAuthPda,
10099
'wM Mint': wmMint.publicKey,
@@ -246,7 +245,26 @@ async function main() {
246245
});
247246

248247
program.command('update-portal-mint').action(async () => {
249-
const [owner] = keysFromEnv(['PAYER_KEYPAIR']);
248+
const [payer, mint] = keysFromEnv(['PAYER_KEYPAIR', 'M_MINT_KEYPAIR']);
249+
const { ntt } = NttManager(connection, payer, mint.publicKey);
250+
251+
let owner = payer.publicKey;
252+
if (process.env.SQUADS_VAULT) {
253+
owner = new PublicKey(process.env.SQUADS_VAULT);
254+
}
255+
256+
const tx = new Transaction().add(updatePortalMint(owner, ntt.pdas.configAccount(), mint.publicKey));
257+
258+
if (process.env.SQUADS_VAULT) {
259+
const b = tx.serialize({ verifySignatures: false });
260+
console.log('Transaction:', {
261+
b64: b.toString('base64'),
262+
b58: bs58.encode(b),
263+
});
264+
} else {
265+
const sig = await connection.sendTransaction(tx, [payer]);
266+
console.log(`Paused: ${sig}`);
267+
}
250268
});
251269

252270
program
@@ -366,7 +384,7 @@ async function main() {
366384
const pauseTxn = (await ntt.pause(sender).next()).value as SolanaUnsignedTransaction<'Mainnet', 'Solana'>;
367385
const tx = pauseTxn.transaction.transaction as Transaction;
368386

369-
if (process.env.SQUADS_MULTISIG) {
387+
if (process.env.SQUADS_VAULT) {
370388
const b = tx.serialize({ verifySignatures: false });
371389
console.log('Transaction:', {
372390
b64: b.toString('base64'),
@@ -390,7 +408,7 @@ async function main() {
390408
const pauseTxn = (await cmd(sender).next()).value as SolanaUnsignedTransaction<'Mainnet', 'Solana'>;
391409
const tx = pauseTxn.transaction.transaction as Transaction;
392410

393-
if (process.env.SQUADS_MULTISIG) {
411+
if (process.env.SQUADS_VAULT) {
394412
const b = tx.serialize({ verifySignatures: false });
395413
console.log('Transaction:', {
396414
b64: b.toString('base64'),

services/cli/utils.ts

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { Keypair, Connection, PublicKey } from '@solana/web3.js';
1+
import { Keypair, Connection, PublicKey, TransactionInstruction } from '@solana/web3.js';
22
import { SolanaNtt } from '@wormhole-foundation/sdk-solana-ntt';
33
import { SolanaPlatform, SolanaSendSigner } from '@wormhole-foundation/sdk-solana';
4-
import { AccountAddress, Wormhole } from '@wormhole-foundation/sdk';
4+
import { AccountAddress, sha256, Wormhole } from '@wormhole-foundation/sdk';
55
import { AnchorProvider, Wallet } from '@coral-xyz/anchor';
6+
import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID } from '@solana/spl-token';
67

78
const PORTAL = new PublicKey('mzp1q2j5Hr1QuLC3KFBCAUz5aUckT6qyuZKZ3WJnMmY');
89

@@ -45,3 +46,42 @@ export function anchorProvider(connection: Connection, owner: Keypair) {
4546
skipPreflight: false,
4647
});
4748
}
49+
50+
export function updatePortalMint(owner: PublicKey, config: PublicKey, mMint: PublicKey): TransactionInstruction {
51+
return new TransactionInstruction({
52+
programId: PORTAL,
53+
keys: [
54+
{
55+
pubkey: owner,
56+
isSigner: true,
57+
isWritable: false,
58+
},
59+
{
60+
pubkey: config,
61+
isSigner: false,
62+
isWritable: true,
63+
},
64+
{
65+
pubkey: mMint,
66+
isSigner: false,
67+
isWritable: false,
68+
},
69+
{
70+
pubkey: PublicKey.findProgramAddressSync([Buffer.from('token_authority')], PORTAL)[0],
71+
isSigner: false,
72+
isWritable: false,
73+
},
74+
{
75+
pubkey: getAssociatedTokenAddressSync(
76+
mMint,
77+
PublicKey.findProgramAddressSync([Buffer.from('token_authority')], PORTAL)[0],
78+
true,
79+
TOKEN_2022_PROGRAM_ID,
80+
),
81+
isSigner: false,
82+
isWritable: false,
83+
},
84+
],
85+
data: Buffer.concat([Buffer.from(sha256('global:set_mint').subarray(0, 8))]),
86+
});
87+
}

0 commit comments

Comments
 (0)