From f4039ddada422d4e8a648e69da8fc96dff79c5f8 Mon Sep 17 00:00:00 2001 From: bigint <69431456+bigint@users.noreply.github.com> Date: Mon, 29 Jan 2024 10:25:49 +0530 Subject: [PATCH] feat: use new nft spec instead of hardcoding everything --- .github/workflows/ci.yml | 2 - apps/api/.env.example | 1 - apps/api/src/routes/nfts/basepaint/canvas.ts | 84 - apps/api/src/routes/nfts/sound/release.ts | 71 - apps/api/src/routes/nfts/unlonely/channel.ts | 57 - apps/api/src/routes/nfts/unlonely/nfc.ts | 62 - apps/api/src/routes/nfts/zora/nft.ts | 35 - apps/api/src/utils/oembed/meta/getNft.ts | 28 +- apps/api/tests/nfts/basepaint/canvas.spec.ts | 15 - apps/api/tests/nfts/sound/release.spec.ts | 13 - apps/api/tests/nfts/unlonely/channel.spec.ts | 14 - apps/api/tests/nfts/unlonely/nfc.spec.ts | 14 - apps/api/tests/nfts/zora/nft.spec.ts | 28 - .../Common/Providers/Web3Provider.tsx | 36 +- .../src/components/Composer/LinkPreviews.tsx | 17 - .../Nft/BasePaintCanvas/Mint/Metadata.tsx | 64 - .../Nft/BasePaintCanvas/Mint/MintAction.tsx | 171 -- .../Nft/BasePaintCanvas/Mint/Price.tsx | 66 - .../Nft/BasePaintCanvas/Mint/index.tsx | 63 - .../Nft/BasePaintCanvas/Shimmer.tsx | 26 - .../Nft/BasePaintCanvas/index.tsx | 168 -- .../Nft/SoundRelease/Shimmer.tsx | 20 - .../HeyOpenActions/Nft/SoundRelease/index.tsx | 196 -- .../Nft/UnlonelyChannel/Shimmer.tsx | 20 - .../Nft/UnlonelyChannel/index.tsx | 120 - .../Nft/UnlonelyNfc/Shimmer.tsx | 20 - .../HeyOpenActions/Nft/UnlonelyNfc/index.tsx | 100 - .../Nft/ZoraNft/Mint/Metadata.tsx | 60 - .../Nft/ZoraNft/Mint/MintAction.tsx | 240 -- .../Nft/ZoraNft/Mint/MintedBy.tsx | 41 - .../HeyOpenActions/Nft/ZoraNft/Mint/Price.tsx | 111 - .../HeyOpenActions/Nft/ZoraNft/Mint/index.tsx | 66 - .../HeyOpenActions/Nft/ZoraNft/Shimmer.tsx | 20 - .../HeyOpenActions/Nft/ZoraNft/index.tsx | 157 -- .../Publication/HeyOpenActions/Nft/index.tsx | 60 - .../UnknownModule/Tip/index.tsx | 2 +- .../Publication/PublicationBody.tsx | 13 +- .../components/Shared/Oembed/Nft/MintedBy.tsx | 37 + .../components/Shared/Oembed/Nft/index.tsx | 65 + .../src/components/Shared/Oembed/index.tsx | 5 +- .../Shimmer/SmallUserProfileShimmer.tsx | 2 +- .../components/Shared/SmallUserProfile.tsx | 8 +- .../components/Shared/SmallWalletProfile.tsx | 57 - .../src/hooks/basepaint/useBasePaintCanvas.ts | 38 - apps/web/src/hooks/sound/useSoundRelease.ts | 41 - .../src/hooks/unlonely/useUnlonelyChannel.ts | 38 - apps/web/src/hooks/unlonely/useUnlonelyNfc.ts | 38 - apps/web/src/hooks/usePublicationMetadata.ts | 13 - apps/web/src/hooks/zora/useZoraNft.ts | 47 - packages/abis/BasePaint.ts | 459 ---- packages/abis/FollowNft.ts | 394 --- packages/abis/ZoraCreator1155Impl.ts | 2336 ----------------- packages/abis/ZoraERC721Drop.ts | 2271 ---------------- packages/abis/index.ts | 4 - packages/data/contracts.ts | 4 - packages/data/tracking.ts | 31 +- packages/lib/getNftChainInfo.spec.ts | 78 + ...getZoraChainInfo.ts => getNftChainInfo.ts} | 35 +- packages/lib/getPublicationData.ts | 6 +- packages/lib/getZoraChainInfo.spec.ts | 106 - packages/lib/nft/getBasePaintCanvas.spec.ts | 15 - packages/lib/nft/getBasePaintCanvas.ts | 22 - packages/lib/nft/getNft.spec.ts | 46 - packages/lib/nft/getNft.ts | 58 - packages/lib/nft/getSoundRelease.ts | 23 - packages/lib/nft/getUnlonelyChannel.spec.ts | 15 - packages/lib/nft/getUnlonelyChannel.ts | 22 - packages/lib/nft/getUnlonelyNfc.spec.ts | 15 - packages/lib/nft/getUnlonelyNfc.ts | 22 - packages/lib/nft/getZoraChainIsMainnet.ts | 12 - packages/lib/nft/getZoraNft.spec.ts | 40 - packages/lib/nft/getZoraNft.ts | 33 - packages/lib/removeUrlsByHostnames.spec.ts | 30 - packages/lib/removeUrlsByHostnames.ts | 19 - packages/types/misc.d.ts | 10 +- packages/types/nft.d.ts | 131 - 76 files changed, 235 insertions(+), 8672 deletions(-) delete mode 100644 apps/api/src/routes/nfts/basepaint/canvas.ts delete mode 100644 apps/api/src/routes/nfts/sound/release.ts delete mode 100644 apps/api/src/routes/nfts/unlonely/channel.ts delete mode 100644 apps/api/src/routes/nfts/unlonely/nfc.ts delete mode 100644 apps/api/src/routes/nfts/zora/nft.ts delete mode 100644 apps/api/tests/nfts/basepaint/canvas.spec.ts delete mode 100644 apps/api/tests/nfts/sound/release.spec.ts delete mode 100644 apps/api/tests/nfts/unlonely/channel.spec.ts delete mode 100644 apps/api/tests/nfts/unlonely/nfc.spec.ts delete mode 100644 apps/api/tests/nfts/zora/nft.spec.ts delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/Metadata.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/MintAction.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/Price.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/index.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Shimmer.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/index.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/SoundRelease/Shimmer.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/SoundRelease/index.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/UnlonelyChannel/Shimmer.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/UnlonelyChannel/index.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/UnlonelyNfc/Shimmer.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/UnlonelyNfc/index.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/ZoraNft/Mint/Metadata.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/ZoraNft/Mint/MintAction.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/ZoraNft/Mint/MintedBy.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/ZoraNft/Mint/Price.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/ZoraNft/Mint/index.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/ZoraNft/Shimmer.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/ZoraNft/index.tsx delete mode 100644 apps/web/src/components/Publication/HeyOpenActions/Nft/index.tsx create mode 100644 apps/web/src/components/Shared/Oembed/Nft/MintedBy.tsx create mode 100644 apps/web/src/components/Shared/Oembed/Nft/index.tsx delete mode 100644 apps/web/src/components/Shared/SmallWalletProfile.tsx delete mode 100644 apps/web/src/hooks/basepaint/useBasePaintCanvas.ts delete mode 100644 apps/web/src/hooks/sound/useSoundRelease.ts delete mode 100644 apps/web/src/hooks/unlonely/useUnlonelyChannel.ts delete mode 100644 apps/web/src/hooks/unlonely/useUnlonelyNfc.ts delete mode 100644 apps/web/src/hooks/zora/useZoraNft.ts delete mode 100644 packages/abis/BasePaint.ts delete mode 100644 packages/abis/FollowNft.ts delete mode 100644 packages/abis/ZoraCreator1155Impl.ts delete mode 100644 packages/abis/ZoraERC721Drop.ts create mode 100644 packages/lib/getNftChainInfo.spec.ts rename packages/lib/{getZoraChainInfo.ts => getNftChainInfo.ts} (51%) delete mode 100644 packages/lib/getZoraChainInfo.spec.ts delete mode 100644 packages/lib/nft/getBasePaintCanvas.spec.ts delete mode 100644 packages/lib/nft/getBasePaintCanvas.ts delete mode 100644 packages/lib/nft/getNft.spec.ts delete mode 100644 packages/lib/nft/getNft.ts delete mode 100644 packages/lib/nft/getSoundRelease.ts delete mode 100644 packages/lib/nft/getUnlonelyChannel.spec.ts delete mode 100644 packages/lib/nft/getUnlonelyChannel.ts delete mode 100644 packages/lib/nft/getUnlonelyNfc.spec.ts delete mode 100644 packages/lib/nft/getUnlonelyNfc.ts delete mode 100644 packages/lib/nft/getZoraChainIsMainnet.ts delete mode 100644 packages/lib/nft/getZoraNft.spec.ts delete mode 100644 packages/lib/nft/getZoraNft.ts delete mode 100644 packages/lib/removeUrlsByHostnames.spec.ts delete mode 100644 packages/lib/removeUrlsByHostnames.ts delete mode 100644 packages/types/nft.d.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 08ef5edfd883..78137e21768e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -95,7 +95,6 @@ jobs: GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} IRYS_PRIVATE_KEY: ${{ secrets.IRYS_PRIVATE_KEY }} IMAGEKIT_URL: ${{ secrets.IMAGEKIT_URL }} - SOUND_API_KEY: ${{ secrets.SOUND_API_KEY }} run: | cd apps/api { @@ -109,7 +108,6 @@ jobs: echo "GOOGLE_API_KEY=${GOOGLE_API_KEY}" echo "IRYS_PRIVATE_KEY=${IRYS_PRIVATE_KEY}" echo "IMAGEKIT_URL=${IMAGEKIT_URL}" - echo "SOUND_API_KEY=${SOUND_API_KEY}" } > .env cd ../.. pnpm test:e2e diff --git a/apps/api/.env.example b/apps/api/.env.example index d28f7f8c2868..1bd6b8d80b38 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -10,4 +10,3 @@ IRYS_PRIVATE_KEY="" IMAGEKIT_URL="" ZENDESK_API_KEY="" RAILWAY_TOKEN="" -SOUND_API_KEY="" diff --git a/apps/api/src/routes/nfts/basepaint/canvas.ts b/apps/api/src/routes/nfts/basepaint/canvas.ts deleted file mode 100644 index 12970106d46c..000000000000 --- a/apps/api/src/routes/nfts/basepaint/canvas.ts +++ /dev/null @@ -1,84 +0,0 @@ -import type { Handler } from 'express'; - -import catchedError from '@utils/catchedError'; -import { SWR_CACHE_AGE_1_MIN_30_DAYS } from '@utils/constants'; -import { noBody } from '@utils/responses'; - -export const get: Handler = async (req, res) => { - const { id } = req.query; - - if (!id) { - return noBody(res); - } - - try { - const allResponses = await Promise.all([ - fetch('https://ponder.basepaint.xyz', { - body: JSON.stringify({ - operationName: 'Canvas', - query: ` - query Canvas($id: Int!) { - canvass(first: 1, orderDirection: "ASC") { - id - } - canvas(id: $id) { - id - totalEarned - totalMints - pixelsCount - contributions(first: 1000, orderBy: "pixelsCount", orderDirection: "ASC") { - id - } - } - } - `, - variables: { - id: parseInt(id as string) - } - }), - headers: { - 'Content-Type': 'application/json', - 'User-agent': 'Hey.xyz' - }, - method: 'POST' - }), - fetch( - `https://basepaint.art/api/trpc/themes.theme?batch=1&input=${encodeURIComponent( - JSON.stringify({ 0: { json: { day: parseInt(id as string) } } }) - )}` - ) - ]); - - const canvas: { - data: { - canvas: any; - canvass: { id: number }[]; - }; - } = await allResponses[0].json(); - const numberId = parseInt(id as string); - const currentCanvas = canvas.data.canvass[0].id; - - const themes: { - result: { data: { json: { palette: string[]; theme: string } } }; - }[] = await allResponses[1].json(); - - const { palette, theme } = themes[0].result.data.json; - - return res - .status(200) - .setHeader('Cache-Control', SWR_CACHE_AGE_1_MIN_30_DAYS) - .json({ - canvas: - { - canContribute: currentCanvas === numberId, - canMint: currentCanvas - 1 === numberId, - palette, - theme, - ...canvas.data.canvas - } || null, - success: true - }); - } catch (error) { - return catchedError(res, error); - } -}; diff --git a/apps/api/src/routes/nfts/sound/release.ts b/apps/api/src/routes/nfts/sound/release.ts deleted file mode 100644 index a5b295e248f8..000000000000 --- a/apps/api/src/routes/nfts/sound/release.ts +++ /dev/null @@ -1,71 +0,0 @@ -import type { Handler } from 'express'; - -import logger from '@hey/lib/logger'; -import catchedError from '@utils/catchedError'; -import { SWR_CACHE_AGE_1_MIN_30_DAYS } from '@utils/constants'; -import { noBody } from '@utils/responses'; - -export const get: Handler = async (req, res) => { - const { handle, slug } = req.query; - - if (!handle || !slug) { - return noBody(res); - } - - try { - const soundResponse = await fetch('https://api.sound.xyz/graphql', { - body: JSON.stringify({ - operationName: 'MintedRelease', - query: ` - query MintedRelease($releaseSlug: String!, $soundHandle: String!) { - mintedRelease(releaseSlug: $releaseSlug, soundHandle: $soundHandle) { - title - numSold - coverImage { - url - dominantColor - } - track { - normalizedPeaks - audio { - audio256k { - url - } - } - } - artist { - name - user { - avatar { - url - } - } - } - } - } - `, - variables: { releaseSlug: slug, soundHandle: handle } - }), - headers: { - 'Content-Type': 'application/json', - 'User-agent': 'Hey.xyz', - 'X-Sound-Client-Key': process.env.SOUND_API_KEY! - }, - method: 'POST' - }); - const release: { data: { mintedRelease: any } } = - await soundResponse.json(); - - logger.info('Release fetched from Sound.xyz'); - - return res - .status(200) - .setHeader('Cache-Control', SWR_CACHE_AGE_1_MIN_30_DAYS) - .json({ - release: release.data.mintedRelease, - success: true - }); - } catch (error) { - return catchedError(res, error); - } -}; diff --git a/apps/api/src/routes/nfts/unlonely/channel.ts b/apps/api/src/routes/nfts/unlonely/channel.ts deleted file mode 100644 index a0c33cd5ffd7..000000000000 --- a/apps/api/src/routes/nfts/unlonely/channel.ts +++ /dev/null @@ -1,57 +0,0 @@ -import type { Handler } from 'express'; - -import logger from '@hey/lib/logger'; -import catchedError from '@utils/catchedError'; -import { SWR_CACHE_AGE_1_MIN_30_DAYS } from '@utils/constants'; -import { noBody } from '@utils/responses'; - -export const get: Handler = async (req, res) => { - const { slug } = req.query; - - if (!slug) { - return noBody(res); - } - - try { - const unlonelyResponse = await fetch( - 'https://unlonely-vqeii.ondigitalocean.app/graphql', - { - body: JSON.stringify({ - operationName: 'GetChannelBySlug', - query: ` - query GetChannelBySlug($slug: String!) { - getChannelBySlug(slug: $slug) { - id - slug - name - description - playbackUrl - isLive - } - } - `, - variables: { slug } - }), - headers: { - 'Content-Type': 'application/json', - 'User-agent': 'Hey.xyz' - }, - method: 'POST' - } - ); - const channel: { - data: { getChannelBySlug: any }; - } = await unlonelyResponse.json(); - logger.info('Channel fetched from Unlonely'); - - return res - .status(200) - .setHeader('Cache-Control', SWR_CACHE_AGE_1_MIN_30_DAYS) - .json({ - channel: channel.data.getChannelBySlug, - success: true - }); - } catch (error) { - return catchedError(res, error); - } -}; diff --git a/apps/api/src/routes/nfts/unlonely/nfc.ts b/apps/api/src/routes/nfts/unlonely/nfc.ts deleted file mode 100644 index f4c83d475747..000000000000 --- a/apps/api/src/routes/nfts/unlonely/nfc.ts +++ /dev/null @@ -1,62 +0,0 @@ -import type { Handler } from 'express'; - -import logger from '@hey/lib/logger'; -import catchedError from '@utils/catchedError'; -import { SWR_CACHE_AGE_1_MIN_30_DAYS } from '@utils/constants'; -import { noBody } from '@utils/responses'; - -export const get: Handler = async (req, res) => { - const { id } = req.query; - - if (!id) { - return noBody(res); - } - - try { - const unlonelyResponse = await fetch( - 'https://unlonely-vqeii.ondigitalocean.app/graphql', - { - body: JSON.stringify({ - operationName: 'GetNFC', - query: ` - query GetNFC($id: ID!) { - getNFC(id: $id) { - id - createdAt - videoLink - videoThumbnail - openseaLink - title - owner { - username - FCImageUrl - lensImageUrl - } - } - } - `, - variables: { id } - }), - headers: { - 'Content-Type': 'application/json', - 'User-agent': 'Hey.xyz' - }, - method: 'POST' - } - ); - const nfc: { - data: { getNFC: any }; - } = await unlonelyResponse.json(); - logger.info('NFC fetched from Unlonely'); - - return res - .status(200) - .setHeader('Cache-Control', SWR_CACHE_AGE_1_MIN_30_DAYS) - .json({ - nfc: nfc.data.getNFC, - success: true - }); - } catch (error) { - return catchedError(res, error); - } -}; diff --git a/apps/api/src/routes/nfts/zora/nft.ts b/apps/api/src/routes/nfts/zora/nft.ts deleted file mode 100644 index fe86c87d98ae..000000000000 --- a/apps/api/src/routes/nfts/zora/nft.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { Handler } from 'express'; - -import logger from '@hey/lib/logger'; -import getZoraChainIsMainnet from '@hey/lib/nft/getZoraChainIsMainnet'; -import catchedError from '@utils/catchedError'; -import { SWR_CACHE_AGE_10_MINS_30_DAYS } from '@utils/constants'; -import { noBody } from '@utils/responses'; -import urlcat from 'urlcat'; - -export const get: Handler = async (req, res) => { - const { address, chain, token } = req.query; - - if (!chain || !address) { - return noBody(res); - } - - try { - const network = getZoraChainIsMainnet(chain as string) ? '' : 'testnet.'; - const zoraResponse = await fetch( - urlcat( - `https://${network}zora.co/api/personalize/collection/:chain::address/:token`, - { address, chain, token: token || 0 } - ) - ); - const nft: { collection: any } = await zoraResponse.json(); - logger.info(`Nft fetched from Zora ${chain}/${address}:${token}`); - - return res - .status(200) - .setHeader('Cache-Control', SWR_CACHE_AGE_10_MINS_30_DAYS) - .json({ nft: nft.collection || null, success: true }); - } catch (error) { - return catchedError(res, error); - } -}; diff --git a/apps/api/src/utils/oembed/meta/getNft.ts b/apps/api/src/utils/oembed/meta/getNft.ts index 202a1c7fef8b..27b963e833c8 100644 --- a/apps/api/src/utils/oembed/meta/getNft.ts +++ b/apps/api/src/utils/oembed/meta/getNft.ts @@ -18,10 +18,10 @@ const getNft = (document: Document, url: string): Nft | null => { document.querySelector('meta[name="nft:chain"]') || document.querySelector('meta[property="nft:chain"]'); const mediaUrl = - document.querySelector('meta[name="eth:nft:media_url"]') || - document.querySelector('meta[property="eth:nft:media_url"]') || document.querySelector('meta[name="og:image"]') || - document.querySelector('meta[property="og:image"]'); + document.querySelector('meta[property="og:image"]') || + document.querySelector('meta[name="eth:nft:media_url"]') || + document.querySelector('meta[property="eth:nft:media_url"]'); const mintCount = document.querySelector('meta[name="eth:nft:mint_count"]') || document.querySelector('meta[property="eth:nft:mint_count"]'); @@ -38,27 +38,31 @@ const getNft = (document: Document, url: string): Nft | null => { document.querySelector('meta[name="eth:nft:endtime"]') || document.querySelector('meta[property="eth:nft:endtime"]'); - const processedCollectionName = - collectionName?.getAttribute('content') || null; - const processedContractAddress = - contractAddress?.getAttribute('content') || null; - const processedCreatorAddress = - creatorAddress?.getAttribute('content') || null; + const processedCollectionName = collectionName?.getAttribute( + 'content' + ) as string; + const processedContractAddress = contractAddress?.getAttribute( + 'content' + ) as `0x${string}`; + const processedCreatorAddress = creatorAddress?.getAttribute( + 'content' + ) as `0x${string}`; const processedChain = chain?.getAttribute('content') || null; - const processedMediaUrl = mediaUrl?.getAttribute('content') || null; + const processedMediaUrl = mediaUrl?.getAttribute('content') as string; const processedMintCount = mintCount?.getAttribute('content') ? Number(mintCount?.getAttribute('content')) : null; const processedMintStatus = mintStatus?.getAttribute('content') || null; const processedMintUrl = mintUrl?.getAttribute('content') || null; - const processedSchema = schema?.getAttribute('content') || null; + const processedSchema = schema?.getAttribute('content') as string; const processedEndTime = endTime?.getAttribute('content') || null; if ( !processedCollectionName && !processedContractAddress && !processedCreatorAddress && - !processedSchema + !processedSchema && + !processedMediaUrl ) { return null; } diff --git a/apps/api/tests/nfts/basepaint/canvas.spec.ts b/apps/api/tests/nfts/basepaint/canvas.spec.ts deleted file mode 100644 index 35fa6ebebb0f..000000000000 --- a/apps/api/tests/nfts/basepaint/canvas.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { TEST_URL } from '@utils/constants'; -import axios from 'axios'; -import { describe, expect, test } from 'vitest'; - -describe('nfts/basepaint/canvas', async () => { - test('should return basepaint canvas', async () => { - const response = await axios.get(`${TEST_URL}/nfts/basepaint/canvas`, { - params: { id: 44 } - }); - - expect(response.data.canvas.canContribute).toBeFalsy(); - expect(response.data.canvas.theme).toEqual('Lens Garden'); - expect(response.data.canvas.contributions).toHaveLength(645); - }); -}); diff --git a/apps/api/tests/nfts/sound/release.spec.ts b/apps/api/tests/nfts/sound/release.spec.ts deleted file mode 100644 index 606f72259df0..000000000000 --- a/apps/api/tests/nfts/sound/release.spec.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { TEST_URL } from '@utils/constants'; -import axios from 'axios'; -import { describe, expect, test } from 'vitest'; - -describe('nfts/sound/release', async () => { - test('should return sound nft', async () => { - const response = await axios.get(`${TEST_URL}/nfts/sound/release`, { - params: { handle: 'annikarose', slug: 'just-like-you' } - }); - - expect(response.data.release.title).toEqual('Just Like You'); - }); -}); diff --git a/apps/api/tests/nfts/unlonely/channel.spec.ts b/apps/api/tests/nfts/unlonely/channel.spec.ts deleted file mode 100644 index f516701fc419..000000000000 --- a/apps/api/tests/nfts/unlonely/channel.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { TEST_URL } from '@utils/constants'; -import axios from 'axios'; -import { describe, expect, test } from 'vitest'; - -describe('nfts/unlonely/channel', async () => { - test('should return unlonely channel', async () => { - const response = await axios.get(`${TEST_URL}/nfts/unlonely/channel`, { - params: { slug: 'pixelnunc' } - }); - - expect(response.data.channel.id).toEqual('145'); - expect(response.data.channel.slug).toEqual('pixelnunc'); - }); -}); diff --git a/apps/api/tests/nfts/unlonely/nfc.spec.ts b/apps/api/tests/nfts/unlonely/nfc.spec.ts deleted file mode 100644 index a10077738445..000000000000 --- a/apps/api/tests/nfts/unlonely/nfc.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { TEST_URL } from '@utils/constants'; -import axios from 'axios'; -import { describe, expect, test } from 'vitest'; - -describe('nfts/unlonely/nfc', async () => { - test('should return unlonely nfc', async () => { - const response = await axios.get(`${TEST_URL}/nfts/unlonely/nfc`, { - params: { id: 700 } - }); - - expect(response.data.nfc.id).toEqual('700'); - expect(response.data.nfc.title).toEqual('supercast is cool'); - }); -}); diff --git a/apps/api/tests/nfts/zora/nft.spec.ts b/apps/api/tests/nfts/zora/nft.spec.ts deleted file mode 100644 index b9691e0e9ec6..000000000000 --- a/apps/api/tests/nfts/zora/nft.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { TEST_URL } from '@utils/constants'; -import axios from 'axios'; -import { describe, expect, test } from 'vitest'; - -describe('nfts/zora/nft', async () => { - test('should return zora nft without token', async () => { - const response = await axios.get(`${TEST_URL}/nfts/zora/nft`, { - params: { - address: '0x84021385852ac3660d847af215098a1ef1b1b5ed', - chain: 'zora' - } - }); - - expect(response.data.nft.contract.name).toEqual('Net AIrt'); - }); - - test('should return zora nft with token', async () => { - const response = await axios.get(`${TEST_URL}/nfts/zora/nft`, { - params: { - address: '0x84021385852ac3660d847af215098a1ef1b1b5ed', - chain: 'zora', - token: 1 - } - }); - - expect(response.data.nft.name).toEqual('Hyperpop Bytes'); - }); -}); diff --git a/apps/web/src/components/Common/Providers/Web3Provider.tsx b/apps/web/src/components/Common/Providers/Web3Provider.tsx index 7da19695ab6f..c1dcca636157 100644 --- a/apps/web/src/components/Common/Providers/Web3Provider.tsx +++ b/apps/web/src/components/Common/Providers/Web3Provider.tsx @@ -2,18 +2,7 @@ import type { FC, ReactNode } from 'react'; import { APP_NAME, WALLETCONNECT_PROJECT_ID } from '@hey/data/constants'; import { createConfig, http, WagmiProvider } from 'wagmi'; -import { - base, - baseGoerli, - goerli, - mainnet, - optimism, - optimismGoerli, - polygon, - polygonMumbai, - zora, - zoraTestnet -} from 'wagmi/chains'; +import { polygon, polygonMumbai } from 'wagmi/chains'; import { coinbaseWallet, injected, walletConnect } from 'wagmi/connectors'; const connectors = [ @@ -23,30 +12,11 @@ const connectors = [ ]; const wagmiConfig = createConfig({ - chains: [ - base, - baseGoerli, - goerli, - mainnet, - optimism, - optimismGoerli, - polygon, - polygonMumbai, - zora, - zoraTestnet - ], + chains: [polygon, polygonMumbai], connectors, transports: { - [base.id]: http(), - [baseGoerli.id]: http(), - [goerli.id]: http(), - [mainnet.id]: http(), - [optimism.id]: http(), - [optimismGoerli.id]: http(), [polygon.id]: http(), - [polygonMumbai.id]: http(), - [zora.id]: http(), - [zoraTestnet.id]: http() + [polygonMumbai.id]: http() } }); diff --git a/apps/web/src/components/Composer/LinkPreviews.tsx b/apps/web/src/components/Composer/LinkPreviews.tsx index 1130f2e30434..0f9a7ac42825 100644 --- a/apps/web/src/components/Composer/LinkPreviews.tsx +++ b/apps/web/src/components/Composer/LinkPreviews.tsx @@ -1,10 +1,7 @@ import type { FC } from 'react'; -import Nft from '@components/Publication/HeyOpenActions/Nft'; import Oembed from '@components/Shared/Oembed'; -import { ZERO_PUBLICATION_ID } from '@hey/data/constants'; import getURLs from '@hey/lib/getURLs'; -import getNft from '@hey/lib/nft/getNft'; import { usePublicationStore } from 'src/store/non-persisted/publication/usePublicationStore'; const LinkPreviews: FC = () => { @@ -18,20 +15,6 @@ const LinkPreviews: FC = () => { return null; } - const nft = getNft(urls); - - if (nft) { - return ( -
- {nft ? ( - - ) : ( - - )} -
- ); - } - return ; }; diff --git a/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/Metadata.tsx b/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/Metadata.tsx deleted file mode 100644 index f519c97e7aea..000000000000 --- a/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/Metadata.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import type { BasePaintCanvas } from '@hey/types/nft'; -import type { FC } from 'react'; - -import { - CurrencyDollarIcon, - PaintBrushIcon, - QrCodeIcon, - SwatchIcon, - UsersIcon -} from '@heroicons/react/24/outline'; -import humanize from '@hey/lib/humanize'; -import { formatEther } from 'viem'; - -interface MetadataProps { - canvas: BasePaintCanvas; -} - -const Metadata: FC = ({ canvas }) => { - const { contributions, pixelsCount, totalEarned, totalMints } = canvas; - - return ( -
- {totalMints > 0 ? ( -
- - {humanize(totalMints)} minted -
- ) : null} -
- - - {contributions.length > 1000 ? '1000+' : contributions.length} artists - -
- {pixelsCount > 0 ? ( -
- - {humanize(pixelsCount)} pixels used -
- ) : null} - {totalEarned ? ( -
- - {formatEther(BigInt(totalEarned))} ETH earned -
- ) : null} -
- - Color Palette -
- {canvas.palette.map((color) => ( - - ))} -
-
-
- ); -}; - -export default Metadata; diff --git a/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/MintAction.tsx b/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/MintAction.tsx deleted file mode 100644 index 37a66425a9e1..000000000000 --- a/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/MintAction.tsx +++ /dev/null @@ -1,171 +0,0 @@ -import type { BasePaintCanvas } from '@hey/types/nft'; -import type { FC } from 'react'; - -import WalletSelector from '@components/Shared/Login/WalletSelector'; -import SwitchNetwork from '@components/Shared/SwitchNetwork'; -import { - CurrencyDollarIcon, - CursorArrowRaysIcon -} from '@heroicons/react/24/outline'; -import { CheckCircleIcon } from '@heroicons/react/24/solid'; -import { BasePaint } from '@hey/abis'; -import { Errors } from '@hey/data'; -import { BASEPAINT_CONTRACT } from '@hey/data/contracts'; -import { PUBLICATION } from '@hey/data/tracking'; -import { Button, Spinner } from '@hey/ui'; -import { Leafwatch } from '@lib/leafwatch'; -import Link from 'next/link'; -import toast from 'react-hot-toast'; -import { useUpdateEffect } from 'usehooks-ts'; -import { parseEther } from 'viem'; -import { base } from 'viem/chains'; -import { - useAccount, - useChainId, - useSimulateContract, - useWaitForTransactionReceipt, - useWriteContract -} from 'wagmi'; - -import { useBasePaintMintStore } from '.'; - -const NO_BALANCE_ERROR = 'exceeds the balance of the account'; - -interface MintActionProps { - canvas: BasePaintCanvas; - openEditionPrice: number; - publicationId: string; -} - -const MintAction: FC = ({ - canvas, - openEditionPrice, - publicationId -}) => { - const quantity = useBasePaintMintStore((state) => state.quantity); - - const chain = useChainId(); - const { isDisconnected } = useAccount(); - - const nftAddress = BASEPAINT_CONTRACT; - const day = canvas.id; - const value = parseEther(openEditionPrice.toString()) * BigInt(quantity); - - const { - data: simulateData, - error: simulateError, - failureCount: simulateFailureCount - } = useSimulateContract({ - abi: BasePaint, - address: nftAddress, - args: [day, quantity], - chainId: base.id, - functionName: 'mint', - value - }); - - const { - data: writeHash, - isPending: isContractWriteLoading, - writeContract - } = useWriteContract(); - - const write = () => { - if (!simulateData) { - return toast.error(Errors.SomethingWentWrong); - } - - return writeContract(simulateData.request); - }; - - const { - data: txnData, - isLoading, - isSuccess - } = useWaitForTransactionReceipt({ - chainId: base.id, - hash: writeHash - }); - - useUpdateEffect(() => { - if (txnData?.transactionHash) { - Leafwatch.track(PUBLICATION.OPEN_ACTIONS.BASEPAINT_NFT.MINT, { - nft: nftAddress, - price: openEditionPrice * quantity, - publication_id: publicationId, - quantity - }); - } - }, [isSuccess]); - - const isSimulateError = simulateFailureCount > 0; - const mintingOrSuccess = isLoading || isSuccess; - - // Errors - const noBalanceError = simulateError?.message?.includes(NO_BALANCE_ERROR); - - return !mintingOrSuccess ? ( -
- {isDisconnected ? ( -
- -
- ) : chain !== base.id ? ( - - ) : isSimulateError ? ( - noBalanceError ? ( - - - - ) : null - ) : ( - - )} -
- ) : ( -
- {isLoading ? ( -
- -
Minting in progress
-
- ) : null} - {isSuccess ? ( -
- -
Minted successful
-
- ) : null} -
- ); -}; - -export default MintAction; diff --git a/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/Price.tsx b/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/Price.tsx deleted file mode 100644 index 4380948096c7..000000000000 --- a/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/Price.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import type { FC } from 'react'; - -import { MinusIcon, PlusIcon } from '@heroicons/react/24/outline'; -import getRedstonePrice from '@hey/lib/getRedstonePrice'; -import { useQuery } from '@tanstack/react-query'; - -import { useBasePaintMintStore } from '.'; - -interface PriceProps { - openEditionPrice: number; -} - -const Price: FC = ({ openEditionPrice }) => { - const quantity = useBasePaintMintStore((state) => state.quantity); - const setQuantity = useBasePaintMintStore((state) => state.setQuantity); - - const { data: usdPrice, isLoading } = useQuery({ - enabled: Boolean(openEditionPrice), - queryFn: async () => await getRedstonePrice('ETH'), - queryKey: ['getRedstonePrice'] - }); - - if (isLoading) { - return null; - } - - const priceInEth = quantity * openEditionPrice; - const priceInUsd = usdPrice * priceInEth; - - return ( -
-
-
-
-
-
{priceInEth.toFixed(3)}
-
ETH
-
-
- ≈ ${priceInUsd.toFixed(2)} USD -
-
-
- - {quantity} - -
-
-
- ); -}; - -export default Price; diff --git a/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/index.tsx b/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/index.tsx deleted file mode 100644 index 10d4e59cc199..000000000000 --- a/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Mint/index.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import type { BasePaintCanvas } from '@hey/types/nft'; -import type { FC } from 'react'; - -import { BasePaint } from '@hey/abis'; -import { BASEPAINT_CONTRACT } from '@hey/data/contracts'; -import { formatEther } from 'viem'; -import { base } from 'viem/chains'; -import { useContractRead } from 'wagmi'; -import { create } from 'zustand'; - -import Metadata from './Metadata'; -import MintAction from './MintAction'; -import Price from './Price'; - -interface BasePaintMintState { - quantity: number; - setQuantity: (quantity: number) => void; -} - -export const useBasePaintMintStore = create((set) => ({ - quantity: 1, - setQuantity: (quantity) => set({ quantity }) -})); - -interface MintProps { - canvas: BasePaintCanvas; - publicationId: string; -} - -const Mint: FC = ({ canvas, publicationId }) => { - const { data, isSuccess } = useContractRead({ - abi: BasePaint, - address: BASEPAINT_CONTRACT, - chainId: base.id, - functionName: 'openEditionPrice' - }); - - const openEditionPrice = parseInt(data?.toString() || '0'); - const etherPrice = parseFloat(formatEther(BigInt(openEditionPrice))); - - return ( -
-
-
- Day #{canvas.id}: {canvas.theme} -
-
- - {isSuccess ? ( - <> - - - - ) : null} -
- ); -}; - -export default Mint; diff --git a/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Shimmer.tsx b/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Shimmer.tsx deleted file mode 100644 index 47122cf3f619..000000000000 --- a/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/Shimmer.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import type { FC } from 'react'; - -import { Card } from '@hey/ui'; - -const NftShimmer: FC = () => { - return ( - -
-
-
-
-
-
-
-
-
-
-
-
-
-
- - ); -}; - -export default NftShimmer; diff --git a/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/index.tsx b/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/index.tsx deleted file mode 100644 index 3ea461b389be..000000000000 --- a/apps/web/src/components/Publication/HeyOpenActions/Nft/BasePaintCanvas/index.tsx +++ /dev/null @@ -1,168 +0,0 @@ -import type { BasePaintCanvasMetadata } from '@hey/types/nft'; -import type { FC } from 'react'; - -import { CursorArrowRaysIcon } from '@heroicons/react/24/outline'; -import { STATIC_IMAGES_URL } from '@hey/data/constants'; -import { BASEPAINT_CONTRACT } from '@hey/data/contracts'; -import { PUBLICATION } from '@hey/data/tracking'; -import stopEventPropagation from '@hey/lib/stopEventPropagation'; -import { Button, Card, Modal, Tooltip } from '@hey/ui'; -import { Leafwatch } from '@lib/leafwatch'; -import Link from 'next/link'; -import { useState } from 'react'; -import useBasePaintCanvas from 'src/hooks/basepaint/useBasePaintCanvas'; -import urlcat from 'urlcat'; - -import Mint, { useBasePaintMintStore } from './Mint'; -import NftShimmer from './Shimmer'; - -interface BasePaintCanvasProps { - nftMetadata: BasePaintCanvasMetadata; - publicationId: string; -} - -const BasePaintCanvas: FC = ({ - nftMetadata, - publicationId -}) => { - const { id } = nftMetadata; - const [showMintModal, setShowMintModal] = useState(false); - const setQuantity = useBasePaintMintStore((state) => state.setQuantity); - - const { - data: canvas, - error, - loading - } = useBasePaintCanvas({ - enabled: Boolean(id), - id - }); - - if (loading) { - return ; - } - - if (!canvas?.bitmap) { - return null; - } - - if (error) { - return null; - } - - const { bitmap, canContribute, canMint, theme } = canvas; - - return ( - stopEventPropagation(event)} - > - BasePaint Canvas -
-
- - BasePaint - -
- Day #{canvas.id}: {theme} -
-
- {canvas.palette.map((color) => ( - - ))} -
-
- {publicationId ? ( - canMint ? ( - <> - - } - onClose={() => setShowMintModal(false)} - show={showMintModal} - title="Mint on BasePaint" - > - - - - ) : canContribute ? ( - - - - ) : ( - - - - ) - ) : ( -
- )} -
- - ); -}; - -export default BasePaintCanvas; diff --git a/apps/web/src/components/Publication/HeyOpenActions/Nft/SoundRelease/Shimmer.tsx b/apps/web/src/components/Publication/HeyOpenActions/Nft/SoundRelease/Shimmer.tsx deleted file mode 100644 index 8c75927dcce7..000000000000 --- a/apps/web/src/components/Publication/HeyOpenActions/Nft/SoundRelease/Shimmer.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import type { FC } from 'react'; - -import { Card } from '@hey/ui'; - -const NftShimmer: FC = () => { - return ( - -
-
-
-
-
-
-
-
- - ); -}; - -export default NftShimmer; diff --git a/apps/web/src/components/Publication/HeyOpenActions/Nft/SoundRelease/index.tsx b/apps/web/src/components/Publication/HeyOpenActions/Nft/SoundRelease/index.tsx deleted file mode 100644 index 85980f64fa98..000000000000 --- a/apps/web/src/components/Publication/HeyOpenActions/Nft/SoundRelease/index.tsx +++ /dev/null @@ -1,196 +0,0 @@ -import type { SoundReleaseMetadata } from '@hey/types/nft'; -import type { APITypes } from 'plyr-react'; - -import Player from '@components/Shared/Audio/Player'; -import { - CursorArrowRaysIcon, - PauseIcon, - PlayIcon -} from '@heroicons/react/24/solid'; -import { REWARDS_ADDRESS, STATIC_IMAGES_URL } from '@hey/data/constants'; -import { PUBLICATION } from '@hey/data/tracking'; -import humanize from '@hey/lib/humanize'; -import stopEventPropagation from '@hey/lib/stopEventPropagation'; -import { Button, Card, Image, Tooltip } from '@hey/ui'; -import { Leafwatch } from '@lib/leafwatch'; -import Link from 'next/link'; -import { type FC, useRef, useState } from 'react'; -import useSoundRelease from 'src/hooks/sound/useSoundRelease'; -import urlcat from 'urlcat'; - -import NftShimmer from './Shimmer'; - -interface SoundReleaseProps { - nftMetadata: SoundReleaseMetadata; - publicationId: string; -} - -const SoundRelease: FC = ({ - nftMetadata, - publicationId -}) => { - const { handle, mintLink, slug } = nftMetadata; - const [playing, setPlaying] = useState(false); - const playerRef = useRef(null); - - const { - data: release, - error, - loading - } = useSoundRelease({ - enabled: Boolean(handle && slug), - handle, - slug - }); - - if (loading) { - return ; - } - - if (!release) { - return null; - } - - if (error) { - return null; - } - - const handlePlayPause = () => { - if (!playerRef.current) { - return; - } - if (playerRef.current?.plyr.paused && !playing) { - setPlaying(true); - Leafwatch.track(PUBLICATION.OPEN_ACTIONS.SOUND_RELEASE.PLAY, { - publication_id: publicationId - }); - - return playerRef.current?.plyr.play(); - } - setPlaying(false); - playerRef.current?.plyr.pause(); - Leafwatch.track(PUBLICATION.OPEN_ACTIONS.SOUND_RELEASE.PAUSE, { - publication_id: publicationId - }); - }; - - const { artist, coverImage, numSold, title, track } = release; - const peaks = track.normalizedPeaks?.reduce( - (acc: number[], curr: number, index) => { - if (index % 10 === 0) { - acc.push(curr / 2); - } - - return acc; - }, - [] - ); - - return ( - stopEventPropagation(event)} - > -
-
-
- {`sound-release-cover-${coverImage.url}`} -
-
-
- -
-
{title}
-
- Artist -
{artist.name}
- - {humanize(numSold)} Mints -
-
-
-
-
- -
-
-
-
- {peaks?.map((peak, index) => ( -
- ))} -
-
-
-
-
- - Sound - -
{title}
-
- - - -
- - ); -}; - -export default SoundRelease; diff --git a/apps/web/src/components/Publication/HeyOpenActions/Nft/UnlonelyChannel/Shimmer.tsx b/apps/web/src/components/Publication/HeyOpenActions/Nft/UnlonelyChannel/Shimmer.tsx deleted file mode 100644 index 958831949165..000000000000 --- a/apps/web/src/components/Publication/HeyOpenActions/Nft/UnlonelyChannel/Shimmer.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import type { FC } from 'react'; - -import { Card } from '@hey/ui'; - -const NftShimmer: FC = () => { - return ( - -
-
-
-
-
-
-
-
- - ); -}; - -export default NftShimmer; diff --git a/apps/web/src/components/Publication/HeyOpenActions/Nft/UnlonelyChannel/index.tsx b/apps/web/src/components/Publication/HeyOpenActions/Nft/UnlonelyChannel/index.tsx deleted file mode 100644 index 676887e06f3d..000000000000 --- a/apps/web/src/components/Publication/HeyOpenActions/Nft/UnlonelyChannel/index.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import type { UnlonelyChannelMetadata } from '@hey/types/nft'; -import type { FC } from 'react'; - -import Video from '@components/Shared/Video'; -import { - CursorArrowRaysIcon, - SignalIcon, - SignalSlashIcon -} from '@heroicons/react/24/outline'; -import { STATIC_IMAGES_URL } from '@hey/data/constants'; -import { PUBLICATION } from '@hey/data/tracking'; -import stopEventPropagation from '@hey/lib/stopEventPropagation'; -import { Button, Card, Tooltip } from '@hey/ui'; -import cn from '@hey/ui/cn'; -import { Leafwatch } from '@lib/leafwatch'; -import Link from 'next/link'; -import useUnlonelyChannel from 'src/hooks/unlonely/useUnlonelyChannel'; -import urlcat from 'urlcat'; - -import NftShimmer from './Shimmer'; - -interface UnlonelyChannelProps { - nftMetadata: UnlonelyChannelMetadata; - publicationId: string; -} - -const UnlonelyChannel: FC = ({ - nftMetadata, - publicationId -}) => { - const { slug } = nftMetadata; - - const { - data: channel, - error, - loading - } = useUnlonelyChannel({ - enabled: Boolean(slug), - slug - }); - - if (loading) { - return ; - } - - if (!channel) { - return null; - } - - if (error) { - return null; - } - - const { isLive, name, playbackUrl } = channel; - - return ( - stopEventPropagation(event)} - > -