From c04cf0b5ddcd3901f07dab3d90b79629003b7182 Mon Sep 17 00:00:00 2001 From: MathisZerbib Date: Sat, 9 Dec 2023 00:02:14 +0100 Subject: [PATCH 1/3] Added right config for AI fraud detector --- AI/.gitignore | 65 +------------ AI/ProcFile | 1 + AI/index.js | 87 ------------------ AI/{src/endpoint.py => main.py} | 16 ++-- AI/package.json | 16 ---- AI/requirements.txt | 13 ++- AI/similarity.py | 50 ++-------- AI/src/__pycache__/similarity.cpython-310.pyc | Bin 2477 -> 0 bytes AI/src/similarity.py | 79 ---------------- 9 files changed, 28 insertions(+), 299 deletions(-) create mode 100644 AI/ProcFile delete mode 100644 AI/index.js rename AI/{src/endpoint.py => main.py} (84%) delete mode 100644 AI/package.json mode change 100755 => 100644 AI/similarity.py delete mode 100644 AI/src/__pycache__/similarity.cpython-310.pyc delete mode 100644 AI/src/similarity.py diff --git a/AI/.gitignore b/AI/.gitignore index 805a81d..f3d94a7 100644 --- a/AI/.gitignore +++ b/AI/.gitignore @@ -1,64 +1 @@ -# Python -__pycache__/ -*.pyc -*.pyo -*.pyd - -# Virtual Environment -myenv/ -venv/ -env/ -env.bak/ -venv.bak/ -*.pyc -*.pyo -*.pyd -__pycache__/ - -# IDE -.idea/ - -# Jupyter Notebooks -.ipynb_checkpoints/ - -# Data and Models -data/ -models/ - -# Compiled Python files -*.pyc -*.pyo -*.pyd - -# Logs and Databases -*.log -*.sqlite3 -*.db - -# Other -.DS_Store -*.class -*.o -*.ko -*.pyc -*.pyo -*.pyd -*.exe -*.dll -*.obj -*.so -*.dylib -*.bak -*.tmp -*.swp -*~ - -# Environment variables file -.env - -# Node -node_modules/ -package-lock.json - -# IMAGES FOR AI FRAUD DETECTION -content/ +/myenv \ No newline at end of file diff --git a/AI/ProcFile b/AI/ProcFile new file mode 100644 index 0000000..dc46f1b --- /dev/null +++ b/AI/ProcFile @@ -0,0 +1 @@ +web: gunicorn main:app \ No newline at end of file diff --git a/AI/index.js b/AI/index.js deleted file mode 100644 index 27b8569..0000000 --- a/AI/index.js +++ /dev/null @@ -1,87 +0,0 @@ -const express = require("express"); -const { spawn } = require("child_process"); -const app = express(); -const bodyParser = require("body-parser"); -const axios = require("axios"); -const fs = require("fs").promises; -const sharp = require("sharp"); - -app.use(bodyParser.json()); - -// Function to run the Python script and return a promise -const runPythonScript = (pythonScriptPath) => { - return new Promise((resolve, reject) => { - const pythonProcess = spawn("python", [pythonScriptPath]); - let data = ""; - pythonProcess.stdout.on("data", (chunk) => { - data += chunk.toString(); - }); - pythonProcess.on("close", (code) => { - console.log(`Python script exited with code ${code}`); - resolve(data); - // console.log("Data: ", data); - }); - pythonProcess.on("error", (err) => { - reject(err); - }); - }); -}; - -// Function to download and convert an image from IPFS to JPG -async function downloadAndConvertImageFromIPFS(cid, outputPath) { - const ipfsGatewayUrl = `https://ipfs.io/ipfs/${cid}`; - console.log(`Downloading and converting image from IPFS: ${ipfsGatewayUrl}`); - try { - const response = await axios.get(ipfsGatewayUrl, { - responseType: "arraybuffer", - }); - - // Ensure the directory exists - await fs.mkdir("content", { recursive: true }); - - // Use sharp to convert and save the image as JPG - await sharp(response.data).jpeg().toFile(outputPath); - - console.log( - `Image downloaded and converted successfully to: ${outputPath}` - ); - } catch (error) { - console.error("Error downloading/convert image from IPFS:", error.message); - } -} - -// Endpoint to trigger the Python script -app.post("/run-similarity", async (req, res) => { - const body = req.body; - const pythonScriptPath = "similarity.py"; - - // That get the URI IPFS from graphQL enpoint - - // Save them locally - // Loop through the request body properties dynamically - for (const key in body) { - if (Object.hasOwnProperty.call(body, key)) { - const cid = body[key]; - - // Download and convert images using unique paths dynamically - const imagePath = `./content/${key}.jpg`; - await downloadAndConvertImageFromIPFS(cid, imagePath); - } - } - try { - // Call the function to run the Python script - const data = await runPythonScript(pythonScriptPath); - - // Send the data back to the client - res.send(data); - } catch (error) { - console.error("Error running Python script:", error); - res.status(500).send("Internal Server Error"); - } -}); - -// Start the Express server -const port = 3000; -app.listen(port, () => { - console.log(`Server is running on http://localhost:${port}`); -}); diff --git a/AI/src/endpoint.py b/AI/main.py similarity index 84% rename from AI/src/endpoint.py rename to AI/main.py index 25c2eca..bd3f8bb 100644 --- a/AI/src/endpoint.py +++ b/AI/main.py @@ -1,6 +1,7 @@ +from flask import Flask, request, jsonify +import os import ssl ssl._create_default_https_context = ssl._create_unverified_context -from flask import Flask, request, jsonify import os import subprocess import requests @@ -24,6 +25,10 @@ def download_and_convert_image_from_ipfs(cid, output_path): print(f"Error downloading/convert image from IPFS: {e}") return None +@app.route('/') +def index(): + return jsonify({"AI Antifraud": "Welcome to our AI antifraud 🚅"}) + @app.route('/run-similarity', methods=['POST']) def run_similarity(): @@ -43,8 +48,10 @@ def run_similarity(): if images[i] is None: continue # Skip similarity calculation if image doesn't exist result = get_similarity_score(firstImage, secondImage) + secondImage = secondImage.replace("./content/", "") + secondImage = secondImage.replace("piece", "/piece") arrayResults.append({ - 'path': secondImage, + 'image': "https://ipfs.io/ipfs/"+secondImage, 'similarity_score': float(result[0]) }) arrayResults.sort(key=lambda x: x['similarity_score'], reverse=True) @@ -61,8 +68,5 @@ def run_similarity(): if os.path.exists(path): os.remove(path) - - if __name__ == '__main__': - port = 3000 - app.run(host='0.0.0.0', port=port) + app.run(debug=True, port=os.getenv("PORT", default=5000)) \ No newline at end of file diff --git a/AI/package.json b/AI/package.json deleted file mode 100644 index 87c0680..0000000 --- a/AI/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "ai", - "version": "1.0.0", - "description": "python -m venv myenv", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "axios": "^1.6.2", - "express": "^4.18.2", - "sharp": "^0.33.0" - } -} diff --git a/AI/requirements.txt b/AI/requirements.txt index d64d6a8..a50fea0 100644 --- a/AI/requirements.txt +++ b/AI/requirements.txt @@ -1,7 +1,12 @@ -numpy +click +flask +gunicorn +itsdangerous +jinja2 +markupSafe +werkzeug pillow +requests tensorflow -matplotlib scikit-learn -flask -jsonify \ No newline at end of file +matplotlib \ No newline at end of file diff --git a/AI/similarity.py b/AI/similarity.py old mode 100755 new mode 100644 index 4bfbb0a..f7bebf7 --- a/AI/similarity.py +++ b/AI/similarity.py @@ -30,6 +30,11 @@ def load_image(image_path): """ input_image = Image.open(image_path) + + # Convert image to RGB if it has an alpha channel + if input_image.mode == 'RGBA': + input_image = input_image.convert('RGB') + resized_image = input_image.resize((224, 224)) return resized_image @@ -56,7 +61,6 @@ def get_similarity_score(first_image : str, second_image : str): return embedding of the image """ - first_image = load_image(first_image) second_image = load_image(second_image) @@ -64,51 +68,11 @@ def get_similarity_score(first_image : str, second_image : str): second_image_vector = get_image_embeddings(second_image) similarity_score = cosine_similarity(first_image_vector, second_image_vector).reshape(1,) - + print(f"Similarity score: {similarity_score}") return similarity_score def show_image(image_path): image = mpimg.imread(image_path) imgplot = plt.imshow(image) plt.savefig('temp.png') # Save the figure to a file instead of showing - plt.close() - -# define the path of the images -image1 = './content/1.jpg' -image2 = './content/2.jpg' - -# use the show_image function to plot the images -show_image(image1), show_image(image2) - -similarity_score = get_similarity_score(image1, image2) -print(similarity_score) - -# # define the path of the images -super = './content/super.jpg' - -show_image(image1), show_image(super) - -similarity_score = get_similarity_score(image1, super) - -print(similarity_score) - -# Delete the temporary image file -os.remove('temp.png') - -# Workflow => - - -# TODO make a route in express to store the source image and the nft that have been already minted (Graqhql) - -# similarity page should be done -# on this page we need to show the fractionnal nft and in subsection we need to list all the similar nft -# on a page similare nft should be listed - - - - - -# 1. Load an image -# 2. Compare it to a list of image -# 4.else return the one best matching (close to 0.8 => 0.999) - + plt.close() \ No newline at end of file diff --git a/AI/src/__pycache__/similarity.cpython-310.pyc b/AI/src/__pycache__/similarity.cpython-310.pyc deleted file mode 100644 index d475157239543a55e766c82c2a5ac40b89295ca0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2477 zcmb_d&1)Pt6d%pkj%U|jYbSR45r!TLTbkV_g-}WfNg5JTN(f2YgP<(qk#;P5W;B(w zcD$@l&NY8QDcGmd|Du1#K%vl+Z@m?IX`eLX-6iSCsfKxalAgZa`@Ns|@^WZFIld$5 z&r6o|hi)tu9~yVzm%oA_7D1VX>l$Gj+IHsTE_RXbb22aYv2S#gwQ!5JP6Ohep{8dk z4{^KEJ7BqNbT3=USMjRR{cJ5?$Lq+VtE5E&vP44Ce&ymW?e1+nu)g>3CJE@~@X8N& zNrx=IwD483Lj93VR>|5+7jKbux=p%td*qT0vI#xc$Q5!G?A{^hxz*b`hg(=rdZ_Xq z=W$B4!nA^&dugg$-#vPC^EN2!374#(L&XmMXGztu^P(VxTFb!DHlag*Z-IB%a1`Q>l96` zGjxomXwN2S-xjM=bm|bh?mKmf1DZXx;a2YCw=inTjmwnT?5Bb!RLV&0(#YI4Dg{4a zgp&Tu=0^04N;aW$qxsNVZ7!%9iy{(cbyDwdmag1qkM7^A9FRTR_}hq{Cv0$4>14V(@?` zs4zhS>aO;y>w+1DQ@xen8Cn}SJdyfZFB!f9f`sGm-W;`bKqFXwiI>ExF&J2EkU}B)~0VvAaL&`pNG#m&b_AC1sDfiTyq8R|3$zM$jE)#$o z&D_RyP2gFfc=RcWVj<$AC@w%F=4XoWBF-Yhz%>%|Xv9UNy`Mz}-~Yo=8Ys|whY|vr zBO^XCcuUy|&?2DlFmWlgOUbgXLxHB!I_P}@-Jwxb~Tr_KoggJ>YQ$|d&H z{n7f#J^{X+y1)z0&zh@x-eeJUGZ%mI<`9Oz6BC>hP%5RHL2)5s8M4T}Zt zxXdwTcX%BY7oae)3XR#h#>1rhe8$?5Ot_$*M?e-j@k~sFb~bK7`fDPtyix$z!C+e( zT+?ISg`f=&AW^x%8;h~K=v~w8)$11v^~{>Tz5-(zfB=SruY*Jcjo!PJ&1K~k zeIo<9ECa5lcKfIGMtW&E(ePem;Ikd5%x=+_6(Q*RySvC>;-YzI4IN%8u; z1Bg}+VZW}$byy#-EsPsbi1&5(cD+MfmKjT8O<%HaI6!Ek#oKZ}qp>LZIaPusaFm#d zLk6#a#)-HJqVlu&2$&zY4bKft3oj`Vvm)Nf=p0*>Bb6|LG)`FXntok`A&=k-SY@2i lI~uI=LlA)#fZIBN1?@ig><;p67y18$zDCH(Mt7yt{THSxY^(qP diff --git a/AI/src/similarity.py b/AI/src/similarity.py deleted file mode 100644 index d7b5154..0000000 --- a/AI/src/similarity.py +++ /dev/null @@ -1,79 +0,0 @@ -import os -import numpy as np -from PIL import Image -from tensorflow.keras.preprocessing import image - -import matplotlib -matplotlib.use('Agg') # Set the backend to 'Agg' to prevent window opening -import matplotlib.pyplot as plt -import matplotlib.image as mpimg - -from keras.applications.vgg16 import VGG16 -from sklearn.metrics.pairwise import cosine_similarity - -vgg16 = VGG16(weights='imagenet', include_top=False, - pooling='max', input_shape=(224, 224, 3)) - -# print the summary of the model's architecture. -# vgg16.summary() - -for model_layer in vgg16.layers: - model_layer.trainable = False - -def load_image(image_path): - """ - ----------------------------------------------------- - Process the image provided. - - Resize the image - ----------------------------------------------------- - return resized image - """ - - input_image = Image.open(image_path) - - # Convert image to RGB if it has an alpha channel - if input_image.mode == 'RGBA': - input_image = input_image.convert('RGB') - - resized_image = input_image.resize((224, 224)) - - return resized_image - -def get_image_embeddings(object_image : image): - - """ - ----------------------------------------------------- - convert image into 3d array and add additional dimension for model input - ----------------------------------------------------- - return embeddings of the given image - """ - - image_array = np.expand_dims(image.img_to_array(object_image), axis = 0) - image_embedding = vgg16.predict(image_array) - - return image_embedding - -def get_similarity_score(first_image : str, second_image : str): - """ - ----------------------------------------------------- - Takes image array and computes its embedding using VGG16 model. - ----------------------------------------------------- - return embedding of the image - - """ - first_image = load_image(first_image) - second_image = load_image(second_image) - - first_image_vector = get_image_embeddings(first_image) - second_image_vector = get_image_embeddings(second_image) - - similarity_score = cosine_similarity(first_image_vector, second_image_vector).reshape(1,) - print(f"Similarity score: {similarity_score}") - return similarity_score - -def show_image(image_path): - image = mpimg.imread(image_path) - imgplot = plt.imshow(image) - plt.savefig('temp.png') # Save the figure to a file instead of showing - plt.close() - From 58ba17c3ce3aa8c9615632f77c4ccb2134e7adc2 Mon Sep 17 00:00:00 2001 From: MathisZerbib Date: Sat, 9 Dec 2023 00:03:35 +0100 Subject: [PATCH 2/3] gitignore modified --- AI/.gitignore | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/AI/.gitignore b/AI/.gitignore index f3d94a7..fdf467d 100644 --- a/AI/.gitignore +++ b/AI/.gitignore @@ -1 +1,65 @@ -/myenv \ No newline at end of file +# Python +__pycache__/ +*.pyc +*.pyo +*.pyd + +# Virtual Environment +myenv/ +venv/ +env/ +env.bak/ +venv.bak/ +*.pyc +*.pyo +*.pyd +__pycache__/ + +# IDE +.idea/ + +# Jupyter Notebooks +.ipynb_checkpoints/ + +# Data and Models +data/ +models/ + +# Compiled Python files +*.pyc +*.pyo +*.pyd + +# Logs and Databases +*.log +*.sqlite3 +*.db + +# Other +.DS_Store +*.class +*.o +*.ko +*.pyc +*.pyo +*.pyd +*.exe +*.dll +*.obj +*.so +*.dylib +*.bak +*.tmp +*.swp +*~ + +# Environment variables file +.env + +# Node +node_modules/ +package-lock.json + +# IMAGES FOR AI FRAUD DETECTION +content/ +myenv/ \ No newline at end of file From ff77a7b2d111bc2aac4543236ee6dc9409eb9bad Mon Sep 17 00:00:00 2001 From: MathisZerbib Date: Sat, 9 Dec 2023 23:24:44 +0100 Subject: [PATCH 3/3] Add poc example of antifraud AI When The service is called with a image that return a 504 then need to be redeployed ... --- src/app/nft/mint/page.tsx | 248 +++++++++++++++++++++--------------- src/app/nft/upload/route.ts | 138 +++++++++++++++++++- 2 files changed, 283 insertions(+), 103 deletions(-) diff --git a/src/app/nft/mint/page.tsx b/src/app/nft/mint/page.tsx index 59b61a8..8478066 100644 --- a/src/app/nft/mint/page.tsx +++ b/src/app/nft/mint/page.tsx @@ -1,111 +1,159 @@ -'use client' +"use client"; import ImageUploader from "@/components/ImageUploader"; import StyledInput from "@/components/InputField"; -import FractionatedNTFFields, {Shard} from "@/components/FractionatedNTFFields"; -import {useState} from "react"; -import {useAccount, useContractRead, useContractWrite, usePrepareContractWrite} from "wagmi"; -import {Modal, ModalBody, ModalContent, ModalHeader} from "@nextui-org/modal"; -import {useDisclosure} from "@nextui-org/use-disclosure"; -import {useMutation} from "@tanstack/react-query"; +import FractionatedNTFFields, { + Shard, +} from "@/components/FractionatedNTFFields"; +import { useState } from "react"; +import { + useAccount, + useContractRead, + useContractWrite, + usePrepareContractWrite, +} from "wagmi"; +import { Modal, ModalBody, ModalContent, ModalHeader } from "@nextui-org/modal"; +import { useDisclosure } from "@nextui-org/use-disclosure"; +import { useMutation } from "@tanstack/react-query"; import NFTMarketplace from "../../../NFTMarketplace.json"; +import { CircularProgress } from "@nextui-org/react"; interface formValues { - name: string; - description: string; - shards: Shard[]; -} -const saveToIpfs = async ({image, name , description}) => { - const res = await fetch('/nft/upload', { - method: 'POST', - body: JSON.stringify({image, name, description}), - }) - return await res.json() + name: string; + description: string; + shards: Shard[]; } +const saveToIpfs = async ({ image, name, description }) => { + const res = await fetch("/nft/upload", { + method: "POST", + body: JSON.stringify({ image, name, description }), + }); + return await res.json(); +}; export default function Page() { - const { address } = useAccount() - const {mutateAsync, isLoading} = useMutation(saveToIpfs) - const {isOpen, onOpen, onOpenChange} = useDisclosure(); - const [modal, setModal] = useState(false); - const { data, isError } = useContractRead({ - address: process.env.NEXT_PUBLIC_CONTRACT, - abi: NFTMarketplace.abi, - functionName: 'getAllNFTs', - }) - console.log(data) - const [selectedImage, setSelectedImage] = useState(null); - const [form, setForm] = useState({name: '', description: '', shards: []}); - const {name, description} = form; - const inValidFrom = !name || !description; - const { data: transactionData, isLoading: loadingTransaction, isSuccess, write } = useContractWrite({ - address: process.env.NEXT_PUBLIC_CONTRACT, - abi: NFTMarketplace.abi, - functionName: 'createNFT' - }) - const onChangeField = (e: any) => { - setForm({...form, [e.target.name]: e.target.value}); - } - const onChangeShards = (shards: Shard[]) => { - setForm({...form, shards}); - } - const mintTokens = async () => { - setModal(true) - const response = await mutateAsync({image: selectedImage, name: form.name, description: form.description}) - write({args: [response.tokenId, response.tokenURIs, response._ids]}) - }; - if (address === undefined) { - return (
-

