Skip to content
Open
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
6 changes: 6 additions & 0 deletions .changeset/famous-deers-sell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@status-im/status-network": patch
"hub": patch
---

add wallet connect
6 changes: 6 additions & 0 deletions .changeset/friendly-cats-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@status-im/status-network": patch
"hub": patch
---

discover section
16 changes: 11 additions & 5 deletions apps/hub/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,30 @@
},
"dependencies": {
"@status-im/colors": "workspace:*",
"@status-im/icons": "workspace:*",
"@status-im/components": "workspace:*",
"@status-im/icons": "workspace:*",
"@status-im/status-network": "workspace:*",
"@status-im/wallet": "workspace:*",
"@tanstack/react-query": "5.66.0",
"@vercel/analytics": "^1.5.0",
"connectkit": "^1.9.0",
"cva": "1.0.0-beta.1",
"framer-motion": "^12.0.6",
"next": "15.1.6",
"next": "15.3.0",
"next-mdx-remote": "^5.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"pino-pretty": "^13.1.1",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"rehype-slug": "^6.0.0",
"ts-pattern": "^5.6.2",
"viem": "2.x",
"wagmi": "2.15.2",
"zod": "^3.24.1"
},
"devDependencies": {
"@ianvs/prettier-plugin-sort-imports": "^4.3.1",
"@next/eslint-plugin-next": "15.3.0",
"@status-im/eslint-config": "workspace:*",
"@ianvs/prettier-plugin-sort-imports": "^4.3.1",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
Expand Down
4 changes: 2 additions & 2 deletions apps/hub/postcss.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ const config = {
plugins: {
tailwindcss: {},
},
};
}

export default config;
export default config
Binary file modified apps/hub/public/apps/cats-fishing-avatar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/hub/public/apps/cats-fishing-cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/cats-on-canvas-avatar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/cats-on-canvas-cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/cuddleclub-avatar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/cuddleclub-cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/feline-friends-avatar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/feline-friends-cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/kittycoin-avatar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/kittycoin-cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/meow-marketplace-avatar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/meow-marketplace-cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/paw-sitive-vibes-avatar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/paw-sitive-vibes-cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/pawse-avatar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/pawse-cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/hub/public/apps/status-network-bridge-avatar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/whiskers-waves-avatar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hub/public/apps/whiskers-waves-cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
100 changes: 77 additions & 23 deletions apps/hub/src/app/_components/app-card.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,90 @@
'use client'

interface AppCardProps {
import { ExternalIcon } from '@status-im/icons/20'
import { TwitterIcon } from '@status-im/icons/social'
import { ButtonLink } from '@status-im/status-network/components'
import Image from 'next/image'

type Props = {
name: string
description: string
category: string
onLaunch: () => void
website: string
twitter?: string
cover: string
icon: string
}

export function AppCard({
name,
description,
category,
onLaunch,
}: AppCardProps) {
function AppCard(props: Props) {
const { name, description, website, twitter, cover, icon } = props

return (
<div className="rounded-16 border border-neutral-20 bg-white-100 p-5 shadow-1 transition-colors hover:border-neutral-30">
<div className="mb-4">
<div className="mb-2 flex items-center justify-between">
<span className="rounded-full bg-customisation-purple-50/10 px-2 py-0.5 text-13 font-medium text-purple">
{category}
</span>
<div className="flex h-full flex-col rounded-28 border border-neutral-20 bg-white-100 p-2 shadow-2 transition-colors hover:border-neutral-30">
<div className="relative mb-4">
<div className="flex aspect-[12/5] w-full items-center justify-center overflow-hidden rounded-24 bg-neutral-20">
<Image
src={cover}
alt={name}
fill
className="overflow-hidden rounded-24 object-cover"
/>
</div>
<div className="absolute bottom-[-15px] left-2 flex size-20 items-center justify-center overflow-hidden rounded-24 bg-neutral-40 text-11 text-neutral-60">
<Image src={icon} alt={name} fill className="object-cover" />
</div>
<h4 className="mb-2 text-19 font-semibold text-neutral-90">{name}</h4>
<p className="text-13 leading-relaxed text-neutral-60">{description}</p>
</div>

<button
onClick={onLaunch}
className="w-full rounded-16 bg-neutral-10 px-3 py-2.5 text-13 font-medium text-neutral-90 transition-colors hover:bg-neutral-20"
>
Launch App
</button>
<div className="flex flex-1 flex-col gap-1 px-2 pb-2 pt-[10px]">
<h3 className="mb-1 text-27 font-semibold text-neutral-90">{name}</h3>
<p className="mb-auto text-15 font-400 text-neutral-100">
{description}
</p>
<div className="mt-1 flex items-start gap-2">
<ButtonLink
href={website}
target="_blank"
rel="noopener noreferrer"
variant="white"
size="32"
>
{website.replace('https://', '')}{' '}
<ExternalIcon className="size-4 text-neutral-50" />
</ButtonLink>
{twitter && (
<ButtonLink
href={`https://x.com/${twitter}`}
target="_blank"
rel="noopener noreferrer"
variant="white"
size="32"
>
<TwitterIcon className="size-4 text-neutral-50" />
</ButtonLink>
)}
</div>
</div>
</div>
)
}

function AppCardSkeleton() {
return (
<div className="rounded-28 border border-neutral-20 bg-white-100 p-2 shadow-2">
<div className="relative mb-4">
<div className="aspect-[12/5] w-full animate-skeleton overflow-hidden rounded-24 bg-gradient-to-r from-neutral-10 via-white-100 to-neutral-10 bg-[size:400%_400%]" />
<div className="absolute bottom-[-15px] left-2 size-20 animate-skeleton rounded-24 bg-gradient-to-r from-neutral-20 via-white-100 to-neutral-20 bg-[size:400%_400%]" />
</div>

<div className="flex flex-col gap-1 px-2 pb-2 pt-[10px]">
<div className="mb-1 h-8 w-3/4 animate-skeleton rounded-12 bg-gradient-to-r from-neutral-10 via-white-100 to-neutral-10 bg-[size:400%_400%]" />
<div className="h-5 w-full animate-skeleton rounded-8 bg-gradient-to-r from-neutral-10 via-white-100 to-neutral-10 bg-[size:400%_400%]" />
<div className="h-5 w-2/3 animate-skeleton rounded-8 bg-gradient-to-r from-neutral-10 via-white-100 to-neutral-10 bg-[size:400%_400%]" />
<div className="mt-1 flex items-start gap-2">
<div className="h-8 w-32 animate-skeleton rounded-12 bg-gradient-to-r from-neutral-10 via-white-100 to-neutral-10 bg-[size:400%_400%]" />
<div className="size-8 animate-skeleton rounded-12 bg-gradient-to-r from-neutral-10 via-white-100 to-neutral-10 bg-[size:400%_400%]" />
</div>
</div>
</div>
)
}

export { AppCard, AppCardSkeleton }
41 changes: 41 additions & 0 deletions apps/hub/src/app/_components/connect-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use client'

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
}

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

const { address, isConnected } = useAccount()

return (
<ConnectKitButton.Custom>
{({ show }) => {
return (
<Button
onClick={show}
variant={isConnected ? 'secondary' : 'primary'}
size={size}
>
{address && isConnected ? (
<ShortenAddress address={address} />
) : (
label
)}
</Button>
)
}}
</ConnectKitButton.Custom>
)
}

