Skip to content

feat(cache): jiti-owned cache-or-lookup layer + TON jetton enrichment#15

Merged
runninyeti merged 1 commit into
mainfrom
feat/jetton-resolver-hook
Jun 18, 2026
Merged

feat(cache): jiti-owned cache-or-lookup layer + TON jetton enrichment#15
runninyeti merged 1 commit into
mainfrom
feat/jetton-resolver-hook

Conversation

@runninyeti

@runninyeti runninyeti commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Moves the entire cache-or-lookup enrichment layer into jiti (per direction): jiti owns the cache orchestration and the resolvers and the resolver RPC. A consumer injects only durable storage — and jiti ships a ready-made Postgres adapter so the consumer just hands it a URI.

What jiti now owns (src/cache/)

  • Core (index.ts): cacheGet / cacheSet — in-process L1, single-flight, negative caching, TTL/immutability, read-through/write-through. Generic + multi-namespace.
  • Registry (registry.ts): per-namespace policy (resolver, TTL, negative-TTL).
  • CacheStorage interface (types.ts): the only thing a consumer implements.
  • TON jetton resolver (resolvers/ton-jetton.ts): wallet → {owner, master} via get_wallet_data (TEP-74) over the free Orbs gateway with host rotation; registers the immutable ton-jetton-wallet namespace. The one place jiti does network RPC, only on the enrichment path.
  • Ready-made PG adapter (storage/postgres.ts): createPostgresCacheStorage({ connectionUri }) — indexer/nbd import it, pass a URI, inject. The jiti_cache table self-creates. pg is an optional peer dependency, lazy-required so it never bundles/loads for consumers that don't use the cache (e.g. oscar's pacemaker) — verified not in the parcel bundle.

token-transfers

Enriches TON jetton transfers (tokenType:'TOKEN', to = wallet, token undefined) → to = owner, token = master, before the contractAddress/walletAddress filters — but only when _ctx.cacheStorage is injected. Opt-in / non-breaking: no storage → transform is sync and byte-identical to today; existing callers (oscar pacemaker, etc.) unaffected.

Consumer side (follow-up, indexer)

Indexer drops its own jiti-cache + resolver and shrinks to: import { createPostgresCacheStorage } from '@indexing/jiti', pass the recent-DB URI (gated by JITI_CACHE_DB_URI), inject as _ctx.cacheStorage. NBD does the same at migration.

Notes

  • Build clean (parcel); cache API + createPostgresCacheStorage in dist/types.d.ts; pg externalized.
  • npm test (fetches real blocks, needs API_KEY) not run locally — sync path unchanged, existing template tests unaffected.
  • The eval-require targets CommonJS consumers (indexer/nbd are CJS).

@runninyeti runninyeti force-pushed the feat/jetton-resolver-hook branch from 8499f7e to b523318 Compare June 18, 2026 13:54
@runninyeti runninyeti changed the title feat(token-transfers): optional injected resolveJetton hook feat(cache): jiti-owned cache-or-lookup layer + TON jetton enrichment Jun 18, 2026
… in tokenTransfers

Adds a generic, multi-namespace "cache-or-lookup" enrichment layer that jiti owns end to
end — in-process L1, single-flight, negative caching, TTL/immutability, read-through/
write-through, the per-namespace resolvers, AND the resolver RPC. A consumer injects only
durable storage.

- src/cache: registry (namespace policies), core (cacheGet/cacheSet), CacheStorage interface.
- src/cache/resolvers/ton-jetton: resolves a jetton wallet -> {owner, master} via get_wallet_data
  (TEP-74) over the free Orbs gateway with host rotation; registers the immutable
  `ton-jetton-wallet` namespace. This is the one place jiti performs network RPC, and only on
  the enrichment path.
- src/cache/storage/postgres: a ready-made createPostgresCacheStorage(uri) — a jiti consumer
  (indexer, nbd) hands it a Postgres URI and injects the result. `pg` is an OPTIONAL peer
  dependency, lazy-required so it never bundles or loads for consumers that don't use the cache
  (e.g. oscar's pacemaker).

The token-transfers template enriches TON jetton transfers (`tokenType:'TOKEN'`, `to` = wallet,
`token` undefined) -> rewrites `to = owner`, `token = master` BEFORE the contractAddress/
walletAddress filters, but ONLY when the caller injects `_ctx.cacheStorage`. With no storage
injected, transform is sync and byte-identical to before — every existing caller (oscar
pacemaker, etc.) is unaffected. Filter logic extracted to applyTransferFilters.
@runninyeti runninyeti force-pushed the feat/jetton-resolver-hook branch from b523318 to 1344b4c Compare June 18, 2026 14:00
@runninyeti runninyeti merged commit 71700a9 into main Jun 18, 2026
1 check passed
@runninyeti runninyeti deleted the feat/jetton-resolver-hook branch June 18, 2026 14:01
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.

1 participant