Welcome please connect wallet

-
) - } + const { address } = useAccount(); + const { mutateAsync, isLoading } = useMutation(saveToIpfs); + const { isOpen, onOpen, onOpenChange } = useDisclosure(); + const [modal, setModal] = useState(false); + const { data, isError } = useContractRead({ + address: process.env.NEXT_PUBLIC_CONTRACT, + abi: NFTMarketplace.abi, + functionName: "getAllNFTs", + }); + console.log(data); + const [selectedImage, setSelectedImage] = useState(null); + const [form, setForm] = useState({ + name: "", + description: "", + shards: [], + }); + const { name, description } = form; + const inValidFrom = !name || !description; + const { + data: transactionData, + isLoading: loadingTransaction, + isSuccess, + write, + } = useContractWrite({ + address: process.env.NEXT_PUBLIC_CONTRACT, + abi: NFTMarketplace.abi, + functionName: "createNFT", + }); + const onChangeField = (e: any) => { + setForm({ ...form, [e.target.name]: e.target.value }); + }; + const onChangeShards = (shards: Shard[]) => { + setForm({ ...form, shards }); + }; + const mintTokens = async () => { + setModal(true); + const response = await mutateAsync({ + image: selectedImage, + name: form.name, + description: form.description, + }); + write({ args: [response.tokenId, response.tokenURIs, response._ids] }); + }; + if (address === undefined) { return ( +
+

Welcome please connect wallet

+
+ ); + } + return ( + <> + + + + Minting NFT + + {isLoading && ( +
+

Storing your NFT

+ +
+ )} + {loadingTransaction && ( +

+ Check your Wallet +

+ )} + {isSuccess && ( + + )} +
+
+
+
+
+ +
+
+ + +
+ {selectedImage && ( <> - - - - Minting NFT - - { - isLoading &&

Storing your NFT

- } - { - loadingTransaction &&

Check your Wallet

- } - { - isSuccess && - } -
-
-
-
-
- -
-
- - -
- { selectedImage && <> -

Fractionalized NFTs

- -
- -
- - } +

+ Fractionalized NFTs +

+ +
+ +
- ) + )} + + ); } diff --git a/src/app/nft/upload/route.ts b/src/app/nft/upload/route.ts index adbe3af..1581753 100644 --- a/src/app/nft/upload/route.ts +++ b/src/app/nft/upload/route.ts @@ -3,6 +3,9 @@ import dotenv from "dotenv"; import { createCanvas, loadImage } from "canvas"; import {NextResponse} from "next/server"; import { v4 as uuidv4 } from 'uuid'; +import {useAccount, useContractRead, useContractWrite, usePrepareContractWrite} from "wagmi"; +import NFTMarketplace from "../../../NFTMarketplace.json"; + dotenv.config(); @@ -78,7 +81,7 @@ async function storePuzzleAsset(originalNFT, name ,description) { const originalImageMetadata = { name, description, - image: new File([originalNFT], "PuzzleNFT.png", { type: "image/png" }), + image: new File([canvas.toBuffer("image/png")], `original.png`, { type: "image/png" }), properties: { pieces: puzzlePiecesMetadata.map((pieceMetadata) => pieceMetadata.url), }, @@ -86,12 +89,32 @@ async function storePuzzleAsset(originalNFT, name ,description) { // Store the metadata and image for the original image on NFT.Storage const originalImage = await client.store(originalImageMetadata); - console.log("Metadata stored on Filecoin and IPFS for original image:"); - console.log(originalImage.url); + console.log("Metadata stored on Filecoin and IPFS for original image:" + originalImage.url); + + + + // HERE CHECK ANTI FRAUD + // try { + // await checkFraud(originalImage) + // } + // catch (e) { + // console.log(e) + // } + + + return puzzlePiecesMetadata.map((metadata, index) => ({ url: metadata.url, id: uuidv4().split('-').map(part => parseInt(part, 16)).join(''), })); + + + + + + + + } catch (error) { // Handle any errors that may occur during the process console.error(error); @@ -101,6 +124,115 @@ async function storePuzzleAsset(originalNFT, name ,description) { +const checkFraud = async (originalImage) => { + const responseIpfs = await getImageUrlFromIpfs(originalImage.url); + await checkAntiFraud(responseIpfs); + }; + + +async function getImageUrlFromIpfs(ipfsUrl: string) { + const ipfsEndpoint = "https://gateway.pinata.cloud"; + ipfsUrl = ipfsUrl.replace('ipfs://', ''); + const fullUrl = `${ipfsEndpoint}/ipfs/${ipfsUrl}`; + + try { + const response = await fetch(fullUrl); + + if (!response.ok) { + throw new Error(`Failed to fetch IPFS image: ${response.status} ${response.statusText}`); + } + + const responseData = await response.text(); + + const data = JSON.parse(responseData); + return data.image; + } catch (error) { + console.error("Error fetching IPFS image:", error); + try { + const response = await fetch("https://ipfs.io/ipfs/" + ipfsUrl); + + if (!response.ok) { + throw new Error(`Failed to fetch IPFS image: ${response.status} ${response.statusText}`); + } + + const responseData = await response.text(); + + const data = JSON.parse(responseData); + return data.image; + } + catch (e) { + console.error("Error fetching IPFS image:", e); + } + + } +} + + +export async function checkAntiFraud(image: string) { + try { + const antifraud_endpoint = process.env.ANTI_FRAUD_URL; + image = image.replace('ipfs://', ''); + console.log('image:', image); + + const response = await fetch(antifraud_endpoint + '/run-similarity', { + method: 'POST', + body: JSON.stringify([ + image, + "bafybeihwetgkyyye2reyev7i7dzf37w3nd52pxwwzzqh56ew6ulktamtya/piece9.png", + "bafybeifrlbawyaaswpwzlk3zx2euvppybnag3d5b3sa6z6nijjm5mrq5dy/piece2.png" + ]), + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (response.ok) { + const data = await response.json(); + console.log("ANTIFRAUD Result:", data); + } else { + console.error("ANTIFRAUD Error:", response.status, response.statusText); + } + } catch (error) { + console.error("ANTIFRAUD Error:", error); + } +} + + +// import NFTMarketplace from "../../../NFTMarketplace.json"; + +// interface UseTriggerGetAllNFTs { +// data: ReturnType['data']; +// isError: ReturnType['isError']; +// triggerGetAllNFTs: () => Promise; // Adjust 'any' to the actual type returned by getAllNFTs +// } + +// // Custom hook to trigger the getAllNFTs function +// export function useTriggerGetAllNFTs(): UseTriggerGetAllNFTs { +// const triggerGetAllNFTs = async () => { +// try { +// // Call the getAllNFTs function +// const result = await useContractRead({ +// address: `0x${process.env.NEXT_PUBLIC_CONTRACT}`, +// abi: NFTMarketplace.abi, +// functionName: "getAllNFTs", +// }); + +// // Handle the result if needed +// console.log("Result of getAllNFTs:", result); +// return result; +// } catch (error) { +// console.error("Error triggering getAllNFTs:", error); +// throw error; +// } +// }; + +// return { data, isError, triggerGetAllNFTs }; +// } + + + + + export async function POST(request: Request) { const {image, name ,description} = await request.json() return storePuzzleAsset(image, name ,description).then((response ) => {