SDK for interacting with MEVBot smart contract on Ethereum mainnet
npm install mev-helperbash
npm install mev-helper
`
Contract 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:
1. Using contractAddresses (recommended for multiple networks):
`typescript
import { MEVBot, Network, ContractAddresses } from 'mev-helper';
const contractAddresses: ContractAddresses = {
[Network.MAINNET]: '0x779B21Cf23E037Ab847831A45A6d71B2e97b6328',
[Network.SEPOLIA]: '0x922E4879B5C4289AF607E563126Db3BeBA52214A'
};
const mevBot = new MEVBot({
network: Network.MAINNET,
contractAddresses
});
`
2. Using contractAddress (for a single address):
`typescript
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:
`typescript
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
$3
`typescript
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());
`
$3
`typescript
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
$3
`typescript
new MEVBot(config?: MEVBotConfig)
`
Parameters:
- config.network (optional): Network to use (Network.MAINNET or Network.SEPOLIA). Defaults to Network.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:
`typescript
// 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
});
`
$3
#### getMaxBatchSize(): Promise
Get the maximum batch size for batch operations.
#### getOwner(): Promise
Get the contract owner address.
#### getBalance(): Promise
Get the contract's ETH balance in wei.
#### isApprovedOperator(operator: string): Promise
Check if an address is an approved operator.
#### detectNFTStandard(nftContract: string): Promise
Detect the NFT standard (ERC721, ERC1155, or UNKNOWN) of a contract.
#### supportsInterface(interfaceId: string): Promise
Check if the contract supports a specific interface.
$3
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 address
- data: Encoded function call data
#### callContractWithValue(target: string, data: string, value: bigint)
Call a contract function with ETH value.
Parameters:
- target: Target contract address
- data: Encoded function call data
- value: Amount of ETH to send (in wei)
#### batchCallContracts(options: BatchCallOptions)
Batch call multiple contracts in a single transaction.
Parameters:
`typescript
{
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:
`typescript
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 address
- tokenId: Token ID to rescue
- recipient: Address to send the NFT to
#### withdrawETH(recipient: string, amount: bigint)
Withdraw ETH from the contract.
Parameters:
- recipient: Address to send ETH to
- amount: Amount to withdraw (in wei)
#### withdrawERC20(tokenContract: string, recipient: string, amount: bigint)
Withdraw ERC20 tokens from the contract.
Parameters:
- tokenContract: ERC20 token contract address
- recipient: Address to send tokens to
- amount: Amount to withdraw
#### transferOwnership(newOwner: string)
Transfer contract ownership to a new address.
#### renounceOwnership()
Renounce contract ownership.
$3
#### onContractCalled(callback: (event: ContractCalledEvent) => void)
Listen to ContractCalled events.
Example:
`typescript
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
$3
`typescript
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);
`
$3
`typescript
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);
`
$3
`typescript
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
});
});
`
$3
`typescript
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
$3
`typescript
enum Network {
MAINNET = 'mainnet',
SEPOLIA = 'sepolia'
}
`
$3
`typescript
enum NFTStandard {
ERC721 = 0,
ERC1155 = 1,
UNKNOWN = 2
}
`
$3
`typescript
interface BatchCallResult {
results: string[];
successes: boolean[];
}
`
$3
`typescript
interface ContractCalledEvent {
targetContract: string;
functionSelector: string;
success: boolean;
result: string;
timestamp: bigint;
}
`
Development
$3
`bash
npm run build
`
$3
`
mev-helper/
├── src/
│ ├── index.ts # Main SDK class
│ └── types.ts # TypeScript type definitions
├── abi.json # Contract ABI
├── package.json
├── tsconfig.json
└── README.md
``