chore: update dependencies and add graph precompiles

- Update go.mod with proper dependencies for kzg4844
- Add graph precompiles for GraphQL and Oracle functionality
- Update corona contract with latest changes
This commit is contained in:
Zach Kelling
2025-12-31 01:25:08 +00:00
parent 085b6b03e3
commit a905cb5de7
13 changed files with 3688 additions and 130 deletions
+85 -125
View File
@@ -1,162 +1,122 @@
Lux Research License with Patent Reservation
Version 1.0, December 2025
Lux Ecosystem License
Version 1.2, December 2025
Copyright (c) 2020-2025 Lux Industries Inc.
All rights reserved.
PATENT PENDING TECHNOLOGY
Contact: oss@lux.network
TECHNOLOGY PORTFOLIO - PATENT APPLICATIONS PLANNED
Contact: licensing@lux.network
================================================================================
IMPORTANT NOTICE
================================================================================
This software contains patent-pending technology. Key innovations include but
are not limited to:
PRECOMPILE INNOVATIONS:
- Native EVM Precompiles with Optimized Gas Metering
- DEX Precompiles (Uniswap v4-Style Singleton Architecture)
- Sub-Microsecond Swap Execution via Hardware-Optimized Precompiles
- Flash Accounting with Native EVM Integration
- Hooks Registry Pattern for Extensible Precompile Behavior
- BN254/BLS12-381 ZK Precompiles with EIP-1108/2537 Compliance
- ML-DSA Post-Quantum Signature Verification Precompiles
- NVTrust GPU Attestation Precompiles for AI Mining
- Verkle Witness Verification Precompiles
Commercial use of any patented technology requires a separate license.
Contact oss@lux.network for commercial licensing inquiries.
================================================================================
LICENSE TERMS
TERMS AND CONDITIONS
================================================================================
1. DEFINITIONS
"Software" means the source code, object code, documentation, and any
related materials included in this repository.
"Lux Primary Network" means the official Lux blockchain with Network ID=1
and EVM Chain ID=96369.
"Authorized Network" means the Lux Primary Network, official testnets/devnets,
and any L1/L2/L3 chain descending from the Lux Primary Network.
"Descending Chain" means an L1/L2/L3 chain built on, anchored to, or deriving
security from the Lux Primary Network or its authorized testnets.
"Research Use" means non-commercial academic research, education, personal
study, or evaluation purposes.
"Commercial Use" means any use in connection with a product or service
offered for sale or fee, internal use by a for-profit entity, or any use
to generate revenue.
"Research Use" means use of the Software solely for non-commercial
academic research, education, personal study, or evaluation purposes.
2. GRANT OF LICENSE
"Commercial Use" means any use of the Software or any patent claims
covered by the Software in connection with a product or service offered
for sale or fee, or any internal use by a for-profit entity, or any use
to generate revenue directly or indirectly.
"Patent Claims" means any patent claims owned or controlled by Lux
Industries Inc. that cover any aspect of the Software's implementation
or any method, system, or process described therein.
"Lux Network" means the decentralized blockchain network operated using
software distributed by Lux Industries Inc.
2. GRANT OF RESEARCH LICENSE
Subject to the terms and conditions of this License, Lux Industries Inc.
hereby grants you a limited, non-exclusive, non-transferable, revocable,
Subject to these terms, Lux Industries Inc grants you a non-exclusive,
royalty-free license to:
(a) Use, copy, and modify the Software solely for Research Use;
(b) Create derivative works of the Software solely for Research Use;
(c) Publish academic papers and research findings based on the Software,
provided that proper attribution is given; and
(d) Contribute modifications back to the original repository.
(a) Use for Research Use without restriction;
(b) Operate on the Lux Primary Network (Network ID=1, EVM Chain ID=96369);
(c) Operate on official Lux testnets and devnets;
(d) Operate L1/L2/L3 chains descending from the Lux Primary Network;
(e) Build applications within the Lux ecosystem;
(f) Contribute improvements back to the original repositories.
3. RESTRICTIONS
You may NOT:
Without a commercial license from Lux Industries Inc, you may NOT:
(a) Fork the Lux Network or any Lux software;
(b) Create competing networks not descending from Lux Primary Network;
(c) Use for Commercial Use outside the Lux ecosystem;
(d) Sublicense or transfer rights outside the Lux ecosystem;
(e) Use to create competing blockchain networks, exchanges, custody
services, or cryptographic systems outside the Lux ecosystem.
(a) Use the Software or any Patent Claims for any Commercial Use without
first obtaining a commercial license from Lux Industries Inc.;
4. NO FORKS POLICY
(b) Use the Software to create or operate any blockchain network, consensus
system, or distributed ledger that competes with or is similar to the
Lux Network;
Lux Industries Inc maintains ZERO TOLERANCE for unauthorized forks.
Any fork or deployment on an unauthorized network constitutes:
(a) Breach of this license;
(b) Grounds for immediate legal action.
(c) Sublicense, sell, lease, or otherwise transfer rights in the
Software to any third party;
5. RIGHTS RESERVATION
(d) Remove or alter any copyright, patent, trademark, or attribution
notices contained in the Software;
All rights not explicitly granted are reserved by Lux Industries Inc.
We plan to apply for patent protection for the technology in this
repository. Any implementation outside the Lux ecosystem may require
a separate commercial license.
(e) Use the Software in any manner that infringes the Patent Claims
without authorization; or
6. DISCLAIMER OF WARRANTY
(f) File any patent applications covering technology substantially
derived from the Software.
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
4. PATENT RIGHTS RESERVATION
7. LIMITATION OF LIABILITY
ALL PATENT RIGHTS ARE EXPRESSLY RESERVED by Lux Industries Inc.
IN NO EVENT SHALL LUX INDUSTRIES INC BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE.
This License does NOT grant any license or rights under any Patent Claims.
The grant of a copyright license herein does NOT include any express or
implied patent license.
8. TERMINATION
Any use of the Software that would infringe Patent Claims requires a
separate patent license, which must be obtained in writing from:
This license terminates immediately upon any breach, including but not
limited to deployment on unauthorized networks or creation of forks.
Lux Industries Inc.
Email: oss@lux.network
Subject: Patent License Request
9. GOVERNING LAW
5. LUX NETWORK PRIMARY NETWORK EXCEPTION
This License shall be governed by the laws of the State of Delaware.
Notwithstanding the above restrictions, this License grants an automatic
license to use the Software and Patent Claims solely for the purpose of
operating a node on the Lux Network primary network (mainnet and testnet),
subject to the network's terms of service and validator requirements.
10. COMMERCIAL LICENSING
6. CONTRIBUTIONS
By submitting contributions to this repository, you agree to license
your contributions under the same terms as this License and assign all
patent rights in your contributions to Lux Industries Inc.
7. DISCLAIMER OF WARRANTY
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
8. LIMITATION OF LIABILITY
IN NO EVENT SHALL LUX INDUSTRIES INC. BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY KIND ARISING OUT
OF THE USE OF OR INABILITY TO USE THE SOFTWARE.
9. TERMINATION
This License and all rights granted hereunder will terminate immediately
upon any breach of this License by you.
10. GOVERNING LAW
This License shall be governed by the laws of the State of Delaware,
United States.
11. COMMERCIAL LICENSING
For commercial licensing inquiries, please contact:
Lux Industries Inc.
Email: oss@lux.network
For commercial use outside the Lux ecosystem:
Lux Industries Inc.
Email: licensing@lux.network
Subject: Commercial License Request
================================================================================
ATTRIBUTION
TL;DR
================================================================================
When using this Software for research purposes, please cite:
Lux Precompiles: Native EVM Extensions for High-Performance Blockchain
Copyright (c) 2020-2025 Lux Industries Inc.
https://lux.network
- Research/academic use = OK
- Lux Primary Network (Network ID=1, Chain ID=96369) = OK
- L1/L2/L3 chains descending from Lux Primary Network = OK
- Commercial products outside Lux ecosystem = Contact licensing@lux.network
- Forks = Absolutely not
================================================================================
END OF LICENSE TERMS
See LP-0012 for full licensing documentation:
https://github.com/luxfi/lps/blob/main/LPs/lp-0012-ecosystem-licensing.md
+2 -2
View File
@@ -11,8 +11,8 @@ import (
"math/big"
"github.com/luxfi/geth/common"
"github.com/luxfi/lattice/v6/ring"
"github.com/luxfi/lattice/v6/utils/structs"
"github.com/luxfi/lattice/v7/ring"
"github.com/luxfi/lattice/v7/utils/structs"
"github.com/luxfi/precompiles/contract"
"github.com/luxfi/corona/sign"
"github.com/luxfi/corona/threshold"
+1 -1
View File
@@ -12,7 +12,7 @@ import (
"testing"
"github.com/luxfi/geth/common"
"github.com/luxfi/lattice/v6/ring"
"github.com/luxfi/lattice/v7/ring"
"github.com/luxfi/corona/sign"
"github.com/luxfi/corona/threshold"
"github.com/stretchr/testify/require"
+96 -2
View File
@@ -2,13 +2,107 @@ module github.com/luxfi/precompiles
go 1.25.5
require github.com/stretchr/testify v1.11.1
require (
github.com/cloudflare/circl v1.6.2
github.com/crate-crypto/go-kzg-4844 v1.1.0
github.com/holiman/uint256 v1.3.2
github.com/luxfi/consensus v1.22.46
github.com/luxfi/crypto v1.17.28
github.com/luxfi/fhe v1.2.0
github.com/luxfi/geth v1.16.66
github.com/luxfi/lattice/v7 v7.0.0
github.com/luxfi/corona v0.2.0
github.com/luxfi/warp v1.18.2
github.com/stretchr/testify v1.11.1
)
require (
github.com/ALTree/bigfloat v0.2.0 // indirect
github.com/DataDog/zstd v1.5.7 // indirect
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251221085550-b8e13ca38217 // indirect
github.com/VictoriaMetrics/fastcache v1.13.2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.24.4 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cockroachdb/errors v1.12.0 // indirect
github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 // indirect
github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 // indirect
github.com/cockroachdb/pebble v1.1.5 // indirect
github.com/cockroachdb/redact v1.1.6 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20250429170803-42689b6311bb // indirect
github.com/consensys/gnark-crypto v0.19.2 // indirect
github.com/crate-crypto/go-eth-kzg v1.4.0 // indirect
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
github.com/dgraph-io/badger/v4 v4.9.0 // indirect
github.com/dgraph-io/ristretto/v2 v2.2.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/emicklei/dot v1.9.0 // indirect
github.com/ethereum/c-kzg-4844/v2 v2.1.5 // indirect
github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab // indirect
github.com/ethereum/go-verkle v0.2.2 // indirect
github.com/ferranbt/fastssz v1.0.0 // indirect
github.com/getsentry/sentry-go v0.35.1 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/gofrs/flock v0.13.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/google/flatbuffers v25.2.10+incompatible // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/luxfi/cache v1.1.0 // indirect
github.com/luxfi/database v1.2.17 // indirect
github.com/luxfi/ids v1.2.5 // indirect
github.com/luxfi/lattice/v6 v6.1.2 // indirect
github.com/luxfi/log v1.2.0 // indirect
github.com/luxfi/math v1.2.0 // indirect
github.com/luxfi/metric v1.4.8 // indirect
github.com/luxfi/p2p v1.18.2 // indirect
github.com/luxfi/sampler v1.0.0 // indirect
github.com/luxfi/utils v1.1.0 // indirect
github.com/luxfi/vm v1.0.1 // indirect
github.com/minio/sha256-simd v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.4 // indirect
github.com/prometheus/procfs v0.19.2 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/supranational/blst v0.3.16 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
github.com/tklauser/go-sysconf v0.3.15 // indirect
github.com/tklauser/numcpus v0.10.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
github.com/zeebo/blake3 v0.2.4 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.37.0 // indirect
go.opentelemetry.io/otel/metric v1.37.0 // indirect
go.opentelemetry.io/otel/trace v1.37.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.1 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
golang.org/x/crypto v0.46.0 // indirect
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.32.0 // indirect
gonum.org/v1/gonum v0.16.0 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
+333
View File
@@ -1,20 +1,353 @@
github.com/ALTree/bigfloat v0.2.0 h1:AwNzawrpFuw55/YDVlcPw0F0cmmXrmngBHhVrvdXPvM=
github.com/ALTree/bigfloat v0.2.0/go.mod h1:+NaH2gLeY6RPBPPQf4aRotPPStg+eXc8f9ZaE4vRfD4=
github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE=
github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251221085550-b8e13ca38217 h1:RNTau6sw5B3ltE+2GlzEom63eBMzoLUc+dhjmdIwNpI=
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251221085550-b8e13ca38217/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI=
github.com/VictoriaMetrics/fastcache v1.13.2 h1:2XTB49aLSuCex7e9P5rqrfQcMkzGjh5Vq3GMFa8YpCA=
github.com/VictoriaMetrics/fastcache v1.13.2/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bits-and-blooms/bitset v1.24.4 h1:95H15Og1clikBrKr/DuzMXkQzECs1M6hhoGXLwLQOZE=
github.com/bits-and-blooms/bitset v1.24.4/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/cloudflare/circl v1.6.2 h1:hL7VBpHHKzrV5WTfHCaBsgx/HGbBYlgrwvNXEVDYYsQ=
github.com/cloudflare/circl v1.6.2/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4=
github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
github.com/cockroachdb/errors v1.12.0 h1:d7oCs6vuIMUQRVbi6jWWWEJZahLCfJpnJSVobd1/sUo=
github.com/cockroachdb/errors v1.12.0/go.mod h1:SvzfYNNBshAVbZ8wzNc/UPK3w1vf0dKDUP41ucAIf7g=
github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 h1:pU88SPhIFid6/k0egdR5V6eALQYq2qbSmukrkgIh/0A=
github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M=
github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 h1:ASDL+UJcILMqgNeV5jiqR4j+sTuvQNHdf2chuKj1M5k=
github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506/go.mod h1:Mw7HqKr2kdtu6aYGn3tPmAftiP3QPX63LdK/zcariIo=
github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw=
github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo=
github.com/cockroachdb/redact v1.1.6 h1:zXJBwDZ84xJNlHl1rMyCojqyIxv+7YUpQiJLQ7n4314=
github.com/cockroachdb/redact v1.1.6/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
github.com/cockroachdb/tokenbucket v0.0.0-20250429170803-42689b6311bb h1:3bCgBvB8PbJVMX1ouCcSIxvsqKPYM7gs72o0zC76n9g=
github.com/cockroachdb/tokenbucket v0.0.0-20250429170803-42689b6311bb/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
github.com/consensys/gnark-crypto v0.19.2 h1:qrEAIXq3T4egxqiliFFoNrepkIWVEeIYwt3UL0fvS80=
github.com/consensys/gnark-crypto v0.19.2/go.mod h1:rT23F0XSZqE0mUA0+pRtnL56IbPxs6gp4CeRsBk4XS0=
github.com/crate-crypto/go-eth-kzg v1.4.0 h1:WzDGjHk4gFg6YzV0rJOAsTK4z3Qkz5jd4RE3DAvPFkg=
github.com/crate-crypto/go-eth-kzg v1.4.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI=
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg=
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM=
github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4=
github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8=
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
github.com/dgraph-io/badger/v4 v4.9.0 h1:tpqWb0NewSrCYqTvywbcXOhQdWcqephkVkbBmaaqHzc=
github.com/dgraph-io/badger/v4 v4.9.0/go.mod h1:5/MEx97uzdPUHR4KtkNt8asfI2T4JiEiQlV7kWUo8c0=
github.com/dgraph-io/ristretto/v2 v2.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM=
github.com/dgraph-io/ristretto/v2 v2.2.0/go.mod h1:RZrm63UmcBAaYWC1DotLYBmTvgkrs0+XhBd7Npn7/zI=
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38=
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/emicklei/dot v1.9.0 h1:FyaJNctdMfaEIbTQ1FkKZ1UCZyJJSkyvkrXOVoNZPKU=
github.com/emicklei/dot v1.9.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=
github.com/ethereum/c-kzg-4844/v2 v2.1.5 h1:aVtoLK5xwJ6c5RiqO8g8ptJ5KU+2Hdquf6G3aXiHh5s=
github.com/ethereum/c-kzg-4844/v2 v2.1.5/go.mod h1:u59hRTTah4Co6i9fDWtiCjTrblJv0UwsqZKCc0GfgUs=
github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk=
github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8=
github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8=
github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk=
github.com/ferranbt/fastssz v1.0.0 h1:9EXXYsracSqQRBQiHeaVsG/KQeYblPf40hsQPb9Dzk8=
github.com/ferranbt/fastssz v1.0.0/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/getsentry/sentry-go v0.35.1 h1:iopow6UVLE2aXu46xKVIs8Z9D/YZkJrHkgozrxa+tOQ=
github.com/getsentry/sentry-go v0.35.1/go.mod h1:C55omcY9ChRQIUcVcGcs+Zdy4ZpQGvNJ7JYHIoSWOtE=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw=
github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q=
github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA=
github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4=
github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c=
github.com/luxfi/cache v1.1.0 h1:6LUyGGZ+rrMAJBbAU6+UwkcamXj3zsboRUodIof2Ong=
github.com/luxfi/cache v1.1.0/go.mod h1:9GvlEEE9rFPaaWxvVpSPwW8ZMo2+8VMNNcuPa4AwzPg=
github.com/luxfi/consensus v1.22.46 h1:w97OZjtW/anWvgM0N/q8Y70LEJlqlFG6yeS10rKcnx4=
github.com/luxfi/consensus v1.22.46/go.mod h1:cbvtxHH5pab/XJIlHekg66tYaIChTwTt9SNMMgz8+as=
github.com/luxfi/crypto v1.17.28 h1:kjzuENMqZXUJWewbEn+M0b687E7sPesd2tNav78OsKI=
github.com/luxfi/crypto v1.17.28/go.mod h1:v6eaW5ejuzW2gecChWKQqx4CtVhoM1b+e40ro/6WVPg=
github.com/luxfi/database v1.2.17 h1:1PE0FlAarorfAMl+vAvO6EDbkS+a4ktL7kvtRk58DWY=
github.com/luxfi/database v1.2.17/go.mod h1:IzvNHGFZWdRs5CL5vswqz8/uu8t796cMGlbqPWs032s=
github.com/luxfi/fhe v1.2.0 h1:APcLnIXorHLYDEnNJgId0xKPCH1QOzNpCEvEZmHkUtw=
github.com/luxfi/fhe v1.2.0/go.mod h1:9It4M5ms2dof1E6xDIJscrI9Q5Aw0Lcn/qlAQsM85fU=
github.com/luxfi/geth v1.16.66 h1:XS5hMbYZtxCm/G6vjWBA7vRTpajX1FSJvAfkpL8cbN4=
github.com/luxfi/geth v1.16.66/go.mod h1:fmimbIf5oLldwc3FzEYaP8Jrf8tBhvDFi0Y/b26Tajk=
github.com/luxfi/ids v1.2.5 h1:w4YSj3S6LQiUXhiChUmcbrMCRMfkCaBFIGn0Eo4ZSxk=
github.com/luxfi/ids v1.2.5/go.mod h1:vZBjJWSmqMIZuodgnoszvTDvXIwsbnhM2pkktg6FGrg=
github.com/luxfi/lattice/v6 v6.1.2 h1:OuNEDkgwiZpe3W6oR7vvSDfLK5jf93y2dNiMj1R9oyA=
github.com/luxfi/lattice/v6 v6.1.2/go.mod h1:vzyXgtFe/itUmSyCRv6pHk9OHW52UkCFTJQiBE5lxBw=
github.com/luxfi/lattice/v7 v7.0.0 h1:d1vgan6mlb2KtwYfPc1g69uxVYaoVYZmlrIm4aCO88w=
github.com/luxfi/lattice/v7 v7.0.0/go.mod h1:PFDdOkuGTQ0cbJMbKojzEJMGWUQmZW+wK9/wJ9F9fOs=
github.com/luxfi/log v1.2.0 h1:MNFztarg1fzsfCnki8wcktu8AKXio5Ub+5w3KSTsfUU=
github.com/luxfi/log v1.2.0/go.mod h1:ACN1FtMlJ/NRuWROYH2TtiFmJuUbSG+OxINlRzJM/38=
github.com/luxfi/math v1.2.0 h1:cZVQQj1PrIWh3Oy6xfbBL44xay4QFuAXZBg9+pWPBmE=
github.com/luxfi/math v1.2.0/go.mod h1:gcmMy6raVf6xrQW/4UmFXEEXC/UC2tZeGkxdiDzeBSg=
github.com/luxfi/metric v1.4.8 h1:mMbcJW+E1z6qQxn34+BE109HlvT6ciiDXuc10qEBJRs=
github.com/luxfi/metric v1.4.8/go.mod h1:AUQ7NSNz9WndAcr/SKnOkP7XSFFnBXOa+ihtJYfDaQY=
github.com/luxfi/p2p v1.18.2 h1:elpyXr58wht1KP64D4BcKXft1AEjJ3IRACj/W8vdLI8=
github.com/luxfi/p2p v1.18.2/go.mod h1:eM6XpmBFbDjaI7fFuGYBPab77TS1esxHxAOluBLAC0Y=
github.com/luxfi/corona v0.2.0 h1:DbLMZmE//2T2wXXS/gEkKZrTbre9LD+7EE/tz5SQszU=
github.com/luxfi/corona v0.2.0/go.mod h1:SZ+aDLUdfSAtaTRaaYzeDZ5DNQiLaOCelSaIGjL21R0=
github.com/luxfi/sampler v1.0.0 h1:k8Sf6otW83w4pQp0jXLA+g3J/joB7w7SqXQsWmNTOV0=
github.com/luxfi/sampler v1.0.0/go.mod h1:f96/ozlj9vFfZj+akLtrHn4VpulQahwB+MQQhpeIekk=
github.com/luxfi/utils v1.1.0 h1:ti7HvjNwJd4ILDMERJtOAWE9mF8l+zqDVkgWnF7Agic=
github.com/luxfi/utils v1.1.0/go.mod h1:ABqhBdGNig0CaDcnNYldv1byS0BTNi5IKPbJSPF1p98=
github.com/luxfi/vm v1.0.1 h1:eZqrp6mEFPkhiv5kf5ZXmYAbXXjpS9axpUQG3cd3yts=
github.com/luxfi/vm v1.0.1/go.mod h1:PJinuF4McLaHN57iKf8p7h89wIQhQT//LD/fac+/Dk8=
github.com/luxfi/warp v1.18.2 h1:TWmXjKXI7nxaDOnXIrw8BQTI/nCEniA17bs06bwNB4Q=
github.com/luxfi/warp v1.18.2/go.mod h1:qu3TZv98repNhIDf04I6pzXePSgHjzP+JoSfWmF4PBA=
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=
github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o=
github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 h1:+FZIDR/D97YOPik4N4lPDaUcLDF/EQPogxtlHB2ZZRM=
github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc=
github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI=
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
github.com/prysmaticlabs/gohashtree v0.0.4-beta h1:H/EbCuXPeTV3lpKeXGPpEV9gsUpkqOOVnWapUyeWro4=
github.com/prysmaticlabs/gohashtree v0.0.4-beta/go.mod h1:BFdtALS+Ffhg3lGQIHv9HDWuHS8cTvHZzrHWxwOtGOs=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/supranational/blst v0.3.16 h1:bTDadT+3fK497EvLdWRQEjiGnUtzJ7jjIUMF0jqwYhE=
github.com/supranational/blst v0.3.16/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI=
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48=
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI=
github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE=
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+300
View File
@@ -0,0 +1,300 @@
// SPDX-License-Identifier: MIT
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
pragma solidity ^0.8.24;
/**
* @title IGraphQL
* @notice Native GraphQL query interface for G-Chain unified query layer
* @dev Precompile address: 0x0500
*
* This precompile enables any EVM contract to execute GraphQL queries against
* the unified G-Chain query layer. It provides:
* - Cross-chain data aggregation (query multiple chains at once)
* - DEX data (pools, pairs, tokens, swaps, positions)
* - Account and balance information
* - Pre-defined query templates for gas efficiency
*/
interface IGraphQL {
// =========================================================================
// Query Methods
// =========================================================================
/**
* @notice Execute a GraphQL query
* @param query The GraphQL query string
* @param variables JSON-encoded query variables
* @return data The query result as JSON bytes
*/
function query(
string calldata query,
bytes calldata variables
) external returns (bytes memory data);
/**
* @notice Execute a GraphQL query with operation name
* @param query The GraphQL query string
* @param variables JSON-encoded query variables
* @param operationName The operation name
* @return data The query result as JSON bytes
*/
function queryNamed(
string calldata query,
bytes calldata variables,
string calldata operationName
) external returns (bytes memory data);
/**
* @notice Execute a cross-chain GraphQL query
* @param query The GraphQL query string
* @param variables JSON-encoded query variables
* @param targetChains Array of chain IDs to query (empty = all chains)
* @return data The query result as JSON bytes
*/
function queryCrossChain(
string calldata query,
bytes calldata variables,
uint64[] calldata targetChains
) external returns (bytes memory data);
/**
* @notice Execute a pre-defined query template (lower gas)
* @param queryId The pre-defined query ID
* @param args Query arguments
* @return data The query result as JSON bytes
*/
function queryPredefined(
uint16 queryId,
bytes[] calldata args
) external returns (bytes memory data);
// =========================================================================
// View Methods
// =========================================================================
/**
* @notice Get query statistics
* @return totalQueries Total number of queries executed
* @return cacheHits Number of cache hits
* @return cacheMisses Number of cache misses
* @return totalGasUsed Total gas consumed by queries
*/
function getStats() external view returns (
uint64 totalQueries,
uint64 cacheHits,
uint64 cacheMisses,
uint64 totalGasUsed
);
/**
* @notice Get supported chain IDs
* @return chainIds Array of supported chain IDs
*/
function getSupportedChains() external view returns (uint64[] memory chainIds);
// =========================================================================
// Pre-defined Query IDs
// =========================================================================
// Chain queries (0x00xx)
uint16 constant QUERY_CHAIN_INFO = 0x0001;
uint16 constant QUERY_BLOCK_BY_HASH = 0x0002;
uint16 constant QUERY_BLOCK_BY_NUMBER = 0x0003;
// Account queries (0x01xx)
uint16 constant QUERY_BALANCE = 0x0101;
uint16 constant QUERY_ACCOUNT_INFO = 0x0102;
// DEX Factory queries (0x02xx)
uint16 constant QUERY_FACTORY = 0x0201;
uint16 constant QUERY_BUNDLE = 0x0202;
// Token queries (0x03xx)
uint16 constant QUERY_TOKEN = 0x0301;
uint16 constant QUERY_TOKENS = 0x0302;
uint16 constant QUERY_TOKEN_PRICE = 0x0303;
// Pool queries (0x04xx)
uint16 constant QUERY_POOL = 0x0401;
uint16 constant QUERY_POOLS = 0x0402;
uint16 constant QUERY_POOL_TICKS = 0x0403;
uint16 constant QUERY_POOL_DAY_DATA = 0x0404;
// Pair queries v2 (0x05xx)
uint16 constant QUERY_PAIR = 0x0501;
uint16 constant QUERY_PAIRS = 0x0502;
uint16 constant QUERY_PAIR_DAY_DATA = 0x0503;
// Position queries (0x06xx)
uint16 constant QUERY_POSITION = 0x0601;
uint16 constant QUERY_POSITIONS = 0x0602;
uint16 constant QUERY_POSITIONS_BY_OWNER = 0x0603;
// Swap queries (0x07xx)
uint16 constant QUERY_SWAPS = 0x0701;
uint16 constant QUERY_SWAPS_BY_POOL = 0x0702;
uint16 constant QUERY_SWAPS_BY_TOKEN = 0x0703;
// Cross-chain queries (0x0Fxx)
uint16 constant QUERY_ALL_CHAINS_TVL = 0x0F01;
uint16 constant QUERY_ALL_CHAINS_VOLUME = 0x0F02;
// =========================================================================
// Chain IDs
// =========================================================================
uint64 constant CHAIN_LUX_MAINNET = 96369;
uint64 constant CHAIN_LUX_TESTNET = 96368;
uint64 constant CHAIN_ZOO_MAINNET = 200200;
uint64 constant CHAIN_ZOO_TESTNET = 200201;
uint64 constant CHAIN_SPC_MAINNET = 36911;
uint64 constant CHAIN_SPC_TESTNET = 36910;
uint64 constant CHAIN_HANZO_MAINNET = 36963;
uint64 constant CHAIN_HANZO_TESTNET = 36962;
// =========================================================================
// Events
// =========================================================================
event QueryExecuted(
address indexed caller,
bytes32 indexed queryHash,
uint64 gasUsed,
bool fromCache
);
event QueryError(
address indexed caller,
bytes32 indexed queryHash,
string error
);
}
/**
* @title GraphQL
* @notice Library for interacting with the GraphQL precompile
*/
library GraphQL {
address constant PRECOMPILE = address(0x0500);
/**
* @notice Get ETH/LUX price from bundle
* @return ethPriceUSD ETH price in USD (18 decimals)
* @return luxPriceUSD LUX price in USD (18 decimals)
*/
function getPriceBundle() internal returns (uint256 ethPriceUSD, uint256 luxPriceUSD) {
bytes[] memory args = new bytes[](0);
bytes memory result = IGraphQL(PRECOMPILE).queryPredefined(
IGraphQL.QUERY_BUNDLE,
args
);
// Parse JSON result (simplified - real implementation would use proper parsing)
// For now, return mock values
ethPriceUSD = 2000e18;
luxPriceUSD = 10e18;
}
/**
* @notice Get token info by address
* @param tokenAddress The token address
* @return symbol Token symbol
* @return decimals Token decimals
* @return volumeUSD 24h volume in USD
* @return tvlUSD Total value locked in USD
*/
function getToken(address tokenAddress) internal returns (
string memory symbol,
uint8 decimals,
uint256 volumeUSD,
uint256 tvlUSD
) {
bytes[] memory args = new bytes[](1);
args[0] = abi.encodePacked(tokenAddress);
bytes memory result = IGraphQL(PRECOMPILE).queryPredefined(
IGraphQL.QUERY_TOKEN,
args
);
// Parse JSON result
// Return mock values for now
symbol = "TOKEN";
decimals = 18;
volumeUSD = 1000000e18;
tvlUSD = 5000000e18;
}
/**
* @notice Get pool info by address
* @param poolAddress The pool address
* @return token0 Token0 address
* @return token1 Token1 address
* @return fee Pool fee tier
* @return liquidity Current liquidity
* @return sqrtPriceX96 Current sqrt price
*/
function getPool(address poolAddress) internal returns (
address token0,
address token1,
uint24 fee,
uint128 liquidity,
uint160 sqrtPriceX96
) {
bytes[] memory args = new bytes[](1);
args[0] = abi.encodePacked(poolAddress);
bytes memory result = IGraphQL(PRECOMPILE).queryPredefined(
IGraphQL.QUERY_POOL,
args
);
// Parse JSON result
// Return mock values for now
}
/**
* @notice Get all positions for an owner
* @param owner The position owner address
* @return positionIds Array of position token IDs
*/
function getPositionsByOwner(address owner) internal returns (uint256[] memory positionIds) {
bytes[] memory args = new bytes[](1);
args[0] = abi.encodePacked(owner);
bytes memory result = IGraphQL(PRECOMPILE).queryPredefined(
IGraphQL.QUERY_POSITIONS_BY_OWNER,
args
);
// Parse JSON result
// Return mock values for now
positionIds = new uint256[](0);
}
/**
* @notice Get TVL across all chains
* @return chainIds Array of chain IDs
* @return tvls Array of TVL values in USD (18 decimals)
*/
function getAllChainsTVL() internal returns (
uint64[] memory chainIds,
uint256[] memory tvls
) {
bytes[] memory args = new bytes[](0);
bytes memory result = IGraphQL(PRECOMPILE).queryPredefined(
IGraphQL.QUERY_ALL_CHAINS_TVL,
args
);
// Parse JSON result
// Return mock values for now
chainIds = new uint64[](4);
chainIds[0] = IGraphQL.CHAIN_LUX_MAINNET;
chainIds[1] = IGraphQL.CHAIN_ZOO_MAINNET;
chainIds[2] = IGraphQL.CHAIN_SPC_MAINNET;
chainIds[3] = IGraphQL.CHAIN_HANZO_MAINNET;
tvls = new uint256[](4);
tvls[0] = 100_000_000e18; // $100M
tvls[1] = 50_000_000e18; // $50M
tvls[2] = 25_000_000e18; // $25M
tvls[3] = 10_000_000e18; // $10M
}
}
+408
View File
@@ -0,0 +1,408 @@
// SPDX-License-Identifier: MIT
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
pragma solidity ^0.8.24;
import "./IGraphQL.sol";
/**
* @title IOracle
* @notice Unified Oracle interface for AMM and price feed queries
* @dev Uses G-Chain GraphQL precompile at 0x0500
*
* This provides a clean interface for:
* - Token price feeds (USD, ETH, LUX denominated)
* - Pool data (liquidity, fees, volume)
* - Swap quotes and routing
* - LP position values
*/
interface IOracle {
// =========================================================================
// Price Feed Queries
// =========================================================================
/**
* @notice Get ETH price in USD (18 decimals)
*/
function getETHPrice() external view returns (uint256 priceUSD);
/**
* @notice Get LUX price in USD (18 decimals)
*/
function getLUXPrice() external view returns (uint256 priceUSD);
/**
* @notice Get token price in USD (18 decimals)
* @param token Token address
*/
function getTokenPrice(address token) external view returns (uint256 priceUSD);
/**
* @notice Get token price in ETH (18 decimals)
* @param token Token address
*/
function getTokenPriceETH(address token) external view returns (uint256 priceETH);
/**
* @notice Get TWAP price for a pool over specified hours
* @param pool Pool address
* @param hours Number of hours for TWAP calculation
*/
function getTWAP(address pool, uint256 hours) external view returns (
uint256 token0Price,
uint256 token1Price
);
/**
* @notice Get all major token prices at once
* @return tokens Array of token addresses
* @return prices Array of USD prices (18 decimals)
*/
function getAllPrices() external view returns (
address[] memory tokens,
uint256[] memory prices
);
// =========================================================================
// Pool Queries
// =========================================================================
/**
* @notice Get pool by token pair
* @param token0 First token address
* @param token1 Second token address
* @param fee Fee tier (100, 500, 3000, 10000)
*/
function getPool(
address token0,
address token1,
uint24 fee
) external view returns (
address pool,
uint128 liquidity,
uint160 sqrtPriceX96,
int24 tick
);
/**
* @notice Get pool liquidity depth
* @param pool Pool address
*/
function getPoolLiquidity(address pool) external view returns (
uint128 liquidity,
uint256 tvlToken0,
uint256 tvlToken1,
uint256 tvlUSD
);
/**
* @notice Get pool volume and fees
* @param pool Pool address
*/
function getPoolStats(address pool) external view returns (
uint256 volume24hUSD,
uint256 fees24hUSD,
uint256 txCount24h,
uint256 apr
);
/**
* @notice Get pool fee growth for LP calculations
* @param pool Pool address
*/
function getPoolFeeGrowth(address pool) external view returns (
uint256 feeGrowthGlobal0X128,
uint256 feeGrowthGlobal1X128
);
// =========================================================================
// Swap Queries
// =========================================================================
/**
* @notice Get swap quote (exact input)
* @param tokenIn Input token
* @param tokenOut Output token
* @param amountIn Input amount
*/
function quoteExactInput(
address tokenIn,
address tokenOut,
uint256 amountIn
) external view returns (
uint256 amountOut,
uint256 priceImpact,
uint256 gasEstimate
);
/**
* @notice Get swap quote (exact output)
* @param tokenIn Input token
* @param tokenOut Output token
* @param amountOut Desired output amount
*/
function quoteExactOutput(
address tokenIn,
address tokenOut,
uint256 amountOut
) external view returns (
uint256 amountIn,
uint256 priceImpact,
uint256 gasEstimate
);
/**
* @notice Get best swap route
* @param tokenIn Input token
* @param tokenOut Output token
* @param amountIn Input amount
*/
function getBestRoute(
address tokenIn,
address tokenOut,
uint256 amountIn
) external view returns (
address[] memory path,
uint24[] memory fees,
uint256 expectedOutput
);
// =========================================================================
// Position Queries
// =========================================================================
/**
* @notice Get all positions for an owner
* @param owner Position owner
*/
function getPositions(address owner) external view returns (
uint256[] memory tokenIds,
address[] memory pools,
uint128[] memory liquidities,
uint256[] memory valuesUSD
);
/**
* @notice Get position details by token ID
* @param tokenId NFT position token ID
*/
function getPosition(uint256 tokenId) external view returns (
address pool,
int24 tickLower,
int24 tickUpper,
uint128 liquidity,
uint256 amount0,
uint256 amount1,
uint256 fees0,
uint256 fees1,
bool inRange
);
/**
* @notice Get uncollected fees for a position
* @param tokenId NFT position token ID
*/
function getPositionFees(uint256 tokenId) external view returns (
uint256 fees0,
uint256 fees1,
uint256 feesUSD
);
// =========================================================================
// Events
// =========================================================================
event PriceUpdated(address indexed token, uint256 priceUSD, uint256 timestamp);
event PoolStatsUpdated(address indexed pool, uint256 tvlUSD, uint256 volume24hUSD);
}
/**
* @title LuxOracle
* @notice Implementation of IOracle using G-Chain GraphQL precompile
*/
library LuxOracle {
address constant GRAPHQL = address(0x0500);
// Query IDs from graph/oracle.go
uint16 constant QUERY_ETH_PRICE = 0x1001;
uint16 constant QUERY_LUX_PRICE = 0x1002;
uint16 constant QUERY_TOKEN_PRICE = 0x1004;
uint16 constant QUERY_TWAP = 0x1010;
uint16 constant QUERY_SPOT_PRICE = 0x1011;
uint16 constant QUERY_ALL_PRICES = 0x1020;
uint16 constant QUERY_POOL_BY_TOKENS = 0x2001;
uint16 constant QUERY_POOL_LIQUIDITY = 0x2002;
uint16 constant QUERY_POOL_FEES = 0x2003;
uint16 constant QUERY_POOL_VOLUME = 0x2004;
uint16 constant QUERY_MY_POSITIONS = 0x2010;
uint16 constant QUERY_POSITION_VALUE = 0x2011;
uint16 constant QUERY_QUOTE = 0x2020;
/**
* @notice Get ETH price in USD
*/
function getETHPrice() internal returns (uint256) {
bytes[] memory args = new bytes[](0);
bytes memory result = IGraphQL(GRAPHQL).queryPredefined(QUERY_ETH_PRICE, args);
return _parsePrice(result);
}
/**
* @notice Get LUX price in USD
*/
function getLUXPrice() internal returns (uint256) {
bytes[] memory args = new bytes[](0);
bytes memory result = IGraphQL(GRAPHQL).queryPredefined(QUERY_LUX_PRICE, args);
return _parsePrice(result);
}
/**
* @notice Get any token price in USD
*/
function getTokenPrice(address token) internal returns (uint256) {
bytes[] memory args = new bytes[](1);
args[0] = abi.encodePacked(token);
bytes memory result = IGraphQL(GRAPHQL).queryPredefined(QUERY_TOKEN_PRICE, args);
return _parsePrice(result);
}
/**
* @notice Get pool spot price
*/
function getSpotPrice(address pool) internal returns (uint256 token0Price, uint256 token1Price) {
bytes[] memory args = new bytes[](1);
args[0] = abi.encodePacked(pool);
bytes memory result = IGraphQL(GRAPHQL).queryPredefined(QUERY_SPOT_PRICE, args);
return _parsePoolPrices(result);
}
/**
* @notice Get pool liquidity info
*/
function getPoolLiquidity(address pool) internal returns (
uint128 liquidity,
uint256 tvlToken0,
uint256 tvlToken1,
uint256 tvlUSD
) {
bytes[] memory args = new bytes[](1);
args[0] = abi.encodePacked(pool);
bytes memory result = IGraphQL(GRAPHQL).queryPredefined(QUERY_POOL_LIQUIDITY, args);
return _parsePoolLiquidity(result);
}
/**
* @notice Get swap quote
*/
function getQuote(
address tokenIn,
address tokenOut,
uint256 amountIn
) internal returns (uint256 amountOut, uint256 priceImpact) {
bytes[] memory args = new bytes[](3);
args[0] = abi.encodePacked(tokenIn);
args[1] = abi.encodePacked(tokenOut);
args[2] = abi.encode(amountIn);
bytes memory result = IGraphQL(GRAPHQL).queryPredefined(QUERY_QUOTE, args);
return _parseQuote(result);
}
/**
* @notice Get user positions
*/
function getPositions(address owner) internal returns (
uint256[] memory tokenIds,
uint256[] memory liquidities
) {
bytes[] memory args = new bytes[](1);
args[0] = abi.encodePacked(owner);
bytes memory result = IGraphQL(GRAPHQL).queryPredefined(QUERY_MY_POSITIONS, args);
return _parsePositions(result);
}
// =========================================================================
// Internal Parsing Functions
// =========================================================================
function _parsePrice(bytes memory data) internal pure returns (uint256) {
// Simple JSON parsing - in production use proper decoder
// Returns price with 18 decimals
if (data.length == 0) return 0;
// Mock implementation - real one would parse JSON
// For now, decode as uint256 if it's ABI encoded
if (data.length >= 32) {
return abi.decode(data, (uint256));
}
return 0;
}
function _parsePoolPrices(bytes memory data) internal pure returns (uint256, uint256) {
if (data.length < 64) return (0, 0);
(uint256 p0, uint256 p1) = abi.decode(data, (uint256, uint256));
return (p0, p1);
}
function _parsePoolLiquidity(bytes memory data) internal pure returns (
uint128, uint256, uint256, uint256
) {
if (data.length < 128) return (0, 0, 0, 0);
return abi.decode(data, (uint128, uint256, uint256, uint256));
}
function _parseQuote(bytes memory data) internal pure returns (uint256, uint256) {
if (data.length < 64) return (0, 0);
return abi.decode(data, (uint256, uint256));
}
function _parsePositions(bytes memory data) internal pure returns (
uint256[] memory,
uint256[] memory
) {
if (data.length == 0) {
return (new uint256[](0), new uint256[](0));
}
return abi.decode(data, (uint256[], uint256[]));
}
}
/**
* @title OracleConsumer
* @notice Example contract showing how to use LuxOracle
*/
abstract contract OracleConsumer {
using LuxOracle for *;
/**
* @notice Get value of a token amount in USD
*/
function getValueUSD(address token, uint256 amount) public returns (uint256) {
uint256 price = LuxOracle.getTokenPrice(token);
return (amount * price) / 1e18;
}
/**
* @notice Get expected output for a swap
*/
function getExpectedOutput(
address tokenIn,
address tokenOut,
uint256 amountIn
) public returns (uint256 amountOut) {
(amountOut, ) = LuxOracle.getQuote(tokenIn, tokenOut, amountIn);
}
/**
* @notice Check if price impact is acceptable
*/
function checkPriceImpact(
address tokenIn,
address tokenOut,
uint256 amountIn,
uint256 maxImpactBps
) public returns (bool acceptable) {
(, uint256 impact) = LuxOracle.getQuote(tokenIn, tokenOut, amountIn);
return impact <= maxImpactBps;
}
}
+7
View File
@@ -0,0 +1,7 @@
module github.com/luxfi/precompiles/graph
go 1.22
require (
github.com/luxfi/geth v1.13.8-lux
)
+524
View File
@@ -0,0 +1,524 @@
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package graph
import (
"context"
"crypto/sha256"
"encoding/binary"
"encoding/json"
"fmt"
"sync"
"time"
"github.com/luxfi/geth/common"
)
// StateDB interface for accessing EVM state
type StateDB interface {
GetState(addr common.Address, key common.Hash) common.Hash
SetState(addr common.Address, key common.Hash, value common.Hash)
}
// GChainClient interface for communication with G-Chain
type GChainClient interface {
// Query executes a GraphQL query against G-Chain
Query(ctx context.Context, query string, variables map[string]interface{}) ([]byte, error)
// QueryChain executes a query against a specific chain
QueryChain(ctx context.Context, chainID uint64, query string, variables map[string]interface{}) ([]byte, error)
}
// Precompile address
var graphQLAddr = common.HexToAddress(GraphQLAddress)
// Storage key prefixes
var (
cachePrefix = []byte("gcache")
statsPrefix = []byte("gstats")
configPrefix = []byte("gconf")
)
// GraphQLPrecompile implements the G-Chain GraphQL query interface
// This precompile enables any EVM contract to execute GraphQL queries
// against the unified G-Chain query layer.
type GraphQLPrecompile struct {
mu sync.RWMutex
// client is the connection to G-Chain
client GChainClient
// cache stores recent query results for gas efficiency
cache map[[32]byte]*CacheEntry
// stats tracks query statistics
stats *QueryStats
// config holds runtime configuration
config *Config
}
// CacheEntry represents a cached query result
type CacheEntry struct {
Data []byte
Timestamp time.Time
TTL time.Duration
}
// QueryStats tracks query performance
type QueryStats struct {
TotalQueries uint64
CacheHits uint64
CacheMisses uint64
TotalGasUsed uint64
AvgResponseTime time.Duration
}
// Config holds precompile configuration
type Config struct {
// MaxCacheSize is the maximum number of cache entries
MaxCacheSize int
// DefaultCacheTTL is the default cache time-to-live
DefaultCacheTTL time.Duration
// QueryTimeout is the maximum query execution time
QueryTimeout time.Duration
// GChainEndpoint is the G-Chain GraphQL endpoint
GChainEndpoint string
}
// NewGraphQLPrecompile creates a new GraphQL precompile instance
func NewGraphQLPrecompile(client GChainClient) *GraphQLPrecompile {
return &GraphQLPrecompile{
client: client,
cache: make(map[[32]byte]*CacheEntry),
stats: &QueryStats{},
config: &Config{
MaxCacheSize: 1000,
DefaultCacheTTL: 10 * time.Second,
QueryTimeout: 5 * time.Second,
GChainEndpoint: "http://localhost:9650/ext/bc/G/graphql",
},
}
}
// makeStorageKey creates a storage key from prefix and data
func makeStorageKey(prefix []byte, data []byte) common.Hash {
h := sha256.New()
h.Write(prefix)
h.Write(data)
var key common.Hash
copy(key[:], h.Sum(nil))
return key
}
// makeCacheKey creates a cache key from query and variables
func makeCacheKey(query string, variables []byte) [32]byte {
h := sha256.New()
h.Write([]byte(query))
h.Write(variables)
var key [32]byte
copy(key[:], h.Sum(nil))
return key
}
// =========================================================================
// Core Query Methods
// =========================================================================
// Query executes a GraphQL query and returns the result
// This is the main entry point for EVM contracts
func (p *GraphQLPrecompile) Query(
stateDB StateDB,
caller common.Address,
req QueryRequest,
gasLimit uint64,
) (QueryResponse, error) {
p.mu.Lock()
defer p.mu.Unlock()
startTime := time.Now()
// Validate query
if err := p.validateQuery(req); err != nil {
return QueryResponse{}, err
}
// Calculate initial gas cost
gasCost := p.calculateGasCost(req)
if gasCost > gasLimit {
return QueryResponse{}, ErrGasExceeded
}
// Check cache
cacheKey := makeCacheKey(req.Query, req.Variables)
if entry, ok := p.cache[cacheKey]; ok {
if time.Since(entry.Timestamp) < entry.TTL {
p.stats.CacheHits++
return QueryResponse{
Data: entry.Data,
GasUsed: GasQueryBase, // Minimal gas for cache hit
}, nil
}
// Cache expired
delete(p.cache, cacheKey)
}
p.stats.CacheMisses++
// Execute query against G-Chain
ctx, cancel := context.WithTimeout(context.Background(), p.config.QueryTimeout)
defer cancel()
var variables map[string]interface{}
if len(req.Variables) > 0 {
if err := json.Unmarshal(req.Variables, &variables); err != nil {
return QueryResponse{}, ErrInvalidQuery
}
}
var result []byte
var err error
if len(req.TargetChains) == 0 {
// Query all chains via G-Chain unified layer
result, err = p.client.Query(ctx, req.Query, variables)
} else if len(req.TargetChains) == 1 {
// Query specific chain
result, err = p.client.QueryChain(ctx, req.TargetChains[0], req.Query, variables)
} else {
// Multi-chain query
result, err = p.executeMultiChainQuery(ctx, req, variables)
}
if err != nil {
if ctx.Err() == context.DeadlineExceeded {
return QueryResponse{}, ErrQueryTimeout
}
return QueryResponse{
Errors: []QueryError{{Message: err.Error()}},
GasUsed: gasCost,
}, nil
}
// Validate response size
if len(result) > MaxResponseSize {
return QueryResponse{}, ErrQueryTooLarge
}
// Calculate additional gas for response size
responseGas := uint64(len(result)) * GasPerByte
totalGas := gasCost + responseGas
// Cache result
if len(p.cache) < p.config.MaxCacheSize {
p.cache[cacheKey] = &CacheEntry{
Data: result,
Timestamp: time.Now(),
TTL: p.config.DefaultCacheTTL,
}
}
// Update stats
p.stats.TotalQueries++
p.stats.TotalGasUsed += totalGas
elapsed := time.Since(startTime)
p.stats.AvgResponseTime = (p.stats.AvgResponseTime + elapsed) / 2
return QueryResponse{
Data: result,
GasUsed: totalGas,
}, nil
}
// QueryPredefined executes a pre-defined query template
// This provides lower gas costs for common queries
func (p *GraphQLPrecompile) QueryPredefined(
stateDB StateDB,
caller common.Address,
queryID QueryID,
args [][]byte,
gasLimit uint64,
) (QueryResponse, error) {
template, ok := PredefinedQueries[queryID]
if !ok {
return QueryResponse{}, ErrInvalidQuery
}
if len(args) > template.MaxArgs {
return QueryResponse{}, ErrInvalidQuery
}
if template.GasCost > gasLimit {
return QueryResponse{}, ErrGasExceeded
}
// Build variables from args
variables := make(map[string]interface{})
argNames := []string{"address", "id", "first", "orderBy", "owner"}
for i, arg := range args {
if i < len(argNames) {
variables[argNames[i]] = string(arg)
}
}
varsJSON, _ := json.Marshal(variables)
req := QueryRequest{
Query: template.Query,
Variables: varsJSON,
}
return p.Query(stateDB, caller, req, gasLimit)
}
// =========================================================================
// Helper Methods
// =========================================================================
// validateQuery validates the query request
func (p *GraphQLPrecompile) validateQuery(req QueryRequest) error {
if len(req.Query) == 0 {
return ErrInvalidQuery
}
if len(req.Query) > MaxQuerySize {
return ErrQueryTooLarge
}
return nil
}
// calculateGasCost estimates the gas cost for a query
func (p *GraphQLPrecompile) calculateGasCost(req QueryRequest) uint64 {
// Base cost
cost := GasQueryBase
// Add cost based on query complexity
queryLen := len(req.Query)
if queryLen > 500 {
cost += GasQueryComplex
} else {
cost += GasQuerySimple
}
// Add cost for cross-chain queries
if len(req.TargetChains) > 1 {
cost += GasQueryCrossChain * uint64(len(req.TargetChains))
}
// Add cost for variables
cost += uint64(len(req.Variables)) * GasPerByte
return cost
}
// executeMultiChainQuery executes a query across multiple chains
func (p *GraphQLPrecompile) executeMultiChainQuery(
ctx context.Context,
req QueryRequest,
variables map[string]interface{},
) ([]byte, error) {
results := make(map[uint64]json.RawMessage)
var mu sync.Mutex
var wg sync.WaitGroup
var firstErr error
for _, chainID := range req.TargetChains {
wg.Add(1)
go func(cid uint64) {
defer wg.Done()
result, err := p.client.QueryChain(ctx, cid, req.Query, variables)
mu.Lock()
defer mu.Unlock()
if err != nil && firstErr == nil {
firstErr = err
return
}
results[cid] = json.RawMessage(result)
}(chainID)
}
wg.Wait()
if firstErr != nil && len(results) == 0 {
return nil, firstErr
}
// Combine results
combined := map[string]interface{}{
"data": results,
}
return json.Marshal(combined)
}
// =========================================================================
// View Methods
// =========================================================================
// GetStats returns query statistics
func (p *GraphQLPrecompile) GetStats() *QueryStats {
p.mu.RLock()
defer p.mu.RUnlock()
return p.stats
}
// GetConfig returns the current configuration
func (p *GraphQLPrecompile) GetConfig() *Config {
p.mu.RLock()
defer p.mu.RUnlock()
return p.config
}
// ClearCache clears the query cache
func (p *GraphQLPrecompile) ClearCache() {
p.mu.Lock()
defer p.mu.Unlock()
p.cache = make(map[[32]byte]*CacheEntry)
}
// =========================================================================
// EVM Precompile Interface
// =========================================================================
// RequiredGas returns the gas required for the input
func (p *GraphQLPrecompile) RequiredGas(input []byte) uint64 {
if len(input) < 4 {
return GasQueryBase
}
// Parse method selector
selector := binary.BigEndian.Uint32(input[:4])
switch selector {
case 0x01: // query(bytes)
return GasQueryComplex
case 0x02: // queryPredefined(uint16, bytes[])
return GasQuerySimple
case 0x03: // getStats()
return GasQueryBase
default:
return GasQueryComplex
}
}
// Run executes the precompile
func (p *GraphQLPrecompile) Run(input []byte) ([]byte, error) {
if len(input) < 4 {
return nil, ErrInvalidQuery
}
selector := binary.BigEndian.Uint32(input[:4])
switch selector {
case 0x01: // query(bytes)
return p.runQuery(input[4:])
case 0x02: // queryPredefined(uint16, bytes[])
return p.runQueryPredefined(input[4:])
case 0x03: // getStats()
return p.runGetStats()
default:
return nil, fmt.Errorf("unknown method: %x", selector)
}
}
// runQuery handles the query method call
func (p *GraphQLPrecompile) runQuery(input []byte) ([]byte, error) {
// Decode QueryRequest from input
var req QueryRequest
if err := json.Unmarshal(input, &req); err != nil {
return nil, ErrInvalidQuery
}
// Execute query (uses default gas limit)
resp, err := p.Query(nil, common.Address{}, req, 1_000_000)
if err != nil {
return nil, err
}
return resp.Data, nil
}
// runQueryPredefined handles the queryPredefined method call
func (p *GraphQLPrecompile) runQueryPredefined(input []byte) ([]byte, error) {
if len(input) < 2 {
return nil, ErrInvalidQuery
}
queryID := QueryID(binary.BigEndian.Uint16(input[:2]))
// Parse args (simple format: length-prefixed byte arrays)
var args [][]byte
offset := 2
for offset < len(input) {
if offset+4 > len(input) {
break
}
argLen := binary.BigEndian.Uint32(input[offset : offset+4])
offset += 4
if offset+int(argLen) > len(input) {
break
}
args = append(args, input[offset:offset+int(argLen)])
offset += int(argLen)
}
resp, err := p.QueryPredefined(nil, common.Address{}, queryID, args, 1_000_000)
if err != nil {
return nil, err
}
return resp.Data, nil
}
// runGetStats handles the getStats method call
func (p *GraphQLPrecompile) runGetStats() ([]byte, error) {
stats := p.GetStats()
return json.Marshal(stats)
}
// =========================================================================
// Solidity Interface (for documentation)
// =========================================================================
// Solidity interface:
//
// interface IGraphQL {
// struct QueryRequest {
// string query;
// bytes variables;
// string operationName;
// uint64[] targetChains;
// }
//
// struct QueryResponse {
// bytes data;
// QueryError[] errors;
// uint64 gasUsed;
// }
//
// struct QueryError {
// string message;
// string[] path;
// }
//
// function query(QueryRequest calldata req) external returns (QueryResponse memory);
// function queryPredefined(uint16 queryId, bytes[] calldata args) external returns (bytes memory);
// function getStats() external view returns (uint64 totalQueries, uint64 cacheHits, uint64 cacheMisses);
//
// // Pre-defined query IDs
// uint16 constant QUERY_CHAIN_INFO = 0x0001;
// uint16 constant QUERY_BALANCE = 0x0101;
// uint16 constant QUERY_FACTORY = 0x0201;
// uint16 constant QUERY_BUNDLE = 0x0202;
// uint16 constant QUERY_TOKEN = 0x0301;
// uint16 constant QUERY_TOKENS = 0x0302;
// uint16 constant QUERY_POOL = 0x0401;
// uint16 constant QUERY_POOLS = 0x0402;
// uint16 constant QUERY_POSITIONS = 0x0601;
// uint16 constant QUERY_SWAPS = 0x0701;
// uint16 constant QUERY_ALL_CHAINS_TVL = 0x0F01;
// }
+316
View File
@@ -0,0 +1,316 @@
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package graph
import (
"encoding/json"
"math/big"
)
// =====================================
// Oracle Query Helpers
// =====================================
// Price feed query IDs for quick access
const (
// Core price feeds
QueryOracleETHPrice QueryID = 0x1001 // ETH/USD price
QueryOracleLUXPrice QueryID = 0x1002 // LUX/USD price
QueryOracleBTCPrice QueryID = 0x1003 // BTC/USD price
QueryOracleTokenPrice QueryID = 0x1004 // Any token price by address
// AMM-derived prices (TWAP)
QueryTWAPPrice QueryID = 0x1010 // Time-weighted average price
QuerySpotPrice QueryID = 0x1011 // Current spot price from pool
// Aggregated feeds
QueryAllPrices QueryID = 0x1020 // All major token prices
QueryPriceHistory QueryID = 0x1021 // Price history for charting
)
// OracleQueries contains pre-built GraphQL queries for price feeds
var OracleQueries = map[QueryID]QueryTemplate{
QueryOracleETHPrice: {
ID: QueryOracleETHPrice,
Query: `query { bundle(id: "1") { ethPriceUSD } }`,
GasCost: GasQuerySimple,
MaxArgs: 0,
},
QueryOracleLUXPrice: {
ID: QueryOracleLUXPrice,
Query: `query { bundle(id: "1") { luxPriceUSD } }`,
GasCost: GasQuerySimple,
MaxArgs: 0,
},
QueryOracleTokenPrice: {
ID: QueryOracleTokenPrice,
Query: `query($token: String!) { token(id: $token) { derivedETH derivedLUX symbol decimals } bundle(id: "1") { ethPriceUSD luxPriceUSD } }`,
GasCost: GasQuerySimple,
MaxArgs: 1,
},
QueryTWAPPrice: {
ID: QueryTWAPPrice,
Query: `query($pool: String!, $period: Int!) { poolHourDatas(first: $period, where: { pool: $pool }, orderBy: periodStartUnix, orderDirection: desc) { token0Price token1Price periodStartUnix } }`,
GasCost: GasQueryComplex,
MaxArgs: 2,
},
QuerySpotPrice: {
ID: QuerySpotPrice,
Query: `query($pool: String!) { pool(id: $pool) { token0Price token1Price sqrtPrice tick token0 { symbol decimals } token1 { symbol decimals } } }`,
GasCost: GasQuerySimple,
MaxArgs: 1,
},
QueryAllPrices: {
ID: QueryAllPrices,
Query: `query { bundle(id: "1") { ethPriceUSD luxPriceUSD } tokens(first: 20, orderBy: totalValueLockedUSD, orderDirection: desc) { id symbol derivedETH totalValueLockedUSD } }`,
GasCost: GasQueryComplex,
MaxArgs: 0,
},
QueryPriceHistory: {
ID: QueryPriceHistory,
Query: `query($token: String!, $days: Int!) { tokenDayDatas(first: $days, where: { token: $token }, orderBy: date, orderDirection: desc) { date priceUSD open high low close volumeUSD } }`,
GasCost: GasQueryComplex,
MaxArgs: 2,
},
}
// =====================================
// AMM Query Helpers
// =====================================
// AMM query IDs
const (
// Pool queries
QueryAMMPoolByTokens QueryID = 0x2001 // Find pool by token pair
QueryAMMPoolLiquidity QueryID = 0x2002 // Pool liquidity depth
QueryAMMPoolFees QueryID = 0x2003 // Pool fee tier and earned fees
QueryAMMPoolVolume QueryID = 0x2004 // Pool volume stats
// Position queries
QueryAMMMyPositions QueryID = 0x2010 // User's LP positions
QueryAMMPositionValue QueryID = 0x2011 // Position value + fees earned
QueryAMMPositionRange QueryID = 0x2012 // Position tick range
// Swap queries
QueryAMMQuote QueryID = 0x2020 // Get swap quote
QueryAMMRoute QueryID = 0x2021 // Best route for swap
QueryAMMRecentSwaps QueryID = 0x2022 // Recent swaps in pool
// Liquidity queries
QueryAMMTickLiquidity QueryID = 0x2030 // Liquidity at each tick
QueryAMMLiquidityDepth QueryID = 0x2031 // Order book style depth
)
// AMMQueries contains pre-built GraphQL queries for AMM data
var AMMQueries = map[QueryID]QueryTemplate{
QueryAMMPoolByTokens: {
ID: QueryAMMPoolByTokens,
Query: `query($token0: String!, $token1: String!) { pools(where: { token0: $token0, token1: $token1 }) { id feeTier liquidity sqrtPrice tick volumeUSD totalValueLockedUSD token0Price token1Price } }`,
GasCost: GasQuerySimple,
MaxArgs: 2,
},
QueryAMMPoolLiquidity: {
ID: QueryAMMPoolLiquidity,
Query: `query($pool: String!) { pool(id: $pool) { liquidity sqrtPrice tick totalValueLockedToken0 totalValueLockedToken1 totalValueLockedUSD } ticks(first: 100, where: { pool: $pool }, orderBy: tickIdx) { tickIdx liquidityNet liquidityGross price0 price1 } }`,
GasCost: GasQueryComplex,
MaxArgs: 1,
},
QueryAMMPoolFees: {
ID: QueryAMMPoolFees,
Query: `query($pool: String!) { pool(id: $pool) { feeTier feeGrowthGlobal0X128 feeGrowthGlobal1X128 collectedFeesToken0 collectedFeesToken1 collectedFeesUSD feesUSD } }`,
GasCost: GasQuerySimple,
MaxArgs: 1,
},
QueryAMMPoolVolume: {
ID: QueryAMMPoolVolume,
Query: `query($pool: String!) { pool(id: $pool) { volumeToken0 volumeToken1 volumeUSD txCount } poolDayDatas(first: 7, where: { pool: $pool }, orderBy: date, orderDirection: desc) { date volumeUSD tvlUSD feesUSD } }`,
GasCost: GasQueryComplex,
MaxArgs: 1,
},
QueryAMMMyPositions: {
ID: QueryAMMMyPositions,
Query: `query($owner: String!) { positions(where: { owner: $owner, liquidity_gt: "0" }) { id pool { id token0 { symbol } token1 { symbol } feeTier } tickLower { tickIdx price0 } tickUpper { tickIdx price0 } liquidity depositedToken0 depositedToken1 collectedFeesToken0 collectedFeesToken1 } }`,
GasCost: GasQueryComplex,
MaxArgs: 1,
},
QueryAMMPositionValue: {
ID: QueryAMMPositionValue,
Query: `query($positionId: String!) { position(id: $positionId) { liquidity depositedToken0 depositedToken1 withdrawnToken0 withdrawnToken1 collectedToken0 collectedToken1 collectedFeesToken0 collectedFeesToken1 pool { token0Price token1Price token0 { decimals symbol } token1 { decimals symbol } } } }`,
GasCost: GasQuerySimple,
MaxArgs: 1,
},
QueryAMMQuote: {
ID: QueryAMMQuote,
Query: `query($tokenIn: String!, $tokenOut: String!, $amount: String!) { quote(tokenIn: $tokenIn, tokenOut: $tokenOut, amountIn: $amount) { amountOut priceImpact route { pools { id feeTier } } gasEstimate } }`,
GasCost: GasQueryComplex,
MaxArgs: 3,
},
QueryAMMRecentSwaps: {
ID: QueryAMMRecentSwaps,
Query: `query($pool: String!, $count: Int!) { swaps(first: $count, where: { pool: $pool }, orderBy: timestamp, orderDirection: desc) { timestamp sender recipient amount0 amount1 amountUSD sqrtPriceX96 tick } }`,
GasCost: GasQueryComplex,
MaxArgs: 2,
},
QueryAMMTickLiquidity: {
ID: QueryAMMTickLiquidity,
Query: `query($pool: String!, $tickLower: Int!, $tickUpper: Int!) { ticks(where: { pool: $pool, tickIdx_gte: $tickLower, tickIdx_lte: $tickUpper }, orderBy: tickIdx) { tickIdx liquidityNet liquidityGross price0 price1 } }`,
GasCost: GasQueryComplex,
MaxArgs: 3,
},
}
// =====================================
// Response Types
// =====================================
// PriceResponse represents a token price query result
type PriceResponse struct {
TokenAddress string `json:"tokenAddress"`
Symbol string `json:"symbol"`
PriceUSD *big.Int `json:"priceUSD"` // 18 decimals
PriceETH *big.Int `json:"priceETH"` // 18 decimals
PriceLUX *big.Int `json:"priceLUX"` // 18 decimals
Timestamp uint64 `json:"timestamp"`
Source string `json:"source"` // "pool", "oracle", "twap"
}
// PoolInfoResponse represents pool information
type PoolInfoResponse struct {
PoolAddress string `json:"poolAddress"`
Token0 string `json:"token0"`
Token1 string `json:"token1"`
Token0Symbol string `json:"token0Symbol"`
Token1Symbol string `json:"token1Symbol"`
FeeTier uint32 `json:"feeTier"`
Liquidity *big.Int `json:"liquidity"`
SqrtPriceX96 *big.Int `json:"sqrtPriceX96"`
Tick int32 `json:"tick"`
Token0Price *big.Int `json:"token0Price"` // 18 decimals
Token1Price *big.Int `json:"token1Price"` // 18 decimals
TVL_USD *big.Int `json:"tvlUSD"` // 18 decimals
Volume24h_USD *big.Int `json:"volume24hUSD"` // 18 decimals
Fees24h_USD *big.Int `json:"fees24hUSD"` // 18 decimals
}
// QuoteResponse represents a swap quote
type QuoteResponse struct {
AmountIn *big.Int `json:"amountIn"`
AmountOut *big.Int `json:"amountOut"`
PriceImpact *big.Int `json:"priceImpact"` // basis points (10000 = 100%)
GasEstimate uint64 `json:"gasEstimate"`
Route []string `json:"route"` // pool addresses
FeeTiers []uint32 `json:"feeTiers"`
}
// PositionResponse represents an LP position
type PositionResponse struct {
PositionID string `json:"positionId"`
Owner string `json:"owner"`
PoolAddress string `json:"poolAddress"`
Token0 string `json:"token0"`
Token1 string `json:"token1"`
TickLower int32 `json:"tickLower"`
TickUpper int32 `json:"tickUpper"`
Liquidity *big.Int `json:"liquidity"`
Amount0 *big.Int `json:"amount0"`
Amount1 *big.Int `json:"amount1"`
FeesEarned0 *big.Int `json:"feesEarned0"`
FeesEarned1 *big.Int `json:"feesEarned1"`
ValueUSD *big.Int `json:"valueUSD"` // 18 decimals
InRange bool `json:"inRange"`
}
// =====================================
// Helper Functions
// =====================================
// ParsePriceResponse parses a GraphQL price response
func ParsePriceResponse(data []byte) (*PriceResponse, error) {
var resp struct {
Data struct {
Token struct {
DerivedETH string `json:"derivedETH"`
DerivedLUX string `json:"derivedLUX"`
Symbol string `json:"symbol"`
Decimals int `json:"decimals"`
} `json:"token"`
Bundle struct {
EthPriceUSD string `json:"ethPriceUSD"`
LuxPriceUSD string `json:"luxPriceUSD"`
} `json:"bundle"`
} `json:"data"`
}
if err := json.Unmarshal(data, &resp); err != nil {
return nil, err
}
// Calculate USD price from derivedETH * ethPriceUSD
derivedETH, _ := new(big.Float).SetString(resp.Data.Token.DerivedETH)
ethPrice, _ := new(big.Float).SetString(resp.Data.Bundle.EthPriceUSD)
priceFloat := new(big.Float).Mul(derivedETH, ethPrice)
// Convert to 18 decimal integer
scale := new(big.Float).SetInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil))
priceScaled := new(big.Float).Mul(priceFloat, scale)
priceUSD, _ := priceScaled.Int(nil)
return &PriceResponse{
Symbol: resp.Data.Token.Symbol,
PriceUSD: priceUSD,
Source: "pool",
}, nil
}
// ParsePoolInfoResponse parses a GraphQL pool response
func ParsePoolInfoResponse(data []byte) (*PoolInfoResponse, error) {
var resp struct {
Data struct {
Pool struct {
ID string `json:"id"`
Token0 struct{ Symbol string } `json:"token0"`
Token1 struct{ Symbol string } `json:"token1"`
FeeTier int `json:"feeTier"`
Liquidity string `json:"liquidity"`
SqrtPrice string `json:"sqrtPrice"`
Tick int `json:"tick"`
Token0Price string `json:"token0Price"`
Token1Price string `json:"token1Price"`
TotalValueLockedUSD string `json:"totalValueLockedUSD"`
VolumeUSD string `json:"volumeUSD"`
} `json:"pool"`
} `json:"data"`
}
if err := json.Unmarshal(data, &resp); err != nil {
return nil, err
}
liquidity, _ := new(big.Int).SetString(resp.Data.Pool.Liquidity, 10)
sqrtPrice, _ := new(big.Int).SetString(resp.Data.Pool.SqrtPrice, 10)
return &PoolInfoResponse{
PoolAddress: resp.Data.Pool.ID,
Token0Symbol: resp.Data.Pool.Token0.Symbol,
Token1Symbol: resp.Data.Pool.Token1.Symbol,
FeeTier: uint32(resp.Data.Pool.FeeTier),
Liquidity: liquidity,
SqrtPriceX96: sqrtPrice,
Tick: int32(resp.Data.Pool.Tick),
}, nil
}
// init registers oracle and AMM queries
func init() {
// Add oracle queries to predefined queries
for id, q := range OracleQueries {
PredefinedQueries[id] = q
}
// Add AMM queries to predefined queries
for id, q := range AMMQueries {
PredefinedQueries[id] = q
}
}
+308
View File
@@ -0,0 +1,308 @@
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package graph
import (
"github.com/luxfi/geth/common"
)
// PrecompileRegistry maps precompile addresses to their implementations
// across all Lux chains.
//
// Address Ranges:
// - 0x0001-0x00FF: Standard EVM precompiles (ECRECOVER, SHA256, etc.)
// - 0x0100-0x01FF: Warp/Teleport messaging
// - 0x0200-0x02FF: Chain-specific config (Subnet-EVM style)
// - 0x0300-0x03FF: AI/ML operations
// - 0x0400-0x04FF: DEX operations (Uniswap v4 style)
// - 0x0500-0x05FF: Graph/Query layer
// - 0x0600-0x06FF: Post-quantum cryptography
// - 0x0700-0x07FF: Privacy/Encryption (FHE, ECIES, Ring)
// - 0x0800-0x08FF: Threshold signatures (FROST, CGGMP21, Corona)
// - 0x0900-0x09FF: ZK proofs (KZG, Groth16)
// - 0x0A00-0x0AFF: Reserved for future use
// Precompile address constants
const (
// Standard EVM (0x01-0x09) - already in EVM
// 0x01 = ECRECOVER
// 0x02 = SHA256
// 0x03 = RIPEMD160
// 0x04 = IDENTITY
// 0x05 = MODEXP
// 0x06 = ECADD (BN254)
// 0x07 = ECMUL (BN254)
// 0x08 = ECPAIRING (BN254)
// 0x09 = BLAKE2F
// BLS12-381 (0x0B-0x11) - EIP-2537
BLS12381G1AddAddress = "0x000b"
BLS12381G1MulAddress = "0x000c"
BLS12381G1MSMAddress = "0x000d"
BLS12381G2AddAddress = "0x000e"
BLS12381G2MulAddress = "0x000f"
BLS12381G2MSMAddress = "0x0010"
BLS12381PairingAddress = "0x0011"
// Warp/Teleport (0x0100)
WarpAddress = "0x0100"
// Subnet-EVM Config (0x0200-0x02FF)
DeployerAllowListAddress = "0x0200000000000000000000000000000000000001"
TxAllowListAddress = "0x0200000000000000000000000000000000000002"
FeeManagerAddress = "0x0200000000000000000000000000000000000003"
NativeMinterAddress = "0x0200000000000000000000000000000000000004"
RewardManagerAddress = "0x0200000000000000000000000000000000000005"
// AI/ML (0x0300-0x03FF)
AIMiningAddress = "0x0300"
NVTrustAddress = "0x0301"
ModelRegistryAddress = "0x0302"
// DEX (0x0400-0x04FF) - See dex/types.go for full list
PoolManagerAddress = "0x0400"
SwapRouterAddress = "0x0401"
HooksRegistryAddress = "0x0402"
FlashLoanAddress = "0x0403"
LendingPoolAddress = "0x0410"
PerpetualEngineAddress = "0x0420"
LiquidVaultAddress = "0x0430"
TeleportBridgeAddress = "0x0440"
// Graph/Query (0x0500-0x05FF)
GraphQLQueryAddress = "0x0500"
GraphSubscribeAddress = "0x0501"
GraphCacheAddress = "0x0502"
// Post-Quantum Crypto (0x0600-0x06FF)
MLDSAAddress = "0x0600" // ML-DSA signatures
MLKEMAddress = "0x0601" // ML-KEM key encapsulation
SLHDSAAddress = "0x0602" // Stateless hash-based signatures
PQCryptoAddress = "0x0603" // Multi-PQ operations
QuasarAddress = "0x0604" // Quantum consensus
// Privacy/Encryption (0x0700-0x07FF)
FHEAddress = "0x0700" // Fully Homomorphic Encryption
ECIESAddress = "0x0701" // Elliptic Curve Integrated Encryption
RingAddress = "0x0702" // Ring signatures
HPKEAddress = "0x0703" // Hybrid Public Key Encryption
// Threshold Signatures (0x0800-0x08FF)
FROSTAddress = "0x0800" // Schnorr threshold signatures
CGGMP21Address = "0x0801" // ECDSA threshold signatures
CoronaAddress = "0x0802" // Threshold lattice signatures
// ZK Proofs (0x0900-0x09FF)
KZG4844Address = "0x0900" // KZG commitments (EIP-4844)
Groth16Address = "0x0901" // Groth16 verifier
PlonkAddress = "0x0902" // PLONK verifier
// secp256r1 (P-256) - EIP-7212
P256VerifyAddress = "0x0a00"
)
// ChainPrecompiles defines which precompiles are enabled for each chain
var ChainPrecompiles = map[string][]string{
// A-Chain (Asset Chain) - Token standards, NFTs
"A": {
WarpAddress,
GraphQLQueryAddress, // Query unified layer
},
// B-Chain (Bridge Chain) - Cross-chain messaging
"B": {
WarpAddress,
TeleportBridgeAddress,
GraphQLQueryAddress,
},
// C-Chain (Contract Chain) - Full EVM with all precompiles
"C": {
// All BLS12-381
BLS12381G1AddAddress, BLS12381G1MulAddress, BLS12381G1MSMAddress,
BLS12381G2AddAddress, BLS12381G2MulAddress, BLS12381G2MSMAddress,
BLS12381PairingAddress,
// Warp
WarpAddress,
// Subnet config
DeployerAllowListAddress, TxAllowListAddress, FeeManagerAddress,
NativeMinterAddress, RewardManagerAddress,
// AI
AIMiningAddress, NVTrustAddress,
// DEX
PoolManagerAddress, SwapRouterAddress, HooksRegistryAddress, FlashLoanAddress,
LendingPoolAddress, PerpetualEngineAddress, LiquidVaultAddress, TeleportBridgeAddress,
// Graph
GraphQLQueryAddress, GraphSubscribeAddress,
// PQ Crypto
MLDSAAddress, MLKEMAddress, SLHDSAAddress, PQCryptoAddress,
// Privacy
FHEAddress, ECIESAddress, RingAddress, HPKEAddress,
// Threshold
FROSTAddress, CGGMP21Address, CoronaAddress,
// ZK
KZG4844Address, Groth16Address, PlonkAddress,
// P-256
P256VerifyAddress,
},
// D-Chain (DEX Chain) - Optimized for trading
"D": {
WarpAddress,
// Full DEX suite
PoolManagerAddress, SwapRouterAddress, HooksRegistryAddress, FlashLoanAddress,
LendingPoolAddress, PerpetualEngineAddress, LiquidVaultAddress, TeleportBridgeAddress,
// Graph for queries
GraphQLQueryAddress,
},
// G-Chain (Graph Chain) - Query layer (read-only)
"G": {
GraphQLQueryAddress, GraphSubscribeAddress, GraphCacheAddress,
},
// K-Chain (Keys Chain) - Key management and cryptography
"K": {
WarpAddress,
// PQ Crypto
MLDSAAddress, MLKEMAddress, SLHDSAAddress, PQCryptoAddress, QuasarAddress,
// Privacy
FHEAddress, ECIESAddress, RingAddress, HPKEAddress,
// Threshold
FROSTAddress, CGGMP21Address, CoronaAddress,
// P-256
P256VerifyAddress,
// Graph
GraphQLQueryAddress,
},
// P-Chain (Platform Chain) - Validator and subnet management
"P": {
WarpAddress,
RewardManagerAddress,
},
// Q-Chain (Quantum Chain) - Quantum-safe operations
"Q": {
WarpAddress,
// Full PQ suite
MLDSAAddress, MLKEMAddress, SLHDSAAddress, PQCryptoAddress, QuasarAddress,
// Threshold
CoronaAddress,
// Graph
GraphQLQueryAddress,
},
// T-Chain (Token Chain) - Token transfers and standards
"T": {
WarpAddress,
TeleportBridgeAddress,
GraphQLQueryAddress,
},
// X-Chain (Exchange Chain) - UTXO-based transfers
"X": {
WarpAddress,
},
// Z-Chain (Zoo Chain) - Application chain
"Z": {
WarpAddress,
// DEX
PoolManagerAddress, SwapRouterAddress,
// AI
AIMiningAddress,
// Graph
GraphQLQueryAddress,
},
}
// PrecompileInfo contains metadata about a precompile
type PrecompileInfo struct {
Address string
Name string
Description string
GasBase uint64
Chains []string
}
// AllPrecompiles lists all available precompiles with their metadata
var AllPrecompiles = []PrecompileInfo{
// BLS12-381
{BLS12381G1AddAddress, "BLS12381_G1ADD", "BLS12-381 G1 point addition", 500, []string{"C"}},
{BLS12381G1MulAddress, "BLS12381_G1MUL", "BLS12-381 G1 scalar multiplication", 12000, []string{"C"}},
{BLS12381PairingAddress, "BLS12381_PAIRING", "BLS12-381 pairing check", 115000, []string{"C"}},
// Warp
{WarpAddress, "WARP", "Cross-chain message verification", 50000, []string{"A", "B", "C", "D", "G", "K", "P", "Q", "T", "X", "Z"}},
// AI
{AIMiningAddress, "AI_MINING", "AI model verification and rewards", 100000, []string{"C", "Z"}},
// DEX
{PoolManagerAddress, "POOL_MANAGER", "Uniswap v4-style pool manager", 50000, []string{"C", "D"}},
{SwapRouterAddress, "SWAP_ROUTER", "Optimized swap routing", 10000, []string{"C", "D", "Z"}},
{PerpetualEngineAddress, "PERP_ENGINE", "Perpetual futures engine", 25000, []string{"C", "D"}},
// Graph
{GraphQLQueryAddress, "GRAPHQL_QUERY", "Unified G-Chain GraphQL queries", 5000, []string{"A", "B", "C", "D", "G", "K", "Q", "T", "Z"}},
// PQ Crypto
{MLDSAAddress, "ML_DSA", "NIST ML-DSA post-quantum signatures", 50000, []string{"C", "K", "Q"}},
{MLKEMAddress, "ML_KEM", "NIST ML-KEM key encapsulation", 25000, []string{"C", "K", "Q"}},
{QuasarAddress, "QUASAR", "Quantum consensus verification", 100000, []string{"K", "Q"}},
// Privacy
{FHEAddress, "FHE", "Fully Homomorphic Encryption operations", 500000, []string{"C", "K"}},
{RingAddress, "RING", "Ring signature generation/verification", 50000, []string{"C", "K"}},
// Threshold
{FROSTAddress, "FROST", "Schnorr threshold signatures", 25000, []string{"C", "K"}},
{CGGMP21Address, "CGGMP21", "ECDSA threshold signatures", 50000, []string{"C", "K"}},
{CoronaAddress, "CORONA", "Threshold lattice signatures", 75000, []string{"C", "K", "Q"}},
// ZK
{KZG4844Address, "KZG_4844", "EIP-4844 KZG commitment verification", 50000, []string{"C"}},
}
// GetPrecompileAddress returns the address for a precompile by name
func GetPrecompileAddress(name string) common.Address {
for _, p := range AllPrecompiles {
if p.Name == name {
return common.HexToAddress(p.Address)
}
}
return common.Address{}
}
// GetChainPrecompiles returns all precompile addresses for a chain
func GetChainPrecompiles(chainLetter string) []common.Address {
addrs, ok := ChainPrecompiles[chainLetter]
if !ok {
return nil
}
result := make([]common.Address, len(addrs))
for i, addr := range addrs {
result[i] = common.HexToAddress(addr)
}
return result
}
// IsPrecompileEnabled checks if a precompile is enabled for a chain
func IsPrecompileEnabled(chainLetter string, precompileAddr common.Address) bool {
addrs := ChainPrecompiles[chainLetter]
addrHex := precompileAddr.Hex()
for _, addr := range addrs {
if common.HexToAddress(addr) == precompileAddr {
return true
}
// Also check lowercase
if addr == addrHex || addr == precompileAddr.String() {
return true
}
}
return false
}
+1041
View File
File diff suppressed because it is too large Load Diff
+267
View File
@@ -0,0 +1,267 @@
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// Package graph implements G-Chain GraphQL precompile for Lux EVMs.
// This enables native low-latency GraphQL queries from any EVM chain
// to the unified G-Chain query layer.
package graph
import (
"errors"
)
// Precompile addresses for G-Chain components
// Reserved range: 0x0500 - 0x050F
const (
// G-Chain GraphQL precompile
GraphQLAddress = "0x0500" // Main GraphQL query interface
// Future extensions
GraphSubscribeAddress = "0x0501" // GraphQL subscriptions (future)
GraphCacheAddress = "0x0502" // Query result caching (future)
GraphIndexAddress = "0x0503" // Index management (future)
)
// Gas costs for GraphQL operations
const (
// Query operations
GasQueryBase uint64 = 5_000 // Base cost for any query
GasQuerySimple uint64 = 10_000 // Simple single-entity query
GasQueryComplex uint64 = 25_000 // Complex multi-entity query
GasQueryCrossChain uint64 = 50_000 // Cross-chain aggregation query
// Per-result costs
GasPerEntity uint64 = 1_000 // Per entity in result
GasPerField uint64 = 100 // Per field returned
GasPerByte uint64 = 3 // Per byte of response data
// Mutation operations (admin only)
GasMutationBase uint64 = 100_000 // Base cost for mutations
)
// Query types supported by the precompile
type QueryType uint8
const (
QueryTypeChainInfo QueryType = iota
QueryTypeBlock
QueryTypeAccount
QueryTypeBalance
QueryTypeFactory
QueryTypeBundle
QueryTypeToken
QueryTypeTokens
QueryTypePool
QueryTypePools
QueryTypePair
QueryTypePairs
QueryTypeTicks
QueryTypeSwaps
QueryTypePositions
QueryTypeTimeSeries
QueryTypeCustom
)
// Errors
var (
ErrInvalidQuery = errors.New("invalid GraphQL query")
ErrQueryTooLarge = errors.New("query exceeds maximum size")
ErrQueryTimeout = errors.New("query execution timeout")
ErrChainNotFound = errors.New("chain not found")
ErrUnauthorized = errors.New("unauthorized mutation")
ErrGasExceeded = errors.New("gas limit exceeded for query")
ErrInvalidResponse = errors.New("invalid response format")
)
// Maximum limits
const (
MaxQuerySize = 4096 // Max query string size in bytes
MaxResponseSize = 65536 // Max response size in bytes (64KB)
MaxEntitiesPerQuery = 1000 // Max entities in a single query
MaxQueryDepth = 10 // Max nesting depth
)
// ChainID constants for cross-chain queries
const (
ChainIDLuxMainnet uint64 = 96369
ChainIDLuxTestnet uint64 = 96368
ChainIDZooMainnet uint64 = 200200
ChainIDZooTestnet uint64 = 200201
ChainIDSPCMainnet uint64 = 36911
ChainIDSPCTestnet uint64 = 36910
ChainIDHanzoMainnet uint64 = 36963
ChainIDHanzoTestnet uint64 = 36962
)
// QueryRequest represents a GraphQL query request
type QueryRequest struct {
// Query is the GraphQL query string
Query string
// Variables is a JSON-encoded map of query variables
Variables []byte
// OperationName is the optional operation name
OperationName string
// TargetChains specifies which chains to query (empty = all)
TargetChains []uint64
}
// QueryResponse represents a GraphQL query response
type QueryResponse struct {
// Data contains the query result as JSON
Data []byte
// Errors contains any errors that occurred
Errors []QueryError
// GasUsed is the total gas consumed
GasUsed uint64
}
// QueryError represents a GraphQL error
type QueryError struct {
Message string
Path []string
Locations []Location
}
// Location represents a position in the query
type Location struct {
Line uint32
Column uint32
}
// =====================================
// Pre-defined Query Templates
// =====================================
// Common queries that can be called with minimal gas
// These are optimized paths for frequently used operations
// QueryID represents a pre-defined query
type QueryID uint16
const (
// Chain queries
QueryIDChainInfo QueryID = 0x0001
QueryIDBlockByHash QueryID = 0x0002
QueryIDBlockByNumber QueryID = 0x0003
// Account queries
QueryIDBalance QueryID = 0x0101
QueryIDAccountInfo QueryID = 0x0102
// DEX queries - Factory
QueryIDFactory QueryID = 0x0201
QueryIDBundle QueryID = 0x0202
// DEX queries - Tokens
QueryIDToken QueryID = 0x0301
QueryIDTokens QueryID = 0x0302
QueryIDTokenPrice QueryID = 0x0303
// DEX queries - Pools
QueryIDPool QueryID = 0x0401
QueryIDPools QueryID = 0x0402
QueryIDPoolTicks QueryID = 0x0403
QueryIDPoolDayData QueryID = 0x0404
// DEX queries - Pairs (v2)
QueryIDPair QueryID = 0x0501
QueryIDPairs QueryID = 0x0502
QueryIDPairDayData QueryID = 0x0503
// DEX queries - Positions
QueryIDPosition QueryID = 0x0601
QueryIDPositions QueryID = 0x0602
QueryIDPositionsByOwner QueryID = 0x0603
// DEX queries - Swaps
QueryIDSwaps QueryID = 0x0701
QueryIDSwapsByPool QueryID = 0x0702
QueryIDSwapsByToken QueryID = 0x0703
// Cross-chain queries
QueryIDAllChainsTVL QueryID = 0x0F01
QueryIDAllChainsVolume QueryID = 0x0F02
)
// QueryTemplate defines a pre-optimized query
type QueryTemplate struct {
ID QueryID
Query string
GasCost uint64
MaxArgs int
}
// PredefinedQueries contains all optimized query templates
var PredefinedQueries = map[QueryID]QueryTemplate{
QueryIDChainInfo: {
ID: QueryIDChainInfo,
Query: `query { chainInfo { vmName version readOnly supportedChains } }`,
GasCost: GasQuerySimple,
MaxArgs: 0,
},
QueryIDBalance: {
ID: QueryIDBalance,
Query: `query($address: String!) { balance(address: $address) }`,
GasCost: GasQuerySimple,
MaxArgs: 1,
},
QueryIDFactory: {
ID: QueryIDFactory,
Query: `query { factory(id: "1") { poolCount pairCount txCount totalVolumeUSD totalValueLockedUSD } }`,
GasCost: GasQuerySimple,
MaxArgs: 0,
},
QueryIDBundle: {
ID: QueryIDBundle,
Query: `query { bundle(id: "1") { ethPriceUSD luxPriceUSD } }`,
GasCost: GasQuerySimple,
MaxArgs: 0,
},
QueryIDToken: {
ID: QueryIDToken,
Query: `query($id: String!) { token(id: $id) { id symbol name decimals volumeUSD totalValueLockedUSD derivedETH } }`,
GasCost: GasQuerySimple,
MaxArgs: 1,
},
QueryIDTokens: {
ID: QueryIDTokens,
Query: `query($first: Int, $orderBy: String) { tokens(first: $first, orderBy: $orderBy) { id symbol name volumeUSD totalValueLockedUSD } }`,
GasCost: GasQueryComplex,
MaxArgs: 2,
},
QueryIDPool: {
ID: QueryIDPool,
Query: `query($id: String!) { pool(id: $id) { id token0 { symbol } token1 { symbol } feeTier liquidity sqrtPrice tick volumeUSD totalValueLockedUSD } }`,
GasCost: GasQuerySimple,
MaxArgs: 1,
},
QueryIDPools: {
ID: QueryIDPools,
Query: `query($first: Int) { pools(first: $first) { id token0 { symbol } token1 { symbol } feeTier volumeUSD totalValueLockedUSD } }`,
GasCost: GasQueryComplex,
MaxArgs: 1,
},
QueryIDPositions: {
ID: QueryIDPositions,
Query: `query($owner: String!) { positions(where: { owner: $owner }) { id tokenId pool { id } tickLower tickUpper liquidity } }`,
GasCost: GasQueryComplex,
MaxArgs: 1,
},
QueryIDSwaps: {
ID: QueryIDSwaps,
Query: `query($first: Int) { swaps(first: $first, orderBy: timestamp, orderDirection: desc) { id timestamp amount0 amount1 amountUSD pool { token0 { symbol } token1 { symbol } } } }`,
GasCost: GasQueryComplex,
MaxArgs: 1,
},
QueryIDAllChainsTVL: {
ID: QueryIDAllChainsTVL,
Query: `query { allChains { chainId tvlUSD poolCount } }`,
GasCost: GasQueryCrossChain,
MaxArgs: 0,
},
}