@web3auth/no-modal 11.0.0-beta.1 → 11.0.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.
- package/dist/lib.cjs/account-linking/errors.js +111 -0
- package/dist/lib.cjs/account-linking/index.js +4 -0
- package/dist/lib.cjs/account-linking/rest.js +6 -6
- package/dist/lib.cjs/account-linking/vue.js +0 -1
- package/dist/lib.cjs/base/connector/constants.js +2 -0
- package/dist/lib.cjs/base/errors/index.js +21 -50
- package/dist/lib.cjs/base/utils.js +1 -1
- package/dist/lib.cjs/connectors/auth-connector/authConnector.js +125 -58
- package/dist/lib.cjs/connectors/metamask-connector/metamaskConnector.js +40 -31
- package/dist/lib.cjs/index.js +24 -19
- package/dist/lib.cjs/noModal.js +60 -26
- package/dist/lib.cjs/providers/account-abstraction-provider/providers/AccountAbstractionProvider.js +8 -4
- package/dist/lib.cjs/providers/account-abstraction-provider/providers/utils.js +0 -17
- package/dist/lib.cjs/providers/account-abstraction-provider/rpc/ethRpcMiddlewares.js +15 -0
- package/dist/lib.cjs/react/context/useWeb3AuthInnerContextValue.js +18 -2
- package/dist/lib.cjs/react/solana/provider.js +6 -2
- package/dist/lib.cjs/react/wagmi/index.js +6 -0
- package/dist/lib.cjs/react/wagmi/provider.js +74 -23
- package/dist/lib.cjs/types/account-linking/errors.d.ts +17 -0
- package/dist/lib.cjs/types/account-linking/index.d.ts +1 -0
- package/dist/lib.cjs/types/base/connector/constants.d.ts +1 -0
- package/dist/lib.cjs/types/base/connector/interfaces.d.ts +1 -1
- package/dist/lib.cjs/types/base/errors/index.d.ts +2 -13
- package/dist/lib.cjs/types/connectors/auth-connector/authConnector.d.ts +8 -2
- package/dist/lib.cjs/types/connectors/auth-connector/interface.d.ts +1 -1
- package/dist/lib.cjs/types/noModal.d.ts +1 -1
- package/dist/lib.cjs/types/providers/account-abstraction-provider/rpc/ethRpcMiddlewares.d.ts +1 -0
- package/dist/lib.cjs/types/react/wagmi/constants.d.ts +2 -0
- package/dist/lib.cjs/types/react/wagmi/provider.d.ts +7 -0
- package/dist/lib.cjs/types/vue/wagmi/constants.d.ts +2 -0
- package/dist/lib.cjs/types/vue/wagmi/provider.d.ts +7 -1
- package/dist/lib.cjs/vue/solana/provider.js +50 -26
- package/dist/lib.cjs/vue/useWeb3AuthInnerContextValue.js +13 -6
- package/dist/lib.cjs/vue/wagmi/index.js +6 -0
- package/dist/lib.cjs/vue/wagmi/provider.js +78 -35
- package/dist/lib.esm/account-linking/errors.js +92 -0
- package/dist/lib.esm/account-linking/index.js +1 -0
- package/dist/lib.esm/account-linking/rest.js +3 -3
- package/dist/lib.esm/account-linking/vue.js +0 -1
- package/dist/lib.esm/base/connector/constants.js +2 -1
- package/dist/lib.esm/base/errors/index.js +21 -50
- package/dist/lib.esm/base/utils.js +1 -1
- package/dist/lib.esm/connectors/auth-connector/authConnector.js +109 -41
- package/dist/lib.esm/connectors/base-solana-connector/baseSolanaConnector.js +1 -1
- package/dist/lib.esm/connectors/metamask-connector/metamaskConnector.js +42 -33
- package/dist/lib.esm/index.js +3 -2
- package/dist/lib.esm/noModal.js +56 -20
- package/dist/lib.esm/providers/account-abstraction-provider/providers/AccountAbstractionProvider.js +10 -5
- package/dist/lib.esm/providers/account-abstraction-provider/providers/utils.js +0 -3
- package/dist/lib.esm/providers/account-abstraction-provider/rpc/ethRpcMiddlewares.js +17 -3
- package/dist/lib.esm/react/context/useWeb3AuthInnerContextValue.js +18 -2
- package/dist/lib.esm/react/solana/provider.js +6 -2
- package/dist/lib.esm/react/wagmi/index.js +1 -1
- package/dist/lib.esm/react/wagmi/provider.js +74 -25
- package/dist/lib.esm/vue/solana/provider.js +51 -28
- package/dist/lib.esm/vue/useWeb3AuthInnerContextValue.js +11 -4
- package/dist/lib.esm/vue/wagmi/index.js +1 -1
- package/dist/lib.esm/vue/wagmi/provider.js +73 -34
- package/package.json +20 -20
package/dist/lib.esm/noModal.js
CHANGED
|
@@ -3,11 +3,11 @@ import _objectSpread from '@babel/runtime/helpers/objectSpread2';
|
|
|
3
3
|
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
4
4
|
import { CHAIN_NAMESPACES, BUTTON_POSITION, CONFIRMATION_STRATEGY } from '@toruslabs/base-controllers';
|
|
5
5
|
import { SMART_ACCOUNT_EIP_STANDARD, EIP7702_SUPPORTED_SMART_ACCOUNT_TYPES } from '@toruslabs/ethereum-controllers';
|
|
6
|
-
import { SafeEventEmitter, serializeError, UX_MODE, cloneDeep, CookieStorage, LocalStorageAdapter, MemoryStorage } from '@web3auth/auth';
|
|
6
|
+
import { SafeEventEmitter, BUILD_ENV, serializeError, UX_MODE, cloneDeep, CookieStorage, LocalStorageAdapter, MemoryStorage } from '@web3auth/auth';
|
|
7
7
|
import deepmerge from 'deepmerge';
|
|
8
8
|
import { deserialize } from './base/deserialize.js';
|
|
9
|
-
import { WalletInitializationError, WalletLoginError, AccountLinkingError } from './base/errors/index.js';
|
|
10
9
|
import { LOGIN_MODE, SMART_ACCOUNT_WALLET_SCOPE, WEB3AUTH_STATE_STORAGE_KEY } from './base/constants.js';
|
|
10
|
+
import { WalletInitializationError, WalletLoginError } from './base/errors/index.js';
|
|
11
11
|
import { log } from './base/loglevel.js';
|
|
12
12
|
import { CONNECTOR_STATUS, CONNECTOR_INITIAL_AUTHENTICATION_MODE, CONNECTOR_EVENTS } from './base/connector/constants.js';
|
|
13
13
|
import { Analytics, ANALYTICS_INTEGRATION_TYPE, ANALYTICS_SDK_TYPE, ANALYTICS_EVENTS } from './base/analytics.js';
|
|
@@ -16,6 +16,7 @@ import { WALLET_CONNECTORS } from './base/wallet/index.js';
|
|
|
16
16
|
import { CONNECTOR_NAMESPACES } from './base/chain/IChainInterface.js';
|
|
17
17
|
import { CONNECTED_STATUSES, CAN_LOGOUT_STATUSES, CAN_AUTHORIZE_STATUSES } from './base/connector/connectorStatus.js';
|
|
18
18
|
import { assertAuthConnector, authConnector, isAuthConnector } from './connectors/auth-connector/authConnector.js';
|
|
19
|
+
import { AccountLinkingError } from './account-linking/errors.js';
|
|
19
20
|
import { CommonJRPCProvider } from './providers/base-provider/CommonJRPCProvider.js';
|
|
20
21
|
import { walletServicesPlugin } from './plugins/wallet-services-plugin/plugin.js';
|
|
21
22
|
import { metaMaskConnector } from './connectors/metamask-connector/metamaskConnector.js';
|
|
@@ -54,7 +55,9 @@ class Web3AuthNoModal extends SafeEventEmitter {
|
|
|
54
55
|
if (!options.clientId) throw WalletInitializationError.invalidParams("Please provide a valid clientId in constructor");
|
|
55
56
|
if (options.enableLogging) log.enableAll();else log.setLevel("error");
|
|
56
57
|
if (!options.initialAuthenticationMode) options.initialAuthenticationMode = CONNECTOR_INITIAL_AUTHENTICATION_MODE.CONNECT_AND_SIGN;
|
|
57
|
-
this.coreOptions = options
|
|
58
|
+
this.coreOptions = _objectSpread(_objectSpread({}, options), {}, {
|
|
59
|
+
authBuildEnv: options.authBuildEnv || BUILD_ENV.PRODUCTION
|
|
60
|
+
});
|
|
58
61
|
this.storage = this.getStorageMethod();
|
|
59
62
|
this.analytics = new Analytics();
|
|
60
63
|
if (options.disableAnalytics) {
|
|
@@ -925,7 +928,6 @@ class Web3AuthNoModal extends SafeEventEmitter {
|
|
|
925
928
|
}));
|
|
926
929
|
this.setActiveWalletConnectorKey();
|
|
927
930
|
this.connectionReconnected = data.reconnected;
|
|
928
|
-
const connectedChainId = ethereumProvider === null || ethereumProvider === void 0 ? void 0 : ethereumProvider.chainId;
|
|
929
931
|
|
|
930
932
|
// when ssr is enabled, we need to get the idToken from the connector.
|
|
931
933
|
if (this.coreOptions.ssr) {
|
|
@@ -950,14 +952,16 @@ class Web3AuthNoModal extends SafeEventEmitter {
|
|
|
950
952
|
// The following block only hits during rehydration
|
|
951
953
|
|
|
952
954
|
const {
|
|
953
|
-
activeAccount
|
|
955
|
+
activeAccount,
|
|
956
|
+
currentChainId
|
|
954
957
|
} = this.state;
|
|
955
|
-
|
|
958
|
+
let rehydrateWithLinkedAccount = false;
|
|
959
|
+
// for rehydration, if the active account is not the primary account, i.e. not `null`, create an isolated connector and connect to the chain
|
|
956
960
|
if (activeAccount && !activeAccount.isPrimary && activeAccount.connector !== WALLET_CONNECTORS.AUTH) {
|
|
957
961
|
var _ref3, _walletConnector$prov, _linkedAccountConnect, _ref4, _walletConnector$sola, _linkedAccountConnect2;
|
|
958
962
|
const accountLinkingConnector = isAuthConnector(connector) ? connector : this.getConnector(WALLET_CONNECTORS.AUTH);
|
|
959
963
|
assertAuthConnector(accountLinkingConnector, "Account switching requires the AUTH connector to be available.");
|
|
960
|
-
const targetChainId = accountLinkingConnector.getChainIdForLinkedAccount(activeAccount,
|
|
964
|
+
const targetChainId = accountLinkingConnector.getChainIdForLinkedAccount(activeAccount, currentChainId);
|
|
961
965
|
const walletConnector = await this.createIsolatedWalletConnector(activeAccount.connector, targetChainId);
|
|
962
966
|
let linkedAccountConnection = null;
|
|
963
967
|
if (!this.hasUsableConnectedSwitchConnector(walletConnector)) {
|
|
@@ -977,6 +981,7 @@ class Web3AuthNoModal extends SafeEventEmitter {
|
|
|
977
981
|
});
|
|
978
982
|
this.setConnectedWalletConnectorState(connectedWalletState, activeAccount);
|
|
979
983
|
this.setActiveWalletConnectorKey(activeAccount);
|
|
984
|
+
rehydrateWithLinkedAccount = true;
|
|
980
985
|
}
|
|
981
986
|
if (ethereumProvider) {
|
|
982
987
|
await this.bindPrimaryEthereumSigningProxy(ethereumProvider, data.connectorName);
|
|
@@ -989,24 +994,44 @@ class Web3AuthNoModal extends SafeEventEmitter {
|
|
|
989
994
|
});
|
|
990
995
|
this.setConnectedWalletConnectorState(primaryConnectedWalletState);
|
|
991
996
|
await this.setState({
|
|
992
|
-
primaryConnectorName: data.connectorName
|
|
993
|
-
currentChainId: connectedChainId
|
|
997
|
+
primaryConnectorName: data.connectorName
|
|
994
998
|
});
|
|
995
999
|
this.cacheWallet(data.connectorName);
|
|
996
1000
|
const isConnectAndSign = this.coreOptions.initialAuthenticationMode === CONNECTOR_INITIAL_AUTHENTICATION_MODE.CONNECT_AND_SIGN;
|
|
997
|
-
|
|
1001
|
+
const pendingUserConsent = this.consentRequired && !this.state.hasUserConsent;
|
|
1002
|
+
if (pendingUserConsent && !isConnectAndSign) {
|
|
998
1003
|
this.status = CONNECTOR_STATUS.CONSENT_REQUIRING;
|
|
999
1004
|
this.emit(CONNECTOR_EVENTS.CONSENT_REQUIRING);
|
|
1000
1005
|
log.debug("consent_requiring", this.status, this.primaryConnectorName);
|
|
1001
1006
|
} else {
|
|
1002
|
-
this.
|
|
1007
|
+
// In CONNECT_AND_SIGN mode the AUTHORIZED handler can run before this point (e.g. when `ssr=true`
|
|
1008
|
+
// this handler `await`s `connector.getAuthTokenInfo()` which fires AUTHORIZED mid-execution).
|
|
1009
|
+
// Don't downgrade an already-advanced status (CONSENT_REQUIRING or AUTHORIZED) back to CONNECTED;
|
|
1010
|
+
// otherwise `acceptConsent` would throw "Cannot accept consent: not in consent_requiring state".
|
|
1011
|
+
if (this.status !== CONNECTOR_STATUS.CONSENT_REQUIRING && this.status !== CONNECTOR_STATUS.AUTHORIZED) {
|
|
1012
|
+
this.status = CONNECTOR_STATUS.CONNECTED;
|
|
1013
|
+
}
|
|
1003
1014
|
log.debug("connected", this.status, this.primaryConnectorName);
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1015
|
+
// Defer plugin connection until consent is accepted; otherwise plugins would start before the consent step completes.
|
|
1016
|
+
// `completeConsentAcceptance` connects the plugins once the user accepts the consent.
|
|
1017
|
+
if (!pendingUserConsent) {
|
|
1018
|
+
this.connectToPlugins(_objectSpread(_objectSpread({}, data), {}, {
|
|
1019
|
+
connector: data.connectorName
|
|
1020
|
+
}));
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
// `pendingUserConsent` signals listeners (LoginModal, React/Vue contexts) to skip processing this CONNECTED event,
|
|
1024
|
+
// so the upcoming AUTHORIZED -> CONSENT_REQUIRING transition is not overridden by a late CONNECTED handler in CONNECT_AND_SIGN mode.
|
|
1007
1025
|
this.emit(CONNECTOR_EVENTS.CONNECTED, _objectSpread(_objectSpread({}, data), {}, {
|
|
1008
|
-
loginMode: this.loginMode
|
|
1026
|
+
loginMode: this.loginMode,
|
|
1027
|
+
pendingUserConsent
|
|
1009
1028
|
}));
|
|
1029
|
+
|
|
1030
|
+
// if we're rehydrating with a linked account, we need to emit a CONNECTION_UPDATED event
|
|
1031
|
+
// so that upstream listeners and context are updated with the linked connection.
|
|
1032
|
+
if (rehydrateWithLinkedAccount) {
|
|
1033
|
+
this.emit(CONNECTOR_EVENTS.CONNECTION_UPDATED, this.connection);
|
|
1034
|
+
}
|
|
1010
1035
|
}
|
|
1011
1036
|
});
|
|
1012
1037
|
connector.on(CONNECTOR_EVENTS.DISCONNECTED, async data => {
|
|
@@ -1226,7 +1251,15 @@ class Web3AuthNoModal extends SafeEventEmitter {
|
|
|
1226
1251
|
return activeChainId;
|
|
1227
1252
|
}
|
|
1228
1253
|
async createLinkingWalletConnector(connectorName, chainId, config) {
|
|
1229
|
-
|
|
1254
|
+
try {
|
|
1255
|
+
const linkingConnector = await this.createIsolatedWalletConnector(connectorName, chainId, config);
|
|
1256
|
+
return linkingConnector;
|
|
1257
|
+
} catch (error) {
|
|
1258
|
+
if (error instanceof AccountLinkingError && error.code === 5405) {
|
|
1259
|
+
throw error;
|
|
1260
|
+
}
|
|
1261
|
+
throw AccountLinkingError.walletProofFailed(error instanceof Error ? error.message : String(error), error);
|
|
1262
|
+
}
|
|
1230
1263
|
}
|
|
1231
1264
|
async createSwitchingWalletConnector(connectorName, chainId, config) {
|
|
1232
1265
|
return this.createIsolatedWalletConnector(connectorName, chainId, config);
|
|
@@ -1381,12 +1414,12 @@ class Web3AuthNoModal extends SafeEventEmitter {
|
|
|
1381
1414
|
account
|
|
1382
1415
|
});
|
|
1383
1416
|
}
|
|
1384
|
-
async linkAccountWithConnector(connectorName, chainId,
|
|
1417
|
+
async linkAccountWithConnector(connectorName, chainId, connectorToLink) {
|
|
1385
1418
|
const authConnector = this.getMainAuthConnector();
|
|
1386
1419
|
const result = await authConnector.linkAccount({
|
|
1387
1420
|
connectorName,
|
|
1388
1421
|
chainId,
|
|
1389
|
-
|
|
1422
|
+
connectorToLink,
|
|
1390
1423
|
authSessionTokens: {
|
|
1391
1424
|
accessToken: this.accessToken,
|
|
1392
1425
|
idToken: this.idToken
|
|
@@ -1395,7 +1428,7 @@ class Web3AuthNoModal extends SafeEventEmitter {
|
|
|
1395
1428
|
await this.setState({
|
|
1396
1429
|
idToken: result.idToken
|
|
1397
1430
|
});
|
|
1398
|
-
await this.cacheConnectedLinkedWalletConnector(authConnector,
|
|
1431
|
+
await this.cacheConnectedLinkedWalletConnector(authConnector, connectorToLink);
|
|
1399
1432
|
return result;
|
|
1400
1433
|
}
|
|
1401
1434
|
getMainAuthConnector() {
|
|
@@ -1575,7 +1608,10 @@ class Web3AuthNoModal extends SafeEventEmitter {
|
|
|
1575
1608
|
});
|
|
1576
1609
|
}
|
|
1577
1610
|
async setCurrentChain(chainId) {
|
|
1578
|
-
|
|
1611
|
+
const {
|
|
1612
|
+
currentChainId
|
|
1613
|
+
} = this.state;
|
|
1614
|
+
if (chainId === currentChainId) return;
|
|
1579
1615
|
const newChain = this.coreOptions.chains.find(chain => chain.chainId === chainId);
|
|
1580
1616
|
if (!newChain) throw WalletInitializationError.invalidParams(`Invalid chainId: ${chainId}`);
|
|
1581
1617
|
await this.setState({
|
package/dist/lib.esm/providers/account-abstraction-provider/providers/AccountAbstractionProvider.js
CHANGED
|
@@ -5,7 +5,7 @@ export { SMART_ACCOUNT } from '@toruslabs/ethereum-controllers';
|
|
|
5
5
|
import { JRPCEngineV2, providerFromEngineV2, providerErrors } from '@web3auth/auth';
|
|
6
6
|
import { defineChain, createPublicClient, http, createWalletClient, custom } from 'viem';
|
|
7
7
|
import { createPaymasterClient, createBundlerClient } from 'viem/account-abstraction';
|
|
8
|
-
import { createEoaMiddleware, providerAsMiddleware, createAaMiddleware } from '../rpc/ethRpcMiddlewares.js';
|
|
8
|
+
import { createEoaMiddleware, providerAsMiddleware, createAaMiddleware, createEip7702And5792MiddlewareForAaProvider } from '../rpc/ethRpcMiddlewares.js';
|
|
9
9
|
import { getProviderHandlers } from './utils.js';
|
|
10
10
|
import { BaseProvider } from '../../base-provider/baseProvider.js';
|
|
11
11
|
import { CHAIN_NAMESPACES } from '@toruslabs/base-controllers';
|
|
@@ -55,9 +55,10 @@ class AccountAbstractionProvider extends BaseProvider {
|
|
|
55
55
|
}
|
|
56
56
|
async setupProvider(eoaProvider) {
|
|
57
57
|
var _bundlerConfig$transp;
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
const currentChain = this.currentChain;
|
|
59
|
+
if (!currentChain) {
|
|
60
|
+
throw WalletInitializationError.invalidProviderConfigError(`AA chain config not found for chain ${this.chainId}`);
|
|
61
|
+
}
|
|
61
62
|
const {
|
|
62
63
|
chainNamespace
|
|
63
64
|
} = currentChain;
|
|
@@ -134,9 +135,13 @@ class AccountAbstractionProvider extends BaseProvider {
|
|
|
134
135
|
eoaProvider,
|
|
135
136
|
handlers: providerHandlers
|
|
136
137
|
});
|
|
138
|
+
|
|
139
|
+
// middleware to handle EIP-7702 and EIP-5792 methods,
|
|
140
|
+
// currently, we do not support EIP-7702 and EIP-5792 methods for account abstraction provider
|
|
141
|
+
const eip7702And5792Middleware = await createEip7702And5792MiddlewareForAaProvider();
|
|
137
142
|
const eoaMiddleware = providerAsMiddleware(eoaProvider);
|
|
138
143
|
const engine = JRPCEngineV2.create({
|
|
139
|
-
middleware: [aaMiddleware, eoaMiddleware]
|
|
144
|
+
middleware: [aaMiddleware, eip7702And5792Middleware, eoaMiddleware]
|
|
140
145
|
});
|
|
141
146
|
const provider = providerFromEngineV2(engine);
|
|
142
147
|
this.updateProviderEngineProxy(provider);
|
|
@@ -2,7 +2,6 @@ import _objectSpread from '@babel/runtime/helpers/objectSpread2';
|
|
|
2
2
|
import { isHexString, add0x } from '@toruslabs/metadata-helpers';
|
|
3
3
|
import { providerErrors } from '@web3auth/auth';
|
|
4
4
|
import { createWalletClient, http } from 'viem';
|
|
5
|
-
import { log } from '../../../base/loglevel.js';
|
|
6
5
|
|
|
7
6
|
function getProviderHandlers({
|
|
8
7
|
bundlerClient,
|
|
@@ -20,8 +19,6 @@ function getProviderHandlers({
|
|
|
20
19
|
const [smartAccounts, eoaAccounts] = await Promise.all([smartAccount.getAddress(), eoaProvider.request({
|
|
21
20
|
method: "eth_accounts"
|
|
22
21
|
})]);
|
|
23
|
-
log.info("smartAccounts", smartAccounts);
|
|
24
|
-
log.info("eoaAccounts", eoaAccounts);
|
|
25
22
|
return [smartAccounts, ...eoaAccounts];
|
|
26
23
|
},
|
|
27
24
|
getPrivateKey: async _ => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _objectSpread from '@babel/runtime/helpers/objectSpread2';
|
|
2
|
-
import { METHOD_TYPES } from '@toruslabs/ethereum-controllers';
|
|
3
|
-
import { createScaffoldMiddlewareV2, rpcErrors } from '@web3auth/auth';
|
|
2
|
+
import { METHOD_TYPES, EIP_5792_METHODS, EIP_7702_METHODS } from '@toruslabs/ethereum-controllers';
|
|
3
|
+
import { createScaffoldMiddlewareV2, providerErrors, rpcErrors } from '@web3auth/auth';
|
|
4
4
|
|
|
5
5
|
async function createAaMiddleware({
|
|
6
6
|
eoaProvider,
|
|
@@ -181,6 +181,20 @@ async function createEoaMiddleware({
|
|
|
181
181
|
eth_requestAccounts: requestAccounts
|
|
182
182
|
});
|
|
183
183
|
}
|
|
184
|
+
async function createEip7702And5792MiddlewareForAaProvider() {
|
|
185
|
+
const eip5792Methods = Object.values(EIP_5792_METHODS);
|
|
186
|
+
const eip7702Methods = Object.values(EIP_7702_METHODS);
|
|
187
|
+
const eip7702And5792Methods = [...eip5792Methods, ...eip7702Methods];
|
|
188
|
+
return async ({
|
|
189
|
+
request,
|
|
190
|
+
next
|
|
191
|
+
}) => {
|
|
192
|
+
if (eip7702And5792Methods.includes(request.method)) {
|
|
193
|
+
throw providerErrors.unsupportedMethod(`${request.method} is not supported for account abstraction provider`);
|
|
194
|
+
}
|
|
195
|
+
return next(request);
|
|
196
|
+
};
|
|
197
|
+
}
|
|
184
198
|
function providerAsMiddleware(provider) {
|
|
185
199
|
return async ({
|
|
186
200
|
request
|
|
@@ -192,4 +206,4 @@ function providerAsMiddleware(provider) {
|
|
|
192
206
|
};
|
|
193
207
|
}
|
|
194
208
|
|
|
195
|
-
export { createAaMiddleware, createEoaMiddleware, providerAsMiddleware };
|
|
209
|
+
export { createAaMiddleware, createEip7702And5792MiddlewareForAaProvider, createEoaMiddleware, providerAsMiddleware };
|
|
@@ -127,19 +127,26 @@ function useWeb3AuthInnerContextValue({
|
|
|
127
127
|
const authorizedListener = () => {
|
|
128
128
|
setStatus(web3Auth.status);
|
|
129
129
|
if (web3Auth.status === CONNECTOR_STATUS.AUTHORIZED) {
|
|
130
|
+
var _web3Auth$currentChai7, _web3Auth$currentChai8;
|
|
131
|
+
setIsInitialized(true);
|
|
130
132
|
setIsConnected(true);
|
|
133
|
+
// on rehydration, `AUTHORIZED` event can be fired first in `CONNECT_AND_SIGN` mode, before `CONNECTED` event.
|
|
134
|
+
// Update the connection state here, so that clients can use the connection state immediately.
|
|
135
|
+
setConnection(web3Auth.connection);
|
|
136
|
+
setChainId(web3Auth.currentChainId);
|
|
137
|
+
setChainNamespace((_web3Auth$currentChai7 = (_web3Auth$currentChai8 = web3Auth.currentChain) === null || _web3Auth$currentChai8 === void 0 ? void 0 : _web3Auth$currentChai8.chainNamespace) !== null && _web3Auth$currentChai7 !== void 0 ? _web3Auth$currentChai7 : null);
|
|
131
138
|
setIsAuthorized(true);
|
|
132
139
|
}
|
|
133
140
|
};
|
|
134
141
|
const consentAcceptedListener = () => {
|
|
135
142
|
setStatus(web3Auth.status);
|
|
136
143
|
if (web3Auth.status === CONNECTOR_STATUS.CONNECTED || web3Auth.status === CONNECTOR_STATUS.AUTHORIZED) {
|
|
137
|
-
var _web3Auth$
|
|
144
|
+
var _web3Auth$currentChai9, _web3Auth$currentChai0;
|
|
138
145
|
setIsInitialized(true);
|
|
139
146
|
setIsConnected(true);
|
|
140
147
|
setConnection(web3Auth.connection);
|
|
141
148
|
setChainId(web3Auth.currentChainId);
|
|
142
|
-
setChainNamespace((_web3Auth$
|
|
149
|
+
setChainNamespace((_web3Auth$currentChai9 = (_web3Auth$currentChai0 = web3Auth.currentChain) === null || _web3Auth$currentChai0 === void 0 ? void 0 : _web3Auth$currentChai0.chainNamespace) !== null && _web3Auth$currentChai9 !== void 0 ? _web3Auth$currentChai9 : null);
|
|
143
150
|
if (web3Auth.status === CONNECTOR_STATUS.AUTHORIZED) {
|
|
144
151
|
setIsAuthorized(true);
|
|
145
152
|
}
|
|
@@ -148,6 +155,13 @@ function useWeb3AuthInnerContextValue({
|
|
|
148
155
|
const mfaEnabledListener = nextIsMFAEnabled => {
|
|
149
156
|
if (typeof nextIsMFAEnabled === "boolean") setIsMFAEnabled(nextIsMFAEnabled);
|
|
150
157
|
};
|
|
158
|
+
const connectionUpdatedListener = () => {
|
|
159
|
+
var _web3Auth$currentChai1, _web3Auth$currentChai10;
|
|
160
|
+
setStatus(web3Auth.status);
|
|
161
|
+
setConnection(web3Auth.connection);
|
|
162
|
+
setChainId(web3Auth.currentChainId);
|
|
163
|
+
setChainNamespace((_web3Auth$currentChai1 = (_web3Auth$currentChai10 = web3Auth.currentChain) === null || _web3Auth$currentChai10 === void 0 ? void 0 : _web3Auth$currentChai10.chainNamespace) !== null && _web3Auth$currentChai1 !== void 0 ? _web3Auth$currentChai1 : null);
|
|
164
|
+
};
|
|
151
165
|
if (web3Auth) {
|
|
152
166
|
web3Auth.on(CONNECTOR_EVENTS.NOT_READY, notReadyListener);
|
|
153
167
|
web3Auth.on(CONNECTOR_EVENTS.READY, readyListener);
|
|
@@ -158,6 +172,7 @@ function useWeb3AuthInnerContextValue({
|
|
|
158
172
|
web3Auth.on(CONNECTOR_EVENTS.ERRORED, errorListener);
|
|
159
173
|
web3Auth.on(CONNECTOR_EVENTS.REHYDRATION_ERROR, rehydrationErrorListener);
|
|
160
174
|
web3Auth.on(CONNECTOR_EVENTS.MFA_ENABLED, mfaEnabledListener);
|
|
175
|
+
web3Auth.on(CONNECTOR_EVENTS.CONNECTION_UPDATED, connectionUpdatedListener);
|
|
161
176
|
if (web3Auth.loginMode === LOGIN_MODE.MODAL) {
|
|
162
177
|
web3Auth.on(CONNECTOR_EVENTS.CONSENT_ACCEPTED, consentAcceptedListener);
|
|
163
178
|
}
|
|
@@ -173,6 +188,7 @@ function useWeb3AuthInnerContextValue({
|
|
|
173
188
|
web3Auth.removeListener(CONNECTOR_EVENTS.REHYDRATION_ERROR, rehydrationErrorListener);
|
|
174
189
|
web3Auth.removeListener(CONNECTOR_EVENTS.MFA_ENABLED, mfaEnabledListener);
|
|
175
190
|
web3Auth.removeListener(CONNECTOR_EVENTS.AUTHORIZED, authorizedListener);
|
|
191
|
+
web3Auth.removeListener(CONNECTOR_EVENTS.CONNECTION_UPDATED, connectionUpdatedListener);
|
|
176
192
|
if (web3Auth.loginMode === LOGIN_MODE.MODAL) {
|
|
177
193
|
web3Auth.removeListener(CONNECTOR_EVENTS.CONSENT_ACCEPTED, consentAcceptedListener);
|
|
178
194
|
}
|
|
@@ -52,6 +52,7 @@ function useFrameworkKitSolanaClient() {
|
|
|
52
52
|
isInitialized
|
|
53
53
|
} = useWeb3Auth();
|
|
54
54
|
const {
|
|
55
|
+
chainId,
|
|
55
56
|
chainNamespace
|
|
56
57
|
} = useChain();
|
|
57
58
|
const ref = useRef(null);
|
|
@@ -102,7 +103,10 @@ function useFrameworkKitSolanaClient() {
|
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
// only reconnect for the primary connector
|
|
105
|
-
if (conn.connectorName !== (web3Auth === null || web3Auth === void 0 ? void 0 : web3Auth.primaryConnectorName))
|
|
106
|
+
if (conn.connectorName !== (web3Auth === null || web3Auth === void 0 ? void 0 : web3Auth.primaryConnectorName)) {
|
|
107
|
+
adopt(makePlaceholder(rpc));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
106
110
|
try {
|
|
107
111
|
const solanaWalletId = "wallet-standard:" + conn.connectorName;
|
|
108
112
|
const connector = createWalletStandardConnector(solanaWallet, {
|
|
@@ -134,7 +138,7 @@ function useFrameworkKitSolanaClient() {
|
|
|
134
138
|
return () => {
|
|
135
139
|
stale = true;
|
|
136
140
|
};
|
|
137
|
-
}, [isConnected, connection === null || connection === void 0 ? void 0 : connection.solanaWallet, chainNamespace, web3Auth, isInitialized, connection === null || connection === void 0 ? void 0 : connection.connectorName]);
|
|
141
|
+
}, [isConnected, connection === null || connection === void 0 ? void 0 : connection.solanaWallet, chainId, chainNamespace, web3Auth, isInitialized, connection === null || connection === void 0 ? void 0 : connection.connectorName]);
|
|
138
142
|
return client;
|
|
139
143
|
}
|
|
140
144
|
function SolanaProvider(_ref) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { WagmiProvider } from './provider.js';
|
|
1
|
+
export { WagmiProvider, connectWeb3AuthWithWagmi, createWeb3AuthConnectorForWagmi, disconnectWeb3AuthFromWagmi, getWeb3authConnector, resetConnectorState, setupConnector } from './provider.js';
|
|
@@ -1,42 +1,61 @@
|
|
|
1
1
|
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
|
|
2
2
|
import _objectSpread from '@babel/runtime/helpers/objectSpread2';
|
|
3
|
-
import { useMemo, createElement, useEffect, Fragment } from 'react';
|
|
4
|
-
import { defineChain } from 'viem';
|
|
5
|
-
import { createConfig, WagmiProvider as WagmiProvider$1, webSocket, http, fallback, useConfig, useReconnect, useConnectionEffect } from 'wagmi';
|
|
6
|
-
import { injected } from 'wagmi/connectors';
|
|
3
|
+
import { useMemo, createElement, useRef, useEffect, Fragment } from 'react';
|
|
4
|
+
import { defineChain, isAddress } from 'viem';
|
|
5
|
+
import { createConfig, WagmiProvider as WagmiProvider$1, injected, webSocket, http, fallback, useConfig, useReconnect, useConnectionEffect } from 'wagmi';
|
|
7
6
|
import { defaultWagmiConfig } from './constants.js';
|
|
8
7
|
import { useWeb3Auth } from '../hooks/useWeb3Auth.js';
|
|
9
8
|
import { CHAIN_NAMESPACES } from '@toruslabs/base-controllers';
|
|
10
9
|
import { WalletInitializationError } from '../../base/errors/index.js';
|
|
11
|
-
import {
|
|
10
|
+
import { WEB3AUTH_CONNECTOR_ID } from '../../base/connector/constants.js';
|
|
12
11
|
import { log } from '../../base/loglevel.js';
|
|
12
|
+
import { useWeb3AuthDisconnect } from '../hooks/useWeb3AuthDisconnect.js';
|
|
13
13
|
|
|
14
14
|
const _excluded = ["children"];
|
|
15
|
-
const WEB3AUTH_CONNECTOR_ID = "web3auth";
|
|
16
15
|
function getWeb3authConnector(config) {
|
|
17
16
|
return config.connectors.find(c => c.id === WEB3AUTH_CONNECTOR_ID);
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
// Helper to
|
|
19
|
+
// Helper to create a Web3Auth connector to connect with wagmi
|
|
21
20
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (connector) return connector;
|
|
25
|
-
|
|
26
|
-
// Create new connector if not already existing
|
|
27
|
-
connector = injected({
|
|
21
|
+
function createWeb3AuthConnectorForWagmi(provider) {
|
|
22
|
+
const baseConnector = injected({
|
|
28
23
|
target: {
|
|
29
24
|
provider: provider,
|
|
30
25
|
id: WEB3AUTH_CONNECTOR_ID,
|
|
31
26
|
name: "Web3Auth"
|
|
32
27
|
}
|
|
33
28
|
});
|
|
29
|
+
return config => {
|
|
30
|
+
const connector = baseConnector(config);
|
|
31
|
+
const baseOnAccountsChanged = connector.onAccountsChanged.bind(connector);
|
|
32
|
+
|
|
33
|
+
// we need to handle the `accountsChanged` event emitted on the cross-namespace chain switch.
|
|
34
|
+
// on evm -> solana, the accountsChanged event is emitted with the solana address, which is not valid for evm.
|
|
35
|
+
// that causes the `invalid account address` error in wagmi. So, here, we're filtering out the solana addresses.
|
|
36
|
+
connector.onAccountsChanged = accounts => {
|
|
37
|
+
if (accounts.length > 0 && !accounts.every(account => typeof account === "string" && isAddress(account))) {
|
|
38
|
+
log.warn("onAccountsChanged::accountsChanged event received on non-EVM address");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
baseOnAccountsChanged(accounts);
|
|
42
|
+
};
|
|
43
|
+
return connector;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Helper to initialize connectors for the given wallets
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
49
|
+
function setupConnector(provider, config) {
|
|
50
|
+
let connector = getWeb3authConnector(config);
|
|
51
|
+
if (connector) return connector;
|
|
52
|
+
|
|
53
|
+
// Create new connector if not already existing
|
|
54
|
+
connector = createWeb3AuthConnectorForWagmi(provider);
|
|
34
55
|
const result = config._internal.connectors.setup(connector);
|
|
35
56
|
config._internal.connectors.setState(current => [...current, result]);
|
|
36
57
|
return result;
|
|
37
58
|
}
|
|
38
|
-
|
|
39
|
-
// Helper to connect a wallet and update wagmi state
|
|
40
59
|
async function connectWeb3AuthWithWagmi(connector, config) {
|
|
41
60
|
var _config$storage, _config$storage2;
|
|
42
61
|
await Promise.all([(_config$storage = config.storage) === null || _config$storage === void 0 ? void 0 : _config$storage.removeItem(`${connector.id}.disconnected`), (_config$storage2 = config.storage) === null || _config$storage2 === void 0 ? void 0 : _config$storage2.setItem("recentConnectorId", connector.id)]);
|
|
@@ -76,9 +95,11 @@ async function disconnectWeb3AuthFromWagmi(config) {
|
|
|
76
95
|
function Web3AuthWagmiProvider({
|
|
77
96
|
children
|
|
78
97
|
}) {
|
|
98
|
+
var _connection$ethereumP, _connection$connector;
|
|
79
99
|
const {
|
|
80
100
|
isConnected,
|
|
81
|
-
connection
|
|
101
|
+
connection,
|
|
102
|
+
chainNamespace
|
|
82
103
|
} = useWeb3Auth();
|
|
83
104
|
const {
|
|
84
105
|
disconnect
|
|
@@ -87,34 +108,62 @@ function Web3AuthWagmiProvider({
|
|
|
87
108
|
const {
|
|
88
109
|
mutate: reconnect
|
|
89
110
|
} = useReconnect();
|
|
111
|
+
const suppressWagmiDisconnect = useRef(false);
|
|
112
|
+
const lastSyncedProvider = useRef((_connection$ethereumP = connection === null || connection === void 0 ? void 0 : connection.ethereumProvider) !== null && _connection$ethereumP !== void 0 ? _connection$ethereumP : null);
|
|
113
|
+
const lastSyncedConnectorName = useRef((_connection$connector = connection === null || connection === void 0 ? void 0 : connection.connectorName) !== null && _connection$connector !== void 0 ? _connection$connector : null);
|
|
90
114
|
useConnectionEffect({
|
|
91
115
|
onDisconnect: async () => {
|
|
92
116
|
log.info("Disconnected from wagmi");
|
|
93
|
-
|
|
94
|
-
|
|
117
|
+
const isSuppressed = suppressWagmiDisconnect.current;
|
|
118
|
+
suppressWagmiDisconnect.current = false;
|
|
119
|
+
if (!isSuppressed && isConnected) await disconnect();
|
|
120
|
+
|
|
95
121
|
// reset wagmi connector state if the provider handles disconnection because of the accountsChanged event
|
|
96
122
|
// from the connected provider
|
|
97
|
-
if (
|
|
123
|
+
if (getWeb3authConnector(wagmiConfig)) {
|
|
98
124
|
resetConnectorState(wagmiConfig);
|
|
99
125
|
}
|
|
100
126
|
}
|
|
101
127
|
});
|
|
102
128
|
useEffect(() => {
|
|
103
|
-
(async
|
|
104
|
-
|
|
105
|
-
|
|
129
|
+
(async _connection$ethereumP2 => {
|
|
130
|
+
const newConnection = connection !== null && connection !== void 0 ? connection : null;
|
|
131
|
+
const newEth = (_connection$ethereumP2 = connection === null || connection === void 0 ? void 0 : connection.ethereumProvider) !== null && _connection$ethereumP2 !== void 0 ? _connection$ethereumP2 : null;
|
|
132
|
+
const w3aWagmiConnector = getWeb3authConnector(wagmiConfig);
|
|
133
|
+
const shouldBindToWagmi = isConnected && chainNamespace === CHAIN_NAMESPACES.EIP155 && Boolean(newConnection && newEth);
|
|
134
|
+
if (shouldBindToWagmi) {
|
|
135
|
+
const hasSameBinding = lastSyncedProvider.current === newEth && lastSyncedConnectorName.current === newConnection.connectorName && wagmiConfig.state.status === "connected";
|
|
136
|
+
if (hasSameBinding) {
|
|
137
|
+
// rehydration: already connected to the same provider, so no need to reconnect
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// `ethereumProvider` is a stable proxy (`commonJRPCProvider`) across account switches,
|
|
142
|
+
// so key wagmi resyncs off the Web3Auth connection object instead of provider identity.
|
|
143
|
+
if (w3aWagmiConnector) {
|
|
144
|
+
resetConnectorState(wagmiConfig);
|
|
145
|
+
}
|
|
146
|
+
lastSyncedProvider.current = newEth;
|
|
147
|
+
lastSyncedConnectorName.current = newConnection.connectorName;
|
|
148
|
+
const connector = setupConnector(newEth, wagmiConfig);
|
|
106
149
|
if (!connector) {
|
|
150
|
+
log.error("Failed to setup react wagmi connector");
|
|
107
151
|
throw new Error("Failed to setup connector");
|
|
108
152
|
}
|
|
109
153
|
await connectWeb3AuthWithWagmi(connector, wagmiConfig);
|
|
110
154
|
reconnect();
|
|
111
|
-
} else
|
|
155
|
+
} else {
|
|
156
|
+
lastSyncedProvider.current = null;
|
|
157
|
+
lastSyncedConnectorName.current = null;
|
|
112
158
|
if (wagmiConfig.state.status === "connected") {
|
|
159
|
+
suppressWagmiDisconnect.current = true;
|
|
113
160
|
await disconnectWeb3AuthFromWagmi(wagmiConfig);
|
|
161
|
+
} else if (w3aWagmiConnector) {
|
|
162
|
+
resetConnectorState(wagmiConfig);
|
|
114
163
|
}
|
|
115
164
|
}
|
|
116
165
|
})();
|
|
117
|
-
}, [
|
|
166
|
+
}, [chainNamespace, connection, isConnected, reconnect, wagmiConfig]);
|
|
118
167
|
return createElement(Fragment, null, children);
|
|
119
168
|
}
|
|
120
169
|
function WagmiProvider(_ref) {
|
|
@@ -208,4 +257,4 @@ function WagmiProvider(_ref) {
|
|
|
208
257
|
}), createElement(Web3AuthWagmiProvider, null, children));
|
|
209
258
|
}
|
|
210
259
|
|
|
211
|
-
export { WagmiProvider };
|
|
260
|
+
export { WagmiProvider, connectWeb3AuthWithWagmi, createWeb3AuthConnectorForWagmi, disconnectWeb3AuthFromWagmi, getWeb3authConnector, resetConnectorState, setupConnector };
|
|
@@ -3,6 +3,7 @@ import { defineComponent, ref, provide, watch, h, Fragment } from 'vue';
|
|
|
3
3
|
import { CHAIN_NAMESPACES } from '@toruslabs/base-controllers';
|
|
4
4
|
import { SOLANA_CLIENT_KEY } from './constants.js';
|
|
5
5
|
import { useWeb3Auth } from '../composables/useWeb3Auth.js';
|
|
6
|
+
import { useChain } from '../composables/useChain.js';
|
|
6
7
|
import { log } from '../../base/loglevel.js';
|
|
7
8
|
|
|
8
9
|
const disposeClient = async client => {
|
|
@@ -29,63 +30,85 @@ const SolanaProvider = defineComponent({
|
|
|
29
30
|
connection,
|
|
30
31
|
web3Auth
|
|
31
32
|
} = useWeb3Auth();
|
|
33
|
+
const {
|
|
34
|
+
chainId
|
|
35
|
+
} = useChain();
|
|
32
36
|
const clientRef = ref(null);
|
|
37
|
+
// Holds the token for the newest requested sync run. Older async runs compare against it
|
|
38
|
+
// before publishing results so a slower reconnect cannot overwrite a newer chain/account update.
|
|
39
|
+
let activeSyncToken = null;
|
|
33
40
|
|
|
34
41
|
// provide the client to the app
|
|
35
42
|
provide(SOLANA_CLIENT_KEY, clientRef);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
const syncClient = async () => {
|
|
44
|
+
var _web3Auth$value, _web3Auth$value2;
|
|
45
|
+
// Only the latest async, `syncing` run should be allowed to attach its client.
|
|
46
|
+
// A fresh Symbol gives each run a unique identity without relying on counters.
|
|
47
|
+
const syncToken = Symbol("solana-client-sync");
|
|
48
|
+
activeSyncToken = syncToken;
|
|
49
|
+
const newIsConnected = isConnected.value;
|
|
50
|
+
const newConnection = connection.value;
|
|
51
|
+
const currentChain = (_web3Auth$value = web3Auth.value) === null || _web3Auth$value === void 0 ? void 0 : _web3Auth$value.currentChain;
|
|
52
|
+
if (!newIsConnected || !(newConnection !== null && newConnection !== void 0 && newConnection.solanaWallet) || (currentChain === null || currentChain === void 0 ? void 0 : currentChain.chainNamespace) !== CHAIN_NAMESPACES.SOLANA ||
|
|
53
|
+
// only reconnect for the primary connector
|
|
54
|
+
newConnection.connectorName !== ((_web3Auth$value2 = web3Auth.value) === null || _web3Auth$value2 === void 0 ? void 0 : _web3Auth$value2.primaryConnectorName)) {
|
|
55
|
+
const prevClient = clientRef.value;
|
|
56
|
+
clientRef.value = null;
|
|
57
|
+
if (prevClient) {
|
|
58
|
+
await disposeClient(prevClient);
|
|
44
59
|
}
|
|
45
60
|
return;
|
|
46
61
|
}
|
|
47
|
-
const currentChain = web3Auth.value.currentChain;
|
|
48
|
-
let chainConfig;
|
|
49
|
-
if ((currentChain === null || currentChain === void 0 ? void 0 : currentChain.chainNamespace) === CHAIN_NAMESPACES.SOLANA) {
|
|
50
|
-
chainConfig = currentChain;
|
|
51
|
-
} else {
|
|
52
|
-
// use the 1st Solana chain if current chain is not solana
|
|
53
|
-
chainConfig = web3Auth.value.coreOptions.chains.find(c => c.chainNamespace === CHAIN_NAMESPACES.SOLANA);
|
|
54
|
-
if (!chainConfig) return;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// only reconnect for the primary connector
|
|
58
|
-
if (newConnection.connectorName !== ((_web3Auth$value = web3Auth.value) === null || _web3Auth$value === void 0 ? void 0 : _web3Auth$value.primaryConnectorName)) return;
|
|
59
62
|
const prevClient = clientRef.value;
|
|
63
|
+
clientRef.value = null;
|
|
64
|
+
if (prevClient) {
|
|
65
|
+
await disposeClient(prevClient);
|
|
66
|
+
}
|
|
67
|
+
let client = null;
|
|
60
68
|
try {
|
|
61
69
|
// create a wallet standard connector from connected wallet
|
|
62
|
-
const solanaWalletId = "wallet-standard:" +
|
|
63
|
-
const connector = createWalletStandardConnector(
|
|
70
|
+
const solanaWalletId = "wallet-standard:" + newConnection.connectorName;
|
|
71
|
+
const connector = createWalletStandardConnector(newConnection.solanaWallet, {
|
|
64
72
|
id: solanaWalletId,
|
|
65
|
-
name:
|
|
73
|
+
name: newConnection.connectorName
|
|
66
74
|
});
|
|
67
75
|
|
|
68
76
|
// create a solana client
|
|
69
77
|
const {
|
|
70
78
|
rpcTarget,
|
|
71
79
|
wsTarget
|
|
72
|
-
} =
|
|
73
|
-
|
|
80
|
+
} = currentChain;
|
|
81
|
+
client = createClient({
|
|
74
82
|
endpoint: rpcTarget,
|
|
75
83
|
websocketEndpoint: wsTarget,
|
|
76
84
|
walletConnectors: [connector]
|
|
77
85
|
});
|
|
78
|
-
clientRef.value = client;
|
|
79
|
-
if (prevClient) await disposeClient(prevClient);
|
|
80
86
|
|
|
81
87
|
// connect the client to the wallet
|
|
82
88
|
await client.actions.connectWallet(solanaWalletId, {
|
|
83
89
|
autoConnect: true
|
|
84
90
|
});
|
|
91
|
+
// If another sync started while connectWallet was in flight, this client is stale.
|
|
92
|
+
if (activeSyncToken !== syncToken) {
|
|
93
|
+
await disposeClient(client);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
clientRef.value = client;
|
|
85
97
|
} catch (err) {
|
|
98
|
+
if (client) {
|
|
99
|
+
await disposeClient(client);
|
|
100
|
+
}
|
|
86
101
|
log.error("Failed to create or connect Solana client", err);
|
|
87
|
-
|
|
102
|
+
// Only clear the shared ref when this failing run is still the newest one.
|
|
103
|
+
if (activeSyncToken === syncToken) {
|
|
104
|
+
clientRef.value = null;
|
|
105
|
+
}
|
|
88
106
|
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// watch for changes in the connection and active chain
|
|
110
|
+
watch([isConnected, connection, chainId], () => {
|
|
111
|
+
void syncClient();
|
|
89
112
|
}, {
|
|
90
113
|
immediate: true
|
|
91
114
|
});
|