Skip to content
This repository has been archived by the owner on Jun 24, 2022. It is now read-only.

Commit

Permalink
Merge pull request #2383 from gnosis/release/1.10
Browse files Browse the repository at this point in the history
[RELEASE ๐Ÿง‘๐Ÿผโ€๐ŸŒพ ] v1.10.0
  • Loading branch information
fairlighteth authored Feb 3, 2022
2 parents bc494da + 95d6ded commit cf9ab41
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 87 deletions.
19 changes: 19 additions & 0 deletions src/custom/hooks/useIsMounted.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useRef, useEffect } from 'react'

/**
* Creates a ref that can be used to solve the issue of
* "Can't perform a React state update on an unmounted component."
*/
export default function useIsMounted() {
const isMounted = useRef(false)

useEffect(() => {
isMounted.current = true

return () => {
isMounted.current = false
}
}, [])

return isMounted
}
12 changes: 6 additions & 6 deletions src/custom/pages/Claim/ClaimAddress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,19 @@ export default function ClaimAddress({ account, toggleWalletModal }: ClaimAddres
<input placeholder="Address or ENS name" value={inputAddress} onChange={handleInputChange} />
</InputField>

{!account && (
<ButtonSecondary onClick={toggleWalletModal}>
<Trans>{buttonLabel}</Trans>
</ButtonSecondary>
)}

{showInputError && (
<InputErrorText>
<TYPE.error error={true}>
<Trans>Enter valid address or ENS</Trans>
</TYPE.error>
</InputErrorText>
)}

{!account && (
<ButtonSecondary onClick={toggleWalletModal}>
<Trans>{buttonLabel}</Trans>
</ButtonSecondary>
)}
</CheckAddress>
)
}
10 changes: 4 additions & 6 deletions src/custom/pages/Claim/ClaimsOnOtherChainsBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo } from 'react'
import { useMemo, Fragment } from 'react'
import styled from 'styled-components/macro'
import { NETWORK_LABELS, SupportedChainId } from 'constants/chains'
import { useClaimState } from 'state/claim/hooks'
Expand Down Expand Up @@ -78,12 +78,10 @@ function ClaimsOnOtherChainsBanner({ className }: { className?: string }) {
const changeNetworksCallback = () => callback(chainId)
const isLastInMultiple = index === array.length - 1 && array.length > 1
return (
<>
<Fragment key={chainId}>
{isLastInMultiple && ' and'}
<ChainSpan key={chainId} onClick={changeNetworksCallback}>
{NETWORK_LABELS[chainId]}
</ChainSpan>
</>
<ChainSpan onClick={changeNetworksCallback}>{NETWORK_LABELS[chainId]}</ChainSpan>
</Fragment>
)
})}
</div>
Expand Down
8 changes: 6 additions & 2 deletions src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,12 @@ export default function InvestOption({ claim, optionIndex, openModal, closeModal
<label>
<span>
<b>Balance:</b>
<i title={balance && `${formatMax(balance, balance.currency.decimals)} ${balance.currency.symbol}`}>
{formatSmartLocaleAware(balance, AMOUNT_PRECISION) || 0} {balance?.currency?.symbol}
<i
title={
balance && `${formatMax(balance, balance.currency.decimals)} ${currencyAmount?.currency?.symbol}`
}
>
{formatSmartLocaleAware(balance, AMOUNT_PRECISION) || 0} {currencyAmount?.currency?.symbol}
</i>
{/* Button should use the max possible amount the user can invest, considering their balance + max investment allowed */}
{!noBalance && isSelfClaiming && (
Expand Down
12 changes: 7 additions & 5 deletions src/custom/pages/Claim/InvestmentFlow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import RoundArrow from 'assets/cow-swap/round-arrow.svg'
import ImportantIcon from 'assets/cow-swap/important.svg'
import CowProtocolImage from 'assets/cow-swap/cowprotocol.svg'
import SVG from 'react-inlinesvg'
import { SupportedChainId } from 'constants/chains'

const STEPS_DATA = [
{
Expand All @@ -56,11 +57,12 @@ const STEPS_DATA = [
},
]

const FAQ_DATA = [
const FAQ_DATA = (chainId: number | undefined) => [
{
title: 'What will happen?',
content:
'By sending this Ethereum transaction, you will be investing tokens from the connected account and exchanging them for vCOW tokens that will be received by the claiming account specified above.',
content: `By sending this ${
chainId !== SupportedChainId.XDAI ? 'Ethereum' : ''
} transaction, you will be investing tokens from the connected account and exchanging them for vCOW tokens that will be received by the claiming account specified above.`,
},
{
title: 'Can I modify (partially) invested amounts later?',
Expand Down Expand Up @@ -147,7 +149,7 @@ function AccountDetails({ isClaimer, label, account, connectedAccount }: Account
}

export default function InvestmentFlow({ claims, hasClaims, isAirdropOnly, modalCbs }: InvestmentFlowProps) {
const { account } = useActiveWeb3React()
const { account, chainId } = useActiveWeb3React()
const { selected, activeClaimAccount, claimStatus, isInvestFlowActive, investFlowStep, investFlowData } =
useClaimState()
const { initInvestFlowData } = useClaimDispatchers()
Expand Down Expand Up @@ -286,7 +288,7 @@ export default function InvestmentFlow({ claims, hasClaims, isAirdropOnly, modal
</AccountClaimSummary>

<h4>Ready to claim your vCOW?</h4>
<FaqDrawer items={FAQ_DATA} />
<FaqDrawer items={FAQ_DATA(chainId)} />
<UserMessage variant={'info'}>
<SVG src={ImportantIcon} description="Information" />
<span>
Expand Down
2 changes: 1 addition & 1 deletion src/custom/pages/Claim/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ export default function Claim() {
{/* Claiming content */}
<InnerPageWrapper>
{isClaimDataLoading ? (
<Loader />
<Loader size="5rem" />
) : (
<>
{/* Approve confirmation modal */}
Expand Down
10 changes: 9 additions & 1 deletion src/custom/pages/Claim/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ export const InnerPageWrapper = styled.div`
border: ${({ theme }) => theme.appBody.border};
box-shadow: ${({ theme }) => theme.appBody.boxShadow};
background: ${({ theme }) => theme.bg1};
min-height: 450px;
justify-content: center;
align-items: center;
${({ theme }) => theme.mediaWidth.upToSmall`
padding: 16px;
Expand All @@ -34,6 +37,10 @@ a {
color: ${({ theme }) => theme.primary4};
}
> a {
width: 100%;
}
p {
font-size: 16px;
display: block;
Expand Down Expand Up @@ -859,7 +866,8 @@ export const InputError = styled.div`
`

export const InputErrorText = styled.div`
margin: 0 0 24px;
margin: 0 0 15px;
text-align: center;
`

export const InputFieldTitle = styled.div`
Expand Down
48 changes: 33 additions & 15 deletions src/custom/state/claim/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import {
import { EnhancedUserClaimData } from 'pages/Claim/types'
import { supportedChainId } from 'utils/supportedChainId'
import { AMOUNT_PRECISION } from 'constants/index'
import useIsMounted from 'hooks/useIsMounted'

const CLAIMS_REPO_BRANCH = '2022-01-22-test-deployment-all-networks'
export const CLAIMS_REPO = `https://raw.githubusercontent.com/gnosis/cow-merkle-drop/${CLAIMS_REPO_BRANCH}/`
Expand All @@ -84,15 +85,6 @@ export enum ClaimType {
Advisor, // free, with vesting, only on mainnet
}

export type TypeToPriceMapper = Map<ClaimType, number>

// Hardcoded values
export const ClaimTypePriceMap: TypeToPriceMapper = new Map([
[ClaimType.GnoOption, 16.66],
[ClaimType.Investor, 26.66],
[ClaimType.UserOption, 36.66],
])

type RepoClaimType = keyof typeof ClaimType

export const FREE_CLAIM_TYPES: ClaimType[] = [ClaimType.Airdrop, ClaimType.Team, ClaimType.Advisor]
Expand Down Expand Up @@ -244,12 +236,16 @@ export function useUserClaims(account: Account, optionalChainId?: SupportedChain
const chainId = optionalChainId || connectedChain

const [claimInfo, setClaimInfo] = useState<{ [account: string]: UserClaims | null }>({})
const [isLoading, setIsLoading] = useState(false)
const [isLoading, setIsLoading] = useState(true)

// We'll have claims on multiple networks
const claimKey = chainId && account && `${chainId}:${account}`

useEffect(() => {
if (chainId && !account) {
setIsLoading(false)
}

if (!claimKey) {
return
}
Expand Down Expand Up @@ -279,6 +275,18 @@ export function useUserClaims(account: Account, optionalChainId?: SupportedChain
return { claims: claimKey ? claimInfo[claimKey] : null, isLoading }
}

let fetch_deployment_timestamp_promise: Promise<number> | null = null
function fetchDeploymentTimestamp(vCowContract: VCowType) {
if (!fetch_deployment_timestamp_promise) {
fetch_deployment_timestamp_promise = vCowContract.deploymentTimestamp().then((ts) => {
console.log(`Deployment timestamp in seconds: ${ts.toString()}`)
return ts.mul('1000').toNumber()
})
}

return fetch_deployment_timestamp_promise
}

/**
* Fetches from contract the deployment timestamp in ms
*
Expand All @@ -287,18 +295,28 @@ export function useUserClaims(account: Account, optionalChainId?: SupportedChain
function useDeploymentTimestamp(): number | null {
const { chainId } = useActiveWeb3React()
const vCowContract = useVCowContract()
const isMounted = useIsMounted()

const [timestamp, setTimestamp] = useState<number | null>(null)

useEffect(() => {
if (!chainId || !vCowContract) {
return
}

vCowContract.deploymentTimestamp().then((ts) => {
console.log(`Deployment timestamp in seconds: ${ts.toString()}`)
setTimestamp(ts.mul('1000').toNumber())
})
}, [chainId, vCowContract])
fetchDeploymentTimestamp(vCowContract)
.then((timestamp) => {
if (isMounted.current) {
setTimestamp(timestamp)
}
})
.catch((err) => {
if (isMounted.current) {
setTimestamp(null)
console.error('vCowContract Deployment Timestamp fetch failed', err)
}
})
}, [chainId, isMounted, vCowContract])

return timestamp
}
Expand Down
52 changes: 1 addition & 51 deletions src/custom/state/claim/hooks/utils.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { Currency, CurrencyAmount, Percent, Token } from '@uniswap/sdk-core'

import { SupportedChainId } from 'constants/chains'
import { GNO, GpEther, USDC_BY_CHAIN, V_COW } from 'constants/tokens'
import { GNO, GpEther, USDC_BY_CHAIN } from 'constants/tokens'
import { ONE_HUNDRED_PERCENT, ZERO_PERCENT } from 'constants/misc'

import {
CLAIMS_REPO,
ClaimType,
ClaimTypePriceMap,
FREE_CLAIM_TYPES,
PAID_CLAIM_TYPES,
RepoClaims,
TypeToPriceMapper,
UserClaims,
VCowPrices,
} from 'state/claim/hooks/index'
Expand Down Expand Up @@ -66,54 +64,6 @@ export function getFreeClaims(claims: UserClaims): UserClaims {
return claims?.filter((claim) => FREE_CLAIM_TYPES.includes(claim.type))
}

/**
* Helper function to transform claim data amount to CurrencyAmount
*
*/
export function parseClaimAmount(value: string, chainId: number | undefined): CurrencyAmount<Token> | undefined {
const vCow = chainId ? V_COW[chainId || 4] : undefined
if (!vCow || !value) return undefined
return CurrencyAmount.fromRawAmount(vCow, value)
}

export type TypeToCurrencyMapper = {
[key: string]: string
}

/**
* Helper function to transform claim data type to coin name that can be displayed in the UI
*
* @param chainId
*/
export function getTypeToCurrencyMap(chainId: number | undefined): TypeToCurrencyMapper {
if (!chainId) return {}

const map: TypeToCurrencyMapper = {
[ClaimType.GnoOption]: 'GNO',
[ClaimType.Investor]: 'USDC',
[ClaimType.UserOption]: '',
}

if ([SupportedChainId.MAINNET, SupportedChainId.RINKEBY].includes(chainId)) {
map[ClaimType.UserOption] = 'ETH'
}

if (chainId === SupportedChainId.XDAI) {
map[ClaimType.UserOption] = 'XDAI'
}

return map
}

/**
* Helper function to get vCow price based on claim type and chainId
*
* @param type
*/
export function getTypeToPriceMap(): TypeToPriceMapper {
return ClaimTypePriceMap
}

/**
* Helper function to check if current type is free claim
*
Expand Down

0 comments on commit cf9ab41

Please sign in to comment.