Skip to content

feat: optimistic inventory and fuel updates via gRPC checkpoint stream#37

Merged
fcsondheim merged 6 commits into
mainfrom
feat/inventory-optimistic-updates
Jun 24, 2026
Merged

feat: optimistic inventory and fuel updates via gRPC checkpoint stream#37
fcsondheim merged 6 commits into
mainfrom
feat/inventory-optimistic-updates

Conversation

@ccp-raudur

@ccp-raudur ccp-raudur commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

What

Replaces the purely poll-driven inventory and fuel state with a two-layer system: a gRPC checkpoint stream for near-real-time optimistic updates, with GraphQL polling retained as the authoritative fallback.

gRPC checkpoint stream

Subscribes to the Sui fullnode's checkpoint stream and filters for ItemMintedEvent, ItemBurnedEvent, and FuelEvent for the currently-loaded assembly. Events are applied directly to React state without waiting for the next poll.

Session management handles the public fullnode's ~30s stream cutoff (rotates at 28s), detects idle streams via a 35s backup timeout, and reconnects with a 1s delay. A deduplication set (capped at 5,000 entries with LRU eviction) prevents replaying events across reconnects.

Optimistic inventory (SmartStorageUnit)

ItemMintedEvent and ItemBurnedEvent are applied immediately: item quantities are adjusted and usedCapacity is updated using cached Datahub volume data (dm³ = quantity × m³/unit × 1000). A checkpoint gap — detected by sequence number comparison — triggers an immediate GraphQL refetch rather than waiting for the poll interval.

The tricky case is a refetch that returns stale indexer data. An inventory signature (a JSON fingerprint of [[typeId, quantity], ...] pairs sorted by type ID) detects when the indexer hasn't caught up yet and preserves the optimistic state rather than reverting it. Once the indexer advances past the signature, fresh data is accepted.

Optimistic fuel (NetworkNode)

FuelEvent carries new_quantity and is_burning directly (no delta computation needed), so applyFuelEventToAssembly is a straightforward field replace. The same stale-refetch protection applies via lastConfirmedFuelSignatureRef (quantity:isBurning string). This means the Network Node Monitor's Start button and total-time-remaining display update immediately when fuel is deposited or a burn unit completes — no longer dependent on the 10s poll.

Code structure

The original 820-line providers/eventRefresh.ts is split into three focused modules under utils/events/:

  • checkpointStream.ts — stream lifecycle, protobuf decoding, dedup, gap detection
  • inventoryEventHandlers.ts — SSU event filtering, delta parsing, optimistic state apply
  • fuelEventHandlers.ts — NetworkNode fuel event filtering and optimistic state apply
  • eventRefresh.ts (slimmed to ~90 lines) — refetch scheduler and subscription entry point

Why

GraphQL indexer lag of 5–15s means users waiting for the poll cycle to confirm a mint or burn see stale state. For inventory this created a visible delay before item counts updated; for the Network Node the Start button remained disabled even with fuel in the tank. Applying the on-chain event result immediately removes that lag while keeping the GraphQL poll as a correctness backstop.

Where has this been tested?

  • In-game browser
  • [x ] External browser

Copilot AI review requested due to automatic review settings June 18, 2026 13:29
@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown

Coverage Report for @evefrontier/dapp-kit

Status Category Percentage Covered / Total
🔵 Lines 90.79% 730 / 804
🔵 Statements 88.87% 775 / 872
🔵 Functions 87.97% 161 / 183
🔵 Branches 77.02% 486 / 631
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/libs/dapp-kit/utils/constants.ts 95.65% 62.5% 91.66% 95.65% 129-130
packages/libs/dapp-kit/utils/inventory.ts 87.5% 78.57% 100% 93.18% 15, 44, 65, 122, 133, 137
packages/libs/dapp-kit/utils/inventoryEventBcs.ts 88.88% 100% 80% 87.5% 4
packages/libs/dapp-kit/utils/transforms.ts 100% 60.24% 100% 100%
packages/libs/dapp-kit/utils/utils.ts 100% 94% 100% 100%
packages/libs/dapp-kit/utils/events/checkpointStream.ts 83.21% 72.07% 92.3% 87.28% 87, 91, 116, 121, 133-134, 138-140, 158, 201, 215-217, 288, 299, 330, 388-389, 400, 406-409
packages/libs/dapp-kit/utils/events/eventRefresh.ts 59.25% 12.5% 50% 60% 32, 61-97
packages/libs/dapp-kit/utils/events/fuelEventHandlers.ts 86.36% 82.35% 100% 100% 25, 38, 61
packages/libs/dapp-kit/utils/events/inventoryEventHandlers.ts 86.81% 79.78% 100% 93.33% 47, 54, 79, 84, 92, 112, 127-128, 150, 190, 242, 245
Generated in workflow #83 for commit a0440a8 by the Vitest Coverage Report Action

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds near-real-time (optimistic) Smart Storage Unit inventory updates by subscribing to Sui checkpoint-stream events and applying mint/burn deltas locally, with periodic GraphQL refetches as the source of truth.

