From bb786be43d4534108afe2d4836e1720cc94821d5 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Jan 2026 22:12:15 +0000 Subject: [PATCH 1/2] feat: load evo-sdk from CDN for faster initial loads - 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 --- app/layout.tsx | 11 ++ lib/services/cdn-loader.ts | 204 +++++++++++++++++++++++ lib/services/document-builder-service.ts | 25 +-- lib/services/document-service.ts | 3 +- lib/services/dpns-service.ts | 3 +- lib/services/evo-sdk-service.ts | 19 ++- lib/services/identity-service.ts | 8 +- lib/services/post-service.ts | 3 +- lib/services/sdk-helpers.ts | 24 ++- lib/services/signer-service.ts | 52 ++++-- lib/services/state-transition-service.ts | 3 +- lib/services/tip-service.ts | 11 +- next.config.js | 24 +-- 13 files changed, 313 insertions(+), 77 deletions(-) create mode 100644 lib/services/cdn-loader.ts diff --git a/app/layout.tsx b/app/layout.tsx index e1e699af..ca1b3441 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -10,6 +10,9 @@ import { LinkPreviewModalProvider } from '@/components/post/link-preview' const basePath = process.env.BASE_PATH || '' +// CDN URL for the evo-sdk - loaded dynamically for better performance +const EVO_SDK_CDN_URL = 'https://cdn.jsdelivr.net/npm/@dashevo/evo-sdk@3.0.0/dist/evo-sdk.module.js' + export const metadata: Metadata = { title: 'Yappr - Share Your Voice', description: 'A modern social platform for sharing thoughts and connecting with others', @@ -26,6 +29,14 @@ export default function RootLayout({ }) { return ( + + {/* Preload the evo-sdk from CDN for faster initial load */} + + diff --git a/lib/services/cdn-loader.ts b/lib/services/cdn-loader.ts new file mode 100644 index 00000000..f876a4e6 --- /dev/null +++ b/lib/services/cdn-loader.ts @@ -0,0 +1,204 @@ +/** + * CDN Loader for @dashevo/evo-sdk + * + * This module loads the evo-sdk from a CDN instead of bundling it with the application. + * This significantly reduces the initial bundle size and improves load times by leveraging + * CDN caching. + * + * The SDK is loaded once and cached for subsequent use. + */ + +// CDN URLs for the SDK +const EVO_SDK_VERSION = '3.0.0'; +const CDN_BASE_URL = 'https://cdn.jsdelivr.net/npm'; +const EVO_SDK_URL = `${CDN_BASE_URL}/@dashevo/evo-sdk@${EVO_SDK_VERSION}/dist/evo-sdk.module.js`; + +// Type definitions for the SDK exports we use +// These match the actual exports from @dashevo/evo-sdk +export interface EvoSdkModule { + EvoSDK: EvoSDKClass; + IdentitySigner: IdentitySignerClass; + PrivateKey: PrivateKeyClass; + IdentityPublicKey: IdentityPublicKeyClass; + Document: DocumentClass; + wallet: WalletModule; +} + +// EvoSDK class type +export interface EvoSDKClass { + testnetTrusted(config?: { settings?: { timeoutMs?: number } }): EvoSDKInstance; + mainnetTrusted(config?: { settings?: { timeoutMs?: number } }): EvoSDKInstance; +} + +export interface EvoSDKInstance { + connect(): Promise; + documents: { + query(query: unknown): Promise>; + get(contractId: string, docType: string, docId: string): Promise; + create(params: { document: unknown; identityKey: unknown; signer: unknown }): Promise; + replace(params: { document: unknown; identityKey: unknown; signer: unknown }): Promise; + delete(params: { document: unknown; identityKey: unknown; signer: unknown }): Promise; + }; + identities: { + fetch(identityId: string): Promise; + balance(identityId: string): Promise; + update(params: unknown): Promise; + creditTransfer(params: unknown): Promise; + }; + contracts: { + fetch(contractId: string): Promise; + }; + dpns: { + usernames(params: { identityId: string; limit?: number }): Promise; + resolve(name: string): Promise; + resolveName(name: string): Promise; + register(params: unknown): Promise; + registerName(params: unknown): Promise; + isContestedUsername(label: string): Promise; + isNameAvailable(name: string): Promise; + isValidUsername(label: string): Promise; + convertToHomographSafe(input: string): Promise; + }; + wasm: { + waitForStateTransitionResult(hash: string): Promise; + }; +} + +// Identity type returned by identities.fetch +export interface Identity { + toJSON(): Record; + getPublicKeys(): WasmPublicKey[]; +} + +// WASM public key type +export interface WasmPublicKey { + keyId: number; + keyTypeNumber: number; + purposeNumber: number; + securityLevelNumber: number; + securityLevel: number; + purpose: string; + keyType: string; + data: string; + disabledAt?: number; +} + +// IdentitySigner class type +export interface IdentitySignerClass { + new (): IdentitySignerInstance; +} + +export interface IdentitySignerInstance { + addKeyFromWif(wif: string): void; + addKey(key: unknown): void; +} + +// PrivateKey class type +export interface PrivateKeyClass { + fromHex(hex: string, network: 'testnet' | 'mainnet'): unknown; +} + +// IdentityPublicKey class type +export interface IdentityPublicKeyClass { + fromJSON(data: unknown): unknown; +} + +// Document class type +export interface DocumentClass { + new ( + data: Record, + documentTypeName: string, + revision: bigint, + contractId: string, + ownerId: string, + documentId?: string + ): DocumentInstance; +} + +export interface DocumentInstance { + id: unknown; + toJSON(): Record; +} + +// Wallet module type +export interface WalletModule { + keyPairFromWif(wif: string): Promise<{ publicKey: string; privateKey: string } | null>; +} + +// Cached SDK module +let cachedModule: EvoSdkModule | null = null; +let loadPromise: Promise | null = null; + +/** + * Load the evo-sdk from CDN + * + * This function dynamically imports the SDK from jsdelivr CDN. + * The module is cached after the first load. + * + * @returns Promise resolving to the SDK module exports + */ +export async function loadEvoSdk(): Promise { + // Return cached module if available + if (cachedModule) { + return cachedModule; + } + + // Return existing load promise if one is in progress + if (loadPromise) { + return loadPromise; + } + + // Start loading + loadPromise = (async () => { + try { + console.log('CDN Loader: Loading evo-sdk from CDN...'); + const startTime = performance.now(); + + // 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); + + const loadTime = Math.round(performance.now() - startTime); + console.log(`CDN Loader: evo-sdk loaded from CDN in ${loadTime}ms`); + + // Cache the module + cachedModule = sdkModule as EvoSdkModule; + return cachedModule; + } catch (error) { + console.error('CDN Loader: Failed to load evo-sdk from CDN:', error); + loadPromise = null; // Reset so we can retry + throw error; + } + })(); + + return loadPromise; +} + +/** + * Check if the SDK is already loaded + */ +export function isEvoSdkLoaded(): boolean { + return cachedModule !== null; +} + +/** + * Get the cached SDK module (returns null if not loaded) + */ +export function getCachedEvoSdk(): EvoSdkModule | null { + return cachedModule; +} + +/** + * Preload the SDK without waiting for it + * Useful for starting the load early in the application lifecycle + */ +export function preloadEvoSdk(): void { + if (!cachedModule && !loadPromise) { + loadEvoSdk().catch(error => { + console.error('CDN Loader: Preload failed:', error); + }); + } +} + +// Re-export the CDN URL for use in preload hints +export const EVO_SDK_CDN_URL = EVO_SDK_URL; diff --git a/lib/services/document-builder-service.ts b/lib/services/document-builder-service.ts index 8486a7a2..7bc023d5 100644 --- a/lib/services/document-builder-service.ts +++ b/lib/services/document-builder-service.ts @@ -6,12 +6,11 @@ * * The new API requires Document WASM objects instead of plain data objects. * - * IMPORTANT: We import the Document class from @dashevo/evo-sdk which re-exports - * from the shared @dashevo/wasm-sdk module. By calling getEvoSdk() first, we ensure + * IMPORTANT: The SDK is loaded from CDN. By calling loadEvoSdk() first, we ensure * the WASM module is initialized before creating any Document objects. */ import { getEvoSdk } from './evo-sdk-service'; -import { Document } from '@dashevo/evo-sdk'; +import { loadEvoSdk, type DocumentInstance } from './cdn-loader'; /** * Ensure WASM module is initialized by connecting SDK @@ -39,10 +38,13 @@ class DocumentBuilderService { documentTypeName: string, ownerId: string, data: Record - ): Promise> { + ): Promise { // Ensure WASM is initialized before creating objects await ensureWasmReady(); + // Load SDK from CDN and get Document class + const { Document } = await loadEvoSdk(); + // Create document with revision 1 for new documents // Document ID is undefined to let the SDK generate it based on entropy // Note: TypeScript types are stricter than the actual WASM API - undefined is valid @@ -80,10 +82,13 @@ class DocumentBuilderService { ownerId: string, data: Record, newRevision: number - ): Promise> { + ): Promise { // Ensure WASM is initialized before creating objects await ensureWasmReady(); + // Load SDK from CDN and get Document class + const { Document } = await loadEvoSdk(); + // Create document with the incremented revision const document = new Document( data, // Updated document data fields @@ -137,10 +142,10 @@ class DocumentBuilderService { * @param document - A WASM Document or document-like object * @returns Normalized document data with $ prefixed fields */ - normalizeDocumentResponse(document: Document | Record): Record { + normalizeDocumentResponse(document: DocumentInstance | Record): Record { // Check if it's a WASM Document with toJSON method - if (document && typeof (document as Document).toJSON === 'function') { - return (document as Document).toJSON(); + if (document && typeof (document as DocumentInstance).toJSON === 'function') { + return (document as DocumentInstance).toJSON(); } // Handle raw objects - normalize field names @@ -172,7 +177,7 @@ class DocumentBuilderService { * @param document - The WASM Document after creation * @returns The document ID as a string */ - getDocumentId(document: Document): string { + getDocumentId(document: DocumentInstance): string { // The document.id property returns an Identifier which can be converted to string const id = document.id; if (typeof id === 'string') { @@ -183,7 +188,7 @@ class DocumentBuilderService { } // Fallback: try to get from JSON const json = document.toJSON(); - return json.$id || json.id || ''; + return (json.$id as string) || (json.id as string) || ''; } } diff --git a/lib/services/document-service.ts b/lib/services/document-service.ts index 3aa52dc8..2d6db6ce 100644 --- a/lib/services/document-service.ts +++ b/lib/services/document-service.ts @@ -90,7 +90,8 @@ export abstract class BaseDocumentService { } // Document has toJSON method - const docData = typeof response.toJSON === 'function' ? response.toJSON() : response; + const doc = response as { toJSON?: () => Record }; + const docData = typeof doc.toJSON === 'function' ? doc.toJSON() : response as Record; const transformed = this.transformDocument(docData); // Cache the result diff --git a/lib/services/dpns-service.ts b/lib/services/dpns-service.ts index dbc8381e..9272badf 100644 --- a/lib/services/dpns-service.ts +++ b/lib/services/dpns-service.ts @@ -1,10 +1,9 @@ import { getEvoSdk } from './evo-sdk-service'; -import { SecurityLevel, KeyPurpose, signerService } from './signer-service'; +import { SecurityLevel, KeyPurpose, signerService, type WasmIdentityPublicKey } from './signer-service'; import { DPNS_CONTRACT_ID, DPNS_DOCUMENT_TYPE } from '../constants'; import { identifierToBase58 } from './sdk-helpers'; import { findMatchingKeyIndex, getSecurityLevelName, type IdentityPublicKeyInfo } from '@/lib/crypto/keys'; import type { UsernameCheckResult, UsernameRegistrationResult } from '../types'; -import type { IdentityPublicKey as WasmIdentityPublicKey } from '@dashevo/wasm-sdk/compressed'; /** * Extract documents array from SDK response (handles Map, Array, and object formats) diff --git a/lib/services/evo-sdk-service.ts b/lib/services/evo-sdk-service.ts index b6a264a6..b87afae8 100644 --- a/lib/services/evo-sdk-service.ts +++ b/lib/services/evo-sdk-service.ts @@ -1,4 +1,4 @@ -import { EvoSDK } from '@dashevo/evo-sdk'; +import { loadEvoSdk, type EvoSDKInstance } from './cdn-loader'; import { DPNS_CONTRACT_ID, YAPPR_DM_CONTRACT_ID, YAPPR_PROFILE_CONTRACT_ID } from '../constants'; export interface EvoSdkConfig { @@ -6,8 +6,11 @@ export interface EvoSdkConfig { contractId: string; } +// Re-export the EvoSDK instance type for convenience +export type EvoSDK = EvoSDKInstance; + class EvoSdkService { - private sdk: EvoSDK | null = null; + private sdk: EvoSDKInstance | null = null; private initPromise: Promise | null = null; private config: EvoSdkConfig | null = null; private _isInitialized = false; @@ -54,7 +57,10 @@ class EvoSdkService { } try { - console.log('EvoSdkService: Creating EvoSDK instance...'); + console.log('EvoSdkService: Loading EvoSDK from CDN...'); + + // Load SDK from CDN + const { EvoSDK } = await loadEvoSdk(); // Create SDK with trusted mode based on network if (this.config.network === 'testnet') { @@ -140,7 +146,7 @@ class EvoSdkService { /** * Get the SDK instance, initializing if necessary */ - async getSdk(): Promise { + async getSdk(): Promise { if (!this._isInitialized || !this.sdk) { if (!this.config) { throw new Error('SDK not configured. Call initialize() first.'); @@ -226,9 +232,6 @@ class EvoSdkService { export const evoSdkService = new EvoSdkService(); // Export helper to ensure SDK is initialized -export async function getEvoSdk(): Promise { +export async function getEvoSdk(): Promise { return evoSdkService.getSdk(); } - -// Re-export EvoSDK type for convenience -export type { EvoSDK }; diff --git a/lib/services/identity-service.ts b/lib/services/identity-service.ts index 40560a47..a9c6da7a 100644 --- a/lib/services/identity-service.ts +++ b/lib/services/identity-service.ts @@ -73,7 +73,7 @@ class IdentityService { console.log('Public keys from identity:', identity.publicKeys); // Normalize public keys to ensure all fields are present - const rawPublicKeys = identity.publicKeys || identity.public_keys || []; + const rawPublicKeys = (identity.publicKeys || identity.public_keys || []) as IdentityPublicKey[]; const normalizedPublicKeys: IdentityPublicKey[] = rawPublicKeys.map((key: IdentityPublicKey) => ({ id: key.id, type: key.type, @@ -86,10 +86,10 @@ class IdentityService { })); const identityInfo: IdentityInfo = { - id: identity.id || identityId, - balance: identity.balance || 0, + id: (identity.id as string) || identityId, + balance: (identity.balance as number) || 0, publicKeys: normalizedPublicKeys, - revision: identity.revision || 0 + revision: (identity.revision as number) || 0 }; // Cache the result diff --git a/lib/services/post-service.ts b/lib/services/post-service.ts index 5078d0c4..6d774939 100644 --- a/lib/services/post-service.ts +++ b/lib/services/post-service.ts @@ -4,8 +4,7 @@ import { dpnsService } from './dpns-service'; import { blockService } from './block-service'; import { followService } from './follow-service'; import { unifiedProfileService } from './unified-profile-service'; -import { identifierToBase58, normalizeSDKResponse, RequestDeduplicator, stringToIdentifierBytes, type DocumentWhereClause } from './sdk-helpers'; -import type { DocumentsQuery } from '@dashevo/wasm-sdk'; +import { identifierToBase58, normalizeSDKResponse, RequestDeduplicator, stringToIdentifierBytes, type DocumentWhereClause, type DocumentsQuery } from './sdk-helpers'; import { seedBlockStatusCache, seedFollowStatusCache } from '../caches/user-status-cache'; import { retryAsync } from '../retry-utils'; import { paginateCount } from './pagination-utils'; diff --git a/lib/services/sdk-helpers.ts b/lib/services/sdk-helpers.ts index 8a006899..dc5e1d29 100644 --- a/lib/services/sdk-helpers.ts +++ b/lib/services/sdk-helpers.ts @@ -5,15 +5,25 @@ * This helper converts that to a simple array of document data. */ -import type { EvoSDK } from '@dashevo/evo-sdk'; -import type { - DocumentsQuery, - DocumentWhereClause, - DocumentOrderByClause, -} from '@dashevo/wasm-sdk'; +import type { EvoSDK } from './evo-sdk-service'; import bs58 from 'bs58'; -export type { DocumentWhereClause, DocumentOrderByClause }; +// Query types - these match the SDK's query interface +// Where clauses can be tuples like ['field', 'operator', value] or objects +export type DocumentWhereClause = [string, string, unknown] | { [key: string]: unknown }; + +// Order by clauses can be tuples like ['field', 'asc'/'desc'] or objects +export type DocumentOrderByClause = [string, 'asc' | 'desc'] | { [key: string]: 'asc' | 'desc' }; + +export interface DocumentsQuery { + dataContractId: string; + documentTypeName: string; + where?: DocumentWhereClause[]; + orderBy?: DocumentOrderByClause[]; + limit?: number; + startAfter?: string; + startAt?: string; +} /** * Convert any identifier value to a base58 string. diff --git a/lib/services/signer-service.ts b/lib/services/signer-service.ts index b83369e3..aa434bdf 100644 --- a/lib/services/signer-service.ts +++ b/lib/services/signer-service.ts @@ -4,18 +4,24 @@ * This service provides utilities for creating signers and identity public keys * for use with the new typed state transition APIs in @dashevo/evo-sdk * - * IMPORTANT: We import WASM types from @dashevo/evo-sdk which re-exports them from - * @dashevo/wasm-sdk. By calling getEvoSdk() first, we ensure the shared WASM module - * is initialized before creating any WASM objects. + * IMPORTANT: The SDK is loaded from CDN. By calling loadEvoSdk() first, we ensure + * the WASM module is initialized before creating any WASM objects. */ import { getEvoSdk } from './evo-sdk-service'; -import { - IdentitySigner, - PrivateKey, - IdentityPublicKey, -} from '@dashevo/evo-sdk'; +import { loadEvoSdk, type IdentitySignerInstance } from './cdn-loader'; import type { IdentityPublicKey as IdentityPublicKeyType } from './identity-service'; -import type { IdentityPublicKey as WasmIdentityPublicKey } from '@dashevo/wasm-sdk/compressed'; + +// WasmIdentityPublicKey type - represents the WASM-level identity public key +// This is compatible with what identity.getPublicKeys() returns +interface WasmIdentityPublicKey { + keyId: number; + keyTypeNumber: number; + purposeNumber: number; + securityLevelNumber: number; + securityLevel: number; + data: string; + disabledAt?: number; +} /** * Ensure WASM module is initialized by connecting SDK @@ -74,11 +80,14 @@ class SignerService { */ async createSigner( privateKeyWif: string - ): Promise> { + ): Promise { // Ensure WASM is initialized before creating objects await ensureWasmReady(); - // Create a new signer instance using imported class + // Load SDK from CDN and get IdentitySigner class + const { IdentitySigner } = await loadEvoSdk(); + + // Create a new signer instance const signer = new IdentitySigner(); // Add key directly from WIF (the signer has a convenience method for this) @@ -97,11 +106,14 @@ class SignerService { async createSignerFromHex( privateKeyHex: string, network: 'testnet' | 'mainnet' = 'testnet' - ): Promise> { + ): Promise { // Ensure WASM is initialized before creating objects await ensureWasmReady(); - // Create a new signer instance using imported class + // Load SDK from CDN and get classes + const { IdentitySigner, PrivateKey } = await loadEvoSdk(); + + // Create a new signer instance const signer = new IdentitySigner(); // Create PrivateKey from hex and add to signer @@ -123,10 +135,13 @@ class SignerService { */ async createIdentityPublicKey( keyData: IdentityPublicKeyType - ): Promise> { + ): Promise { // Ensure WASM is initialized before creating objects await ensureWasmReady(); + // Load SDK from CDN and get IdentityPublicKey class + const { IdentityPublicKey } = await loadEvoSdk(); + // Normalize the key data to match the expected JSON format // The fromJSON method expects camelCase fields const normalizedKeyData = { @@ -213,8 +228,8 @@ class SignerService { privateKeyWif: string, keyData: IdentityPublicKeyType ): Promise<{ - signer: InstanceType; - identityKey: InstanceType; + signer: IdentitySignerInstance; + identityKey: unknown; }> { const [signer, identityKey] = await Promise.all([ this.createSigner(privateKeyWif), @@ -241,7 +256,7 @@ class SignerService { privateKeyWif: string, wasmKey: WasmIdentityPublicKey ): Promise<{ - signer: InstanceType; + signer: IdentitySignerInstance; identityKey: WasmIdentityPublicKey; }> { const signer = await this.createSigner(privateKeyWif); @@ -250,5 +265,8 @@ class SignerService { } } +// Re-export WasmIdentityPublicKey type for use by other services +export type { WasmIdentityPublicKey }; + // Singleton instance export const signerService = new SignerService(); diff --git a/lib/services/state-transition-service.ts b/lib/services/state-transition-service.ts index 9c4c9201..806031b3 100644 --- a/lib/services/state-transition-service.ts +++ b/lib/services/state-transition-service.ts @@ -1,8 +1,7 @@ import { getEvoSdk } from './evo-sdk-service'; -import { SecurityLevel, KeyPurpose, signerService } from './signer-service'; +import { SecurityLevel, KeyPurpose, signerService, type WasmIdentityPublicKey } from './signer-service'; import { documentBuilderService } from './document-builder-service'; import { findMatchingKeyIndex, getSecurityLevelName, type IdentityPublicKeyInfo } from '@/lib/crypto/keys'; -import type { IdentityPublicKey as WasmIdentityPublicKey } from '@dashevo/wasm-sdk/compressed'; export interface StateTransitionResult { success: boolean; diff --git a/lib/services/tip-service.ts b/lib/services/tip-service.ts index b6db3bee..ba52eb27 100644 --- a/lib/services/tip-service.ts +++ b/lib/services/tip-service.ts @@ -1,10 +1,9 @@ import { getEvoSdk } from './evo-sdk-service'; import { identityService } from './identity-service'; -import { signerService, KeyPurpose } from './signer-service'; -import { wallet } from '@dashevo/evo-sdk'; +import { signerService, KeyPurpose, type WasmIdentityPublicKey } from './signer-service'; +import { loadEvoSdk } from './cdn-loader'; import { TipInfo } from '../types'; import { findMatchingKeyIndex, type IdentityPublicKeyInfo } from '@/lib/crypto/keys'; -import type { IdentityPublicKey as WasmIdentityPublicKey } from '@dashevo/wasm-sdk/compressed'; export interface TipResult { success: boolean; @@ -154,12 +153,14 @@ class TipService { // Try to derive public key from the provided private key and compare try { + const { wallet } = await loadEvoSdk(); const keyPair = await wallet.keyPairFromWif(transferKeyWif.trim()); console.log('Derived key pair from WIF:', keyPair); // Find transfer keys (purpose 3) on the identity interface IdentityPublicKey { id: number; purpose: number; data?: string } - const transferKeys = identityJson.publicKeys.filter((k: IdentityPublicKey) => k.purpose === 3); + const publicKeys = (identityJson.publicKeys || []) as IdentityPublicKey[]; + const transferKeys = publicKeys.filter((k: IdentityPublicKey) => k.purpose === 3); console.log('Transfer keys on identity:', transferKeys); if (keyPair?.publicKey) { @@ -177,7 +178,7 @@ class TipService { console.log('Derived public key (base64):', pubKeyBase64); // Compare with key 3's public key - const key3 = identityJson.publicKeys.find((k: IdentityPublicKey) => k.id === 3); + const key3 = publicKeys.find((k: IdentityPublicKey) => k.id === 3); if (key3) { console.log('Key 3 public key (from identity):', key3.data); console.log('Keys match:', pubKeyBase64 === key3.data); diff --git a/next.config.js b/next.config.js index 3200a9b2..a595bb1e 100644 --- a/next.config.js +++ b/next.config.js @@ -36,25 +36,11 @@ const nextConfig = { domains: ['images.unsplash.com'], }, webpack: (config, { isServer }) => { - // Optimize EvoSDK bundle size - if (!isServer) { - config.optimization = { - ...config.optimization, - splitChunks: { - chunks: 'all', - cacheGroups: { - dashevo: { - test: /[\\/]node_modules[\\/]@dashevo[\\/]/, - name: 'evo-sdk', - priority: 10, - reuseExistingChunk: true, - }, - }, - }, - } - } + // Note: The main evo-sdk is loaded from CDN using dynamic import with webpackIgnore. + // This avoids bundling the large SDK while still allowing specialized WASM classes + // (like IdentityPublicKeyInCreation) to be imported directly when needed. - // Handle WASM files (required for @dashevo/evo-sdk) + // Handle WASM files (required for @dashevo/wasm-sdk) config.experiments = { ...config.experiments, asyncWebAssembly: true, @@ -71,7 +57,7 @@ const nextConfig = { key: 'Content-Security-Policy', value: [ "default-src 'self'", - "script-src 'self' 'unsafe-eval' 'unsafe-inline'", + "script-src 'self' 'unsafe-eval' 'unsafe-inline' https://cdn.jsdelivr.net", "style-src 'self' 'unsafe-inline'", "img-src 'self' data: https: blob:", "font-src 'self'", From 3e22c22b18677e6898874c90141526f7135f18f4 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Jan 2026 22:12:55 +0000 Subject: [PATCH 2/2] chore: update package-lock.json https://claude.ai/code/session_015si4GM8oRDKC3bZfc1fBa5 --- package-lock.json | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8e976b83..db1df801 100644 --- a/package-lock.json +++ b/package-lock.json @@ -249,7 +249,6 @@ "resolved": "https://registry.npmjs.org/@dicebear/core/-/core-9.2.4.tgz", "integrity": "sha512-hz6zArEcUwkZzGOSJkWICrvqnEZY7BKeiq9rqKzVJIc1tRVv0MkR0FGvIxSvXiK9TTIgKwu656xCWAGAl6oh+w==", "license": "MIT", - "peer": true, "dependencies": { "@types/json-schema": "^7.0.11" }, @@ -2546,7 +2545,6 @@ "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -2558,7 +2556,6 @@ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "devOptional": true, "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "^18.0.0" } @@ -2618,7 +2615,6 @@ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -3177,7 +3173,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3720,7 +3715,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001726", "electron-to-chromium": "^1.5.173", @@ -4104,8 +4098,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -4628,7 +4621,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -4797,7 +4789,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -6855,7 +6846,6 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "license": "MIT", - "peer": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -7329,7 +7319,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -7521,7 +7510,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -7534,7 +7522,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -8702,7 +8689,6 @@ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -8878,7 +8864,6 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver"