Skip to main content

intent_transfer/bridge/cpi/
ntt_with_executor.rs

1use anchor_lang::prelude::*;
2use anchor_lang::solana_program;
3use anchor_lang::solana_program::instruction::Instruction;
4
5pub const NTT_WITH_EXECUTOR_PROGRAM_ID: Pubkey =
6    Pubkey::from_str_const("nex1gkSWtRBheEJuQZMqHhbMG5A45qPU76KqnCZNVHR");
7
8pub const EXECUTOR_PROGRAM_ID: Pubkey =
9    Pubkey::from_str_const("execXUrAsMnqMmTHj5m7N1YQgsDz3cwGLYCYyuDRciV");
10
11pub const RELAY_NTT_MESSAGE_DISCRIMINATOR: [u8; 8] = [192, 85, 112, 237, 55, 33, 49, 150];
12
13#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)]
14pub struct RelayNttMessageArgs {
15    pub recipient_chain: u16,
16    pub exec_amount: u64,
17    pub signed_quote_bytes: Vec<u8>,
18    pub relay_instructions: Vec<u8>,
19}
20
21#[derive(Accounts)]
22pub struct RelayNttMessage<'info> {
23    /// CHECK: unneeded for CPI
24    pub payer: AccountInfo<'info>,
25
26    /// CHECK: unneeded for CPI
27    pub payee: AccountInfo<'info>,
28
29    /// CHECK: unneeded for CPI
30    pub ntt_program_id: AccountInfo<'info>,
31
32    /// CHECK: unneeded for CPI
33    pub ntt_peer: AccountInfo<'info>,
34
35    /// CHECK: unneeded for CPI
36    pub ntt_message: AccountInfo<'info>,
37
38    /// CHECK: unneeded for CPI
39    pub executor_program: AccountInfo<'info>,
40
41    /// CHECK: unneeded for CPI
42    pub system_program: AccountInfo<'info>,
43}
44
45pub fn relay_ntt_message<'info>(
46    ctx: CpiContext<'_, '_, '_, 'info, RelayNttMessage<'info>>,
47    args: RelayNttMessageArgs,
48) -> Result<()> {
49    let accounts = ctx.accounts;
50    let account_metas = vec![
51        AccountMeta::new(*accounts.payer.key, true),
52        AccountMeta::new(*accounts.payee.key, false),
53        AccountMeta::new_readonly(*accounts.ntt_program_id.key, false),
54        AccountMeta::new_readonly(*accounts.ntt_peer.key, false),
55        AccountMeta::new_readonly(*accounts.ntt_message.key, false),
56        AccountMeta::new_readonly(*accounts.executor_program.key, false),
57        AccountMeta::new_readonly(*accounts.system_program.key, false),
58    ];
59
60    let mut data = Vec::new();
61    data.extend_from_slice(&RELAY_NTT_MESSAGE_DISCRIMINATOR);
62    args.serialize(&mut data)?;
63
64    let instruction = Instruction {
65        program_id: NTT_WITH_EXECUTOR_PROGRAM_ID,
66        accounts: account_metas,
67        data,
68    };
69
70    let account_infos = &[
71        accounts.payer,
72        accounts.payee,
73        accounts.ntt_program_id,
74        accounts.ntt_peer,
75        accounts.ntt_message,
76        accounts.executor_program,
77        accounts.system_program,
78    ];
79
80    solana_program::program::invoke_signed(&instruction, account_infos, ctx.signer_seeds)
81        .map_err(Into::into)
82}