Переглянути джерело

reference section and how it works

nidhi-singh02 2 місяців тому
батько
коміт
466e058886

+ 45 - 0
apps/developer-hub/content/docs/express-relay/contract-addresses.mdx

@@ -0,0 +1,45 @@
+---
+title: "SVM Contract Addresses"
+description: >-
+  Contract addresses and network details for Express Relay deployment on Solana Virtual Machine environments.
+---
+
+# SVM Contract Addresses
+
+Express Relay is currently deployed on the following SVM environments:
+
+## Production (Solana Mainnet-Beta)
+
+**Auction Server endpoint:** https://per-mainnet.dourolabs.app/
+
+| Name                     | Address/Value                                                                                                         |
+| ------------------------ | --------------------------------------------------------------------------------------------------------------------- |
+| Express Relay Program    | [PytERJFhAKuNNuaiXkApLfWzwNwSNDACpigT3LwQfou](https://solscan.io/account/PytERJFhAKuNNuaiXkApLfWzwNwSNDACpigT3LwQfou) |
+| Limo Limit Order Program | [LiMoM9rMhrdYrfzUCxQppvxCSG1FcrUK9G8uLq4A1GF](https://solscan.io/account/LiMoM9rMhrdYrfzUCxQppvxCSG1FcrUK9G8uLq4A1GF) |
+| Chain Id                 | solana                                                                                                                |
+| Public RPC               | https://api.mainnet-beta.solana.com                                                                                   |
+| Limo Global Order Config | [prod7Mog8r56sn5dPwze8nVdf94veEawdxNNqd5v7A1](https://solscan.io/account/prod7Mog8r56sn5dPwze8nVdf94veEawdxNNqd5v7A1) |
+| Frontend                 | https://swap.kamino.finance                                                                                           |
+
+## Testing (Solana Mainnet-Beta)
+
+> **Warning**: To simulate real performance conditions and activity, the staging/testing environment for Solana is on the mainnet-beta network. This environment is not for production use and should only be used for testing.
+
+**Auction Server endpoint:** https://per-staging.dourolabs.app/
+
+| Name                                 | Address/Value                                                                                                         |
+| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
+| Express Relay Program (Swaps)        | [stag1NN9voD7436oFvKmy1kvRZYLLW8drKocSCt2W79](https://solscan.io/account/stag1NN9voD7436oFvKmy1kvRZYLLW8drKocSCt2W79) |
+| Express Relay Program (Limit Orders) | [PytERJFhAKuNNuaiXkApLfWzwNwSNDACpigT3LwQfou](https://solscan.io/account/PytERJFhAKuNNuaiXkApLfWzwNwSNDACpigT3LwQfou) |
+| Limo Limit Order Program             | [LiMoM9rMhrdYrfzUCxQppvxCSG1FcrUK9G8uLq4A1GF](https://solscan.io/account/LiMoM9rMhrdYrfzUCxQppvxCSG1FcrUK9G8uLq4A1GF) |
+| Chain Id                             | development-solana                                                                                                    |
+| Public RPC                           | https://api.mainnet-beta.solana.com                                                                                   |
+| Limo Global Order Config             | [TeStcUQMmECYEtdeXo9cXpktQWaGe4bhJ7zxAUMzB2X](https://solscan.io/account/TeStcUQMmECYEtdeXo9cXpktQWaGe4bhJ7zxAUMzB2X) |
+| Testing Frontend                     | https://limo.kamino-webapp.pages.dev/swap                                                                             |
+
+### Common Assets on development-solana
+
+| Asset | Address                                                                                                                 |
+| ----- | ----------------------------------------------------------------------------------------------------------------------- |
+| WSOL  | [So11111111111111111111111111111111111111112](https://solscan.io/account/So11111111111111111111111111111111111111112)   |
+| USDC  | [EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v](https://solscan.io/account/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v) |

+ 204 - 0
apps/developer-hub/content/docs/express-relay/errors.mdx

@@ -0,0 +1,204 @@
+---
+title: "Error Codes"
+description: >-
+  Reference guide for Express Relay error codes and troubleshooting common issues.
+---
+
+# Error Codes
+
+This page provides a reference for common error codes you may encounter when integrating with Express Relay, along with explanations and suggested solutions.
+
+## HTTP API Errors
+
+### 400 Bad Request
+
+**Invalid chain_id**
+
+- **Error:** Chain ID is not supported
+- **Solution:** Ensure you're using a supported chain ID (e.g., "solana", "development-solana")
+
+**Invalid transaction format**
+
+- **Error:** Transaction data is not properly encoded
+- **Solution:** Ensure transaction is base64 encoded and properly formatted
+
+**Missing required fields**
+
+- **Error:** Required fields are missing from the request
+- **Solution:** Check that all required parameters are included in your request
+
+### 401 Unauthorized
+
+**Invalid authentication**
+
+- **Error:** Authentication credentials are invalid or missing
+- **Solution:** Verify your API credentials and authentication headers
+
+### 404 Not Found
+
+**Opportunity not found**
+
+- **Error:** The requested opportunity does not exist
+- **Solution:** Check that the opportunity ID is correct and the opportunity hasn't expired
+
+### 429 Too Many Requests
+
+**Rate limit exceeded**
+
+- **Error:** Too many requests sent in a short time period
+- **Solution:** Implement exponential backoff and respect rate limits
+
+### 500 Internal Server Error
+
+**Server error**
+
+- **Error:** Internal server error occurred
+- **Solution:** Retry the request after a brief delay. If the issue persists, contact support
+
+## WebSocket Errors
+
+### Connection Errors
+
+**Connection failed**
+
+- **Error:** Unable to establish WebSocket connection
+- **Solution:** Check network connectivity and WebSocket endpoint URL
+
+**Authentication failed**
+
+- **Error:** WebSocket authentication failed
+- **Solution:** Verify authentication credentials for WebSocket connection
+
+### Subscription Errors
+
+**Invalid subscription**
+
+- **Error:** Subscription parameters are invalid
+- **Solution:** Check that chain_ids array contains valid chain identifiers
+
+**Subscription limit exceeded**
+
+- **Error:** Too many active subscriptions
+- **Solution:** Unsubscribe from unused chains before subscribing to new ones
+
+## Transaction Errors
+
+### Bid Submission Errors
+
+**Insufficient balance**
+
+- **Error:** Insufficient funds to cover bid amount
+- **Solution:** Ensure wallet has sufficient balance for the bid amount plus transaction fees
+
+**Invalid bid amount**
+
+- **Error:** Bid amount is below minimum or above maximum
+- **Solution:** Check bid amount constraints for the specific opportunity
+
+**Permission denied**
+
+- **Error:** Not authorized to submit bid for this opportunity
+- **Solution:** Verify permission key and ensure proper authorization
+
+### On-Chain Execution Errors
+
+**Transaction failed**
+
+- **Error:** Transaction execution failed on-chain
+- **Solution:** Check transaction logs for specific failure reasons
+
+**Transaction expired**
+
+- **Error:** Transaction expired before execution
+- **Solution:** Submit bids with sufficient time before deadline
+
+**Insufficient gas/compute**
+
+- **Error:** Transaction ran out of gas or compute units
+- **Solution:** Increase gas limit or compute unit allocation
+
+## SDK-Specific Errors
+
+### JavaScript SDK Errors
+
+**Network timeout**
+
+- **Error:** Request timed out
+- **Solution:** Increase timeout configuration or check network connectivity
+
+**Invalid configuration**
+
+- **Error:** SDK configuration is invalid
+- **Solution:** Verify baseUrl and other configuration parameters
+
+### Python SDK Errors
+
+**Connection error**
+
+- **Error:** Failed to connect to Express Relay server
+- **Solution:** Check network connectivity and server endpoint
+
+**Serialization error**
+
+- **Error:** Failed to serialize/deserialize data
+- **Solution:** Ensure data types match expected format
+
+## Troubleshooting Tips
+
+### General Guidelines
+
+1. **Check network connectivity** - Ensure your application can reach Express Relay endpoints
+2. **Verify parameters** - Double-check all request parameters for correct format and values
+3. **Monitor rate limits** - Implement proper rate limiting to avoid 429 errors
+4. **Handle timeouts** - Implement retry logic with exponential backoff
+5. **Check logs** - Review both client and server logs for detailed error information
+
+### Getting Help
+
+If you encounter persistent issues:
+
+1. Check the [API documentation](https://per-mainnet.dourolabs.app/docs) for detailed endpoint specifications
+2. Review example implementations in the SDK repositories
+3. Join the community Discord for support and discussion
+4. Contact technical support with detailed error information and reproduction steps
+
+### Common Patterns
+
+**Retry Logic Example**
+
+```typescript
+const maxRetries = 3;
+let retryCount = 0;
+
+while (retryCount < maxRetries) {
+  try {
+    const result = await client.submitBid(bid);
+    return result;
+  } catch (error) {
+    retryCount++;
+    if (retryCount === maxRetries) {
+      throw error;
+    }
+    await new Promise((resolve) => setTimeout(resolve, 1000 * retryCount));
+  }
+}
+```
+
+**Error Handling Example**
+
+```typescript
+try {
+  const opportunities = await client.getOpportunities();
+} catch (error) {
+  if (error.status === 429) {
+    // Rate limited - wait and retry
+    await new Promise((resolve) => setTimeout(resolve, 5000));
+  } else if (error.status === 500) {
+    // Server error - log and alert
+    console.error("Server error:", error);
+  } else {
+    // Other errors - handle appropriately
+    console.error("Request failed:", error);
+  }
+}
+```

+ 29 - 0
apps/developer-hub/content/docs/express-relay/how-express-relay-works/auction.mdx

@@ -0,0 +1,29 @@
+---
+title: "Auction Mechanism"
+description: >-
+  Learn how Express Relay's off-chain auction determines winning bids and maximizes revenue sharing with integrated protocols.
+---
+
+# Auction
+
+The auction in Express Relay is held off-chain at the auction server.
+Bids arrive at the auction server and compete against other bids, vying for the same [permission key](./permissioning).
+A relayer selected by governance serves as the auctioneer and determines the auction in line with the criterion of maximizing the revenue shared back to the protocol that generated this opportunity. That means the auctioneer is expected to forward on-chain the subset of bids that maximizes the revenue back to the protocol.
+
+Thus, the Express Relay auction is analogous to a sealed-bid auction, i.e., participants in the auction will not have the contents of their bid disclosed publicly unless they win the auction and are forwarded on-chain.
+
+The forwarded subset of transactions is submitted on-chain and first processed by the [`ExpressRelay`](https://github.com/pyth-network/per/blob/fccac65b00cff1cfe5c278b333a582fe66bda0f8/contracts/evm/src/express-relay/ExpressRelay.sol) contract before individual searchers' submissions are routed to their corresponding **targetContracts**.
+
+Generally, the auction server expects bids to execute successfully on-chain. Fallback bids are also forwarded in case of execution failures for the predicted winners.
+
+The **ExpressRelay** contract extracts the payment of the specified bid amount only if the searcher's bid is successfully executed on-chain.
+Hence, the Express Relay auction can be seen as a generalization of a [first-price sealed-bid auction](https://en.wikipedia.org/wiki/First-price_sealed-bid_auction), in that multiple bids can win and pay their first price.
+
+## Revenue Sharing
+
+The revenue from the auction is shared amongst relevant stakeholders in the Express Relay system. These stakeholders include:
+
+- **The protocol** that generates the relevant opportunity
+- **The relayer**, which handles running the off-chain components of the system
+
+> **ℹ️ Revenue Distribution**: The Express Relay contract enforces the exact revenue splits and is subject to change based on governance decisions.

+ 84 - 0
apps/developer-hub/content/docs/express-relay/how-express-relay-works/index.mdx

@@ -0,0 +1,84 @@
+---
+title: "How Express Relay Works"
+description: >-
+  Understand how Express Relay eliminates MEV through off-chain auctions and priority mechanisms for protocol operations.
+---
+
+import { IntegrationCard } from "../../../../src/components/IntegrationCard";
+import { Gavel, Lightning, Shield } from "@phosphor-icons/react/dist/ssr";
+
+# How Express Relay Works
+
+Express Relay allows protocols to eliminate [Maximal Extractable Value](https://www.ledger.com/academy/glossary/maximal-extractable-value-mev) (MEV).
+Many protocols generate MEV on a regular basis.
+For example, borrow-lending protocols provide bonuses to searchers for liquidating undercollateralized loans.
+Searchers compete for these bonuses by tipping the chain's miners or validators.
+The validators capture most of the value of the liquidation bonus via these tips, so the liquidation bonus is in essence a transfer of wealth from the protocol's users to the validators in the form of tips.
+
+Express Relay solves the problem of MEV by providing protocol developers with an [auction](./how-express-relay-works/auction) primitive that they can use to prioritize access to valuable protocol operations.
+Developers specify a set of operations in their protocol that must be accessed through Express Relay.
+Searchers then participate in an off-chain auction to access these operations.
+Their bids in the auction are used to determine the order in which their transactions will be executed.
+The winners' transactions are forwarded to the Express Relay smart contract. As part of the transaction, searchers must pay their specified bid.
+The auction profits are then split between the integrated protocol and other participants in Express Relay.
+
+### Before Express Relay
+
+Searchers tip miners/validators to guarantee transaction execution, with validators capturing most of the MEV value.
+
+### After Express Relay
+
+Searchers bid in off-chain auctions, with auction profits shared between integrated protocols and Express Relay participants.
+
+The comparison above shows how Express Relay changes the MEV landscape for a liquidation.
+In the status quo (above), Searchers tip miners to guarantee that their liquidation transaction lands on-chain and that their transaction directly interacts with the protocol, exposing the liquidation opportunity.
+With Express Relay (below), Searchers submit bids for their transaction to the Express Relay auction.
+After the auction, the winning bids are relayed to the blockchain, where the Express Relay smart contract processes the transactions before being forwarded on to the integrated protocol.
+The Express Relay contract collects payment from the Searchers and forwards a share of the revenue back to the integrated protocol.
+
+## Which protocols can use Express Relay?
+
+Any protocol with valuable operations can use Express Relay.
+These operations generate MEV, as the validators control which searchers have the right to access them.
+Express Relay enables protocols to auction access instead of the validators.
+Lending, perps, and derivatives protocols with liquidation mechanisms are clear candidates that can benefit from integration with Express Relay.
+
+Aside from eliminating MEV, protocols that need a stable set of searchers would benefit from using Express Relay.
+Express Relay provides access to a robust network of searchers who are already active in the Express Relay ecosystem.
+
+## Participants in Express Relay
+
+There are four types of participants in the Express Relay protocol:
+
+- **The Relayer** runs the off-chain auction and forwards winning transactions onto the blockchain.
+- **Protocol developers** integrate their protocol with Express Relay in order to eliminate MEV and gain access to searchers.
+- **Searchers** participate in auctions to access on-chain opportunities such as liquidations.
+- **The Pyth DAO** owns and governs the Express Relay system.
+
+## Learn More
+
+<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mt-8">
+  <IntegrationCard
+    href="./how-express-relay-works/auction"
+    colorScheme="blue"
+    title="Auction"
+    description="Learn about the auction mechanism"
+    icon={<Gavel size={16} />}
+  />
+
+<IntegrationCard
+  href="./how-express-relay-works/opportunities"
+  colorScheme="green"
+  title="Opportunities"
+  description="Understand available opportunities"
+  icon={<Lightning size={16} />}
+/>
+
+  <IntegrationCard
+    href="./how-express-relay-works/permissioning"
+    colorScheme="purple"
+    title="Permissioning"
+    description="Learn about access controls"
+    icon={<Shield size={16} />}
+  />
+</div>

+ 66 - 0
apps/developer-hub/content/docs/express-relay/how-express-relay-works/opportunities.mdx

@@ -0,0 +1,66 @@
+---
+title: "Opportunities"
+description: >-
+  Understand what opportunities are in Express Relay, how they work, and how the Opportunity Adapter unifies different protocols.
+---
+
+# Opportunities
+
+In the context of Express Relay, an opportunity refers to a potential transaction that a searcher can execute on a protocol. Typically, the term "opportunity" is used for such transactions that are lucrative and therefore competed for by many searchers.
+
+In the pre-Express Relay world, opportunities corresponded to MEV: a protocol generated MEV when an opportunity appeared on that protocol and searchers bid up the right to execute the opportunity at the validator level.
+
+In the context of Express Relay, the value deriving from an opportunity no longer flows to the validator but instead is recaptured by the system and shared back with the protocol. In Express Relay, protocols expose opportunities to the network of integrated searchers, and the searchers then bid on priority to execute those opportunities. Critically, the auction has moved from being determined by validators to a lower level of the stack (the protocol level).
+
+## Oracle-agnostic
+
+Opportunities do not refer to only transactions that use an oracle. In truth, any transaction that is lucrative but limited (available to only the first user(s) who executes it) generates MEV. As a result, Express Relay and the opportunity schema have been designed to be oracle-agnostic.
+
+Examples of opportunities include:
+
+- **Liquidations** - Undercollateralized positions in lending protocols
+- **Open trade offers** - Limit orders waiting to be filled
+- **NFT mints** - Limited supply token drops
+- **Top-of-block DEX arbitrage** - Price discrepancies between exchanges
+
+## Opportunity Adapter
+
+The Opportunity Adapter contract enables searchers to engage with opportunities from different protocols without needing to do any bespoke integration work per protocol. Instead of exposing lower-level fields determined by protocols (e.g. amountCollateral, addressBorrower), the Opportunity Adapter abstracts away the semantics of the opportunity and instead [exposes the fundamental traits](https://github.com/pyth-network/per/blob/30c3fc695034f518225f8255ebe8423604e8aca3/contracts/src/opportunity-adapter/Structs.sol#L20-L23) of any opportunity:
+
+- The tokens sold by the searcher
+- The tokens bought by the searcher
+- The identity of the searcher executing this opportunity
+- The contract to call and the calldata and value to call with
+- The user's bid
+
+Thus, the Opportunity Adapter unifies the disparate interfaces of different protocols with respect to their different opportunities. This unification in a single interface is what makes Express Relay an opportunity hub connecting protocols and searchers.
+
+To use the Opportunity Adapter workflow, a searcher submits a bid with the target contract set to the **OpportunityAdapterFactory** contract. The factory contract then routes the searcher's transaction to their respective **OpportunityAdapter** contract. Each searcher has their own **OpportunityAdapter** contract per chain that is automatically created for them when they first interact with **OpportunityAdapterFactory**.
+
+### Permit2
+
+The **OpportunityAdapter** contract uses the [Permit2](https://github.com/Uniswap/permit2) token approval system, which handles the validation of a searcher's signature. Permit2 enables users to authorize token approvals for specific transaction data. In combination with Permit2, **OpportunityAdapter** allows a searcher to authorize use of their tokens only with a call to a particular contract with specified calldata and conditional on receipt of a set of specified **buyTokens**.
+
+## Opportunity Server
+
+Once on-chain opportunities arise, searchers can be notified of their existence via the opportunity server. Like the auction server, this is an off-chain piece of the Express Relay stack that is run by an infrastructure partner designated by the DAO. The opportunity server presents opportunities to searchers in a way that abstracts away bespoke integration work for the searcher: instead of worrying about crafting calldata specific to every new liquidation interface, searchers now view liquidation opportunities in terms of tokens they need to sell (debt they repay) in exchange for tokens they buy (collateral they liquidate). This simplified interface unifies different liquidation schemas and allows searchers to easily plug into more protocols.
+
+In addition to learning about present opportunities, searchers can also query the opportunity server for data about historical opportunities.
+
+### Before Express Relay
+
+Each searcher must connect to every new protocol with a custom integration, creating integration overhead and friction.
+
+### After Express Relay
+
+Searchers integrate once with Express Relay to access all current and future integrated protocols.
+
+The diagrams above illustrate the difference between the nature of integrations pre- and post-Express Relay. In the status quo, each searcher must connect to every new protocol with a custom integration. Similarly, protocols have to court and incentivize individual searchers. This creates a lot of integration overhead and friction for both parties.
+
+With Express Relay, the integration is abstracted away, and searchers can connect to all current and future Express Relay-integrated protocols by **integrating once** with Express Relay. On the other hand, protocols that integrate with Express Relay gain access to the network of searchers integrated with Express Relay.
+
+## Opportunity Monitor
+
+Many integrated protocols with Express Relay build out an opportunity monitor script to query executable opportunities on their protocol and expose them to searchers. This allows them to tap into all Express Relay-integrated searchers, who do not need to do any additional integration work beyond having access to the relevant tokens to execute opportunities on the protocol.
+
+In terms of existing infrastructure, the opportunity monitor script is most analogous to a protocol's liquidation scripts/bots. Typically, many lending protocols build liquidation bot libraries that they share publicly in hopes of encouraging adoption by liquidators. With minor modifications, these scripts can serve as the opportunity monitor that enables all Express Relay-integrated searchers to participate in this protocol's liquidations.

+ 44 - 0
apps/developer-hub/content/docs/express-relay/how-express-relay-works/permissioning.mdx

@@ -0,0 +1,44 @@
+---
+title: "Permissioning"
+description: >-
+  Learn how Express Relay uses permission IDs and keys to manage access control and distinguish between different opportunities.
+---
+
+# Permissioning
+
+**permissionId** is a **bytes** object that represents the unique identifier of a position within the protocol. **permissionId** allows the system to distinguish between bids competing on different opportunities and thereby run more scoped and efficient auctions.
+
+Each borrower has a unique position for some protocols, so the borrower address uniquely identifies a position.
+In other protocols, each borrower might have multiple positions, distinguished by the address of the collateral asset or by a **uint256** ID number.
+In those cases, the information set that uniquely identifies a position would include multiple fields.
+
+**permissionId** can be the concatenation of all these fields in bytes format. You can call **abi.encode()** to concatenate these fields together.
+
+## Examples
+
+### Single Position Per Borrower
+
+For example, if a protocol featured a unique position per borrower, then it could form **permissionId** as:
+
+```solidity
+bytes memory permissionId = abi.encode(borrowerAddress);
+```
+
+### Multiple Positions Per Borrower
+
+On the other hand, if a protocol allowed a borrower to open as many new positions as they wanted, denoted by an identifier **uint256 positionId**, then it could form **permissionId** as:
+
+```solidity
+bytes memory permissionId = abi.encode(borrowerAddress, positionId);
+```
+
+## Permission Key
+
+The Express Relay contract uses the **permissionId** to toggle permissions for interacting with the protocol.
+This toggling is checked within the protocol's code to ensure that the current transaction is within the context of Express Relay so that the recaptured value can be returned to the protocol. In particular, the Express Relay contract checks the toggling of the **permissionKey**, which is the concatenation of the protocol address and the **permissionId**:
+
+```solidity
+bytes memory permissionKey = abi.encode(protocolAddress, permissionId);
+```
+
+> **ℹ️ Access Control**: The permission key system ensures that only Express Relay can grant access to protocol operations, enabling MEV recapture and proper revenue sharing.

+ 125 - 0
apps/developer-hub/content/docs/express-relay/http-api-reference.mdx

@@ -0,0 +1,125 @@
+---
+title: "HTTP API Reference"
+description: >-
+  Complete HTTP API reference for Express Relay endpoints, including opportunities, bids, and configuration.
+---
+
+# HTTP API Reference
+
+Express Relay provides a comprehensive HTTP API for interacting with the protocol. The API allows you to fetch opportunities, submit bids, and access configuration data.
+
+## Interactive API Documentation
+
+The complete HTTP API reference is available as an interactive Swagger/OpenAPI documentation:
+
+### 🌐 Live API Documentation
+
+_Interactive API explorer with live examples_
+
+**Production (Mainnet):**  
+[https://per-mainnet.dourolabs.app/docs](https://per-mainnet.dourolabs.app/docs)
+
+**Staging (Testing):**  
+[https://per-staging.dourolabs.app/docs](https://per-staging.dourolabs.app/docs)
+
+## Base URLs
+
+Use the appropriate base URL for your environment:
+
+- **Production (Mainnet):** https://per-mainnet.dourolabs.app
+- **Staging (Testing):** https://per-staging.dourolabs.app
+
+## Key Endpoints
+
+### Opportunities
+
+**GET /v1/opportunities**
+
+- Retrieve available opportunities for bidding
+- Query parameters: chain_id, mode (live/historical)
+- Returns: Array of opportunity objects
+
+**Example:**
+
+```bash
+curl "https://per-mainnet.dourolabs.app/v1/opportunities?chain_id=solana&mode=live"
+```
+
+### Bids
+
+**POST /v1/bids**
+
+- Submit a bid for an opportunity
+- Request body: JSON with chain_id and transaction (base64 encoded)
+- Returns: Bid status and ID
+
+**Example:**
+
+```bash
+curl -X POST "https://per-mainnet.dourolabs.app/v1/bids" \
+  -H "Content-Type: application/json" \
+  -d '{
+    "chain_id": "solana",
+    "transaction": "SGVsbG8sIFdvcmxkIQ=="
+  }'
+```
+
+### Configuration
+
+**GET /v1/chains**
+
+- Get supported chains and their configurations
+- Returns: Array of supported chain configurations
+
+### WebSocket
+
+**WS /v1/ws**
+
+- Real-time WebSocket connection for opportunities and bid updates
+- See [WebSocket API Reference](./websocket-api-reference) for details
+
+## Authentication
+
+Most Express Relay endpoints are public and don't require authentication. However, some advanced features may require API keys or signed requests.
+
+## Rate Limits
+
+Express Relay implements rate limiting to ensure fair usage:
+
+- Standard endpoints: 100 requests per minute
+- WebSocket connections: 10 concurrent connections per IP
+- Bid submissions: 1000 bids per minute
+
+## Error Handling
+
+All API endpoints return standard HTTP status codes:
+
+- **200** - Success
+- **400** - Bad Request (invalid parameters)
+- **429** - Rate Limit Exceeded
+- **500** - Internal Server Error
+
+Error responses include detailed error messages in JSON format. See the [Error Codes](./errors) page for specific error scenarios and solutions.
+
+## SDKs
+
+Instead of calling the HTTP API directly, consider using the official SDKs:
+
+- **TypeScript/JavaScript:** [@pythnetwork/express-relay-js](https://www.npmjs.com/package/@pythnetwork/express-relay-js)
+- **Python:** Available in the [Express Relay GitHub repository](https://github.com/pyth-network/per/tree/main/sdk/python)
+
+## Examples
+
+For complete integration examples, see:
+
+- [Integrate as a Protocol](./integrate-as-protocol) - Frontend integration guide
+- [Integrate as a Searcher](./integrate-as-searcher) - Searcher integration guide
+
+## Support
+
+If you encounter issues with the API:
+
+1. Check the [Error Codes](./errors) page for common issues
+2. Review the interactive API documentation for parameter requirements
+3. Join the Pyth Discord for community support
+4. Contact technical support for persistent issues

+ 214 - 0
apps/developer-hub/content/docs/express-relay/websocket-api-reference.mdx

@@ -0,0 +1,214 @@
+---
+title: "WebSocket API Reference"
+description: >-
+  Complete reference for Express Relay's WebSocket API for subscribing to opportunities and submitting bids with reduced latency.
+---
+
+# WebSocket API Reference
+
+Searchers can connect to the server via WebSocket to reduce latency and subscribe to various events.
+The WebSocket endpoint lives at `/v1/ws` (e.g wss://per-mainnet.dourolabs.app/v1/ws).
+
+## General Format
+
+Each request sent to the server via WebSocket should be in the following JSON format:
+
+```json
+{
+  "id": "...", // used for uniquely identifying the response to this request
+  "method": "...", // name of the server method to invoke
+  "params": {...} // parameters necessary for the method
+}
+```
+
+The server responds using the same **id** specified in the request:
+
+```json
+{
+  "id": "...",
+  "status": "success",
+  "result": {}
+}
+```
+
+In case of error, the **status** field will be **error**, and the error message will be available in the **result** field as a string:
+
+```json
+{
+  "id": "...",
+  "status": "error",
+  "result": "..."
+}
+```
+
+## Subscribing to Opportunities
+
+To subscribe to opportunities, you can send a request using the **chain_ids** parameter, which specifies the chains as an array.
+
+```json
+{
+  "id": "1",
+  "method": "subscribe",
+  "params": {
+    "chain_ids": ["development-solana"]
+  }
+}
+```
+
+After a successful subscription, you will receive new opportunities for the selected chains via the WebSocket in the following format:
+
+```json
+{
+  "type": "new_opportunity",
+  "opportunity": {...}
+}
+```
+
+The schema for the opportunity is similar to what's returned in the [HTTP requests](https://per-mainnet.dourolabs.app/docs#tag/opportunity/operation/get_opportunities).
+
+To unsubscribe from a list of chains, you can send the following message:
+
+```json
+{
+  "id": "1",
+  "method": "unsubscribe",
+  "params": {
+    "chain_ids": ["development-solana"]
+  }
+}
+```
+
+## Submitting Bids
+
+In addition to the HTTP methods, you can submit your bids via WebSocket in order to avoid additional network round trips and get notified about changes to your bid status.
+Here is an example JSON payload for submitting a new bid:
+
+```json
+{
+  "id": "1",
+  "method": "post_bid",
+  "params": {
+    "bid": {
+      "chain_id": "development-solana",
+      "transaction": "SGVsbG8sIFdvcmxkIQ=="
+    }
+  }
+}
+```
+
+A successful response to a bid submission has the following schema:
+
+```json
+{
+  "id": "1", // WebSocket request id
+  "status": "success",
+  "result": {
+    "id": "beedbeed-b346-4fa1-8fab-2541a9e1872d", // bid id
+    "status": "OK"
+  }
+}
+```
+
+## Bid Status Updates
+
+After submitting your bid via WebSocket, you will receive notifications about the bid status updates in JSON format.
+
+### Status Types
+
+**Pending**
+
+```json
+// The temporary state which means the auction for this bid is pending.
+// It will be updated to Lost or Submitted after the auction takes place.
+{
+  "type": "bid_status_update",
+  "status": {
+    "id": "beedbeed-0e42-400f-a8ef-d78aa5422252",
+    "bid_status": {
+      "type": "pending"
+    }
+  }
+}
+```
+
+**Submitted**
+
+```json
+// The bid won the auction and was submitted to the chain, with the signature
+// of the corresponding transaction provided in the result field.
+// This state is temporary and will be updated to either Won or Failed after
+// the transaction is included in a block, or Expired if the transaction expires.
+{
+  "type": "bid_status_update",
+  "status": {
+    "id": "beedbeed-0e42-400f-a8ef-d78aa5422252",
+    "bid_status": {
+      "type": "submitted",
+      "result": "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg"
+    }
+  }
+}
+```
+
+**Lost**
+
+```json
+// The bid did not win the auction and therefore was not submitted.
+{
+  "type": "bid_status_update",
+  "status": {
+    "id": "beedbeed-0e42-400f-a8ef-d78aa5422252",
+    "bid_status": {
+      "type": "lost"
+    }
+  }
+}
+```
+
+**Won**
+
+```json
+// The final state which means the bid was submitted to the chain and successfully executed.
+{
+  "type": "bid_status_update",
+  "status": {
+    "id": "beedbeed-0e42-400f-a8ef-d78aa5422252",
+    "bid_status": {
+      "type": "won",
+      "result": "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg"
+    }
+  }
+}
+```
+
+**Failed**
+
+```json
+// The final state which means the bid was submitted to the chain but failed to execute.
+{
+  "type": "bid_status_update",
+  "status": {
+    "id": "beedbeed-0e42-400f-a8ef-d78aa5422252",
+    "bid_status": {
+      "type": "failed",
+      "result": "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg"
+    }
+  }
+}
+```
+
+**Expired**
+
+```json
+// The final state which means the bid was submitted to the chain but expired before execution.
+{
+  "type": "bid_status_update",
+  "status": {
+    "id": "beedbeed-0e42-400f-a8ef-d78aa5422252",
+    "bid_status": {
+      "type": "expired",
+      "result": "Jb2urXPyEh4xiBgzYvwEFe4q1iMxG1DNxWGGQg94AmKgqFTwLAiTiHrYiYxwHUB4DV8u5ahNEVtMMDm3sNSRdTg"
+    }
+  }
+}
+```