53 Commits
Author SHA1 Message Date
zeekay 8c24d384da feat(indexer): enrich AMM token symbol/name/decimals from ERC20
Token entities were seeded with placeholder metadata (symbol=addr[:8],
name=full address, decimals=18) — no contract read happened, so the AMM
graph returned every token as its own address. Add erc20.go: read
symbol()/name()/decimals() via the existing eth_call RPC (canonical ABI
string + legacy bytes32 fallback, garbage-decimals guard), memoised once
per token (revert→placeholder cached too, never re-probed). Route all four
seed sites through a cache-first seedToken with a cold-start no-downgrade
guard. BackfillTokens (opt-in BACKFILL_TOKENS=1) enriches existing
placeholder rows in place — ≤3 eth_calls per token, no re-sync.
v1.2.6
2026-06-21 23:52:42 -07:00
zeekay 705e38c45e fix(indexer): gate V2/V3 AMM handlers to canonical factory; floor parseLimit everywhere
Red re-verify found the V4 AMM-spoof gate left a parallel bypass.

MEDIUM — V2/V3 AMM handlers were UNGATED: handlePairCreated, handlePoolCreated,
handleSwapV2, handleSwapV3 accepted events from ANY emitter — a parallel path to
seed phantom pairs/pools/swaps and inflate the SAME public Factory/TVL/volume
aggregates the now-gated V4 handlers (0x9999) block. Mirror the V4 gate:
  - PairCreated/PoolCreated now require the canonical FactoryV2/FactoryV3 emitter
    (the AMM trust root), exactly as V4 requires 0x9999.
  - V2/V3 Swaps are emitted by the pair/pool, not the factory, so the gate is
    "is the emitter a pool the canonical factory created?" (isKnownPool). The
    factory authorizes a pool; only that pool's Swaps are honored. A rogue
    factory's PairCreated is rejected, so its pools are never registered, so its
    Swaps are rejected — the whole parallel path is closed.
  - Pair/pool keys lower-cased at seed so the Swap-side lookup is RPC-casing safe.
  - Factory addresses configurable (Config.FactoryV2/V3 + FACTORY_V2/V3 env),
    default to canonical Lux mainnet (LuxMainnet.Factory{V2,V3}); main wires env.

INFO — the per-namespace resolver limit lacked the `if limit < 1 { limit = 100 }`
floor that resolvers/dex has, so a negative/zero `first` flowed to ListByType
(`first:-1` = "no limit" in SQLite — an unbounded scan). Brought every pl()/
parseLimit() copy to the dex-canonical body (floor <1->100 + cap 1000); fhe and
platform also gained the previously-missing 1000 cap. All namespaces now identical.

Tests (go test ./...): indexer + resolvers/{dex,exchange,fhe,platform} green.
  - TestHandleV2_RejectsNonFactory, TestHandleV3_RejectsNonFactory: rogue
    PairCreated/PoolCreated/Swap seeds nothing and does not inflate the factory
    aggregate; the canonical-source event IS honored end-to-end.
  - TestPL_ClampsFirst / TestParseLimit_ClampsFirst (exchange/fhe/platform):
    negative/zero floored to 100, capped at 1000.
v1.2.5
2026-06-21 20:27:48 -07:00
zeekay c2bd4165e6 fix(indexer): scope V4 Initialize/Swap to 0x9999, guard poller, cap DEX first
Three confirmed findings in the explorer/graph indexer:

- MEDIUM: handleInitializeV4/handleSwapV4 seeded AMM pools/tokens/swaps from
  ANY emitting contract, so any contract could emit lookalike V4 events to
  create phantom pools/tokens and inflate the explorer's public TVL/volume
  aggregates. Gate both to the canonical 0x9999 PoolManager (idx.isPoolManager),
  mirroring handleDEXFill. The now-always-true inner Market guard in
  handleInitializeV4 is de-nested (one path).

- LOW (DoS): unguarded fixed-offset slices (token0[:8], l.Address[:8]) panic on
  a short/malformed RPC log, and the poll goroutine had no recover() -> one bad
  log crashed graphd. Route those symbol slices through the length-checked
  shortAddr helper, and wrap each poll in pollGuarded() which recovers any panic
  into an error so the loop continues.

- LOW (query-DoS): resolvers/dex parseLimit had no max cap. Clamp <1 -> 100 and
  cap min(limit, 1000), matching every other resolver namespace.

Tests:
- TestHandleV4_RejectsNonPoolManager: rogue Initialize/Swap seeds nothing; the
  same event from 0x9999 is honored.
