diff --git a/.prettierrc.js b/.prettierrc.cjs similarity index 100% rename from .prettierrc.js rename to .prettierrc.cjs diff --git a/package.json b/package.json index 720258251c..d02732c7c9 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,9 @@ "name": "@metafam/the-game", "version": "0.2.0", "license": "GPL-3.0", + "type": "module", "engines": { - "node": ">=16" + "node": ">=20" }, "private": true, "scripts": { @@ -99,11 +100,11 @@ "@ceramicnetwork/common": "2.31.1", "did-resolver": "4.1.0", "dids": "4.0.4", - "ethers": "5.7.0", - "graphql": "16.8.0", + "graphql": "16.5.0", "multihashes": "4.0.3", "node-gyp": "10.0.1", - "better-sqlite3": "9.0.0" + "better-sqlite3": "9.4.5", + "nan": "2.18.0" }, "browserslist": [ "defaults", diff --git a/packages/backend/package.json b/packages/backend/package.json index 1b6790c2af..3ad23842dd 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -29,10 +29,10 @@ "cors": "2.8.5", "discord.js": "13.6.0", "dotenv": "16.0.0", - "ethers": "5.6.9", + "ethers": "^6.11.1", "express": "^4.18.2", "express-graphql": "0.12.0", - "graphql": "16.7.1", + "graphql": "16.5.0", "graphql-request": "4.0.0", "graphql-tag": "2.12.6", "showdown": "^2.1.0", @@ -49,7 +49,8 @@ "ts-node": "^10.9.1" }, "resolutions": { - "typescript": "4.8.4" + "better-sqlite3": "9.4.5", + "node-gyp": "10.0.1" }, "nodemonConfig": { "exec": "node --inspect=0.0.0.0:4322 --loader ts-node/esm src/index.ts", diff --git a/packages/backend/src/handlers/actions/player/syncBalances.ts b/packages/backend/src/handlers/actions/player/syncBalances.ts index 79bfc5da20..924582066e 100644 --- a/packages/backend/src/handlers/actions/player/syncBalances.ts +++ b/packages/backend/src/handlers/actions/player/syncBalances.ts @@ -1,5 +1,5 @@ import { getCurrentSeasonStart, Maybe } from '@metafam/utils'; -import ethers from 'ethers'; +import { ethers } from 'ethers'; import { Request, Response } from 'express'; import { client } from '../../../lib/hasuraClient.js'; @@ -65,9 +65,7 @@ const setBalances = async ({ uniqueDrops[executionDate] ??= {}; uniqueDrops[executionDate][to] ??= 0; if (tokenAddress === guildTokenAddress) { - uniqueDrops[executionDate][to] += Number( - ethers.utils.formatEther(value), - ); + uniqueDrops[executionDate][to] += Number(ethers.formatEther(value)); } }); }); diff --git a/packages/backend/src/lib/ethereum.ts b/packages/backend/src/lib/ethereum.ts index 53a0187b5e..0f2bb05ac9 100644 --- a/packages/backend/src/lib/ethereum.ts +++ b/packages/backend/src/lib/ethereum.ts @@ -5,13 +5,10 @@ import ERC20_ABI from './abis/ERC20.json' assert { type: 'json' }; const { infuraId } = CONFIG; -export const mainnetProvider = new ethers.providers.InfuraProvider(1, infuraId); -export const polygonProvider = new ethers.providers.InfuraProvider( - 137, - infuraId, -); +export const mainnetProvider = new ethers.InfuraProvider(1, infuraId); +export const polygonProvider = new ethers.InfuraProvider(137, infuraId); export const getERC20Contract = ( contractAddress: string, - provider: ethers.providers.BaseProvider = mainnetProvider, + provider: ethers.Provider = mainnetProvider, ): ethers.Contract => new ethers.Contract(contractAddress, ERC20_ABI, provider); diff --git a/packages/discord-bot/package.json b/packages/discord-bot/package.json index e31ad593b5..51b1c77b4e 100644 --- a/packages/discord-bot/package.json +++ b/packages/discord-bot/package.json @@ -33,7 +33,7 @@ "dotenv": "16.0.0", "ethers": "5.6.9", "express": "4.17.3", - "graphql": "^16.8.0", + "graphql": "16.5.0", "graphql-request": "^6.1.0", "graphql-tag": "2.12.6", "node-fetch": "3.2.1", diff --git a/packages/utils/package.json b/packages/utils/package.json index 2181336b74..268bf316ec 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -19,10 +19,9 @@ "@ceramicnetwork/http-client": "^2.15.0", "@datamodels/identity-accounts-crypto": "^0.2.0", "@datamodels/identity-profile-basic": "^0.2.0", - "@ethersproject/address": "5.6.0", "bignumber.js": "^9.1.0", "cids": "^1.1.9", - "ethers": "5.7.0", + "ethers": "^6.11.1", "imgix-core-js": "2.3.2", "js-base64": "3.7.2", "node-fetch": "3.2.1", @@ -31,5 +30,9 @@ "devDependencies": { "key-did-provider-ed25519": "^2.0.1", "key-did-resolver": "^2.1.3" + }, + "resolutions": { + "better-sqlite3": "9.4.5", + "node-gyp": "10.0.1" } } diff --git a/packages/utils/src/did/index.ts b/packages/utils/src/did/index.ts index 2ecaa8d840..f0880ea3f5 100644 --- a/packages/utils/src/did/index.ts +++ b/packages/utils/src/did/index.ts @@ -1,4 +1,4 @@ -import { providers } from 'ethers'; +import { BrowserProvider, Provider } from 'ethers'; import { Base64 } from 'js-base64'; import { v4 as uuidv4 } from 'uuid'; @@ -18,7 +18,7 @@ type Claim = { }; export async function createToken( - provider: providers.Web3Provider, + provider: BrowserProvider, userAddress: string, ): Promise { const iat = +new Date(); @@ -40,7 +40,7 @@ export async function createToken( export async function verifyToken( token: string, - provider: providers.JsonRpcProvider, + provider: Provider, connectedAddress?: string, ): Promise> { const rawToken = Base64.decode(token); diff --git a/packages/utils/src/ethereumHelper.ts b/packages/utils/src/ethereumHelper.ts index f7def7fcd1..3ff0497b5a 100644 --- a/packages/utils/src/ethereumHelper.ts +++ b/packages/utils/src/ethereumHelper.ts @@ -1,25 +1,11 @@ -import { Contract, providers, utils } from 'ethers'; +import { BrowserProvider, Contract, ethers, Provider } from 'ethers'; export async function getSignature( - provider: providers.Web3Provider, + provider: BrowserProvider, msg: string, - extraParams?: string[] | undefined, ): Promise { - const ethereum = provider.provider; - const signer = provider.getSigner(); - const address = await signer.getAddress(); - if (!ethereum.request) throw new Error('No `request` On Ethereum Provider'); - let params = [msg, address]; - - if (extraParams) { - params = [...params, ...extraParams]; - } - - const signature = await ethereum.request({ - method: 'personal_sign', - params, - }); - return signature; + const signer = await provider.getSigner(); + return signer.signMessage(msg); } const smartWalletABI = [ @@ -33,7 +19,7 @@ enum WalletType { async function getWalletType( address: string, - provider: providers.BaseProvider, + provider: Provider, ): Promise { const code = await new Promise((resolve, reject) => { const seconds = 45; @@ -58,24 +44,24 @@ export async function verifySignature( address: string, message: string, signature: string, - provider: providers.BaseProvider, + provider: Provider, ): Promise { const walletType = await getWalletType(address, provider); if (walletType === WalletType.EOA) { - const recoveredAddress = utils.verifyMessage(message, signature); + const recoveredAddress = ethers.verifyMessage(message, signature); return address === recoveredAddress; } // Smart wallet - const msgBytes = utils.toUtf8Bytes(message); - const hexMsg = utils.hexlify(msgBytes); - const hexArray = utils.arrayify(hexMsg); - const hashMsg = utils.hashMessage(hexArray); + const msgBytes = ethers.toUtf8Bytes(message); + const hexMsg = ethers.hexlify(msgBytes); + const hexArray = ethers.getBytes(hexMsg); + const hashMsg = ethers.hashMessage(hexArray); const contract = new Contract(address, smartWalletABI, provider); try { - return contract.isValidSignature(hashMsg, signature); + return await contract.isValidSignature(hashMsg, signature); } catch (error) { throw new Error(`Unsupported Smart Wallet: ${(error as Error).message}`); } diff --git a/packages/web/components/Guild/GuildForm.tsx b/packages/web/components/Guild/GuildForm.tsx index 8e4548be69..3887654261 100644 --- a/packages/web/components/Guild/GuildForm.tsx +++ b/packages/web/components/Guild/GuildForm.tsx @@ -1,4 +1,3 @@ -import { isAddress } from '@ethersproject/address'; import { Box, CloseButton, @@ -19,6 +18,7 @@ import { SelectOption } from '@metafam/ds/src/MultiSelect'; import FileOpenIcon from 'assets/file-open-icon.svg'; import { Field, FieldDescription } from 'components/Forms/Field'; import { MetaLink } from 'components/Link'; +import { isAddress } from 'ethers'; import { DiscordRole, GuildDaoInput, diff --git a/packages/web/components/Guild/UnverifiedGuildForm.tsx b/packages/web/components/Guild/UnverifiedGuildForm.tsx index 951688583f..364a56bf03 100644 --- a/packages/web/components/Guild/UnverifiedGuildForm.tsx +++ b/packages/web/components/Guild/UnverifiedGuildForm.tsx @@ -1,4 +1,3 @@ -import { isAddress } from '@ethersproject/address'; import { Box, chakra, @@ -16,6 +15,7 @@ import { } from '@metafam/ds'; import FileOpenIcon from 'assets/file-open-icon.svg'; import { Field, FieldDescription } from 'components/Forms/Field'; +import { isAddress } from 'ethers'; import { AddUnverifiedGuildMutation, AddUnverifiedGuildMutationVariables, diff --git a/packages/web/components/Landing/UserGrid.tsx b/packages/web/components/Landing/UserGrid.tsx deleted file mode 100644 index 361715edaa..0000000000 --- a/packages/web/components/Landing/UserGrid.tsx +++ /dev/null @@ -1,162 +0,0 @@ -import { Box, Link, Text } from '@metafam/ds'; -import { PlayerProfilePictureRound } from 'components/Player/PlayerProfilePictureRound'; -import { RoundImage } from 'components/RoundImage'; -import { GuildFragment, Player } from 'graphql/autogen/types'; -import { formatAddress } from 'utils/playerHelpers'; - -// this will work with production DB -const whoWeAreGuilds = [ - 'cr8rdao', - 'metacartelventures', - 'daohaus', - 'metafactory', - 'bloomnetwork', - 'raidguild', - 'Giveth', -]; - -type Elder = { - name: string; - img: string; - link: string; -}; - -export const UserGrid: React.FC<{ - players?: Player[]; - guilds?: GuildFragment[]; - elders?: Elder[]; - link?: string; -}> = ({ players, guilds, elders, link }) => ( - - {players?.length - ? players?.map((player, i) => ( - - - - {player.profile?.name || formatAddress(player.ethereumAddress)} - - - )) - : ''} - - {guilds - ?.filter((guild) => whoWeAreGuilds.includes(guild.guildname)) - ?.map((guild, i) => ( - - - - - {guild.guildname} - - - - ))} - - {elders?.map((elder, i) => ( - - - - - {elder.name} - - - - ))} - - - - - more - - - - - -); diff --git a/packages/web/components/Landing/WhatDo.tsx b/packages/web/components/Landing/WhatDo.tsx deleted file mode 100644 index 4095b0b38b..0000000000 --- a/packages/web/components/Landing/WhatDo.tsx +++ /dev/null @@ -1,210 +0,0 @@ -import { - Box, - Container, - ListItem, - Text, - UnorderedList, - useBreakpointValue, -} from '@metafam/ds'; -import BackgroundImageMobile from 'assets/landing/sections/section-5.sm.webp'; -import BackgroundImageDesktop from 'assets/landing/sections/section-5.webp'; -import { FullPageContainer } from 'components/Container'; -import { useMotionDetector } from 'lib/hooks/useMotionDetector'; -import { useOnScreen } from 'lib/hooks/useOnScreen'; -import React, { useRef } from 'react'; - -import { LandingNextButton } from './LandingNextButton'; -import { LandingPageSectionProps } from './landingSection'; -import { Rain } from './OnboardingGame/Rain'; - -const WhatDo: React.FC = ({ - section, - nextSection, -}) => { - const ref = useRef(null); - const onScreen = useOnScreen(ref); - const root = typeof window !== 'undefined' ? document.body : null; - const noMotion = useMotionDetector(root); - const displayElement = noMotion ? true : !!onScreen; - const responsiveBg = useBreakpointValue({ - base: BackgroundImageMobile, - md: BackgroundImageDesktop, - }); - - return ( - - - - - What are we doing? - - - - - 01Producing content - - - Educational content such as Playbooks & Great Houses as well - as something more fun, like our podcasts, news or recordings of - the below. - - - - - 02Organizing events - - - Regularly bringing awesome people to present at our community - calls or do workshops. Also organized a conference, a hackathon - & a festival. - - - - - 03Assembling the puzzle - - - Building things like MetaSys & MyMeta as well as the MetaOS - - to make it easy to integrate other people's building blocks - - - - - 04Uniting aligned peoples - - - Bringing together anyone aligned on the idea of building a new - kind of society; individuals joining MetaFam as well as projects - joining MetaAlliance. - - - - - - In short, anything & everything related to DAOs & helping - people build the future they want to live in. - - - - - - - - ); -}; - -export default WhatDo; diff --git a/packages/web/components/Landing/WhatSay.tsx b/packages/web/components/Landing/WhatSay.tsx deleted file mode 100644 index ba6a584935..0000000000 --- a/packages/web/components/Landing/WhatSay.tsx +++ /dev/null @@ -1,195 +0,0 @@ -import { Box, Container, Flex, HStack, Text } from '@metafam/ds'; -import { FullPageContainer } from 'components/Container'; -import { PlayerAvatar } from 'components/Player/PlayerAvatar'; -import { Player } from 'graphql/autogen/types'; -import { getPlayer } from 'graphql/getPlayer'; -import { useMotionDetector } from 'lib/hooks/useMotionDetector'; -import { useOnScreen } from 'lib/hooks/useOnScreen'; -import React, { ReactNode, useEffect, useRef, useState } from 'react'; - -import { LandingNextButton } from './LandingNextButton'; -import { LandingPageSectionProps } from './landingSection'; - -const WhatSay: React.FC = ({ - section, - nextSection, -}) => { - const ref = useRef(null); - const onScreen = useOnScreen(ref); - const root = typeof window !== 'undefined' ? document.body : null; - const noMotion = useMotionDetector(root); - const displayElement = noMotion ? true : !!onScreen; - - return ( - - - - - - What people are saying - - - - - - - - - - - MetaGame inspired me join the Web3 ecosystem after a season - of disillusionment and ICO scams 😛 -
- Through MetaGame I found the most amazing community of - values aligned ecosystem innovators that I still work with - today 🤩 - - } - username="yalormewn" - /> - -
- - - - - -
-
-
- -
- ); -}; - -const WhatSayCard: React.FC<{ - player: string; - testimony: string | ReactNode; - username?: string; -}> = ({ player, testimony, username }) => { - const [pfp, setPfp] = useState(undefined); - - useEffect(() => { - const getPfp = async () => { - if (username != null) { - const getPlayerResponse = await getPlayer(username); - - if (getPlayerResponse?.profile?.profileImageURL) { - setPfp(getPlayerResponse); - } - } - }; - getPfp(); - }, [username]); - - return ( - - - - {player} - - {testimony} - - ); -}; - -export default WhatSay; diff --git a/packages/web/components/Landing/WhoAreWe.tsx b/packages/web/components/Landing/WhoAreWe.tsx deleted file mode 100644 index 24f1634aa5..0000000000 --- a/packages/web/components/Landing/WhoAreWe.tsx +++ /dev/null @@ -1,269 +0,0 @@ -import { - Box, - Container, - ListItem, - Text, - UnorderedList, - useBreakpointValue, -} from '@metafam/ds'; -import BackgroundImageMobile from 'assets/landing/sections/section-5.sm.webp'; -import BackgroundImageDesktop from 'assets/landing/sections/section-5.webp'; -import { FullPageContainer } from 'components/Container'; -import { GuildFragment } from 'graphql/autogen/types'; -import { Patron } from 'graphql/types'; -import { usePlayerFilter } from 'lib/hooks/player/players'; -import { useMotionDetector } from 'lib/hooks/useMotionDetector'; -import { useOnScreen } from 'lib/hooks/useOnScreen'; -import React, { useMemo, useRef } from 'react'; - -import { LandingNextButton } from './LandingNextButton'; -import { LandingPageSectionProps } from './landingSection'; -import { Rain } from './OnboardingGame/Rain'; -import { UserGrid } from './UserGrid'; - -const elders = [ - { - name: 'Griff Green', - img: 'https://i.imgur.com/DIX26Sl.jpg', - link: 'https://twitter.com/thegrifft', - }, - { - name: 'Zargham', - img: 'https://bafybeid364yqceeedrximgjcejam6plca2eqcdwi7hkmjjpvrap5au5xye.ipfs.dweb.link/', - link: '/player/mz', - }, - { - name: 'James Young', - img: 'https://i.imgur.com/HVNMGXC.jpg', - link: 'https://twitter.com/jamesyoung', - }, - { - name: 'Hanzi Freinacht', - img: 'https://i.imgur.com/p3mDmJ2.jpg', - link: 'https://twitter.com/HFreinacht', - }, - { - name: 'Jeremy Akers', - img: 'https://i.imgur.com/4dD03FZ.jpg', - link: 'https://twitter.com/gospelofchange', - }, - { - name: 'You?', - img: 'https://i.imgur.com/tdi3NGa.png', - link: '', - }, - { - name: 'You?', - img: 'https://i.imgur.com/tdi3NGa.png', - link: '', - }, -]; - -interface LandingPageSectionPropsWithPatronsGuildsAndElders - extends LandingPageSectionProps { - patrons: Patron[]; - guilds: GuildFragment[]; -} - -const WhoAreWe: React.FC = ({ - section, - nextSection, - patrons, - guilds, -}) => { - const ref = useRef(null); - const onScreen = useOnScreen(ref); - const root = typeof window !== 'undefined' ? document.body : null; - const noMotion = useMotionDetector(root); - const displayElement = noMotion ? true : !!onScreen; - const responsiveBg = useBreakpointValue({ - base: BackgroundImageMobile, - md: BackgroundImageDesktop, - }); - - const { players } = usePlayerFilter(); - - const topPlayers = useMemo(() => players.slice(0, 7), [players]); - const topPatrons = useMemo(() => patrons.slice(0, 7), [patrons]); - - return ( - - - - - Who we are? - - - - - 01Players (Builders) - - {topPlayers && ( - - )} - - - - 02Patrons (Funders) - - {topPatrons && ( - - )} - - - - 03Elders (Advisors) - - {players && ( - - )} - - - - 04MetaAlliance (Member projects) - - {guilds && ( - - )} - - - - - - - - - ); -}; - -export default WhoAreWe; diff --git a/packages/web/components/Landing/WhyAreWeHere.tsx b/packages/web/components/Landing/WhyAreWeHere.tsx deleted file mode 100644 index 2c7f07b126..0000000000 --- a/packages/web/components/Landing/WhyAreWeHere.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import { Box, Container, Text, useBreakpointValue } from '@metafam/ds'; -import BackgroundImageDesktop from 'assets/landing/sections/section-4.jpg'; -import BackgroundImageMobile from 'assets/landing/sections/section-4.sm.jpg'; -import { FullPageContainer } from 'components/Container'; -import { useMotionDetector } from 'lib/hooks/useMotionDetector'; -import { useOnScreen } from 'lib/hooks/useOnScreen'; -import React, { useRef } from 'react'; - -import { LandingNextButton } from './LandingNextButton'; -import { LandingPageSectionProps } from './landingSection'; - -export const WhyAreWeHere: React.FC = ({ - section, - nextSection, -}) => { - const ref = useRef(null); - const onScreen = useOnScreen(ref); - const root = typeof window !== 'undefined' ? document.body : null; - const noMotion = useMotionDetector(root); - const displayElement = noMotion ? true : !!onScreen; - const responsiveBg = useBreakpointValue({ - base: BackgroundImageMobile, - md: BackgroundImageDesktop, - }); - - return ( - - - - - Why are we here? - - - To help{' '} - - you - {' '} - tame it. - - - We are here to help transform{' '} - - the wild web - {' '} - into a{' '} - - web of opportunity. - - - - To help you break into this brave new world, avoid traps,{' '} - - level up - {' '} - &{' '} - - make an impact. - - - - To build a new kind of socioeconomic system, optimized for{' '} - - wellbeing over profit. - - - - - - - ); -}; diff --git a/packages/web/components/Landing/WildWeb.tsx b/packages/web/components/Landing/WildWeb.tsx deleted file mode 100644 index 426fe5af24..0000000000 --- a/packages/web/components/Landing/WildWeb.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import { Box, Container, Text, useBreakpointValue } from '@metafam/ds'; -import BackgroundImageDesktop from 'assets/landing/sections/section-4.jpg'; -import BackgroundImageMobile from 'assets/landing/sections/section-4.sm.jpg'; -import { FullPageContainer } from 'components/Container'; -import { useMotionDetector } from 'lib/hooks/useMotionDetector'; -import { useOnScreen } from 'lib/hooks/useOnScreen'; -import React, { useRef } from 'react'; - -import { LandingNextButton } from './LandingNextButton'; -import { LandingPageSectionProps } from './landingSection'; - -const WildWeb: React.FC = ({ - section, - nextSection, -}) => { - const ref = useRef(null); - const onScreen = useOnScreen(ref); - const root = typeof window !== 'undefined' ? document.body : null; - const noMotion = useMotionDetector(root); - const displayElement = noMotion ? true : !!onScreen; - const responsiveBg = useBreakpointValue({ - base: BackgroundImageMobile, - md: BackgroundImageDesktop, - }); - - return ( - - - - - The problem? - - - A new world is being built but it’s{' '} - - hard to navigate. - - - - The resources, building blocks & tools are all over the place{' '} - - but the maps are inexistent. - - - - There are pitfalls, gold-rushing cowboys & snake oil salesmen at - every corner. - - - - It’s a Wild Web. - - - - - - ); -}; - -export default WildWeb; diff --git a/packages/web/components/Patron/PatronRank.tsx b/packages/web/components/Patron/PatronRank.tsx index c3a778edba..ff8fa83dbe 100644 --- a/packages/web/components/Patron/PatronRank.tsx +++ b/packages/web/components/Patron/PatronRank.tsx @@ -1,6 +1,6 @@ import { Flex, MetaTag, Text } from '@metafam/ds'; import { computeRank, Constants, Maybe } from '@metafam/utils'; -import { utils } from 'ethers'; +import { ethers } from 'ethers'; import { Player } from 'graphql/autogen/types'; import { Patron } from 'graphql/types'; import React, { useMemo } from 'react'; @@ -22,7 +22,7 @@ export const PatronRank: React.FC = ({ index, patron, pSeedPrice }) => { const displayBalance = useMemo(() => { const pSeedAmount = parseFloat( - utils.formatUnits(patron.pSeedBalance, Constants.PSEED_DECIMALS), + ethers.formatUnits(patron.pSeedBalance, Constants.PSEED_DECIMALS), ); const pSeedBalance = `${Math.floor(pSeedAmount).toLocaleString()} pSEED`; return pSeedPrice == null diff --git a/packages/web/components/Player/PlayerSection.tsx b/packages/web/components/Player/PlayerSection.tsx index e2dbd4b572..0005b2bc8b 100644 --- a/packages/web/components/Player/PlayerSection.tsx +++ b/packages/web/components/Player/PlayerSection.tsx @@ -3,7 +3,7 @@ import { PlayerAchievements } from 'components/Player/Section/PlayerAchievements import { PlayerCompletedQuests } from 'components/Player/Section/PlayerCompletedQuests'; import { PlayerGallery } from 'components/Player/Section/PlayerGallery'; import { PlayerHero } from 'components/Player/Section/PlayerHero'; -import { PlayerMemberships } from 'components/Player/Section/PlayerMemberships'; +import { PlayerMemberships } from 'components/Player/Section/PlayerLinks/PlayerMemberships'; import { PlayerPersonalityType } from 'components/Player/Section/PlayerPersonalityType'; import { PlayerRoles } from 'components/Player/Section/PlayerRoles'; import { PlayerSkills } from 'components/Player/Section/PlayerSkills'; @@ -17,6 +17,7 @@ import { FaTimes } from 'react-icons/fa'; import { BoxMetadata, BoxType, BoxTypes, createBoxKey } from 'utils/boxTypes'; import { PlayerDework } from './Section/PlayerDework'; +import { PlayerEAS } from './Section/PlayerEAS'; import { PlayerLinks } from './Section/PlayerLinks'; type Props = { @@ -58,6 +59,8 @@ const PlayerSectionInner: React.FC< return ; case BoxTypes.PLAYER_COMPLETED_QUESTS: return ; + case BoxTypes.PLAYER_ATTESTATIONS: + return case BoxTypes.EMBEDDED_URL: { const { url } = metadata ?? {}; return url ? : null; diff --git a/packages/web/components/Player/PlayerTile.tsx b/packages/web/components/Player/PlayerTile.tsx index 79feeb88f1..e9e5239a82 100644 --- a/packages/web/components/Player/PlayerTile.tsx +++ b/packages/web/components/Player/PlayerTile.tsx @@ -27,7 +27,7 @@ import React, { useCallback, useEffect, useState } from 'react'; import { getPlayerDescription } from 'utils/playerHelpers'; import { PlayerRank } from './PlayerRank'; -import { DAOMembershipSmall } from './Section/PlayerMemberships'; +import { DAOMembershipSmall } from './Section/PlayerLinks/PlayerMemberships'; type Props = { player: Player; diff --git a/packages/web/components/Player/Profile/MeetWithWalletProfileEdition.tsx b/packages/web/components/Player/Profile/MeetWithWalletProfileEdition.tsx index a24d1ebce3..6de65c471f 100644 --- a/packages/web/components/Player/Profile/MeetWithWalletProfileEdition.tsx +++ b/packages/web/components/Player/Profile/MeetWithWalletProfileEdition.tsx @@ -93,7 +93,7 @@ const MeetWithWalletProfileEdition: React.FC = ({ const signature = await ethereumHelper.getSignature( provider, sigMessageResult.message, - ['meetwithwallet.xyz'], + // ['meetwithwallet.xyz'], ); const accountRequest = { address, diff --git a/packages/web/components/Player/Section/Attestations.tsx b/packages/web/components/Player/Section/Attestations.tsx new file mode 100644 index 0000000000..9ae255105f --- /dev/null +++ b/packages/web/components/Player/Section/Attestations.tsx @@ -0,0 +1,187 @@ +import { + Flex, + MetaButton, + Text, + Textarea, + useToast, + VStack, +} from '@metafam/ds'; +import { Player } from 'graphql/autogen/types'; +import { useWeb3 } from 'lib/hooks'; +import { useEAS } from 'lib/hooks/useEAS'; +import React, { useEffect, useState } from 'react'; + +const MAX_DESC_LEN = 420; // characters + +export const Attestations: React.FC<{ player: Player }> = ({ player }) => { + const { attest, getAttestationsForRecipient } = useEAS(); + const [attestation, setAttestion] = useState(''); + const [attestations, setAttestations] = useState([]); + const { address } = useWeb3(); + const [isAttesting, setIsAttesting] = useState(false); + const toast = useToast(); + + useEffect(() => { + const getAttestationData = async () => { + const attestationData = await getAttestationsForRecipient( + player?.ethereumAddress, + ); + setAttestations(attestationData); + }; + getAttestationData(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [player?.ethereumAddress, isAttesting]); + + const handleAttest = async () => { + try { + setIsAttesting(true); + await attest(attestation, player?.ethereumAddress); + setAttestion(''); + } catch (err) { + toast({ + title: 'Error', + description: `Unable to save layout. Error: ${(err as Error).message}`, + status: 'error', + isClosable: true, + }); + } finally { + setIsAttesting(false); + } + }; + + return ( +
+ {player?.ethereumAddress.toLocaleLowerCase === address?.toLocaleLowerCase && ( +
+

Your Attestations: ({attestations?.length})

+ + {attestations?.map((att, i) => { + const attestor = att[3].value; + const timeCreated = att[1].value.value; + + const attestationVal = att[0].value; + return ( + + + {attestationVal.value} + + + By {attestor} + + {timeCreated} + + ); + })} + +
+ )} + {player?.ethereumAddress.toLocaleLowerCase() !== address?.toLocaleLowerCase() && ( + <> +
+

Your Attestations: ({attestations?.length})

+ + {attestations?.map((att, i) => { + const attestor = att[3].value; + const timeCreated = att[1].value.value; + + const attestationVal = att[0].value; + return ( + + + {attestationVal.value} + + + By {attestor} + + {timeCreated} + + ); + })} + +
+
+