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
5 changes: 5 additions & 0 deletions .changeset/tame-gifts-hope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"hub": patch
---

update wallet connect
3 changes: 2 additions & 1 deletion apps/hub/.env
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
# – https://vercel.com/docs/cli/env#exporting-development-environment-variables


NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID="123"
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=""
NEXT_PUBLIC_STATUS_NETWORK_API_URL=""
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@status-im/web fyi, rename from NEXT_PUBLIC_API_URL to NEXT_PUBLIC_STATUS_NETWORK_API_URL

20 changes: 20 additions & 0 deletions apps/hub/.env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# note: next lint doesn't use .env.development
# note: use .env.local instead for now
#
# – https://github.com/vercel/next.js/discussions/32354

# .env, .env.development, and .env.production files should be included in your repository as they define defaults.
# .env*.local should be added to .gitignore, as those files are intended to be ignored.
# .env.local is where secrets can be stored.
#
# – https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#default-environment-variables

# The vercel env pull sub-command will export development environment variables to a local .env file or a different file of your choice.
#
# `vercel env pull .env[.development].local`
#
# – https://vercel.com/docs/cli/env#exporting-development-environment-variables


NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=""
NEXT_PUBLIC_STATUS_NETWORK_API_URL=""
2 changes: 1 addition & 1 deletion apps/hub/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"rehype-slug": "^6.0.0",
"siwe": "^2.3.2",
"ts-pattern": "^5.6.2",
"viem": "^2.21.1",
"viem": "^2.29.1",
"wagmi": "2.15.2",
"zod": "^3.24.1"
},
Expand Down
24 changes: 9 additions & 15 deletions apps/hub/src/app/_components/connect-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,39 @@

import { Button, ShortenAddress } from '@status-im/status-network/components'
import { ConnectKitButton } from 'connectkit'
import { useAccount } from 'wagmi'

import type { ComponentProps } from 'react'

type Props = {
size?: ComponentProps<typeof Button>['size']
label?: string
shortLabel?: string
className?: string
/** If true, shows the label instead of the shortened address when connected */
alwaysShowLabel?: boolean
}

