kornrunner/ethereum-address
Generate Ethereum addresses in PHP: create a new address with private/public keys or derive one from an existing private key. Lightweight library with simple API (get address, private key, public key) for Ethereum-compatible wallets and tooling.
Installation:
composer require kornrunner/ethereum-address
Add to composer.json under require if not using Composer directly.
First Use Case: Generate a new Ethereum address and private key in a Laravel controller or service:
use kornrunner\Ethereum\Address;
$address = new Address();
$ethAddress = $address->get(); // e.g., "0x4e1c45599f667b4dc3604d69e43722d4ace6b770"
$privateKey = $address->getPrivateKey(); // Store securely!
Validation: Validate an existing address in a request handler:
$validator = Validator::make($request->all(), [
'address' => ['required', function ($attribute, $value, $fail) {
$address = new Address($value);
if (!$address->isValid()) {
$fail('Invalid Ethereum address.');
}
}]
]);
kornrunner\Ethereum\Address for methods like get(), getPrivateKey(), getPublicKey(), and isValid().tests/ for edge cases (e.g., invalid inputs, key formats).Address Generation: Use in Laravel migrations or seeders to pre-generate wallet addresses for testing:
// In DatabaseSeeder.php
$address = new Address();
DB::table('wallets')->insert([
'address' => $address->get(),
'private_key' => $address->getPrivateKey(), // Encrypt this!
'created_at' => now(),
]);
Request Validation: Validate incoming Ethereum addresses in API routes:
Route::post('/deposit', function (Request $request) {
$address = new Address($request->address);
if (!$address->isValid()) {
return response()->json(['error' => 'Invalid address'], 400);
}
// Proceed with deposit logic...
});
Key Management:
Store private keys securely (e.g., encrypted in Laravel's config/filesystems.php):
// Encrypt private key before storage
$encryptedKey = Crypt::encrypt($address->getPrivateKey());
DB::table('wallets')->insert(['private_key' => $encryptedKey]);
Integration with Web3:
Combine with web3.php or web3p for transactions:
use Web3\Web3;
$web3 = new Web3('https://mainnet.infura.io/v3/YOUR_KEY');
$tx = $web3->eth->sendTransaction([
'from' => $address->get(),
'to' => '0xRecipientAddress',
'value' => '0x1000000000000000000', // 0.1 ETH
'gas' => 21000,
]);
Service Providers:
Bind the Address class for dependency injection:
// In AppServiceProvider
$this->app->bind(Address::class, function () {
return new Address();
});
Use in controllers:
public function __construct(private Address $address) {}
Commands: Generate addresses via Artisan:
// In app/Console/Commands/GenerateWallet.php
public function handle() {
$address = new Address();
$this->info("Address: {$address->get()}");
$this->info("Private Key: {$address->getPrivateKey()}");
}
Events/Listeners: Trigger events when addresses are generated (e.g., log to a queue):
event(new WalletGenerated($address->get(), $address->getPrivateKey()));
Private Key Exposure:
Crypt::encrypt()) and never commit plaintext keys to version control.Address Format:
0x4e1c...). Etherscan and some APIs expect mixed case (e.g., 0x4E1C...).$address->get()->toUpperCase();
Validation Edge Cases:
isValid() may return true for checksum addresses (e.g., 0x9c7b7a00972121fb843af7af74526d7eb585b171) but the package doesn’t enforce checksum validation by default.Web3\Utils::toChecksumAddress() if checksum validation is required.Thread Safety:
$address = new Address();
$uniqueAddress = $address->get() . '-' . Str::uuid();
Invalid Addresses:
If isValid() returns false, check:
0x prefix).0-9, a-f).filter_var($address, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^0x[a-fA-F0-9]{40}$/']]) for quick validation.Private Key Issues:
Custom Key Derivation: Extend the class to support BIP-32/44 hierarchies:
class HierarchicalAddress extends Address {
public function derivePath(string $path): self {
// Implement HD wallet logic
return $this;
}
}
Address Metadata: Add methods to store metadata (e.g., tags, balances) alongside addresses:
class TaggedAddress extends Address {
private $tags = [];
public function addTag(string $tag): void {
$this->tags[] = $tag;
}
public function getTags(): array {
return $this->tags;
}
}
Batch Generation: Create a helper for bulk address generation (e.g., for airdrops):
function generateAddresses(int $count): array {
return collect(range(1, $count))->map(fn() => new Address())->pluck('get')->all();
}
config/ethereum-address.php. All logic is self-contained in the Address class..env:
ENCRYPTION_KEY=your_app_key_here
Caching: Cache generated addresses if they’re static (e.g., for testing):
$address = Cache::remember('test-wallet-address', now()->addDays(7), function () {
return (new Address())->get();
});
Lazy Loading: Avoid generating keys until needed (e.g., defer private key retrieval until required):
$address = new Address();
$publicKey = $address->getPublicKey(); // Cheap operation
$privateKey = $address->getPrivateKey(); // Expensive; call only when needed
How can I help you explore Laravel packages today?