fix(solana-utils): lazy-load jito-ts so non-Jito consumers don't crash#3702
fix(solana-utils): lazy-load jito-ts so non-Jito consumers don't crash#37020xghost42 wants to merge 1 commit into
Conversation
Closes pyth-network#1838. `jito.ts` previously did top-level value imports of `jito-ts/dist/sdk/block-engine/{searcher,types}`. Pulling those modules also pulls jito-ts's nested `@solana/web3.js@~1.77.3`, which transitively `require`s `rpc-websockets/dist/lib/client` — a path removed in `rpc-websockets@>=7.11`. Because `solana_utils/transaction.ts` imports `buildJitoTipInstruction` from `./jito`, any consumer that loaded a @pythnetwork/solana-utils export — including `PythSolanaReceiver` from `@pythnetwork/pyth-solana-receiver` — eagerly walked the broken chain and crashed at module load with: Error: Cannot find module 'rpc-websockets/dist/lib/client' This change splits the imports so that jito-ts only resolves when the Jito send path is actually exercised: - `SearcherClient` and `Bundle` become `import type` — these were only used as types in function signatures. - `sendTransactionsJito` dynamic-`import`s `Bundle` from `jito-ts/.../types` immediately before constructing the bundle. The function is already async, so this is zero-cost for callers. Non-Jito consumers (the case reported in the issue) no longer trigger the broken require. Jito users still get the same runtime path; the underlying jito-ts/rpc-websockets clash there is a separate problem for jito-ts to solve. Tests - Added `JitoLazyImport.test.ts` asserting that importing either `../transaction` or `../jito` leaves `jito-ts/*` out of `require.cache`. - Existing `TransactionSize.test.ts` still passes (2 cases). - `pnpm --filter @pythnetwork/solana-utils build` succeeds (esm + cjs). Bumped to 0.6.1 (patch — runtime contract preserved, only load order changes).
|
@0xghost42 is attempting to deploy a commit to the Pyth Network Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
There was a problem hiding this comment.
🚩 Dependencies use pinned version ranges instead of catalog references
The REVIEW.md states "For TypeScript dependencies, prefer using catalog: versions over declaring package-specific dependency versions." Several dependencies in this package use explicit version ranges (e.g., @coral-xyz/anchor: ^0.29.0, @solana/web3.js: ^1.90.0, bs58: ^5.0.0) while the pnpm workspace catalog defines versions for some of these (e.g., @coral-xyz/anchor: ^0.30.1, @solana/web3.js: ^1.98.0, bs58: ^6.0.0). This is a pre-existing issue not introduced by this PR, but it's worth noting the divergence — the package uses older version ranges than what the catalog specifies.
Was this helpful? React with 👍 or 👎 to provide feedback.
| "type": "module", | ||
| "types": "./dist/cjs/index.d.ts", | ||
| "version": "0.6.0" | ||
| "version": "0.6.1" |
There was a problem hiding this comment.
🚩 Lock file not updated after version bump
The version was bumped from 0.6.0 to 0.6.1 in package.json:84, but the pnpm-lock.yaml was not updated in this PR. Per the repository's REVIEW.md guidelines ("Also suggest the lock file changes when a bump happens"), the lock file should typically be regenerated to reflect the new version. This is usually handled by running pnpm install before committing.
Was this helpful? React with 👍 or 👎 to provide feedback.
|
Confirmed clean: re-ran Reason: every workspace consumer of Re: the catalog finding — agreed it's pre-existing divergence, kept this PR scoped to the require-time crash fix; happy to follow up with a catalog migration sweep separately. |
Summary
Closes #1838.
target_chains/solana/sdk/js/solana_utils/src/jito.tspreviously did top-level value imports ofjito-ts/dist/sdk/block-engine/{searcher,types}. Loading those modules transitively pullsjito-ts's nested@solana/web3.js@~1.77.3, which in turnrequiresrpc-websockets/dist/lib/client— a path removed inrpc-websockets@>=7.11.Because
solana_utils/transaction.tsimportsbuildJitoTipInstructionfrom./jito, any consumer that loaded a@pythnetwork/solana-utilsexport — includingPythSolanaReceiverfrom@pythnetwork/pyth-solana-receiver— eagerly walked the broken chain and crashed at module load with:(matches the stack the issue reporter pasted)
Change
Split
jito.tsimports so thatjito-tsonly resolves when the Jito send path is actually exercised:SearcherClientandBundlebecomeimport type(they were only used as types in function signatures and as a constructor inside one function).sendTransactionsJitoawait importsBundleimmediately before constructing the bundle. The function is already async, so this is zero-cost for callers.jito.tsrecords the why so this isn't undone in a future cleanup.Non-Jito consumers (the case reported in the issue) no longer trigger the broken require. Jito users still get the same runtime path; the underlying
jito-ts/rpc-websocketsclash there is a separate problem forjito-tsitself to resolve.Verification
Added
src/__tests__/JitoLazyImport.test.tswith two cases that assert importing either../transactionor../jitoleavesjito-ts/*out of Node'srequire.cache. Both pass; existingTransactionSize.test.tsstill passes.pnpm --filter @pythnetwork/solana-utils buildsucceeds (esm + cjs). No public API change — runtime contract is preserved, only the module-load order changes.Bumped patch version
0.6.0->0.6.1.Out of scope
jito-tsitself. Even the latestjito-ts@4.xstill pins@solana/web3.js@~1.77.3, so the bump alone wouldn't have helped here; lazy-loading is the more robust fix and survives whateverjito-tsdecides to do upstream.rpc-websocketsoverrides (the workaround in the issue comment thread) remain a valid escape hatch if a user explicitly needs the Jito path on a newer rpc-websockets.