EVM Compatibility
RP1 provides full Ethereum Virtual Machine compatibility through Ethermint integration.
Overview
| Feature | Support |
|---|---|
| Solidity | 0.8.x |
| EVM Version | Shanghai |
| JSON-RPC | Full |
| Web3.js | ✅ |
| Ethers.js | ✅ |
| MetaMask | ✅ |
Network Configuration
Mainnet
| Parameter | Value |
|---|---|
| Network Name | RP1 Mainnet |
| RPC URL | https://evm.rp.one |
| Chain ID | 1111 |
| Currency Symbol | RP1 |
| Block Explorer | https://explorer.rp.one |
Testnet
| Parameter | Value |
|---|---|
| Network Name | RP1 Testnet |
| RPC URL | https://evm.testnet.rp.one |
| Chain ID | 1112 |
| Currency Symbol | RP1 |
| Block Explorer | https://testnet.explorer.rp.one |
MetaMask Setup
- Open MetaMask
- Click "Add Network"
- Enter network details above
- Import your account
Or use:
await window.ethereum.request({
method: 'wallet_addEthereumChain',
params: [{
chainId: '0x457', // 1111 in hex
chainName: 'RP1 Mainnet',
rpcUrls: ['https://evm.rp.one'],
nativeCurrency: {
name: 'RP1',
symbol: 'RP1',
decimals: 18,
},
blockExplorerUrls: ['https://explorer.rp.one'],
}],
});
JSON-RPC Methods
Standard Ethereum Methods
import { ethers } from 'ethers';
const provider = new ethers.JsonRpcProvider('https://evm.rp.one');
// Get balance
const balance = await provider.getBalance('0x...');
// Get block
const block = await provider.getBlock('latest');
// Send transaction
const tx = await wallet.sendTransaction({
to: '0x...',
value: ethers.parseEther('1.0'),
});
// Call contract
const result = await contract.someMethod();
Supported Methods
| Method | Status |
|---|---|
| eth_chainId | ✅ |
| eth_blockNumber | ✅ |
| eth_getBalance | ✅ |
| eth_getCode | ✅ |
| eth_call | ✅ |
| eth_sendTransaction | ✅ |
| eth_sendRawTransaction | ✅ |
| eth_getTransactionReceipt | ✅ |
| eth_getLogs | ✅ |
| eth_subscribe | ✅ |
| eth_getBlockByNumber | ✅ |
| eth_getBlockByHash | ✅ |
| eth_estimateGas | ✅ |
| eth_gasPrice | ✅ |
| debug_traceTransaction | ✅ |
RP1-Specific Methods
// Get RP1 privacy status
const privacy = await provider.send('rp1_getPrivacyStatus', [address]);
// Get oracle price
const price = await provider.send('rp1_getOraclePrice', ['BTC']);
Contract Development
Hardhat Configuration
// hardhat.config.js
require('@nomiclabs/hardhat-ethers');
require('@nomiclabs/hardhat-waffle');
module.exports = {
solidity: {
version: '0.8.19',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
networks: {
rp1: {
url: 'https://evm.rp.one',
chainId: 1111,
accounts: [process.env.PRIVATE_KEY],
gasPrice: 'auto',
},
rp1Testnet: {
url: 'https://evm.testnet.rp.one',
chainId: 1112,
accounts: [process.env.PRIVATE_KEY],
},
},
};
Foundry Configuration
# foundry.toml
[profile.default]
src = 'src'
out = 'out'
libs = ['lib']
solc_version = '0.8.19'
[rpc_endpoints]
rp1 = "https://evm.rp.one"
rp1_testnet = "https://evm.testnet.rp.one"
[etherscan]
rp1 = { key = "${RP1_EXPLORER_KEY}", url = "https://explorer.rp.one/api" }
Precompiled Contracts
RP1 includes special precompiled contracts:
| Address | Contract | Purpose |
|---|---|---|
| 0x0...100 | Oracle | Get price feeds |
| 0x0...101 | Privacy | Shield/unshield |
| 0x0...102 | Lending | Borrow/supply |
| 0x0...103 | Staking | Delegate/undelegate |
Using Precompiles
interface IRP1Oracle {
function getPrice(string memory symbol) external view returns (uint256);
function getTWAP(string memory symbol, uint256 period) external view returns (uint256);
}
contract MyDeFi {
IRP1Oracle constant oracle = IRP1Oracle(0x0000000000000000000000000000000000000100);
function getCollateralValue(uint256 amount) public view returns (uint256) {
uint256 price = oracle.getPrice("RP1");
return amount * price / 1e18;
}
}
Address Conversion
RP1 supports both Cosmos (bech32) and EVM (hex) addresses:
import { ethers } from 'ethers';
import { bech32 } from 'bech32';
// EVM to Cosmos
function evmToCosmos(evmAddress) {
const bytes = ethers.getBytes(evmAddress);
const words = bech32.toWords(bytes);
return bech32.encode('rp1', words);
}
// Cosmos to EVM
function cosmosToEvm(cosmosAddress) {
const { words } = bech32.decode(cosmosAddress);
const bytes = bech32.fromWords(words);
return ethers.hexlify(bytes);
}
// Example
const evmAddr = '0x1234567890123456789012345678901234567890';
const cosmosAddr = evmToCosmos(evmAddr);
// rp1qzgxqxzsv9s2zwx...
Gas Mechanics
| Operation | Gas Cost |
|---|---|
| Simple transfer | 21,000 |
| Contract deploy | Variable |
| Storage write | 20,000 |
| Storage read | 2,100 |
| Oracle call | 5,000 |
Gas Price Oracle
const gasPrice = await provider.getGasPrice();
// Returns gas price in wei
// For EIP-1559
const feeData = await provider.getFeeData();
console.log('Max Fee:', feeData.maxFeePerGas);
console.log('Priority Fee:', feeData.maxPriorityFeePerGas);
Events and Logs
// Subscribe to events
const filter = contract.filters.Transfer();
contract.on(filter, (from, to, amount) => {
console.log(`Transfer: ${from} -> ${to}: ${amount}`);
});
// Query historical logs
const logs = await provider.getLogs({
address: contractAddress,
fromBlock: 0,
toBlock: 'latest',
topics: [ethers.id('Transfer(address,address,uint256)')],
});
Differences from Ethereum
| Feature | Ethereum | RP1 |
|---|---|---|
| Block Time | 12s | 200ms |
| Finality | ~15 min | Instant |
| Gas Token | ETH | RP1 |
| Chain ID | 1 | 1111 |
| Consensus | PoS | CometBFT |