@metamask/connect-multichain 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +24 -1
  2. package/README.md +20 -19
  3. package/dist/browser/es/connect-multichain.d.mts +62 -6
  4. package/dist/browser/es/connect-multichain.mjs +286 -124
  5. package/dist/browser/es/connect-multichain.mjs.map +1 -1
  6. package/dist/browser/es/metafile-esm.json +1 -1
  7. package/dist/browser/iife/connect-multichain.d.ts +62 -6
  8. package/dist/browser/iife/connect-multichain.js +304 -124
  9. package/dist/browser/iife/connect-multichain.js.map +1 -1
  10. package/dist/browser/iife/metafile-iife.json +1 -1
  11. package/dist/browser/umd/connect-multichain.d.ts +62 -6
  12. package/dist/browser/umd/connect-multichain.js +286 -124
  13. package/dist/browser/umd/connect-multichain.js.map +1 -1
  14. package/dist/browser/umd/metafile-cjs.json +1 -1
  15. package/dist/node/cjs/connect-multichain.d.ts +62 -6
  16. package/dist/node/cjs/connect-multichain.js +287 -124
  17. package/dist/node/cjs/connect-multichain.js.map +1 -1
  18. package/dist/node/cjs/metafile-cjs.json +1 -1
  19. package/dist/node/es/connect-multichain.d.mts +62 -6
  20. package/dist/node/es/connect-multichain.mjs +286 -124
  21. package/dist/node/es/connect-multichain.mjs.map +1 -1
  22. package/dist/node/es/metafile-esm.json +1 -1
  23. package/dist/react-native/es/connect-multichain.d.mts +62 -6
  24. package/dist/react-native/es/connect-multichain.mjs +286 -124
  25. package/dist/react-native/es/connect-multichain.mjs.map +1 -1
  26. package/dist/react-native/es/metafile-esm.json +1 -1
  27. package/dist/src/domain/multichain/index.d.ts +1 -1
  28. package/dist/src/domain/multichain/index.d.ts.map +1 -1
  29. package/dist/src/domain/multichain/index.js +7 -3
  30. package/dist/src/domain/multichain/index.js.map +1 -1
  31. package/dist/src/domain/multichain/types.d.ts +15 -3
  32. package/dist/src/domain/multichain/types.d.ts.map +1 -1
  33. package/dist/src/domain/utils/index.d.ts +2 -1
  34. package/dist/src/domain/utils/index.d.ts.map +1 -1
  35. package/dist/src/domain/utils/index.js +1 -1
  36. package/dist/src/domain/utils/index.js.map +1 -1
  37. package/dist/src/multichain/index.d.ts.map +1 -1
  38. package/dist/src/multichain/index.js +109 -63
  39. package/dist/src/multichain/index.js.map +1 -1
  40. package/dist/src/multichain/rpc/requestRouter.d.ts.map +1 -1
  41. package/dist/src/multichain/rpc/requestRouter.js +27 -9
  42. package/dist/src/multichain/rpc/requestRouter.js.map +1 -1
  43. package/dist/src/multichain/transports/mwp/index.d.ts.map +1 -1
  44. package/dist/src/multichain/transports/mwp/index.js +17 -5
  45. package/dist/src/multichain/transports/mwp/index.js.map +1 -1
  46. package/dist/src/multichain/utils/analytics.d.ts +82 -1
  47. package/dist/src/multichain/utils/analytics.d.ts.map +1 -1
  48. package/dist/src/multichain/utils/analytics.js +252 -17
  49. package/dist/src/multichain/utils/analytics.js.map +1 -1
  50. package/dist/types/connect-multichain.d.ts +62 -6
  51. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.15.0]
