diff --git a/app/(general)/integration/lens-protocol/explore/page.tsx b/app/(general)/integration/lens-protocol/explore/page.tsx
new file mode 100644
index 00000000..e8aa4451
--- /dev/null
+++ b/app/(general)/integration/lens-protocol/explore/page.tsx
@@ -0,0 +1,13 @@
+"use client"
+
+import { ExploreProfiles } from "@/integrations/lens-protocol/components/profile/explore-profiles"
+import { ExplorePublications } from "@/integrations/lens-protocol/components/publications/explore-publications"
+
+export default function PageIntegration() {
+ return (
+ <>
+
+
+ >
+ )
+}
diff --git a/app/(general)/integration/lens-protocol/layout.tsx b/app/(general)/integration/lens-protocol/layout.tsx
new file mode 100644
index 00000000..1e851aab
--- /dev/null
+++ b/app/(general)/integration/lens-protocol/layout.tsx
@@ -0,0 +1,75 @@
+"use client"
+
+import { ReactNode } from "react"
+import Link from "next/link"
+import { turboIntegrations } from "@/data/turbo-integrations"
+import { LensProvider } from "@lens-protocol/react-web"
+import { LuBook } from "react-icons/lu"
+
+import { cn } from "@/lib/utils"
+import { buttonVariants } from "@/components/ui/button"
+import { WalletConnect } from "@/components/blockchain/wallet-connect"
+import {
+ PageHeader,
+ PageHeaderCTA,
+ PageHeaderDescription,
+ PageHeaderHeading,
+} from "@/components/layout/page-header"
+import { PageSection } from "@/components/layout/page-section"
+import { IsWalletConnected } from "@/components/shared/is-wallet-connected"
+import { IsWalletDisconnected } from "@/components/shared/is-wallet-disconnected"
+import { LightDarkImage } from "@/components/shared/light-dark-image"
+import { Navbar } from "@/integrations/lens-protocol/components/navbar"
+import { lensProviderConfig } from "@/integrations/lens-protocol/lens-provider"
+
+export default function LayoutIntegration({
+ children,
+}: {
+ children: ReactNode
+}) {
+ return (
+ <>
+
+
+
+ {turboIntegrations.lensProtocol.name}
+
+
+ {turboIntegrations.lensProtocol.description}
+
+
+
+
+ Documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )
+}
diff --git a/app/(general)/integration/lens-protocol/opengraph-image.tsx b/app/(general)/integration/lens-protocol/opengraph-image.tsx
new file mode 100644
index 00000000..657902a0
--- /dev/null
+++ b/app/(general)/integration/lens-protocol/opengraph-image.tsx
@@ -0,0 +1,9 @@
+import { IntegrationOgImage } from "@/components/ui/social/og-image-integrations"
+
+export const runtime = "edge"
+export const size = {
+ width: 1200,
+ height: 630,
+}
+
+export default IntegrationOgImage("lensProtocol")
diff --git a/app/(general)/integration/lens-protocol/page.tsx b/app/(general)/integration/lens-protocol/page.tsx
new file mode 100644
index 00000000..bbcc659c
--- /dev/null
+++ b/app/(general)/integration/lens-protocol/page.tsx
@@ -0,0 +1,5 @@
+import { redirect } from "next/navigation"
+
+export default function PageIntegration() {
+ redirect("/integration/lens-protocol/profiles")
+}
diff --git a/app/(general)/integration/lens-protocol/profiles/[handle]/page.tsx b/app/(general)/integration/lens-protocol/profiles/[handle]/page.tsx
new file mode 100644
index 00000000..539ac4ea
--- /dev/null
+++ b/app/(general)/integration/lens-protocol/profiles/[handle]/page.tsx
@@ -0,0 +1,11 @@
+"use client"
+
+import { Profile } from "@/integrations/lens-protocol/components/profile/profile"
+
+export default function PageIntegration({
+ params,
+}: {
+ params: { handle: string }
+}) {
+ return
+}
diff --git a/app/(general)/integration/lens-protocol/profiles/address/[address]/page.tsx b/app/(general)/integration/lens-protocol/profiles/address/[address]/page.tsx
new file mode 100644
index 00000000..8eccd9b1
--- /dev/null
+++ b/app/(general)/integration/lens-protocol/profiles/address/[address]/page.tsx
@@ -0,0 +1,11 @@
+"use client"
+
+import { AddressProfiles } from "@/integrations/lens-protocol/components/profile/address-profiles"
+
+export default function PageIntegration({
+ params,
+}: {
+ params: { address: string }
+}) {
+ return
+}
diff --git a/app/(general)/integration/lens-protocol/profiles/page.tsx b/app/(general)/integration/lens-protocol/profiles/page.tsx
new file mode 100644
index 00000000..f73d62c5
--- /dev/null
+++ b/app/(general)/integration/lens-protocol/profiles/page.tsx
@@ -0,0 +1,7 @@
+"use client"
+
+import { OwnedProfiles } from "@/integrations/lens-protocol/components/profile/owned-profiles"
+
+export default function PageIntegration() {
+ return
+}
diff --git a/app/(general)/integration/lens-protocol/publications/[id]/page.tsx b/app/(general)/integration/lens-protocol/publications/[id]/page.tsx
new file mode 100644
index 00000000..a9c16c30
--- /dev/null
+++ b/app/(general)/integration/lens-protocol/publications/[id]/page.tsx
@@ -0,0 +1,13 @@
+"use client"
+
+import { PublicationId } from "@lens-protocol/react-web"
+
+import { Publication } from "@/integrations/lens-protocol/components/publications/publication"
+
+export default function PageIntegration({
+ params,
+}: {
+ params: { id: string }
+}) {
+ return
+}
diff --git a/app/(general)/integration/lens-protocol/search/page.tsx b/app/(general)/integration/lens-protocol/search/page.tsx
new file mode 100644
index 00000000..cf71d562
--- /dev/null
+++ b/app/(general)/integration/lens-protocol/search/page.tsx
@@ -0,0 +1,17 @@
+"use client"
+
+import { useSearchParams } from "next/navigation"
+
+import { SearchProfiles } from "@/integrations/lens-protocol/components/profile/search-profiles"
+import { SearchPublications } from "@/integrations/lens-protocol/components/publications/search-publications"
+
+export default function PageIntegration() {
+ const searchParams = useSearchParams()
+ const query = searchParams.get("q") ?? ""
+ return (
+ <>
+
+
+ >
+ )
+}
diff --git a/app/(general)/integration/lens-protocol/twitter-image.tsx b/app/(general)/integration/lens-protocol/twitter-image.tsx
new file mode 100644
index 00000000..215a2a59
--- /dev/null
+++ b/app/(general)/integration/lens-protocol/twitter-image.tsx
@@ -0,0 +1,9 @@
+import Image from "./opengraph-image"
+
+export const runtime = "edge"
+export const size = {
+ width: 1200,
+ height: 630,
+}
+
+export default Image
diff --git a/components/shared/example-demos.tsx b/components/shared/example-demos.tsx
index 7991bf2f..8e4d2326 100644
--- a/components/shared/example-demos.tsx
+++ b/components/shared/example-demos.tsx
@@ -472,6 +472,22 @@ const demos = [
),
},
+ {
+ title: turboIntegrations.lensProtocol.name,
+ description: turboIntegrations.lensProtocol.description,
+ href: turboIntegrations.lensProtocol.href,
+ demo: (
+
+
+
+ ),
+ },
{
title: turboIntegrations.starter.name,
description: turboIntegrations.starter.description,
diff --git a/config/networks.ts b/config/networks.ts
index 884eb8bc..2c1fa8a1 100644
--- a/config/networks.ts
+++ b/config/networks.ts
@@ -83,6 +83,7 @@ export const ETH_CHAINS_PROD = [
goerli,
base,
baseGoerli,
+ polygonMumbai,
]
export const ETH_CHAINS_DEV =
env.NEXT_PUBLIC_PROD_NETWORKS_DEV === "true"
diff --git a/data/integrations.ts b/data/integrations.ts
index cd343a3d..641f5232 100644
--- a/data/integrations.ts
+++ b/data/integrations.ts
@@ -107,6 +107,14 @@ export const integrations = {
imgLight: "/integrations/arweave-light.png",
imgDark: "/integrations/arweave-dark.png",
},
+ lensProtocol: {
+ name: "Lens Protocol",
+ href: "/integration/lens-protocol",
+ url: "https://www.lens.xyz/",
+ description: "Lens Protocol is the social layer for Web3",
+ imgLight: "/integrations/lensprotocol-light.svg",
+ imgDark: "/integrations/lensprotocol-dark.svg",
+ },
},
services: {
disco: {
diff --git a/data/turbo-integrations.ts b/data/turbo-integrations.ts
index 999b11c3..d0a6df71 100644
--- a/data/turbo-integrations.ts
+++ b/data/turbo-integrations.ts
@@ -148,6 +148,14 @@ export const turboIntegrations = {
imgLight: "/integrations/arweave-light.png",
imgDark: "/integrations/arweave-dark.png",
},
+ lensProtocol: {
+ name: "Lens Protocol",
+ href: "/integration/lens-protocol",
+ url: "https://www.lens.xyz/",
+ description: "Lens Protocol is the social layer for Web3",
+ imgLight: "/integrations/lensprotocol-light.svg",
+ imgDark: "/integrations/lensprotocol-dark.svg",
+ },
starter: {
name: "Starter Template",
href: "/integration/starter",
diff --git a/integrations/lens-protocol/components/auth/is-user-authenticated.tsx b/integrations/lens-protocol/components/auth/is-user-authenticated.tsx
new file mode 100644
index 00000000..ca418607
--- /dev/null
+++ b/integrations/lens-protocol/components/auth/is-user-authenticated.tsx
@@ -0,0 +1,17 @@
+import { ReactNode } from "react"
+import { useActiveWallet } from "@lens-protocol/react-web"
+
+import { Skeleton } from "@/components/ui/skeleton"
+
+export const IsUserAuthenticated = ({
+ children,
+ showLoading,
+}: {
+ children: ReactNode
+ showLoading?: boolean
+}) => {
+ const { data: wallet, loading } = useActiveWallet()
+ if (loading && showLoading) return
+ if (wallet && children) return <>{children}>
+ return null
+}
diff --git a/integrations/lens-protocol/components/auth/login-button.tsx b/integrations/lens-protocol/components/auth/login-button.tsx
new file mode 100644
index 00000000..529ace10
--- /dev/null
+++ b/integrations/lens-protocol/components/auth/login-button.tsx
@@ -0,0 +1,44 @@
+import { useEffect } from "react"
+import { useWalletLogin } from "@lens-protocol/react-web"
+import { useAccount } from "wagmi"
+
+import { useToast } from "@/lib/hooks/use-toast"
+import { Button } from "@/components/ui/button"
+
+export const LoginButton = () => {
+ const { execute: login, error: loginError, isPending } = useWalletLogin()
+ const { address } = useAccount()
+ const { toast, dismiss } = useToast()
+
+ useEffect(() => {
+ if (loginError) showErrorToast(String(loginError))
+ }, [loginError])
+
+ const showErrorToast = (loginError: string) => {
+ toast({
+ title: "Login failed",
+ description: loginError,
+ })
+
+ setTimeout(() => {
+ dismiss()
+ }, 10000)
+ }
+
+ const onLoginClick = async () => {
+ if (!address) return null
+ await login({
+ address,
+ })
+ }
+ return (
+
+ )
+}
diff --git a/integrations/lens-protocol/components/auth/logout-button.tsx b/integrations/lens-protocol/components/auth/logout-button.tsx
new file mode 100644
index 00000000..f89f567a
--- /dev/null
+++ b/integrations/lens-protocol/components/auth/logout-button.tsx
@@ -0,0 +1,18 @@
+import { useWalletLogout } from "@lens-protocol/react-web"
+
+import { Button } from "@/components/ui/button"
+
+export const LogoutButton = () => {
+ const { execute: logout, isPending } = useWalletLogout()
+
+ return (
+
+ )
+}
diff --git a/integrations/lens-protocol/components/auth/not-authenticated-yet.tsx b/integrations/lens-protocol/components/auth/not-authenticated-yet.tsx
new file mode 100644
index 00000000..a4021b86
--- /dev/null
+++ b/integrations/lens-protocol/components/auth/not-authenticated-yet.tsx
@@ -0,0 +1,8 @@
+import { ReactNode } from "react"
+import { useActiveWallet } from "@lens-protocol/react-web"
+
+export const NotAuthenticatedYet = ({ children }: { children: ReactNode }) => {
+ const { data: wallet } = useActiveWallet()
+ if (!wallet) return <>{children}>
+ return null
+}
diff --git a/integrations/lens-protocol/components/feed.tsx b/integrations/lens-protocol/components/feed.tsx
new file mode 100644
index 00000000..fbbb4079
--- /dev/null
+++ b/integrations/lens-protocol/components/feed.tsx
@@ -0,0 +1,41 @@
+import { ProfileId, useActiveProfile, useFeed } from "@lens-protocol/react-web"
+
+import { LoadMoreButton } from "./load-more-button"
+import {
+ PublicationCard,
+ PublicationCardMode,
+} from "./publications/publication-card"
+
+export const Feed = ({ profileId }: { profileId: ProfileId }) => {
+ const activeProfile = useActiveProfile()
+ const { data, loading, hasMore, next } = useFeed({
+ observerId: activeProfile?.data?.id ?? undefined,
+ profileId,
+ limit: 10,
+ })
+ return (
+
+
Feed
+ {data?.map((feedItem) => (
+
+ ))}
+ {loading &&
+ Array(5)
+ .fill(0)
+ .map((_, index) => (
+
+ ))}
+
+ {!loading && !data?.length &&
User feed is empty.}
+
+ )
+}
diff --git a/integrations/lens-protocol/components/load-more-button.tsx b/integrations/lens-protocol/components/load-more-button.tsx
new file mode 100644
index 00000000..917b1416
--- /dev/null
+++ b/integrations/lens-protocol/components/load-more-button.tsx
@@ -0,0 +1,18 @@
+import { Button } from "@/components/ui/button"
+
+export const LoadMoreButton = ({
+ hasMore,
+ loading,
+ onClick,
+}: {
+ hasMore: boolean
+ loading: boolean
+ onClick: () => void
+}) =>
+ hasMore ? (
+
+
+
+ ) : null
diff --git a/integrations/lens-protocol/components/navbar.tsx b/integrations/lens-protocol/components/navbar.tsx
new file mode 100644
index 00000000..c4df2563
--- /dev/null
+++ b/integrations/lens-protocol/components/navbar.tsx
@@ -0,0 +1,116 @@
+import { useCallback, useState } from "react"
+import { useRouter } from "next/navigation"
+import { useActiveProfile } from "@lens-protocol/react-web"
+
+import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
+import { Button } from "@/components/ui/button"
+import { LinkComponent } from "@/components/shared/link-component"
+
+import { getProfilePictureSrc } from "../utils"
+import { IsUserAuthenticated } from "./auth/is-user-authenticated"
+import { LoginButton } from "./auth/login-button"
+import { LogoutButton } from "./auth/logout-button"
+import { NotAuthenticatedYet } from "./auth/not-authenticated-yet"
+
+export const Navbar = () => {
+ const [searchQuery, setSearchQuery] = useState("")
+ const router = useRouter()
+ const search = useCallback(() => {
+ router.push(`/integration/lens-protocol/search?q=${searchQuery}`)
+ }, [searchQuery])
+ const { data: activeProfile } = useActiveProfile()
+ return (
+
+ )
+}
diff --git a/integrations/lens-protocol/components/profile/address-profiles.tsx b/integrations/lens-protocol/components/profile/address-profiles.tsx
new file mode 100644
index 00000000..a31b9f23
--- /dev/null
+++ b/integrations/lens-protocol/components/profile/address-profiles.tsx
@@ -0,0 +1,35 @@
+import { useActiveProfile, useProfilesOwnedBy } from "@lens-protocol/react-web"
+
+import { LoadMoreButton } from "../load-more-button"
+import { ProfileCard } from "./profile-card"
+
+export const AddressProfiles = ({ address }: { address: string }) => {
+ const { data: activeProfile } = useActiveProfile()
+ const {
+ data: profiles,
+ loading,
+ hasMore,
+ next,
+ } = useProfilesOwnedBy({
+ limit: 10,
+ address,
+ observerId: activeProfile?.id,
+ })
+ return (
+
+
+ {address}Profiles
+
+
+ {profiles?.map((profile) => (
+
+ ))}
+ {loading &&
+ Array(4)
+ .fill(0)
+ .map((_, index) =>
)}
+
+
+
+ )
+}
diff --git a/integrations/lens-protocol/components/profile/explore-profiles.tsx b/integrations/lens-protocol/components/profile/explore-profiles.tsx
new file mode 100644
index 00000000..fa053007
--- /dev/null
+++ b/integrations/lens-protocol/components/profile/explore-profiles.tsx
@@ -0,0 +1,44 @@
+import { useRouter } from "next/navigation"
+import { useActiveProfile, useExploreProfiles } from "@lens-protocol/react-web"
+
+import { LoadMoreButton } from "../load-more-button"
+import { ProfileCard } from "./profile-card"
+
+export const ExploreProfiles = () => {
+ const profile = useActiveProfile()
+ const {
+ data: profiles,
+ loading,
+ hasMore,
+ next,
+ } = useExploreProfiles({
+ limit: 10,
+ observerId: profile?.data?.id ?? undefined,
+ })
+ const router = useRouter()
+ return (
+ <>
+
+
Profiles
+
+ {profiles?.map((profile) => (
+
+ router.push(
+ `/integration/lens-protocol/profiles/${profile.handle}`
+ )
+ }
+ />
+ ))}
+ {loading &&
+ Array(4)
+ .fill(0)
+ .map((_, index) => )}
+
+
+
+ >
+ )
+}
diff --git a/integrations/lens-protocol/components/profile/follow-unfollow-button.tsx b/integrations/lens-protocol/components/profile/follow-unfollow-button.tsx
new file mode 100644
index 00000000..c1383f27
--- /dev/null
+++ b/integrations/lens-protocol/components/profile/follow-unfollow-button.tsx
@@ -0,0 +1,117 @@
+import { useEffect } from "react"
+import {
+ FollowPolicyType,
+ Profile,
+ ProfileOwnedByMe,
+ useActiveProfile,
+ useFollow,
+ useProfile,
+ useUnfollow,
+} from "@lens-protocol/react-web"
+
+import { useToast } from "@/lib/hooks/use-toast"
+import { Button } from "@/components/ui/button"
+
+const UnauthorizedFollowButton = () => {
+ const { toast, dismiss } = useToast()
+ const showErrorToast = () => {
+ toast({
+ title: "You need to login first.",
+ })
+
+ setTimeout(() => {
+ dismiss()
+ }, 10000)
+ }
+ return (
+
+ )
+}
+
+const AuthorizedFollowUnfollowButton = ({
+ profile,
+ activeProfile,
+}: {
+ profile: Profile
+ activeProfile: ProfileOwnedByMe
+}) => {
+ const { data: followeeProfile } = useProfile({
+ observerId: activeProfile.id,
+ profileId: profile.id,
+ })
+ const {
+ execute: follow,
+ error,
+ isPending: followLoading,
+ } = useFollow({ follower: activeProfile, followee: profile })
+ const { execute: unfollow, isPending: unfollowLoading } = useUnfollow({
+ follower: activeProfile,
+ followee: profile,
+ })
+ const { toast, dismiss } = useToast()
+
+ useEffect(() => {
+ if (error) showErrorToast(String(error))
+ }, [error])
+
+ const showErrorToast = (error: string) => {
+ toast({
+ title: "Operation failed",
+ description: error,
+ })
+
+ setTimeout(() => {
+ dismiss()
+ }, 10000)
+ }
+ if (followeeProfile?.isFollowedByMe)
+ return (
+
+ )
+ return (
+
+ )
+}
+
+export const FollowUnfollowButton = ({ profile }: { profile: Profile }) => {
+ const { data: activeProfile } = useActiveProfile()
+ if (!activeProfile) return
+ if (profile.ownedByMe) return null
+ return (
+
+ )
+}
diff --git a/integrations/lens-protocol/components/profile/owned-profiles.tsx b/integrations/lens-protocol/components/profile/owned-profiles.tsx
new file mode 100644
index 00000000..7edce831
--- /dev/null
+++ b/integrations/lens-protocol/components/profile/owned-profiles.tsx
@@ -0,0 +1,146 @@
+import { turboIntegrations } from "@/data/turbo-integrations"
+import {
+ useActiveProfile,
+ useActiveProfileSwitch,
+ useProfilesOwnedByMe,
+} from "@lens-protocol/react-web"
+import { FaExternalLinkAlt } from "react-icons/fa"
+
+import { Avatar, AvatarFallback } from "@/components/ui/avatar"
+import { Button } from "@/components/ui/button"
+import { Card } from "@/components/ui/card"
+import { Input } from "@/components/ui/input"
+import { LightDarkImage } from "@/components/shared/light-dark-image"
+import { LinkComponent } from "@/components/shared/link-component"
+
+import { useCreateTestProfile } from "../../hooks/use-create-profile"
+import { IsUserAuthenticated } from "../auth/is-user-authenticated"
+import { LoginButton } from "../auth/login-button"
+import { NotAuthenticatedYet } from "../auth/not-authenticated-yet"
+import { LoadMoreButton } from "../load-more-button"
+import { ProfileCard } from "./profile-card"
+
+export const OwnedProfiles = () => {
+ const {
+ data: profiles,
+ loading,
+ hasMore,
+ next,
+ } = useProfilesOwnedByMe({
+ limit: 10,
+ })
+ const {
+ onSubmit,
+ handle,
+ error,
+ setHandle,
+ isPending: isCreating,
+ } = useCreateTestProfile()
+ const { data: activeProfile } = useActiveProfile()
+ const { execute: switchActiveProfile, isPending } = useActiveProfileSwitch()
+ return (
+
+
Owned Profiles
+
+
+ {profiles
+ ?.filter(
+ (profile, index, arr) =>
+ arr.findIndex((p) => p.handle === profile.handle) === index
+ )
+ .map((profile) => {
+ const isProfileSelected = profile.id === activeProfile?.id
+ return (
+
+
+
+ View
+
+
+ }
+ />
+ )
+ })}
+ {loading &&
+ Array(4)
+ .fill(0)
+ .map((_, index) => )}
+
+
+
+ +
+
+
+
+ Create a new profile on testnet
+
+
+
+
+
+
+
+
+
+ Claim a new handle on Lens
+
+
+ Join the waitlist
+
+
+
+
+
+
+
+
+ You need to login first to be able to see your profiles.
+
+
+
+
+
+ )
+}
diff --git a/integrations/lens-protocol/components/profile/profile-card.tsx b/integrations/lens-protocol/components/profile/profile-card.tsx
new file mode 100644
index 00000000..0e4bdefd
--- /dev/null
+++ b/integrations/lens-protocol/components/profile/profile-card.tsx
@@ -0,0 +1,86 @@
+import { ReactNode } from "react"
+import { useRouter } from "next/navigation"
+import { Profile } from "@lens-protocol/react-web"
+
+import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
+import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card"
+import { Skeleton } from "@/components/ui/skeleton"
+
+import { getProfilePictureSrc } from "../../utils"
+import { FollowUnfollowButton } from "./follow-unfollow-button"
+
+export const ProfileCard = ({
+ profile,
+ onClick,
+ cta,
+}: {
+ profile: Profile | null
+ onClick?: () => void
+ cta?: ReactNode
+}) => {
+ const router = useRouter()
+ return (
+ {
+ e.stopPropagation()
+ if (onClick) onClick()
+ else if (profile)
+ router.push(`/integration/lens-protocol/profiles/${profile.handle}`)
+ }}
+ >
+
+ {profile ? (
+
+
+
+ {profile.handle.substring(0, 1)}
+
+
+ ) : (
+
+ )}
+ {profile ? (
+
+ @{profile.handle}
+
+ ) : (
+
+ )}
+ {profile ? (
+
+ {profile.name ?? profile.handle}
+
+ ) : (
+
+ )}
+
+ {profile ? (
+
+ {profile.stats.totalFollowers}
+ Followers
+
+ ) : (
+
+ )}
+ {profile ? (
+
+ {profile.stats.totalFollowing}
+ Followings
+
+ ) : (
+
+ )}
+
+
+
+ {profile ? (
+
+ ) : (
+
+ )}
+ {cta && cta}
+
+
+ )
+}
diff --git a/integrations/lens-protocol/components/profile/profile-list-modal.tsx b/integrations/lens-protocol/components/profile/profile-list-modal.tsx
new file mode 100644
index 00000000..3888b0bd
--- /dev/null
+++ b/integrations/lens-protocol/components/profile/profile-list-modal.tsx
@@ -0,0 +1,105 @@
+import { ReactNode } from "react"
+import { useRouter } from "next/navigation"
+import { Profile } from "@lens-protocol/react-web"
+
+import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
+import {
+ Dialog,
+ DialogContent,
+ DialogHeader,
+ DialogTrigger,
+} from "@/components/ui/dialog"
+import { Skeleton } from "@/components/ui/skeleton"
+
+import { getProfilePictureSrc } from "../../utils"
+import { LoadMoreButton } from "../load-more-button"
+import { FollowUnfollowButton } from "./follow-unfollow-button"
+
+const ProfileRow = ({ profile }: { profile: Profile | null }) => {
+ const router = useRouter()
+
+ return (
+
+
{
+ e.stopPropagation()
+ if (profile)
+ router.push(`/integration/lens-protocol/profiles/${profile.handle}`)
+ }}
+ >
+ {profile ? (
+
+
+
+ {profile.handle.substring(0, 1)}
+
+
+ ) : (
+
+ )}
+
+ {profile ? (
+
+ {profile.name ?? profile.handle}
+
+ ) : (
+
+ )}
+ {profile ? (
+
+ @{profile.handle}
+
+ ) : (
+
+ )}
+
+
+ {profile ? (
+
+ ) : (
+
+ )}
+
+ )
+}
+
+export const ProfileListModal = ({
+ profiles,
+ trigger,
+ hasMore,
+ loading,
+ title,
+ next,
+}: {
+ profiles: Profile[]
+ trigger: ReactNode
+ hasMore: boolean
+ loading: boolean
+ title: string
+ next: () => void
+}) => {
+ return (
+
+ )
+}
diff --git a/integrations/lens-protocol/components/profile/profile-publications.tsx b/integrations/lens-protocol/components/profile/profile-publications.tsx
new file mode 100644
index 00000000..1c70429c
--- /dev/null
+++ b/integrations/lens-protocol/components/profile/profile-publications.tsx
@@ -0,0 +1,69 @@
+import {
+ Post,
+ ProfileId,
+ PublicationTypes,
+ useActiveProfile,
+ usePublications,
+} from "@lens-protocol/react-web"
+import { FaRetweet } from "react-icons/fa"
+
+import { LoadMoreButton } from "../load-more-button"
+import { PublicationCard } from "../publications/publication-card"
+
+export const ProfilePublications = ({
+ profileId,
+ publicationTypes,
+ title,
+}: {
+ profileId: ProfileId
+ publicationTypes: PublicationTypes[]
+ title: string
+}) => {
+ const { data: activeProfile } = useActiveProfile()
+ const {
+ data: publications,
+ loading,
+ hasMore,
+ next,
+ } = usePublications({
+ profileId,
+ observerId: activeProfile?.id,
+ publicationTypes,
+ limit: 10,
+ })
+ return (
+
+
{title}
+ {publications?.map((publication) =>
+ publication.__typename === "Mirror" ? (
+ <>
+
+
+
+ {publication.profile.name ?? publication.profile.handle}
+
+ Mirrored
+
+
+ >
+ ) : (
+
+ )
+ )}
+ {loading &&
+ Array(5)
+ .fill(0)
+ .map((_, index) => (
+
+ ))}
+
+ {publications?.length === 0 &&
No {title} yet.}
+
+ )
+}
diff --git a/integrations/lens-protocol/components/profile/profile-revenue.tsx b/integrations/lens-protocol/components/profile/profile-revenue.tsx
new file mode 100644
index 00000000..f621f6cc
--- /dev/null
+++ b/integrations/lens-protocol/components/profile/profile-revenue.tsx
@@ -0,0 +1,36 @@
+import { ProfileId, useProfileFollowRevenue } from "@lens-protocol/react-web"
+
+import { Skeleton } from "@/components/ui/skeleton"
+
+export const ProfileRevenue = ({ profileId }: { profileId: ProfileId }) => {
+ const { data, loading: revenueLoading } = useProfileFollowRevenue({
+ profileId,
+ })
+ return (
+
+
Profile Revenue
+ {data?.map((revenue) => {
+ const { asset } = revenue.totalAmount
+ return (
+
+
+ {revenue.totalAmount.toNumber()}
+
+ {asset.symbol}
+
+ )
+ })}
+ {revenueLoading && (
+
+
+
+ )}
+ {!data?.length && (
+
None yet
+ )}
+
+ )
+}
diff --git a/integrations/lens-protocol/components/profile/profile-stats.tsx b/integrations/lens-protocol/components/profile/profile-stats.tsx
new file mode 100644
index 00000000..d5381a99
--- /dev/null
+++ b/integrations/lens-protocol/components/profile/profile-stats.tsx
@@ -0,0 +1,68 @@
+import {
+ Profile,
+ useActiveProfile,
+ useProfileFollowers,
+ useProfileFollowing,
+} from "@lens-protocol/react-web"
+
+import { ProfileListModal } from "./profile-list-modal"
+
+export const ProfileStats = ({ profile }: { profile: Profile }) => {
+ const { data: activeProfile } = useActiveProfile()
+ const {
+ data: followers,
+ loading: followersLoading,
+ hasMore: followersHasMore,
+ next: followersNext,
+ } = useProfileFollowers({
+ profileId: profile.id,
+ observerId: activeProfile?.id,
+ limit: 10,
+ })
+ const {
+ data: followings,
+ loading: followingsLoading,
+ hasMore: followingsHasMore,
+ next: followingsNext,
+ } = useProfileFollowing({
+ walletAddress: profile.ownedBy,
+ observerId: activeProfile?.id,
+ limit: 10,
+ })
+ return (
+
+
+ follower.wallet.defaultProfile
+ ? [follower.wallet.defaultProfile]
+ : []
+ ) ?? []
+ }
+ title="Followers"
+ trigger={
+
+ {profile.stats.totalFollowers}
+ Followers
+
+ }
+ />
+ following.profile) ?? []}
+ title="Followings"
+ trigger={
+
+ {profile.stats.totalFollowing}
+ Followings
+
+ }
+ />
+
+ )
+}
diff --git a/integrations/lens-protocol/components/profile/profile.tsx b/integrations/lens-protocol/components/profile/profile.tsx
new file mode 100644
index 00000000..21b2ff7a
--- /dev/null
+++ b/integrations/lens-protocol/components/profile/profile.tsx
@@ -0,0 +1,191 @@
+import Link from "next/link"
+import {
+ PublicationTypes,
+ useActiveProfile,
+ useProfile,
+} from "@lens-protocol/react-web"
+
+import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
+import { Skeleton } from "@/components/ui/skeleton"
+import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
+
+import { getProfilePictureSrc } from "../../utils"
+import { IsUserAuthenticated } from "../auth/is-user-authenticated"
+import { LoginButton } from "../auth/login-button"
+import { NotAuthenticatedYet } from "../auth/not-authenticated-yet"
+import { Feed } from "../feed"
+import { PublicationCard } from "../publications/publication-card"
+import { FollowUnfollowButton } from "./follow-unfollow-button"
+import { ProfilePublications } from "./profile-publications"
+import { ProfileRevenue } from "./profile-revenue"
+import { ProfileStats } from "./profile-stats"
+
+export const Profile = ({ handle }: { handle: string }) => {
+ const activeProfile = useActiveProfile()
+ const { data: profile, loading } = useProfile({
+ handle,
+ observerId: activeProfile?.data?.id ?? undefined,
+ })
+
+ if (!loading && !profile)
+ return Profile not found!
+ return (
+
+
+ {profile ? (
+
+
+
+ {profile.handle.substring(0, 1)}
+
+
+ ) : (
+
+ )}
+ {!profile ? (
+
+ ) : (
+ profile.name && (
+
+ {profile.name}
+
+ )
+ )}
+ {profile ? (
+
@{profile.handle}
+ ) : (
+
+ )}
+ {profile ? (
+
+ ) : (
+
+
+
+
+ )}
+ {profile && !profile.ownedByMe && (
+
+ )}
+ {!profile ? (
+
+
+
+
+
+ ) : (
+ profile.bio && (
+ <>
+
Bio
+
+ {profile.bio}
+
+ >
+ )
+ )}
+
+ {profile ? (
+
Owned by
+ ) : (
+
+ )}
+ {profile ? (
+
+ {profile.ownedBy}
+
+ ) : (
+
+ )}
+ {profile ? (
+
+ See all profiles
+
+ ) : (
+
+ )}
+
+ {profile && Object.keys(profile.attributes).length > 0 && (
+
+ {Object.entries(profile.attributes).map(([key, attribute]) => (
+
+ {key}:
+
+ {attribute.toString()}
+
+
+ ))}
+
+ )}
+ {profile ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ {profile ? (
+
+ Feed
+ Posts
+ Replies
+
+ ) : (
+
+
+ Feed
+ Posts
+ Replies
+
+
+ )}
+
+ {profile ? (
+ <>
+
+
+
+
+
+
+ You need to login to see the profile feed.
+
+
+
+
+
+
+
+
+
+
+ >
+ ) : (
+
+ {Array(5)
+ .fill(0)
+ .map((_, index) => (
+
+ ))}
+
+ )}
+
+
+
+ )
+}
diff --git a/integrations/lens-protocol/components/profile/search-profiles.tsx b/integrations/lens-protocol/components/profile/search-profiles.tsx
new file mode 100644
index 00000000..3656e3fc
--- /dev/null
+++ b/integrations/lens-protocol/components/profile/search-profiles.tsx
@@ -0,0 +1,44 @@
+import { useRouter } from "next/navigation"
+import { useActiveProfile, useSearchProfiles } from "@lens-protocol/react-web"
+
+import { LoadMoreButton } from "../load-more-button"
+import { ProfileCard } from "./profile-card"
+
+export const SearchProfiles = ({ query }: { query: string }) => {
+ const profile = useActiveProfile()
+ const {
+ data: profiles,
+ loading,
+ hasMore,
+ next,
+ } = useSearchProfiles({
+ query,
+ limit: 10,
+ observerId: profile?.data?.id ?? undefined,
+ })
+ const router = useRouter()
+ return (
+
+
Profiles
+
+ {profiles?.map((profile) => (
+
+ router.push(
+ `/integration/lens-protocol/profiles/${profile.handle}`
+ )
+ }
+ />
+ ))}
+ {loading &&
+ Array(4)
+ .fill(0)
+ .map((_, index) => )}
+
+
+ {!loading && !profiles?.length &&
No profiles found.}
+
+ )
+}
diff --git a/integrations/lens-protocol/components/publications/actions/button.tsx b/integrations/lens-protocol/components/publications/actions/button.tsx
new file mode 100644
index 00000000..03c80e6b
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/actions/button.tsx
@@ -0,0 +1,50 @@
+import { ReactNode } from "react"
+
+import { Button } from "@/components/ui/button"
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger,
+} from "@/components/ui/tooltip"
+
+export const ActionButton = ({
+ color,
+ execute,
+ name,
+ hideCount,
+ count,
+ disabled,
+ icon,
+}: {
+ color: string
+ execute: () => void
+ name: string
+ hideCount: boolean
+ count: number
+ disabled: boolean
+ icon: ReactNode
+}) => {
+ const btnColor = `text-${color}-500 dark:text-${color}-300 hover:text-${color}-600 hover:dark:text-${color}-200`
+ return (
+
+ )
+}
diff --git a/integrations/lens-protocol/components/publications/actions/comment.tsx b/integrations/lens-protocol/components/publications/actions/comment.tsx
new file mode 100644
index 00000000..8c2e16cb
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/actions/comment.tsx
@@ -0,0 +1,30 @@
+import { FaRegCommentAlt } from "react-icons/fa"
+
+import { useToast } from "@/lib/hooks/use-toast"
+
+import { IActionButton } from "."
+import { ActionButton } from "./button"
+
+export const CommentButton = ({ publication, hideCount }: IActionButton) => {
+ const { toast, dismiss } = useToast()
+ const showErrorToast = () => {
+ toast({
+ title: "Commenting on a publication is not supported currently.",
+ })
+
+ setTimeout(() => {
+ dismiss()
+ }, 10000)
+ }
+ return (
+ showErrorToast()}
+ hideCount={hideCount}
+ icon={}
+ name="comment"
+ />
+ )
+}
diff --git a/integrations/lens-protocol/components/publications/actions/index.tsx b/integrations/lens-protocol/components/publications/actions/index.tsx
new file mode 100644
index 00000000..b4f1aa12
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/actions/index.tsx
@@ -0,0 +1,6 @@
+import { Comment, Post } from "@lens-protocol/react-web"
+
+export interface IActionButton {
+ publication: Post | Comment
+ hideCount: boolean
+}
diff --git a/integrations/lens-protocol/components/publications/actions/like.tsx b/integrations/lens-protocol/components/publications/actions/like.tsx
new file mode 100644
index 00000000..e864a94e
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/actions/like.tsx
@@ -0,0 +1,96 @@
+import {
+ Profile,
+ ReactionTypes,
+ useActiveProfile,
+ useReaction,
+} from "@lens-protocol/react-web"
+import { FaHeart, FaRegHeart } from "react-icons/fa"
+
+import { useToast } from "@/lib/hooks/use-toast"
+
+import { IActionButton } from "."
+import { IsUserAuthenticated } from "../../auth/is-user-authenticated"
+import { NotAuthenticatedYet } from "../../auth/not-authenticated-yet"
+import { ActionButton } from "./button"
+
+const UnAuthorizedLikeButton = ({ publication, hideCount }: IActionButton) => {
+ const { toast, dismiss } = useToast()
+ const showErrorToast = () => {
+ toast({
+ title: "You need to login first.",
+ })
+
+ setTimeout(() => {
+ dismiss()
+ }, 10000)
+ }
+ return (
+ showErrorToast()}
+ hideCount={hideCount}
+ icon={}
+ name="like"
+ />
+ )
+}
+
+const AuthorizedLikeButton = ({
+ publication,
+ hideCount,
+ profile,
+}: IActionButton & { profile: Profile }) => {
+ const { addReaction, removeReaction, hasReaction, isPending } = useReaction({
+ profileId: profile.id,
+ })
+
+ const reactionType = ReactionTypes.Upvote
+
+ const hasReactionType = hasReaction({
+ reactionType,
+ publication,
+ })
+
+ const execute = async () => {
+ if (isPending) return
+ if (!hasReactionType) {
+ await addReaction({
+ reactionType,
+ publication,
+ })
+ } else if (hasReactionType) {
+ await removeReaction({
+ reactionType,
+ publication,
+ })
+ }
+ }
+
+ return (
+ : }
+ name="like"
+ />
+ )
+}
+
+export const LikeButton = (props: IActionButton) => {
+ const { data: profile } = useActiveProfile()
+ return (
+ <>
+
+
+
+
+ {profile && }
+
+ >
+ )
+}
diff --git a/integrations/lens-protocol/components/publications/actions/mirror.tsx b/integrations/lens-protocol/components/publications/actions/mirror.tsx
new file mode 100644
index 00000000..bbd9aa9e
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/actions/mirror.tsx
@@ -0,0 +1,98 @@
+import { useEffect } from "react"
+import {
+ ProfileOwnedByMe,
+ useActiveProfile,
+ useCreateMirror,
+} from "@lens-protocol/react-web"
+import { FaRetweet } from "react-icons/fa"
+
+import { useToast } from "@/lib/hooks/use-toast"
+
+import { IActionButton } from "."
+import { IsUserAuthenticated } from "../../auth/is-user-authenticated"
+import { NotAuthenticatedYet } from "../../auth/not-authenticated-yet"
+import { ActionButton } from "./button"
+
+const UnAuthorizedMirrorButton = ({
+ publication,
+ hideCount,
+}: IActionButton) => {
+ const { toast, dismiss } = useToast()
+ const showErrorToast = () => {
+ toast({
+ title: "You need to login first.",
+ })
+
+ setTimeout(() => {
+ dismiss()
+ }, 10000)
+ }
+ return (
+ showErrorToast()}
+ hideCount={hideCount}
+ icon={}
+ name="mirror"
+ />
+ )
+}
+
+const AuthorizedMirrorButton = ({
+ publication,
+ hideCount,
+ profile,
+}: IActionButton & { profile: ProfileOwnedByMe }) => {
+ const {
+ execute: create,
+ isPending,
+ error,
+ } = useCreateMirror({ publisher: profile })
+ const { toast, dismiss } = useToast()
+ const showErrorToast = (error: string) => {
+ toast({
+ title: "Mirror failed.",
+ description: error,
+ })
+
+ setTimeout(() => {
+ dismiss()
+ }, 10000)
+ }
+ useEffect(() => {
+ if (error) showErrorToast(String(error))
+ }, [error])
+ return (
+ }
+ name="mirror"
+ execute={() =>
+ create({
+ publication,
+ })
+ }
+ />
+ )
+}
+
+export const MirrorButton = (props: IActionButton) => {
+ const { data: profile } = useActiveProfile()
+ return (
+ <>
+
+
+
+
+ {profile && }
+
+ >
+ )
+}
diff --git a/integrations/lens-protocol/components/publications/commnets.tsx b/integrations/lens-protocol/components/publications/commnets.tsx
new file mode 100644
index 00000000..47cea9d1
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/commnets.tsx
@@ -0,0 +1,46 @@
+import { PublicationId, useComments } from "@lens-protocol/react-web"
+
+import { LoadMoreButton } from "../load-more-button"
+import { PublicationCard } from "./publication-card"
+
+export const Comments = ({
+ publicationId,
+}: {
+ publicationId: PublicationId
+}) => {
+ const {
+ data: comments,
+ loading,
+ hasMore,
+ next,
+ } = useComments({
+ commentsOf: publicationId,
+ limit: 10,
+ })
+ return (
+
+ {comments?.map((comment, index) => (
+
+ ))}
+ {loading &&
+ Array(5)
+ .fill(0)
+ .map((_, index) => (
+
+ ))}
+
+
+ )
+}
diff --git a/integrations/lens-protocol/components/publications/explore-publications.tsx b/integrations/lens-protocol/components/publications/explore-publications.tsx
new file mode 100644
index 00000000..ec35cc79
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/explore-publications.tsx
@@ -0,0 +1,40 @@
+import {
+ Post,
+ PublicationTypes,
+ useExplorePublications,
+} from "@lens-protocol/react-web"
+
+import { LoadMoreButton } from "../load-more-button"
+import { PublicationCard } from "./publication-card"
+
+export const ExplorePublications = () => {
+ const {
+ data: publications,
+ loading,
+ hasMore,
+ next,
+ } = useExplorePublications({
+ limit: 10,
+ publicationTypes: [PublicationTypes.Post],
+ })
+ return (
+ <>
+
+
Publications
+ {publications?.map((publication) => (
+
+ ))}
+ {loading &&
+ Array(5)
+ .fill(0)
+ .map((_, index) => (
+
+ ))}
+
+
+ >
+ )
+}
diff --git a/integrations/lens-protocol/components/publications/publication-actions-and-stats.tsx b/integrations/lens-protocol/components/publications/publication-actions-and-stats.tsx
new file mode 100644
index 00000000..6450d31f
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/publication-actions-and-stats.tsx
@@ -0,0 +1,25 @@
+import { Comment, Post } from "@lens-protocol/react-web"
+
+import { CommentButton } from "./actions/comment"
+import { LikeButton } from "./actions/like"
+import { MirrorButton } from "./actions/mirror"
+import { PublicationStats } from "./stats"
+
+export const PublicationActionsAndStats = ({
+ publication,
+ showCounts = false,
+}: {
+ publication: Post | Comment
+ showCounts: boolean
+}) => {
+ return (
+
+ {showCounts &&
}
+
+
+
+
+
+
+ )
+}
diff --git a/integrations/lens-protocol/components/publications/publication-card.tsx b/integrations/lens-protocol/components/publications/publication-card.tsx
new file mode 100644
index 00000000..3625b298
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/publication-card.tsx
@@ -0,0 +1,243 @@
+import { ReactNode } from "react"
+import { useRouter } from "next/navigation"
+import { Comment, FeedItem, Post } from "@lens-protocol/react-web"
+import moment from "moment"
+import { FaRetweet } from "react-icons/fa"
+
+import { cn } from "@/lib/utils"
+import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
+import { Card, CardContent } from "@/components/ui/card"
+import { Skeleton } from "@/components/ui/skeleton"
+
+import { getProfilePictureSrc } from "../../utils"
+import { Comments } from "./commnets"
+import { PublicationActionsAndStats } from "./publication-actions-and-stats"
+import { PublicationRevenue } from "./publication-revenue"
+
+export enum PublicationCardMode {
+ Normal = "normal",
+ Compact = "compact",
+ FeedComment = "FeedComment",
+ Full = "full",
+}
+
+const Wrapper = ({
+ shouldLinkToFullMode,
+ children,
+ id,
+ classNames,
+ chainedStyle,
+ last,
+}: {
+ shouldLinkToFullMode: boolean
+ children: ReactNode
+ id?: string
+ classNames: string
+ chainedStyle: boolean
+ last: boolean
+}) => {
+ const router = useRouter()
+ const defaultClassName = "p-6 w-full block"
+ const bottomLine =
+ "before:absolute before:left-[32px] before:top-[40px] before:h-full before:bg-slate-200 before:dark:bg-neutral-600 before:self-start before:w-[1px]"
+ const topLine =
+ "after:absolute after:left-[32px] after:top-[0px] after:h-[24px] after:bg-slate-200 after:dark:bg-neutral-600 after:self-start after:w-[1px]"
+ const chainedClassName = "relative ml-[-12px]"
+ const baseClassName = cn(
+ defaultClassName,
+ chainedStyle && chainedClassName,
+ chainedStyle && !last && bottomLine,
+ chainedStyle && topLine
+ )
+ if (shouldLinkToFullMode)
+ return (
+ {
+ e.stopPropagation()
+ if (id) router.push(`/integration/lens-protocol/publications/${id}`)
+ }}
+ >
+ {children}
+
+ )
+ return (
+
+ {children}
+
+ )
+}
+
+export const PublicationCard = ({
+ publication,
+ feedItem,
+ mode = PublicationCardMode.Normal,
+ wrapperClassNames = "",
+ last = false,
+ chainedStyle = false,
+}: {
+ publication: Post | Comment | null
+ feedItem?: FeedItem
+ mode?: PublicationCardMode
+ wrapperClassNames?: string
+ last?: boolean
+ chainedStyle?: boolean
+}) => {
+ const router = useRouter()
+ const compactMode = mode === PublicationCardMode.Compact
+ const fullMode = mode === PublicationCardMode.Full
+ const feedCommentMode = mode === PublicationCardMode.FeedComment
+ const { profile } = publication ?? { profile: null }
+ const mirrored = feedItem?.electedMirror ?? false
+ const bottomLine =
+ "relative before:absolute before:left-[-20px] before:top-[-16px] before:h-[calc(100%_+_32px)] before:bg-slate-200 before:dark:bg-neutral-600 before:self-start before:w-[1px]"
+ return (
+
+ {mirrored && (
+
+
+
+ {feedItem?.electedMirror?.profile.name ??
+ feedItem?.electedMirror?.profile.handle}
+
+ Mirrored
+
+ )}
+
+
+
{
+ e.stopPropagation()
+ if (profile)
+ router.push(
+ `/integration/lens-protocol/profiles/${profile.handle}`
+ )
+ }}
+ >
+ {profile ? (
+
+
+
+ {profile.handle.substring(0, 1)}
+
+
+ ) : (
+
+ )}
+
+
+ {profile ? (
+ profile.name ?? profile.handle
+ ) : (
+
+ )}
+
+ {!compactMode && (
+
+ {profile ? (
+ <>@{profile.handle}>
+ ) : (
+
+ )}
+
+ )}
+
+
+
+
+
+
+ {publication ? (
+ publication.metadata?.content
+ ) : (
+
+
+
+
+
+ )}
+
+
+ {publication ? (
+ moment(publication.createdAt).format("HH:mm YY MMM DD")
+ ) : (
+
+ )}
+
+ {!compactMode && publication && (
+
+ )}
+ {fullMode && publication && (
+
+ )}
+
+
+ {fullMode ? (
+ publication ? (
+
+ ) : (
+
+ {Array(3)
+ .fill(0)
+ .map((_, index) => (
+
+ ))}
+
+ )
+ ) : null}
+ {feedCommentMode && feedItem?.comments?.[0] && (
+
+ )}
+
+
+ )
+}
diff --git a/integrations/lens-protocol/components/publications/publication-revenue.tsx b/integrations/lens-protocol/components/publications/publication-revenue.tsx
new file mode 100644
index 00000000..720bad6b
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/publication-revenue.tsx
@@ -0,0 +1,29 @@
+import { PublicationId, usePublicationRevenue } from "@lens-protocol/react-web"
+
+export const PublicationRevenue = ({
+ publicationId,
+}: {
+ publicationId: PublicationId
+}) => {
+ const { data, loading: revenueLoading } = usePublicationRevenue({
+ publicationId,
+ })
+ if (revenueLoading) return null
+ return (
+
+
Publication Revenue
+ {data ? (
+
+
+ {data.revenue.totalAmount.toNumber()}
+
+
+ {data.revenue.totalAmount.asset.symbol}
+
+
+ ) : (
+
None yet
+ )}
+
+ )
+}
diff --git a/integrations/lens-protocol/components/publications/publication.tsx b/integrations/lens-protocol/components/publications/publication.tsx
new file mode 100644
index 00000000..6d88c545
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/publication.tsx
@@ -0,0 +1,115 @@
+import {
+ Comment,
+ Mirror,
+ Post,
+ PublicationId,
+ usePublication,
+} from "@lens-protocol/react-web"
+import { FaRegCommentAlt, FaRetweet } from "react-icons/fa"
+
+import { LinkComponent } from "@/components/shared/link-component"
+
+import { PublicationCard, PublicationCardMode } from "./publication-card"
+
+export const Publication = ({
+ publicationId,
+}: {
+ publicationId: PublicationId
+}) => {
+ return (
+
+ )
+}
+
+export const PublicationDetails = ({
+ publicationId,
+}: {
+ publicationId: PublicationId
+}) => {
+ const { data: publication, loading } = usePublication({
+ publicationId,
+ })
+ if (loading)
+ return (
+
+ )
+ if (!publication)
+ return Publication not found!
+ if (publication.__typename === "Mirror")
+ return
+ if (publication.__typename === "Comment")
+ return
+ if (publication.__typename === "Post")
+ return
+ return (
+ Unknown type of publication!
+ )
+}
+
+const RenderPost = ({ publication }: { publication: Post }) => {
+ return (
+
+ )
+}
+
+const RenderMirror = ({ publication }: { publication: Mirror }) => {
+ const { profile } = publication
+ return (
+
+
+
+
+
+ {profile.name ?? profile.handle}
+
+
+ Mirrored
+
+ {publication.mirrorOf.__typename === "Post" && (
+
+ )}
+ {publication.mirrorOf.__typename === "Comment" && (
+
+ )}
+
+ )
+}
+
+const RenderComment = ({ publication }: { publication: Comment }) => {
+ const { profile } = publication
+ return (
+
+
+ Original publication
+
+ {publication.commentOn?.__typename === "Post" && (
+
+ )}
+
+
+
+
+ {profile.name ?? profile.handle}
+
+
+ Commented
+
+
+
+ )
+}
diff --git a/integrations/lens-protocol/components/publications/search-publications.tsx b/integrations/lens-protocol/components/publications/search-publications.tsx
new file mode 100644
index 00000000..d999f8be
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/search-publications.tsx
@@ -0,0 +1,32 @@
+import { Post, useSearchPublications } from "@lens-protocol/react-web"
+
+import { LoadMoreButton } from "../load-more-button"
+import { PublicationCard } from "./publication-card"
+
+export const SearchPublications = ({ query }: { query: string }) => {
+ const {
+ data: publications,
+ loading,
+ hasMore,
+ next,
+ } = useSearchPublications({ query, limit: 10 })
+ return (
+
+
Publications
+ {publications?.map((publication) => (
+
+ ))}
+ {loading &&
+ Array(5)
+ .fill(0)
+ .map((_, index) => (
+
+ ))}
+
+ {!loading && !publications?.length &&
No publications found.}
+
+ )
+}
diff --git a/integrations/lens-protocol/components/publications/stats/index.tsx b/integrations/lens-protocol/components/publications/stats/index.tsx
new file mode 100644
index 00000000..c3e0d25e
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/stats/index.tsx
@@ -0,0 +1,69 @@
+import {
+ Comment,
+ Post,
+ useActiveProfile,
+ useWhoCollectedPublication,
+ useWhoMirroredPublication,
+ useWhoReacted,
+} from "@lens-protocol/react-web"
+
+import { Stat } from "./stat"
+
+export const PublicationStats = ({
+ publication,
+}: {
+ publication: Post | Comment
+}) => {
+ const { data: profile } = useActiveProfile()
+ const likes = useWhoReacted({
+ publicationId: publication.id,
+ observerId: profile?.id,
+ limit: 10,
+ })
+ const mirrors = useWhoMirroredPublication({
+ publicationId: publication.id,
+ observerId: profile?.id,
+ limit: 10,
+ })
+ const collects = useWhoCollectedPublication({
+ publicationId: publication.id,
+ observerId: profile?.id,
+ limit: 10,
+ })
+ return (
+
+
+
+ {publication.stats.commentsCount}
+
+ comments
+
+ reaction.profile)}
+ hasMore={likes.hasMore}
+ loading={likes.loading}
+ name="likes"
+ next={likes.next}
+ value={publication.stats.totalUpvotes}
+ />
+
+
+ wallet.defaultProfile ? [wallet.defaultProfile] : []
+ )}
+ hasMore={collects.hasMore}
+ loading={collects.loading}
+ name="collects"
+ next={collects.next}
+ value={publication.stats.totalAmountOfCollects}
+ />
+
+ )
+}
diff --git a/integrations/lens-protocol/components/publications/stats/stat.tsx b/integrations/lens-protocol/components/publications/stats/stat.tsx
new file mode 100644
index 00000000..6b3b0a56
--- /dev/null
+++ b/integrations/lens-protocol/components/publications/stats/stat.tsx
@@ -0,0 +1,33 @@
+import { Profile } from "@lens-protocol/react-web"
+
+import { ProfileListModal } from "../../profile/profile-list-modal"
+
+export const Stat = ({
+ name,
+ value,
+ data,
+ hasMore,
+ loading,
+ next,
+}: {
+ name: string
+ value: number
+ data?: Profile[]
+ hasMore: boolean
+ loading: boolean
+ next: () => void
+}) => (
+
+ {value}
+ {name}
+
+ }
+ />
+)
diff --git a/integrations/lens-protocol/hooks/use-create-profile.ts b/integrations/lens-protocol/hooks/use-create-profile.ts
new file mode 100644
index 00000000..e05cc0f8
--- /dev/null
+++ b/integrations/lens-protocol/hooks/use-create-profile.ts
@@ -0,0 +1,23 @@
+import { FormEvent, useState } from "react"
+import { isValidHandle, useCreateProfile } from "@lens-protocol/react-web"
+
+export const useCreateTestProfile = () => {
+ const [handle, setHandle] = useState(null)
+ const [error, setError] = useState(null)
+
+ const { execute: create, error: createError, isPending } = useCreateProfile()
+
+ const onSubmit = async (e: FormEvent) => {
+ e.preventDefault()
+ setError(null)
+ if (!handle) return
+ if (!isValidHandle(handle)) {
+ setError("Handle is taken.")
+ return
+ }
+ setHandle(null)
+ await create({ handle })
+ }
+
+ return { error: error ?? createError, isPending, onSubmit, handle, setHandle }
+}
diff --git a/integrations/lens-protocol/lens-provider.ts b/integrations/lens-protocol/lens-provider.ts
new file mode 100644
index 00000000..37c9a3b6
--- /dev/null
+++ b/integrations/lens-protocol/lens-provider.ts
@@ -0,0 +1,7 @@
+import { development, LensConfig } from "@lens-protocol/react-web"
+import { bindings as wagmiBindings } from "@lens-protocol/wagmi"
+
+export const lensProviderConfig: LensConfig = {
+ bindings: wagmiBindings(),
+ environment: development,
+}
diff --git a/integrations/lens-protocol/utils/index.ts b/integrations/lens-protocol/utils/index.ts
new file mode 100644
index 00000000..405a475b
--- /dev/null
+++ b/integrations/lens-protocol/utils/index.ts
@@ -0,0 +1,14 @@
+import { Profile } from "@lens-protocol/react-web"
+
+export const getProfilePictureSrc = (profile: Profile): string | undefined => {
+ if (!profile || !profile.picture) return undefined
+ if (profile.picture.__typename === "MediaSet") {
+ const splittedUrl = profile.picture.original.url.split("ipfs://")
+ if (splittedUrl.length === 2)
+ return `https://gateway.ipfs.io/ipfs/${splittedUrl[1]}`
+ return profile.picture.original.url
+ }
+ if (profile.picture.__typename === "NftImage")
+ return `https://cdn.stamp.fyi/avatar/eth:${profile.picture.uri}`
+ return undefined
+}
diff --git a/package.json b/package.json
index 5c3a0b86..ede8ea69 100644
--- a/package.json
+++ b/package.json
@@ -43,6 +43,8 @@
"@gelatonetwork/automate-sdk": "^2.14.0",
"@graphql-typed-document-node/core": "^3.2.0",
"@hookform/resolvers": "^3.1.1",
+ "@lens-protocol/react-web": "^1.3.0",
+ "@lens-protocol/wagmi": "^2.1.0",
"@lit-protocol/lit-node-client": "2.1.161",
"@livepeer/react": "^2.6.0",
"@moralisweb3/common-evm-utils": "^2.22.4",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 34002e8a..bc9b7c76 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,5 +1,9 @@
lockfileVersion: '6.0'
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
dependencies:
'@bgd-labs/aave-address-book':
specifier: ^1.30.0
@@ -19,6 +23,12 @@ dependencies:
'@hookform/resolvers':
specifier: ^3.1.1
version: 3.1.1(react-hook-form@7.43.9)
+ '@lens-protocol/react-web':
+ specifier: ^1.3.0
+ version: 1.3.0(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)(zod@3.21.4)
+ '@lens-protocol/wagmi':
+ specifier: ^2.1.0
+ version: 2.1.0(@lens-protocol/react-web@1.3.0)(ethers@5.7.2)(viem@1.0.0)(wagmi@1.3.10)
'@lit-protocol/lit-node-client':
specifier: 2.1.161
version: 2.1.161(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(react@18.2.0)
@@ -384,6 +394,11 @@ devDependencies:
packages:
+ /@aashutoshrathi/word-wrap@1.2.6:
+ resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
/@adraffy/ens-normalize@1.9.0:
resolution: {integrity: sha512-iowxq3U30sghZotgl4s/oJRci6WPBfNO5YYgk2cIOMCHr3LeGPcsZjCEr+33Q4N+oV3OABDAtA+pyvWjbvBifQ==}
@@ -410,6 +425,42 @@ packages:
leven: 3.1.0
dev: false
+ /@apollo/client@3.8.1(graphql@16.8.0)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-JGGj/9bdoLEqzatRikDeN8etseY5qeFAY0vSAx/Pd0ePNsaflKzHx6V2NZ0NsGkInq+9IXXX3RLVDf0EotizMA==}
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0
+ graphql-ws: ^5.5.5
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+ subscriptions-transport-ws: ^0.9.0 || ^0.11.0
+ peerDependenciesMeta:
+ graphql-ws:
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ subscriptions-transport-ws:
+ optional: true
+ dependencies:
+ '@graphql-typed-document-node/core': 3.2.0(graphql@16.8.0)
+ '@wry/context': 0.7.3
+ '@wry/equality': 0.5.6
+ '@wry/trie': 0.4.3
+ graphql: 16.8.0
+ graphql-tag: 2.12.6(graphql@16.8.0)
+ hoist-non-react-statics: 3.3.2
+ optimism: 0.17.5
+ prop-types: 15.8.1
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ response-iterator: 0.2.6
+ symbol-observable: 4.0.0
+ ts-invariant: 0.10.3
+ tslib: 2.5.0
+ zen-observable-ts: 1.2.5
+ dev: false
+
/@ardatan/fast-json-stringify@0.0.6(ajv-formats@2.1.1)(ajv@8.12.0):
resolution: {integrity: sha512-//BefMIP6U1ptNeBf44Le4vqThejTwZndtYLtAuFBwA/DmbVbbYTCLNIMhZ96WZnhI92EvTXneT5tKJrgINE9A==}
peerDependencies:
@@ -6441,6 +6492,251 @@ packages:
/@ledgerhq/connect-kit-loader@1.1.2:
resolution: {integrity: sha512-mscwGroSJQrCTjtNGBu+18FQbZYA4+q6Tyx6K7CXHl6AwgZKbWfZYdgP2F+fyZcRUdGRsMX8QtvU61VcGGtO1A==}
+ /@lens-protocol/api-bindings@0.10.0(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-CoILWFbVQWg7rfJUv1EINimrOG1MJpn413PlWFOILsXEQT4RiSp0JRPs752piog6DKQ4QJCaDld1fi/Haix/qg==}
+ peerDependencies:
+ '@faker-js/faker': ^7.6.0
+ react: ^18.2.0
+ peerDependenciesMeta:
+ '@faker-js/faker':
+ optional: true
+ dependencies:
+ '@apollo/client': 3.8.1(graphql@16.8.0)(react-dom@18.2.0)(react@18.2.0)
+ '@lens-protocol/domain': 0.10.0(ethers@5.7.2)
+ '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2)
+ graphql: 16.8.0
+ graphql-tag: 2.12.6(graphql@16.8.0)
+ react: 18.2.0
+ tslib: 2.5.0
+ transitivePeerDependencies:
+ - '@jest/globals'
+ - ethers
+ - graphql-ws
+ - jest-mock-extended
+ - jest-when
+ - react-dom
+ - subscriptions-transport-ws
+ - wait-for-expect
+ dev: false
+
+ /@lens-protocol/blockchain-bindings@0.9.1(ethers@5.7.2):
+ resolution: {integrity: sha512-dc06vo4nlbmL4lwwoSLGi6upo3sdON0wz3KUi6oknPhgoMKt6qIiAbyBfyyDgLIaLPOKEcxkoCg4rKtc7j+3Eg==}
+ peerDependencies:
+ ethers: ^5.7.2
+ dependencies:
+ '@ethersproject/abi': 5.7.0
+ '@ethersproject/providers': 5.7.2
+ '@lens-protocol/domain': 0.10.0(ethers@5.7.2)
+ '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2)
+ ethers: 5.7.2
+ tslib: 2.5.0
+ transitivePeerDependencies:
+ - '@faker-js/faker'
+ - '@jest/globals'
+ - bufferutil
+ - jest-mock-extended
+ - jest-when
+ - utf-8-validate
+ - wait-for-expect
+ dev: false
+
+ /@lens-protocol/domain@0.10.0(ethers@5.7.2):
+ resolution: {integrity: sha512-Au5a5BfOZDisRBxZ0w4pGqFp9ATf1iLo+haEcNwH11L8ssGVzZ3FLKK7jF1az4pliCt+gfwcAo83BQk8Hso2aQ==}
+ peerDependencies:
+ '@faker-js/faker': ^7.6.0
+ '@jest/globals': ^29.3.1
+ jest-mock-extended: ^3.0.1
+ jest-when: ^3.5.2
+ wait-for-expect: ^3.0.2
+ peerDependenciesMeta:
+ '@faker-js/faker':
+ optional: true
+ '@jest/globals':
+ optional: true
+ jest-mock-extended:
+ optional: true
+ jest-when:
+ optional: true
+ wait-for-expect:
+ optional: true
+ dependencies:
+ '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2)
+ tslib: 2.5.0
+ transitivePeerDependencies:
+ - ethers
+ dev: false
+
+ /@lens-protocol/gated-content@0.3.2(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)(zod@3.21.4):
+ resolution: {integrity: sha512-e6JnKMQZ+TfEMT0J9hhIhMFqPd2b3gHZbchQOsdempgt0sSCXYLXLp0FGoRlwtaAtDK+FqYVQXyYJEQZgCJv5w==}
+ peerDependencies:
+ '@ethersproject/contracts': ^5.7.0
+ '@ethersproject/hash': ^5.7.0
+ '@ethersproject/providers': ^5.7.2
+ '@ethersproject/wallet': ^5.7.0
+ ethers: ^5.7.2
+ zod: ^3.20.6
+ dependencies:
+ '@ethersproject/address': 5.7.0
+ '@ethersproject/bignumber': 5.7.0
+ '@ethersproject/contracts': 5.7.0
+ '@ethersproject/hash': 5.7.0
+ '@ethersproject/providers': 5.7.2
+ '@ethersproject/wallet': 5.7.0
+ '@lens-protocol/api-bindings': 0.10.0(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)
+ '@lens-protocol/domain': 0.10.0(ethers@5.7.2)
+ '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2)
+ '@lens-protocol/storage': 0.7.4(ethers@5.7.2)
+ '@lit-protocol/constants': 2.1.62
+ '@lit-protocol/crypto': 2.1.62
+ '@lit-protocol/encryption': 2.1.62
+ '@lit-protocol/node-client': 2.1.62(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)
+ '@lit-protocol/types': 2.1.62
+ ethers: 5.7.2
+ siwe: 1.1.6(ethers@5.7.2)
+ tslib: 2.5.0
+ zod: 3.21.4
+ transitivePeerDependencies:
+ - '@faker-js/faker'
+ - '@jest/globals'
+ - '@react-native-async-storage/async-storage'
+ - '@walletconnect/modal'
+ - bufferutil
+ - encoding
+ - graphql-ws
+ - jest-mock-extended
+ - jest-when
+ - lokijs
+ - react
+ - react-dom
+ - subscriptions-transport-ws
+ - utf-8-validate
+ - wait-for-expect
+ dev: false
+
+ /@lens-protocol/react-web@1.3.0(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)(zod@3.21.4):
+ resolution: {integrity: sha512-0ztmgGi6URjyX2hYujaJ+HH30gRsI4/Rgk3VviLTtNi1xmduECywEqFljUqZx8zIEndZs+bDpXPojCHhHmjdAQ==}
+ peerDependencies:
+ '@xmtp/react-sdk': 1.0.0-preview.40
+ ethers: ^5.7.2
+ react: ^18.2.0
+ peerDependenciesMeta:
+ '@xmtp/react-sdk':
+ optional: true
+ dependencies:
+ '@lens-protocol/api-bindings': 0.10.0(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)
+ '@lens-protocol/domain': 0.10.0(ethers@5.7.2)
+ '@lens-protocol/gated-content': 0.3.2(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)(zod@3.21.4)
+ '@lens-protocol/react': 1.3.0(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)
+ '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2)
+ '@lens-protocol/storage': 0.7.4(ethers@5.7.2)
+ ethers: 5.7.2
+ react: 18.2.0
+ tslib: 2.5.0
+ transitivePeerDependencies:
+ - '@ethersproject/contracts'
+ - '@ethersproject/hash'
+ - '@ethersproject/providers'
+ - '@ethersproject/wallet'
+ - '@faker-js/faker'
+ - '@jest/globals'
+ - '@react-native-async-storage/async-storage'
+ - '@walletconnect/modal'
+ - bufferutil
+ - encoding
+ - graphql-ws
+ - jest-mock-extended
+ - jest-when
+ - lokijs
+ - react-dom
+ - subscriptions-transport-ws
+ - utf-8-validate
+ - wait-for-expect
+ - zod
+ dev: false
+
+ /@lens-protocol/react@1.3.0(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-yrF79WMqmCe5yKpBXBmhhxuDrMszQljZT2gjWy3+zOg0EbktMCg69Z7wmEczOrk6CjSEL2GxW510fZ+8yaJNIQ==}
+ peerDependencies:
+ ethers: ^5.7.2
+ react: ^18.2.0
+ dependencies:
+ '@apollo/client': 3.8.1(graphql@16.8.0)(react-dom@18.2.0)(react@18.2.0)
+ '@ethersproject/abstract-signer': 5.7.0
+ '@ethersproject/providers': 5.7.2
+ '@lens-protocol/api-bindings': 0.10.0(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)
+ '@lens-protocol/blockchain-bindings': 0.9.1(ethers@5.7.2)
+ '@lens-protocol/domain': 0.10.0(ethers@5.7.2)
+ '@lens-protocol/gated-content': 0.3.2(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)(zod@3.21.4)
+ '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2)
+ '@lens-protocol/storage': 0.7.4(ethers@5.7.2)
+ ethers: 5.7.2
+ graphql: 16.8.0
+ jwt-decode: 3.1.2
+ lodash: 4.17.21
+ react: 18.2.0
+ tslib: 2.5.0
+ uuid: 9.0.0
+ zod: 3.21.4
+ transitivePeerDependencies:
+ - '@ethersproject/contracts'
+ - '@ethersproject/hash'
+ - '@ethersproject/wallet'
+ - '@faker-js/faker'
+ - '@jest/globals'
+ - '@react-native-async-storage/async-storage'
+ - '@walletconnect/modal'
+ - bufferutil
+ - encoding
+ - graphql-ws
+ - jest-mock-extended
+ - jest-when
+ - lokijs
+ - react-dom
+ - subscriptions-transport-ws
+ - utf-8-validate
+ - wait-for-expect
+ dev: false
+
+ /@lens-protocol/shared-kernel@0.10.0(ethers@5.7.2):
+ resolution: {integrity: sha512-I8WSYI39ALB9dMZOYKb6pmnaKPkEaoXI73G8dZ0ghQRoV7AkWu8a2RrPYuoCq1VIFwQElCL9AmCjuLHTQkOeuQ==}
+ peerDependencies:
+ ethers: ^5.7.2
+ peerDependenciesMeta:
+ ethers:
+ optional: true
+ dependencies:
+ decimal.js: 10.4.3
+ ethers: 5.7.2
+ lodash: 4.17.21
+ tslib: 2.5.0
+ uuid: 9.0.0
+ dev: false
+
+ /@lens-protocol/storage@0.7.4(ethers@5.7.2):
+ resolution: {integrity: sha512-ezr44IhhcF3OEgJrqCmeOUX1p+UMYhU1sv6ua8AqbpTJZT33nPhXbyiXOYjtPTXi2VZJZPBpKU8rpkixrEgXTA==}
+ dependencies:
+ '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2)
+ tslib: 2.5.0
+ zod: 3.21.4
+ transitivePeerDependencies:
+ - ethers
+ dev: false
+
+ /@lens-protocol/wagmi@2.1.0(@lens-protocol/react-web@1.3.0)(ethers@5.7.2)(viem@1.0.0)(wagmi@1.3.10):
+ resolution: {integrity: sha512-TpwZjaY8xegyA/Waj8ABxRCmkhz7rcyctSK8NO5+akQ67AVfzn8yhBqNep5Wx4HJokiCRKA8XmSi9md7dNDkLA==}
+ peerDependencies:
+ '@lens-protocol/react-web': 1.3.0
+ ethers: ^5.7.2
+ viem: ^1.0.0
+ wagmi: ^1.1.0
+ dependencies:
+ '@lens-protocol/react-web': 1.3.0(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)(zod@3.21.4)
+ '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2)
+ ethers: 5.7.2
+ viem: 1.0.0(typescript@5.0.4)(zod@3.21.4)
+ wagmi: 1.3.10(react-dom@18.2.0)(react-native@0.72.4)(react@18.2.0)(typescript@5.0.4)(viem@1.0.0)(zod@3.21.4)
+ dev: false
+
/@lit-labs/ssr-dom-shim@1.1.1:
resolution: {integrity: sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ==}
@@ -6458,6 +6754,20 @@ packages:
- utf-8-validate
dev: false
+ /@lit-protocol/access-control-conditions@2.1.62:
+ resolution: {integrity: sha512-nP+iqiLUzQa6bfZL9hM9a+s+YVW21HoHkHP7s2E11VFQmucdnJmUUr7Aw46SK/4yClTjLb6RuHyfIPvCdmIKhQ==}
+ dependencies:
+ '@lit-protocol/constants': 2.1.62
+ '@lit-protocol/misc': 2.1.62
+ '@lit-protocol/types': 2.1.62
+ '@lit-protocol/uint8arrays': 2.1.62
+ ethers: 5.7.2
+ tslib: 2.5.0
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+ dev: false
+
/@lit-protocol/auth-browser@2.1.161(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(react@18.2.0):
resolution: {integrity: sha512-QdUzRLjziMJtjLtBQkaRhmhn8T1EiqKTyPWyoyzx9/5WFpaRYc0TmMbK/EidcG68YGObTDEuy2r/XZ3lGr/fcg==}
dependencies:
@@ -6490,10 +6800,44 @@ packages:
- utf-8-validate
dev: false
+ /@lit-protocol/auth-browser@2.1.62(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0):
+ resolution: {integrity: sha512-/4BTl0omR+JUCyJJc93FCiygSn/4ldrbeBuzWYQzuOFh2f6fcY1GJe3ttEoSJUfwu7OblW86YpWAT65b56rACA==}
+ dependencies:
+ '@lit-protocol/constants': 2.1.62
+ '@lit-protocol/misc': 2.1.62
+ '@lit-protocol/misc-browser': 2.1.62
+ '@lit-protocol/types': 2.1.62
+ '@lit-protocol/uint8arrays': 2.1.62
+ '@walletconnect/ethereum-provider': 2.9.2(@walletconnect/modal@2.6.1)
+ ethers: 5.7.2
+ lit-connect-modal: 0.1.11
+ lit-siwe: 1.1.8(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)
+ tslib: 2.5.0
+ tweetnacl: 1.0.3
+ tweetnacl-util: 0.13.5
+ util: 0.12.5
+ web-vitals: 3.3.1
+ transitivePeerDependencies:
+ - '@ethersproject/contracts'
+ - '@ethersproject/hash'
+ - '@ethersproject/providers'
+ - '@ethersproject/wallet'
+ - '@react-native-async-storage/async-storage'
+ - '@walletconnect/modal'
+ - bufferutil
+ - encoding
+ - lokijs
+ - utf-8-validate
+ dev: false
+
/@lit-protocol/bls-sdk@2.1.161:
resolution: {integrity: sha512-+ubypaILDWjZejtsyHCeuEGbiMIX6PXKEw9uTMM7wV4PCOTtwUixsaGZr8/+xM6ivGnowO3e80hKKCR3gpXhaA==}
dev: false
+ /@lit-protocol/bls-sdk@2.1.62:
+ resolution: {integrity: sha512-UjNjycoNXOEoLH/foIJx1L9PLL5OxmHcCD/mFXr4KSeQV/v4srvGNpY/4ng7+k9sJEbvwRwv+FB07ng3/Ihacg==}
+ dev: false
+
/@lit-protocol/constants@2.1.161:
resolution: {integrity: sha512-91Rs01/BmRdi7YYmwqkaqI7TYOxhldpLIf5nLBaAQNZloijdF073KbXa9dFZtVbTo3c8fG5O6ts6DOQLK7mSKA==}
dependencies:
@@ -6501,6 +6845,13 @@ packages:
tslib: 2.5.0
dev: false
+ /@lit-protocol/constants@2.1.62:
+ resolution: {integrity: sha512-4CigP3GS7Cxpa9RXT1twCCvYI5wvfo1UAMbdrjoDgM9VMDtpvSrmlG8AwC9yMoqPM6409BYcgGI9LDGzUjNUjg==}
+ dependencies:
+ '@lit-protocol/types': 2.1.62
+ tslib: 2.5.0
+ dev: false
+
/@lit-protocol/crypto@2.1.161:
resolution: {integrity: sha512-0ntmjz1jdFqGgng7jomHMHt/aW2Ov9tOrKCQ/8phy1x3hkTL2o336vkMU7H+3UbpOt2wryHrobcFyP82ZLm/qQ==}
dependencies:
@@ -6518,10 +6869,31 @@ packages:
- utf-8-validate
dev: false
+ /@lit-protocol/crypto@2.1.62:
+ resolution: {integrity: sha512-pWte+VQOPmSFvfoMxvobmj5JjkGSD44XMkkTXGubpGTBr27hK9CuDxpVHTsI9NsGFSJRdPBpRou+YD5I22yDiA==}
+ dependencies:
+ '@lit-protocol/bls-sdk': 2.1.62
+ '@lit-protocol/constants': 2.1.62
+ '@lit-protocol/ecdsa-sdk': 2.1.62
+ '@lit-protocol/misc': 2.1.62
+ '@lit-protocol/nacl': 2.1.62
+ '@lit-protocol/types': 2.1.62
+ '@lit-protocol/uint8arrays': 2.1.62
+ ethers: 5.7.2
+ tslib: 2.5.0
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+ dev: false
+
/@lit-protocol/ecdsa-sdk@2.1.161:
resolution: {integrity: sha512-UuZvzCEYnoXflJItwmDATDc60H1dH+z8J8iW3rAkPbxYcwCBSbVSo4aUel2Y9Vf9/uaBtm1xSjeWnBv6PBVFWw==}
dev: false
+ /@lit-protocol/ecdsa-sdk@2.1.62:
+ resolution: {integrity: sha512-VWYAQh31e5Vu6YXvw7iDQja/f2Je6Obj8VoXLweWWfSpUnKqe1JJKGDLxOAuQUT3ZSaX7bYrq7hLIJdwdWmJQw==}
+ dev: false
+
/@lit-protocol/encryption@2.1.161(node-fetch@2.6.9):
resolution: {integrity: sha512-O8ZiZtjzrXvBY8OuRyOviAQ1VK3Lsmh1G5qAovGwB1Za8fshGB2mTR4PBlQ7Zf2rb+qlxC7220sZ8Y20UtCd5A==}
dependencies:
@@ -6545,6 +6917,25 @@ packages:
- utf-8-validate
dev: false
+ /@lit-protocol/encryption@2.1.62:
+ resolution: {integrity: sha512-Nmte/UINgc+YVlA3RewhW+1SFnKcSikd94HlBxS+TX9yb2KBUO6oKNjTQSGX4P/KD3zBxaFlbY8+jrWeYR1aQQ==}
+ dependencies:
+ '@lit-protocol/bls-sdk': 2.1.62
+ '@lit-protocol/constants': 2.1.62
+ '@lit-protocol/crypto': 2.1.62
+ '@lit-protocol/ecdsa-sdk': 2.1.62
+ '@lit-protocol/misc': 2.1.62
+ '@lit-protocol/nacl': 2.1.62
+ '@lit-protocol/types': 2.1.62
+ '@lit-protocol/uint8arrays': 2.1.62
+ ethers: 5.7.2
+ jszip: 3.10.1
+ tslib: 2.5.0
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+ dev: false
+
/@lit-protocol/lit-node-client-nodejs@2.1.161(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0):
resolution: {integrity: sha512-mQR56sh0rZF7XxmuQphPrx4hBB+rHY7sneDhdp6ZCxbUcM7NWRbz5h+idn8Ln49E6qXHplFCyp2dWqrwF0vr9w==}
dependencies:
@@ -6633,6 +7024,10 @@ packages:
resolution: {integrity: sha512-TwO+nKCL2CC8L4O7ypJ06RvBmSXntL+Yrfr+Bqj/d1xhVOB+RwohMoF8lyP6zvQokcKZqar+uPgu/hiaQhIlJw==}
dev: false
+ /@lit-protocol/lit-third-party-libs@2.1.62:
+ resolution: {integrity: sha512-js8Z3uG4v30Dw9HNqnjxkzMcB3cp3UcF6tfsWGo99+g5OqqKnkCDbb4IXeqnGbslVPn6ll6XouRQPmCcuzeGaw==}
+ dev: false
+
/@lit-protocol/misc-browser@2.1.161:
resolution: {integrity: sha512-FpN5N+jSff9r3WoH/H7Es/MX0nwnYqmOL1Zfg1HWHlTXbUV8ROg7QX3UPQWLFFF1nGLw649+OgN+bkXdDTG7fg==}
dependencies:
@@ -6647,6 +7042,20 @@ packages:
- utf-8-validate
dev: false
+ /@lit-protocol/misc-browser@2.1.62:
+ resolution: {integrity: sha512-2NX//tUe5ChrWCN4Msi4RE8DlYjTMGqyPYJHS86r7nKHG7sHSPCucn84LiTmVGA3DVKzspeGJdMbEF/W8Ogn6w==}
+ dependencies:
+ '@lit-protocol/constants': 2.1.62
+ '@lit-protocol/misc': 2.1.62
+ '@lit-protocol/types': 2.1.62
+ '@lit-protocol/uint8arrays': 2.1.62
+ ethers: 5.7.2
+ tslib: 2.5.0
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+ dev: false
+
/@lit-protocol/misc@2.1.161:
resolution: {integrity: sha512-wA927QjBfTEtpXglsduB1QTadIdzl/ELytRO+UzilQwQOGwSr7I/jp9giJU8WKoeFHQZuZYREQvBRxyocu1quw==}
dependencies:
@@ -6655,18 +7064,76 @@ packages:
tslib: 2.5.0
dev: false
+ /@lit-protocol/misc@2.1.62:
+ resolution: {integrity: sha512-i6A/kxiJQgy8BZJGH7H8V2kxqOA2xboAjH2BzAbE/pMezfHG7wybkXT9cnXnXOZsAnuGnOKd93u+j7bskuDd2w==}
+ dependencies:
+ '@lit-protocol/constants': 2.1.62
+ '@lit-protocol/types': 2.1.62
+ tslib: 2.5.0
+ dev: false
+
/@lit-protocol/nacl@2.1.161:
resolution: {integrity: sha512-FrbhM1J/SkMGZqOenW+Fm3lSHLiOUFvorU+rwG6PzOokgRWk+PSp2ZVsFT2xfM6dg527eq6L5IL5asRVZX9zZg==}
dev: false
+ /@lit-protocol/nacl@2.1.62:
+ resolution: {integrity: sha512-0v9fa6Sd4xphjlYMZ9L8TTyR7G4YLvp323E8OJ76giuaPla4HXuwSiGMzUOaC6NKraArSrd54CKkHJ/bxEqVDA==}
+ dev: false
+
+ /@lit-protocol/node-client@2.1.62(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0):
+ resolution: {integrity: sha512-rLEUleDoJ+AATZfWNWXvy7UdSrUXMyCjpyB5bevVfk9YjIa5rd9BBXdFENCIA+9kLgVOgtND/R1PpEI/vZkMmw==}
+ dependencies:
+ '@lit-protocol/access-control-conditions': 2.1.62
+ '@lit-protocol/auth-browser': 2.1.62(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)
+ '@lit-protocol/bls-sdk': 2.1.62
+ '@lit-protocol/constants': 2.1.62
+ '@lit-protocol/crypto': 2.1.62
+ '@lit-protocol/ecdsa-sdk': 2.1.62
+ '@lit-protocol/encryption': 2.1.62
+ '@lit-protocol/lit-third-party-libs': 2.1.62
+ '@lit-protocol/misc': 2.1.62
+ '@lit-protocol/misc-browser': 2.1.62
+ '@lit-protocol/nacl': 2.1.62
+ '@lit-protocol/types': 2.1.62
+ '@lit-protocol/uint8arrays': 2.1.62
+ '@walletconnect/ethereum-provider': 2.9.2(@walletconnect/modal@2.6.1)
+ ethers: 5.7.2
+ jszip: 3.10.1
+ lit-connect-modal: 0.1.11
+ lit-siwe: 1.1.8(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)
+ node-fetch: 2.6.12
+ tslib: 2.5.0
+ tweetnacl: 1.0.3
+ tweetnacl-util: 0.15.1
+ transitivePeerDependencies:
+ - '@ethersproject/contracts'
+ - '@ethersproject/hash'
+ - '@ethersproject/providers'
+ - '@ethersproject/wallet'
+ - '@react-native-async-storage/async-storage'
+ - '@walletconnect/modal'
+ - bufferutil
+ - encoding
+ - lokijs
+ - utf-8-validate
+ dev: false
+
/@lit-protocol/types@2.1.161:
resolution: {integrity: sha512-d/PGjmuREERHghcxGOnq4SA0ivX8e3tta7eXEKKV7FfsUXW6fNsSfwaDRKUK3FtlhaRvKtdlatrrZP4emG1WSA==}
dev: false
+ /@lit-protocol/types@2.1.62:
+ resolution: {integrity: sha512-DoIOmbI+Bg3zLWzqx4fLv1vW3k1sbDof/fxslHsLt5aX/MXHSZVKTJb+jWgNVcQ4ba+YLqgoKaPb1i58DMvCPw==}
+ dev: false
+
/@lit-protocol/uint8arrays@2.1.161:
resolution: {integrity: sha512-EjW6mn9+DzI27lUV/1vyUoZV59hOJwKQ7UkjUdPDouW7EOcMhvpScYhgsYEx67Zv0hiiP8XWLBiDGZD4U2qVvg==}
dev: false
+ /@lit-protocol/uint8arrays@2.1.62:
+ resolution: {integrity: sha512-Q9Leppzyb9Y2jwe+i8btAUkTXqgnu21PFql83v6N70dkELSC+fKBzRSRqUpFqruW7dcrG8mNWsOCQbQ0kL/w/w==}
+ dev: false
+
/@lit/reactive-element@1.6.1:
resolution: {integrity: sha512-va15kYZr7KZNNPZdxONGQzpUr+4sxVu7V/VG7a8mRfPPXUyhEYj5RzXCQmGrlP3tAh0L3HHm5AjBMFYRqlM9SA==}
dependencies:
@@ -6773,7 +7240,7 @@ packages:
'@ethereumjs/block': 3.6.3
ethereumjs-util: 7.1.5
merkle-patricia-tree: 4.2.4
- node-fetch: 2.6.9
+ node-fetch: 2.6.12
transitivePeerDependencies:
- encoding
dev: false
@@ -6785,7 +7252,7 @@ packages:
'@ethereumjs/block': 3.6.3
ethereumjs-util: 7.1.5
merkle-patricia-tree: 4.2.4
- node-fetch: 2.6.9
+ node-fetch: 2.6.12
transitivePeerDependencies:
- encoding
dev: false
@@ -10844,8 +11311,8 @@ packages:
resolution: {integrity: sha512-xUeFPpElybgn1a+lknqtHleei4VyuV/4qWgB1nP8qQUAO6a5pNsioODrnB2VAPdUHJYBdx2dCt2maRk6g53IPQ==}
dependencies:
'@walletconnect/heartbeat': 1.2.1
- '@walletconnect/jsonrpc-provider': 1.0.12
- '@walletconnect/jsonrpc-utils': 1.0.7
+ '@walletconnect/jsonrpc-provider': 1.0.13
+ '@walletconnect/jsonrpc-utils': 1.0.8
'@walletconnect/jsonrpc-ws-connection': 1.0.11
'@walletconnect/keyvaluestorage': 1.0.2
'@walletconnect/logger': 2.0.1
@@ -11045,6 +11512,7 @@ packages:
dependencies:
keyvaluestorage-interface: 1.0.0
tslib: 1.14.1
+ dev: false
/@walletconnect/jsonrpc-types@1.0.3:
resolution: {integrity: sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw==}
@@ -11070,7 +11538,7 @@ packages:
/@walletconnect/jsonrpc-ws-connection@1.0.11:
resolution: {integrity: sha512-TiFJ6saasKXD+PwGkm5ZGSw0837nc6EeFmurSPgIT/NofnOV4Tv7CVJqGQN0rQYoJUSYu21cwHNYaFkzNpUN+w==}
dependencies:
- '@walletconnect/jsonrpc-utils': 1.0.7
+ '@walletconnect/jsonrpc-utils': 1.0.8
'@walletconnect/safe-json': 1.0.2
events: 3.3.0
tslib: 1.14.1
@@ -11200,7 +11668,7 @@ packages:
/@walletconnect/relay-api@1.0.9:
resolution: {integrity: sha512-Q3+rylJOqRkO1D9Su0DPE3mmznbAalYapJ9qmzDgK28mYF9alcP3UwG/og5V7l7CFOqzCLi7B8BvcBUrpDj0Rg==}
dependencies:
- '@walletconnect/jsonrpc-types': 1.0.2
+ '@walletconnect/jsonrpc-types': 1.0.3
tslib: 1.14.1
/@walletconnect/relay-auth@1.0.4:
@@ -11617,6 +12085,27 @@ packages:
tslib: 2.5.0
dev: true
+ /@wry/context@0.7.3:
+ resolution: {integrity: sha512-Nl8WTesHp89RF803Se9X3IiHjdmLBrIvPMaJkl+rKVJAYyPsz1TEUbu89943HpvujtSJgDUx9W4vZw3K1Mr3sA==}
+ engines: {node: '>=8'}
+ dependencies:
+ tslib: 2.5.0
+ dev: false
+
+ /@wry/equality@0.5.6:
+ resolution: {integrity: sha512-D46sfMTngaYlrH+OspKf8mIJETntFnf6Hsjb0V41jAXJ7Bx2kB8Rv8RCUujuVWYttFtHkUNp7g+FwxNQAr6mXA==}
+ engines: {node: '>=8'}
+ dependencies:
+ tslib: 2.5.0
+ dev: false
+
+ /@wry/trie@0.4.3:
+ resolution: {integrity: sha512-I6bHwH0fSf6RqQcnnXLJKhkSXG45MFral3GxPaY4uAl0LYDZM+YDVDAiU9bYwjTuysy1S0IeecWtmq1SZA3M1w==}
+ engines: {node: '>=8'}
+ dependencies:
+ tslib: 2.5.0
+ dev: false
+
/@xtuc/ieee754@1.2.0:
resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
dev: false
@@ -13856,6 +14345,10 @@ packages:
engines: {node: '>=10'}
dev: false
+ /decimal.js@10.4.3:
+ resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==}
+ dev: false
+
/decode-named-character-reference@1.0.2:
resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==}
dependencies:
@@ -16308,7 +16801,6 @@ packages:
dependencies:
graphql: 16.8.0
tslib: 2.5.0
- dev: true
/graphql-ws@5.12.1(graphql@16.8.0):
resolution: {integrity: sha512-umt4f5NnMK46ChM2coO36PTFhHouBrK9stWWBczERguwYrGnPNxJ9dimU6IyOBfOkC6Izhkg4H8+F51W/8CYDg==}
@@ -17027,8 +17519,8 @@ packages:
it-to-stream: 1.0.0
merge-options: 3.0.4
nanoid: 3.3.6
- native-fetch: 3.0.0(node-fetch@2.6.9)
- node-fetch: 2.6.9
+ native-fetch: 3.0.0(node-fetch@2.6.12)
+ node-fetch: 2.6.12
react-native-fetch-api: 3.0.0
stream-to-it: 0.2.4
transitivePeerDependencies:
@@ -17986,6 +18478,10 @@ packages:
resolution: {integrity: sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==}
dev: false
+ /jwt-decode@3.1.2:
+ resolution: {integrity: sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==}
+ dev: false
+
/keccak@3.0.3:
resolution: {integrity: sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==}
engines: {node: '>=10.0.0'}
@@ -19786,6 +20282,14 @@ packages:
resolution: {integrity: sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==}
dev: false
+ /native-fetch@3.0.0(node-fetch@2.6.12):
+ resolution: {integrity: sha512-G3Z7vx0IFb/FQ4JxvtqGABsOTIqRWvgQz6e+erkB+JJD6LrszQtMozEHI4EkmgZQvnGHrpLVzUWk7t4sJCIkVw==}
+ peerDependencies:
+ node-fetch: '*'
+ dependencies:
+ node-fetch: 2.6.12
+ dev: false
+
/native-fetch@3.0.0(node-fetch@2.6.9):
resolution: {integrity: sha512-G3Z7vx0IFb/FQ4JxvtqGABsOTIqRWvgQz6e+erkB+JJD6LrszQtMozEHI4EkmgZQvnGHrpLVzUWk7t4sJCIkVw==}
peerDependencies:
@@ -20228,10 +20732,19 @@ packages:
asn1.js: 5.4.1
dev: false
+ /optimism@0.17.5:
+ resolution: {integrity: sha512-TEcp8ZwK1RczmvMnvktxHSF2tKgMWjJ71xEFGX5ApLh67VsMSTy1ZUlipJw8W+KaqgOmQ+4pqwkeivY89j+4Vw==}
+ dependencies:
+ '@wry/context': 0.7.3
+ '@wry/trie': 0.4.3
+ tslib: 2.5.0
+ dev: false
+
/optionator@0.9.1:
resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==}
engines: {node: '>= 0.8.0'}
dependencies:
+ '@aashutoshrathi/word-wrap': 1.2.6
deep-is: 0.1.4
fast-levenshtein: 2.0.6
levn: 0.4.1
@@ -21153,7 +21666,7 @@ packages:
bl: 5.1.0
debug: 4.3.4(supports-color@5.5.0)
minimist: 1.2.8
- node-fetch: 2.6.9
+ node-fetch: 2.6.12
readable-stream: 3.6.2
transitivePeerDependencies:
- encoding
@@ -21789,6 +22302,11 @@ packages:
supports-preserve-symlinks-flag: 1.0.0
dev: true
+ /response-iterator@0.2.6:
+ resolution: {integrity: sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw==}
+ engines: {node: '>=0.8'}
+ dev: false
+
/responselike@2.0.1:
resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==}
dependencies:
@@ -22837,6 +23355,11 @@ packages:
engines: {node: '>=0.10'}
dev: false
+ /symbol-observable@4.0.0:
+ resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==}
+ engines: {node: '>=0.10'}
+ dev: false
+
/synckit@0.8.5:
resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==}
engines: {node: ^14.18.0 || >=16.0.0}
@@ -23119,6 +23642,13 @@ packages:
/ts-interface-checker@0.1.13:
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+ /ts-invariant@0.10.3:
+ resolution: {integrity: sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ tslib: 2.5.0
+ dev: false
+
/ts-log@2.2.5:
resolution: {integrity: sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==}
dev: true
@@ -24758,6 +25288,16 @@ packages:
engines: {node: '>=12.20'}
dev: true
+ /zen-observable-ts@1.2.5:
+ resolution: {integrity: sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==}
+ dependencies:
+ zen-observable: 0.8.15
+ dev: false
+
+ /zen-observable@0.8.15:
+ resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==}
+ dev: false
+
/zod-to-json-schema@3.21.4(zod@3.21.4):
resolution: {integrity: sha512-fjUZh4nQ1s6HMccgIeE0VP4QG/YRGPmyjO9sAh890aQKPEk3nqbfUXhMFaC+Dr5KvYBm8BCyvfpZf2jY9aGSsw==}
peerDependencies:
diff --git a/public/integrations/lensprotocol-dark.svg b/public/integrations/lensprotocol-dark.svg
new file mode 100644
index 00000000..e8733fae
--- /dev/null
+++ b/public/integrations/lensprotocol-dark.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/integrations/lensprotocol-light.svg b/public/integrations/lensprotocol-light.svg
new file mode 100644
index 00000000..bca241f5
--- /dev/null
+++ b/public/integrations/lensprotocol-light.svg
@@ -0,0 +1,3 @@
+