Changes:

  • Introduces inventory utilities for sorting, optimistic used-capacity adjustments, and safe merging of refetch results with stream-updated state.
  • Adds gRPC checkpoint-stream subscription + event application logic, wired into SmartObjectProvider.
  • Updates UI inventory rendering and capacity bar display (including optional whole-number display).

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
packages/libs/ui-components/modules/InventoryView.tsx Uses fetched Datahub item details per type_id, updates list keys, tweaks capacity bar props.
packages/libs/ui-components/components/EveLinearBar.tsx Adds wholeNumbers display option for numerator/denominator.
packages/libs/dapp-kit/utils/transforms.ts Sorts storage inventory items by quantity during GraphQL transform.
packages/libs/dapp-kit/utils/inventoryEventBcs.ts Adds BCS decoding helpers for inventory move events (used when stream JSON is absent).
packages/libs/dapp-kit/utils/inventory.ts New utilities for optimistic used-capacity updates, item sorting, and merge logic for refetch vs optimistic state.
packages/libs/dapp-kit/utils/constants.ts Adds SUI_GRPC_URLS and getSuiGrpcBaseUrl for network-specific gRPC endpoints.
packages/libs/dapp-kit/utils/tests/transforms.test.ts Tests inventory sorting behavior in transformToAssembly.
packages/libs/dapp-kit/utils/tests/inventoryEventBcs.test.ts Adds BCS decoding test (currently depends on live testnet RPC).
packages/libs/dapp-kit/utils/tests/inventory.test.ts Tests inventory utility behaviors (used capacity adjustments, merging, equality).
packages/libs/dapp-kit/providers/SmartObjectProvider.tsx Primes volume cache, merges refetch results with optimistic state, and subscribes to inventory stream events.
packages/libs/dapp-kit/providers/eventRefresh.ts New checkpoint-stream subscription, event extraction/decoding, optimistic application, and refetch scheduling logic.
packages/libs/dapp-kit/providers/tests/eventRefresh.test.ts Comprehensive unit tests for event extraction, dedupe, scheduling, and optimistic assembly updates.
packages/libs/dapp-kit/config/dapp-kit.ts Uses shared SUI_GRPC_URLS for dApp kit gRPC client configuration.

Comment thread packages/libs/ui-components/modules/InventoryView.tsx Outdated
Comment thread packages/libs/ui-components/components/EveLinearBar.tsx Outdated
Comment thread packages/libs/dapp-kit/providers/SmartObjectProvider.tsx
Comment thread packages/libs/dapp-kit/providers/SmartObjectProvider.tsx Outdated
Comment thread packages/libs/dapp-kit/providers/eventRefresh.ts Outdated
Comment thread packages/libs/dapp-kit/providers/eventRefresh.ts Outdated
Comment thread packages/libs/dapp-kit/utils/__tests__/inventoryEventBcs.test.ts Outdated
@ccp-raudur ccp-raudur marked this pull request as draft June 18, 2026 13:39
@fcsondheim fcsondheim self-assigned this Jun 23, 2026
ccp-raudur and others added 3 commits June 24, 2026 11:03
Replace event polling with SubscribeCheckpoints for ItemMinted/Burned events,
with optimistic UI updates, staggered GraphQL refetch, and 10s poll fallback.

Co-authored-by: Cursor <cursoragent@cursor.com>
@fcsondheim fcsondheim force-pushed the feat/inventory-optimistic-updates branch from 1429bc1 to c65ab65 Compare June 24, 2026 11:03
@fcsondheim fcsondheim changed the title Feat/inventory optimistic updates feat: optimistic inventory and fuel updates via gRPC checkpoint stream Jun 24, 2026
@fcsondheim fcsondheim marked this pull request as ready for review June 24, 2026 14:17
@fcsondheim fcsondheim merged commit c9e0a4d into main Jun 24, 2026
3 checks passed
@fcsondheim fcsondheim deleted the feat/inventory-optimistic-updates branch June 24, 2026 14:18
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.

3 participants