The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .github
    ├── CODEOWNERS
    ├── CODE_OF_CONDUCT.md
    ├── CONTRIBUTING.md
    ├── FUNDING.yml
    ├── ISSUE_TEMPLATE
    │   ├── bug_report.yml
    │   └── feature_request.yml
    ├── PULL_REQUEST_TEMPLATE.md
    ├── SECURITY.md
    ├── actions
    │   └── docker
    │   │   └── action.yml
    └── workflows
    │   ├── cd.yml
    │   └── ci.yml
├── .gitignore
├── .husky
    └── pre-commit
├── .npmrc
├── .nvmrc
├── .vscode
    ├── extensions.json
    └── settings.json
├── LICENSE
├── README.md
├── apps
    ├── api
    │   ├── .env.example
    │   ├── .gitignore
    │   ├── Dockerfile
    │   ├── README.md
    │   ├── env.d.ts
    │   ├── package.json
    │   ├── src
    │   │   ├── helpers
    │   │   │   ├── did
    │   │   │   │   └── resolverAbi.ts
    │   │   │   ├── oembed
    │   │   │   │   ├── constructIframe.ts
    │   │   │   │   ├── extractOgTags.ts
    │   │   │   │   └── regex.ts
    │   │   │   └── tower
    │   │   │   │   └── checkEventExistence.ts
    │   │   ├── index.ts
    │   │   ├── middlewares.ts
    │   │   └── routes
    │   │   │   ├── allowed-tokens.ts
    │   │   │   ├── avatar.ts
    │   │   │   ├── curated.ts
    │   │   │   ├── did.ts
    │   │   │   ├── gateway.ts
    │   │   │   ├── metadata.ts
    │   │   │   ├── oembed.ts
    │   │   │   ├── rates.ts
    │   │   │   ├── stats.ts
    │   │   │   ├── sts.ts
    │   │   │   ├── tail.ts
    │   │   │   ├── toggles.ts
    │   │   │   ├── tower.ts
    │   │   │   ├── trails.ts
    │   │   │   └── verified.ts
    │   └── tsconfig.json
    ├── contracts
    │   ├── .env.example
    │   ├── .gitignore
    │   ├── README.md
    │   ├── contracts
    │   │   └── TapePermissionlessCreator.sol
    │   ├── env.d.ts
    │   ├── hardhat.config.ts
    │   ├── package.json
    │   ├── scripts
    │   │   └── deploy.ts
    │   └── tsconfig.json
    ├── cron
    │   ├── .env.example
    │   ├── Dockerfile
    │   ├── README.md
    │   ├── env.d.ts
    │   ├── package.json
    │   ├── src
    │   │   ├── index.ts
    │   │   └── services
    │   │   │   ├── backup
    │   │   │       ├── events.ts
    │   │   │       └── trails.ts
    │   │   │   ├── cleanup.ts
    │   │   │   ├── curate.ts
    │   │   │   ├── stats.ts
    │   │   │   ├── tower.ts
    │   │   │   ├── trails.ts
    │   │   │   └── wake.ts
    │   └── tsconfig.json
    ├── embed
    │   ├── next.config.js
    │   ├── package.json
    │   ├── postcss.config.mjs
    │   ├── src
    │   │   ├── app
    │   │   │   ├── [pubId]
    │   │   │   │   └── page.tsx
    │   │   │   ├── favicon.ico
    │   │   │   ├── globals.css
    │   │   │   └── layout.tsx
    │   │   ├── components
    │   │   │   ├── Custom404.tsx
    │   │   │   ├── Publication.tsx
    │   │   │   ├── TopOverlay.tsx
    │   │   │   └── Video.tsx
    │   │   └── tower.ts
    │   ├── tailwind.config.ts
    │   └── tsconfig.json
    ├── mobile
    │   ├── .gitignore
    │   ├── app.json
    │   ├── app
    │   │   ├── (protected)
    │   │   │   ├── (feed)
    │   │   │   │   ├── _layout.tsx
    │   │   │   │   └── index.tsx
    │   │   │   ├── +not-found.tsx
    │   │   │   ├── _layout.tsx
    │   │   │   ├── create.tsx
    │   │   │   └── watch
    │   │   │   │   └── [id].tsx
    │   │   └── _layout.tsx
    │   ├── assets
    │   │   ├── fonts
    │   │   │   ├── sans-b.ttf
    │   │   │   ├── sans-m.ttf
    │   │   │   ├── sans-sb.ttf
    │   │   │   ├── sans.ttf
    │   │   │   └── serif.ttf
    │   │   └── images
    │   │   │   ├── adaptive-icon.png
    │   │   │   ├── auth-el.png
    │   │   │   ├── icon.png
    │   │   │   └── splash.png
    │   ├── babel.config.js
    │   ├── components
    │   │   ├── auth
    │   │   │   ├── background.tsx
    │   │   │   ├── instructions.tsx
    │   │   │   ├── profile.tsx
    │   │   │   ├── queries.ts
    │   │   │   ├── scan.tsx
    │   │   │   └── screen.tsx
    │   │   ├── create
    │   │   │   ├── controls.tsx
    │   │   │   └── screen.tsx
    │   │   ├── feed
    │   │   │   ├── actions.tsx
    │   │   │   ├── header.tsx
    │   │   │   ├── item.tsx
    │   │   │   ├── list.tsx
    │   │   │   ├── media.tsx
    │   │   │   ├── queries.ts
    │   │   │   └── video.tsx
    │   │   ├── providers
    │   │   │   ├── net-info.tsx
    │   │   │   └── react-query.tsx
    │   │   ├── shared
    │   │   │   ├── edge-gradient.tsx
    │   │   │   └── external-link.tsx
    │   │   ├── ui
    │   │   │   ├── animated-button.tsx
    │   │   │   └── render-markdown.tsx
    │   │   └── watch
    │   │   │   ├── publication.tsx
    │   │   │   └── queries.ts
    │   ├── eas.json
    │   ├── helpers
    │   │   ├── colors.ts
    │   │   ├── date-time.ts
    │   │   ├── execute.ts
    │   │   ├── haptics.ts
    │   │   ├── normalize-font.ts
    │   │   ├── refresh.ts
    │   │   └── style-atoms.ts
    │   ├── metro.config.js
    │   ├── package.json
    │   ├── store
    │   │   ├── auth.tsx
    │   │   ├── device.tsx
    │   │   └── profile.tsx
    │   └── tsconfig.json
    ├── og
    │   ├── .dockerignore
    │   ├── .gitignore
    │   ├── Dockerfile
    │   ├── next.config.mjs
    │   ├── package.json
    │   ├── src
    │   │   ├── app
    │   │   │   ├── favicon.ico
    │   │   │   ├── layout.tsx
    │   │   │   ├── u
    │   │   │   │   └── [handle]
    │   │   │   │   │   └── page.tsx
    │   │   │   └── watch
    │   │   │   │   └── [id]
    │   │   │   │       └── page.tsx
    │   │   ├── common.ts
    │   │   └── other-metadata.ts
    │   └── tsconfig.json
    ├── web-vite
    │   ├── index.html
    │   ├── package.json
    │   ├── public
    │   │   ├── fonts
    │   │   │   ├── mono.woff2
    │   │   │   ├── sans.woff2
    │   │   │   └── serif.woff2
    │   │   └── images
    │   │   │   └── hero.webp
    │   ├── src
    │   │   ├── components
    │   │   │   ├── create
    │   │   │   │   ├── advanced.tsx
    │   │   │   │   ├── category.tsx
    │   │   │   │   ├── details.tsx
    │   │   │   │   ├── drag-and-drop.ts
    │   │   │   │   ├── drop-zone.tsx
    │   │   │   │   ├── page.tsx
    │   │   │   │   ├── preview.tsx
    │   │   │   │   └── suggested-thumbnails.tsx
    │   │   │   ├── embed
    │   │   │   │   ├── page.tsx
    │   │   │   │   ├── post.tsx
    │   │   │   │   └── top.tsx
    │   │   │   ├── explore
    │   │   │   │   └── page.tsx
    │   │   │   ├── feed
    │   │   │   │   ├── byte.tsx
    │   │   │   │   └── page.tsx
    │   │   │   ├── following
    │   │   │   │   └── page.tsx
    │   │   │   ├── home
    │   │   │   │   ├── about.tsx
    │   │   │   │   ├── bytes.tsx
    │   │   │   │   ├── curated.tsx
    │   │   │   │   ├── feed.tsx
    │   │   │   │   ├── hero.tsx
    │   │   │   │   ├── invite.tsx
    │   │   │   │   ├── page.tsx
    │   │   │   │   ├── trending.tsx
    │   │   │   │   └── users.tsx
    │   │   │   ├── mod
    │   │   │   │   ├── page.tsx
    │   │   │   │   └── posts.tsx
    │   │   │   ├── open
    │   │   │   │   ├── middle-grid-item.tsx
    │   │   │   │   ├── page.tsx
    │   │   │   │   └── queries.ts
    │   │   │   ├── privacy
    │   │   │   │   └── page.tsx
    │   │   │   ├── settings
    │   │   │   │   ├── me.tsx
    │   │   │   │   └── sidebar.tsx
    │   │   │   ├── shared
    │   │   │   │   ├── auth
    │   │   │   │   │   ├── authenticate.tsx
    │   │   │   │   │   ├── connect-wallet.tsx
    │   │   │   │   │   ├── create-account.tsx
    │   │   │   │   │   ├── frame.tsx
    │   │   │   │   │   └── links.tsx
    │   │   │   │   ├── floating-nav.tsx
    │   │   │   │   ├── footer
    │   │   │   │   │   ├── index.tsx
    │   │   │   │   │   ├── links.tsx
    │   │   │   │   │   ├── network.tsx
    │   │   │   │   │   ├── socials.tsx
    │   │   │   │   │   └── status.tsx
    │   │   │   │   ├── header
    │   │   │   │   │   ├── accounts.tsx
    │   │   │   │   │   ├── index.tsx
    │   │   │   │   │   ├── left.tsx
    │   │   │   │   │   ├── logo.tsx
    │   │   │   │   │   ├── notifications
    │   │   │   │   │   │   ├── followed.tsx
    │   │   │   │   │   │   └── index.tsx
    │   │   │   │   │   ├── right.tsx
    │   │   │   │   │   └── user-menu.tsx
    │   │   │   │   ├── horizontal-view.tsx
    │   │   │   │   ├── search
    │   │   │   │   │   ├── index.tsx
    │   │   │   │   │   ├── input.tsx
    │   │   │   │   │   └── results.tsx
    │   │   │   │   ├── shimmers
    │   │   │   │   │   └── button.tsx
    │   │   │   │   ├── tape-svg.tsx
    │   │   │   │   ├── video-card.tsx
    │   │   │   │   └── virtualized.tsx
    │   │   │   ├── sign-in
    │   │   │   │   └── page.tsx
    │   │   │   ├── sign-up
    │   │   │   │   └── page.tsx
    │   │   │   ├── terms
    │   │   │   │   └── page.tsx
    │   │   │   ├── u
    │   │   │   │   ├── actions.tsx
    │   │   │   │   ├── page.tsx
    │   │   │   │   └── profile.tsx
    │   │   │   ├── watch
    │   │   │   │   ├── account.tsx
    │   │   │   │   ├── actions.tsx
    │   │   │   │   ├── comments.tsx
    │   │   │   │   ├── content.tsx
    │   │   │   │   ├── creator.tsx
    │   │   │   │   ├── page.tsx
    │   │   │   │   ├── stats-and-actions.tsx
    │   │   │   │   └── stats.tsx
    │   │   │   └── winder
    │   │   │   │   ├── content.tsx
    │   │   │   │   ├── header.tsx
    │   │   │   │   ├── intro-animation.tsx
    │   │   │   │   ├── intro.tsx
    │   │   │   │   ├── map.tsx
    │   │   │   │   ├── page.tsx
    │   │   │   │   └── sidebar.tsx
    │   │   ├── helpers
    │   │   │   ├── category.ts
    │   │   │   ├── date-time.ts
    │   │   │   ├── execute.ts
    │   │   │   ├── format-number.ts
    │   │   │   ├── generate-thumbnails.ts
    │   │   │   ├── metadata.ts
    │   │   │   ├── parse-jwt.ts
    │   │   │   ├── refresh-tokens.ts
    │   │   │   ├── sanitize-storage-url.ts
    │   │   │   └── upload.tsx
    │   │   ├── main.css
    │   │   ├── main.tsx
    │   │   ├── providers
    │   │   │   ├── animations.tsx
    │   │   │   ├── dev-only.tsx
    │   │   │   ├── index.tsx
    │   │   │   ├── log.tsx
    │   │   │   ├── react-query.tsx
    │   │   │   ├── sw-provider.tsx
    │   │   │   └── wallet.tsx
    │   │   ├── queries
    │   │   │   ├── account.tsx
    │   │   │   ├── auth.ts
    │   │   │   ├── comment.tsx
    │   │   │   ├── notification.tsx
    │   │   │   ├── post.tsx
    │   │   │   └── search.tsx
    │   │   ├── routeTree.gen.ts
    │   │   ├── routes
    │   │   │   ├── __root.tsx
    │   │   │   ├── _auth-hoc.tsx
    │   │   │   ├── _auth-hoc
    │   │   │   │   ├── sign-in.tsx
    │   │   │   │   └── sign-up.tsx
    │   │   │   ├── _layout-hoc.tsx
    │   │   │   ├── _layout-hoc
    │   │   │   │   ├── _home-hoc.tsx
    │   │   │   │   ├── _home-hoc
    │   │   │   │   │   ├── explore.tsx
    │   │   │   │   │   ├── following.tsx
    │   │   │   │   │   └── index.tsx
    │   │   │   │   ├── _settings-hoc.tsx
    │   │   │   │   ├── _settings-hoc
    │   │   │   │   │   └── settings
    │   │   │   │   │   │   └── me.tsx
    │   │   │   │   ├── create
    │   │   │   │   │   └── index.tsx
    │   │   │   │   ├── feed
    │   │   │   │   │   └── index.tsx
    │   │   │   │   ├── mod
    │   │   │   │   │   └── index.tsx
    │   │   │   │   ├── privacy
    │   │   │   │   │   └── index.tsx
    │   │   │   │   ├── terms
    │   │   │   │   │   └── index.tsx
    │   │   │   │   ├── u
    │   │   │   │   │   └── $handle.tsx
    │   │   │   │   └── watch
    │   │   │   │   │   └── $postId.tsx
    │   │   │   ├── embed
    │   │   │   │   └── $postId.tsx
    │   │   │   ├── open
    │   │   │   │   └── index.tsx
    │   │   │   └── winder
    │   │   │   │   └── index.tsx
    │   │   ├── store
    │   │   │   ├── cookie.tsx
    │   │   │   ├── post.tsx
    │   │   │   └── scroll.tsx
    │   │   ├── vite-env.d.ts
    │   │   └── worker
    │   │   │   ├── build.mjs
    │   │   │   ├── cache.ts
    │   │   │   ├── events.ts
    │   │   │   └── sw.ts
    │   ├── tsconfig.app.json
    │   ├── tsconfig.json
    │   ├── tsconfig.node.json
    │   ├── tsr.config.json
    │   └── vite.config.ts
    └── web
    │   ├── next.config.js
    │   ├── package.json
    │   ├── postcss.config.js
    │   ├── public
    │       ├── favicon.ico
    │       ├── manifest.json
    │       ├── robots.txt
    │       └── sitemap.xml
    │   ├── src
    │       ├── components
    │       │   ├── Bytes
    │       │   │   ├── BottomOverlay.tsx
    │       │   │   ├── ByteActions.tsx
    │       │   │   ├── ByteComments.tsx
    │       │   │   ├── ByteVideo.tsx
    │       │   │   ├── SliderPlugin.tsx
    │       │   │   ├── TopOverlay.tsx
    │       │   │   └── index.tsx
    │       │   ├── Common
    │       │   │   ├── Alert.tsx
    │       │   │   ├── Badge.tsx
    │       │   │   ├── CategoryFilters.tsx
    │       │   │   ├── CollectorsList.tsx
    │       │   │   ├── EmbedMedia.tsx
    │       │   │   ├── ErrorBoundary.tsx
    │       │   │   ├── FollowActions.tsx
    │       │   │   ├── FullPageLoader.tsx
    │       │   │   ├── HorizontalScroller.tsx
    │       │   │   ├── HoverableProfile.tsx
    │       │   │   ├── InterweaveContent.tsx
    │       │   │   ├── Layout.tsx
    │       │   │   ├── Links
    │       │   │   │   ├── AddressExplorerLink.tsx
    │       │   │   │   ├── ArweaveExplorerLink.tsx
    │       │   │   │   ├── HashExplorerLink.tsx
    │       │   │   │   ├── IPFSLink.tsx
    │       │   │   │   └── TokenExplorerLink.tsx
    │       │   │   ├── Logo.tsx
    │       │   │   ├── MetaTags.tsx
    │       │   │   ├── MirrorPublication.tsx
    │       │   │   ├── MirroredList.tsx
    │       │   │   ├── MobileBottomNav.tsx
    │       │   │   ├── Navbar.tsx
    │       │   │   ├── ProfileSuspended.tsx
    │       │   │   ├── Providers
    │       │   │   │   ├── CuratedProfilesProvider.tsx
    │       │   │   │   ├── ServiceWorkerProvider.tsx
    │       │   │   │   ├── SubscriptionProvider.tsx
    │       │   │   │   ├── ThemeProvider.tsx
    │       │   │   │   ├── TogglesProvider.tsx
    │       │   │   │   ├── Web3Provider.tsx
    │       │   │   │   └── index.tsx
    │       │   │   ├── Publication
    │       │   │   │   ├── PublicationActions.tsx
    │       │   │   │   ├── PublicationComments.tsx
    │       │   │   │   ├── PublicationOptions.tsx
    │       │   │   │   └── PublicationReaction.tsx
    │       │   │   ├── Search
    │       │   │   │   ├── GlobalSearch.tsx
    │       │   │   │   ├── Profiles.tsx
    │       │   │   │   └── Publications.tsx
    │       │   │   ├── TapeMenu.tsx
    │       │   │   ├── UserMenu.tsx
    │       │   │   ├── VideoCard
    │       │   │   │   ├── QueuedVideo.tsx
    │       │   │   │   ├── Share.tsx
    │       │   │   │   ├── ThumbnailImage.tsx
    │       │   │   │   ├── ThumbnailOverlays.tsx
    │       │   │   │   └── index.tsx
    │       │   │   └── matchers
    │       │   │   │   ├── EmailMatcher.tsx
    │       │   │   │   ├── HashtagMatcher.tsx
    │       │   │   │   ├── MentionMatcher.tsx
    │       │   │   │   ├── TimeMatcher.tsx
    │       │   │   │   ├── UrlMatcher.tsx
    │       │   │   │   └── utils.ts
    │       │   ├── Create
    │       │   │   ├── ChooseThumbnail.tsx
    │       │   │   ├── CollectModule
    │       │   │   │   ├── ChargeQuestion.tsx
    │       │   │   │   ├── CollectDuration.tsx
    │       │   │   │   ├── EditionSize.tsx
    │       │   │   │   ├── FeeCollectForm.tsx
    │       │   │   │   ├── PermissionQuestion.tsx
    │       │   │   │   ├── Splits.tsx
    │       │   │   │   └── index.tsx
    │       │   │   ├── Details.tsx
    │       │   │   ├── DropZone.tsx
    │       │   │   ├── IrysInfo.tsx
    │       │   │   ├── MediaCategory.tsx
    │       │   │   ├── MediaLicense.tsx
    │       │   │   ├── OpenAction
    │       │   │   │   └── index.tsx
    │       │   │   ├── ReferenceModule
    │       │   │   │   └── index.tsx
    │       │   │   ├── SelectedMedia.tsx
    │       │   │   ├── UploadMethod.tsx
    │       │   │   ├── filereader.d.ts
    │       │   │   └── index.tsx
    │       │   ├── Explore
    │       │   │   ├── Category
    │       │   │   │   └── index.tsx
    │       │   │   ├── Feed.tsx
    │       │   │   ├── Hashtag
    │       │   │   │   └── index.tsx
    │       │   │   └── index.tsx
    │       │   ├── Feed
    │       │   │   └── index.tsx
    │       │   ├── Home
    │       │   │   ├── Feed.tsx
    │       │   │   ├── GitcoinAlert.tsx
    │       │   │   ├── LatestBytes.tsx
    │       │   │   ├── LensManagerAlert.tsx
    │       │   │   ├── Timeline.tsx
    │       │   │   ├── TopSection.tsx
    │       │   │   ├── WelcomeAlert.tsx
    │       │   │   ├── ZorbAlert.tsx
    │       │   │   └── index.tsx
    │       │   ├── Login
    │       │   │   ├── Authenticate.tsx
    │       │   │   ├── BackgroundComets.tsx
    │       │   │   ├── CardBorders.tsx
    │       │   │   ├── Connectors.tsx
    │       │   │   └── Signup.tsx
    │       │   ├── Mod
    │       │   │   ├── Recents.tsx
    │       │   │   ├── Signup.tsx
    │       │   │   └── index.tsx
    │       │   ├── Notifications
    │       │   │   ├── Acted.tsx
    │       │   │   ├── Commented.tsx
    │       │   │   ├── Filter.tsx
    │       │   │   ├── Followed.tsx
    │       │   │   ├── Mentioned.tsx
    │       │   │   ├── Mirrored.tsx
    │       │   │   ├── Quoted.tsx
    │       │   │   ├── Reactions.tsx
    │       │   │   └── index.tsx
    │       │   ├── Profile
    │       │   │   ├── BasicInfo
    │       │   │   │   ├── Follow.tsx
    │       │   │   │   ├── Stats
    │       │   │   │   │   ├── Followers.tsx
    │       │   │   │   │   ├── Following.tsx
    │       │   │   │   │   └── index.tsx
    │       │   │   │   ├── SuperFollow.tsx
    │       │   │   │   ├── UnFollow.tsx
    │       │   │   │   └── index.tsx
    │       │   │   ├── Bookmarks.tsx
    │       │   │   ├── Cover.tsx
    │       │   │   ├── CoverLinks.tsx
    │       │   │   ├── Mutual
    │       │   │   │   ├── Bubbles.tsx
    │       │   │   │   └── MutualFollowers.tsx
    │       │   │   ├── Tabs
    │       │   │   │   ├── PinnedVideo.tsx
    │       │   │   │   ├── ProfileBytes.tsx
    │       │   │   │   ├── ProfileVideos.tsx
    │       │   │   │   └── index.tsx
    │       │   │   └── index.tsx
    │       │   ├── Report
    │       │   │   ├── Profile.tsx
    │       │   │   └── Publication.tsx
    │       │   ├── Settings
    │       │   │   ├── Allowance
    │       │   │   │   ├── Modules
    │       │   │   │   │   └── index.tsx
    │       │   │   │   └── index.tsx
    │       │   │   ├── BasicInfo.tsx
    │       │   │   ├── Blocked
    │       │   │   │   ├── List.tsx
    │       │   │   │   └── index.tsx
    │       │   │   ├── DangerZone
    │       │   │   │   ├── Delete.tsx
    │       │   │   │   ├── Guardian.tsx
    │       │   │   │   └── index.tsx
    │       │   │   ├── Follow
    │       │   │   │   ├── FeeFollow.tsx
    │       │   │   │   ├── RevertFollow.tsx
    │       │   │   │   └── index.tsx
    │       │   │   ├── Handles
    │       │   │   │   ├── List.tsx
    │       │   │   │   └── index.tsx
    │       │   │   ├── Manager
    │       │   │   │   ├── LensManager
    │       │   │   │   │   ├── ToggleLensManager.tsx
    │       │   │   │   │   └── index.tsx
    │       │   │   │   ├── Managers.tsx
    │       │   │   │   ├── Managing.tsx
    │       │   │   │   └── index.tsx
    │       │   │   ├── ProfileInterests
    │       │   │   │   ├── Topics.tsx
    │       │   │   │   └── index.tsx
    │       │   │   ├── Sessions
    │       │   │   │   ├── List.tsx
    │       │   │   │   └── index.tsx
    │       │   │   ├── SettingsSidebar.tsx
    │       │   │   └── index.tsx
    │       │   ├── Shimmers
    │       │   │   ├── BubblesShimmer.tsx
    │       │   │   ├── ButtonShimmer.tsx
    │       │   │   ├── CategoriesShimmer.tsx
    │       │   │   ├── CategoryItemShimmer.tsx
    │       │   │   ├── ChannelCardShimmer.tsx
    │       │   │   ├── CommentItemShimmer.tsx
    │       │   │   ├── CommentsShimmer.tsx
    │       │   │   ├── LatestBytesShimmer.tsx
    │       │   │   ├── NotificationsShimmer.tsx
    │       │   │   ├── OpenActionsShimmer.tsx
    │       │   │   ├── PinnedVideoShimmer.tsx
    │       │   │   ├── ProfilePageShimmer.tsx
    │       │   │   ├── SettingsShimmer.tsx
    │       │   │   ├── SquareButtonShimmer.tsx
    │       │   │   ├── SuggestedShimmer.tsx
    │       │   │   ├── ThumbnailsShimmer.tsx
    │       │   │   ├── TimelineShimmer.tsx
    │       │   │   ├── VideoCardShimmer.tsx
    │       │   │   └── WatchShimmer.tsx
    │       │   ├── Thanks
    │       │   │   └── index.tsx
    │       │   ├── UIElements
    │       │   │   ├── Confirm.tsx
    │       │   │   ├── CountDown.tsx
    │       │   │   ├── EmojiPicker.tsx
    │       │   │   ├── InputMentions.tsx
    │       │   │   ├── NoDataFound.tsx
    │       │   │   ├── ProfileSuggestion.tsx
    │       │   │   └── SignalWaveGraphic.tsx
    │       │   └── Watch
    │       │   │   ├── Comments
    │       │   │       ├── AudioComment.tsx
    │       │   │       ├── CommentMedia.tsx
    │       │   │       ├── CommentOptions.tsx
    │       │   │       ├── CommentReplies.tsx
    │       │   │       ├── CommentsFilter.tsx
    │       │   │       ├── NewComment.tsx
    │       │   │       ├── NonRelevantComments.tsx
    │       │   │       ├── QueuedComment.tsx
    │       │   │       ├── RenderComment.tsx
    │       │   │       └── VideoComment.tsx
    │       │   │   ├── OpenActions
    │       │   │       ├── BalanceAlert.tsx
    │       │   │       ├── Collect
    │       │   │       │   └── index.tsx
    │       │   │       ├── PermissionAlert.tsx
    │       │   │       ├── Unknown
    │       │   │       │   ├── Tip
    │       │   │       │   │   └── index.tsx
    │       │   │       │   └── index.tsx
    │       │   │       ├── index.tsx
    │       │   │       └── verified-contracts.tsx
    │       │   │   ├── SuggestedVideoCard.tsx
    │       │   │   ├── SuggestedVideos.tsx
    │       │   │   ├── TipForm.tsx
    │       │   │   ├── Video.tsx
    │       │   │   ├── VideoMeta.tsx
    │       │   │   └── index.tsx
    │       ├── hooks
    │       │   ├── useDid.ts
    │       │   ├── useHandleWrongNetwork.ts
    │       │   ├── usePendingTxn.ts
    │       │   └── useSw.ts
    │       ├── lib
    │       │   ├── authLink.ts
    │       │   ├── createIdbStorage.ts
    │       │   ├── formatTime.ts
    │       │   ├── getCollectModuleInput.ts
    │       │   ├── getCollectModuleOutput.ts
    │       │   ├── getCurrentSession.ts
    │       │   └── store
    │       │   │   ├── auth.ts
    │       │   │   ├── comment.ts
    │       │   │   ├── idb
    │       │   │       ├── collect.ts
    │       │   │       ├── curated.ts
    │       │   │       ├── profile.ts
    │       │   │       ├── toggles.ts
    │       │   │       ├── tokens.ts
    │       │   │       └── verified.ts
    │       │   │   ├── index.ts
    │       │   │   ├── nonce.ts
    │       │   │   ├── notification.ts
    │       │   │   └── persist.ts
    │       ├── pages
    │       │   ├── 404.tsx
    │       │   ├── 500.tsx
    │       │   ├── _app.tsx
    │       │   ├── _document.tsx
    │       │   ├── bookmarks.tsx
    │       │   ├── bytes
    │       │   │   ├── [id].tsx
    │       │   │   └── index.tsx
    │       │   ├── create.tsx
    │       │   ├── explore
    │       │   │   ├── [category].tsx
    │       │   │   ├── hashtag
    │       │   │   │   └── [hashtag].tsx
    │       │   │   └── index.tsx
    │       │   ├── feed.tsx
    │       │   ├── index.tsx
    │       │   ├── login.tsx
    │       │   ├── mod.tsx
    │       │   ├── notifications.tsx
    │       │   ├── privacy.tsx
    │       │   ├── profile
    │       │   │   └── [id].tsx
    │       │   ├── settings
    │       │   │   ├── allowance.tsx
    │       │   │   ├── blocked.tsx
    │       │   │   ├── danger.tsx
    │       │   │   ├── follow.tsx
    │       │   │   ├── handles.tsx
    │       │   │   ├── index.tsx
    │       │   │   ├── interests.tsx
    │       │   │   ├── manager.tsx
    │       │   │   └── sessions.tsx
    │       │   ├── terms.tsx
    │       │   ├── thanks.tsx
    │       │   ├── u
    │       │   │   └── [[...handle]].tsx
    │       │   └── watch
    │       │   │   └── [id].tsx
    │       └── styles
    │       │   └── index.css
    │   ├── tailwind.config.js
    │   └── tsconfig.json
