Skip to content

release: envio 3.0.2-svm-alpha.2 (SVM block-time on published client 0.0.5)#1262

Open
JasoonS wants to merge 13 commits into
solana-instruction-basicsfrom
release/v3.0.2-svm-alpha.2
Open

release: envio 3.0.2-svm-alpha.2 (SVM block-time on published client 0.0.5)#1262
JasoonS wants to merge 13 commits into
solana-instruction-basicsfrom
release/v3.0.2-svm-alpha.2

Conversation

@JasoonS
Copy link
Copy Markdown
Contributor

@JasoonS JasoonS commented Jun 1, 2026

Release branch for cutting the 3.0.2-svm-alpha.2 npm alpha. Not intended to merge; it exists to get a green Build & Verify on the release commit so the tag-publish reuses that artifact.

Contents = the hack28/svm-block-time work (block_time on handlers, v0.0.4 balances + chunk caps, include_token_balances config fix) made self-contained:

  • Dropped the [patch.crates-io] local-path override from the root Cargo.toml.
  • Bumped hypersync-client-solana / hypersync-solana-net-types to 0.0.5 (published 0.0.4 plus reqwest rustls-tls-native-roots, the TLS fix for Let's Encrypt R13 certs).

Stacked on solana-instruction-basics (#1241) for a clean delta diff. cargo check is clean against the registry locally.

JasoonS and others added 12 commits May 28, 2026 15:40
…ept null definedTypes

Two fixes to the Solana instruction-indexer (found building the Flow X-Ray demo):

1. IDL-decoded programs got empty args/accounts and never registered a decode
   schema. resolve_program_schema parsed the Anchor IDL but kept only
   defined_types, discarding the per-instruction schemas; lookup_program_schema
   returned None for AnchorIdl. So resolve_instruction_layout's disc lookup never
   matched and every idl: instruction fell through to empty -> codegen emitted
   `args: {}` and the runtime registered no schema (decode returned None). Now
   SvmAbi carries an owned `instructions` map (populated for both AnchorIdl and
   Bundled) and resolve_instruction_layout looks it up directly.

2. Inline-schema programs send `definedTypes: null` in the program schema
   descriptor; the Rust `#[serde(default)]` accepts an absent field but not an
   explicit null ("expected a map"), crashing schema registration. Coalesce null
   to {} in HyperSyncSolanaSource.buildSchemaHandles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Indexes Jupiter / Kamino / Drift / Raydium Solana instructions (is_inner unset)
so each tx's CPI tree + cross-protocol edges reconstruct in SQL views. Flat
append-only entities (InstructionNode / TokenDelta / FlowTx / LiquidationEvent /
IndexerStats) keyed by txSig + instructionAddress; aggregation lives in
sql/views.sql. IDL programs carry explicit Anchor discriminators (legacy IDLs
have none). SPL-Token/System dropped from the matched set (volume); value comes
from transaction.tokenBalances. Includes idls/, sql/views.sql + apply-views.sh,
and a live vitest against a pinned slot window.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Drift program_id was a vanity-address lookalike ending in ...ozatL,
which matches no program on-chain, so the instruction filter returned zero
Drift instructions on every endpoint. Replace with the real Drift v2 mainnet
program dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH (drift-labs/protocol-v2
DRIFT_PROGRAM_ID), verified against live HyperSync data where matched
instructions carry the configured placePerpOrder discriminator.

https://claude.ai/code/session_01R5MK69GPR4kiw8er5QoZKm
Previously every svmInstructionEvent carried `blockTime: None` and
`block.time: 0` even though the HyperSync Solana client already exposes
the column. Wire it through:

- Always request `block: [Slot, BlockTime]` in the field selection,
  so the response's blocks table is populated. (Other tables already
  default to all-columns when not explicitly restricted.)
- Build a `blockTimeBySlot` lookup once per response.
- Populate `svmInstructionEvent.blockTime` + `block.time` from it.
- Update `reorgGuard.rangeLastBlock.blockTimestamp` and
  `latestFetchedBlockTimestamp` from the highest-slot block in the
  response, so the indexer's source-stream timestamps also reflect
  real wall-clock time.

Handler code already reads these via the shared Ecosystem.t getters, so
no codegen changes needed; the public TS type already declares
`blockTime?: number`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Bump hypersync-client-solana 0.0.3-rc.1 -> 0.0.4 (token_balance scoped
  join + per-selection include_token_balances flag, all serde-default
  additive). Add the new fields to the napi binding's InstructionSelection
  / TransactionSelection / LogSelection / SolanaQuery + From impls and
  expose them on the ReScript binding (HyperSyncSolanaClient.res).
- HyperSyncSolanaSource: cap chunk size (maxNumBlocks=4000,
  maxNumTransactions=5000, maxNumInstructions=20000,
  maxNumTokenBalances=40000). Without these the server resets the
  connection mid-stream on multi-day windows once balances are joined in.
- config.yaml: bump start_block 420_650_000 -> 422_060_000 (50k slots
  behind current head ~422.11M). Backfill stays well under the server's
  per-request budget while covering ~5.5h of chain time.
- sql/views.sql: bump anchor 1748000000000 -> 1780000000000 (May 2025 ->
  May 2026), matching the frontend slotToUnixMs fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- patch.crates-io: point hypersync-client-solana + net-types + schema at a
  local clone whose only difference is `rustls-tls` -> `rustls-tls-native-
  roots`. The published 0.0.4 uses webpki-roots, and on this host that
  bundle was missing the Let's Encrypt R13 intermediate path, so every
  request died with `invalid peer certificate: UnknownIssuer`. Native roots
  pulls the trust store from the macOS keychain (where curl already works).
- HyperSyncSolanaSource: shrink the per-chunk caps (4000/5000/20000/40000
  -> 1000/2000/8000/16000) so a single chunk fits well inside the server's
  per-request budget while upstream HOS-1304 lands.
- config.yaml: bump start_block 422_060_000 -> 422_100_000 (~10k slots
  behind head, 70min of chain time) — keeps backfill short and on-disk
  small.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
svmEventDescriptorSchema in Config.res didn't list "includeTokenBalances",
so rescript-schema parsing of the public-config JSON silently stripped the
field. Downstream, the Utils.magic widening in buildContractEvents
re-typed the slot as `bool` but the actual JS value was `undefined`, which
ReScript treats as falsy, so every svmInstructionEventConfig ended up with
includeTokenBalances = false even though config.yaml said
field_selection: token_balance_fields: true.

Net effect: needsTokenBalances stayed false, the per-instruction
include_token_balances join flag was never set, the field selection
didn't request the token_balance columns, and TokenDelta stayed empty
forever despite the v0.0.4 server being fully wired.

Wire it through the schema so the field survives parsing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- config.yaml: match Orca (whirL...) and Meteora (LBUZ...) program-wide via
  a discriminator-free instruction (renamed from "any" — reserved by codegen
  — to "programIx"). Catches every Orca/Meteora ix including the inner ones
  fired by Jupiter routes, so the CPI tree + cross-protocol heuristic light
  up the way the UI assumes. token_balance_fields:true on both so deltas
  flow through.
- handlers/flow.ts: register("Orca","programIx") + register("Meteora",
  "programIx"). No arg mapper — the storyline is the CPI node + token deltas.
- views.sql: seed mint_price with USD1, cbBTC, JLP, KMNO, ORCA, PYTH,
  POPCAT to cover the next tier of high-volume mints in the indexed window.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Almost every Jupiter route CPIs into Orca or Meteora; without indexing
their swap ix the cross-protocol heuristic (protocol_count >= 3) never
fires and every tx card looks like "Jupiter-only" or "Jupiter+Raydium".

- config.yaml: add Orca whirlpool + Meteora DLMM as separate matches with
  the canonical swap discriminator 0xf8c69e91e17587c8 (sha256("global:swap"
  )[..8]). Discriminator-filtered (not program-wide like the attempt that
  timed out), so the response stays inside the server's per-request budget.
- handlers/flow.ts: register("Orca","swap"), register("Meteora","swap").
  No arg mapper — the storyline is the CPI node + the token deltas the
  parent tx already carries.
- start_block: 422_100_000 (~220k slots / ~24h of chain time) — empirically
  the widest window that backfills cleanly with the new matches. Wider
  windows trip the server's per-request budget; revisit once HOS-1304 ships.

After this lands, expect: real cross-protocol whales (e.g. Jupiter+Meteora
$104k), Jupiter+Meteora+Orca 3-protocol routes, and the cross-protocol /
protocol-edge views are no longer empty.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Composite ranking so the feed leads with the genuinely interesting txs
instead of whatever happens to be at the head slot. Weight ladder:
  liquidation     5000
  whale (>$100k)  4000
  cross-protocol  2000  (>= 3 distinct programs)
  arb-like        1000  (>= 2 programs, >= 2 mints, > $10k)
  log(gross_usd)  0..500 tie-breaker

UI's Q_INTERESTING_FEED orders by interest_score desc, slot desc — see
monorepo commit. Existing flag columns are unchanged; tasks reading the
view without interest_score are unaffected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the [patch.crates-io] local-path override and bump the cli deps
0.0.4 -> 0.0.5, so all three solana crates resolve from crates.io.
0.0.5 is published 0.0.4 plus reqwest rustls-tls-native-roots (TLS fix
for Let's Encrypt R13 certs). cargo check is clean against the registry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 1, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e525dc94-f847-4be8-b60a-6ae2d25b564e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands and usage tips.

…file regen

The block-time lockfile regeneration dropped the top-level overrides block
(react-dom: 19.2.3) that package.json still declares, so the frozen
pnpm install in build-envio-package failed with ERR_PNPM_LOCKFILE_CONFIG_MISMATCH.
react-dom already resolves to 19.2.3 throughout, so this restores the block
to match package.json. Verified locally with pnpm install --frozen-lockfile.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants