SVM Searcher Integration
SVM Express Relay searchers fulfill opportunities representing limit orders on the Limo (opens in a new tab) program.
Subscribe to New Opportunities
Express Relay provides searchers with Typescript (opens in a new tab) and Python (opens in a new tab) SDKs to interact with Express Relay. Searchers can also directly fetch available opportunities via HTTP or subscribe to them via WebSocket.
Pyth provides a Typescript SDK, which allows searchers to subscribe to opportunities:
import { Client, Opportunity } from "@pythnetwork/express-relay-js";
const handleOpportunity = async (opportunity: Opportunity) => {
console.log("Received opportunity");
// Implement your opportunity handler here
};
const client = new Client(
{ baseUrl: "https://pyth-express-relay-mainnet.asymmetric.re" },
undefined, // Default WebSocket options
handleOpportunity
);
async function main() {
await client.subscribeChains(["solana"]);
}
main();
The server responds with opportunities in the following format:
{
"order": "UxMUbQAsjrfQUp5stVwMJ6Mucq7VWTvt4ICe69BJ8lVXqwM+0sysV8OqZTdM0W4p...", // The Limo order to be executed, encoded in base64
"order_address": "DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5", // Address of the order account
"program": "limo", // Identifier of the program that the order exists in
"chain_id": "development-solana",
"version": "v1" // Opportunity format version
}
Construct the Bid
Searchers should construct a bid by evaluating the fetched opportunity.
Before constructing the bid, make sure your wallet has the required assets to fulfill the limit order and SOL to pay the bid amount.
See the following examples of how to construct a bid object via the SDKs:
Below is an excerpt of example code. See the full example in the Typescript SDK (opens in a new tab).
import { OpportunitySvm } from "../index";
import { BidSvm } from "../types";
import * as anchor from "@coral-xyz/anchor";
import * as limo from "@kamino-finance/limo-sdk";
/**
* Generates a bid for a given opportunity.
* The transaction in this bid transfers assets from the searcher's wallet to fulfill the limit order.
* @param opportunity The SVM opportunity to bid on.
* @returns The generated bid object.
*/
async generateBid(opportunity: OpportunitySvm): Promise<BidSvm> {
const order = opportunity.order;
const limoClient = new limo.LimoClient(
this.connectionSvm,
order.state.globalConfig
);
const ixsTakeOrder = await this.generateTakeOrderIxs(limoClient, order);
const feeInstruction = ComputeBudgetProgram.setComputeUnitPrice({
microLamports:
this.latestChainUpdate[this.chainId].latestPrioritizationFee,
});
const txRaw = new anchor.web3.Transaction().add(
feeInstruction,
...ixsTakeOrder
);
const bidAmount = await this.getBidAmount(order);
const config = await this.getExpressRelayConfig();
const bid = await this.client.constructSvmBid(
txRaw,
this.searcher.publicKey,
getPdaAuthority(limoClient.getProgramID(), order.state.globalConfig),
order.address,
bidAmount,
new anchor.BN(Math.round(Date.now() / 1000 + DAY_IN_SECONDS)),
this.chainId,
config.relayerSigner,
config.feeReceiverRelayer
);
bid.transaction.recentBlockhash =
this.latestChainUpdate[this.chainId].blockhash;
bid.transaction.sign(this.searcher);
return bid;
}
The bid you construct will look like
{
// serialized transaction object, in base-64 encoding
"transaction": "SGVsbG8sIFdvcmxkIQ==",
"chain_id": "solana",
"env": "svm"
}
where the serialized transaction object should contain an Express Relay SubmitBid
instruction that specifies the amount you are bidding and the permission details.
Submit Bids on Opportunities to Express Relay
Searchers can submit their constructed bids to Express Relay via the SDKs, an HTTP POST request, or a WebSocket connection.
The code snippet below demonstrates how to submit a bid using the Typescript SDK:
const generateBid = async (opportunity: OpportunitySvm, recentBlockhash: Blockhash): BidSvm => {
...
}
const handleOpportunity = async (opportunity: Opportunity) => {
...
const bid = await this.generateBid(opportunity as OpportunitySvm);
await client.submitBid(bid);
}