├── biome.json
├── package.json
├── packages
    ├── abis
    │   ├── index.ts
    │   ├── package.json
    │   ├── src
    │   │   ├── LensHubProxy.ts
    │   │   ├── LensPermissionlessCreator.ts
    │   │   └── TapeSignupProxy.ts
    │   └── tsconfig.json
    ├── browser
    │   ├── font.ts
    │   ├── font
    │   │   ├── Satoshi-Bold.woff2
    │   │   ├── Satoshi-Medium.woff2
    │   │   └── Satoshi-Regular.woff2
    │   ├── functions
    │   │   ├── fingerprint.ts
    │   │   ├── generateVideoThumbnails.ts
    │   │   ├── getFileFromDataURL.ts
    │   │   ├── getToastOptions.ts
    │   │   ├── getUserLocale.ts
    │   │   ├── livepeer.ts
    │   │   └── tw.ts
    │   ├── hooks
    │   │   ├── uploadToIPFS.ts
    │   │   ├── useAverageColor.ts
    │   │   ├── useCopyToClipboard.ts
    │   │   ├── useDebounce.ts
    │   │   ├── useDragAndDrop.ts
    │   │   ├── useHorizontalScroll.ts
    │   │   ├── useIsMounted.ts
    │   │   └── useOutsideClick.ts
    │   ├── index.ts
    │   ├── package.json
    │   ├── tsconfig.json
    │   └── worker
    │   │   ├── build.mjs
    │   │   └── sw.ts
    ├── constants
    │   ├── auth-routes.ts
    │   ├── categories.ts
    │   ├── endpoints.ts
    │   ├── feature-flags.ts
    │   ├── general.ts
    │   ├── index.ts
    │   ├── misused.ts
    │   ├── package.json
    │   ├── regex.ts
    │   ├── suspended.ts
    │   └── tsconfig.json
    ├── generic
    │   ├── events.ts
    │   ├── functions
    │   │   ├── canUploadedToIpfs.ts
    │   │   ├── checkIsBytesVideo.ts
    │   │   ├── checkLensManagerPermissions.ts
    │   │   ├── formatBytes.ts
    │   │   ├── formatMB.ts
    │   │   ├── formatNumber.ts
    │   │   ├── get-attachments-data.ts
    │   │   ├── get-profile-cover.ts
    │   │   ├── get-profile-picture.ts
    │   │   ├── get-profile.ts
    │   │   ├── get-publication-data.ts
    │   │   ├── get-sharable-link.ts
    │   │   ├── get-thumbnail-url.ts
    │   │   ├── getCategoryName.ts
    │   │   ├── getFromAttributes.ts
    │   │   ├── getIsFeatureEnabled.ts
    │   │   ├── getIsProfileOwner.ts
    │   │   ├── getIsSensitiveContent.ts
    │   │   ├── getIsSuspendedProfile.ts
    │   │   ├── getLennyPicture.ts
    │   │   ├── getMetadataCid.ts
    │   │   ├── getPublication.ts
    │   │   ├── getPublicationMediaUrl.ts
    │   │   ├── getShouldUploadVideo.ts
    │   │   ├── getSignature.ts
    │   │   ├── getUploadedMediaType.ts
    │   │   ├── image-cdn.ts
    │   │   ├── isOpenActionAllowed.ts
    │   │   ├── isWatchable.ts
    │   │   ├── omitKey.ts
    │   │   ├── parse-jwt.ts
    │   │   ├── resolveDid.ts
    │   │   ├── sanitizeDStorageUrl.ts
    │   │   ├── sanitizeProfileInterests.ts
    │   │   ├── shortenAddress.ts
    │   │   ├── splitNumber.ts
    │   │   ├── trim-new-lines.ts
    │   │   ├── trimify.ts
    │   │   ├── truncate.ts
    │   │   └── uploadToAr.ts
    │   ├── index.ts
    │   ├── logger.ts
    │   ├── package.json
    │   └── tsconfig.json
    ├── indexer
    │   ├── codegen.ts
    │   ├── custom-types.ts
    │   ├── documents
    │   │   ├── fragments
    │   │   │   ├── account-manager-permissions.graphql
    │   │   │   ├── account
    │   │   │   │   ├── account-fields.graphql
    │   │   │   │   ├── account-follow-rule-fields.graphql
    │   │   │   │   ├── account-metadata-fields.graphql
    │   │   │   │   ├── logged-in-account-operations-fields.graphql
    │   │   │   │   └── username-fields.graphql
    │   │   │   ├── any-key-value-fields.graphql
    │   │   │   ├── app-fields.graphql
    │   │   │   ├── boolean-value-fields.graphql
    │   │   │   ├── erc20-amount-fields.graphql
    │   │   │   ├── erc20-fields.graphql
    │   │   │   ├── metadata-attribute-fields.graphql
    │   │   │   ├── network-address-fields.graphql
    │   │   │   ├── notifications
    │   │   │   │   ├── comment-notification-fields.graphql
    │   │   │   │   ├── follow-notification-fields.graphql
    │   │   │   │   ├── mention-notification-fields.graphql
    │   │   │   │   ├── quote-notification-fields.graphql
    │   │   │   │   ├── reaction-notification-fields.graphql
    │   │   │   │   └── repost-notification-fields.graphql
    │   │   │   ├── post
    │   │   │   │   ├── collect
    │   │   │   │   │   ├── pay-to-collect-config-fields.graphql
    │   │   │   │   │   ├── simple-collect-action-fields.graphql
    │   │   │   │   │   └── unknown-action-fields.graphql
    │   │   │   │   ├── logged-in-post-operations-fields.graphql
    │   │   │   │   ├── metadata
    │   │   │   │   │   ├── media
    │   │   │   │   │   │   ├── media-audio-fields.graphql
    │   │   │   │   │   │   ├── media-fields.graphql
    │   │   │   │   │   │   ├── media-image-fields.graphql
    │   │   │   │   │   │   └── media-video-fields.graphql
    │   │   │   │   │   └── video-metadata-fields.graphql
    │   │   │   │   ├── post-action-fields.graphql
    │   │   │   │   ├── post-base-fields.graphql
    │   │   │   │   ├── post-fields.graphql
    │   │   │   │   ├── post-metadata-fields.graphql
    │   │   │   │   ├── post-stats-fields.graphql
    │   │   │   │   └── repost-fields.graphql
    │   │   │   ├── self-funded-transaction-request-fields.graphql
    │   │   │   └── sponsored-transaction-request-fields.graphql
    │   │   ├── mutations
    │   │   │   ├── account
    │   │   │   │   └── create-account.graphql
    │   │   │   ├── auth
    │   │   │   │   ├── authenticate.graphql
    │   │   │   │   ├── challenge.graphql
    │   │   │   │   └── refresh.graphql
    │   │   │   └── post
    │   │   │   │   ├── add-reaction.graphql
    │   │   │   │   ├── bookmark-post.graphql
    │   │   │   │   ├── create-post.graphql
    │   │   │   │   ├── delete-post.graphql
    │   │   │   │   ├── edit-post.graphql
    │   │   │   │   ├── report-post.graphql
    │   │   │   │   ├── repost.graphql
    │   │   │   │   ├── undo-bookmark.graphql
    │   │   │   │   └── undo-reaction.graphql
    │   │   └── queries
    │   │   │   ├── account
    │   │   │       ├── account-managers.graphql
    │   │   │       ├── account-stats.graphql
    │   │   │       ├── account.graphql
    │   │   │       ├── accounts-available.graphql
    │   │   │       ├── accounts-blocked.graphql
    │   │   │       ├── accounts.graphql
    │   │   │       ├── authenticated-sessions.graphql
    │   │   │       ├── followers-you-know.graphql
    │   │   │       ├── followers.graphql
    │   │   │       ├── following.graphql
    │   │   │       ├── last-logged-in-account.graphql
    │   │   │       ├── me.graphql
    │   │   │       ├── notifications.graphql
    │   │   │       └── usernames.graphql
    │   │   │   ├── post
    │   │   │       ├── post-references.graphql
    │   │   │       ├── post.graphql
    │   │   │       └── posts.graphql
    │   │   │   └── search.graphql
    │   ├── gql
    │   │   ├── generated
    │   │   │   ├── fragment-masking.ts
    │   │   │   ├── gql.ts
    │   │   │   ├── graphql.ts
    │   │   │   └── index.ts
    │   │   └── index.ts
    │   ├── package.json
    │   └── tsconfig.json
    ├── lens
    │   ├── apollo
    │   │   ├── cache.ts
    │   │   ├── cursorBasedPagination.ts
    │   │   └── index.ts
    │   ├── codegen.ts
    │   ├── custom-types.ts
    │   ├── documents
    │   │   ├── fragments
    │   │   │   ├── amount-fields.graphql
    │   │   │   ├── any-publication-metadata-fields.graphql
    │   │   │   ├── comment-base-fields.graphql
    │   │   │   ├── comment-fields.graphql
    │   │   │   ├── erc20-fields.graphql
    │   │   │   ├── fiat-amount-fields.graphql
    │   │   │   ├── follow-module-fields.graphql
    │   │   │   ├── handle-info-fields.graphql
    │   │   │   ├── image-set-fields.graphql
    │   │   │   ├── metadata-attribute-fields.graphql
    │   │   │   ├── mirror-fields.graphql
    │   │   │   ├── network-address-fields.graphql
    │   │   │   ├── open-action-modules-fields.graphql
    │   │   │   ├── post-fields.graphql
    │   │   │   ├── primary-publication-fields.graphql
    │   │   │   ├── profile-fields.graphql
    │   │   │   ├── profile-metadata-fields.graphql
    │   │   │   ├── profile-operations-fields.graphql
    │   │   │   ├── profile-stats-fields.graphql
    │   │   │   ├── publication-metadata
    │   │   │   │   ├── article-metadata-v3-fields.graphql
    │   │   │   │   ├── audio-metadata-v3-fields.graphql
    │   │   │   │   ├── checkin-metadata-v3-fields.graphql
    │   │   │   │   ├── image-metadata-v3-fields.graphql
    │   │   │   │   ├── link-metadata-v3-fields.graphql
    │   │   │   │   ├── live-stream-metadata-v3-fields.graphql
    │   │   │   │   ├── media-fields
    │   │   │   │   │   ├── publication-metadata-media-audio-fields.graphql
    │   │   │   │   │   ├── publication-metadata-media-fields.graphql
    │   │   │   │   │   ├── publication-metadata-media-image-fields.graphql
    │   │   │   │   │   └── publication-metadata-media-video-fields.graphql
    │   │   │   │   ├── mint-metadata-v3-fields.graphql
    │   │   │   │   ├── text-only-metadata-v3-fields.graphql
    │   │   │   │   └── video-metadata-v3-fields.graphql
    │   │   │   ├── publication-operation-fields.graphql
    │   │   │   ├── publication-stats-fields.graphql
    │   │   │   ├── quote-base-fields.graphql
    │   │   │   └── quote-fields.graphql
    │   │   ├── mutations
    │   │   │   ├── Authenticate.graphql
    │   │   │   ├── Broadcast.graphql
    │   │   │   ├── momoka
    │   │   │   │   ├── Momoka.graphql
    │   │   │   │   ├── create-momoka-comment-typed-data.graphql
    │   │   │   │   ├── create-momoka-mirror-typed-data.graphql
    │   │   │   │   └── create-momoka-post-typed-data.graphql
    │   │   │   ├── on-chain
    │   │   │   │   ├── create-change-profile-managers-typed-data.graphql
    │   │   │   │   ├── create-onchain-comment-typed-data.graphql
    │   │   │   │   ├── create-onchain-mirror-typed-data.graphql
    │   │   │   │   ├── create-onchain-post-typed-data.graphql
    │   │   │   │   ├── create-onchain-set-profile-metadata-typed-data.graphql
    │   │   │   │   └── on-chain.graphql
    │   │   │   ├── profile
    │   │   │   │   ├── Block.graphql
    │   │   │   │   ├── Follow.graphql
    │   │   │   │   ├── Unblock.graphql
    │   │   │   │   ├── Unfollow.graphql
    │   │   │   │   ├── add-profile-interests.graphql
    │   │   │   │   ├── create-profile-with-handle.graphql
    │   │   │   │   ├── link-handle-to-profile.graphql
    │   │   │   │   ├── remove-profile-interests.graphql
    │   │   │   │   ├── set-follow-module.graphql
    │   │   │   │   ├── set-profile-metadata.graphql
    │   │   │   │   └── unlink-handle-from-profile.graphql
    │   │   │   └── publication
    │   │   │   │   ├── act-on-open-action.graphql
    │   │   │   │   ├── add-publication-bookmark.graphql
    │   │   │   │   ├── add-publication-not-interested.graphql
    │   │   │   │   ├── add-reaction.graphql
    │   │   │   │   ├── hide-publication.graphql
    │   │   │   │   ├── legacy-collect.graphql
    │   │   │   │   ├── remove-publication-bookmark.graphql
    │   │   │   │   ├── remove-reaction.graphql
    │   │   │   │   ├── report-profile.graphql
    │   │   │   │   ├── report-publication.graphql
    │   │   │   │   └── undo-publication-not-interested.graphql
    │   │   ├── queries
    │   │   │   ├── Challenge.graphql
    │   │   │   ├── Followers.graphql
    │   │   │   ├── Following.graphql
    │   │   │   ├── Notifications.graphql
    │   │   │   ├── Profile.graphql
    │   │   │   ├── Profiles.graphql
    │   │   │   ├── Publication.graphql
    │   │   │   ├── Publications.graphql
    │   │   │   ├── approved-authentications.graphql
    │   │   │   ├── approved-module-allowance-amount.graphql
    │   │   │   ├── current-profile.graphql
    │   │   │   ├── explore-publications.graphql
    │   │   │   ├── feed-highlights.graphql
    │   │   │   ├── generate-lens-apirelay-address.graphql
    │   │   │   ├── generate-module-currency-approval-data.graphql
    │   │   │   ├── handle-to-address.graphql
    │   │   │   ├── has-publication-indexed.graphql
    │   │   │   ├── latest-notification-id.graphql
    │   │   │   ├── lens-transaction-status.graphql
    │   │   │   ├── mod-explore-publications.graphql
    │   │   │   ├── module-metadata.graphql
    │   │   │   ├── mutual-followers.graphql
    │   │   │   ├── owned-handles.graphql
    │   │   │   ├── profile-feed.graphql
    │   │   │   ├── profile-follow-module.graphql
    │   │   │   ├── profile-interests-options.graphql
    │   │   │   ├── profile-managers.graphql
    │   │   │   ├── profiles-managed.graphql
    │   │   │   ├── publication-bookmarks.graphql
    │   │   │   ├── revenue-from-publication.graphql
    │   │   │   ├── revenue-from-publications.graphql
    │   │   │   ├── revoke-authentication.graphql
    │   │   │   ├── search-profiles.graphql
    │   │   │   ├── search-publications.graphql
    │   │   │   ├── tx-id-to-tx-hash.graphql
    │   │   │   ├── who-acted-on-publication.graphql
    │   │   │   ├── who-have-blocked.graphql
    │   │   │   └── who-reacted-publication.graphql
    │   │   └── subscriptions
    │   │   │   ├── authorization-record-revoked.graphql
    │   │   │   ├── new-notification.graphql
    │   │   │   └── user-sig-nonces.graphql
    │   ├── generated.ts
    │   ├── package.json
    │   └── tsconfig.json
    ├── server
    │   ├── .env.example
    │   ├── .gitignore
    │   ├── db
    │   │   ├── clickhouse
    │   │   │   ├── client.ts
    │   │   │   └── schema.sql
    │   │   ├── indexer
    │   │   │   └── client.ts
    │   │   ├── redis
    │   │   │   └── client.ts
    │   │   └── tape
    │   │   │   ├── client.ts
    │   │   │   ├── migrations
    │   │   │       ├── 20240720140713_init
    │   │   │       │   └── migration.sql
    │   │   │       ├── 20240723044050_curated_profile
    │   │   │       │   └── migration.sql
    │   │   │       ├── 20240723105833_unique_profile_id
    │   │   │       │   └── migration.sql
    │   │   │       ├── 20240809041517_add_profile
    │   │   │       │   └── migration.sql
    │   │   │       ├── 20240809042300_update_default_time
    │   │   │       │   └── migration.sql
    │   │   │       ├── 20240809051310_drop_tables
    │   │   │       │   └── migration.sql
    │   │   │       ├── 20241004061051_stats
    │   │   │       │   └── migration.sql
    │   │   │       ├── 20241004061452_stats_optional
    │   │   │       │   └── migration.sql
    │   │   │       ├── 20241004062254_platform_stats
    │   │   │       │   └── migration.sql
    │   │   │       └── migration_lock.toml
    │   │   │   ├── schema.prisma
    │   │   │   └── seeds
    │   │   │       └── execute.sql
    │   ├── env.d.ts
    │   ├── index.ts
    │   ├── package.json
    │   └── tsconfig.json
    ├── tsconfig
    │   ├── base.json
    │   ├── nextjs.json
    │   ├── package.json
    │   └── react.json
    ├── ui
    │   ├── index.ts
    │   ├── package.json
    │   ├── postcss.config.js
    │   ├── src
    │   │   ├── Accordion.tsx
    │   │   ├── Badge.tsx
    │   │   ├── Button.tsx
    │   │   ├── Callout.tsx
    │   │   ├── Checkbox.tsx
    │   │   ├── Dropdown.tsx
    │   │   ├── HoverCard.tsx
    │   │   ├── Input.tsx
    │   │   ├── LoadingBorder.tsx
    │   │   ├── Modal.tsx
    │   │   ├── Popover.tsx
    │   │   ├── RangeSlider.tsx
    │   │   ├── Select.tsx
    │   │   ├── Spinner.tsx
    │   │   ├── Switch.tsx
    │   │   ├── Tabs.tsx
    │   │   ├── TextArea.tsx
    │   │   ├── Tooltip.tsx
    │   │   ├── icons
    │   │   │   ├── AddImageOutline.tsx
    │   │   │   ├── BellOutline.tsx
    │   │   │   ├── BookmarkOutline.tsx
    │   │   │   ├── BytesOutline.tsx
    │   │   │   ├── CheckOutline.tsx
    │   │   │   ├── ChevronDownOutline.tsx
    │   │   │   ├── ChevronLeftOutline.tsx
    │   │   │   ├── ChevronRightOutline.tsx
    │   │   │   ├── ChevronUpOutline.tsx
    │   │   │   ├── CodeOutline.tsx
    │   │   │   ├── CogOutline.tsx
    │   │   │   ├── CollectOutline.tsx
    │   │   │   ├── CommentOutline.tsx
    │   │   │   ├── CopyOutline.tsx
    │   │   │   ├── DisconnectOutline.tsx
    │   │   │   ├── EmojiOutline.tsx
    │   │   │   ├── ExploreOutline.tsx
    │   │   │   ├── ExternalOutline.tsx
    │   │   │   ├── FeedOutline.tsx
    │   │   │   ├── FireOutline.tsx
    │   │   │   ├── FlagOutline.tsx
    │   │   │   ├── FollowOutline.tsx
    │   │   │   ├── FollowingOutline.tsx
    │   │   │   ├── ForbiddenOutline.tsx
    │   │   │   ├── GlobeOutline.tsx
    │   │   │   ├── GraphOutline.tsx
    │   │   │   ├── HandWaveOutline.tsx
    │   │   │   ├── HashtagOutline.tsx
    │   │   │   ├── HeartFilled.tsx
    │   │   │   ├── HeartOutline.tsx
    │   │   │   ├── HomeOutline.tsx
    │   │   │   ├── InfoOutline.tsx
    │   │   │   ├── InfoSolid.tsx
    │   │   │   ├── InterestsOutline.tsx
    │   │   │   ├── KeyOutline.tsx
    │   │   │   ├── LinkOutline.tsx
    │   │   │   ├── LocationOutline.tsx
    │   │   │   ├── LockOutline.tsx
    │   │   │   ├── MentionOutline.tsx
    │   │   │   ├── MirrorOutline.tsx
    │   │   │   ├── MoonOutline.tsx
    │   │   │   ├── MusicOutline.tsx
    │   │   │   ├── NewVideoOutline.tsx
    │   │   │   ├── PauseOutline.tsx
    │   │   │   ├── PinOutline.tsx
    │   │   │   ├── PlayOutline.tsx
    │   │   │   ├── PlusOutline.tsx
    │   │   │   ├── ProfileBanOutline.tsx
    │   │   │   ├── ProfileManagerOutline.tsx
    │   │   │   ├── QuoteOutline.tsx
    │   │   │   ├── RefreshOutline.tsx
    │   │   │   ├── ReplyOutline.tsx
    │   │   │   ├── RoadmapOutline.tsx
    │   │   │   ├── SearchOutline.tsx
    │   │   │   ├── ShareOutline.tsx
    │   │   │   ├── SignOutline.tsx
    │   │   │   ├── SortOutline.tsx
    │   │   │   ├── SplitOutline.tsx
    │   │   │   ├── StopOutline.tsx
    │   │   │   ├── StreamOutline.tsx
    │   │   │   ├── SubscribeOutline.tsx
    │   │   │   ├── SunOutline.tsx
    │   │   │   ├── SwitchProfileOutline.tsx
    │   │   │   ├── TagOutline.tsx
    │   │   │   ├── ThreeDotsOutline.tsx
    │   │   │   ├── TimesOutline.tsx
    │   │   │   ├── TipOutline.tsx
    │   │   │   ├── TrashOutline.tsx
    │   │   │   ├── UploadOutline.tsx
    │   │   │   ├── UserOutline.tsx
    │   │   │   ├── VerifiedSolid.tsx
    │   │   │   ├── VideoOutline.tsx
    │   │   │   ├── WalletOutline.tsx
    │   │   │   ├── WarningOutline.tsx
    │   │   │   └── index.ts
    │   │   └── players
    │   │   │   └── video
    │   │   │       ├── Player.tsx
    │   │   │       ├── SensitiveWarning.tsx
    │   │   │       └── index.tsx
    │   ├── tailwind-preset.ts
    │   ├── tailwind.config.js
    │   └── tsconfig.json
    └── winder
    │   ├── index.ts
    │   ├── package.json
    │   ├── src
    │       ├── _components
    │       │   ├── alert.tsx
    │       │   ├── animated-number.tsx
    │       │   ├── audio-player.tsx
    │       │   ├── avatar.tsx
    │       │   ├── badge.tsx
    │       │   ├── button.tsx
    │       │   ├── dialog.tsx
    │       │   ├── dropdown-menu.tsx
    │       │   ├── empty-state.tsx
    │       │   ├── input.tsx
    │       │   ├── morph.tsx
    │       │   ├── popover.tsx
    │       │   ├── scroll-area.tsx
    │       │   ├── select.tsx
    │       │   ├── show-more.tsx
    │       │   ├── spinner.tsx
    │       │   ├── switch.tsx
    │       │   ├── tabs.tsx
    │       │   ├── textarea.tsx
    │       │   ├── theme-switcher.tsx
    │       │   ├── toast.tsx
    │       │   ├── tooltip.tsx
    │       │   └── video-player.tsx
    │       ├── icons.ts
    │       ├── theme.tsx
    │       ├── tw.ts
    │       └── winder.css
    │   └── tsconfig.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
└── scripts
    ├── clean-branches
    ├── clean-packages
    ├── sync-branches
    └── update-dependencies


/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @sasicodes
2 | 


--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: tapexyz
2 | custom: ['https://tape.xyz/donate']
3 | 


--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
 1 | name: Feature Request
 2 | description: Request a feature for Tape
 3 | title: "[Feature Request] "
 4 | labels: [needs review, triage]
 5 | body:
 6 |   - type: markdown
 7 |     attributes:
 8 |       value: Thanks for taking the time to file a feature request! Please fill out this form as completely as possible.
 9 |   - type: textarea
10 |     attributes:
11 |       label: Describe the feature you'd like to request
12 |       placeholder: Clearly describe what you want to see in Tape.
13 |     validations:
14 |       required: true
15 | 


--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | pnpm run biome:check
2 | 


--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | node-linker=hoisted
2 | 


--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 20
2 | 


--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 |   "recommendations": [
3 |     "biomejs.biome",
4 |     "bradlc.vscode-tailwindcss",
5 |     "Prisma.prisma",
6 |     "ms-azuretools.vscode-docker"
7 |   ]
8 | }
9 | 


--------------------------------------------------------------------------------
/apps/api/.env.example:
--------------------------------------------------------------------------------
 1 | EVER_ACCESS_KEY=
 2 | EVER_ACCESS_SECRET=
 3 | LOGTAIL_API_KEY=
 4 | WALLET_PRIVATE_KEY= #pk without 0x
 5 | TAPE_DATABASE_URL=
 6 | INDEXER_DATABASE_URL=
 7 | REDIS_URL=
 8 | CLICKHOUSE_URL=""
 9 | CLICKHOUSE_PASSWORD=""
10 | 


--------------------------------------------------------------------------------
/apps/api/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | 
4 | # Change them to your taste:
5 | package-lock.json
6 | yarn.lock
7 | pnpm-lock.yaml


--------------------------------------------------------------------------------
/apps/api/README.md:
--------------------------------------------------------------------------------
 1 | # Api Server
 2 | 
 3 | # Run
 4 | 
 5 | ```
 6 | pnpm dev
 7 | ```
 8 | 
 9 | # Migrations
10 | 
11 | ```
12 | cd apps/api
13 | ```
14 | 
15 | ```sh
16 | pnpm db:migrate
17 | ```
18 | 


--------------------------------------------------------------------------------
/apps/api/env.d.ts:
--------------------------------------------------------------------------------
 1 | declare namespace NodeJS {
 2 |   interface ProcessEnv {
 3 |     EVER_ACCESS_KEY: string;
 4 |     EVER_ACCESS_SECRET: string;
 5 |     LOGTAIL_API_KEY: string;
 6 |     WALLET_PRIVATE_KEY: string;
 7 |     TAPE_DATABASE_URL: string;
 8 |     INDEXER_DATABASE_URL: string;
 9 |     REDIS_URL: string;
10 |     CLICKHOUSE_URL: string;
11 |     CLICKHOUSE_PASSWORD: string;
12 |   }
13 | }
14 | 


--------------------------------------------------------------------------------
/apps/api/src/helpers/did/resolverAbi.ts:
--------------------------------------------------------------------------------
 1 | export const resolverAbi = [
 2 |   {
 3 |     inputs: [{ internalType: "contract ENS", name: "_ens", type: "address" }],
 4 |     stateMutability: "nonpayable",
 5 |     type: "constructor"
 6 |   },
 7 |   {
 8 |     inputs: [
 9 |       { internalType: "address[]", name: "addresses", type: "address[]" }
10 |     ],
11 |     name: "getNames",
12 |     outputs: [{ internalType: "string[]", name: "r", type: "string[]" }],
13 |     stateMutability: "view",
14 |     type: "function"
15 |   }
16 | ];
17 | 


--------------------------------------------------------------------------------
/apps/api/src/helpers/oembed/regex.ts:
--------------------------------------------------------------------------------
1 | export const COMMON_REGEX = {
2 |   TAPE_WATCH:
3 |     /^https?:\/\/tape\.xyz\/watch\/([\dA-Za-z-]+)(\?si=[\dA-Za-z]+)?$/,
4 |   YOUTUBE_WATCH:
5 |     /^https?:\/\/(?:www\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)[\w-]+(?:\?.*)?$/,
6 |   VIMEO_WATCH:
7 |     /^https?:\/\/(?:www\.|player\.)?vimeo\.com\/(?:video\/)?[\d]+(?:\?.*)?$/
8 | };
9 | 


--------------------------------------------------------------------------------
/apps/api/src/helpers/tower/checkEventExistence.ts:
--------------------------------------------------------------------------------
 1 | export const checkEventExistence = (
 2 |   obj: Record<string, unknown>,
 3 |   event: string
 4 | ): boolean => {
 5 |   for (const key in obj) {
 6 |     const value = obj[key];
 7 |     if (typeof value === "object" && value !== null) {
 8 |       if (checkEventExistence(value as Record<string, unknown>, event)) {
 9 |         return true;
10 |       }
11 |     } else if (value === event) {
12 |       return true;
13 |     }
14 |   }
15 |   return false;
16 | };
17 | 


--------------------------------------------------------------------------------
/apps/api/tsconfig.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "extends": "@tape.xyz/tsconfig/base.json",
 3 |   "compilerOptions": {
 4 |     "outDir": "./dist",
 5 |     "target": "ESNext",
 6 |     "module": "ESNext",
 7 |     "moduleResolution": "node",
 8 |     "noEmit": false,
 9 |     "lib": ["esnext"],
10 |     "jsx": "react-jsx",
11 |     "types": ["node"],
12 |     "jsxImportSource": "hono/jsx",
13 |     "paths": {
14 |       "@/*": ["./src/*"]
15 |     }
16 |   },
17 |   "exclude": ["node_modules", "dist"]
18 | }
19 | 


--------------------------------------------------------------------------------
/apps/contracts/.env.example:
--------------------------------------------------------------------------------
1 | POLYGONSCAN_API_KEY=""
2 | ALCHEMY_API_KEY=""
3 | PRIVATE_KEY=""
4 | 


--------------------------------------------------------------------------------
/apps/contracts/.gitignore:
--------------------------------------------------------------------------------
 1 | node_modules
 2 | .env
 3 | 
 4 | # Hardhat files
 5 | /cache
 6 | /artifacts
 7 | 
 8 | # TypeChain files
 9 | /typechain
10 | /typechain-types
11 | 
12 | # solidity-coverage files
13 | /coverage
14 | /coverage.json
15 | 
16 | .openzeppelin
17 | 


--------------------------------------------------------------------------------
/apps/contracts/env.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace NodeJS {
2 |   interface ProcessEnv {
3 |     POLYGONSCAN_API_KEY: string;
4 |     ALCHEMY_API_KEY: string;
5 |     PRIVATE_KEY: string;
6 |   }
7 | }
8 | 


--------------------------------------------------------------------------------
/apps/contracts/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "@tape.xyz/contracts",
 3 |   "version": "0.0.0",
 4 |   "author": "sasicodes",
 5 |   "license": "AGPL-3.0",
 6 |   "scripts": {
 7 |     "typecheck": "tsc --pretty --noEmit"
 8 |   },
 9 |   "devDependencies": {
10 |     "@nomicfoundation/hardhat-ethers": "^3.0.8",
11 |     "@nomicfoundation/hardhat-toolbox": "^5.0.0",
12 |     "@nomicfoundation/hardhat-verify": "^2.0.12",
13 |     "@openzeppelin/contracts": "^5.2.0",
14 |     "@openzeppelin/contracts-upgradeable": "^5.2.0",
15 |     "@openzeppelin/hardhat-upgrades": "^3.9.0",
16 |     "@tape.xyz/tsconfig": "workspace:*",
17 |     "dotenv": "^16.4.7",
18 |     "ethers": "^6.13.5",
19 |     "hardhat": "^2.22.18",
20 |     "ts-node": "^10.9.2",
21 |     "typescript": "^5.7.3"
22 |   }
23 | }
24 | 


--------------------------------------------------------------------------------
/apps/contracts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 |   "extends": "@tape.xyz/tsconfig/base.json"
3 | }
4 | 


--------------------------------------------------------------------------------
/apps/cron/.env.example:
--------------------------------------------------------------------------------
 1 | REDIS_URL=""
 2 | TAPE_DATABASE_URL=""
 3 | INDEXER_DATABASE_URL=""
 4 | CLICKHOUSE_URL=""
 5 | CLICKHOUSE_PASSWORD=""
 6 | S3_ACCESS_KEY_ID=""
 7 | S3_SECRET_ACCESS_KEY=""
 8 | S3_BUCKET_URL=""
 9 | EVER_ACCESS_KEY=""
10 | EVER_ACCESS_SECRET=""
11 | 


--------------------------------------------------------------------------------
/apps/cron/README.md:
--------------------------------------------------------------------------------
1 | # Cron
2 | 
3 | # Run
4 | 
5 | ```
6 | pnpm dev
7 | ```
8 | 


--------------------------------------------------------------------------------
/apps/cron/env.d.ts:
--------------------------------------------------------------------------------
 1 | declare namespace NodeJS {
 2 |   interface ProcessEnv {
 3 |     REDIS_URL: string;
 4 |     TAPE_DATABASE_URL: string;
 5 |     INDEXER_DATABASE_URL: string;
 6 |     CLICKHOUSE_URL: string;
 7 |     CLICKHOUSE_PASSWORD: string;
 8 |     S3_ACCESS_KEY_ID: string;
 9 |     S3_SECRET_ACCESS_KEY: string;
10 |     S3_BUCKET_URL: string;
11 |     EVER_ACCESS_KEY: string;
12 |     EVER_ACCESS_SECRET: string;
13 |   }
14 | }
15 | 


--------------------------------------------------------------------------------
/apps/cron/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "@tape.xyz/cron",
 3 |   "version": "0.0.0",
 4 |   "main": "dist/index.js",
 5 |   "private": true,
 6 |   "scripts": {
 7 |     "dev:cron": "tsx --watch src/index.ts",
 8 |     "build": "tsc",
 9 |     "start": "tsx src/index.ts",
10 |     "typecheck": "tsc --pretty --noEmit"
11 |   },
12 |   "license": "AGPL-3.0",
13 |   "dependencies": {
14 |     "@aws-sdk/client-s3": "3.799.0",
15 |     "node-cron": "^3.0.3"
16 |   },
17 |   "devDependencies": {
18 |     "@tape.xyz/constants": "workspace:*",
19 |     "@tape.xyz/server": "workspace:*",
20 |     "@tape.xyz/tsconfig": "workspace:*",
21 |     "@types/node": "^22.13.1",
22 |     "@types/node-cron": "^3.0.11",
23 |     "tsx": "^4.19.2",
24 |     "typescript": "^5.7.3"
25 |   }
26 | }
27 | 


--------------------------------------------------------------------------------
/apps/cron/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 |   "extends": "@tape.xyz/tsconfig/base.json",
3 |   "compilerOptions": {
4 |     "outDir": "./dist"
5 |   },
6 |   "exclude": ["node_modules", "dist"]
7 | }
8 | 


--------------------------------------------------------------------------------
/apps/embed/next.config.js:
--------------------------------------------------------------------------------
 1 | /** @type {import('next').NextConfig} */
 2 | const nextConfig = {
 3 |   transpilePackages: [
 4 |     "@tape.xyz/lens",
 5 |     "@tape.xyz/browser",
 6 |     "@tape.xyz/generic",
 7 |     "@tape.xyz/tsconfig",
 8 |     "@tape.xyz/ui"
 9 |   ],
10 |   reactStrictMode: true,
11 |   headers() {
12 |     return [
13 |       {
14 |         source: "/(.*)",
15 |         headers: [{ key: "Cache-Control", value: "public, max-age=31536000" }]
16 |       }
17 |     ];
18 |   }
19 | };
20 | 
21 | module.exports = nextConfig;
22 | 


--------------------------------------------------------------------------------
/apps/embed/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 |   plugins: {
4 |     tailwindcss: {}
5 |   }
6 | };
7 | 
8 | export default config;
9 | 


--------------------------------------------------------------------------------
/apps/embed/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/embed/src/app/favicon.ico


--------------------------------------------------------------------------------
/apps/embed/src/app/globals.css:
--------------------------------------------------------------------------------
 1 | @tailwind base;
 2 | @tailwind components;
 3 | @tailwind utilities;
 4 | 
 5 | body {
 6 |   @apply min-h-screen bg-white antialiased;
 7 | }
 8 | .livepeer-aspect-ratio-container,
 9 | .livepeer-contents-container {
10 |   height: inherit !important;
11 | }
12 | 
13 | button:active {
14 |   animation: button-pop 0.25s ease-out;
15 | }
16 | 
17 | @keyframes button-pop {
18 |   0% {
19 |     transform: scale(0.9);
20 |   }
21 |   40% {
22 |     transform: scale(1.02);
23 |   }
24 |   to {
25 |     transform: scale(1);
26 |   }
27 | }
28 | 


--------------------------------------------------------------------------------
/apps/embed/src/app/layout.tsx:
--------------------------------------------------------------------------------
 1 | import "./globals.css";
 2 | 
 3 | import { TAPE_APP_DESCRIPTION, TAPE_APP_NAME } from "@tape.xyz/constants";
 4 | import type { Metadata } from "next";
 5 | import type React from "react";
 6 | 
 7 | export const metadata: Metadata = {
 8 |   title: TAPE_APP_NAME,
 9 |   description: TAPE_APP_DESCRIPTION
10 | };
11 | 
12 | const RootLayout = ({ children }: { children: React.ReactNode }) => {
13 |   return (
14 |     <html lang="en">
15 |       <body>{children}</body>
16 |     </html>
17 |   );
18 | };
19 | 
20 | export default RootLayout;
21 | 


