@metamask/connect-multichain 0.5.2 → 0.6.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 (139) hide show
  1. package/CHANGELOG.md +38 -1
  2. package/README.md +415 -3
  3. package/dist/browser/es/connect-multichain.d.mts +33 -9
  4. package/dist/browser/es/connect-multichain.mjs +864 -510
  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 +33 -9
  8. package/dist/browser/iife/connect-multichain.js +24802 -24331
  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 +33 -9
  12. package/dist/browser/umd/connect-multichain.js +864 -510
  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 +33 -9
  16. package/dist/node/cjs/connect-multichain.js +693 -340
  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 +33 -9
  20. package/dist/node/es/connect-multichain.mjs +694 -339
  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 +33 -9
  24. package/dist/react-native/es/connect-multichain.mjs +857 -503
  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/logger/index.d.ts +1 -1
  28. package/dist/src/domain/logger/index.d.ts.map +1 -1
  29. package/dist/src/domain/logger/index.js.map +1 -1
  30. package/dist/src/domain/multichain/api/constants.js.map +1 -1
  31. package/dist/src/domain/multichain/api/types.d.ts +1 -1
  32. package/dist/src/domain/multichain/api/types.d.ts.map +1 -1
  33. package/dist/src/domain/multichain/index.d.ts +15 -4
  34. package/dist/src/domain/multichain/index.d.ts.map +1 -1
  35. package/dist/src/domain/multichain/index.js +14 -0
  36. package/dist/src/domain/multichain/index.js.map +1 -1
  37. package/dist/src/domain/multichain/types.d.ts +14 -0
  38. package/dist/src/domain/multichain/types.d.ts.map +1 -1
  39. package/dist/src/domain/platform/index.d.ts.map +1 -1
  40. package/dist/src/domain/platform/index.js +1 -0
  41. package/dist/src/domain/platform/index.js.map +1 -1
  42. package/dist/src/index.browser.d.ts.map +1 -1
  43. package/dist/src/index.browser.js +9 -4
  44. package/dist/src/index.browser.js.map +1 -1
  45. package/dist/src/index.native.d.ts.map +1 -1
  46. package/dist/src/index.native.js +9 -4
  47. package/dist/src/index.native.js.map +1 -1
  48. package/dist/src/index.node.d.ts.map +1 -1
  49. package/dist/src/index.node.js +8 -4
  50. package/dist/src/index.node.js.map +1 -1
  51. package/dist/src/multichain/index.d.ts +4 -3
  52. package/dist/src/multichain/index.d.ts.map +1 -1
  53. package/dist/src/multichain/index.js +181 -59
  54. package/dist/src/multichain/index.js.map +1 -1
  55. package/dist/src/multichain/rpc/handlers/rpcClient.d.ts +9 -2
  56. package/dist/src/multichain/rpc/handlers/rpcClient.d.ts.map +1 -1
  57. package/dist/src/multichain/rpc/handlers/rpcClient.js +13 -3
  58. package/dist/src/multichain/rpc/handlers/rpcClient.js.map +1 -1
  59. package/dist/src/multichain/rpc/requestRouter.d.ts +14 -1
  60. package/dist/src/multichain/rpc/requestRouter.d.ts.map +1 -1
  61. package/dist/src/multichain/rpc/requestRouter.js +27 -5
  62. package/dist/src/multichain/rpc/requestRouter.js.map +1 -1
  63. package/dist/src/multichain/transports/default/index.d.ts +5 -3
  64. package/dist/src/multichain/transports/default/index.d.ts.map +1 -1
  65. package/dist/src/multichain/transports/default/index.js +31 -28
  66. package/dist/src/multichain/transports/default/index.js.map +1 -1
  67. package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts +3 -3
  68. package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts.map +1 -1
  69. package/dist/src/multichain/transports/multichainApiClientWrapper/index.js +33 -29
  70. package/dist/src/multichain/transports/multichainApiClientWrapper/index.js.map +1 -1
  71. package/dist/src/multichain/transports/mwp/KeyManager.d.ts.map +1 -1
  72. package/dist/src/multichain/transports/mwp/KeyManager.js.map +1 -1
  73. package/dist/src/multichain/transports/mwp/index.d.ts +16 -3
  74. package/dist/src/multichain/transports/mwp/index.d.ts.map +1 -1
  75. package/dist/src/multichain/transports/mwp/index.js +157 -39
  76. package/dist/src/multichain/transports/mwp/index.js.map +1 -1
  77. package/dist/src/multichain/utils/analytics.d.ts.map +1 -1
  78. package/dist/src/multichain/utils/analytics.js +1 -0
  79. package/dist/src/multichain/utils/analytics.js.map +1 -1
  80. package/dist/src/multichain/utils/index.d.ts +48 -0
  81. package/dist/src/multichain/utils/index.d.ts.map +1 -1
  82. package/dist/src/multichain/utils/index.js +91 -6
  83. package/dist/src/multichain/utils/index.js.map +1 -1
  84. package/dist/src/polyfills/buffer-shim.js +5 -11
  85. package/dist/src/polyfills/buffer-shim.js.map +1 -1
  86. package/dist/src/store/adapters/node.d.ts +1 -1
  87. package/dist/src/store/adapters/node.d.ts.map +1 -1
  88. package/dist/src/store/adapters/node.js +11 -4
  89. package/dist/src/store/adapters/node.js.map +1 -1
  90. package/dist/src/store/adapters/rn.d.ts.map +1 -1
  91. package/dist/src/store/adapters/rn.js +1 -0
  92. package/dist/src/store/adapters/rn.js.map +1 -1
  93. package/dist/src/store/adapters/web.d.ts +5 -5
  94. package/dist/src/store/adapters/web.d.ts.map +1 -1
  95. package/dist/src/store/adapters/web.js +7 -1
  96. package/dist/src/store/adapters/web.js.map +1 -1
  97. package/dist/src/store/index.d.ts.map +1 -1
  98. package/dist/src/store/index.js +2 -0
  99. package/dist/src/store/index.js.map +1 -1
  100. package/dist/src/ui/ModalFactory.d.ts.map +1 -1
  101. package/dist/src/ui/ModalFactory.js +1 -4
  102. package/dist/src/ui/ModalFactory.js.map +1 -1
  103. package/dist/src/ui/index.d.ts.map +1 -1
  104. package/dist/src/ui/index.js +2 -0
  105. package/dist/src/ui/index.js.map +1 -1
  106. package/dist/src/ui/index.native.d.ts.map +1 -1
  107. package/dist/src/ui/index.native.js +4 -1
  108. package/dist/src/ui/index.native.js.map +1 -1
  109. package/dist/src/ui/modals/base/AbstractInstallModal.d.ts +2 -3
  110. package/dist/src/ui/modals/base/AbstractInstallModal.d.ts.map +1 -1
  111. package/dist/src/ui/modals/base/AbstractInstallModal.js +28 -12
  112. package/dist/src/ui/modals/base/AbstractInstallModal.js.map +1 -1
  113. package/dist/src/ui/modals/base/AbstractOTPModal.d.ts +2 -2
  114. package/dist/src/ui/modals/base/AbstractOTPModal.d.ts.map +1 -1
  115. package/dist/src/ui/modals/base/AbstractOTPModal.js.map +1 -1
  116. package/dist/src/ui/modals/base/utils.d.ts +12 -0
  117. package/dist/src/ui/modals/base/utils.d.ts.map +1 -1
  118. package/dist/src/ui/modals/base/utils.js +16 -5
  119. package/dist/src/ui/modals/base/utils.js.map +1 -1
  120. package/dist/src/ui/modals/node/install.d.ts.map +1 -1
  121. package/dist/src/ui/modals/node/install.js +1 -1
  122. package/dist/src/ui/modals/node/install.js.map +1 -1
  123. package/dist/src/ui/modals/node/otp.d.ts.map +1 -1
  124. package/dist/src/ui/modals/node/otp.js +6 -2
  125. package/dist/src/ui/modals/node/otp.js.map +1 -1
  126. package/dist/src/ui/modals/rn/install.d.ts.map +1 -1
  127. package/dist/src/ui/modals/rn/install.js +7 -3
  128. package/dist/src/ui/modals/rn/install.js.map +1 -1
  129. package/dist/src/ui/modals/rn/otp.d.ts.map +1 -1
  130. package/dist/src/ui/modals/rn/otp.js +6 -2
  131. package/dist/src/ui/modals/rn/otp.js.map +1 -1
  132. package/dist/src/ui/modals/web/install.d.ts.map +1 -1
  133. package/dist/src/ui/modals/web/install.js +1 -1
  134. package/dist/src/ui/modals/web/install.js.map +1 -1
  135. package/dist/src/ui/modals/web/otp.d.ts.map +1 -1
  136. package/dist/src/ui/modals/web/otp.js +6 -2
  137. package/dist/src/ui/modals/web/otp.js.map +1 -1
  138. package/dist/types/connect-multichain.d.ts +33 -9
  139. package/package.json +3 -3
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.6.0]
11
+
12
+ ### Added
13
+
14
+ - 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))
15
+
16
+ ### Changed
17
+
18
+ - **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))
19
+ - **BREAKING** `ConnectMultichain.openDeeplinkIfNeeded()` is renamed to `openSimpleDeeplinkIfNeeded()` ([#176](https://github.com/MetaMask/connect-monorepo/pull/176))
20
+ - `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))
21
+ - `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))
22
+ - `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))
23
+
24
+ ### Fixed
25
+
26
+ - `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))
27
+ - 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))
28
+ - 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))
29
+ - 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))
30
+ - 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))
31
+
32
+ ## [0.5.3]
33
+
34
+ ### Added
35
+
36
+ - `createMultichainClient()` now accepts an optional `debug` param option which enables console debug logs when set to `true`. Defaults to `false`. ([#149](https://github.com/MetaMask/connect-monorepo/pull/149))
37
+
38
+ ### Fixed
39
+
40
+ - Fix QR rejection handling: properly propagate user rejection errors from MetaMask Mobile to the dApp ([#156](https://github.com/MetaMask/connect-monorepo/pull/156))
41
+ - Close QR modal automatically when user rejects connection ([#156](https://github.com/MetaMask/connect-monorepo/pull/156))
42
+ - Use `@metamask/rpc-errors` for EIP-1193 compliant error handling ([#156](https://github.com/MetaMask/connect-monorepo/pull/156))
43
+ - 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))
44
+
10
45
  ## [0.5.2]
11
46
 
12
47
  ### Changed
@@ -122,7 +157,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
122
157
 
123
158
  - Initial release
124
159
 
125
- [Unreleased]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.5.2...HEAD
160
+ [Unreleased]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.6.0...HEAD
161
+ [0.6.0]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.5.3...@metamask/connect-multichain@0.6.0
162
+ [0.5.3]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.5.2...@metamask/connect-multichain@0.5.3
126
163
  [0.5.2]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.5.1...@metamask/connect-multichain@0.5.2
127
164
  [0.5.1]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.5.0...@metamask/connect-multichain@0.5.1
128
165
  [0.5.0]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-multichain@0.4.0...@metamask/connect-multichain@0.5.0
package/README.md CHANGED
@@ -1,15 +1,427 @@
1
1
  # `@metamask/connect-multichain`
2
2
 
3
- multichain
3
+ > Core multichain connectivity library for MetaMask Connect SDK. Supports multiple blockchain networks including EVM chains (Ethereum, Polygon, etc.) and non-EVM chains (Solana, etc.).
4
+
5
+ This package provides support for connecting to MetaMask and using the [CAIP Multichain API](https://github.com/MetaMask/metamask-improvement-proposals/blob/main/MIPs/mip-5.md) which agnostically supports making requests to multiple blockchain ecosystems simultaneously.
4
6
 
5
7
  ## Installation
6
8
 
7
- `yarn add @metamask/connect-multichain`
9
+ ```bash
10
+ yarn add @metamask/connect-multichain
11
+ ```
8
12
 
9
13
  or
10
14
 
11
- `npm install @metamask/connect-multichain`
15
+ ```bash
16
+ npm install @metamask/connect-multichain
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ```typescript
22
+ import {
23
+ createMultichainClient,
24
+ getInfuraRpcUrls,
25
+ } from '@metamask/connect-multichain';
26
+
27
+ const client = await createMultichainClient({
28
+ dapp: {
29
+ name: 'My DApp',
30
+ url: 'https://mydapp.com',
31
+ },
32
+ api: {
33
+ supportedNetworks: {
34
+ // use the `getInfuraRpcUrls` helper to generate a map of Infura RPC endpoints
35
+ ...getInfuraRpcUrls(INFURA_API_KEY),
36
+ // or specify your own CAIP Chain ID to rpc endpoint mapping
37
+ 'eip155:1': 'https://mainnet.example.io/rpc',
38
+ 'eip155:137': 'https://polygon-mainnet.example.io/rpc',
39
+ },
40
+ },
41
+ });
42
+
43
+ // Connect to MetaMask with specific chain scopes
44
+ await client.connect(['eip155:1', 'eip155:137'], []);
45
+
46
+ // Invoke methods on specific chains
47
+ const blockNumber = await client.invokeMethod({
48
+ scope: 'eip155:1',
49
+ request: {
50
+ method: 'eth_blockNumber',
51
+ params: [],
52
+ },
53
+ });
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ ### Browser (Web)
59
+
60
+ ```typescript
61
+ import { createMultichainClient } from '@metamask/connect-multichain';
62
+
63
+ const client = await createMultichainClient({
64
+ dapp: {
65
+ name: 'My Web DApp',
66
+ url: 'https://mydapp.com',
67
+ iconUrl: 'https://mydapp.com/icon.png',
68
+ },
69
+ api: {
70
+ supportedNetworks: {
71
+ 'eip155:1': 'https://mainnet.infura.io/v3/YOUR_KEY',
72
+ },
73
+ },
74
+ ui: {
75
+ preferExtension: true, // Prefer browser extension over mobile QR
76
+ showInstallModal: false, // Show modal to install extension
77
+ headless: false, // Set true for custom QR UI
78
+ },
79
+ });
80
+ ```
81
+
82
+ ### Node.js
83
+
84
+ ```typescript
85
+ import { createMultichainClient } from '@metamask/connect-multichain';
86
+
87
+ const client = await createMultichainClient({
88
+ dapp: {
89
+ name: 'My Node App',
90
+ url: 'https://mydapp.com',
91
+ },
92
+ api: {
93
+ supportedNetworks: {
94
+ 'eip155:1': 'https://mainnet.infura.io/v3/YOUR_KEY',
95
+ },
96
+ },
97
+ });
98
+
99
+ // Connect will display QR code in terminal
100
+ await client.connect(['eip155:1'], []);
101
+ ```
102
+
103
+ ### React Native
104
+
105
+ ```typescript
106
+ import { Linking } from 'react-native';
107
+ import { createMultichainClient } from '@metamask/connect-multichain';
108
+
109
+ const client = await createMultichainClient({
110
+ dapp: {
111
+ name: 'My RN App',
112
+ url: 'https://mydapp.com',
113
+ },
114
+ api: {
115
+ supportedNetworks: {
116
+ 'eip155:1': 'https://mainnet.infura.io/v3/YOUR_KEY',
117
+ },
118
+ },
119
+ mobile: {
120
+ preferredOpenLink: (deeplink) => {
121
+ Linking.openURL(deeplink);
122
+ },
123
+ },
124
+ });
125
+ ```
126
+
127
+ ## TypeScript
128
+
129
+ This package is written in TypeScript and includes full type definitions. No additional `@types` package is required.
130
+
131
+ ## API Reference
132
+
133
+ ### `createMultichainClient(options)`
134
+
135
+ Factory function to create a new Multichain SDK instance.
136
+
137
+ #### Parameters
138
+
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 |
157
+
158
+ #### Returns
159
+
160
+ `Promise<MetaMaskConnectMultichain>` - A fully initialized SDK instance.
161
+
162
+ ```typescript
163
+ const client = await createMultichainClient({
164
+ dapp: { name: 'My DApp', url: 'https://mydapp.com' },
165
+ api: {
166
+ supportedNetworks: {
167
+ 'eip155:1': 'https://mainnet.infura.io/v3/KEY',
168
+ 'eip155:137': 'https://polygon-mainnet.infura.io/v3/KEY',
169
+ },
170
+ },
171
+ });
172
+ ```
173
+
174
+ ---
175
+
176
+ ### `MetaMaskConnectMultichain`
177
+
178
+ The main SDK class extending `MultichainCore`.
179
+
180
+ #### Methods
181
+
182
+ ##### `connect(scopes, caipAccountIds, sessionProperties?, forceRequest?)`
183
+
184
+ Connects to MetaMask with specified chain scopes.
185
+
186
+ **Parameters**
187
+
188
+ | Name | Type | Required | Description |
189
+ | ------------------- | ------------------- | -------- | ------------------------------------------------------------------------------------------------------- |
190
+ | `scopes` | `Scope[]` | Yes | Array of CAIP-2 chain identifiers to request permission for |
191
+ | `caipAccountIds` | `CaipAccountId[]` | Yes | Array of CAIP-10 account identifiers to request (pass `[]` if no specific accounts should be requested) |
192
+ | `sessionProperties` | `SessionProperties` | No | Additional session properties |
193
+ | `forceRequest` | `boolean` | No | Force a new connection request even if already connected |
194
+
195
+ **Returns**
196
+
197
+ `Promise<void>`
198
+
199
+ ```typescript
200
+ await client.connect(
201
+ ['eip155:1', 'eip155:137'], // Chain scopes to request
202
+ ['eip155:1:0x...'], // Specific accounts to request
203
+ );
204
+ ```
205
+
206
+ ##### `disconnect(scopes?)`
207
+
208
+ 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
+
210
+ **Parameters**
211
+
212
+ | Name | Type | Required | Description |
213
+ | -------- | --------- | -------- | -------------------------------------------------------------------- |
214
+ | `scopes` | `Scope[]` | No | Array of CAIP-2 chain identifiers to revoke (defaults to all scopes) |
215
+
216
+ **Returns**
217
+
218
+ `Promise<void>`
219
+
220
+ ```typescript
221
+ // Fully disconnect
222
+ await client.disconnect();
223
+
224
+ // Disconnect only specific scopes
225
+ await client.disconnect(['eip155:1']);
226
+ ```
227
+
228
+ ##### `invokeMethod(options)`
229
+
230
+ Invokes an RPC method on a specific chain.
231
+
232
+ **Parameters**
233
+
234
+ | Name | Type | Required | Description |
235
+ | ------------------------ | ----------- | -------- | --------------------------------------------------- |
236
+ | `options.scope` | `Scope` | Yes | The CAIP-2 chain identifier to invoke the method on |
237
+ | `options.request.method` | `string` | Yes | The RPC method name |
238
+ | `options.request.params` | `unknown[]` | No | The method parameters |
239
+
240
+ **Returns**
241
+
242
+ `Promise<Json>` - The result of the RPC method call.
243
+
244
+ ```typescript
245
+ const result = await client.invokeMethod({
246
+ scope: 'eip155:1',
247
+ request: {
248
+ method: 'eth_getBalance',
249
+ params: ['0x...', 'latest'],
250
+ },
251
+ });
252
+ ```
253
+
254
+ #### Properties
255
+
256
+ | Property | Type | Description |
257
+ | ----------- | --------------------- | --------------------------------------------------------------------------------------------- |
258
+ | `status` | `ConnectionStatus` | Connection status ( `'loaded'`, `'pending'`, `'connecting'`, `'connected'`, `'disconnected'`) |
259
+ | `provider` | `MultichainApiClient` | Multichain API client |
260
+ | `transport` | `ExtendedTransport` | Active transport layer |
261
+
262
+ #### Events
263
+
264
+ ```typescript
265
+ // Session changes
266
+ client.on('wallet_sessionChanged', (session) => {
267
+ console.log('Session updated:', session);
268
+ });
269
+
270
+ // QR code display (for custom UI)
271
+ client.on('display_uri', (uri) => {
272
+ console.log('Display QR code:', uri);
273
+ });
274
+
275
+ // Connection state changes
276
+ client.on('stateChanged', (status) => {
277
+ console.log('Status:', status);
278
+ });
279
+ ```
280
+
281
+ ---
282
+
283
+ ### `MultichainCore`
284
+
285
+ Abstract base class providing core multichain functionality.
286
+
287
+ #### Methods
288
+
289
+ ##### `on(event, handler)`
290
+
291
+ Registers an event handler.
292
+
293
+ **Parameters**
294
+
295
+ | Name | Type | Required | Description |
296
+ | --------- | ---------- | -------- | --------------------------------------------------------- |
297
+ | `event` | `string` | Yes | The event name to listen for |
298
+ | `handler` | `Function` | Yes | The callback function to invoke when the event is emitted |
299
+
300
+ **Returns**
301
+
302
+ `void`
303
+
304
+ ##### `off(event, handler)`
305
+
306
+ Removes an event handler.
307
+
308
+ **Parameters**
309
+
310
+ | Name | Type | Required | Description |
311
+ | --------- | ---------- | -------- | ------------------------------------ |
312
+ | `event` | `string` | Yes | The event name to stop listening for |
313
+ | `handler` | `Function` | Yes | The callback function to remove |
314
+
315
+ **Returns**
316
+
317
+ `void`
318
+
319
+ ##### `emit(event, args)`
320
+
321
+ Emits an event to all registered handlers.
322
+
323
+ **Parameters**
324
+
325
+ | Name | Type | Required | Description |
326
+ | ------- | -------- | -------- | --------------------------------------- |
327
+ | `event` | `string` | Yes | The event name to emit |
328
+ | `args` | `any` | No | Arguments to pass to the event handlers |
329
+
330
+ **Returns**
331
+
332
+ `void`
333
+
334
+ ---
335
+
336
+ ### Utilities
337
+
338
+ #### `getInfuraRpcUrls(infuraApiKey)`
339
+
340
+ Generates Infura RPC URLs for common networks keyed by CAIP Chain ID.
341
+
342
+ **Parameters**
343
+
344
+ | Name | Type | Required | Description |
345
+ | -------------- | -------- | -------- | ------------------- |
346
+ | `infuraApiKey` | `string` | Yes | Your Infura API key |
347
+
348
+ **Returns**
349
+
350
+ A map of hex chain IDs to Infura RPC URLs. See https://docs.metamask.io/services
351
+
352
+ ```typescript
353
+ import { getInfuraRpcUrls } from '@metamask/connect-multichain';
354
+
355
+ const rpcUrls = getInfuraRpcUrls('YOUR_INFURA_KEY');
356
+ // {
357
+ // 'eip155:1': 'https://mainnet.infura.io/v3/YOUR_KEY',
358
+ // 'eip155:137': 'https://polygon-mainnet.infura.io/v3/YOUR_KEY',
359
+ // 'eip155:11155111': 'https://sepolia.infura.io/v3/YOUR_KEY',
360
+ // ...
361
+ // }
362
+ ```
363
+
364
+ ---
365
+
366
+ ### Errors
367
+
368
+ The package exports various error classes for handling specific error conditions:
369
+
370
+ - `ProtocolError` - Base protocol error
371
+ - `StorageError` - Storage operation errors
372
+ - `RpcError` - RPC request errors
373
+
374
+ ```typescript
375
+ import { ProtocolError } from '@metamask/connect-multichain';
376
+
377
+ try {
378
+ await client.connect(['eip155:1'], []);
379
+ } catch (error) {
380
+ if (error instanceof ProtocolError) {
381
+ console.log('Protocol error:', error.code, error.message);
382
+ }
383
+ }
384
+ ```
385
+
386
+ ---
387
+
388
+ ## Headless Mode
389
+
390
+ For custom QR code implementations, use headless mode:
391
+
392
+ ```typescript
393
+ const client = await createMultichainClient({
394
+ dapp: { name: 'My DApp' },
395
+ api: { supportedNetworks: { 'eip155:1': 'https://...' } },
396
+ ui: { headless: true },
397
+ });
398
+
399
+ // Listen for QR code URIs
400
+ client.on('display_uri', (uri) => {
401
+ // Display your custom QR code with this URI
402
+ displayMyCustomQRCode(uri);
403
+ });
404
+
405
+ await client.connect(['eip155:1'], []);
406
+ ```
407
+
408
+ ## Standards
409
+
410
+ - [CAIP-25](https://chainagnostic.org/CAIPs/caip-25) (please see CAIP Multichain API)
411
+ - [CAIP-27](https://chainagnostic.org/CAIPs/caip-27)
412
+ - [CAIP-2](https://chainagnostic.org/CAIPs/caip-2)
413
+ - [CAIP-10](https://chainagnostic.org/CAIPs/caip-10)
414
+ - [CAIP-217](https://chainagnostic.org/CAIPs/caip-217)
415
+ - [CAIP-316](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-316.md)
416
+ - [CAIP-312](https://chainagnostic.org/CAIPs/caip-312)
417
+ - [CAIP-311](https://chainagnostic.org/CAIPs/caip-311)
418
+ - [CAIP-285](https://chainagnostic.org/CAIPs/caip-285)
419
+ - [CAIP Multichain API](https://github.com/MetaMask/metamask-improvement-proposals/blob/main/MIPs/mip-5.md)
12
420
 
13
421
  ## Contributing
14
422
 
15
423
  This package is part of a monorepo. Instructions for contributing can be found in the [monorepo README](https://github.com/MetaMask/connect-monorepo#readme).
424
+
425
+ ## License
426
+
427
+ MIT
@@ -265,17 +265,16 @@ type RPCResponse = {
265
265
  result: unknown;
266
266
  };
267
267
 
268
- declare abstract class AbstractOTPCodeModal extends Modal<OTPCodeWidgetProps, OTPCode> {
268
+ declare abstract class AbstractOTPCodeModal extends Modal<OTPCodeWidgetProps> {
269
269
  protected instance?: HTMLMmOtpModalElement | undefined;
270
270
  get otpCode(): string;
271
271
  set otpCode(code: string);
272
272
  updateOTPCode(code: string): void;
273
273
  }
274
274
 
275
- declare abstract class AbstractInstallModal extends Modal<InstallWidgetProps, QRLink> {
275
+ declare abstract class AbstractInstallModal extends Modal<InstallWidgetProps> {
276
+ #private;
276
277
  protected instance?: HTMLMmInstallModalElement | undefined;
277
- private expirationInterval;
278
- private lastLoggedCountdown;
279
278
  abstract renderQRCode(link: QRLink, connectionRequest: ConnectionRequest): void;
280
279
  get link(): QRLink;
281
280
  set link(link: QRLink);
@@ -428,12 +427,24 @@ type MultichainOptions = {
428
427
  extensionId?: string;
429
428
  onNotification?: (notification: unknown) => void;
430
429
  };
430
+ /** Enable debug logging */
431
+ debug?: boolean;
431
432
  };
432
433
  type MultiChainFNOptions = Omit<MultichainOptions, 'storage' | 'ui'> & {
433
434
  ui?: Omit<MultichainOptions['ui'], 'factory'>;
434
435
  } & {
435
436
  storage?: StoreClient;
436
437
  };
438
+ /**
439
+ * Options that can be merged/overwritten when createMultichainClient is called
440
+ * with an existing singleton.
441
+ */
442
+ type MergeableMultichainOptions = Omit<MultichainOptions, 'dapp' | 'analytics' | 'storage' | 'api' | 'ui' | 'transport'> & {
443
+ api?: MultichainOptions['api'];
444
+ ui?: Pick<MultichainOptions['ui'], 'headless' | 'preferExtension' | 'showInstallModal'>;
445
+ transport?: Pick<NonNullable<MultichainOptions['transport']>, 'extensionId'>;
446
+ debug?: boolean;
447
+ };
437
448
  /**
438
449
  * Complete options for Multichain SDK configuration.
439
450
  *
@@ -452,6 +463,8 @@ type ExtendedTransport = Omit<Transport, 'connect'> & {
452
463
  timeout?: number;
453
464
  }) => Promise<TResponse>;
454
465
  getActiveSession: () => Promise<Session | undefined>;
466
+ getStoredPendingSessionRequest: () => Promise<SessionRequest | null>;
467
+ disconnect: (scopes: Scope[]) => Promise<void>;
455
468
  };
456
469
 
457
470
  declare const infuraRpcUrls: RpcUrlsMap;
@@ -473,7 +486,7 @@ declare enum TransportType {
473
486
  * must provide, including session management, connection handling, and method invocation.
474
487
  */
475
488
  declare abstract class MultichainCore extends EventEmitter<SDKEvents> {
476
- protected readonly options: MultichainOptions;
489
+ protected options: MultichainOptions;
477
490
  abstract storage: StoreClient;
478
491
  abstract status: ConnectionStatus;
479
492
  abstract provider: MultichainApiClient<RPCAPI>;
@@ -490,7 +503,7 @@ declare abstract class MultichainCore extends EventEmitter<SDKEvents> {
490
503
  *
491
504
  * @returns Promise that resolves when disconnection is complete
492
505
  */
493
- abstract disconnect(): Promise<void>;
506
+ abstract disconnect(scopes?: Scope[]): Promise<void>;
494
507
  /**
495
508
  * Invokes an RPC method with the specified options.
496
509
  *
@@ -498,8 +511,19 @@ declare abstract class MultichainCore extends EventEmitter<SDKEvents> {
498
511
  * @returns Promise that resolves to the method result
499
512
  */
500
513
  abstract invokeMethod(options: InvokeMethodOptions): Promise<Json>;
501
- abstract openDeeplinkIfNeeded(): void;
514
+ abstract openSimpleDeeplinkIfNeeded(): void;
515
+ abstract emitSessionChanged(): Promise<void>;
502
516
  constructor(options: MultichainOptions);
517
+ /**
518
+ * Merges the given options into the current instance options.
519
+ * Only the mergeable keys are updated (api.supportedNetworks, ui.*, mobile.*, transport.extensionId, debug).
520
+ * The main thing to note is that the value for `dapp` is not merged as it does not make sense for
521
+ * subsequent calls to `createMultichainClient` to have a different `dapp` value.
522
+ * Used when createMultichainClient is called with an existing singleton.
523
+ *
524
+ * @param partial - Options to merge/overwrite onto the current instance
525
+ */
526
+ mergeOptions(partial: MergeableMultichainOptions): void;
503
527
  }
504
528
  declare function getTransportType(type: string): TransportType;
505
529
 
@@ -521,7 +545,7 @@ declare abstract class StoreClient {
521
545
  * Supported debug namespace types for the MetaMask SDK logger.
522
546
  * These namespaces help categorize and filter debug output.
523
547
  */
524
- type LoggerNameSpaces = 'metamask-sdk' | 'metamask-sdk:core' | 'metamask-sdk:provider' | 'metamask-sdk:ui' | 'metamask-sdk:transport';
548
+ type LoggerNameSpaces = 'metamask-sdk:*' | 'metamask-sdk' | 'metamask-sdk:core' | 'metamask-sdk:provider' | 'metamask-sdk:ui' | 'metamask-sdk:transport';
525
549
  /**
526
550
  * Creates a debug logger instance with the specified namespace and color.
527
551
  *
@@ -651,4 +675,4 @@ declare function getVersion(): string;
651
675
 
652
676
  declare const createMultichainClient: CreateMultichainFN;
653
677
 
654
- 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 };
678
+ 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 };