Commit Graph
60 Commits
Author SHA1 Message Date
zeekayandHanzo Dev 84a4bdf91e perf(indexer): bound the swap history one valuation pass reads
The previous commit stopped the pass WRITING a row per swap. It still READ
every swap row in the table, every 30 seconds, into a map.

That is the same shape of mistake one layer down. A live chain's swap table
grows without limit — the Lux C-Chain's already spans blocks 53..1,096,496 in
a 732 MB store — so the cost of a pass grows with chain age forever, and the
allocation churn lands on a process sharing 4Gi with six other chains.

storage.SwapsRaw is replaced by RecentSwapsRaw(limit), which uses the indexed
timestamp column to take the newest `limit` rows in SQL rather than filtering
in Go. The pass takes the newest 50,000.

Where that bound binds, the volume figure is the volume of those 50,000 trades
and the log line says so outright. A partial sum silently presented as a total
is worse than a smaller number that is honest about its window.

Co-authored-by: Hanzo Dev <[email protected]>
v1.2.12
2026-07-26 18:42:27 -07:00
zeekayandHanzo Dev 01aa717953 fix(indexer): valuation must be O(pools) writes, and V3 amounts are signed
Deployed v1.2.10 to a six-chain explorer and watched one chain produce
aggregates while two others produced nothing at all — no result line, no error
line. Two distinct defects, both found by that silence.

