Skip to content

Commit 542f44c

Browse files
committed
wip: add core functions
1 parent e40cb3f commit 542f44c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1242
-551
lines changed

.github/FUNDING.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
github: :vendor_name
1+
github: farbcode

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
blank_issues_enabled: false
22
contact_links:
33
- name: Ask a question
4-
url: https://github.com/:vendor_slug/:package_name/discussions/new?category=q-a
4+
url: https://github.com/farbcodegmbh/laravel-evm/discussions/new?category=q-a
55
about: Ask the community for help
66
- name: Request a feature
7-
url: https://github.com/:vendor_slug/:package_name/discussions/new?category=ideas
7+
url: https://github.com/farbcodegmbh/laravel-evm/discussions/new?category=ideas
88
about: Share ideas for new features
99
- name: Report a security issue
10-
url: https://github.com/:vendor_slug/:package_name/security/policy
10+
url: https://github.com/farbcodegmbh/laravel-evm/security/policy
1111
about: Learn how to notify us for sensitive bugs

.github/copilot-instructions.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Laravel EVM Package - AI Coding Instructions
2+
3+
## Architecture Overview
4+
5+
This is a Laravel package for Ethereum Virtual Machine (EVM) blockchain interactions with server-side focus. The package provides a clean abstraction layer for:
6+
- **Smart contract interaction** (read/write operations)
7+
- **Asynchronous transaction handling** via Laravel queues
8+
- **EIP-1559 transaction signing** with gas fee management
9+
- **Multi-RPC failover** with round-robin load balancing
10+
- **Nonce management** to prevent transaction conflicts
11+
12+
## Core Components
13+
14+
### 1. Service Container Bindings (`LaravelEvmServiceProvider`)
15+
The package uses Laravel's service container with singleton bindings for all major components:
16+
- `RpcClient``RpcHttpClient` (handles multiple RPC URLs)
17+
- `ContractClient``ContractClientGeneric` (main API interface)
18+
- `Signer``PrivateKeySigner` (transaction signing)
19+
- `NonceManager``LocalNonceManager` (prevents nonce conflicts)
20+
- `FeePolicy``SimpleFeePolicy` (EIP-1559 gas pricing)
21+
22+
### 2. Contract Interaction Pattern
23+
```php
24+
// Read operations (synchronous)
25+
$contract = Evm::at('0xAddress', $abiJson);
26+
$result = $contract->call('functionName', $args);
27+
28+
// Write operations (asynchronous via queue)
29+
$jobId = $contract->sendAsync('functionName', $args);
30+
```
31+
32+
### 3. Transaction Lifecycle
33+
Write operations use `SendTransaction` job that handles:
34+
1. Gas estimation with configurable padding
35+
2. Nonce retrieval/management
36+
3. EIP-1559 fee calculation
37+
4. Transaction signing and broadcast
38+
5. Receipt polling with timeout
39+
6. Gas price replacement attempts if stuck
40+
7. Event emission at each stage (`TxQueued`, `TxBroadcasted`, `TxMined`, `TxFailed`)
41+
42+
## Key Development Patterns
43+
44+
### Configuration-Driven Behavior
45+
All critical parameters are configurable via `config/evm.php`:
46+
- Multiple RPC endpoints (`EVM_RPC_1`, `EVM_RPC_2`, etc.)
47+
- Gas estimation padding (`estimate_padding: 1.2`)
48+
- Transaction timeouts and retry limits
49+
- Queue configuration for transaction jobs
50+
51+
### Contract Interface Implementation
52+
Follow the `ContractClient` interface pattern when extending functionality:
53+
- `at()` - sets contract address/ABI
54+
- `call()` - synchronous reads
55+
- `sendAsync()` - asynchronous writes returning job ID
56+
- `wait()` - blocks until transaction receipt
57+
58+
### Error Handling Strategy
59+
The package uses custom exceptions in `src/Exceptions/`:
60+
- `RpcException` for network/RPC issues
61+
- `GasException` for gas estimation problems
62+
- `SignerException` for signing failures
63+
- Events for transaction state tracking rather than exceptions
64+
65+
## Development Workflows
66+
67+
### Testing
68+
```bash
69+
composer test # Run Pest test suite
70+
composer analyse # PHPStan static analysis
71+
composer format # Laravel Pint code formatting
72+
```
73+
74+
### Adding New RPC Methods
75+
1. Extend `RpcClient` interface if needed
76+
2. Implement in `RpcHttpClient` with failover logic
77+
3. Add integration tests
78+
79+
### Extending Signer Support
80+
1. Implement `Signer` contract
81+
2. Add driver configuration in `LaravelEvmServiceProvider`
82+
3. Ensure `privateKey()` method availability for transaction signing
83+
84+
### Command Usage Examples
85+
```bash
86+
php artisan evm:call 0xAddress ./abi.json functionName arg1 arg2
87+
php artisan evm:send 0xAddress ./abi.json functionName arg1 arg2
88+
php artisan evm:wait 0xTransactionHash
89+
php artisan evm:health
90+
```
91+
92+
## Critical Dependencies
93+
94+
- **web3p/web3.php**: ABI encoding/decoding
95+
- **web3p/ethereum-tx**: EIP-1559 transaction creation and signing
96+
- **spatie/laravel-package-tools**: Laravel package scaffolding
97+
98+
## Environment Requirements
99+
100+
- **Queue system required**: Redis recommended for `QUEUE_CONNECTION`
101+
- **Private key management**: Store `EVM_PRIVATE_KEY` securely
102+
- **RPC reliability**: Configure multiple `EVM_RPC_*` endpoints for redundancy
103+
- **Chain ID**: Must match target network (`EVM_CHAIN_ID`)
104+
105+
## Transaction Queue Considerations
106+
107+
- Keep queue concurrency at 1 per signing address to prevent nonce conflicts
108+
- Use dedicated queue (`evm-send`) to isolate blockchain operations
109+
- Monitor transaction events for debugging and logging
110+
- Failed transactions emit `TxFailed` events rather than throwing exceptions

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# Changelog
22

