2828 TokenAccountInitializationConfigs ,
2929 } ,
3030 service:: {
31+ get_express_relay_metadata:: GetExpressRelayMetadataInput ,
3132 get_live_opportunities:: GetLiveOpportunitiesInput ,
3233 get_opportunities:: GetLiveOpportunityByIdInput ,
3334 get_quote:: {
@@ -278,26 +279,50 @@ impl Service {
278279 } )
279280 }
280281
281- pub fn extract_swap_data (
282+ pub async fn extract_swap_data (
283+ & self ,
282284 instruction : & CompiledInstruction ,
283- ) -> Result < express_relay_svm:: SwapArgs , RestError > {
284- let discriminator = express_relay_svm:: instruction:: Swap :: DISCRIMINATOR ;
285- express_relay_svm:: SwapArgs :: try_from_slice (
286- & instruction. data . as_slice ( ) [ discriminator. len ( ) ..] ,
287- )
288- . map_err ( |e| RestError :: BadParameters ( format ! ( "Invalid swap instruction data: {}" , e) ) )
285+ ) -> Result < express_relay_svm:: SwapV2Args , RestError > {
286+ if instruction
287+ . data
288+ . starts_with ( express_relay_svm:: instruction:: Swap :: DISCRIMINATOR )
289+ {
290+ let discriminator = express_relay_svm:: instruction:: Swap :: DISCRIMINATOR ;
291+ let express_relay_metadata = self
292+ . opportunity_service
293+ . get_express_relay_metadata ( GetExpressRelayMetadataInput {
294+ chain_id : self . config . chain_id . clone ( ) ,
295+ } )
296+ . await ?;
297+ let swap_args = express_relay_svm:: SwapArgs :: try_from_slice (
298+ & instruction. data . as_slice ( ) [ discriminator. len ( ) ..] ,
299+ )
300+ . map_err ( |e| {
301+ RestError :: BadParameters ( format ! ( "Invalid swap instruction data: {}" , e) )
302+ } ) ?;
303+ Ok ( swap_args. convert_to_v2 ( express_relay_metadata. swap_platform_fee_bps ) )
304+ } else {
305+ let discriminator = express_relay_svm:: instruction:: SwapV2 :: DISCRIMINATOR ;
306+ express_relay_svm:: SwapV2Args :: try_from_slice (
307+ & instruction. data . as_slice ( ) [ discriminator. len ( ) ..] ,
308+ )
309+ . map_err ( |e| RestError :: BadParameters ( format ! ( "Invalid swap instruction data: {}" , e) ) )
310+ }
289311 }
290312
291313 pub fn extract_express_relay_instruction (
292314 & self ,
293315 transaction : VersionedTransaction ,
294316 instruction_type : BidPaymentInstructionType ,
295317 ) -> Result < ( usize , CompiledInstruction ) , RestError > {
296- let discriminator = match instruction_type {
318+ let valid_discriminators = match instruction_type {
297319 BidPaymentInstructionType :: SubmitBid => {
298- express_relay_svm:: instruction:: SubmitBid :: DISCRIMINATOR
320+ vec ! [ express_relay_svm:: instruction:: SubmitBid :: DISCRIMINATOR ]
299321 }
300- BidPaymentInstructionType :: Swap => express_relay_svm:: instruction:: Swap :: DISCRIMINATOR ,
322+ BidPaymentInstructionType :: Swap => vec ! [
323+ express_relay_svm:: instruction:: Swap :: DISCRIMINATOR ,
324+ express_relay_svm:: instruction:: SwapV2 :: DISCRIMINATOR ,
325+ ] ,
301326 } ;
302327 let instructions = Self :: extract_program_instructions (
303328 & transaction,
@@ -316,7 +341,10 @@ impl Service {
316341 instructions. len ( ) ,
317342 ) ) ,
318343 } ?;
319- if !instruction. data . starts_with ( discriminator) {
344+ if valid_discriminators
345+ . iter ( )
346+ . all ( |discriminator| !instruction. data . starts_with ( discriminator) )
347+ {
320348 return Err ( RestError :: BadParameters (
321349 "Wrong instruction type for Express Relay Program" . to_string ( ) ,
322350 ) ) ;
@@ -398,7 +426,7 @@ impl Service {
398426 bid_data. transaction . clone ( ) ,
399427 BidPaymentInstructionType :: Swap ,
400428 ) ?;
401- let swap_data = Self :: extract_swap_data ( & swap_instruction) ?;
429+ let swap_data = self . extract_swap_data ( & swap_instruction) . await ?;
402430 let SwapAccounts {
403431 user_wallet,
404432 mint_searcher,
@@ -508,11 +536,20 @@ impl Service {
508536 ) ) ;
509537 }
510538
511- if swap_data. referral_fee_bps != opportunity_swap_data. referral_fee_bps {
539+ if swap_data. referral_fee_ppm != opportunity_swap_data. referral_fee_ppm {
512540 return Err ( RestError :: InvalidSwapInstruction (
513541 SwapInstructionError :: ReferralFee {
514- expected : opportunity_swap_data. referral_fee_bps ,
515- found : swap_data. referral_fee_bps ,
542+ expected : opportunity_swap_data. referral_fee_ppm ,
543+ found : swap_data. referral_fee_ppm ,
544+ } ,
545+ ) ) ;
546+ }
547+
548+ if swap_data. swap_platform_fee_ppm != opportunity_swap_data. platform_fee_ppm {
549+ return Err ( RestError :: InvalidSwapInstruction (
550+ SwapInstructionError :: PlatformFee {
551+ expected : opportunity_swap_data. platform_fee_ppm ,
552+ found : swap_data. swap_platform_fee_ppm ,
516553 } ,
517554 ) ) ;
518555 }
@@ -604,7 +641,7 @@ impl Service {
604641 async fn check_transfer_instruction (
605642 & self ,
606643 tx : & VersionedTransaction ,
607- swap_data : & express_relay_svm:: SwapArgs ,
644+ swap_data : & express_relay_svm:: SwapV2Args ,
608645 swap_accounts : & SwapAccounts ,
609646 opportunity_swap_data : & OpportunitySvmProgramSwap ,
610647 ) -> Result < ( ) , RestError > {
@@ -1081,7 +1118,7 @@ impl Service {
10811118 async fn check_wrap_unwrap_native_token_instructions (
10821119 & self ,
10831120 tx : & VersionedTransaction ,
1084- swap_data : & express_relay_svm:: SwapArgs ,
1121+ swap_data : & express_relay_svm:: SwapV2Args ,
10851122 swap_accounts : & SwapAccounts ,
10861123 opportunity_swap_data : & OpportunitySvmProgramSwap ,
10871124 ) -> Result < ( ) , RestError > {
@@ -1170,7 +1207,7 @@ impl Service {
11701207 bid_data. transaction . clone ( ) ,
11711208 BidPaymentInstructionType :: Swap ,
11721209 ) ?;
1173- let swap_data = Self :: extract_swap_data ( & swap_instruction) ?;
1210+ let swap_data = self . extract_swap_data ( & swap_instruction) . await ?;
11741211 let swap_accounts = self
11751212 . extract_swap_accounts ( & bid_data. transaction , & swap_instruction)
11761213 . await ?;
@@ -1229,7 +1266,7 @@ impl Service {
12291266 & quote_tokens,
12301267 & user_wallet,
12311268 & router_token_account,
1232- swap_data. referral_fee_bps ,
1269+ swap_data. referral_fee_ppm ,
12331270 ) ;
12341271
12351272 Ok ( BidDataSvm {
@@ -1607,6 +1644,7 @@ mod tests {
16071644 } ,
16081645 } ,
16091646 borsh:: BorshDeserialize ,
1647+ express_relay:: state:: FEE_BPS_TO_PPM ,
16101648 express_relay_api_types:: opportunity as opportunity_api,
16111649 express_relay_client:: svm:: {
16121650 self ,
@@ -1654,10 +1692,12 @@ mod tests {
16541692 Self {
16551693 user_wallet_address,
16561694 platform_fee_bps : 0 ,
1695+ platform_fee_ppm : 0 ,
16571696 token_program_user : spl_token:: id ( ) ,
16581697 token_program_searcher : spl_token:: id ( ) ,
16591698 fee_token : FeeToken :: UserToken ,
16601699 referral_fee_bps : 10 ,
1700+ referral_fee_ppm : 1_000 ,
16611701 user_mint_user_balance : LAMPORTS_PER_SOL ,
16621702 token_account_initialization_configs :
16631703 TokenAccountInitializationConfigs :: searcher_payer ( ) ,
@@ -1721,6 +1761,7 @@ mod tests {
17211761 searcher_token : spl_token:: native_mint:: id ( ) ,
17221762 } ;
17231763 let referral_fee_bps = 10 ;
1764+ let referral_fee_ppm = referral_fee_bps * FEE_BPS_TO_PPM ;
17241765
17251766 let router_token_account = get_associated_token_address_with_program_id (
17261767 & router,
@@ -1737,25 +1778,25 @@ mod tests {
17371778 & tokens_user_specified,
17381779 & user_wallet_address,
17391780 & router_token_account,
1740- referral_fee_bps ,
1781+ referral_fee_ppm ,
17411782 ) ;
17421783 let permission_account_searcher_token_specified = get_quote_virtual_permission_account (
17431784 & tokens_searcher_specified,
17441785 & user_wallet_address,
17451786 & router_token_account,
1746- referral_fee_bps ,
1787+ referral_fee_ppm ,
17471788 ) ;
17481789 let permission_account_user_token_wsol = get_quote_virtual_permission_account (
17491790 & tokens_user_wsol,
17501791 & user_wallet_address,
17511792 & router_token_account_wsol,
1752- referral_fee_bps ,
1793+ referral_fee_ppm ,
17531794 ) ;
17541795 let permission_account_searcher_token_wsol = get_quote_virtual_permission_account (
17551796 & tokens_searcher_wsol,
17561797 & user_wallet_address,
17571798 & router_token_account,
1758- referral_fee_bps ,
1799+ referral_fee_ppm ,
17591800 ) ;
17601801
17611802 let opp_user_token_specified = OpportunitySvm {
@@ -1875,7 +1916,7 @@ mod tests {
18751916 & tokens_user_specified,
18761917 & indicative_price_taker,
18771918 & router_token_account,
1878- referral_fee_bps ,
1919+ referral_fee_ppm ,
18791920 ) ;
18801921
18811922 let opp_with_indicative_price_taker = OpportunitySvm {
@@ -2026,6 +2067,24 @@ mod tests {
20262067 . cloned ( )
20272068 } ) ;
20282069
2070+ opportunity_service
2071+ . expect_get_express_relay_metadata ( )
2072+ . returning ( move |_| {
2073+ Ok ( express_relay:: state:: ExpressRelayMetadata {
2074+ admin : Pubkey :: new_unique ( ) ,
2075+ relayer_signer : Pubkey :: new_unique ( ) ,
2076+ fee_receiver_relayer : Pubkey :: new_unique ( ) ,
2077+ // the portion of the bid that goes to the router, in bps
2078+ split_router_default : 10 ,
2079+ // the portion of the remaining bid (after router fees) that goes to the relayer, in bps
2080+ split_relayer : 20 ,
2081+ // the portion of the swap amount that should go to the platform (relayer + express relay), in bps
2082+ swap_platform_fee_bps : 30 ,
2083+ // secondary relayer signer, useful for 0-downtime transitioning to a new relayer
2084+ secondary_relayer_signer : Pubkey :: new_unique ( ) ,
2085+ } )
2086+ } ) ;
2087+
20292088 (
20302089 opportunity_service,
20312090 TestOpportunities {
@@ -2897,7 +2956,7 @@ mod tests {
28972956 OpportunitySvmProgram :: Swap ( program) => program,
28982957 _ => panic ! ( "Expected swap program" ) ,
28992958 } ;
2900- program. referral_fee_bps += 1 ;
2959+ program. referral_fee_ppm += 1 ;
29012960 opportunity. program = OpportunitySvmProgram :: Swap ( program. clone ( ) ) ;
29022961 let swap_instruction = svm:: Svm :: get_swap_instruction ( GetSwapInstructionParams {
29032962 searcher : searcher. pubkey ( ) ,
@@ -2914,8 +2973,8 @@ mod tests {
29142973 assert_eq ! (
29152974 result. unwrap_err( ) ,
29162975 RestError :: InvalidSwapInstruction ( SwapInstructionError :: ReferralFee {
2917- expected: program. referral_fee_bps - 1 ,
2918- found: program. referral_fee_bps ,
2976+ expected: program. referral_fee_ppm - 1 ,
2977+ found: program. referral_fee_ppm ,
29192978 } )
29202979 ) ;
29212980 }
0 commit comments