If you build backends in PHP and want to talk to Ethereum without pulling in a full Node stack, this library gives you a clean methods for the main functionality: wallet management, ETH transfers (legacy and EIP‑1559), balances, transaction queries, and utilities.
GitHub: Edgaras0x4E/Ethereum
What you can do
- Wallets: Create/import wallets, derive address/public key
- Transfers: Send ETH using legacy (Type‑0) and EIP‑1559 (Type‑2) transactions; wait for confirmations
-
Balances & network:
getBalance
,getBalanceInEther
,getBlockNumber
,getNetworkInfo
-
Transactions:
getTransaction
,getTransactionReceipt
,getTransactionStatus
,getTransactionDetails
-
Address activity: Scan recent blocks with
getTransactionsForAddress
-
Blocks: Fetch transactions with
getTransactionsByBlockNumber
- Utilities: Unit conversion, checksum addresses, hex helpers, hashing
Requirements
- PHP 8.3+
- Extensions:
gmp
,bcmath
- An Ethereum JSON‑RPC endpoint (Infura)
Install
composer require edgaras/ethereum
Quick start: create a wallet and read balance
<?php
use Edgaras\Ethereum\Ethereum;
use Edgaras\Ethereum\Wallet;
$rpcUrl = 'https://sepolia.infura.io/v3/YOUR_API_KEY';
$chainId = 11155111; // Sepolia
$eth = new Ethereum($rpcUrl, $chainId);
// Create a new wallet (or import with new Wallet('0xPRIVATE_KEY_HEX'))
$wallet = $eth->createWallet();
$eth->setWallet($wallet);
echo "Address: {$wallet->getAddress()}\n";
echo "Balance: {$eth->getBalanceInEther()} ETH\n";
Send ETH (legacy Type‑0)
use Edgaras\Ethereum\Ethereum;
use Edgaras\Ethereum\Wallet;
$eth = new Ethereum($rpcUrl, $chainId);
$eth->setWallet(new Wallet('0xYOUR_PRIVATE_KEY_HEX'));
$txHash = $eth->sendEther('0xRecipientAddress...', '0.01');
echo "tx: $txHash\n";
// Optional: wait for confirmation
$receipt = $eth->waitForConfirmation($txHash, maxAttempts: 60, delaySeconds: 2);
echo "included in block: {$receipt['blockNumber']}\n";
Send ETH with EIP‑1559 (Type‑2)
use Edgaras\Ethereum\Ethereum;
use Edgaras\Ethereum\Wallet;
use Edgaras\Ethereum\Utils;
$eth = new Ethereum($rpcUrl, $chainId);
$eth->setWallet(new Wallet('0xYOUR_PRIVATE_KEY_HEX'));
// Set EIP‑1559 gas parameters (in gwei)
$maxPriorityFeePerGasGwei = '2'; // 2 gwei tip
$maxFeePerGasGwei = '20'; // 20 gwei max fee
// Convert to wei hex
$maxPriorityFeePerGas = Utils::toHex(Utils::gweiToWei($maxPriorityFeePerGasGwei));
$maxFeePerGas = Utils::toHex(Utils::gweiToWei($maxFeePerGasGwei));
$txHash = $eth->sendEtherEIP1559(
'0xRecipientAddress...',
'0.01',
$maxFeePerGas,
$maxPriorityFeePerGas
);
echo "EIP‑1559 tx: $txHash\n";
Practical examples
Minimal wallet overview (balance + recent txs):
use Edgaras\Ethereum\Ethereum;
use Edgaras\Ethereum\Utils;
$eth = new Ethereum($rpcUrl, $chainId);
$address = '0xRecipientAddress...';
$balanceEth = $eth->getBalanceInEther($address);
echo "Address: " . Utils::toChecksumAddress($address) . "\n";
echo "Balance: $balanceEth ETH\n\n";
$txs = $eth->getTransactionsForAddress($address, maxBlocksToScan: 1500, maxTxToShow: 20);
foreach ($txs as $t) {
echo sprintf("[%s] %s | %s ETH | peer: %s | block: %d\n",
$t['direction'], $t['hash'], $t['valueEth'], $t['peer'], $t['blockNumber']
);
}
List transactions in a block:
use Edgaras\Ethereum\Ethereum;
$eth = new Ethereum($rpcUrl, $chainId);
$blockNumber = 9354804; // example
$txs = $eth->getTransactionsByBlockNumber($blockNumber, limit: 10);
foreach ($txs as $i => $tx) {
$idx = $i + 1;
echo "#$idx\n";
echo " hash: " . ($tx['hash'] ?? '') . "\n";
echo " from: " . ($tx['from'] ?? '') . "\n";
echo " to: " . ($tx['to'] ?? '') . "\n";
echo " value: " . ($tx['value'] ?? '0x0') . " (wei hex)\n\n";
}
Utilities you’ll actually use
use Edgaras\Ethereum\Utils;
// Unit conversion
$wei = Utils::etherToWei('1.5');
$eth = Utils::weiToEther('0x204fce5e3e250261100000000'); // hex or decimals
$gwei = Utils::weiToGwei('0x4a817c800');
// Address helpers
$isValid = Utils::isValidAddress('0x242d35Cc6634C0532925a3b8D4C9db96C4b4d8b6');
$checksum = Utils::toChecksumAddress('0x242d35cc6634c0532925a3b8d4c9db96c4b4d8b6');
// Hex helpers
$hex = Utils::toHex('255'); // 0xff
$dec = Utils::fromHex('0xff'); // 255
EIP‑1559 in practice (why it matters)
- Better fee predictability and reduced overpayment when the network is quiet
- Dynamic fee market: you set a max fee and a priority tip; the base fee adjusts
-
Typed transactions: EIP‑2718 with proper hashing (
0x02 || RLP(list)
) for sender recovery
Pick EIP‑1559 for modern fee markets; fall back to legacy for maximum compatibility.
Production tips
- Keep your private keys out of source control; inject via env/config vaults
- Monitor base fee and adjust
maxFeePerGas
/maxPriorityFeePerGas
dynamically - Wrap RPC errors and rate limits; the library exposes clear exceptions
- Use
waitForConfirmation
with sensible timeouts and backoff in worker jobs
Top comments (0)