Skip to content

Commit

Permalink
test
Browse files Browse the repository at this point in the history
  • Loading branch information
m30m committed Jan 15, 2025
1 parent a65ae6c commit 3589fc3
Show file tree
Hide file tree
Showing 14 changed files with 1,674 additions and 1,006 deletions.
14 changes: 11 additions & 3 deletions auction-server/api-types/src/bid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,11 @@ pub struct BidCreateOnChainSvm {
}

#[derive(Serialize, Deserialize, ToSchema, Clone, Debug)]
#[serde(tag = "type")]
#[serde(rename_all = "snake_case")]
pub enum BidCreateSwapSvmTag {
Swap
}
#[derive(Serialize, Deserialize, ToSchema, Clone, Debug)]
pub struct BidCreateSwapSvm {
/// The chain id to bid on.
#[schema(example = "solana", value_type = String)]
Expand All @@ -277,16 +281,20 @@ pub struct BidCreateSwapSvm {
#[serde(with = "crate::serde::transaction_svm")]
pub transaction: VersionedTransaction,
/// The id of the swap opportunity to bid on.
#[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = Option<String>)]
#[schema(example = "obo3ee3e-58cc-4372-a567-0e02b2c3d479", value_type = String)]
pub opportunity_id: OpportunityId,
/// The bid type. Should be "swap"
#[schema(example = "swap")]
#[serde(rename = "type")]
pub _type: BidCreateSwapSvmTag, // this is mainly to distinguish next types of bids in the future
}


#[derive(Serialize, Deserialize, ToSchema, Debug, Clone)]
#[serde(untagged)]
pub enum BidCreateSvm {
OnChain(BidCreateOnChainSvm),
Swap(BidCreateSwapSvm),
OnChain(BidCreateOnChainSvm),
}


Expand Down
19 changes: 16 additions & 3 deletions auction-server/api-types/src/opportunity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,11 @@ pub struct TokenAmountSvm {
/// Program specific parameters for the opportunity.
#[serde_as]
#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)]
#[serde(tag = "program")]
#[serde(tag = "program", rename_all = "snake_case")]
pub enum OpportunityCreateProgramParamsV1Svm {
/// Limo program specific parameters for the opportunity.
/// It contains the Limo order to be executed, encoded in base64.
/// SDKs will decode this order and create transaction for bidding on the opportunity.
#[serde(rename = "limo")]
#[schema(title = "limo")]
Limo {
/// The Limo order to be executed, encoded in base64.
Expand All @@ -211,7 +210,6 @@ pub enum OpportunityCreateProgramParamsV1Svm {
order_address: Pubkey,
},
/// Swap program specific parameters for the opportunity.
#[serde(rename = "swap")]
#[schema(title = "swap")]
Swap {
/// The user wallet address which requested the quote from the wallet.
Expand Down Expand Up @@ -331,12 +329,27 @@ pub enum OpportunityParamsV1ProgramSvm {
#[serde_as(as = "DisplayFromStr")]
router_account: Pubkey,

/// The referral fee in basis points.
#[schema(example = 10, value_type = u16)]
referral_fee_bps: u16,

/// Specifies whether the fees are to be paid in input or output token.
#[schema(example = "input_token")]
fee_token: FeeToken,

/// Details about the tokens to be swapped. Either the input token amount or the output token amount must be specified.
#[schema(inline)]
tokens: QuoteTokens,
},
}

#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)]
#[serde(rename_all = "snake_case")]
pub enum FeeToken {
InputToken,
OutputToken,
}

#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum QuoteTokens {
Expand Down
4 changes: 4 additions & 0 deletions auction-server/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,9 @@ pub async fn start_api(run_options: RunOptions, store: Arc<StoreNew>) -> Result<
api_types::ws::APIResponse,
api_types::bid::BidCreate,
api_types::bid::BidCreateEvm,
api_types::bid::BidCreateOnChainSvm,
api_types::bid::BidCreateSwapSvm,
api_types::bid::BidCreateSwapSvmTag,
api_types::bid::BidCreateSvm,
api_types::bid::BidStatus,
api_types::bid::BidStatusEvm,
Expand Down Expand Up @@ -372,6 +375,7 @@ pub async fn start_api(run_options: RunOptions, store: Arc<StoreNew>) -> Result<
api_types::opportunity::OpportunityDeleteV1Svm,
api_types::opportunity::OpportunityDeleteV1Evm,
api_types::opportunity::ProgramSvm,
api_types::opportunity::FeeToken,
ErrorBodyResponse,
api_types::ws::ClientRequest,
Expand Down
157 changes: 87 additions & 70 deletions auction-server/src/auction/service/verification.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::str::FromStr;
use {
super::{
auction_manager::TOTAL_BIDS_PER_AUCTION_EVM,
Expand Down Expand Up @@ -447,7 +448,7 @@ impl Service<Svm> {

match instructions.len() {
1 => Ok(instructions[0].clone()),
_ => Err(RestError::BadParameters("Bid must include exactly one instruction to Express Relay program that pays the bid".to_string())),
_ => Err(RestError::BadParameters(format!("Bid must include exactly one instruction to Express Relay program that pays the bid but found {} instructions", instructions.len()))),
}
}

Expand Down Expand Up @@ -483,42 +484,31 @@ impl Service<Svm> {

async fn extract_bid_data(
&self,
transaction: VersionedTransaction,
bid_chain_data_create_svm: &BidChainDataCreateSvm,
) -> Result<BidDataSvm, RestError> {
let submit_bid_instruction_result = self.extract_express_relay_bid_instruction(
transaction.clone(),
BidPaymentInstructionType::SubmitBid,
);
let swap_instruction_result = self.extract_express_relay_bid_instruction(
transaction.clone(),
BidPaymentInstructionType::Swap,
);

match (
submit_bid_instruction_result.clone(),
swap_instruction_result.clone(),
) {
(Ok(submit_bid_instruction), Err(_)) => {
let svm_config = &self.config
.chain_config
.express_relay;
match bid_chain_data_create_svm {
BidChainDataCreateSvm::OnChain(bid_data) => {
let submit_bid_instruction = self.extract_express_relay_bid_instruction(
bid_data.transaction.clone(),
BidPaymentInstructionType::SubmitBid,
)?;
let submit_bid_data = Self::extract_submit_bid_data(&submit_bid_instruction)?;

let permission_account = self
.extract_account(
&transaction,
&bid_data.transaction,
&submit_bid_instruction,
self.config
.chain_config
.express_relay
.permission_account_position_submit_bid,
svm_config.permission_account_position_submit_bid,
)
.await?;
let router = self
.extract_account(
&transaction,
&bid_data.transaction,
&submit_bid_instruction,
self.config
.chain_config
.express_relay
.router_account_position_submit_bid,
svm_config.router_account_position_submit_bid,
)
.await?;
Ok(BidDataSvm {
Expand All @@ -534,49 +524,34 @@ impl Service<Svm> {
})?,
submit_type: SubmitType::ByServer,
})
}
(Err(_), Ok(swap_instruction)) => {
},
BidChainDataCreateSvm::Swap(bid_data) => {
let swap_instruction = self.extract_express_relay_bid_instruction(
bid_data.transaction.clone(),
BidPaymentInstructionType::Swap,
)?;
let swap_data = Self::extract_swap_data(&swap_instruction)?;

let router = self
.extract_account(
&transaction,
&swap_instruction,
self.config
.chain_config
.express_relay
.router_account_position_swap,
)
.await?;
let user_wallet = self
.extract_account(
&transaction,
&bid_data.transaction,
&swap_instruction,
self.config
.chain_config
.express_relay
.user_wallet_account_position_swap,
svm_config.user_wallet_account_position_swap,
)
.await?;

let mint_input = self
.extract_account(
&transaction,
&bid_data.transaction,
&swap_instruction,
self.config
.chain_config
.express_relay
.mint_input_account_position_swap,
svm_config.mint_input_account_position_swap,
)
.await?;
let mint_output = self
.extract_account(
&transaction,
&bid_data.transaction,
&swap_instruction,
self.config
.chain_config
.express_relay
.mint_output_account_position_swap,
svm_config.mint_output_account_position_swap,
)
.await?;

Expand All @@ -602,14 +577,66 @@ impl Service<Svm> {
},
),
};
let mint_fee = match swap_data.fee_token {
FeeToken::Input => mint_input,
FeeToken::Output => mint_output,
};

let opp = self.opportunity_service.get_opportunity_by_id(GetOpportunityByIdInput { opportunity_id: bid_data.opportunity_id }).await.ok_or(
RestError::BadParameters("No swap opportunity with the given id found".to_string())
)?;

let router_fee_receiver_ta = self
.extract_account(
&bid_data.transaction,
&swap_instruction,
self.config
.chain_config
.express_relay
.router_account_position_swap,
)
.await?;

//TODO* : do not hardcode the token program and refactor into separate function
let fee_token_program = Pubkey::from_str(
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
)
.map_err(|e| {
RestError::BadParameters(format!("Invalid token program address: {:?}", e))
})?;
let associated_token_program = Pubkey::from_str(
"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
)
.map_err(|e| {
RestError::BadParameters(format!(
"Invalid associated token program address: {:?}",
e
))
})?;

let expected_router_fee_receiver_ta = Pubkey::find_program_address(
&[
&opp.router.to_bytes(),
&fee_token_program.to_bytes(),
&mint_fee.to_bytes(),
],
&associated_token_program,
)
.0;

if router_fee_receiver_ta != expected_router_fee_receiver_ta {
return Err(RestError::BadParameters(
"Must use approved router token account for swap instruction".to_string(),
));
}

let permission_account =
get_quote_permission_key(&tokens, &user_wallet, swap_data.referral_fee_bps);

Ok(BidDataSvm {
amount: bid_amount,
permission_account,
router,
router: opp.router,
deadline: OffsetDateTime::from_unix_timestamp(swap_data.deadline).map_err(
|e| {
RestError::BadParameters(format!(
Expand All @@ -620,10 +647,8 @@ impl Service<Svm> {
)?,
submit_type: SubmitType::ByOther,
})

}
_ => Err(RestError::BadParameters(
"Either submit_bid or swap must be present, but not both".to_string(),
)),
}
}

Expand Down Expand Up @@ -695,14 +720,6 @@ impl Service<Svm> {
})
.await;


// if bid.chain_data.opportunity_id.is_some() {
// let opp = self.opportunity_service.get_opportunity_by_id(GetOpportunityByIdInput { opportunity_id: bid.chain_data.opportunity_id.unwrap() }).await;
// tracing::info!("opp {:?}", opp);
// tracing::info!("chain_data {:?}", chain_data);
// }


let opportunity = opportunities
.first()
.ok_or_else(|| RestError::BadParameters("Opportunity not found".to_string()))?;
Expand Down Expand Up @@ -846,11 +863,11 @@ impl Verification<Svm> for Service<Svm> {
input: VerifyBidInput<Svm>,
) -> Result<VerificationResult<Svm>, RestError> {
let bid = input.bid_create;
Svm::check_tx_size(&bid.chain_data.get_transaction())?;
self.check_compute_budget(&bid.chain_data.get_transaction())
.await?;
let transaction = bid.chain_data.get_transaction().clone();
Svm::check_tx_size(&transaction)?;
self.check_compute_budget(&transaction).await?;
let bid_data = self
.extract_bid_data(bid.chain_data.get_transaction().clone())
.extract_bid_data(&bid.chain_data)
.await?;
let bid_payment_instruction_type = match bid_data.submit_type {
SubmitType::ByServer => BidPaymentInstructionType::SubmitBid,
Expand All @@ -866,7 +883,7 @@ impl Verification<Svm> for Service<Svm> {
permission_account: bid_data.permission_account,
router: bid_data.router,
bid_payment_instruction_type,
transaction: bid.chain_data.get_transaction().clone(),
transaction: transaction.clone(),
};
let permission_key = bid_chain_data.get_permission_key();
tracing::Span::current().record("permission_key", bid_data.permission_account.to_string());
Expand Down
6 changes: 6 additions & 0 deletions auction-server/src/opportunity/entities/opportunity_svm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,16 @@ impl From<OpportunitySvm> for api::OpportunitySvm {
output_token: sell_token.token,
}
};
let fee_token = match program.fee_token {
FeeToken::InputToken => api::FeeToken::InputToken,
FeeToken::OutputToken => api::FeeToken::OutputToken,
};
api::OpportunityParamsV1ProgramSvm::Swap {
user_wallet_address: program.user_wallet_address,
permission_account: val.permission_account,
router_account: val.router,
fee_token,
referral_fee_bps: program.referral_fee_bps,
// TODO can we make it type safe?
tokens,
}
Expand Down
2 changes: 0 additions & 2 deletions sdk/js/src/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,10 @@ export const SVM_CONSTANTS: Record<string, SvmConstantsConfig> = {
expressRelayProgram: new PublicKey(
"PytERJFhAKuNNuaiXkApLfWzwNwSNDACpigT3LwQfou"
),
walletRouter: new PublicKey("3hv8L8UeBbyM3M25dF3h2C5p8yA4FptD7FFZu4Z1jCMn"),
},
solana: {
expressRelayProgram: new PublicKey(
"PytERJFhAKuNNuaiXkApLfWzwNwSNDACpigT3LwQfou"
),
walletRouter: new PublicKey("3hv8L8UeBbyM3M25dF3h2C5p8yA4FptD7FFZu4Z1jCMn"),
},
};
Loading

0 comments on commit 3589fc3

Please sign in to comment.