Skip to content

Load evo-sdk from CDN to reduce bundle size - #230

Open
PastaPastaPasta wants to merge 2 commits into
masterfrom
claude/evosdk-cdn-migration-xJiOQ
Open

Load evo-sdk from CDN to reduce bundle size#230
PastaPastaPasta wants to merge 2 commits into
masterfrom
claude/evosdk-cdn-migration-xJiOQ

Conversation

@PastaPastaPasta

Copy link
Copy Markdown
Owner

Summary

This PR refactors the application to load the @dashevo/evo-sdk from a CDN (jsDelivr) instead of bundling it with the application. This significantly reduces the initial bundle size and improves load times by leveraging CDN caching and browser module preloading.

Key Changes

  • New CDN Loader Service (lib/services/cdn-loader.ts): Created a new service that dynamically imports the evo-sdk from jsDelivr CDN with proper caching and error handling. Includes comprehensive TypeScript type definitions for all SDK exports.

  • Updated SDK Service (lib/services/evo-sdk-service.ts): Modified to use loadEvoSdk() from the CDN loader instead of direct imports. The SDK is now loaded dynamically when first needed.

  • Module Preloading (app/layout.tsx): Added <link rel="modulepreload"> in the document head to hint to the browser to preload the SDK module early, improving perceived performance.

  • Service Updates: Updated all services that previously imported SDK classes directly to now call loadEvoSdk() and destructure the needed classes:

    • document-builder-service.ts: Load Document class from CDN
    • signer-service.ts: Load IdentitySigner, PrivateKey, IdentityPublicKey from CDN
    • tip-service.ts: Load wallet module from CDN
    • dpns-service.ts: Import WasmIdentityPublicKey type from signer-service instead of wasm-sdk
  • Type Definitions: Moved type definitions from direct SDK imports to the cdn-loader service and local type definitions where appropriate. Exported WasmIdentityPublicKey type from signer-service for reuse.

  • Query Types: Moved DocumentsQuery, DocumentWhereClause, and DocumentOrderByClause types to sdk-helpers.ts to avoid direct wasm-sdk imports.

  • Build Configuration (next.config.js):

    • Removed webpack chunk splitting optimization for @dashevo packages (no longer needed)
    • Updated CSP header to allow scripts from https://cdn.jsdelivr.net
    • Added comments explaining the CDN loading strategy

Implementation Details

  • The SDK is loaded once and cached for subsequent use, avoiding redundant network requests
  • Dynamic imports use webpackIgnore: true to prevent webpack from trying to bundle the CDN URL
  • Comprehensive error handling and logging for CDN load failures
  • All WASM initialization is still properly handled through ensureWasmReady() calls
  • Type safety is maintained through detailed TypeScript interfaces matching the SDK's actual exports

https://claude.ai/code/session_015si4GM8oRDKC3bZfc1fBa5

- Add cdn-loader.ts to dynamically import evo-sdk from jsdelivr CDN
- Update evo-sdk-service.ts to use CDN loader instead of bundled SDK
- Update signer-service.ts, document-builder-service.ts, tip-service.ts
  to load SDK classes from CDN
- Add modulepreload hint in layout.tsx for faster SDK loading
- Update CSP in next.config.js to allow scripts from cdn.jsdelivr.net
- Define local types for DocumentWhereClause/DocumentOrderByClause
- Export WasmIdentityPublicKey type from signer-service.ts

The SDK (~7.6MB) is now loaded from CDN instead of being bundled,
which improves initial load times by leveraging CDN caching and
reducing the main bundle size.

https://claude.ai/code/session_015si4GM8oRDKC3bZfc1fBa5
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@thepastaclaw

thepastaclaw commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

🕓 Ready for review — 58 ahead in queue (commit 3e22c22)
Queue position: 59/74 · 3 reviews active
ETA: start ~07:23 UTC · complete ~08:00 UTC (median 36m across 30 recent reviews; 3 slots)
Queued 40m ago · Last checked: 2026-07-21 19:20 UTC

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Preliminary review — Codex only

The CDN refactor introduces a runtime supply-chain boundary into private-key signing: code fetched from jsDelivr receives users' WIF keys without being authenticated against the lockfile or build artifact. The global module preload also fetches the 8,030,052-byte SDK on every exported route, defeating the intended on-demand transfer savings.

Validated blockers were found in the Codex precheck. Sonnet is deferred until a fresh Codex revalidation clears the blocker gate.

Review provenance

  • Codex reviewers: gpt-5.6-sol — general (failed), gpt-5.6-sol — general (failed), gpt-5.6-sol — general (failed), gpt-5.6-sol — general (failed), gpt-5.6-sol — general (completed)
  • Verifier: gpt-5.6-sol — verifier
  • Sonnet: not run (deferred by blocker gate)

🔴 1 blocking | 🟡 1 suggestion(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `lib/services/cdn-loader.ts`:
- [BLOCKING] lib/services/cdn-loader.ts:159: Do not execute CDN code in private-key signing flows
  This dynamic import executes the response served by jsDelivr without verifying it against the dependency lockfile or another cryptographic integrity value. The imported `IdentitySigner` is passed users' WIF private keys by `signer-service.ts`, and the same remote module participates in identity updates and credit transfers. A compromised or incorrectly served response could therefore read and exfiltrate private keys or alter signed transitions. Pinning the package version prevents ordinary version drift but does not remove the new runtime trust in the CDN; bundle the lockfile-pinned dependency or serve an integrity-controlled first-party artifact instead.

In `app/layout.tsx`:
- [SUGGESTION] app/layout.tsx:32-38: Avoid preloading the SDK on every page
  Placing this `modulepreload` in the root layout makes every initial route fetch and prepare the SDK, whether or not the user invokes a Platform-dependent workflow. The referenced module is 8,030,052 bytes, and the current static export contains this preload in all 36 generated HTML files. This negates the refactor's on-demand transfer benefit; remove the global hint or initiate preloading only when the user approaches a workflow that requires the SDK.


// Dynamic import from CDN
// Note: This works because the SDK is published as an ES module
const sdkModule = await import(/* webpackIgnore: true */ EVO_SDK_URL);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🔴 Blocking: Do not execute CDN code in private-key signing flows

This dynamic import executes the response served by jsDelivr without verifying it against the dependency lockfile or another cryptographic integrity value. The imported IdentitySigner is passed users' WIF private keys by signer-service.ts, and the same remote module participates in identity updates and credit transfers. A compromised or incorrectly served response could therefore read and exfiltrate private keys or alter signed transitions. Pinning the package version prevents ordinary version drift but does not remove the new runtime trust in the CDN; bundle the lockfile-pinned dependency or serve an integrity-controlled first-party artifact instead.

Suggested change
const sdkModule = await import(/* webpackIgnore: true */ EVO_SDK_URL);
const sdkModule = await import('@dashevo/evo-sdk');

source: ['codex']

Comment thread app/layout.tsx
Comment on lines +32 to +38
<head>
{/* Preload the evo-sdk from CDN for faster initial load */}
<link
rel="modulepreload"
href={EVO_SDK_CDN_URL}
crossOrigin="anonymous"
/>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🟡 Suggestion: Avoid preloading the SDK on every page

Placing this modulepreload in the root layout makes every initial route fetch and prepare the SDK, whether or not the user invokes a Platform-dependent workflow. The referenced module is 8,030,052 bytes, and the current static export contains this preload in all 36 generated HTML files. This negates the refactor's on-demand transfer benefit; remove the global hint or initiate preloading only when the user approaches a workflow that requires the SDK.

source: ['codex']

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