Skip to content

Commit

Permalink
Merge branch 'sepolia'
Browse files Browse the repository at this point in the history
* sepolia:
  fix link domain for testing
  update opensea sepolia url
  nextjs builtin font package not working rn
  update siwe package
  update unlock packages to support sepolia
  update browserslist db
  add script to fix token balances
  switch to built-in next/font, disable query logger
  npm audit fix
  upgrade wagmi, ethers, viem. add sepolia
  update deploy scripts
  • Loading branch information
lyoshenka committed Mar 13, 2024
2 parents 4ebd270 + 7a7cefe commit 8ba200f
Show file tree
Hide file tree
Showing 60 changed files with 15,110 additions and 6,207 deletions.
1 change: 0 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Public
NEXT_PUBLIC_APP_ENV="dev" # dev | prod
NEXT_PUBLIC_ALCHEMY_APP_NAME="Cabin Census"
NEXT_PUBLIC_USE_TESTNETS=true
NEXT_PUBLIC_VERCEL_URL='localhost:3000'
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY="" # See README for instructions
NEXT_PUBLIC_IPFS_GATEWAY='https://ipfs.io/ipfs/'
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ When working on a new feature, follow these steps:
- Once the changes are tested and ready to be deployed to production, create a PR from `dev`
to `main`
- Make sure you double check all the changes previously merged to `dev`
- Once the PR is approved, merge it into `main`
- Fauna migrations will be run against the production database
- Once the PR is approved, merge it into `main` and push it
- Migrations will be run against the production database

## Google Analytics

Expand Down
9 changes: 7 additions & 2 deletions bin/deploy_cabin_token
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ source .env.forge


forge create --rpc-url $RPC_URL \
--private-key $SCRIPT_PRIVATE_KEY contracts/src/cabin-token/MockCabinToken.sol:MockCabinToken \
--private-key $SCRIPT_PRIVATE_KEY \
--etherscan-api-key $ETHERSCAN_API_KEY \
--constructor-args $CONTRACT_OWNER_ADDRESS \
--verify
--verify \
contracts/src/cabin-token/MockCabinToken.sol:MockCabinToken


# manual verification
# forge verify-contract --etherscan-api-key $ETHERSCAN_API_KEY --watch $CONTRACT_ADDRESS --chain sepolia --constructor-args $(cast abi-encode "constructor(address)" "$CONTRACT_OWNER_ADDRESS") contracts/src/cabin-token/MockCabinToken.sol:MockCabinToken
13 changes: 9 additions & 4 deletions bin/deploy_cabin_unlock_hooks
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@
echo "Reading vars from .env.forge"
source .env.forge

LOCK_ADDRESS=$1
#LOCK_ADDRESS=$1
echo "LOCK_ADDRESS: $LOCK_ADDRESS"

SIGNER_ADDRESS=$2
#SIGNER_ADDRESS=$2
echo "SIGNER_ADDRESS: $SIGNER_ADDRESS"

forge create --rpc-url $RPC_URL \
--private-key $SCRIPT_PRIVATE_KEY contracts/src/CabinUnlockHooks.sol:CabinUnlockHooks \
--private-key $SCRIPT_PRIVATE_KEY
--etherscan-api-key $ETHERSCAN_API_KEY \
--constructor-args $LOCK_ADDRESS $SIGNER_ADDRESS \
--verify
--verify \
contracts/src/CabinUnlockHooks.sol:CabinUnlockHooks


# manual verification
# forge verify-contract --etherscan-api-key $ETHERSCAN_API_KEY --watch $CONTRACT_ADDRESS --chain sepolia --constructor-args $(cast abi-encode "constructor(address,address)" "$LOCK_ADDRESS" "$SIGNER_ADDRESS") contracts/src/CabinUnlockHooks.sol:CabinUnlockHooks
3 changes: 2 additions & 1 deletion bin/run_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
# bin/run_script reset-db.ts
# bin/run_script sync-until-done.ts http://localhost:3000/api/sync/hats

