Issue
@canton-network/dapp-sdk@1.1.0 declares @walletconnect/sign-client and @walletconnect/types as optional peer dependencies, signalling that consumers who don't use WalletConnectAdapter shouldn't have to install or bundle them. The current build, however, forces them on every consumer:
// node_modules/@canton-network/dapp-sdk/dist/index.js
import { WindowTransport } from '@canton-network/core-rpc-transport';
import SignClient from '@walletconnect/sign-client'; // ← top-level, in index.js
import * as coreWalletDappRpcClient from '@canton-network/core-wallet-dapp-rpc-client';
// …
That static import in the entry module means any consumer that imports anything from @canton-network/dapp-sdk pulls SignClient and its transitive cone (~2.8 MB on disk; ~500–900 KB minified-bundled) into their bundle. It's also a mild conflict with the package.json signal that the peer dep is optional — without @walletconnect/sign-client installed, a fresh consumer's bundler errors at resolution time, not at runtime where the optional-peer contract would normally trigger.
This affects any dApp that:
- only uses RemoteAdapter (CIP-103 wallet gateways) — but still pays for WalletConnect,
- defers wallet sign-in behind a feature flag — but still ships WC in the critical-path bundle,
- targets a build where WC isn't even wired (e.g. a minimal demo).
Proposed fix
Move the SignClient import (and any other @walletconnect/* references) out of src/index.ts and into src/adapter/walletconnect-adapter.ts, where it's actually used. The WalletConnectAdapter class already lives there. With the import collocated, consumers who never import WalletConnectAdapter get the WC chunk tree-shaken out by Rollup/esbuild/Webpack. Consumers who do import it still pay the same cost, but only when they ask for it.
Concretely, somewhere in src/index.ts the SDK currently does (or its bundler hoists):
import SignClient from '@walletconnect/sign-client'
…in a path that ends up in the entry. If this lives only inside walletconnect-adapter.ts and index.ts does export { WalletConnectAdapter } from './adapter/walletconnect-adapter', tree-shaking can prune it.
A second, smaller win: change the WalletConnectAdapter constructor's call into SignClient.init({...}) to a dynamic import('@walletconnect/sign-client') inside the async establishSession method. Then even consumers who import WalletConnectAdapter for its type or for conditional registration only pay the cost when a session is actually established. This is closer to what the "optional peer dep" contract suggests.
Workaround
For now we lazy-import the wallet stack behind a React component boundary so it lands in a separate chunk that doesn't load until the wallet sign-in feature is engaged. Happy to share the diff if useful. But the upstream fix would let every consumer get this for free.
Thanks for the SDK
Issue
@canton-network/dapp-sdk@1.1.0 declares @walletconnect/sign-client and @walletconnect/types as optional peer dependencies, signalling that consumers who don't use WalletConnectAdapter shouldn't have to install or bundle them. The current build, however, forces them on every consumer:
That static import in the entry module means any consumer that imports anything from @canton-network/dapp-sdk pulls SignClient and its transitive cone (~2.8 MB on disk; ~500–900 KB minified-bundled) into their bundle. It's also a mild conflict with the package.json signal that the peer dep is optional — without @walletconnect/sign-client installed, a fresh consumer's bundler errors at resolution time, not at runtime where the optional-peer contract would normally trigger.
This affects any dApp that:
Proposed fix
Move the SignClient import (and any other @walletconnect/* references) out of src/index.ts and into src/adapter/walletconnect-adapter.ts, where it's actually used. The WalletConnectAdapter class already lives there. With the import collocated, consumers who never import WalletConnectAdapter get the WC chunk tree-shaken out by Rollup/esbuild/Webpack. Consumers who do import it still pay the same cost, but only when they ask for it.
Concretely, somewhere in src/index.ts the SDK currently does (or its bundler hoists):
…in a path that ends up in the entry. If this lives only inside walletconnect-adapter.ts and index.ts does export { WalletConnectAdapter } from './adapter/walletconnect-adapter', tree-shaking can prune it.
A second, smaller win: change the WalletConnectAdapter constructor's call into SignClient.init({...}) to a dynamic import('@walletconnect/sign-client') inside the async establishSession method. Then even consumers who import WalletConnectAdapter for its type or for conditional registration only pay the cost when a session is actually established. This is closer to what the "optional peer dep" contract suggests.
Workaround
For now we lazy-import the wallet stack behind a React component boundary so it lands in a separate chunk that doesn't load until the wallet sign-in feature is engaged. Happy to share the diff if useful. But the upstream fix would let every consumer get this for free.
Thanks for the SDK