diff --git a/README.md b/README.md
index 7f97f7f6..ed17ca17 100644
--- a/README.md
+++ b/README.md
@@ -74,17 +74,6 @@ are generated in `gatsby-node.ts`. The pages text content is stored in markdown
---
-## Crowdloan Pages
-
-Both crowdloan pages
-
-- `/parachain/crowdloan`
-- `/altair/crowdloan`
-
-are generated in `gatsby-node.ts`. Most of their content is static because the auctions are closed already. The routes are taken over from the former site to keep urls alive.
-
----
-
## GraphQL Fragments
Queries of component data are defined inside the component file. To be able to spread them into the page query, they are exported as fragments.
diff --git a/data/crowdloan/altair.json b/data/crowdloan/altair.json
deleted file mode 100644
index 1765d407..00000000
--- a/data/crowdloan/altair.json
+++ /dev/null
@@ -1,64 +0,0 @@
-{
- "slug": "/altair",
- "seo": {
- "title": "Altair Wins 9th Slot in Kusama Auctions | Centrifuge"
- },
- "network": "altair",
- "hero_crowdloan": {
- "title": "Altair Wins 9th Slot in Kusama Auctions",
- "amount": "187.84K KSM",
- "contributors": "18,342"
- },
- "stats": [
- {
- "title": "Top referrers",
- "items": [
- {
- "address": "Fc2rXRok…Gu",
- "amount": "641"
- },
- {
- "address": "CxZXGR8q…2v",
- "amount": "570"
- },
- {
- "address": "EoqDfBE7…tF",
- "amount": "367"
- },
- {
- "address": "DVSTJwhk…gu",
- "amount": "354"
- },
- {
- "address": "G4SrBW47…ac",
- "amount": "153"
- }
- ]
- },
- {
- "title": "Top contributors",
- "items": [
- {
- "address": "HNf7Bz3Q…ic",
- "amount": "25,000 KSM"
- },
- {
- "address": "DDTVgKoS…c1",
- "amount": "11,000 KSM"
- },
- {
- "address": "FFis2qYe…yr",
- "amount": "7,000 KSM"
- },
- {
- "address": "J6bvL3mh…ZW",
- "amount": "5,000 KSM"
- },
- {
- "address": "EkTrycMC…Ck",
- "amount": "3,000 KSM"
- }
- ]
- }
- ]
-}
diff --git a/data/crowdloan/parachain.json b/data/crowdloan/parachain.json
deleted file mode 100644
index 48dc3b22..00000000
--- a/data/crowdloan/parachain.json
+++ /dev/null
@@ -1,69 +0,0 @@
-{
- "slug": "/parachain",
- "seo": {
- "title": "Centrifuge Parachain Crowdloan | Centrifuge"
- },
- "network": "centrifuge",
- "hero_crowdloan": {
- "title": "Boom! Centrifuge wins slot in Parachain auctions",
- "body": "5,435,161 DOT raised from 27,101 contributions",
- "amount": "5,435,161 DOT",
- "contributors": "27,101",
- "anchor": {
- "label": "Learn more on parachains.info",
- "href": "https://parachains.info/"
- }
- },
- "stats": [
- {
- "title": "Top referrers",
- "items": [
- {
- "address": "14b8az…nLA9MJ",
- "amount": "4485"
- },
- {
- "address": "12xiw7…5grrgU",
- "amount": "3753"
- },
- {
- "address": "13Mf6q…QLJrm1",
- "amount": "671"
- },
- {
- "address": "16DgBy…BZijXd",
- "amount": "597"
- },
- {
- "address": "1PF1HL…MB5Mt1",
- "amount": "565"
- }
- ]
- },
- {
- "title": "Top contributors",
- "items": [
- {
- "address": "12KjzR…JX3pMF",
- "amount": "1,008,505 DOT"
- },
- {
- "address": "17QnZ6…cheWxx",
- "amount": "549,970 DOT"
- },
- {
- "address": "12KweL…2a991h",
- "amount": "350,000 DOT"
- },
- {
- "address": "162nEB…eao8cG",
- "amount": "171,240 DOT"
- },
- {
- "address": "13gQM3…WgMFrH",
- "amount": "100,007 DOT"
- }
- ]
- }
- ]
-}
diff --git a/functions/esbuild.js b/functions/esbuild.js
index 15d4f085..425ee051 100644
--- a/functions/esbuild.js
+++ b/functions/esbuild.js
@@ -13,8 +13,6 @@ esbuild
'functions/index.ts',
'functions/src/getExample.ts',
'functions/src/getLeverPositions.ts',
- 'functions/src/createProof.ts',
- 'functions/src/getRewardData.ts',
'functions/src/getPoolsData.ts',
'functions/src/getTotalAssetsTokenized.ts',
],
diff --git a/functions/src/createProof.ts b/functions/src/createProof.ts
deleted file mode 100644
index bc1e200f..00000000
--- a/functions/src/createProof.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { Request, Response } from 'express'
-import { createProof as createActualProof, getContributionAmount } from './handleCreateProof'
-const { u8aToHex } = require('@polkadot/util')
-const { decodeAddress } = require('@polkadot/util-crypto')
-const JSONbig = require('json-bigint')({
- useNativeBigInt: true,
- alwaysParseAsBig: true,
-})
-
-export default async function createProof(req: Request, res: Response) {
- if (req.method !== 'POST') {
- return res.status(405).send('Method not allowed. Use POST.')
- }
-
- try {
- const { address, parachain } = JSON.parse(req.body)
-
- const merkleTree =
- parachain === 'centrifuge'
- ? require('../../config/crowdloan/centrifuge-reward-merkle-tree.js').merkleTree
- : require('../../config/crowdloan/altair-reward-merkle-tree.js').merkleTree
-
- const hexAddress = u8aToHex(decodeAddress(address))
-
- const proof = createActualProof(hexAddress, merkleTree)
- const contribution = getContributionAmount(hexAddress, merkleTree)
-
- return res.status(200).send(
- JSONbig.stringify({
- proof,
- signMessage: hexAddress,
- contribution,
- })
- )
- } catch (error) {
- return res.status(500).send(JSON.stringify(error))
- }
-}
diff --git a/functions/src/getRewardData.ts b/functions/src/getRewardData.ts
deleted file mode 100644
index 8b144173..00000000
--- a/functions/src/getRewardData.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { u8aToHex } from '@polkadot/util'
-import { decodeAddress } from '@polkadot/util-crypto'
-import { Request, Response } from 'express'
-import { getContributionAmount } from './handleCreateProof'
-
-export default async function getRewardData(req: Request, res: Response) {
- if (req.method !== 'POST') {
- return res.status(405).send('Method not allowed. Use POST.')
- }
-
- const { address, parachain } = JSON.parse(req.body)
-
- const merkleTree =
- parachain === 'centrifuge'
- ? require('../../config/crowdloan/centrifuge-reward-merkle-tree.js').merkleTree
- : require('../../config/crowdloan/altair-reward-merkle-tree.js').merkleTree
-
- const hexAddress = u8aToHex(decodeAddress(address))
-
- const amount = getContributionAmount(hexAddress, merkleTree)
-
- return res.status(200).send(
- JSON.stringify({
- address,
- contributionAmount: String(amount),
- })
- )
-}
diff --git a/gatsby-node.ts b/gatsby-node.ts
index b5e4e40f..8c0d700e 100644
--- a/gatsby-node.ts
+++ b/gatsby-node.ts
@@ -1,7 +1,7 @@
import type { GatsbyNode } from 'gatsby'
import path from 'path'
-export const createPages: GatsbyNode['createPages'] = async ({ actions: { createPage } }) => {
+export const createPages: GatsbyNode['createPages'] = async ({ actions: { createPage, createRedirect } }) => {
try {
const legalPages = ['/imprint', '/terms', '/security', '/data-privacy-policy']
@@ -15,16 +15,9 @@ export const createPages: GatsbyNode['createPages'] = async ({ actions: { create
})
})
- const crowdloanPages = ['/altair', '/parachain']
-
- crowdloanPages.forEach((route) => {
- createPage({
- path: `${route}/crowdloan`,
- component: path.resolve('./src/templates/crowdloan.tsx'),
- context: {
- slug: route,
- },
- })
+ createRedirect({
+ fromPath: `/parachain/crowdloan`,
+ toPath: `/`,
})
} catch (err) {
console.log('error', err)
diff --git a/src/components/StatsCrowdloan.tsx b/src/components/StatsCrowdloan.tsx
deleted file mode 100644
index effdf221..00000000
--- a/src/components/StatsCrowdloan.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import { Grid, Shelf, Box, Container, Text, Stack } from '@centrifuge/fabric'
-import React from 'react'
-import { graphql } from 'gatsby'
-
-export const query = graphql`
- fragment StatsCrowdloanFragment on CrowdloanJsonStats {
- title
- items {
- address
- amount
- }
- }
-`
-
-export type StatsCrowdloanProps = {
- stats: {
- title: string
- items: {
- address: string
- amount: string
- }[]
- }[]
-}
-
-export function StatsCrowdloan({ stats }: StatsCrowdloanProps) {
- return (
-
-
- {stats.map((entry) => (
-
-
- {entry.title}
-
-
-
- {entry.items.map(({ address, amount }, index) => (
-
-
- {address}
-
-
- {amount}
-
-
- ))}
-
-
- ))}
-
-
- )
-}
diff --git a/src/components/crowdloan-user/User.tsx b/src/components/crowdloan-user/User.tsx
deleted file mode 100644
index a5a702fc..00000000
--- a/src/components/crowdloan-user/User.tsx
+++ /dev/null
@@ -1,130 +0,0 @@
-import {
- formatBalanceAbbreviated,
- useCentrifuge,
- useCentrifugeTransaction,
- useWallet,
- WalletMenu,
-} from '@centrifuge/centrifuge-react'
-import { Button, Container, Shelf, Stack, Text } from '@centrifuge/fabric'
-import { decodeAddress, signatureVerify } from '@polkadot/util-crypto'
-import type { WalletAccount } from '@subwallet/wallet-connect/types'
-import BN from 'bn.js'
-import * as React from 'react'
-import { switchMap } from 'rxjs'
-import { getAccountDetails, useDidClaim, useTotalRewards } from './utils'
-
-export function User() {
- const [isClaiming, setIsClaiming] = React.useState(false)
- const centrifuge = useCentrifuge()
- const {
- substrate: { selectedAccount },
- } = useWallet()
- const didClaim = useDidClaim(selectedAccount?.address)
- const totalRewards = useTotalRewards({ address: selectedAccount?.address, parachain: centrifuge.config.network })
- const currency = centrifuge.config.network === 'altair' ? 'AIR' : 'CFG'
-
- const { execute, isLoading } = useCentrifugeTransaction(
- 'Claiming rewards',
- (cent) =>
- ([proof, signature, address]: [any, string, string], options) => {
- return cent.getApi().pipe(
- switchMap((api) => {
- const verification = signatureVerify(proof.signMessage, signature, decodeAddress(address))
- if (!['sr25519', 'ed25519', 'ecdsa'].includes(verification.crypto)) {
- throw new Error('Verification of signature failed with given account.')
- }
-
- const submittable = api.tx.crowdloanClaim.claimReward(
- address,
- address,
- {
- [verification.crypto]: signature,
- },
- {
- leafHash: proof.proof.leafHash,
- sortedHashes: proof.proof.sortedHashes,
- },
- proof.contribution
- )
-
- return cent.wrapSignAndSend(api, submittable, options)
- })
- )
- }
- )
-
- async function claim(account: WalletAccount | null) {
- if (!account) {
- return
- }
-
- setIsClaiming(true)
-
- await getAccountDetails(account, centrifuge.config.network)
- .then((response) => {
- if (response) {
- execute(response)
- }
- })
- .catch((error) => console.log(error))
- .finally(() => {
- setIsClaiming(false)
- })
- }
-
- return (
-
-
-
-
- {didClaim != null &&
- (didClaim ? (
-
-
- Rewards already claimed
-
-
- ) : (
-
-
- Total rewards:{' '}
- {totalRewards ? (
-
- {formatBalanceAbbreviated(totalRewards, currency)}
-
- ) : (
-
- 0.0
-
- )}
-
- {!!totalRewards && totalRewards?.gt(new BN(0)) && (
-
- )}
-
- ))}
-
-
- Learn how to claim
-
-
-
- )
-}
diff --git a/src/components/crowdloan-user/index.tsx b/src/components/crowdloan-user/index.tsx
deleted file mode 100644
index 764fd15c..00000000
--- a/src/components/crowdloan-user/index.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { UserProvidedConfig } from '@centrifuge/centrifuge-js'
-import { Provider } from '@centrifuge/centrifuge-react'
-import * as React from 'react'
-import { User } from './User'
-
-export type CrowdloanUserProps = {
- network: 'altair' | 'centrifuge'
-}
-
-export default function CrowdloanUser({ network }: CrowdloanUserProps) {
- const centConfig: UserProvidedConfig = React.useMemo(
- () => ({
- network,
- ...(process.env.NODE_ENV === 'development' && {
- centrifugeWsUrl: 'wss://fullnode.development.cntrfg.com',
- altairWsUrl: 'wss://fullnode.development.cntrfg.com',
- }),
- }),
- []
- )
-
- return (
-
-
-
- )
-}
diff --git a/src/components/crowdloan-user/utils.tsx b/src/components/crowdloan-user/utils.tsx
deleted file mode 100644
index 59afca06..00000000
--- a/src/components/crowdloan-user/utils.tsx
+++ /dev/null
@@ -1,101 +0,0 @@
-import { CurrencyBalance } from '@centrifuge/centrifuge-js'
-import { useCentrifugeQuery } from '@centrifuge/centrifuge-react'
-import { cryptoWaitReady } from '@polkadot/util-crypto'
-import type { WalletAccount } from '@subwallet/wallet-connect/types'
-import jsonBigInt from 'json-bigint'
-import { useQuery } from 'react-query'
-import { map, switchMap } from 'rxjs'
-import type { CrowdloanUserProps } from './index'
-
-const JsonBig = jsonBigInt({ useNativeBigInt: true, alwaysParseAsBig: true })
-
-export function useTotalRewards({
- address,
- parachain,
-}: {
- address?: WalletAccount['address']
- parachain: CrowdloanUserProps['network']
-}) {
- const { data } = useQuery(
- ['getRewardData', address, parachain],
- async () => {
- const response = await fetch(`${process.env.GATSBY_FUNCTIONS_URL}/getRewardData`, {
- method: 'POST',
- body: JSON.stringify({
- address,
- parachain,
- }),
- })
-
- const json = await response.json()
- const amount = new CurrencyBalance(json.contributionAmount, 18)
- return amount
- },
- {
- enabled: !!address,
- }
- )
-
- return data
-}
-
-export function useDidClaim(address?: string) {
- const [data] = useCentrifugeQuery(
- ['claimedRewards', address],
- (cent) => {
- return cent.getApi().pipe(
- switchMap((api) => {
- return api.query.crowdloanClaim.processedClaims([address, 1])
- }),
- map((didClaim) => {
- return didClaim.toHuman() ? true : false
- })
- )
- },
- {
- enabled: !!address,
- }
- )
- return data
-}
-
-export async function getAccountDetails(
- account: WalletAccount,
- parachain: CrowdloanUserProps['network']
-): Promise<[any, string, string] | null> {
- if (!account) {
- return null
- }
-
- const proof = await fetch(`${process.env.GATSBY_FUNCTIONS_URL}/createProof`, {
- method: 'POST',
- body: JSON.stringify({ address: account.address, parachain }),
- })
- .then(async (response) => {
- if (!response.ok) {
- throw new Error('Could not create proof')
- }
-
- return await response.text()
- })
- .then((text) => JsonBig.parse(text))
- .catch((error) => console.log(error))
-
- const signature = await cryptoWaitReady()
- .then((_) => account.wallet?.signer?.signRaw)
- .then(async (signRaw) => {
- if (!signRaw) {
- throw new Error('signRaw was not defined')
- }
-
- return await signRaw({
- address: account.address,
- data: proof.signMessage,
- type: 'bytes',
- })
- })
- .then((payload) => payload.signature)
- .catch((error) => console.log(error))
-
- return [proof, signature as string, account.address]
-}
diff --git a/src/components/hero-crowdloan/index.tsx b/src/components/hero-crowdloan/index.tsx
deleted file mode 100644
index 1521415f..00000000
--- a/src/components/hero-crowdloan/index.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import React from 'react'
-import { graphql } from 'gatsby'
-import { Container, Box, Text, AnchorButton } from '@centrifuge/fabric'
-
-export const query = graphql`
- fragment HeroCrowdloanFragment on CrowdloanJsonHero_crowdloan {
- title
- amount
- contributors
- anchor {
- label
- href
- }
- }
-`
-
-export type HeroCrowdloanProps = {
- title: string
- amount: string
- contributors: string
- anchor?: {
- label: string
- href: string
- }
-}
-
-export function HeroCrowdloan({ title, amount, contributors, anchor }: HeroCrowdloanProps) {
- return (
-
-
- Crowdloan
-
-
- {title}
-
-
- {amount} raised from {contributors} contributions
-
- {anchor && (
-
-
- {anchor.label}
-
-
- )}
-
- )
-}
-
-function Em({ children }: { children: React.ReactNode }) {
- return (
-
- {children}
-
- )
-}
diff --git a/src/templates/crowdloan.tsx b/src/templates/crowdloan.tsx
deleted file mode 100644
index b3aab9fd..00000000
--- a/src/templates/crowdloan.tsx
+++ /dev/null
@@ -1,74 +0,0 @@
-import * as React from 'react'
-import { Box, Stack, Text } from '@centrifuge/fabric'
-import type { HeadProps } from 'gatsby'
-import { graphql } from 'gatsby'
-import type { CrowdloanUserProps } from '../components/crowdloan-user'
-import type { HeroCrowdloanProps } from '../components/hero-crowdloan'
-import { HeroCrowdloan } from '../components/hero-crowdloan'
-import { Layout } from '../components/Layout'
-import type { SEOProps } from '../components/Seo'
-import { SEO } from '../components/Seo'
-import type { StatsCrowdloanProps } from '../components/StatsCrowdloan'
-import { StatsCrowdloan } from '../components/StatsCrowdloan'
-
-const CrowdloanUser = React.lazy(() => import('../components/crowdloan-user'))
-
-export const query = graphql`
- query ($slug: String!) {
- crowdloanJson(slug: { eq: $slug }) {
- seo {
- title
- }
-
- network
-
- hero_crowdloan {
- ...HeroCrowdloanFragment
- }
-
- stats {
- ...StatsCrowdloanFragment
- }
- }
- }
-`
-
-type CrowdloanPageProps = {
- data: {
- crowdloanJson: {
- seo: SEOProps
- network: CrowdloanUserProps['network']
- hero_crowdloan: HeroCrowdloanProps
- stats: StatsCrowdloanProps['stats']
- }
- }
-}
-
-export default function CrowdloanPage({ data }: CrowdloanPageProps) {
- const [isRendered, setIsRendered] = React.useState(false)
- const { hero_crowdloan, stats, network } = data.crowdloanJson
-
- React.useEffect(() => setIsRendered(true), [])
-
- return (
-
-
-
- Auction ended — Closed for contribution
-
-
-
-
- {isRendered ? : null}
-
-
-
- )
-}
-
-export const Head = ({ data, location }: CrowdloanPageProps & HeadProps) => {
- const { seo } = data.crowdloanJson
- const { pathname } = location
-
- return
-}