11
+
12
+ ### Added
13
+
14
+ - Add an `analytics.enabled` option to `createMultichainClient()`. Set it to `false` to disable dapp-side analytics events and omit `analytics.remote_session_id` connection metadata. ([#303](https://github.com/MetaMask/connect-monorepo/pull/303))
15
+
16
+ ## [0.14.0]
17
+
18
+ ### Added
19
+
20
+ - Attach a `failure_reason` tag to `mmconnect_wallet_action_failed` and `mmconnect_connection_failed` events via a new `classifyFailureReason` helper, distinguishing transport timeouts, transport disconnects, EIP-1193 wallet errors (`4100 wallet_unauthorized`, `4200 wallet_method_unsupported`, `4902 unrecognized_chain`), and JSON-RPC wallet errors (`-32601`, `-32602`, `-32603`, plus the `-32000…-32099` server-error range), with an `unknown` fallback. Schema-side: [`metamask-sdk-analytics-api#31`](https://github.com/consensys-vertical-apps/metamask-sdk-analytics-api/pull/31). ([#290](https://github.com/MetaMask/connect-monorepo/pull/290))
21
+ - Attach `error_code` and `error_message_sample` companion properties to `mmconnect_wallet_action_failed` and `mmconnect_connection_failed`. `error_code` preserves the raw wallet-side JSON-RPC / EIP-1193 code (e.g. `4001`, `-32603`). `error_message_sample` is a sanitised, 200-char-max preview of the original error message, with wallet addresses, long hex blobs, URLs, and large decimal numbers scrubbed. Both fields are optional and only set on the two `*_failed` events. Schema-side: [`metamask-sdk-analytics-api#32`](https://github.com/consensys-vertical-apps/metamask-sdk-analytics-api/pull/32). ([#290](https://github.com/MetaMask/connect-monorepo/pull/290))
22
+
23
+ ### Changed
24
+
25
+ - Improves QR code scanning reliability. The QR code MWP flow (desktop web and Node.js) now omits the initial `wallet_createSession` request from the deeplink URI, instead sending it as a separate request after the wallet completes the MWP handshake. This results in a shorter deeplink URI and a less dense QR code. The native deeplink (non-QR MWP) flow used on mobile web and React Native is unchanged. ([#295](https://github.com/MetaMask/connect-monorepo/pull/295))
26
+
27
+ ### Fixed
28
+
29
+ - Tightened `isRejectionError` so `mmconnect_wallet_action_rejected` more accurately reflects user-driven cancellations: it now unwraps `RPCInvokeMethodErr` (so wallet-side codes survive the router's transport-boundary wrapping rather than being masked by the wrapper's `code: 53`), no longer classifies EIP-1193 `4100 Unauthorized` as a rejection (it's a CAIP-25 permission denial, not a user decision), and narrows the bare `"user"` substring match to four explicit phrases — `"user rejected"` / `"user denied"` / `"user cancelled"` / `"user canceled"` — so unrelated messages like Account Abstraction's `"user operation reverted"` no longer count. Net effect: `_rejected` becomes more precise; `_failed` picks up everything `4100` was previously hiding. ([#292](https://github.com/MetaMask/connect-monorepo/pull/292))
30
+
10
31
  ## [0.13.0]
11
32
 
12
33
  ### Uncategorized
@@ -262,7 +283,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
262
283
 
263
284
  - Initial release
264
285
 
265
- [Unreleased]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.13.0...HEAD
286
+ [Unreleased]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.15.0...HEAD
287
+ [0.15.0]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.14.0...@metamask/connect-multichain@0.15.0
288
+ [0.14.0]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.13.0...@metamask/connect-multichain@0.14.0
266
289
  [0.13.0]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.12.1...@metamask/connect-multichain@0.13.0
267
290
  [0.12.1]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.12.0...@metamask/connect-multichain@0.12.1
268
291
  [0.12.0]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.11.1...@metamask/connect-multichain@0.12.0
package/README.md CHANGED
@@ -138,25 +138,26 @@ Factory function to create a new Multichain SDK instance.
138
138
 
139
139
  #### Parameters
140
140
 
141
- | Option | Type | Required | Description |
142
- | --------------------------- | --------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
143
- | `dapp.name` | `string` | Yes | Name of your dApp |
144
- | `api.supportedNetworks` | `RpcUrlsMap` | Yes | Map of [CAIP-2 chain IDs](https://chainagnostic.org/CAIPs/caip-2) to RPC URLs |
145
- | `dapp.url` | `string` | No | URL of your dApp |
146
- | `dapp.iconUrl` | `string` | No | Icon URL for your dApp |
147
- | `dapp.base64Icon` | `string` | No | Base64-encoded icon (alternative to iconUrl) |
148
- | `storage` | `StoreClient` | No | Custom storage adapter |
149
- | `ui.factory` | `BaseModalFactory` | No | Custom modal factory |
150
- | `ui.headless` | `boolean` | No | Run without UI (for custom QR implementations) |
151
- | `ui.preferExtension` | `boolean` | No | Prefer browser extension (default: true) |
152
- | `ui.showInstallModal` | `boolean` | No | Show installation modal |
153
- | `mobile.preferredOpenLink` | `(deeplink: string, target?: string) => void` | No | Custom deeplink handler |
154
- | `mobile.useDeeplink` | `boolean` | No | Use `metamask://` instead of universal links |
155
- | `analytics.integrationType` | `string` | No | Integration type for analytics |
156
- | `transport.extensionId` | `string` | No | Custom extension ID |
157
- | `transport.onNotification` | `(notification: unknown) => void` | No | Notification handler |
158
- | `versions` | `Partial<ConnectVersions>` | No | Internal: set automatically by `createEVMClient` / `createSolanaClient`. Consumers do not need to provide this. |
159
- | `debug` | `boolean` | No | Enable debug logging |
141
+ | Option | Type | Required | Description |
142
+ | --------------------------- | --------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- |
143
+ | `dapp.name` | `string` | Yes | Name of your dApp |
144
+ | `api.supportedNetworks` | `RpcUrlsMap` | Yes | Map of [CAIP-2 chain IDs](https://chainagnostic.org/CAIPs/caip-2) to RPC URLs |
145
+ | `dapp.url` | `string` | No | URL of your dApp |
146
+ | `dapp.iconUrl` | `string` | No | Icon URL for your dApp |
147
+ | `dapp.base64Icon` | `string` | No | Base64-encoded icon (alternative to iconUrl) |
148
+ | `storage` | `StoreClient` | No | Custom storage adapter |
149
+ | `ui.factory` | `BaseModalFactory` | No | Custom modal factory |
150
+ | `ui.headless` | `boolean` | No | Run without UI (for custom QR implementations) |
151
+ | `ui.preferExtension` | `boolean` | No | Prefer browser extension (default: true) |
152
+ | `ui.showInstallModal` | `boolean` | No | Show installation modal |
153
+ | `mobile.preferredOpenLink` | `(deeplink: string, target?: string) => void` | No | Custom deeplink handler |
154
+ | `mobile.useDeeplink` | `boolean` | No | Use `metamask://` instead of universal links |
155
+ | `analytics.enabled` | `boolean` | No | Enables dapp-side analytics. Defaults to `true`; set to `false` to disable analytics events and wallet correlation metadata. |
156
+ | `analytics.integrationType` | `string` | No | Integration type for analytics |
157
+ | `transport.extensionId` | `string` | No | Custom extension ID |
158
+ | `transport.onNotification` | `(notification: unknown) => void` | No | Notification handler |
159
+ | `versions` | `Partial<ConnectVersions>` | No | Internal: set automatically by `createEVMClient` / `createSolanaClient`. Consumers do not need to provide this. |
160
+ | `debug` | `boolean` | No | Enable debug logging |
160
161
 
161
162
  #### Returns
162
163
 
@@ -406,6 +406,19 @@ type ConnectionRequest = {
406
406
  type ConnectVersions = {
407
407
  'connect-multichain': string;
408
408
  } & Partial<Record<'connect-evm' | 'connect-solana', string>>;
409
+ type AnalyticsOptions = {
410
+ /**
411
+ * Whether to enable analytics tracking. Defaults to `true` when omitted.
412
+ * Set to `false` to disable all analytics event collection.
413
+ */
414
+ enabled?: boolean;
415
+ /**
416
+ * Identifies the integration surface that instantiated the SDK (e.g. `'direct'`,
417
+ * `'wagmi'`). Recorded as the `integration_types` global analytics property.
418
+ * Defaults to `'direct'` when omitted or empty.
419
+ */
420
+ integrationType?: string;
421
+ };
409
422
  /**
410
423
  * Constructor options for creating a Multichain SDK instance.
411
424
  *
@@ -422,9 +435,7 @@ type MultichainOptions = {
422
435
  supportedNetworks: RpcUrlsMap;
423
436
  };
424
437
  /** Analytics configuration */
425
- analytics?: {
426
- integrationType: string;
427
- };
438
+ analytics?: AnalyticsOptions;
428
439
  /** Storage client for persisting SDK data */
429
440
  storage: StoreClient;
430
441
  /** UI configuration options */
@@ -464,6 +475,7 @@ type MultiChainFNOptions = Omit<MultichainOptions, 'storage' | 'ui'> & {
464
475
  * with an existing singleton.
465
476
  */
466
477
  type MergeableMultichainOptions = Omit<MultichainOptions, 'dapp' | 'analytics' | 'storage' | 'api' | 'ui' | 'transport' | 'versions'> & {
478
+ analytics?: AnalyticsOptions;
467
479
  api?: MultichainOptions['api'];
468
480
  ui?: Pick<MultichainOptions['ui'], 'headless' | 'preferExtension' | 'showInstallModal'>;
469
481
  transport?: Pick<NonNullable<MultichainOptions['transport']>, 'extensionId'>;
@@ -553,7 +565,7 @@ declare abstract class MultichainCore extends EventEmitter<SDKEvents> {
553
565
  constructor(options: MultichainOptions);
554
566
  /**
555
567
  * Merges the given options into the current instance options.
556
- * Only the mergeable keys are updated (api.supportedNetworks, versions, ui.*, mobile.*, transport.extensionId, debug).
568
+ * Only the mergeable keys are updated (api.supportedNetworks, analytics, versions, ui.*, mobile.*, transport.extensionId, debug).
557
569
  * The main thing to note is that the value for `dapp` is not merged as it does not make sense for
558
570
  * subsequent calls to `createMultichainClient` to have a different `dapp` value.
559
571
  * Used when createMultichainClient is called with an existing singleton.
@@ -679,13 +691,42 @@ declare abstract class Modal<Options, Data extends DataType = DataType> {
679
691
  set data(data: Data);
680
692
  }
681
693
 
694
+ /**
695
+ * Tag describing the cause of a failed wallet action / connection. Surfaced
696
+ * as the `failure_reason` property on `mmconnect_wallet_action_failed` and
697
+ * `mmconnect_connection_failed` events so we can distinguish e.g. a transport
698
+ * timeout from a wallet-side internal error in Mixpanel.
699
+ *
700
+ * Intentionally a string union (not a const enum) so callers stay free to
701
+ * pass through a new bucket; the schema-side property is an open string for
702
+ * the same reason.
703
+ */
704
+ type FailureReason = 'transport_timeout' | 'transport_disconnect' | 'wallet_method_unsupported' | 'wallet_invalid_params' | 'wallet_internal_error' | 'wallet_unauthorized' | 'unrecognized_chain' | 'unknown';
682
705
  /**
683
706
  * Checks if an error represents a user rejection.
684
707
  *
708
+ * Unwraps `RPCInvokeMethodErr` so the wallet's `code: 4001` survives the
709
+ * SDK's transport-boundary wrapping (the outer error otherwise reports
710
+ * `code: 53`, which would never match the heuristics here).
711
+ *
685
712
  * @param error - The error object to check
686
713
  * @returns True if the error indicates a user rejection, false otherwise
687
714
  */
688
715
  declare function isRejectionError(error: unknown): boolean;
716
+ /**
717
+ * Classifies a failed wallet action / connection error into a short tag for
718
+ * the `failure_reason` analytics property. Caller is expected to have already
719
+ * established that the error is *not* a user rejection (use `isRejectionError`
720
+ * for that branching).
721
+ *
722
+ * The taxonomy is deliberately producer-side-only — the schema accepts any
723
+ * string — so we can add buckets here without an API migration. Once the
724
+ * distribution stabilises we may convert the schema field to a closed enum.
725
+ *
726
+ * @param error - The error to classify
727
+ * @returns A short, snake_case tag describing why the operation failed
728
+ */
729
+ declare function classifyFailureReason(error: unknown): FailureReason;
689
730
  /**
690
731
  * Gets analytics properties specific to wallet action events.
691
732
  *
@@ -693,15 +734,30 @@ declare function isRejectionError(error: unknown): boolean;
693
734
  * @param storage - Storage client for getting anonymous ID
694
735
  * @param invokeOptions - The invoke method options containing method and scope
695
736
  * @param transportType - The transport type to use for the analytics event
737
+ * @param extra - Optional event-specific diagnostic properties. Used by
738
+ * `mmconnect_wallet_action_failed` to attach the {@link ErrorDiagnostics}
739
+ * bundle (`failure_reason`, `error_code`, `error_message_sample`).
740
+ * @param extra.failure_reason - A short tag describing why the operation
741
+ * failed; see `classifyFailureReason` and the `FailureReason` union.
742
+ * @param extra.error_code - The raw wallet-side error code, if present.
743
+ * @param extra.error_message_sample - A sanitised, truncated sample of the
744
+ * original error message.
696
745
  * @returns Wallet action analytics properties
697
746
  */
698
- declare function getWalletActionAnalyticsProperties(options: MultichainOptions, storage: StoreClient, invokeOptions: InvokeMethodOptions, transportType: TransportType): Promise<{
747
+ declare function getWalletActionAnalyticsProperties(options: MultichainOptions, storage: StoreClient, invokeOptions: InvokeMethodOptions, transportType: TransportType, extra?: {
748
+ failure_reason?: FailureReason;
749
+ error_code?: number;
750
+ error_message_sample?: string;
751
+ }): Promise<{
699
752
  mmconnect_versions: Record<string, string>;
700
753
  dapp_id: string;
701
754
  method: string;
702
755
  caip_chain_id: string;
703
756
  anon_id: string;
704
757
  transport_type: TransportType;
758
+ failure_reason?: FailureReason;
759
+ error_code?: number;
760
+ error_message_sample?: string;
705
761
  }>;
706
762
 
707
763
  /**
@@ -713,4 +769,4 @@ declare function getVersion(): string;
713
769
 
714
770
  declare const createMultichainClient: CreateMultichainFN;
715
771
 
716
- export { type ConnectVersions, type ConnectionRequest, type ConnectionStatus, type CreateMultichainFN, type DappSettings, type DataType, type DomainErrorCodes, type Enumerate, type ErrorCodeRange, type ErrorCodes, EventEmitter, type EventTypes, type ExtendedTransport, type InstallWidgetProps, type InvokeMethodOptions, type LoggerNameSpaces, type MergeableMultichainOptions, Modal, type ModalFactoryConnectOptions, type ModalFactoryOptions, MultichainCore, type MultichainOptions, type NotificationCallback, type OTPCode, type OTPCodeWidgetProps, PlatformType, type QRLink, type RPCAPI, type RPCErrorCodes, RPCHttpErr, RPCInvokeMethodErr, RPCReadonlyRequestErr, RPCReadonlyResponseErr, type RPCResponse, RPC_HANDLED_METHODS, type RpcMethod, type RpcUrlsMap, type SDKEvents, SDK_HANDLED_METHODS, type Scope, type StorageErrorCodes, StoreAdapter, StoreClient, type StoreOptions, TransportType, createLogger, createMultichainClient, enableDebug, getInfuraRpcUrls, getPlatformType, getTransportType, getVersion, getWalletActionAnalyticsProperties, hasExtension, infuraRpcUrls, isEnabled, isMetamaskExtensionInstalled, isRejectionError, isSecure };
772
+ export { type AnalyticsOptions, type ConnectVersions, type ConnectionRequest, type ConnectionStatus, type CreateMultichainFN, type DappSettings, type DataType, type DomainErrorCodes, type Enumerate, type ErrorCodeRange, type ErrorCodes, EventEmitter, type EventTypes, type ExtendedTransport, type FailureReason, type InstallWidgetProps, type InvokeMethodOptions, type LoggerNameSpaces, type MergeableMultichainOptions, Modal, type ModalFactoryConnectOptions, type ModalFactoryOptions, MultichainCore, type MultichainOptions, type NotificationCallback, type OTPCode, type OTPCodeWidgetProps, PlatformType, type QRLink, type RPCAPI, type RPCErrorCodes, RPCHttpErr, RPCInvokeMethodErr, RPCReadonlyRequestErr, RPCReadonlyResponseErr, type RPCResponse, RPC_HANDLED_METHODS, type RpcMethod, type RpcUrlsMap, type SDKEvents, SDK_HANDLED_METHODS, type Scope, type StorageErrorCodes, StoreAdapter, StoreClient, type StoreOptions, TransportType, classifyFailureReason, createLogger, createMultichainClient, enableDebug, getInfuraRpcUrls, getPlatformType, getTransportType, getVersion, getWalletActionAnalyticsProperties, hasExtension, infuraRpcUrls, isEnabled, isMetamaskExtensionInstalled, isRejectionError, isSecure };