3-
All notable changes to `:package_name` will be documented in this file.
3+
All notable changes to `laravel-evm` will be documented in this file.

LICENSE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) :vendor_name <author@domain.com>
3+
Copyright (c) farbcode GmbH <hello@farbcode.net>
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 24 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,47 @@
1-
# :package_description
1+
# This is my package laravel-evm
22

3-
[![Latest Version on Packagist](https://img.shields.io/packagist/v/:vendor_slug/:package_slug.svg?style=flat-square)](https://packagist.org/packages/:vendor_slug/:package_slug)
4-
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/:vendor_slug/:package_slug/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3Arun-tests+branch%3Amain)
5-
[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/:vendor_slug/:package_slug/fix-php-code-style-issues.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
6-
[![Total Downloads](https://img.shields.io/packagist/dt/:vendor_slug/:package_slug.svg?style=flat-square)](https://packagist.org/packages/:vendor_slug/:package_slug)
7-
<!--delete-->
8-
---
9-
This repo can be used to scaffold a Laravel package. Follow these steps to get started:
3+
[![Latest Version on Packagist](https://img.shields.io/packagist/v/farbcodegmbh/laravel-evm.svg?style=flat-square)](https://packagist.org/packages/farbcodegmbh/laravel-evm)
4+
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/farbcodegmbh/laravel-evm/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/farbcodegmbh/laravel-evm/actions?query=workflow%3Arun-tests+branch%3Amain)
5+
[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/farbcodegmbh/laravel-evm/fix-php-code-style-issues.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/farbcodegmbh/laravel-evm/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
6+
[![Total Downloads](https://img.shields.io/packagist/dt/farbcodegmbh/laravel-evm.svg?style=flat-square)](https://packagist.org/packages/farbcodegmbh/laravel-evm)
107

11-
1. Press the "Use this template" button at the top of this repo to create a new repo with the contents of this skeleton.
12-
2. Run "php ./configure.php" to run a script that will replace all placeholders throughout all the files.
13-
3. Have fun creating your package.
14-
4. If you need help creating a package, consider picking up our <a href="https://laravelpackage.training">Laravel Package Training</a> video course.
15-
---
16-
<!--/delete-->
17-
This is where your description should go. Limit it to a paragraph or two. Consider adding a small example.
18-
19-
## Support us
20-
21-
[<img src="https://github-ads.s3.eu-central-1.amazonaws.com/:package_name.jpg?t=1" width="419px" />](https://spatie.be/github-ad-click/:package_name)
22-
23-
We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).
24-
25-
We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).
8+
A Laravel native EVM client for server side use
9+
RPC via Http facade ABI encoding EIP 1559 signing nonces jobs events
2610

2711
## Installation
2812

2913
You can install the package via composer:
3014

3115
```bash
32-
composer require :vendor_slug/:package_slug
16+
composer require farbcode/laravel-evm
3317
```
3418

35-
You can publish and run the migrations with:
19+
You can publish the config file with:
3620

3721
```bash
38-
php artisan vendor:publish --tag=":package_slug-migrations"
39-
php artisan migrate
22+
php artisan vendor:publish --tag="laravel-evm-config"
4023
```
4124

42-
You can publish the config file with:
4325

44-
```bash
45-
php artisan vendor:publish --tag=":package_slug-config"
46-
```
26+
## env
27+
EVM_CHAIN_ID=137
28+
EVM_RPC_1=https://polygon-mainnet.g.alchemy.com/v2/KEY
29+
EVM_PRIVATE_KEY=0xabc123...64hex
30+
QUEUE_CONNECTION=redis
4731

48-
This is the contents of the published config file:
32+
## Usage
4933

5034
```php
51-
return [
52-
];
53-
```
35+
use LaravelEvm; // Facade alias defined in composer.json
5436

55-
Optionally, you can publish the views using
37+
$abi = file_get_contents(storage_path('app/abi/IntegrityAnchorSimple.abi.json'));
38+
$contract = LaravelEvm::at('0xYourContract', $abi);
5639

57-
```bash
58-
php artisan vendor:publish --tag=":package_slug-views"
59-
```
40+
// read
41+
$res = $contract->call('isAnchored', [1, '0x'.$hashHex]);
6042

61-
## Usage
62-
63-
```php
64-
$variable = new VendorName\Skeleton();
65-
echo $variable->echoPhrase('Hello, VendorName!');
43+
// write non blocking
44+
$jobId = $contract->sendAsync('anchor', [1, '0x'.$hashHex, 'meta']);
6645
```
6746

6847
## Testing
@@ -85,7 +64,7 @@ Please review [our security policy](../../security/policy) on how to report secu
8564

8665
## Credits
8766

88-
- [:author_name](https://github.com/:author_username)
67+
- [Martin Weinschenk](https://github.com/mweinschenk)
8968
- [All Contributors](../../contributors)
9069

9170
## License

composer.json

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
{
2-
"name": ":vendor_slug/:package_slug",
3-
"description": ":package_description",
2+
"name": "farbcodegmbh/laravel-evm",
3+
"description": "This is my package laravel-evm",
44
"keywords": [
5-
":vendor_name",
5+
"farbcode",
66
"laravel",
7-
":package_slug"
7+
"laravel-evm"
88
],
9-
"homepage": "https://github.com/:vendor_slug/:package_slug",
9+
"homepage": "https://github.com/farbcodegmbh/laravel-evm",
1010
"license": "MIT",
1111
"authors": [
1212
{
13-
"name": ":author_name",
14-
"email": "author@domain.com",
13+
"name": "Martin Weinschenk",
14+
"email": "martin.weinschenk@farbcode.net",
1515
"role": "Developer"
1616
}
1717
],
1818
"require": {
1919
"php": "^8.4",
20+
"illuminate/contracts": "^11.0||^12.0",
21+
"kornrunner/ethereum-address": "^0.3.0",
22+
"kornrunner/keccak": "^1.1",
2023
"spatie/laravel-package-tools": "^1.16",
21-
"illuminate/contracts": "^11.0||^12.0"
24+
"web3p/ethereum-tx": "^0.4.3",
25+
"web3p/web3.php": "^0.1.6"
2226
},
2327
"require-dev": {
2428
"laravel/pint": "^1.14",
@@ -30,18 +34,16 @@
3034
"pestphp/pest-plugin-laravel": "^4.0",
3135
"phpstan/extension-installer": "^1.4",
3236
"phpstan/phpstan-deprecation-rules": "^2.0",
33-
"phpstan/phpstan-phpunit": "^2.0",
34-
"spatie/laravel-ray": "^1.35"
37+
"phpstan/phpstan-phpunit": "^2.0"
3538
},
3639
"autoload": {
3740
"psr-4": {
38-
"VendorName\\Skeleton\\": "src/",
39-
"VendorName\\Skeleton\\Database\\Factories\\": "database/factories/"
41+
"Farbcode\\LaravelEvm\\": "src/"
4042
}
4143
},
4244
"autoload-dev": {
4345
"psr-4": {
44-
"VendorName\\Skeleton\\Tests\\": "tests/",
46+
"Farbcode\\LaravelEvm\\Tests\\": "tests/",
4547
"Workbench\\App\\": "workbench/app/"
4648
}
4749
},
@@ -63,10 +65,10 @@
6365
"extra": {
6466
"laravel": {
6567
"providers": [
66-
"VendorName\\Skeleton\\SkeletonServiceProvider"
68+
"Farbcode\\LaravelEvm\\LaravelEvmServiceProvider"
6769
],
6870
"aliases": {
69-
"Skeleton": "VendorName\\Skeleton\\Facades\\Skeleton"
71+
"LaravelEvm": "Farbcode\\LaravelEvm\\Facades\\LaravelEvm"
7072
}
7173
}
7274
},

config/evm.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
// config for Farbcode/LaravelEvm
4+
return [
5+
'chain_id' => env('EVM_CHAIN_ID', 137),
6+
7+
// Multiple RPC urls supported. Client uses round robin with fallback.
8+
'rpc_urls' => array_values(array_filter([
9+
env('EVM_RPC_1'),
10+
env('EVM_RPC_2'),
11+
env('EVM_RPC_3'),
12+
])),
13+
14+
// Signer configuration.
15+
'signer' => [
16+
'driver' => env('EVM_SIGNER', 'private_key'),
17+
'private_key' => env('EVM_PRIVATE_KEY'),
18+
// 'kms_key' => env('EVM_KMS_KEY_ARN'),
19+
],
20+
21+
// Fee policy for EIP 1559.
22+
'fees' => [
23+
'min_priority_gwei' => env('EVM_MIN_PRIORITY_GWEI', 3),
24+
'min_maxfee_gwei' => env('EVM_MIN_MAXFEE_GWEI', 40),
25+
'base_multiplier' => env('EVM_BASE_MULTIPLIER', 3),
26+
'replacement_factor'=> env('EVM_REPLACEMENT_FACTOR', 1.5),
27+
],
28+
29+
// Transaction behavior.
30+
'tx' => [
31+
'estimate_padding' => env('EVM_ESTIMATE_PADDING', 1.2),
32+
'confirm_timeout' => env('EVM_CONFIRM_TIMEOUT', 120), // seconds
33+
'max_replacements' => env('EVM_MAX_REPLACEMENTS', 2),
34+
'poll_interval_ms' => env('EVM_POLL_INTERVAL_MS', 800),
35+
36+
// Queue used for sending jobs. Keep concurrency at one per writer address.
37+
'queue' => env('EVM_QUEUE', 'evm-send'),
38+
],
39+
];

config/skeleton.php

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)