--------------------------------------------------------------------------------
/apps/embed/src/components/Custom404.tsx:
--------------------------------------------------------------------------------
 1 | import { STATIC_ASSETS, TAPE_APP_NAME } from "@tape.xyz/constants";
 2 | 
 3 | const Custom404 = () => {
 4 |   return (
 5 |     <div className="flex h-[calc(100vh-8rem)] flex-col items-center justify-center space-y-4 text-center">
 6 |       <div className="mb-10">
 7 |         <img
 8 |           src={`${STATIC_ASSETS}/images/illustrations/404.gif`}
 9 |           draggable={false}
10 |           height={200}
11 |           width={200}
12 |           alt={TAPE_APP_NAME}
13 |         />
14 |       </div>
15 |       <h1 className="font-bold text-4xl">404</h1>
16 |       <div className="mb-6">This publication could not be found.</div>
17 |     </div>
18 |   );
19 | };
20 | 
21 | export default Custom404;
22 | 


--------------------------------------------------------------------------------
/apps/embed/tailwind.config.ts:
--------------------------------------------------------------------------------
 1 | const base = require("@tape.xyz/ui/tailwind-preset");
 2 | import type { Config } from "tailwindcss";
 3 | 
 4 | const config: Config = {
 5 |   ...base,
 6 |   content: [
 7 |     "./src/pages/**/*.{ts,tsx}",
 8 |     "./src/components/**/*.{ts,tsx}",
 9 |     "../../packages/ui/src/**/*.{ts,tsx}"
10 |   ],
11 |   plugins: [require("@tailwindcss/aspect-ratio")]
12 | };
13 | 
14 | export default config;
15 | 


--------------------------------------------------------------------------------
/apps/embed/tsconfig.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "extends": "@tape.xyz/tsconfig/nextjs.json",
 3 |   "compilerOptions": {
 4 |     "baseUrl": ".",
 5 |     "paths": {
 6 |       "@/*": ["./src/*"]
 7 |     },
 8 |     "isolatedModules": true,
 9 |     "plugins": [
10 |       {
11 |         "name": "next"
12 |       }
13 |     ],
14 |     "strictNullChecks": true
15 |   },
16 |   "include": [
17 |     "next-env.d.ts",
18 |     "**/*.ts",
19 |     "**/*.tsx",
20 |     "src/styles/index.css",
21 |     ".next/types/**/*.ts"
22 |   ],
23 |   "exclude": ["node_modules"]
24 | }
25 | 


--------------------------------------------------------------------------------
/apps/mobile/.gitignore:
--------------------------------------------------------------------------------
1 | 
2 | # @generated expo-cli sync-2b81b286409207a5da26e14c78851eb30d8ccbdb
3 | # The following patterns were generated by expo-cli
4 | 
5 | expo-env.d.ts
6 | # @end expo-cli


--------------------------------------------------------------------------------
/apps/mobile/app/(protected)/(feed)/index.tsx:
--------------------------------------------------------------------------------
 1 | import { List } from "@/components/feed/list";
 2 | import { Colors } from "@/helpers/colors";
 3 | import { StatusBar } from "expo-status-bar";
 4 | import { StyleSheet, View } from "react-native";
 5 | 
 6 | export default function HomeScreen() {
 7 |   return (
 8 |     <View style={styles.container}>
 9 |       <StatusBar style="dark" key="feed" />
10 |       <List />
11 |     </View>
12 |   );
13 | }
14 | 
15 | const styles = StyleSheet.create({
16 |   container: {
17 |     flex: 1,
18 |     backgroundColor: Colors.background
19 |   }
20 | });
21 | 


--------------------------------------------------------------------------------
/apps/mobile/app/(protected)/create.tsx:
--------------------------------------------------------------------------------
 1 | import { CreateScreen } from "@/components/create/screen";
 2 | import { StatusBar } from "expo-status-bar";
 3 | import { StyleSheet, View } from "react-native";
 4 | 
 5 | export default function CreateModal() {
 6 |   return (
 7 |     <View style={styles.container}>
 8 |       <StatusBar hidden />
 9 |       <CreateScreen />
10 |     </View>
11 |   );
12 | }
13 | 
14 | const styles = StyleSheet.create({
15 |   container: {
16 |     flex: 1
17 |   }
18 | });
19 | 


--------------------------------------------------------------------------------
/apps/mobile/assets/fonts/sans-b.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/mobile/assets/fonts/sans-b.ttf


--------------------------------------------------------------------------------
/apps/mobile/assets/fonts/sans-m.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/mobile/assets/fonts/sans-m.ttf


--------------------------------------------------------------------------------
/apps/mobile/assets/fonts/sans-sb.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/mobile/assets/fonts/sans-sb.ttf


--------------------------------------------------------------------------------
/apps/mobile/assets/fonts/sans.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/mobile/assets/fonts/sans.ttf


--------------------------------------------------------------------------------
/apps/mobile/assets/fonts/serif.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/mobile/assets/fonts/serif.ttf


--------------------------------------------------------------------------------
/apps/mobile/assets/images/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/mobile/assets/images/adaptive-icon.png


--------------------------------------------------------------------------------
/apps/mobile/assets/images/auth-el.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/mobile/assets/images/auth-el.png


--------------------------------------------------------------------------------
/apps/mobile/assets/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/mobile/assets/images/icon.png


--------------------------------------------------------------------------------
/apps/mobile/assets/images/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/mobile/assets/images/splash.png


--------------------------------------------------------------------------------
/apps/mobile/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = (api) => {
2 |   api.cache(true);
3 |   return {
4 |     presets: ["babel-preset-expo"]
5 |   };
6 | };
7 | 


--------------------------------------------------------------------------------
/apps/mobile/components/auth/queries.ts:
--------------------------------------------------------------------------------
 1 | import { execute } from "@/helpers/execute";
 2 | import { queryOptions } from "@tanstack/react-query";
 3 | import { ProfileDocument } from "@tape.xyz/indexer";
 4 | 
 5 | export const profileByIdQuery = (forProfileId: string | null) => {
 6 |   return queryOptions({
 7 |     queryKey: ["account", forProfileId],
 8 |     queryFn: () =>
 9 |       execute(ProfileDocument, {
10 |         request: { forProfileId }
11 |       }),
12 |     enabled: Boolean(forProfileId)
13 |   });
14 | };
15 | 


--------------------------------------------------------------------------------
/apps/mobile/components/feed/queries.ts:
--------------------------------------------------------------------------------
 1 | import { execute } from "@/helpers/execute";
 2 | import { infiniteQueryOptions } from "@tanstack/react-query";
 3 | import { FeedDocument, FeedEventItemType } from "@tape.xyz/indexer";
 4 | 
 5 | export const feedQuery = (profileId: string) =>
 6 |   infiniteQueryOptions({
 7 |     queryKey: ["feed", profileId],
 8 |     queryFn: ({ pageParam }) =>
 9 |       execute(FeedDocument, {
10 |         request: {
11 |           where: {
12 |             feedEventItemTypes: [FeedEventItemType.Post],
13 |             for: profileId
14 |           },
15 |           cursor: pageParam
16 |         }
17 |       }),
18 |     enabled: Boolean(profileId),
19 |     initialPageParam: null,
20 |     getNextPageParam: (lastPage) => lastPage.feed.pageInfo.next
21 |   });
22 | 


--------------------------------------------------------------------------------
/apps/mobile/components/shared/external-link.tsx:
--------------------------------------------------------------------------------
 1 | import { type Href, Link } from "expo-router";
 2 | import { openBrowserAsync } from "expo-web-browser";
 3 | import type { ComponentProps } from "react";
 4 | import { Platform } from "react-native";
 5 | 
 6 | type Props = Omit<ComponentProps<typeof Link>, "href"> & { href: string };
 7 | 
 8 | export const ExternalLink = ({ href, ...rest }: Props) => {
 9 |   return (
10 |     <Link
11 |       target="_blank"
12 |       {...rest}
13 |       suppressHighlighting
14 |       href={href as Href}
15 |       onPress={async (event) => {
16 |         if (Platform.OS !== "web") {
17 |           event.preventDefault();
18 |           await openBrowserAsync(href);
19 |         }
20 |       }}
21 |     />
22 |   );
23 | };
24 | 


--------------------------------------------------------------------------------
/apps/mobile/eas.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "cli": {
 3 |     "version": ">= 12.6.2",
 4 |     "appVersionSource": "remote"
 5 |   },
 6 |   "build": {
 7 |     "development": {
 8 |       "distribution": "internal",
 9 |       "ios": {
10 |         "credentialsSource": "remote"
11 |       }
12 |     },
13 |     "preview": {
14 |       "distribution": "internal"
15 |     },
16 |     "production": {
17 |       "autoIncrement": true
18 |     }
19 |   },
20 |   "submit": {
21 |     "production": {}
22 |   }
23 | }
24 | 


--------------------------------------------------------------------------------
/apps/mobile/helpers/colors.ts:
--------------------------------------------------------------------------------
 1 | export const Colors = {
 2 |   text: "#000000",
 3 |   textSecondary: "#22222280",
 4 |   white: "#ffffff",
 5 |   black: "#000000",
 6 |   buttonText: "#000000",
 7 |   background: "#F5F5F5",
 8 |   border: "#22222220",
 9 |   link: "#3F88C5"
10 | };
11 | 


--------------------------------------------------------------------------------
/apps/mobile/helpers/haptics.ts:
--------------------------------------------------------------------------------
1 | import { ImpactFeedbackStyle, impactAsync } from "expo-haptics";
2 | 
3 | export const haptic = () => {
4 |   impactAsync(ImpactFeedbackStyle.Soft);
5 | };
6 | 


--------------------------------------------------------------------------------
/apps/mobile/helpers/normalize-font.ts:
--------------------------------------------------------------------------------
 1 | import { Dimensions, PixelRatio, Platform } from "react-native";
 2 | 
 3 | export const { width: windowWidth, height: windowHeight } =
 4 |   Dimensions.get("window");
 5 | 
 6 | // based on iphone 5s's scale
 7 | const scale = windowWidth / 320;
 8 | 
 9 | const normalizeFont = (size: number) => {
10 |   const newSize = size * scale;
11 |   if (Platform.OS === "ios") {
12 |     return Math.round(PixelRatio.roundToNearestPixel(newSize));
13 |   }
14 |   return Math.round(PixelRatio.roundToNearestPixel(newSize)) - 2;
15 | };
16 | 
17 | export default normalizeFont;
18 | 


--------------------------------------------------------------------------------
/apps/mobile/metro.config.js:
--------------------------------------------------------------------------------
 1 | const { getDefaultConfig } = require("expo/metro-config");
 2 | const { resolve } = require("node:path");
 3 | 
 4 | const projectRoot = __dirname;
 5 | const monorepoRoot = resolve(projectRoot, "../..");
 6 | 
 7 | const config = getDefaultConfig(projectRoot);
 8 | 
 9 | config.watchFolders = [monorepoRoot];
10 | config.resolver.nodeModulesPaths = [
11 |   resolve(projectRoot, "node_modules"),
12 |   resolve(monorepoRoot, "node_modules")
13 | ];
14 | config.resolver.disableHierarchicalLookup = true;
15 | 
16 | module.exports = config;
17 | 


--------------------------------------------------------------------------------
/apps/mobile/store/device.tsx:
--------------------------------------------------------------------------------
 1 | import { create } from "zustand";
 2 | 
 3 | type State = {
 4 |   feedItemWidth: number;
 5 |   setFeedItemWidth: (feedItemWidth: number) => void;
 6 | };
 7 | 
 8 | export const useDevice = create<State>()((set) => ({
 9 |   feedItemWidth: 0,
10 |   setFeedItemWidth: (feedItemWidth) => set({ feedItemWidth })
11 | }));
12 | 


--------------------------------------------------------------------------------
/apps/mobile/store/profile.tsx:
--------------------------------------------------------------------------------
 1 | import type { Profile } from "@tape.xyz/indexer";
 2 | import { create } from "zustand";
 3 | 
 4 | type State = {
 5 |   profile: Profile | null;
 6 |   setProfile: (profile: Profile) => void;
 7 | };
 8 | 
 9 | export const useActiveProfile = create<State>()((set) => ({
10 |   profile: null,
11 |   setProfile: (profile) => set({ profile })
12 | }));
13 | 


--------------------------------------------------------------------------------
/apps/mobile/tsconfig.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "extends": "expo/tsconfig.base",
 3 |   "compilerOptions": {
 4 |     "strict": true,
 5 |     "paths": {
 6 |       "@/*": ["./*"]
 7 |     }
 8 |   },
 9 |   "include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts"]
10 | }
11 | 


--------------------------------------------------------------------------------
/apps/og/.dockerignore:
--------------------------------------------------------------------------------
 1 | node_modules
 2 | .next
 3 | .env.example
 4 | .openzeppelin
 5 | artifacts
 6 | cache
 7 | coverage
 8 | README.md
 9 | .git
10 | .dockerignore
11 | 


--------------------------------------------------------------------------------
/apps/og/.gitignore:
--------------------------------------------------------------------------------
 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
 2 | 
 3 | # dependencies
 4 | /node_modules
 5 | /.pnp
 6 | .pnp.js
 7 | .yarn/install-state.gz
 8 | 
 9 | # testing
10 | /coverage
11 | 
12 | # next.js
13 | /.next/
14 | /out/
15 | 
16 | # production
17 | /build
18 | 
19 | # misc
20 | .DS_Store
21 | *.pem
22 | 
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 | 
28 | # local env files
29 | .env*.local
30 | 
31 | # vercel
32 | .vercel
33 | 
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 | 


--------------------------------------------------------------------------------
/apps/og/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 |   output: "standalone",
4 |   poweredByHeader: false
5 | };
6 | 
7 | export default nextConfig;
8 | 


--------------------------------------------------------------------------------
/apps/og/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/og/src/app/favicon.ico


--------------------------------------------------------------------------------
/apps/og/src/app/layout.tsx:
--------------------------------------------------------------------------------
 1 | import type { Metadata } from "next";
 2 | import type React from "react";
 3 | 
 4 | import common from "@/common";
 5 | 
 6 | export const metadata: Metadata = common;
 7 | 
 8 | const RootLayout = ({ children }: { children: React.ReactNode }) => {
 9 |   return (
10 |     <html lang="en">
11 |       <body>{children}</body>
12 |     </html>
13 |   );
14 | };
15 | 
16 | export default RootLayout;
17 | 


--------------------------------------------------------------------------------
/apps/og/src/common.ts:
--------------------------------------------------------------------------------
 1 | import {
 2 |   OG_IMAGE,
 3 |   TAPE_APP_DESCRIPTION,
 4 |   TAPE_APP_NAME,
 5 |   TAPE_WEBSITE_URL
 6 | } from "@tape.xyz/constants";
 7 | import type { Metadata } from "next";
 8 | 
 9 | const common: Metadata = {
10 |   title: TAPE_APP_NAME,
11 |   description: TAPE_APP_DESCRIPTION,
12 |   metadataBase: new URL(TAPE_WEBSITE_URL),
13 |   openGraph: {
14 |     type: "website",
15 |     siteName: TAPE_APP_NAME,
16 |     images: [OG_IMAGE],
17 |     title: TAPE_APP_NAME,
18 |     description: TAPE_APP_DESCRIPTION,
19 |     url: new URL(TAPE_WEBSITE_URL)
20 |   },
21 |   twitter: {
22 |     card: "summary_large_image",
23 |     title: TAPE_APP_NAME,
24 |     description: TAPE_APP_DESCRIPTION,
25 |     images: [OG_IMAGE]
26 |   }
27 | };
28 | 
29 | export default common;
30 | 


--------------------------------------------------------------------------------
/apps/og/tsconfig.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "extends": "@tape.xyz/tsconfig/nextjs.json",
 3 |   "compilerOptions": {
 4 |     "baseUrl": ".",
 5 |     "target": "es5",
 6 |     "lib": ["dom", "dom.iterable", "esnext"],
 7 |     "allowJs": true,
 8 |     "skipLibCheck": true,
 9 |     "strict": true,
10 |     "noEmit": true,
11 |     "esModuleInterop": true,
12 |     "module": "esnext",
13 |     "moduleResolution": "bundler",
14 |     "resolveJsonModule": true,
15 |     "isolatedModules": true,
16 |     "jsx": "preserve",
17 |     "incremental": true,
18 |     "plugins": [
19 |       {
20 |         "name": "next"
21 |       }
22 |     ],
23 |     "paths": {
24 |       "@/*": ["./src/*"]
25 |     }
26 |   },
27 |   "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
28 |   "exclude": ["node_modules"]
29 | }
30 | 


--------------------------------------------------------------------------------
/apps/web-vite/public/fonts/mono.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/web-vite/public/fonts/mono.woff2


--------------------------------------------------------------------------------
/apps/web-vite/public/fonts/sans.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/web-vite/public/fonts/sans.woff2


--------------------------------------------------------------------------------
/apps/web-vite/public/fonts/serif.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/web-vite/public/fonts/serif.woff2


--------------------------------------------------------------------------------
/apps/web-vite/public/images/hero.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/web-vite/public/images/hero.webp


--------------------------------------------------------------------------------
/apps/web-vite/src/components/create/advanced.tsx:
--------------------------------------------------------------------------------
 1 | import { ShowMore } from "@tape.xyz/winder";
 2 | 
 3 | export const Advanced = () => {
 4 |   return (
 5 |     <div>
 6 |       <ShowMore content="Advanced options" onToggle={() => {}} />
 7 |     </div>
 8 |   );
 9 | };
10 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/create/drag-and-drop.ts:
--------------------------------------------------------------------------------
 1 | import { useState } from "react";
 2 | 
 3 | export const useDragAndDrop = () => {
 4 |   const [dragging, setDragging] = useState(false);
 5 | 
 6 |   const onDragOver = (e: React.SyntheticEvent) => {
 7 |     e.preventDefault();
 8 |     setDragging(true);
 9 |   };
10 | 
11 |   const onDragLeave = () => setDragging(false);
12 | 
13 |   return {
14 |     dragging,
15 |     setDragging,
16 |     onDragOver,
17 |     onDragLeave
18 |   };
19 | };
20 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/create/page.tsx:
--------------------------------------------------------------------------------
 1 | import { Details } from "./details";
 2 | import DropZone from "./drop-zone";
 3 | 
 4 | export const CreatePage = () => {
 5 |   return (
 6 |     <div className="flex min-h-[calc(100vh-60px)] flex-col items-center rounded-card bg-theme">
 7 |       <div className="flex w-full max-w-screen-lg flex-wrap gap-14 px-2 py-20 md:flex-nowrap">
 8 |         <DropZone />
 9 |         <Details />
10 |       </div>
11 |     </div>
12 |   );
13 | };
14 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/embed/page.tsx:
--------------------------------------------------------------------------------
1 | import { PostEmbed } from "./post";
2 | 
3 | export const EmbedPage = () => {
4 |   return <PostEmbed />;
5 | };
6 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/home/page.tsx:
--------------------------------------------------------------------------------
 1 | import { About } from "./about";
 2 | import { Feed } from "./feed";
 3 | import { Hero } from "./hero";
 4 | import { Invite } from "./invite";
 5 | import { Users } from "./users";
 6 | 
 7 | export const HomePage = () => {
 8 |   return (
 9 |     <div className="space-y-1.5">
10 |       <Hero />
11 |       <Invite />
12 |       <Feed />
13 |       <About />
14 |       <Users />
15 |     </div>
16 |   );
17 | };
18 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/mod/page.tsx:
--------------------------------------------------------------------------------
 1 | import { Posts } from "./posts";
 2 | 
 3 | export const ModPage = () => {
 4 |   return (
 5 |     <div className="flex min-h-screen flex-col items-center 2xl:container">
 6 |       <Posts />
 7 |     </div>
 8 |   );
 9 | };
10 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/settings/me.tsx:
--------------------------------------------------------------------------------
1 | export const Me = () => {
2 |   return (
3 |     <div>
4 |       <h6>Me</h6>
5 |       <p className="text-muted">Basic Information about Me</p>
6 |     </div>
7 |   );
8 | };
9 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/shared/auth/links.tsx:
--------------------------------------------------------------------------------
 1 | import { Link } from "@tanstack/react-router";
 2 | 
 3 | export const Links = () => {
 4 |   return (
 5 |     <div className="flex items-center space-x-2.5 text-muted text-xs [&>a]:transition-colors [&>a]:hover:text-primary">
 6 |       <span>&copy; {new Date().getFullYear()} Tape</span>
 7 |       <div className="h-3 w-[1px] rounded-sm bg-primary/10" />
 8 |       <Link to="/privacy">Privacy</Link>
 9 |       <div className="h-3 w-[1px] rounded-sm bg-primary/10" />
10 |       <Link to="/terms">Terms</Link>
11 |     </div>
12 |   );
13 | };
14 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/shared/footer/index.tsx:
--------------------------------------------------------------------------------
 1 | import { Logo } from "../header/logo";
 2 | import { Links } from "./links";
 3 | import { NetworkState } from "./network";
 4 | import { Socials } from "./socials";
 5 | import { Status } from "./status";
 6 | 
 7 | export const Footer = () => {
 8 |   return (
 9 |     <footer className="flex flex-wrap justify-between gap-5 px-5 py-[26px] md:flex-nowrap">
10 |       <div className="flex w-1/3 gap-6">
11 |         <Logo />
12 |         <Socials />
13 |       </div>
14 | 
15 |       <Links />
16 | 
17 |       <div className="hidden w-1/3 justify-end gap-6 lg:flex">
18 |         <NetworkState />
19 |         <Status />
20 |       </div>
21 |     </footer>
22 |   );
23 | };
24 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/shared/footer/status.tsx:
--------------------------------------------------------------------------------
 1 | import { TAPE_STATUS_PAGE } from "@tape.xyz/constants";
 2 | import { Button } from "@tape.xyz/winder";
 3 | 
 4 | export const Status = () => {
 5 |   return (
 6 |     <a href={TAPE_STATUS_PAGE} target="_blank" rel="noreferrer">
 7 |       <Button variant="secondary">
 8 |         <span className="flex items-center space-x-[10px]">
 9 |           <span className="relative flex size-1.5">
10 |             <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-[#2A59FF]" />
11 |             <span className="relative inline-flex size-1.5 rounded-full bg-[#2A59FF]" />
12 |           </span>
13 |           <span>All systems normal</span>
14 |         </span>
15 |       </Button>
16 |     </a>
17 |   );
18 | };
19 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/shared/header/index.tsx:
--------------------------------------------------------------------------------
 1 | import { SearchTrigger } from "../search";
 2 | import { LeftSection } from "./left";
 3 | import { RightSection } from "./right";
 4 | 
 5 | export const Header = () => {
 6 |   return (
 7 |     <header className="sticky inset-x-0 top-0 z-50 flex h-[52px] w-full items-center justify-between gap-1.5 px-5 py-2">
 8 |       <LeftSection />
 9 |       <SearchTrigger />
10 |       <RightSection />
11 |     </header>
12 |   );
13 | };
14 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/shared/header/logo.tsx:
--------------------------------------------------------------------------------
 1 | import { Link } from "@tanstack/react-router";
 2 | import { memo } from "react";
 3 | import { TapeSvg } from "../tape-svg";
 4 | 
 5 | export const Logo = memo(() => {
 6 |   return (
 7 |     <Link
 8 |       to="/"
 9 |       onContextMenu={(e) => {
10 |         e.preventDefault();
11 |         window.open("/winder#brand", "_blank");
12 |       }}
13 |     >
14 |       <div className="flex h-9 items-center rounded-custom border border-custom px-3.5 pt-2.5 pb-2">
15 |         <TapeSvg className="h-5 text-primary" />
16 |       </div>
17 |     </Link>
18 |   );
19 | });
20 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/shared/shimmers/button.tsx:
--------------------------------------------------------------------------------
 1 | import { tw } from "@tape.xyz/winder";
 2 | 
 3 | export const ButtonShimmer = ({
 4 |   className = "h-11"
 5 | }: { className?: string }) => {
 6 |   return (
 7 |     <div className="w-full animate-shimmer">
 8 |       <div className={tw("w-full rounded-custom bg-secondary", className)} />
 9 |     </div>
10 |   );
11 | };
12 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/u/actions.tsx:
--------------------------------------------------------------------------------
 1 | import { Button, DotsThreeVertical, UserPlus } from "@tape.xyz/winder";
 2 | 
 3 | export const Actions = () => {
 4 |   return (
 5 |     <>
 6 |       <Button variant="secondary" size="icon">
 7 |         <DotsThreeVertical className="size-5" weight="bold" />
 8 |       </Button>
 9 |       <Button>
10 |         <span className="inline-flex space-x-1.5">
11 |           <span>Follow</span>
12 |           <UserPlus className="size-5" />
13 |         </span>
14 |       </Button>
15 |     </>
16 |   );
17 | };
18 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/u/page.tsx:
--------------------------------------------------------------------------------
 1 | import { Profile } from "./profile";
 2 | 
 3 | export const ProfilePage = () => {
 4 |   return (
 5 |     <div className="flex min-h-screen flex-col overflow-hidden rounded-card bg-theme">
 6 |       <Profile />
 7 |     </div>
 8 |   );
 9 | };
10 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/watch/creator.tsx:
--------------------------------------------------------------------------------
 1 | import { Account } from "./account";
 2 | import { Comments } from "./comments";
 3 | 
 4 | export const CreatorAndComments = () => {
 5 |   return (
 6 |     <div className="flex-1 space-y-5">
 7 |       <Account />
 8 |       <Comments />
 9 |     </div>
10 |   );
11 | };
12 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/watch/stats-and-actions.tsx:
--------------------------------------------------------------------------------
 1 | import { Actions } from "./actions";
 2 | import { Stats } from "./stats";
 3 | 
 4 | export const StatsAndActions = () => {
 5 |   return (
 6 |     <div className="flex flex-wrap items-center justify-between gap-5">
 7 |       <Stats />
 8 |       <Actions />
 9 |     </div>
10 |   );
11 | };
12 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/components/winder/page.tsx:
--------------------------------------------------------------------------------
 1 | import { Content } from "./content";
 2 | import { Header } from "./header";
 3 | import { Sidebar } from "./sidebar";
 4 | 
 5 | export const WinderPage = () => {
 6 |   return (
 7 |     <div className="container mx-auto min-h-screen max-w-6xl overflow-x-hidden md:overflow-x-visible">
 8 |       <Header />
 9 |       <div className="min-w-[300px] md:grid md:grid-cols-[250px_1fr]">
10 |         <Sidebar />
11 |         <Content />
12 |       </div>
13 |     </div>
14 |   );
15 | };
16 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/helpers/format-number.ts:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * @param bytes number of bytes
 3 |  * @returns formatted bytes (eg. 1000 bytes, 1 KB, 1 MB, 1 GB, 1 TB)
 4 |  */
 5 | export const formatBytes = (bytes: number) => {
 6 |   if (!bytes || bytes === 0) return "0 bytes";
 7 |   if (bytes < 1_000) {
 8 |     return `${bytes} bytes`;
 9 |   }
10 | 
11 |   const mb = bytes / 1_000_000;
12 |   if (mb < 1) {
13 |     const kb = bytes / 1_000;
14 |     return `${kb.toFixed(2)} KB`;
15 |   }
16 | 
17 |   const gb = mb / 1_000;
18 |   if (gb >= 1) {
19 |     return `${gb.toFixed(2)} GB`;
20 |   }
21 | 
22 |   return `${mb.toFixed(2)} MB`;
23 | };
24 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/helpers/parse-jwt.ts:
--------------------------------------------------------------------------------
 1 | type ReturnType = {
 2 |   sub: string;
 3 |   iat: number;
 4 |   exp: number;
 5 | };
 6 | 
 7 | const hasBuffer = typeof Buffer === "undefined";
 8 | const decoded = (str: string): string =>
 9 |   hasBuffer ? atob(str) : Buffer.from(str, "base64").toString("binary");
10 | 
11 | export const parseJwt = (token: string): ReturnType => {
12 |   try {
13 |     const splited = token.split(".")[1] ?? "";
14 |     return JSON.parse(decoded(splited));
15 |   } catch {
16 |     return { sub: "", iat: 0, exp: 0 };
17 |   }
18 | };
19 | 
20 | export const shouldRefreshTokens = (token = "") => {
21 |   const { exp } = parseJwt(token);
22 |   return Date.now() >= exp * 1000;
23 | };
24 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/main.css:
--------------------------------------------------------------------------------
 1 | @import "@tape.xyz/winder/src/winder.css";
 2 | @source "../../../packages/winder/**/*.{ts,tsx}";
 3 | 
 4 | * {
 5 |   scrollbar-color: var(--scrollbar-thumb) transparent;
 6 | }
 7 | 
 8 | html {
 9 |   font-family: var(--tape-font-sans);
10 |   @apply scroll-smooth bg-site antialiased text-primary;
11 | }
12 | 
13 | button {
14 |   @apply cursor-pointer;
15 | }
16 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/providers/animations.tsx:
--------------------------------------------------------------------------------
1 | import { domMax } from "motion/react";
2 | 
3 | export default domMax;
4 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/providers/log.tsx:
--------------------------------------------------------------------------------
 1 | import { useEffect, useRef } from "react";
 2 | 
 3 | export const Log = () => {
 4 |   const ref = useRef(false);
 5 |   useEffect(() => {
 6 |     if (ref.current) return;
 7 |     console.info(`
 8 | ░▒▓███████▓▒░░▒▓██████▓▒░░▒▓███████▓▒░░▒▓██████▓▒░ 
 9 |    ░▒▓█▓▒░  ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░        
10 |    ░▒▓█▓▒░  ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░        
11 |    ░▒▓█▓▒░  ░▒▓████████▓▒░▒▓███████▓▒░░▒▓█████▓▒░   
12 |    ░▒▓█▓▒░  ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░      ░▒▓█▓▒░        
13 |    ░▒▓█▓▒░  ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░      ░▒▓█▓▒░        
14 |    ░▒▓█▓▒░  ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░      ░▒▓██████▓▒░ 
15 |                                                     
16 | We are open-source → https://github.com/tapexyz`);
17 |     ref.current = true;
18 |   }, []);
19 |   return null;
20 | };
21 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/queries/notification.tsx:
--------------------------------------------------------------------------------
 1 | import { execute } from "@/helpers/execute";
 2 | import { infiniteQueryOptions, useInfiniteQuery } from "@tanstack/react-query";
 3 | import { NotificationsDocument } from "@tape.xyz/indexer";
 4 | 
 5 | export const notificationsQuery = infiniteQueryOptions({
 6 |   queryKey: ["notifications"],
 7 |   queryFn: ({ pageParam }) =>
 8 |     execute({
 9 |       query: NotificationsDocument,
10 |       variables: {
11 |         request: {
12 |           cursor: pageParam
13 |         }
14 |       }
15 |     }),
16 |   initialPageParam: null,
17 |   getNextPageParam: (lastPage) => lastPage.notifications.pageInfo.next
18 | });
19 | export const useNotificationsQuery = () => useInfiniteQuery(notificationsQuery);
20 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_auth-hoc/sign-in.tsx:
--------------------------------------------------------------------------------
1 | import { SignInPage } from "@/components/sign-in/page";
2 | import { createFileRoute } from "@tanstack/react-router";
3 | 
4 | export const Route = createFileRoute("/_auth-hoc/sign-in")({
5 |   component: SignInPage
6 | });
7 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_auth-hoc/sign-up.tsx:
--------------------------------------------------------------------------------
1 | import { SignUpPage } from "@/components/sign-up/page";
2 | import { createFileRoute } from "@tanstack/react-router";
3 | 
4 | export const Route = createFileRoute("/_auth-hoc/sign-up")({
5 |   component: SignUpPage
6 | });
7 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_layout-hoc.tsx:
--------------------------------------------------------------------------------
 1 | import { Footer } from "@/components/shared/footer";
 2 | import { Header } from "@/components/shared/header";
 3 | import { meQuery } from "@/queries/account";
 4 | import { Outlet, createFileRoute } from "@tanstack/react-router";
 5 | 
 6 | export const Route = createFileRoute("/_layout-hoc")({
 7 |   loader: ({ context }) => context.rqClient.ensureQueryData(meQuery),
 8 |   component: () => {
 9 |     return (
10 |       <main className="container mx-auto flex min-h-screen max-w-screen-2xl flex-col px-3">
11 |         <Header />
12 |         <Outlet />
13 |         <Footer />
14 |       </main>
15 |     );
16 |   }
17 | });
18 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_layout-hoc/_home-hoc.tsx:
--------------------------------------------------------------------------------
 1 | import { FloatingNav } from "@/components/shared/floating-nav";
 2 | import { Outlet, createFileRoute } from "@tanstack/react-router";
 3 | 
 4 | export const Route = createFileRoute("/_layout-hoc/_home-hoc")({
 5 |   component: () => {
 6 |     return (
 7 |       <>
 8 |         <Outlet />
 9 |         <FloatingNav />
10 |       </>
11 |     );
12 |   }
13 | });
14 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_layout-hoc/_home-hoc/explore.tsx:
--------------------------------------------------------------------------------
 1 | import { ExplorePage } from "@/components/explore/page";
 2 | import { createFileRoute } from "@tanstack/react-router";
 3 | 
 4 | const media = ["all", "videos", "livestreams", "audios"] as const;
 5 | 
 6 | type ExploreSearchParams = {
 7 |   media: (typeof media)[number];
 8 | };
 9 | 
10 | export const Route = createFileRoute("/_layout-hoc/_home-hoc/explore")({
11 |   validateSearch: (search: Record<string, unknown>): ExploreSearchParams => {
12 |     return {
13 |       media: media.includes(search.media as ExploreSearchParams["media"])
14 |         ? (search.media as ExploreSearchParams["media"])
15 |         : "all"
16 |     };
17 |   },
18 |   component: ExplorePage
19 | });
20 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_layout-hoc/_home-hoc/following.tsx:
--------------------------------------------------------------------------------
1 | import { FollowingPage } from "@/components/following/page";
2 | import { createFileRoute } from "@tanstack/react-router";
3 | 
4 | export const Route = createFileRoute("/_layout-hoc/_home-hoc/following")({
5 |   component: FollowingPage
6 | });
7 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_layout-hoc/_home-hoc/index.tsx:
--------------------------------------------------------------------------------
1 | import { HomePage } from "@/components/home/page";
2 | import { createFileRoute } from "@tanstack/react-router";
3 | 
4 | export const Route = createFileRoute("/_layout-hoc/_home-hoc/")({
5 |   component: HomePage
6 | });
7 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_layout-hoc/_settings-hoc.tsx:
--------------------------------------------------------------------------------
 1 | import { Sidebar } from "@/components/settings/sidebar";
 2 | import { Outlet, createFileRoute } from "@tanstack/react-router";
 3 | 
 4 | export const Route = createFileRoute("/_layout-hoc/_settings-hoc")({
 5 |   component: () => {
 6 |     return (
 7 |       <div className="flex min-h-[calc(100vh-60px)] flex-col items-center rounded-card bg-theme">
 8 |         <div className="flex w-full max-w-screen-lg flex-1 gap-12 p-2 lg:py-10">
 9 |           <Sidebar />
10 |           <Outlet />
11 |         </div>
12 |       </div>
13 |     );
14 |   }
15 | });
16 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_layout-hoc/_settings-hoc/settings/me.tsx:
--------------------------------------------------------------------------------
1 | import { Me } from "@/components/settings/me";
2 | import { createFileRoute } from "@tanstack/react-router";
3 | 
4 | export const Route = createFileRoute("/_layout-hoc/_settings-hoc/settings/me")({
5 |   component: Me
6 | });
7 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_layout-hoc/create/index.tsx:
--------------------------------------------------------------------------------
1 | import { CreatePage } from "@/components/create/page";
2 | import { createFileRoute } from "@tanstack/react-router";
3 | 
4 | export const Route = createFileRoute("/_layout-hoc/create/")({
5 |   component: CreatePage
6 | });
7 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_layout-hoc/feed/index.tsx:
--------------------------------------------------------------------------------
 1 | import { FeedPage } from "@/components/feed/page";
 2 | import { bytesQuery } from "@/queries/post";
 3 | import { createFileRoute } from "@tanstack/react-router";
 4 | 
 5 | export const Route = createFileRoute("/_layout-hoc/feed/")({
 6 |   loader: ({ context: { rqClient } }) => {
 7 |     return rqClient.ensureInfiniteQueryData(bytesQuery);
 8 |   },
 9 |   component: FeedPage
10 | });
11 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_layout-hoc/mod/index.tsx:
--------------------------------------------------------------------------------
1 | import { ModPage } from "@/components/mod/page";
2 | import { createFileRoute } from "@tanstack/react-router";
3 | 
4 | export const Route = createFileRoute("/_layout-hoc/mod/")({
5 |   component: ModPage
6 | });
7 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_layout-hoc/privacy/index.tsx:
--------------------------------------------------------------------------------
1 | import { PrivacyPage } from "@/components/privacy/page";
2 | import { createFileRoute } from "@tanstack/react-router";
3 | 
4 | export const Route = createFileRoute("/_layout-hoc/privacy/")({
5 |   component: PrivacyPage
6 | });
7 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_layout-hoc/terms/index.tsx:
--------------------------------------------------------------------------------
1 | import { TermsPage } from "@/components/terms/page";
2 | import { createFileRoute } from "@tanstack/react-router";
3 | 
4 | export const Route = createFileRoute("/_layout-hoc/terms/")({
5 |   component: TermsPage
6 | });
7 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/_layout-hoc/watch/$postId.tsx:
--------------------------------------------------------------------------------
 1 | import { WatchPage } from "@/components/watch/page";
 2 | import { commentsQuery } from "@/queries/comment";
 3 | import { postQuery } from "@/queries/post";
 4 | import { createFileRoute } from "@tanstack/react-router";
 5 | import { Spinner } from "@tape.xyz/winder";
 6 | 
 7 | export const Route = createFileRoute("/_layout-hoc/watch/$postId")({
 8 |   loader: ({ context: { rqClient }, params: { postId } }) => {
 9 |     rqClient.ensureQueryData(postQuery(postId));
10 |     return rqClient.ensureInfiniteQueryData(commentsQuery(postId));
11 |   },
12 |   pendingComponent: () => (
13 |     <div className="grid min-h-screen place-items-center">
14 |       <Spinner />
15 |     </div>
16 |   ),
17 |   component: WatchPage
18 | });
19 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/embed/$postId.tsx:
--------------------------------------------------------------------------------
 1 | import { EmbedPage } from "@/components/embed/page";
 2 | import { postQuery } from "@/queries/post";
 3 | import { createFileRoute } from "@tanstack/react-router";
 4 | 
 5 | type EmbedSearchParams = {
 6 |   t: number;
 7 |   loop: number;
 8 |   autoplay: number;
 9 | };
10 | 
11 | export const Route = createFileRoute("/embed/$postId")({
12 |   loader: ({ context: { rqClient }, params: { postId } }) => {
13 |     return rqClient.ensureQueryData(postQuery(postId));
14 |   },
15 |   validateSearch: (search: Record<string, unknown>): EmbedSearchParams => {
16 |     return {
17 |       t: Number(search.t) || 0,
18 |       loop: Number(search.loop) || 0,
19 |       autoplay: Number(search.autoplay) || 1
20 |     };
21 |   },
22 |   component: EmbedPage
23 | });
24 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/open/index.tsx:
--------------------------------------------------------------------------------
1 | import { OpenPage } from "@/components/open/page";
2 | import { createFileRoute } from "@tanstack/react-router";
3 | 
4 | export const Route = createFileRoute("/open/")({
5 |   component: OpenPage
6 | });
7 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/routes/winder/index.tsx:
--------------------------------------------------------------------------------
1 | import { WinderPage } from "@/components/winder/page";
2 | import { createFileRoute } from "@tanstack/react-router";
3 | 
4 | export const Route = createFileRoute("/winder/")({
5 |   component: WinderPage
6 | });
7 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/store/scroll.tsx:
--------------------------------------------------------------------------------
 1 | import type { RefObject } from "react";
 2 | import { create } from "zustand";
 3 | 
 4 | interface ScrollState {
 5 |   scrollRef: RefObject<HTMLDivElement> | null;
 6 |   setScrollRef: (ref: RefObject<HTMLDivElement>) => void;
 7 | }
 8 | 
 9 | export const useScrollStore = create<ScrollState>((set) => ({
10 |   scrollRef: null,
11 |   setScrollRef: (ref) => set({ scrollRef: ref })
12 | }));
13 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | /// <reference types="vite/client" />
2 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/worker/build.mjs:
--------------------------------------------------------------------------------
 1 | import esbuild from "esbuild";
 2 | 
 3 | esbuild.build({
 4 |   allowOverwrite: true,
 5 |   bundle: true,
 6 |   entryPoints: ["src/worker/sw.ts"],
 7 |   format: "esm",
 8 |   minify: true,
 9 |   outfile: "dist/sw.js",
10 |   platform: "browser",
11 |   target: "esnext",
12 |   define: { "process.env.NODE_ENV": '"production"' }
13 | });
14 | 


--------------------------------------------------------------------------------
/apps/web-vite/src/worker/sw.ts:
--------------------------------------------------------------------------------
 1 | import { cacheNewAssets, deleteOldCaches } from "./cache";
 2 | import { pushEventToQueue } from "./events";
 3 | 
 4 | declare let self: ServiceWorkerGlobalScope;
 5 | 
 6 | // Activate the new service worker immediately
 7 | self.addEventListener("install", () => {
 8 |   self.skipWaiting();
 9 | });
10 | 
11 | // Take control of all clients (open tabs, etc.) immediately
12 | self.addEventListener("activate", (event: ExtendableEvent) => {
13 |   event.waitUntil(deleteOldCaches().then(() => self.clients.claim()));
14 | });
15 | 
16 | self.addEventListener("fetch", (event) => {
17 |   cacheNewAssets(event);
18 | });
19 | 
20 | self.addEventListener("message", (event) => {
21 |   pushEventToQueue(event);
22 | });
23 | 


--------------------------------------------------------------------------------
/apps/web-vite/tsconfig.app.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "extends": "@tape.xyz/tsconfig/react.json",
 3 |   "compilerOptions": {
 4 |     "target": "ES2020",
 5 |     "useDefineForClassFields": true,
 6 |     "module": "ESNext",
 7 |     "moduleResolution": "bundler",
 8 |     "moduleDetection": "force",
 9 |     "allowImportingTsExtensions": true,
10 |     "noEmit": true,
11 |     "baseUrl": ".",
12 |     "lib": ["DOM", "ESNext", "WebWorker"],
13 |     "outDir": "dist",
14 |     "paths": {
15 |       "@/*": ["./src/*"]
16 |     }
17 |   },
18 |   "include": ["src"]
19 | }
20 | 


