From 401757b98174ef054b90232d33dffc21510cc11c Mon Sep 17 00:00:00 2001 From: zzq0826 <770166635@qq.com> Date: Tue, 14 Jan 2025 11:10:42 +0800 Subject: [PATCH] Add fag page (#1407) --- next.config.mjs | 2 +- public/files/airdrop/scroll-airdrop-faq.md | 133 ++++++++++++++++++ src/app/airdrop-faq/components/Markdown.tsx | 16 +++ .../components/tableOfContents.tsx | 104 ++++++++++++++ src/app/airdrop-faq/detail.tsx | 81 +++++++++++ src/app/airdrop-faq/page.tsx | 35 +++++ 6 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 public/files/airdrop/scroll-airdrop-faq.md create mode 100644 src/app/airdrop-faq/components/Markdown.tsx create mode 100644 src/app/airdrop-faq/components/tableOfContents.tsx create mode 100644 src/app/airdrop-faq/detail.tsx create mode 100644 src/app/airdrop-faq/page.tsx diff --git a/next.config.mjs b/next.config.mjs index 244a7ba20..d4269f5d6 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -55,7 +55,7 @@ const nextConfig = { { source: "/blog/scrollsFreshCoat", destination: "/blog/scrolls-fresh-coat", permanent: true }, { source: "/sticker-vote", destination: "/sticker-winners", permanent: true }, - { source: "/airdrop-faq", destination: "https://scroll-faqs.gitbook.io/faqs", permanent: false}, + // { source: "/airdrop-faq", destination: "https://scroll-faqs.gitbook.io/faqs", permanent: false}, ] }, diff --git a/public/files/airdrop/scroll-airdrop-faq.md b/public/files/airdrop/scroll-airdrop-faq.md new file mode 100644 index 000000000..a9cd0733f --- /dev/null +++ b/public/files/airdrop/scroll-airdrop-faq.md @@ -0,0 +1,133 @@ +# $SCR Airdrop FAQ + +## 1. Why am I geoblocked? + +Scroll may block IP addresses if it is detected that persons participating or attempting to participate in the airdrop may be located in a Sanctioned Jurisdiction, the United States, or any other jurisdiction where airdrop or distribution of tokens are prohibited or restricted under applicable laws and regulations - as those persons are not eligible to participate in the Scroll airdrop. This is to ensure that Scroll complies with applicable laws and regulations. + +For more information, please refer to [Scroll Airdrop Terms & Conditions](https://scroll.io/files/airdrop/terms-and-conditions.pdf) and [Scroll Terms of Services](https://scroll.io/terms-of-service). + +## 2. I earned marks, why did I not get an airdrop? + +In order to qualify for the airdrop you must meet the minimum marks cutoff of 200 as of the snapshot date (October 19, 2024). This cutoff is in place to ensure that users are able to claim a meaningful amount of tokens. If you didn't meet the cutoff this time, don't worry! Your marks will continue to accumulate and you may be eligible for future programs. + +## 3. Is there a deadline to claim the airdrop? + +The deadline to claim the airdrop is January 20, 2025. After the deadline, any unclaimed tokens will be allocated to future airdrops. + +## 4. I didn't get the allocation I was expecting, how do I reach support? + +If you believe that your allocation is incorrect, please go through the following: + +- Check our token and airdrop docs here to find out more about allocations and eligibility +- Head over to our Discord (https://discord.gg/scroll), check our #airdrop-support forum and reach out for help from our Mods. + +## 5. Will there be future airdrops? + +Yes! Scroll has allocated 15% of the total token supply to community-focused airdrops, so there will be more airdrops to come. Make sure to follow us on X (https://x.com/Scroll_ZKP) for updates. + +## 6. When was the snapshot taken? + +The snapshot was taken on October 19, 2024 at 00:00 UTC. + +## 7. How can I verify that I'm on the real [scroll.io](https://scroll.io) domain? + +To verify you're on the real scroll.io domain, check the URL in your browser's address bar. It should start with "https://" and have a secure padlock icon next to it. Make sure the domain is spelled correctly as "claim.scroll.io" without any extra characters or words. + +## 8. How are gas fees handled for the claims process? + +There are two types of claims, and both are made through claim.scroll.io: + +**Onchain Claim:** $SCR allocations made to specific Scroll addresses that meet specific criteria. These claims are virtually immediate and will require gas. Read more about the criteria [here](#20-who-is-eligible-for-the-airdrop-). + +**Offchain contributions:** \$SCR allocated to Github users and specific emails. These allocations are in recognition of offchain contributions such as hackathon winners, zk researchers, etc. Read more about these recipients here. These $SCR are sent in batches by the Scroll Airdrop team and do not occur immediately, but we'll be working as quickly as we can to send them out. Read more about the criteria [here](#20-who-is-eligible-for-the-airdrop-). + +No gas is required to claim the second type of allocation. However, we strongly recommend that all claimants delegate their governance rights as part of the claim flow, which will require a small amount of gas. If your wallet does not already have ETH on the Scroll network, we recommend bridging a few dollars' worth of ETH to the Scroll network on the wallet where you're claiming $SCR so that you can delegate your voting power on-chain. + +## 9. Can I use another wallet to claim my tokens? + +If an address has been allocated \$SCR, and you wish to claim the \$SCR on behalf of the address (e.g. because it is a smart contract that cannot connect with the claim.scroll.io UI, then you can use a different wallet/address and claim the tokens on behalf of another address. This will transfer \$SCR to the address to which the $SCR was originally allocated. To do so: + +1. Visit https://scrollscan.com/token/0xd29687c813d741e2f938f4ac377128810e217b1b +2. Connect with an EOA wallet +3. Visit the contract's Write Functions +4. Call the claim function, passing in the recipient's address You can verify that the transaction occurred successfully by checking the recipient's address on Scrollscan. + +## 10. My claim transaction failed, what should I do? + +Some reasons why transactions could fail would be: + +- Check that you have sufficient ETH for gas fees or a proper gas limit set +- Check on [Scrollscan](https://scrollscan.com/) that no other transaction for the claim has been processed successfully +- Make sure that you are eligible for an on-chain or off-chain claim + +For any other issues, please go to our Discord (https://discord.gg/scroll) for additional support. + +## 11. My claim transaction succeeded but I don't see tokens in my wallet + +Depending on the wallet you're using, you may need to manually add \$SCR to your wallet. Find details about $SCR [here](https://scrollscan.com/token/0xd29687c813d741e2f938f4ac377128810e217b1b). Please consult the process for adding tokens in your wallet documentation. + +## 12. How can I bridge to Scroll to claim my tokens? + +To bridge funds over to Scroll, we highly recommend using the Scroll native bridge (https://scroll.io/bridge). However, you can also use any of our supported third party bridges listed on our ecosystem page (https://scroll.io/ecosystem). + +## 13. Is there a lockup or vesting period for token claims? + +There is no lockup or vesting period for tokens claimed in the airdrop. You will have access to your tokens once the claim process is complete. + +## 14. What can I do with SCR token? + +You'll be able to participate in the future of Scroll through delegating your SCR tokens or participating in governance yourself. If you want to get involved, you can find the right place to do so at gov.scroll.io + +Otherwise, check out our ecosystem page (https://scroll.io/ecosystem) and discover new ways to interact with SCR and our Ecosystem. + +## 15. How can I participate in Scroll Governance? + +Get involved in shaping the future of Scroll by visiting [gov.scroll.io](http://gov.scroll.io/). + +## 16. What is a delegate? + +A delegate is a member of the Scroll community who you can select to participate in governance matters on your behalf. + +## 17. What do value tags mean? + +Value tags are a way for delegates to signal their priorities to help you find the one(s) that align best with your interests. + +## 18. What happens to my tokens when I delegate? + +You still own your tokens. Delegation means that the voting power associated with holding your tokens is assigned to someone who you select and vote on your behalf. You can pick one or multiple delegates if you like. + +## 19. May I change my delegation later? + +Yes, you can change who you delegate to at anytime. You always remain in control of your governing power. + +## 20. Who is eligible for the airdrop? + +To claim SCR tokens, you must meet specific criteria such as participated in Scroll on-chain activities, contributed to Scroll community, or developed projects on the Scroll network. In addition, you are not a Prohibited Person or a U.S. Person. + +Please refer to our Token Distribution and Airdrop blog and the [Scroll Airdrop Terms and Conditions](https://scroll.io/files/airdrop/terms-and-conditions.pdf) for more details on the eligibility criteria. + +## 21. How do I check if I'm eligible for a community reward? + +Within the claim site, click on the "Check Eligibility" button next to the relevant category (Community Contributor or Community Developer). Follow the prompts to verify your information, such as providing your email or GitHub ID. If you meet the criteria, you'll see a confirmation message. + +## 22. What should I do if my address or GitHub ID is not eligible? + +If your address, email or GitHub ID is deemed ineligible, it may mean that you do not meet the necessary criteria for that specific reward. Double-check your information, and if you believe there's an error, Contact our community team on Discord (https://discord.gg/scroll) for further assistance. + +## 23. When will I receive my SCR tokens after claiming? + +There are two types of claims made through claim.scroll.io. + +1. $SCR allocations made to specific addresses that meet specific criteria. These claims are virtually immediate and will require gas; you will execute a claim transaction at the end of the flow on claim.scroll.io. + +2. $SCR allocated to specific emails and github users. These allocations are in recognition of contributions to specific papers or projects and are processed in batches, hence do not occur immediately. We'll be working as quickly as we can to send them out. Batches will be sent every few hours on the first 1-2 days of the airdrop, and then every few days after that until the claim period ends on January 20, 2025. You can track the progress through your wallet + +If you are eligible for multiple types of allocations, the first type will be executed at the end of the claim flow when you execute the claim transaction, and the email/github allocations will be sent later. + +## 24. I minted canvas, why did I not get an airdrop? + +Users below the 200 marks minimum, accounting for their participation in Sessions and in Canvas/badges collectively, are unfortunately not eligible for this airdrop. However if this was your case, your marks are not reset to zero and you can continue accruing them from here on. + +## 25. My wallet was compromised am I able to claim using another wallet address? + +No, you must have control of the private keys of the wallet designated for the airdrop. Please reach out to your wallet service provider for support and next steps. diff --git a/src/app/airdrop-faq/components/Markdown.tsx b/src/app/airdrop-faq/components/Markdown.tsx new file mode 100644 index 000000000..a8d321978 --- /dev/null +++ b/src/app/airdrop-faq/components/Markdown.tsx @@ -0,0 +1,16 @@ +import ReactMarkdown from "react-markdown" +import rehypeKatex from "rehype-katex" +import rehypeRaw from "rehype-raw" +import remarkGfm from "remark-gfm" +import remarkMath from "remark-math" + +export function Markdown({ markdownString }) { + return ( + + ) +} diff --git a/src/app/airdrop-faq/components/tableOfContents.tsx b/src/app/airdrop-faq/components/tableOfContents.tsx new file mode 100644 index 000000000..e9bb28389 --- /dev/null +++ b/src/app/airdrop-faq/components/tableOfContents.tsx @@ -0,0 +1,104 @@ +import { usePathname } from "next/navigation" +import type { FC } from "react" +import { useEffect, useRef, useState } from "react" + +export interface Heading { + depth: string + text: string + slug: string +} + +const TableOfContents: FC = () => { + const pathname = usePathname() + + const [headings, setHeadings] = useState([]) + const tableOfContents = useRef(null) + const [currentID, setCurrentID] = useState("") + const scrolledRef = useRef(false) + + const hash = pathname!.split("#")[1] + const hashRef = useRef(hash) + + useEffect(() => { + if (hash) { + // We want to reset if the hash has changed + if (hashRef.current !== hash) { + hashRef.current = hash + scrolledRef.current = false + } + + // only attempt to scroll if we haven't yet (this could have just reset above if hash changed) + if (!scrolledRef.current) { + const id = hash.replace("#", "") + const element = document.getElementById(id) + if (element) { + element.scrollIntoView() + scrolledRef.current = true + } + } + } + }, [tableOfContents.current]) + + useEffect(() => { + if (!tableOfContents.current) return + const setCurrent: IntersectionObserverCallback = entries => { + for (const entry of entries) { + if (entry.isIntersecting) { + setCurrentID(entry.target.id) + break + } + } + } + + const observerOptions: IntersectionObserverInit = { + // Negative top margin accounts for `scroll-margin`. + // Negative bottom margin means heading needs to be towards top of viewport to trigger intersection. + rootMargin: "0px 0% -66%", + } + + const headingsObserver = new IntersectionObserver(setCurrent, observerOptions) + // Observe all the h2 in the main page content. + document.querySelectorAll("h2").forEach((heading: HTMLHeadElement) => { + const id = (heading.textContent as string) + .toLowerCase() + .replace(/[^a-z0-9]+/g, "-") + .replace(/[^a-z0-9]+/g, "-") + heading.id = id + headingsObserver.observe(heading) + }) + // Stop observing when the component is unmounted. + return () => headingsObserver.disconnect() + }, [tableOfContents.current]) + + useEffect(() => { + if (!tableOfContents.current) return + refreshHeadings() + }, [tableOfContents.current]) + + const refreshHeadings = () => { + const headingList: Heading[] = [] + document.querySelectorAll("h2").forEach((heading: HTMLHeadElement) => { + if (heading.className) return + headingList.push({ + depth: heading.nodeName.charAt(1), + text: heading.textContent as string, + slug: heading.id, + }) + }) + setHeadings(headingList) + } + + return ( + <> + + + ) +} + +export default TableOfContents diff --git a/src/app/airdrop-faq/detail.tsx b/src/app/airdrop-faq/detail.tsx new file mode 100644 index 000000000..92ece90d7 --- /dev/null +++ b/src/app/airdrop-faq/detail.tsx @@ -0,0 +1,81 @@ +"use client" + +import { useEffect, useState } from "react" +import ReactMarkdown from "react-markdown" +import rehypeKatex from "rehype-katex" +import rehypeRaw from "rehype-raw" +import remarkGfm from "remark-gfm" +import remarkMath from "remark-math" + +import { Box } from "@mui/material" +import { styled } from "@mui/system" + +import LoadingPage from "@/components/LoadingPage" + +import TOC from "./components/tableOfContents" + +const AirdropFaqContainer = styled(Box)( + ({ theme }) => ` + max-width: 140rem; + padding: 6rem 4rem 14rem; + overflow: visible; + display: flex; + ${theme.breakpoints.down("md")} { + padding: 4rem 2rem; + display: block; + overflow: hidden; + }; + `, +) + +const AirdropFaqNavbar = styled(Box)(({ theme }) => ({ + position: "sticky", + top: "14rem", + maxWidth: "32vw", + [theme.breakpoints.down("md")]: { + display: "none", + }, +})) + +const AirdropFaqDetail = () => { + const [airdropFaqContent, setAirdropFaqContent] = useState(null) + + const [loading, setLoading] = useState(true) + + useEffect(() => { + const airdropFaqPath = "/files/airdrop/scroll-airdrop-faq.md" + setLoading(true) + fetch(airdropFaqPath) + .then(response => response.text()) + .then(text => { + setLoading(false) + setAirdropFaqContent(text) + }) + }, []) + + return ( + + {loading ? ( + + ) : ( + + + + + + + + + + + )} + + ) +} + +export default AirdropFaqDetail diff --git a/src/app/airdrop-faq/page.tsx b/src/app/airdrop-faq/page.tsx new file mode 100644 index 000000000..9e3eb2736 --- /dev/null +++ b/src/app/airdrop-faq/page.tsx @@ -0,0 +1,35 @@ +import { genMeta } from "@/utils/route" + +import Detail from "./detail" + +export const generateMetadata = genMeta(({ params }) => { + return { + titleSuffix: "$SCR Airdrop FAQ", + relativeURL: "https://scroll.io/airdrop-faq", + description: "$SCR Airdrop FAQ", + ogImg: "https://scroll.io/og_scroll.png", + twitterImg: "https://scroll.io/og_scroll.png", + alternates: {}, + } +}) + +const AirdropFaq = () => { + return ( + <> + + + + + ) +} + +export default AirdropFaq