1. The pass wrote O(swaps) rows per interval.

   valueSwaps rewrote every swap's own amountUSD, one serialized INSERT OR
   REPLACE each, every 30s. A chain with a real trade history never finished a
   pass, so it never wrote its pool/factory aggregates either — while a quiet
   chain beside it looked perfectly healthy. Volume is a per-pool rollup and
   belongs on the pool: valueSwaps now READS the swap rows and writes none.
   (Per-swap amountUSD stays "0". It is a separate gap, and the honest fix
   values a swap at the price of its OWN block, not at today's.)

2. A V3 Swap emits int256, and the handler read it unsigned.

   One leg of every V3 swap is negative — the token leaving the pool. Reading
   it unsigned persisted ~2^256 in place of a small negative number. Nothing
   had ever added those amounts up, so the corruption was invisible until the
   volume rollup landed and reported $4.07e72 of trading on Zoo.

   handleSwapV3 now uses decodeInt256, the same decoder the V4 handler already
   used for the same reason. Rows the old build already wrote are healed on
   read rather than by a re-index: a stored leg at or above 2^255 IS the
   two's-complement encoding of a negative int256, and the V2 handler's
   difference of two uint112 reserves can never reach that magnitude, so the
   boundary is unambiguous.

Both were invisible for the same reason, so the third change is observability:

  - Config.Label names the indexer ("cchain/amm") and every indexer log line
    now carries it. One process runs seven of these; a line that does not say
    whose it is cannot be acted on.
  - Every revalue exit logs, including "read no balances", and the result line
    reports valued/total pools and elapsed time. An indexer that reports
    nothing was indistinguishable from one that was never scheduled.
  - Each pass runs under a 60s budget, so a pass that cannot finish is
    cancelled and says so instead of wedging its chain forever.

Tests pin all three: the wrapped-negative leg valuing identically to the signed
one, handleSwapV3 persisting "-2500", and revalue leaving swap rows untouched.

Co-authored-by: Hanzo Dev <[email protected]>
v1.2.11
2026-07-26 18:38:23 -07:00
zeekayandHanzo Dev 1015359a85 feat(indexer): valuation pass — derive AMM TVL, prices and volume from chain state
Every USD field the exchange reads was an empty string. `pools`, `tokens` and
`factories` all resolved — with real addresses, real symbols, real fee tiers —
and then reported totalValueLockedUSD:"", volumeUSD:"", token0Price:"". The
landing page's TVL / 24h-volume / active-pool header had nothing to render, so
it rendered nothing.

Nothing was ever writing those fields. processLog's Sync/Mint/Burn arm was an
explicit no-op ("storage for these types not yet wired"), and bumpFactory's
comment deferred the USD aggregates to a "price oracle / day data" that does not
exist. Sync is the only event carrying V2 reserves, so with it inert there was
no path — at any block height — from the chain to a TVL number.

Fixed by adding the missing concern rather than by decoding one more event:

  indexer/valuation.go is the ONE owner of the derived USD aggregates. It reads
  balanceOf(pool) for both legs of every registered pool in a single JSON-RPC
  batch, anchors stablecoins at $1 by symbol, and relaxes prices outward through
  the pool graph — each unknown token taking its quote from the DEEPEST pool
  that already has a priced side, which is both deterministic and the least
  manipulable choice when pools disagree. A token no path connects to a stable
  stays unpriced and contributes nothing: unknown is reported as unknown.

Reserves are chain STATE, not chain HISTORY, so this is a pass beside the log
poller, not a handler inside it. That distinction is the whole point:

  - Sync exists only on V2. balanceOf answers the same question for V2, V3 and
    V4 identically.
  - An event-sourced TVL only converges by replaying all history, and a pool
    whose last Sync is a million blocks back reads empty until it trades again.
    On an idle chain it never trades again.
  - It is one fact, so it gets one writer. The Sync/Mint/Burn arm stays inert on
    purpose and now says why.

poolCount moves to the same pass for the same reason: it is derived from the
store, not accumulated by the create handlers, so it can no longer drift across
a restart, a re-index or a duplicate create. bumpFactory keeps the one field
that genuinely is a running total of events — txCount.

Fails closed: an unreachable RPC aborts the pass rather than overwriting good
aggregates with zeros.

Tests: valuation_test.go drives a stub RPC shaped like the live mainnet book —
a stablecoin pair anchoring a WLUX pair — and asserts derived TVL, spot prices,
per-token TVL, factory poolCount, the deeper-quote rule, non-clobbering of
fields the pass does not own, and the RPC-blip guard. Full suite green.

Co-authored-by: Hanzo Dev <[email protected]>
v1.2.10
2026-07-26 18:20:23 -07:00
zeekay 1e934c363d fix(indexer): bind clean BASE/QUOTE pair symbol + assetsBound on 0x9999 Initialize
handleInitializeV4 now sets the DEX Market symbol to the human BASE/QUOTE pair
(from the two currencies' ERC20 symbols) and marks assetsBound=true when both
resolve to a clean symbol. This is the exact shape the public exchange-api
real-asset gate (dexMarkets.ts isStructurallyReal) requires: without it every
native 0x9999 market was stripped (poolId-hex symbol failed the clean-pair check)
and the markets surface was empty despite real on-chain DEXFills. A token with no
identifiable symbol yields no pair -> the market stays unbound and hidden.

One place computes a market's display identity, read by every downstream surface
(explorer /dex, exchange-api gate, FE). New TDD: BindsCleanPairSymbol + UnnamedTokenStaysUnbound.
v1.2.9
2026-06-28 22:07:41 -07:00
zeekay 61ec197a34 fix(indexer): clob_get_* -> dex_get_* to match D-Chain read RPC (red H1)
The D-Chain read surface (luxfi/dex pkg/dchain/read.go:50-53) serves
dex_get_{markets,trades,orders,book}; the CLOB source still called the old
clob_get_* names -> 404 -> empty dex subgraph while real fills matched
on-chain (lux.exchange showed no markets though the chain was correct).

Proven: GOWORK=off go test ./indexer/ -run TestCLOB green.
v1.2.8
2026-06-25 15:52:07 -07:00
zeekay 9e363a5913 chore(deps): fix phantom go-sqlite3 v2.0.3 pin -> v1.14.47 + regen go.sum
go-sqlite3 v2.0.3+incompatible is a deleted upstream tag (unknown revision),
breaking every standalone graph build. Pin to v1.14.47 (latest v1.14 patch;
the cgo driver store_sqlite.go imports). Regenerate go.sum first-party hashes
stale from the org tag re-move (luxfi/age etc.).
2026-06-25 15:52:07 -07:00
zeekay 27d1b84235 feat(indexer): native D-Chain CLOB source for the dex subgraph
The dex subgraph indexer only consumed EVM 0x9999 settlement logs (the
cross-chain settlement view). On a native-DEX deployment the trade engine
IS the D-Chain (dexvm): a trade is a consensus state transition matched at
Block.Verify, not an EVM event, so native fills never appear on the EVM RPC
and the dex subgraph stays empty (markets:null).

Add CLOBSource (indexer/clob.go): an orthogonal, READ-ONLY poller of the
D-Chain committed-state read RPC clob_get_{markets,trades,orders} that writes
the same Market/Fill/Order entities the existing dex resolvers serve. Enabled
by Config.DexRPC; empty preserves EVM-only behaviour. The two sources share
only the store and the entity shapes, so this is purely additive — the amm
(EVM) subgraph is untouched.

- markets <- clob_get_markets (per-market authoritative book summary; bound-
  market hex symbol decoded to its human pair, e.g. LUX/LUSD)
- fills   <- clob_get_trades?since=<h> (global height-ordered log; keyed
  height:seq -> idempotent; incremental by accepted height)
- orders  <- clob_get_orders?market=<id> (resting book per market)

Tests (httptest doubles serving the exact read.go JSON shapes captured live
from lux-devnet): markets/trades/orders ingest + symbol decode, incremental
cursor + idempotent re-read, and EVM-AMM no-regression with DexRPC set.
v1.2.7
2026-06-22 15:48:53 -07:00
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