- TestPoll_MalformedLogDoesNotCrash: malformed logs don't panic processLog, and
  pollGuarded converts a poll panic into an error.
- TestParseLimit_Caps: default 100, floor 1->100, hard cap 1000.
2026-06-21 18:25:55 -07:00
zeekay 600ee3dca3 ci: route docker.yml to lux-build ARC + drop QEMU arm64 (amd64-only)
The classic [self-hosted, linux, amd64] triple is serviced by fleet arcd hosts
that are not reliably available (v1.2.3 queued 30+ min). Use the in-cluster
lux-build autoscalingrunnerset (same as node + exchange-api). amd64-only — QEMU
arm64 pushed builds to ~2h. Artifact identical to v1.2.3; CI-plumbing only.
v1.2.4
2026-06-21 15:01:20 -07:00
zeekay 223316ec3b docs(LLM.md): native 0x9999 DEX indexing + two-exchange-api-image topology 2026-06-21 14:34:02 -07:00
zeekay b87f7805bb Merge fix/native-dex-indexing: native 0x9999 V4/DEXFill indexing + dex/amm subgraphs + re-genesis self-heal v1.2.3 2026-06-21 14:29:34 -07:00
zeekay d24bd62198 graph/indexer: gate re-genesis rewind on a deterministic genesis-hash change
Item 4: the 3-consecutive-poll hysteresis alone could be satisfied by a deeply-stale
load-balanced RPC backend held >reorgDepth behind for the full window (~6s), wiping a
still-canonical chain and re-indexing from genesis (DoS amplification).

Keep the streak as a CHEAP PRE-FILTER, but gate the actual rewind on a deterministic
signal: the chain's genesis (block 0) hash. Every node serves block 0 regardless of
how far behind its head is, so an unchanged genesis hash deterministically rules out
a re-genesis even on a deeply-lagging backend (unlike a cursor by-number/by-hash probe,
which a backend whose head is below the cursor cannot serve and would false-trip).
Honors the no-eth_getCode rule (only eth_getBlockByNumber 0x0 header is read). The
probe is a struct field (genesisHashFn) so tests drive canonicality without a live RPC;
baseline captured lazily before any reset decision. Fail-closed: a probe error or
missing baseline never wipes.

3 existing regenesis tests updated to the new signature/semantics + 3 new
(deeply-behind-but-canonical => NO wipe; changed genesis => wipe; probe-fails => NO
wipe). Full indexer+engine suites green.
2026-06-21 13:51:33 -07:00
zeekay 305636ac07 graph: re-genesis hysteresis + preserve factory TVL/volume + rich-market merge
Red MEDIUM (FIX C): maybeResetForRegenesis rewound to StartBlock on the FIRST poll
where head << cursor, so an idle chain (eth_blockNumber=0x0, 'Building block') or a
briefly-lagging RPC backend triggered a full re-index from genesis (DoS amplification).
Add hysteresis: require the low head to persist across regenesisConfirmations
consecutive polls; a recovered/normal head clears the streak. A genuine relaunch holds
low for many polls; a transient dip recovers in one or two.

Red MEDIUM: bumpFactory wrote SeedFactoryData with empty TVL/volume, and SeedFactory is
INSERT OR REPLACE, so every pool-create/swap clobbered totalVolumeUSD/totalValueLockedUSD
(emptying the landing-page header). Carry both USD aggregates through the
read-modify-write (asString helper).

