You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: pages/express-relay/integrate-as-searcher.mdx
+8-3Lines changed: 8 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,12 +14,17 @@ Searchers can integrate with Express Relay in three steps:
14
14
2. Construct the bid
15
15
3. Submit the bid to Express Relay.
16
16
17
-
Searchers can integrate with Express Relay on Solana Virtual Machine (SVM) chains.
17
+
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.
18
18
19
19
<Cards>
20
20
<Card
21
21
icon={<CodeIcon />}
22
-
title="Integrate with Express Relay on SVM Chains"
SVM Express Relay searchers fulfill market order opportunities as well as limit orders on the [Limo](https://solscan.io/account/LiMoM9rMhrdYrfzUCxQppvxCSG1FcrUK9G8uLq4A1GF) program.
Quote requests are broadcasted through the same websocket channel used for receiving other opportunities. Here is a sample payload:
14
+
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.
In this example the user with wallet address `FuBFy9TKJWxQdvramP8WTfvhVSm1h5dPiveTpyjAtwPd` wants to sell 1.000000 USDT (`Es9vMF…`) in exchange for the maximum USDC (`EPjFWdd…`) possible.
57
+
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.
49
58
50
-
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`:
59
+
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`:
This means the user wants to the send the least amount of USDT (`Es9vMF…`)to receive exactly 1.000000 USDC (`EPjFWdd…`).
72
+
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…`).
64
73
65
74
Other fields necessary for constructing the transaction include:
66
75
76
+
-`user_wallet_address` The address of the counterparty in the trade. Should be included as a signer in the Express Relay program instruction
67
77
-`fee_token` Whether the fees will be deducted from the searcher token or the user token
68
-
69
-
When `fee_token` is set to `user_token` the fees will be deducted from the token users provide. In this case `user_amount_including_fees > user_amount` but searchers will receive the `user_amount` in the end. You need still need to provide `user_amount_including_fees` to the contract as parameters for correct validation (SDK handles this automatically)
70
-
71
78
-`router_account` The account receiving the referral fees
72
-
-`referral_fee_bps` Amount of fees deduced from the swap in basis points
79
+
-`permission_account` The account to be specified as the permission in the Express Relay program instruction
80
+
-`referral_fee_bps` Amount of referral fees deducted from the swap in basis points
81
+
-`referral_fee_ppm` Amount of referral fees deducted from the swap in parts per million (1 basis point = 100 parts per million)
82
+
-`platform_fee_bps` Amount of platform fees deducted from the swap in basis points
83
+
-`platform_fee_ppm` Amount of platform fees deducted from the swap in parts per million
73
84
-`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.
74
85
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
86
+
-`memo` A field indicating a string that should be included via a memo program instruction in the submitted transaction (SDK handles this automatically)
87
+
-`cancellable` A boolean indicating whether the searcher's quote can be cancelled
88
+
-`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.
89
+
90
+
#### Fee Token Dynamics
91
+
92
+
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:
- The user specifies the amount of tokens they want to receive.
112
+
- Fees are deducted from the user's token.
113
+
- The searcher provides the exact `searcher_amount`.
114
+
- 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.
115
+
- 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).
- The user specifies the amount of tokens they want to receive.
120
+
- Fees are deducted from the searcher's token.
121
+
- 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`.
122
+
- The user receives the exact requested amount.
123
+
124
+
Again, the SDK handles all four of these cases; refer to the logic and documentation therein.
125
+
126
+
### Bid Submission
75
127
76
128
The transaction containing the bid should include the following instructions:
77
129
78
-
- A `setComputeUnitPrice` instruction to adjust priority fees (similar to limit order bids)
79
-
- A set of instructions ensuring that the fee token accounts for the `user wallet` , `router`, `searcher` and the `protocol` exist. You can use the `createAssociatedTokenAccountIdempotentInstruction` instruction in the spl-token library to do this.
80
-
- A single `swap` 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.
130
+
- 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.
131
+
- 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.
132
+
- 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.
81
133
82
-
The SDKs provided will help you constructing 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. All calculations for fee distribution are done on-chain and nothing should be implemented in the SDKs or in your code.
134
+
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.
83
135
84
-
The schema for swap bids include a partially signed transaction (with searcher as the fee payer, i.e. the first signature is the searchers) along with the `opportunity_id` received:
136
+
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:
85
137
86
138
```jsx
87
139
{
@@ -92,30 +144,33 @@ The schema for swap bids include a partially signed transaction (with searcher a
92
144
}
93
145
```
94
146
95
-
You must include `opportunity_id` and `type` field in bids related to market orders.
147
+
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`.
96
148
97
149
The winner bid will be communicated to the users for the final signature and on-chain submission.
98
150
99
151
### Status Updates
100
152
101
-
Bid status notifications will be sent in the same websocket channel. The bid status can have the following values:
153
+
Bid status notifications will be sent in the same WebSocket channel. The bid status can have the following values:
102
154
103
155
-`lost`: Bid was not high enough and another searcher won the auction.
104
156
-`won` : Bid was submitted on-chain and is now confirmed and successful.
105
-
-`failed`: Bid was submitted on-chain and is now confirmed but the transaction failed.
106
-
-`expired`: Bid couldn’t land on-chain due to congestion.
157
+
-`failed`: Bid was submitted on-chain but the transaction failed.
158
+
-`expired`: Bid didn't land on-chain, either because the user didn't submit their signature or due to congestion.
107
159
-`awaiting_signature`: Bid won the auction and is sent to the user. Waiting for user to sign the transaction.
108
-
-`submitted`: User has signed the transaction and is now being submitted on-chain.
109
-
-`sent_to_user_for_submission`: Waiting for the user to sign the transaction and submit it directly (only or non-cancellable requests).
160
+
-`submitted`: User has signed the transaction, and the transaction is now being submitted on-chain.
161
+
-`sent_to_user_for_submission`: Waiting for the user to sign the transaction and submit it directly (only for non-cancellable requests).
110
162
-`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.
111
163
-`submission_failed_deadline_passed`: The user submitted the signature but it already passed the specified deadline, so it will not be submitted on-chain.
112
164
165
+
Below is a thorough transition diagram that details the interactions among the different statuses.
166
+
167
+

168
+
113
169
### Cancelling Bids
114
170
115
-
Searchers are able to cancel their submitted bids for cancellable quotes as long as
116
-
it’s not signed by the user (before step 6). This feature increases flexibility for more competitive pricing without additional risk of adverse selection.
117
-
This functionality is available via the `cancel_bid` api.
118
-
Here is a sample payload that can be sent via websocket:
171
+
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.
172
+
173
+
This functionality is available via the `cancel_bid` api. Here is a sample payload that can be sent via WebSocket:
Copy file name to clipboardExpand all lines: pages/express-relay/websocket-api-reference.mdx
+15Lines changed: 15 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -221,6 +221,21 @@ Refer to the examples below:
221
221
222
222
</Tabs>
223
223
224
+
## Prioritization Fees
225
+
226
+
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:
0 commit comments