mev-helper
v1.0.1
Published
SDK for interacting with MEVBot smart contract on Ethereum mainnet
Maintainers
Readme
MEV Helper
A TypeScript/JavaScript SDK for interacting with the MEVBot smart contract on Ethereum networks.
Installation
npm install mev-helperContract Addresses Configuration
⚠️ Important: Contract addresses are now required and must be provided when creating a MEVBot instance. The SDK no longer includes hardcoded default addresses.
You can provide contract addresses in two ways:
- Using
contractAddresses(recommended for multiple networks):
import { MEVBot, Network, ContractAddresses } from 'mev-helper';
const contractAddresses: ContractAddresses = {
[Network.MAINNET]: '0x779B21Cf23E037Ab847831A45A6d71B2e97b6328',
[Network.SEPOLIA]: '0x922E4879B5C4289AF607E563126Db3BeBA52214A'
};
const mevBot = new MEVBot({
network: Network.MAINNET,
contractAddresses
});- Using
contractAddress(for a single address):
const mevBot = new MEVBot({
contractAddress: '0x779B21Cf23E037Ab847831A45A6d71B2e97b6328'
});Network Support
The SDK supports both mainnet and testnet environments. You can specify the network when creating a MEVBot instance:
import { MEVBot, Network, ContractAddresses } from 'mev-helper';
const contractAddresses: ContractAddresses = {
[Network.MAINNET]: '0x779B21Cf23E037Ab847831A45A6d71B2e97b6328',
[Network.SEPOLIA]: '0x922E4879B5C4289AF607E563126Db3BeBA52214A'
};
// Use mainnet
const mevBotMainnet = new MEVBot({
network: Network.MAINNET,
contractAddresses
});
// Use Sepolia testnet
const mevBotSepolia = new MEVBot({
network: Network.SEPOLIA,
contractAddresses
});Quick Start
Basic Usage (Read Operations)
import { MEVBot, Network, ContractAddresses } from 'mev-helper';
import { ethers } from 'ethers';
// Define contract addresses
const contractAddresses: ContractAddresses = {
[Network.MAINNET]: '0x779B21Cf23E037Ab847831A45A6d71B2e97b6328',
[Network.SEPOLIA]: '0x922E4879B5C4289AF607E563126Db3BeBA52214A'
};
// Create instance with default provider (read-only, mainnet by default)
const mevBot = new MEVBot({
network: Network.MAINNET,
contractAddresses
});
// Or specify network explicitly
const mevBotMainnet = new MEVBot({
network: Network.MAINNET,
contractAddresses
});
const mevBotSepolia = new MEVBot({
network: Network.SEPOLIA,
contractAddresses
});
// Get contract owner
const owner = await mevBot.getOwner();
console.log('Owner:', owner);
// Get contract balance
const balance = await mevBot.getBalance();
console.log('Balance:', ethers.formatEther(balance), 'ETH');
// Get max batch size
const maxBatchSize = await mevBot.getMaxBatchSize();
console.log('Max batch size:', maxBatchSize.toString());Write Operations (Requires Signer)
import { MEVBot, Network } from 'mev-helper';
import { ethers } from 'ethers';
// Connect with a signer (e.g., from a wallet)
// For mainnet
const providerMainnet = new ethers.JsonRpcProvider('YOUR_MAINNET_RPC_URL');
const signerMainnet = new ethers.Wallet('YOUR_PRIVATE_KEY', providerMainnet);
const mevBot = new MEVBot({ network: Network.MAINNET, provider: signerMainnet });
// For Sepolia testnet
const providerSepolia = new ethers.JsonRpcProvider('YOUR_SEPOLIA_RPC_URL');
const signerSepolia = new ethers.Wallet('YOUR_PRIVATE_KEY', providerSepolia);
const mevBotSepolia = new MEVBot({ network: Network.SEPOLIA, provider: signerSepolia });
// Call a contract function
const targetContract = '0x...';
const functionData = '0x...'; // Encoded function call
const receipt = await mevBot.callContract(targetContract, functionData);
console.log('Transaction hash:', receipt.hash);
// Call with ETH value
const value = ethers.parseEther('0.1'); // 0.1 ETH
const receipt2 = await mevBot.callContractWithValue(
targetContract,
functionData,
value
);API Reference
Constructor
new MEVBot(config?: MEVBotConfig)Parameters:
config.network(optional): Network to use (Network.MAINNETorNetwork.SEPOLIA). Defaults toNetwork.MAINNET.config.contractAddress(optional): Custom contract address. If provided, overrides the network-based address.config.provider(optional): ethers Provider or Signer. Defaults to the default provider for the specified network.
Examples:
// Use mainnet (default)
const mevBot1 = new MEVBot();
// Use Sepolia testnet
const mevBot2 = new MEVBot({ network: Network.SEPOLIA });
// Use custom address
const mevBot3 = new MEVBot({ contractAddress: '0x...' });
// Use custom provider with network
const mevBot4 = new MEVBot({
network: Network.SEPOLIA,
provider: customProvider
});Read Functions
getMaxBatchSize(): Promise<bigint>
Get the maximum batch size for batch operations.
getOwner(): Promise<string>
Get the contract owner address.
getBalance(): Promise<bigint>
Get the contract's ETH balance in wei.
isApprovedOperator(operator: string): Promise<boolean>
Check if an address is an approved operator.
detectNFTStandard(nftContract: string): Promise<NFTStandard>
Detect the NFT standard (ERC721, ERC1155, or UNKNOWN) of a contract.
supportsInterface(interfaceId: string): Promise<boolean>
Check if the contract supports a specific interface.
Write Functions
All write functions require a signer and return a transaction receipt.
callContract(target: string, data: string)
Call a contract function without sending ETH.
Parameters:
target: Target contract addressdata: Encoded function call data
callContractWithValue(target: string, data: string, value: bigint)
Call a contract function with ETH value.
Parameters:
target: Target contract addressdata: Encoded function call datavalue: Amount of ETH to send (in wei)
batchCallContracts(options: BatchCallOptions)
Batch call multiple contracts in a single transaction.
Parameters:
{
dataArray: string[]; // Array of encoded function call data
targets: string[]; // Array of target contract addresses
values: bigint[]; // Array of ETH values to send (in wei)
}Example:
const receipt = await mevBot.batchCallContracts({
dataArray: ['0x...', '0x...'],
targets: ['0x...', '0x...'],
values: [ethers.parseEther('0.1'), 0n]
});addApprovedOperator(operator: string)
Add an approved operator address.
removeApprovedOperator(operator: string)
Remove an approved operator address.
rescueNFT(nftContract: string, tokenId: bigint, recipient: string)
Rescue an NFT from the contract.
Parameters:
nftContract: NFT contract addresstokenId: Token ID to rescuerecipient: Address to send the NFT to
withdrawETH(recipient: string, amount: bigint)
Withdraw ETH from the contract.
Parameters:
recipient: Address to send ETH toamount: Amount to withdraw (in wei)
withdrawERC20(tokenContract: string, recipient: string, amount: bigint)
Withdraw ERC20 tokens from the contract.
Parameters:
tokenContract: ERC20 token contract addressrecipient: Address to send tokens toamount: Amount to withdraw
transferOwnership(newOwner: string)
Transfer contract ownership to a new address.
renounceOwnership()
Renounce contract ownership.
Event Listeners
onContractCalled(callback: (event: ContractCalledEvent) => void)
Listen to ContractCalled events.
Example:
mevBot.onContractCalled((event) => {
console.log('Contract called:', event.targetContract);
console.log('Success:', event.success);
});onBatchContractCalled(callback: (event: BatchContractCalledEvent) => void)
Listen to BatchContractCalled events.
onNFTReceived(callback: (event: NFTReceivedEvent) => void)
Listen to NFTReceived events.
onBatchNFTReceived(callback: (event: BatchNFTReceivedEvent) => void)
Listen to BatchNFTReceived events.
onOwnershipTransferred(callback: (previousOwner: string, newOwner: string) => void)
Listen to OwnershipTransferred events.
removeAllListeners()
Remove all event listeners.
Examples
Example 1: Network Selection
import { MEVBot, Network, ContractAddresses } from 'mev-helper';
// Define contract addresses for different networks
// In production, these should come from environment variables or configuration
const contractAddresses: ContractAddresses = {
[Network.MAINNET]: '0x779B21Cf23E037Ab847831A45A6d71B2e97b6328',
[Network.SEPOLIA]: '0x922E4879B5C4289AF607E563126Db3BeBA52214A'
};
// Use mainnet
const mevBotMainnet = new MEVBot({
network: Network.MAINNET,
contractAddresses
});
console.log('Mainnet address:', contractAddresses[Network.MAINNET]);
// Use Sepolia testnet
const mevBotSepolia = new MEVBot({
network: Network.SEPOLIA,
contractAddresses
});
console.log('Sepolia address:', contractAddresses[Network.SEPOLIA]);
// Get owner from different networks
const ownerMainnet = await mevBotMainnet.getOwner();
const ownerSepolia = await mevBotSepolia.getOwner();
console.log('Mainnet owner:', ownerMainnet);
console.log('Sepolia owner:', ownerSepolia);Example 2: Batch Contract Calls
import { MEVBot, Network, ContractAddresses } from 'mev-helper';
import { ethers } from 'ethers';
const contractAddresses: ContractAddresses = {
[Network.MAINNET]: '0x779B21Cf23E037Ab847831A45A6d71B2e97b6328',
[Network.SEPOLIA]: '0x922E4879B5C4289AF607E563126Db3BeBA52214A'
};
const provider = new ethers.JsonRpcProvider('YOUR_RPC_URL');
const signer = new ethers.Wallet('YOUR_PRIVATE_KEY', provider);
const mevBot = new MEVBot({
provider: signer,
contractAddresses
});
// Prepare batch call
const iface = new ethers.Interface(['function transfer(address,uint256)']);
const data1 = iface.encodeFunctionData('transfer', ['0x...', ethers.parseEther('100')]);
const data2 = iface.encodeFunctionData('transfer', ['0x...', ethers.parseEther('200')]);
const receipt = await mevBot.batchCallContracts({
dataArray: [data1, data2],
targets: ['0xTokenContract1', '0xTokenContract2'],
values: [0n, 0n]
});
console.log('Batch call completed:', receipt.hash);Example 3: Monitoring Events
import { MEVBot, Network, ContractAddresses } from 'mev-helper';
const contractAddresses: ContractAddresses = {
[Network.MAINNET]: '0x779B21Cf23E037Ab847831A45A6d71B2e97b6328',
[Network.SEPOLIA]: '0x922E4879B5C4289AF607E563126Db3BeBA52214A'
};
const mevBot = new MEVBot({
network: Network.MAINNET,
contractAddresses
});
// Listen to contract calls
mevBot.onContractCalled((event) => {
console.log('Contract called:', {
target: event.targetContract,
selector: event.functionSelector,
success: event.success,
timestamp: new Date(Number(event.timestamp) * 1000)
});
});
// Listen to NFT received events
mevBot.onNFTReceived((event) => {
console.log('NFT received:', {
standard: event.standard === 0 ? 'ERC721' : 'ERC1155',
tokenId: event.tokenId.toString(),
from: event.from
});
});Example 4: Check Operator Status
import { MEVBot } from 'mev-helper';
const mevBot = new MEVBot();
const operatorAddress = '0x...';
const isApproved = await mevBot.isApprovedOperator(operatorAddress);
console.log(`Operator ${operatorAddress} is ${isApproved ? 'approved' : 'not approved'}`);Types
Network
enum Network {
MAINNET = 'mainnet',
SEPOLIA = 'sepolia'
}NFTStandard
enum NFTStandard {
ERC721 = 0,
ERC1155 = 1,
UNKNOWN = 2
}BatchCallResult
interface BatchCallResult {
results: string[];
successes: boolean[];
}ContractCalledEvent
interface ContractCalledEvent {
targetContract: string;
functionSelector: string;
success: boolean;
result: string;
timestamp: bigint;
}Development
Build
npm run buildProject Structure
mev-helper/
├── src/
│ ├── index.ts # Main SDK class
│ └── types.ts # TypeScript type definitions
├── abi.json # Contract ABI
├── package.json
├── tsconfig.json
└── README.mdLicense
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
