@web3auth/no-modal 10.5.5 → 10.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 (25) hide show
  1. package/dist/lib.cjs/base/utils.js +1 -1
  2. package/dist/lib.cjs/connectors/wallet-connect-v2-connector/WalletConnectV2Provider.js +25 -5
  3. package/dist/lib.cjs/connectors/wallet-connect-v2-connector/walletConnectV2Connector.js +14 -0
  4. package/dist/lib.cjs/connectors/wallet-connect-v2-connector/walletConnectV2Utils.js +22 -3
  5. package/dist/lib.cjs/providers/ethereum-mpc-provider/providers/signingProviders/EthereumSigningProvider.js +32 -0
  6. package/dist/lib.cjs/providers/ethereum-provider/rpc/ethRpcMiddlewares.js +10 -2
  7. package/dist/lib.cjs/react/wagmi/provider.js +15 -1
  8. package/dist/lib.cjs/types/base/chain/IChainInterface.d.ts +16 -1
  9. package/dist/lib.cjs/types/connectors/wallet-connect-v2-connector/WalletConnectV2Provider.d.ts +3 -1
  10. package/dist/lib.cjs/types/connectors/wallet-connect-v2-connector/walletConnectV2Utils.d.ts +6 -0
  11. package/dist/lib.cjs/types/providers/ethereum-mpc-provider/providers/signingProviders/EthereumSigningProvider.d.ts +2 -1
  12. package/dist/lib.cjs/types/providers/ethereum-provider/rpc/ethRpcMiddlewares.d.ts +1 -1
  13. package/dist/lib.cjs/types/providers/ethereum-provider/rpc/interfaces.d.ts +2 -0
  14. package/dist/lib.cjs/vue/wagmi/provider.js +15 -1
  15. package/dist/lib.esm/base/utils.js +1 -1
  16. package/dist/lib.esm/connectors/wallet-connect-v2-connector/WalletConnectV2Provider.js +27 -7
  17. package/dist/lib.esm/connectors/wallet-connect-v2-connector/walletConnectV2Connector.js +14 -0
  18. package/dist/lib.esm/connectors/wallet-connect-v2-connector/walletConnectV2Utils.js +19 -1
  19. package/dist/lib.esm/providers/ethereum-mpc-provider/providers/signingProviders/EthereumSigningProvider.js +32 -0
  20. package/dist/lib.esm/providers/ethereum-provider/rpc/ethRpcMiddlewares.js +10 -2
  21. package/dist/lib.esm/react/wagmi/provider.js +16 -2
  22. package/dist/lib.esm/vue/wagmi/provider.js +16 -2
  23. package/dist/noModal.umd.min.js +1 -1
  24. package/dist/noModal.umd.min.js.LICENSE.txt +9 -0
  25. package/package.json +11 -11
@@ -145,7 +145,7 @@ const getWalletServicesAnalyticsProperties = walletServicesConfig => {
145
145
  ws_default_portfolio: walletServicesConfig === null || walletServicesConfig === void 0 || (_walletServicesConfig1 = walletServicesConfig.whiteLabel) === null || _walletServicesConfig1 === void 0 ? void 0 : _walletServicesConfig1.defaultPortfolio
146
146
  };
147
147
  };
