Repeatedly going over the rate limit will result in temporary IP ban, ranging from 3 minutes to 24 hours.
HTTPS
It's recommended that you use HTTP Keep-Alive connections to connect to the RPC endpoint to minimize TLS connection establishment times as it significantly reduces request latency when sending a bundle if the TLS handshake is already complete.
The /ping endpoint is available for establishing a session, you can have a maximum of 2 sessions per IP address, and sessions will persist for a maximum of 15 minutes.
Example:
import axios from'axios';// Abstracted function to create the PFL bundlefunctioncreatePflBundle(bundleId, opportunityRawTx, solverOpStruct) {return { id: bundleId, jsonrpc:"2.0", method:"pfl_addSearcherBundle", params: [opportunityRawTx, solverOpStruct] };}// Helper function to submit the bundle to the Fastlane endpointasyncfunctionsubmitBundle(bundle) {consthttpFastlaneEndpoint="https://polygon-rpc.fastlane.xyz";try {constresponse=awaitaxios.post(httpFastlaneEndpoint, bundle, { timeout:1000 });if (response.data.error) {console.error(`Error submitting bundle ${bundle.id}`,response.data); } else {console.log(`Response received for bundle ${bundle.id}`,response.data); } } catch (error) {console.error(`Error submitting bundle ${bundle.id}`, error); }}// Main function to submit the bundleasyncfunctionmain() {// Define your variablesconstbundleId=1;constopportunityRawTx="0x..."; // Replace with your actual opportunity raw transactionconstsolverOpStruct="0x..."; // Replace with your actual solver operation structure// Create the PFL bundleconstpflBundle=createPflBundle(bundleId, opportunityRawTx, solverOpStruct);// Submit the bundle to the Fastlane endpointawaitsubmitBundle(pflBundle);}main().catch(console.error);
import asyncioimport aiohttpimport json# Asynchronous function to test the connection to the Fastlane endpointasyncdefping_fastlane(): http_fastlane_ping_endpoint ="https://polygon-rpc.fastlane.xyz/ping"try:asyncwith aiohttp.ClientSession()as session:asyncwith session.get(http_fastlane_ping_endpoint, timeout=10)as response:if response.status ==200: text =await response.text()print("Ping successful:", text)else:print("Ping failed with status code:", response.status)except aiohttp.ClientError as e:print("Ping failed:", e)except asyncio.TimeoutError:print("Ping failed: Request timed out")# Function to create the PFL bundle with specified argumentsdefcreate_pfl_bundle(bundle_id,opportunity_raw_tx,solver_op_struct):return{"id": bundle_id,"jsonrpc":"2.0","method":"submitBundle","params": [opportunity_raw_tx, solver_op_struct]}# Asynchronous function to submit the bundle to the Fastlane endpointasyncdefsubmit_bundle(bundle): http_fastlane_endpoint ="https://polygon-rpc.fastlane.xyz"try:asyncwith aiohttp.ClientSession()as session:asyncwith session.post(http_fastlane_endpoint, json=bundle, timeout=10)as response: response.raise_for_status()# Raise an error for bad HTTP status codes response_data =await response.json()if'error'in response_data:print(f"Error submitting bundle {bundle['id']}: {response_data['error']}")else:print(f"Response received for bundle {bundle['id']}: {response_data['result']}")except aiohttp.ClientResponseError as http_err:print(f"HTTP error occurred while submitting bundle {bundle['id']}: {http_err}")except aiohttp.ClientError as client_err:print(f"Client error occurred while submitting bundle {bundle['id']}: {client_err}")except asyncio.TimeoutError:print(f"Error submitting bundle {bundle['id']}: Request timed out")except json.JSONDecodeError as json_err:print(f"JSON decode error for bundle {bundle['id']}: {json_err}")# Asynchronous main function to test connection and submit the bundleasyncdefmain():# Test the connection to the Fastlane endpointawaitping_fastlane()# Wait until you're ready to send a bundle, refreshing session as necessary# You might include a delay or a condition here if needed# Define your variables bundle_id =1 opportunity_raw_tx ="0x..."# Replace with your actual opportunity raw transaction solver_op_struct ="0x..."# Replace with your actual solver operation structure# Create the PFL bundle with the specified arguments pfl_bundle =create_pfl_bundle(bundle_id, opportunity_raw_tx, solver_op_struct)# Submit the bundle to the Fastlane endpointawaitsubmit_bundle(pfl_bundle)if__name__=="__main__": asyncio.run(main())
Websocket
Ping messages will be sent to your connection every 60 seconds. A pong response must be sent to avoid disconnection. Alternatively, you can send ping messages yourself to the server every minutes and get pong responses.
To keep a websocket connection open and stable on a long term, we highly recommend to send ping messages to the server every minutes, and to answer pong every time the server sends a ping message.
To better track responses (e.g. when sending multiple concurrent requests), it is highly advised to specify a unique id for each new requests, see example below.
Example:
constWebSocket=require('ws');// Abstracted function to create the PFL bundle with argumentsfunctioncreatePflBundle(bundleId, opportunityRawTx, solverOpStruct) {return { id: bundleId, jsonrpc:"2.0", method:"pfl_addSearcherBundle", params: [`${opportunityRawTx}`,`${JSON.stringify(solverOpStruct)}`] };}// Helper function to submit the bundle to the Fastlane endpoint over WebSocketasyncfunctionsubmitBundle(bundle) {constwsFastlaneEndpoint="wss://beta-rpc.fastlane-labs.xyz/ws";returnnewPromise((resolve, reject) => {constws=newWebSocket(wsFastlaneEndpoint);ws.on('open',functionopen() {// Send the bundle as a JSON-RPC requestws.send(JSON.stringify(bundle)); });ws.on('message',functionincoming(data) {constresponse=JSON.parse(data);if (response.error) {console.error(`Error submitting bundle ${bundle.id}`, response);ws.close();reject(response.error); } else {console.log(`Response received for bundle ${bundle.id}`, response);ws.close();resolve(response.result); } });ws.on('error',functionerror(err) {console.error(`WebSocket error for bundle ${bundle.id}`, err);ws.close();reject(err); });ws.on('close',functionclose(code, reason) {console.log(`WebSocket connection closed: ${code}${reason}`); }); });}// Main function to submit the bundleasyncfunctionmain() {// Define your variablesconstbundleId=1;constopportunityRawTx="0x..."; // Replace with your actual opportunity raw transactionconstsolverOpStruct="0x..."; // Replace with your actual solver operation structure// Create the PFL bundleconstpflBundle=createPflBundle(bundleId, opportunityRawTx, solverOpStruct);// Submit the bundle to the Fastlane endpointawaitsubmitBundle(pflBundle);}main().catch(console.error);
import asyncioimport websocketsimport json# Function to create the PFL bundle with argumentsdefcreate_pfl_bundle(bundleId,opportunityRawTx,solverOpStruct):return{"id": bundleId,"jsonrpc":"2.0","method":"pfl_addSearcherBundle",# Ensure the method name matches the JS version"params": [f"{opportunityRawTx}",# Convert opportunityRawTx to stringf"{json.dumps(solverOpStruct)}"# Serialize solverOpStruct to JSON string ]}# Helper function to submit the bundle via WebSocketasyncdefsubmit_bundle(bundle): websocket_endpoint ="wss://polygon-rpc.fastlane.xyz"try:asyncwith websockets.connect(websocket_endpoint)as websocket:await websocket.send(json.dumps(bundle)) response =await websocket.recv() response_data = json.loads(response)if'error'in response_data:print(f"Error submitting bundle {bundle['id']}:", response_data['error'])else:print(f"Response received for bundle {bundle['id']}:", response_data['result'])exceptExceptionas e:print(f"Error submitting bundle {bundle['id']}:", e)# Main function to submit the bundleasyncdefmain():# Wait until you're ready to send a bundle, refreshing session as necessary# You might want to include some delay or conditions here# Define your variables bundleId =1 opportunityRawTx ="0x..."# Replace with your actual opportunity raw transaction solverOpStruct ="0x..."# Replace with your actual solver operation structure# Create the PFL bundle with the specified arguments pfl_bundle =create_pfl_bundle(bundleId, opportunityRawTx, solverOpStruct)# Submit the bundle to the Fastlane endpointawaitsubmit_bundle(pfl_bundle)if__name__=="__main__": asyncio.run(main())