-
Notifications
You must be signed in to change notification settings - Fork 39
Express Relay: Add Mkt Order Docs #733
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -14,12 +14,17 @@ Searchers can integrate with Express Relay in three steps: | |||||
| 2. Construct the bid | ||||||
| 3. Submit the bid to Express Relay. | ||||||
|
|
||||||
| Searchers can integrate with Express Relay on Solana Virtual Machine (SVM) chains. | ||||||
| Searchers can integrate with Express Relay on Solana Virtual Machine (SVM) chains to fulfill [market order](./integrate-as-searcher/market-orders.mdx) opportunities as well as [limit orders](./integrate-as-searcher/limit-orders.mdx) on the [Limo](https://solscan.io/account/LiMoM9rMhrdYrfzUCxQppvxCSG1FcrUK9G8uLq4A1GF) program. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think we need to explain |
||||||
|
|
||||||
| <Cards> | ||||||
| <Card | ||||||
| icon={<CodeIcon />} | ||||||
| title="Integrate with Express Relay on SVM Chains" | ||||||
| href="/express-relay/integrate-as-searcher/svm" | ||||||
| title="Integrate with Market Orders" | ||||||
| href="/express-relay/integrate-as-searcher/market-orders" | ||||||
| /> | ||||||
| <Card | ||||||
| icon={<CodeIcon />} | ||||||
| title="Integrate with Limit Orders" | ||||||
| href="/express-relay/integrate-as-searcher/limit-orders" | ||||||
| /> | ||||||
| </Cards> | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| { | ||
| "svm": "Integrate on SVM chains" | ||
| "market-orders": "Integrate on Market Orders", | ||
| "limit-orders": "Integrate on Limit Orders" | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,8 +1,6 @@ | ||||||
| import { Callout, Tabs, Steps } from "nextra/components"; | ||||||
|
|
||||||
| # SVM Searcher Integration | ||||||
|
|
||||||
| SVM Express Relay searchers fulfill market order opportunities as well as limit orders on the [Limo](https://solscan.io/account/LiMoM9rMhrdYrfzUCxQppvxCSG1FcrUK9G8uLq4A1GF) program. | ||||||
| # Limit Orders Integration | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| <Steps> | ||||||
|
|
||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,207 @@ | ||||||||||||||||||||||||||||||||||
| import { Callout, Tabs, Steps } from "nextra/components"; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Market Orders Integration | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Unlike limit orders, market orders are created by users and need instant fulfilment within a single transaction. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ### Request Flow | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| The following diagram illustrates the flow of a market order: | ||||||||||||||||||||||||||||||||||
|  | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ### Opportunity Structure | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Quote requests are broadcast through the same WebSocket channel used for receiving other opportunities. To receive market order quote requests, you should subscribe to WebSocket updates; see the [WebSocket API reference](../websocket-api-reference.mdx) for more details. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Here is a sample payload: | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ```jsx | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| 'opportunity_id': '27dc5825-5b7f-4146-b00d-76be08a7139c', | ||||||||||||||||||||||||||||||||||
| 'creation_time': 1751077051829889, | ||||||||||||||||||||||||||||||||||
| 'version': 'v1', | ||||||||||||||||||||||||||||||||||
| 'program': 'swap', | ||||||||||||||||||||||||||||||||||
| 'user_wallet_address': '64Z52fmBUqAL6MFdC8garjrbvnV1w8iFGnGLWWbieYhc', | ||||||||||||||||||||||||||||||||||
| 'user_mint_user_balance': 99999999979999552, | ||||||||||||||||||||||||||||||||||
| 'permission_account': 'Hsto7eviBUvgFNS4KWRtVYRMnCcMHYEYMuq6YmBLkNJL', | ||||||||||||||||||||||||||||||||||
| 'router_account': '69ib85nGQS2Hzr4tQ8twbkGh76gKFUfWJFeJfQ37R3hW', | ||||||||||||||||||||||||||||||||||
| 'referral_fee_bps': 0, | ||||||||||||||||||||||||||||||||||
| 'referral_fee_ppm': 0, | ||||||||||||||||||||||||||||||||||
| 'platform_fee_bps': 10, | ||||||||||||||||||||||||||||||||||
| 'platform_fee_ppm': 1000, | ||||||||||||||||||||||||||||||||||
| 'fee_token': 'user_token', | ||||||||||||||||||||||||||||||||||
| 'tokens': { | ||||||||||||||||||||||||||||||||||
| 'side_specified': 'user', | ||||||||||||||||||||||||||||||||||
| 'searcher_token': 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', | ||||||||||||||||||||||||||||||||||
| 'user_token': 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB', | ||||||||||||||||||||||||||||||||||
| 'user_amount': 2218, | ||||||||||||||||||||||||||||||||||
| 'user_amount_including_fees': 2220, | ||||||||||||||||||||||||||||||||||
| 'token_program_searcher': 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', | ||||||||||||||||||||||||||||||||||
| 'token_program_user': 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' | ||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||
| 'token_account_initialization_configs': { | ||||||||||||||||||||||||||||||||||
| 'user_ata_mint_searcher': 'user_payer', | ||||||||||||||||||||||||||||||||||
| 'user_ata_mint_user': 'unneeded', | ||||||||||||||||||||||||||||||||||
| 'router_fee_receiver_ta': 'unneeded', | ||||||||||||||||||||||||||||||||||
| 'relayer_fee_receiver_ata': 'unneeded', | ||||||||||||||||||||||||||||||||||
| 'express_relay_fee_receiver_ata': 'unneeded' | ||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||
| 'memo': 'memo', | ||||||||||||||||||||||||||||||||||
| 'cancellable': True, | ||||||||||||||||||||||||||||||||||
| 'minimum_deadline': 1751077057, | ||||||||||||||||||||||||||||||||||
| 'profile_id': None, | ||||||||||||||||||||||||||||||||||
| 'chain_id': 'solana' | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| The user token refers to the token that the user puts in to the trade, while the searcher token refers to the token that the searcher contributes to the trade. In this example the user with wallet address `64Z52fmBUqAL6MFdC8garjrbvnV1w8iFGnGLWWbieYhc` wants to sell 1.000000 USDT (`Es9vMF…`) in exchange for the maximum USDC (`EPjFWdd…`) possible. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| The `side_specified` field in the opportunity shows whether the user has specified a certain amount for the token they are selling (`side_specified="user"`) or the token they are buying (`side_specified="searcher"`). Here is a sample payload when `side_specified` is `searcher`: | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ```jsx | ||||||||||||||||||||||||||||||||||
| "tokens": { | ||||||||||||||||||||||||||||||||||
| "side_specified": "searcher", | ||||||||||||||||||||||||||||||||||
| "searcher_token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", | ||||||||||||||||||||||||||||||||||
| "user_token": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", | ||||||||||||||||||||||||||||||||||
| "searcher_amount": 4023, | ||||||||||||||||||||||||||||||||||
| "token_program_searcher": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", | ||||||||||||||||||||||||||||||||||
| "token_program_user": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| This means the user wants to receive the best possible quote--i.e. send the least amount of USDT (`Es9vMF…`)--to receive exactly 1.000000 USDC (`EPjFWdd…`). | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Other fields necessary for constructing the transaction include: | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - `user_wallet_address` The address of the counterparty in the trade. Should be included as a signer in the Express Relay program instruction | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - `fee_token` Whether the fees will be deducted from the searcher token or the user token | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - `router_account` The account receiving the referral fees | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - `permission_account` The account to be specified as the permission in the Express Relay program instruction | ||||||||||||||||||||||||||||||||||
| - `referral_fee_bps` Amount of referral fees deducted from the swap in basis points | ||||||||||||||||||||||||||||||||||
| - `referral_fee_ppm` Amount of referral fees deducted from the swap in parts per million (1 basis point = 100 parts per million) | ||||||||||||||||||||||||||||||||||
| - `platform_fee_bps` Amount of platform fees deducted from the swap in basis points | ||||||||||||||||||||||||||||||||||
| - `platform_fee_ppm` Amount of platform fees deducted from the swap in parts per million | ||||||||||||||||||||||||||||||||||
| - `token_account_initialization_configs` Specifies which token accounts are required to be created in this transaction. Each of the internal fields represent one of the token accounts that potentially needs to be created. | ||||||||||||||||||||||||||||||||||
| The value for each field can be one of the following: - `unneeded`: This token account already exists and no creation instructions are needed - `user_payer`: This token account should be created and the account storage can be paid by the user - `searcher_payer`: This token account should be created and the account storage must be paid by the searcher | ||||||||||||||||||||||||||||||||||
| - `memo` A field indicating a string that should be included via a memo program instruction in the submitted transaction (SDK handles this automatically) | ||||||||||||||||||||||||||||||||||
| - `cancellable` A boolean indicating whether the searcher's quote can be cancelled | ||||||||||||||||||||||||||||||||||
| - `minimum_deadline` The minimum acceptable deadline for the quote, in seconds since the Unix epoch. The transaction must have a deadline greater than this value. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| #### Fee Token Dynamics | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| There are four possible combinations of `side_specified` and `fee_token`, and the way searchers should handle each case differs. We cover them here for clarity: | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| 1. **side_specified = "user", fee_token = "user_token"** | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - The user specifies the amount of tokens they want to sell. | ||||||||||||||||||||||||||||||||||
| - Fees are deducted from the user's token. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - `user_amount_including_fees` is greater than `user_amount`. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - The searcher receives `user_amount`. | ||||||||||||||||||||||||||||||||||
| - You need still need to provide `user_amount_including_fees` to the contract as parameters for correct validation (SDK handles this automatically). | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| 2. **side_specified = "user", fee_token = "searcher_token"** | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - The user specifies the amount of tokens they want to sell. | ||||||||||||||||||||||||||||||||||
| - Fees are deducted from the searcher's token. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - `user_amount_including_fees` equals `user_amount`. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - The searcher receives `user_amount`. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| 3. **side_specified = "searcher", fee_token = "user_token"** | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - The user specifies the amount of tokens they want to receive. | ||||||||||||||||||||||||||||||||||
| - Fees are deducted from the user's token. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - The searcher provides the exact `searcher_amount`. | ||||||||||||||||||||||||||||||||||
| - The searcher's quote should include the fact that fees will be taken from the user's token. For example, if the searcher is willing to receive 1000 tokens but there is a total fee of 10 bps, the searcher should quote 1001 tokens to include the 1 token fee. | ||||||||||||||||||||||||||||||||||
| - Here, the searcher needs to specify in the Express Relay contract instruction the total amount that the user should pay inclusive of fees (SDK handles this automatically). | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| 4. **side_specified = "searcher", fee_token = "searcher_token"** | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - The user specifies the amount of tokens they want to receive. | ||||||||||||||||||||||||||||||||||
| - Fees are deducted from the searcher's token. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - The opportunity broadcast from the server will already include fees in the `searcher_amount` shown to searchers. So the searcher just needs to provide exactly `searcher_amount`. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is repetitive. We can be say this like. |
||||||||||||||||||||||||||||||||||
| - The user receives the exact requested amount. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Again, the SDK handles all four of these cases; refer to the logic and documentation therein. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you put it in a callout as a NOTE. "The SDK abstracts all of the cases/logic ..... )" |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ### Bid Submission | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| The transaction containing the bid should include the following instructions: | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - A `setComputeUnitPrice` instruction to adjust priority fees (similar to limit order bids). Priority fees should be set in line with the [prioritization fee updates](../websocket-api-reference.mdx#prioritization-fees) broadcast from the server via WebSocket. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @anihamde |
||||||||||||||||||||||||||||||||||
| - A set of instructions ensuring that the fee token accounts for the `user_wallet_address` , `router`, `searcher` and the `protocol` exist, as needed. You can use the `createAssociatedTokenAccountIdempotentInstruction` instruction in the spl-token library to do this. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you link it if you this it's necessary? |
||||||||||||||||||||||||||||||||||
| - A single `swap_v2` instruction calling the Pyth Express Relay program with the necessary accounts and data. If the input amount is already specified by user, you need to set the output amount and vice versa. This would essentially represent your bid or quote for the request. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, what do you mean by |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| The SDKs provided will help you construct these instructions. Please note that at the moment, these are the only instructions permitted in an swap transaction; if other types of instructions are included, the bid will not be accepted. This is for security reasons, and if you find that you need to use a different instruction not listed above please inform us. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth mentioning this in a callout. |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| The schema for swap bids includes a partially signed transaction (with searcher as the fee payer, i.e. the first signature is the searchers) along with the `opportunity_id` received: | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ```jsx | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| chain_id: 'solana', | ||||||||||||||||||||||||||||||||||
| opportunity_id: '44382da2-5971-453c-b647-2ba2317c7d56', | ||||||||||||||||||||||||||||||||||
| type: 'swap', | ||||||||||||||||||||||||||||||||||
| transaction: 'Ai22...' | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| You must include `opportunity_id` and `type` field in bids related to market orders. Once the opportunity is created and broadcast, there is a window of 250 milliseconds that the server waits to receive bids. You must submit your bid within that window for it to be considered in the auction. Otherwise, if your bid arrives too late, the opportunity corresponding to the `opportunity_id` you provide will have expired, and you will receive the error message `No swap opportunity with the given id found`. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Callout ?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or too many callouts? 😅
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| The winner bid will be communicated to the users for the final signature and on-chain submission. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ### Status Updates | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Bid status notifications will be sent in the same WebSocket channel. The bid status can have the following values: | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. status notifications -> status updates.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sent in -> sent through
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - `lost`: Bid was not high enough and another searcher won the auction. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should it be high, or can we say competitive? |
||||||||||||||||||||||||||||||||||
| - `won` : Bid was submitted on-chain and is now confirmed and successful. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - `failed`: Bid was submitted on-chain but the transaction failed. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - `expired`: Bid didn't land on-chain, either because the user didn't submit their signature or due to congestion. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - `awaiting_signature`: Bid won the auction and is sent to the user. Waiting for user to sign the transaction. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - `submitted`: User has signed the transaction, and the transaction is now being submitted on-chain. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - `sent_to_user_for_submission`: Waiting for the user to sign the transaction and submit it directly (only for non-cancellable requests). | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
| - `submission_failed_cancelled`: The user submitted the signature but the searcher submitted a cancellation in the meantime, so the transaction will not be submitted on-chain. This will count towards the cancellation ratio of searchers. | ||||||||||||||||||||||||||||||||||
| - `submission_failed_deadline_passed`: The user submitted the signature but it already passed the specified deadline, so it will not be submitted on-chain. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Below is a thorough transition diagram that details the interactions among the different statuses. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|  | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ### Cancelling Bids | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Searchers are able to cancel their submitted bids for quotes marked with `'cancellable': True` as long as the transactions are not signed by the user (before step 6 in the flow diagram above). This feature increases flexibility for more competitive pricing without additional risk of adverse selection. | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| This functionality is available via the `cancel_bid` api. Here is a sample payload that can be sent via WebSocket: | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ```jsx | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| "method": "cancel_bid", | ||||||||||||||||||||||||||||||||||
| "params": { | ||||||||||||||||||||||||||||||||||
| "data": { | ||||||||||||||||||||||||||||||||||
| "bid_id": "fd586110-b22c-4e7e-a199-99c4db9c7515", | ||||||||||||||||||||||||||||||||||
| "chain_id": "solana" | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Endpoints and addresses: | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - Program address: [`PytERJFhAKuNNuaiXkApLfWzwNwSNDACpigT3LwQfou`](https://solscan.io/address/PytERJFhAKuNNuaiXkApLfWzwNwSNDACpigT3LwQfou) | ||||||||||||||||||||||||||||||||||
| - Auction Server Endpoint: [`https://per-mainnet.dourolabs.app/`](https://per-staging.dourolabs.app/) | ||||||||||||||||||||||||||||||||||
| - Chain id: `solana` | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| You can test your service using real tokens like USDC and USDT. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Links and references: | ||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please give some one liner information about every reference. |
||||||||||||||||||||||||||||||||||
| JS SDK: https://www.npmjs.com/package/@pythnetwork/express-relay-js/ | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Python SDK: https://pypi.org/project/express-relay/ | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Rust Client SDK: https://crates.io/crates/express-relay-client | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Rust API Types: https://crates.io/crates/express-relay-api-types/ | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Api References: https://per-mainnet.dourolabs.app/docs | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Testing Ui: You can use [Kamino Swap](https://swap.kamino.finance/) or Jupiter to test | ||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -221,6 +221,21 @@ Refer to the examples below: | |||||||||
|
|
||||||||||
| </Tabs> | ||||||||||
|
|
||||||||||
| ## Prioritization Fees | ||||||||||
|
|
||||||||||
| For SVM chains, you will also receive `svm_chain_update` messages which include recent prioritization fee estimates needed for your transactions to land on chain. These prioritization fees will be specified in microlamports per compute unit; refer to [Solana docs](https://solana.com/developers/guides/advanced/how-to-use-priority-fees) to learn more about prioritization fees. The format for these updates is: | ||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
|
|
||||||||||
| ```json | ||||||||||
| { | ||||||||||
| "type": "svm_chain_update", | ||||||||||
| "update": { | ||||||||||
| "chain_id": "solana", | ||||||||||
| "blockhash": "PTgMRAF9GXRvYnWnpmDcX9gc1zesYV37kDjrax8kz3o", | ||||||||||
| "latest_prioritization_fee": 1000 | ||||||||||
| } | ||||||||||
| } | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ## Connection Persistence | ||||||||||
|
|
||||||||||
| The WebSocket server responds to ping messages according to WebSocket standards. | ||||||||||
|
|
||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have any other diagram? I would suggest you to send this to Yanis and he can make it more readable.