feat: optimistic inventory and fuel updates via gRPC checkpoint stream#37
Merged
Conversation
Coverage Report for @evefrontier/dapp-kit
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
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. |
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>
1429bc1 to
c65ab65
Compare
fcsondheim
approved these changes
Jun 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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, andFuelEventfor 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)
ItemMintedEventandItemBurnedEventare applied immediately: item quantities are adjusted andusedCapacityis 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)
FuelEventcarriesnew_quantityandis_burningdirectly (no delta computation needed), soapplyFuelEventToAssemblyis a straightforward field replace. The same stale-refetch protection applies vialastConfirmedFuelSignatureRef(quantity:isBurningstring). 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.tsis split into three focused modules underutils/events/:checkpointStream.ts— stream lifecycle, protobuf decoding, dedup, gap detectioninventoryEventHandlers.ts— SSU event filtering, delta parsing, optimistic state applyfuelEventHandlers.ts— NetworkNode fuel event filtering and optimistic state applyeventRefresh.ts(slimmed to ~90 lines) — refetch scheduler and subscription entry pointWhy
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?