const ConnectButton = (props: Props) => {
const {
size = '32',
label = 'Connect wallet',
shortLabel = 'Connect',
className,
alwaysShowLabel = false,
} = props

const { address, isConnected } = useAccount()

return (
<ConnectKitButton.Custom>
{({ show }) => {
{({ show, isConnected, address }) => {
return (
<Button
onClick={show}
variant={isConnected ? 'secondary' : 'primary'}
size={size}
className={className}
>
{address && isConnected ? (
{address && isConnected && !alwaysShowLabel ? (
<ShortenAddress address={address} />
) : (
<>
<span className="hidden whitespace-nowrap lg:block">
{label}
</span>
<span className="block whitespace-nowrap lg:hidden">
{shortLabel}
</span>
</>
label
)}
</Button>
)
Expand Down
51 changes: 39 additions & 12 deletions apps/hub/src/app/_constants/chain.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,52 @@
import type { Chain } from 'wagmi/chains'
import { getDefaultConfig } from 'connectkit'
import { defineChain } from 'viem'
import { createConfig, http } from 'wagmi'
import { type Chain, mainnet } from 'wagmi/chains'

export const statusNetworkTestnet: Chain = {
id: Number(1660990954),
import { clientEnv } from './env.client.mjs'

import type {
CreateConfigParameters,
CreateConnectorFn,
Transport,
} from 'wagmi'

export const testnet = defineChain({
id: 1660990954,
name: 'Status Network Testnet',
nativeCurrency: {
decimals: 18,
name: 'Ether',
symbol: 'ETH',
},
testnet: true,
sourceId: 1660990954,
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrls: {
default: {
http: ['https://public.sepolia.rpc.status.network'],
},
public: {
http: ['https://public.sepolia.rpc.status.network'],
},
},
blockExplorers: {
default: {
name: 'Status Explorer',
url: 'https://sepoliascan.status.network',
},
},
}
})

export const getDefaultWagmiConfig = () =>
getDefaultConfig({
chains: [mainnet, testnet],
transports: {
[mainnet.id]: http(mainnet.rpcUrls.default.http[0]),
[testnet.id]: http(testnet.rpcUrls.default.http[0]),
},
walletConnectProjectId:
clientEnv.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID as string,
appName: 'Status Hub',
appDescription: 'Status Network DeFi Dashboard',
appUrl: 'https://status.app',
appIcon: 'https://status.app/icon.png',
}) as CreateConfigParameters<
readonly [Chain, ...Chain[]],
Record<number, Transport>,
readonly CreateConnectorFn[]
>

export const wagmiConfig = createConfig(getDefaultWagmiConfig())
3 changes: 3 additions & 0 deletions apps/hub/src/app/_constants/env.client.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ export const envSchema = z.object({
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID: z
.string()
.min(1, 'WalletConnect Project ID is required.'),
NEXT_PUBLIC_STATUS_NETWORK_API_URL: z.string().url(),
})

export const result = envSchema.strip().safeParse({
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID:
process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID,
NEXT_PUBLIC_STATUS_NETWORK_API_URL:
process.env.NEXT_PUBLIC_STATUS_NETWORK_API_URL,
})

if (!result.success) {
Expand Down
1 change: 1 addition & 0 deletions apps/hub/src/app/_constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './address'
export * from './chain'
export * from './siwe'
export * from './staking'
73 changes: 73 additions & 0 deletions apps/hub/src/app/_constants/siwe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { clientEnv } from './env.client.mjs'

import type { SIWEConfig } from 'connectkit'

// API configuration
const API_BASE_URL = clientEnv.NEXT_PUBLIC_STATUS_NETWORK_API_URL

const AUTH_ENDPOINTS = {
verify: `${API_BASE_URL}/auth/ethereum`,
session: `${API_BASE_URL}/auth/me`,
logout: `${API_BASE_URL}/auth/logout`,
} as const

// Helper for API calls
const fetchAPI = async (url: string, options?: RequestInit) => {
const response = await fetch(url, {
credentials: 'include', // Send cookies with cross-origin requests
headers: {
'Content-Type': 'application/json',
...options?.headers,
},
...options,
})
return response
}

export const siweConfig: SIWEConfig = {
getNonce: async () => {
return Math.random().toString(36).substring(2, 15)
},

createMessage: async () => {
const payload = { timestamp: Math.floor(Date.now() / 1000) }
return window.btoa(JSON.stringify(payload))
},

verifyMessage: async ({ message, signature }) => {
try {
const response = await fetchAPI(AUTH_ENDPOINTS.verify, {
method: 'POST',
body: JSON.stringify({ payload: message, signature }),
})
return response.ok
} catch {
return false
}
},

getSession: async () => {
try {
const response = await fetchAPI(AUTH_ENDPOINTS.session)
if (!response.ok) return null

const data = await response.json()
return data.result ?? null
} catch {
return null
}
},

signOut: async () => {
try {
const response = await fetchAPI(AUTH_ENDPOINTS.logout, {
method: 'POST',
})
return response.ok
} catch {
return false
}
},

signOutOnDisconnect: false,
}
15 changes: 0 additions & 15 deletions apps/hub/src/app/_providers/connectkit-provider.tsx

This file was deleted.

58 changes: 49 additions & 9 deletions apps/hub/src/app/_providers/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,61 @@
'use client'

import { VaultStateProvider } from '../_hooks/useVaultStateContext'
import { ConnectKitProvider } from './connectkit-provider'
import { QueryClientProvider } from './query-client-provider'
import { WagmiProvider } from './wagmi-provider'
import { ToastContainer } from '@status-im/components'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ConnectKitProvider, SIWEProvider } from 'connectkit'
import { WagmiProvider } from 'wagmi'

import { testnet, wagmiConfig } from '~constants/chain'
import { siweConfig } from '~constants/siwe'
import { VaultStateProvider } from '~hooks/useVaultStateContext'

import { VaultProvider } from './vault-provider'

interface ProvidersProps {
children: React.ReactNode
}

const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
retryOnMount: false,
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
},
},
})

/**
* Application Providers
*
* Provider hierarchy (order matters):
* 1. WagmiProvider - Blockchain connection & wallet state
* 2. QueryClientProvider - React Query for data fetching
* 3. SiweProvider - SIWE authentication
* 4. ConnectKitProvider - Wallet connection UI
* 5. VaultStateProvider - Vault operation state machine
* 6. VaultProvider - Vault-specific features
*/
export function Providers({ children }: ProvidersProps) {
return (
<WagmiProvider>
<QueryClientProvider>
<ConnectKitProvider>
<VaultStateProvider>{children}</VaultStateProvider>
</ConnectKitProvider>
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>
<SIWEProvider {...siweConfig}>
<ConnectKitProvider
options={{
initialChainId: testnet.id,
}}
>
<VaultStateProvider>
<VaultProvider>
{children}
<ToastContainer />
</VaultProvider>
</VaultStateProvider>
</ConnectKitProvider>
</SIWEProvider>
</QueryClientProvider>
</WagmiProvider>
)
Expand Down
31 changes: 0 additions & 31 deletions apps/hub/src/app/_providers/query-client-provider.tsx

This file was deleted.

Loading
Loading