farbcode/laravel-evm
Simple, reliable Ethereum integration for Laravel with EIP-1559 fees, queued async transactions, nonce tracking, and events for every step from queued to mined. Requires PHP 8.4+ and ext-gmp.
baseFee + priority fee, receipt polling, reorg/replacement races, and queue-safe broadcast. A PM can frame adoption as buying back roughly 2–6 engineer-weeks and, more importantly, buying back the class of bugs that are silently wrong rather than loudly broken.call(), EvmLogs querying and ABI event decoding → balances, token holdings, transfer history, reconciliation) and a write track (sendAsync() → transfers, mints, approvals). The read track is low-risk and can ship first; the write track is where custody, treasury, and compliance decisions land. That split is a useful milestone boundary and a natural go/no-go gate.Transfer logs. Anything requiring sub-second finality, high transaction volume, or fiat on-ramp is out of its scope and belongs to a provider decision, not this package.EVM_PRIVATE_KEY in .env is a hot wallet in your application's secret store. The Signer contract (v0.4.0 moved signing behind it, and PrivateKeySigner no longer exposes the key) means "we can swap in a KMS/HSM signer later without rewriting the transaction path" is a legitimate architectural option — a real decision point for whether this is acceptable for your value at risk.EVM_QUEUE forces an explicit choice: which queue, which worker pool, what timeout, what dead-letter path. The v0.4.0 addition of a per-signing-address cache lock (one in-flight transaction per address) sets a throughput ceiling you should size against your roadmap now rather than discover at launch.EVM_CHAIN_ID + per-chain RPC config makes "Ethereum mainnet, Polygon, an L2" a configuration exercise, not a rewrite. Chains without EIP-1559 semantics are a different conversation, and non-EVM chains are explicitly out of scope.Consider it when most of these are true:
ext-gmp (plus bcmath for arithmetic — v0.4.0 returns all integers as decimal strings, so any balance math needs bcmath/GMP).TxQueued → TxBroadcasted → TxMined → TxFailed/TxReverted) maps onto existing listeners and logging rather than requiring new infrastructure.Signer backed by KMS/HSM before going live with meaningful amounts.Look elsewhere when any of these are true:
EvmLogs::chunked()..env private keys as an acceptable end state for treasury.ext-gmp. The requirement is hard.If you adopt: pin the exact version, treat composer.lock as load-bearing, read UPGRADING.md before every minor bump, and budget for the real possibility of owning a fork — the codebase is small enough that forking is a viable mitigation, which is itself part of the argument.
To executives — one paragraph: "We can ship on-chain functionality — token payments, balances, transfer reconciliation, minting — as a normal Laravel feature instead of a blockchain project. This MIT-licensed package supplies the parts that are expensive and easy to get wrong: transaction queuing on our existing workers, fee calculation, nonce management, and step-by-step events we can log and alert on. It is a library, not a service: no per-transaction fees, no vendor account, no data leaving our infrastructure beyond the RPC provider we choose. The trade-off is maturity — it has a small user base and is pre-1.0 — so we pin the version and keep the integration thin enough to replace or fork. Recommended as a scoped pilot on a read-first, low-value write path, not as the foundation of a treasury system."
To engineering — the honest version:
baseFee and priority fee; automatic nonce tracking with an invalidation path; queue-safe async broadcast with timeout, retry guard, and multi-hash polling across fee bumps; typed RPC errors (RpcErrorException::isRevert() vs. RpcTransportException); ABI encode/decode including log topic filtering and event decoding; Receipt::isSuccessful() so a mined-but-reverted transaction is never credited; optional evm_transactions tracking table; a Signer contract so KMS/HSM is a swap, not a rewrite.ext-gmp and PHP 8.4; integers come back as decimal strings, so all amounts go through bcmath/GMP — no int casts, ever; a queue worker dedicated to EVM_QUEUE with correct $timeout; one transaction at a time per signing address, enforced by a cache lock; you own RPC provider selection, key storage, and alerting.prefer-lowest and prefer-stable. The defects it fixed — amounts clamped above PHP_INT_MAX, reverted transactions reported as mined, provider API keys written to laravel.log, ltrim($x, '0x') corrupting roughly 1 in 16 inputs — are exactly the failure modes you would hit building this yourself, and they are now covered by tests.UPGRADING.md on every bump; start with read-only (call(), EvmLogs) to validate the ABI and provider path; ship the first write path with a value cap and an explicit Signer interface; add a reconciliation job that compares evm_transactions against chain state before trusting any ledger entry.How can I help you explore Laravel packages today?