From 124aaa4867c91b9567cceaa8e41097c113260ac3 Mon Sep 17 00:00:00 2001 From: Tempe Techie <95053628+tempe-techie@users.noreply.github.com> Date: Mon, 27 Nov 2023 20:31:16 +0100 Subject: [PATCH] link previews via axios, shared code between netlify and vercel functions --- api/linkPreviews.js | 199 +----------------------- netlify/functions/linkPreviews.js | 208 +------------------------ package-lock.json | 13 +- package.json | 1 + utils/linkPreviewUtils.js | 247 ++++++++++++++++++++++++++++++ utils/rpcUtils.js | 8 +- 6 files changed, 275 insertions(+), 401 deletions(-) create mode 100644 utils/linkPreviewUtils.js diff --git a/api/linkPreviews.js b/api/linkPreviews.js index 13d78f7c..df487f03 100644 --- a/api/linkPreviews.js +++ b/api/linkPreviews.js @@ -1,199 +1,12 @@ -export default async function handler(request, response) { - const ethers = require('ethers'); - - const metascraper = require('metascraper')([ - require('metascraper-description')(), - require('metascraper-image')(), - require('metascraper-title')() - ]) +const { fetchMetadata } = require('../utils/linkPreviewUtils'); +export default async function handler(request, response) { const url = request.query.url; - // link previews for specific sites - if (url.startsWith("https://sparklesnft.com/item/flare/")) { - // SPARKLES ITEM - const cleanUrl = url.split("?")[0]; - const addrTokenId = cleanUrl.split("https://sparklesnft.com/item/flare/")[1].replace("/", ""); - const addr = addrTokenId.split("_")[0]; - const tokenId = addrTokenId.split("_")[1]; - - const provider = new ethers.providers.JsonRpcProvider("https://flare-api.flare.network/ext/C/rpc"); - - const nftInterface = new ethers.utils.Interface([ - "function uri(uint256 _tokenId) external view returns (string memory)", - "function tokenURI(uint256 _tokenId) external view returns (string memory)" - ]); - - const nftContract = new ethers.Contract(addr, nftInterface, provider); - - let nftMetadataUri; - - try { - // erc-1155 - nftMetadataUri = await nftContract.uri(tokenId); - } catch (error) { - // erc-721 - nftMetadataUri = await nftContract.tokenURI(tokenId); - } - - let json; - - if ( - !nftMetadataUri.startsWith("https://") && - !nftMetadataUri.startsWith("http://") && - !nftMetadataUri.startsWith("ipfs://") - ) { - const result = atob(nftMetadataUri.substring(29)); - json = JSON.parse(result); - } else if (nftMetadataUri.startsWith("ipfs://")) { - // ipfs://QmTLJDoCTihqD3AkNkMMQFXLMQFZkdqLFR3Mdcg14Ln7bL/7.json - // https://bafkreiecjcejcg6h5wh2g3wcacy2lnod2mfrvimlr53ikvlsh53mw2zdty.ipfs.w3s.link/ - // https://QmTLJDoCTihqD3AkNkMMQFXLMQFZkdqLFR3Mdcg14Ln7bL.ipfs.dweb.link/7.json - // https://bafybeickgncmppcbrhg4cbzw3nxqajxoe2vj7ixmmcshddkyn5itv7ang4.ipfs.dweb.link/7.json - - json = { - "name": "Check this NFT on Sparkles", - "description": "Sparkles NFT Marketplace", - "image": "https://bafkreifyx3seviqnnhpcuge72lr7la3yfrvucr3n5aoqijzjul2fyzh64i.ipfs.w3s.link" - } - } else { - const res = await fetch(nftMetadataUri); - json = await res.json(); - } - - const finalMetadata = { - "url": url, - "title": json["name"], - "description": json["description"], - "image": { - url: json["image"] - } - }; - - return response.status(200).json({ - data: finalMetadata - }); - } else if (url.startsWith("https://opensea.io/assets/base/")) { - // OPENSEA ITEM - const cleanUrl = url.split("?")[0]; - const addrTokenId = cleanUrl.split("opensea.io/assets/base/")[1]; - const addr = addrTokenId.split("/")[0]; - const tokenId = addrTokenId.split("/")[1].replace("/", ""); - - const provider = new ethers.providers.JsonRpcProvider("https://mainnet.base.org"); - - const nftInterface = new ethers.utils.Interface([ - "function uri(uint256 _tokenId) external view returns (string memory)", - "function tokenURI(uint256 _tokenId) external view returns (string memory)" - ]); - - const nftContract = new ethers.Contract(addr, nftInterface, provider); - - let nftMetadataUri; - - try { - // erc-1155 - nftMetadataUri = await nftContract.uri(tokenId); - } catch (error) { - // erc-721 - nftMetadataUri = await nftContract.tokenURI(tokenId); - } - - let json; - - if ( - !nftMetadataUri.startsWith("https://") && - !nftMetadataUri.startsWith("http://") && - !nftMetadataUri.startsWith("ipfs://") - ) { - const result = atob(nftMetadataUri.substring(29)); - json = JSON.parse(result); - } else if (nftMetadataUri.startsWith("ipfs://")) { - // ipfs://QmTLJDoCTihqD3AkNkMMQFXLMQFZkdqLFR3Mdcg14Ln7bL/7.json - // https://bafkreiecjcejcg6h5wh2g3wcacy2lnod2mfrvimlr53ikvlsh53mw2zdty.ipfs.w3s.link/ - // https://QmTLJDoCTihqD3AkNkMMQFXLMQFZkdqLFR3Mdcg14Ln7bL.ipfs.dweb.link/7.json - // https://bafybeickgncmppcbrhg4cbzw3nxqajxoe2vj7ixmmcshddkyn5itv7ang4.ipfs.dweb.link/7.json - - json = { - "name": "Check this NFT on OpenSea", - "description": "OpenSea is the world's first and largest web3 marketplace for NFTs and crypto collectibles. Browse, create, buy, sell, and auction NFTs using OpenSea today.", - "image": "https://static.opensea.io/og-images/Metadata-Image.png" - } - } else { - const res = await fetch(nftMetadataUri); - json = await res.json(); - } - - const finalMetadata = { - "url": url, - "title": json["name"], - "description": json["description"], - "image": { - url: json["image"] - } - }; - - return response.status(200).json({ - data: finalMetadata - }); - } else if (url.startsWith("https://twitter.com") || url.startsWith("https://x.com")) { - // TWITTER - const finalMetadata = { - "url": url, - "title": "Twitter / X.com", - "description": "Elon's land, Elon's rules. Enter at your own risk.", - "image": { - url: "https://www.newswire.lk/wp-content/uploads/2022/12/elon-musk-twitter.jpg" - } - }; - - return response.status(200).json({ - data: finalMetadata - }); - } - - // link previews for all other sites - try { - const res = await fetch(url); - const html = await res.text(); - - const metadata = await metascraper({ html, url }); - - const finalMetadata = { - "url": url, - "title": metadata.title, - "description": metadata.description, - "image": { - url: metadata.image - } - }; - - if (finalMetadata?.title) { - if (url.startsWith("https://opensea.io") && (finalMetadata.title == "Access denied" || finalMetadata.title.startsWith("Just a moment"))) { - finalMetadata.title = "OpenSea"; - finalMetadata.description = "OpenSea is the world's first and largest web3 marketplace for NFTs and crypto collectibles. Browse, create, buy, sell, and auction NFTs using OpenSea today."; - finalMetadata.image.url = "https://static.opensea.io/og-images/Metadata-Image.png"; - } else if (url.startsWith("https://dune.com") && (finalMetadata.title.startsWith("Attention Required") || finalMetadata.title.startsWith("Just a moment"))) { - finalMetadata.title = "Dune"; - finalMetadata.description = "Blockchain ecosystem analytics by and for the community. Explore and share data from Ethereum, Polygon, Arbitrum, Optimism, and others for free."; - finalMetadata.image.url = "https://dune.com/assets/poster-1440w.png"; - } else if (finalMetadata.title.startsWith("Just a moment...")) { - return response.status(500).json({ - error: "Data not fetched yet." - }); - } - } - - return response.status(200).json({ - data: finalMetadata - }); - - } catch (error) { - console.error('Error fetching link preview metadata:', error); + const { metadata, status } = await fetchMetadata(url); - return response.status(500).json({ - error: error - }); - } + return response.status(status).json({ + data: metadata + }); }; \ No newline at end of file diff --git a/netlify/functions/linkPreviews.js b/netlify/functions/linkPreviews.js index eaacb608..eb4aba26 100644 --- a/netlify/functions/linkPreviews.js +++ b/netlify/functions/linkPreviews.js @@ -1,205 +1,13 @@ -exports.handler = async function (event, context) { - const ethers = require('ethers'); - - const metascraper = require('metascraper')([ - require('metascraper-description')(), - require('metascraper-image')(), - require('metascraper-title')() - ]) +const { fetchMetadata } = require('../../utils/linkPreviewUtils'); +exports.handler = async function (event, context) { const url = event.queryStringParameters.url; - // link previews for specific sites - if (url.startsWith("https://sparklesnft.com/item/flare/")) { - // SPARKLES ITEM - const cleanUrl = url.split("?")[0]; - const addrTokenId = cleanUrl.split("https://sparklesnft.com/item/flare/")[1].replace("/", ""); - const addr = addrTokenId.split("_")[0]; - const tokenId = addrTokenId.split("_")[1]; - - const provider = new ethers.providers.JsonRpcProvider("https://flare-api.flare.network/ext/C/rpc"); - - const nftInterface = new ethers.utils.Interface([ - "function uri(uint256 _tokenId) external view returns (string memory)", - "function tokenURI(uint256 _tokenId) external view returns (string memory)" - ]); - - const nftContract = new ethers.Contract(addr, nftInterface, provider); - - let nftMetadataUri; - - try { - // erc-1155 - nftMetadataUri = await nftContract.uri(tokenId); - } catch (error) { - // erc-721 - nftMetadataUri = await nftContract.tokenURI(tokenId); - } - - let json; - - if ( - !nftMetadataUri.startsWith("https://") && - !nftMetadataUri.startsWith("http://") && - !nftMetadataUri.startsWith("ipfs://") - ) { - const result = atob(nftMetadataUri.substring(29)); - json = JSON.parse(result); - } else if (nftMetadataUri.startsWith("ipfs://")) { - // ipfs://QmTLJDoCTihqD3AkNkMMQFXLMQFZkdqLFR3Mdcg14Ln7bL/7.json - // https://bafkreiecjcejcg6h5wh2g3wcacy2lnod2mfrvimlr53ikvlsh53mw2zdty.ipfs.w3s.link/ - // https://QmTLJDoCTihqD3AkNkMMQFXLMQFZkdqLFR3Mdcg14Ln7bL.ipfs.dweb.link/7.json - // https://bafybeickgncmppcbrhg4cbzw3nxqajxoe2vj7ixmmcshddkyn5itv7ang4.ipfs.dweb.link/7.json - - json = { - "name": "Check this NFT on Sparkles", - "description": "Sparkles NFT Marketplace", - "image": "https://bafkreifyx3seviqnnhpcuge72lr7la3yfrvucr3n5aoqijzjul2fyzh64i.ipfs.w3s.link" - } - } else { - const response = await fetch(nftMetadataUri); - json = await response.json(); - } - - const finalMetadata = { - "url": url, - "title": json["name"], - "description": json["description"], - "image": { - url: json["image"] - } - }; - - return { - statusCode: 200, - body: JSON.stringify({ data: finalMetadata }), - }; - } else if (url.startsWith("https://opensea.io/assets/base/")) { - // OPENSEA ITEM - const cleanUrl = url.split("?")[0]; - const addrTokenId = cleanUrl.split("opensea.io/assets/base/")[1]; - const addr = addrTokenId.split("/")[0]; - const tokenId = addrTokenId.split("/")[1].replace("/", ""); - - const provider = new ethers.providers.JsonRpcProvider("https://mainnet.base.org"); - - const nftInterface = new ethers.utils.Interface([ - "function uri(uint256 _tokenId) external view returns (string memory)", - "function tokenURI(uint256 _tokenId) external view returns (string memory)" - ]); - - const nftContract = new ethers.Contract(addr, nftInterface, provider); - - let nftMetadataUri; - - try { - // erc-1155 - nftMetadataUri = await nftContract.uri(tokenId); - } catch (error) { - // erc-721 - nftMetadataUri = await nftContract.tokenURI(tokenId); - } - - let json; - - if ( - !nftMetadataUri.startsWith("https://") && - !nftMetadataUri.startsWith("http://") && - !nftMetadataUri.startsWith("ipfs://") - ) { - const result = atob(nftMetadataUri.substring(29)); - json = JSON.parse(result); - } else if (nftMetadataUri.startsWith("ipfs://")) { - // ipfs://QmTLJDoCTihqD3AkNkMMQFXLMQFZkdqLFR3Mdcg14Ln7bL/7.json - // https://bafkreiecjcejcg6h5wh2g3wcacy2lnod2mfrvimlr53ikvlsh53mw2zdty.ipfs.w3s.link/ - // https://QmTLJDoCTihqD3AkNkMMQFXLMQFZkdqLFR3Mdcg14Ln7bL.ipfs.dweb.link/7.json - // https://bafybeickgncmppcbrhg4cbzw3nxqajxoe2vj7ixmmcshddkyn5itv7ang4.ipfs.dweb.link/7.json - - json = { - "name": "Check this NFT on OpenSea", - "description": "OpenSea is the world's first and largest web3 marketplace for NFTs and crypto collectibles. Browse, create, buy, sell, and auction NFTs using OpenSea today.", - "image": "https://static.opensea.io/og-images/Metadata-Image.png" - } - } else { - const response = await fetch(nftMetadataUri); - json = await response.json(); - } - - const finalMetadata = { - "url": url, - "title": json["name"], - "description": json["description"], - "image": { - url: json["image"] - } - }; - - return { - statusCode: 200, - body: JSON.stringify({ data: finalMetadata }), - }; - } else if (url.startsWith("https://twitter.com") || url.startsWith("https://x.com")) { - // TWITTER - const finalMetadata = { - "url": url, - "title": "Twitter / X.com", - "description": "Elon's land, Elon's rules. Enter at your own risk.", - "image": { - url: "https://www.newswire.lk/wp-content/uploads/2022/12/elon-musk-twitter.jpg" - } - }; - - return { - statusCode: 200, - body: JSON.stringify({ data: finalMetadata }), - }; - } - - // link previews for all other sites - try { - const response = await fetch(url); - const html = await response.text(); - - const metadata = await metascraper({ html, url }); - - const finalMetadata = { - "url": url, - "title": metadata.title, - "description": metadata.description, - "image": { - url: metadata.image - } - }; - - if (finalMetadata?.title) { - if (url.startsWith("https://opensea.io") && (finalMetadata.title == "Access denied" || finalMetadata.title.startsWith("Just a moment"))) { - finalMetadata.title = "OpenSea"; - finalMetadata.description = "OpenSea is the world's first and largest web3 marketplace for NFTs and crypto collectibles. Browse, create, buy, sell, and auction NFTs using OpenSea today."; - finalMetadata.image.url = "https://static.opensea.io/og-images/Metadata-Image.png"; - } else if (url.startsWith("https://dune.com") && (finalMetadata.title.startsWith("Attention Required") || finalMetadata.title.startsWith("Just a moment"))) { - finalMetadata.title = "Dune"; - finalMetadata.description = "Blockchain ecosystem analytics by and for the community. Explore and share data from Ethereum, Polygon, Arbitrum, Optimism, and others for free."; - finalMetadata.image.url = "https://dune.com/assets/poster-1440w.png"; - } else if (finalMetadata.title.startsWith("Just a moment...")) { - return { - statusCode: 500, - body: JSON.stringify({ error: "Data not fetched yet." }), - }; - } - } - - return { - statusCode: 200, - body: JSON.stringify({ data: finalMetadata }), - }; - - } catch (error) { - console.error('Error fetching link preview metadata:', error); + const { metadata, status } = await fetchMetadata(url); - return { - statusCode: 500, - body: JSON.stringify({ error }), - }; - } + return { + statusCode: status, + body: JSON.stringify({ data: metadata }), + }; -}; \ No newline at end of file +}; diff --git a/package-lock.json b/package-lock.json index 28f0e99d..b40d9df3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@spheron/storage": "^2.0.4", "@vueuse/core": "^9.2.0", "@vueuse/nuxt": "^9.2.0", + "axios": "^1.6.2", "emoji-mart-vue-fast": "^15.0.0", "ethers": "^5.7.2", "metascraper": "^5.36.0", @@ -8214,9 +8215,9 @@ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" }, "node_modules/axios": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz", - "integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -28917,9 +28918,9 @@ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" }, "axios": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz", - "integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", "requires": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", diff --git a/package.json b/package.json index 23b40591..5c3e89bc 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@spheron/storage": "^2.0.4", "@vueuse/core": "^9.2.0", "@vueuse/nuxt": "^9.2.0", + "axios": "^1.6.2", "emoji-mart-vue-fast": "^15.0.0", "ethers": "^5.7.2", "metascraper": "^5.36.0", diff --git a/utils/linkPreviewUtils.js b/utils/linkPreviewUtils.js new file mode 100644 index 00000000..1b686415 --- /dev/null +++ b/utils/linkPreviewUtils.js @@ -0,0 +1,247 @@ +const axios = require('axios'); +const ethers = require('ethers'); +const metascraper = require('metascraper')([ + require('metascraper-description')(), + require('metascraper-image')(), + require('metascraper-title')() +]); + +async function fetchMetadata(url) { + let metadata; + let status; + + try { + if (url.startsWith("https://opensea.io")) { + metadata = await getOpenSeaPreview(url); + } else if (url.startsWith("https://sparklesnft.com/item/")) { + metadata = await getSparklesPreview(url); + } else if (url.startsWith("https://twitter.com") || url.startsWith("https://x.com")) { + metadata = getTwitterPreview(url); + } else if (url.startsWith("https://dune.com")) { + metadata = getDunePreview(url); + } else { + metadata = await getMetascraperPreview(url); + } + + status = 200; + } catch (error) { + console.log(error); + metadata = { error: "Error fetching URL preview data." }; + status = 500; + } + + return { metadata, status }; +} + +async function fetchNftMetadata(url, addr, tokenId, rpcUrl, marketplace) { + const provider = new ethers.providers.JsonRpcProvider(rpcUrl); + + const nftInterface = new ethers.utils.Interface([ + "function uri(uint256 _tokenId) external view returns (string memory)", + "function tokenURI(uint256 _tokenId) external view returns (string memory)" + ]); + + const nftContract = new ethers.Contract(addr, nftInterface, provider); + + let nftMetadataUri; + + try { + // erc-1155 + nftMetadataUri = await nftContract.uri(tokenId); + } catch (error) { + // erc-721 + nftMetadataUri = await nftContract.tokenURI(tokenId); + } + + let json; + + if ( + !nftMetadataUri.startsWith("https://") && + !nftMetadataUri.startsWith("http://") && + !nftMetadataUri.startsWith("ipfs://") + ) { + const result = atob(nftMetadataUri.substring(29)); + json = JSON.parse(result); + } else { + if (nftMetadataUri.startsWith("ipfs://")) { + // ipfs://QmeSjSinHpPnmXmspMjwiXyN6zS4E9zccariGR3jxcaWtq/2614 + // https://dweb.link/ipfs/QmeSjSinHpPnmXmspMjwiXyN6zS4E9zccariGR3jxcaWtq/2614 + + nftMetadataUri = nftMetadataUri.replace("ipfs://", "https://dweb.link/ipfs/"); + } + + const res = await axios.get(nftMetadataUri); + json = await res.data; + } + + if (json["image"].startsWith("ipfs://")) { + json["image"] = json["image"].replace("ipfs://", "https://dweb.link/ipfs/"); + } + + if (!json["description"]) { + json["description"] = url; + } + + if (!json["name"]) { + json["name"] = tokenId; + } + + return { + "url": url, + "title": json?.name, + "description": json?.description, + "image": { + url: json["image"] + } + }; +} + +function getDunePreview(url) { + return { + "url": url, + "title": "Dune", + "description": "Blockchain ecosystem analytics by and for the community. Explore and share data from Ethereum, Polygon, Arbitrum, Optimism, and others for free.", + "image": { + url: "https://dune.com/assets/poster-1440w.png" + } + } +} + +async function getMetascraperPreview(url) { + let metadata; + + try { + const res = await axios.get(url); + const html = await res.data; + const mdRes = await metascraper({ html, url }); + + metadata = { + "url": url, + "title": mdRes.title, + "description": mdRes.description, + "image": { + url: mdRes.image + } + }; + } catch (error) { + //console.log(error); + } + + return metadata; +} + +async function getOpenSeaPreview(url) { + let finalMetadata = { + title: "OpenSea", + description: "OpenSea is the first web3 marketplace for NFTs and crypto collectibles. Browse, create, buy, sell, and auction NFTs using OpenSea today.", + image: { + url: "https://i.postimg.cc/Gm6KcZXB/opensea.jpg" + } + }; + + if (url.startsWith("https://opensea.io/assets/arbitrum/")) { + const cleanUrl = url.split("?")[0]; + const addrTokenId = cleanUrl.split("opensea.io/assets/arbitrum/")[1]; + const addr = addrTokenId.split("/")[0]; + const tokenId = addrTokenId.split("/")[1].replace("/", ""); + finalMetadata = await fetchNftMetadata(url, addr, tokenId, "https://rpc.ankr.com/arbitrum", "opensea"); + } else if (url.startsWith("https://opensea.io/assets/avalanche/")) { + const cleanUrl = url.split("?")[0]; + const addrTokenId = cleanUrl.split("opensea.io/assets/avalanche/")[1]; + const addr = addrTokenId.split("/")[0]; + const tokenId = addrTokenId.split("/")[1].replace("/", ""); + finalMetadata = await fetchNftMetadata(url, addr, tokenId, "https://rpc.ankr.com/avalanche", "opensea"); + } else if (url.startsWith("https://opensea.io/assets/base/")) { + const cleanUrl = url.split("?")[0]; + const addrTokenId = cleanUrl.split("opensea.io/assets/base/")[1]; + const addr = addrTokenId.split("/")[0]; + const tokenId = addrTokenId.split("/")[1].replace("/", ""); + finalMetadata = await fetchNftMetadata(url, addr, tokenId, "https://mainnet.base.org", "opensea"); + } else if (url.startsWith("https://opensea.io/assets/bsc/")) { + const cleanUrl = url.split("?")[0]; + const addrTokenId = cleanUrl.split("opensea.io/assets/bsc/")[1]; + const addr = addrTokenId.split("/")[0]; + const tokenId = addrTokenId.split("/")[1].replace("/", ""); + finalMetadata = await fetchNftMetadata(url, addr, tokenId, "https://rpc.ankr.com/bsc", "opensea"); + } else if (url.startsWith("https://opensea.io/assets/ethereum/")) { + const cleanUrl = url.split("?")[0]; + const addrTokenId = cleanUrl.split("opensea.io/assets/ethereum/")[1]; + const addr = addrTokenId.split("/")[0]; + const tokenId = addrTokenId.split("/")[1].replace("/", ""); + finalMetadata = await fetchNftMetadata(url, addr, tokenId, "https://rpc.ankr.com/eth", "opensea"); + } else if (url.startsWith("https://opensea.io/assets/optimism/")) { + const cleanUrl = url.split("?")[0]; + const addrTokenId = cleanUrl.split("opensea.io/assets/optimism/")[1]; + const addr = addrTokenId.split("/")[0]; + const tokenId = addrTokenId.split("/")[1].replace("/", ""); + finalMetadata = await fetchNftMetadata(url, addr, tokenId, "https://rpc.ankr.com/optimism", "opensea"); + } else if (url.startsWith("https://opensea.io/assets/matic/")) { + const cleanUrl = url.split("?")[0]; + const addrTokenId = cleanUrl.split("opensea.io/assets/matic/")[1]; + const addr = addrTokenId.split("/")[0]; + const tokenId = addrTokenId.split("/")[1].replace("/", ""); + finalMetadata = await fetchNftMetadata(url, addr, tokenId, "https://rpc.ankr.com/polygon", "opensea"); + } else if (url.startsWith("https://opensea.io/assets/zora/")) { + const cleanUrl = url.split("?")[0]; + const addrTokenId = cleanUrl.split("opensea.io/assets/zora/")[1]; + const addr = addrTokenId.split("/")[0]; + const tokenId = addrTokenId.split("/")[1].replace("/", ""); + finalMetadata = await fetchNftMetadata(url, addr, tokenId, "https://rpc.zora.energy", "opensea"); + } + + return finalMetadata; +} + +// https://bafybeihpjhkeuiq3k6nqa3fkgeigeri7iebtrsuyuey5y6vy36n345xmbi.ipfs.dweb.link/2614 +// ipfs://QmeSjSinHpPnmXmspMjwiXyN6zS4E9zccariGR3jxcaWtq/2614 +// https://dweb.link/ipfs/QmeSjSinHpPnmXmspMjwiXyN6zS4E9zccariGR3jxcaWtq/2614 + +async function getSparklesPreview(url) { + let rpcUrl = "https://flare-api.flare.network/ext/C/rpc"; + let urlStart = "https://sparklesnft.com/item/flare/"; + + if (url.startsWith("https://sparklesnft.com/item/songbird/")) { + rpcUrl = "https://songbird-api.flare.network/ext/C/rpc"; + urlStart = "https://sparklesnft.com/item/songbird/"; + } + + const cleanUrl = url.split("?")[0]; + const addrTokenId = cleanUrl.split(urlStart)[1].replace("/", ""); + const addr = addrTokenId.split("_")[0]; + const tokenId = addrTokenId.split("_")[1]; + + finalMetadata = await fetchNftMetadata(url, addr, tokenId, rpcUrl, "sparkles"); // TODO + + return finalMetadata; +} + +function getTwitterPreview(url) { + return { + "url": url, + "title": "Twitter / X.com", + "description": "Elon's land, Elon's rules. Enter at your own risk.", + "image": { + url: "https://www.newswire.lk/wp-content/uploads/2022/12/elon-musk-twitter.jpg" + } + }; +} + +function marketplaceFallback(marketplace) { + if (marketplace === "opensea") { + return { + "name": "Check this NFT on OpenSea", + "description": "OpenSea is the world's first and largest web3 marketplace for NFTs and crypto collectibles. Browse, create, buy, sell, and auction NFTs using OpenSea today.", + "image": "https://static.opensea.io/og-images/Metadata-Image.png" + } + } else if (marketplace === "sparkles") { + return { + "name": "Check this NFT on Sparkles", + "description": "Sparkles NFT Marketplace", + "image": "https://i.postimg.cc/QMCd8ynT/sparkles.png" + } + } +} + +module.exports = { + fetchMetadata +}; diff --git a/utils/rpcUtils.js b/utils/rpcUtils.js index 9323dc50..e891c865 100644 --- a/utils/rpcUtils.js +++ b/utils/rpcUtils.js @@ -14,9 +14,11 @@ export function getRpcs() { "420": "https://optimism-goerli.public.blastapi.io", "592": "https://astar.public.blastapi.io", "1284": "https://rpc.ankr.com/moonbeam", + "8453": "https://mainnet.base.org", "42161": "https://rpc.ankr.com/arbitrum", "43114": "https://rpc.ankr.com/avalanche", - "80001": "https://polygon-mumbai-bor.publicnode.com" + "80001": "https://polygon-mumbai-bor.publicnode.com", + "7777777": "https://rpc.zora.energy" } } @@ -37,9 +39,11 @@ export function getRpcs2() { "420": "https://goerli.optimism.io", "592": "https://astar.public.blastapi.io", "1284": "https://rpc.ankr.com/moonbeam", + "8453": "https://mainnet.base.org", "4002": "https://rpc.ankr.com/fantom_testnet", "42161": "https://rpc.ankr.com/arbitrum", "43114": "https://rpc.ankr.com/avalanche", - "80001": "https://polygon-testnet.public.blastapi.io" + "80001": "https://polygon-testnet.public.blastapi.io", + "7777777": "https://rpc.zora.energy" } } \ No newline at end of file