Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: expose a public function to get connect method order with appkit instance #3482

Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .changeset/silver-rockets-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
'@reown/appkit-scaffold-ui': patch
'@reown/appkit': patch
'@reown/appkit-core': 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-siwe': patch
'@reown/appkit-siwx': patch
'@reown/appkit-ui': patch
'@reown/appkit-wallet': patch
'@reown/appkit-wallet-button': patch
---

Expose a public function to get connect method order with AppKit instance
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ const SortableConnectMethodList = dynamic(
export function SectionConnectOptions() {
const { config, updateFeatures, updateSocials, updateEnableWallets } = useAppKitContext()
const collapseWallets = config.features.collapseWallets
const connectMethodsOrder =
config.features.connectMethodsOrder || ConstantsUtil.DEFAULT_FEATURES.connectMethodsOrder
const connectMethodsOrder = config.features.connectMethodsOrder

function toggleCollapseWallets() {
updateFeatures({ collapseWallets: !collapseWallets })
Expand Down
19 changes: 16 additions & 3 deletions apps/builder/components/preview-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import { Button } from '@/components/ui/button'
import { toast } from 'sonner'
import { Link1Icon, ResetIcon } from '@radix-ui/react-icons'
import { useAppKitContext } from '@/hooks/use-appkit'
import { useAppKitState } from '@reown/appkit/react'
import { useEffect } from 'react'
import { useState } from 'react'

export function PreviewContent() {
const { isInitialized, resetConfigs } = useAppKitContext()
const [shouldRender, setShouldRender] = useState(false)
const { initialized } = useAppKitState()
const { resetConfigs } = useAppKitContext()

async function handleShare() {
try {
Expand All @@ -17,10 +22,18 @@ export function PreviewContent() {
}
}

useEffect(() => {
setShouldRender(initialized)
}, [initialized])

if (!shouldRender) {
return null
}

return (
<>
<div className="w-full max-w-[400px] py-8 mx-auto flex-grow items-center justify-center flex-1 flex items-center justify-center">
{isInitialized ? (
<div className="w-full max-w-[400px] py-8 mx-auto flex-grow flex-1 flex items-center justify-center">
{shouldRender ? (
<>
{/* @ts-ignore */}
<w3m-modal
Expand Down
3 changes: 0 additions & 3 deletions apps/builder/components/sidebar-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import * as React from 'react'
import { buttonVariants } from '@/components/ui/button'
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { useAppKitContext } from '@/hooks/use-appkit'
import { cn } from '@/lib/utils'

import Link from 'next/link'
Expand All @@ -14,8 +13,6 @@ import { SectionDesign } from '@/components/configuration-sections/section-desig
import { BrandingHeader } from '@/components/branding-header'

export function SidebarContent() {
const { config } = useAppKitContext()
const { isInitialized } = useAppKitContext()
const [activeTab, setActiveTab] = React.useState('auth')

return (
Expand Down
5 changes: 1 addition & 4 deletions apps/builder/components/social-buttons.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { SortableSocialGrid } from '@/components/sortable-social-grid'
import { useAppKitContext } from '@/hooks/use-appkit'
import { urlStateUtils } from '@/lib/url-state'
import { UniqueIdentifier } from '@dnd-kit/core'
import { ConstantsUtil, SocialProvider } from '@reown/appkit-core'

Expand All @@ -10,9 +9,7 @@ export function SocialButtons() {
const { updateFeatures } = useAppKitContext()

function handleNewOrder(items: UniqueIdentifier[]) {
const currentFeatures =
urlStateUtils.getStateFromURL()?.features || ConstantsUtil.DEFAULT_FEATURES
updateFeatures({ ...currentFeatures, socials: items as SocialProvider[] })
updateFeatures({ socials: items as SocialProvider[] })
}

return (
Expand Down
15 changes: 7 additions & 8 deletions apps/builder/components/sortable-list-connect-method.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'
import { createPortal } from 'react-dom'

import {
Active,
closestCenter,
CollisionDetection,
DragOverlay,
Expand Down Expand Up @@ -43,7 +42,6 @@ import { ConnectMethodItem } from './connect-method-item'
import { SortableConnectMethodItem } from '@/components/sortable-item-connect-method'
import { Wrapper } from '@/components/ui/wrapper'
import { List } from '@/components/ui/list'
import { useAppKitContext } from '@/hooks/use-appkit'

export interface Props {
activationConstraint?: PointerActivationConstraint
Expand All @@ -55,7 +53,6 @@ export interface Props {
dropAnimation?: DropAnimation | null
getNewIndex?: NewIndexGetter
handle?: boolean
itemCount?: number
items?: UniqueIdentifier[]
measuring?: MeasuringConfiguration
modifiers?: Modifiers
Expand Down Expand Up @@ -98,7 +95,6 @@ export function SortableConnectMethodList({
getItemStyles = () => ({}),
getNewIndex,
handle = false,
itemCount = 3,
items: initialItems,
measuring,
modifiers,
Expand All @@ -109,9 +105,7 @@ export function SortableConnectMethodList({
onToggleOption,
handleNewOrder
}: Props) {
const [items, setItems] = useState<UniqueIdentifier[]>(
() => initialItems ?? createRange<UniqueIdentifier>(itemCount, index => index)
)
const [items, setItems] = useState<UniqueIdentifier[]>(() => initialItems ?? [])
const [activeId, setActiveId] = useState<UniqueIdentifier | null>(null)
const sensors = useSensors(
useSensor(MouseSensor, {
Expand All @@ -136,13 +130,18 @@ export function SortableConnectMethodList({
}, [activeId])

const orderString = useMemo(() => items.join(','), [items])
const orderFromPropsString = useMemo(() => initialItems?.join(','), [initialItems])

useEffect(() => {
if (handleNewOrder) {
if (handleNewOrder && orderString) {
handleNewOrder(orderString.split(','))
}
}, [orderString])

useEffect(() => {
setItems(orderFromPropsString ? orderFromPropsString.split(',') : [])
}, [orderFromPropsString])

return (
<DndContext
sensors={sensors}
Expand Down
1 change: 0 additions & 1 deletion apps/builder/contexts/appkit-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ interface AppKitContextType {
enableWallets: boolean
socialsEnabled: boolean
isDraggingByKey: Record<string, boolean>
isInitialized: boolean
updateThemeMode: (mode: ThemeMode) => void
updateFeatures: (features: Partial<Features>) => void
updateSocials: (enabled: boolean) => void
Expand Down
15 changes: 11 additions & 4 deletions apps/builder/providers/appkit-context-provider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import { ReactNode, useEffect, useState } from 'react'
import { Features, ThemeMode, ThemeVariables, type AppKit } from '@reown/appkit/react'
import { Features, ThemeMode, ThemeVariables, useAppKitState } from '@reown/appkit/react'
import { ConnectMethod, ConstantsUtil } from '@reown/appkit-core'
import { ThemeStore } from '../lib/theme-store'
import { URLState, urlStateUtils } from '@/lib/url-state'
Expand All @@ -24,7 +24,8 @@ interface AppKitProviderProps {
const initialConfig = urlStateUtils.getStateFromURL()

export const ContextProvider: React.FC<AppKitProviderProps> = ({ children }) => {
const [isInitialized, setIsInitialized] = useState(false)
const { initialized } = useAppKitState()

const [features, setFeatures] = useState<Features>(
initialConfig?.features || ConstantsUtil.DEFAULT_FEATURES
)
Expand Down Expand Up @@ -118,9 +119,16 @@ export const ContextProvider: React.FC<AppKitProviderProps> = ({ children }) =>

useEffect(() => {
setTheme(theme as ThemeMode)
setIsInitialized(true)
}, [])

useEffect(() => {
if (initialized) {
const connectMethodsOrder = appKit?.getConnectMethodsOrder()
const order = connectMethodsOrder
updateFeatures({ connectMethodsOrder: order })
}
}, [initialized])

const socialsEnabled = Array.isArray(features.socials)

return (
Expand All @@ -143,7 +151,6 @@ export const ContextProvider: React.FC<AppKitProviderProps> = ({ children }) =>
socialsEnabled,
enableWallets,
isDraggingByKey,
isInitialized,
updateFeatures,
updateThemeMode,
updateSocials,
Expand Down
9 changes: 9 additions & 0 deletions packages/appkit/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ import type { SessionTypes } from '@walletconnect/types'
import type { UniversalProviderOpts } from '@walletconnect/universal-provider'
import { W3mFrameProviderSingleton } from './auth-provider/W3MFrameProviderSingleton.js'
import { WcHelpersUtil } from './utils/HelpersUtil.js'
import { WalletUtil } from '@reown/appkit-scaffold-ui/utils'

declare global {
interface Window {
Expand Down Expand Up @@ -234,6 +235,7 @@ export class AppKit {
}
}
})
PublicStateController.set({ initialized: true })
}

// -- Public -------------------------------------------------------------------
Expand Down Expand Up @@ -642,6 +644,13 @@ export class AppKit {
await this.connectionControllerClient?.disconnect()
}

public getConnectMethodsOrder() {
return WalletUtil.getConnectOrderMethod(
OptionsController.state.features,
ConnectorController.getConnectors()
)
}

// -- Private ------------------------------------------------------------------
private async initControllers(
options: AppKitOptions & {
Expand Down
30 changes: 26 additions & 4 deletions packages/core/src/controllers/PublicStateController.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,42 @@
import { proxy, subscribe as sub } from 'valtio/vanilla'
import type { CaipNetworkId } from '@reown/appkit-common'
import type { CaipNetworkId, ChainNamespace } from '@reown/appkit-common'

// -- Types --------------------------------------------- //
export interface PublicStateControllerState {
/**
* @description Indicates if the AppKit is loading.
* @type {boolean}
*/
loading: boolean
/**
* @description Indicates if the AppKit modal is open.
* @type {boolean}
*/
open: boolean
selectedNetworkId?: CaipNetworkId
activeChain?: string
/**
* @description Indicates the selected network id in CAIP-2 format.
* @type {CaipNetworkId | undefined}
*/
selectedNetworkId?: CaipNetworkId | undefined
/**
* @description Indicates the active chain namespace.
* @type {ChainNamespace | undefined}
*/
activeChain?: ChainNamespace | undefined
/**
* @description Indicates if the AppKit has been initialized. This sets to true when all controllers, adapters and internal state is ready.
* @type {boolean}
*/
initialized: boolean
}

// -- State --------------------------------------------- //
const state = proxy<PublicStateControllerState>({
loading: false,
open: false,
selectedNetworkId: undefined,
activeChain: undefined
activeChain: undefined,
initialized: false
})

// -- Controller ---------------------------------------- //
Expand Down
14 changes: 10 additions & 4 deletions packages/core/tests/controllers/PublicStateController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,28 @@ describe('PublicStateController', () => {
expect(PublicStateController.state).toEqual({
loading: false,
open: false,
selectedNetworkId: undefined
selectedNetworkId: undefined,
activeChain: undefined,
initialized: false
})
})

it('should update state correctly on set()', () => {
PublicStateController.set({ open: true })
expect(PublicStateController.state).toEqual({
loading: false,
open: true,
selectedNetworkId: undefined
selectedNetworkId: undefined,
activeChain: undefined,
initialized: false,
open: true
})
PublicStateController.set({ selectedNetworkId: 'eip155:1' })
expect(PublicStateController.state).toEqual({
loading: false,
open: true,
selectedNetworkId: 'eip155:1'
selectedNetworkId: 'eip155:1',
activeChain: undefined,
initialized: false
})
})
})
3 changes: 3 additions & 0 deletions packages/scaffold-ui/exports/utils.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from '../src/utils/ConnectorUtil.js'
export * from '../src/utils/ConstantsUtil.js'
export * from '../src/utils/WalletUtil.js'
5 changes: 5 additions & 0 deletions packages/scaffold-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
"types": "./dist/types/exports/w3m-modal.d.ts",
"import": "./dist/esm/exports/w3m-modal.js",
"default": "./dist/esm/exports/w3m-modal.js"
},
"./utils": {
"types": "./dist/types/exports/utils.d.ts",
"import": "./dist/esm/exports/utils.js",
"default": "./dist/esm/exports/utils.js"
}
},
"scripts": {
Expand Down
25 changes: 24 additions & 1 deletion packages/scaffold-ui/src/utils/WalletUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import {
OptionsController,
StorageUtil
} from '@reown/appkit-core'
import type { WcWallet } from '@reown/appkit-core'
import type { ConnectMethod, Connector, Features, WcWallet } from '@reown/appkit-core'
import { ConnectorUtil } from './ConnectorUtil.js'
import { ConstantsUtil } from './ConstantsUtil.js'

interface AppKitWallet extends WcWallet {
installed: boolean
Expand Down Expand Up @@ -79,5 +81,26 @@ export const WalletUtil = {
)

return sortedWallets
},

getConnectOrderMethod(_features: Features | undefined, _connectors: Connector[]) {
const connectMethodOrder =
_features?.connectMethodsOrder || OptionsController.state.features?.connectMethodsOrder
const connectors = _connectors || ConnectorController.state.connectors

if (connectMethodOrder) {
return connectMethodOrder
}

const { injected, announced } = ConnectorUtil.getConnectorsByType(connectors)

const shownInjected = injected.filter(ConnectorUtil.showConnector)
const shownAnnounced = announced.filter(ConnectorUtil.showConnector)

if (shownInjected.length || shownAnnounced.length) {
return ['wallet', 'email', 'social'] as ConnectMethod[]
}

return ConstantsUtil.DEFAULT_CONNECT_METHOD_ORDER
}
}
Loading
Loading