148
- const sdkVersion = "10.5.5";
148
+ const sdkVersion = "10.6.0";
149
149
  const getErrorAnalyticsProperties = error => {
150
150
  try {
151
151
  const code = error instanceof index.Web3AuthError ? error.code : error === null || error === void 0 ? void 0 : error.code;
@@ -77,11 +77,9 @@ class WalletConnectV2Provider extends baseProvider.BaseProvider {
77
77
  message: "Connector is not initialized, pass wallet connect connector in constructor",
78
78
  code: 4902
79
79
  });
80
- const currentChainConfig = this.getChain(chainId);
81
- const {
82
- chainId: currentChainId
83
- } = currentChainConfig;
84
- const currentNumChainId = parseInt(currentChainId, 16);
80
+ const newChainConfig = this.getChain(chainId);
81
+ if (!newChainConfig) throw index.WalletLoginError.connectionError("Chain config is not available");
82
+ const currentNumChainId = parseInt(this.getCurrentChainId(), 16);
85
83
  await walletConnectV2Utils.switchChain({
86
84
  connector: this.connector,
87
85
  chainId: currentNumChainId,
@@ -93,6 +91,18 @@ class WalletConnectV2Provider extends baseProvider.BaseProvider {
93
91
  chainId
94
92
  });
95
93
  }
94
+ async addChain(chainConfig) {
95
+ if (!this.connector) throw auth.providerErrors.custom({
96
+ message: "Connector is not initialized, pass wallet connect connector in constructor",
97
+ code: 4902
98
+ });
99
+ const currentNumChainId = parseInt(this.getCurrentChainId(), 16);
100
+ await walletConnectV2Utils.addChain({
101
+ connector: this.connector,
102
+ chainId: currentNumChainId,
103
+ chainConfig
104
+ });
105
+ }
96
106
  // no need to implement this method in wallet connect v2.
97
107
  async lookupNetwork(_, chainId) {
98
108
  return chainId;
@@ -166,6 +176,9 @@ class WalletConnectV2Provider extends baseProvider.BaseProvider {
166
176
  await this.switchChain({
167
177
  chainId
168
178
  });
179
+ },
180
+ addChain: async params => {
181
+ await this.addChain(params);
169
182
  }
170
183
  };
171
184
  const chainSwitchMiddleware = ethRpcMiddlewares.createEthChainSwitchMiddleware(chainSwitchHandlers);
@@ -230,6 +243,13 @@ class WalletConnectV2Provider extends baseProvider.BaseProvider {
230
243
  }
231
244
  });
232
245
  }
246
+ getCurrentChainId() {
247
+ const currentChain = this.state.chainId;
248
+ if (!currentChain || currentChain === "loading") {
249
+ return this.config.chains[0].chainId;
250
+ }
251
+ return currentChain;
252
+ }
233
253
  }
234
254
  _WalletConnectV2Provider = WalletConnectV2Provider;
235
255
  _defineProperty(WalletConnectV2Provider, "getProviderInstance", async params => {
@@ -448,6 +448,20 @@ class WalletConnectV2Connector extends baseConnector.BaseConnector {
448
448
  sessionRemovedByWallet: true
449
449
  });
450
450
  });
451
+ this.connector.events.on("session_expire", ({
452
+ topic
453
+ }) => {
454
+ var _this$activeSession6;
455
+ // Session has expired -> clean up the session
456
+ loglevel.log.info("Session expired event received for topic:", topic);
457
+ if (((_this$activeSession6 = this.activeSession) === null || _this$activeSession6 === void 0 ? void 0 : _this$activeSession6.topic) === topic) {
458
+ this.disconnect({
459
+ sessionRemovedByWallet: true
460
+ }).catch(error => {
461
+ loglevel.log.error("Failed to disconnect expired session", error);
462
+ });
463
+ }
464
+ });
451
465
  }