npx ts-node --skipProject --require dotenv/config "scripts/$1" "${@:2}"
#npx ts-node --skipProject --require dotenv/config "scripts/$1" "${@:2}"
npx tsx "scripts/$1" "${@:2}"
4 changes: 2 additions & 2 deletions components/checkout/CheckoutPageView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isDevEnv } from '@/utils/dev'
import { isProd } from '@/utils/dev'
import { CartFragment } from '@/utils/types/cart'
import styled from 'styled-components'
import { Body1, H2 } from '@/components/core/Typography'
Expand All @@ -20,7 +20,7 @@ const CheckoutPageView = ({ cart }: { cart: CartFragment }) => {
</Body1>
<H2>Payment</H2>

{isDevEnv && (
{!isProd && (
<Body1
style={{
backgroundColor: theme.colors.yellow400,
Expand Down
4 changes: 2 additions & 2 deletions components/citizenship/CitizenshipView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const CitizenshipView = () => {
loadUnlockCheckout(provider)
}

const { handleSwitch, rightChain } = useChainSwitch(performMint)
const { handleSwitch, isOnRightChain } = useChainSwitch(performMint)

const handleMint = async () => {
if (!user) return
Expand All @@ -60,7 +60,7 @@ export const CitizenshipView = () => {
addressMatch(w.address, externalUser?.wallet?.address ?? '')
)

if (!currentUserWallet || !rightChain) {
if (!currentUserWallet || !isOnRightChain) {
handleSwitch()
return
}
Expand Down
3 changes: 2 additions & 1 deletion components/core/FileUploadDropzone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import {
SUPPORTED_FILE_TYPES,
fileTypesListString,
} from '@/lib/file-storage/configuration'
import { bytesToMegabytes } from '@/lib/file'

interface FileUploadDropzoneProps {
iconName: IconName
onFilesUploaded: (fileNameIpfsHashMap: FileNameIpfsHashMap) => Promise<void>
preprocessFiles?: (files: FileList | File[]) => FileList | File[]
}

const bytesToMegabytes = (bytes: number) => bytes / 1024 / 1024

export const FileUploadDropzone = ({
iconName,
onFilesUploaded,
Expand Down
4 changes: 2 additions & 2 deletions components/core/SwitchNetworkModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ModalContainer } from './modals/ModalContainer'
import { ModalTitle } from './modals/ModalTitle'
import { Body2, H4 } from './Typography'
import { Button } from './Button'
import { appChain } from '@/lib/wagmi/wagmi-client'
import { defaultChain } from '@/lib/chains'

interface SwitchNetworkModalProps {
onSwitch?: VoidFunction
Expand All @@ -24,7 +24,7 @@ export const SwitchNetworkModal = ({
</Question>
<Body2>
Minting your Citizenship NFT requires you to switch to the{' '}
{appChain.name} network.
{defaultChain.name} network.
</Body2>
</QuestionContainer>
<Actions>
Expand Down
5 changes: 2 additions & 3 deletions components/core/Typography.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import theme, { ColorName } from '../../styles/theme'
import styled, { css } from 'styled-components'

import { Inter, IBM_Plex_Mono, Poppins } from '@next/font/google'
import styled, { css } from 'styled-components'
import theme, { ColorName } from '../../styles/theme'

const inter = Inter({
display: 'swap',
Expand Down
55 changes: 28 additions & 27 deletions components/hooks/useChainSwitch.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { appChain } from '@/lib/wagmi/wagmi-client'
import { defaultChain } from '@/lib/chains'
import { useRouter } from 'next/router'
import { useNetwork, useSwitchNetwork } from 'wagmi'
import { useAccount, useSwitchChain } from 'wagmi'
import { useModal } from './useModal'
import { SwitchNetworkModal } from '../core/SwitchNetworkModal'
import { useExternalUser } from '../auth/useExternalUser'
Expand All @@ -10,26 +10,11 @@ import { addressMatch } from '@/utils/address-match'
export const useChainSwitch = (afterSwitch?: VoidFunction) => {
const { hideModal, showLoadingModal } = useModal()
const router = useRouter()
const { chain } = useNetwork()
const { wallets } = useWallets()
const { externalUser } = useExternalUser()
const isEmbeddedWallet = externalUser?.wallet?.walletClient === 'privy'
const { switchNetwork } = useSwitchNetwork({
throwForSwitchChainNotSupported: true,
chainId: appChain.id,
onSuccess: () => {
afterSwitch?.()
hideModal()
},
onError: () => {
console.error('Error switching chain')

if (isEmbeddedWallet) {
switchChainForEmbeddedWallet()
}
hideModal()
},
})
const { chain } = useAccount()
const { switchChain } = useSwitchChain()

const switchChainForEmbeddedWallet = async () => {
const wallet =
Expand All @@ -41,27 +26,43 @@ export const useChainSwitch = (afterSwitch?: VoidFunction) => {

const provider = await wallet.getEthersProvider()

await provider.send('wallet_switchEthereumChain', [`0x${appChain.id}`])
await provider.send('wallet_switchEthereumChain', [`0x${defaultChain.id}`])
}

const handleLeave = () => {
router.push('/profile')
router.push('/profile').then()
hideModal()
}

const switchChain = () => {
if (chain?.id === appChain.id) return
const switchToAppChain = () => {
if (chain?.id === defaultChain.id) return

switchNetwork?.()
switchChain(
{ chainId: defaultChain.id },
{
onSuccess: () => {
afterSwitch?.()
hideModal()
},
onError: () => {
if (isEmbeddedWallet) {
switchChainForEmbeddedWallet()
} else {
console.error('Error switching chain')
}
hideModal()
},
}
)
}

const handleSwitch = () => {
if (chain && chain?.id !== appChain.id) {
if (chain?.id !== defaultChain.id) {
showLoadingModal(() => (
<SwitchNetworkModal onSwitch={switchChain} onLeave={handleLeave} />
<SwitchNetworkModal onSwitch={switchToAppChain} onLeave={handleLeave} />
))
}
}

return { handleSwitch, rightChain: chain?.id === appChain.id }
return { handleSwitch, isOnRightChain: chain?.id === defaultChain.id }
}
4 changes: 2 additions & 2 deletions components/hooks/useEns.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useEffect, useCallback, useState } from 'react'
import { getAlchemyProvider } from '@/lib/alchemy'
import { getEthersAlchemyProvider } from '@/lib/chains'

const useEns = (address: string | undefined) => {
const [ens, setEns] = useState<string | null>(null)

const fetchEns = useCallback(async () => {
try {
const provider = getAlchemyProvider('mainnet')
const provider = getEthersAlchemyProvider('mainnet')
if (!address) return

const _ens = await provider.lookupAddress(address)
Expand Down
44 changes: 24 additions & 20 deletions components/hooks/useGetUnlockNFT.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { DEFAULT_NFT_IMAGE, UnlockNFT } from '@/utils/citizenship'
import { useEffect, useState } from 'react'
import { useConfig } from 'wagmi'
import { useProfile } from '../auth/useProfile'
import { usePublicLockContract } from './usePublicLockContract'
import { BigNumber } from 'ethers'
import { readCitizenshipContract } from '@/generated/contracts'
import { defaultChain } from '@/lib/chains'

export const useGetUnlockNFT = () => {
const publicLockContract = usePublicLockContract()
const [activeNFT, setActiveNFT] = useState<UnlockNFT | null>(null)
const [loading, setLoading] = useState(false)
const { user: profile } = useProfile()
const config = useConfig()

const getDateFromBigNumber = (bigNumber: BigNumber) => {
const getDateFromBigint = (bi: bigint) => {
try {
const date = new Date(bigNumber.toNumber() * 1000)
return date
return new Date(Number(bi) * 1000)
} catch (error) {
// Example invalid date: '115792089237316195423570985008687907853269984665640564039457584007913129639935'
console.error('Invalid date', error)
Expand All @@ -23,31 +23,35 @@ export const useGetUnlockNFT = () => {

useEffect(() => {
const getNFT = async () => {
if (
!publicLockContract ||
!profile?.walletAddress ||
!profile.citizenshipMintedAt
) {
if (!profile?.walletAddress || !profile.citizenshipMintedAt) {
setLoading(false)
return
}

setLoading(true)
const nft = await publicLockContract.getHasValidKey(profile.walletAddress)
const hasCitizenship = await readCitizenshipContract(config, {
chainId: defaultChain.id,
functionName: 'getHasValidKey',
args: [profile.walletAddress as `0x${string}`],
})

if (nft) {
const tokenId = await publicLockContract.tokenOfOwnerByIndex(
profile.walletAddress,
0
)
if (hasCitizenship) {
const tokenId = await readCitizenshipContract(config, {
chainId: defaultChain.id,
functionName: 'tokenOfOwnerByIndex',
args: [profile.walletAddress as `0x${string}`, BigInt(0)],
})

const expirationTimestamp =
await publicLockContract.keyExpirationTimestampFor(tokenId)
const expirationTimestamp = await readCitizenshipContract(config, {
chainId: defaultChain.id,
functionName: 'keyExpirationTimestampFor',
args: [tokenId],
})

setActiveNFT({
tokenId: tokenId.toString(),
mintedDate: new Date(profile.citizenshipMintedAt),
expirationDate: getDateFromBigNumber(expirationTimestamp),
expirationDate: getDateFromBigint(expirationTimestamp),
image: DEFAULT_NFT_IMAGE,
})
}
Expand Down
18 changes: 0 additions & 18 deletions components/hooks/usePublicLockContract.ts

This file was deleted.

4 changes: 2 additions & 2 deletions components/hooks/useSignAuthMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback, useEffect, useRef, useState } from 'react'
import { SiweMessage } from 'siwe'
import { useNetwork, useSignMessage } from 'wagmi'
import { useAccount, useSignMessage } from 'wagmi'

interface UseSignAuthMessageProps {
prefetchNonce?: boolean
Expand All @@ -11,7 +11,7 @@ export function useSignAuthMessage(props: UseSignAuthMessageProps = {}) {

const [nonce, setNonce] = useState<string | null>(null)
const fetchingNonce = useRef<boolean>(false)
const { chain: activeChain } = useNetwork()
const { chain: activeChain } = useAccount()
const { signMessageAsync } = useSignMessage()

const fetchNonce = useCallback(async () => {
Expand Down
13 changes: 6 additions & 7 deletions components/offers/OfferView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { isAfter, isBefore } from 'date-fns'
import { useDeviceSize } from '@/components/hooks/useDeviceSize'
import { OfferNameAndDates } from '@/components/offers/OfferNameAndDates'
import { OfferFragment, OfferType } from '@/utils/types/offer'
import { isProd, isVercelDev } from '@/utils/dev'

export const OfferView = ({
offer,
Expand Down Expand Up @@ -166,13 +167,11 @@ export const OfferView = ({
}

const _getHostIds = (offer: OfferFragment): string[] => {
const charlie =
process.env.NEXT_PUBLIC_VERCEL_ENV === 'production'
? '362368728841584721'
: process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview' ||
process.env.NEXT_PUBLIC_VERCEL_ENV === 'development'
? '359768139021418582'
: '373424375382147584'
const charlie = isProd
? '362368728841584721'
: isVercelDev
? '359768139021418582'
: '373424375382147584'

const gatherer =
offer.type !== OfferType.CabinWeek ||
Expand Down
4 changes: 2 additions & 2 deletions components/profile/AvatarSetup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ export const AvatarSetup = ({ onNftSelected, avatar }: AvatarSetupProps) => {
url,
network: nft.network,
contractAddress: nft.contract.address,
title: nft.title,
title: nft.name,
tokenId: nft.tokenId,
tokenUri: nft.tokenUri?.raw,
tokenUri: nft.raw.tokenUri,
})
hideModal()
}
Expand Down
Loading

0 comments on commit 8ba200f

Please sign in to comment.