@metamask/connect-multichain 0.5.3 → 0.7.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 (60) hide show
  1. package/CHANGELOG.md +41 -1
  2. package/README.md +30 -22
  3. package/dist/browser/es/connect-multichain.d.mts +29 -4
  4. package/dist/browser/es/connect-multichain.mjs +636 -335
  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 +29 -4
  8. package/dist/browser/iife/connect-multichain.js +3487 -3072
  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 +29 -4
  12. package/dist/browser/umd/connect-multichain.js +636 -335
  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 +29 -4
  16. package/dist/node/cjs/connect-multichain.js +454 -153
  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 +29 -4
  20. package/dist/node/es/connect-multichain.mjs +454 -153
  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 +29 -4
  24. package/dist/react-native/es/connect-multichain.mjs +629 -328
  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 +15 -4
  28. package/dist/src/domain/multichain/index.d.ts.map +1 -1
  29. package/dist/src/domain/multichain/index.js +14 -0
  30. package/dist/src/domain/multichain/index.js.map +1 -1
  31. package/dist/src/domain/multichain/types.d.ts +14 -0
  32. package/dist/src/domain/multichain/types.d.ts.map +1 -1
  33. package/dist/src/multichain/index.d.ts +3 -2
  34. package/dist/src/multichain/index.d.ts.map +1 -1
  35. package/dist/src/multichain/index.js +158 -61
  36. package/dist/src/multichain/index.js.map +1 -1
  37. package/dist/src/multichain/transports/default/index.d.ts +3 -1
  38. package/dist/src/multichain/transports/default/index.d.ts.map +1 -1
  39. package/dist/src/multichain/transports/default/index.js +17 -11
  40. package/dist/src/multichain/transports/default/index.js.map +1 -1
  41. package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts +3 -1
  42. package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts.map +1 -1
  43. package/dist/src/multichain/transports/multichainApiClientWrapper/index.js +28 -32
  44. package/dist/src/multichain/transports/multichainApiClientWrapper/index.js.map +1 -1
  45. package/dist/src/multichain/transports/mwp/index.d.ts +15 -2
  46. package/dist/src/multichain/transports/mwp/index.d.ts.map +1 -1
  47. package/dist/src/multichain/transports/mwp/index.js +161 -39
  48. package/dist/src/multichain/transports/mwp/index.js.map +1 -1
  49. package/dist/src/multichain/utils/index.d.ts +23 -0
  50. package/dist/src/multichain/utils/index.d.ts.map +1 -1
  51. package/dist/src/multichain/utils/index.js +94 -4
  52. package/dist/src/multichain/utils/index.js.map +1 -1
  53. package/dist/src/polyfills/buffer-shim.js +4 -14
  54. package/dist/src/polyfills/buffer-shim.js.map +1 -1
  55. package/dist/src/store/adapters/web.d.ts +1 -1
  56. package/dist/src/store/adapters/web.d.ts.map +1 -1
  57. package/dist/src/store/adapters/web.js +1 -1
  58. package/dist/src/store/adapters/web.js.map +1 -1
  59. package/dist/types/connect-multichain.d.ts +29 -4
  60. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -7,6 +7,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.7.0]