--------------------------------------------------------------------------------
/apps/web-vite/tsconfig.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "files": [],
 3 |   "compilerOptions": {
 4 |     "baseUrl": ".",
 5 |     "paths": {
 6 |       "@/*": ["./src/*"]
 7 |     }
 8 |   },
 9 |   "references": [
10 |     { "path": "./tsconfig.app.json" },
11 |     { "path": "./tsconfig.node.json" }
12 |   ]
13 | }
14 | 


--------------------------------------------------------------------------------
/apps/web-vite/tsconfig.node.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "extends": "@tape.xyz/tsconfig/base.json",
 3 |   "compilerOptions": {
 4 |     "target": "ES2022",
 5 |     "lib": ["ES2023"],
 6 |     "module": "ESNext",
 7 |     "skipLibCheck": true,
 8 |     "moduleResolution": "bundler",
 9 |     "allowImportingTsExtensions": true,
10 |     "isolatedModules": true,
11 |     "moduleDetection": "force",
12 |     "noEmit": true
13 |   },
14 |   "include": ["vite.config.ts"]
15 | }
16 | 


--------------------------------------------------------------------------------
/apps/web-vite/tsr.config.json:
--------------------------------------------------------------------------------
1 | {
2 |   "autoCodeSplitting": true
3 | }
4 | 


--------------------------------------------------------------------------------
/apps/web/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 |   plugins: {
3 |     tailwindcss: {},
4 |     autoprefixer: {}
5 |   }
6 | };
7 | 


--------------------------------------------------------------------------------
/apps/web/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/apps/web/public/favicon.ico


--------------------------------------------------------------------------------
/apps/web/public/robots.txt:
--------------------------------------------------------------------------------
1 | Sitemap: https://tape.xyz/sitemap.xml
2 | 
3 | User-agent: *
4 | Allow: /*
5 | 
6 | Disallow: /api/*
7 | Disallow: /settings/*
8 | 


--------------------------------------------------------------------------------
/apps/web/public/sitemap.xml:
--------------------------------------------------------------------------------
 1 | <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
 2 |     <sitemap>
 3 |         <loc>https://tape.xyz/sitemaps/profiles/1.xml</loc>
 4 |     </sitemap>
 5 |     <sitemap>
 6 |         <loc>https://tape.xyz/sitemaps/profiles/2.xml</loc>
 7 |     </sitemap>
 8 |     <sitemap>
 9 |         <loc>https://tape.xyz/sitemaps/profiles/3.xml</loc>
10 |     </sitemap>
11 |     <sitemap>
12 |         <loc>https://tape.xyz/sitemaps/videos/1.xml</loc>
13 |     </sitemap>
14 |     <sitemap>
15 |         <loc>https://tape.xyz/sitemaps/videos/2.xml</loc>
16 |     </sitemap>
17 | </sitemapindex>
18 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Bytes/TopOverlay.tsx:
--------------------------------------------------------------------------------
 1 | import type { FC } from "react";
 2 | 
 3 | type Props = {
 4 |   onClickVideo: () => void;
 5 | };
 6 | 
 7 | const TopOverlay: FC<Props> = ({ onClickVideo }) => {
 8 |   return (
 9 |     <div
10 |       role="button"
11 |       tabIndex={0}
12 |       onClick={() => onClickVideo()}
13 |       onKeyDown={() => onClickVideo()}
14 |       className="absolute inset-0 z-[1] w-full cursor-default outline-none"
15 |     />
16 |   );
17 | };
18 | 
19 | export default TopOverlay;
20 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Common/Alert.tsx:
--------------------------------------------------------------------------------
 1 | import { tw } from "@tape.xyz/browser";
 2 | import type { FC, ReactNode } from "react";
 3 | 
 4 | type Props = {
 5 |   children: ReactNode;
 6 |   className?: string;
 7 |   variant?: "warning" | "danger" | "success";
 8 | };
 9 | 
10 | const Alert: FC<Props> = ({ children, variant = "warning", className }) => {
11 |   return (
12 |     <div
13 |       className={tw("flex items-center rounded-xl border p-4", className, {
14 |         "border-yellow-500 border-opacity-50": variant === "warning",
15 |         "border-red-500 border-opacity-50": variant === "danger",
16 |         "border-green-500 border-opacity-50": variant === "success"
17 |       })}
18 |     >
19 |       {children}
20 |     </div>
21 |   );
22 | };
23 | 
24 | export default Alert;
25 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Common/Links/AddressExplorerLink.tsx:
--------------------------------------------------------------------------------
 1 | import { POLYGONSCAN_URL } from "@tape.xyz/constants";
 2 | import Link from "next/link";
 3 | import type { ReactElement } from "react";
 4 | 
 5 | const AddressExplorerLink = ({
 6 |   address,
 7 |   children
 8 | }: {
 9 |   address: string;
10 |   children: ReactElement;
11 | }) => {
12 |   return (
13 |     <Link
14 |       href={`${POLYGONSCAN_URL}/address/${address}`}
15 |       rel="noreferer noreferrer"
16 |       target="_blank"
17 |     >
18 |       {children}
19 |     </Link>
20 |   );
21 | };
22 | 
23 | export default AddressExplorerLink;
24 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Common/Links/ArweaveExplorerLink.tsx:
--------------------------------------------------------------------------------
 1 | import Link from "next/link";
 2 | import type { ReactElement } from "react";
 3 | 
 4 | const ArweaveExplorerLink = ({
 5 |   txId,
 6 |   children
 7 | }: {
 8 |   txId: string;
 9 |   children: ReactElement;
10 | }) => {
11 |   return (
12 |     <Link
13 |       href={`https://api.tape.xyz/gateway/ar/${txId}?pretty`}
14 |       rel="noreferer noreferrer"
15 |       target="_blank"
16 |     >
17 |       {children}
18 |     </Link>
19 |   );
20 | };
21 | 
22 | export default ArweaveExplorerLink;
23 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Common/Links/HashExplorerLink.tsx:
--------------------------------------------------------------------------------
 1 | import { POLYGONSCAN_URL } from "@tape.xyz/constants";
 2 | import Link from "next/link";
 3 | import type { ReactElement } from "react";
 4 | 
 5 | const HashExplorerLink = ({
 6 |   hash,
 7 |   children
 8 | }: {
 9 |   hash: string;
10 |   children: ReactElement;
11 | }) => {
12 |   return (
13 |     <Link
14 |       href={`${POLYGONSCAN_URL}/tx/${hash}`}
15 |       rel="noreferer noreferrer"
16 |       target="_blank"
17 |     >
18 |       {children}
19 |     </Link>
20 |   );
21 | };
22 | 
23 | export default HashExplorerLink;
24 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Common/Links/IPFSLink.tsx:
--------------------------------------------------------------------------------
 1 | import { IPFS_GATEWAY_URL } from "@tape.xyz/constants";
 2 | import Link from "next/link";
 3 | import type { ReactElement } from "react";
 4 | 
 5 | const IPFSLink = ({
 6 |   hash,
 7 |   children
 8 | }: {
 9 |   hash: string;
10 |   children: ReactElement;
11 | }) => {
12 |   return (
13 |     <Link
14 |       href={`${IPFS_GATEWAY_URL}/${hash}`}
15 |       rel="noreferer noreferrer"
16 |       target="_blank"
17 |     >
18 |       {children}
19 |     </Link>
20 |   );
21 | };
22 | 
23 | export default IPFSLink;
24 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Common/Links/TokenExplorerLink.tsx:
--------------------------------------------------------------------------------
 1 | import { POLYGONSCAN_URL } from "@tape.xyz/constants";
 2 | import Link from "next/link";
 3 | import type { ReactElement } from "react";
 4 | 
 5 | const TokenExplorerLink = ({
 6 |   address,
 7 |   children
 8 | }: {
 9 |   address: string;
10 |   children: ReactElement;
11 | }) => {
12 |   return (
13 |     <Link
14 |       href={`${POLYGONSCAN_URL}/token/${address}`}
15 |       rel="noreferer noreferrer"
16 |       target="_blank"
17 |     >
18 |       {children}
19 |     </Link>
20 |   );
21 | };
22 | 
23 | export default TokenExplorerLink;
24 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Common/Providers/ThemeProvider.tsx:
--------------------------------------------------------------------------------
 1 | import { ThemeProvider as NextTheme } from "next-themes";
 2 | import type { FC, ReactNode } from "react";
 3 | 
 4 | type Props = {
 5 |   children: ReactNode;
 6 | };
 7 | 
 8 | const ThemeProvider: FC<Props> = ({ children }) => {
 9 |   return (
10 |     <NextTheme
11 |       defaultTheme="light"
12 |       attribute="class"
13 |       enableSystem
14 |       enableColorScheme
15 |     >
16 |       {children}
17 |     </NextTheme>
18 |   );
19 | };
20 | 
21 | export default ThemeProvider;
22 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Common/matchers/HashtagMatcher.tsx:
--------------------------------------------------------------------------------
 1 | import { Matcher } from "interweave";
 2 | import Link from "next/link";
 3 | import { createElement } from "react";
 4 | 
 5 | const Hashtag = ({ ...props }: any) => {
 6 |   return (
 7 |     <Link href={`/explore/hashtag/${props.display?.slice(1)}`}>
 8 |       {props.display}
 9 |     </Link>
10 |   );
11 | };
12 | 
13 | export class HashtagMatcher extends Matcher {
14 |   replaceWith(match: string, props: any) {
15 |     return createElement(Hashtag, props, match);
16 |   }
17 | 
18 |   asTag(): string {
19 |     return "a";
20 |   }
21 | 
22 |   match(value: string) {
23 |     return this.doMatch(value, /\B#[\w&-i̇]+/, (matches) => {
24 |       return {
25 |         display: matches[0]
26 |       };
27 |     });
28 |   }
29 | }
30 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Create/filereader.d.ts:
--------------------------------------------------------------------------------
1 | declare module "filereader-stream";
2 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Home/index.tsx:
--------------------------------------------------------------------------------
 1 | import { EVENTS } from "@tape.xyz/generic";
 2 | import type { NextPage } from "next";
 3 | import { useEffect } from "react";
 4 | 
 5 | import useSw from "@/hooks/useSw";
 6 | 
 7 | import Feed from "./Feed";
 8 | import TopSection from "./TopSection";
 9 | 
10 | const Home: NextPage = () => {
11 |   const { addEventToQueue } = useSw();
12 | 
13 |   useEffect(() => {
14 |     addEventToQueue(EVENTS.PAGEVIEW, { page: EVENTS.PAGE_VIEW.HOME });
15 |   }, []);
16 | 
17 |   return (
18 |     <div className="container mx-auto max-w-screen-ultrawide">
19 |       <TopSection />
20 |       <Feed />
21 |     </div>
22 |   );
23 | };
24 | 
25 | export default Home;
26 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Profile/BasicInfo/Stats/index.tsx:
--------------------------------------------------------------------------------
 1 | import type { Profile } from "@tape.xyz/lens";
 2 | import type { FC } from "react";
 3 | 
 4 | import Followers from "./Followers";
 5 | import Following from "./Following";
 6 | 
 7 | type Props = {
 8 |   profile: Profile;
 9 | };
10 | 
11 | const Stats: FC<Props> = ({ profile }) => {
12 |   return (
13 |     <div className="flex gap-3">
14 |       <Followers stats={profile.stats} profileId={profile.id} />
15 |       <Following stats={profile.stats} profileId={profile.id} />
16 |     </div>
17 |   );
18 | };
19 | 
20 | export default Stats;
21 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Settings/Allowance/index.tsx:
--------------------------------------------------------------------------------
 1 | import MetaTags from "@/components/Common/MetaTags";
 2 | 
 3 | import ModuleAllowance from "./Modules";
 4 | 
 5 | const Allowance = () => {
 6 |   return (
 7 |     <>
 8 |       <MetaTags title="Allowance" />
 9 |       <ModuleAllowance />
10 |     </>
11 |   );
12 | };
13 | 
14 | export default Allowance;
15 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Settings/Blocked/index.tsx:
--------------------------------------------------------------------------------
 1 | import MetaTags from "@/components/Common/MetaTags";
 2 | 
 3 | import List from "./List";
 4 | 
 5 | const Blocked = () => {
 6 |   return (
 7 |     <>
 8 |       <MetaTags title="Blocked Profiles" />
 9 |       <div className="mb-5 space-y-2">
10 |         <h1 className="font-bold text-brand-400 text-xl">Blocked Profiles</h1>
11 |         <p className="text opacity-80">
12 |           Here is a list of profiles that you have been blocked. You have the
13 |           option to unblock them whenever you wish.
14 |         </p>
15 |       </div>
16 |       <List />
17 |     </>
18 |   );
19 | };
20 | 
21 | export default Blocked;
22 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Settings/Follow/index.tsx:
--------------------------------------------------------------------------------
 1 | import type { Profile } from "@tape.xyz/lens";
 2 | 
 3 | import MetaTags from "@/components/Common/MetaTags";
 4 | 
 5 | import FeeFollow from "./FeeFollow";
 6 | import RevertFollow from "./RevertFollow";
 7 | 
 8 | type Props = {
 9 |   profile: Profile;
10 | };
11 | 
12 | const FollowSettings = ({ profile }: Props) => {
13 |   return (
14 |     <>
15 |       <MetaTags title="Follow Settings" />
16 |       <div className="space-y-4">
17 |         <FeeFollow profile={profile} />
18 |         <RevertFollow profile={profile} />
19 |       </div>
20 |     </>
21 |   );
22 | };
23 | 
24 | export default FollowSettings;
25 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Settings/Handles/index.tsx:
--------------------------------------------------------------------------------
 1 | import MetaTags from "@/components/Common/MetaTags";
 2 | 
 3 | import List from "./List";
 4 | 
 5 | const Handles = () => {
 6 |   return (
 7 |     <div>
 8 |       <MetaTags title="Owned Handles" />
 9 |       <div className="mb-5 space-y-2">
10 |         <h1 className="font-bold text-brand-400 text-xl">Owned Handles</h1>
11 |         <p className="text opacity-80">
12 |           List of handles with profile owned by the connected address.
13 |         </p>
14 |       </div>
15 |       <List />
16 |     </div>
17 |   );
18 | };
19 | 
20 | export default Handles;
21 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Shimmers/ButtonShimmer.tsx:
--------------------------------------------------------------------------------
 1 | import { tw } from "@tape.xyz/browser";
 2 | 
 3 | const ButtonShimmer = ({ className = "h-10" }: { className?: string }) => {
 4 |   return (
 5 |     <div className="w-full animate-shimmer">
 6 |       <div
 7 |         className={tw(
 8 |           "w-full rounded-lg bg-gray-200 dark:bg-gray-800",
 9 |           className
10 |         )}
11 |       />
12 |     </div>
13 |   );
14 | };
15 | 
16 | export default ButtonShimmer;
17 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Shimmers/CategoriesShimmer.tsx:
--------------------------------------------------------------------------------
 1 | import { useMemo } from "react";
 2 | 
 3 | import CategoryItemShimmer from "./CategoryItemShimmer";
 4 | 
 5 | const CategoriesShimmer = () => {
 6 |   const cards = useMemo(() => Array(14).fill(1), []);
 7 | 
 8 |   return (
 9 |     <div className="my-1 hidden gap-4 sm:grid-cols-2 md:grid md:grid-cols-4 lg:grid-cols-7">
10 |       {cards.map((i, idx) => (
11 |         <CategoryItemShimmer key={`${i}_${idx}`} />
12 |       ))}
13 |     </div>
14 |   );
15 | };
16 | 
17 | export default CategoriesShimmer;
18 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Shimmers/CategoryItemShimmer.tsx:
--------------------------------------------------------------------------------
 1 | const CategoryItemShimmer = () => {
 2 |   return (
 3 |     <div className="animate-shimmer">
 4 |       <div className="rounded-lg bg-gray-200 p-9 dark:bg-gray-800" />
 5 |     </div>
 6 |   );
 7 | };
 8 | 
 9 | export default CategoryItemShimmer;
10 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Shimmers/CommentsShimmer.tsx:
--------------------------------------------------------------------------------
 1 | import CommentItemShimmer from "./CommentItemShimmer";
 2 | 
 3 | const CommentsShimmer = () => {
 4 |   return (
 5 |     <div className="space-y-2">
 6 |       <CommentItemShimmer />
 7 |       <CommentItemShimmer />
 8 |     </div>
 9 |   );
10 | };
11 | 
12 | export default CommentsShimmer;
13 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Shimmers/LatestBytesShimmer.tsx:
--------------------------------------------------------------------------------
 1 | import { useMemo } from "react";
 2 | 
 3 | const LatestBytesShimmer = ({ count = 15 }: { count?: number }) => {
 4 |   const cards = useMemo(() => Array(count).fill(1), [count]);
 5 |   return (
 6 |     <div className="animate-shimmer">
 7 |       <div className="no-scrollbar relative mb-8 flex items-start space-x-4 overflow-x-auto scroll-smooth">
 8 |         {cards.map((i, idx) => (
 9 |           <div key={`${i}_${idx}`} className="space-y-1.5">
10 |             <div className="aspect-[9/16] h-[350px] ultrawide:h-[400px] ultrawide:w-[260px] w-[220px] rounded-large bg-gray-200 dark:bg-gray-800" />
11 |           </div>
12 |         ))}
13 |       </div>
14 |     </div>
15 |   );
16 | };
17 | 
18 | export default LatestBytesShimmer;
19 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Shimmers/SettingsShimmer.tsx:
--------------------------------------------------------------------------------
 1 | import { Spinner } from "@tape.xyz/ui";
 2 | 
 3 | const SettingsShimmer = () => {
 4 |   return (
 5 |     <div className="grid h-[80vh] place-content-center">
 6 |       <Spinner />
 7 |     </div>
 8 |   );
 9 | };
10 | 
11 | export default SettingsShimmer;
12 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Shimmers/SquareButtonShimmer.tsx:
--------------------------------------------------------------------------------
 1 | const SquareButtonShimmer = () => {
 2 |   return (
 3 |     <div className="flex self-center">
 4 |       <div className="flex animate-shimmer">
 5 |         <div className="rounded-lg bg-gray-200 p-3.5 md:rounded-xl md:p-[18px] dark:bg-gray-800" />
 6 |       </div>
 7 |     </div>
 8 |   );
 9 | };
10 | 
11 | export default SquareButtonShimmer;
12 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Shimmers/SuggestedShimmer.tsx:
--------------------------------------------------------------------------------
 1 | const SuggestedShimmer = () => {
 2 |   return (
 3 |     <div className="w-full rounded-md">
 4 |       <div className="flex animate-shimmer space-x-2">
 5 |         <div className="h-24 w-44 rounded-small bg-gray-200 dark:bg-gray-800" />
 6 |         <div className="flex flex-1 flex-col space-y-2 py-1">
 7 |           <div className="h-4 w-full rounded bg-gray-200 dark:bg-gray-800" />
 8 |           <div className="h-3 w-1/2 rounded bg-gray-200 dark:bg-gray-800" />
 9 |           <div className="h-3 w-1/2 rounded bg-gray-200 dark:bg-gray-800" />
10 |         </div>
11 |       </div>
12 |     </div>
13 |   );
14 | };
15 | 
16 | export default SuggestedShimmer;
17 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Shimmers/ThumbnailsShimmer.tsx:
--------------------------------------------------------------------------------
 1 | import { useMemo } from "react";
 2 | 
 3 | import { THUMBNAIL_GENERATE_COUNT } from "@/components/Create/ChooseThumbnail";
 4 | 
 5 | const ThumbnailsShimmer = () => {
 6 |   const thumbnails = useMemo(() => Array(THUMBNAIL_GENERATE_COUNT).fill(1), []);
 7 | 
 8 |   return (
 9 |     <>
10 |       {thumbnails.map((e, i) => (
11 |         <div
12 |           key={`${e}_${i}`}
13 |           className="tape-border aspect-[16/9] h-full w-full animate-shimmer rounded-md"
14 |         >
15 |           <div className="h-full rounded-md bg-gray-200 dark:bg-gray-800" />
16 |         </div>
17 |       ))}
18 |     </>
19 |   );
20 | };
21 | 
22 | export default ThumbnailsShimmer;
23 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Shimmers/TimelineShimmer.tsx:
--------------------------------------------------------------------------------
 1 | import { tw } from "@tape.xyz/browser";
 2 | import { useMemo } from "react";
 3 | 
 4 | import VideoCardShimmer from "./VideoCardShimmer";
 5 | 
 6 | const TimelineShimmer = ({
 7 |   className,
 8 |   count = 15
 9 | }: {
10 |   className?: string;
11 |   count?: number;
12 | }) => {
13 |   const cards = useMemo(() => Array(count).fill(1), [count]);
14 |   return (
15 |     <div
16 |       className={tw(
17 |         "grid-col-1 grid desktop:grid-cols-4 tablet:grid-cols-3 ultrawide:grid-cols-6 gap-x-4 gap-y-2 md:gap-y-6",
18 |         className
19 |       )}
20 |     >
21 |       {cards.map((i, idx) => (
22 |         <VideoCardShimmer key={`${i}_${idx}`} />
23 |       ))}
24 |     </div>
25 |   );
26 | };
27 | 
28 | export default TimelineShimmer;
29 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Watch/Comments/AudioComment.tsx:
--------------------------------------------------------------------------------
 1 | import { sanitizeDStorageUrl } from "@tape.xyz/generic";
 2 | import type { FC } from "react";
 3 | 
 4 | type Props = {
 5 |   uri: string;
 6 | };
 7 | 
 8 | const AudioComment: FC<Props> = ({ uri }) => {
 9 |   return (
10 |     <div className="my-2">
11 |       <audio controls controlsList="nodownload noplaybackrate">
12 |         <source src={sanitizeDStorageUrl(uri)} type="audio/mpeg" />
13 |         Your browser does not support the audio element.
14 |         <track kind="captions" />
15 |       </audio>
16 |     </div>
17 |   );
18 | };
19 | export default AudioComment;
20 | 


--------------------------------------------------------------------------------
/apps/web/src/components/Watch/OpenActions/verified-contracts.tsx:
--------------------------------------------------------------------------------
1 | import { IS_MAINNET } from "@tape.xyz/constants";
2 | 
3 | export const VERIFIED_UNKNOWN_OPEN_ACTION_CONTRACTS = {
4 |   TIP: IS_MAINNET
5 |     ? "0x22cb67432C101a9b6fE0F9ab542c8ADD5DD48153"
6 |     : "0x6111e258a6d00d805DcF1249900895c7aA0cD186"
7 | };
8 | 


--------------------------------------------------------------------------------
/apps/web/src/hooks/useSw.ts:
--------------------------------------------------------------------------------
 1 | import { createContext, useContext } from "react";
 2 | 
 3 | type ServiceWorkerContextType = {
 4 |   addEventToQueue: (name: string, properties?: Record<string, unknown>) => void;
 5 | };
 6 | 
 7 | export const ServiceWorkerContext = createContext<
 8 |   ServiceWorkerContextType | undefined
 9 | >(undefined);
10 | 
11 | const useSw = () => {
12 |   const context = useContext(ServiceWorkerContext);
13 |   if (!context) {
14 |     throw new Error("[SW] useSw must be used within a ServiceWorkerProvider");
15 |   }
16 |   return context;
17 | };
18 | 
19 | export default useSw;
20 | 


--------------------------------------------------------------------------------
/apps/web/src/lib/getCurrentSession.ts:
--------------------------------------------------------------------------------
 1 | import { parseJwt } from "@tape.xyz/generic";
 2 | 
 3 | import { hydrateAuthTokens } from "./store/auth";
 4 | 
 5 | const getCurrentSession = () => {
 6 |   const { refreshToken } = hydrateAuthTokens();
 7 | 
 8 |   const currentSession = parseJwt(refreshToken || "");
 9 | 
10 |   return {
11 |     profileId: currentSession?.id,
12 |     authorizationId: currentSession?.authorizationId
13 |   };
14 | };
15 | 
16 | export default getCurrentSession;
17 | 


--------------------------------------------------------------------------------
/apps/web/src/lib/store/comment.ts:
--------------------------------------------------------------------------------
 1 | import { CustomCommentsFilterEnum } from "@tape.xyz/lens/custom-types";
 2 | import { create } from "zustand";
 3 | 
 4 | interface CommentState {
 5 |   selectedCommentFilter: CustomCommentsFilterEnum;
 6 |   setSelectedCommentFilter: (filter: CustomCommentsFilterEnum) => void;
 7 | }
 8 | 
 9 | const useCommentStore = create<CommentState>((set) => ({
10 |   selectedCommentFilter: CustomCommentsFilterEnum.RELEVANT_COMMENTS,
11 |   setSelectedCommentFilter: (selectedCommentFilter) =>
12 |     set({ selectedCommentFilter })
13 | }));
14 | 
15 | export default useCommentStore;
16 | 


--------------------------------------------------------------------------------
/apps/web/src/lib/store/idb/curated.ts:
--------------------------------------------------------------------------------
 1 | import { LocalIDBStore } from "@tape.xyz/lens/custom-types";
 2 | import { create } from "zustand";
 3 | import { persist } from "zustand/middleware";
 4 | 
 5 | import createIdbStorage from "@/lib/createIdbStorage";
 6 | 
 7 | interface State {
 8 |   curatedProfiles: string[];
 9 |   setCuratedProfiles: (curatedProfiles: string[]) => void;
10 | }
11 | 
12 | const useCuratedProfiles = create(
13 |   persist<State>(
14 |     (set) => ({
15 |       curatedProfiles: [],
16 |       setCuratedProfiles: (curatedProfiles) => set({ curatedProfiles })
17 |     }),
18 |     {
19 |       name: LocalIDBStore.ALLOWED_TOKENS_STORE,
20 |       storage: createIdbStorage()
21 |     }
22 |   )
23 | );
24 | 
25 | export default useCuratedProfiles;
26 | 


--------------------------------------------------------------------------------
/apps/web/src/lib/store/idb/verified.ts:
--------------------------------------------------------------------------------
 1 | import { LocalIDBStore } from "@tape.xyz/lens/custom-types";
 2 | import { create } from "zustand";
 3 | import { persist } from "zustand/middleware";
 4 | 
 5 | import createIdbStorage from "@/lib/createIdbStorage";
 6 | 
 7 | interface State {
 8 |   verifiedProfiles: string[];
 9 |   setVerifiedProfiles: (verifiedProfiles: string[]) => void;
10 | }
11 | 
12 | const useVerifiedStore = create(
13 |   persist<State>(
14 |     (set) => ({
15 |       verifiedProfiles: [],
16 |       setVerifiedProfiles: (verifiedProfiles) => set({ verifiedProfiles })
17 |     }),
18 |     {
19 |       name: LocalIDBStore.VERIFIED_STORE,
20 |       storage: createIdbStorage()
21 |     }
22 |   )
23 | );
24 | 
25 | export default useVerifiedStore;
26 | 


--------------------------------------------------------------------------------
/apps/web/src/lib/store/nonce.ts:
--------------------------------------------------------------------------------
 1 | import { create } from "zustand";
 2 | 
 3 | interface NonceState {
 4 |   lensHubOnchainSigNonce: number;
 5 |   setLensHubOnchainSigNonce: (nonce: number) => void;
 6 | }
 7 | 
 8 | const useNonceStore = create<NonceState>((set) => ({
 9 |   lensHubOnchainSigNonce: 0,
10 |   setLensHubOnchainSigNonce: (nonce: number) =>
11 |     set({ lensHubOnchainSigNonce: nonce })
12 | }));
13 | 
14 | export default useNonceStore;
15 | 


--------------------------------------------------------------------------------
/apps/web/src/lib/store/notification.ts:
--------------------------------------------------------------------------------
 1 | import { create } from "zustand";
 2 | 
 3 | interface NotificationState {
 4 |   hasNewNotification: boolean;
 5 |   setHasNewNotification: (value: boolean) => void;
 6 | }
 7 | 
 8 | const useNotificationStore = create<NotificationState>((set) => ({
 9 |   hasNewNotification: false,
10 |   setHasNewNotification: (hasNewNotification) => set({ hasNewNotification })
11 | }));
12 | 
13 | export default useNotificationStore;
14 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/_app.tsx:
--------------------------------------------------------------------------------
 1 | import "../styles/index.css";
 2 | 
 3 | import { tapeFont } from "@tape.xyz/browser/font";
 4 | import type { AppProps } from "next/app";
 5 | 
 6 | import Providers from "@/components/Common/Providers";
 7 | 
 8 | const App = ({ Component, pageProps }: AppProps) => {
 9 |   return (
10 |     <Providers>
11 |       <style jsx global>{`
12 |         html {
13 |           font-family: ${tapeFont.style.fontFamily};
14 |         }
15 |       `}</style>
16 |       <Component {...pageProps} />
17 |     </Providers>
18 |   );
19 | };
20 | 
21 | export default App;
22 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/bookmarks.tsx:
--------------------------------------------------------------------------------
1 | import Bookmarks from "@/components/Profile/Bookmarks";
2 | 
3 | export default Bookmarks;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/bytes/[id].tsx:
--------------------------------------------------------------------------------
1 | import Bytes from "@/components/Bytes";
2 | 
3 | export default Bytes;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/bytes/index.tsx:
--------------------------------------------------------------------------------
1 | import Bytes from "@/components/Bytes";
2 | 
3 | export default Bytes;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/create.tsx:
--------------------------------------------------------------------------------
1 | import CreateSteps from "@/components/Create";
2 | 
3 | export default CreateSteps;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/explore/[category].tsx:
--------------------------------------------------------------------------------
1 | import ExploreCategory from "@/components/Explore/Category";
2 | 
3 | export default ExploreCategory;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/explore/hashtag/[hashtag].tsx:
--------------------------------------------------------------------------------
1 | import ExploreHashtag from "@/components/Explore/Hashtag";
2 | 
3 | export default ExploreHashtag;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/explore/index.tsx:
--------------------------------------------------------------------------------
1 | import Explore from "@/components/Explore";
2 | 
3 | export default Explore;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/feed.tsx:
--------------------------------------------------------------------------------
1 | import Feed from "@/components/Feed";
2 | 
3 | export default Feed;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import Home from "@/components/Home";
2 | 
3 | export default Home;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/mod.tsx:
--------------------------------------------------------------------------------
1 | import Mod from "@/components/Mod";
2 | 
3 | export default Mod;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/notifications.tsx:
--------------------------------------------------------------------------------
1 | import Notifications from "@/components/Notifications";
2 | 
3 | const notifications = () => {
4 |   return <Notifications />;
5 | };
6 | 
7 | export default notifications;
8 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/profile/[id].tsx:
--------------------------------------------------------------------------------
1 | import Profile from "@/components/Profile";
2 | 
3 | export default Profile;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/settings/allowance.tsx:
--------------------------------------------------------------------------------
1 | import Settings from "@/components/Settings";
2 | 
3 | export default Settings;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/settings/blocked.tsx:
--------------------------------------------------------------------------------
1 | import Settings from "@/components/Settings";
2 | 
3 | export default Settings;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/settings/danger.tsx:
--------------------------------------------------------------------------------
1 | import Settings from "@/components/Settings";
2 | 
3 | export default Settings;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/settings/follow.tsx:
--------------------------------------------------------------------------------
1 | import Settings from "@/components/Settings";
2 | 
3 | export default Settings;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/settings/handles.tsx:
--------------------------------------------------------------------------------
1 | import Settings from "@/components/Settings";
2 | 
3 | export default Settings;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/settings/index.tsx:
--------------------------------------------------------------------------------
1 | import Settings from "@/components/Settings";
2 | 
3 | export default Settings;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/settings/interests.tsx:
--------------------------------------------------------------------------------
1 | import Settings from "@/components/Settings";
2 | 
3 | export default Settings;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/settings/manager.tsx:
--------------------------------------------------------------------------------
1 | import Settings from "@/components/Settings";
2 | 
3 | export default Settings;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/settings/sessions.tsx:
--------------------------------------------------------------------------------
1 | import Settings from "@/components/Settings";
2 | 
3 | export default Settings;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/thanks.tsx:
--------------------------------------------------------------------------------
1 | import Thanks from "@/components/Thanks";
2 | 
3 | export default Thanks;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/u/[[...handle]].tsx:
--------------------------------------------------------------------------------
1 | import ViewProfile from "@/components/Profile";
2 | 
3 | export default ViewProfile;
4 | 


--------------------------------------------------------------------------------
/apps/web/src/pages/watch/[id].tsx:
--------------------------------------------------------------------------------
1 | import VideoDetails from "@/components/Watch";
2 | 
3 | export default VideoDetails;
4 | 


--------------------------------------------------------------------------------
/apps/web/tailwind.config.js:
--------------------------------------------------------------------------------
 1 | const base = require("@tape.xyz/ui/tailwind-preset");
 2 | 
 3 | /** @type {import ('tailwindcss').Config} */
 4 | module.exports = {
 5 |   ...base,
 6 |   content: ["./src/**/*.{ts,tsx}", "../../packages/ui/src/**/*.{ts,tsx}"],
 7 |   plugins: [
 8 |     require("@tailwindcss/aspect-ratio"),
 9 |     require("@tailwindcss/typography")
10 |   ]
11 | };
12 | 


