diff --git a/apps/evm/lingui.config.js b/apps/bob-pay/lingui.config.ts similarity index 50% rename from apps/evm/lingui.config.js rename to apps/bob-pay/lingui.config.ts index 82f1610ab..5124ecf01 100644 --- a/apps/evm/lingui.config.js +++ b/apps/bob-pay/lingui.config.ts @@ -1,6 +1,7 @@ -/** @type {import('@lingui/conf').LinguiConfig} */ -module.exports = { - locales: ['en', 'zh'], +import { LinguiConfig } from '@lingui/conf'; + +const config = { + locales: ['en', 'zh'] as const, sourceLocale: 'en', fallbackLocales: { default: 'en' @@ -11,4 +12,6 @@ module.exports = { include: ['src/'] } ] -}; +} as const satisfies LinguiConfig; + +export default config; diff --git a/apps/evm/.env.test b/apps/evm/.env.test index 889bc86bf..0d3d43ccb 100644 --- a/apps/evm/.env.test +++ b/apps/evm/.env.test @@ -5,10 +5,11 @@ NEXT_PUBLIC_L1_CHAIN="11155111" NEXT_PUBLIC_L2_CHAIN="808813" NEXT_COINGECKO_API_KEY= NEXT_PUBLIC_GEOBLOCK_ENABLED=false -NEXT_PUBLIC_FEATURE_FLAG_WALLET=enabled NEXT_PUBLIC_INDEXER_URL= NEXT_PUBLIC_SENTRY_AUTH_TOKEN= NEXT_PUBLIC_SENTRY_URL= SENTRY_AUTH_TOKEN= KV_REST_API_URL= -KV_REST_API_TOKEN= \ No newline at end of file +KV_REST_API_TOKEN= +NEXT_PUBLIC_FEATURE_FLAG_TOP_100_SPICE_USERS=enabled +NEXT_PUBLIC_FEATURE_FLAG_OP_SUPERUSER=enabled \ No newline at end of file diff --git a/apps/bob-pay/lingui.config.js b/apps/evm/lingui.config.ts similarity index 59% rename from apps/bob-pay/lingui.config.js rename to apps/evm/lingui.config.ts index 82f1610ab..7685ec857 100644 --- a/apps/bob-pay/lingui.config.js +++ b/apps/evm/lingui.config.ts @@ -1,5 +1,6 @@ -/** @type {import('@lingui/conf').LinguiConfig} */ -module.exports = { +import { LinguiConfig } from '@lingui/conf'; + +const config = { locales: ['en', 'zh'], sourceLocale: 'en', fallbackLocales: { @@ -11,4 +12,6 @@ module.exports = { include: ['src/'] } ] -}; +} as const satisfies LinguiConfig; + +export default config; diff --git a/apps/evm/next.config.mjs b/apps/evm/next.config.mjs index dcec0f93c..0845fe517 100644 --- a/apps/evm/next.config.mjs +++ b/apps/evm/next.config.mjs @@ -2,6 +2,9 @@ import { withSentryConfig } from '@sentry/nextjs'; /** @type {import('next').NextConfig} */ const nextConfig = { + images: { + domains: ['raw.githubusercontent.com'] // Add the allowed hostname here + }, compiler: { styledComponents: true }, diff --git a/apps/evm/package.json b/apps/evm/package.json index 3e6b06403..1e3492d5f 100644 --- a/apps/evm/package.json +++ b/apps/evm/package.json @@ -42,6 +42,7 @@ "date-fns": "catalog:", "graphql-request": "catalog:", "lottie-react": "^2.4.0", + "react-calendly": "^4.3.1", "negotiator": "catalog:", "next": "catalog:", "react": "catalog:", diff --git a/apps/evm/public/assets/optimism-city.png b/apps/evm/public/assets/optimism-city.png new file mode 100644 index 000000000..01b687f58 Binary files /dev/null and b/apps/evm/public/assets/optimism-city.png differ diff --git a/apps/evm/public/assets/partners/superchain-eco.png b/apps/evm/public/assets/partners/superchain-eco.png new file mode 100644 index 000000000..af2f0ccab Binary files /dev/null and b/apps/evm/public/assets/partners/superchain-eco.png differ diff --git a/apps/evm/public/assets/top-100-spice.webp b/apps/evm/public/assets/top-100-spice.webp new file mode 100644 index 000000000..8abe8ad6a Binary files /dev/null and b/apps/evm/public/assets/top-100-spice.webp differ diff --git a/apps/evm/src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx b/apps/evm/src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx index 358c5a714..7410a2aa9 100644 --- a/apps/evm/src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx +++ b/apps/evm/src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx @@ -2,6 +2,7 @@ import { Clock, Flex, FlexProps } from '@gobob/ui'; import { Trans } from '@lingui/macro'; import { formatDistanceToNow, isFuture } from 'date-fns'; import { ReactNode, useMemo } from 'react'; +import { useParams } from 'next/navigation'; import { BridgeTransaction } from '../../hooks'; @@ -9,6 +10,7 @@ import { StyledTimePill } from './BridgeStatus.style'; import { BridgeStep } from './BridgeStep'; import { BridgeSteps } from '@/types'; +import { getLocale } from '@/utils'; const TimeLabel = ({ label }: { label: ReactNode }) => ( @@ -28,6 +30,8 @@ type InheritAttrs = Omit; type TimeStepProps = Props & InheritAttrs; const TimeStep = ({ step, data, currentStep }: TimeStepProps): JSX.Element => { + const { lang } = useParams(); + const timeLabel = useMemo(() => { // should only show step if it is not a complete step const showTime = @@ -44,7 +48,12 @@ const TimeStep = ({ step, data, currentStep }: TimeStepProps): JSX.Element => { return step === 'challenge-period' ? 7 days : 2 hours; } - return {formatDistanceToNow(data.statusEndDate)} remaining; + return ( + + {formatDistanceToNow(data.statusEndDate, { locale: getLocale(lang as Parameters[0]) })}{' '} + remaining + + ); }, [step, currentStep, data.statusEndDate]); return ( diff --git a/apps/evm/src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx b/apps/evm/src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx index 2f09c9c61..776e56f39 100644 --- a/apps/evm/src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx +++ b/apps/evm/src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx @@ -3,11 +3,13 @@ import { Currency, CurrencyAmount } from '@gobob/currency'; import { ArrowLongRight, Flex, FlexProps, P, UnstyledButton } from '@gobob/ui'; import { Trans } from '@lingui/macro'; import { formatDistanceToNow } from 'date-fns'; +import { useParams } from 'next/navigation'; import { StyledDetailsButton, StyledExpandIcon } from './TransactionList.style'; import { Chain } from '@/components'; import { TransactionDirection } from '@/types'; +import { getLocale } from '@/utils'; type Props = { direction: TransactionDirection; @@ -35,6 +37,7 @@ const TransactionDetails = ({ onExpand, ...props }: TransactionDetailsProps): JSX.Element => { + const { lang } = useParams(); const directionLabel = direction === TransactionDirection.L1_TO_L2 ? Deposit : Withdraw; const isExpandable = !!onExpand; @@ -46,7 +49,7 @@ const TransactionDetails = ({ {directionLabel}

- {formatDistanceToNow(date)} ago + {formatDistanceToNow(date, { locale: getLocale(lang as Parameters[0]) })} ago

diff --git a/apps/evm/src/app/[lang]/(bridge)/stake/hooks/tests/useGetStakingStrategies.test.tsx b/apps/evm/src/app/[lang]/(bridge)/stake/hooks/tests/useGetStakingStrategies.test.tsx index 75222296d..6ff0f99c3 100644 --- a/apps/evm/src/app/[lang]/(bridge)/stake/hooks/tests/useGetStakingStrategies.test.tsx +++ b/apps/evm/src/app/[lang]/(bridge)/stake/hooks/tests/useGetStakingStrategies.test.tsx @@ -116,13 +116,70 @@ const mockSegmentStrategy: GatewayStrategyContract = { } } as const; +const mockPellUniBTCStrategy: GatewayStrategyContract = { + id: 'pell-unibtc', + type: 'deposit', + address: '0xf5f2f90d3edc557b7ff0a285169a0b194df7b6f2', + method: '', + chain: { + id: '', + chainId: 60808, + slug: 'bob', + name: 'bob', + logo: '', + type: 'evm', + singleChainSwap: true, + singleChainStaking: true + }, + integration: { + type: 'staking', + slug: 'pell-unibtc', + name: 'Pell (uniBTC)', + logo: '', + monetization: false + }, + inputToken: { + symbol: 'WBTC', + address: '0x03c7054bcb39f7b2e5b2c7acb37583e32d70cfa3', + logo: 'https://ethereum-optimism.github.io/data/WBTC/logo.svg', + decimals: 8, + chain: 'bob' + }, + outputToken: null +} as const; + +const seTokensContractDataMock = { + seSOLVBTCBBN: [200420547971521033526791436n, 90941658309n, '0xCC0966D8418d412c599A6421b760a847eB169A8c'], + seTBTC: [207537267655402594884495418n, 8255486068n, '0xBBa2eF945D523C4e2608C9E1214C2Cc64D4fc2e2'], + seUNIBTC: [20020877878162857n, 8875128907n, '0x236f8c0a61dA474dB21B693fB2ea7AAB0c803894'], + seWBTC: [20083839753286961n, 63216624241n, '0x03C7054BCB39f7b2e5B2c7AcB37583e32D70Cfa3'] +} as const; + +const seTokensUnderlyingContractDataMock = { + seSOLVBTCBBN: 18, + seTBTC: 18, + seUNIBTC: 8, + seWBTC: 8 +} as const; + +const tokensContractDataMock = { + 'SolvBTC.BBN': [1669199681543807681873n, 18], + uniBTC: [42320720383n, 8] +} as const; + +const noOuputTokenContractDataMock = { + '0xdf3aa56f2626e253b5db7703ac7241e835140566': 8587056375410955041n, + '0xf5f2f90d3edc557b7ff0a285169a0b194df7b6f2': 20351418531n +} as const; + +const noOuputTokenContractSharesToUnderlyingDataMock = { + '0xdf3aa56f2626e253b5db7703ac7241e835140566': 8587056375410955041n, + '0xf5f2f90d3edc557b7ff0a285169a0b194df7b6f2': 20351418531n +} as const; + describe('useGetStakingStrategies', () => { afterEach(vi.clearAllMocks); - const mockExchangeRateStored = 207520794671396869399540716n; - const mockTotalSupply = 9036849246n; - const mockUnderlying = '0xabc'; - const underlyingDecimals = 18; const decimals = 8; @@ -131,13 +188,19 @@ describe('useGetStakingStrategies', () => { beforeEach(() => { (useReadContracts as Mock) .mockReturnValueOnce({ - data: [mockExchangeRateStored, mockTotalSupply, mockUnderlying] + data: seTokensContractDataMock + }) + .mockReturnValueOnce({ + data: seTokensUnderlyingContractDataMock }) .mockReturnValueOnce({ - data: [underlyingDecimals] + data: tokensContractDataMock }) .mockReturnValueOnce({ - data: [mockTotalSupply, decimals] + data: noOuputTokenContractDataMock + }) + .mockReturnValueOnce({ + data: noOuputTokenContractSharesToUnderlyingDataMock }); (usePrices as Mock).mockReturnValue({ @@ -148,13 +211,19 @@ describe('useGetStakingStrategies', () => { it('should return strategy data', async () => { (useReadContracts as Mock) .mockReturnValueOnce({ - data: [mockExchangeRateStored, mockTotalSupply, mockUnderlying] + data: seTokensContractDataMock }) .mockReturnValueOnce({ - data: [underlyingDecimals] + data: seTokensUnderlyingContractDataMock }) .mockReturnValueOnce({ - data: [mockTotalSupply, decimals] + data: tokensContractDataMock + }) + .mockReturnValueOnce({ + data: noOuputTokenContractDataMock + }) + .mockReturnValueOnce({ + data: noOuputTokenContractSharesToUnderlyingDataMock }); (gatewaySDK.getStrategies as Mock).mockReturnValue([mockStrategy]); @@ -177,7 +246,9 @@ describe('useGetStakingStrategies', () => { mockStrategy.outputToken.symbol ) : undefined, - tvl: new Big(mockTotalSupply.toString()) + tvl: new Big( + tokensContractDataMock[mockStrategy.outputToken?.symbol as keyof typeof tokensContractDataMock][0].toString() + ) .mul(mockPrice) .div(10 ** decimals) .toNumber() @@ -187,23 +258,25 @@ describe('useGetStakingStrategies', () => { expect(result.current.data).toEqual([expectedData]); }); - it('should return undefined currency when outputToken is missing', async () => { + it('should return tvl value if output token is se* token', async () => { (useReadContracts as Mock) .mockReturnValueOnce({ - data: [mockExchangeRateStored, mockTotalSupply, mockUnderlying] + data: seTokensContractDataMock + }) + .mockReturnValueOnce({ + data: seTokensUnderlyingContractDataMock + }) + .mockReturnValueOnce({ + data: tokensContractDataMock }) .mockReturnValueOnce({ - data: [underlyingDecimals] + data: noOuputTokenContractDataMock }) .mockReturnValueOnce({ - data: [mockTotalSupply, decimals] + data: noOuputTokenContractSharesToUnderlyingDataMock }); - const mockStrategyWithoutToken = { - outputToken: undefined - }; - - (gatewaySDK.getStrategies as Mock).mockReturnValue([mockStrategyWithoutToken]); + (gatewaySDK.getStrategies as Mock).mockReturnValue([mockSegmentStrategy]); const { result, waitForValueToChange } = renderHook>( () => useGetStakingStrategies(), @@ -213,27 +286,52 @@ describe('useGetStakingStrategies', () => { await waitForValueToChange(() => result.current.data); const expectedData = { - raw: mockStrategyWithoutToken, - currency: undefined, - tvl: null + raw: mockSegmentStrategy, + currency: mockSegmentStrategy.outputToken + ? new Token( + ChainId.BOB, + mockSegmentStrategy.outputToken.address as Address, + mockSegmentStrategy.outputToken.decimals, + mockSegmentStrategy.outputToken.symbol, + mockSegmentStrategy.outputToken.symbol + ) + : undefined, + tvl: new Big( + ( + seTokensContractDataMock[ + mockSegmentStrategy.outputToken?.symbol as keyof typeof seTokensContractDataMock + ][0] * + seTokensContractDataMock[mockSegmentStrategy.outputToken?.symbol as keyof typeof seTokensContractDataMock][1] + ).toString() + ) + .mul(mockPrice) + .div(1e18) + .div(10 ** underlyingDecimals) + .toNumber() }; expect(result.current.data).toEqual([expectedData]); }); - it('should return tvl value if output token is se* token', async () => { + it('should return tvl value if no output', async () => { (useReadContracts as Mock) .mockReturnValueOnce({ - data: [mockExchangeRateStored, mockTotalSupply, mockUnderlying] + data: seTokensContractDataMock }) .mockReturnValueOnce({ - data: [underlyingDecimals] + data: seTokensUnderlyingContractDataMock }) .mockReturnValueOnce({ - data: [mockTotalSupply, decimals] + data: tokensContractDataMock + }) + .mockReturnValueOnce({ + data: noOuputTokenContractDataMock + }) + .mockReturnValueOnce({ + data: noOuputTokenContractSharesToUnderlyingDataMock }); - (gatewaySDK.getStrategies as Mock).mockReturnValue([mockSegmentStrategy]); + (gatewaySDK.getStrategies as Mock).mockReturnValue([mockPellUniBTCStrategy]); const { result, waitForValueToChange } = renderHook>( () => useGetStakingStrategies(), @@ -243,20 +341,15 @@ describe('useGetStakingStrategies', () => { await waitForValueToChange(() => result.current.data); const expectedData = { - raw: mockSegmentStrategy, - currency: mockSegmentStrategy.outputToken - ? new Token( - ChainId.BOB, - mockSegmentStrategy.outputToken.address as Address, - mockSegmentStrategy.outputToken.decimals, - mockSegmentStrategy.outputToken.symbol, - mockSegmentStrategy.outputToken.symbol - ) - : undefined, - tvl: new Big((mockExchangeRateStored * mockTotalSupply).toString()) + raw: mockPellUniBTCStrategy, + currency: undefined, + tvl: new Big( + noOuputTokenContractSharesToUnderlyingDataMock[ + mockPellUniBTCStrategy.address as keyof typeof noOuputTokenContractSharesToUnderlyingDataMock + ].toString() + ) .mul(mockPrice) - .div(1e18) - .div(10 ** underlyingDecimals) + .div(10 ** (tokensContractDataMock.uniBTC[1]! as number)) .toNumber() }; diff --git a/apps/evm/src/app/[lang]/(bridge)/stake/hooks/useGetStakingStrategies.ts b/apps/evm/src/app/[lang]/(bridge)/stake/hooks/useGetStakingStrategies.ts index 2575727a7..fc50ea333 100644 --- a/apps/evm/src/app/[lang]/(bridge)/stake/hooks/useGetStakingStrategies.ts +++ b/apps/evm/src/app/[lang]/(bridge)/stake/hooks/useGetStakingStrategies.ts @@ -90,9 +90,31 @@ const useGetStakingStrategies = () => { }); // se tokens contract data + const seTokenContractDataSelector = useCallback( + (data: (bigint | `0x${string}`)[]) => { + if (!strategies) return null; + + return strategies.reduce( + (acc, strategy) => { + if (hasUnderlying(strategy.raw.outputToken?.symbol) && data) { + const idx = Object.keys(acc).length * 3; + + // for each se* token we need tulpes of 3 call results + acc[strategy.raw.outputToken?.symbol] = data.slice(idx, idx + 3) as [bigint, bigint, Address]; + } + + return acc; + }, + {} as Record + ); + }, + [strategies] + ); + const { data: seTokensContractData } = useReadContracts({ query: { - enabled: isStrategiesSucess + enabled: isStrategiesSucess, + select: seTokenContractDataSelector }, allowFailure: false, config: { @@ -122,28 +144,31 @@ const useGetStakingStrategies = () => { ) }); - const seTokenContractDataCalls = useMemo(() => { - if (!strategies) return null; - - return strategies.reduce( - (acc, strategy) => { - if (hasUnderlying(strategy.raw.outputToken?.symbol) && seTokensContractData) { - const idx = Object.keys(acc).length * 3; - - // for each se* token we need tulpes of 3 call results - acc[strategy.raw.outputToken?.symbol] = seTokensContractData.slice(idx, idx + 3) as [bigint, bigint, Address]; - } - - return acc; - }, - {} as Record - ); - }, [seTokensContractData, strategies]); - // se tokens underlying contract data + const seTokenUnderlyingContractDataSelector = useCallback( + (data: number[]) => { + if (!strategies) return null; + + return strategies.reduce( + (acc, strategy) => { + if (hasUnderlying(strategy.raw.outputToken?.symbol) && data) { + const idx = Object.keys(acc).length; + + acc[strategy.raw.outputToken?.symbol] = data[idx] as number; + } + + return acc; + }, + {} as Record + ); + }, + [strategies] + ); + const { data: seTokensUnderlyingContractData } = useReadContracts({ query: { - enabled: isStrategiesSucess + enabled: isStrategiesSucess, + select: seTokenUnderlyingContractDataSelector }, allowFailure: false, config: { @@ -154,7 +179,7 @@ const useGetStakingStrategies = () => { hasUnderlying(strategy.raw.outputToken?.symbol) ? ([ { - address: seTokenContractDataCalls?.[strategy.raw.outputToken?.symbol]?.[2] as Address, + address: seTokensContractData?.[strategy.raw.outputToken?.symbol]?.[2] as Address, abi: erc20Abi, functionName: 'decimals' } @@ -163,27 +188,31 @@ const useGetStakingStrategies = () => { ) }); - const seTokenUnderlyingContractDataCalls = useMemo(() => { - if (!strategies) return null; - - return strategies.reduce( - (acc, strategy) => { - if (hasUnderlying(strategy.raw.outputToken?.symbol) && seTokensUnderlyingContractData) { - const idx = Object.keys(acc).length; - - acc[strategy.raw.outputToken?.symbol] = seTokensUnderlyingContractData[idx] as number; - } - - return acc; - }, - {} as Record - ); - }, [seTokensUnderlyingContractData, strategies]); - // erc20 tokens contract data + const tokensContractDataSelector = useCallback( + (data: (number | bigint)[]) => { + if (!strategies) return null; + + return strategies.reduce( + (acc, strategy) => { + if (hasCGId(strategy.raw.outputToken?.symbol) && data) { + const idx = Object.keys(acc).length * 2; + + acc[strategy.raw.outputToken?.symbol] = data.slice(idx, idx + 2) as [bigint, number]; + } + + return acc; + }, + {} as Record + ); + }, + [strategies] + ); + const { data: tokensContractData } = useReadContracts({ query: { - enabled: isStrategiesSucess + enabled: isStrategiesSucess, + select: tokensContractDataSelector }, allowFailure: false, config: { @@ -208,27 +237,31 @@ const useGetStakingStrategies = () => { ) }); - const tokensContractDataCalls = useMemo(() => { - if (!strategies) return null; - - return strategies.reduce( - (acc, strategy) => { - if (hasCGId(strategy.raw.outputToken?.symbol) && tokensContractData) { - const idx = Object.keys(acc).length * 2; - - acc[strategy.raw.outputToken?.symbol] = tokensContractData.slice(idx, idx + 2) as [bigint, number]; - } - - return acc; - }, - {} as Record - ); - }, [strategies, tokensContractData]); - // no output token strategies contract data + const noOuputTokenContractDataSelector = useCallback( + (data: bigint[]) => { + if (!strategies) return null; + + return strategies.reduce( + (acc, strategy) => { + if (hasNoOutputToken(strategy.raw.address) && data) { + const idx = Object.keys(acc).length; + + acc[strategy.raw.address] = data[idx] as bigint; + } + + return acc; + }, + {} as Record + ); + }, + [strategies] + ); + const { data: noOuputTokenContractData } = useReadContracts({ query: { - enabled: isStrategiesSucess + enabled: isStrategiesSucess, + select: noOuputTokenContractDataSelector }, allowFailure: false, config: { @@ -248,59 +281,46 @@ const useGetStakingStrategies = () => { ) }); - const noOuputTokenContractDataCalls = useMemo(() => { - if (!strategies) return null; + const noOuputTokenContractSharesToUnderlyingDataSelector = useCallback( + (data: bigint[]) => { + if (!strategies) return null; - return strategies.reduce( - (acc, strategy) => { - if (hasNoOutputToken(strategy.raw.address) && noOuputTokenContractData) { - const idx = Object.keys(acc).length; + return strategies.reduce( + (acc, strategy) => { + if (hasNoOutputToken(strategy.raw.address) && data) { + const idx = Object.keys(acc).length; - acc[strategy.raw.address] = noOuputTokenContractData[idx] as bigint; - } + acc[strategy.raw.address] = data[idx] as bigint; + } - return acc; - }, - {} as Record - ); - }, [noOuputTokenContractData, strategies]); + return acc; + }, + {} as Record + ); + }, + [strategies] + ); const { data: noOuputTokenContractSharesToUnderlyingData } = useReadContracts({ query: { - enabled: isStrategiesSucess + enabled: isStrategiesSucess, + select: noOuputTokenContractSharesToUnderlyingDataSelector }, allowFailure: false, contracts: strategies?.flatMap((strategy) => - hasNoOutputToken(strategy.raw.address) && noOuputTokenContractDataCalls?.[strategy.raw.address] + hasNoOutputToken(strategy.raw.address) && noOuputTokenContractData?.[strategy.raw.address] ? ([ { address: strategyToLimitsMapping[strategy.raw.address] as Address, abi: strategyBaseTVLLimitAbi, functionName: 'sharesToUnderlyingView', - args: [noOuputTokenContractDataCalls[strategy.raw.address]] + args: [noOuputTokenContractData[strategy.raw.address]] } ] as const) : ([] as const) ) }); - const noOuputTokenContractSharesToUnderlyingDataCalls = useMemo(() => { - if (!strategies) return null; - - return strategies.reduce( - (acc, strategy) => { - if (hasNoOutputToken(strategy.raw.address) && noOuputTokenContractSharesToUnderlyingData) { - const idx = Object.keys(acc).length; - - acc[strategy.raw.address] = noOuputTokenContractSharesToUnderlyingData[idx] as bigint; - } - - return acc; - }, - {} as Record - ); - }, [noOuputTokenContractSharesToUnderlyingData, strategies]); - // get prices const { getPrice } = usePrices(); @@ -309,15 +329,11 @@ const useGetStakingStrategies = () => { strategies?.map((strategy) => { const symbol = strategy.raw.outputToken?.symbol; - if ( - hasUnderlying(symbol) && - seTokenContractDataCalls?.[symbol] && - seTokenUnderlyingContractDataCalls?.[symbol] - ) { + if (hasUnderlying(symbol) && seTokensContractData?.[symbol] && seTokensUnderlyingContractData?.[symbol]) { // `(totalCash + totalBorrows - totalReserves)` is multiplied by 1e18 to perform uint division // exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply - const [exchangeRateStored, totalSupply] = seTokenContractDataCalls[symbol]!; - const underlyingDecimals = seTokenUnderlyingContractDataCalls[symbol]!; + const [exchangeRateStored, totalSupply] = seTokensContractData[symbol]!; + const underlyingDecimals = seTokensUnderlyingContractData[symbol]!; const totalSupplyInUnderlyingAsset = exchangeRateStored * totalSupply; const underlyingTicker = seTokenToUnderlyingMapping[symbol]; @@ -333,8 +349,8 @@ const useGetStakingStrategies = () => { }; } - if (hasCGId(symbol) && tokensContractDataCalls?.[symbol]) { - const [totalSupply, decimals] = tokensContractDataCalls[symbol]!; + if (hasCGId(symbol) && tokensContractData?.[symbol]) { + const [totalSupply, decimals] = tokensContractData[symbol]!; const ticker = tokenToIdMapping[symbol]; const price = getPrice(ticker!); @@ -349,8 +365,8 @@ const useGetStakingStrategies = () => { const strategyAddress = strategy.raw.address; - if (hasNoOutputToken(strategyAddress) && noOuputTokenContractSharesToUnderlyingDataCalls?.[strategyAddress]) { - const totalSharesToUnderlying = noOuputTokenContractSharesToUnderlyingDataCalls[strategyAddress]!; + if (hasNoOutputToken(strategyAddress) && noOuputTokenContractSharesToUnderlyingData?.[strategyAddress]) { + const totalSharesToUnderlying = noOuputTokenContractSharesToUnderlyingData[strategyAddress]!; const limitsContractAddress = strategyToLimitsMapping[strategyAddress]!; const [ticker, decimals] = limitsToUnderlyingMapping[limitsContractAddress]!; const price = getPrice(ticker!); @@ -371,10 +387,10 @@ const useGetStakingStrategies = () => { }), [ strategies, - seTokenContractDataCalls, - seTokenUnderlyingContractDataCalls, - tokensContractDataCalls, - noOuputTokenContractSharesToUnderlyingDataCalls, + seTokensContractData, + seTokensUnderlyingContractData, + tokensContractData, + noOuputTokenContractSharesToUnderlyingData, getPrice ] ); diff --git a/apps/evm/src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx b/apps/evm/src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx index a9f81777f..dcfd4d474 100644 --- a/apps/evm/src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx +++ b/apps/evm/src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx @@ -1,51 +1,65 @@ import { Card, Dd, Divider, Dl, DlGroup, Dt, Flex, P, Skeleton, SolidClock, Span, Tooltip } from '@gobob/ui'; import { formatDistanceToNow } from 'date-fns'; import { Trans } from '@lingui/macro'; +import { useParams } from 'next/navigation'; import { SpiceChip } from '../SpiceChip'; import { LoginButton, SignUpButton } from '@/components'; +import { getLocale } from '@/utils'; type Props = { isAuthenticated?: boolean; roundEndsAt?: string; votesRemaining?: number }; type UserVotingInfoProps = Props; -const UserVotingInfo = ({ isAuthenticated, roundEndsAt, votesRemaining }: UserVotingInfoProps): JSX.Element => ( - - <> - {isAuthenticated ? ( -
- -
- Votes Left: -
-
- -
-
-
- ) : ( - - - Log in - - - or - - - Create Account - - - )} - - Time left until voting round ends}> - - - {roundEndsAt ?

{formatDistanceToNow(roundEndsAt)}

: } -
-
- -
-); +const UserVotingInfo = ({ isAuthenticated, roundEndsAt, votesRemaining }: UserVotingInfoProps): JSX.Element => { + const { lang } = useParams(); + + return ( + + <> + {isAuthenticated ? ( +
+ +
+ Votes Left: +
+
+ +
+
+
+ ) : ( + + + Log in + + + or + + + Create Account + + + )} + + Time left until voting round ends}> + + + {roundEndsAt ? ( +

+ {formatDistanceToNow(roundEndsAt, { + locale: getLocale(lang as Parameters[0]) + })} +

+ ) : ( + + )} +
+
+ +
+ ); +}; export { UserVotingInfo }; diff --git a/apps/evm/src/app/[lang]/apps/hooks/useVote.tsx b/apps/evm/src/app/[lang]/apps/hooks/useVote.tsx index 7ad49ea52..b9b27771f 100644 --- a/apps/evm/src/app/[lang]/apps/hooks/useVote.tsx +++ b/apps/evm/src/app/[lang]/apps/hooks/useVote.tsx @@ -1,5 +1,4 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { useAccount } from 'wagmi'; import { useGetUser } from '@/hooks'; import { appsKeys, fusionKeys } from '@/lib/react-query'; @@ -9,10 +8,8 @@ const useVote = () => { const queryClient = useQueryClient(); const { data: user } = useGetUser(); - const { address } = useAccount(); - return useMutation({ - mutationKey: appsKeys.vote(address), + mutationKey: appsKeys.vote(user?.username), mutationFn: async ({ isRetract, refCode }: { refCode: string; isRetract: boolean }) => { if (isRetract) { return apiClient.retractVote(refCode); diff --git a/apps/evm/src/app/[lang]/fusion/Fusion.tsx b/apps/evm/src/app/[lang]/fusion/Fusion.tsx index 600001626..5cbd74ba0 100644 --- a/apps/evm/src/app/[lang]/fusion/Fusion.tsx +++ b/apps/evm/src/app/[lang]/fusion/Fusion.tsx @@ -1,25 +1,30 @@ 'use client'; -import { Card, Flex, H1, H2, Link, P } from '@gobob/ui'; -import { t, Trans } from '@lingui/macro'; +import { Card, Flex, H1, H2, Link, P, useMediaQuery } from '@gobob/ui'; +import { useIsClient, useLocalStorage, useSessionStorage } from 'usehooks-ts'; +import { Trans, t } from '@lingui/macro'; import { useLingui } from '@lingui/react'; import x from '@public/assets/x.png'; -import { useCallback, useEffect, useId, useState } from 'react'; -import { useLocalStorage, useSessionStorage } from 'usehooks-ts'; +import { useEffect, useId, useState } from 'react'; import { useAccount } from 'wagmi'; +import superchainEco from '@public/assets/partners/superchain-eco.png'; +import Image from 'next/image'; +import { useTheme } from 'styled-components'; import { useGetApps } from '../apps/hooks'; import { CommunityVoting, Leaderboard, + LotterySection, + OpSuperuserModal, Quest, Strategies, UserInfo, WelcomeBackModal, - WelcomeModal + WelcomeModal, + TopUserModal } from './components'; -import { LotterySection } from './components/LotterySections'; import { StyledBackground, StyledBannerImg, @@ -30,11 +35,11 @@ import { StyledMain, StyledStrategiesWrapper } from './Fusion.style'; -import { useGetQuests } from './hooks'; +import { useDismissOPSuperuserModal, useDismissTopUserModal, useGetQuests } from './hooks'; import { Geoblock } from '@/components'; -import { isClient, LocalStorageKey } from '@/constants'; -import { useGetUser } from '@/hooks'; +import { LocalStorageKey } from '@/constants'; +import { FeatureFlags, useFeatureFlag, useGetUser } from '@/hooks'; import { SessionStorageKey } from '@/types'; const Fusion = () => { @@ -43,9 +48,36 @@ const Fusion = () => { const { data: user } = useGetUser(); const { data: apps } = useGetApps(); const { data: quests } = useGetQuests(); + const { mutate: dismissTopUserModal } = useDismissTopUserModal(); + const { mutate: dismissOPSuperuserModal } = useDismissOPSuperuserModal(); + const isClient = useIsClient(); + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down('md')); + const isTop100SpiceUsersEnabled = useFeatureFlag(FeatureFlags.TOP_100_SPICE_USERS); + const isOPSuperusersEnabled = useFeatureFlag(FeatureFlags.OP_SUPERUSER); const questsSectionId = useId(); + const [showTopUserModal, setShowTopUserModal] = useLocalStorage(LocalStorageKey.SHOW_TOP_USER_MODAL, true, { + initializeWithValue: isClient + }); + + const [showOPSuperuserModal, setShowOPSuperuserModal] = useLocalStorage( + LocalStorageKey.SHOW_OP_SUPERUSER_MODAL, + true, + { initializeWithValue: isClient } + ); + + const onCloseTopUserModal = (shouldDismissTopUserModal: boolean) => { + setShowTopUserModal(false); + if (shouldDismissTopUserModal) dismissTopUserModal(); + }; + + const onCloseOPUserModal = (shouldDismissOPSuperuserModal: boolean) => { + setShowOPSuperuserModal(false); + if (shouldDismissOPSuperuserModal) dismissOPSuperuserModal(); + }; + const [scrollQuests, setScrollQuests] = useSessionStorage(SessionStorageKey.SCROLL_QUESTS, false, { initializeWithValue: isClient }); @@ -64,11 +96,13 @@ const Fusion = () => { const [isFusionWelcomeModalOpen, setFusionWelcomeModalOpen] = useState(!isHideFusionWelcomeModal); - const onPressBanner = useCallback( - () => window.open('https://x.com/build_on_bob', '_blank', 'noreferrer'), - // eslint-disable-next-line react-hooks/exhaustive-deps - [] - ); + const onPressXBanner = () => window.open('https://x.com/build_on_bob', '_blank', 'noreferrer'); + const onPressOPBanner = () => + window.open( + 'https://blog.gobob.xyz/posts/bob-hybrid-l2-joins-superchain-to-accelerate-bitcoin-defi', + '_blank', + 'noreferrer' + ); useEffect(() => { if (scrollQuests) { @@ -79,6 +113,10 @@ const Fusion = () => { const isAuthenticated = Boolean(user && address); const hasPastHarvest = user?.leaderboardRank && user.leaderboardRank.total_points > 0; + const shouldDisplayOPSuperuserModal = isOPSuperusersEnabled && showOPSuperuserModal && user?.notices.showIsOpUser; + const shouldDisplayTopUserModal = isTop100SpiceUsersEnabled && showTopUserModal && user?.notices.showIsFusionTopUser; + const isOpSuperuser = isOPSuperusersEnabled && user?.notices.isOpUser; + const isFusionTopUser = isTop100SpiceUsersEnabled && user?.is_fusion_top_user; return ( @@ -89,7 +127,11 @@ const Fusion = () => {

- BOB Fusion: The Final Season + {isFusionTopUser ? ( + You are one of the top 100 Spice holders in BOB Fusion + ) : ( + BOB Fusion: The Final Season + )}

@@ -107,24 +149,66 @@ const Fusion = () => {

- - -

- Follow us on X -

-

- To stay up-to date with the BOB ecosystem follow @build_on_bob. -

- -
-
+ {isOpSuperuser ? ( + + + + +

+ Bringing Bitcoin DeFi to the Superchain +

+

+ + To celebrate BOB joining the Superchain, you have qualified for an OP exclusive 50% bonus on + all Spice harvested between 9 December 2024 and 12 January 2025.{' '} + + Learn more + + +

+
+ {t(i18n)`Superchain +
+
+
+ ) : ( + + +

+ Follow us on X +

+

+ To stay up-to date with the BOB ecosystem follow @build_on_bob. +

+ +
+
+ )}
@@ -138,7 +222,11 @@ const Fusion = () => { {user ? ( - hasPastHarvest ? ( + shouldDisplayOPSuperuserModal ? ( + + ) : shouldDisplayTopUserModal ? ( + + ) : hasPastHarvest ? ( { const theme = useTheme(); const isClient = useIsClient(); const isMobile = useMediaQuery(theme.breakpoints.down('s')); + const { lang } = useParams(); const { data: votingAppsData } = useGetVotingApps(); const { i18n } = useLingui(); @@ -49,7 +52,12 @@ const CommunityVoting = ({}: CommunityVotingProps) => { > {votingAppsData?.roundEndsAt ? ( }> - {formatDistanceToNow(votingAppsData.roundEndsAt)} until voting round ends + + {formatDistanceToNow(votingAppsData.roundEndsAt, { + locale: getLocale(lang as Parameters[0]) + })}{' '} + until voting round ends + ) : ( diff --git a/apps/evm/src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx b/apps/evm/src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx index 6e845e7d9..cd16ca9cd 100644 --- a/apps/evm/src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx +++ b/apps/evm/src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx @@ -17,12 +17,11 @@ import { useLocale } from '@gobob/ui'; import { Plural, Trans } from '@lingui/macro'; -import { formatDistanceToNow } from 'date-fns'; import { useParams } from 'next/navigation'; -import { ROUND_END_TIME } from '../constants'; import { Ticket } from '../icons'; import confettiAnimationData from '../lotties/confettie.json'; +import { useTimeToNextDraw } from '../hooks'; import { StyledButton, StyledLottie, StyledPoints } from './LotteryModal.style'; @@ -50,6 +49,7 @@ const LotteryModal = ({ const { lang } = useParams(); const { locale } = useLocale(); const { data: user } = useGetUser(); + const { data: timeToNextDraw } = useTimeToNextDraw(lang as Parameters[0]); const { data: lotteryRollData, isIdle, @@ -67,7 +67,7 @@ const LotteryModal = ({ }> - new tickets drop in {formatDistanceToNow(ROUND_END_TIME)} + new tickets drop in {timeToNextDraw}

@@ -160,7 +160,7 @@ const LotteryModal = ({ }> - new tickets drop in {formatDistanceToNow(ROUND_END_TIME)} + new tickets drop in {timeToNextDraw}

{getHeaderText()} diff --git a/apps/evm/src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx b/apps/evm/src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx index 4e0d1519f..bf1173b3d 100644 --- a/apps/evm/src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx +++ b/apps/evm/src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx @@ -1,8 +1,8 @@ import { Chip, Flex, H2, P, Skeleton, SolidClock, Span } from '@gobob/ui'; import { Plural, t, Trans } from '@lingui/macro'; import { useLingui } from '@lingui/react'; +import { useParams } from 'next/navigation'; import lottery from '@public/assets/lottery.png'; -import { formatDistanceToNow } from 'date-fns'; import Image from 'next/image'; import { useState } from 'react'; import { useIsClient } from 'usehooks-ts'; @@ -10,7 +10,7 @@ import { useAccount } from 'wagmi'; import { LotteryModal } from './LotteryModal'; import { StyledButton, StyledCard } from './LotterySections.style'; -import { ROUND_END_TIME } from './constants'; +import { useTimeToNextDraw } from './hooks'; import { useGetUser, useLotteryStats } from '@/hooks'; @@ -21,6 +21,8 @@ const LotterySection = () => { const { data: user } = useGetUser(); const { data: lotteryStatsData, isError, isLoading } = useLotteryStats(); const { i18n } = useLingui(); + const { lang } = useParams(); + const { data: timeToNextDraw } = useTimeToNextDraw(lang as Parameters[0]); return ( <> @@ -46,11 +48,7 @@ const LotterySection = () => { }> - {isClient ? ( - {formatDistanceToNow(ROUND_END_TIME)} until next draw - ) : ( - - )} + {isClient ? {timeToNextDraw} until next draw : }

{!isClient || (!address && isClient) || !user || isError || isLoading ? ( diff --git a/apps/evm/src/app/[lang]/fusion/components/LotterySections/constants.ts b/apps/evm/src/app/[lang]/fusion/components/LotterySections/constants.ts deleted file mode 100644 index 614df1859..000000000 --- a/apps/evm/src/app/[lang]/fusion/components/LotterySections/constants.ts +++ /dev/null @@ -1,5 +0,0 @@ -const date = new Date(); - -date.setUTCHours(24, 0, 0, 0); - -export const ROUND_END_TIME = date; diff --git a/apps/evm/src/app/[lang]/fusion/components/LotterySections/hooks/index.ts b/apps/evm/src/app/[lang]/fusion/components/LotterySections/hooks/index.ts new file mode 100644 index 000000000..7b3fa89d1 --- /dev/null +++ b/apps/evm/src/app/[lang]/fusion/components/LotterySections/hooks/index.ts @@ -0,0 +1 @@ +export { useTimeToNextDraw } from './useTimeToNextDraw'; diff --git a/apps/evm/src/app/[lang]/fusion/components/LotterySections/hooks/useTimeToNextDraw.ts b/apps/evm/src/app/[lang]/fusion/components/LotterySections/hooks/useTimeToNextDraw.ts new file mode 100644 index 000000000..4a32eb019 --- /dev/null +++ b/apps/evm/src/app/[lang]/fusion/components/LotterySections/hooks/useTimeToNextDraw.ts @@ -0,0 +1,22 @@ +import { useQuery } from '@tanstack/react-query'; +import { formatDistanceToNow } from 'date-fns'; + +import { getLocale } from '@/utils'; +import { INTERVAL } from '@/constants'; +import { fusionKeys } from '@/lib/react-query'; + +const useTimeToNextDraw = (lang: 'en' | 'zh' = 'en') => { + return useQuery({ + queryKey: fusionKeys.lotteryTimeToNextDraw(), + queryFn: () => { + const date = new Date(); + + date.setUTCHours(24, 0, 0, 0); + + return formatDistanceToNow(date, { locale: getLocale(lang as Parameters[0]) }); + }, + refetchInterval: INTERVAL.MINUTE + }); +}; + +export { useTimeToNextDraw }; diff --git a/apps/evm/src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx b/apps/evm/src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx new file mode 100644 index 000000000..619419bed --- /dev/null +++ b/apps/evm/src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx @@ -0,0 +1,62 @@ +/* eslint-disable jsx-a11y/label-has-associated-control */ +import { Button, Flex, H3, Modal, ModalBody, ModalFooter, ModalProps, P, Switch } from '@gobob/ui'; +import { useState } from 'react'; +import { t, Trans } from '@lingui/macro'; +import { useLingui } from '@lingui/react'; +import Image from 'next/image'; +import optimismCity from '@public/assets/optimism-city.png'; + +type Props = { onClose: (hideForever: boolean) => void }; + +type InheritAttrs = Omit; + +type OpSuperuserModalProps = Props & InheritAttrs; + +const OpSuperuserModal = ({ onClose, ...props }: OpSuperuserModalProps): JSX.Element => { + const [shouldHideForever, setShouldHideForever] = useState(false); + const { i18n } = useLingui(); + + return ( + + {t(i18n)`Optimism + +

+ Exclusive Spice Bonus For Superchain Users +

+ +

+ + BOB is bringing Bitcoin DeFi to the Superchain, and to celebrate, active Superchain ecosystem users like + you have unlocked an exclusive BOB Spice bonus. + +

+

+ + All Spice you harvest between 9 December 2024 and 12 January 2025 will receive an exclusive 50% bonus, + only available to OP airdrop recipients. + +

+
+
+ + setShouldHideForever(e.target.checked)}> + Don't show this message again + + + +
+ ); +}; + +export { OpSuperuserModal }; diff --git a/apps/evm/src/app/[lang]/fusion/components/OpSuperuserModal/index.tsx b/apps/evm/src/app/[lang]/fusion/components/OpSuperuserModal/index.tsx new file mode 100644 index 000000000..8813145c5 --- /dev/null +++ b/apps/evm/src/app/[lang]/fusion/components/OpSuperuserModal/index.tsx @@ -0,0 +1 @@ +export { OpSuperuserModal } from './OpSuperuserModal'; diff --git a/apps/evm/src/app/[lang]/fusion/components/Quest/Quest.tsx b/apps/evm/src/app/[lang]/fusion/components/Quest/Quest.tsx index 3dc0346bb..5eadd020c 100644 --- a/apps/evm/src/app/[lang]/fusion/components/Quest/Quest.tsx +++ b/apps/evm/src/app/[lang]/fusion/components/Quest/Quest.tsx @@ -3,18 +3,20 @@ import { formatDistanceToNow } from 'date-fns'; import { useTheme } from 'styled-components'; import { t, Trans } from '@lingui/macro'; import { useIsClient } from 'usehooks-ts'; +import { useParams } from 'next/navigation'; import Image from 'next/image'; import { useLingui } from '@lingui/react'; import welcomeSeason3 from '@public/assets/welcome-season-3.jpg'; import { StyledCard, StyledDescription, StyledIntract, StyledOpacityOverlay } from './Quest.style'; -import { QuestS3Response } from '@/utils'; +import { getLocale, QuestS3Response } from '@/utils'; type QuestProps = { quests: QuestS3Response | undefined; id: string }; const Quest = ({ id, quests }: QuestProps) => { const theme = useTheme(); + const { lang } = useParams(); const isClient = useIsClient(); const isMobile = useMediaQuery(theme.breakpoints.down('s')); @@ -53,7 +55,12 @@ const Quest = ({ id, quests }: QuestProps) => { {intractQuest ? ( }> {isActive ? ( - {formatDistanceToNow(intractQuest.end_date)} until quest ends + + {formatDistanceToNow(intractQuest.end_date, { + locale: getLocale(lang as Parameters[0]) + })}{' '} + until quest ends + ) : ( Coming Soon )} diff --git a/apps/evm/src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx b/apps/evm/src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx new file mode 100644 index 000000000..c4df01d79 --- /dev/null +++ b/apps/evm/src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx @@ -0,0 +1,91 @@ +import { Button, Flex, H3, Link, Modal, ModalBody, ModalFooter, ModalProps, P, Switch } from '@gobob/ui'; +import { colors } from '@gobob/ui/src/theme/themes/bob/colors'; +import { t, Trans } from '@lingui/macro'; +import { useState } from 'react'; +import { PopupModal, useCalendlyEventListener } from 'react-calendly'; +import top100SpiceUser from '@public/assets/top-100-spice.webp'; +import Image from 'next/image'; +import { useLingui } from '@lingui/react'; +// import { sendGTMEvent } from '@next/third-parties/google'; + +type Props = { + onClose: (shouldDismissTopUserModal: boolean) => void; +}; + +type InheritAttrs = Omit; + +type TopUserModalProps = Props & InheritAttrs; + +const TopUserModal = ({ onClose, isOpen, ...props }: TopUserModalProps): JSX.Element => { + const [isCalendlyOpen, setIsCalendlyOpen] = useState(false); + const [shouldHideForever, setShouldHideForever] = useState(false); + const { i18n } = useLingui(); + + useCalendlyEventListener({ + onEventScheduled: () => { + // sendGTMEvent(e.data); // send `.event` and `.payload` + onClose(true); + } + }); + + return ( + <> + + {t(i18n)`Top + +

+ You are one of the top 100 Spice holders in BOB Fusion +

+

+ + As one of our most important community members, we would love the opportunity to gain your input on the + BOB ecosystem and our future plans. + +

+

+ + BOB co-founder, Alexei Zamyatin, would like to invite you + to a private 1-to-1 call to hear your thoughts on BOB and Bitcoin DeFi. If you are interested, please + click the button below to book a call at a time that suits you. + +

+
+ + + + + + setShouldHideForever(e.target.checked)}> + Don't show this message again + + +
+ setIsCalendlyOpen(false)} + /> + + ); +}; + +export { TopUserModal }; diff --git a/apps/evm/src/app/[lang]/fusion/components/TopUserModal/index.ts b/apps/evm/src/app/[lang]/fusion/components/TopUserModal/index.ts new file mode 100644 index 000000000..0500ddb6d --- /dev/null +++ b/apps/evm/src/app/[lang]/fusion/components/TopUserModal/index.ts @@ -0,0 +1 @@ +export { TopUserModal } from './TopUserModal'; diff --git a/apps/evm/src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx b/apps/evm/src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx index 9b2d646e8..81f6928dc 100644 --- a/apps/evm/src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx +++ b/apps/evm/src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx @@ -23,7 +23,7 @@ import { useLingui } from '@lingui/react'; import { useQuery } from '@tanstack/react-query'; import { useParams, useRouter } from 'next/navigation'; import { useState } from 'react'; -import { useCopyToClipboard, useSessionStorage } from 'usehooks-ts'; +import { useCopyToClipboard, useLocalStorage, useSessionStorage } from 'usehooks-ts'; import { Barometer } from './Barometer'; import { MultipliersModal } from './MultipliersModal'; @@ -44,10 +44,11 @@ import { UserReferralModal } from './UserReferralModal'; import { AppData } from '@/app/[lang]/apps/hooks'; import { LoginSection, SignUpButton, SpiceAmount } from '@/components'; -import { INTERVAL, isClient, RoutesPath } from '@/constants'; +import { INTERVAL, isClient, LocalStorageKey, RoutesPath } from '@/constants'; import { fusionKeys } from '@/lib/react-query'; import { SessionStorageKey } from '@/types'; import { apiClient, QuestS3Response, UserResponse } from '@/utils'; +import { FeatureFlags, useFeatureFlag } from '@/hooks'; type UserInfoProps = { user?: UserResponse; @@ -65,6 +66,9 @@ const UserInfo = ({ apps, user, quests, isAuthenticated }: UserInfoProps) => { const [, setScrollQuests] = useSessionStorage(SessionStorageKey.SCROLL_QUESTS, false, { initializeWithValue: isClient }); + const [, setShowTopUserModal] = useLocalStorage(LocalStorageKey.SHOW_TOP_USER_MODAL, true, { + initializeWithValue: isClient + }); const [, copy] = useCopyToClipboard(); const { data: tvlLevel, isLoading: isLoadingTvlLevel } = useQuery({ @@ -104,9 +108,27 @@ const UserInfo = ({ apps, user, quests, isAuthenticated }: UserInfoProps) => { ? Number(tvlLevel.tvlGoal) : currentTvl + currentTvl * 0.2; + const isTop100SpiceUsersEnabled = useFeatureFlag(FeatureFlags.TOP_100_SPICE_USERS); + const isOPSuperusersEnabled = useFeatureFlag(FeatureFlags.OP_SUPERUSER); + + const isOpSuperuser = isOPSuperusersEnabled && user?.notices.isOpUser; + const showFusionTopUser = isTop100SpiceUsersEnabled && user?.notices.showIsFusionTopUser; + return ( - + {showFusionTopUser && ( +

+ We would love to hear your thoughts on the BOB ecosystem and Bitcoin DeFi. +

+ )} + + {showFusionTopUser && ( + + + + )}
@@ -221,9 +243,15 @@ const UserInfo = ({ apps, user, quests, isAuthenticated }: UserInfoProps) => { {hasReferrals && ( @@ -248,7 +276,7 @@ const UserInfo = ({ apps, user, quests, isAuthenticated }: UserInfoProps) => { /> )} - + {isLoadingTvlLevel ? ( diff --git a/apps/evm/src/app/[lang]/fusion/components/UserInfo/UserInfoCard.tsx b/apps/evm/src/app/[lang]/fusion/components/UserInfo/UserInfoCard.tsx index dc88c192f..fada0152f 100644 --- a/apps/evm/src/app/[lang]/fusion/components/UserInfo/UserInfoCard.tsx +++ b/apps/evm/src/app/[lang]/fusion/components/UserInfo/UserInfoCard.tsx @@ -12,8 +12,8 @@ type InheritAttrs = Omit; type UserInfoCardProps = Props & InheritAttrs; const UserInfoCard = ({ description, title, tooltipLabel, children, ...props }: UserInfoCardProps) => ( - - + +
{title}
{tooltipLabel && ( diff --git a/apps/evm/src/app/[lang]/fusion/components/index.tsx b/apps/evm/src/app/[lang]/fusion/components/index.tsx index a39ad8715..31eebad62 100644 --- a/apps/evm/src/app/[lang]/fusion/components/index.tsx +++ b/apps/evm/src/app/[lang]/fusion/components/index.tsx @@ -1,7 +1,10 @@ -export * from './UserInfo'; +export * from './CommunityVoting'; export * from './Leaderboard'; +export * from './LotterySections'; +export * from './OpSuperuserModal'; +export * from './TopUserModal'; +export * from './Quest'; +export * from './Strategies'; +export * from './UserInfo'; export * from './WelcomeBackModal'; export * from './WelcomeModal'; -export * from './CommunityVoting'; -export * from './Strategies'; -export * from './Quest'; diff --git a/apps/evm/src/app/[lang]/fusion/hooks/index.ts b/apps/evm/src/app/[lang]/fusion/hooks/index.ts index 66bc75777..9161d1746 100644 --- a/apps/evm/src/app/[lang]/fusion/hooks/index.ts +++ b/apps/evm/src/app/[lang]/fusion/hooks/index.ts @@ -1,2 +1,4 @@ export * from './useGetTokensInfo'; export * from './useGetQuests'; +export * from './useDismissTopUserModal'; +export * from './useDismissOPSuperuserModal'; diff --git a/apps/evm/src/app/[lang]/fusion/hooks/useDismissOPSuperuserModal.tsx b/apps/evm/src/app/[lang]/fusion/hooks/useDismissOPSuperuserModal.tsx new file mode 100644 index 000000000..9809d8529 --- /dev/null +++ b/apps/evm/src/app/[lang]/fusion/hooks/useDismissOPSuperuserModal.tsx @@ -0,0 +1,32 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; + +import { useGetUser } from '@/hooks'; +import { fusionKeys } from '@/lib/react-query'; +import { apiClient, UserResponse } from '@/utils'; + +const useDismissOPSuperuserModal = () => { + const { data: user } = useGetUser(); + const queryClient = useQueryClient(); + + return useMutation({ + mutationKey: fusionKeys.opSuperuserModal(user?.username), + mutationFn: () => apiClient.dismissOPUserModal(), + onSuccess() { + queryClient.setQueryData( + fusionKeys.user(), + (oldData: UserResponse): UserResponse => ({ + ...oldData, + notices: { + ...oldData.notices, + showIsOpUser: false + } + }) + ); + }, + onSettled() { + queryClient.refetchQueries({ queryKey: fusionKeys.user() }); + } + }); +}; + +export { useDismissOPSuperuserModal }; diff --git a/apps/evm/src/app/[lang]/fusion/hooks/useDismissTopUserModal.tsx b/apps/evm/src/app/[lang]/fusion/hooks/useDismissTopUserModal.tsx new file mode 100644 index 000000000..677b33d55 --- /dev/null +++ b/apps/evm/src/app/[lang]/fusion/hooks/useDismissTopUserModal.tsx @@ -0,0 +1,32 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; + +import { useGetUser } from '@/hooks'; +import { fusionKeys } from '@/lib/react-query'; +import { apiClient, UserResponse } from '@/utils'; + +const useDismissTopUserModal = () => { + const { data: user } = useGetUser(); + const queryClient = useQueryClient(); + + return useMutation({ + mutationKey: fusionKeys.topUserModal(user?.username), + mutationFn: () => apiClient.dismissTopUserModal(), + onSuccess() { + queryClient.setQueryData( + fusionKeys.user(), + (oldData: UserResponse): UserResponse => ({ + ...oldData, + notices: { + ...oldData.notices, + showIsFusionTopUser: false + } + }) + ); + }, + onSettled() { + queryClient.refetchQueries({ queryKey: fusionKeys.user() }); + } + }); +}; + +export { useDismissTopUserModal }; diff --git a/apps/evm/src/app/[lang]/index.css b/apps/evm/src/app/[lang]/index.css index efc40e805..0a23e7a5f 100644 --- a/apps/evm/src/app/[lang]/index.css +++ b/apps/evm/src/app/[lang]/index.css @@ -9,7 +9,7 @@ font-weight: 400; color: #ffffff; - color-scheme: light dark; + /* color-scheme: light dark; */ font-synthesis: none; text-rendering: optimizeLegibility; diff --git a/apps/evm/src/components/Layout/FusionPopover.tsx b/apps/evm/src/components/Layout/FusionPopover.tsx index ae9f15b79..6c6a96bed 100644 --- a/apps/evm/src/components/Layout/FusionPopover.tsx +++ b/apps/evm/src/components/Layout/FusionPopover.tsx @@ -10,7 +10,7 @@ import { PopoverTrigger, useLocale } from '@gobob/ui'; -import { Spice } from '@gobob/icons'; +import { Optimism, Spice } from '@gobob/icons'; import { useFocusRing } from '@react-aria/focus'; import { Trans } from '@lingui/macro'; @@ -20,11 +20,12 @@ import { SpiceAmount } from '../SpiceAmount'; import { StyledChip, StyledContentWrapper, StyledHarvestCard, StyledOpacityOverlay } from './FusionPopover.style'; -import { useGetUser, useHaltedLockedTokens, useLockedTokens } from '@/hooks'; +import { FeatureFlags, useFeatureFlag, useGetUser, useHaltedLockedTokens, useLockedTokens } from '@/hooks'; const FusionPopover = (): JSX.Element | null => { const { data: user } = useGetUser(); const { locale } = useLocale(); + const isOPSuperusersEnabled = useFeatureFlag(FeatureFlags.OP_SUPERUSER); useLockedTokens(); useHaltedLockedTokens(); @@ -34,6 +35,7 @@ const FusionPopover = (): JSX.Element | null => { if (!user) return null; const season3leaderboardData = user.season3Data.s3LeaderboardData[0]; + const isOpSuperuser = user?.notices.isOpUser; const season3TotalPoints = season3leaderboardData?.total_points; @@ -41,7 +43,17 @@ const FusionPopover = (): JSX.Element | null => { <> - + {Intl.NumberFormat(locale, { notation: 'compact' }).format(season3TotalPoints!)} @@ -71,6 +83,33 @@ const FusionPopover = (): JSX.Element | null => {

#{season3leaderboardData?.group_rank}

+ {isOpSuperuser && ( + + + + +

+ + Active Superchain users who have received any of the five OP Airdrops qualify for an exclusive 50% + bonus on all Spice harvested between 9 December 2024 and 12 January 2025. The bonus will be + applied at the end of the campaign. + +

+
+
+ )} <>

diff --git a/apps/evm/src/constants/local-storage.ts b/apps/evm/src/constants/local-storage.ts index 217a4f961..b02fa1a75 100644 --- a/apps/evm/src/constants/local-storage.ts +++ b/apps/evm/src/constants/local-storage.ts @@ -4,6 +4,8 @@ enum LocalStorageKey { HIDE_FAULT_PROOFS_NOTICE = 'hideFaultsProofsNotice', HIDE_FUSION_WELCOME_MODAL = 'hideFusionWelcomeModal', HIDE_FUSION_WELCOME_BACK_MODAL = 'hideFusionWelcomeBackModal', - PROMPT_SWITCH_CHAIN = 'promptSwitchChain' + PROMPT_SWITCH_CHAIN = 'promptSwitchChain', + SHOW_TOP_USER_MODAL = 'showTopUserModal', + SHOW_OP_SUPERUSER_MODAL = 'showOPSuperuserModal' } export { LocalStorageKey }; diff --git a/apps/evm/src/hooks/useFeatureFlag.ts b/apps/evm/src/hooks/useFeatureFlag.ts index 9eefc3179..220b69b9c 100644 --- a/apps/evm/src/hooks/useFeatureFlag.ts +++ b/apps/evm/src/hooks/useFeatureFlag.ts @@ -2,11 +2,15 @@ import { useMemo } from 'react'; enum FeatureFlags { // TODO: replace with real feature flag - EMPTY + EMPTY, + TOP_100_SPICE_USERS, + OP_SUPERUSER } const featureFlags: Record = { - [FeatureFlags.EMPTY]: process.env.NEXT_PUBLIC_FEATURE_FLAG_EMPTY + [FeatureFlags.EMPTY]: process.env.NEXT_PUBLIC_FEATURE_FLAG_EMPTY, + [FeatureFlags.TOP_100_SPICE_USERS]: process.env.NEXT_PUBLIC_FEATURE_FLAG_TOP_100_SPICE_USERS, + [FeatureFlags.OP_SUPERUSER]: process.env.NEXT_PUBLIC_FEATURE_FLAG_OP_SUPERUSER }; const useFeatureFlag = (feature: FeatureFlags): boolean => diff --git a/apps/evm/src/lib/react-query/keys.ts b/apps/evm/src/lib/react-query/keys.ts index bfc42859b..f66af2e6a 100644 --- a/apps/evm/src/lib/react-query/keys.ts +++ b/apps/evm/src/lib/react-query/keys.ts @@ -72,7 +72,7 @@ export const appsKeys = { apps: () => ['apps'], appsVotes: (username: string | undefined) => [...appsKeys.apps(), 'votes', username], appsResultVotes: () => [...appsKeys.apps(), 'result-votes'], - vote: (address: Address | undefined) => [appsKeys.apps(), 'vote', address] + vote: (username: string | undefined) => [appsKeys.apps(), 'vote', username] as string[] }; export const fusionKeys = { @@ -87,5 +87,9 @@ export const fusionKeys = { quests: () => [...fusionKeys.fusion(), 'quests'], tvlLevel: () => [...fusionKeys.fusion(), 'tvl-level'], lotteryStats: (username: string | undefined) => [...fusionKeys.fusion(), 'lottery-stats', username] as string[], - lotteryRoll: (username: string | undefined) => [...fusionKeys.fusion(), 'lottery-roll', username] as string[] + lotteryRoll: (username: string | undefined) => [...fusionKeys.fusion(), 'lottery-roll', username] as string[], + lotteryTimeToNextDraw: () => [...fusionKeys.fusion(), 'lottery-time-to-next-draw'], + topUserModal: (username: string | undefined) => [...fusionKeys.fusion(), 'top-user-modal', username] as string[], + opSuperuserModal: (username: string | undefined) => + [...fusionKeys.fusion(), 'op-superuser-modal', username] as string[] }; diff --git a/apps/evm/src/locales/en.po b/apps/evm/src/locales/en.po index ccbe6d520..1b39451c9 100644 --- a/apps/evm/src/locales/en.po +++ b/apps/evm/src/locales/en.po @@ -22,26 +22,34 @@ msgstr ", due to the challenge period" #~ msgid "{0}" #~ msgstr "{0}" -#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:49 +#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:52 msgid "{0} ago" msgstr "{0} ago" -#: src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx:47 +#: src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx:52 msgid "{0} remaining" msgstr "{0} remaining" #: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:50 -msgid "{0} until next draw" -msgstr "{0} until next draw" +#~ msgid "{0} until next draw" +#~ msgstr "{0} until next draw" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:56 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:58 msgid "{0} until quest ends" msgstr "{0} until quest ends" -#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:52 +#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:55 msgid "{0} until voting round ends" msgstr "{0} until voting round ends" +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:245 +#~ msgid "{0}Share this link with a friend and when they sign up, you will receive {1} of their Spice harvest as a bonus, plus {2} of the Spice harvest of anyone they refer" +#~ msgstr "{0}Share this link with a friend and when they sign up, you will receive {1} of their Spice harvest as a bonus, plus {2} of the Spice harvest of anyone they refer" + +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:51 +msgid "{timeToNextDraw} until next draw" +msgstr "{timeToNextDraw} until next draw" + #: src/app/[lang]/fusion/components/UserInfo/MultipliersModal.tsx:228 msgid "* The multipliers displayed are subject to change based on the payout structure of the respective projects." msgstr "* The multipliers displayed are subject to change based on the payout structure of the respective projects." @@ -50,7 +58,7 @@ msgstr "* The multipliers displayed are subject to change based on the payout st #~ msgid "< 1 minute" #~ msgstr "< 1 minute" -#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:59 +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:57 msgid "<0>{0} {1, plural, one {Ticket} other {Tickets}} Remaining" msgstr "<0>{0} {1, plural, one {Ticket} other {Tickets}} Remaining" @@ -62,12 +70,20 @@ msgstr "<0>{0} {1, plural, one {Ticket} other {Tickets}} Remaining" msgid "<0>{rollsRemaining}/3 {0, plural, one {Ticket} other {Tickets}} Remaining" msgstr "<0>{rollsRemaining}/3 {0, plural, one {Ticket} other {Tickets}} Remaining" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:54 +#~ msgid "<0>Enhanced Referral Bonuses: Earn even more from your network by sharing your unique referral link." +#~ msgstr "<0>Enhanced Referral Bonuses: Earn even more from your network by sharing your unique referral link." + +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:60 +#~ msgid "<0>Extra Rewards for TVL Achievements: Benefit from additional incentives as BOB's Total Value Locked (TVL) milestones are reached." +#~ msgstr "<0>Extra Rewards for TVL Achievements: Benefit from additional incentives as BOB's Total Value Locked (TVL) milestones are reached." + #: src/app/[lang]/fusion/components/Strategies/Strategies.tsx:21 #: src/app/[lang]/fusion/components/Strategies/Strategies.tsx:60 msgid "<0>Stake your BTC with 1-click and receive BTC LSTs on BOB." msgstr "<0>Stake your BTC with 1-click and receive BTC LSTs on BOB." -#: src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx:44 +#: src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx:48 msgid "2 hours" msgstr "2 hours" @@ -80,7 +96,7 @@ msgstr "3rd Party" msgid "404 Error" msgstr "404 Error" -#: src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx:44 +#: src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx:48 msgid "7 days" msgstr "7 days" @@ -89,6 +105,11 @@ msgstr "7 days" msgid "About" msgstr "About" +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:248 +#: src/components/Layout/FusionPopover.tsx:99 +msgid "Active Superchain users who have received any of the five OP Airdrops qualify for an exclusive 50% bonus on all Spice harvested between 9 December 2024 and 12 January 2025. The bonus will be applied at the end of the campaign." +msgstr "Active Superchain users who have received any of the five OP Airdrops qualify for an exclusive 50% bonus on all Spice harvested between 9 December 2024 and 12 January 2025. The bonus will be applied at the end of the campaign." + #: src/app/[lang]/(bridge)/components/GatewayTransactionDetails/GatewayFeeSettingsModal.tsx:106 msgid "Adjusting the fee rate affects how quickly your Bitcoin transaction is confirmed. Lower fees may lead to significant delays in confirmation time." msgstr "Adjusting the fee rate affects how quickly your Bitcoin transaction is confirmed. Lower fees may lead to significant delays in confirmation time." @@ -101,6 +122,14 @@ msgstr "Advanced Fee Settings" msgid "All Apps" msgstr "All Apps" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:43 +msgid "All Spice you harvest between 9 December 2024 and 12 January 2025 will receive an exclusive 50% bonus, only available to OP airdrop recipients." +msgstr "All Spice you harvest between 9 December 2024 and 12 January 2025 will receive an exclusive 50% bonus, only available to OP airdrop recipients." + +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:37 +#~ msgid "All Spice you harvest during between 9 December 2024 and 12 January 2025 will receive an exclusive 50% bonus, only available to OP airdrop recipients." +#~ msgstr "All Spice you harvest during between 9 December 2024 and 12 January 2025 will receive an exclusive 50% bonus, only available to OP airdrop recipients." + #: src/components/LoginSection/LoginSection.tsx:11 msgid "Already harvesting?" msgstr "Already harvesting?" @@ -111,8 +140,8 @@ msgid "Amount" msgstr "Amount" #: src/app/[lang]/(bridge)/components/BannerCarousel/OKXCryptopediaBanner.tsx:26 -msgid "An Exclusive Bitcoin Staking and DeFi Campaign" -msgstr "An Exclusive Bitcoin Staking and DeFi Campaign" +#~ msgid "An Exclusive Bitcoin Staking and DeFi Campaign" +#~ msgstr "An Exclusive Bitcoin Staking and DeFi Campaign" #: src/components/BannerCarousel/BinanceCampaignBanner.tsx:25 #~ msgid "An exclusive quest campaign." @@ -136,14 +165,22 @@ msgstr "Approve" msgid "Apps" msgstr "Apps" -#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:30 +#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:33 msgid "Apps leaderboard hero" msgstr "Apps leaderboard hero" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:175 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:197 msgid "Apps Used" msgstr "Apps Used" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:46 +#~ msgid "As an OP Superuser, you unlock special rewards when you join BOB's Fusion campaign and explore the future of Bitcoin DeFi." +#~ msgstr "As an OP Superuser, you unlock special rewards when you join BOB's Fusion campaign and explore the future of Bitcoin DeFi." + +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:49 +msgid "As one of our most important community members, we would love the opportunity to gain your input on the BOB ecosystem and our future plans." +msgstr "As one of our most important community members, we would love the opportunity to gain your input on the BOB ecosystem and our future plans." + #: src/app/[lang]/fusion/components/UserInfo/MultipliersModal.tsx:64 msgid "Asset" msgstr "Asset" @@ -204,12 +241,16 @@ msgstr "BOB" msgid "BOB Bridge" msgstr "BOB Bridge" +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:55 +msgid "BOB co-founder, <0>Alexei Zamyatin, would like to invite you to a private 1-to-1 call to hear your thoughts on BOB and Bitcoin DeFi. If you are interested, please click the button below to book a call at a time that suits you." +msgstr "BOB co-founder, <0>Alexei Zamyatin, would like to invite you to a private 1-to-1 call to hear your thoughts on BOB and Bitcoin DeFi. If you are interested, please click the button below to book a call at a time that suits you." + #: src/app/[lang]/(bridge)/components/BannerCarousel/OKXCryptopediaBanner.tsx:22 -msgid "BOB Ecosystem on OKX Cryptopedia" -msgstr "BOB Ecosystem on OKX Cryptopedia" +#~ msgid "BOB Ecosystem on OKX Cryptopedia" +#~ msgstr "BOB Ecosystem on OKX Cryptopedia" #: src/app/[lang]/(bridge)/components/BannerCarousel/FusionBanner.tsx:22 -#: src/app/[lang]/fusion/Fusion.tsx:92 +#: src/app/[lang]/fusion/Fusion.tsx:133 msgid "BOB Fusion: The Final Season" msgstr "BOB Fusion: The Final Season" @@ -222,15 +263,19 @@ msgstr "BOB Gateway allows you to swap BTC on Bitcoin to ETH on BOB" #~ msgstr "BOB Gateway allows you to swap BTC on Bitcoin to ETH on BOB." #: src/app/[lang]/(bridge)/components/BannerCarousel/OnrampBanner.tsx:17 -msgid "BOB Gateway is live!" -msgstr "BOB Gateway is live!" +#~ msgid "BOB Gateway is live!" +#~ msgstr "BOB Gateway is live!" #: src/app/[lang]/layout.tsx:33 #: src/app/[lang]/layout.tsx:52 msgid "BOB is a hybrid L2 that combines the security of Bitcoin with the versatility of Ethereum" msgstr "BOB is a hybrid L2 that combines the security of Bitcoin with the versatility of Ethereum" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:273 +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:37 +msgid "BOB is bringing Bitcoin DeFi to the Superchain, and to celebrate, active Superchain ecosystem users like you have unlocked an exclusive BOB Spice bonus." +msgstr "BOB is bringing Bitcoin DeFi to the Superchain, and to celebrate, active Superchain ecosystem users like you have unlocked an exclusive BOB Spice bonus." + +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:301 msgid "BOB TVL Progress" msgstr "BOB TVL Progress" @@ -238,6 +283,22 @@ msgstr "BOB TVL Progress" #~ msgid "BOB Wallet" #~ msgstr "BOB Wallet" +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:54 +#~ msgid "Book a call" +#~ msgstr "Book a call" + +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:65 +msgid "Book A Call" +msgstr "Book A Call" + +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:128 +msgid "Book a call with the founders" +msgstr "Book a call with the founders" + +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:49 +#~ msgid "Book Meeting" +#~ msgstr "Book Meeting" + #: src/app/[lang]/(bridge)/bridge/page.tsx:14 #: src/app/[lang]/page.tsx:15 #: src/components/Layout/Header.tsx:67 @@ -250,7 +311,7 @@ msgstr "Bridge" msgid "Bridge Asset" msgstr "Bridge Asset" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:168 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:190 msgid "Bridge Assets" msgstr "Bridge Assets" @@ -279,6 +340,10 @@ msgstr "Bridge your assets to BOB to start harvesting Spice.<0/>TIP: Some assets msgid "Bridging ALEX is disabled because Alex Lab suffered an exploit involving the XLink bridge. For more information, kindly refer to this <0>announcement." msgstr "Bridging ALEX is disabled because Alex Lab suffered an exploit involving the XLink bridge. For more information, kindly refer to this <0>announcement." +#: src/app/[lang]/fusion/Fusion.tsx:165 +msgid "Bringing Bitcoin DeFi to the Superchain" +msgstr "Bringing Bitcoin DeFi to the Superchain" + #: src/app/[lang]/(bridge)/components/GatewayTransactionDetails/GatewayTransactionDetails.tsx:76 msgid "BTC bridge is currently unavailable. This may be due to: {0}. Please try again later." msgstr "BTC bridge is currently unavailable. This may be due to: {0}. Please try again later." @@ -337,7 +402,7 @@ msgid "Combining liquidity and security from Bitcoin and Ethereum. Mainnet live! msgstr "Combining liquidity and security from Bitcoin and Ethereum. Mainnet live!" #: src/app/[lang]/(bridge)/bridge/components/ExternalBridgeForm/ExternalBridgeCard.tsx:123 -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:58 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:65 #: src/app/[lang]/fusion/components/Strategies/Strategies.tsx:210 msgid "Coming Soon" msgstr "Coming Soon" @@ -351,7 +416,7 @@ msgid "Common Prefix auditor" msgstr "Common Prefix auditor" #: src/app/[lang]/apps/components/HeroBanner/HeroBanner.tsx:45 -#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:58 +#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:66 msgid "Community Voting" msgstr "Community Voting" @@ -359,7 +424,7 @@ msgstr "Community Voting" msgid "Community Voting Information" msgstr "Community Voting Information" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:72 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:79 msgid "Complete a variety of on- and off-chain quests using Intract and the BOB Stake Portal to harvest an additional 62,500 Spice." msgstr "Complete a variety of on- and off-chain quests using Intract and the BOB Stake Portal to harvest an additional 62,500 Spice." @@ -402,19 +467,19 @@ msgstr "Connected with <0>{wallet}" #~ msgid "Copy Address" #~ msgstr "Copy Address" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:240 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:268 msgid "Copy referral URL" msgstr "Copy referral URL" -#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:36 +#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:41 msgid "Create Account" msgstr "Create Account" -#: src/components/Layout/FusionPopover.tsx:63 +#: src/components/Layout/FusionPopover.tsx:70 msgid "Current Harvest" msgstr "Current Harvest" -#: src/components/Layout/FusionPopover.tsx:70 +#: src/components/Layout/FusionPopover.tsx:77 msgid "Current Leaderboard Rank" msgstr "Current Leaderboard Rank" @@ -422,7 +487,7 @@ msgstr "Current Leaderboard Rank" msgid "Current Spice" msgstr "Current Spice" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:312 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:340 msgid "Current TVL:" msgstr "Current TVL:" @@ -435,7 +500,7 @@ msgid "Deploy high priority assets into high priority DeFi protocols to maximize msgstr "Deploy high priority assets into high priority DeFi protocols to maximize your Spice harvest." #: src/app/[lang]/(bridge)/bridge/Bridge.tsx:128 -#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:38 +#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:41 msgid "Deposit" msgstr "Deposit" @@ -488,6 +553,8 @@ msgstr "Docs" msgid "Don't believe in the Bitcoin Renaissance? You can withdraw your funds from the contract to your wallet on Ethereum. You will no longer earn Spice if you withdraw your assets. <0>You will keep the Spice harvested so far." msgstr "Don't believe in the Bitcoin Renaissance? You can withdraw your funds from the contract to your wallet on Ethereum. You will no longer earn Spice if you withdraw your assets. <0>You will keep the Spice harvested so far." +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:52 +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:72 #: src/app/[lang]/fusion/components/WelcomeModal/WelcomeModal.tsx:58 msgid "Don't show this message again" msgstr "Don't show this message again" @@ -546,6 +613,10 @@ msgstr "Estimated within 30 minutes" msgid "Estimated within the next block" msgstr "Estimated within the next block" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:33 +msgid "Exclusive Spice Bonus For Superchain Users" +msgstr "Exclusive Spice Bonus For Superchain Users" + #: src/connect-ui/component/ConnectModal/ConnectModal.tsx:138 #: src/connect-ui/component/ConnectModal/ConnectModal.tsx:174 msgid "Failed to connect to {0}" @@ -584,7 +655,7 @@ msgstr "Featured Assets" msgid "Fee" msgstr "Fee" -#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:69 +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:67 msgid "Feeling lucky? Try your luck with the daily lottery!<0/>Participate in Fusion voting to receive 3 lottery tickets each day." msgstr "Feeling lucky? Try your luck with the daily lottery!<0/>Participate in Fusion voting to receive 3 lottery tickets each day." @@ -609,7 +680,7 @@ msgid "Follow the steps of <0>this guide to provide liquity into a DEX pool msgstr "Follow the steps of <0>this guide to provide liquity into a DEX pool on Oku." #: src/app/[lang]/(bridge)/components/BannerCarousel/XBanner.tsx:18 -#: src/app/[lang]/fusion/Fusion.tsx:120 +#: src/app/[lang]/fusion/Fusion.tsx:203 msgid "Follow us on X" msgstr "Follow us on X" @@ -635,8 +706,8 @@ msgstr "Fusion season 3 is your last ever chance to harvest Spice. Stake your Bi msgid "Fusion season three" msgstr "Fusion season three" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:114 -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:304 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:136 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:332 msgid "Fusion Users:" msgstr "Fusion Users:" @@ -673,7 +744,7 @@ msgstr "Go Back" msgid "Got it!" msgstr "Got it!" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:294 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:322 msgid "Grab the final opportunity to harvest Spice. Join Season 3." msgstr "Grab the final opportunity to harvest Spice. Join Season 3." @@ -697,7 +768,7 @@ msgstr "Harvest {pointsMissing} more Spice to play" #~ msgid "Harvest {pointsMissing} more SPICE to your account to play" #~ msgstr "Harvest {pointsMissing} more SPICE to your account to play" -#: src/app/[lang]/fusion/Fusion.tsx:95 +#: src/app/[lang]/fusion/Fusion.tsx:137 msgid "Harvest Spice by depositing into BOB apps, voting, and solving quests. Keep an eye out for special events." msgstr "Harvest Spice by depositing into BOB apps, voting, and solving quests. Keep an eye out for special events." @@ -709,10 +780,14 @@ msgstr "Here are your active referrals and the Spice they're currently earning f msgid "Hero banner" msgstr "Hero banner" -#: src/app/[lang]/fusion/Fusion.tsx:88 +#: src/app/[lang]/fusion/Fusion.tsx:126 msgid "Hero dots" msgstr "Hero dots" +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:68 +msgid "Hide" +msgstr "Hide" + #: src/app/[lang]/fusion/components/UserInfo/MultipliersModal.tsx:65 msgid "Holding" msgstr "Holding" @@ -749,7 +824,7 @@ msgstr "Invalid referral code. You can try again, or proceed without one." #~ msgid "Join BOB's voting campaign, vote on projects, & get tickets for prizes. New users get a spice bonus. Engage, vote, and win!" #~ msgstr "Join BOB's voting campaign, vote on projects, & get tickets for prizes. New users get a spice bonus. Engage, vote, and win!" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:135 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:157 msgid "Last 24 hours" msgstr "Last 24 hours" @@ -770,7 +845,7 @@ msgid "Leaderboard" msgstr "Leaderboard" #: src/app/[lang]/fusion/components/WelcomeBackModal/WelcomeBackModal.tsx:81 -#: src/app/[lang]/fusion/Fusion.tsx:105 +#: src/app/[lang]/fusion/Fusion.tsx:147 msgid "Learn More" msgstr "Learn More" @@ -812,6 +887,10 @@ msgstr "Lending rate of satUSD" msgid "Lending, Restaking, CDP *" msgstr "Lending, Restaking, CDP *" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:42 +#~ msgid "Let's celebrate BOB's membership of the OP Superchain" +#~ msgstr "Let's celebrate BOB's membership of the OP Superchain" + #: src/app/[lang]/(bridge)/stake/components/StrategyDetailsModal/StrategyDetailsModal.tsx:45 #: src/app/[lang]/(bridge)/stake/components/StrategyDetailsModal/StrategyDetailsModal.tsx:106 #~ msgid "Liquid Staking" @@ -829,15 +908,15 @@ msgstr "Locked Amount" msgid "Locked Capital Breakdown" msgstr "Locked Capital Breakdown" -#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:30 +#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:35 msgid "Log in" msgstr "Log in" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:290 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:318 msgid "Log in to View Dashboard" msgstr "Log in to View Dashboard" -#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:81 +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:79 msgid "Login to play" msgstr "Login to play" @@ -845,8 +924,8 @@ msgstr "Login to play" msgid "Login with wallet" msgstr "Login with wallet" -#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:36 -#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:57 +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:38 +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:55 msgid "Lottery" msgstr "Lottery" @@ -922,7 +1001,7 @@ msgstr "navigate to Common Prefix audit" msgid "navigate to discord" msgstr "navigate to discord" -#: src/app/[lang]/(bridge)/components/BannerCarousel/BannerCarousel.tsx:90 +#: src/app/[lang]/(bridge)/components/BannerCarousel/BannerCarousel.tsx:61 msgid "navigate to ecosystem section in fusion page" msgstr "navigate to ecosystem section in fusion page" @@ -954,14 +1033,19 @@ msgstr "Network Fee" msgid "Network Fee Rate" msgstr "Network Fee Rate" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:65 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:72 msgid "New Quests Coming Soon" msgstr "New Quests Coming Soon" #: src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx:70 #: src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx:163 -msgid "new tickets drop in {0}" -msgstr "new tickets drop in {0}" +#~ msgid "new tickets drop in {0}" +#~ msgstr "new tickets drop in {0}" + +#: src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx:70 +#: src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx:163 +msgid "new tickets drop in {timeToNextDraw}" +msgstr "new tickets drop in {timeToNextDraw}" #: src/app/[lang]/wallet/Wallet.tsx:70 #~ msgid "No assets shown" @@ -971,10 +1055,14 @@ msgstr "new tickets drop in {0}" msgid "No bridging operations found" msgstr "No bridging operations found" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:276 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:304 msgid "No new goal at the moment. Stay tuned for updates!" msgstr "No new goal at the moment. Stay tuned for updates!" +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:52 +#~ msgid "No Thanks" +#~ msgstr "No Thanks" + #: src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx:50 #~ msgid "Not enough spice" #~ msgstr "Not enough spice" @@ -996,8 +1084,8 @@ msgid "Not your lucky day... yet!" msgstr "Not your lucky day... yet!" #: src/app/[lang]/(bridge)/components/BannerCarousel/OKXCryptopediaBanner.tsx:30 -msgid "OKX Cryptopedia" -msgstr "OKX Cryptopedia" +#~ msgid "OKX Cryptopedia" +#~ msgstr "OKX Cryptopedia" #: src/connect-ui/component/ConnectModal/ConnectModal.tsx:246 msgid "On BOB, you have the option to link both your EVM and BTC wallets. For optimal functionality, it's advised to connect wallets from both networks." @@ -1011,12 +1099,16 @@ msgstr "Once complete, your season 3 score will be added to seasons 1 and 2 to c msgid "open drawer" msgstr "open drawer" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:22 +msgid "Optimism city" +msgstr "Optimism city" + #: src/app/[lang]/fusion/components/Strategies/Strategies.tsx:34 #: src/app/[lang]/fusion/components/Strategies/Strategies.tsx:99 msgid "Optional: It's possible to repeat steps 2-4 multiple times." msgstr "Optional: It's possible to repeat steps 2-4 multiple times." -#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:33 +#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:38 msgid "or" msgstr "or" @@ -1028,12 +1120,12 @@ msgstr "OtterSec auditor" msgid "Output Token" msgstr "Output Token" -#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:62 +#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:65 msgid "Pending" msgstr "Pending" #: src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx:208 -#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:81 +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:79 msgid "Play" msgstr "Play" @@ -1093,11 +1185,11 @@ msgid "Provide liquidity into Oku DEX" msgstr "Provide liquidity into Oku DEX" #: src/app/[lang]/fusion/components/Leaderboard/Leaderboard.tsx:80 -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:65 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:72 msgid "Quests" msgstr "Quests" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:206 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:228 msgid "Quests Completed" msgstr "Quests Completed" @@ -1176,23 +1268,23 @@ msgstr "Rewards" msgid "Satoshi protocol points" msgstr "Satoshi protocol points" -#: src/components/Layout/FusionPopover.tsx:77 +#: src/components/Layout/FusionPopover.tsx:111 msgid "Season 1 & 2 (Completed)" msgstr "Season 1 & 2 (Completed)" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:150 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:172 msgid "Season 1 & 2 Total Spice (Completed):" msgstr "Season 1 & 2 Total Spice (Completed):" -#: src/components/Layout/FusionPopover.tsx:88 +#: src/components/Layout/FusionPopover.tsx:122 msgid "Season 2 Final Rank" msgstr "Season 2 Final Rank" -#: src/components/Layout/FusionPopover.tsx:57 +#: src/components/Layout/FusionPopover.tsx:64 msgid "Season 3 (Ongoing)" msgstr "Season 3 (Ongoing)" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:128 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:150 msgid "Season 3 Harvested Spice" msgstr "Season 3 Harvested Spice" @@ -1258,7 +1350,7 @@ msgstr "Select Token" msgid "Share on X" msgstr "Share on X" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:224 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:251 msgid "Share this link with a friend and when they sign up, you will receive 15% of their Spice harvest as a bonus, plus 7% of the Spice harvest of anyone they refer" msgstr "Share this link with a friend and when they sign up, you will receive 15% of their Spice harvest as a bonus, plus 7% of the Spice harvest of anyone they refer" @@ -1410,12 +1502,17 @@ msgstr "Staking table" #~ msgid "Staking Token" #~ msgstr "Staking Token" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:67 +#~ msgid "Start earning exclusive perks and solidify your role as a leader in Bitcoin DeFi today!" +#~ msgstr "Start earning exclusive perks and solidify your role as a leader in Bitcoin DeFi today!" + #: src/app/[lang]/fusion/components/WelcomeBackModal/WelcomeBackModal.tsx:84 #: src/app/[lang]/fusion/components/WelcomeModal/WelcomeModal.tsx:61 msgid "Start Harvesting" msgstr "Start Harvesting" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:297 +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:55 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:325 #: src/app/[lang]/sign-up/SignUp.tsx:127 msgid "Start Harvesting Spice" msgstr "Start Harvesting Spice" @@ -1452,6 +1549,10 @@ msgstr "Successfully finalized transaction" msgid "Successfully submitted ${0} proof" msgstr "Successfully submitted ${0} proof" +#: src/app/[lang]/fusion/Fusion.tsx:178 +msgid "Superchain Eco" +msgstr "Superchain Eco" + #: src/app/[lang]/(bridge)/stake/components/StakeRewards/StakeRewards.tsx:66 msgid "Supply APR" msgstr "Supply APR" @@ -1514,8 +1615,8 @@ msgid "Thank you for your understanding and we hope to be able to serve you in a msgstr "Thank you for your understanding and we hope to be able to serve you in a more decentralized future. The BOB L2 network itself is fully decentralized, cannot be censored and all code is open source." #: src/app/[lang]/(bridge)/components/BannerCarousel/OnrampBanner.tsx:21 -msgid "The fastest and easiest way to bridge BTC to BOB." -msgstr "The fastest and easiest way to bridge BTC to BOB." +#~ msgid "The fastest and easiest way to bridge BTC to BOB." +#~ msgstr "The fastest and easiest way to bridge BTC to BOB." #: src/app/[lang]/fusion/components/WelcomeBackModal/WelcomeBackModal.tsx:39 #: src/app/[lang]/fusion/components/WelcomeModal/WelcomeModal.tsx:24 @@ -1534,11 +1635,11 @@ msgstr "The leaderboard resets for the new season" msgid "The Network Fee is paid to Bitcoin miners for including your transaction in a block and confirming it on the blockchain. A higher fee increases the chances of faster confirmation, while a lower fee may delay or even prevent timely inclusion." msgstr "The Network Fee is paid to Bitcoin miners for including your transaction in a block and confirming it on the blockchain. A higher fee increases the chances of faster confirmation, while a lower fee may delay or even prevent timely inclusion." -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:176 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:198 msgid "The number of BOB ecosystem apps that you have harvested Spice with" msgstr "The number of BOB ecosystem apps that you have harvested Spice with" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:207 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:229 msgid "The number of Intract and Galxe quests that you have completed" msgstr "The number of Intract and Galxe quests that you have completed" @@ -1546,7 +1647,7 @@ msgstr "The number of Intract and Galxe quests that you have completed" #~ msgid "The previous quest has ended. Stay tuned for more exciting quests with Intract and BOB Stake Portal. More rewards are on the way!" #~ msgstr "The previous quest has ended. Stay tuned for more exciting quests with Intract and BOB Stake Portal. More rewards are on the way!" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:77 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:84 msgid "The previous quest has ended. Stay tuned for more exciting quests with Intract and BOB Stake. More rewards are on the way!" msgstr "The previous quest has ended. Stay tuned for more exciting quests with Intract and BOB Stake. More rewards are on the way!" @@ -1599,7 +1700,7 @@ msgstr "There is currently no available liquidity to onramp BTC into {assetName} msgid "This is often done to comply with local laws and regulations. Website hosters must comply with regulations and may be forced to block certain countries. It seems your country is unfortunately on the list of restricted countries according to the Terms and Conditions of the hoster of this website. We are constantly working to expand our reach and provide our services to more regions." msgstr "This is often done to comply with local laws and regulations. Website hosters must comply with regulations and may be forced to block certain countries. It seems your country is unfortunately on the list of restricted countries according to the Terms and Conditions of the hoster of this website. We are constantly working to expand our reach and provide our services to more regions." -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:139 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:161 msgid "This is the amount of spice you have harvested in the last 24 hours. It is updated every 15 minutes." msgstr "This is the amount of spice you have harvested in the last 24 hours. It is updated every 15 minutes." @@ -1615,7 +1716,7 @@ msgstr "This is the final amount you will receive after deducting the Protocol f msgid "This website is not available in your location due to geoblocking. Geoblocking is a practice used by content providers to restrict access to their content based on the geographical location of the user." msgstr "This website is not available in your location due to geoblocking. Geoblocking is a practice used by content providers to restrict access to their content based on the geographical location of the user." -#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:41 +#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:46 msgid "Time left until voting round ends" msgstr "Time left until voting round ends" @@ -1623,11 +1724,24 @@ msgstr "Time left until voting round ends" msgid "To cast your vote, please log in" msgstr "To cast your vote, please log in" +#: src/app/[lang]/fusion/Fusion.tsx:168 +msgid "To celebrate BOB joining the Superchain, you have qualified for an OP exclusive 50% bonus on all Spice harvested between 9 December 2024 and 12 January 2025. <0>Learn more" +msgstr "To celebrate BOB joining the Superchain, you have qualified for an OP exclusive 50% bonus on all Spice harvested between 9 December 2024 and 12 January 2025. <0>Learn more" + +#: src/app/[lang]/(bridge)/components/BannerCarousel/OPBanner.tsx:22 +#: src/app/[lang]/fusion/Fusion.tsx:168 +#~ msgid "To celebrate BOB joining the Superchain, you have qualified for an OP exclusive 50% bonus on all Spice harvested between 9 December 2024 and 12 January 2025. Learn more^" +#~ msgstr "To celebrate BOB joining the Superchain, you have qualified for an OP exclusive 50% bonus on all Spice harvested between 9 December 2024 and 12 January 2025. Learn more^" + #: src/app/[lang]/(bridge)/components/BannerCarousel/XBanner.tsx:22 -#: src/app/[lang]/fusion/Fusion.tsx:123 +#: src/app/[lang]/fusion/Fusion.tsx:206 msgid "To stay up-to date with the BOB ecosystem follow @build_on_bob." msgstr "To stay up-to date with the BOB ecosystem follow @build_on_bob." +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:35 +msgid "Top 100 spice user" +msgstr "Top 100 spice user" + #: src/app/[lang]/(bridge)/components/GatewayGasSwitch/GatewayGasSwitch.tsx:23 msgid "Top up Gas" msgstr "Top up Gas" @@ -1640,7 +1754,7 @@ msgstr "Top up Gas" #~ msgid "Total Assets" #~ msgstr "Total Assets" -#: src/components/Layout/FusionPopover.tsx:81 +#: src/components/Layout/FusionPopover.tsx:115 msgid "Total Harvest" msgstr "Total Harvest" @@ -1690,7 +1804,7 @@ msgstr "Unfortunately, is not possible to bridge to BOB using smart accounts. We #~ msgstr "uniBTC represents the staked wBTC plus all future staking rewards and accrual of Babylon staking rewards and Bedrock diamonds." #: src/app/[lang]/(bridge)/components/BridgeStatus/BridgeStep.tsx:230 -#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:71 +#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:74 msgid "Unknown" msgstr "Unknown" @@ -1718,7 +1832,7 @@ msgstr "USDT can only be withdrawn to Ethereum. When bridging to BOB, you will b msgid "Use any of the <0>supported bridges." msgstr "Use any of the <0>supported bridges." -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:192 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:214 msgid "Use Apps" msgstr "Use Apps" @@ -1739,7 +1853,7 @@ msgid "Use your bridged assets in apps to maximise your Spice harvest.<0/>TIP: S msgstr "Use your bridged assets in apps to maximise your Spice harvest.<0/>TIP: Some types of apps offer greater multipliers than others. Explore the “Hot Strategies” section to learn more." #: src/app/[lang]/apps/components/HeroBanner/HeroBanner.tsx:48 -#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:61 +#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:69 msgid "Use your Spice total to support your favourite BOB builders. Winners will be announced each week." msgstr "Use your Spice total to support your favourite BOB builders. Winners will be announced each week." @@ -1766,21 +1880,21 @@ msgstr "Using the official bridge usually takes 7 days. For faster withdrawals w msgid "View All Transactions" msgstr "View All Transactions" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:94 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:101 msgid "View Intract" msgstr "View Intract" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:165 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:187 msgid "View Multipliers" msgstr "View Multipliers" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:94 -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:218 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:101 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:240 msgid "View Quests" msgstr "View Quests" #: src/app/[lang]/apps/components/SpiceChip/SpiceChip.tsx:99 -#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:66 +#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:74 msgid "Vote" msgstr "Vote" @@ -1792,7 +1906,7 @@ msgstr "Vote for maximum three projects per week" msgid "Vote for maximum three projects per week by clicking on the flame icon." msgstr "Vote for maximum three projects per week by clicking on the flame icon." -#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:20 +#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:25 msgid "Votes Left:" msgstr "Votes Left:" @@ -1817,6 +1931,10 @@ msgstr "Wallet" msgid "We will provide you with updates accordingly. You can monitor the progress on your bridge page; it will be marked as complete once the process has concluded." msgstr "We will provide you with updates accordingly. You can monitor the progress on your bridge page; it will be marked as complete once the process has concluded." +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:121 +msgid "We would love to hear your thoughts on the BOB ecosystem and Bitcoin DeFi." +msgstr "We would love to hear your thoughts on the BOB ecosystem and Bitcoin DeFi." + #: src/app/[lang]/geoblock/Geoblock.tsx:14 msgid "We're Sorry" msgstr "We're Sorry" @@ -1825,7 +1943,11 @@ msgstr "We're Sorry" msgid "Website" msgstr "Website" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:33 +#: src/components/Layout/FusionPopover.tsx:99 +#~ msgid "Welcome OP Superuser" +#~ msgstr "Welcome OP Superuser" + +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:35 msgid "Welcome season 3" msgstr "Welcome season 3" @@ -1843,7 +1965,7 @@ msgid "When you vote, you do not give away any of your harvest. Your Spice total msgstr "When you vote, you do not give away any of your harvest. Your Spice total is simply used to calculate the weight of your vote." #: src/app/[lang]/(bridge)/bridge/Bridge.tsx:131 -#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:38 +#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:41 msgid "Withdraw" msgstr "Withdraw" @@ -1869,6 +1991,15 @@ msgstr "Yield Assets" msgid "You" msgstr "You" +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:46 +#: src/app/[lang]/fusion/Fusion.tsx:131 +msgid "You are one of the top 100 Spice holders in BOB Fusion" +msgstr "You are one of the top 100 Spice holders in BOB Fusion" + +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:116 +#~ msgid "You are one of the top 100 Spice holders in BOB Fusion. We would love to hear your thoughts on the BOB ecosystem and Bitcoin DeFi." +#~ msgstr "You are one of the top 100 Spice holders in BOB Fusion. We would love to hear your thoughts on the BOB ecosystem and Bitcoin DeFi." + #: src/app/[lang]/(bridge)/components/GatewayTransactionDetails/GatewayTransactionDetails.tsx:76 #~ msgid "You are using a BTC address type (Taproot/P2TR) which we don't support yet. Change the BTC address type to Native SegWit in your wallet to continue." #~ msgstr "You are using a BTC address type (Taproot/P2TR) which we don't support yet. Change the BTC address type to Native SegWit in your wallet to continue." @@ -1923,6 +2054,10 @@ msgstr "You've used all your tickets for today, new tickets will be available on #~ msgid "You've used all your tickets for today. New tickets will be available once the timer resets. Be sure to come back and vote daily to increase your chances of earning more SPICE!" #~ msgstr "You've used all your tickets for today. New tickets will be available once the timer resets. Be sure to come back and vote daily to increase your chances of earning more SPICE!" +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:243 +#~ msgid "Your {0} Referral Code" +#~ msgstr "Your {0} Referral Code" + #: src/app/[lang]/fusion/components/UserInfo/UserReferralModal.tsx:53 msgid "Your Active Referrals" msgstr "Your Active Referrals" @@ -1947,10 +2082,10 @@ msgstr "Your funds are safe!" msgid "Your performance in seasons 1 & 2" msgstr "Your performance in seasons 1 & 2" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:223 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:245 msgid "Your Referral Code" msgstr "Your Referral Code" -#: src/components/Layout/FusionPopover.tsx:53 +#: src/components/Layout/FusionPopover.tsx:60 msgid "Your Spice Harvest Overview" msgstr "Your Spice Harvest Overview" diff --git a/apps/evm/src/locales/zh.po b/apps/evm/src/locales/zh.po index 775bcec86..4b4bf0172 100644 --- a/apps/evm/src/locales/zh.po +++ b/apps/evm/src/locales/zh.po @@ -22,26 +22,34 @@ msgstr "" #~ msgid "{0}" #~ msgstr "" -#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:49 +#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:52 msgid "{0} ago" msgstr "" -#: src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx:47 +#: src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx:52 msgid "{0} remaining" msgstr "" #: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:50 -msgid "{0} until next draw" -msgstr "" +#~ msgid "{0} until next draw" +#~ msgstr "" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:56 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:58 msgid "{0} until quest ends" msgstr "距离任务结束还有{0}" -#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:52 +#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:55 msgid "{0} until voting round ends" msgstr "距离投票轮结束还有{0}" +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:245 +#~ msgid "{0}Share this link with a friend and when they sign up, you will receive {1} of their Spice harvest as a bonus, plus {2} of the Spice harvest of anyone they refer" +#~ msgstr "" + +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:51 +msgid "{timeToNextDraw} until next draw" +msgstr "" + #: src/app/[lang]/fusion/components/UserInfo/MultipliersModal.tsx:228 msgid "* The multipliers displayed are subject to change based on the payout structure of the respective projects." msgstr "* 显示的倍数可能会根据相应项目的支付结构而变化。" @@ -50,7 +58,7 @@ msgstr "* 显示的倍数可能会根据相应项目的支付结构而变化。" #~ msgid "< 1 minute" #~ msgstr "" -#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:59 +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:57 msgid "<0>{0} {1, plural, one {Ticket} other {Tickets}} Remaining" msgstr "" @@ -62,12 +70,20 @@ msgstr "" msgid "<0>{rollsRemaining}/3 {0, plural, one {Ticket} other {Tickets}} Remaining" msgstr "" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:54 +#~ msgid "<0>Enhanced Referral Bonuses: Earn even more from your network by sharing your unique referral link." +#~ msgstr "" + +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:60 +#~ msgid "<0>Extra Rewards for TVL Achievements: Benefit from additional incentives as BOB's Total Value Locked (TVL) milestones are reached." +#~ msgstr "" + #: src/app/[lang]/fusion/components/Strategies/Strategies.tsx:21 #: src/app/[lang]/fusion/components/Strategies/Strategies.tsx:60 msgid "<0>Stake your BTC with 1-click and receive BTC LSTs on BOB." msgstr "<0>一键质押你的BTC 并在BOB上接收BTC LSTs。" -#: src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx:44 +#: src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx:48 msgid "2 hours" msgstr "" @@ -80,7 +96,7 @@ msgstr "" msgid "404 Error" msgstr "404 错误" -#: src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx:44 +#: src/app/[lang]/(bridge)/components/BridgeStatus/TimeStep.tsx:48 msgid "7 days" msgstr "" @@ -89,6 +105,11 @@ msgstr "" msgid "About" msgstr "关于" +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:248 +#: src/components/Layout/FusionPopover.tsx:99 +msgid "Active Superchain users who have received any of the five OP Airdrops qualify for an exclusive 50% bonus on all Spice harvested between 9 December 2024 and 12 January 2025. The bonus will be applied at the end of the campaign." +msgstr "" + #: src/app/[lang]/(bridge)/components/GatewayTransactionDetails/GatewayFeeSettingsModal.tsx:106 msgid "Adjusting the fee rate affects how quickly your Bitcoin transaction is confirmed. Lower fees may lead to significant delays in confirmation time." msgstr "" @@ -101,6 +122,14 @@ msgstr "" msgid "All Apps" msgstr "所有应用" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:43 +msgid "All Spice you harvest between 9 December 2024 and 12 January 2025 will receive an exclusive 50% bonus, only available to OP airdrop recipients." +msgstr "" + +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:37 +#~ msgid "All Spice you harvest during between 9 December 2024 and 12 January 2025 will receive an exclusive 50% bonus, only available to OP airdrop recipients." +#~ msgstr "" + #: src/components/LoginSection/LoginSection.tsx:11 msgid "Already harvesting?" msgstr "已经在收获?" @@ -111,8 +140,8 @@ msgid "Amount" msgstr "" #: src/app/[lang]/(bridge)/components/BannerCarousel/OKXCryptopediaBanner.tsx:26 -msgid "An Exclusive Bitcoin Staking and DeFi Campaign" -msgstr "" +#~ msgid "An Exclusive Bitcoin Staking and DeFi Campaign" +#~ msgstr "" #: src/components/BannerCarousel/BinanceCampaignBanner.tsx:25 #~ msgid "An exclusive quest campaign." @@ -136,14 +165,22 @@ msgstr "通过" msgid "Apps" msgstr "" -#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:30 +#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:33 msgid "Apps leaderboard hero" msgstr "" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:175 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:197 msgid "Apps Used" msgstr "已体验的应用" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:46 +#~ msgid "As an OP Superuser, you unlock special rewards when you join BOB's Fusion campaign and explore the future of Bitcoin DeFi." +#~ msgstr "" + +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:49 +msgid "As one of our most important community members, we would love the opportunity to gain your input on the BOB ecosystem and our future plans." +msgstr "" + #: src/app/[lang]/fusion/components/UserInfo/MultipliersModal.tsx:64 msgid "Asset" msgstr "资产" @@ -204,12 +241,16 @@ msgstr "" msgid "BOB Bridge" msgstr "" -#: src/app/[lang]/(bridge)/components/BannerCarousel/OKXCryptopediaBanner.tsx:22 -msgid "BOB Ecosystem on OKX Cryptopedia" +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:55 +msgid "BOB co-founder, <0>Alexei Zamyatin, would like to invite you to a private 1-to-1 call to hear your thoughts on BOB and Bitcoin DeFi. If you are interested, please click the button below to book a call at a time that suits you." msgstr "" +#: src/app/[lang]/(bridge)/components/BannerCarousel/OKXCryptopediaBanner.tsx:22 +#~ msgid "BOB Ecosystem on OKX Cryptopedia" +#~ msgstr "" + #: src/app/[lang]/(bridge)/components/BannerCarousel/FusionBanner.tsx:22 -#: src/app/[lang]/fusion/Fusion.tsx:92 +#: src/app/[lang]/fusion/Fusion.tsx:133 msgid "BOB Fusion: The Final Season" msgstr "BOB Fusion:最终季" @@ -222,15 +263,19 @@ msgstr "" #~ msgstr "" #: src/app/[lang]/(bridge)/components/BannerCarousel/OnrampBanner.tsx:17 -msgid "BOB Gateway is live!" -msgstr "" +#~ msgid "BOB Gateway is live!" +#~ msgstr "" #: src/app/[lang]/layout.tsx:33 #: src/app/[lang]/layout.tsx:52 msgid "BOB is a hybrid L2 that combines the security of Bitcoin with the versatility of Ethereum" msgstr "" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:273 +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:37 +msgid "BOB is bringing Bitcoin DeFi to the Superchain, and to celebrate, active Superchain ecosystem users like you have unlocked an exclusive BOB Spice bonus." +msgstr "" + +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:301 msgid "BOB TVL Progress" msgstr "BOB TVL进度" @@ -238,6 +283,22 @@ msgstr "BOB TVL进度" #~ msgid "BOB Wallet" #~ msgstr "BOB 钱包" +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:54 +#~ msgid "Book a call" +#~ msgstr "" + +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:65 +msgid "Book A Call" +msgstr "" + +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:128 +msgid "Book a call with the founders" +msgstr "" + +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:49 +#~ msgid "Book Meeting" +#~ msgstr "" + #: src/app/[lang]/(bridge)/bridge/page.tsx:14 #: src/app/[lang]/page.tsx:15 #: src/components/Layout/Header.tsx:67 @@ -250,7 +311,7 @@ msgstr "桥" msgid "Bridge Asset" msgstr "" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:168 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:190 msgid "Bridge Assets" msgstr "跨链资产" @@ -279,6 +340,10 @@ msgstr "将你的资产跨链到BOB以开始收获Spice。<0/>提示:某些资 msgid "Bridging ALEX is disabled because Alex Lab suffered an exploit involving the XLink bridge. For more information, kindly refer to this <0>announcement." msgstr "由于 Alex Lab 遭受了涉及 XLink 桥接的攻击,桥接 ALEX 已被禁用。有关更多信息,请参阅此 <0>公告。" +#: src/app/[lang]/fusion/Fusion.tsx:165 +msgid "Bringing Bitcoin DeFi to the Superchain" +msgstr "将比特币 DeFi 引入OP超级链" + #: src/app/[lang]/(bridge)/components/GatewayTransactionDetails/GatewayTransactionDetails.tsx:76 msgid "BTC bridge is currently unavailable. This may be due to: {0}. Please try again later." msgstr "" @@ -337,7 +402,7 @@ msgid "Combining liquidity and security from Bitcoin and Ethereum. Mainnet live! msgstr "结合比特币和以太坊的流动性和安全性。= 主网已上线!。" #: src/app/[lang]/(bridge)/bridge/components/ExternalBridgeForm/ExternalBridgeCard.tsx:123 -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:58 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:65 #: src/app/[lang]/fusion/components/Strategies/Strategies.tsx:210 msgid "Coming Soon" msgstr "即将推出" @@ -351,7 +416,7 @@ msgid "Common Prefix auditor" msgstr "" #: src/app/[lang]/apps/components/HeroBanner/HeroBanner.tsx:45 -#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:58 +#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:66 msgid "Community Voting" msgstr "社区投票" @@ -359,7 +424,7 @@ msgstr "社区投票" msgid "Community Voting Information" msgstr "社区投票信息" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:72 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:79 msgid "Complete a variety of on- and off-chain quests using Intract and the BOB Stake Portal to harvest an additional 62,500 Spice." msgstr "完成各种链上和链下任务,使用Intract和BOB Stake来额外收获62,500 Spice。" @@ -402,19 +467,19 @@ msgstr "" #~ msgid "Copy Address" #~ msgstr "" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:240 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:268 msgid "Copy referral URL" msgstr "复制推荐URL" -#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:36 +#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:41 msgid "Create Account" msgstr "创建账户" -#: src/components/Layout/FusionPopover.tsx:63 +#: src/components/Layout/FusionPopover.tsx:70 msgid "Current Harvest" msgstr "当前收获" -#: src/components/Layout/FusionPopover.tsx:70 +#: src/components/Layout/FusionPopover.tsx:77 msgid "Current Leaderboard Rank" msgstr "当前排行榜排名" @@ -422,7 +487,7 @@ msgstr "当前排行榜排名" msgid "Current Spice" msgstr "当前Spice" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:312 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:340 msgid "Current TVL:" msgstr "" @@ -435,7 +500,7 @@ msgid "Deploy high priority assets into high priority DeFi protocols to maximize msgstr "将高优先级资产部署到高优先级DeFi协议中,以最大化你的Spice收获。" #: src/app/[lang]/(bridge)/bridge/Bridge.tsx:128 -#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:38 +#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:41 msgid "Deposit" msgstr "" @@ -488,6 +553,8 @@ msgstr "" msgid "Don't believe in the Bitcoin Renaissance? You can withdraw your funds from the contract to your wallet on Ethereum. You will no longer earn Spice if you withdraw your assets. <0>You will keep the Spice harvested so far." msgstr "想要退出?你可以将资金从合约中提取到以太坊钱包。请注意,提取资产后你将不再赚取Spice。<0>不过,你已收获的Spice都会保留。" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:52 +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:72 #: src/app/[lang]/fusion/components/WelcomeModal/WelcomeModal.tsx:58 msgid "Don't show this message again" msgstr "不再显示此消息" @@ -546,6 +613,10 @@ msgstr "" msgid "Estimated within the next block" msgstr "" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:33 +msgid "Exclusive Spice Bonus For Superchain Users" +msgstr "" + #: src/connect-ui/component/ConnectModal/ConnectModal.tsx:138 #: src/connect-ui/component/ConnectModal/ConnectModal.tsx:174 msgid "Failed to connect to {0}" @@ -584,7 +655,7 @@ msgstr "特色资产" msgid "Fee" msgstr "" -#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:69 +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:67 msgid "Feeling lucky? Try your luck with the daily lottery!<0/>Participate in Fusion voting to receive 3 lottery tickets each day." msgstr "" @@ -609,7 +680,7 @@ msgid "Follow the steps of <0>this guide to provide liquity into a DEX pool msgstr "按照 <0>本指南 的步骤为Oku上的DEX池提供流动性。" #: src/app/[lang]/(bridge)/components/BannerCarousel/XBanner.tsx:18 -#: src/app/[lang]/fusion/Fusion.tsx:120 +#: src/app/[lang]/fusion/Fusion.tsx:203 msgid "Follow us on X" msgstr "" @@ -635,8 +706,8 @@ msgstr "Fusion第3季是你收获Spice的最后机会。质押比特币获得最 msgid "Fusion season three" msgstr "" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:114 -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:304 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:136 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:332 msgid "Fusion Users:" msgstr "" @@ -673,7 +744,7 @@ msgstr "返回" msgid "Got it!" msgstr "" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:294 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:322 msgid "Grab the final opportunity to harvest Spice. Join Season 3." msgstr "抓住最后收获Spice的机会!加入第3季!" @@ -697,7 +768,7 @@ msgstr "" #~ msgid "Harvest {pointsMissing} more SPICE to your account to play" #~ msgstr "" -#: src/app/[lang]/fusion/Fusion.tsx:95 +#: src/app/[lang]/fusion/Fusion.tsx:137 msgid "Harvest Spice by depositing into BOB apps, voting, and solving quests. Keep an eye out for special events." msgstr "通过存入BOB应用、投票和完成任务来收获Spice。密切关注特别活动" @@ -709,10 +780,14 @@ msgstr "这里展示了你推荐的活跃用户及他们为你赚取的Spice。 msgid "Hero banner" msgstr "" -#: src/app/[lang]/fusion/Fusion.tsx:88 +#: src/app/[lang]/fusion/Fusion.tsx:126 msgid "Hero dots" msgstr "" +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:68 +msgid "Hide" +msgstr "" + #: src/app/[lang]/fusion/components/UserInfo/MultipliersModal.tsx:65 msgid "Holding" msgstr "持有" @@ -749,7 +824,7 @@ msgstr "" #~ msgid "Join BOB's voting campaign, vote on projects, & get tickets for prizes. New users get a spice bonus. Engage, vote, and win!" #~ msgstr "" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:135 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:157 msgid "Last 24 hours" msgstr "过去24小时" @@ -770,7 +845,7 @@ msgid "Leaderboard" msgstr "排行榜" #: src/app/[lang]/fusion/components/WelcomeBackModal/WelcomeBackModal.tsx:81 -#: src/app/[lang]/fusion/Fusion.tsx:105 +#: src/app/[lang]/fusion/Fusion.tsx:147 msgid "Learn More" msgstr "了解更多" @@ -812,6 +887,10 @@ msgstr "satUSD的借贷利率" msgid "Lending, Restaking, CDP *" msgstr "借贷、再质押、抵押债仓(CDP) *" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:42 +#~ msgid "Let's celebrate BOB's membership of the OP Superchain" +#~ msgstr "" + #: src/app/[lang]/(bridge)/stake/components/StrategyDetailsModal/StrategyDetailsModal.tsx:45 #: src/app/[lang]/(bridge)/stake/components/StrategyDetailsModal/StrategyDetailsModal.tsx:106 #~ msgid "Liquid Staking" @@ -829,15 +908,15 @@ msgstr "锁定金额" msgid "Locked Capital Breakdown" msgstr "锁定资本明细" -#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:30 +#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:35 msgid "Log in" msgstr "登录" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:290 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:318 msgid "Log in to View Dashboard" msgstr "登录查看仪表板" -#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:81 +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:79 msgid "Login to play" msgstr "" @@ -845,8 +924,8 @@ msgstr "" msgid "Login with wallet" msgstr "使用钱包登录" -#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:36 -#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:57 +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:38 +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:55 msgid "Lottery" msgstr "" @@ -922,7 +1001,7 @@ msgstr "" msgid "navigate to discord" msgstr "" -#: src/app/[lang]/(bridge)/components/BannerCarousel/BannerCarousel.tsx:90 +#: src/app/[lang]/(bridge)/components/BannerCarousel/BannerCarousel.tsx:61 msgid "navigate to ecosystem section in fusion page" msgstr "" @@ -954,13 +1033,18 @@ msgstr "" msgid "Network Fee Rate" msgstr "" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:65 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:72 msgid "New Quests Coming Soon" msgstr "" #: src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx:70 #: src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx:163 -msgid "new tickets drop in {0}" +#~ msgid "new tickets drop in {0}" +#~ msgstr "" + +#: src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx:70 +#: src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx:163 +msgid "new tickets drop in {timeToNextDraw}" msgstr "" #: src/app/[lang]/wallet/Wallet.tsx:70 @@ -971,10 +1055,14 @@ msgstr "" msgid "No bridging operations found" msgstr "" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:276 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:304 msgid "No new goal at the moment. Stay tuned for updates!" msgstr "目前暂无新目标。请保持关注更新!" +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:52 +#~ msgid "No Thanks" +#~ msgstr "" + #: src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx:50 #~ msgid "Not enough spice" #~ msgstr "" @@ -996,8 +1084,8 @@ msgid "Not your lucky day... yet!" msgstr "" #: src/app/[lang]/(bridge)/components/BannerCarousel/OKXCryptopediaBanner.tsx:30 -msgid "OKX Cryptopedia" -msgstr "" +#~ msgid "OKX Cryptopedia" +#~ msgstr "" #: src/connect-ui/component/ConnectModal/ConnectModal.tsx:246 msgid "On BOB, you have the option to link both your EVM and BTC wallets. For optimal functionality, it's advised to connect wallets from both networks." @@ -1011,12 +1099,16 @@ msgstr "第3季结束后,你的得分将与第1季和第2季的得分合并, msgid "open drawer" msgstr "" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:22 +msgid "Optimism city" +msgstr "" + #: src/app/[lang]/fusion/components/Strategies/Strategies.tsx:34 #: src/app/[lang]/fusion/components/Strategies/Strategies.tsx:99 msgid "Optional: It's possible to repeat steps 2-4 multiple times." msgstr "可选:可以多次重复步骤2-4。" -#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:33 +#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:38 msgid "or" msgstr "或" @@ -1028,12 +1120,12 @@ msgstr "" msgid "Output Token" msgstr "" -#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:62 +#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:65 msgid "Pending" msgstr "" #: src/app/[lang]/fusion/components/LotterySections/LotteryModal/LotteryModal.tsx:208 -#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:81 +#: src/app/[lang]/fusion/components/LotterySections/LotterySections.tsx:79 msgid "Play" msgstr "" @@ -1093,11 +1185,11 @@ msgid "Provide liquidity into Oku DEX" msgstr "为Oku DEX提供流动性" #: src/app/[lang]/fusion/components/Leaderboard/Leaderboard.tsx:80 -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:65 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:72 msgid "Quests" msgstr "任务" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:206 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:228 msgid "Quests Completed" msgstr "完成的任务" @@ -1176,23 +1268,23 @@ msgstr "奖励" msgid "Satoshi protocol points" msgstr "Satoshi协议积分" -#: src/components/Layout/FusionPopover.tsx:77 +#: src/components/Layout/FusionPopover.tsx:111 msgid "Season 1 & 2 (Completed)" msgstr "第1季和第2季(已完成)" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:150 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:172 msgid "Season 1 & 2 Total Spice (Completed):" msgstr "第1季和第2季总Spice(已完成):" -#: src/components/Layout/FusionPopover.tsx:88 +#: src/components/Layout/FusionPopover.tsx:122 msgid "Season 2 Final Rank" msgstr "第2季最终排名" -#: src/components/Layout/FusionPopover.tsx:57 +#: src/components/Layout/FusionPopover.tsx:64 msgid "Season 3 (Ongoing)" msgstr "第3季(进行中)" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:128 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:150 msgid "Season 3 Harvested Spice" msgstr "第3季收获的Spice" @@ -1258,7 +1350,7 @@ msgstr "" msgid "Share on X" msgstr "" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:224 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:251 msgid "Share this link with a friend and when they sign up, you will receive 15% of their Spice harvest as a bonus, plus 7% of the Spice harvest of anyone they refer" msgstr "与朋友分享此链接,当他们注册时,你将获得他们Spice收获的15%作为奖励,以及他们推荐的任何人的Spice收获的7%" @@ -1406,8 +1498,8 @@ msgstr "" msgid "Staking table" msgstr "" -#: src/app/[lang]/(bridge)/stake/components/StrategyDetailsModal/StrategyDetailsModal.tsx:39 -#~ msgid "Staking Token" +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:67 +#~ msgid "Start earning exclusive perks and solidify your role as a leader in Bitcoin DeFi today!" #~ msgstr "" #: src/app/[lang]/fusion/components/WelcomeBackModal/WelcomeBackModal.tsx:84 @@ -1415,7 +1507,8 @@ msgstr "" msgid "Start Harvesting" msgstr "开始收获" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:297 +#: src/app/[lang]/fusion/components/OpSuperuserModal/OpSuperuserModal.tsx:55 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:325 #: src/app/[lang]/sign-up/SignUp.tsx:127 msgid "Start Harvesting Spice" msgstr "开始收获Spice" @@ -1452,6 +1545,10 @@ msgstr "" msgid "Successfully submitted ${0} proof" msgstr "" +#: src/app/[lang]/fusion/Fusion.tsx:178 +msgid "Superchain Eco" +msgstr "" + #: src/app/[lang]/(bridge)/stake/components/StakeRewards/StakeRewards.tsx:66 msgid "Supply APR" msgstr "" @@ -1514,8 +1611,8 @@ msgid "Thank you for your understanding and we hope to be able to serve you in a msgstr "" #: src/app/[lang]/(bridge)/components/BannerCarousel/OnrampBanner.tsx:21 -msgid "The fastest and easiest way to bridge BTC to BOB." -msgstr "" +#~ msgid "The fastest and easiest way to bridge BTC to BOB." +#~ msgstr "" #: src/app/[lang]/fusion/components/WelcomeBackModal/WelcomeBackModal.tsx:39 #: src/app/[lang]/fusion/components/WelcomeModal/WelcomeModal.tsx:24 @@ -1534,11 +1631,11 @@ msgstr "" msgid "The Network Fee is paid to Bitcoin miners for including your transaction in a block and confirming it on the blockchain. A higher fee increases the chances of faster confirmation, while a lower fee may delay or even prevent timely inclusion." msgstr "" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:176 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:198 msgid "The number of BOB ecosystem apps that you have harvested Spice with" msgstr "你已经使用过的BOB生态系统应用数量" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:207 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:229 msgid "The number of Intract and Galxe quests that you have completed" msgstr "在Intract和Galxe上完成的任务" @@ -1546,7 +1643,7 @@ msgstr "在Intract和Galxe上完成的任务" #~ msgid "The previous quest has ended. Stay tuned for more exciting quests with Intract and BOB Stake Portal. More rewards are on the way!" #~ msgstr "" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:77 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:84 msgid "The previous quest has ended. Stay tuned for more exciting quests with Intract and BOB Stake. More rewards are on the way!" msgstr "" @@ -1595,7 +1692,7 @@ msgstr "" msgid "This is often done to comply with local laws and regulations. Website hosters must comply with regulations and may be forced to block certain countries. It seems your country is unfortunately on the list of restricted countries according to the Terms and Conditions of the hoster of this website. We are constantly working to expand our reach and provide our services to more regions." msgstr "" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:139 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:161 msgid "This is the amount of spice you have harvested in the last 24 hours. It is updated every 15 minutes." msgstr "" @@ -1611,7 +1708,7 @@ msgstr "" msgid "This website is not available in your location due to geoblocking. Geoblocking is a practice used by content providers to restrict access to their content based on the geographical location of the user." msgstr "" -#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:41 +#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:46 msgid "Time left until voting round ends" msgstr "" @@ -1619,11 +1716,19 @@ msgstr "" msgid "To cast your vote, please log in" msgstr "" +#: src/app/[lang]/fusion/Fusion.tsx:168 +msgid "To celebrate BOB joining the Superchain, you have qualified for an OP exclusive 50% bonus on all Spice harvested between 9 December 2024 and 12 January 2025. <0>Learn more" +msgstr "为庆祝 BOB 加入”超级链”,您已符合资格获得 OP 专属奖励:2024 年 12 月 9 日至 2025 年 1 月 12 日期间收获的所有 Spice 可享额外 50% 奖励。<0>了解更多" + #: src/app/[lang]/(bridge)/components/BannerCarousel/XBanner.tsx:22 -#: src/app/[lang]/fusion/Fusion.tsx:123 +#: src/app/[lang]/fusion/Fusion.tsx:206 msgid "To stay up-to date with the BOB ecosystem follow @build_on_bob." msgstr "" +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:35 +msgid "Top 100 spice user" +msgstr "" + #: src/app/[lang]/(bridge)/components/GatewayGasSwitch/GatewayGasSwitch.tsx:23 msgid "Top up Gas" msgstr "" @@ -1636,7 +1741,7 @@ msgstr "" #~ msgid "Total Assets" #~ msgstr "总资产" -#: src/components/Layout/FusionPopover.tsx:81 +#: src/components/Layout/FusionPopover.tsx:115 msgid "Total Harvest" msgstr "总收获" @@ -1686,7 +1791,7 @@ msgstr "很抱歉,目前智能账户还不能跨链到BOB。我们正在努力 #~ msgstr "" #: src/app/[lang]/(bridge)/components/BridgeStatus/BridgeStep.tsx:230 -#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:71 +#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:74 msgid "Unknown" msgstr "" @@ -1714,7 +1819,7 @@ msgstr "" msgid "Use any of the <0>supported bridges." msgstr "使用任何 <0>支持的跨链桥。" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:192 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:214 msgid "Use Apps" msgstr "体验应用" @@ -1735,7 +1840,7 @@ msgid "Use your bridged assets in apps to maximise your Spice harvest.<0/>TIP: S msgstr "在应用中使用你跨链的资产以最大化你的Spice收获。<0/>提示:某些类型的应用提供更高的倍数。浏览\"热门策略\"部分以了解更多。" #: src/app/[lang]/apps/components/HeroBanner/HeroBanner.tsx:48 -#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:61 +#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:69 msgid "Use your Spice total to support your favourite BOB builders. Winners will be announced each week." msgstr "用你的Spice总数来支持你最喜爱的BOB构建者。获胜者将每周公布。" @@ -1762,21 +1867,21 @@ msgstr "" msgid "View All Transactions" msgstr "" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:94 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:101 msgid "View Intract" msgstr "" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:165 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:187 msgid "View Multipliers" msgstr "查看倍数" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:94 -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:218 +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:101 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:240 msgid "View Quests" msgstr "查看任务" #: src/app/[lang]/apps/components/SpiceChip/SpiceChip.tsx:99 -#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:66 +#: src/app/[lang]/fusion/components/CommunityVoting/CommunityVoting.tsx:74 msgid "Vote" msgstr "投票" @@ -1788,7 +1893,7 @@ msgstr "每周最多可以为三个项目投票" msgid "Vote for maximum three projects per week by clicking on the flame icon." msgstr "通过点击火焰图标,每周最多可为三个项目投票" -#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:20 +#: src/app/[lang]/apps/components/VotingDashboard/UserVotingInfo.tsx:25 msgid "Votes Left:" msgstr "剩余投票次数:" @@ -1813,6 +1918,10 @@ msgstr "钱包" msgid "We will provide you with updates accordingly. You can monitor the progress on your bridge page; it will be marked as complete once the process has concluded." msgstr "" +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:121 +msgid "We would love to hear your thoughts on the BOB ecosystem and Bitcoin DeFi." +msgstr "" + #: src/app/[lang]/geoblock/Geoblock.tsx:14 msgid "We're Sorry" msgstr "" @@ -1821,7 +1930,11 @@ msgstr "" msgid "Website" msgstr "" -#: src/app/[lang]/fusion/components/Quest/Quest.tsx:33 +#: src/components/Layout/FusionPopover.tsx:99 +#~ msgid "Welcome OP Superuser" +#~ msgstr "" + +#: src/app/[lang]/fusion/components/Quest/Quest.tsx:35 msgid "Welcome season 3" msgstr "" @@ -1839,7 +1952,7 @@ msgid "When you vote, you do not give away any of your harvest. Your Spice total msgstr "投票时,你不会失去任何收获。你的Spice总数仅用于计算你的投票权重。" #: src/app/[lang]/(bridge)/bridge/Bridge.tsx:131 -#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:38 +#: src/app/[lang]/(bridge)/components/TransactionList/TransactionDetails.tsx:41 msgid "Withdraw" msgstr "" @@ -1865,6 +1978,15 @@ msgstr "收益资产" msgid "You" msgstr "" +#: src/app/[lang]/fusion/components/TopUserModal/TopUserModal.tsx:46 +#: src/app/[lang]/fusion/Fusion.tsx:131 +msgid "You are one of the top 100 Spice holders in BOB Fusion" +msgstr "" + +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:116 +#~ msgid "You are one of the top 100 Spice holders in BOB Fusion. We would love to hear your thoughts on the BOB ecosystem and Bitcoin DeFi." +#~ msgstr "" + #: src/app/[lang]/(bridge)/components/GatewayTransactionDetails/GatewayTransactionDetails.tsx:76 #~ msgid "You are using a BTC address type (Taproot/P2TR) which we don't support yet. Change the BTC address type to Native SegWit in your wallet to continue." #~ msgstr "" @@ -1919,6 +2041,10 @@ msgstr "" #~ msgid "You've used all your tickets for today. New tickets will be available once the timer resets. Be sure to come back and vote daily to increase your chances of earning more SPICE!" #~ msgstr "" +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:243 +#~ msgid "Your {0} Referral Code" +#~ msgstr "" + #: src/app/[lang]/fusion/components/UserInfo/UserReferralModal.tsx:53 msgid "Your Active Referrals" msgstr "已推荐的活跃用户" @@ -1943,10 +2069,10 @@ msgstr "" msgid "Your performance in seasons 1 & 2" msgstr "你在第1季和第2季的表现" -#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:223 +#: src/app/[lang]/fusion/components/UserInfo/UserInfo.tsx:245 msgid "Your Referral Code" msgstr "你的推荐码" -#: src/components/Layout/FusionPopover.tsx:53 +#: src/components/Layout/FusionPopover.tsx:60 msgid "Your Spice Harvest Overview" msgstr "" diff --git a/apps/evm/src/types/global.d.ts b/apps/evm/src/types/global.d.ts index 1bf31d4d9..37b35d976 100644 --- a/apps/evm/src/types/global.d.ts +++ b/apps/evm/src/types/global.d.ts @@ -9,13 +9,14 @@ declare global { NEXT_PUBLIC_L2_CHAIN: `${number}`; NEXT_COINGECKO_API_KEY: string; NEXT_PUBLIC_GEOBLOCK_ENABLED: `${boolean}`; - NEXT_PUBLIC_FEATURE_FLAG_WALLET: 'enabled' | 'disabled'; NEXT_PUBLIC_INDEXER_URL: string; NEXT_PUBLIC_SENTRY_AUTH_TOKEN: string; NEXT_PUBLIC_SENTRY_URL: string; NEXT_PUBLIC_TRACES_SAMPLE_RATE: `${number}`; SENTRY_AUTH_TOKEN: string; + NEXT_PUBLIC_FEATURE_FLAG_OP_SUPERUSER: 'enabled' | 'disabled'; + NEXT_PUBLIC_FEATURE_FLAG_TOP_100_SPICE_USERS: 'enabled' | 'disabled'; } } } diff --git a/apps/evm/src/utils/api-client.ts b/apps/evm/src/utils/api-client.ts index 47af25798..758e21e07 100644 --- a/apps/evm/src/utils/api-client.ts +++ b/apps/evm/src/utils/api-client.ts @@ -9,6 +9,10 @@ export enum QuestRefCodes { INTRACT = '6y2pac' } +interface PostResponse { + ok: boolean; +} + type Logos = { default?: string }; interface DepositStat { @@ -113,6 +117,7 @@ export type UserResponse = { data: any; created_at: Date; updated_at: Date; + is_fusion_top_user: boolean; leaderboardRank?: { user_address: string; total_points: number; @@ -130,6 +135,11 @@ export type UserResponse = { quests_breakdown: Record; total_quest_points: string; season3Data: Season3Data; + notices: { + showIsFusionTopUser: boolean; + showIsOpUser: boolean; // will be set to false once dismissed + isOpUser: boolean; // stable + }; }; type LeaderboardResponse = { @@ -576,6 +586,24 @@ class ApiClient { return this.handleResponse(response); } + async dismissTopUserModal(): Promise { + const response = await fetch(`${this.baseUrl}/me/dismiss-fusion-top-user-notice`, { + method: 'POST', + credentials: 'include' + }); + + return this.handleResponse(response); + } + + async dismissOPUserModal(): Promise { + const response = await fetch(`${this.baseUrl}/me/dismiss-op-user-notice`, { + method: 'POST', + credentials: 'include' + }); + + return this.handleResponse(response); + } + async getLastVotingResults(): Promise { const response = await fetch(`${this.baseUrl}/finalized-voting-round/latest/results`); diff --git a/apps/evm/src/utils/index.ts b/apps/evm/src/utils/index.ts index 8bdb7d4f3..d64a5c705 100644 --- a/apps/evm/src/utils/index.ts +++ b/apps/evm/src/utils/index.ts @@ -1,3 +1,4 @@ export * from './api-client'; export * from './esplora-client'; export * from './math'; +export * from './locale'; diff --git a/apps/evm/src/utils/locale.ts b/apps/evm/src/utils/locale.ts new file mode 100644 index 000000000..5d8e15805 --- /dev/null +++ b/apps/evm/src/utils/locale.ts @@ -0,0 +1,12 @@ +import { enUS, zhCN } from 'date-fns/locale'; + +import linguiConfig from '../../lingui.config'; + +const localeMapping = { + en: enUS, + zh: zhCN +}; + +export const getLocale = (lang: (typeof linguiConfig)['locales'][number] = 'en') => { + return localeMapping[lang]; +}; diff --git a/packages/icons/src/Superchain.tsx b/packages/icons/src/Superchain.tsx new file mode 100644 index 000000000..384f9063f --- /dev/null +++ b/packages/icons/src/Superchain.tsx @@ -0,0 +1,211 @@ +import { forwardRef } from 'react'; +import { Icon, IconProps } from '@gobob/ui'; + +const Superchain = forwardRef((props, ref) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)); + +Superchain.displayName = 'Superchain'; + +export { Superchain }; diff --git a/packages/icons/src/index.ts b/packages/icons/src/index.ts index e00c5e601..0a4431711 100644 --- a/packages/icons/src/index.ts +++ b/packages/icons/src/index.ts @@ -22,6 +22,7 @@ export { Metamask } from './Metamask'; export { Moonbeam } from './Moonbeam'; export { OKXWallet } from './OKXWallet'; export { Optimism } from './Optimism'; +export { Superchain } from './Superchain'; export { Polygon } from './Polygon'; export { RabbyWallet } from './RabbyWallet'; export { Spice } from './Spice'; diff --git a/packages/ui/src/theme/themes/bob/switch.ts b/packages/ui/src/theme/themes/bob/switch.ts index f3eadf9f3..4a7fcefe8 100644 --- a/packages/ui/src/theme/themes/bob/switch.ts +++ b/packages/ui/src/theme/themes/bob/switch.ts @@ -12,7 +12,7 @@ const getSizeStyles = (width: string, height: string, percentage: string): Switc width: `calc(${height} * ${percentage})`, height: `calc(${height} * ${percentage})`, transform: `translateX(calc(${width} / 15))`, - top: `calc(50% - (${height} * 0.35))`, + top: `calc(50% - (${height} * 0.375))`, left: 0 }, checked: { @@ -35,7 +35,7 @@ const _switch: SwitchTheme = { }, focusVisible: `2px solid ${color('primary-500')}`, size: { - s: getSizeStyles(spacing('4xl'), spacing('2xl'), '0.7'), + s: getSizeStyles(spacing('4xl'), spacing('2xl'), '0.75'), md: getSizeStyles(spacing('5xl'), spacing('3xl'), '0.75'), lg: getSizeStyles(spacing('7xl'), spacing('4xl'), '0.75') } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4bc149b2b..2212d478e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -526,6 +526,9 @@ importers: react: specifier: ^18.2.0 version: 18.3.1 + react-calendly: + specifier: ^4.3.1 + version: 4.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-dom: specifier: ^18.2.0 version: 18.3.1(react@18.3.1) @@ -10660,6 +10663,13 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} + react-calendly@4.3.1: + resolution: {integrity: sha512-poyUH3NOUOlsotr8ho5WzbsbPuRAppaY+Jvu+C/PkwTP6WT807pNFI8+HrbbuRknXZbd75zpzysOJQvcu3P8Pg==} + engines: {node: '>=8', npm: '>=5'} + peerDependencies: + react: ^18.2.0 + react-dom: ^18.2.0 + react-clientside-effect@1.2.6: resolution: {integrity: sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==} peerDependencies: @@ -26484,6 +26494,11 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 + react-calendly@4.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-clientside-effect@1.2.6(react@18.3.1): dependencies: '@babel/runtime': 7.24.7