export { ConnectButton }
export type { Props as ConnectButtonProps }
9 changes: 4 additions & 5 deletions apps/hub/src/app/_components/top-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@

import { Button, IconButton, Tag } from '@status-im/components'
import { SettingsIcon } from '@status-im/icons/20'
import {
Button as ButtonPrimary,
Link,
} from '@status-im/status-network/components'
import { Link } from '@status-im/status-network/components'
import Image from 'next/image'

import { ConnectButton } from './connect-button'

interface TopBarProps {
onMenuToggle: () => void
}
Expand Down Expand Up @@ -64,7 +63,7 @@ export function TopBar({ onMenuToggle }: TopBarProps) {
</div>

{/* Connect Wallet Button */}
<ButtonPrimary size="32">Connect Wallet</ButtonPrimary>
<ConnectButton />

{/* Settings Button */}
<IconButton variant="ghost" icon={<SettingsIcon />} />
Expand Down
15 changes: 15 additions & 0 deletions apps/hub/src/app/_providers/connectkit-provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use client'

import { ConnectKitProvider as ConnectKit } from 'connectkit'

type ConnectKitProviderProps = {
children: React.ReactNode
}

export function ConnectKitProvider({ children }: ConnectKitProviderProps) {
return (
<ConnectKit theme="auto" mode="light">
{children}
</ConnectKit>
)
}
19 changes: 19 additions & 0 deletions apps/hub/src/app/_providers/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use client'

import { ConnectKitProvider } from './connectkit-provider'
import { QueryClientProvider } from './query-client-provider'
import { WagmiProvider } from './wagmi-provider'

interface ProvidersProps {
children: React.ReactNode
}

export function Providers({ children }: ProvidersProps) {
return (
<WagmiProvider>
<QueryClientProvider>
<ConnectKitProvider>{children}</ConnectKitProvider>
</QueryClientProvider>
</WagmiProvider>
)
}
31 changes: 31 additions & 0 deletions apps/hub/src/app/_providers/query-client-provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use client'

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

import type React from 'react'

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

type Props = {
children: React.ReactNode
}

function _QueryClientProvider(props: Props) {
const { children } = props

return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
)
}

export { _QueryClientProvider as QueryClientProvider }
45 changes: 45 additions & 0 deletions apps/hub/src/app/_providers/wagmi-provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use client'

import { createConfig, http, WagmiProvider as WagmiProviderBase } from 'wagmi'
import { mainnet } from 'wagmi/chains'
import { injected } from 'wagmi/connectors'

import type React from 'react'

export const config = createConfig({
chains: [mainnet],
ssr: false,
connectors: [injected()],
transports: {
// todo: replace public clients
[mainnet.id]: http(),
},
})

declare module 'wagmi' {
interface Register {
config: typeof config
}
}

type Props = {
children: React.ReactNode
}

function WagmiProvider(props: Props) {
const { children } = props

return (
<WagmiProviderBase
config={
config as unknown as React.ComponentProps<
typeof WagmiProviderBase
>['config']
}
>
{children}
</WagmiProviderBase>
)
}

export { config as wagmiConfig, WagmiProvider }
Loading
Loading