--------------------------------------------------------------------------------
/apps/web/tsconfig.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "extends": "@tape.xyz/tsconfig/nextjs.json",
 3 |   "compilerOptions": {
 4 |     "baseUrl": ".",
 5 |     "noEmit": true,
 6 |     "isolatedModules": true,
 7 |     "strictNullChecks": true,
 8 |     "paths": {
 9 |       "@/*": ["./src/*"]
10 |     },
11 |     "plugins": [
12 |       {
13 |         "name": "next"
14 |       }
15 |     ]
16 |   },
17 |   "include": [
18 |     "next-env.d.ts",
19 |     "**/*.ts",
20 |     "**/*.tsx",
21 |     "src/styles/index.css",
22 |     ".next/types/**/*.ts"
23 |   ],
24 |   "exclude": ["node_modules"]
25 | }
26 | 


--------------------------------------------------------------------------------
/packages/abis/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./src/LensHubProxy";
2 | export * from "./src/LensPermissionlessCreator";
3 | export * from "./src/TapeSignupProxy";
4 | 


--------------------------------------------------------------------------------
/packages/abis/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "@tape.xyz/abis",
 3 |   "version": "0.0.0",
 4 |   "private": true,
 5 |   "license": "AGPL-3.0",
 6 |   "main": "index.ts",
 7 |   "scripts": {
 8 |     "typecheck": "tsc --pretty --noEmit"
 9 |   },
10 |   "dependencies": {
11 |     "typescript": "^5.7.3"
12 |   },
13 |   "devDependencies": {
14 |     "@tape.xyz/tsconfig": "workspace:*",
15 |     "@types/node": "^22.13.1"
16 |   }
17 | }
18 | 


--------------------------------------------------------------------------------
/packages/abis/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 |   "extends": "@tape.xyz/tsconfig/base.json"
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/browser/font.ts:
--------------------------------------------------------------------------------
 1 | import localFont from "next/font/local";
 2 | 
 3 | export const tapeFont = localFont({
 4 |   src: [
 5 |     {
 6 |       path: "./font/Satoshi-Regular.woff2",
 7 |       weight: "400"
 8 |     },
 9 |     {
10 |       path: "./font/Satoshi-Medium.woff2",
11 |       weight: "500"
12 |     },
13 |     {
14 |       path: "./font/Satoshi-Bold.woff2",
15 |       weight: "700"
16 |     }
17 |   ],
18 |   fallback: ["system-ui", "sans-serif"],
19 |   preload: true,
20 |   variable: "--font-tape"
21 | });
22 | 


--------------------------------------------------------------------------------
/packages/browser/font/Satoshi-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/packages/browser/font/Satoshi-Bold.woff2


--------------------------------------------------------------------------------
/packages/browser/font/Satoshi-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/packages/browser/font/Satoshi-Medium.woff2


--------------------------------------------------------------------------------
/packages/browser/font/Satoshi-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tapexyz/tape/84bd954b5f90570d0c1cc7a40e95e6f1cb62c0d1/packages/browser/font/Satoshi-Regular.woff2


--------------------------------------------------------------------------------
/packages/browser/functions/fingerprint.ts:
--------------------------------------------------------------------------------
 1 | import { getCurrentBrowserFingerPrint } from "@rajesh896/broprint.js";
 2 | import { LocalStore } from "@tape.xyz/lens/custom-types";
 3 | 
 4 | const getFingerprint = async () => {
 5 |   const fingerprint = await getCurrentBrowserFingerPrint();
 6 |   return fingerprint;
 7 | };
 8 | 
 9 | export const setFingerprint = async () => {
10 |   const storedFingerprint = localStorage.getItem(LocalStore.TAPE_FINGERPRINT);
11 |   if (!storedFingerprint) {
12 |     const fingerprint = await getFingerprint();
13 |     if (fingerprint) {
14 |       localStorage.setItem(LocalStore.TAPE_FINGERPRINT, fingerprint);
15 |     }
16 |   }
17 | };
18 | 


--------------------------------------------------------------------------------
/packages/browser/functions/getUserLocale.ts:
--------------------------------------------------------------------------------
1 | export const getUserLocale = () => {
2 |   const locale = navigator?.languages?.length
3 |     ? navigator.languages[0]
4 |     : navigator.language;
5 | 
6 |   return locale || "en";
7 | };
8 | 


--------------------------------------------------------------------------------
/packages/browser/functions/tw.ts:
--------------------------------------------------------------------------------
1 | import type { ClassValue } from "clsx";
2 | import { clsx } from "clsx";
3 | import { twMerge } from "tailwind-merge";
4 | 
5 | export const tw = (...inputs: ClassValue[]) => {
6 |   return twMerge(clsx(inputs));
7 | };
8 | 


--------------------------------------------------------------------------------
/packages/browser/hooks/useAverageColor.ts:
--------------------------------------------------------------------------------
 1 | import { FastAverageColor } from "fast-average-color";
 2 | import { useCallback, useEffect, useState } from "react";
 3 | 
 4 | const fac = new FastAverageColor();
 5 | 
 6 | export const useAverageColor = (src: string, check: boolean) => {
 7 |   const [color, setColor] = useState("");
 8 | 
 9 |   const getColors = useCallback(() => {
10 |     if (!check || !src) {
11 |       return;
12 |     }
13 |     return fac
14 |       .getColorAsync(src)
15 |       .then((color) => {
16 |         setColor(color.hex);
17 |       })
18 |       .catch(() => {});
19 |   }, [src, check]);
20 | 
21 |   useEffect(() => {
22 |     getColors();
23 |   }, [getColors]);
24 | 
25 |   return { color };
26 | };
27 | 


--------------------------------------------------------------------------------
/packages/browser/hooks/useDebounce.ts:
--------------------------------------------------------------------------------
 1 | import { useEffect, useState } from "react";
 2 | 
 3 | export function useDebounce<T>(value: T, delay?: number): T {
 4 |   const [debouncedValue, setDebouncedValue] = useState<T>(value);
 5 | 
 6 |   useEffect(() => {
 7 |     const timer = setTimeout(() => setDebouncedValue(value), delay || 500);
 8 | 
 9 |     return () => {
10 |       clearTimeout(timer);
11 |     };
12 |   }, [value, delay]);
13 | 
14 |   return debouncedValue;
15 | }
16 | 


--------------------------------------------------------------------------------
/packages/browser/hooks/useDragAndDrop.ts:
--------------------------------------------------------------------------------
 1 | import { useState } from "react";
 2 | 
 3 | export const useDragAndDrop = () => {
 4 |   const [dragOver, setDragOver] = useState(false);
 5 |   const [fileDropError, setFileDropError] = useState("");
 6 | 
 7 |   const onDragOver = (e: React.SyntheticEvent) => {
 8 |     e.preventDefault();
 9 |     setDragOver(true);
10 |   };
11 | 
12 |   const onDragLeave = () => setDragOver(false);
13 | 
14 |   return {
15 |     dragOver,
16 |     setDragOver,
17 |     onDragOver,
18 |     onDragLeave,
19 |     fileDropError,
20 |     setFileDropError
21 |   };
22 | };
23 | 


--------------------------------------------------------------------------------
/packages/browser/hooks/useHorizontalScroll.ts:
--------------------------------------------------------------------------------
 1 | import { useEffect, useRef } from "react";
 2 | 
 3 | export const useHorizontalScroll = () => {
 4 |   const elRef = useRef<HTMLDivElement>(null);
 5 |   useEffect(() => {
 6 |     const el = elRef.current;
 7 |     if (!el) {
 8 |       return;
 9 |     }
10 |     const handleWheelEvent = (e: any) => {
11 |       if (e.deltaY === 0) {
12 |         return;
13 |       }
14 |       e.preventDefault();
15 |       el.scrollTo({
16 |         left: el.scrollLeft + e.deltaY,
17 |         behavior: "smooth"
18 |       });
19 |     };
20 |     el.addEventListener("wheel", handleWheelEvent);
21 |     return () => el.removeEventListener("wheel", handleWheelEvent);
22 |   }, []);
23 |   return elRef;
24 | };
25 | 


--------------------------------------------------------------------------------
/packages/browser/hooks/useIsMounted.ts:
--------------------------------------------------------------------------------
 1 | import { useCallback, useEffect, useRef } from "react";
 2 | 
 3 | export const useIsMounted = () => {
 4 |   const isMounted = useRef(false);
 5 | 
 6 |   useEffect(() => {
 7 |     isMounted.current = true;
 8 | 
 9 |     return () => {
10 |       isMounted.current = false;
11 |     };
12 |   }, []);
13 | 
14 |   return useCallback(() => isMounted.current, []);
15 | };
16 | 


--------------------------------------------------------------------------------
/packages/browser/index.ts:
--------------------------------------------------------------------------------
 1 | export * from "./font";
 2 | export * from "./functions/fingerprint";
 3 | export * from "./functions/generateVideoThumbnails";
 4 | export * from "./functions/getFileFromDataURL";
 5 | export * from "./functions/getToastOptions";
 6 | export * from "./functions/getUserLocale";
 7 | export * from "./functions/livepeer";
 8 | export * from "./functions/tw";
 9 | export * from "./hooks/uploadToIPFS";
10 | export * from "./hooks/useAverageColor";
11 | export * from "./hooks/useCopyToClipboard";
12 | export * from "./hooks/useDebounce";
13 | export * from "./hooks/useDragAndDrop";
14 | export * from "./hooks/useHorizontalScroll";
15 | export * from "./hooks/useIsMounted";
16 | export * from "./hooks/useOutsideClick";
17 | 


--------------------------------------------------------------------------------
/packages/browser/tsconfig.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "extends": "@tape.xyz/tsconfig/base.json",
 3 |   "compilerOptions": {
 4 |     "lib": ["DOM", "ESNext", "WebWorker"],
 5 |     "skipLibCheck": true
 6 |   },
 7 |   "include": ["./worker/sw.ts"],
 8 |   "exclude": ["node_modules"]
 9 | }
10 | 


--------------------------------------------------------------------------------
/packages/browser/worker/build.mjs:
--------------------------------------------------------------------------------
 1 | import esbuild from "esbuild";
 2 | 
 3 | esbuild.build({
 4 |   allowOverwrite: true,
 5 |   bundle: true,
 6 |   entryPoints: ["worker/sw.ts"],
 7 |   format: "esm",
 8 |   minify: true,
 9 |   outfile: "../../apps/web/public/sw.js",
10 |   platform: "browser",
11 |   target: "es2020",
12 |   define: { "process.env.NODE_ENV": '"production"' }
13 | });
14 | 


--------------------------------------------------------------------------------
/packages/constants/auth-routes.ts:
--------------------------------------------------------------------------------
 1 | // auth routes
 2 | export const AUTH_ROUTES = [
 3 |   "/create",
 4 |   "/settings",
 5 |   "/feed",
 6 |   "/settings/follow",
 7 |   "/settings/handles",
 8 |   "/settings/sessions",
 9 |   "/settings/allowance",
10 |   "/settings/interests",
11 |   "/settings/danger",
12 |   "/settings/manager",
13 |   "/settings/blocked",
14 |   "/notifications"
15 | ];
16 | 
17 | export const OWNER_ONLY_ROUTES = ["/settings/danger", "/settings/manager"];
18 | 


--------------------------------------------------------------------------------
/packages/constants/endpoints.ts:
--------------------------------------------------------------------------------
1 | export enum LensEndpoint {
2 |   Mainnet = "https://api-v2.lens.dev",
3 |   Staging = "https://api.staging.lens.dev/graphql",
4 |   Testnet = "https://api.testnet.lens.dev/graphql"
5 | }
6 | 


--------------------------------------------------------------------------------
/packages/constants/feature-flags.ts:
--------------------------------------------------------------------------------
 1 | import { IS_MAINNET } from "./general";
 2 | 
 3 | export enum FEATURE_FLAGS {
 4 |   POST_WITH_SOURCE_URL = "PostWithSource",
 5 |   TAPE_CONNECT = "TapeConnect"
 6 | }
 7 | 
 8 | type FeatureFlag = {
 9 |   flag: string;
10 |   enabledFor: string[];
11 | };
12 | 
13 | export const featureFlags: FeatureFlag[] = [
14 |   {
15 |     flag: FEATURE_FLAGS.POST_WITH_SOURCE_URL,
16 |     enabledFor: IS_MAINNET ? ["0x2d"] : []
17 |   },
18 |   {
19 |     flag: FEATURE_FLAGS.TAPE_CONNECT,
20 |     enabledFor: IS_MAINNET ? ["0x2d", "0xc001"] : []
21 |   }
22 | ];
23 | 


--------------------------------------------------------------------------------
/packages/constants/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./auth-routes";
2 | export * from "./categories";
3 | export * from "./endpoints";
4 | export * from "./feature-flags";
5 | export * from "./general";
6 | export * from "./misused";
7 | export * from "./regex";
8 | export * from "./suspended";
9 | 


--------------------------------------------------------------------------------
/packages/constants/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "@tape.xyz/constants",
 3 |   "version": "0.0.0",
 4 |   "private": true,
 5 |   "license": "AGPL-3.0",
 6 |   "main": "index.ts",
 7 |   "scripts": {
 8 |     "typecheck": "tsc --pretty --noEmit"
 9 |   },
10 |   "devDependencies": {
11 |     "@tape.xyz/tsconfig": "workspace:*",
12 |     "@types/node": "^22.13.1",
13 |     "typescript": "^5.7.3"
14 |   }
15 | }
16 | 


--------------------------------------------------------------------------------
/packages/constants/regex.ts:
--------------------------------------------------------------------------------
 1 | export const COMMON_REGEX = {
 2 |   ZORA: /https:\/\/(?:testnet\.)?zora\.co\/collect\/(eth|oeth|base|zora|gor|ogor|basegor|zgor):(0x[\dA-Fa-f]{40})((?:\/(\d+))?|$)/,
 3 |   MENTION_MATCHER_REGEX: /(@[a-zA-Z0-9-_.]+(?:\/[a-zA-Z0-9-_.]+)?)/,
 4 |   HANDLE: /^[\dA-Za-z]\w{4,25}$/g,
 5 |   TAPE_WATCH:
 6 |     /^https?:\/\/tape\.xyz\/watch\/([\dA-Za-z-]+)(\?si=[\dA-Za-z]+)?$/,
 7 |   YOUTUBE_WATCH:
 8 |     /^https?:\/\/(?:www\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)[\w-]+(?:\?.*)?$/,
 9 |   VIMEO_WATCH: /^https?:\/\/(?:www\.)?vimeo\.com\/[\d]+(?:\?.*)?$/
10 | };
11 | 


--------------------------------------------------------------------------------
/packages/constants/suspended.ts:
--------------------------------------------------------------------------------
 1 | import { IS_MAINNET } from "./general";
 2 | 
 3 | export const SUSPENDED_PROFILES = IS_MAINNET
 4 |   ? [
 5 |       "0x084311",
 6 |       "0x03eee1",
 7 |       "0x6e64",
 8 |       "0x79f2",
 9 |       "0x4e24",
10 |       "0x923a",
11 |       "0x99",
12 |       "0x9b5d",
13 |       "0x9cb4",
14 |       "0x8441",
15 |       "0x0dc2",
16 |       "0x02a0b4"
17 |     ]
18 |   : [];
19 | 


--------------------------------------------------------------------------------
/packages/constants/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 |   "extends": "@tape.xyz/tsconfig/base.json"
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/generic/functions/canUploadedToIpfs.ts:
--------------------------------------------------------------------------------
 1 | import { IPFS_FREE_UPLOAD_LIMIT } from "@tape.xyz/constants";
 2 | import type { Profile } from "@tape.xyz/lens";
 3 | 
 4 | export const canUploadedToIpfs = (
 5 |   bytes: number,
 6 |   activeProfile: Profile | null
 7 | ) => {
 8 |   if (!activeProfile || bytes === null || bytes === undefined) {
 9 |     return false;
10 |   }
11 | 
12 |   // Calculate the size of the file in megabytes
13 |   const megaBytes = bytes / 1024 ** 2;
14 | 
15 |   // Check if the file size is within the allowed limit
16 |   return megaBytes < IPFS_FREE_UPLOAD_LIMIT;
17 | };
18 | 


--------------------------------------------------------------------------------
/packages/generic/functions/checkIsBytesVideo.ts:
--------------------------------------------------------------------------------
1 | export const checkIsBytesVideo = (durationInSeconds: number) => {
2 |   const durationInMinutes = durationInSeconds / 60;
3 |   if (durationInMinutes < 2) {
4 |     return true;
5 |   }
6 |   return false;
7 | };
8 | 


--------------------------------------------------------------------------------
/packages/generic/functions/checkLensManagerPermissions.ts:
--------------------------------------------------------------------------------
 1 | import type { Profile } from "@tape.xyz/lens";
 2 | 
 3 | export const checkLensManagerPermissions = (
 4 |   profile: Profile | null
 5 | ): {
 6 |   canBroadcast: boolean;
 7 |   canUseLensManager: boolean;
 8 | } => {
 9 |   if (!profile) {
10 |     return { canBroadcast: false, canUseLensManager: false };
11 |   }
12 |   const canUseLensManager = profile?.signless && profile?.sponsor;
13 |   const canBroadcast = profile?.sponsor;
14 |   return { canBroadcast, canUseLensManager };
15 | };
16 | 


--------------------------------------------------------------------------------
/packages/generic/functions/formatBytes.ts:
--------------------------------------------------------------------------------
 1 | export const formatBytes = (bytes: number) => {
 2 |   if (bytes && bytes > 0) {
 3 |     const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
 4 |     const i = Math.min(
 5 |       Number.parseInt(
 6 |         Math.floor(Math.log(bytes) / Math.log(1024)).toString(),
 7 |         10
 8 |       ),
 9 |       sizes.length - 1
10 |     );
11 |     return `${Math.round(bytes / 1024 ** i)} ${sizes[i]}`;
12 |   }
13 |   return "n/a";
14 | };
15 | 


--------------------------------------------------------------------------------
/packages/generic/functions/formatMB.ts:
--------------------------------------------------------------------------------
1 | export const formatMB = (sizeInMB: number) => {
2 |   if (sizeInMB >= 1024) {
3 |     // Convert MB to GB if size is greater than or equal to 1 GB
4 |     const sizeInGB = sizeInMB / 1024;
5 |     return `${Math.floor(sizeInGB)} GB`;
6 |   }
7 |   return `${sizeInMB} MB`;
8 | };
9 | 


--------------------------------------------------------------------------------
/packages/generic/functions/formatNumber.ts:
--------------------------------------------------------------------------------
 1 | export const formatNumber = (num: number) => {
 2 |   let numberToFormat = num;
 3 |   if (numberToFormat < 0) {
 4 |     numberToFormat = Math.abs(num);
 5 |   }
 6 |   if (numberToFormat > 999 && numberToFormat < 1000000) {
 7 |     return `${(numberToFormat / 1000).toPrecision(3)}k`;
 8 |   }
 9 |   if (numberToFormat > 1000000) {
10 |     return `${(numberToFormat / 1000000).toPrecision(3)}m`;
11 |   }
12 |   if (numberToFormat < 1000) {
13 |     return numberToFormat;
14 |   }
15 | };
16 | 


--------------------------------------------------------------------------------
/packages/generic/functions/get-profile-cover.ts:
--------------------------------------------------------------------------------
 1 | import type { ProfileMetadata } from "@tape.xyz/lens";
 2 | 
 3 | export const getProfileCoverPicture = (
 4 |   metadata: ProfileMetadata,
 5 |   withFallback = false
 6 | ): string => {
 7 |   return metadata?.coverPicture?.optimized?.uri
 8 |     ? metadata.coverPicture.optimized.uri
 9 |     : withFallback
10 |       ? "ipfs://bafkreihn5v4hpuxgcysnpb4pgcerkmhwddxq65qswmit6j4nj44btyzdou" //`${STATIC_ASSETS}/images/fallback-cover.svg`
11 |       : "";
12 | };
13 | 


--------------------------------------------------------------------------------
/packages/generic/functions/getCategoryName.ts:
--------------------------------------------------------------------------------
 1 | import { TAPE_MEDIA_CATEGORIES } from "@tape.xyz/constants";
 2 | 
 3 | export const getCategoryName = (tag: string) => {
 4 |   if (!tag) {
 5 |     return null;
 6 |   }
 7 |   return TAPE_MEDIA_CATEGORIES.find((c) => c.tag === tag)?.name;
 8 | };
 9 | 
10 | export const getCategoryByTag = (tag: string) => {
11 |   return TAPE_MEDIA_CATEGORIES.find(
12 |     (c) => c.tag === tag
13 |   ) as (typeof TAPE_MEDIA_CATEGORIES)[0];
14 | };
15 | 


--------------------------------------------------------------------------------
/packages/generic/functions/getFromAttributes.ts:
--------------------------------------------------------------------------------
 1 | import type { MetadataAttribute } from "@tape.xyz/lens";
 2 | 
 3 | // key available only profile metadata
 4 | export const getValueFromKeyInAttributes = (
 5 |   attributes: MetadataAttribute[] | null | undefined,
 6 |   key: string
 7 | ) => {
 8 |   return attributes?.find((el) => el.key === key)?.value ?? "";
 9 | };
10 | 


--------------------------------------------------------------------------------
/packages/generic/functions/getIsFeatureEnabled.ts:
--------------------------------------------------------------------------------
 1 | import type { FEATURE_FLAGS } from "@tape.xyz/constants";
 2 | import { featureFlags } from "@tape.xyz/constants";
 3 | 
 4 | export const getIsFeatureEnabled = (flag: FEATURE_FLAGS, profileId: string) => {
 5 |   if (!profileId) {
 6 |     return false;
 7 |   }
 8 |   const feature = featureFlags.find((f) => f.flag === flag);
 9 |   return feature?.enabledFor.includes(profileId);
10 | };
11 | 


--------------------------------------------------------------------------------
/packages/generic/functions/getIsProfileOwner.ts:
--------------------------------------------------------------------------------
 1 | import type { Profile } from "@tape.xyz/lens";
 2 | 
 3 | import { getProfile } from "./get-profile";
 4 | 
 5 | export const getIsProfileOwner = (
 6 |   profile: Profile,
 7 |   address: string | undefined
 8 | ) => {
 9 |   return getProfile(profile)?.address?.toLowerCase() === address?.toLowerCase();
10 | };
11 | 


--------------------------------------------------------------------------------
/packages/generic/functions/getIsSensitiveContent.ts:
--------------------------------------------------------------------------------
 1 | import type { PublicationMetadata } from "@tape.xyz/lens";
 2 | 
 3 | export const getIsSensitiveContent = (
 4 |   metadata: PublicationMetadata | null
 5 | ): boolean => {
 6 |   return (
 7 |     Boolean(metadata?.attributes?.find((el) => el.value === "sensitive")) ||
 8 |     Boolean(metadata?.contentWarning)
 9 |   );
10 | };
11 | 


--------------------------------------------------------------------------------
/packages/generic/functions/getIsSuspendedProfile.ts:
--------------------------------------------------------------------------------
1 | import { SUSPENDED_PROFILES } from "@tape.xyz/constants";
2 | 
3 | export const getIsSuspendedProfile = (profileId: string): boolean => {
4 |   return SUSPENDED_PROFILES.includes(profileId);
5 | };
6 | 


--------------------------------------------------------------------------------
/packages/generic/functions/getLennyPicture.ts:
--------------------------------------------------------------------------------
1 | import { IS_MAINNET, WORKER_AVATAR_URL } from "@tape.xyz/constants";
2 | 
3 | export const getLennyPicture = (profileId: string) => {
4 |   return IS_MAINNET
5 |     ? `${WORKER_AVATAR_URL}/${profileId}`
6 |     : `https://cdn.stamp.fyi/avatar/${profileId}?s=300`;
7 | };
8 | 


--------------------------------------------------------------------------------
/packages/generic/functions/getMetadataCid.ts:
--------------------------------------------------------------------------------
 1 | import type { AnyPublication } from "@tape.xyz/lens";
 2 | 
 3 | import { getPublication } from "./getPublication";
 4 | 
 5 | export const getMetadataCid = (publication: AnyPublication): string => {
 6 |   const target = getPublication(publication);
 7 |   const hash = target.metadata.rawURI.split("/").pop();
 8 |   return hash ?? "";
 9 | };
10 | 


--------------------------------------------------------------------------------
/packages/generic/functions/getShouldUploadVideo.ts:
--------------------------------------------------------------------------------
 1 | import type { PrimaryPublication, VideoMetadataV3 } from "@tape.xyz/lens";
 2 | 
 3 | export const getShouldUploadVideo = (video: PrimaryPublication): boolean => {
 4 |   const metadata = video.metadata as VideoMetadataV3;
 5 |   // Define the time threshold for video optimization (4 hours ago)
 6 |   const fourHoursAgo = new Date(Date.now() - 4 * 60 * 60 * 1000);
 7 |   const createdAt = new Date(video.createdAt);
 8 | 
 9 |   // Check if the video's URI is not optimized (not ending with .m3u8)
10 |   const isNotOptimized =
11 |     !metadata.asset.video.optimized?.uri?.endsWith(".m3u8");
12 | 
13 |   // Return true if the video is older than 4 hours and not optimized
14 |   return createdAt < fourHoursAgo && isNotOptimized;
15 | };
16 | 


