Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 5 additions & 2 deletions packages/widget-playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
},
"dependencies": {
"@base-org/account": "~2.5.2",
"@bigmi/core": "^0.7.0",
"@bigmi/client": "^0.7.0",
"@bigmi/react": "^0.7.0",
"@coinbase/wallet-sdk": "~4.3.6",
"@emotion/react": "^11.14.0",
Expand All @@ -40,8 +42,9 @@
"@mui/material": "^7.3.6",
"@mui/system": "^7.3.6",
"@mysten/dapp-kit": "^0.20.0",
"@reown/appkit": ">=1.8.15",
"@reown/appkit": ">=1.8.16",
"@reown/appkit-adapter-solana": "^1.8.17",
"@reown/appkit-adapter-bitcoin": "^1.8.17",
"@reown/appkit-adapter-wagmi": "^1.8.17",
"@reown/appkit-common": "^1.8.17",
"@walletconnect/ethereum-provider": "~2.23.4",
Expand All @@ -52,7 +55,7 @@
"react": "^19.2.4",
"react-dom": "^19.2.4",
"viem": "^2.45.1",
"wagmi": "^3.1.0",
"wagmi": "^3.3.2",
"zustand": "^5.0.11"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import type { Config } from '@bigmi/client'
import { createConfig, reown } from '@bigmi/client'
import { bitcoin, ChainId, createClient, http } from '@bigmi/core'
import { BigmiProvider } from '@bigmi/react'
import {
useAppKitAccount,
useAppKitProvider,
useWalletInfo,
} from '@reown/appkit/react'
import type { BitcoinConnector } from '@reown/appkit-adapter-bitcoin'
import { type FC, type PropsWithChildren, useEffect } from 'react'

const bigmiConfig = createConfig({
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Module-level bigmiConfig stores mutable connector/state at import time; in SSR/Node environments this can persist across requests and leak per-request connection data.

Details

✨ AI Reasoning
​A module-scoped configuration object is created once at import time and persists for the lifetime of the process. In server/SSR contexts, that object can retain request-specific connectors, accounts, or connection state across different requests/users, leading to data leakage or race conditions. The code initializes a Config (bigmiConfig) at the top-level and later mutates its internal connectors and events based on per-request/provider state. This pattern introduces shared mutable state that is not request-scoped.

🔧 How do I fix it?
Avoid storing request-specific data in module-level variables. Use request-scoped variables or explicitly mark shared caches as intentional.

Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info

chains: [bitcoin],
client: ({ chain }) => createClient({ chain, transport: http() }),
multiInjectedProviderDiscovery: false,
ssr: true,
}) as Config

const BitcoinReownHandler: FC<PropsWithChildren> = ({ children }) => {
const { isConnected, address } = useAppKitAccount({ namespace: 'bip122' })
const { walletProvider } = useAppKitProvider<BitcoinConnector>('bip122')
const { walletInfo } = useWalletInfo('bip122')

useEffect(() => {
if (!isConnected || !walletProvider || !address) {
bigmiConfig._internal.connectors.setState([])
bigmiConfig.setState((state) => ({ ...state, connections: new Map() }))
return
}

const connector = bigmiConfig._internal.connectors.setup(
reown({
connector: walletProvider,
walletInfo,
address,
})
)

bigmiConfig._internal.connectors.setState([connector])

connector.getAccounts().then((accounts) => {
bigmiConfig._internal.events.connect({
accounts,
chainId: ChainId.BITCOIN_MAINNET,
uid: connector.uid,
})
})
}, [isConnected, walletProvider, address, walletInfo])

return <>{children}</>
}

export const BitcoinProvider: FC<PropsWithChildren> = ({ children }) => (
<BigmiProvider config={bigmiConfig} reconnectOnMount={true}>
<BitcoinReownHandler>{children}</BitcoinReownHandler>
</BigmiProvider>
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { ChainType, type ExtendedChain } from '@lifi/widget'
import { useSyncWagmiConfig } from '@lifi/widget-provider-ethereum'
import { mainnet, solana } from '@reown/appkit/networks'
import { bitcoin, mainnet, solana } from '@reown/appkit/networks'
import { type AppKit, createAppKit } from '@reown/appkit/react'
import { BitcoinAdapter } from '@reown/appkit-adapter-bitcoin'
import { SolanaAdapter } from '@reown/appkit-adapter-solana'
import { WagmiAdapter } from '@reown/appkit-adapter-wagmi'
import type { AppKitNetwork } from '@reown/appkit-common'
Expand All @@ -13,6 +14,7 @@ import {
getChainImagesConfig,
} from '../../utils/appkit.js'
import { useEnvVariables } from '../EnvVariablesProvider.js'
import { BitcoinProvider } from './BitcoinProvider.js'
import { SolanaProvider } from './SolanaProvider.js'

const metadata = {
Expand All @@ -35,7 +37,7 @@ export function ReownWalletProvider({
const { themeMode } = useThemeMode()

if (!wagmi.current || !modal.current) {
const networks: [AppKitNetwork, ...AppKitNetwork[]] = [solana]
const networks: [AppKitNetwork, ...AppKitNetwork[]] = [solana, bitcoin]
const evmChains = chains.filter(
(chain) => chain.chainType === ChainType.EVM
)
Expand All @@ -51,8 +53,12 @@ export function ReownWalletProvider({
})
const solanaAdapter = new SolanaAdapter({ registerWalletStandard: true })

const bitcoinAdapter = new BitcoinAdapter({
projectId: EVMWalletConnectId,
})

const appKit = createAppKit({
adapters: [wagmiAdapter, solanaAdapter],
adapters: [wagmiAdapter, solanaAdapter, bitcoinAdapter],
networks,
projectId: EVMWalletConnectId,
metadata,
Expand Down Expand Up @@ -81,7 +87,9 @@ export function ReownWalletProvider({

return (
<WagmiProvider config={wagmiConfig} reconnectOnMount={false}>
<SolanaProvider>{children}</SolanaProvider>
<SolanaProvider>
<BitcoinProvider>{children}</BitcoinProvider>
</SolanaProvider>
</WagmiProvider>
)
}
Loading