Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Swap js integration #320

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -95,28 +95,28 @@ local_resource(
"svm-create-mints",
"""solana-keygen new -o keypairs/mint_buy.json -f --no-bip39-passphrase \
&& solana-keygen new -o keypairs/mint_sell.json -f --no-bip39-passphrase \
&& spl-token create-token -u localhost --fee-payer keypairs/admin.json --mint-authority keypairs/admin.json keypairs/mint_sell.json \
&& spl-token create-token -u localhost --fee-payer keypairs/admin.json --mint-authority keypairs/admin.json keypairs/mint_buy.json \
&& spl-token create-token -u localhost --fee-payer keypairs/admin.json --decimals 6 --mint-authority keypairs/admin.json keypairs/mint_sell.json \
&& spl-token create-token -u localhost --fee-payer keypairs/admin.json --decimals 6 --mint-authority keypairs/admin.json keypairs/mint_buy.json \
&& spl-token create-account -u localhost keypairs/mint_buy.json --fee-payer keypairs/admin.json --owner keypairs/searcher_js.json \
&& spl-token create-account -u localhost keypairs/mint_sell.json --fee-payer keypairs/admin.json --owner keypairs/searcher_js.json \
&& spl-token create-account -u localhost keypairs/mint_buy.json --fee-payer keypairs/admin.json --owner keypairs/searcher_py.json \
&& spl-token create-account -u localhost keypairs/mint_sell.json --fee-payer keypairs/admin.json --owner keypairs/searcher_py.json \
&& spl-token create-account -u localhost keypairs/mint_buy.json --fee-payer keypairs/admin.json --owner keypairs/admin.json \
&& spl-token create-account -u localhost keypairs/mint_sell.json --fee-payer keypairs/admin.json --owner keypairs/admin.json \
&& spl-token mint -u localhost keypairs/mint_buy.json 1000000000 --recipient-owner keypairs/searcher_js.json --mint-authority keypairs/admin.json \
&& spl-token mint -u localhost keypairs/mint_sell.json 1000000000 --recipient-owner keypairs/searcher_js.json --mint-authority keypairs/admin.json \
&& spl-token mint -u localhost keypairs/mint_buy.json 1000000000 --recipient-owner keypairs/searcher_py.json --mint-authority keypairs/admin.json \
&& spl-token mint -u localhost keypairs/mint_sell.json 1000000000 --recipient-owner keypairs/searcher_py.json --mint-authority keypairs/admin.json \
&& spl-token mint -u localhost keypairs/mint_buy.json 1000000000 --recipient-owner keypairs/admin.json --mint-authority keypairs/admin.json \
&& spl-token mint -u localhost keypairs/mint_sell.json 1000000000 --recipient-owner keypairs/admin.json --mint-authority keypairs/admin.json""",
&& spl-token mint -u localhost keypairs/mint_buy.json 100000000000 --recipient-owner keypairs/searcher_js.json --mint-authority keypairs/admin.json \
&& spl-token mint -u localhost keypairs/mint_sell.json 100000000000 --recipient-owner keypairs/searcher_js.json --mint-authority keypairs/admin.json \
&& spl-token mint -u localhost keypairs/mint_buy.json 100000000000 --recipient-owner keypairs/searcher_py.json --mint-authority keypairs/admin.json \
&& spl-token mint -u localhost keypairs/mint_sell.json 100000000000 --recipient-owner keypairs/searcher_py.json --mint-authority keypairs/admin.json \
&& spl-token mint -u localhost keypairs/mint_buy.json 100000000000 --recipient-owner keypairs/admin.json --mint-authority keypairs/admin.json \
&& spl-token mint -u localhost keypairs/mint_sell.json 100000000000 --recipient-owner keypairs/admin.json --mint-authority keypairs/admin.json""",
resource_deps=["svm-setup-accounts"]
)

# setup limo global config and vaults for buy and sell tokens
RUN_CLI= "ADMIN=../../keypairs/admin.json RPC_ENV=localnet npm exec limo-cli --"
SET_GLOBAL_CONFIG = "LIMO_GLOBAL_CONFIG=$(solana-keygen pubkey ../../keypairs/limo_global_config.json)"
MINT_SELL= "$(solana-keygen pubkey ../../keypairs/mint_sell.json)"
MINT_BUY= "$(solana-keygen pubkey ../../keypairs/mint_buy.json)"
MINT_SELL= "$(solana-keygen pubkey %s/keypairs/mint_sell.json)" % config.main_dir
MINT_BUY= "$(solana-keygen pubkey %s/keypairs/mint_buy.json)" % config.main_dir
local_resource(
"svm-limo-setup",
"""solana-keygen new -o ../../keypairs/limo_global_config.json -f --no-bip39-passphrase \
Expand Down Expand Up @@ -211,14 +211,21 @@ local_resource(

local_resource(
"svm-searcher-py",
serve_cmd="poetry run python3 -m express_relay.searcher.examples.testing_searcher_svm --endpoint-express-relay http://127.0.0.1:9000 --chain-id development-solana --private-key-json-file ../../keypairs/searcher_js.json --endpoint-svm http://127.0.0.1:8899 --bid 10000000 --fill-rate 4 --bid-margin 100 --with-latency",
serve_cmd="poetry run python3 -m express_relay.searcher.examples.testing_searcher_svm --endpoint-express-relay http://127.0.0.1:9000 --chain-id development-solana --private-key-json-file ../../keypairs/searcher_py.json --endpoint-svm http://127.0.0.1:8899 --bid 10000000 --fill-rate 4 --bid-margin 100 --with-latency",
serve_dir="sdk/python",
resource_deps=["svm-initialize-programs", "auction-server"],
)

local_resource(
"svm-searcher-js",
serve_cmd="pnpm run testing-searcher-limo --endpoint-express-relay http://127.0.0.1:9000 --chain-id development-solana --private-key-json-file ../../keypairs/searcher_py.json --endpoint-svm http://127.0.0.1:8899 --bid 10000000 --fill-rate 4 --bid-margin 100 --with-latency",
serve_cmd="pnpm run testing-searcher-limo --endpoint-express-relay http://127.0.0.1:9000 --chain-id development-solana --private-key-json-file ../../keypairs/searcher_js.json --endpoint-svm http://127.0.0.1:8899 --bid 10000000 --fill-rate 4 --bid-margin 100",
serve_dir="sdk/js",
resource_deps=["svm-initialize-programs", "auction-server"],
)

local_resource(
"svm-test-swap-endpoint",
"poetry -C tilt-scripts run python3 -m tilt-scripts.svm.test_swap --file-private-key-taker keypairs/searcher_py.json --auction-server-url http://localhost:9000 --input-mint {MINT_SELL} --output-mint {MINT_BUY} --rpc-url {RPC_URL}"
.format(RPC_URL=rpc_url_solana, MINT_SELL=MINT_SELL, MINT_BUY=MINT_BUY),
resource_deps=["svm-searcher-js"],
)
40 changes: 38 additions & 2 deletions auction-server/api-types/src/bid.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use {
crate::{
opportunity::OpportunityId,
profile::ProfileId,
AccessLevel,
ChainId,
Expand Down Expand Up @@ -251,7 +252,7 @@ pub struct BidCreateEvm {
}

#[derive(Serialize, Deserialize, ToSchema, Clone, Debug)]
pub struct BidCreateSvm {
pub struct BidCreateOnChainSvm {
/// The chain id to bid on.
#[schema(example = "solana", value_type = String)]
pub chain_id: ChainId,
Expand All @@ -265,6 +266,38 @@ pub struct BidCreateSvm {
pub slot: Option<Slot>,
}

#[derive(Serialize, Deserialize, ToSchema, Clone, Debug)]
#[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)]
pub chain_id: ChainId,
/// The transaction for bid.
#[schema(example = "SGVsbG8sIFdvcmxkIQ==", value_type = String)]
#[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 = 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 {
Swap(BidCreateSwapSvm),
OnChain(BidCreateOnChainSvm),
}


#[derive(Serialize, Deserialize, ToSchema, Debug, Clone)]
#[serde(untagged)] // Remove tags to avoid key-value wrapping
pub enum BidCreate {
Expand Down Expand Up @@ -304,7 +337,10 @@ impl BidCreate {
pub fn get_chain_id(&self) -> ChainId {
match self {
BidCreate::Evm(bid_create_evm) => bid_create_evm.chain_id.clone(),
BidCreate::Svm(bid_create_svm) => bid_create_svm.chain_id.clone(),
BidCreate::Svm(BidCreateSvm::Swap(bid_create_svm)) => bid_create_svm.chain_id.clone(),
BidCreate::Svm(BidCreateSvm::OnChain(bid_create_svm)) => {
bid_create_svm.chain_id.clone()
}
}
}
}
Expand Down
31 changes: 20 additions & 11 deletions auction-server/api-types/src/opportunity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,10 @@ pub struct OpportunityBidResult {
}

#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, Display)]
#[serde(rename_all = "lowercase")]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum ProgramSvm {
#[serde(rename = "swap_kamino")]
#[strum(serialize = "swap_kamino")]
SwapKamino,
#[serde(rename = "limo")]
#[strum(serialize = "limo")]
m30m marked this conversation as resolved.
Show resolved Hide resolved
Limo,
}

Expand Down Expand Up @@ -195,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 @@ -214,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 @@ -300,12 +295,11 @@ pub struct OpportunityEvm {
/// Program specific parameters for the opportunity.
#[serde_as]
#[derive(Serialize, Deserialize, ToSchema, Clone, PartialEq, Debug, ToResponse)]
#[serde(tag = "program")]
#[serde(tag = "program", rename_all = "snake_case")]
pub enum OpportunityParamsV1ProgramSvm {
/// 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 @@ -318,7 +312,6 @@ pub enum OpportunityParamsV1ProgramSvm {
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 All @@ -336,13 +329,29 @@ 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 {
InputTokenSpecified {
input_token: TokenAmountSvm,
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
19 changes: 15 additions & 4 deletions auction-server/src/auction/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,15 +422,26 @@ impl ApiTrait<Svm> for Svm {
profile: Option<models::Profile>,
) -> Result<entities::BidCreate<Svm>, RestError> {
match bid {
BidCreate::Svm(bid_create_svm) => {
BidCreate::Svm(BidCreateSvm::OnChain(bid_create_svm)) => {
Ok(entities::BidCreate::<Svm> {
chain_id: bid_create_svm.chain_id.clone(),
profile,
initiation_time: OffsetDateTime::now_utc(),
chain_data: entities::BidChainDataCreateSvm {
chain_data: entities::BidChainDataCreateSvm::OnChain(entities::BidChainDataOnChainCreateSvm {
transaction: bid_create_svm.transaction.clone(),
slot: bid_create_svm.slot,
},
slot: bid_create_svm.slot,
}),
})
},
BidCreate::Svm(BidCreateSvm::Swap(bid_create_svm)) => {
Ok(entities::BidCreate::<Svm> {
chain_id: bid_create_svm.chain_id.clone(),
profile,
initiation_time: OffsetDateTime::now_utc(),
chain_data: entities::BidChainDataCreateSvm::Swap(entities::BidChainDataSwapCreateSvm {
transaction: bid_create_svm.transaction.clone(),
opportunity_id: bid_create_svm.opportunity_id,
}),
})
}
_ => Err(RestError::BadParameters(
Expand Down
2 changes: 1 addition & 1 deletion auction-server/src/auction/entities/auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub struct Auction<T: ChainTrait> {
pub bids: Vec<Bid<T>>,
}

#[derive(PartialEq)]
#[derive(PartialEq, Debug)]
pub enum SubmitType {
ByServer,
ByOther,
Expand Down
26 changes: 24 additions & 2 deletions auction-server/src/auction/entities/bid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,33 @@ pub struct BidCreate<T: ChainTrait> {
}

#[derive(Clone, Debug)]
pub struct BidChainDataCreateSvm {
pub struct BidChainDataOnChainCreateSvm {
pub transaction: VersionedTransaction,
pub slot: Option<Slot>,
}

#[derive(Clone, Debug)]
pub struct BidChainDataSwapCreateSvm {
pub transaction: VersionedTransaction,
pub opportunity_id: Uuid,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switch to opportunity id

}


#[derive(Clone, Debug)]
pub enum BidChainDataCreateSvm {
OnChain(BidChainDataOnChainCreateSvm),
Swap(BidChainDataSwapCreateSvm),
}

impl BidChainDataCreateSvm {
pub fn get_transaction(&self) -> &VersionedTransaction {
match self {
BidChainDataCreateSvm::OnChain(data) => &data.transaction,
BidChainDataCreateSvm::Swap(data) => &data.transaction,
}
}
}

#[derive(Clone, Debug)]
pub struct BidChainDataCreateEvm {
pub target_contract: Address,
Expand All @@ -280,7 +302,7 @@ pub type BidAmountEvm = U256;

impl PartialEq<Bid<Svm>> for BidCreate<Svm> {
fn eq(&self, other: &Bid<Svm>) -> bool {
self.chain_data.transaction == other.chain_data.transaction
*self.chain_data.get_transaction() == other.chain_data.transaction
&& self.chain_id == other.chain_id
}
}
Expand Down
Loading
Loading