--------------------------------------------------------------------------------
/packages/generic/functions/getUploadedMediaType.ts:
--------------------------------------------------------------------------------
 1 | import { MediaVideoMimeType } from "@lens-protocol/metadata";
 2 | 
 3 | export const getUploadedMediaType = (mimeType: string): MediaVideoMimeType => {
 4 |   switch (mimeType) {
 5 |     case "video/mp4":
 6 |       return MediaVideoMimeType.MP4;
 7 |     case "video/mpeg":
 8 |       return MediaVideoMimeType.MPEG;
 9 |     case "video/webm":
10 |       return MediaVideoMimeType.WEBM;
11 |     case "video/quicktime":
12 |       return MediaVideoMimeType.QUICKTIME;
13 |     case "video/mov":
14 |       return MediaVideoMimeType.MOV;
15 |     default:
16 |       return MediaVideoMimeType.MP4;
17 |   }
18 | };
19 | 


--------------------------------------------------------------------------------
/packages/generic/functions/image-cdn.ts:
--------------------------------------------------------------------------------
 1 | import {
 2 |   IMAGEKIT_URL,
 3 |   IMAGE_TRANSFORMATIONS,
 4 |   IS_PRODUCTION
 5 | } from "@tape.xyz/constants";
 6 | 
 7 | export const imageCdn = (
 8 |   url: string,
 9 |   type?: keyof typeof IMAGE_TRANSFORMATIONS
10 | ): string => {
11 |   if (!url) {
12 |     return url;
13 |   }
14 | 
15 |   return IS_PRODUCTION
16 |     ? type
17 |       ? `${IMAGEKIT_URL}/${IMAGE_TRANSFORMATIONS[type]}/${url}`
18 |       : `${IMAGEKIT_URL}/${url}`
19 |     : url;
20 | };
21 | 


--------------------------------------------------------------------------------
/packages/generic/functions/isWatchable.ts:
--------------------------------------------------------------------------------
 1 | import type { MirrorablePublication } from "@tape.xyz/lens";
 2 | 
 3 | export const isWatchable = (publication: MirrorablePublication) => {
 4 |   const canWatch =
 5 |     publication &&
 6 |     (publication.metadata.__typename === "VideoMetadataV3" ||
 7 |       publication.metadata.__typename === "LiveStreamMetadataV3") &&
 8 |     !publication?.isHidden;
 9 | 
10 |   return canWatch;
11 | };
12 | 


--------------------------------------------------------------------------------
/packages/generic/functions/omitKey.ts:
--------------------------------------------------------------------------------
1 | export const omitKey = (object: { [key: string]: any }, key: string) => {
2 |   const cloned = { ...object }; // cloning to fix a reference issue recently after v13
3 |   delete cloned[key];
4 |   return cloned;
5 | };
6 | 


--------------------------------------------------------------------------------
/packages/generic/functions/parse-jwt.ts:
--------------------------------------------------------------------------------
 1 | type ReturnType = {
 2 |   id: string;
 3 |   role: string;
 4 |   authorizationId: string;
 5 |   iat: number;
 6 |   exp: number;
 7 | };
 8 | 
 9 | const hasBuffer = typeof Buffer === "undefined";
10 | const decoded = (str: string): string =>
11 |   hasBuffer ? atob(str) : Buffer.from(str, "base64").toString("binary");
12 | 
13 | export const parseJwt = (token: string): ReturnType => {
14 |   try {
15 |     const splited = token.split(".")[1] ?? "";
16 |     return JSON.parse(decoded(splited));
17 |   } catch {
18 |     return { id: "", role: "", authorizationId: "", iat: 0, exp: 0 };
19 |   }
20 | };
21 | 
22 | export const isTokenExpired = (token: string) => {
23 |   const { exp } = parseJwt(token);
24 |   return Date.now() >= exp * 1000;
25 | };
26 | 


--------------------------------------------------------------------------------
/packages/generic/functions/resolveDid.ts:
--------------------------------------------------------------------------------
 1 | import { WORKER_DID_URL } from "@tape.xyz/constants";
 2 | import axios from "axios";
 3 | 
 4 | export const resolveDid = async (addresses: string[]) => {
 5 |   try {
 6 |     const response = await axios.post(WORKER_DID_URL, {
 7 |       addresses: addresses.map((address) => address.split("/")[0])
 8 |     });
 9 |     return response.data.dids;
10 |   } catch {
11 |     return [];
12 |   }
13 | };
14 | 


--------------------------------------------------------------------------------
/packages/generic/functions/sanitizeDStorageUrl.ts:
--------------------------------------------------------------------------------
 1 | import { IPFS_GATEWAY_URL, IRYS_GATEWAY_URL } from "@tape.xyz/constants";
 2 | 
 3 | export const sanitizeDStorageUrl = (url: string) => {
 4 |   const ipfsGateway = `${IPFS_GATEWAY_URL}/`;
 5 |   const irysGateway = `${IRYS_GATEWAY_URL}/`;
 6 |   if (!url) {
 7 |     return url;
 8 |   }
 9 | 
10 |   return url
11 |     .replace(/^Qm[1-9A-Za-z]{44}/gm, `${ipfsGateway}/${url}`)
12 |     .replace("https://ipfs.io/ipfs/", ipfsGateway)
13 |     .replace("https://ipfs.infura.io/ipfs/", ipfsGateway)
14 |     .replace("https://gateway.pinata.cloud/ipfs/", ipfsGateway)
15 |     .replace("https://gw.ipfs-lens.dev/ipfs/", ipfsGateway)
16 |     .replace("ipfs://ipfs/", ipfsGateway)
17 |     .replace("ar://", irysGateway)
18 |     .replace("ipfs://", ipfsGateway);
19 | };
20 | 


--------------------------------------------------------------------------------
/packages/generic/functions/shortenAddress.ts:
--------------------------------------------------------------------------------
1 | export const shortenAddress = (address: string, chars = 4): string => {
2 |   return `${address?.substring(0, chars + 2)}...${address.substring(
3 |     42 - chars
4 |   )}`;
5 | };
6 | 


--------------------------------------------------------------------------------
/packages/generic/functions/splitNumber.ts:
--------------------------------------------------------------------------------
 1 | export const splitNumber = (num = 1, parts = 1) => {
 2 |   const n = Math.floor(num / parts);
 3 |   const numbers: number[] = [];
 4 |   for (let i = 0; i < parts; i++) {
 5 |     numbers.push(n);
 6 |   }
 7 |   if (numbers.reduce((a, b) => a + b, 0) === num) {
 8 |     return numbers;
 9 |   }
10 |   for (let i = 0; i < parts; i++) {
11 |     numbers[i]!++;
12 |     if (numbers.reduce((a, b) => a + b, 0) === num) {
13 |       return numbers;
14 |     }
15 |   }
16 |   return numbers;
17 | };
18 | 


--------------------------------------------------------------------------------
/packages/generic/functions/trim-new-lines.ts:
--------------------------------------------------------------------------------
1 | export const trimNewLines = (text: string) => {
2 |   if (!text) {
3 |     return text;
4 |   }
5 |   return text.replaceAll("\n", "");
6 | };
7 | 


--------------------------------------------------------------------------------
/packages/generic/functions/trimify.ts:
--------------------------------------------------------------------------------
1 | export const trimify = (value: string): string => value?.trim();
2 | 


--------------------------------------------------------------------------------
/packages/generic/functions/truncate.ts:
--------------------------------------------------------------------------------
 1 | export const truncate = (str: string, max: number, suffix = "...") => {
 2 |   if (!str) {
 3 |     return "";
 4 |   }
 5 |   return str.length < max
 6 |     ? str
 7 |     : `${str.substring(
 8 |         0,
 9 |         str.substring(0, max - suffix.length).lastIndexOf(" ")
10 |       )}${suffix}`;
11 | };
12 | 


--------------------------------------------------------------------------------
/packages/generic/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "@tape.xyz/generic",
 3 |   "version": "0.0.0",
 4 |   "license": "AGPL-3.0",
 5 |   "main": "index.ts",
 6 |   "scripts": {
 7 |     "typecheck": "tsc --pretty --noEmit"
 8 |   },
 9 |   "dependencies": {
10 |     "@lens-protocol/metadata": "^1.2.0",
11 |     "axios": "^1.8.4",
12 |     "viem": "^2.23.14"
13 |   },
14 |   "devDependencies": {
15 |     "@tape.xyz/constants": "workspace:*",
16 |     "@tape.xyz/lens": "workspace:*",
17 |     "@tape.xyz/tsconfig": "workspace:*",
18 |     "@types/node": "^22.13.1",
19 |     "typescript": "^5.7.3"
20 |   }
21 | }
22 | 


--------------------------------------------------------------------------------
/packages/generic/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 |   "extends": "@tape.xyz/tsconfig/base.json"
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/indexer/codegen.ts:
--------------------------------------------------------------------------------
 1 | import type { CodegenConfig } from "@graphql-codegen/cli";
 2 | import { LensEndpoint } from "@tape.xyz/constants";
 3 | 
 4 | const config: CodegenConfig = {
 5 |   schema: LensEndpoint.Testnet,
 6 |   documents: "documents/**/*.graphql",
 7 |   generates: {
 8 |     "gql/generated/": {
 9 |       preset: "client",
10 |       config: {
11 |         documentMode: "string"
12 |       }
13 |     }
14 |   },
15 |   hooks: {
16 |     afterAllFileWrite: ["biome format --write ."]
17 |   }
18 | };
19 | 
20 | export default config;
21 | 


