SDK Integration
Integrate Reflex MEV capture into your client applications, DApps, and custom trading strategies using the TypeScript SDK.
Overview
The Reflex SDK provides a powerful and easy-to-use interface for building MEV-enabled DApps. Whether you're integrating MEV capture into a DApp frontend or creating custom trading interfaces, the SDK handles the complexity of interacting with Reflex smart contracts.
Installation
npm install @reflex-mev/sdk ethers
# or
yarn add @reflex-mev/sdk ethers
Quick Start
Basic Setup
import { ReflexSDK } from "@reflex-mev/sdk";
import { ethers } from "ethers";
// Initialize provider and signer
const provider = new ethers.JsonRpcProvider(
"https://mainnet.infura.io/v3/YOUR_KEY"
);
const signer = new ethers.Wallet("YOUR_PRIVATE_KEY", provider);
// Create SDK instance
const reflex = new ReflexSDK(provider, signer, {
routerAddress: "0xYourReflexRouterAddress",
defaultGasLimit: 300000n,
});
DApp Integration
Frontend Integration
// React hook for MEV integration
import { useState, useEffect, useCallback } from "react";
import { ReflexSDK } from "@reflex-mev/sdk";
export function useReflexMEV(provider, signer) {
const [reflex, setReflex] = useState(null);
const [mevStats, setMevStats] = useState({
totalCaptured: 0n,
userRewards: 0n,
successRate: 0,
});
useEffect(() => {
if (provider && signer) {
const reflexInstance = new ReflexSDK(provider, signer, {
routerAddress: "0xYourReflexRouterAddress",
defaultGasLimit: 500000n,
});
setReflex(reflexInstance);
// Note: Event listening would be implemented through provider event filters
// Example: Listen for BackrunExecuted events directly from the contract
}
}, [provider, signer]);
const executeSwapWithMEV = useCallback(
async (swapParams) => {
if (!reflex) return null;
try {
// Prepare the user's swap transaction as executeParams
const executeParams = {
target: swapParams.poolAddress,
value: swapParams.value || 0n,
callData: swapParams.swapCallData,
};
// Prepare backrun parameters (array of BackrunParams)
const backrunParams = [
{
triggerPoolId: swapParams.poolAddress,
swapAmountIn: swapParams.amountIn / 20n, // 5% of swap
token0In: swapParams.token0In,
recipient: swapParams.user,
configId: swapParams.configId,
},
];
// Execute swap + MEV capture atomically
const result = await reflex.backrunedExecute(
executeParams,
backrunParams
);
return {
success: result.success,
transactionHash: result.transactionHash,
returnData: result.returnData,
profits: result.profits,
profitTokens: result.profitTokens,
};
} catch (error) {
console.error("Swap with MEV failed:", error);
throw error;
}
},
[reflex]
);
return {
reflex,
mevStats,
executeSwapWithMEV,
isReady: !!reflex,
};
}
Trading Interface Component
// MEV-enabled trading component
import React, { useState } from "react";
export function MEVTradingInterface({ useReflexMEV }) {
const { executeSwapWithMEV, mevStats, isReady } = useReflexMEV(
provider,
signer
);
const [swapAmount, setSwapAmount] = useState("");
const [isSwapping, setIsSwapping] = useState(false);
const handleSwap = async () => {
setIsSwapping(true);
try {
const result = await executeSwapWithMEV({
tokenIn: selectedTokenIn.address,
tokenOut: selectedTokenOut.address,
amountIn: ethers.parseEther(swapAmount),
poolAddress: poolAddress,
user: userAddress,
token0In: selectedTokenIn.address < selectedTokenOut.address,
swapCallData: encodedSwapData, // Pre-encoded swap transaction
});
if (
result.success &&
result.profits.length > 0 &&
result.profits[0] > 0n
) {
showNotification({
type: "success",
title: "Swap Completed with MEV Bonus!",
message: `You received an additional ${ethers.formatEther(
result.profits[0]
)} ${result.profitTokens[0]} from MEV capture`,
});
}
} catch (error) {
showNotification({
type: "error",
title: "Swap Failed",
message: error.message,
});
} finally {
setIsSwapping(false);
}
};
return (
<div className="trading-interface">
{/* MEV Stats Display */}
<div className="mev-stats">
<h3>MEV Benefits</h3>
<div>
Total Captured: {ethers.formatEther(mevStats.totalCaptured)} ETH
</div>
<div>Your Rewards: {ethers.formatEther(mevStats.userRewards)} ETH</div>
<div>Success Rate: {(mevStats.successRate * 100).toFixed(1)}%</div>
</div>
{/* Trading Interface */}
<div className="swap-form">
<input
type="number"
value={swapAmount}
onChange={(e) => setSwapAmount(e.target.value)}
placeholder="Amount to swap"
/>
<button
onClick={handleSwap}
disabled={!isReady || isSwapping}
className="swap-button"
>
{isSwapping ? "Swapping..." : "Swap with MEV Protection"}
</button>
</div>
</div>
);
}
Configuration and Optimization
Gas Management
// Advanced gas optimization
const reflex = new ReflexSDK(provider, signer, {
routerAddress: "0xYourReflexRouterAddress",
defaultGasLimit: 500000n,
gasPriceMultiplier: 1.2,
});
// Transaction options can be passed to backrunedExecute
const options = {
gasLimit: 600000n,
maxFeePerGas: ethers.parseUnits("100", "gwei"),
maxPriorityFeePerGas: ethers.parseUnits("2", "gwei"),
};
Event Monitoring
// Event monitoring through provider
import { Interface } from "ethers";
import { REFLEX_ROUTER_ABI } from "@reflex-mev/sdk";
const routerInterface = new Interface(REFLEX_ROUTER_ABI);
// Listen for BackrunExecuted events
provider.on(
{
address: reflexConfig.routerAddress,
topics: [routerInterface.getEvent("BackrunExecuted").topicHash],
},
(log) => {
const event = routerInterface.parseLog(log);
analytics.track("MEV_Captured", {
profit: event.args.profit,
triggerPoolId: event.args.triggerPoolId,
recipient: event.args.recipient,
timestamp: Date.now(),
});
}
);
Testing
Mock Environment
// Test your integration
import { ethers } from "ethers";
import { ReflexSDK } from "@reflex-mev/sdk";
describe("MEV Integration", () => {
let reflex: ReflexSDK;
let provider: ethers.Provider;
let signer: ethers.Wallet;
beforeEach(() => {
// Create test provider and wallet
provider = new ethers.JsonRpcProvider("http://localhost:8545");
signer = new ethers.Wallet("0x" + "1".repeat(64), provider);
reflex = new ReflexSDK(provider, signer, {
routerAddress: "0x1234567890123456789012345678901234567890",
defaultGasLimit: 500000n,
});
});
it("should capture MEV successfully", async () => {
const executeParams = {
target: "0x1234567890123456789012345678901234567890",
value: 0n,
callData: "0x123456", // encoded swap data
};
const backrunParams = [
{
triggerPoolId: "0x1234567890123456789012345678901234567890",
swapAmountIn: ethers.parseEther("1"),
token0In: true,
recipient: "0x1234567890123456789012345678901234567890",
configId:
"0x0000000000000000000000000000000000000000000000000000000000000000",
},
];
const result = await reflex.backrunedExecute(executeParams, backrunParams);
expect(result.success).toBe(true);
expect(result.profits.length).toBeGreaterThan(0);
expect(result.profits[0]).toBeGreaterThan(0n);
});
});
Best Practices
Error Handling
- Always handle SDK errors gracefully
- Implement retry logic for network issues
- Use try/catch for all async operations
- Monitor and log all MEV attempts
Performance
- Cache frequently used data
- Use batch operations when possible
- Implement connection pooling
- Monitor gas usage patterns
Security
- Never expose private keys in frontend code
- Validate all user inputs
- Use secure RPC endpoints
- Implement rate limiting
For revenue configuration details, see the Revenue Configuration Guide. For smart contract integration, see the Smart Contract Integration Guide.