Skip to content

Commit

Permalink
Fix/improve quote api (#366)
Browse files Browse the repository at this point in the history
* refactor router/referral_fee_bps -> referral_fee_info

* fix internal names

* add opportunity id to quote

* refine frontend api

* fix rust sdk

* fixed program names

* improved ta/ata names

* add referral info to api

* update js sdk

* fix get_quote permission key bug

* python sdk

* before_fees -> including_fees + docstring improvements

* small improvements in docs

* Update auction-server/src/opportunity/api.rs

Co-authored-by: guibescos <59208140+guibescos@users.noreply.github.com>

* address comments

* address moar comments

* bump everything

* bump everything

* update the generated types to new version numbers

* get rid of quote_id from quote response

---------

Co-authored-by: guibescos <59208140+guibescos@users.noreply.github.com>
  • Loading branch information
anihamde and guibescos authored Jan 29, 2025
1 parent 162c6e9 commit e421c2f
Show file tree
Hide file tree
Showing 49 changed files with 2,183 additions and 1,428 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion auction-server/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "auction-server"
version = "0.16.0"
version = "0.17.0"
edition = "2021"
license-file = "license.txt"

Expand Down
2 changes: 1 addition & 1 deletion auction-server/api-types/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "express-relay-api-types"
version = "0.3.0"
version = "0.4.0"
edition = "2021"
description = "Pyth Express Relay api types"
repository = "https://github.com/pyth-network/per"
Expand Down
104 changes: 53 additions & 51 deletions auction-server/api-types/src/opportunity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ pub enum OpportunityParamsV1ProgramSvm {
#[serde_as(as = "DisplayFromStr")]
user_wallet_address: Pubkey,

/// The permission account to be permitted by the ER contract for the opportunity execution of the protocol.
/// The permission account that serves as an identifier for the swap opportunity.
#[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)]
#[serde_as(as = "DisplayFromStr")]
permission_account: Pubkey,
Expand All @@ -330,11 +330,11 @@ pub enum OpportunityParamsV1ProgramSvm {
#[schema(example = 10)]
platform_fee_bps: u64,

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

/// Details about the tokens to be swapped. Either the input token amount or the output token amount must be specified.
/// Details about the tokens to be swapped. Either the searcher token amount or the user token amount must be specified.
#[schema(inline)]
tokens: QuoteTokensWithTokenPrograms,
},
Expand All @@ -343,59 +343,59 @@ pub enum OpportunityParamsV1ProgramSvm {
#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)]
#[serde(rename_all = "snake_case")]
pub enum FeeToken {
InputToken,
OutputToken,
SearcherToken,
UserToken,
}

#[serde_as]
#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)]
#[serde(tag = "side_specified")]
pub enum QuoteTokens {
#[serde(rename = "input")]
#[schema(title = "input_specified")]
InputTokenSpecified {
/// The token that the user wants to receive
#[serde(rename = "searcher")]
#[schema(title = "searcher_specified")]
SearcherTokenSpecified {
/// The token that the searcher will provide
#[schema(example = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", value_type = String)]
#[serde_as(as = "DisplayFromStr")]
input_token: Pubkey,
/// The exact amount that the user wants to receive from the input_token
input_amount: u64,
/// The token that the user wants to send in exchange
searcher_token: Pubkey,
/// The exact amount that the searcher will provide
searcher_amount: u64,
/// The token that the user will provide
#[schema(example = "So11111111111111111111111111111111111111112", value_type = String)]
#[serde_as(as = "DisplayFromStr")]
output_token: Pubkey,
user_token: Pubkey,
},
#[serde(rename = "output")]
#[schema(title = "output_specified")]
OutputTokenSpecified {
/// The token that the user wants to receive
#[serde(rename = "user")]
#[schema(title = "user_specified")]
UserTokenSpecified {
/// The token that the searcher will provide
#[schema(example = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", value_type = String)]
#[serde_as(as = "DisplayFromStr")]
input_token: Pubkey,
/// The token that the user wants to send in exchange
searcher_token: Pubkey,
/// The token that the user will provide
#[schema(example = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", value_type = String)]
#[serde_as(as = "DisplayFromStr")]
output_token: Pubkey,
/// The amount that searcher will receive after deducting fees
output_amount: u64,
/// The exact amount of output_token that the user wants to send in exchange
output_amount_before_fees: u64,
user_token: Pubkey,
/// The amount that searcher will receive from the user after deducting fees
user_amount: u64,
/// The exact amount that the user will provide, including any fees on the user token side
user_amount_including_fees: u64,
},
}

#[serde_as]
#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)]
pub struct QuoteTokensWithTokenPrograms {
#[serde(flatten)]
pub tokens: QuoteTokens,
/// The token program of the input mint.
pub tokens: QuoteTokens,
/// The token program of the searcher mint.
#[schema(example = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", value_type = String)]
#[serde_as(as = "DisplayFromStr")]
pub input_token_program: Pubkey,
/// The token program of the output mint.
pub token_program_searcher: Pubkey,
/// The token program of the user mint.
#[schema(example = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", value_type = String)]
#[serde_as(as = "DisplayFromStr")]
pub output_token_program: Pubkey,
pub token_program_user: Pubkey,
}


Expand Down Expand Up @@ -521,54 +521,56 @@ pub struct OpportunityBidEvm {
}

/// Parameters needed to create a new opportunity from the swap request.
/// Auction server will extract the output token price for the auction.
#[serde_as]
#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)]
pub struct QuoteCreateV1SvmParams {
/// The user wallet address which requested the quote from the wallet.
#[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)]
#[serde_as(as = "DisplayFromStr")]
pub user_wallet_address: Pubkey,
/// The token mint address of the input token.
/// The mint address of the token the user will provide in the swap.
#[schema(example = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", value_type = String)]
#[serde_as(as = "DisplayFromStr")]
pub input_token_mint: Pubkey,
/// The token mint address of the output token.
/// The mint address of the token the user will receive in the swap.
#[schema(example = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", value_type = String)]
#[serde_as(as = "DisplayFromStr")]
pub output_token_mint: Pubkey,
/// The token amount that the user wants to swap out of/into.
#[schema(inline)]
pub specified_token_amount: SpecifiedTokenAmount,
/// The router account to send referral fees to.
#[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)]
#[serde_as(as = "DisplayFromStr")]
pub router: Pubkey,
/// The referral fee in basis points. If not provided, the referral fee will default to 0.
#[serde(default = "default_referral_fee_bps")]
#[schema(example = 10, value_type = u16)]
pub referral_fee_bps: u16,
/// Information about the referral fee and the router to send the fee to. If not provided, referral fee will be set to 0.
#[schema(inline)]
pub referral_fee_info: Option<ReferralFeeInfo>,
/// The chain id for creating the quote.
#[schema(example = "solana", value_type = String)]
pub chain_id: ChainId,
}

fn default_referral_fee_bps() -> u16 {
0
#[serde_as]
#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)]
pub struct ReferralFeeInfo {
/// The router account to send referral fees to.
#[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)]
#[serde_as(as = "DisplayFromStr")]
pub router: Pubkey,
/// The referral fee in basis points.
#[schema(example = 10, value_type = u16)]
pub referral_fee_bps: u16,
}

#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)]
#[serde(tag = "side")]
pub enum SpecifiedTokenAmount {
#[serde(rename = "input")]
#[schema(title = "input")]
InputToken {
UserInputToken {
#[schema(example = 100)]
amount: u64,
},
#[serde(rename = "output")]
#[schema(title = "output")]
OutputToken {
UserOutputToken {
#[schema(example = 50)]
amount: u64,
},
Expand All @@ -591,20 +593,20 @@ pub enum QuoteCreate {

#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)]
pub struct QuoteV1Svm {
/// The signed transaction for the quote to be executed on chain which is valid until the expiration time.
/// The transaction for the quote to be executed on chain which is valid until the expiration time.
#[schema(example = "SGVsbG8sIFdvcmxkIQ==", value_type = String)]
#[serde(with = "crate::serde::transaction_svm")]
pub transaction: VersionedTransaction,
/// The expiration time of the quote (in seconds since the Unix epoch).
#[schema(example = 1_700_000_000_000_000i64, value_type = i64)]
pub expiration_time: i64,
/// The token and amount that the user needs to send to fulfill the swap transaction.
pub output_token: TokenAmountSvm,
/// The token and amount that the user will receive when the swap is complete.
pub input_token: TokenAmountSvm,
/// The token and amount that the referrer will receive when the swap is complete.
/// The token and amount that the user will receive when the swap is complete.
pub output_token: TokenAmountSvm,
/// The token and amount of the referral fee paid to the party that routed the swap request to Express Relay.
pub referrer_fee: TokenAmountSvm,
/// The token and amount that the platform will receive when the swap is complete.
/// The token and amount of the platform fee paid to the Express Relay program and relayer.
pub platform_fee: TokenAmountSvm,
/// The chain id for the quote.
#[schema(example = "solana", value_type = String)]
Expand Down
26 changes: 13 additions & 13 deletions auction-server/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ const SUBMIT_BID_ROUTER_ACCOUNT_SVM: &str = "router";

const SWAP_INSTRUCTION_SVM: &str = "swap";
const SWAP_ROUTER_TOKEN_ACCOUNT_SVM: &str = "router_fee_receiver_ta";
const SWAP_USER_WALLET_ACCOUNT_SVM: &str = "trader";
const SWAP_MINT_INPUT_ACCOUNT_SVM: &str = "mint_input";
const SWAP_MINT_OUTPUT_ACCOUNT_SVM: &str = "mint_output";
const SWAP_TOKEN_PROGRAM_INPUT_SVM: &str = "token_program_input";
const SWAP_TOKEN_PROGRAM_OUTPUT_SVM: &str = "token_program_output";
const SWAP_USER_WALLET_ACCOUNT_SVM: &str = "user";
const SWAP_MINT_SEARCHER_ACCOUNT_SVM: &str = "mint_searcher";
const SWAP_MINT_USER_ACCOUNT_SVM: &str = "mint_user";
const SWAP_TOKEN_PROGRAM_SEARCHER_SVM: &str = "token_program_searcher";
const SWAP_TOKEN_PROGRAM_USER_SVM: &str = "token_program_user";
const IDL_LOCATION: &str = "../contracts/svm/target/idl/express_relay.json";

fn extract_account_position(idl: Idl, instruction_name: &str, account_name: &str) -> usize {
Expand Down Expand Up @@ -107,35 +107,35 @@ fn verify_and_extract_idl_data() {
)
);
println!(
"cargo::rustc-env=SWAP_MINT_INPUT_ACCOUNT_POSITION={}",
"cargo::rustc-env=SWAP_MINT_SEARCHER_ACCOUNT_POSITION={}",
extract_account_position(
express_relay_idl.clone(),
SWAP_INSTRUCTION_SVM,
SWAP_MINT_INPUT_ACCOUNT_SVM,
SWAP_MINT_SEARCHER_ACCOUNT_SVM,
)
);
println!(
"cargo::rustc-env=SWAP_MINT_OUTPUT_ACCOUNT_POSITION={}",
"cargo::rustc-env=SWAP_MINT_USER_ACCOUNT_POSITION={}",
extract_account_position(
express_relay_idl.clone(),
SWAP_INSTRUCTION_SVM,
SWAP_MINT_OUTPUT_ACCOUNT_SVM,
SWAP_MINT_USER_ACCOUNT_SVM,
)
);
println!(
"cargo::rustc-env=SWAP_TOKEN_PROGRAM_INPUT_POSITION={}",
"cargo::rustc-env=SWAP_TOKEN_PROGRAM_SEARCHER_POSITION={}",
extract_account_position(
express_relay_idl.clone(),
SWAP_INSTRUCTION_SVM,
SWAP_TOKEN_PROGRAM_INPUT_SVM,
SWAP_TOKEN_PROGRAM_SEARCHER_SVM,
)
);
println!(
"cargo::rustc-env=SWAP_TOKEN_PROGRAM_OUTPUT_POSITION={}",
"cargo::rustc-env=SWAP_TOKEN_PROGRAM_USER_POSITION={}",
extract_account_position(
express_relay_idl.clone(),
SWAP_INSTRUCTION_SVM,
SWAP_TOKEN_PROGRAM_OUTPUT_SVM,
SWAP_TOKEN_PROGRAM_USER_SVM,
)
);
}
Expand Down
5 changes: 5 additions & 0 deletions auction-server/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ pub async fn start_api(run_options: RunOptions, store: Arc<StoreNew>) -> Result<
api_types::opportunity::OpportunityDeleteV1Evm,
api_types::opportunity::ProgramSvm,
api_types::opportunity::FeeToken,
api_types::opportunity::ReferralFeeInfo,
ErrorBodyResponse,
api_types::ws::ClientRequest,
Expand Down Expand Up @@ -430,11 +431,15 @@ pub async fn start_api(run_options: RunOptions, store: Arc<StoreNew>) -> Result<
}))
.build_pair();

let original_doc = serde_json::to_value(ApiDoc::openapi())
.expect("Failed to serialize OpenAPI document to json value");

let app: Router<()> = Router::new()
.merge(Redoc::with_url(Route::Docs.as_ref(), ApiDoc::openapi()))
.merge(routes)
.route(Route::Root.as_ref(), get(root))
.route(Route::Liveness.as_ref(), get(live))
.route(Route::OpenApi.as_ref(), get(original_doc.to_string()))
.layer(CorsLayer::permissive())
.layer(middleware::from_extractor_with_state::<Auth, Arc<StoreNew>>(store.clone()))
.layer(prometheus_layer)
Expand Down
12 changes: 6 additions & 6 deletions auction-server/src/auction/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,12 @@ pub mod verification;
pub mod workers;

pub struct SwapInstructionAccountPositions {
pub router_token_account: usize,
pub user_wallet_account: usize,
pub mint_input_account: usize,
pub mint_output_account: usize,
pub token_program_input: usize,
pub token_program_output: usize,
pub router_token_account: usize,
pub user_wallet_account: usize,
pub mint_searcher_account: usize,
pub mint_user_account: usize,
pub token_program_searcher: usize,
pub token_program_user: usize,
}

pub struct SubmitBidInstructionAccountPositions {
Expand Down
Loading

0 comments on commit e421c2f

Please sign in to comment.