diff --git a/.env.example b/.env.example index 9e62f7f..ea79d68 100644 --- a/.env.example +++ b/.env.example @@ -1,10 +1,10 @@ # Network information -NEXT_PUBLIC_CHAIN_ID="14801" -NEXT_PUBLIC_CHAIN_NAME="Vana Satori Testnet" +NEXT_PUBLIC_CHAIN_ID="14800" +NEXT_PUBLIC_CHAIN_NAME="Vana Moksha Testnet" NEXT_PUBLIC_CURRENCY="VANA" NEXT_PUBLIC_NETWORK="satori" -NEXT_PUBLIC_RPC_URL="https://rpc.satori.vana.org" -NEXT_PUBLIC_EXPLORER_URL="https://satori.vanascan.io" +NEXT_PUBLIC_RPC_URL="https://rpc.moksha.vana.org" +NEXT_PUBLIC_EXPLORER_URL="https://moksha.vanascan.io" # OAuth client ID for interacting with the Dropbox API. # To create your own, go to: https://www.dropbox.com/developers/documentation/http/documentation @@ -15,11 +15,9 @@ NEXT_PUBLIC_DROPBOX_CALLBACK_URL=http://localhost:3000/auth # To create your own, go to: https://developers.google.com/identity/oauth2/web/guides/get-google-api-clientid NEXT_PUBLIC_GOOGLE_DRIVE_CLIENT_ID=432753364585-8qg4oko082olompd6s0vedgjldd19c5f.apps.googleusercontent.com -# Smart contract addresses for the Satori and Moksha testnets. These are the default values and can be overridden in the UI. -NEXT_PUBLIC_SMART_CONTRACT_ADDRESS_SATORI_TESTNET=0xa0519f5ADc4e82729b21Ef1586d397260D9B9E45 -NEXT_PUBLIC_SMART_CONTRACT_ADDRESS_MOKSHA_TESTNET=0xee4e3Fd107BE4097718B8aACFA3a8d2d9349C9a5 +# DLP Smart contract addresses for the Satori and Moksha testnets. These are the default values and can be overridden in the UI. +NEXT_PUBLIC_SMART_CONTRACT_ADDRESS_SATORI_TESTNET=0x3AdCbED837068CA6505A4c99e552B3b6709113c3 +NEXT_PUBLIC_SMART_CONTRACT_ADDRESS_MOKSHA_TESTNET=0x0D1C88bAf92Db7A8B18c9D078A450d9ff4dEe10E -# Public key used for encrypting the symmetric key used to encrypt a user's file. -# This is the default value and can be overridden in the UI. However, the DLP validator must have the corresponding private key to decrypt it and retreive the symmetric key back to decrypt the user's file. -# To generate a new keypair, follow the instructions in keys.md -NEXT_PUBLIC_FILE_ENCRYPTION_PUBLIC_KEY_BASE64=LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgptUUdOQkdZMUp3RUJEQUM5RkoyaWpxZzdrcHVKb0NpeEZKa29CUDZRUE1VRjlEcUprTjNzTGxxc1RXU2IxSXQrCnVlT20wMHUvY2l4RUM3VkYrdjZDc0ErblRPaTNBYTdodHZwcGxRSWNHall5aUFZZXNOaW5XQmdPVHBFa05yNVEKOTAvejNCQUV0OUlZamVZOFB4TnUwZGFtY2JDOEtWdVNSMkF1M2ZXdkpNWjhXWTVmcXZ4SzA3MDh5bHk3b3JZMgpxdXJRT0RmcWJPNkR0SHpDUkVoQ08yNWlBSGVGdldOd0JtMzZtUE1pTCtCWlFBT1hhVENhU3owZjRPdml6SUdaCnBRSWZVMWhYa1ZEdWw5Mk9WZHkyM1kxUGlVbEZJSnd3eGNSNllYTjE5dU9wSzlFUFNPTHJoZXY5ZHlRdGhqUzMKcXJVYVo4MnVyKysxcFlPMWNTMlNuRFdiejNKRkovRVMwOXppandSeWM1SzFRSnFEcXhaejZMam5BQ2FJZUhQYQpkR3JJYW5kM1N5akZWUEs2SGVzUDVVcWFrYk5DZVBCOTc2U1R3dkUveVk1ajVjWnJ0bjdpRUEwK3BMQU5zeHB5Cm8xUnNQTmRKUFlXZmpRcUJ1cTJOQVlrUlcvMG13MlpQMXhucVRLUWl2cnUyQ293R0Q3U0NSMmg5bVRuWUdEU0IKS1UvYkZSQmRTSFprMUpFQUVRRUFBYlFXVm05c2IyUWdQSFp2Ykc5a1FIWmhibUV1WTI5dFBva0IwUVFUQVFnQQpPeFloQkhvRllVa1hQa25zRzgvRWYyUnJEdFZOVXdtWkJRSm1OU2NCQWhzREJRc0pDQWNDQWlJQ0JoVUtDUWdMCkFnUVdBZ01CQWg0SEFoZUFBQW9KRUdSckR0Vk5Vd21aaFpZTC9BMzNNdkNCTERWMmVtaFJnUEpnTWJZcFd2NjUKcklXbmk5UUJONlNzRjBpWFQyTzlpbHNCaHBGcFBWTkpWdUNJZFZJTDZWQUpnU1NIQnNrVmlRWFg1UGo1Z2NrQQpzZE9MM3dlTWE1K1RuM0Urb2ZpTm1OeDkvU0hWaStLdDJkeEppbE9mc1k4S3FYdjIxdlkwN3EyUi9CRnEzMXh2ClFlY05pSmxJaVAvQ0RSUHNIVDlUNFdSTmYzOWVIRlQ3Y3g2SWlRcTVwaDYxVnpDWEtoWW1OaWtHOFJ1T3RsbGQKRFNDaldNQTVKTVpvbCtORFdhSXQ0Ym9GRVIrRk1PV1NBS1FzMmtqUkVhbDlWL0RLcU52bit1RzhuNmNrVnYzLwpmcFFsMHVNZVhNYk9MdXNqdzQvMHA1TGpLdWhiT3JOU1UxM3BXNXRqeDZ0b3MxRFVIbkNIM3BHMk8xby94dWdDCkZtbnd3RVlDMlgzU2FYbHVNN1ljQ0k2SmMrdjExVytCM2dCc1hSRmpNVi92RSsxZkdQS25xUVJ2Sm1ZVk5JSy8KR0EwcFV0TklTTGJZM2xodG9Qbld4V0wraVFNcDlodU4rSXpkZHM3UitmSWRENEhjOEpVd0lzeTdmZ0tOZHdqMApla0pVY2k0SVg0TXQzWnVJUVFlUlVJSHBRc1d1UVlSbzJVQkhXTGtCalFSbU5TY0JBUXdBMkg2cWRnVnpIeFBZClFGUEpOaDVsWm04b3dQUjFHYXFVM1BJODA1SzVDd2Q5RFpFc1BCaTBNUXNJWmFMbmIzME1YN3NKRG8yWVV3OGYKZURNYlFqd3g3VUlFSnlVbloxWXYwQkF3K3dXKzRheTRpS0ZUTklpMUNDellYQjV2UUNJRDRiNTdYbE9PMFhCYQpCRXkxU3hVWGJiSHl0STU2MVk4bVNhdWtIMHdKdWJPSVoyK2Z4WHNzVGhDMGlIT2x0T2dPenlqUG8xQURRWXRsCldyYUhZS0M5bGl4SlhoWXNVY1Y5ZnFQUGh6WW0rWm90RmJ5cDZxNHo3cTdRZlEyODF6YjFpN3RPSWtKTnRzdmEKTENVNDNxd1JwbldFZFBlbkRnZVZ0SGxjaGtpMmhvVldqMXZvL2NNcjRsdmY5S2prVzQ5TVhJeXE3RHRMNUNrUgo3V2lpSXp6OTJ1b0s5ak8vM2FQbXpMdFp5eGhvODZJN0VaWmVCY0pRcDMzNFhLcUsxRmNXRnlIUFE0eWl2L1AwCjM1Sm9sUGM3elhhOGIreE5FeEwyRGoyNmdXR0VkOTc5cHpxV2tYZjNxMjcvWXFJQTJtVlluWDNKUjFXNG8wbDkKaFNWWEJWdnFJUjU5TXNTTUFNeURHeFZ5NmkwNXNOemN6N0VZYTBDZDVwUUNwOGFDUStpL0FCRUJBQUdKQWJZRQpHQUVJQUNBV0lRUjZCV0ZKRno1SjdCdlB4SDlrYXc3VlRWTUptUVVDWmpVbkFRSWJEQUFLQ1JCa2F3N1ZUVk1KCm1jbWJDLzBmaGU0K3hJT2xxczg2bjZ5cUZXRTZYMmNsd0JwZkdiK2x6TmlSMlBEekU2QnFueHBCWGppUzVaak0KRHQzcll3ZUEwc0xvajgxQXk3NWFQa09BQzkyTkNIdklOdmFsTWVGZi9XMko5aEFvYlVUM0Z6a3RRWFR5TUlzVAp5K012MHFoZ0hnUW5qaURTYzhwbTc0OC82SmpUUm5ybjNZWmNkTStrUndzNUhpbjRXVTk0MFNGa0FVUDIwVnBkClpSalZJd1lqWUViSC9aRm5MRGdDVDJzaktaV3o2R1VmNWRYSjdDWk1uRW5QdXlUZTc2NTRiNXdoc2JSdEZLUEgKRW9vaUNSbk1wZjhTcjVxWHJkVkVEYTMyOXdSaHZUdytWVmNJMW5VaEZyb0psSFBlR0xIK25DaVIyaVpTbVhQOAprZklZYmw0UmtGL3NhWGdjTHJUUWVJYnBZcXZubVBXWWNmRHBSK01PUWcwcWhJbWloR0MrTy9ia1NTSHcwVXRXCm45cVJHSHJaZEtyOFU4eEd1KzBCY3VxLzROSDdTb3ZzV2NjeUxQOERob1JDMDRROTlXaXVGeHhrTzdXMGZTUFcKVys3Ukx4N0E5V3ZXOGJiWFVzTVIzejRZTEFvWHpmWExiSGhkUWZnZTd3dTlRMWQyT1FSMnpnb2lnTXNxNklVKwpNMVJvVlJBPQo9N2pWYgotLS0tLUVORCBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCg== +NEXT_PUBLIC_SMART_CONTRACT_ADDRESS_DATA_REGISTRY=0xEA882bb75C54DE9A08bC46b46c396727B4BFe9a5 +NEXT_PUBLIC_SMART_CONTRACT_ADDRESS_TEE_POOL=0xF084Ca24B4E29Aa843898e0B12c465fAFD089965 \ No newline at end of file diff --git a/app/claim/upload/page.tsx b/app/claim/upload/page.tsx deleted file mode 100644 index cc4b2ab..0000000 --- a/app/claim/upload/page.tsx +++ /dev/null @@ -1,308 +0,0 @@ -"use client"; - -import { - FileMetadata, - getShareLink, - signMessage, - uploadFile, - useConnectWallet, - useNetworkStore, - useStorageStore, - useWalletStore, -} from "@/app/core"; -import { clientSideEncrypt } from "@/app/utils/crypto"; -import { Carousel } from "@mantine/carousel"; -import { - Box, - Container, - Dialog, - Grid, - Image, - Notification, - Paper, - Stack, - Text, - Title, -} from "@mantine/core"; -import { useDisclosure } from "@mantine/hooks"; -import { notifications } from "@mantine/notifications"; -import Autoplay from "embla-carousel-autoplay"; -import { ethers } from "ethers"; -import * as openpgp from "openpgp"; -import { useEffect, useRef, useState } from "react"; -import DataLiquidityPool from "./../../contracts/DataLiquidityPool.json"; -import { ConnectStep } from "./components/connect"; -import { Success } from "./components/success"; -import { UploadState } from "./components/upload"; -import { UploadedFileState } from "./components/uploaded"; -import { UploadingState } from "./components/uploading"; -import { Disclaimer } from "../components/disclaimer"; - -const FIXED_MESSAGE = "Please sign to retrieve your encryption key"; - -export default function Page() { - const [shareUrl, setShareUrl] = useState(null); - const storageProvider = useStorageStore((state) => state.provider); - const contractAddress = useNetworkStore((state) => state.contract); - const dropboxToken = useStorageStore((state) => state.token); - const publicKeyBase64 = useNetworkStore((state) => state.publicKeyBase64); - const isDropboxConnected = !!dropboxToken; - - const [opened, { close }] = useDisclosure(false); - - const [uploadState, setUploadState] = useState< - "initial" | "loading" | "done" - >("initial"); - const [fileId, setFileId] = useState(null); - - const [uploadedFileMetadata, setUploadedFileMetadata] = - useState(null); - - const walletAddress = useWalletStore((state) => state.walletAddress); - const { connect } = useConnectWallet(); - - const [file, setFile] = useState(null); - const [encryptedFile, setEncryptedFile] = useState(null); - - const handleError = () => { - notifications.show({ - color: "red", - title: "Error", - message: - "There was an error trying to encode your file. Please try again.", - }); - }; - - const handleSetFile = async (file: File | null) => { - try { - if (!walletAddress) { - await connect(); - } - } catch (error) { - setUploadState("initial"); - handleError(); - } - - setFile(file); - }; - - const handleFileUpload = async (file: File) => { - if (!walletAddress) { - setUploadState("initial"); - handleError(); - console.error("Wallet address not found"); - return; - } - - try { - setUploadState("loading"); - // Sign a fixed message with the user's wallet to create a deterministic signature - const signature = await signMessage(walletAddress, FIXED_MESSAGE); - console.log("Signature:", signature); - - // Encrypt the file using the signature as the symmetric key - const encryptedData = await clientSideEncrypt(file, signature); - const encryptedFile = new Blob([encryptedData], { - type: "application/octet-stream", - }); - - if (!dropboxToken || !storageProvider) { - throw new Error("Token not found"); - } - - const uploadedFileMetadata = await uploadFile( - encryptedFile, - file.name, - dropboxToken, - storageProvider - ); - - // Get shareUrl to file in storage - const shareUrl = await getShareLink( - dropboxToken, - uploadedFileMetadata.id, - storageProvider - ); - - console.log("Share url:", shareUrl); - - setShareUrl(shareUrl); - - setUploadedFileMetadata(uploadedFileMetadata); - - setEncryptedFile(encryptedFile); - - // Encrypt the signature (symmetric key) using the DLP public key - if (!publicKeyBase64) { - setUploadState("initial"); - console.error("Public key not found in config"); - throw new Error("Public key not found in config"); - } - - const publicKey = await openpgp.readKey({ - armoredKey: atob(publicKeyBase64), - }); - const encryptedSignature = await openpgp.encrypt({ - message: await openpgp.createMessage({ text: signature }), - encryptionKeys: publicKey, - format: "armored", - }); - - setUploadState("done"); - - const provider = new ethers.BrowserProvider(window.ethereum); - const signer = await provider.getSigner(); - - const contractABI = [...DataLiquidityPool.abi]; - const contract = new ethers.Contract( - contractAddress as string, - contractABI, - signer - ); - - // Get base64 encoded signature - const encryptedKey = btoa(encryptedSignature as string); - const tx = await contract.addFile(shareUrl, encryptedKey); - const receipt = await tx.wait(); - - console.log("File added, transaction receipt:", receipt.hash); - - // Get file id from receipt transaction log - const log = receipt.logs[0]; - const fileId = BigInt(log.data); - console.log("File ID:", fileId); - setFileId(Number(fileId)); - - setUploadState("done"); - - console.log(`File uploaded with ID: ${fileId}`); - } catch (error) { - console.error("Error encrypting and uploading file:", error); - setUploadState("initial"); - handleError(); - } - }; - - // const handleOpenDropbox = async () => { - // const folderLink = `https://www.dropbox.com/home/${config.dropboxFolderName}`; - // window.open(folderLink, "_blank"); - // }; - - const handleDownload = async () => { - if (!shareUrl) return; - - window.open(shareUrl, "_blank"); - }; - - useEffect(() => { - if (!file) return; - - handleFileUpload(file); - }, [file]); - - return ( - - - - - - - Instructions - - - - - - 1. Navigate to your account and open settings. - - - 2. Open the Data Controls tab and click on "Export". - - - 3. You will receive an email to download your data. - - - 4. Please upload this data file on the right. - - - - - - - - {uploadState === "done" ? "Congratulations" : "Upload data"} - - - {uploadState === "initial" && !isDropboxConnected && ( - - )} - - {uploadState === "initial" && isDropboxConnected && ( - - )} - - {uploadState === "loading" && file && ( - - )} - - {uploadState === "done" && encryptedFile && uploadedFileMetadata && ( - - )} - - - - There was an error trying to encode your file. Please make - sure you have a wallet connected and try again. - - - - {uploadState === "done" && fileId && ( - - )} - - - - - - ); -} - -const InstructionsGallery = () => { - const autoplay = useRef(Autoplay({ delay: 2000 })); - - const slides = new Array(10).fill(null).map((_, idx) => { - const url = `/images/claim/instructions_${idx + 1}.png`; - return ( - - - - ); - }); - - return ( - - - {slides} - - - ); -}; diff --git a/app/components/layout/layout.tsx b/app/components/layout/layout.tsx index 06a3bfd..c83d5cd 100644 --- a/app/components/layout/layout.tsx +++ b/app/components/layout/layout.tsx @@ -22,7 +22,6 @@ import { useDisclosure } from "@mantine/hooks"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { useEffect } from "react"; -import { SettingsButton } from "./settings-button"; const links = [ { title: "Claim", href: "/claim" }, @@ -188,7 +187,6 @@ export const Layout: React.FC<{ children: React.ReactNode }> = ({ Connect )} - diff --git a/app/components/layout/settings-button.tsx b/app/components/layout/settings-button.tsx deleted file mode 100644 index 67fcabe..0000000 --- a/app/components/layout/settings-button.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { useNetworkStore } from "@/app/core"; -import { Icon } from "@iconify/react"; -import { ActionIcon, Button, Drawer, Group, Textarea, TextInput } from "@mantine/core"; -import { useForm } from "@mantine/form"; -import { useDisclosure } from "@mantine/hooks"; -import { useEffect } from "react"; - -export const SettingsButton = () => { - const [opened, { open, close }] = useDisclosure(false); - const contract = useNetworkStore((state) => state.contract); - const publicKeyBase64 = useNetworkStore((state) => state.publicKeyBase64); - const setPublicKeyBase64 = useNetworkStore((state) => state.setPublicKeyBase64); - const setContract = useNetworkStore((state) => state.setContract); - - const form = useForm({ - mode: "uncontrolled", - initialValues: { - contract, - publicKey: atob(publicKeyBase64), - }, - }); - - useEffect(() => { - form.setValues({ contract, publicKey: atob(publicKeyBase64) }); - }, [contract, publicKeyBase64]); - - const handleSubmit = (values: { contract: string, publicKey: string }) => { - setContract(values.contract); - setPublicKeyBase64(btoa(values.publicKey)); - - close(); - }; - - return ( - <> - -
- -