Skip to content

Commit

Permalink
Fix/improve server swap (#315)
Browse files Browse the repository at this point in the history
* remove unnecessary TODO

* get rid of wallet_program_router_account

* parse deadline

* add fee token specification in Opportunity

* add referral fees to quot
e api & opportunity

* change location of TODO

* rename bid payment type

* nit improve todo

* feat: create quote response submit method, typescript (#312)

* create quote response submit method, typescript

* ignore generated files in linting

* bump package version

* convert to date

* add todo

* make referral_fee_bps optional

* fix the optional/default behavior in server + client

* address comments 1

* add a todo around distinguishing enum variants
  • Loading branch information
anihamde authored Jan 10, 2025
1 parent ffd3f07 commit 76d65c2
Show file tree
Hide file tree
Showing 29 changed files with 205 additions and 122 deletions.
4 changes: 2 additions & 2 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.15.0"
version = "0.15.1"
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.2.0"
version = "0.2.1"
edition = "2021"
description = "Pyth Express Relay api types"
repository = "https://github.com/pyth-network/per"
Expand Down
2 changes: 1 addition & 1 deletion auction-server/api-types/src/bid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ pub struct BidSvm {
#[schema(example = "1000", value_type = u64)]
pub bid_amount: BidAmountSvm,
/// The permission key for bid in base64 format.
/// This is the concatenation of the permission account and the router account.
/// This is the concatenation of the opportunity type, the router, and the permission account.
#[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)]
pub permission_key: PermissionKeySvm,
}
Expand Down
2 changes: 1 addition & 1 deletion auction-server/api-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub type MicroLamports = u64;
pub type ChainId = String;
pub type PermissionKeyEvm = Bytes;
#[derive(Clone, Debug)]
pub struct PermissionKeySvm(pub [u8; 64]);
pub struct PermissionKeySvm(pub [u8; 65]);
impl Serialize for PermissionKeySvm {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
Expand Down
12 changes: 11 additions & 1 deletion auction-server/api-types/src/opportunity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,13 @@ pub enum OpportunityCreateProgramParamsV1Svm {
#[serde(rename = "swap")]
#[schema(title = "swap")]
Swap {
// TODO*: we should make this more generic, a la `Swap`
/// The user wallet address which requested the quote from the wallet.
#[schema(example = "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", value_type = String)]
#[serde_as(as = "DisplayFromStr")]
user_wallet_address: Pubkey,
/// The referral fee in basis points.
#[schema(example = 10, value_type = u16)]
referral_fee_bps: u16,
},
}

Expand Down Expand Up @@ -500,11 +502,19 @@ pub struct QuoteCreateV1SvmParams {
#[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,
/// The chain id for creating the quote.
#[schema(example = "solana", value_type = String)]
pub chain_id: ChainId,
}

fn default_referral_fee_bps() -> u16 {
0
}

#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug)]
#[serde(tag = "side")]
pub enum SpecifiedTokenAmount {
Expand Down
1 change: 0 additions & 1 deletion auction-server/config.sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,3 @@ chains:
rpc_read_url: http://localhost:8899
rpc_tx_submission_url: http://localhost:8899
ws_addr: ws://localhost:8900
wallet_program_router_account: 3hv8L8UeBbyM3M25dF3h2C5p8yA4FptD7FFZu4Z1jCMn
42 changes: 33 additions & 9 deletions auction-server/src/auction/entities/bid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use {
},
hash::Hash,
},
strum::FromRepr,
time::OffsetDateTime,
uuid::Uuid,
};
Expand Down Expand Up @@ -180,9 +181,10 @@ pub trait BidChainData: Send + Sync + Clone + Debug + PartialEq {

#[derive(Clone, Debug, PartialEq)]
pub struct BidChainDataSvm {
pub transaction: VersionedTransaction,
pub router: Pubkey,
pub permission_account: Pubkey,
pub transaction: VersionedTransaction,
pub bid_payment_instruction_type: BidPaymentInstructionType,
pub router: Pubkey,
pub permission_account: Pubkey,
}

#[derive(Clone, Debug, PartialEq)]
Expand All @@ -197,9 +199,10 @@ impl BidChainData for BidChainDataSvm {
type PermissionKey = PermissionKeySvm;

fn get_permission_key(&self) -> Self::PermissionKey {
let mut permission_key = [0; 64];
permission_key[..32].copy_from_slice(&self.router.to_bytes());
permission_key[32..].copy_from_slice(&self.permission_account.to_bytes());
let mut permission_key = [0; 65];
permission_key[0] = self.bid_payment_instruction_type.clone().into();
permission_key[1..33].copy_from_slice(&self.router.to_bytes());
permission_key[33..].copy_from_slice(&self.permission_account.to_bytes());
PermissionKeySvm(permission_key)
}
}
Expand All @@ -212,16 +215,37 @@ impl BidChainData for BidChainDataEvm {
}
}

#[derive(Clone, Debug, PartialEq, FromRepr)]
pub enum BidPaymentInstructionType {
SubmitBid,
Swap,
}

impl From<BidPaymentInstructionType> for u8 {
fn from(instruction: BidPaymentInstructionType) -> Self {
match instruction {
BidPaymentInstructionType::SubmitBid => 0,
BidPaymentInstructionType::Swap => 1,
}
}
}

impl BidChainDataSvm {
pub fn get_bid_payment_instruction_type(
permission_key: &PermissionKeySvm,
) -> Option<BidPaymentInstructionType> {
BidPaymentInstructionType::from_repr(permission_key.0[0].into())
}

pub fn get_router(permission_key: &PermissionKeySvm) -> Pubkey {
let slice: [u8; 32] = permission_key.0[..32]
let slice: [u8; 32] = permission_key.0[1..33]
.try_into()
.expect("Failed to extract first 32 bytes from permission key");
.expect("Failed to extract bytes 1 through 33 from permission key");
Pubkey::new_from_array(slice)
}

pub fn get_permission_account(permission_key: &PermissionKeySvm) -> Pubkey {
let slice: [u8; 32] = permission_key.0[32..]
let slice: [u8; 32] = permission_key.0[33..]
.try_into()
.expect("Failed to extract last 32 bytes from permission key");
Pubkey::new_from_array(slice)
Expand Down
19 changes: 15 additions & 4 deletions auction-server/src/auction/repository/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,15 +404,26 @@ impl ModelTrait<Svm> for Svm {
}

fn get_chain_data_entity(bid: &Bid<Svm>) -> anyhow::Result<entities::BidChainDataSvm> {
let slice: [u8; 64] =
let slice: [u8; 65] =
bid.permission_key.clone().try_into().map_err(|e| {
anyhow::anyhow!("Failed to convert permission key to slice {:?}", e)
})?;
let permission_key: PermissionKeySvm = PermissionKeySvm(slice);
Ok(entities::BidChainDataSvm {
transaction: bid.metadata.transaction.clone(),
router: entities::BidChainDataSvm::get_router(&permission_key),
permission_account: entities::BidChainDataSvm::get_permission_account(&permission_key),
transaction: bid.metadata.transaction.clone(),
bid_payment_instruction_type:
match entities::BidChainDataSvm::get_bid_payment_instruction_type(&permission_key) {
Some(bid_payment_instruction_type) => bid_payment_instruction_type,
None => {
return Err(anyhow::anyhow!(
"Failed to get bid payment instruction type from permission key, due to invalid data"
))
}
},
router: entities::BidChainDataSvm::get_router(&permission_key),
permission_account: entities::BidChainDataSvm::get_permission_account(
&permission_key,
),
})
}

Expand Down
49 changes: 23 additions & 26 deletions auction-server/src/auction/service/auction_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ use {
Service,
},
crate::{
auction::{
entities,
entities::BidStatusAuction,
auction::entities::{
self,
BidPaymentInstructionType,
BidStatusAuction,
},
kernel::{
contracts::MulticallIssuedFilter,
Expand Down Expand Up @@ -542,30 +543,26 @@ impl AuctionManager<Svm> for Service<Svm> {
&self,
permission_key: &entities::PermissionKey<Svm>,
) -> entities::SubmitType {
if permission_key.0.starts_with(
&self
.config
.chain_config
.wallet_program_router_account
.to_bytes(),
) {
if self
.opportunity_service
.get_live_opportunities(GetLiveOpportunitiesInput {
key: opportunity::entities::OpportunityKey(
self.config.chain_id.clone(),
Bytes::from(permission_key.0),
),
})
.await
.is_empty()
{
entities::SubmitType::Invalid
} else {
entities::SubmitType::ByOther
match entities::BidChainDataSvm::get_bid_payment_instruction_type(permission_key) {
Some(BidPaymentInstructionType::Swap) => {
if self
.opportunity_service
.get_live_opportunities(GetLiveOpportunitiesInput {
key: opportunity::entities::OpportunityKey(
self.config.chain_id.clone(),
Bytes::from(permission_key.0),
),
})
.await
.is_empty()
{
entities::SubmitType::Invalid
} else {
entities::SubmitType::ByOther
}
}
} else {
entities::SubmitType::ByServer
Some(BidPaymentInstructionType::SubmitBid) => entities::SubmitType::ByServer,
None => entities::SubmitType::Invalid, // TODO: may want to distinguish this arm from the prior Invalid SubmitType. Maybe two different enum variants?
}
}

Expand Down
1 change: 0 additions & 1 deletion auction-server/src/auction/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ pub struct ExpressRelaySvm {

pub struct ConfigSvm {
pub client: RpcClient,
pub wallet_program_router_account: Pubkey,
pub express_relay: ExpressRelaySvm,
pub simulator: Simulator,
pub ws_address: String,
Expand Down
Loading

0 comments on commit 76d65c2

Please sign in to comment.