--------------------------------------------------------------------------------
/packages/indexer/custom-types.ts:
--------------------------------------------------------------------------------
1 | export enum AUTH_CHALLENGE_TYPE {
2 |   ONBOARDING_USER = "ONBOARDING_USER",
3 |   ACCOUNT_OWNER = "ACCOUNT_OWNER",
4 |   ACCOUNT_MANAGER = "ACCOUNT_MANAGER"
5 | }
6 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/account-manager-permissions.graphql:
--------------------------------------------------------------------------------
1 | fragment AccountManagerPermissions on AccountManagerPermissions {
2 |   canExecuteTransactions
3 |   canSetMetadataUri
4 |   canTransferNative
5 |   canTransferTokens
6 | }
7 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/account/account-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment AccountFields on Account {
 2 |   owner
 3 |   address
 4 |   createdAt
 5 |   rules {
 6 |     anyOf {
 7 |       ...AccountFollowRuleFields
 8 |     }
 9 |     required {
10 |       ...AccountFollowRuleFields
11 |     }
12 |   }
13 |   metadata {
14 |     ...AccountMetadataFields
15 |   }
16 |   username(request: { autoResolve: true }) {
17 |     ...UsernameFields
18 |   }
19 |   operations {
20 |     ...LoggedInAccountOperationsFields
21 |   }
22 | }
23 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/account/account-follow-rule-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment AccountFollowRuleFields on AccountFollowRule {
2 |   id
3 |   type
4 |   address
5 |   config {
6 |     ...AnyKeyValueFields
7 |   }
8 | }
9 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/account/account-metadata-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment AccountMetadataFields on AccountMetadata {
 2 |   id
 3 |   name
 4 |   bio
 5 |   picture
 6 |   coverPicture
 7 |   attributes {
 8 |     ...MetadataAttributeFields
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/account/logged-in-account-operations-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment LoggedInAccountOperationsFields on LoggedInAccountOperations {
2 |   id
3 |   isFollowedByMe
4 |   isFollowingMe
5 |   isMutedByMe
6 |   isBlockedByMe
7 | }
8 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/account/username-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment UsernameFields on Username {
2 |   namespace
3 |   localName
4 |   linkedTo
5 |   value
6 | }
7 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/any-key-value-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment AnyKeyValueFields on AnyKeyValue {
 2 |   ... on AddressKeyValue {
 3 |     key
 4 |     address
 5 |   }
 6 |   ... on BigDecimalKeyValue {
 7 |     key
 8 |     bigDecimal
 9 |   }
10 |   ... on StringKeyValue {
11 |     key
12 |     string
13 |   }
14 | }
15 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/app-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment AppFields on App {
 2 |   address
 3 |   defaultFeedAddress
 4 |   graphAddress
 5 |   namespaceAddress
 6 |   sponsorshipAddress
 7 |   treasuryAddress
 8 |   createdAt
 9 |   metadata {
10 |     description
11 |     developer
12 |     logo
13 |     name
14 |     platforms
15 |     privacyPolicy
16 |     termsOfService
17 |     url
18 |   }
19 | }
20 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/boolean-value-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment BooleanValueFields on BooleanValue {
2 |   onChain
3 |   optimistic
4 | }
5 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/erc20-amount-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment Erc20AmountFields on Erc20Amount {
2 |   asset {
3 |     ...Erc20Fields
4 |   }
5 |   value
6 | }
7 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/erc20-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment Erc20Fields on Erc20 {
 2 |   contract {
 3 |     address
 4 |     chainId
 5 |   }
 6 |   decimals
 7 |   name
 8 |   symbol
 9 | }
10 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/metadata-attribute-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment MetadataAttributeFields on MetadataAttribute {
2 |   type
3 |   key
4 |   value
5 | }
6 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/network-address-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment NetworkAddressFields on NetworkAddress {
2 |   address
3 |   chainId
4 | }
5 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/notifications/comment-notification-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment CommentNotificationFields on CommentNotification {
2 |   __typename
3 |   id
4 |   comment {
5 |     ...PostFields
6 |   }
7 | }
8 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/notifications/follow-notification-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment FollowNotificationFields on FollowNotification {
 2 |   __typename
 3 |   id
 4 |   followers {
 5 |     account {
 6 |       ...AccountFields
 7 |     }
 8 |   }
 9 | }
10 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/notifications/mention-notification-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment MentionNotificationFields on MentionNotification {
2 |   __typename
3 |   id
4 |   post {
5 |     ...PostFields
6 |   }
7 | }
8 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/notifications/quote-notification-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment QuoteNotificationFields on QuoteNotification {
2 |   __typename
3 |   id
4 |   quote {
5 |     ...PostFields
6 |   }
7 | }
8 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/notifications/reaction-notification-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment ReactionNotificationFields on ReactionNotification {
 2 |   __typename
 3 |   id
 4 |   post {
 5 |     ...PostFields
 6 |   }
 7 |   reactions {
 8 |     account {
 9 |       ...AccountFields
10 |     }
11 |   }
12 | }
13 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/notifications/repost-notification-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment RepostNotificationFields on RepostNotification {
 2 |   __typename
 3 |   id
 4 |   post {
 5 |     ...PostFields
 6 |   }
 7 |   reposts {
 8 |     account {
 9 |       ...AccountFields
10 |     }
11 |     repostedAt
12 |   }
13 | }
14 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/collect/pay-to-collect-config-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment PayToCollectConfigFields on PayToCollectConfig {
 2 |   referralShare
 3 |   recipients {
 4 |     address
 5 |     percent
 6 |   }
 7 |   amount {
 8 |     ...Erc20AmountFields
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/collect/simple-collect-action-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment SimpleCollectActionFields on SimpleCollectAction {
 2 |   address
 3 |   collectLimit
 4 |   isImmutable
 5 |   endsAt
 6 |   payToCollect {
 7 |     ...PayToCollectConfigFields
 8 |   }
 9 | }
10 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/collect/unknown-action-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment UnknownPostActionFields on UnknownPostAction {
2 |   __typename
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/logged-in-post-operations-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment LoggedInPostOperationsFields on LoggedInPostOperations {
 2 |   id
 3 |   hasBookmarked
 4 |   hasReacted
 5 |   hasSimpleCollected
 6 |   hasTipped
 7 |   isNotInterested
 8 |   hasCommented {
 9 |     ...BooleanValueFields
10 |   }
11 |   hasQuoted {
12 |     ...BooleanValueFields
13 |   }
14 |   hasReposted {
15 |     ...BooleanValueFields
16 |   }
17 |   canRepost {
18 |     __typename
19 |   }
20 |   canQuote {
21 |     __typename
22 |   }
23 |   canComment {
24 |     __typename
25 |   }
26 |   simpleCollectCount
27 |   postTipCount
28 | }
29 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/metadata/media/media-audio-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment MediaAudioFields on MediaAudio {
2 |   artist
3 |   item
4 |   cover
5 |   license
6 | }
7 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/metadata/media/media-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment MediaFields on AnyMedia {
 2 |   ... on MediaVideo {
 3 |     ...MediaVideoFields
 4 |   }
 5 |   ... on MediaImage {
 6 |     ...MediaImageFields
 7 |   }
 8 |   ... on MediaAudio {
 9 |     ...MediaAudioFields
10 |   }
11 | }
12 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/metadata/media/media-image-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment MediaImageFields on MediaImage {
2 |   altTag
3 |   attributes {
4 |     ...MetadataAttributeFields
5 |   }
6 |   item
7 |   license
8 | }
9 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/metadata/media/media-video-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment MediaVideoFields on MediaVideo {
 2 |   altTag
 3 |   attributes {
 4 |     ...MetadataAttributeFields
 5 |   }
 6 |   cover
 7 |   duration
 8 |   item
 9 |   license
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/metadata/video-metadata-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment VideoMetadataFields on VideoMetadata {
 2 |   __typename
 3 |   id
 4 |   title
 5 |   content
 6 |   tags
 7 |   attributes {
 8 |     ...MetadataAttributeFields
 9 |   }
10 |   attachments {
11 |     ...MediaFields
12 |   }
13 |   video {
14 |     ...MediaVideoFields
15 |   }
16 | }
17 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/post-action-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment PostActionFields on PostAction {
2 |   ... on SimpleCollectAction {
3 |     ...SimpleCollectActionFields
4 |   }
5 |   ... on UnknownPostAction {
6 |     ...UnknownPostActionFields
7 |   }
8 | }
9 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/post-base-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment PostBaseFields on Post {
 2 |   __typename
 3 |   id
 4 |   slug
 5 |   isEdited
 6 |   isDeleted
 7 |   timestamp
 8 |   author {
 9 |     ...AccountFields
10 |   }
11 |   feed {
12 |     group {
13 |       address
14 |       metadata {
15 |         name
16 |         description
17 |         icon
18 |         coverPicture
19 |       }
20 |     }
21 |   }
22 |   app {
23 |     ...AppFields
24 |   }
25 |   metadata {
26 |     ...PostMetadataFields
27 |   }
28 |   actions {
29 |     ...PostActionFields
30 |   }
31 |   stats {
32 |     ...PostStatsFields
33 |   }
34 |   operations {
35 |     ...LoggedInPostOperationsFields
36 |   }
37 | }
38 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/post-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment PostFields on Post {
 2 |   ...PostBaseFields
 3 |   root {
 4 |     ...PostBaseFields
 5 |   }
 6 |   commentOn {
 7 |     ...PostBaseFields
 8 |   }
 9 |   quoteOf {
10 |     ...PostBaseFields
11 |   }
12 | }
13 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/post-stats-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment PostStatsFields on PostStats {
2 |   bookmarks
3 |   collects
4 |   comments
5 |   quotes
6 |   reactions
7 |   reposts
8 | }
9 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/post/repost-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment RepostFields on Repost {
 2 |   __typename
 3 |   id
 4 |   author {
 5 |     ...AccountFields
 6 |   }
 7 |   isDeleted
 8 |   timestamp
 9 |   repostOf {
10 |     ...PostFields
11 |   }
12 | }
13 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/self-funded-transaction-request-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment SelfFundedTransactionRequestFields on SelfFundedTransactionRequest {
 2 |   reason
 3 |   raw {
 4 |     chainId
 5 |     data
 6 |     from
 7 |     gasLimit
 8 |     maxFeePerGas
 9 |     maxPriorityFeePerGas
10 |     nonce
11 |     to
12 |     type
13 |     value
14 |   }
15 | }
16 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/fragments/sponsored-transaction-request-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment SponsoredTransactionRequestFields on SponsoredTransactionRequest {
 2 |   reason
 3 |   raw {
 4 |     chainId
 5 |     data
 6 |     from
 7 |     gasLimit
 8 |     maxFeePerGas
 9 |     maxPriorityFeePerGas
10 |     nonce
11 |     to
12 |     type
13 |     value
14 |     customData {
15 |       customSignature
16 |       factoryDeps
17 |       gasPerPubdata
18 |       paymasterParams {
19 |         paymaster
20 |         paymasterInput
21 |       }
22 |     }
23 |   }
24 | }
25 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/mutations/account/create-account.graphql:
--------------------------------------------------------------------------------
 1 | mutation CreateAccountWithUsername(
 2 |   $request: CreateAccountWithUsernameRequest!
 3 | ) {
 4 |   createAccountWithUsername(request: $request) {
 5 |     ... on UsernameTaken {
 6 |       reason
 7 |     }
 8 |     ... on CreateAccountResponse {
 9 |       hash
10 |     }
11 |     ... on NamespaceOperationValidationFailed {
12 |       reason
13 |     }
14 |     ... on SelfFundedTransactionRequest {
15 |       reason
16 |     }
17 |     ... on SponsoredTransactionRequest {
18 |       reason
19 |     }
20 |     ... on TransactionWillFail {
21 |       reason
22 |     }
23 |   }
24 | }
25 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/mutations/auth/authenticate.graphql:
--------------------------------------------------------------------------------
 1 | mutation Authenticate($request: SignedAuthChallenge!) {
 2 |   authenticate(request: $request) {
 3 |     ... on AuthenticationTokens {
 4 |       __typename
 5 |       accessToken
 6 |       refreshToken
 7 |       idToken
 8 |     }
 9 |     ... on ExpiredChallengeError {
10 |       __typename
11 |       reason
12 |     }
13 |     ... on ForbiddenError {
14 |       __typename
15 |       reason
16 |     }
17 |     ... on WrongSignerError {
18 |       __typename
19 |       reason
20 |     }
21 |   }
22 | }
23 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/mutations/auth/challenge.graphql:
--------------------------------------------------------------------------------
1 | mutation Challenge($request: ChallengeRequest!) {
2 |   challenge(request: $request) {
3 |     id
4 |     text
5 |   }
6 | }
7 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/mutations/auth/refresh.graphql:
--------------------------------------------------------------------------------
 1 | mutation Refresh($request: RefreshRequest!) {
 2 |   refresh(request: $request) {
 3 |     ... on AuthenticationTokens {
 4 |       __typename
 5 |       accessToken
 6 |       refreshToken
 7 |       idToken
 8 |     }
 9 |     ... on ForbiddenError {
10 |       __typename
11 |       reason
12 |     }
13 |   }
14 | }
15 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/mutations/post/add-reaction.graphql:
--------------------------------------------------------------------------------
 1 | mutation AddReaction($request: AddReactionRequest!) {
 2 |   addReaction(request: $request) {
 3 |     ... on AddReactionResponse {
 4 |       success
 5 |     }
 6 |     ... on AddReactionFailure {
 7 |       reason
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/mutations/post/bookmark-post.graphql:
--------------------------------------------------------------------------------
1 | mutation BookmarkPost($request: BookmarkPostRequest!) {
2 |   bookmarkPost(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/mutations/post/create-post.graphql:
--------------------------------------------------------------------------------
 1 | mutation CreatePost($request: CreatePostRequest!) {
 2 |   post(request: $request) {
 3 |     ... on PostResponse {
 4 |       hash
 5 |     }
 6 |     ... on SelfFundedTransactionRequest {
 7 |       ...SelfFundedTransactionRequestFields
 8 |     }
 9 |     ... on SponsoredTransactionRequest {
10 |       ...SponsoredTransactionRequestFields
11 |     }
12 |     ... on TransactionWillFail {
13 |       reason
14 |     }
15 |   }
16 | }
17 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/mutations/post/delete-post.graphql:
--------------------------------------------------------------------------------
 1 | mutation DeletePost($request: DeletePostRequest!) {
 2 |   deletePost(request: $request) {
 3 |     ... on DeletePostResponse {
 4 |       hash
 5 |     }
 6 |     ... on SelfFundedTransactionRequest {
 7 |       ...SelfFundedTransactionRequestFields
 8 |     }
 9 |     ... on SponsoredTransactionRequest {
10 |       ...SponsoredTransactionRequestFields
11 |     }
12 |     ... on TransactionWillFail {
13 |       reason
14 |     }
15 |   }
16 | }
17 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/mutations/post/edit-post.graphql:
--------------------------------------------------------------------------------
 1 | mutation EditPost($request: EditPostRequest!) {
 2 |   editPost(request: $request) {
 3 |     ... on PostResponse {
 4 |       hash
 5 |     }
 6 |     ... on SelfFundedTransactionRequest {
 7 |       ...SelfFundedTransactionRequestFields
 8 |     }
 9 |     ... on SponsoredTransactionRequest {
10 |       ...SponsoredTransactionRequestFields
11 |     }
12 |     ... on TransactionWillFail {
13 |       reason
14 |     }
15 |   }
16 | }
17 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/mutations/post/report-post.graphql:
--------------------------------------------------------------------------------
1 | mutation ReportPost($request: ReportPostRequest!) {
2 |   reportPost(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/mutations/post/repost.graphql:
--------------------------------------------------------------------------------
 1 | mutation Repost($request: CreateRepostRequest!) {
 2 |   repost(request: $request) {
 3 |     ... on PostResponse {
 4 |       hash
 5 |     }
 6 |     ... on SelfFundedTransactionRequest {
 7 |       ...SelfFundedTransactionRequestFields
 8 |     }
 9 |     ... on SponsoredTransactionRequest {
10 |       ...SponsoredTransactionRequestFields
11 |     }
12 |     ... on TransactionWillFail {
13 |       reason
14 |     }
15 |   }
16 | }
17 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/mutations/post/undo-bookmark.graphql:
--------------------------------------------------------------------------------
1 | mutation UndoBookmarkPost($request: BookmarkPostRequest!) {
2 |   undoBookmarkPost(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/mutations/post/undo-reaction.graphql:
--------------------------------------------------------------------------------
 1 | mutation UndoReaction($request: UndoReactionRequest!) {
 2 |   undoReaction(request: $request) {
 3 |     ... on UndoReactionResponse {
 4 |       success
 5 |     }
 6 |     ... on UndoReactionFailure {
 7 |       reason
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/account-managers.graphql:
--------------------------------------------------------------------------------
 1 | query AccountManagers($request: AccountManagersRequest!) {
 2 |   accountManagers(request: $request) {
 3 |     items {
 4 |       manager
 5 |       isLensManager
 6 |       permissions {
 7 |         ...AccountManagerPermissions
 8 |       }
 9 |       addedAt
10 |     }
11 |     pageInfo {
12 |       next
13 |     }
14 |   }
15 | }
16 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/account-stats.graphql:
--------------------------------------------------------------------------------
 1 | query AccountStats($request: AccountStatsRequest!) {
 2 |   accountStats(request: $request) {
 3 |     feedStats {
 4 |       posts
 5 |       comments
 6 |       reposts
 7 |       quotes
 8 |       reacted
 9 |       reactions
10 |       collects
11 |     }
12 |     graphFollowStats {
13 |       followers
14 |       following
15 |     }
16 |   }
17 | }
18 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/account.graphql:
--------------------------------------------------------------------------------
1 | query Account($request: AccountRequest!) {
2 |   account(request: $request) {
3 |     ...AccountFields
4 |   }
5 | }
6 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/accounts-available.graphql:
--------------------------------------------------------------------------------
 1 | query AccountsAvailable(
 2 |   $accountsAvailableRequest: AccountsAvailableRequest!
 3 |   $lastLoggedInAccountRequest: LastLoggedInAccountRequest!
 4 | ) {
 5 |   lastLoggedInAccount(request: $lastLoggedInAccountRequest) {
 6 |     ...AccountFields
 7 |   }
 8 |   accountsAvailable(request: $accountsAvailableRequest) {
 9 |     items {
10 |       ... on AccountManaged {
11 |         __typename
12 |         account {
13 |           ...AccountFields
14 |         }
15 |       }
16 |       ... on AccountOwned {
17 |         __typename
18 |         account {
19 |           ...AccountFields
20 |         }
21 |       }
22 |     }
23 |     pageInfo {
24 |       next
25 |     }
26 |   }
27 | }
28 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/accounts-blocked.graphql:
--------------------------------------------------------------------------------
 1 | query AccountsBlocked($request: AccountsBlockedRequest!) {
 2 |   accountsBlocked(request: $request) {
 3 |     items {
 4 |       account {
 5 |         ...AccountFields
 6 |       }
 7 |       blockedAt
 8 |     }
 9 |     pageInfo {
10 |       next
11 |     }
12 |   }
13 | }
14 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/accounts.graphql:
--------------------------------------------------------------------------------
 1 | query Accounts($request: AccountsRequest!) {
 2 |   accounts(request: $request) {
 3 |     items {
 4 |       ...AccountFields
 5 |     }
 6 |     pageInfo {
 7 |       next
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/authenticated-sessions.graphql:
--------------------------------------------------------------------------------
 1 | query AuthenticatedSessions($request: AuthenticatedSessionsRequest!) {
 2 |   authenticatedSessions(request: $request) {
 3 |     items {
 4 |       authenticationId
 5 |       app
 6 |       browser
 7 |       device
 8 |       os
 9 |       origin
10 |       signer
11 |       createdAt
12 |       updatedAt
13 |     }
14 |     pageInfo {
15 |       next
16 |     }
17 |   }
18 | }
19 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/followers-you-know.graphql:
--------------------------------------------------------------------------------
 1 | query FollowersYouKnow($request: FollowersYouKnowRequest!) {
 2 |   followersYouKnow(request: $request) {
 3 |     items {
 4 |       follower {
 5 |         ...AccountFields
 6 |       }
 7 |       followedOn
 8 |     }
 9 |     pageInfo {
10 |       next
11 |     }
12 |   }
13 | }
14 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/followers.graphql:
--------------------------------------------------------------------------------
 1 | query Followers($request: FollowersRequest!) {
 2 |   followers(request: $request) {
 3 |     items {
 4 |       follower {
 5 |         ...AccountFields
 6 |       }
 7 |       followedOn
 8 |     }
 9 |     pageInfo {
10 |       next
11 |     }
12 |   }
13 | }
14 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/following.graphql:
--------------------------------------------------------------------------------
 1 | query Following($request: FollowingRequest!) {
 2 |   following(request: $request) {
 3 |     items {
 4 |       following {
 5 |         ...AccountFields
 6 |       }
 7 |       followedOn
 8 |     }
 9 |     pageInfo {
10 |       next
11 |     }
12 |   }
13 | }
14 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/last-logged-in-account.graphql:
--------------------------------------------------------------------------------
 1 | query LastLoggedInAccount($request: LastLoggedInAccountRequest!) {
 2 |   lastLoggedInAccount(request: $request) {
 3 |     address
 4 |     owner
 5 |     score
 6 |     metadata {
 7 |       ...AccountMetadataFields
 8 |     }
 9 |     username {
10 |       ...UsernameFields
11 |     }
12 |     operations {
13 |       ...LoggedInAccountOperationsFields
14 |     }
15 |   }
16 | }
17 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/me.graphql:
--------------------------------------------------------------------------------
 1 | query Me {
 2 |   me {
 3 |     loggedInAs {
 4 |       ... on AccountManaged {
 5 |         account {
 6 |           ...AccountFields
 7 |         }
 8 |         addedAt
 9 |       }
10 |       ... on AccountOwned {
11 |         account {
12 |           ...AccountFields
13 |         }
14 |         addedAt
15 |       }
16 |     }
17 |     isSignless
18 |     isSponsored
19 |     appLoggedIn
20 |     limit {
21 |       window
22 |       allowanceLeft
23 |       allowanceUsed
24 |       allowance
25 |     }
26 |   }
27 | }
28 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/notifications.graphql:
--------------------------------------------------------------------------------
 1 | query Notifications($request: NotificationRequest!) {
 2 |   notifications(request: $request) {
 3 |     items {
 4 |       ... on CommentNotification {
 5 |         ...CommentNotificationFields
 6 |       }
 7 |       ... on FollowNotification {
 8 |         ...FollowNotificationFields
 9 |       }
10 |       ... on MentionNotification {
11 |         ...MentionNotificationFields
12 |       }
13 |       ... on QuoteNotification {
14 |         ...QuoteNotificationFields
15 |       }
16 |       ... on ReactionNotification {
17 |         ...ReactionNotificationFields
18 |       }
19 |       ... on RepostNotification {
20 |         ...RepostNotificationFields
21 |       }
22 |     }
23 |     pageInfo {
24 |       next
25 |     }
26 |   }
27 | }
28 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/account/usernames.graphql:
--------------------------------------------------------------------------------
 1 | query Usernames($request: UsernamesRequest!) {
 2 |   usernames(request: $request) {
 3 |     items {
 4 |       ...UsernameFields
 5 |     }
 6 |     pageInfo {
 7 |       next
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/post/post-references.graphql:
--------------------------------------------------------------------------------
 1 | query PostReferences($request: PostReferencesRequest!) {
 2 |   postReferences(request: $request) {
 3 |     items {
 4 |       ...PostFields
 5 |     }
 6 |     pageInfo {
 7 |       next
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/post/post.graphql:
--------------------------------------------------------------------------------
1 | query Post($request: PostRequest!) {
2 |   post(request: $request) {
3 |     ...PostFields
4 |   }
5 | }
6 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/post/posts.graphql:
--------------------------------------------------------------------------------
 1 | query Posts($request: PostsRequest!) {
 2 |   posts(request: $request) {
 3 |     items {
 4 |       ... on Post {
 5 |         ...PostFields
 6 |       }
 7 |       ... on Repost {
 8 |         ...RepostFields
 9 |       }
10 |     }
11 |     pageInfo {
12 |       next
13 |     }
14 |   }
15 | }
16 | 


--------------------------------------------------------------------------------
/packages/indexer/documents/queries/search.graphql:
--------------------------------------------------------------------------------
 1 | query Search($postsRequest: PostsRequest!, $accountsRequest: AccountsRequest!) {
 2 |   posts(request: $postsRequest) {
 3 |     items {
 4 |       ... on Post {
 5 |         ...PostFields
 6 |       }
 7 |       ... on Repost {
 8 |         ...RepostFields
 9 |       }
10 |     }
11 |   }
12 |   accounts(request: $accountsRequest) {
13 |     items {
14 |       ...AccountFields
15 |     }
16 |   }
17 | }
18 | 


--------------------------------------------------------------------------------
/packages/indexer/gql/generated/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./fragment-masking";
2 | export * from "./gql";


--------------------------------------------------------------------------------
/packages/indexer/gql/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./generated";
2 | export * from "./generated/graphql";
3 | 


--------------------------------------------------------------------------------
/packages/indexer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 |   "extends": "@tape.xyz/tsconfig/base.json",
3 |   "compilerOptions": {
4 |     "module": "ESNext",
5 |     "moduleResolution": "Node"
6 |   }
7 | }
8 | 


--------------------------------------------------------------------------------
/packages/lens/codegen.ts:
--------------------------------------------------------------------------------
 1 | import type { CodegenConfig } from "@graphql-codegen/cli";
 2 | import { LensEndpoint } from "@tape.xyz/constants";
 3 | 
 4 | const config: CodegenConfig = {
 5 |   overwrite: true,
 6 |   schema: LensEndpoint.Testnet,
 7 |   documents: "./documents/**/*.graphql",
 8 |   customFetch: "node-fetch",
 9 |   generates: {
10 |     "generated.ts": {
11 |       plugins: [
12 |         "typescript",
13 |         "typescript-operations",
14 |         "typescript-react-apollo",
15 |         "fragment-matcher"
16 |       ]
17 |     }
18 |   },
19 |   hooks: {
20 |     afterAllFileWrite: ["biome format --write ."]
21 |   }
22 | };
23 | 
24 | export default config;
25 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/amount-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment AmountFields on Amount {
2 |   asset {
3 |     ...Erc20Fields
4 |   }
5 |   value
6 | }
7 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/comment-base-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment CommentBaseFields on Comment {
 2 |   __typename
 3 |   id
 4 |   publishedOn {
 5 |     id
 6 |   }
 7 |   isHidden
 8 |   momoka {
 9 |     proof
10 |   }
11 |   txHash
12 |   createdAt
13 |   by {
14 |     ...ProfileFields
15 |   }
16 |   stats {
17 |     ...PublicationStatsFields
18 |   }
19 |   operations {
20 |     ...PublicationOperationFields
21 |   }
22 |   metadata {
23 |     ...AnyPublicationMetadataFields
24 |   }
25 |   openActionModules {
26 |     ...OpenActionModulesFields
27 |   }
28 |   root {
29 |     ...PostFields
30 |   }
31 | }
32 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/comment-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment CommentFields on Comment {
2 |   ...CommentBaseFields
3 |   commentOn {
4 |     ...PrimaryPublicationFields
5 |   }
6 | }
7 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/erc20-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment Erc20Fields on Asset {
 2 |   ... on Erc20 {
 3 |     name
 4 |     symbol
 5 |     decimals
 6 |     contract {
 7 |       ...NetworkAddressFields
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/fiat-amount-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment FiatAmountFields on FiatAmount {
2 |   asset {
3 |     name
4 |     symbol
5 |     decimals
6 |   }
7 |   value
8 | }
9 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/follow-module-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment FollowModuleFields on FollowModule {
 2 |   ... on FeeFollowModuleSettings {
 3 |     type
 4 |     amount {
 5 |       ...AmountFields
 6 |       asFiat(request: { for: USD }) {
 7 |         ...FiatAmountFields
 8 |       }
 9 |     }
10 |     recipient
11 |   }
12 |   ... on RevertFollowModuleSettings {
13 |     type
14 |   }
15 |   ... on UnknownFollowModuleSettings {
16 |     type
17 |   }
18 | }
19 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/handle-info-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment HandleInfoFields on HandleInfo {
2 |   id
3 |   fullHandle
4 |   localName
5 |   ownedBy
6 | }
7 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/image-set-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment ImageSetFields on ImageSet {
 2 |   __typename
 3 |   raw {
 4 |     uri
 5 |   }
 6 |   optimized {
 7 |     uri
 8 |   }
 9 | }
10 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/metadata-attribute-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment MetadataAttributeFields on MetadataAttribute {
2 |   type
3 |   key
4 |   value
5 | }
6 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/mirror-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment MirrorFields on Mirror {
 2 |   id
 3 |   publishedOn {
 4 |     id
 5 |   }
 6 |   isHidden
 7 |   momoka {
 8 |     proof
 9 |   }
10 |   txHash
11 |   createdAt
12 |   mirrorOn {
13 |     ...PrimaryPublicationFields
14 |   }
15 | }
16 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/network-address-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment NetworkAddressFields on NetworkAddress {
2 |   address
3 |   chainId
4 | }
5 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/post-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment PostFields on Post {
 2 |   __typename
 3 |   id
 4 |   publishedOn {
 5 |     id
 6 |   }
 7 |   isHidden
 8 |   momoka {
 9 |     proof
10 |   }
11 |   txHash
12 |   createdAt
13 |   by {
14 |     ...ProfileFields
15 |   }
16 |   stats {
17 |     ...PublicationStatsFields
18 |   }
19 |   operations {
20 |     ...PublicationOperationFields
21 |   }
22 |   metadata {
23 |     ...AnyPublicationMetadataFields
24 |   }
25 |   openActionModules {
26 |     ...OpenActionModulesFields
27 |   }
28 | }
29 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/primary-publication-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment PrimaryPublicationFields on PrimaryPublication {
 2 |   ... on Post {
 3 |     ...PostFields
 4 |   }
 5 |   ... on Comment {
 6 |     ...CommentBaseFields
 7 |   }
 8 |   ... on Quote {
 9 |     ...QuoteBaseFields
10 |   }
11 | }
12 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/profile-metadata-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment ProfileMetadataFields on ProfileMetadata {
 2 |   displayName
 3 |   bio
 4 |   rawURI
 5 |   picture {
 6 |     ... on ImageSet {
 7 |       ...ImageSetFields
 8 |     }
 9 |     ... on NftImage {
10 |       image {
11 |         ...ImageSetFields
12 |       }
13 |     }
14 |   }
15 |   coverPicture {
16 |     ...ImageSetFields
17 |   }
18 |   attributes {
19 |     ...MetadataAttributeFields
20 |   }
21 | }
22 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/profile-operations-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment ProfileOperationsFields on ProfileOperations {
 2 |   id
 3 |   isBlockedByMe {
 4 |     value
 5 |   }
 6 |   isFollowedByMe {
 7 |     value
 8 |   }
 9 |   isFollowingMe {
10 |     value
11 |   }
12 |   canBlock
13 |   canUnblock
14 |   canFollow
15 |   canUnfollow
16 | }
17 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/profile-stats-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment ProfileStatsFields on ProfileStats {
 2 |   id
 3 |   followers
 4 |   following
 5 |   comments
 6 |   posts
 7 |   mirrors
 8 |   quotes
 9 |   publications
10 |   reactions
11 |   reacted
12 |   countOpenActions
13 |   lensClassifierScore
14 | }
15 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-metadata/article-metadata-v3-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment ArticleMetadataV3Fields on ArticleMetadataV3 {
 2 |   __typename
 3 |   id
 4 |   content
 5 |   tags
 6 |   attributes {
 7 |     ...MetadataAttributeFields
 8 |   }
 9 |   attachments {
10 |     ...PublicationMetadataMediaFields
11 |   }
12 | }
13 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-metadata/audio-metadata-v3-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment AudioMetadataV3Fields on AudioMetadataV3 {
 2 |   __typename
 3 |   id
 4 |   rawURI
 5 |   tags
 6 |   contentWarning
 7 |   attributes {
 8 |     ...MetadataAttributeFields
 9 |   }
10 |   asset {
11 |     ...PublicationMetadataMediaAudioFields
12 |   }
13 |   attachments {
14 |     ...PublicationMetadataMediaFields
15 |   }
16 |   title
17 |   content
18 | }
19 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-metadata/checkin-metadata-v3-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment CheckingInMetadataV3Fields on CheckingInMetadataV3 {
 2 |   __typename
 3 |   id
 4 |   location
 5 |   tags
 6 |   geographic {
 7 |     latitude
 8 |     longitude
 9 |   }
10 |   attributes {
11 |     ...MetadataAttributeFields
12 |   }
13 |   attachments {
14 |     ...PublicationMetadataMediaFields
15 |   }
16 |   content
17 | }
18 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-metadata/image-metadata-v3-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment ImageMetadataV3Fields on ImageMetadataV3 {
 2 |   __typename
 3 |   id
 4 |   rawURI
 5 |   tags
 6 |   contentWarning
 7 |   attributes {
 8 |     ...MetadataAttributeFields
 9 |   }
10 |   attachments {
11 |     ...PublicationMetadataMediaFields
12 |   }
13 |   asset {
14 |     ...PublicationMetadataMediaImageFields
15 |   }
16 |   title
17 |   content
18 | }
19 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-metadata/link-metadata-v3-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment LinkMetadataV3Fields on LinkMetadataV3 {
 2 |   __typename
 3 |   id
 4 |   rawURI
 5 |   tags
 6 |   contentWarning
 7 |   attributes {
 8 |     ...MetadataAttributeFields
 9 |   }
10 |   sharingLink
11 |   attachments {
12 |     ...PublicationMetadataMediaFields
13 |   }
14 |   content
15 | }
16 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-metadata/live-stream-metadata-v3-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment LiveStreamMetadataV3Fields on LiveStreamMetadataV3 {
 2 |   __typename
 3 |   id
 4 |   rawURI
 5 |   tags
 6 |   contentWarning
 7 |   attributes {
 8 |     ...MetadataAttributeFields
 9 |   }
10 |   startsAt
11 |   endsAt
12 |   playbackURL
13 |   liveURL
14 |   checkLiveAPI
15 |   title
16 |   content
17 |   attachments {
18 |     ...PublicationMetadataMediaFields
19 |   }
20 | }
21 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-metadata/media-fields/publication-metadata-media-audio-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment PublicationMetadataMediaAudioFields on PublicationMetadataMediaAudio {
 2 |   audio {
 3 |     raw {
 4 |       uri
 5 |     }
 6 |     optimized {
 7 |       uri
 8 |     }
 9 |   }
10 |   cover {
11 |     raw {
12 |       uri
13 |     }
14 |     optimized {
15 |       uri
16 |     }
17 |   }
18 |   duration
19 | }
20 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-metadata/media-fields/publication-metadata-media-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment PublicationMetadataMediaFields on PublicationMetadataMedia {
 2 |   ... on PublicationMetadataMediaVideo {
 3 |     __typename
 4 |     ...PublicationMetadataMediaVideoFields
 5 |   }
 6 |   ... on PublicationMetadataMediaImage {
 7 |     __typename
 8 |     ...PublicationMetadataMediaImageFields
 9 |   }
10 |   ... on PublicationMetadataMediaAudio {
11 |     __typename
12 |     ...PublicationMetadataMediaAudioFields
13 |   }
14 | }
15 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-metadata/media-fields/publication-metadata-media-image-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment PublicationMetadataMediaImageFields on PublicationMetadataMediaImage {
 2 |   image {
 3 |     raw {
 4 |       uri
 5 |     }
 6 |     optimized {
 7 |       uri
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-metadata/media-fields/publication-metadata-media-video-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment PublicationMetadataMediaVideoFields on PublicationMetadataMediaVideo {
 2 |   video {
 3 |     raw {
 4 |       uri
 5 |     }
 6 |     optimized {
 7 |       uri
 8 |     }
 9 |   }
10 |   cover {
11 |     raw {
12 |       uri
13 |     }
14 |     optimized {
15 |       uri
16 |     }
17 |   }
18 |   duration
19 | }
20 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-metadata/mint-metadata-v3-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment MintMetadataV3Fields on MintMetadataV3 {
 2 |   __typename
 3 |   id
 4 |   rawURI
 5 |   tags
 6 |   contentWarning
 7 |   attributes {
 8 |     ...MetadataAttributeFields
 9 |   }
10 |   mintLink
11 |   attachments {
12 |     ...PublicationMetadataMediaFields
13 |   }
14 |   content
15 | }
16 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-metadata/text-only-metadata-v3-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment TextOnlyMetadataV3Fields on TextOnlyMetadataV3 {
 2 |   __typename
 3 |   id
 4 |   rawURI
 5 |   tags
 6 |   contentWarning
 7 |   attributes {
 8 |     ...MetadataAttributeFields
 9 |   }
10 |   content
11 | }
12 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-metadata/video-metadata-v3-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment VideoMetadataV3Fields on VideoMetadataV3 {
 2 |   __typename
 3 |   id
 4 |   rawURI
 5 |   tags
 6 |   contentWarning
 7 |   attributes {
 8 |     ...MetadataAttributeFields
 9 |   }
10 |   asset {
11 |     ...PublicationMetadataMediaVideoFields
12 |   }
13 |   attachments {
14 |     ...PublicationMetadataMediaFields
15 |   }
16 |   title
17 |   content
18 |   isShortVideo
19 | }
20 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-operation-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment PublicationOperationFields on PublicationOperations {
 2 |   isNotInterested
 3 |   hasBookmarked
 4 |   hasReported
 5 |   canAct
 6 |   hasActed {
 7 |     value
 8 |     isFinalisedOnchain
 9 |   }
10 |   actedOn {
11 |     ... on KnownCollectOpenActionResult {
12 |       type
13 |     }
14 |     ... on UnknownOpenActionResult {
15 |       address
16 |       category
17 |       initReturnData
18 |     }
19 |   }
20 |   hasReacted(request: { type: UPVOTE })
21 |   canComment
22 |   canMirror
23 |   hasMirrored
24 |   canDecrypt {
25 |     result
26 |     reasons
27 |     extraDetails
28 |   }
29 | }
30 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/publication-stats-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment PublicationStatsFields on PublicationStats {
2 |   id
3 |   comments
4 |   mirrors
5 |   quotes
6 |   reactions(request: { type: UPVOTE })
7 |   countOpenActions
8 | }
9 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/quote-base-fields.graphql:
--------------------------------------------------------------------------------
 1 | fragment QuoteBaseFields on Quote {
 2 |   __typename
 3 |   id
 4 |   publishedOn {
 5 |     id
 6 |   }
 7 |   isHidden
 8 |   momoka {
 9 |     proof
10 |   }
11 |   txHash
12 |   createdAt
13 |   by {
14 |     ...ProfileFields
15 |   }
16 |   stats {
17 |     ...PublicationStatsFields
18 |   }
19 |   operations {
20 |     ...PublicationOperationFields
21 |   }
22 |   metadata {
23 |     ...AnyPublicationMetadataFields
24 |   }
25 |   openActionModules {
26 |     ...OpenActionModulesFields
27 |   }
28 | }
29 | 


--------------------------------------------------------------------------------
/packages/lens/documents/fragments/quote-fields.graphql:
--------------------------------------------------------------------------------
1 | fragment QuoteFields on Quote {
2 |   ...QuoteBaseFields
3 |   quoteOn {
4 |     ...PrimaryPublicationFields
5 |   }
6 | }
7 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/Authenticate.graphql:
--------------------------------------------------------------------------------
1 | mutation Authenticate($request: SignedAuthChallenge!) {
2 |   authenticate(request: $request) {
3 |     accessToken
4 |     refreshToken
5 |     identityToken
6 |   }
7 | }
8 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/Broadcast.graphql:
--------------------------------------------------------------------------------
 1 | mutation BroadcastOnchain($request: BroadcastRequest!) {
 2 |   broadcastOnchain(request: $request) {
 3 |     ... on RelaySuccess {
 4 |       __typename
 5 |       txHash
 6 |       txId
 7 |     }
 8 |     ... on RelayError {
 9 |       __typename
10 |       reason
11 |     }
12 |   }
13 | }
14 | 
15 | mutation BroadcastOnMomoka($request: BroadcastRequest!) {
16 |   broadcastOnMomoka(request: $request) {
17 |     ... on CreateMomokaPublicationResult {
18 |       id
19 |       proof
20 |       momokaId
21 |     }
22 |     ... on RelayError {
23 |       __typename
24 |       reason
25 |     }
26 |   }
27 | }
28 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/momoka/create-momoka-mirror-typed-data.graphql:
--------------------------------------------------------------------------------
 1 | mutation CreateMomokaMirrorTypedData($request: MomokaMirrorRequest!) {
 2 |   createMomokaMirrorTypedData(request: $request) {
 3 |     id
 4 |     expiresAt
 5 |     typedData {
 6 |       types {
 7 |         Mirror {
 8 |           name
 9 |           type
10 |         }
11 |       }
12 |       domain {
13 |         name
14 |         chainId
15 |         version
16 |         verifyingContract
17 |       }
18 |       value {
19 |         nonce
20 |         metadataURI
21 |         deadline
22 |         profileId
23 |         pointedProfileId
24 |         pointedPubId
25 |         referrerProfileIds
26 |         referrerPubIds
27 |         referenceModuleData
28 |       }
29 |     }
30 |   }
31 | }
32 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/momoka/create-momoka-post-typed-data.graphql:
--------------------------------------------------------------------------------
 1 | mutation CreateMomokaPostTypedData($request: MomokaPostRequest!) {
 2 |   createMomokaPostTypedData(request: $request) {
 3 |     id
 4 |     expiresAt
 5 |     typedData {
 6 |       types {
 7 |         Post {
 8 |           name
 9 |           type
10 |         }
11 |       }
12 |       domain {
13 |         name
14 |         chainId
15 |         version
16 |         verifyingContract
17 |       }
18 |       value {
19 |         nonce
20 |         deadline
21 |         profileId
22 |         contentURI
23 |         actionModules
24 |         actionModulesInitDatas
25 |         referenceModule
26 |         referenceModuleInitData
27 |       }
28 |     }
29 |   }
30 | }
31 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/on-chain/create-onchain-set-profile-metadata-typed-data.graphql:
--------------------------------------------------------------------------------
 1 | mutation CreateOnchainSetProfileMetadataTypedData(
 2 |   $options: TypedDataOptions
 3 |   $request: OnchainSetProfileMetadataRequest!
 4 | ) {
 5 |   createOnchainSetProfileMetadataTypedData(
 6 |     options: $options
 7 |     request: $request
 8 |   ) {
 9 |     expiresAt
10 |     id
11 |     typedData {
12 |       domain {
13 |         name
14 |         chainId
15 |         version
16 |         verifyingContract
17 |       }
18 |       types {
19 |         SetProfileMetadataURI {
20 |           name
21 |           type
22 |         }
23 |       }
24 |       value {
25 |         nonce
26 |         deadline
27 |         profileId
28 |         metadataURI
29 |       }
30 |     }
31 |   }
32 | }
33 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/profile/add-profile-interests.graphql:
--------------------------------------------------------------------------------
1 | mutation AddProfileInterests($request: ProfileInterestsRequest!) {
2 |   addProfileInterests(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/profile/create-profile-with-handle.graphql:
--------------------------------------------------------------------------------
 1 | mutation CreateProfileWithHandle($request: CreateProfileWithHandleRequest!) {
 2 |   createProfileWithHandle(request: $request) {
 3 |     ... on RelaySuccess {
 4 |       txHash
 5 |       txId
 6 |     }
 7 |     ... on CreateProfileWithHandleErrorResult {
 8 |       reason
 9 |     }
10 |   }
11 | }
12 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/profile/remove-profile-interests.graphql:
--------------------------------------------------------------------------------
1 | mutation RemoveProfileInterests($request: ProfileInterestsRequest!) {
2 |   removeProfileInterests(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/profile/set-profile-metadata.graphql:
--------------------------------------------------------------------------------
 1 | mutation SetProfileMetadata($request: OnchainSetProfileMetadataRequest!) {
 2 |   setProfileMetadata(request: $request) {
 3 |     ... on RelaySuccess {
 4 |       txHash
 5 |       txId
 6 |     }
 7 |     ... on LensProfileManagerRelayError {
 8 |       reason
 9 |     }
10 |   }
11 | }
12 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/publication/add-publication-bookmark.graphql:
--------------------------------------------------------------------------------
1 | mutation AddPublicationBookmark($request: PublicationBookmarkRequest!) {
2 |   addPublicationBookmark(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/publication/add-publication-not-interested.graphql:
--------------------------------------------------------------------------------
1 | mutation AddPublicationNotInterested(
2 |   $request: PublicationNotInterestedRequest!
3 | ) {
4 |   addPublicationNotInterested(request: $request)
5 | }
6 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/publication/add-reaction.graphql:
--------------------------------------------------------------------------------
1 | mutation AddReaction($request: ReactionRequest!) {
2 |   addReaction(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/publication/hide-publication.graphql:
--------------------------------------------------------------------------------
1 | mutation HidePublication($request: HidePublicationRequest!) {
2 |   hidePublication(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/publication/remove-publication-bookmark.graphql:
--------------------------------------------------------------------------------
1 | mutation RemovePublicationBookmark($request: PublicationBookmarkRequest!) {
2 |   removePublicationBookmark(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/publication/remove-reaction.graphql:
--------------------------------------------------------------------------------
1 | mutation RemoveReaction($request: ReactionRequest!) {
2 |   removeReaction(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/publication/report-profile.graphql:
--------------------------------------------------------------------------------
1 | mutation ReportProfile($request: ReportProfileRequest!) {
2 |   reportProfile(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/publication/report-publication.graphql:
--------------------------------------------------------------------------------
1 | mutation ReportPublication($request: ReportPublicationRequest!) {
2 |   reportPublication(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/mutations/publication/undo-publication-not-interested.graphql:
--------------------------------------------------------------------------------
1 | mutation UndoPublicationNotInterested(
2 |   $request: PublicationNotInterestedRequest!
3 | ) {
4 |   undoPublicationNotInterested(request: $request)
5 | }
6 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/Challenge.graphql:
--------------------------------------------------------------------------------
1 | query Challenge($request: ChallengeRequest!) {
2 |   challenge(request: $request) {
3 |     id
4 |     text
5 |   }
6 | }
7 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/Followers.graphql:
--------------------------------------------------------------------------------
 1 | query Followers($request: FollowersRequest!) {
 2 |   followers(request: $request) {
 3 |     items {
 4 |       ...ProfileFields
 5 |     }
 6 |     pageInfo {
 7 |       next
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/Following.graphql:
--------------------------------------------------------------------------------
 1 | query Following($request: FollowingRequest!) {
 2 |   following(request: $request) {
 3 |     items {
 4 |       ...ProfileFields
 5 |     }
 6 |     pageInfo {
 7 |       next
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/Profile.graphql:
--------------------------------------------------------------------------------
1 | query Profile($request: ProfileRequest!) {
2 |   profile(request: $request) {
3 |     ...ProfileFields
4 |   }
5 | }
6 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/Profiles.graphql:
--------------------------------------------------------------------------------
 1 | query Profiles($request: ProfilesRequest!) {
 2 |   profiles(request: $request) {
 3 |     items {
 4 |       ...ProfileFields
 5 |     }
 6 |     pageInfo {
 7 |       next
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/Publication.graphql:
--------------------------------------------------------------------------------
 1 | query Publication($request: PublicationRequest!) {
 2 |   publication(request: $request) {
 3 |     ... on Post {
 4 |       ...PostFields
 5 |     }
 6 |     ... on Comment {
 7 |       ...CommentFields
 8 |     }
 9 |     ... on Mirror {
10 |       ...MirrorFields
11 |     }
12 |     ... on Quote {
13 |       ...QuoteFields
14 |     }
15 |   }
16 | }
17 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/Publications.graphql:
--------------------------------------------------------------------------------
 1 | query Publications($request: PublicationsRequest!) {
 2 |   publications(request: $request) {
 3 |     items {
 4 |       ... on Post {
 5 |         ...PostFields
 6 |       }
 7 |       ... on Comment {
 8 |         ...CommentFields
 9 |       }
10 |       ... on Mirror {
11 |         ...MirrorFields
12 |       }
13 |       ... on Quote {
14 |         ...QuoteFields
15 |       }
16 |     }
17 |     pageInfo {
18 |       next
19 |     }
20 |   }
21 | }
22 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/approved-authentications.graphql:
--------------------------------------------------------------------------------
 1 | query ApprovedAuthentications($request: ApprovedAuthenticationRequest!) {
 2 |   approvedAuthentications(request: $request) {
 3 |     items {
 4 |       authorizationId
 5 |       browser
 6 |       device
 7 |       os
 8 |       origin
 9 |       expiresAt
10 |       createdAt
11 |       updatedAt
12 |     }
13 |     pageInfo {
14 |       next
15 |     }
16 |   }
17 | }
18 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/approved-module-allowance-amount.graphql:
--------------------------------------------------------------------------------
 1 | query ApprovedModuleAllowanceAmount(
 2 |   $request: ApprovedModuleAllowanceAmountRequest!
 3 | ) {
 4 |   approvedModuleAllowanceAmount(request: $request) {
 5 |     allowance {
 6 |       value
 7 |       asset {
 8 |         ...Erc20Fields
 9 |       }
10 |       asFiat(request: { for: USD }) {
11 |         ...FiatAmountFields
12 |       }
13 |     }
14 |     moduleContract {
15 |       ...NetworkAddressFields
16 |     }
17 |     moduleName
18 |   }
19 | }
20 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/current-profile.graphql:
--------------------------------------------------------------------------------
1 | query CurrentProfile($request: ProfileRequest!) {
2 |   profile(request: $request) {
3 |     ...ProfileFields
4 |   }
5 |   userSigNonces {
6 |     lensHubOnchainSigNonce
7 |   }
8 | }
9 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/explore-publications.graphql:
--------------------------------------------------------------------------------
 1 | query ExplorePublications($request: ExplorePublicationRequest!) {
 2 |   explorePublications(request: $request) {
 3 |     items {
 4 |       ... on Post {
 5 |         ...PostFields
 6 |       }
 7 |       ... on Quote {
 8 |         ...QuoteFields
 9 |       }
10 |     }
11 |     pageInfo {
12 |       next
13 |     }
14 |   }
15 | }
16 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/feed-highlights.graphql:
--------------------------------------------------------------------------------
 1 | query FeedHighlights($request: FeedHighlightsRequest!) {
 2 |   feedHighlights(request: $request) {
 3 |     items {
 4 |       ... on Post {
 5 |         ...PostFields
 6 |       }
 7 |       ... on Quote {
 8 |         ...QuoteFields
 9 |       }
10 |     }
11 |     pageInfo {
12 |       next
13 |     }
14 |   }
15 | }
16 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/generate-lens-apirelay-address.graphql:
--------------------------------------------------------------------------------
1 | query GenerateLensAPIRelayAddress {
2 |   generateLensAPIRelayAddress
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/generate-module-currency-approval-data.graphql:
--------------------------------------------------------------------------------
 1 | query GenerateModuleCurrencyApprovalData(
 2 |   $request: GenerateModuleCurrencyApprovalDataRequest!
 3 | ) {
 4 |   generateModuleCurrencyApprovalData(request: $request) {
 5 |     to
 6 |     from
 7 |     data
 8 |   }
 9 | }
10 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/handle-to-address.graphql:
--------------------------------------------------------------------------------
1 | query HandleToAddress($request: HandleToAddressRequest!) {
2 |   handleToAddress(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/has-publication-indexed.graphql:
--------------------------------------------------------------------------------
 1 | query HasPublicationIndexed($request: PublicationRequest!) {
 2 |   publication(request: $request) {
 3 |     ... on Post {
 4 |       id
 5 |     }
 6 |     ... on Comment {
 7 |       id
 8 |     }
 9 |     ... on Mirror {
10 |       id
11 |     }
12 |     ... on Quote {
13 |       id
14 |     }
15 |   }
16 | }
17 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/latest-notification-id.graphql:
--------------------------------------------------------------------------------
 1 | query LatestNotificationId($request: NotificationRequest!) {
 2 |   notifications(request: $request) {
 3 |     items {
 4 |       ... on ReactionNotification {
 5 |         id
 6 |       }
 7 |       ... on CommentNotification {
 8 |         id
 9 |       }
10 |       ... on MirrorNotification {
11 |         id
12 |       }
13 |       ... on QuoteNotification {
14 |         id
15 |       }
16 |       ... on ActedNotification {
17 |         id
18 |       }
19 |       ... on FollowNotification {
20 |         id
21 |       }
22 |       ... on MentionNotification {
23 |         id
24 |       }
25 |     }
26 |   }
27 | }
28 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/lens-transaction-status.graphql:
--------------------------------------------------------------------------------
1 | query LensTransactionStatus($request: LensTransactionStatusRequest!) {
2 |   lensTransactionStatus(request: $request) {
3 |     status
4 |     txHash
5 |     reason
6 |     extraInfo
7 |   }
8 | }
9 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/mod-explore-publications.graphql:
--------------------------------------------------------------------------------
 1 | query ModExplorePublications($request: ModExplorePublicationRequest!) {
 2 |   modExplorePublications(request: $request) {
 3 |     items {
 4 |       ... on Post {
 5 |         ...PostFields
 6 |       }
 7 |       ... on Comment {
 8 |         ...CommentFields
 9 |       }
10 |       ... on Quote {
11 |         ...QuoteFields
12 |       }
13 |     }
14 |     pageInfo {
15 |       next
16 |     }
17 |   }
18 | }
19 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/module-metadata.graphql:
--------------------------------------------------------------------------------
 1 | query ModuleMetadata($request: ModuleMetadataRequest!) {
 2 |   moduleMetadata(request: $request) {
 3 |     metadata {
 4 |       attributes {
 5 |         key
 6 |         type
 7 |         value
 8 |       }
 9 |       authors
10 |       description
11 |       initializeCalldataABI
12 |       initializeResultDataABI
13 |       name
14 |       processCalldataABI
15 |       title
16 |     }
17 |     moduleType
18 |     signlessApproved
19 |     sponsoredApproved
20 |     verified
21 |   }
22 | }
23 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/mutual-followers.graphql:
--------------------------------------------------------------------------------
 1 | query MutualFollowers($request: MutualFollowersRequest!) {
 2 |   mutualFollowers(request: $request) {
 3 |     items {
 4 |       ...ProfileFields
 5 |     }
 6 |     pageInfo {
 7 |       next
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/owned-handles.graphql:
--------------------------------------------------------------------------------
 1 | query OwnedHandles($request: OwnedHandlesRequest!) {
 2 |   ownedHandles(request: $request) {
 3 |     items {
 4 |       id
 5 |       linkedTo {
 6 |         nftTokenId
 7 |         contract {
 8 |           address
 9 |         }
10 |       }
11 |       fullHandle
12 |     }
13 |     pageInfo {
14 |       next
15 |     }
16 |   }
17 | }
18 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/profile-feed.graphql:
--------------------------------------------------------------------------------
 1 | query Feed($request: FeedRequest!) {
 2 |   feed(request: $request) {
 3 |     items {
 4 |       root {
 5 |         ... on Post {
 6 |           ...PostFields
 7 |         }
 8 |         ... on Comment {
 9 |           ...CommentFields
10 |         }
11 |         ... on Quote {
12 |           ...QuoteFields
13 |         }
14 |       }
15 |     }
16 |     pageInfo {
17 |       next
18 |     }
19 |   }
20 | }
21 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/profile-follow-module.graphql:
--------------------------------------------------------------------------------
1 | query ProfileFollowModule($request: ProfileRequest!) {
2 |   profile(request: $request) {
3 |     followModule {
4 |       ...FollowModuleFields
5 |     }
6 |   }
7 | }
8 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/profile-interests-options.graphql:
--------------------------------------------------------------------------------
1 | query ProfileInterestsOptions($request: ProfileRequest!) {
2 |   profileInterestsOptions
3 |   profile(request: $request) {
4 |     id
5 |     interests
6 |   }
7 | }
8 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/profile-managers.graphql:
--------------------------------------------------------------------------------
 1 | query ProfileManagers($request: ProfileManagersRequest!) {
 2 |   profileManagers(request: $request) {
 3 |     items {
 4 |       address
 5 |       isLensManager
 6 |     }
 7 |     pageInfo {
 8 |       next
 9 |     }
10 |   }
11 | }
12 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/profiles-managed.graphql:
--------------------------------------------------------------------------------
 1 | query ProfilesManaged(
 2 |   $request: ProfilesManagedRequest!
 3 |   $lastLoggedInProfileRequest: LastLoggedInProfileRequest!
 4 | ) {
 5 |   profilesManaged(request: $request) {
 6 |     items {
 7 |       ...ProfileFields
 8 |     }
 9 |     pageInfo {
10 |       next
11 |     }
12 |   }
13 |   lastLoggedInProfile(request: $lastLoggedInProfileRequest) {
14 |     ...ProfileFields
15 |   }
16 | }
17 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/publication-bookmarks.graphql:
--------------------------------------------------------------------------------
 1 | query PublicationBookmarks($request: PublicationBookmarksRequest!) {
 2 |   publicationBookmarks(request: $request) {
 3 |     items {
 4 |       ... on Post {
 5 |         ...PostFields
 6 |       }
 7 |       ... on Comment {
 8 |         ...CommentFields
 9 |       }
10 |       ... on Mirror {
11 |         ...MirrorFields
12 |       }
13 |       ... on Quote {
14 |         ...QuoteFields
15 |       }
16 |     }
17 |     pageInfo {
18 |       next
19 |     }
20 |   }
21 | }
22 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/revenue-from-publication.graphql:
--------------------------------------------------------------------------------
 1 | query RevenueFromPublication($request: RevenueFromPublicationRequest!) {
 2 |   revenueFromPublication(request: $request) {
 3 |     publication {
 4 |       ... on Post {
 5 |         ...PostFields
 6 |       }
 7 |       ... on Comment {
 8 |         ...CommentFields
 9 |       }
10 |       ... on Mirror {
11 |         ...MirrorFields
12 |       }
13 |       ... on Quote {
14 |         ...QuoteFields
15 |       }
16 |     }
17 |     revenue {
18 |       total {
19 |         ...AmountFields
20 |       }
21 |     }
22 |   }
23 | }
24 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/revenue-from-publications.graphql:
--------------------------------------------------------------------------------
 1 | query RevenueFromPublications($request: RevenueFromPublicationsRequest!) {
 2 |   revenueFromPublications(request: $request) {
 3 |     items {
 4 |       publication {
 5 |         ... on Post {
 6 |           ...PostFields
 7 |         }
 8 |         ... on Comment {
 9 |           ...CommentFields
10 |         }
11 |         ... on Mirror {
12 |           ...MirrorFields
13 |         }
14 |         ... on Quote {
15 |           ...QuoteFields
16 |         }
17 |       }
18 |       revenue {
19 |         total {
20 |           ...AmountFields
21 |         }
22 |       }
23 |     }
24 |   }
25 | }
26 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/revoke-authentication.graphql:
--------------------------------------------------------------------------------
1 | mutation RevokeAuthentication($request: RevokeAuthenticationRequest!) {
2 |   revokeAuthentication(request: $request)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/search-profiles.graphql:
--------------------------------------------------------------------------------
 1 | query SearchProfiles($request: ProfileSearchRequest!) {
 2 |   searchProfiles(request: $request) {
 3 |     items {
 4 |       ...ProfileFields
 5 |     }
 6 |     pageInfo {
 7 |       next
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/search-publications.graphql:
--------------------------------------------------------------------------------
 1 | query SearchPublications($request: PublicationSearchRequest!) {
 2 |   searchPublications(request: $request) {
 3 |     items {
 4 |       ... on Post {
 5 |         ...PostFields
 6 |       }
 7 |       ... on Comment {
 8 |         ...CommentFields
 9 |       }
10 |       ... on Quote {
11 |         ...QuoteFields
12 |       }
13 |     }
14 |     pageInfo {
15 |       next
16 |     }
17 |   }
18 | }
19 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/tx-id-to-tx-hash.graphql:
--------------------------------------------------------------------------------
1 | query TxIdToTxHash($for: TxId!) {
2 |   txIdToTxHash(for: $for)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/who-acted-on-publication.graphql:
--------------------------------------------------------------------------------
 1 | query WhoActedOnPublication($request: WhoActedOnPublicationRequest!) {
 2 |   whoActedOnPublication(request: $request) {
 3 |     items {
 4 |       ...ProfileFields
 5 |     }
 6 |     pageInfo {
 7 |       next
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/who-have-blocked.graphql:
--------------------------------------------------------------------------------
 1 | query WhoHaveBlocked($request: WhoHaveBlockedRequest!) {
 2 |   whoHaveBlocked(request: $request) {
 3 |     items {
 4 |       ...ProfileFields
 5 |     }
 6 |     pageInfo {
 7 |       next
 8 |     }
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/packages/lens/documents/queries/who-reacted-publication.graphql:
--------------------------------------------------------------------------------
 1 | query WhoReactedPublication($request: WhoReactedPublicationRequest!) {
 2 |   whoReactedPublication(request: $request) {
 3 |     items {
 4 |       profile {
 5 |         ...ProfileFields
 6 |       }
 7 |     }
 8 |     pageInfo {
 9 |       next
10 |     }
11 |   }
12 | }
13 | 


--------------------------------------------------------------------------------
/packages/lens/documents/subscriptions/authorization-record-revoked.graphql:
--------------------------------------------------------------------------------
1 | subscription AuthorizationRecordRevokedSubscription($authorizationId: UUID!) {
2 |   authorizationRecordRevoked(authorizationId: $authorizationId)
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/lens/documents/subscriptions/new-notification.graphql:
--------------------------------------------------------------------------------
 1 | subscription NewNotificationSubscription($for: ProfileId!) {
 2 |   newNotification(for: $for) {
 3 |     ... on ReactionNotification {
 4 |       id
 5 |     }
 6 |     ... on CommentNotification {
 7 |       id
 8 |     }
 9 |     ... on MirrorNotification {
10 |       id
11 |     }
12 |     ... on QuoteNotification {
13 |       id
14 |     }
15 |     ... on ActedNotification {
16 |       id
17 |     }
18 |     ... on FollowNotification {
19 |       id
20 |     }
21 |     ... on MentionNotification {
22 |       id
23 |     }
24 |   }
25 | }
26 | 


--------------------------------------------------------------------------------
/packages/lens/documents/subscriptions/user-sig-nonces.graphql:
--------------------------------------------------------------------------------
1 | subscription UserSigNoncesSubscription($address: EvmAddress!) {
2 |   userSigNonces(address: $address) {
3 |     lensHubOnchainSigNonce
4 |   }
5 | }
6 | 


--------------------------------------------------------------------------------
/packages/lens/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 |   "extends": "@tape.xyz/tsconfig/base.json",
3 |   "compilerOptions": {
4 |     "module": "ESNext",
5 |     "moduleResolution": "Node"
6 |   }
7 | }
8 | 


--------------------------------------------------------------------------------
/packages/server/.env.example:
--------------------------------------------------------------------------------
1 | TAPE_DATABASE_URL=
2 | 


--------------------------------------------------------------------------------
/packages/server/.gitignore:
--------------------------------------------------------------------------------
1 | generated
2 | 


--------------------------------------------------------------------------------
/packages/server/db/clickhouse/client.ts:
--------------------------------------------------------------------------------
 1 | import { createClient } from "@clickhouse/client";
 2 | 
 3 | const clickhouseClient = createClient({
 4 |   compression: { request: true, response: true },
 5 |   keep_alive: { enabled: true },
 6 |   username: "clickhouse",
 7 |   password: process.env.CLICKHOUSE_PASSWORD,
 8 |   url: process.env.CLICKHOUSE_URL
 9 | });
10 | 
11 | export { clickhouseClient };
12 | 


--------------------------------------------------------------------------------
/packages/server/db/indexer/client.ts:
--------------------------------------------------------------------------------
 1 | // import pgp from "pg-promise";
 2 | 
 3 | // const initOptions: pgp.IInitOptions = {
 4 | //   error: (err, e) => {
 5 | //     console.error("[indexer-db] Error:", err?.message || err);
 6 | //     if (e.query) {
 7 | //       console.info("[indexer-db] Error Query:", e.query);
 8 | //       if (e.params) {
 9 | //         console.info("[indexer-db] Error Parameters:", e.params);
10 | //       }
11 | //     }
12 | //   }
13 | // };
14 | 
15 | // const indexerDb = pgp(initOptions)({
16 | //   connectionString: process.env.INDEXER_DATABASE_URL,
17 | //   port: 6432,
18 | //   max: 20
19 | // });
20 | 
21 | // export { indexerDb };
22 | 


--------------------------------------------------------------------------------
/packages/server/db/tape/client.ts:
--------------------------------------------------------------------------------
1 | import { PrismaClient } from "@prisma/client";
2 | 
3 | const tapeDb = new PrismaClient({ log: ["info"] });
4 | 
5 | export { tapeDb };
6 | 


--------------------------------------------------------------------------------
/packages/server/db/tape/migrations/20240723044050_curated_profile/migration.sql:
--------------------------------------------------------------------------------
1 | -- CreateTable
2 | CREATE TABLE "CuratedProfile" (
3 |     "id" UUID NOT NULL DEFAULT gen_random_uuid(),
4 |     "profileId" TEXT NOT NULL,
5 |     "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
6 | 
7 |     CONSTRAINT "CuratedProfile_pkey" PRIMARY KEY ("id")
8 | );
9 | 


--------------------------------------------------------------------------------
/packages/server/db/tape/migrations/20240809041517_add_profile/migration.sql:
--------------------------------------------------------------------------------
 1 | -- CreateTable
 2 | CREATE TABLE "Profile" (
 3 |     "id" UUID NOT NULL DEFAULT gen_random_uuid(),
 4 |     "profileId" TEXT NOT NULL,
 5 |     "isCurated" BOOLEAN NOT NULL DEFAULT false,
 6 |     "isVerified" BOOLEAN NOT NULL DEFAULT false,
 7 |     "isSuspended" BOOLEAN NOT NULL DEFAULT false,
 8 |     "isLimited" BOOLEAN NOT NULL DEFAULT false,
 9 |     "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
10 |     "updatedAt" TIMESTAMP(3) NOT NULL,
11 | 
12 |     CONSTRAINT "Profile_pkey" PRIMARY KEY ("id")
13 | );
14 | 
15 | -- CreateIndex
16 | CREATE UNIQUE INDEX "Profile_profileId_key" ON "Profile"("profileId");
17 | 
18 | -- CreateIndex
19 | CREATE INDEX "Profile_profileId_idx" ON "Profile"("profileId");
20 | 


--------------------------------------------------------------------------------
/packages/server/db/tape/migrations/20240809042300_update_default_time/migration.sql:
--------------------------------------------------------------------------------
1 | -- AlterTable
2 | ALTER TABLE "Profile" ALTER COLUMN "updatedAt" SET DEFAULT CURRENT_TIMESTAMP;
3 | 


--------------------------------------------------------------------------------
/packages/server/db/tape/migrations/20240809051310_drop_tables/migration.sql:
--------------------------------------------------------------------------------
 1 | /*
 2 |   Warnings:
 3 | 
 4 |   - You are about to drop the `CuratedProfile` table. If the table is not empty, all the data it contains will be lost.
 5 |   - You are about to drop the `ProfileRestriction` table. If the table is not empty, all the data it contains will be lost.
 6 |   - You are about to drop the `Verified` table. If the table is not empty, all the data it contains will be lost.
 7 | 
 8 | */
 9 | -- DropTable
10 | DROP TABLE "CuratedProfile";
11 | 
12 | -- DropTable
13 | DROP TABLE "ProfileRestriction";
14 | 
15 | -- DropTable
16 | DROP TABLE "Verified";
17 | 


--------------------------------------------------------------------------------
/packages/server/db/tape/migrations/20241004061051_stats/migration.sql:
--------------------------------------------------------------------------------
 1 | -- CreateTable
 2 | CREATE TABLE "PlatformStats" (
 3 |     "id" UUID NOT NULL DEFAULT gen_random_uuid(),
 4 |     "profiles" TEXT NOT NULL,
 5 |     "acts" TEXT NOT NULL,
 6 |     "posts" TEXT NOT NULL,
 7 |     "comments" TEXT NOT NULL,
 8 |     "mirrors" TEXT NOT NULL,
 9 |     "creatorEarnings" JSONB NOT NULL,
10 |     "blockTimestamp" TEXT NOT NULL,
11 |     "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
12 |     "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
13 | 
14 |     CONSTRAINT "PlatformStats_pkey" PRIMARY KEY ("id")
15 | );
16 | 


--------------------------------------------------------------------------------
/packages/server/db/tape/migrations/20241004061452_stats_optional/migration.sql:
--------------------------------------------------------------------------------
1 | -- AlterTable
2 | ALTER TABLE "PlatformStats" ALTER COLUMN "creatorEarnings" DROP NOT NULL,
3 | ALTER COLUMN "blockTimestamp" DROP NOT NULL;
4 | 


--------------------------------------------------------------------------------
/packages/server/db/tape/migrations/20241004062254_platform_stats/migration.sql:
--------------------------------------------------------------------------------
 1 | /*
 2 |   Warnings:
 3 | 
 4 |   - Made the column `creatorEarnings` on table `PlatformStats` required. This step will fail if there are existing NULL values in that column.
 5 |   - Made the column `blockTimestamp` on table `PlatformStats` required. This step will fail if there are existing NULL values in that column.
 6 | 
 7 | */
 8 | -- AlterTable
 9 | ALTER TABLE "PlatformStats" ALTER COLUMN "creatorEarnings" SET NOT NULL,
10 | ALTER COLUMN "blockTimestamp" SET NOT NULL;
11 | 


--------------------------------------------------------------------------------
/packages/server/db/tape/migrations/migration_lock.toml:
--------------------------------------------------------------------------------
1 | # Please do not edit this file manually
2 | # It should be added in your version-control system (i.e. Git)
3 | provider = "postgresql"


--------------------------------------------------------------------------------
/packages/server/db/tape/seeds/execute.sql:
--------------------------------------------------------------------------------
 1 | INSERT INTO "AllowedToken" (name, symbol, decimals, address) 
 2 | VALUES 
 3 | ('Wrapped Matic', 'WMATIC', 18, '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270'),
 4 | ('Wrapped Ether', 'WETH', 18, '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619'),
 5 | ('Tether USD', 'USDT', 6, '0xc2132D05D31c914a87C6611C10748AEb04B58e8F'),
 6 | ('USD Coin', 'USDC', 6, '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359'),
 7 | ('DAI Stablecoin', 'DAI', 18, '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063'),
 8 | ('Bonsai', 'BONSAI', 18, '0x3d2bD0e15829AA5C362a4144FdF4A1112fa29B5c');
 9 | 
10 | INSERT INTO "CuratedProfile" ("profileId") VALUES 
11 | ('0x0105f8'),
12 | ('0x01cada');
13 | 


--------------------------------------------------------------------------------
/packages/server/env.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace NodeJS {
2 |   interface ProcessEnv {
3 |     TAPE_DATABASE_URL: string;
4 |   }
5 | }
6 | 


--------------------------------------------------------------------------------
/packages/server/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./db/clickhouse/client";
2 | export * from "./db/tape/client";
3 | // export * from "./db/indexer/client";
4 | export * from "./db/redis/client";
5 | 


--------------------------------------------------------------------------------
/packages/server/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "@tape.xyz/server",
 3 |   "version": "0.0.0",
 4 |   "license": "AGPL-3.0",
 5 |   "main": "index.ts",
 6 |   "scripts": {
 7 |     "typecheck": "tsc --pretty --noEmit",
 8 |     "tape:migrate": "prisma migrate dev --schema ./db/tape/schema.prisma",
 9 |     "prisma:generate": "prisma generate --schema ./db/tape/schema.prisma",
10 |     "postinstall": "pnpm prisma:generate"
11 |   },
12 |   "dependencies": {
13 |     "@clickhouse/client": "^1.11.0",
14 |     "@prisma/client": "^6.3.1",
15 |     "pg-promise": "^11.13.0",
16 |     "redis": "^4.7.0"
17 |   },
18 |   "devDependencies": {
19 |     "@tape.xyz/tsconfig": "workspace:*",
20 |     "@types/node": "^22.13.1",
21 |     "prisma": "^6.3.1",
22 |     "typescript": "^5.7.3"
23 |   }
24 | }
25 | 


--------------------------------------------------------------------------------
/packages/server/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 |   "extends": "@tape.xyz/tsconfig/base.json"
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/tsconfig/base.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "$schema": "https://json.schemastore.org/tsconfig",
 3 |   "display": "Default",
 4 |   "compilerOptions": {
 5 |     "esModuleInterop": true,
 6 |     "incremental": false,
 7 |     "isolatedModules": true,
 8 |     "lib": ["es2022", "DOM", "DOM.Iterable"],
 9 |     "module": "NodeNext",
10 |     "moduleDetection": "force",
11 |     "moduleResolution": "NodeNext",
12 |     "noUncheckedIndexedAccess": true,
13 |     "resolveJsonModule": true,
14 |     "skipLibCheck": true,
15 |     "strict": true,
16 |     "target": "ES2022"
17 |   }
18 | }
19 | 


--------------------------------------------------------------------------------
/packages/tsconfig/nextjs.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "$schema": "https://json.schemastore.org/tsconfig",
 3 |   "display": "Next.js",
 4 |   "extends": "./base.json",
 5 |   "compilerOptions": {
 6 |     "plugins": [{ "name": "next" }],
 7 |     "module": "ESNext",
 8 |     "moduleResolution": "Bundler",
 9 |     "allowJs": true,
10 |     "jsx": "preserve",
11 |     "noEmit": true
12 |   }
13 | }
14 | 


--------------------------------------------------------------------------------
/packages/tsconfig/package.json:
--------------------------------------------------------------------------------
1 | {
2 |   "name": "@tape.xyz/tsconfig",
3 |   "private": true
4 | }
5 | 


--------------------------------------------------------------------------------
/packages/tsconfig/react.json:
--------------------------------------------------------------------------------
1 | {
2 |   "$schema": "https://json.schemastore.org/tsconfig",
3 |   "display": "React",
4 |   "extends": "./base.json",
5 |   "compilerOptions": {
6 |     "jsx": "react-jsx"
7 |   }
8 | }
9 | 


--------------------------------------------------------------------------------
/packages/ui/index.ts:
--------------------------------------------------------------------------------
 1 | export * from "./src/Accordion";
 2 | export * from "./src/Badge";
 3 | export * from "./src/Button";
 4 | export * from "./src/Callout";
 5 | export * from "./src/Checkbox";
 6 | export * from "./src/Dropdown";
 7 | export * from "./src/HoverCard";
 8 | export * from "./src/icons";
 9 | export * from "./src/Input";
10 | export * from "./src/Modal";
11 | export * from "./src/players/video";
12 | export * from "./src/Popover";
13 | export * from "./src/RangeSlider";
14 | export * from "./src/Select";
15 | export * from "./src/Spinner";
16 | export * from "./src/Switch";
17 | export * from "./src/Tabs";
18 | export * from "./src/TextArea";
19 | export * from "./src/Tooltip";
20 | 


--------------------------------------------------------------------------------
/packages/ui/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 |   plugins: {
3 |     tailwindcss: {},
4 |     autoprefixer: {}
5 |   }
6 | };
7 | 


--------------------------------------------------------------------------------
/packages/ui/src/Accordion.tsx:
--------------------------------------------------------------------------------
1 | import * as AccordionPrimitive from "@radix-ui/react-accordion";
2 | 
3 | export const { Accordion } = AccordionPrimitive;
4 | export const { AccordionItem } = AccordionPrimitive;
5 | export const { AccordionTrigger } = AccordionPrimitive;
6 | export const { AccordionContent } = AccordionPrimitive;
7 | 


--------------------------------------------------------------------------------
/packages/ui/src/HoverCard.tsx:
--------------------------------------------------------------------------------
1 | import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
2 | 
3 | export const HoverCard = HoverCardPrimitive.Root;
4 | export const HoverCardTrigger = HoverCardPrimitive.Trigger;
5 | export const HoverCardContent = HoverCardPrimitive.Content;
6 | 


--------------------------------------------------------------------------------
/packages/ui/src/Popover.tsx:
--------------------------------------------------------------------------------
1 | import * as PopoverPrimitive from "@radix-ui/react-popover";
2 | 
3 | export const Popover = PopoverPrimitive.Root;
4 | export const PopoverTrigger = PopoverPrimitive.Trigger;
5 | export const PopoverContent = PopoverPrimitive.Content;
6 | 


--------------------------------------------------------------------------------
/packages/ui/src/Tabs.tsx:
--------------------------------------------------------------------------------
1 | import * as TabsPrimitive from "@radix-ui/react-tabs";
2 | 
3 | export const Tabs = TabsPrimitive.Root;
4 | export const { TabsTrigger } = TabsPrimitive;
5 | export const { TabsList } = TabsPrimitive;
6 | export const TabsContent = TabsPrimitive.Content;
7 | 


--------------------------------------------------------------------------------
/packages/ui/src/icons/CheckOutline.tsx:
--------------------------------------------------------------------------------
 1 | import type { SVGProps } from "react";
 2 | 
 3 | export const CheckOutline = (props: SVGProps<SVGSVGElement>) => (
 4 |   <svg
 5 |     {...props}
 6 |     viewBox="0 0 13 12"
 7 |     fill="none"
 8 |     xmlns="http://www.w3.org/2000/svg"
 9 |   >
10 |     <path
11 |       fillRule="evenodd"
12 |       clipRule="evenodd"
13 |       d="M12.4933 0.935023C12.8053 1.20743 12.8374 1.68122 12.565 1.99325L4.70786 10.9933C4.56543 11.1564 4.35943 11.25 4.14287 11.25C3.9263 11.25 3.72031 11.1564 3.57788 10.9933L0.435023 7.39325C0.162612 7.08122 0.194733 6.60743 0.506767 6.33502C0.818802 6.06261 1.29259 6.09473 1.565 6.40677L4.14287 9.3596L11.435 1.00677C11.7074 0.694733 12.1812 0.662612 12.4933 0.935023Z"
14 |       fill="currentColor"
15 |     />
16 |   </svg>
17 | );
18 | 


--------------------------------------------------------------------------------
/packages/ui/src/icons/ChevronDownOutline.tsx:
--------------------------------------------------------------------------------
 1 | import type { SVGProps } from "react";
 2 | 
 3 | export const ChevronDownOutline = (props: SVGProps<SVGSVGElement>) => (
 4 |   <svg
 5 |     {...props}
 6 |     viewBox="0 0 16 8"
 7 |     fill="none"
 8 |     xmlns="http://www.w3.org/2000/svg"
 9 |   >
10 |     <path
11 |       fillRule="evenodd"
12 |       clipRule="evenodd"
13 |       d="M0.430571 0.51192C0.700138 0.197426 1.17361 0.161005 1.48811 0.430571L8.00001 6.01221L14.5119 0.430572C14.8264 0.161005 15.2999 0.197426 15.5695 0.511921C15.839 0.826415 15.8026 1.29989 15.4881 1.56946L8.48811 7.56946C8.20724 7.8102 7.79279 7.8102 7.51192 7.56946L0.51192 1.56946C0.197426 1.29989 0.161005 0.826414 0.430571 0.51192Z"
14 |       fill="currentColor"
15 |     />
16 |   </svg>
17 | );
18 | 


--------------------------------------------------------------------------------
/packages/ui/src/icons/ChevronLeftOutline.tsx:
--------------------------------------------------------------------------------
 1 | import type { SVGProps } from "react";
 2 | 
 3 | export const ChevronLeftOutline = (props: SVGProps<SVGSVGElement>) => (
 4 |   <svg
 5 |     {...props}
 6 |     viewBox="0 0 8 16"
 7 |     fill="none"
 8 |     xmlns="http://www.w3.org/2000/svg"
 9 |   >
10 |     <path
11 |       fillRule="evenodd"
12 |       clipRule="evenodd"
13 |       d="M7.48809 0.430571C7.80259 0.700138 7.83901 1.17361 7.56944 1.48811L1.98781 8.00001L7.56944 14.5119C7.83901 14.8264 7.80259 15.2999 7.48809 15.5695C7.1736 15.839 6.70012 15.8026 6.43056 15.4881L0.430558 8.48811C0.189814 8.20724 0.189814 7.79279 0.430558 7.51192L6.43056 0.51192C6.70012 0.197426 7.1736 0.161005 7.48809 0.430571Z"
14 |       fill="currentColor"
15 |     />
16 |   </svg>
17 | );
18 | 


--------------------------------------------------------------------------------
/packages/ui/src/icons/ChevronRightOutline.tsx:
--------------------------------------------------------------------------------
 1 | import type { SVGProps } from "react";
 2 | 
 3 | export const ChevronRightOutline = (props: SVGProps<SVGSVGElement>) => (
 4 |   <svg
 5 |     {...props}
 6 |     viewBox="0 0 8 16"
 7 |     fill="none"
 8 |     xmlns="http://www.w3.org/2000/svg"
 9 |   >
10 |     <path
11 |       fillRule="evenodd"
12 |       clipRule="evenodd"
13 |       d="M0.51192 0.430571C0.826414 0.161005 1.29989 0.197426 1.56946 0.51192L7.56946 7.51192C7.8102 7.79279 7.8102 8.20724 7.56946 8.48811L1.56946 15.4881C1.29989 15.8026 0.826414 15.839 0.51192 15.5695C0.197426 15.2999 0.161005 14.8264 0.430571 14.5119L6.01221 8.00001L0.430571 1.48811C0.161005 1.17361 0.197426 0.700138 0.51192 0.430571Z"
14 |       fill="currentColor"
15 |     />
16 |   </svg>
17 | );
18 | 


--------------------------------------------------------------------------------
/packages/ui/src/icons/ChevronUpOutline.tsx:
--------------------------------------------------------------------------------
 1 | import type { SVGProps } from "react";
 2 | 
 3 | export const ChevronUpOutline = (props: SVGProps<SVGSVGElement>) => (
 4 |   <svg
 5 |     {...props}
 6 |     viewBox="0 0 16 8"
 7 |     fill="none"
 8 |     xmlns="http://www.w3.org/2000/svg"
 9 |   >
10 |     <path
11 |       fillRule="evenodd"
12 |       clipRule="evenodd"
13 |       d="M7.51192 0.430558C7.79279 0.189814 8.20724 0.189814 8.48811 0.430558L15.4881 6.43056C15.8026 6.70012 15.839 7.1736 15.5695 7.48809C15.2999 7.80259 14.8264 7.83901 14.5119 7.56944L8.00001 1.98781L1.48811 7.56944C1.17361 7.83901 0.700138 7.80259 0.430571 7.48809C0.161005 7.1736 0.197426 6.70012 0.51192 6.43056L7.51192 0.430558Z"
14 |       fill="currentColor"
15 |     />
16 |   </svg>
17 | );
18 | 


--------------------------------------------------------------------------------
/packages/ui/src/icons/HeartFilled.tsx:
--------------------------------------------------------------------------------
 1 | import type { SVGProps } from "react";
 2 | 
 3 | export const HeartFilled = (props: SVGProps<SVGSVGElement>) => (
 4 |   <svg
 5 |     {...props}
 6 |     viewBox="0 0 20 18"
 7 |     fill="none"
 8 |     xmlns="http://www.w3.org/2000/svg"
 9 |   >
10 |     <path
11 |       d="M0 6.1371C0 11 4.01943 13.5914 6.96173 15.9109C8 16.7294 9 17.5 10 17.5C11 17.5 12 16.7294 13.0383 15.9109C15.9806 13.5914 20 11 20 6.1371C20 1.27416 14.4998 -2.17454 10 2.50063C5.50016 -2.17454 0 1.27416 0 6.1371Z"
12 |       fill="currentColor"
13 |     />
14 |   </svg>
15 | );
16 | 


--------------------------------------------------------------------------------
/packages/ui/src/icons/InfoSolid.tsx:
--------------------------------------------------------------------------------
 1 | import type { SVGProps } from "react";
 2 | 
 3 | export const InfoSolid = (props: SVGProps<SVGSVGElement>) => (
 4 |   <svg
 5 |     {...props}
 6 |     viewBox="0 0 20 20"
 7 |     fill="none"
 8 |     xmlns="http://www.w3.org/2000/svg"
 9 |   >
10 |     <path
11 |       fillRule="evenodd"
12 |       clipRule="evenodd"
13 |       d="M20 10C20 15.5228 15.5228 20 10 20C4.47715 20 0 15.5228 0 10C0 4.47715 4.47715 0 10 0C15.5228 0 20 4.47715 20 10ZM10 15.75C10.4142 15.75 10.75 15.4142 10.75 15V9C10.75 8.58579 10.4142 8.25 10 8.25C9.58579 8.25 9.25 8.58579 9.25 9V15C9.25 15.4142 9.58579 15.75 10 15.75ZM10 5C10.5523 5 11 5.44772 11 6C11 6.55228 10.5523 7 10 7C9.44771 7 9 6.55228 9 6C9 5.44772 9.44771 5 10 5Z"
14 |       fill="currentColor"
15 |     />
16 |   </svg>
17 | );
18 | 


--------------------------------------------------------------------------------
/packages/ui/tailwind.config.js:
--------------------------------------------------------------------------------
 1 | const base = require("./tailwind-preset");
 2 | 
 3 | /** @type {import ('tailwindcss').Config} */
 4 | module.exports = {
 5 |   ...base,
 6 |   content: ["./**/*.{ts,tsx}"],
 7 |   plugins: [
 8 |     require("@tailwindcss/aspect-ratio"),
 9 |     require("@tailwindcss/typography")
10 |   ]
11 | };
12 | 


--------------------------------------------------------------------------------
/packages/ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 |   "extends": "@tape.xyz/tsconfig/react.json"
3 | }
4 | 


--------------------------------------------------------------------------------
/packages/winder/src/_components/animated-number.tsx:
--------------------------------------------------------------------------------
 1 | import { type Spring, m, useSpring, useTransform } from "motion/react";
 2 | import { useEffect } from "react";
 3 | import { tw } from "../tw";
 4 | 
 5 | type AnimatedNumber = {
 6 |   value: number;
 7 |   className?: string;
 8 |   springOptions?: Spring;
 9 | };
10 | 
11 | export const AnimatedNumber = (props: AnimatedNumber) => {
12 |   const { value, className, springOptions } = props;
13 | 
14 |   const spring = useSpring(value, springOptions);
15 |   const display = useTransform(spring, (current) =>
16 |     Math.round(current).toLocaleString("en-US")
17 |   );
18 | 
19 |   useEffect(() => {
20 |     spring.set(value);
21 |   }, [spring, value]);
22 | 
23 |   return <m.span className={tw("tabular-nums", className)}>{display}</m.span>;
24 | };
25 | 


--------------------------------------------------------------------------------
/packages/winder/src/_components/toast.tsx:
--------------------------------------------------------------------------------
 1 | import { Toaster as Sonner, type ToasterProps, toast } from "sonner";
 2 | import { useTheme } from "../theme";
 3 | 
 4 | const Toaster = ({ ...props }: React.ComponentProps<typeof Sonner>) => {
 5 |   const { theme = "system" } = useTheme();
 6 | 
 7 |   return (
 8 |     <Sonner
 9 |       theme={theme as ToasterProps["theme"]}
10 |       richColors
11 |       toastOptions={{
12 |         classNames: {
13 |           icon: "hidden",
14 |           toast: "font-sans"
15 |         }
16 |       }}
17 |       {...props}
18 |     />
19 |   );
20 | };
21 | 
22 | export { Toaster, toast };
23 | 


--------------------------------------------------------------------------------
/packages/winder/src/tw.ts:
--------------------------------------------------------------------------------
1 | import type { ClassValue } from "clsx";
2 | import { clsx } from "clsx";
3 | import { twMerge } from "tailwind-merge";
4 | 
5 | export const tw = (...inputs: ClassValue[]) => {
6 |   return twMerge(clsx(inputs));
7 | };
8 | 


--------------------------------------------------------------------------------
/packages/winder/tsconfig.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "extends": "@tape.xyz/tsconfig/react.json",
 3 |   "compilerOptions": {
 4 |     "baseUrl": ".",
 5 |     "paths": {
 6 |       "@/*": ["./src/*"]
 7 |     },
 8 |     "module": "ESNext",
 9 |     "moduleResolution": "bundler"
10 |   },
11 |   "include": ["src"],
12 |   "exclude": ["node_modules"]
13 | }
14 | 


--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 |   - 'apps/**'
3 |   - 'packages/**'
4 | 


--------------------------------------------------------------------------------
/scripts/clean-branches:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | 
3 | echo "Deleting all branches but 'main' 🗑"
4 | git branch | grep -v "main" | xargs git branch -D
5 | echo "Branches deleted 🎉"
6 | 


--------------------------------------------------------------------------------
/scripts/clean-packages:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | 
3 | echo "Deleting all node_modules and pnpm-lock.yaml files recursively 🗑"
4 | find . -name "node_modules" -type d -prune -exec rm -rf '{}' + -print
5 | find . -name ".next" -type d -prune -exec rm -rf '{}' + -print
6 | find . -name "pnpm-lock.yaml" -type f -prune -exec rm -rf '{}' + -print
7 | find . -name "tsconfig.tsbuildinfo" -type f -prune -exec rm -rf '{}' + -print
8 | echo "node_modules and lock files deleted 🎉"
9 | 


--------------------------------------------------------------------------------
/scripts/sync-branches:
--------------------------------------------------------------------------------
 1 | #!/bin/bash
 2 | 
 3 | git checkout main
 4 | echo "Syncing testnet branch with main branch 🔄"
 5 | git pull origin main
 6 | git checkout testnet
 7 | git merge main
 8 | git push origin testnet
 9 | git checkout main
10 | echo "Branches synced 🎉"


--------------------------------------------------------------------------------