feat: link external wallet#2437
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| activeAccount: this.activeAccount, | ||
| currentChainId: this.currentChainId, | ||
| }); | ||
| if (!switchResult) { |
There was a problem hiding this comment.
should we log something here if the switch doesn't do anything
There was a problem hiding this comment.
There's only one case that authConnector.switchAccount can return empty value, i.e when the target account is already active.
We should not need any log for that, this is not an error. Clients should handle it to prevent switching to same account again.
| if (connector.status === CONNECTOR_STATUS.NOT_READY && this.cachedConnector !== connectorName) { | ||
| if ( | ||
| connector.status === CONNECTOR_STATUS.NOT_READY && | ||
| this.cachedConnector !== connectorName && |
There was a problem hiding this comment.
do we need to check both ? what could be the case 1 of cached and current connection match
There was a problem hiding this comment.
On load, we init all the connectors (including external wallet connectors) again.
There's a case that user has linked the external wallet (the connector status is Connected) but it's not an active account (not cachedConnector).
| status: ACCOUNT_LINKING_STATUS.INITIALIZING, | ||
| }; | ||
| }); | ||
| this.setState({ |
There was a problem hiding this comment.
updateAccountLinkingState already setState i don't think we need this anymore
| /** Address of the account */ | ||
| address: string | null; | ||
| /** Auth connection id of the account */ | ||
| authConnectionId: string | null; |
There was a problem hiding this comment.
groupedAuthConnectionId?
| success: boolean; | ||
|
|
||
| /** Refreshed id token for the user */ | ||
| idToken: string; |
There was a problem hiding this comment.
do we also get a new access token?
There was a problem hiding this comment.
No. We don't store linked account info in the accessToken, only in idToken.
| /** Whether the Citadel server accepted the linking request. */ | ||
| success: boolean; | ||
|
|
||
| /** Refreshed id token for the user */ |
There was a problem hiding this comment.
No, we don't refresh the accessToken.
| */ | ||
| export interface UnlinkAccountPayload { | ||
| /** Access token to authenticate the request */ | ||
| idToken: string; |
There was a problem hiding this comment.
isn't all these access token and not idtoken
There was a problem hiding this comment.
idToken, if I'm not mistaken.
I've updated the comment for the interfaces.
| let result: UnlinkAccountResult; | ||
|
|
||
| try { | ||
| result = await post<UnlinkAccountResult>(url, payload, { |
| [CONNECTOR_EVENTS.MFA_ENABLED]: (isMFAEnabled: boolean) => void; | ||
| [CONNECTOR_EVENTS.CONSENT_REQUIRING]: (data: CONNECTED_EVENT_DATA) => void; | ||
| [CONNECTOR_EVENTS.CONSENT_ACCEPTED]: (data: CONNECTED_EVENT_DATA & { loginMode: LoginModeType }) => void; | ||
| [CONNECTOR_EVENTS.CONNECTION_UPDATED]: () => void; |
| [CONNECTOR_EVENTS.CONSENT_REQUIRING]: () => void; | ||
| [CONNECTOR_EVENTS.CONSENT_ACCEPTED]: (data: SDK_CONSENT_ACCEPTED_EVENT_DATA) => void; | ||
| [CONNECTOR_EVENTS.ERRORED]: (error: Web3AuthError, loginMode: LoginModeType) => void; | ||
| [CONNECTOR_EVENTS.CONNECTION_UPDATED]: () => void; |
| }; | ||
|
|
||
| const connectionUpdatedListener = () => { | ||
| status.value = newWeb3Auth.status; |
| return this.state.idToken || null; | ||
| } | ||
|
|
||
| get accessToken(): string | null { |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f3f96c9. Configure here.
| } | ||
|
|
||
| // attach all event bridges to the new provider | ||
| this._providerEngineProxy = provider; |
There was a problem hiding this comment.
we shouldn't ideally re-assign this object.
listeners are already set on this by clients
you're moving listeners to a new obj but depending on client framework used, it may not work correctly

Jira Link
https://consensyssoftware.atlassian.net/browse/EMBED-85?atlOrigin=eyJpIjoiM2UxZDY3YTZlOGFkNGU2Nzg0YjFjYjliOTc5N2I1MjAiLCJwIjoiaiJ9
Description
This PR adds external wallet account linking to Web3Auth.
Users authenticated through the
AUTHconnector can now link and unlink external wallets, retrieve connected account metadata from user info, and access framework-level React/Vue helpers for the flow. The change also updates the demo apps to showcase the new linking UX.What Changed
linkAccount(params)andunlinkAccount(address)toWeb3AuthNoModal./v1/link/walletand/v1/unlink/walletrequests.AccountLinkingErrorerror codes and analytics events for linking/unlinking start, success, and failure.generateChallengeAndSign()so external wallets can produce proof-of-ownership signatures for linking.AuthConnector.getUserInfo()to includeconnectedAccountsfetched from Citadel/v1/user.useLinkAccounthooks/composables for:@web3auth/modal/react@web3auth/modal/vue@web3auth/no-modal/react@web3auth/no-modal/vueUser-Facing Features
useLinkAccountAPI with loading, error, and linked account state.Notes
AUTHconnector.METAMASKandWALLET_CONNECT_V2.How has this been tested?
AUTHconnector.getUserInfo()and verifyconnectedAccountsis returned.Screenshots (if appropriate)
Types of changes
Checklist
Note
High Risk
High risk because it adds new account-linking and account-switching flows that touch core connector interfaces, modal state management, and WalletConnect session handling, which can affect authentication and connection lifecycle across apps.
Overview
Adds external wallet account linking and active-wallet switching to Web3Auth, including new
linkAccount,unlinkAccount, andswitchAccountAPIs, plus React/Vue hooks/composables and REST helpers for Citadel-backed linking/unlinking requests.Updates the modal UI/state machine to support a dedicated WalletConnect-based account-linking session (QR flow, status/intent tracking, cleanup/reset on close), and adjusts Wagmi providers to resync on Web3Auth connection changes rather than provider identity.
Demo apps are updated to showcase linking, unlinking, switching between connected wallets, and displaying
userInfo.connectedAccounts; dependencies and lockfiles are refreshed (notably MetaMask connect packages).Reviewed by Cursor Bugbot for commit d0c8e95. Bugbot is set up for automated code reviews on this repo. Configure here.