452
466
  async _getSignedMessage(challenge, accounts, chainNamespace) {
453
467
  const signedMessage = await this.provider.request({
@@ -2,7 +2,7 @@
2
2
 
3
3
  var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
4
4
  var bs58 = require('@toruslabs/bs58');
5
- var utils = require('@walletconnect/utils');
5
+ var utils$1 = require('@walletconnect/utils');
6
6
  var auth = require('@web3auth/auth');
7
7
  var wsEmbed = require('@web3auth/ws-embed');
8
8
  require('@babel/runtime/helpers/defineProperty');
@@ -18,6 +18,7 @@ require('../../base/plugin/errors.js');
18
18
  require('../../base/plugin/IPlugin.js');
19
19
  require('@toruslabs/constants');
20
20
  require('@toruslabs/http-helpers');
21
+ var utils = require('./utils.js');
21
22
 
22
23
  async function getLastActiveSession(signClient) {
23
24
  if (signClient.session.length) {
@@ -58,10 +59,10 @@ async function getAccounts(signClient) {
58
59
  if (!session) {
59
60
  throw auth.providerErrors.disconnected();
60
61
  }
61
- const accounts = utils.getAccountsFromNamespaces(session.namespaces);
62
+ const accounts = utils$1.getAccountsFromNamespaces(session.namespaces);
62
63
  if (accounts && accounts.length) {
63
64
  return [...new Set(accounts.map(add => {
64
- return utils.parseAccountId(add).address;
65
+ return utils$1.parseAccountId(add).address;
65
66
  }))];
66
67
  }
67
68
  throw index.WalletLoginError.connectionError("Failed to get accounts");
@@ -155,7 +156,25 @@ async function switchChain({
155
156
  chainId: newChainId
156
157
  }]);
157
158
  }
159
+ async function addChain({
160
+ connector,
161
+ chainId,
162
+ chainConfig
163
+ }) {
164
+ if (!chainConfig) {
165
+ throw auth.providerErrors.custom({
166
+ message: "Chain config is required",
167
+ code: 4902
168
+ });
169
+ }
170
+ const formattedChainId = utils.formatChainId(chainConfig.chainId);
171
+ const formattedChainConfig = _objectSpread(_objectSpread({}, chainConfig), {}, {
172
+ chainId: formattedChainId
173
+ });
174
+ await sendJrpcRequest(connector, `eip155:${chainId}`, "wallet_addEthereumChain", [formattedChainConfig]);
175
+ }
158
176
 
177
+ exports.addChain = addChain;
159
178
  exports.getAccounts = getAccounts;
160
179
  exports.getEthProviderHandlers = getEthProviderHandlers;
161
180
  exports.getSolProviderHandlers = getSolProviderHandlers;
@@ -141,6 +141,35 @@ class EthereumSigningProvider extends baseProvider.BaseProvider {
141
141
  });
142
142
  await this.setupProvider(this.state.signMethods, params.chainId);
143
143
  }
144
+ async addChain(chainConfig) {
145
+ if (!this._providerEngineProxy) throw auth.providerErrors.custom({
146
+ message: "Provider is not initialized",
147
+ code: 4902
148
+ });
149
+ if (!this.state.signMethods) {
150
+ throw auth.providerErrors.custom({
151
+ message: "sign methods are undefined",
152
+ code: 4902
153
+ });
154
+ }
155
+ // find existing chain config with the same chainId
156
+ const existingChain = this.config.chains.find(chain => chain.chainId === chainConfig.chainId);
157
+ if (existingChain) {
158
+ return;
159
+ }
160
+ // add the chain config to the config
161
+ this.config.chains.push({
162
+ chainId: chainConfig.chainId,
163
+ displayName: chainConfig.chainName,
164
+ rpcTarget: chainConfig.rpcUrls[0],
165
+ chainNamespace: baseControllers.CHAIN_NAMESPACES.EIP155,
166
+ blockExplorerUrl: chainConfig.blockExplorerUrls[0],
167
+ logo: chainConfig.iconUrls[0],
168
+ tickerName: chainConfig.nativeCurrency.name,
169
+ ticker: chainConfig.nativeCurrency.symbol,
170
+ decimals: chainConfig.nativeCurrency.decimals
171
+ });
172
+ }
144
173
  async lookupNetwork(_, chainId) {
145
174
  if (!this._providerEngineProxy) throw auth.providerErrors.custom({
146
175
  message: "Provider is not initialized",
@@ -164,6 +193,9 @@ class EthereumSigningProvider extends baseProvider.BaseProvider {
164
193
  await this.switchChain({
165
194
  chainId
166
195
  });
196
+ },
197
+ addChain: async params => {
198
+ await this.addChain(params);
167
199
  }
168
200
  };
169
201
  const chainSwitchMiddleware = ethRpcMiddlewares.createEthChainSwitchMiddleware(chainSwitchHandlers);
@@ -29,7 +29,8 @@ function createEthMiddleware(providerHandlers) {
29
29
  return ethMiddleware;
30
30
  }
31
31
  function createEthChainSwitchMiddleware({
32
- switchChain
32
+ switchChain,
33
+ addChain
33
34
  }) {
34
35
  async function updateChain(req, res) {
35
36
  var _req$params;
@@ -37,8 +38,15 @@ function createEthChainSwitchMiddleware({
37
38
  if (!chainParams) throw auth.rpcErrors.invalidParams("Missing chainId");
38
39
  res.result = await switchChain(chainParams);
39
40
  }
41
+ async function addChainConfig(req, res) {
42
+ var _req$params2;
43
+ const chainConfig = (_req$params2 = req.params) !== null && _req$params2 !== void 0 && _req$params2.length ? req.params[0] : undefined;
44
+ if (!chainConfig) throw auth.rpcErrors.invalidParams("Missing chainConfig");
45
+ res.result = await addChain(chainConfig);
46
+ }
40
47
  return auth.createScaffoldMiddleware({
41
- wallet_switchEthereumChain: auth.createAsyncMiddleware(updateChain)
48
+ wallet_switchEthereumChain: auth.createAsyncMiddleware(updateChain),
49
+ wallet_addEthereumChain: auth.createAsyncMiddleware(addChainConfig)
42
50
  });
43
51
  }
44
52
 
@@ -124,6 +124,20 @@ function WagmiProvider(_ref) {
124
124
  web3Auth,
125
125
  isInitialized
126
126
  } = useWeb3Auth.useWeb3Auth();
127
+ const getTransport = chain => {
128
+ const {
129
+ wsTarget,
130
+ rpcTarget,
131
+ fallbackWsTargets = [],
132
+ fallbackRpcTargets = []
133
+ } = chain;
134
+ const transports = [];
135
+ if (wsTarget) transports.push(wagmi.webSocket(wsTarget));
136
+ if (fallbackWsTargets.length > 0) transports.push(...fallbackWsTargets.map(target => wagmi.webSocket(target)));
137
+ if (rpcTarget) transports.push(wagmi.http(rpcTarget));
138
+ if (fallbackRpcTargets.length > 0) transports.push(...fallbackRpcTargets.map(target => wagmi.http(target)));
139
+ return wagmi.fallback(transports);
140
+ };
127
141
  const finalConfig = react.useMemo(() => {
128
142
  var _web3Auth$coreOptions;
129
143
  web3Auth === null || web3Auth === void 0 || web3Auth.setAnalyticsProperties({
@@ -174,7 +188,7 @@ function WagmiProvider(_ref) {
174
188
  } else {
175
189
  wagmiChains.push(wagmiChain);
176
190
  }
177
- finalConfig.transports[wagmiChain.id] = chain.wsTarget ? wagmi.webSocket(chain.wsTarget) : wagmi.http(chain.rpcTarget);
191
+ finalConfig.transports[wagmiChain.id] = getTransport(chain);
178
192
  });
179
193
  finalConfig.chains = [wagmiChains[0], ...wagmiChains.slice(1)];
180
194
  }
@@ -8,4 +8,19 @@ export declare const CONNECTOR_NAMESPACES: {
8
8
  };
9
9
  export type ConnectorNamespaceType = (typeof CONNECTOR_NAMESPACES)[keyof typeof CONNECTOR_NAMESPACES];
10
10
  export { CHAIN_NAMESPACES, type ChainNamespaceType };
11
- export type CustomChainConfig = ProviderConfig;
11
+ export type CustomChainConfig = ProviderConfig & {
12
+ fallbackRpcTargets?: string[];
13
+ fallbackWsTargets?: string[];
14
+ };
15
+ export type AddEthereumChainConfig = {
16
+ chainId: string;
17
+ chainName: string;
18
+ rpcUrls: string[];
19
+ blockExplorerUrls: string[];
20
+ nativeCurrency: {
21
+ name: string;
22
+ symbol: string;
23
+ decimals: number;
24
+ };
25
+ iconUrls: string[];
26
+ };
@@ -1,5 +1,5 @@
1
1
  import type { ISignClient } from "@walletconnect/types";
2
- import { CustomChainConfig } from "../../base";
2
+ import { AddEthereumChainConfig, CustomChainConfig } from "../../base";
3
3
  import { BaseProvider, BaseProviderConfig, BaseProviderState } from "../../providers/base-provider";
4
4
  export type WalletConnectV2ProviderConfig = BaseProviderConfig;
5
5
  export interface WalletConnectV2ProviderState extends BaseProviderState {
@@ -23,6 +23,7 @@ export declare class WalletConnectV2Provider extends BaseProvider<BaseProviderCo
23
23
  switchChain({ chainId }: {
24
24
  chainId: string;
25
25
  }): Promise<void>;
26
+ addChain(chainConfig: AddEthereumChainConfig): Promise<void>;
26
27
  protected lookupNetwork(_: ISignClient, chainId: string): Promise<string>;
27
28
  private setupEngine;
28
29
  private setupEthEngine;
@@ -31,4 +32,5 @@ export declare class WalletConnectV2Provider extends BaseProvider<BaseProviderCo
31
32
  private connectedTopic;
32
33
  private checkIfAccountAllowed;
33
34
  private onConnectorStateUpdate;
35
+ private getCurrentChainId;
34
36
  }
@@ -1,4 +1,5 @@
1
1
  import type { ISignClient } from "@walletconnect/types";
2
+ import { AddEthereumChainConfig } from "../../base";
2
3
  import type { IEthProviderHandlers } from "../../providers/ethereum-provider";
3
4
  import type { ISolanaProviderHandlers } from "../../providers/solana-provider";
4
5
  export declare function sendJrpcRequest<T, U>(signClient: ISignClient, chainId: string, method: string, params: U): Promise<T>;
@@ -16,3 +17,8 @@ export declare function switchChain({ connector, chainId, newChainId, }: {
16
17
  chainId: number;
17
18
  newChainId: string;
18
19
  }): Promise<void>;
20
+ export declare function addChain({ connector, chainId, chainConfig, }: {
21
+ connector: ISignClient;
22
+ chainId: number;
23
+ chainConfig: AddEthereumChainConfig;
24
+ }): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { CustomChainConfig } from "../../../../base";
1
+ import { AddEthereumChainConfig, CustomChainConfig } from "../../../../base";
2
2
  import { BaseProvider, BaseProviderConfig, BaseProviderState } from "../../../../providers/base-provider";
3
3
  interface ProviderParams {
4
4
  sign: (msgHash: Buffer, rawMsg?: Buffer) => Promise<{
@@ -66,6 +66,7 @@ export declare class EthereumSigningProvider extends BaseProvider<BaseProviderCo
66
66
  switchChain(params: {
67
67
  chainId: string;
68
68
  }): Promise<void>;
69
+ addChain(chainConfig: AddEthereumChainConfig): Promise<void>;
69
70
  protected lookupNetwork(_: ProviderParams, chainId: string): Promise<string>;
70
71
  private getChainSwitchMiddleware;
71
72
  private getAccountMiddleware;
@@ -1,4 +1,4 @@
1
1
  import { JRPCMiddleware } from "@web3auth/auth";
2
2
  import { IEthChainSwitchHandlers, IEthProviderHandlers } from "./interfaces";
3
3
  export declare function createEthMiddleware(providerHandlers: IEthProviderHandlers): JRPCMiddleware<unknown, unknown>;
4
- export declare function createEthChainSwitchMiddleware({ switchChain }: IEthChainSwitchHandlers): JRPCMiddleware<unknown, unknown>;
4
+ export declare function createEthChainSwitchMiddleware({ switchChain, addChain }: IEthChainSwitchHandlers): JRPCMiddleware<unknown, unknown>;
@@ -1,5 +1,6 @@
1
1
  import type { JRPCRequest } from "@web3auth/auth";
2
2
  import type { TransactionLike, TypedDataDomain, TypedDataField } from "ethers";
3
+ import { AddEthereumChainConfig } from "../../../base";
3
4
  export interface IEthAccountHandlers {
4
5
  updatePrivatekey: (params: {
5
6
  privateKey: string;
@@ -9,6 +10,7 @@ export interface IEthChainSwitchHandlers {
9
10
  switchChain: (params: {
10
11
  chainId: string;
11
12
  }) => Promise<void>;
13
+ addChain: (params: AddEthereumChainConfig) => Promise<void>;
12
14
  }
13
15
  export type TransactionParams<A = string> = TransactionLike<A> & {
14
16
  input?: string;
@@ -150,6 +150,20 @@ const WagmiProvider = vue.defineComponent({
150
150
  } = useWeb3Auth.useWeb3Auth();
151
151
  const finalConfig = vue.shallowRef(constants.defaultWagmiConfig);
152
152
  const configKey = vue.ref(auth.randomId());
153
+ const getTransport = chain => {
154
+ const {
155
+ wsTarget,
156
+ rpcTarget,
157
+ fallbackWsTargets = [],
158
+ fallbackRpcTargets = []
159
+ } = chain;
160
+ const transports = [];
161
+ if (wsTarget) transports.push(viem.webSocket(wsTarget));
162
+ if (fallbackWsTargets.length > 0) transports.push(...fallbackWsTargets.map(target => viem.webSocket(target)));
163
+ if (rpcTarget) transports.push(viem.http(rpcTarget));
164
+ if (fallbackRpcTargets.length > 0) transports.push(...fallbackRpcTargets.map(target => viem.http(target)));
165
+ return viem.fallback(transports);
166
+ };
153
167
  const defineWagmiConfig = () => {
154
168
  var _web3Auth$value;
155
169
  const configParams = _objectSpread(_objectSpread({
@@ -196,7 +210,7 @@ const WagmiProvider = vue.defineComponent({
196
210
  } else {
197
211
  wagmiChains.push(wagmiChain);
198
212
  }
199
- configParams.transports[wagmiChain.id] = chain.wsTarget ? viem.webSocket(chain.wsTarget) : viem.http(chain.rpcTarget);
213
+ configParams.transports[wagmiChain.id] = getTransport(chain);
200
214
  });
201
215
  configParams.chains = [wagmiChains[0], ...wagmiChains.slice(1)];
202
216
  }
@@ -145,7 +145,7 @@ const getWalletServicesAnalyticsProperties = walletServicesConfig => {
145
145
  ws_default_portfolio: walletServicesConfig === null || walletServicesConfig === void 0 || (_walletServicesConfig1 = walletServicesConfig.whiteLabel) === null || _walletServicesConfig1 === void 0 ? void 0 : _walletServicesConfig1.defaultPortfolio
146
146
  };
147
147
  };
148
- const sdkVersion = "10.5.5";
148
+ const sdkVersion = "10.6.0";
149
149
  const getErrorAnalyticsProperties = error => {
150
150
  try {
151
151
  const code = error instanceof Web3AuthError ? error.code : error === null || error === void 0 ? void 0 : error.code;
@@ -3,14 +3,14 @@ import _defineProperty from '@babel/runtime/helpers/defineProperty';
3
3
  import { getAccountsFromNamespaces, parseAccountId } from '@walletconnect/utils';
4
4
  import { providerErrors, JRPCEngine, providerFromEngine } from '@web3auth/auth';
5
5
  import { formatChainId } from './utils.js';
6
- import { switchChain, getAccounts, getEthProviderHandlers, getSolProviderHandlers } from './walletConnectV2Utils.js';
6
+ import { switchChain, addChain, getAccounts, getEthProviderHandlers, getSolProviderHandlers } from './walletConnectV2Utils.js';
7
7
  import { createEthMiddleware, createEthChainSwitchMiddleware } from '../../providers/ethereum-provider/rpc/ethRpcMiddlewares.js';
8
8
  import { createEthJsonRpcClient } from '../../providers/ethereum-provider/rpc/jrpcClient.js';
9
9
  import { createSolanaMiddleware } from '../../providers/solana-provider/rpc/solanaRpcMiddlewares.js';
10
10
  import { createSolanaJsonRpcClient } from '../../providers/solana-provider/rpc/JrpcClient.js';
11
11
  import { BaseProvider } from '../../providers/base-provider/baseProvider.js';
12
- import { CHAIN_NAMESPACES } from '@toruslabs/base-controllers';
13
12
  import { WalletLoginError } from '../../base/errors/index.js';
13
+ import { CHAIN_NAMESPACES } from '@toruslabs/base-controllers';
14
14
  import { log } from '../../base/loglevel.js';
15
15
 
16
16
  var _WalletConnectV2Provider;
@@ -55,11 +55,9 @@ class WalletConnectV2Provider extends BaseProvider {
55
55
  message: "Connector is not initialized, pass wallet connect connector in constructor",
56
56
  code: 4902
57
57
  });
58
- const currentChainConfig = this.getChain(chainId);
59
- const {
60
- chainId: currentChainId
61
- } = currentChainConfig;
62
- const currentNumChainId = parseInt(currentChainId, 16);
58
+ const newChainConfig = this.getChain(chainId);
59
+ if (!newChainConfig) throw WalletLoginError.connectionError("Chain config is not available");
60
+ const currentNumChainId = parseInt(this.getCurrentChainId(), 16);
63
61
  await switchChain({
64
62
  connector: this.connector,
65
63
  chainId: currentNumChainId,
@@ -71,6 +69,18 @@ class WalletConnectV2Provider extends BaseProvider {
71
69
  chainId
72
70
  });
73
71
  }
72
+ async addChain(chainConfig) {
73
+ if (!this.connector) throw providerErrors.custom({
74
+ message: "Connector is not initialized, pass wallet connect connector in constructor",
75
+ code: 4902
76
+ });
77
+ const currentNumChainId = parseInt(this.getCurrentChainId(), 16);
78
+ await addChain({
79
+ connector: this.connector,
80
+ chainId: currentNumChainId,
81
+ chainConfig
82
+ });
83
+ }
74
84
 
75
85
  // no need to implement this method in wallet connect v2.
76
86
  async lookupNetwork(_, chainId) {
@@ -145,6 +155,9 @@ class WalletConnectV2Provider extends BaseProvider {
145
155
  await this.switchChain({
146
156
  chainId
147
157
  });
158
+ },
159
+ addChain: async params => {
160
+ await this.addChain(params);
148
161
  }
149
162
  };
150
163
  const chainSwitchMiddleware = createEthChainSwitchMiddleware(chainSwitchHandlers);
@@ -209,6 +222,13 @@ class WalletConnectV2Provider extends BaseProvider {
209
222
  }
210
223
  });
211
224
  }
225
+ getCurrentChainId() {
226
+ const currentChain = this.state.chainId;
227
+ if (!currentChain || currentChain === "loading") {
228
+ return this.config.chains[0].chainId;
229
+ }
230
+ return currentChain;
231
+ }
212
232
  }
213
233
  _WalletConnectV2Provider = WalletConnectV2Provider;
214
234
  _defineProperty(WalletConnectV2Provider, "getProviderInstance", async params => {
@@ -448,6 +448,20 @@ class WalletConnectV2Connector extends BaseConnector {
448
448
  sessionRemovedByWallet: true
449
449
  });
450
450
  });
451
+ this.connector.events.on("session_expire", ({
452
+ topic
453
+ }) => {
454
+ var _this$activeSession6;
455
+ // Session has expired -> clean up the session
456
+ log.info("Session expired event received for topic:", topic);
457
+ if (((_this$activeSession6 = this.activeSession) === null || _this$activeSession6 === void 0 ? void 0 : _this$activeSession6.topic) === topic) {
458
+ this.disconnect({
459
+ sessionRemovedByWallet: true
460
+ }).catch(error => {
461
+ log.error("Failed to disconnect expired session", error);
462
+ });
463
+ }
464
+ });
451
465
  }
452
466
  async _getSignedMessage(challenge, accounts, chainNamespace) {
453
467
  const signedMessage = await this.provider.request({
@@ -3,6 +3,7 @@ import { bs58 } from '@toruslabs/bs58';
3
3
  import { getAccountsFromNamespaces, parseAccountId } from '@walletconnect/utils';
4
4
  import { providerErrors, rpcErrors } from '@web3auth/auth';
5
5
  import { EVM_METHOD_TYPES, SOLANA_METHOD_TYPES } from '@web3auth/ws-embed';
6
+ import { formatChainId } from './utils.js';
6
7
  import { WalletLoginError } from '../../base/errors/index.js';
7
8
  import { SOLANA_CAIP_CHAIN_MAP } from '../../base/constants.js';
8
9
 
@@ -142,5 +143,22 @@ async function switchChain({
142
143
  chainId: newChainId
143
144
  }]);
144
145
  }
146
+ async function addChain({
147
+ connector,
148
+ chainId,
149
+ chainConfig
150
+ }) {
151
+ if (!chainConfig) {
152
+ throw providerErrors.custom({
153
+ message: "Chain config is required",
154
+ code: 4902
155
+ });
156
+ }
157
+ const formattedChainId = formatChainId(chainConfig.chainId);
158
+ const formattedChainConfig = _objectSpread(_objectSpread({}, chainConfig), {}, {
159
+ chainId: formattedChainId
160
+ });
161
+ await sendJrpcRequest(connector, `eip155:${chainId}`, "wallet_addEthereumChain", [formattedChainConfig]);
162
+ }
145
163
 
146
- export { getAccounts, getEthProviderHandlers, getSolProviderHandlers, sendJrpcRequest, switchChain };
164
+ export { addChain, getAccounts, getEthProviderHandlers, getSolProviderHandlers, sendJrpcRequest, switchChain };
@@ -125,6 +125,35 @@ class EthereumSigningProvider extends BaseProvider {
125
125
  });
126
126
  await this.setupProvider(this.state.signMethods, params.chainId);
127
127
  }
128
+ async addChain(chainConfig) {
129
+ if (!this._providerEngineProxy) throw providerErrors.custom({
130
+ message: "Provider is not initialized",
131
+ code: 4902
132
+ });
133
+ if (!this.state.signMethods) {
134
+ throw providerErrors.custom({
135
+ message: "sign methods are undefined",
136
+ code: 4902
137
+ });
138
+ }
139
+ // find existing chain config with the same chainId
140
+ const existingChain = this.config.chains.find(chain => chain.chainId === chainConfig.chainId);
141
+ if (existingChain) {
142
+ return;
143
+ }
144
+ // add the chain config to the config
145
+ this.config.chains.push({
146
+ chainId: chainConfig.chainId,
147
+ displayName: chainConfig.chainName,
148
+ rpcTarget: chainConfig.rpcUrls[0],
149
+ chainNamespace: CHAIN_NAMESPACES.EIP155,
150
+ blockExplorerUrl: chainConfig.blockExplorerUrls[0],
151
+ logo: chainConfig.iconUrls[0],
152
+ tickerName: chainConfig.nativeCurrency.name,
153
+ ticker: chainConfig.nativeCurrency.symbol,
154
+ decimals: chainConfig.nativeCurrency.decimals
155
+ });
156
+ }
128
157
  async lookupNetwork(_, chainId) {
129
158
  if (!this._providerEngineProxy) throw providerErrors.custom({
130
159
  message: "Provider is not initialized",
@@ -148,6 +177,9 @@ class EthereumSigningProvider extends BaseProvider {
148
177
  await this.switchChain({
149
178
  chainId
150
179
  });
180
+ },
181
+ addChain: async params => {
182
+ await this.addChain(params);
151
183
  }
152
184
  };
153
185
  const chainSwitchMiddleware = createEthChainSwitchMiddleware(chainSwitchHandlers);
@@ -27,7 +27,8 @@ function createEthMiddleware(providerHandlers) {
27
27
  return ethMiddleware;
28
28
  }
29
29
  function createEthChainSwitchMiddleware({
30
- switchChain
30
+ switchChain,
31
+ addChain
31
32
  }) {
32
33
  async function updateChain(req, res) {
33
34
  var _req$params;
@@ -35,8 +36,15 @@ function createEthChainSwitchMiddleware({
35
36
  if (!chainParams) throw rpcErrors.invalidParams("Missing chainId");
36
37
  res.result = await switchChain(chainParams);
37
38
  }
39
+ async function addChainConfig(req, res) {
40
+ var _req$params2;
41
+ const chainConfig = (_req$params2 = req.params) !== null && _req$params2 !== void 0 && _req$params2.length ? req.params[0] : undefined;
42
+ if (!chainConfig) throw rpcErrors.invalidParams("Missing chainConfig");
43
+ res.result = await addChain(chainConfig);
44
+ }
38
45
  return createScaffoldMiddleware({
39
- wallet_switchEthereumChain: createAsyncMiddleware(updateChain)
46
+ wallet_switchEthereumChain: createAsyncMiddleware(updateChain),
47
+ wallet_addEthereumChain: createAsyncMiddleware(addChainConfig)
40
48
  });
41
49
  }
42
50
 
@@ -2,7 +2,7 @@ import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProper
2
2
  import _objectSpread from '@babel/runtime/helpers/objectSpread2';
3
3
  import { useMemo, createElement, useEffect, Fragment } from 'react';
4
4
  import { defineChain } from 'viem';
5
- import { webSocket, http, createConfig, WagmiProvider as WagmiProvider$1, useConfig, useReconnect, useAccountEffect } from 'wagmi';
5
+ import { createConfig, WagmiProvider as WagmiProvider$1, webSocket, http, fallback, useConfig, useReconnect, useAccountEffect } from 'wagmi';
6
6
  import { injected } from 'wagmi/connectors';
7
7
  import { defaultWagmiConfig } from './constants.js';
8
8
  import { useWeb3Auth } from '../hooks/useWeb3Auth.js';
@@ -113,6 +113,20 @@ function WagmiProvider(_ref) {
113
113
  web3Auth,
114
114
  isInitialized
115
115
  } = useWeb3Auth();
116
+ const getTransport = chain => {
117
+ const {
118
+ wsTarget,
119
+ rpcTarget,
120
+ fallbackWsTargets = [],
121
+ fallbackRpcTargets = []
122
+ } = chain;
123
+ const transports = [];
124
+ if (wsTarget) transports.push(webSocket(wsTarget));
125
+ if (fallbackWsTargets.length > 0) transports.push(...fallbackWsTargets.map(target => webSocket(target)));
126
+ if (rpcTarget) transports.push(http(rpcTarget));
127
+ if (fallbackRpcTargets.length > 0) transports.push(...fallbackRpcTargets.map(target => http(target)));
128
+ return fallback(transports);
129
+ };
116
130
  const finalConfig = useMemo(() => {
117
131
  var _web3Auth$coreOptions;
118
132
  web3Auth === null || web3Auth === void 0 || web3Auth.setAnalyticsProperties({
@@ -163,7 +177,7 @@ function WagmiProvider(_ref) {
163
177
  } else {
164
178
  wagmiChains.push(wagmiChain);
165
179
  }
166
- finalConfig.transports[wagmiChain.id] = chain.wsTarget ? webSocket(chain.wsTarget) : http(chain.rpcTarget);
180
+ finalConfig.transports[wagmiChain.id] = getTransport(chain);
167
181
  });
168
182
  finalConfig.chains = [wagmiChains[0], ...wagmiChains.slice(1)];
169
183
  }