1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use {
    crate::{
        accounts,
        instruction,
        InitializeArgs,
        SubmitBidArgs,
        ID as EXPRESS_RELAY_PID,
        SEED_CONFIG_ROUTER,
        SEED_METADATA,
    },
    anchor_lang::{
        prelude::*,
        solana_program::{
            instruction::Instruction,
            sysvar::instructions as sysvar_instructions,
        },
        system_program,
        InstructionData,
    },
};

// This file contains setup helpers for integrating programs to set up express relay for Rust-based tests

/// Helper method to create an instruction to initialize the express relay program
/// Should be able to sign transactions with the secret keys of the provided payer and relayer_signer
/// The fee split is set to 100% for the router, since fee payments to relayer are not important for the integrating program's tests
/// Instead it is more important for the integrating program to ensure their router account has enough rent to avoid InsufficientRent error
pub fn create_initialize_express_relay_ix(
    payer: Pubkey,
    admin: Pubkey,
    relayer_signer: Pubkey,
    fee_receiver_relayer: Pubkey,
) -> Instruction {
    let express_relay_metadata =
        Pubkey::find_program_address(&[SEED_METADATA], &EXPRESS_RELAY_PID).0;

    let split_router_default = 10000;
    let split_relayer = 0;

    let accounts_initialize = accounts::Initialize {
        payer,
        express_relay_metadata,
        admin,
        relayer_signer,
        fee_receiver_relayer,
        system_program: system_program::ID,
    }
    .to_account_metas(None);
    let data_initialize = instruction::Initialize {
        data: InitializeArgs {
            split_router_default,
            split_relayer,
        },
    }
    .data();

    Instruction {
        program_id: EXPRESS_RELAY_PID,
        accounts:   accounts_initialize,
        data:       data_initialize,
    }
}

/// Creates and adds to the provided instructions a SubmitBid instruction
pub fn add_express_relay_submit_bid_instruction(
    ixs: &mut Vec<Instruction>,
    searcher: Pubkey,
    relayer_signer: Pubkey,
    fee_receiver_relayer: Pubkey,
    permission: Pubkey,
    router: Pubkey,
    bid_amount: u64,
) -> Vec<Instruction> {
    let deadline = i64::MAX;

    let ix_submit_bid = create_submit_bid_instruction(
        searcher,
        relayer_signer,
        fee_receiver_relayer,
        permission,
        router,
        deadline,
        bid_amount,
    );
    ixs.push(ix_submit_bid);

    ixs.to_vec()
}


pub fn create_submit_bid_instruction(
    searcher: Pubkey,
    relayer_signer: Pubkey,
    fee_receiver_relayer: Pubkey,
    permission: Pubkey,
    router: Pubkey,
    deadline: i64,
    bid_amount: u64,
) -> Instruction {
    let config_router =
        Pubkey::find_program_address(&[SEED_CONFIG_ROUTER, router.as_ref()], &EXPRESS_RELAY_PID).0;
    let express_relay_metadata =
        Pubkey::find_program_address(&[SEED_METADATA], &EXPRESS_RELAY_PID).0;

    let accounts_submit_bid = accounts::SubmitBid {
        searcher,
        relayer_signer,
        permission,
        router,
        config_router,
        fee_receiver_relayer,
        express_relay_metadata,
        system_program: system_program::ID,
        sysvar_instructions: sysvar_instructions::ID,
    }
    .to_account_metas(None);
    let data_submit_bid = instruction::SubmitBid {
        data: SubmitBidArgs {
            deadline,
            bid_amount,
        },
    }
    .data();

    Instruction {
        program_id: EXPRESS_RELAY_PID,
        accounts:   accounts_submit_bid,
        data:       data_submit_bid,
    }
}