Red LOW: handleInitializeV4 now MERGES with any volume stub a prior fill accumulated
(don't reset volume24h/tradeCount to 0 when enriching with the token pair/fee).
decodeUint256 guards the SetString ok bool (malformed hex -> clean 0, not a half-parsed
amount).

Tests: regenesis requires sustained low head; idle-low-head-that-recovers does NOT wipe;
shallow reorg no reset; Initialize builds a rich Market (pair+fee), merges stub volume;
bumpFactory preserves TVL/volume; decodeInt256 signed. New engine end-to-end: the dex
schema resolves the FE markets/fills query shapes against indexed entities, amm does NOT
(the exchange-api routing rationale, mirroring Red's live finding). Full graph suite
green (CGO_ENABLED=1).
2026-06-21 13:15:52 -07:00
zeekay ed9e132af8 fix(dex): wire native 0x9999 V4/DEXFill indexing + uniswapFactories alias + re-genesis self-heal
- indexer: handleSwapV4 (AMM swap/pool), handleInitializeV4 (pool/Market/factory),
  handleDEXFill (sole CLOB Fill source, scoped to 0x9999), bumpFactory, signed int128 decode
- indexer: poll() re-genesis self-heal (head<<cursor by >reorgDepth => rewind to StartBlock)
- indexer: correct SigInitializeV4/SigModifyLiquidity hashes; add SigDEXFill + LXSettleAddress
- engine: uniswapFactory(ies) alias resolvers (single-source schema-delta fix)
- tests: dex_v4_test (V4/Fill/regenesis/scoping), e2e dex_native_test (dex schema + alias)
- fix pre-existing e2e/wasm_test.go missing os import
2026-06-21 12:26:11 -07:00
zooqueenandHanzo Dev 5783d1167f docs: tidy LLM.md indexes; CLAUDE.md -> LLM.md symlink convention
Co-authored-by: Hanzo Dev <[email protected]>
2026-06-17 09:54:03 -07:00
zeekay 3e916c59b5 corona→corona: academic Corona now only in lp-220-p3q-corona 2026-06-11 10:28:03 -07:00
zeekay 920dea4d2d scrub Liquidity branding + corona→corona (OSS brand hygiene) 2026-06-10 23:36:13 -07:00
zeekay f16ffb8082 ci: route to canonical native arcd labels [self-hosted, linux, <arch>]
Replaces non-canonical scale-set / org-prefixed labels with the
existing labels every arcd host registers with. Matches evo for
amd64 and spark for arm64. No new labels added.
2026-06-10 20:22:19 -07:00
zeekay 26463e3afd deps: bump Go to 1.26.4 across go.mod, Dockerfiles, GH Actions
Workspace-wide sync. luxfi/node already shipped on 1.26.4 in v1.30.6
(commit 121aca1fa9); this is the cross-repo catch-up.
2026-06-07 10:45:10 -07:00
zeekay 1c5bbea6f4 go: 1.26.3 → 1.26.4 (security: crypto/x509, mime, net/textproto) 2026-06-06 22:09:24 -07:00
zeekay a211263b30 WIP: session checkpoint 2026-06-05 (codec rip in flight) 2026-06-05 15:33:54 -07:00
zeekay f04061d5fa fix: gofmt -s across repo (CI format check) 2026-06-02 11:38:29 -07:00
zeekay 21683d2393 merge: feat-ql-alias 2026-06-01 16:34:48 -07:00
zooqueenandHanzo Dev 050748ea4e Add agent project docs (CLAUDE.md, LLM.md)
Co-authored-by: Hanzo Dev <[email protected]>
2026-05-31 21:57:56 -07:00
zeekay a146c834aa chore: brand-neutral cleanup — remove cross-tenant references 2026-05-25 15:13:54 -07:00
zeekay 738544d4da drop hardcoded /Users/z paths — use $HOME-relative 2026-05-21 15:01:37 -07:00
zeekay 65bf5c2f83 ci: switch workflows to lux-build (luxfi-scoped ARC pool)
Cross-org runs-on dispatch failure: hanzo-build-linux-amd64 scale set is
registered to github.com/hanzoai and silently rejects luxfi/* jobs.
Switch to lux-build (githubConfigUrl=github.com/luxfi, max 20).
2026-05-19 13:21:06 -07:00
zeekay 1270e76233 ci: fix runner label (hanzo-build pool)
Imaginary runner label `lux-build-linux-amd64` does not exist. The live
amd64 pool is `hanzo-build-linux-amd64`.

- docker.yml: docker job
2026-05-19 08:03:38 -07:00
zeekayandGitHub 449a3c0478 chore: bump Go toolchain to 1.26.3 (#4)
Pin Go version to 1.26.3 across go.mod, CI workflows, and Dockerfiles
for canonical alignment with the rest of the luxfi/* stack.
2026-05-16 16:43:20 -07:00
zeekayandGitHub c8e3c07730 chore: add LICENSE (Lux Ecosystem License v1.2) + LICENSING.md pointer (#3)
* chore: add Lux Ecosystem License v1.2

* docs: add LICENSING.md pointer to canonical IP/licensing strategy
2026-05-16 10:47:36 -07:00
zeekay e5143ccf54 go.mod: bump go directive to 1.26.3 (security advisory) 2026-05-12 21:29:51 -07:00
zeekay 007cb9d837 ci(docker): go build -mod=mod populates go.sum on the fly 2026-05-05 21:53:54 -07:00
zeekay b821f244b2 ci: drop ci.yml — Docker workflow handles cgo build via alpine 2026-05-05 21:51:17 -07:00
zeekay 19a7c28927 ci: ARC has no_new_privs (no sudo); copy . . before mod download 2026-05-05 21:44:09 -07:00
zeekay ce9276fce5 ci: regenerate go.sum at build time (proxy cache inconsistency) 2026-05-05 21:34:15 -07:00
zeekay d98d95c40b ci: refresh go.sum (proxy hash drift), install gcc on ARC runner 2026-05-05 21:13:22 -07:00
zeekay 4e30001132 ci: align with luxfi org's actual ARC pool (lux-build-linux-amd64) 2026-05-05 21:04:27 -07:00
zeekay ce7bc9830e ci(docker): inline multi-arch build, drop cross-org reusable 2026-05-05 21:00:17 -07:00
zeekay 8508374fbf refactor: rename cmd/graph → cmd/graphd, hanzo runners
Daemon naming convention: standalone binary is graphd. The library
package (engine, indexer, storage, resolvers) keeps the import path
github.com/luxfi/graph for use by the unified luxfi/explorer binary
and external consumers.

- cmd/graphd/                        renamed (was cmd/graph/)
- Dockerfile                         builds /usr/local/bin/graphd
- Makefile                           bin/graphd target
- .github/workflows/docker.yml       multi-arch + hanzo ARC runners
- .github/workflows/ci.yml           hanzo runner
- .github/actionlint.yaml            register custom runner labels
2026-05-05 20:45:54 -07:00
zeekayandGitHub 2b5501c5db feat: /ql alias for /graphql (POST + GET GraphiQL) (#2)
Less-typing canonical short path. With GRAPH_PREFIX=/v1/graph the
binary now serves both /v1/graph/graphql and /v1/graph/ql. Same
handlers, same payload shape.
2026-05-04 10:29:18 -07:00
zeekay 39371f8812 feat: /ql alias for /graphql (POST + GET GraphiQL)
Less-typing canonical short path. With GRAPH_PREFIX=/v1/graph the
binary now serves both /v1/graph/graphql and /v1/graph/ql. Same
handlers, same payload shape.
2026-05-04 10:28:57 -07:00
zeekay 3c955dcb34 indexer: full ERC-3643 + ONCHAINID event ingestion
Adds the missing topic0 signatures + handlers so the resolvers under
resolvers/securities/ + resolvers/identity/ are actually fed live data:

  events.go (new constants):
    - IToken: AddressFrozen, TokensFrozen, TokensUnfrozen, Paused, Unpaused,
              RecoverySuccess, UpdatedTokenInformation,
              IdentityRegistryAdded, ComplianceAdded
    - IdentityRegistry / IdentityRegistryStorage:
              IdentityRegistered/Removed/Updated, CountryUpdated, IdentityStored
    - ONCHAINID (ERC-734/735):
              ClaimAdded/Removed/Changed, KeyAdded/Removed,
              Approved (exec), Executed (exec)
    - TrustedIssuersRegistry / ClaimTopicsRegistry:
              TrustedIssuerAdded/Removed, ClaimTopicsUpdated,
              ClaimTopicAdded/Removed
    - ModularCompliance + IModule:
              ModuleAdded/Removed, TokenBound/Unbound, ModuleInteraction
    - SecuritiesTopics() returns the full set, appended into knownTopics().

  indexer_securities.go (new):
    - Per-event handlers writing structured entities through Store.SetEntity.
    - Entity types match the resolver expectations:
        SecurityTransfer, TransferAgentAction, FrozenAccount, FrozenTokens,
        IdentityRegistryAction, OnchainIdClaim, OnchainIdKey, ComplianceAction,
        TrustedIssuerAction, ClaimTopicAction, SecuritiesEvent.
    - Decoders for indexed bool / uint256 / address topics.

  indexer.go (processLog dispatch):
    - Adds case branches for each new topic0 to the appropriate handler.

Result: any deployed @luxfi/contracts SecurityToken (T-REX), IdentityRegistry,
ONCHAINID, TrustedIssuersRegistry, ClaimTopicsRegistry, or ModularCompliance
contract is now indexed by `graph` out of the box, queryable via the existing
GraphQL resolvers — no per-deployment manifest needed.

Build: go build ./indexer/... → exit 0
2026-04-28 18:32:01 -07:00
zeekay ee2deb21c4 merge: lux-graph-subgraphs-update-2026-04-28 (fhe+securities resolver upgrades) 2026-04-28 13:37:18 -07:00
zeekay f455dd6e78 feat(resolvers): add ERC-3643 + ONCHAINID + FHE policy surfaces
- securities: add OnchainIdClaim, TransferAgentAction, FrozenAccount,
  FrozenTokens, IdentityRegistryAction resolvers covering ERC-3643 transfer-
  agent / compliance / identity-registry workflow plus ONCHAINID claim
  lifecycle (ClaimAdded/Removed/Changed). Wires #258.
- fhe: add FHEPolicy and FHEPolicyBinding resolvers so the indexer can expose
  encrypted-policy descriptors anchored on M-Chain and their bindings to on-
  chain resources per LP-114 M-Chain × F-Chain integration.
- STATE.md: per-subgraph inventory + status, sibling subgraph repo state,
  build/deploy notes, follow-on work (event-signature constants, storage
  type registration, erc3643 alias, LoadConfig TODO).
2026-04-28 13:31:26 -07:00
zeekayandGitHub 92e99d924a ci: migrate to canonical docker-build reusable (#1)
- Add docker.yml using hanzoai/.github/.github/workflows/docker-build.yml@main
- Add workflow-sanity.yml to enforce canonical CI contract
- Remove bespoke docker build steps from existing workflows

Refs: hanzoai/.github canonical Docker CI contract.
2026-04-23 19:12:18 -07:00
zeekay 92ae685826 ci: migrate to canonical docker-build reusable
- Add docker.yml using hanzoai/.github/.github/workflows/docker-build.yml@main
- Add workflow-sanity.yml to enforce canonical CI contract
- Remove bespoke docker build steps from existing workflows

Refs: hanzoai/.github canonical Docker CI contract.
2026-04-23 19:09:16 -07:00
zeekay 971593e47d ci: docker multi-arch build + semver release workflow 2026-04-16 14:15:33 -07:00
zeekay e7e1a95cf8 docs: update comment reference node/vms/graphvm → chains/graphvm 2026-04-13 05:27:19 -07:00
zeekay f0a5411f10 fix: cap GraphQL pagination to 1000 items per page
Prevents OOM from unbounded first:999999999 queries.
All 24 resolver pl() functions + engine.resolveBlocks capped via min(limit, 1000).
2026-04-13 03:11:36 -07:00
zeekay 6498b67284 fix: default prefix /v1/explorer (not /v1/graph) 2026-04-13 01:24:22 -07:00
zeekay 1005133987 feat: configurable prefix — standalone /v1/graph, unified /v1/explorer/graphql 2026-04-13 01:16:38 -07:00
zeekay cfb7f3ee6f graph: add utxo + zk + mpc resolvers for full 15-chain coverage
graph had resolvers for 10 of 15 platform chains. This adds the three
missing ones:

- resolvers/utxo/: X-Chain (XVM) — UTXO, Asset, AssetCreateTx, UTXOBalance
- resolvers/zk/:   Z-Chain (ZKVM) — ZKProof, Verifier, CircuitHash, ProofBatch, ZKSession
- resolvers/mpc/:  M-Chain (MPC)  — SigningSession, KeygenSession, SignerSet, Presignature, SignRequest

Registered in engine.go under "utxo", "zk"/"zchain", "mpc"/"mchain"
selectors and added to the "all" batch. Removed the duplicate
"zchain" alias from "privacy" (privacy is a cross-chain protocol, not
Z-Chain — Z-Chain is ZK proofs, now correctly wired to zk.Register).

Now graph supports the same 15 platform chains as indexer:
P, X, C, A, B, D, G, I, K, M, O, Q, R, T, Z.
2026-04-12 22:42:05 -07:00
zeekay 1c5f1f2568 feat: Liquidity Protocol + Liquid Protocol graph resolvers
Liquidity Protocol resolvers:
- CrossChainSwap, LimitOrder, Arbitrage
- OMAPool, OMASwap, PriceUpdate
- StrategyOrder, MarketMaker, BridgeTransfer

Liquid Protocol resolvers:
- LiquidFee, ValidatorReward, SlashingEvent
- DepositMint, YieldMint, WithdrawBurn
- BackingUpdate, VaultStrategy, YieldHarvest

Both registered in engine under 'liquidity', 'liquid-protocol', and 'all'.
2026-04-12 11:48:05 -07:00
zeekay 72147a0672 feat: 8 new graph resolvers — governance, DAO, treasury, liquid, DID, prediction, securities, derivatives (84 tests) 2026-04-12 11:34:18 -07:00
zeekay f85d32cd62 test: comprehensive resolver tests for all 18 VM schema types (1354 lines) 2026-04-12 10:33:55 -07:00