Skip to content

Commit

Permalink
chore: add authProvider field to useAppKitAccount and serialize corre…
Browse files Browse the repository at this point in the history
…ct provider in appkit.getProvider (#3611)
  • Loading branch information
tomiir authored Jan 20, 2025
1 parent 018c6f1 commit 6431f0c
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 54 deletions.
23 changes: 23 additions & 0 deletions .changeset/nervous-bugs-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
'@reown/appkit': patch
'@reown/appkit-core': patch
'@reown/appkit-adapter-bitcoin': patch
'@reown/appkit-adapter-ethers': patch
'@reown/appkit-adapter-ethers5': patch
'@reown/appkit-adapter-solana': patch
'@reown/appkit-adapter-wagmi': patch
'@reown/appkit-utils': patch
'@reown/appkit-cdn': patch
'@reown/appkit-cli': patch
'@reown/appkit-common': patch
'@reown/appkit-experimental': patch
'@reown/appkit-polyfills': patch
'@reown/appkit-scaffold-ui': patch
'@reown/appkit-siwe': patch
'@reown/appkit-siwx': patch
'@reown/appkit-ui': patch
'@reown/appkit-wallet': patch
'@reown/appkit-wallet-button': patch
---

Fixes issue where appKit.getProvider() would not return correct provider.
23 changes: 23 additions & 0 deletions .changeset/unlucky-islands-juggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
'@reown/appkit': patch
'@reown/appkit-core': patch
'@reown/appkit-adapter-bitcoin': patch
'@reown/appkit-adapter-ethers': patch
'@reown/appkit-adapter-ethers5': patch
'@reown/appkit-adapter-solana': patch
'@reown/appkit-adapter-wagmi': patch
'@reown/appkit-utils': patch
'@reown/appkit-cdn': patch
'@reown/appkit-cli': patch
'@reown/appkit-common': patch
'@reown/appkit-experimental': patch
'@reown/appkit-polyfills': patch
'@reown/appkit-scaffold-ui': patch
'@reown/appkit-siwe': patch
'@reown/appkit-siwx': patch
'@reown/appkit-ui': patch
'@reown/appkit-wallet': patch
'@reown/appkit-wallet-button': patch
---

Adds authProvider to embeddedWalletInfo in useAppKitAccount
25 changes: 14 additions & 11 deletions packages/appkit/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,18 +285,22 @@ export class AppKit {
}

public subscribeAccount(callback: (newState: UseAppKitAccountReturn) => void) {
const authConnector = ConnectorController.getAuthConnector()
function updateVal() {
callback({
allAccounts: AccountController.state.allAccounts,
caipAddress: ChainController.state.activeCaipAddress,
address: CoreHelperUtil.getPlainAddress(ChainController.state.activeCaipAddress),
isConnected: Boolean(ChainController.state.activeCaipAddress),
status: AccountController.state.status,
embeddedWalletInfo: {
user: AccountController.state.user,
accountType: AccountController.state.preferredAccountType,
isSmartAccountDeployed: Boolean(AccountController.state.smartAccountDeployed)
}
embeddedWalletInfo: authConnector
? {
user: AccountController.state.user,
authProvider: AccountController.state.socialProvider || 'email',
accountType: AccountController.state.preferredAccountType,
isSmartAccountDeployed: Boolean(AccountController.state.smartAccountDeployed)
}
: undefined
})
}

Expand Down Expand Up @@ -424,7 +428,9 @@ export class AppKit {
return ChainController.getAccountProp('address', chainNamespace)
}

public getProvider = () => AccountController.state.provider
public getProvider = <T>(namespace: ChainNamespace) => ProviderUtil.getProvider<T>(namespace)

public getProviderType = (namespace: ChainNamespace) => ProviderUtil.state.providerIds[namespace]

public getPreferredAccountType = () =>
AccountController.state.preferredAccountType as W3mFrameTypes.AccountType
Expand All @@ -433,10 +439,6 @@ export class AppKit {
AccountController.setCaipAddress(caipAddress, chain)
}

public setProvider: (typeof AccountController)['setProvider'] = (provider, chain) => {
AccountController.setProvider(provider, chain)
}

public setBalance: (typeof AccountController)['setBalance'] = (balance, balanceSymbol, chain) => {
AccountController.setBalance(balance, balanceSymbol, chain)
}
Expand Down Expand Up @@ -1643,7 +1645,8 @@ export class AppKit {

private syncConnectedWalletInfo(chainNamespace: ChainNamespace) {
const connectorId = StorageUtil.getConnectedConnectorId(chainNamespace)
const providerType = ProviderUtil.state.providerIds[chainNamespace]
const providerType = ProviderUtil.getProviderId(chainNamespace)

if (
providerType === UtilConstantsUtil.CONNECTOR_TYPE_ANNOUNCED ||
providerType === UtilConstantsUtil.CONNECTOR_TYPE_INJECTED
Expand Down
24 changes: 10 additions & 14 deletions packages/appkit/tests/appkit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
type ChainAdapter,
ChainController,
type ChainControllerState,
type CombinedProvider,
ConnectionController,
type Connector,
ConnectorController,
Expand Down Expand Up @@ -353,9 +352,11 @@ describe('Base', () => {
})

it('should get provider', () => {
const mockProvider = { request: vi.fn() }
vi.mocked(AccountController).state = { provider: mockProvider } as any
expect(appKit.getProvider()).toBe(mockProvider)
const mockProvider = vi.fn()
vi.mocked(ProviderUtil.state).providers = { eip155: mockProvider } as any
vi.mocked(ProviderUtil.state).providerIds = { eip155: 'INJECTED' } as any

expect(appKit.getProvider<any>('eip155')).toBe(mockProvider)
})

it('should get preferred account type', () => {
Expand All @@ -376,14 +377,6 @@ describe('Base', () => {
expect(appKit.getIsConnectedState()).toBe(true)
})

it('should set provider', () => {
const mockProvider = {
request: vi.fn()
}
appKit.setProvider(mockProvider as unknown as CombinedProvider, 'eip155')
expect(AccountController.setProvider).toHaveBeenCalledWith(mockProvider, 'eip155')
})

it('should set balance', () => {
appKit.setBalance('1.5', 'ETH', 'eip155')
expect(AccountController.setBalance).toHaveBeenCalledWith('1.5', 'ETH', 'eip155')
Expand Down Expand Up @@ -730,7 +723,9 @@ describe('Base', () => {
vi.mocked(appKit as any).caipNetworks = [mainnet]
// Mock the connector data
const mockConnector = {
id: 'test-wallet'
id: 'test-wallet',
name: 'Test Wallet',
imageUrl: 'test-wallet-icon'
} as Connector

vi.mocked(ConnectorController.getConnectors).mockReturnValue([mockConnector])
Expand All @@ -752,7 +747,8 @@ describe('Base', () => {

expect(AccountController.setConnectedWalletInfo).toHaveBeenCalledWith(
expect.objectContaining({
name: mockConnector.id
name: mockConnector.name,
icon: mockConnector.imageUrl
}),
'eip155'
)
Expand Down
6 changes: 3 additions & 3 deletions packages/core/exports/react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ export function useAppKitNetworkCore(): Pick<
}

export function useAppKitAccount(): UseAppKitAccountReturn {
const { status, user, preferredAccountType, smartAccountDeployed, allAccounts } = useSnapshot(
AccountController.state
)
const { status, user, preferredAccountType, smartAccountDeployed, allAccounts, socialProvider } =
useSnapshot(AccountController.state)

const { activeCaipAddress } = useSnapshot(ChainController.state)

Expand All @@ -43,6 +42,7 @@ export function useAppKitAccount(): UseAppKitAccountReturn {
embeddedWalletInfo: authConnector
? {
user,
authProvider: socialProvider || 'email',
accountType: preferredAccountType,
isSmartAccountDeployed: Boolean(smartAccountDeployed)
}
Expand Down
45 changes: 29 additions & 16 deletions packages/core/exports/vue.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,62 @@
import { onUnmounted, ref } from 'vue'
import { type Ref, onUnmounted, ref } from 'vue'

import { AccountController } from '../src/controllers/AccountController.js'
import { ChainController } from '../src/controllers/ChainController.js'
import { ConnectionController } from '../src/controllers/ConnectionController.js'
import { ConnectorController } from '../src/controllers/ConnectorController.js'
import { CoreHelperUtil } from '../src/utils/CoreHelperUtil.js'
import type { SocialProvider, UseAppKitAccountReturn } from '../src/utils/TypeUtil.js'

// -- Hooks ------------------------------------------------------------
export function useAppKitAccount() {
export function useAppKitAccount(): Ref<UseAppKitAccountReturn> {
const authConnector = ConnectorController.getAuthConnector()
const state = ref({
allAccounts: AccountController.state.allAccounts,
address: CoreHelperUtil.getPlainAddress(ChainController.state.activeCaipAddress) ?? null,
caipAddress: ChainController.state.activeCaipAddress ?? null,
status: AccountController.state.status ?? null,
address: CoreHelperUtil.getPlainAddress(ChainController.state.activeCaipAddress),
caipAddress: ChainController.state.activeCaipAddress,
status: AccountController.state.status,
isConnected: Boolean(ChainController.state.activeCaipAddress),
embeddedWalletInfo: {
user: AccountController.state.user ?? null,
accountType: AccountController.state.preferredAccountType ?? null,
isSmartAccountDeployed: Boolean(AccountController.state.smartAccountDeployed)
}
embeddedWalletInfo: authConnector
? {
user: AccountController.state.user,
authProvider:
AccountController.state.socialProvider ?? ('email' as SocialProvider | 'email'),
accountType: AccountController.state.preferredAccountType,
isSmartAccountDeployed: Boolean(AccountController.state.smartAccountDeployed)
}
: undefined
})

const unsubscribeCaipAddress = ChainController.subscribeKey('activeCaipAddress', val => {
state.value.caipAddress = val ?? null
state.value.address = CoreHelperUtil.getPlainAddress(val) ?? null
state.value.caipAddress = val
state.value.address = CoreHelperUtil.getPlainAddress(val)
state.value.isConnected = Boolean(val)
})

const unsubscribeStatus = AccountController.subscribeKey('status', val => {
state.value.status = val ?? null
state.value.status = val
})

const unsubscribeAllAccounts = AccountController.subscribeKey('allAccounts', val => {
state.value.allAccounts = [...val]
})

const unsubscribeAccountDeployed = AccountController.subscribeKey('smartAccountDeployed', val => {
state.value.embeddedWalletInfo.isSmartAccountDeployed = Boolean(val)
if (state.value.embeddedWalletInfo) {
state.value.embeddedWalletInfo.isSmartAccountDeployed = Boolean(val)
}
})

const unsubscribeAccountType = AccountController.subscribeKey('preferredAccountType', val => {
state.value.embeddedWalletInfo.accountType = val ?? null
if (state.value.embeddedWalletInfo) {
state.value.embeddedWalletInfo.accountType = val
}
})

const unsubscribeUser = AccountController.subscribeKey('user', val => {
state.value.embeddedWalletInfo.user = val ?? null
if (state.value.embeddedWalletInfo) {
state.value.embeddedWalletInfo.user = val
}
})

onUnmounted(() => {
Expand Down
10 changes: 0 additions & 10 deletions packages/core/src/controllers/AccountController.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type UniversalProvider from '@walletconnect/universal-provider'
import { proxy, ref } from 'valtio/vanilla'

import type { CaipAddress, ChainNamespace } from '@reown/appkit-common'
Expand All @@ -11,9 +10,7 @@ import { SwapApiUtil } from '../utils/SwapApiUtil.js'
import type {
AccountType,
AccountTypeMap,
CombinedProvider,
ConnectedWalletInfo,
Provider,
SocialProvider,
User
} from '../utils/TypeUtil.js'
Expand Down Expand Up @@ -43,7 +40,6 @@ export interface AccountControllerState {
preferredAccountType?: W3mFrameTypes.AccountType
socialWindow?: Window
farcasterUrl?: string
provider?: UniversalProvider | Provider | CombinedProvider
status?: 'reconnecting' | 'connected' | 'disconnected' | 'connecting'
lastRetry?: number
}
Expand Down Expand Up @@ -111,12 +107,6 @@ export const AccountController = {
return ChainController.getAccountProp('caipAddress', chain)
},

setProvider(provider: AccountControllerState['provider'], chain: ChainNamespace | undefined) {
if (provider) {
ChainController.setAccountProp('provider', provider, chain)
}
},

setCaipAddress(
caipAddress: AccountControllerState['caipAddress'],
chain: ChainNamespace | undefined
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/utils/TypeUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,7 @@ export type UseAppKitAccountReturn = {
isConnected: boolean
embeddedWalletInfo?: {
user: AccountControllerState['user']
authProvider: AccountControllerState['socialProvider'] | 'email'
accountType: W3mFrameTypes.AccountType | undefined
isSmartAccountDeployed: boolean
}
Expand Down
44 changes: 44 additions & 0 deletions packages/core/tests/hooks/react.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,50 @@ describe('useAppKitAccount', () => {
email: 'email@email.test',
userName: 'test'
},
authProvider: 'email',
isSmartAccountDeployed: false,
accountType: 'eoa'
}
})

expect(useSnapshot).toHaveBeenCalledWith(AccountController.state)
expect(useSnapshot).toHaveBeenCalledWith(ChainController.state)
})

it('should return appropiate auth provider when social provider is set', () => {
const mockCaipAddress = 'eip155:1:0x123...'
const mockPlainAddress = '0x123...'

vi.spyOn(ConnectorController, 'getAuthConnector').mockReturnValue({} as any)

// Mock the useSnapshot hook for both calls
useSnapshot
.mockReturnValueOnce({
allAccounts: undefined,
status: 'connected',
socialProvider: 'google',
preferredAccountType: 'eoa',
smartAccountDeployed: false,
user: {
email: 'email@email.test',
userName: 'test'
}
}) // For AccountController
.mockReturnValueOnce({ activeCaipAddress: mockCaipAddress }) // For ChainController

const result = useAppKitAccount()

expect(result).toEqual({
address: mockPlainAddress,
caipAddress: mockCaipAddress,
isConnected: true,
status: 'connected',
embeddedWalletInfo: {
user: {
email: 'email@email.test',
userName: 'test'
},
authProvider: 'google',
isSmartAccountDeployed: false,
accountType: 'eoa'
}
Expand Down

0 comments on commit 6431f0c

Please sign in to comment.