DEV Community

Edgaras
Edgaras

Posted on

Ethereum Integration in PHP for Wallets and Transfers

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
Enter fullscreen mode Exit fullscreen mode

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";
Enter fullscreen mode Exit fullscreen mode

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";
Enter fullscreen mode Exit fullscreen mode

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";
Enter fullscreen mode Exit fullscreen mode

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']
    );
}
Enter fullscreen mode Exit fullscreen mode

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";
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)