11
+
12
+ ### Changed
13
+
14
+ - Correct README documentation across `connect-solana`, `connect-evm`, and `connect-multichain` to match actual API behaviour. ([#194](https://github.com/MetaMask/connect-monorepo/pull/194))
15
+ - Redact logs ([#191](https://github.com/MetaMask/connect-monorepo/pull/191]))
16
+ - Pin eciesjs to exact version 0.4.17 ([#188](https://github.com/MetaMask/connect-monorepo/pull/188))
17
+
18
+ ### Fixed
19
+
20
+ - Fix uncaught exception in `parseWalletError` when the wallet returns error codes outside the EIP-1193 provider range (1000–4999), such as standard JSON-RPC codes like `-32603` (Internal error). This prevented Solana request rejections from being handled gracefully. ([#189](https://github.com/MetaMask/connect-monorepo/pull/189))
21
+
22
+ ## [0.6.0]
23
+
24
+ ### Added
25
+
26
+ - When `ConnectMultichain.connect()` is called while a connection is already pending, the user is re-prompted with the pending connection deeplink. ([#176](https://github.com/MetaMask/connect-monorepo/pull/176))
27
+
28
+ ### Changed
29
+
30
+ - Normalize non-http(s) dapp URLs to valid https URLs on React Native to prevent RPC middleware crashes ([#190](https://github.com/MetaMask/connect-monorepo/pull/190))
31
+ - **BREAKING** `createMultichainClient()` now returns a singleton. Any incoming constructor params on subsequent calls to `createMultichainClient()` will be applied to the existing singleton instance except for the `dapp`, `storage`, and `ui.factory` param options. ([#157](https://github.com/MetaMask/connect-monorepo/pull/157))
32
+ - **BREAKING** `ConnectMultichain.openDeeplinkIfNeeded()` is renamed to `openSimpleDeeplinkIfNeeded()` ([#176](https://github.com/MetaMask/connect-monorepo/pull/176))
33
+ - `ConnectMultichain.connect()` now throws an `'Existing connection is pending. Please check your MetaMask Mobile app to continue.'` error if there is already an pending connection attempt. Previously it would abort that ongoing connection in favor of a new one. ([#157](https://github.com/MetaMask/connect-monorepo/pull/157))
34
+ - `ConnectMultichain.connect()` adds newly requested scopes and accounts onto any existing permissions rather than fully replacing them. ([#157](https://github.com/MetaMask/connect-monorepo/pull/157))
35
+ - `ConnectMultichain.disconnect()` accepts an optional array of scopes. When provided, only those scopes will be revoked from the existing permissions. If no scopes remain after a partial revoke, then the underly connection is fully discarded. If no scopes are specified ()`[]`), then all scopes will be removed. By default all scopes will be removed. ([#157](https://github.com/MetaMask/connect-monorepo/pull/157))
36
+
37
+ ### Fixed
38
+
39
+ - `ConnectMultichain` now waits 10 seconds (rather than 2 minutes) when attempting to resume a pending connection on initial instantiation via `createMultichainClient()` ([#175](https://github.com/MetaMask/connect-monorepo/pull/175))
40
+ - Fix `beforeunload` event listener not being properly removed on disconnect due to `.bind()` creating different function references, causing a listener leak on each connect/disconnect cycle ([#170](https://github.com/MetaMask/connect-monorepo/pull/170))
41
+ - Rename `StoreAdapterWeb.DB_NAME` from `mmsdk` to `mmconnect` to prevent IndexedDB collisions when the legacy MetaMask SDK and MM Connect run in the same browser context ([#177](https://github.com/MetaMask/connect-monorepo/pull/177))
42
+ - Clean up stale MWP session from KVStore on connection rejection so subsequent QR code connection attempts are not blocked ([#180](https://github.com/MetaMask/connect-monorepo/pull/180))
43
+ - Fix bug with JSON-RPC requests where previously used `id` value could be re-used causing the wallet to ignore the request when a dapp was refreshed/reloaded. ([#183](https://github.com/MetaMask/connect-monorepo/pull/183))
44
+
10
45
  ## [0.5.3]
11
46
 
12
47
  ### Added
@@ -15,6 +50,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
15
50
 
16
51
  ### Fixed
17
52
 
53
+ - Fix QR rejection handling: properly propagate user rejection errors from MetaMask Mobile to the dApp ([#156](https://github.com/MetaMask/connect-monorepo/pull/156))
54
+ - Close QR modal automatically when user rejects connection ([#156](https://github.com/MetaMask/connect-monorepo/pull/156))
55
+ - Use `@metamask/rpc-errors` for EIP-1193 compliant error handling ([#156](https://github.com/MetaMask/connect-monorepo/pull/156))
18
56
  - Fix `sessionProperties` not being passed to `wallet_createSession` when recreating a session after scope/account changes ([#123](https://github.com/MetaMask/connect-monorepo/pull/123))
19
57
 
20
58
  ## [0.5.2]
@@ -132,7 +170,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
132
170
 
133
171
  - Initial release
134
172
 
135
- [Unreleased]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.5.3...HEAD
173
+ [Unreleased]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.7.0...HEAD
174
+ [0.7.0]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.6.0...@metamask/connect-multichain@0.7.0
175
+ [0.6.0]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.5.3...@metamask/connect-multichain@0.6.0
136
176
  [0.5.3]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.5.2...@metamask/connect-multichain@0.5.3
137
177
  [0.5.2]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.5.1...@metamask/connect-multichain@0.5.2
138
178
  [0.5.1]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.5.0...@metamask/connect-multichain@0.5.1
package/README.md CHANGED
@@ -134,26 +134,28 @@ This package is written in TypeScript and includes full type definitions. No add
134
134
 
135
135
  Factory function to create a new Multichain SDK instance.
136
136
 
137
+ > **Singleton:** `createMultichainClient` returns a single shared instance per global context. Calling it a second time with different options will merge the new `api.supportedNetworks`, `ui.*`, `mobile.*`, `transport.extensionId`, and `debug` values into the existing instance rather than creating a new one. The `dapp` value is never overwritten on subsequent calls.
138
+
137
139
  #### Parameters
138
140
 
139
- | Option | Type | Required | Description |
140
- | --------------------------- | --------------------------------------------- | -------- | ---------------------------------------------- |
141
- | `dapp.name` | `string` | Yes | Name of your dApp |
142
- | `api.supportedNetworks` | `RpcUrlsMap` | Yes | Map of CAIP chain IDs to RPC URLs |
143
- | `dapp.url` | `string` | No | URL of your dApp |
144
- | `dapp.iconUrl` | `string` | No | Icon URL for your dApp |
145
- | `dapp.base64Icon` | `string` | No | Base64-encoded icon (alternative to iconUrl) |
146
- | `storage` | `StoreClient` | No | Custom storage adapter |
147
- | `ui.factory` | `BaseModalFactory` | No | Custom modal factory |
148
- | `ui.headless` | `boolean` | No | Run without UI (for custom QR implementations) |
149
- | `ui.preferExtension` | `boolean` | No | Prefer browser extension (default: true) |
150
- | `ui.showInstallModal` | `boolean` | No | Show installation modal |
151
- | `mobile.preferredOpenLink` | `(deeplink: string, target?: string) => void` | No | Custom deeplink handler |
152
- | `mobile.useDeeplink` | `boolean` | No | Use `metamask://` instead of universal links |
153
- | `analytics.integrationType` | `string` | No | Integration type for analytics |
154
- | `transport.extensionId` | `string` | No | Custom extension ID |
155
- | `transport.onNotification` | `(notification: unknown) => void` | No | Notification handler |
156
- | `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.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
+ | `debug` | `boolean` | No | Enable debug logging |
157
159
 
158
160
  #### Returns
159
161
 
@@ -203,20 +205,26 @@ await client.connect(
203
205
  );
204
206
  ```
205
207
 
206
- ##### `disconnect()`
208
+ ##### `disconnect(scopes?)`
207
209
 
208
- Disconnects from the wallet and cleans up resources.
210
+ Disconnects from the wallet. If `scopes` are provided, only the specified scopes are revoked; if there are remaining scopes, the connection stays alive. If omitted or empty, all scopes are revoked and the connection is fully torn down.
209
211
 
210
212
  **Parameters**
211
213
 
212
- None.
214
+ | Name | Type | Required | Description |
215
+ | -------- | --------- | -------- | -------------------------------------------------------------------- |
216
+ | `scopes` | `Scope[]` | No | Array of CAIP-2 chain identifiers to revoke (defaults to all scopes) |
213
217
 
214
218
  **Returns**
215
219
 
216
220
  `Promise<void>`
217
221
 
218
222
  ```typescript
223
+ // Fully disconnect
219
224
  await client.disconnect();
225
+
226
+ // Disconnect only specific scopes
227
+ await client.disconnect(['eip155:1']);
220
228
  ```
221
229
 
222
230
  ##### `invokeMethod(options)`
@@ -341,7 +349,7 @@ Generates Infura RPC URLs for common networks keyed by CAIP Chain ID.
341
349
 
342
350
  **Returns**
343
351
 
344
- A map of hex chain IDs to Infura RPC URLs. See https://docs.metamask.io/services
352
+ A map of [CAIP-2 chain IDs](https://chainagnostic.org/CAIPs/caip-2) to Infura RPC URLs. See https://docs.metamask.io/services
345
353
 
346
354
  ```typescript
347
355
  import { getInfuraRpcUrls } from '@metamask/connect-multichain';
@@ -369,6 +369,8 @@ declare function hasExtension(): Promise<boolean>;
369
369
  type DappSettings = {
370
370
  name: string;
371
371
  url?: string;
372
+ /** The original non-http(s) URL before normalization on React Native platforms */
373
+ nativeScheme?: string;
372
374
  } & ({
373
375
  iconUrl?: string;
374
376
  } | {
@@ -435,6 +437,16 @@ type MultiChainFNOptions = Omit<MultichainOptions, 'storage' | 'ui'> & {
435
437
  } & {
436
438
  storage?: StoreClient;
437
439
  };
440
+ /**
441
+ * Options that can be merged/overwritten when createMultichainClient is called
442
+ * with an existing singleton.
443
+ */
444
+ type MergeableMultichainOptions = Omit<MultichainOptions, 'dapp' | 'analytics' | 'storage' | 'api' | 'ui' | 'transport'> & {
445
+ api?: MultichainOptions['api'];
446
+ ui?: Pick<MultichainOptions['ui'], 'headless' | 'preferExtension' | 'showInstallModal'>;
447
+ transport?: Pick<NonNullable<MultichainOptions['transport']>, 'extensionId'>;
448
+ debug?: boolean;
449
+ };
438
450
  /**
439
451
  * Complete options for Multichain SDK configuration.
440
452
  *
@@ -453,6 +465,8 @@ type ExtendedTransport = Omit<Transport, 'connect'> & {
453
465
  timeout?: number;
454
466
  }) => Promise<TResponse>;
455
467
  getActiveSession: () => Promise<Session | undefined>;
468
+ getStoredPendingSessionRequest: () => Promise<SessionRequest | null>;
469
+ disconnect: (scopes: Scope[]) => Promise<void>;
456
470
  };
457
471
 
458
472
  declare const infuraRpcUrls: RpcUrlsMap;
@@ -474,7 +488,7 @@ declare enum TransportType {
474
488
  * must provide, including session management, connection handling, and method invocation.
475
489
  */
476
490
  declare abstract class MultichainCore extends EventEmitter<SDKEvents> {
477
- protected readonly options: MultichainOptions;
491
+ protected options: MultichainOptions;
478
492
  abstract storage: StoreClient;
479
493
  abstract status: ConnectionStatus;
480
494
  abstract provider: MultichainApiClient<RPCAPI>;
@@ -491,7 +505,7 @@ declare abstract class MultichainCore extends EventEmitter<SDKEvents> {
491
505
  *
492
506
  * @returns Promise that resolves when disconnection is complete
493
507
  */
494
- abstract disconnect(): Promise<void>;
508
+ abstract disconnect(scopes?: Scope[]): Promise<void>;
495
509
  /**
496
510
  * Invokes an RPC method with the specified options.
497
511
  *
@@ -499,8 +513,19 @@ declare abstract class MultichainCore extends EventEmitter<SDKEvents> {
499
513
  * @returns Promise that resolves to the method result
500
514
  */
501
515
  abstract invokeMethod(options: InvokeMethodOptions): Promise<Json>;
502
- abstract openDeeplinkIfNeeded(): void;
516
+ abstract openSimpleDeeplinkIfNeeded(): void;
517
+ abstract emitSessionChanged(): Promise<void>;
503
518
  constructor(options: MultichainOptions);
519
+ /**
520
+ * Merges the given options into the current instance options.
521
+ * Only the mergeable keys are updated (api.supportedNetworks, ui.*, mobile.*, transport.extensionId, debug).
522
+ * The main thing to note is that the value for `dapp` is not merged as it does not make sense for
523
+ * subsequent calls to `createMultichainClient` to have a different `dapp` value.
524
+ * Used when createMultichainClient is called with an existing singleton.
525
+ *
526
+ * @param partial - Options to merge/overwrite onto the current instance
527
+ */
528
+ mergeOptions(partial: MergeableMultichainOptions): void;
504
529
  }
505
530
  declare function getTransportType(type: string): TransportType;
506
531
 
@@ -652,4 +677,4 @@ declare function getVersion(): string;
652
677
 
653
678
  declare const createMultichainClient: CreateMultichainFN;
654
679
 
655
- export { 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, 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 };
680
+ export { 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 };