diff --git a/apps/beets-frontend-v3/app/(app)/pools/[chain]/[variant]/[id]/opengraph-image.jpg b/apps/beets-frontend-v3/app/(app)/pools/[chain]/[variant]/[id]/opengraph-image.jpg deleted file mode 100644 index 8bf26e872..000000000 Binary files a/apps/beets-frontend-v3/app/(app)/pools/[chain]/[variant]/[id]/opengraph-image.jpg and /dev/null differ diff --git a/apps/beets-frontend-v3/app/(app)/pools/[chain]/opengraph-image.png b/apps/beets-frontend-v3/app/(app)/pools/[chain]/opengraph-image.png new file mode 100644 index 000000000..efcb62dbe Binary files /dev/null and b/apps/beets-frontend-v3/app/(app)/pools/[chain]/opengraph-image.png differ diff --git a/apps/beets-frontend-v3/app/(app)/pools/cow/opengraph-image.png b/apps/beets-frontend-v3/app/(app)/pools/cow/opengraph-image.png deleted file mode 100644 index eff224d69..000000000 Binary files a/apps/beets-frontend-v3/app/(app)/pools/cow/opengraph-image.png and /dev/null differ diff --git a/apps/beets-frontend-v3/app/(app)/pools/layout.tsx b/apps/beets-frontend-v3/app/(app)/pools/layout.tsx index 05407516f..ac59be357 100644 --- a/apps/beets-frontend-v3/app/(app)/pools/layout.tsx +++ b/apps/beets-frontend-v3/app/(app)/pools/layout.tsx @@ -4,9 +4,9 @@ import { PropsWithChildren } from 'react' export const metadata: Metadata = { title: 'Beets DeFi Liquidity Pools', description: ` - Explore DeFi liquidity pools or create your own. - Provide liquidity to accumulate yield from swap fees - while retaining your token exposure as prices move. + Fuel your liquidity. + Earn yield from swap fees, incentives, and more. + Create and customize pools tailored to your strategy. `, } diff --git a/apps/beets-frontend-v3/app/(app)/pools/page.tsx b/apps/beets-frontend-v3/app/(app)/pools/page.tsx index a8b4d44dc..a07b73651 100644 --- a/apps/beets-frontend-v3/app/(app)/pools/page.tsx +++ b/apps/beets-frontend-v3/app/(app)/pools/page.tsx @@ -7,9 +7,9 @@ import { Suspense } from 'react' // import { getProjectConfig } from '@repo/lib/config/getProjectConfig' // import { GetFeaturedPoolsDocument } from '@repo/lib/shared/services/api/generated/graphql' // import { FeaturedPools } from '@repo/lib/modules/featured-pools/FeaturedPools' -import { CowPromoBanner } from '@repo/lib/shared/components/promos/CowPromoBanner' import { PoolListDisplayType } from '@repo/lib/modules/pool/pool.types' import { GqlPoolType } from '@repo/lib/shared/services/api/generated/graphql' +import { BeetsPromoBanner } from '@/lib/components/promos/BeetsPromoBanner' export default async function PoolsPage() { // Featured pools set up @@ -29,11 +29,11 @@ export default async function PoolsPage() { return ( <> - + - + {/* @@ -48,13 +48,13 @@ export default async function PoolsPage() { }> diff --git a/apps/beets-frontend-v3/app/(app)/pools/cow/page.tsx b/apps/beets-frontend-v3/app/(app)/pools/sonic/page.tsx similarity index 55% rename from apps/beets-frontend-v3/app/(app)/pools/cow/page.tsx rename to apps/beets-frontend-v3/app/(app)/pools/sonic/page.tsx index c6095e214..2dbfe2503 100644 --- a/apps/beets-frontend-v3/app/(app)/pools/cow/page.tsx +++ b/apps/beets-frontend-v3/app/(app)/pools/sonic/page.tsx @@ -1,34 +1,20 @@ +import { BeetsPromoBanner } from '@/lib/components/promos/BeetsPromoBanner' +import { Box, Skeleton } from '@chakra-ui/react' +import { PoolListDisplayType } from '@repo/lib/modules/pool/pool.types' import { PoolList } from '@repo/lib/modules/pool/PoolList/PoolList' +import { DefaultPageContainer } from '@repo/lib/shared/components/containers/DefaultPageContainer' import FadeInOnView from '@repo/lib/shared/components/containers/FadeInOnView' -import { GqlPoolType } from '@repo/lib/shared/services/api/generated/graphql' -import { Box, Skeleton } from '@chakra-ui/react' +import { GqlChain, GqlPoolType } from '@repo/lib/shared/services/api/generated/graphql' import { Suspense } from 'react' -import { Metadata } from 'next' -import { CowFooter } from '@repo/lib/shared/components/navs/CowFooter' -import { DefaultPageContainer } from '@repo/lib/shared/components/containers/DefaultPageContainer' -import { CowHeader } from '@repo/lib/shared/components/navs/CowHeader' - -export const metadata: Metadata = { - title: `CoW AMM DeFi Liquidity Pools`, - description: ` - CoW AMM protects LPs from LVR so they can provide liquidity - with less risk and more return. - `, -} export default function PoolsPage() { return ( <> - + - + @@ -37,12 +23,20 @@ export default function PoolsPage() { }> - + - - ) } diff --git a/apps/beets-frontend-v3/app/(app)/stake/layout.tsx b/apps/beets-frontend-v3/app/(app)/stake/layout.tsx new file mode 100644 index 000000000..094e34430 --- /dev/null +++ b/apps/beets-frontend-v3/app/(app)/stake/layout.tsx @@ -0,0 +1,8 @@ +'use client' + +import { DefaultPageContainer } from '@repo/lib/shared/components/containers/DefaultPageContainer' +import { PropsWithChildren } from 'react' + +export default function LstLayout({ children }: PropsWithChildren) { + return {children} +} diff --git a/apps/beets-frontend-v3/app/(app)/stake/page.tsx b/apps/beets-frontend-v3/app/(app)/stake/page.tsx new file mode 100644 index 000000000..01435b634 --- /dev/null +++ b/apps/beets-frontend-v3/app/(app)/stake/page.tsx @@ -0,0 +1,12 @@ +'use client' + +import { Lst } from '@/lib/modules/lst/Lst' +import LstProvidersLayout from '@/lib/modules/lst/LstProvidersLayout' + +export default function LstPage() { + return ( + + + + ) +} diff --git a/apps/beets-frontend-v3/app/(marketing)/3rd-party-services/page.tsx b/apps/beets-frontend-v3/app/(marketing)/3rd-party-services/page.tsx deleted file mode 100644 index 27a03047a..000000000 --- a/apps/beets-frontend-v3/app/(marketing)/3rd-party-services/page.tsx +++ /dev/null @@ -1,96 +0,0 @@ -'use client' - -import { Container, HStack, VStack, Image, Text } from '@chakra-ui/react' -import { Prose } from '@nikolovlazar/chakra-ui-prose' -import FadeInOnView from '@repo/lib/shared/components/containers/FadeInOnView' - -export default function Cookies() { - const services = [ - { - name: 'Infura', - description: 'Used to fetch on-chain data and constructs contract calls with an Infura API.', - iconUrl: '/images/services/infura.svg', - }, - { - name: 'Alchemy', - description: 'Used to fetch on-chain data and constructs contract calls with an Alchemy API.', - iconUrl: '/images/services/alchemy.svg', - }, - { - name: 'The Graph', - description: 'Used to fetch blockchain data from The Graph’s hosted service.', - iconUrl: '/images/services/the-graph.svg', - }, - { - name: 'Fathom Analytics', - description: 'Used to understand user behavior on the site and marketing performance.', - iconUrl: '/images/services/fathom-analytics.svg', - }, - { - name: 'Appzi', - description: 'Used to capture and store user feedback from optional surveys', - iconUrl: '/images/services/appzi.svg', - }, - { - name: 'Hypernative', - description: - 'Used to securely check wallet addresses and shares it with Hypernative Inc. for risk and compliance reasons.', - iconUrl: '/images/services/hypernative.svg', - }, - { - name: 'Sentry', - description: 'Used for error tracking and performance monitoring.', - iconUrl: '/images/services/sentry.svg', - }, - { - name: 'Amazon Web Services', - description: - 'Used for a variety of infrastructure services, but primarily to fetch and cache blockchain data.', - iconUrl: '/images/services/aws.svg', - }, - ] - - return ( - - -
- -
-

Use of 3rd party services

-

- Last Updated: October 2023 -

-

- Balancer is an open source, permissionless, decentralized protocol. The smart - contracts that power the ecosystem may be used by anyone. This website is the - Balancer Foundation's front-end to the ecosystem and it is also open-source. - You are free to fork it on Github and modify it as you wish. -

-

This website uses the following 3rd party services:

- - {services.map(service => ( - - {service.name} - - - {service.name} - - - {service.description} - - - - ))} - -
-
-
-
-
- ) -} diff --git a/apps/beets-frontend-v3/app/(marketing)/components/SandPatterns.tsx b/apps/beets-frontend-v3/app/(marketing)/components/SandPatterns.tsx deleted file mode 100644 index c4453ed0f..000000000 --- a/apps/beets-frontend-v3/app/(marketing)/components/SandPatterns.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import React, { PropsWithChildren } from 'react' -import { Box, Flex } from '@chakra-ui/react' -import { motion, MotionStyle, useAnimation, useReducedMotion } from 'framer-motion' - -function SandPatterns({ children, ...rest }: PropsWithChildren) { - const circles = Array.from({ length: 10 }, (_, i) => i + 1) - const controls = useAnimation() - const shouldReduceMotion = useReducedMotion() - - const circleStyle: MotionStyle = { - position: 'absolute', - top: '50%', - left: '50%', - transform: 'translate(-50%, -50%)', - border: `1px solid var(--chakra-colors-input-borderDefault)`, - backgroundColor: 'transparent', - zIndex: '-10', - } - - React.useEffect(() => { - if (!shouldReduceMotion) { - controls.start(i => { - const calculatedWidth = 30 * (1 + 0.25 * i) - return { - width: [`${calculatedWidth}vw`], - height: [`${calculatedWidth}vw`], - borderRadius: ['10%', '50%', '10%'], - opacity: 1 - i * 0.1, - transition: { - duration: 90, - repeat: Infinity, - repeatType: 'reverse', - delay: i * 1.5, - ease: 'easeOut', - }, - } - }) - } - }, [controls, shouldReduceMotion]) - - return ( - - {circles.map(circleNum => ( - - ))} - - {children} - - - ) -} - -export default SandPatterns diff --git a/apps/beets-frontend-v3/app/(marketing)/components/page.tsx b/apps/beets-frontend-v3/app/(marketing)/components/page.tsx deleted file mode 100644 index 782e046c0..000000000 --- a/apps/beets-frontend-v3/app/(marketing)/components/page.tsx +++ /dev/null @@ -1,1266 +0,0 @@ -'use client' - -import { - Text, - Center, - Heading, - Box, - Button, - Flex, - Input, - InputGroup, - InputRightElement, - Select, - UnorderedList, - ListItem, - Stack, - Avatar, - Card, - Checkbox, - Radio, - RadioGroup, - CardHeader, - CardBody, - Link, - CardFooter, - Image, - Slider, - SliderTrack, - SliderFilledTrack, - SliderThumb, - Tag, - Alert, - AlertIcon, - AlertTitle, - AlertDescription, - FormControl, - FormLabel, - FormErrorMessage, - FormHelperText, -} from '@chakra-ui/react' - -import { darken } from '@chakra-ui/theme-tools' -import Section from '@repo/lib/shared/components/layout/Section' - -export default function Components() { - return ( - - - - Components - - - Contents - - - - Colors - - - Typography - - - Buttons - - - Radius - - - Elevation - - - Shadows - - - Alerts - - - Cards - - - - Form fields - - - - -
- - Colors - - -
- Primary - -
- 50 -
- -
- 100 -
- -
- 200 -
- -
- 300 -
- -
- 400 -
- -
- 500 -
- -
- 600 -
- -
- 700 -
-
- 800 -
-
- 900 -
-
-
- -
- Gray - -
- 50 -
- -
- 100 -
- -
- 200 -
- -
- 300 -
- -
- 400 -
- -
- 500 -
- -
- 600 -
- -
- 700 -
-
- 800 -
-
- 900 -
-
-
- -
- Brown - -
- 50 -
-
- 100 -
-
- 200 -
-
- 300 -
-
- 400 -
-
- 500 -
-
- 600 -
-
- 700 -
-
- 800 -
-
- 900 -
-
-
- -
- Orange - -
- 50 -
- -
- 100 -
- -
- 200 -
- -
- 300 -
- -
- 400 -
- -
- 500 -
- -
- 600 -
- -
- 700 -
-
- 800 -
-
- 900 -
-
-
- -
- Red - -
- 50 -
-
- 100 -
-
- 200 -
-
- 300 -
-
- 400 -
-
- 500 -
-
- 600 -
-
- 700 -
-
- 800 -
-
- 900 -
-
-
-
- Purple - -
- 50 -
-
- 100 -
-
- 200 -
-
- 300 -
-
- 400 -
-
- 500 -
-
- 600 -
-
- 700 -
-
- 800 -
-
- 900 -
-
-
-
- Green - -
- 50 -
-
- 100 -
-
- 200 -
-
- 300 -
-
- 400 -
-
- 500 -
-
- 600 -
-
- 700 -
-
- 800 -
-
- 900 -
-
-
-
- Gradients - - -
- Background special -
-
- -
- Background special secondary -
-
-
-
- -
- - Typography - - - - H1 Hero - - Hero heading 1 - - - - - H1 - - Default app Heading 1 - - - - - H2 - - Heading 2 - - - - - H3 - - Heading 3 - - - - - H4 - - Heading 4 - - - - - H5 - - Heading 5 - - - - - H6 - - Heading 6 - - - - - P - - Body text lorem ipsum dolor sit amet consectetur adipisicing elit. Tempora quidem ipsa - magnam dignissimos impedit odit tempore, necessitatibus provident cupiditate. Explicabo - iusto incidunt illum molestiae, dolores quam odit cupiditate id quibusdam! - - - - Text secondary - - Body text lorem ipsum dolor sit amet consectetur adipisicing elit. Tempora quidem ipsa - magnam dignissimos impedit odit tempore, necessitatibus provident cupiditate. Explicabo - iusto incidunt illum molestiae, dolores quam odit cupiditate id quibusdam! - - - - Text error - - Body text lorem ipsum dolor sit amet consectetur adipisicing elit. - - - - Text special - - Body text lorem ipsum dolor sit amet consectetur adipisicing elit. Tempora quidem ipsa - magnam dignissimos impedit odit tempore, necessitatibus provident cupiditate. Explicabo - iusto incidunt illum molestiae, dolores quam odit cupiditate id quibusdam! - - - - Text special secondary - - Body text lorem ipsum dolor sit amet consectetur adipisicing elit. Tempora quidem ipsa - magnam dignissimos impedit odit tempore, necessitatibus provident cupiditate. Explicabo - iusto incidunt illum molestiae, dolores quam odit cupiditate id quibusdam! - - - - Unordered list items - - To do - - - - Colors - - - Typography - - - Buttons - - - Cards - - - Inputs - - - - - Link - - - Cookies policy - - - - - External link - - Learn more on Aura - - - - Eyebrow - Lorem ipsum - -
- -
- - Buttons - -
- - Button sizes - - - - - - - -
-
- - Button variants - - - - - - - -
-
- - Custom{' '} - - - - - - -
-
- -
- - Border Radius - - -
- none -
-
- -
sm
-
2px
-
-
-
- -
base
-
4px
-
-
-
- -
lg
-
8px
-
-
-
- -
xl
-
12px
-
-
-
- -
2xl
-
16px
-
-
-
- -
3xl
-
20px
-
-
-
- -
full
-
9999px
-
-
-
-
- -
- - Elevation - - 8 level elevation system - - - Background color is determined by height. - - The higher it is, the lighter the color. - - - - Shadows are relative. - - - The shadow size is dependent on the relative distance between it and the next level. - - - - - Card colors -
- - - Card level 0 - - - Card level 1 - - - Card level 2 - - - Card level 3 - - - Card level 4 - - - - - - - - - - -
-
- -
- - Shadows - - - - - xs - - - - - sm - - - - - base - - - - - md - - - - - lg - - - - - xl - - - - - 2xl - - - - - dark-lg - - - - - - - outline - - - - - inner base - - - - - inner - - - - - innerSm - - - - - innerMd - - - - - innerLg - - - -
- -
- - Alerts - -
- - - Your browser is outdated! - Your Chakra experience may be degraded. - -
- -
- - - Your browser is outdated! - Your Chakra experience may be degraded. - -
-
- - - Your browser is outdated! - Your Chakra experience may be degraded. - -
- -
- - - Your browser is outdated! - A tip or piece of information. - -
-
- -
- - Cards - - - - - - - - - Title - Subtitle - - - - - - - lorem ipsum dolor sit amet consectetur adipisicing elit. Tempora quidem ipsa magnam - dignissimos impedit odit tempore, necessitatibus provident cupiditate. Explicabo iusto - incidunt illum molestiae, dolores quam odit cupiditate id quibusdam! - - - Chakra UI - - button': { - minW: '136px', - }, - }} - > - - - - - -
- -
- - Form fields - - - - - Custom input fields - - - For some reason, I haven't been able to get some of these styles into the theme, so - I've listed all the code below - - - -
-
- - - Input label - - - - {/* */} - {/* This doesn't work, but color="yellow" does work... */} - - - - Hint text that is displayed on focus of the input - - - -
-
- - Input label - - - Exceeds wallet balance - - -
-
- - - Disabled input label - - - -
-
- - - - Theme inputs - - This is how it comes out of the theme. - - - - - Input - - - - - - - Disabled input - - - - - - - Select - - - - - - - Checkbox - - - Checkbox - Checkbox - - - - - - Radios - - - - - Checked - - Unchecked - Unchecked - - - - - - - Slider - - - - - - - - -
-
- ) -} diff --git a/apps/beets-frontend-v3/app/(marketing)/cookies-policy/page.tsx b/apps/beets-frontend-v3/app/(marketing)/cookies-policy/page.tsx deleted file mode 100644 index 4036767ba..000000000 --- a/apps/beets-frontend-v3/app/(marketing)/cookies-policy/page.tsx +++ /dev/null @@ -1,122 +0,0 @@ -'use client' - -import Link from 'next/link' -import { Container } from '@chakra-ui/react' -import { Prose } from '@nikolovlazar/chakra-ui-prose' -import FadeInOnView from '@repo/lib/shared/components/containers/FadeInOnView' - -export default function Cookies() { - return ( - - -
- -
-

Balancer Cookies Policy

-

- Last Updated: October 2023 -

-
-
- -
-

I. Introduction and Scope of Policy

-

- This Cookies Policy (“Policy”) applies to your interaction with the Balancer - Foundation, its subsidiary, Balancer OpCo Limited, and material service providers - operating under a legal agreement (“Balancer Foundation,” “Balancer,” “we,” “our,” - or “us”). -

-
-
- -
-

II. About Cookies

-

- Cookies are pieces of data stored on your device. Browser cookies are assigned by a - web server to the browser on your device. When you return to a site you have visited - before, your browser gives this data back to the server. Mobile applications may - also use cookies. -

- -

- We do not generally use cookies; however our third party vendors do. We do not - intentionally collect information to customize your experience on the website or the - Balancer.fi user interface (UI) to the Balancer Protocol. (“Sites” or “Site”). -

-

- Industry standards are currently evolving, and we may not separately respond to or - take any action with respect to a “do not track” configuration set in your internet - browser. -

-

- Other parties that collect information about your web browsing behavior when you use - our Site are generally limited to service providers who only use any information - collected to provide services for us and not to provide services or advertising for - any other party. Note, however, that we also provide certain widgets or tools on our - sites that allow you to interact with third parties who provide these features, such - as tools that allow web surfers to easily share information on another platform. At - other times, information from a third party may be embedded on our Site, such as a - map. These widgets, tools, and informational items often function through the use of - third-party cookies utilized by the third party site. As a result, these third - parties may have access to information about your web browsing on the pages of our - Site where these widgets, tools, or information are placed. You may wish to review - information at third party sites, where you have an account, to determine how these - third parties treat data that they obtain through the use of cookies. -

-
-
- -
-

III. Do You Have to Accept Cookies?

- -

- You may be able to set your browser to reject cookies. If you set your browser - options to disallow cookies, you may limit the functionality we can provide when you - visit our Site. The latest versions of internet browsers provide cookie management - tools, such as the ability to delete or reject cookies. We recommend that you refer - to information supplied by browser providers for more specific information, - including how to use these tools. -

-
-
- -
-

IV. Additional Technologies

-

- We do not typically use additional technologies such as pixel tags, web beacons, and - clear GIFs. We permit third-party service providers to use these technologies. They - use these technologies for purposes such as determining viewing and response rates. -

-
-
- -
-

V. Using Information

-

- In addition to the uses described above, we may use information for purposes as - allowed by law such as: servicing; communicating with you; improving our Site, - products, or services; legal compliance; risk control; information security; - anti-fraud purposes; tracking website usage, such as number of hits, pages visited, - and the length of user sessions in order to evaluate the usefulness of our sites. -

-
-
- -
-

VI. Sharing

-

- We share information with service providers with whom we work, such as service - providers and companies that help us service you better. When permitted or required - by law, we may share information with additional third parties for purposes - including response to legal process. As applicable, please see our{' '} - Privacy policy for more information on how we may - share information with affiliates and third parties. -

-
-
-
-
-
- ) -} diff --git a/apps/beets-frontend-v3/app/(marketing)/layout.tsx b/apps/beets-frontend-v3/app/(marketing)/layout.tsx index 21e5be9ba..574bb02ea 100644 --- a/apps/beets-frontend-v3/app/(marketing)/layout.tsx +++ b/apps/beets-frontend-v3/app/(marketing)/layout.tsx @@ -1,13 +1,7 @@ /* eslint-disable max-len */ import { Box } from '@chakra-ui/react' -import { Metadata } from 'next' import { PropsWithChildren } from 'react' -export const metadata: Metadata = { - title: 'Beets DeFi AMMs made easy', - description: `DeFi's most extensive AMM product suite—Balancer is a decentralized Automated Market Maker protocol built on Ethereum with a clear focus on fungible and yield-bearing liquidity.`, -} - export default function MarketingLayout({ children }: PropsWithChildren) { - return {children} + return {children} } diff --git a/apps/beets-frontend-v3/app/(marketing)/page.tsx b/apps/beets-frontend-v3/app/(marketing)/page.tsx index 824b593dd..2583a3a27 100644 --- a/apps/beets-frontend-v3/app/(marketing)/page.tsx +++ b/apps/beets-frontend-v3/app/(marketing)/page.tsx @@ -1,25 +1,55 @@ -'use client' +import { LandingPageLayout } from '@/lib/modules/landing-page/LandingPageLayout' +import { getApolloServerClient } from '@repo/lib/shared/services/api/apollo-server.client' +import { PROJECT_CONFIG } from '@repo/lib/config/getProjectConfig' +import { mins } from '@repo/lib/shared/utils/time' +import { + GetProtocolStatsDocument, + GetProtocolStatsPerChainDocument, + GqlChain, +} from '@repo/lib/shared/services/api/generated/graphql' -import { ReactLenis } from '@studio-freight/react-lenis' -import { Box } from '@chakra-ui/react' -import { AnimatedSVG } from '@repo/lib/shared/components/marketing/AnimatedSVG' -import { HomeHero } from '@repo/lib/shared/components/marketing/HomeHero' -import { HomeBuilders } from '@repo/lib/shared/components/marketing/HomeBuilders' -import { HomeProtocols } from '@repo/lib/shared/components/marketing/HomeProtocols' -import { HomeActivity } from '@repo/lib/shared/components/marketing/HomeActivity' +export default async function Home() { + const client = getApolloServerClient() + + const variables = { + chains: [...PROJECT_CONFIG.supportedNetworks, GqlChain.Fantom], // manually adding Fantom to the list to get the data for the landing page + } + + const { data: protocolData } = await client.query({ + query: GetProtocolStatsDocument, + variables, + context: { + fetchOptions: { + next: { revalidate: mins(10).toSecs() }, + }, + }, + }) + + const { data: protocolDataSonic } = await client.query({ + query: GetProtocolStatsPerChainDocument, + variables: { + chain: GqlChain.Sonic, + }, + }) + + const { data: protocolDataOptimism } = await client.query({ + query: GetProtocolStatsPerChainDocument, + variables: { + chain: GqlChain.Optimism, + }, + }) + + const { data: protocolDataFantom } = await client.query({ + query: GetProtocolStatsPerChainDocument, + variables: { + chain: GqlChain.Fantom, + }, + }) -export default function Home() { return ( - - - - - - - - - - - + ) } diff --git a/apps/beets-frontend-v3/app/(marketing)/privacy-policy/page.tsx b/apps/beets-frontend-v3/app/(marketing)/privacy-policy/page.tsx deleted file mode 100644 index b526065a8..000000000 --- a/apps/beets-frontend-v3/app/(marketing)/privacy-policy/page.tsx +++ /dev/null @@ -1,426 +0,0 @@ -'use client' - -import Link from 'next/link' -import { Container } from '@chakra-ui/react' -import { Prose } from '@nikolovlazar/chakra-ui-prose' -import FadeInOnView from '@repo/lib/shared/components/containers/FadeInOnView' - -export default function Privacy() { - return ( - - -
- -
-

Balancer Privacy Policy

-

- Last Updated: October 2023 -

-

- - This Privacy Policy explains how the Balancer Foundation, its subsidiary, Balancer - OpCo Limited (“Balancer Foundation,” “Balancer,” “we,” “our,” or “us”) collects, - uses, and discloses information about you. This Privacy Policy applies when you - use our website, Balancer Protocol user-interface or application and other online - products (collectively, our “UI”), engage with us on social media, or otherwise - interact with us. - -

-

- - We may change this Privacy Policy from time to time. If we make changes, we will - notify you by revising the date at the top of this policy and, when material, we - will provide you with additional notice by adding a statement to our website and - consent as required under applicable law. Your continued use of this UI after we - make changes is deemed to be acceptance of those changes when permissible. We - encourage you to review this Privacy Policy regularly to stay informed about our - information practices and the choices available to you. - -

-
-
- -
-

Summary

-
    -
  • - Balancer does not typically request, collect or use personal information. With the - exception of your wallet address, there is no reason for you to provide personal - information when you use the UI. -
  • -
  • - Balancer does not and has not stored personal information from users of the UI. - However, Balancer uses third party services including, without limitation, - Cloudflare, Fathom Analytics, Appzi and others who collect and store certain user - information only for use in the provision of their services. -
  • -
  • - Balancer does not set any cookies. However, we use third party service providers - that set cookies. -
  • -
-
-
- -
-

Collection of Information

-

Information You Provide to Us

- -

- We do not typically request, collect or use personal information from you except - under limited circumstances as described herein. With the exception of your wallet - address, there is no reason for you to provide personal information when you use the - UI. Your use of the UI will not be customized and this policy reflects that - practice. -

-

- Balancer is not directed to children under the age of 16. If a parent or guardian - becomes aware that his or her child has provided us with personal information - without your consent, please contact us at - - privacypolicy@balancer.finance - - . If we become aware that a child under the age of 16 has provided us with personal - information, we will take reasonable efforts to delete such personal information. -

- -

Information We Collect Automatically When You Interact With Us

-

- When you access or use our UI, we may automatically collect certain information, - including: -

-
    -
  • - Device and Usage Information: We (and our - service providers) collect information about how you access the UI, including data - about the device and network you use, such as your hardware model, operating - system version, mobile network, browser type, IP address and app version. We do - not typically, but we may, also collect information about your activity on the UI, - such as access times, pages viewed, links clicked, and the page you visited before - navigating to the UI. -
  • -
  • - - Information Collected by Cookies and Similar Tracking Technologies: - - We do not typically use tracking technologies, such as cookies and web beacons, to - collect information about you; however, third parties we rely on may do so. - Cookies are small data files stored on your hard drive or in device memory that - help us improve the UI and your experience, see which areas and features of the UI - are popular, and count visits. Web beacons (also known as “pixel tags” or “clear - GIFs”) are electronic images that we use on the UI to help deliver cookies, count - visits, and understand usage and campaign effectiveness. For more information - about cookies and how to disable them, see our{' '} - Cookies policy and the Your Choices section - below. -
  • -
- -

Information We Collect from Other Sources

- -

- We do not typically obtain information from third-party sources in order to provide - business services. We do not sell information we collect. -

- -

Information We Derive

- -

- We may derive limited information or draw inferences about you based on the - information we have access to or receive, most importantly, from our service - providers. Your wallet and IP address is accessible to Balancer and its vendor(s). - We may make inferences about you based on your wallet or IP address. -

-
-
- -
-

Use of Information

- -

- We do not collect your personal information, other than wallet address, to customize - the UI for your use. However, we reserve the ability to use information we collect - to provide, maintain, administer and/or improve the UI. We may also use the - information we collect to: -

-
    -
  • Ensure proper functioning of Balancer and the UI;
  • -
  • Provide services, content, material and other information on the UI;
  • -
  • Identify and/or diagnose problems on or related to the UI;
  • -
  • - Send technical notices, security alerts, and support and administrative messages; -
  • -
  • - Provide requested information, technical support and/or integrations such as an - application programming interface or API; -
  • -
  • Respond to comments and questions;
  • -
  • Analyze trends, usage, and activities in connection with the UI;
  • -
  • - Detect, investigate, and prevent security incidents and other malicious, - deceptive, fraudulent, or illegal activity and protect the rights and property of - Balancer and others; -
  • -
  • Debug to identify and repair errors in the UI;
  • -
  • Comply with legal, regulatory and financial obligations;
  • -
  • - Carry out any other purpose described to you at the time the information was - collected; and -
  • -
  • - For other reasonable internal use or uses aligned with your relationship with us - and the context in which we collected the information. -
  • -
-
-
- -
-

Sharing of Information

- -

- We do not have access to or share personally identifiable information, other than as - described herein, in the normal course of Balancer business. However, when Balancer - has access to personal information, such as your wallet and certain IP addresses, it - may share that information in the following circumstances or as otherwise described - in this policy: -

-
    -
  • - We share personal information with vendors, service providers, and consultants - that need access to personal information in order to perform services for us, such - as transaction monitoring, data management, fraud prevention, customer service and - support, marketing and/or advertising. -
  • -
  • - If you choose to use integrations, we may share certain information with the - integration partners. -
  • -
  • - We may disclose personal information if we believe that disclosure is in - accordance with, or required by, any applicable law or legal process, including - lawful requests by public authorities to meet national security or law enforcement - requirements. -
  • -
  • - We may share personal information if we believe that your actions are inconsistent - with our user agreements or policies, if we believe that you have violated the - law, or if we believe it is necessary to protect the rights, property, and safety - of Balancer, the Balancer ecosystem, the public, or others. -
  • -
  • - We share personal information with our lawyers and other professional advisors - where necessary to obtain advice or otherwise protect and manage our business - interests. -
  • -
  • - We may share personal information in connection with, or during negotiations - concerning, merger, sale of company assets, financing, bankruptcy, business - closure, or acquisition of all or a portion of our assets. Additionally, as part - of such an event, we may transfer or sell personal information to a third party. - We will provide notice to you on our UI of any such sharing to a third party and - any choices you may have regarding the sharing of your personal information. -
  • -
  • - Personal information may be shared between and among Balancer and our current and - future parents, affiliates, and subsidiaries and other companies under common - control and ownership (“corporate affiliates”). This information may be used to - provide you with offers, services, or products that may be of interest to you and - provide you with their products and services. Any such corporate affiliate may use - your personal information only according to the terms of this Policy. If you are - located in a jurisdiction where such sharing requires your permission, we will - only share such information with your consent. If you decide you no longer wish to - receive these promotional communications, please follow the instructions provided - in Your Choices section below. -
  • -
  • We share personal information with your consent or at your direction.
  • -
  • - We also share aggregated or de-identified information that cannot reasonably be - used to identify you. -
  • -
-
-
- -
-

Advertising and Analytics

- -

- We do not work with third parties to serve ads to you as part of customized - campaigns on the UI or third-party UIs. -

-
-
- -
-

Transfer of information to the United States and Other Countries

- -

- Balancer Foundation is headquartered in the Cayman Islands with a subsidiary in the - British Virgin Islands (BVI). Therefore, we and our service providers may transfer - your personal information to, or store or access it in, jurisdictions that may not - provide levels of data protection that are equivalent to those of your home - jurisdiction. We will take steps to ensure that your personal information receives - an adequate level of protection in the jurisdictions in which we process it. -

-
-
- -
-

Your Choices

-

Cookies

-

- Balancer and its third party vendors may use any cookies to affect the availability - and functionality of the UI. For more information about cookies and how to disable - them, see our Cookies policy. -

-
-
- -
-

Additional Considerations

- -

- In the preceding 12 months, we or our vendors may have collected the following - categories of personal information: identifiers, internet or other electronic - network activity information and inferences. For details about the data points we - collect and the categories of sources of such collection, please see the Collection - of Information section above. We collect personal information for the purposes - described in the Use of Information section above. In the preceding 12 months, we - have disclosed the following categories of personal information for business - purposes to the following categories of recipients: -

- - - - - - - - - - - - - - -
Category of Personal InformationType of Information & Categories of Recipients
Identifiers -

- We share with vendors, such CloudFlare and Fathom Analytics: certain IP - addresses, device identifiers or other similar identifiers. -

- -

- With our compliance partner, TRM Labs, we only share wallet addresses used to - connect a wallet to our UI (all other user information like IP addresses, - device identifiers and location are not shared). The code for the UI is open - source, and can be reviewed by anyone at any time. -

-
Internet or other electronic network activity information - We share with vendors: information regarding an interaction with an UI/website -
- -

- Balancer does not “sell” personal information to advertise our products to you or - otherwise. -

- -

- Subject to certain limitations, you have the right to (1) request to know more about - the categories and specific pieces of personal information we collect, use, and - disclose, and sell, (2) request deletion of your personal information, (3) opt out - of any “sales” of your personal information that may be occurring, and (4) not be - discriminated against for exercising these rights. You may make these requests by - emailing us at - - privacypolicy@balancer.finance - - . If we receive your request from an authorized agent, we may ask for evidence that - you have provided such agent with a power of attorney or that the agent otherwise - has valid written authority to submit requests to exercise rights on your behalf. If - you are an authorized agent seeking to make a request, please contact us. -

- -

Shine the Light

- -

- Balancer does not share such information with third parties for direct marketing - purposes. -

- -

Do Not Track Signals

- -

- Our Services do not respond to “Do Not Track” signals communicated by your browser. - We do not knowingly retain or sell tracking information collected about your online - activity. For more information about Do Not Track, please visit{' '} - - www.allaboutdnt.com - - . -

-
-
- -
-

Additional Disclousures for Individuals in Europe

- -

- If you are located in the European Economic Area (EEA), the United Kingdom, or - Switzerland, you have certain rights and protections under the law regarding the - processing of your personal data, and this section applies to you. -

-

Legal Basis for Processing

- -

- Balancer does not typically process user personal data. If Balancer processes data, - such as a wallet address and certain IP addresses, it will do so in reliance on the - following lawful bases: -

-
    -
  • - To perform our responsibilities under our contract with you (e.g., providing - access to the UI you requested). -
  • -
  • - When we have a legitimate interest in processing your personal data to operate the - UI or protect our interests (e.g., to adhere with applicable laws, rules and - regulations, provide, maintain, and improve our products and UI, conduct data - analytics, and communicate with you). -
  • -
  • To comply with our legal obligations.
  • -
-

Data Retention

- -

- We do not maintain customer accounts or store personal data. Our vendor will store - your wallet address in order to provide requested services. -

-

Data Subject Requests

-

- Subject to certain limitations, you have the right to request access to the personal - data we hold about you and to receive your data in a portable format, the right to - ask that your personal data be corrected or erased, and the right to object to, or - request that we restrict, certain processing. Balancer does not typically hold or - store such personal data. -

-
-
- -
-

Contact Us

- -

- If you have any questions about this Privacy Policy, please contact us at{' '} - - privacypolicy@balancer.finance - - . -

-
-
-
-
-
- ) -} diff --git a/apps/beets-frontend-v3/app/(marketing)/risks/page.tsx b/apps/beets-frontend-v3/app/(marketing)/risks/page.tsx index a4ef7b727..9ee425ff1 100644 --- a/apps/beets-frontend-v3/app/(marketing)/risks/page.tsx +++ b/apps/beets-frontend-v3/app/(marketing)/risks/page.tsx @@ -4,22 +4,37 @@ import Link from 'next/link' import { Container, Divider, Box } from '@chakra-ui/react' import { Prose } from '@nikolovlazar/chakra-ui-prose' import FadeInOnView from '@repo/lib/shared/components/containers/FadeInOnView' +import { useEffect } from 'react' export default function Privacy() { + useEffect(() => { + const handleHashChange = () => { + const { hash } = window.location + if (hash) { + const id = hash.substring(1) + const element = document.getElementById(id) + element?.scrollIntoView({ behavior: 'smooth' }) + } + } + + // Run on initial load + handleHashChange() + }, []) + return (
-

Risks of using Balancer

+

Risks of using Beets

Last Updated: May 2024

There are many inherent risks developers accept when working in DeFi and using the - Balancer Protocol. This page aims to summarize the top risks to help you with your + Beets Protocol. This page aims to summarize the top risks to help you with your risk decisions. It is important to note that this list is not exhaustive, and there may be additional risks not explicitly mentioned here. As the risk environment is fluid, we expect to periodically update this summary. @@ -70,6 +85,9 @@ export default function Privacy() {

  • Impermanent loss risk
  • +
  • + Hooks risk +
  • User Interface risk
  • @@ -708,6 +726,37 @@ export default function Privacy() {
    + +
    +

    + Hooks +

    +

    + Hooks introduces complex logic into Balancer pools and changes in its parameters can + significantly impact the risk profile of a pool. This complexity increases the + potential for unforeseen errors or vulnerabilities in the hook's code, that may + i.e. amplify impermanent loss, introduce new sources of volatility or impose + restrictions on pool interactions like joins and exits. +

    +
      +
    • + Hook specific risk: Balancer hooks introduce unique functionalities to Balancer + pools, and while they offer exciting possibilities, they also present specific + risks that users should be aware of. +
    • +
    • + Hook Interactions: Hooks can interact with each other and with the pool contracts + in unexpected ways. These interactions may lead to unintended and yet unknown + consequences or exploits. +
    • +
    • + Hook Updates: Hooks may be updated or modified over time. These updates could + introduce new risks or alter the functionality of the pool in ways that may + negatively impact your assets. +
    • +
    +
    +

    @@ -1016,39 +1065,37 @@ export default function Privacy() { liquidity, and increased yield for Liquidity Providers.
  • - For traders, Boosted Pools are a cheaper entry/exit into lending protocols - like Aave. + For traders, Boosted Pools are a cheaper entry/exit into decentralized lending + protocols like Aave.
  • Boosted Pools increase the opportunity for LPs to gain exposure to a wide variety of yield increases from multiple yield protocols.
  • -

    Third party lending platform risk exposure (DeFi composability risk)
    +
    Third party platform risk exposure (DeFi composability risk)

    - Since boosted pools deposit excess liquidity into lending protocols, like Aave, - to generate yield, LPs must fully understand the risks of the underlying lending + Since boosted pools deposit excess liquidity into third-party protocols, like + Aave, to generate yield, LPs must fully understand the risks of the underlying protocol since a portion of their funds will be exposed to the risks of that - protocol. Some of the risks of the underlying lending protocol may include smart + protocol. Some of the risks of the underlying protocol may include smart contract bugs, economic attack vulnerabilities and counterparty risk from the - protocol’s borrowers. Lending platforms may also use{' '} + protocol’s borrowers. Underlaying protocols may also use{' '} Oracles {' '} which face additional risks (described above).

    -

    - Also note, some Boosted pools, like those by Tetu and Idle may use strategies - that utilize multiple yield protocols in order to maximize yield. Since these - strategies may change exposure to the underlying yield protocols at any time, - LPs must accept the risk that the protocol utilizing these strategies carefully - vets all third party protocols to reduce composability risks. + Also note, some boosted pools may use strategies that utilize multiple yield + protocols in order to maximize yield. Since these strategies may change exposure + to the underlying yield protocols at any time, LPs must accept the risk that the + protocol utilizing these strategies carefully vets all third party protocols to + reduce composability risks.

    -

    - If the underlying lending protocol were to get hacked, LPs in a boosted pool - that deposits liquidity in that protocol could lose funds. + If the underlying protocol were to get hacked, LPs in a boosted pool that + deposits liquidity in that protocol could lose funds.

    Depegging risk

    diff --git a/apps/beets-frontend-v3/app/(marketing)/terms-of-service/page.tsx b/apps/beets-frontend-v3/app/(marketing)/terms-of-service/page.tsx new file mode 100644 index 000000000..cff15dafa --- /dev/null +++ b/apps/beets-frontend-v3/app/(marketing)/terms-of-service/page.tsx @@ -0,0 +1,55 @@ +'use client' + +import Link from 'next/link' +import { Container } from '@chakra-ui/react' +import { Prose } from '@nikolovlazar/chakra-ui-prose' +import FadeInOnView from '@repo/lib/shared/components/containers/FadeInOnView' + +export default function Terms() { + return ( + + + +

    +

    Beets Terms of service

    +

    + Last updated: February 2023 +

    +
    + + +
    +

    BeethovenX DAO Reliquary NFT Terms

    +

    Protocol & Entity Participation.

    +

    + Unless otherwise indicated, the defined and capitalized terms used below incorporate + the same meaning as the terms used in the BeethovenX DAO LLC operating agreement (the + “Agreement”), available{' '} + + here + + . The NFT is referred to as the “Token” in the Agreement. +

    +

    + By using this NFT to participate in the governance and operations of BeethovenX , the + holder of this NFT agrees to be subject to the terms of the Agreement, including as a + Member of its entity structure. BeethovenX formed a nonprofit LLC under the laws of + the Republic of the Marshall Islands on TBD. Participation in the governance + and operations of BeethovenX includes, but is not limited to, utilizing the NFT to: + (1) vote on Proposals to become Governance Resolutions, (2) attend events and + otherwise communicate with the BeethovenX community, and (3) interact with the Beets + protocol. +

    +

    + Except as otherwise provided in the Agreement, a Token Holder’s membership interest or + rights thereunder in relation to this NFT are freely transferable to another person + through its conveyance. Except as otherwise provided in the Agreement, a Member shall + be deemed to have resigned from the BeethovenX DAO LLC upon the disposal or transfer + of this NFT. +

    +
    +
    + + + ) +} diff --git a/apps/beets-frontend-v3/app/(marketing)/terms-of-use/page.tsx b/apps/beets-frontend-v3/app/(marketing)/terms-of-use/page.tsx deleted file mode 100644 index ae2c09b1a..000000000 --- a/apps/beets-frontend-v3/app/(marketing)/terms-of-use/page.tsx +++ /dev/null @@ -1,596 +0,0 @@ -'use client' - -import Link from 'next/link' -import { Container } from '@chakra-ui/react' -import { Prose } from '@nikolovlazar/chakra-ui-prose' -import FadeInOnView from '@repo/lib/shared/components/containers/FadeInOnView' - -export default function Terms() { - return ( - - - -
    -

    Balancer Terms of Use

    -

    - Last updated: August 2024 -

    -

    - - Do not access this site where such access is prohibited by applicable law. Please - carefully read these terms of use before using the site. These terms apply to any - person or entity accessing the site and by using the site you agree to be bound by - them. The terms of use contain a mandatory individual arbitration and class - action/jury trial waiver provision that requires the use of arbitration on an - individual basis to resolve disputes, rather than jury trials or class actions. If - you do not want to be bound by these terms of use, you should not access the site. - By using the site in any capacity, you agree that you have read, understood, and - agree to be subject to these terms of use. - -

    -
    -
    - -
    -

    1. Overview

    -

    - This Balancer Terms of Use document (“Terms” or “agreement”) (“Balancer ”, “we” and - “us” refers to the Balancer Foundation and its subsidiary Balancer OpCo Limited) - covers the website, Balancer Protocol user-interface and free application - (collectively “the Site”) we own and administer, at times in conjunction with others, - which provides the ability to access the decentralized Balancer Protocol. - Additionally, you can access the Balancer Protocol through third-party web or mobile - interfaces. These Terms apply to you (“You” or “you”) as a user of our Site including - all the products, services, tools and information, without limitation, made available - on the Site. -

    -

    - To avoid any confusion, you agree a) you retain full control, at all times, over your - cryptocurrency assets, b) there are no intermediaries involved when you interact with - the Balancer Protocol and c) the online interface (UI) is a mere graphical interface - for you to interact with the Balancer protocol, which can be accessed through other - means, including other interfaces. -

    -

    - You must be able to form a legally binding contract online either as an individual or - on behalf of a legal entity. You represent that, if you are agreeing to these Terms on - behalf of a legal entity, you have the legal authority to bind that entity to these - Terms and you are not indirectly or directly included on any sanctions list and at - least 18 years old or the age of majority where you reside, (whichever is older) can - form a legally binding contract online, and have the full, right, power and authority - to enter into and to comply with the obligations under these Terms. -

    -

    - You are advised to periodically review these Terms so you understand any changes to - the Terms. Balancer in its sole discretion, reserves the right to make changes to our - Terms. Changes are binding on users of the Site and will take effect immediately upon - posting. As a user, you agree to be bound by any changes, variations, or modifications - to our Terms and your continued use of the Site shall constitute acceptance of any - such changes, revisions, variations, or modifications. When we make changes, we will - make the updated Terms available on the interface and update the “Last Updated” date - at the beginning of the Terms accordingly. -

    -

    - You accept such changes, by continuing to use the Site and by doing so you agree that - we have provided you with sufficient notice of such change. Our{' '} - Privacy policy and{' '} - Cookies policy also apply to your access and use of - the Site. You are entering into a binding Agreement. Any failure by us to exercise any - rights or provisions of the Agreement shall not constitute a waiver of such right or - provision. -

    -
    -
    - -
    -

    2. Site

    -

    - As part of the Site, Balancer provides access to a decentralized finance application - (“Application” or “Balancer Protocol app”) on the Ethereum blockchain, that allows - swappers or liquidity providers of Ethereum assets (“Cryptocurrency Assets”) to - transact using smart contracts (“Smart Contracts”). Use of the Balancer Protocol may - require that you pay a fee, such as gas charges on the Ethereum network to perform a - transaction. You acknowledge and agree that Balancer has no control over any - activities, transactions, the method of payment of any transactions, or any actual - processing of payments of transactions. You must ensure that you have a sufficient - balance to complete any transaction on the Balancer Protocol before initiating such - transaction. You should not take or refrain from taking any action based on any - information contained on the Site or any other available information at any time. - Before you make any legal, technical, or financial decisions involving the Services, - you should seek independent professional advice from a licensed and qualified - individual in the area for which such advice would be appropriate. -

    -

    - - You acknowledge and agree that Balancer has no control over any transactions - conducted through the Balancer Protocol, the method of payment of any transactions - or any actual payments of transactions including use of any third-party services - such as Metamask, or other wallet services. - - Likewise, you must ensure that you have a sufficient balance of the applicable - cryptocurrency tokens stored at your Balancer Protocol-compatible wallet address - (“Cryptocurrency Wallet”) to complete any transaction on the Balancer Protocol or the - Ethereum network before initiating such transaction. -

    -

    - You acknowledge and accept the material potential risks associated with using the - smart contracts that can be accessed via the Balancer user interface including, - without limitation, the smart contracts for Balancer Pools. Before using these - features or Pools, please confirm you understand the functionality and risks. For more - information about the risks, please carefully read risks. -

    -
    -
    - -
    -

    3. Access / Disclaimer of Warranties

    -

    - ACCESS TO THIS SITE AND THE PRODUCTS HEREIN ARE PROVIDED ON AN `'`AS IS`'` - AND `'`AS AVAILABLE`'` BASIS WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS - OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. NO WARRANTY IS PROVIDED THAT - THE SITE OR ANY PRODUCT WILL BE FREE FROM DEFECTS OR VIRUSES OR THAT OPERATION OF THE - PRODUCT WILL BE UNINTERRUPTED. YOUR USE OF THE SITE AND ANY PRODUCT AND ANY MATERIAL - OR SERVICES OBTAINED OR ACCESSED VIA THE SITE IS AT YOUR OWN DISCRETION AND RISK, AND - YOU ARE SOLELY RESPONSIBLE FOR ANY DAMAGE RESULTING FROM THEIR USE. SOME JURISDICTIONS - DO NOT ALLOW THE EXCLUSION OF CERTAIN WARRANTIES, SO SOME OF THE ABOVE LIMITATIONS MAY - NOT APPLY TO YOU. TRANSACTIONS THAT ARE RECORDED VIA THE SITE MUST BE TREATED AS - PERMANENT AND CANNOT BE UNDONE BY US OR BY ANYONE. -

    -

    - We do not guarantee or promise that the Site, or any content on it, will always be - available, functional, usable or uninterrupted. From time to time, access may be - interrupted, suspended or restricted, including because of a fault, error or - unforeseen circumstances or because we are carrying out planned maintenance or - changes. You acknowledge and agree that you will access and use the site at your own - risk. By using the Site, you will be solely responsible for conducting your own due - diligence into the risks of a transaction. -

    -

    - We reserve the right to limit the availability of the site to any person, geographic - area or jurisdiction in our sole discretion and/or to terminate your access to and use - of the site, at any time and in our sole discretion. We may suspend or disable your - access to the Site for any reason and in our sole discretion, including for any - intentional or unintentional breaches of these Terms. We may remove or amend the - content of the Site at any time. Some of the content may be out of date at any given - time and we are under no obligation to update or revise it. We do not promise or - guarantee that the Site, or any content on it, will be free from errors or omissions. -

    -

    - We will not be liable to you for any issue, loss or damage you may or have suffered as - a result of the Site being unavailable at any time for any reason. You will comply - with all applicable domestic and international laws, statutes, ordinances, rules and - regulations applicable to your use of the site (“Applicable Laws”). Likewise, we are - not liable for any third-party services and are not responsible for the content or - services of these party’s. -

    -

    - As a condition to accessing or using the Site, you agree and represent that you will: -

    -
      -
    • - Only use the Services and the Site for lawful purposes and in adherence with these - Terms; -
    • -
    • - Ensure that all information that you provide on the Site is current, complete, and - accurate; and -
    • -
    • - Maintain the security, privacy and confidentiality of access to your cryptocurrency - wallet address. -
    • -
    -

    As a condition to accessing or using the Site or the Services, you will not:

    -
      -
    • - Violate any Applicable Law, including, without limitation, any relevant and - applicable anti-money laundering and anti-terrorist financing and sanctions laws and - any relevant and applicable privacy, secrecy and data protection laws. -
    • -
    • - Use the Site for any purpose or conduct that is directly or indirectly unlawful; -
    • -
    • - Export, reexport, or transfer, directly or indirectly, any Balancer technology in - violation of applicable export laws or regulations; -
    • -
    • - Infringe on or misappropriate any contract, intellectual property or other - third-party right, or commit a tort while using the Site; -
    • -
    • - Misrepresent, with omission or otherwise, the truthfulness, sourcing or reliability - of any content on the Site; -
    • -
    • - Use the Site in any manner that could interfere with, disrupt, negatively affect, - redirect or inhibit other users from fully enjoying the Site or the Balancer - Protocol, or that could damage, disable, overburden, or impair the functioning of - the Site or the Balancer Protocol in any manner; -
    • -
    • - Attempt to circumvent or disable any content filtering techniques or security - measures that Balancer employs on the Site, or attempt to access any service or area - of the Site that you are not authorized to access; -
    • -
    • - Use any robot, spider, crawler, scraper, or other automated means or interface not - provided by us, to access the Site to extract data; -
    • -
    • - Introduce or use any malware, virus, Trojan horse, worm, logic bomb, drop-dead - device, backdoor, shutdown mechanism or other harmful material into the Site; -
    • -
    • - Post content or communications on the Site that are, in our sole discretion, - libelous, defamatory, profane, obscene, pornographic, sexually explicit, indecent, - lewd, vulgar, suggestive, harassing, hateful, threatening, offensive, - discriminatory, bigoted, abusive, inflammatory, fraudulent, deceptive or otherwise - objectionable; -
    • -
    • - To the extent applicable, post content on the Site containing unsolicited - promotions, commercial messages or any chain messages or user content designed to - deceive, induce or trick the user of the Site; or -
    • -
    • - Encourage or induce any third party to engage in any of the activities prohibited - under these Terms. -
    • -
    -
    -
    - -
    -

    - 3(a). You acknowledge that the Site and your use of the Site present certain risks, - including without limitation the following risks: -

    -
      -
    • - Losses while digital assets are being supplied to the Balancer Protocol and losses - due to the fluctuation of prices of tokens in a swapping pair or liquidity pool. - Prices of digital currencies, tokens and/or other digital assets fluctuate day by - day or even minute by minute. The value of your available balance could surge or - drop suddenly. Please note that there is a possibility that the price of tokens - could decrease to zero. Prices of tokens are prone to significant fluctuations, for - example, due to announced proposed legislative acts, governmental restrictions, news - related to cyber crimes or other factors causing potentially excessive market - enthusiasm, disproportionate loss in confidence, or manipulation by others in the - market. -
    • -
    • - Risks associated with accessing the Balancer Protocol through third party web or - mobile interfaces. You are responsible for doing your own diligence on those - interfaces to understand and accept the risks that use entails. You are also - responsible for doing your own diligence on those interfaces to understand and - accept any fees that those interfaces may charge. -
    • -
    • Risks associated with any Smart Contracts with which you interact.
    • -
    • - Although Balancer does not have access to your assets, you are reminded and - acknowledge that at any time, your access to your Cryptocurrency Assets through - third party wallet services, unrelated to Balancer or the Balancer.Fi website, may - be suspended or terminated or there may be a delay in your access or use of your - Cryptocurrency Assets, which may result in the Cryptocurrency Assets diminishing in - value or you being unable to complete a Smart Contract. -
    • -
    • - - You are reminded of the inherent risks with digital assets and decentralized - finance including the fact that tokens are not legal tender and are not backed by - any government. - - Unlike fiat currencies, which are regulated and backed by local governments and - central banks, tokens are based only on technology and user consensus, which means - that in cases of manipulations or market panic, central governments will not take - any corrective actions or measures to achieve stability, maintain liquidity or - protect their value. There is a possibility that certain transactions cannot be - settled or may be difficult to settle, or can be completed only at significantly - adverse prices depending on the market situation and/or market volume. Transactions - may be irreversible, and, accordingly, potential losses due to fraudulent or - accidental transactions are not recoverable. Some blockchain transactions are deemed - to be completed when recorded on a public ledger, which is not necessarily the date - or time when you or another party initiated the transaction. -
    • -
    • - The regulatory frameworks applicable to blockchain transactions in connection with - tokens are still developing and evolving. It is possible that your transactions or - funds are, or may be in the future, subject to various reporting, tax or other - liabilities and obligations. Legislative and regulatory changes or actions at the - country or international level may materially and adversely affect the use, - transfer, exchange, and value of your tokens. -
    • -
    • - The site and/or application may be wholly or partially suspended or terminated for - any or no reason, which may limit your access to your Cryptocurrency Assets. -
    • -
    • - You are solely responsible for understanding and complying with any and all - Applicable Laws in connection with your acceptance of these Terms and your use of - any part of the Site, including but not limited to those related to taxes as well as - reporting and disclosure obligations. -
    • -
    • - This list of risk factors is non-exhaustive, and other risks, arising either now or - in the future, could additionally be relevant and applicable to you in making an - informed judgment to accept, or continue to accept, these Terms and/or use, or - continue to use the Site. -
    • -
    - -

    Violating our rules may result in our intervention.

    -

    - You agree and acknowledge that if you use the Site and its Services to engage in - conduct prohibited by applicable law, we reserve the right to completely or partially - restrict or revoke your access to the Services at our sole discretion. We reserve the - right to investigate violations and prosecute any suspected breaches of this - Agreement, including the Terms. Any information may be disclosed to satisfy any new - regulation, law, government request, or legal process. -

    - -

    Accordingly, you expressly agree that:

    -
      -
    1. - you assume all risk in connection with the specific risks identified above in 3(a); -
    2. -
    3. - you assume all risk in connection with your access to and use of the Site, the - Application and the Smart Contracts; -
    4. -
    5. - that you expressly waive and release Balancer from any and all liability, claims, - causes of action, responsibility or damages arising from or in any way related to - your use of the Site, the Application or the Smart Contracts. -
    6. -
    7. - upgrades and modifications to the protocol are managed in a community-driven way by - holders of the Balancer Protocol governance token. No developer or entity involved - in creating the Balancer Protocol will be liable for any claims or damages - whatsoever associated with your use, inability to use, or your interaction with - other users of, the Balancer Protocol, including any direct, indirect, incidental, - special, exemplary, punitive or consequential damages, or loss of profits, - cryptocurrencies, tokens, or anything else of value. -
    8. -
    -
    -
    - -
    -

    4. Third-Party Content

    -

    - The Site may contain hyperlinks or references to third party websites or content. Any - such hyperlinks or references are provided for your information and convenience only. - We have no control over third party websites and accept no legal responsibility for - any content, material or information contained in them. The display of any hyperlink - and reference to any third-party website does not mean that we endorse that third - party`'`s website, products or services or opine on the accuracy or reliability - of such information. Your use of a third-party site may be governed by the terms and - conditions of that third-party site. -

    -
    -
    - -
    -

    5. Our Privacy Policy and Cookies Policy

    -

    - Certain areas of our website may record and collect information about you. You can - find more information about how we will process your personal information in our{' '} - Privacy policy. -

    -

    - When you use the Site, we may collect information about your computer and your - interaction with the Site. See our Cookies policy{' '} - for more information. -

    -
    -
    - -
    -

    6. Intellectual Property Rights

    -

    - Balancer is the owner of all intellectual property rights in the Site and the material - published on them. To the extent practical, these works are protected by copyright - laws and all such rights are reserved. www.Balancer.fi is the uniform resource locator - (`'`URL`'`) of Balancer. You will not make use of this URL (or any other URL - owned by us) on another website or digital platform without our prior written consent. - Any unauthorized use or reproduction may be prosecuted. You will retain ownership of - all copyright in data you upload or submit by, through or to the Site. You grant us a - worldwide, royalty-free, irrevocable license to use, copy, distribute or publish and - send this data in any manner. -

    -
    -
    - -
    -

    7. Limitation of Liability

    -

    - - Under no circumstances shall we or any of our officers, directors, employees, - contractors, agents, affiliates, or subsidiaries be liable to you for any indirect, - punitive, incidental, special, consequential, or exemplary damages, including (but - not limited to) damages for loss of profits, goodwill, use, data, or other - intangible property, arising out of or relating to any access or use of the Site - including the user-interface, nor will we be responsible for any damage, loss, or - injury resulting from hacking, tampering, or other unauthorized access or use of the - Site including the user-interface or the information contained within it. - -

    -

    - - We assume no liability or responsibility for any: (a) errors, mistakes, or - inaccuracies of content; (b) personal injury or property damage, of any nature - whatsoever, resulting from any access or use of the Site including the - user-interface; (c) unauthorized access or use of any secure server or database in - our control, or the use of any information or data stored therein; (d) interruption - or cessation of function related to the Site; (e) bugs, viruses, trojan horses, or - the like that may be transmitted to or through the Site; (f) errors or omissions in, - or loss or damage incurred as a result of the use of, any content made available - through the Site; and (g) the defamatory, offensive, or illegal conduct of any third - party. - -

    -

    - - Under no circumstances shall we or any of our officers, directors, employees, - contractors, agents, affiliates, or subsidiaries be liable to you for any claims, - proceedings, liabilities, obligations, damages, losses, or costs in an amount - exceeding $100.00. This limitation of liability applies regardless of whether the - alleged liability is based on contract, tort, negligence, strict liability, or any - other basis, and even if we have been advised of the possibility of such liability. - Some jurisdictions do not allow the exclusion of certain warranties or the - limitation or exclusion of certain liabilities, but your acceptance of these Terms - constitutes an agreement to limit the liability of Balancer and our officers, - directors, employees, contractors, agents, affiliates, or subsidiaries to the - maximum extent possible under any applicable laws. - -

    -
    -
    - -
    -

    8. Disclaimers

    -

    We do not guarantee that the Site will be secure or free from bugs or viruses.

    -

    - You are responsible for configuring your information technology, computer programs - and/or platform in order to access the Site. You should use and deploy your own virus - protection and security software. We cannot promise that the use of the Site, or any - content taken from the Site, will not infringe the rights of any third party. -

    -

    - The content and materials available on the Site are for informational purposes only - and are not intended to address your particular requirements or needs. In particular, - the content and materials available on the Site do not constitute any form of advice, - referral or recommendation by us, should not be regarded as an offer, solicitation, - invitation or recommendation to buy or sell tokens or any other financial services and - is not intended to be relied upon by you in making any specific decision to buy or - sell a token. - - We recommend that you seek independent advice from financial, legal and tax advisors - before making any such decision particularly in light of the risks associated with - digital assets. - -

    -

    - Nothing included in the site constitutes an offer or solicitation to sell, or - distribution of, investments and related services to anyone in any jurisdiction. -

    -

    - From time to time, reference may be made to data we have gathered. These references - may be selective or, may be partial. As markets change continuously, previously - published information and data may not be current and should not be relied upon. -

    -
    -
    - -
    -

    9. Indemnification

    -

    - You agree to indemnify and hold Balancer and our officers, directors, employees, - contractors, agents, affiliates, or subsidiaries harmless from any claim or demand, - including attorneys’ fees and costs, made by any third-party due to or arising out of - 1) your use of the site or 2) this agreement. -

    -
    -
    - -
    -

    10. General

    -

    - We may perform any of our obligations, and exercise any of the rights granted to us - under these Terms, through an affiliated or unaffiliated third-party. We may assign - any or all our rights and obligations under these Terms to any third-party. -

    -

    - If any clause or part of any clause of these Terms is found to be void, unenforceable - or invalid, then it will be severed from these Terms, leaving the remainder in full - force and effect, provided that the severance has not altered the basic nature of - these Terms. -

    -

    - No single or partial exercise, or failure or delay in exercising any right, power or - remedy by us shall constitute a waiver by us of, or impair or preclude any further - exercise of, that or any right, power or remedy arising under these terms and - conditions or otherwise. If any of the provisions in these Terms are found to be - illegal, invalid or unenforceable by any court of competent jurisdiction, the - remainder shall continue in full force and effect. -

    -

    - All disclaimers, indemnities and exclusions in these Terms shall survive termination - of the Terms and shall continue to apply during any suspension or any period during - which the Site is not available for you to use for any reason whatsoever. -

    -

    - These Terms and the documents referred to in them set out the entire agreement between - you and us with respect to your use of the site, Balancer and the services provided - via the site and supersede any and all prior or contemporaneous representations, - communications or agreements (written or oral) made between you or us. -

    -

    - - Any dispute, controversy, or claim arising out of or in relation to these Terms, - including the validity, invalidity, breach or termination thereof, shall be settled - by arbitration in accordance with the Cayman Islands Arbitration Law, 2012. There - shall be one arbitrator; the appointing authority may be based on mutual agreement, - be chosen by the parties or in the absence of such agreement, the court may - designate an appointing authority. The seat of the arbitration shall be the Cayman - Islands and the language of the arbitration shall be English. The applicable law - shall be Cayman Islands law or another choice of law determined in Balancer’s sole - discretion. - -

    -

    - - With respect to all persons and entities, regardless of whether they have obtained - or used the site for personal, commercial or other purposes, all disputes, - controversies or claims must be brought in the parties’ individual capacity, and not - as a plaintiff or class member in any purported class action, collective action or - other representative proceeding. This waiver applies to class arbitration, and, - unless we agree otherwise, the arbitrator may not consolidate more than one person’s - claims. You agree that, by entering into this agreement, you and Balancer are each - waiving the right to a trial by jury or to participate in a class action, collective - action, or other representative proceeding of any kind. - -

    -

    - - There is a Cayman Island International Arbitration Centre expected in the near term, - but in the meantime there is the modern Arbitration Act, 2012. - -

    -
    -
    - -
    -

    11. Force Majeure

    -

    - There is a risk that transactions effected through the Site may be affected by system - failures resulting from adverse events, natural disasters, pandemics and other - emergencies, as well as unforeseen significant changes in the external environment. - With regards to opportunity loss (e.g., loss of opportunity to place a payment - instruction, resulting in loss of profits which could have been obtained) due to - occurrences such as emergency situations and force majeure events, Balancer is under - no obligation to take any corrective action or measure and shall no under - circumstances be liable for any lost profits or other swapping losses. -

    -
    -
    - -
    -

    12. Contact Us

    -

    - Balancer is a foundation company organized in the Cayman Islands with an operating - company organized in the British Virgin Islands (BVI). Please contact us if you have - any questions about these Terms or other topics, by sending an email to{' '} - - termsofuse@balancer.finance - - . -

    -
    -
    -
    -
    - ) -} diff --git a/apps/beets-frontend-v3/app/api/rpc/[chain]/route.ts b/apps/beets-frontend-v3/app/api/rpc/[chain]/route.ts index 0800ec63f..79d522429 100644 --- a/apps/beets-frontend-v3/app/api/rpc/[chain]/route.ts +++ b/apps/beets-frontend-v3/app/api/rpc/[chain]/route.ts @@ -18,12 +18,12 @@ const chainToRpcMap: Record = { [GqlChain.Polygon]: dRpcUrl('polygon'), [GqlChain.Avalanche]: dRpcUrl('avalanche'), [GqlChain.Fantom]: dRpcUrl('fantom'), - [GqlChain.Sonic]: dRpcUrl('fantom'), //TODO: groninge will fix it in another PR [GqlChain.Sepolia]: dRpcUrl('sepolia'), [GqlChain.Fraxtal]: dRpcUrl('fraxtal'), [GqlChain.Gnosis]: dRpcUrl('gnosis'), [GqlChain.Mode]: dRpcUrl('mode'), [GqlChain.Zkevm]: dRpcUrl('polygon-zkevm'), + [GqlChain.Sonic]: dRpcUrl('sonic'), } function getRpcUrl(chain: string) { diff --git a/apps/beets-frontend-v3/app/layout.tsx b/apps/beets-frontend-v3/app/layout.tsx index c282b621e..8c850d10c 100644 --- a/apps/beets-frontend-v3/app/layout.tsx +++ b/apps/beets-frontend-v3/app/layout.tsx @@ -12,25 +12,14 @@ import { FooterContainer } from '@/lib/components/footer/FooterContainer' import { DEFAULT_THEME_COLOR_MODE } from '@repo/lib/shared/services/chakra/themes/base/foundations' import { ThemeProvider as ColorThemeProvider } from 'next-themes' import { ThemeProvider } from '@/lib/services/chakra/ThemeProvider' +import { LzBeetsMigrateModal } from '@/lib/components/modals/LzBeetsMigrateModal' +import { PoolsNetworkWatcher } from '@/lib/components/navs/PoolsNetworkWatcher' export const metadata: Metadata = { - title: 'Beets DeFi Liquidity Pools', - description: `Explore DeFi liquidity pools and swap tokens. Provide liquidity to accumulate yield from swap fees while retaining your token exposure as prices move.`, - icons: [ - { rel: 'icon', type: 'image/x-icon', url: '/favicon.ico' }, - { - rel: 'icon', - type: 'image/png', - url: '/favicon-light.png', - media: '(prefers-color-scheme: light)', - }, - { - rel: 'icon', - type: 'image/png', - url: '/favicon-dark.png', - media: '(prefers-color-scheme: dark)', - }, - ], + title: 'Beets', + description: `The Flagship LST Hub on Sonic. From seamless staking to earning real yield on LST-focused liquidity pools, beets is the ultimate destination for your liquid-staked tokens.`, + icons: [{ rel: 'icon', type: 'image/x-icon', url: '/favicon.ico' }], + metadataBase: new URL('https://zen.beets.fi'), } export default function RootLayout({ children }: PropsWithChildren) { @@ -41,18 +30,27 @@ export default function RootLayout({ children }: PropsWithChildren) { style={{ marginRight: '0px !important' }} // Required to prevent layout shift introduced by Rainbowkit suppressHydrationWarning > - - - - - - - {children} - - - - - +
    + + + + + + + {children} + + + + + + + +
    ) diff --git a/apps/beets-frontend-v3/app/opengraph-image.jpg b/apps/beets-frontend-v3/app/opengraph-image.jpg deleted file mode 100644 index 53cda0462..000000000 Binary files a/apps/beets-frontend-v3/app/opengraph-image.jpg and /dev/null differ diff --git a/apps/beets-frontend-v3/app/opengraph-image.png b/apps/beets-frontend-v3/app/opengraph-image.png new file mode 100644 index 000000000..efcb62dbe Binary files /dev/null and b/apps/beets-frontend-v3/app/opengraph-image.png differ diff --git a/apps/beets-frontend-v3/lib/components/footer/FooterContainer.tsx b/apps/beets-frontend-v3/lib/components/footer/FooterContainer.tsx index 3603c708f..a22e6c437 100644 --- a/apps/beets-frontend-v3/lib/components/footer/FooterContainer.tsx +++ b/apps/beets-frontend-v3/lib/components/footer/FooterContainer.tsx @@ -13,8 +13,8 @@ export function FooterContainer() { linkSections={linkSections} logoType={} socialLinks={getSocialLinks()} - subTitle="Beets is a battle-tested toolkit for true AMM experimentation and innovation." - title="AMMs made easy" + subTitle="Beets is your ultimate destination for liquid-staked tokens, real yield, and AMM innovation." + title="The Hub for LSTs" /> ) } diff --git a/apps/beets-frontend-v3/lib/components/footer/useFooterData.tsx b/apps/beets-frontend-v3/lib/components/footer/useFooterData.tsx index 1210ddb53..ff568c08c 100644 --- a/apps/beets-frontend-v3/lib/components/footer/useFooterData.tsx +++ b/apps/beets-frontend-v3/lib/components/footer/useFooterData.tsx @@ -21,7 +21,7 @@ export function useFooterData() { { label: 'Explore pools', href: '/pools' }, { label: 'Swap tokens', href: '/swap' }, { label: 'View portfolio', href: '/portfolio' }, - { label: 'Get maBEETS', href: 'https://beets.fi/mabeets', isExternal: true }, + { label: 'Get maBEETS', href: 'https://ma.beets.fi', isExternal: true }, ], }, { @@ -34,16 +34,11 @@ export function useFooterData() { isExternal: true, }, { label: 'Analytics', href: 'https://beets.defilytica.com', isExternal: true }, - { - label: 'Brand assets', - href: 'https://brand.beets.fi/', - isExternal: true, - }, ], }, ] - const legalLinks = [{ label: 'Terms of use', href: '/terms-of-use' }] + const legalLinks = [{ label: 'Terms of service', href: '/terms-of-service' }] return { linkSections, legalLinks } } diff --git a/apps/beets-frontend-v3/lib/components/imgs/BeetsLogo.tsx b/apps/beets-frontend-v3/lib/components/imgs/BeetsLogo.tsx index 6b8fa5892..6d834497a 100644 --- a/apps/beets-frontend-v3/lib/components/imgs/BeetsLogo.tsx +++ b/apps/beets-frontend-v3/lib/components/imgs/BeetsLogo.tsx @@ -3,20 +3,34 @@ import { SVGProps } from 'react' export function BeetsLogo(props: SVGProps) { return ( - - + + + + + + + + + + + ) } diff --git a/apps/beets-frontend-v3/lib/components/imgs/BeetsLogoType.tsx b/apps/beets-frontend-v3/lib/components/imgs/BeetsLogoType.tsx index 74a6742d8..f38298961 100644 --- a/apps/beets-frontend-v3/lib/components/imgs/BeetsLogoType.tsx +++ b/apps/beets-frontend-v3/lib/components/imgs/BeetsLogoType.tsx @@ -7,61 +7,53 @@ export function BeetsLogoType(props: SVGProps) { aria-labelledby="logoTitle logoDesc" data-name="Layer 1" id="Layer_1" - viewBox="0 0 670 120" + viewBox="0 0 940 330" xmlns="http://www.w3.org/2000/svg" {...props} > - - - - - - - - - - - + + + + + + + + + + ) diff --git a/apps/beets-frontend-v3/lib/components/imgs/FantomToSonicSvg.tsx b/apps/beets-frontend-v3/lib/components/imgs/FantomToSonicSvg.tsx new file mode 100644 index 000000000..0b0feaf7b --- /dev/null +++ b/apps/beets-frontend-v3/lib/components/imgs/FantomToSonicSvg.tsx @@ -0,0 +1,40 @@ +/* eslint-disable max-len */ +import { SVGProps } from 'react' + +export function FantomToSonicSvg(props: SVGProps) { + return ( + + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/components/imgs/SonicLogo.tsx b/apps/beets-frontend-v3/lib/components/imgs/SonicLogo.tsx new file mode 100644 index 000000000..f0b120e87 --- /dev/null +++ b/apps/beets-frontend-v3/lib/components/imgs/SonicLogo.tsx @@ -0,0 +1,34 @@ +/* eslint-disable max-len */ +import { SVGProps } from 'react' + +export function SonicLogo(props: SVGProps) { + return ( + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/components/modals/LzBeetsMigrateModal.tsx b/apps/beets-frontend-v3/lib/components/modals/LzBeetsMigrateModal.tsx new file mode 100644 index 000000000..fc0b9c364 --- /dev/null +++ b/apps/beets-frontend-v3/lib/components/modals/LzBeetsMigrateModal.tsx @@ -0,0 +1,292 @@ +'use client' + +import { + Box, + Button, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Text, + useDisclosure, +} from '@chakra-ui/react' +import { + TokenBalancesProvider, + useTokenBalances, +} from '@repo/lib/modules/tokens/TokenBalancesProvider' +import TokenRow from '@repo/lib/modules/tokens/TokenRow/TokenRow' +import { useTokens } from '@repo/lib/modules/tokens/TokensProvider' +import { ConnectWallet } from '@repo/lib/modules/web3/ConnectWallet' +import { NetworkSwitchButton, useChainSwitch } from '@repo/lib/modules/web3/useChainSwitch' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { useTokenAllowances } from '@repo/lib/modules/web3/useTokenAllowances' +import { ErrorAlert } from '@repo/lib/shared/components/errors/ErrorAlert' +import { getBlockExplorerTxUrl } from '@repo/lib/shared/utils/blockExplorer' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' +import { bn } from '@repo/lib/shared/utils/numbers' +import { QueryObserverResult } from '@tanstack/react-query' +import Link from 'next/link' +import { useEffect, useState } from 'react' +import { Address, formatUnits } from 'viem' +import { type BaseError, useBalance, useWaitForTransactionReceipt, useWriteContract } from 'wagmi' + +const sonicChainId = 146 +const lzBeetsAddress = '0x1E5fe95fB90ac0530F581C617272cd0864626795' +const migratorAddress = '0x5f9a5CD0B77155AC1814EF6Cd9D82dA53d05E386' + +function MigrationButton({ + balance, + isBalancesRefetching, + refetchBalances, +}: { + balance: bigint + isBalancesRefetching: boolean + refetchBalances: () => Promise[]> +}) { + const { data: hash, writeContract, isPending, error } = useWriteContract() + const { isLoading: isConfirming, isSuccess: isConfirmed } = useWaitForTransactionReceipt({ + hash, + }) + + const hasLzBeetsBalance = bn(balance).gt(0) + + function migrate() { + writeContract({ + address: migratorAddress, + abi: [ + { + name: 'exchangeOperaToSonic', + type: 'function', + inputs: [{ type: 'uint256' }], + outputs: [], + }, + ], + functionName: 'exchangeOperaToSonic', + chainId: sonicChainId, + args: [balance], + }) + } + + useEffect(() => { + if (isConfirmed) { + refetchBalances() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isConfirmed]) + + return ( + <> + {error && ( + + + Error: {(error as BaseError).shortMessage || error.message} + + + )} + {isConfirmed && !!hash && ( + + )} + + + ) +} + +function ApproveButton({ + balance, + refetchAllowances, + isAllowancesLoading, +}: { + balance: bigint + refetchAllowances: () => void + isAllowancesLoading: boolean +}) { + const { data: hash, writeContract, isPending, error } = useWriteContract() + const { isLoading: isConfirming, isSuccess: isConfirmed } = useWaitForTransactionReceipt({ + hash, + }) + + const hasLzBeetsBalance = bn(balance).gt(0) + + function approve() { + writeContract({ + address: lzBeetsAddress, + abi: [ + { + name: 'approve', + type: 'function', + inputs: [{ type: 'address' }, { type: 'uint256' }], + outputs: [], + }, + ], + functionName: 'approve', + chainId: sonicChainId, + args: [migratorAddress, balance], + }) + } + + useEffect(() => { + if (isConfirmed) { + refetchAllowances() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isConfirmed]) + + return ( + <> + {error && ( + + + Error: {(error as BaseError).shortMessage || error.message} + + + )} + + + ) +} + +export function LzBeetsMigrateModal() { + const { getTokensByChain } = useTokens() + + return ( + + + + ) +} + +export function LzBeetsMigrateModalContent() { + const { shouldChangeNetwork } = useChainSwitch(sonicChainId) + const [shouldShow, setShouldShow] = useState(true) + const { isOpen, onOpen, onClose } = useDisclosure() + const { isConnected, userAddress } = useUserAccount() + const { refetchBalances, isBalancesRefetching } = useTokenBalances() + const { data: balanceData } = useBalance({ + chainId: sonicChainId, + address: userAddress, + token: lzBeetsAddress, + }) + + const { allowances, refetchAllowances, isAllowancesRefetching, isAllowancesLoading } = + useTokenAllowances({ + chainId: sonicChainId, + userAddress: userAddress as Address, + spenderAddress: migratorAddress, + tokenAddresses: [lzBeetsAddress], + }) + + const balance = formatUnits(balanceData?.value || 0n, balanceData?.decimals || 18) + const hasBalance = bn(balanceData?.value || 0n).gt(0) + const hasAllowance = bn(allowances[lzBeetsAddress] || 0n).gte(bn(balanceData?.value || 0n)) + + useEffect(() => { + if (hasBalance && !isOpen && shouldShow) { + onOpen() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [hasBalance, isOpen, shouldShow]) + + function handleClose() { + onClose() + setShouldShow(false) + } + + return ( + + + + Claim your Sonic BEETS + + + + + + + You have {balance} lzBEETS in your wallet. lzBEETS serve as a receipt token when + bridging to Sonic. Claim your BEETS on Sonic now. + + + + + {isConnected ? ( + shouldChangeNetwork ? ( + + ) : hasAllowance ? ( + + ) : ( + + ) + ) : ( + + )} + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/components/navs/MaBeetsNavLink.tsx b/apps/beets-frontend-v3/lib/components/navs/MaBeetsNavLink.tsx new file mode 100644 index 000000000..33c647bf8 --- /dev/null +++ b/apps/beets-frontend-v3/lib/components/navs/MaBeetsNavLink.tsx @@ -0,0 +1,100 @@ +import { + Modal, + Text, + ModalOverlay, + ModalContent, + ModalHeader, + ModalCloseButton, + ModalBody, + ModalFooter, + Button, + HStack, + Link, + useDisclosure, + LinkProps, +} from '@chakra-ui/react' +import { ArrowUpRight } from 'react-feather' +import NextLink from 'next/link' +import { ReactNode } from 'react' + +interface MaBeetsRedirectModalProps extends LinkProps { + triggerEl?: ReactNode +} + +export function MaBeetsNavLink({ triggerEl, ...props }: MaBeetsRedirectModalProps) { + const { isOpen, onOpen, onClose } = useDisclosure() + + return ( + <> + + {triggerEl || 'maBEETS'} + + + + + ) +} + +export function MaBeetsRedirectModal({ + isOpen, + onClose, +}: { + isOpen: boolean + onClose: () => void +}) { + return ( + + + + maBEETS + + + + BEETS are live on Sonic! Visit the Fantom App to migrate your BEETS and maBEETS relics + to sonic. + {/* + https://ma.beets.fi + + . */} + + + + For more information, refer to the migration guide at{' '} + + https://docs.beets.fi/sonic#mabeets-and-beets + + . + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/components/navs/NavBarContainer.tsx b/apps/beets-frontend-v3/lib/components/navs/NavBarContainer.tsx index b6012fa4c..f43e79a2a 100644 --- a/apps/beets-frontend-v3/lib/components/navs/NavBarContainer.tsx +++ b/apps/beets-frontend-v3/lib/components/navs/NavBarContainer.tsx @@ -1,28 +1,61 @@ 'use client' import { useNavData } from './useNavData' -import { NavBar } from '@repo/lib/shared/components/navs/NavBar' +import { NavBar, NavActions } from '@repo/lib/shared/components/navs/NavBar' import { NavLogo } from './NavLogo' import { MobileNav } from '@repo/lib/shared/components/navs/MobileNav' import { useNav } from '@repo/lib/shared/components/navs/useNav' import { BeetsLogoType } from '../imgs/BeetsLogoType' +import { Box, HStack } from '@chakra-ui/react' +import { motion } from 'framer-motion' +import { fadeIn } from '@repo/lib/shared/utils/animations' +import { MaBeetsNavLink } from './MaBeetsNavLink' +import { SonicMigrationLink } from './SonicMigrationLink' +import { FantomToSonicSvg } from '../imgs/FantomToSonicSvg' export function NavBarContainer() { const { appLinks, ecosystemLinks, getSocialLinks } = useNavData() const { defaultAppLinks } = useNav() const allAppLinks = [...defaultAppLinks, ...appLinks] + + const mobileNav = ( + + + + Migrate to Sonic + + + } + /> + + } + ecosystemLinks={ecosystemLinks} + socialLinks={getSocialLinks()} + /> + ) + return ( + customLinks={ + <> + + + + + + + } navLogo={} + rightSlot={} /> ) } diff --git a/apps/beets-frontend-v3/lib/components/navs/PoolsLink.tsx b/apps/beets-frontend-v3/lib/components/navs/PoolsLink.tsx new file mode 100644 index 000000000..eb37f71f7 --- /dev/null +++ b/apps/beets-frontend-v3/lib/components/navs/PoolsLink.tsx @@ -0,0 +1,77 @@ +import { + Box, + Button, + Link, + Popover, + PopoverArrow, + PopoverBody, + PopoverCloseButton, + PopoverContent, + PopoverHeader, + PopoverTrigger, +} from '@chakra-ui/react' +import { useNav } from '@repo/lib/shared/components/navs/useNav' +import NextLink from 'next/link' + +function PoolNetworkLink({ + text, + href, + isLast, + onClose, +}: { + text: string + href: string + isLast?: boolean + onClose: () => void +}) { + return ( + + + {text} + + + ) +} + +export function PoolsLink() { + const { linkColorFor } = useNav() + + return ( + + {({ onClose }) => ( + <> + + + + + + + Select a network + + + + + + + + )} + + ) +} diff --git a/apps/beets-frontend-v3/lib/components/navs/PoolsNetworkWatcher.tsx b/apps/beets-frontend-v3/lib/components/navs/PoolsNetworkWatcher.tsx new file mode 100644 index 000000000..54b93c484 --- /dev/null +++ b/apps/beets-frontend-v3/lib/components/navs/PoolsNetworkWatcher.tsx @@ -0,0 +1,31 @@ +'use client' + +import { usePoolListQueryState } from '@repo/lib/modules/pool/PoolList/usePoolListQueryState' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' +import { usePathname, useSearchParams } from 'next/navigation' +import { useEffect } from 'react' + +const POOLS_PATH = '/pools' + +export function PoolsNetworkWatcher() { + const { chain } = useUserAccount() + const { setNetworks, networks } = usePoolListQueryState() + const pathname = usePathname() + const searchParams = useSearchParams() + + useEffect(() => { + if (pathname === POOLS_PATH && chain) { + if (searchParams.size === 0 || (searchParams.size === 1 && networks.length > 0)) { + if (chain.id === 146) { + setNetworks([GqlChain.Sonic]) + } else if (chain.id === 10) { + setNetworks([GqlChain.Optimism]) + } + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [chain, pathname, searchParams.size]) + + return <>{null} +} diff --git a/apps/beets-frontend-v3/lib/components/navs/SonicMigrationLink.tsx b/apps/beets-frontend-v3/lib/components/navs/SonicMigrationLink.tsx new file mode 100644 index 000000000..229d764ef --- /dev/null +++ b/apps/beets-frontend-v3/lib/components/navs/SonicMigrationLink.tsx @@ -0,0 +1,105 @@ +import { + Box, + Button, + HStack, + Link, + LinkProps, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Text, + useDisclosure, +} from '@chakra-ui/react' +import NextLink from 'next/link' +import { ReactNode } from 'react' +import { ArrowUpRight } from 'react-feather' +import { FantomToSonicSvg } from '../imgs/FantomToSonicSvg' + +interface SonicMigrationRedirectModalProps extends LinkProps { + triggerEl?: ReactNode +} + +export function SonicMigrationLink({ triggerEl, ...props }: SonicMigrationRedirectModalProps) { + const { isOpen, onOpen, onClose } = useDisclosure() + + return ( + <> + + {triggerEl || ( + + + + + Migrate{' '} + + to Sonic + + + + + )} + + + + + ) +} + +function SonicMigrationModal({ isOpen, onClose }: { isOpen: boolean; onClose: () => void }) { + return ( + + + + Upgrade to Sonic + + + + Sonic mainnet is live, offering enhanced performance and new opportunities. If you still + have assets on Fantom Opera, it's time to make the switch. We've prepared a + migration guide to help you get started. + + + + You can find the legacy Fantom app at{' '} + + https://ftm.beets.fi + + . + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/components/navs/useNavData.tsx b/apps/beets-frontend-v3/lib/components/navs/useNavData.tsx index b78d3e57d..c1ac8804b 100644 --- a/apps/beets-frontend-v3/lib/components/navs/useNavData.tsx +++ b/apps/beets-frontend-v3/lib/components/navs/useNavData.tsx @@ -7,12 +7,8 @@ import { AppLink } from '@repo/lib/shared/components/navs/useNav' export function useNavData() { const appLinks: AppLink[] = [ { - href: '/mabeets', - label: 'maBEETS', - }, - { - href: '/sftmx', - label: 'sFTMX', + href: '/stake', + label: 'Stake $S', }, ] @@ -25,7 +21,7 @@ export function useNavData() { const getSocialLinks = (size = 24) => [ { icon: , - href: 'https://x.com/beethoven_x', + href: 'https://x.com/beets_fi', }, { icon: , diff --git a/apps/beets-frontend-v3/lib/components/promos/BeetsPromoBanner.tsx b/apps/beets-frontend-v3/lib/components/promos/BeetsPromoBanner.tsx new file mode 100644 index 000000000..291c58718 --- /dev/null +++ b/apps/beets-frontend-v3/lib/components/promos/BeetsPromoBanner.tsx @@ -0,0 +1,58 @@ +'use client' + +import { Heading, Flex, Box, Center } from '@chakra-ui/react' + +export function BeetsPromoBanner() { + return ( + +
    + + + BEETS 2.0: + + + The Sonic Revolution + + + Simpler. Sleeker. Smarter. + + +
    +
    + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/LandingPageLayout.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/LandingPageLayout.tsx new file mode 100644 index 000000000..20433cee1 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/LandingPageLayout.tsx @@ -0,0 +1,44 @@ +import { Box } from '@chakra-ui/react' +import { BeetsLandingHeroImg } from './components/BeetsLandingHeroImg' +import { LandingBalancerV3Section } from './sections/LandingBalancerV3Section' +import { LandingBeetsData } from './sections/LandingBeetsData' +import { LandingBeetsHero } from './sections/LandingBeetsHero' +import { LandingBeetsSecuritySection } from './sections/LandingBeetsSecuritySection' +import { LandingBeetsSocialClub } from './sections/LandingBeetsSocialClub' +import { LandingBeetsStakedSonic } from './sections/LandingBeetsStakedSonic' +import { LandingMaBeetsSection } from './sections/LandingMaBeetsSection' +import { + GetProtocolStatsPerChainQuery, + GetProtocolStatsQuery, +} from '@repo/lib/shared/services/api/generated/graphql' +import { BeetsLandingModal } from './components/BeetsLandingModal' + +export function LandingPageLayout({ + protocolData, + protocolDataPerChain, +}: { + protocolData: GetProtocolStatsQuery + protocolDataPerChain: GetProtocolStatsPerChainQuery[] +}) { + return ( + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/BalancerV3BoostedPoolsSvg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/BalancerV3BoostedPoolsSvg.tsx new file mode 100644 index 000000000..cbe65eff8 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/BalancerV3BoostedPoolsSvg.tsx @@ -0,0 +1,97 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function BalancerV3BoostedPoolsSvg() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/BalancerV3CustomPoolsSvg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/BalancerV3CustomPoolsSvg.tsx new file mode 100644 index 000000000..1b63c88e1 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/BalancerV3CustomPoolsSvg.tsx @@ -0,0 +1,72 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function BalancerV3CustomPoolsSvg() { + return ( + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/BalancerV3HooksSvg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/BalancerV3HooksSvg.tsx new file mode 100644 index 000000000..acb00a29a --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/BalancerV3HooksSvg.tsx @@ -0,0 +1,74 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function BalancerV3HooksSvg() { + return ( + + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/BeetsByTheNumbers.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/BeetsByTheNumbers.tsx new file mode 100644 index 000000000..40b9c864f --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/BeetsByTheNumbers.tsx @@ -0,0 +1,114 @@ +import React from 'react' + +/* eslint-disable max-len */ +export function BeetsByTheNumbers() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/BeetsLandingHeroImg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/BeetsLandingHeroImg.tsx new file mode 100644 index 000000000..d816c6334 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/BeetsLandingHeroImg.tsx @@ -0,0 +1,51 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +'use client' + +import { AnimatePresence, motion, useInView } from 'framer-motion' +import { useEffect, useRef, useState } from 'react' +import Image from 'next/image' +import { Box } from '@chakra-ui/react' + +// @ts-ignore +import bgSrc from '../images/hero-bg.png' + +export function BeetsLandingHeroImg() { + const [shouldAnimate, setShouldAnimate] = useState(false) + const ref = useRef(null) + const isInView = useInView(ref, { once: true }) + + useEffect(() => { + if (isInView) { + setShouldAnimate(true) + } + }, [isInView]) + + return ( + + + + background + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/BeetsLandingModal.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/BeetsLandingModal.tsx new file mode 100644 index 000000000..d5c645a1c --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/BeetsLandingModal.tsx @@ -0,0 +1,100 @@ +'use client' + +import { + Button, + Checkbox, + HStack, + Link, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Text, + useDisclosure, +} from '@chakra-ui/react' +import NextLink from 'next/link' +import { ArrowUpRight } from 'react-feather' +import { useEffect, useState } from 'react' + +export function BeetsLandingModal() { + const { isOpen, onOpen, onClose } = useDisclosure() + const [hideOnNextVisit, setHideOnNextVisit] = useState(false) + + useEffect(() => { + const shouldShowModal = localStorage.getItem('hideLandingModal') !== 'true' + + if (shouldShowModal) { + onOpen() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + const handleClose = () => { + if (hideOnNextVisit) { + localStorage.setItem('hideLandingModal', 'true') + } + onClose() + } + + return ( + + + + Welcome to the new BEETS + + + + This is your gateway to Sonic and Optimism—designed for liquid staking, real yield, and + next-generation DeFi. + + + Start your migration today and unlock the full potential of DeFi.{' '} + + Learn More About Migration + + . + + + You can find the legacy Fantom app at{' '} + + https://ftm.beets.fi + + . + + + + + setHideOnNextVisit(e.target.checked)} + > + Do not show this message again + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/LandingSectionContainer.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/LandingSectionContainer.tsx new file mode 100644 index 000000000..9b4d98257 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/LandingSectionContainer.tsx @@ -0,0 +1,51 @@ +import { Center, Heading, VStack, Text, Button, Flex } from '@chakra-ui/react' +import { DefaultPageContainer } from '@repo/lib/shared/components/containers/DefaultPageContainer' +import React from 'react' +import NextLink from 'next/link' + +export function LandingSectionContainer({ + children, + title, + subtitle, + button, +}: { + children: React.ReactNode + title: string + subtitle: string + button?: { + text: string + href: string + isExternal?: boolean + } +}) { + return ( + <> +
    + + + {title} + + + {subtitle} + + +
    + + {children} + {button && ( + + + + )} + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial1.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial1.tsx new file mode 100644 index 000000000..6c2d9280e --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial1.tsx @@ -0,0 +1,48 @@ +import React from 'react' + +/* eslint-disable max-len */ +export function LudwigSocial1() { + return ( + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial2.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial2.tsx new file mode 100644 index 000000000..8cc4c33f3 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial2.tsx @@ -0,0 +1,34 @@ +import React from 'react' + +/* eslint-disable max-len */ +export function LudwigSocial2() { + return ( + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial3.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial3.tsx new file mode 100644 index 000000000..3e6a36cc6 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial3.tsx @@ -0,0 +1,44 @@ +import React from 'react' + +/* eslint-disable max-len */ +export function LudwigSocial3() { + return ( + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial4.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial4.tsx new file mode 100644 index 000000000..1c59e8b5a --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial4.tsx @@ -0,0 +1,44 @@ +import React from 'react' + +/* eslint-disable max-len */ +export function LudwigSocial4() { + return ( + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial5.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial5.tsx new file mode 100644 index 000000000..acbd8b7fa --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/LudwigSocial5.tsx @@ -0,0 +1,48 @@ +import React from 'react' + +/* eslint-disable max-len */ +export function LudwigSocial5() { + return ( + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsAddLiquiditySvg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsAddLiquiditySvg.tsx new file mode 100644 index 000000000..be6ca63f1 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsAddLiquiditySvg.tsx @@ -0,0 +1,135 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function MaBeetsAddLiquiditySvg() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsFairerRewardsSvg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsFairerRewardsSvg.tsx new file mode 100644 index 000000000..34a0cde2b --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsFairerRewardsSvg.tsx @@ -0,0 +1,68 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function MaBeetsFairerRewardsSvg() { + return ( + + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsGrowEarnSvg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsGrowEarnSvg.tsx new file mode 100644 index 000000000..e4857f993 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsGrowEarnSvg.tsx @@ -0,0 +1,168 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function MaBeetsGrowEarnSvg() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsMaturityVsLocking.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsMaturityVsLocking.tsx new file mode 100644 index 000000000..dc5335723 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsMaturityVsLocking.tsx @@ -0,0 +1,30 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function MaBeetsMaturityVsLockingSvg() { + return ( + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsMintMabeetsSvg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsMintMabeetsSvg.tsx new file mode 100644 index 000000000..e6a356c63 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/MaBeetsMintMabeetsSvg.tsx @@ -0,0 +1,56 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function MaBeetsMintMabeetsSvg() { + return ( + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/SecurityAuditsSvg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/SecurityAuditsSvg.tsx new file mode 100644 index 000000000..79dc0a6bb --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/SecurityAuditsSvg.tsx @@ -0,0 +1,34 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function SecurityAuditsSvg() { + return ( + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/SecurityMonitoringSvg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/SecurityMonitoringSvg.tsx new file mode 100644 index 000000000..840954e17 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/SecurityMonitoringSvg.tsx @@ -0,0 +1,62 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function SecurityMonitoringSvg() { + return ( + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/SecurityOpenSourceSvg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/SecurityOpenSourceSvg.tsx new file mode 100644 index 000000000..6026a7141 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/SecurityOpenSourceSvg.tsx @@ -0,0 +1,42 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function SecurityOpenSourceSvg() { + return ( + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/StakedSonicComposabilitySvg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/StakedSonicComposabilitySvg.tsx new file mode 100644 index 000000000..2986cea19 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/StakedSonicComposabilitySvg.tsx @@ -0,0 +1,65 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function StakedSonicComposabilitySvg() { + return ( + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/StakedSonicDecentralizationSvg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/StakedSonicDecentralizationSvg.tsx new file mode 100644 index 000000000..655172b29 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/StakedSonicDecentralizationSvg.tsx @@ -0,0 +1,678 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function StakedSonicDecentralizationSvg() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/StakedSonicStakingRewardsSvg.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/StakedSonicStakingRewardsSvg.tsx new file mode 100644 index 000000000..3b3567bfc --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/StakedSonicStakingRewardsSvg.tsx @@ -0,0 +1,130 @@ +import React from 'react' + +/* eslint-disable max-len */ + +export function StakedSonicStakingRewardsSvg() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/components/Title.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/components/Title.tsx new file mode 100644 index 000000000..61db8c562 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/components/Title.tsx @@ -0,0 +1,108 @@ +'use client' + +import { Box, BoxProps, Heading } from '@chakra-ui/react' +import { motion, AnimatePresence } from 'framer-motion' +import { useEffect, useState, useRef } from 'react' +import { useBreakpoints } from '@repo/lib/shared/hooks/useBreakpoints' +import { LettersPullUp } from '@repo/lib/shared/components/animations/LettersPullUp' + +const words = [ + { word: 'DeFi', color: '#457dff' }, + { word: 'Staking', color: '#00d395' }, + { word: 'Yield', color: '#f97316' }, + //{ word: 'Growth', color: '#F06147' }, +] + +export function Title({ ...rest }: BoxProps) { + const [currentWordIndex, setCurrentWordIndex] = useState(0) + const [widths, setWidths] = useState>({}) + const measureRef = useRef(null) + const { isMobile } = useBreakpoints() + + // Measure all words once on mount + useEffect(() => { + if (measureRef.current) { + const newWidths: Record = {} + words.forEach(({ word }) => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + measureRef.current!.textContent = word + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + newWidths[word] = measureRef.current!.offsetWidth + 20 + }) + setWidths(newWidths) + } + }, []) + + useEffect(() => { + const wordInterval = setInterval(() => { + const nextIndex = currentWordIndex === words.length - 1 ? 0 : currentWordIndex + 1 + setCurrentWordIndex(nextIndex) + }, 5000) + + return () => clearInterval(wordInterval) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentWordIndex]) + + return ( + + + Powering{' '} + + + {words.map( + ({ word, color }) => + words[currentWordIndex].word === word && ( + + ) + )} + + + {/* Hidden measurement element */} + + {!isMobile && <> on Sonic} + + {isMobile && ( + + on Sonic + + )} + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/images/hero-bg.png b/apps/beets-frontend-v3/lib/modules/landing-page/images/hero-bg.png new file mode 100644 index 000000000..9e72be177 Binary files /dev/null and b/apps/beets-frontend-v3/lib/modules/landing-page/images/hero-bg.png differ diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBalancerV3Section.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBalancerV3Section.tsx new file mode 100644 index 000000000..246802a89 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBalancerV3Section.tsx @@ -0,0 +1,115 @@ +'use client' + +import { Box, GridItem, Heading, Text, Grid, Center } from '@chakra-ui/react' +import React from 'react' +import { BalancerV3BoostedPoolsSvg } from '../components/BalancerV3BoostedPoolsSvg' +import { BalancerV3CustomPoolsSvg } from '../components/BalancerV3CustomPoolsSvg' +import { BalancerV3HooksSvg } from '../components/BalancerV3HooksSvg' +import { LandingSectionContainer } from '../components/LandingSectionContainer' +function Card({ + title, + description, + image, +}: { + title: string + description: string + image: React.ReactNode +}) { + return ( + + {image} + + + {title} + + + {description} + + + + ) +} + +export function LandingBalancerV3Section() { + return ( + + + + + Balancer v3 provides permissionless technology to streamline AMM development for + developers and empower liquidity providers with an ever-expanding DEX product suite. + + + + + + } + title="Custom Pools" + /> + } + title="Hooks Framework" + /> + } + title="100% Boosted Pools" + /> + + +
    + + Balancer v3 transforms beets into a hub of cutting-edge liquidity solutions, empowering + builders to shape the future of Sonic. + +
    +
    +
    + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsData.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsData.tsx new file mode 100644 index 000000000..2a734cf48 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsData.tsx @@ -0,0 +1,262 @@ +'use client' + +import React from 'react' +import { + Box, + //BoxProps, + Button, + Center, + Flex, + Grid, + GridItem, + HStack, + Heading, + Progress, + Text, + VStack, + chakra, +} from '@chakra-ui/react' +import { DefaultPageContainer } from '@repo/lib/shared/components/containers/DefaultPageContainer' +import { useCurrency } from '@repo/lib/shared/hooks/useCurrency' +import { BeetsByTheNumbers } from '../components/BeetsByTheNumbers' +import { + GetProtocolStatsPerChainQuery, + GetProtocolStatsQuery, + GqlChain, +} from '@repo/lib/shared/services/api/generated/graphql' +import { getChainId } from '@repo/lib/config/app.config' +//import { fNum } from '@repo/lib/shared/utils/numbers' +import { bn } from '@repo/lib/shared/utils/numbers' +import NextLink from 'next/link' + +// function SubStatBar({ +// stat, +// label, +// color, +// totalTvl, +// ...rest +// }: { stat: number; label: string; color: string; totalTvl: string } & BoxProps) { +// const { toCurrency } = useCurrency() +// return ( +// +// +// +// {label} +// + +// {toCurrency(stat)} +// +// ) +// } + +function ChainStats({ + protocolData, + totalTvl, +}: { + protocolData: GetProtocolStatsPerChainQuery + totalTvl: string +}) { + const { toCurrency } = useCurrency() + + return ( + + + TVL + {toCurrency(protocolData.protocolMetricsChain.totalLiquidity)} + + + + {/*sSonicBeetsTvl && } + {maBeetsTvl && } + {boostedPoolTvl && } + {sFtmXLegacyTvl && ( + + )} + {maBeetsLegacyTvl && ( + + )*/} + + + + + + 24h Volume + + {toCurrency(protocolData.protocolMetricsChain.swapVolume24h)} + + + + + + 24h Fees + {toCurrency(protocolData.protocolMetricsChain.swapFee24h)} + + + + + ) +} + +function ChainDataCard({ + chain, + networkColor, + protocolData, + totalTvl, + button, +}: { + chain: GqlChain + networkColor: string + protocolData: GetProtocolStatsPerChainQuery + totalTvl: string + button: React.ReactNode +}) { + return ( + + + + Beets on{' '} + + {chain} + + + + +
    {button}
    +
    + ) +} + +function GlobalStatsCard({ label, value }: { label: string; value: string }) { + return ( + + + {label} + + + {value} + + + ) +} + +export function LandingBeetsData({ + protocolData, + protocolDataPerChain, +}: { + protocolData: GetProtocolStatsQuery + protocolDataPerChain: GetProtocolStatsPerChainQuery[] +}) { + const { toCurrency } = useCurrency() + + const chainData: Record = protocolDataPerChain.reduce( + (acc, item) => { + acc[item.protocolMetricsChain.chainId] = item + return acc + }, + {} as Record + ) + + const protocolMetricsAggregated = protocolData.protocolMetricsAggregated + const totalTvl = protocolMetricsAggregated.totalLiquidity + + return ( + + + + + + + + + + + + + + + + + + + + + + Sonic Pools + + } + chain={GqlChain.Sonic} + networkColor="orange" + protocolData={chainData[getChainId(GqlChain.Sonic)]} + totalTvl={totalTvl} + /> + + + + Optimism Pools + + } + chain={GqlChain.Optimism} + networkColor="red" + protocolData={chainData[getChainId(GqlChain.Optimism)]} + totalTvl={totalTvl} + /> + + + + Fantom Pools + + } + chain={GqlChain.Fantom} + networkColor="deepskyblue" + protocolData={chainData[getChainId(GqlChain.Fantom)]} + totalTvl={totalTvl} + /> + + + + + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsHero.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsHero.tsx new file mode 100644 index 000000000..3357f0df1 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsHero.tsx @@ -0,0 +1,34 @@ +import { Box, Button, Center, Flex, Text, VStack } from '@chakra-ui/react' +import { Title } from '../components/Title' +import NextLink from 'next/link' + +export function LandingBeetsHero() { + return ( + +
    + + + <Text + fontSize="2xl" + fontWeight="thin" + maxW="full" + px={{ base: 'md', md: 'none' }} + w="2xl" + > + The Flagship LST Hub on Sonic. From seamless staking to earning real yield on + LST-focused liquidity pools, beets is the ultimate destination for your liquid-staked + tokens. + </Text> + <Flex gap="lg" mt="lg"> + <Button as={NextLink} href="/stake" size="lg" variant="primary"> + Stake $S + </Button> + <Button as={NextLink} href="/pools" size="lg" variant="secondary"> + Explore Pools + </Button> + </Flex> + </VStack> + </Center> + </Box> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsSecuritySection.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsSecuritySection.tsx new file mode 100644 index 000000000..d4e613170 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsSecuritySection.tsx @@ -0,0 +1,87 @@ +'use client' + +import { Box, Flex, Grid, GridItem, Heading, Text } from '@chakra-ui/react' +import React from 'react' +import { LandingSectionContainer } from '../components/LandingSectionContainer' +import { SecurityAuditsSvg } from '../components/SecurityAuditsSvg' +import { SecurityMonitoringSvg } from '../components/SecurityMonitoringSvg' +import { SecurityOpenSourceSvg } from '../components/SecurityOpenSourceSvg' + +function Card({ + title, + description, + image, +}: { + title: React.ReactNode + description: string + image: React.ReactNode +}) { + return ( + <GridItem mb={{ base: 'lg', lg: 'none' }}> + <Flex mb="md"> + <Box flex="1"> + <Heading fontSize="2xl">{title}</Heading> + </Box> + {image} + </Flex> + <Text fontSize="lg" fontWeight="thin"> + {description} + </Text> + </GridItem> + ) +} + +export function LandingBeetsSecuritySection() { + return ( + <LandingSectionContainer + subtitle="Built with security at its core, beets prioritizes trust at every level. From rigorous audits to open-source transparency and continuous monitoring, our ecosystem ensures your assets remain safe, reliable, and accessible." + title="Code you can trust" + > + <Box bg="rgba(255, 255, 255, 0.05)" p="xl" w="full"> + <Grid + bg="rgba(0, 0, 0, 0.2)" + gap="2xl" + p="lg" + templateColumns={{ + base: '1fr', + lg: '1fr 1fr 1fr', + }} + > + <Card + description="Our code is thoroughly audited by leading security firms." + image={<SecurityAuditsSvg />} + title={ + <> + Rigorous + <br /> + Audits + </> + } + /> + <Card + description="All code is publicly available for community scrutiny and trust." + image={<SecurityOpenSourceSvg />} + title={ + <> + Open-Source + <br /> + Transparency + </> + } + /> + <Card + description="Ongoing security assessments ensure the integrity of the beets ecosystem." + image={<SecurityMonitoringSvg />} + title={ + <> + Continous + <br /> + Monitoring + </> + } + /> + </Grid> + </Box> + </LandingSectionContainer> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsSocialClub.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsSocialClub.tsx new file mode 100644 index 000000000..6d7af422e --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsSocialClub.tsx @@ -0,0 +1,58 @@ +'use client' + +import { useNavData } from '@/lib/components/navs/useNavData' +import { Box, Center, HStack, IconButton, Link, Text } from '@chakra-ui/react' +import { DefaultPageContainer } from '@repo/lib/shared/components/containers/DefaultPageContainer' +import { AppLink } from '@repo/lib/shared/components/navs/useNav' + +function SocialLinks({ socialLinks }: { socialLinks: AppLink[] }) { + return ( + <HStack spacing="lg"> + {socialLinks.map(({ href, icon }) => ( + <IconButton + aria-label="Social icon" + as={Link} + bg="background.level2" + h="72px" + href={href} + isExternal + isRound + key={href} + rounded="full" + variant="tertiary" + w="72px" + > + {icon} + </IconButton> + ))} + </HStack> + ) +} + +export function LandingBeetsSocialClub() { + const { getSocialLinks } = useNavData() + const socialLinks = getSocialLinks(36) + + return ( + <DefaultPageContainer noVerticalPadding pb="3xl"> + <Box + backgroundImage="url(/images/misc/beets-social-club.png)" + backgroundPosition="center" + backgroundRepeat="no-repeat" + backgroundSize="auto 100%" + height="140px" + mb="2xl" + /> + <Center mb="2xl"> + <Text fontSize="2xl" fontWeight="thin" maxW="full" textAlign="center" w="2xl"> + Join our vibrant community of DeFi enthusiasts, builders, and visionaries. Share insights, + collaborate on projects, and help shape the BEETS ecosystem together. Connect, learn, and + grow with us. + </Text> + </Center> + <Center> + <SocialLinks socialLinks={socialLinks} /> + </Center> + </DefaultPageContainer> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsStakedSonic.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsStakedSonic.tsx new file mode 100644 index 000000000..40864a187 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingBeetsStakedSonic.tsx @@ -0,0 +1,105 @@ +'use client' + +import { Box, Flex, Grid, GridItem, Heading, HStack, Text, Link } from '@chakra-ui/react' +import { LandingSectionContainer } from '../components/LandingSectionContainer' +import { StakedSonicComposabilitySvg } from '../components/StakedSonicComposabilitySvg' +import { StakedSonicDecentralizationSvg } from '../components/StakedSonicDecentralizationSvg' +import { StakedSonicStakingRewardsSvg } from '../components/StakedSonicStakingRewardsSvg' +import { SpearbitLogo } from '@repo/lib/shared/components/imgs/SpearbitLogo' + +export function LandingBeetsStakedSonic() { + return ( + <LandingSectionContainer + button={{ + text: 'Stake $S', + href: '/stake', + }} + subtitle="stS redefines Liquid Staking by combining deep liquidity, robust security, and competitive yield into one powerful position. Purpose-built for Sonic, stS delivers an unparalleled staking experience—maximizing rewards without sacrificing flexibility." + title="stS: Liquid Staking on Sonic" + > + <Box + backgroundColor="rgba(255, 255, 255, 0.05)" + backgroundImage={{ base: 'none', lg: 'url(/images/misc/staking-bg.png)' }} + backgroundPosition="left bottom" + backgroundRepeat="no-repeat" + backgroundSize="50%" + p="xl" + w="full" + > + <Grid + gap="sm" + templateColumns={{ + base: '1fr', + lg: '1fr 1fr', + }} + > + <GridItem> + {/* <Box mb="xl"> + <Heading fontSize="3xl">Sonic's Leading LST</Heading> + <Text fontSize="lg" fontWeight="thin"> + stS redefines Liquid Staking by combining deep liquidity, robust security, and + competitive yield into one powerful position. Purpose-built for Sonic, stS delivers + an unparalleled staking experience—maximizing rewards without sacrificing + flexibility. + </Text> + </Box> */} + <Box mb="xl"> + <Heading fontSize="3xl">Earn Network Rewards</Heading> + <Text fontSize="lg" fontWeight="thin"> + Convert S to stS and earn continuous staking yields - while keeping your capital + fully liquid. + </Text> + </Box> + </GridItem> + <GridItem> + <Flex alignItems="center" mb="xl"> + <Box bg="rgba(255, 255, 255, 0.05)" height="170px" width="170px"> + <StakedSonicDecentralizationSvg /> + </Box> + <Box flex="1" ml="xl"> + <Heading fontSize="2xl">Drive Decentralization</Heading> + <Text fontSize="lg" fontWeight="thin"> + Support Sonic's security by distributing consensus power, enhancing ecosystem + resilience. + </Text> + </Box> + </Flex> + <Flex alignItems="center" mb="xl"> + <Box flex="1" mr="xl"> + <Heading fontSize="2xl">Composability</Heading> + <Text fontSize="lg" fontWeight="thin"> + Use stS seamlessly across DeFi - access lending markets, liquidity pools, and more + without pausing your rewards. + </Text> + </Box> + <Box bg="rgba(255, 255, 255, 0.05)" height="170px" width="170px"> + <StakedSonicComposabilitySvg /> + </Box> + </Flex> + <Flex alignItems="center"> + <Box bg="rgba(255, 255, 255, 0.05)" height="170px" width="170px"> + <StakedSonicStakingRewardsSvg /> + </Box> + <Box flex="1" ml="xl"> + <Heading fontSize="2xl">Security & Trust</Heading> + <Text fontSize="lg" fontWeight="thin" mb="md"> + Protected by audited contracts and transparent governance, stS ensures your assets + remain secure and accessible. + </Text> + <Link + href="https://github.com/spearbit/portfolio/blob/master/pdfs/Beethoven-Sonic-Staking-Spearbit-Security-Review-December-2024.pdf" + target="_blank" + > + <HStack gap="md"> + <Heading fontSize="2xl">Audited by: </Heading> + <SpearbitLogo color="#25f2d0" height="36px" width="176px" /> + </HStack> + </Link> + </Box> + </Flex> + </GridItem> + </Grid> + </Box> + </LandingSectionContainer> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingMaBeetsSection.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingMaBeetsSection.tsx new file mode 100644 index 000000000..d7a4bee93 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/sections/LandingMaBeetsSection.tsx @@ -0,0 +1,150 @@ +'use client' + +import { + Box, + Button, + Center, + Flex, + Grid, + GridItem, + Heading, + HStack, + Text, + VStack, +} from '@chakra-ui/react' +import React from 'react' +import { LandingSectionContainer } from '../components/LandingSectionContainer' +import { MaBeetsAddLiquiditySvg } from '../components/MaBeetsAddLiquiditySvg' +import { MaBeetsFairerRewardsSvg } from '../components/MaBeetsFairerRewardsSvg' +import { MaBeetsGrowEarnSvg } from '../components/MaBeetsGrowEarnSvg' +import { MaBeetsMaturityVsLockingSvg } from '../components/MaBeetsMaturityVsLocking' +import { MaBeetsMintMabeetsSvg } from '../components/MaBeetsMintMabeetsSvg' +import { MaBeetsNavLink } from '@/lib/components/navs/MaBeetsNavLink' + +function FeatureCard({ + title, + description, + image, +}: { + title: string + description: string + image: React.ReactNode +}) { + return ( + <HStack align="start" h="full" spacing="none" w="full"> + <Box bg="rgba(0, 0, 0, 0.1)" borderBottom="30px solid rgba(0, 0, 0, 0.4)" h="full" w="40%"> + {image} + </Box> + <VStack align="start" borderBottom="30px solid rgba(0, 0, 0, 0.3)" h="full" p="lg" w="60%"> + <Heading fontSize="2xl">{title}</Heading> + <Text fontSize="lg" fontWeight="thin"> + {description} + </Text> + </VStack> + </HStack> + ) +} + +function HowItWorksCard({ + title, + description, + image, +}: { + title: string + description: string + image: React.ReactNode +}) { + return ( + <GridItem + alignItems="center" + bg={{ base: 'rgba(0, 0, 0, 0.2)', lg: 'none' }} + display={{ base: 'flex', lg: 'block' }} + flexDirection="column" + p={{ base: 'lg', lg: 'none' }} + > + <Box height="100px" mb="lg"> + {image} + </Box> + <Heading fontSize="xl" mb="md"> + {title} + </Heading> + <Text fontSize="lg" fontWeight="thin"> + {description} + </Text> + </GridItem> + ) +} + +export function LandingMaBeetsSection() { + return ( + <LandingSectionContainer + subtitle="Shape the Future. Earn as You Grow. maBEETS unlocks maturity-adjusted voting power, + allowing you to participate in governance decisions and earn rewards without locking + your assets." + title="maBEETS: Your Voice, Your Rewards" + > + <Box bg="rgba(255, 255, 255, 0.05)" p="xl" w="full"> + <Grid + gap="xl" + mb="xl" + templateColumns={{ + base: '1fr', + lg: '1fr 1fr', + }} + > + <GridItem> + <FeatureCard + description="Your voting power grows with time, rewarding commitment and active participation, not lock-ups." + image={<MaBeetsMaturityVsLockingSvg />} + title="Maturity vs Locking" + /> + </GridItem> + <GridItem> + <FeatureCard + description="Earn based on both the size and maturity of your position, aligning long-term contributors with the protocol’s success. " + image={<MaBeetsFairerRewardsSvg />} + title="Fairer Rewards" + /> + </GridItem> + </Grid> + <Box mb="lg"> + <Center> + <Heading fontSize="3xl">How it works</Heading> + </Center> + </Box> + <Grid + gap="lg" + templateColumns={{ + base: '1fr', + lg: '1fr 1fr 1fr', + }} + > + <HowItWorksCard + description="Join the Fresh Beets Pool (80/20 BEETS/stS) to receive fBEETS." + image={<MaBeetsAddLiquiditySvg />} + title="Add Liquidity" + /> + <HowItWorksCard + description="Deposit your fBEETS to create a maBEETS position tied to a Relic NFT." + image={<MaBeetsMintMabeetsSvg />} + title="Mint maBEETS" + /> + <HowItWorksCard + description="As your position matures, enjoy increasing rewards and voting power." + image={<MaBeetsGrowEarnSvg />} + title="Grow & Earn" + /> + </Grid> + </Box> + <Flex justify="center" pt="2xl"> + <MaBeetsNavLink + triggerEl={ + <Button minWidth="160px" variant="primary"> + Get maBEETS + </Button> + } + /> + </Flex> + </LandingSectionContainer> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/landing-page/sections/Token.tsx b/apps/beets-frontend-v3/lib/modules/landing-page/sections/Token.tsx new file mode 100644 index 000000000..51ef85ff2 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/landing-page/sections/Token.tsx @@ -0,0 +1,79 @@ +'use client' + +import React from 'react' +import { Box, Center, Grid, GridItem, Heading, HStack, Link, Text, VStack } from '@chakra-ui/react' +import { DefaultPageContainer } from '@repo/lib/shared/components/containers/DefaultPageContainer' +import { CoingeckoIcon } from '@repo/lib/shared/components/icons/CoingeckoIcon' +import { useCurrency } from '@repo/lib/shared/hooks/useCurrency' + +export function FeatureCard({ title, description }: { title: string; description: string }) { + return ( + <HStack align="start" h="full" spacing="none" w="full"> + <Box bg="rgba(0, 0, 0, 0.1)" borderBottom="30px solid rgba(0, 0, 0, 0.4)" h="full" w="40%" /> + <VStack align="start" borderBottom="30px solid rgba(0, 0, 0, 0.3)" h="full" p="lg" w="60%"> + <Heading fontSize="2xl">{title}</Heading> + <Text fontSize="lg">{description}</Text> + </VStack> + </HStack> + ) +} + +export function Token() { + const { toCurrency } = useCurrency() + + return ( + <> + <Center mb="xl" textAlign="center"> + <VStack> + <Heading fontSize="5xl">The $BEETS token</Heading> + <Text fontSize="2xl" fontWeight="thin" maxW="full" w="2xl"> + The $BEETS token is our primary method of incentive and reward. But it's so much + more. + </Text> + </VStack> + </Center> + <DefaultPageContainer noVerticalPadding pb="3xl"> + <Box bg="rgba(255, 255, 255, 0.05)" p="xl" w="full"> + <Grid + gap="xl" + templateColumns={{ base: '1fr', lg: 'repeat(2, 1fr)' }} + templateRows={{ base: 'repeat(4, 1fr)', lg: 'repeat(2, 1fr)' }} + > + <GridItem> + <FeatureCard + description="$BEETS is a key instrument in many incentivized pools as well as 'bribe' rewards and other partner offers." + title="Rewards" + /> + </GridItem> + <GridItem> + <FeatureCard + description="Vest $BEETS in the maBEETS initiative to get voting power in our DAO based governance model." + title="Vote" + /> + </GridItem> + <GridItem> + <FeatureCard + description="$BEETS is bridgeable between Optimism and Fantom - and more importantly for existing holders on FTM, easily migratable to Sonic." + title="Bridge & Migrate" + /> + </GridItem> + <GridItem> + <Center h="full" w="full"> + <VStack> + <Heading size="lg">$BEETS Price</Heading> + <Text fontSize="3xl">{toCurrency(0.0303)}</Text> + <HStack> + <Link href="https://www.coingecko.com/en/coins/beethoven-x" isExternal> + View price history + </Link> + <CoingeckoIcon height={16} width={16} /> + </HStack> + </VStack> + </Center> + </GridItem> + </Grid> + </Box> + </DefaultPageContainer> + </> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/Lst.tsx b/apps/beets-frontend-v3/lib/modules/lst/Lst.tsx new file mode 100644 index 000000000..3d2164304 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/Lst.tsx @@ -0,0 +1,431 @@ +/* eslint-disable max-len */ +'use client' + +import { + Box, + Button, + Card, + CardBody, + CardFooter, + HStack, + Tooltip, + useDisclosure, + VStack, + Text, + Skeleton, + BoxProps, + Grid, + GridItem, + Flex, +} from '@chakra-ui/react' +import { ConnectWallet } from '@repo/lib/modules/web3/ConnectWallet' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import FadeInOnView from '@repo/lib/shared/components/containers/FadeInOnView' +import { useIsMounted } from '@repo/lib/shared/hooks/useIsMounted' +import { useEffect, useRef, useState } from 'react' +import ButtonGroup, { + ButtonGroupOption, +} from '@repo/lib/shared/components/btns/button-group/ButtonGroup' +import { useLst } from './LstProvider' +import { LstStakeModal } from './modals/LstStakeModal' +import { useTokens } from '@repo/lib/modules/tokens/TokensProvider' +import { useTokenBalances } from '@repo/lib/modules/tokens/TokenBalancesProvider' +import { LstStake } from './components/LstStake' +import { LstUnstake } from './components/LstUnstake' +import { LstUnstakeModal } from './modals/LstUnstakeModal' +import { LstWithdraw } from './components/LstWithdraw' +import { useGetUserWithdraws, UserWithdraw } from './hooks/useGetUserWithdraws' +import { useGetUserNumWithdraws } from './hooks/useGetUserNumWithdraws' +import { useGetStakedSonicData } from './hooks/useGetStakedSonicData' +import { bn, fNum, fNumCustom } from '@repo/lib/shared/utils/numbers' +import { ZenGarden } from '@repo/lib/shared/components/zen/ZenGarden' +import { NoisyCard } from '@repo/lib/shared/components/containers/NoisyCard' +import { LstFaq } from './components/LstFaq' +import { DefaultPageContainer } from '@repo/lib/shared/components/containers/DefaultPageContainer' +import { GetStakedSonicDataQuery } from '@repo/lib/shared/services/api/generated/graphql' +import { useCurrency } from '@repo/lib/shared/hooks/useCurrency' +import { LstStats } from './components/LstStats' +import networkConfigs from '@repo/lib/config/networks' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' +import { Address } from 'viem' +import { TokenIcon } from '@repo/lib/modules/tokens/TokenIcon' + +const CHAIN = GqlChain.Sonic + +const COMMON_NOISY_CARD_PROPS: { contentProps: BoxProps; cardProps: BoxProps } = { + contentProps: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + borderBottomLeftRadius: 'none', + borderTopLeftRadius: 'none', + borderBottomRightRadius: 'none', + rounded: 'lg', + overflow: 'hidden', + }, + cardProps: { + position: 'relative', + height: 'full', + rounded: 'lg', + overflow: 'hidden', + }, +} + +function LstForm() { + const nextBtn = useRef(null) + const stakeModalDisclosure = useDisclosure() + const unstakeModalDisclosure = useDisclosure() + const [disclosure, setDisclosure] = useState(stakeModalDisclosure) + const isMounted = useIsMounted() + const { isConnected } = useUserAccount() + const { isBalancesLoading } = useTokenBalances() + const { startTokenPricePolling } = useTokens() + + const { + activeTab, + setActiveTab, + amountAssets, + amountShares, + setAmountAssets, + setAmountShares, + isDisabled, + disabledReason, + isStakeTab, + isUnstakeTab, + isWithdrawTab, + stakeTransactionSteps, + unstakeTransactionSteps, + chain, + nativeAsset, + stakedAsset, + getAmountShares, + getAmountAssets, + isRateLoading, + } = useLst() + + const { userNumWithdraws, isLoading: isUserNumWithdrawsLoading } = useGetUserNumWithdraws(chain) + + const { data: UserWithdraws, isLoading: isWithdrawalsLoading } = useGetUserWithdraws( + chain, + userNumWithdraws + ) + const isLoading = + !isMounted || isBalancesLoading || isWithdrawalsLoading || isUserNumWithdrawsLoading + + const loadingText = isLoading ? 'Loading...' : undefined + + const tabs: ButtonGroupOption[] = [ + { + value: '0', + label: 'Stake', + disabled: false, + }, + { + value: '1', + label: 'Unstake', + disabled: false, + }, + { + value: '2', + label: 'Withdraw', + disabled: false, + }, + ] + + useEffect(() => { + if (isStakeTab) { + setDisclosure(stakeModalDisclosure) + setAmountAssets('') + } else if (isUnstakeTab) { + setDisclosure(unstakeModalDisclosure) + setAmountShares('') + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [activeTab]) + + useEffect(() => { + setActiveTab(tabs[0]) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + function onModalClose() { + // restart polling for token prices when modal is closed again + startTokenPricePolling() + + // just reset all transaction steps + stakeTransactionSteps.resetTransactionSteps() + unstakeTransactionSteps.resetTransactionSteps() + + // reset amounts + setAmountAssets('') + setAmountShares('') + + // finally close the modal + disclosure.onClose() + } + + return ( + <VStack h="full" w="full"> + <CardBody align="start" as={VStack} h="full" w="full"> + <Box h="full" w="full"> + <VStack spacing="md" w="full"> + <ButtonGroup + currentOption={activeTab} + groupId="add-liquidity" + hasLargeTextLabel + isFullWidth + onChange={setActiveTab} + options={tabs} + size="md" + /> + </VStack> + {isStakeTab && <LstStake />} + {isUnstakeTab && <LstUnstake />} + {isWithdrawTab && !isWithdrawalsLoading && ( + <LstWithdraw + isLoading={isWithdrawalsLoading || isUserNumWithdrawsLoading} + withdrawalsData={UserWithdraws as UserWithdraw[]} + /> + )} + </Box> + {/* <HStack> + {isStakedSonicDataLoading ? ( + <Skeleton h="full" w="12" /> + ) : ( + <> + <Text>{`1 ${tokenIn}`}</Text> + <Icon as={ArrowRight} /> + <Text>{`${fNum('token', rate)} ${tokenOut}`}</Text> + </> + )} + </HStack> */} + {isStakeTab && !isRateLoading && amountAssets !== '' && ( + <LstYouWillReceive + address={stakedAsset?.address || ''} + amount={getAmountShares(amountAssets)} + label="You will receive" + symbol={stakedAsset?.symbol || ''} + /> + )} + {isUnstakeTab && !isRateLoading && amountShares !== '' && ( + <LstYouWillReceive + address={nativeAsset?.address || ''} + amount={getAmountAssets(amountShares)} + label="You can withdraw (after 14 days)" + symbol={nativeAsset?.symbol || ''} + /> + )} + </CardBody> + <CardFooter w="full"> + {isConnected && !isWithdrawTab && ( + <Tooltip label={isDisabled ? disabledReason : ''}> + <Button + isDisabled={isDisabled} + isLoading={isLoading} + loadingText={loadingText} + onClick={() => disclosure.onOpen()} + ref={nextBtn} + size="lg" + variant="secondary" + w="full" + > + Next + </Button> + </Tooltip> + )} + {!isConnected && ( + <ConnectWallet + isLoading={isLoading} + loadingText={loadingText} + size="lg" + variant="primary" + w="full" + /> + )} + </CardFooter> + <LstStakeModal + finalFocusRef={nextBtn} + isOpen={stakeModalDisclosure.isOpen} + onClose={onModalClose} + onOpen={stakeModalDisclosure.onOpen} + /> + <LstUnstakeModal + finalFocusRef={nextBtn} + isOpen={unstakeModalDisclosure.isOpen} + onClose={onModalClose} + onOpen={unstakeModalDisclosure.onOpen} + /> + </VStack> + ) +} + +function LstYouWillReceive({ + label, + amount, + address, + symbol, +}: { + label: string + amount: string + address: string + symbol: string +}) { + const amountFormatted = fNumCustom(amount, '0,0.[000000]') + + return ( + <Box w="full"> + <FadeInOnView> + <Flex alignItems="flex-end" w="full"> + <Box flex="1"> + <Text color="grayText" mb="sm"> + {label} + </Text> + <Text fontSize="3xl"> + {amountFormatted === 'NaN' ? amount : amountFormatted} {symbol} + </Text> + </Box> + <Box> + <TokenIcon address={address} alt={symbol} chain={CHAIN} size={40} /> + </Box> + </Flex> + </FadeInOnView> + </Box> + ) +} + +function LstStatRow({ + label, + value, + secondaryValue, + isLoading, +}: { + label: string + value: string + secondaryValue?: string + isLoading?: boolean +}) { + return ( + <HStack align="flex-start" justify="space-between" w="full"> + <Text color="font.secondary">{label}</Text> + <Box alignItems="flex-end" display="flex" flexDirection="column"> + {isLoading ? <Skeleton h="full" w="12" /> : <Text fontWeight="bold">{value}</Text>} + {isLoading ? ( + <Skeleton h="full" w="12" /> + ) : ( + <Text color="grayText" fontSize="sm"> + {secondaryValue} + </Text> + )} + </Box> + </HStack> + ) +} + +function LstInfo({ + stakedSonicData, + isStakedSonicDataLoading, +}: { + stakedSonicData?: GetStakedSonicDataQuery + isStakedSonicDataLoading: boolean +}) { + const lstAddress = (networkConfigs[CHAIN].contracts.beets?.lstStakingProxy || '') as Address + const { getToken, usdValueForToken } = useTokens() + const lstToken = getToken(lstAddress, CHAIN) + const { toCurrency } = useCurrency() + const assetsToSharesRate = stakedSonicData?.stsGetGqlStakedSonicData.exchangeRate || '1.0' + const sharesToAssetsRate = bn(1).div(bn(assetsToSharesRate)) + + return ( + <NoisyCard + cardProps={COMMON_NOISY_CARD_PROPS.cardProps} + contentProps={COMMON_NOISY_CARD_PROPS.contentProps} + > + <Box bottom={0} left={0} overflow="hidden" position="absolute" right={0} top={0}> + <ZenGarden sizePx="280px" subdued variant="circle" /> + </Box> + <VStack + align="flex-start" + h="full" + justify="flex-start" + m="auto" + p={{ base: 'md', md: 'lg' }} + role="group" + spacing="sm" + w="full" + zIndex={1} + > + <LstStatRow + isLoading={isStakedSonicDataLoading} + label="Total ($S)" + secondaryValue={toCurrency( + usdValueForToken(lstToken, stakedSonicData?.stsGetGqlStakedSonicData.totalAssets || '0') + )} + value={fNum('token', stakedSonicData?.stsGetGqlStakedSonicData.totalAssets || '0')} + /> + <LstStatRow + isLoading={isStakedSonicDataLoading} + label="Delegated ($S)" + secondaryValue={toCurrency( + usdValueForToken( + lstToken, + stakedSonicData?.stsGetGqlStakedSonicData.totalAssetsDelegated || '0' + ) + )} + value={fNum( + 'token', + stakedSonicData?.stsGetGqlStakedSonicData.totalAssetsDelegated || '0' + )} + /> + <LstStatRow + isLoading={isStakedSonicDataLoading} + label="Pending delegation ($S)" + secondaryValue={toCurrency( + usdValueForToken( + lstToken, + stakedSonicData?.stsGetGqlStakedSonicData.totalAssetsPool || '0' + ) + )} + value={fNum('token', stakedSonicData?.stsGetGqlStakedSonicData.totalAssetsPool || '0')} + /> + <LstStatRow + isLoading={isStakedSonicDataLoading} + label="stS rate" + secondaryValue={`1 S = ${fNum('token', sharesToAssetsRate)} stS`} + value={`1 stS = ${fNum('token', assetsToSharesRate)} S`} + /> + <Box minH="120px" w="full" /> + {/* <Box minH="200px" w="full"> + <ReactECharts option={options} style={{ height: '100%', width: '100%' }} /> + </Box> */} + </VStack> + </NoisyCard> + ) +} + +export function Lst() { + const { data: stakedSonicData, loading: isStakedSonicDataLoading } = useGetStakedSonicData() + + return ( + <FadeInOnView> + <DefaultPageContainer noVerticalPadding> + <VStack gap="xl" w="full"> + <LstStats /> + <Card rounded="xl" w="full"> + <Grid gap="lg" templateColumns={{ base: '1fr', lg: '5fr 4fr' }}> + <GridItem> + <LstForm /> + </GridItem> + <GridItem> + <LstInfo + isStakedSonicDataLoading={isStakedSonicDataLoading} + stakedSonicData={stakedSonicData} + /> + </GridItem> + </Grid> + </Card> + <LstFaq /> + </VStack> + </DefaultPageContainer> + </FadeInOnView> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/LstProvider.tsx b/apps/beets-frontend-v3/lib/modules/lst/LstProvider.tsx new file mode 100644 index 000000000..1c79afe0b --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/LstProvider.tsx @@ -0,0 +1,152 @@ +/* eslint-disable max-len */ +'use client' + +import { useState, PropsWithChildren, createContext } from 'react' +import { useMandatoryContext } from '@repo/lib/shared/utils/contexts' +import { ButtonGroupOption } from '@repo/lib/shared/components/btns/button-group/ButtonGroup' +import { useTransactionSteps } from '@repo/lib/modules/transactions/transaction-steps/useTransactionSteps' +import { useLstStakeStep } from './hooks/useLstStakeStep' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' +import sonicNetworkConfig from '@repo/lib/config/networks/sonic' +import { useLstUnstakeStep } from './hooks/useLstUnstakeStep' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { LABELS } from '@repo/lib/shared/labels' +import { bn } from '@repo/lib/shared/utils/numbers' +import { isDisabledWithReason } from '@repo/lib/shared/utils/functions/isDisabledWithReason' +import { useTokens } from '@repo/lib/modules/tokens/TokensProvider' +import { PaginationState } from '@repo/lib/shared/components/pagination/pagination.types' +import { useLstWithdrawStep } from './hooks/useLstWithdrawStep' +import { useTokenInputsValidation } from '@repo/lib/modules/tokens/TokenInputsValidationProvider' +import { formatUnits, parseUnits } from 'viem' +import { useGetRate } from './hooks/useGetRate' + +const CHAIN = GqlChain.Sonic +const WITHDRAW_DELAY = 1209600 // 14 days in seconds + +export function _useLst() { + const [activeTab, setActiveTab] = useState<ButtonGroupOption>() + const [amountAssets, setAmountAssets] = useState('') + const [amountShares, setAmountShares] = useState('') + const [amountWithdraw, setAmountWithdraw] = useState(0n) + const [first, setFirst] = useState(5) + const [skip, setSkip] = useState(0) + const [withdrawId, setWithdrawId] = useState<bigint>(0n) + const { isConnected } = useUserAccount() + const { getToken } = useTokens() + const { hasValidationError, getValidationError } = useTokenInputsValidation() + + function setPagination(pagination: PaginationState) { + setFirst(pagination.pageSize) + setSkip(pagination.pageIndex * pagination.pageSize) + } + + const pagination: PaginationState = { + pageIndex: skip / first, + pageSize: first, + } + + const isStakeTab = activeTab?.value === '0' + const isUnstakeTab = activeTab?.value === '1' + const isWithdrawTab = activeTab?.value === '2' + + const nativeAsset = getToken(sonicNetworkConfig.tokens.nativeAsset.address, CHAIN) + const stakedAsset = getToken(sonicNetworkConfig.tokens.stakedAsset?.address || '', CHAIN) + + const { step: stakeStep } = useLstStakeStep(amountAssets, CHAIN, isStakeTab) + const stakeTransactionSteps = useTransactionSteps([stakeStep], false) + const lstStakeTxHash = stakeTransactionSteps.lastTransaction?.result?.data?.transactionHash + const lstStakeTxConfirmed = stakeTransactionSteps.lastTransactionConfirmed + + const { step: unstakeStep } = useLstUnstakeStep(amountShares, CHAIN, isUnstakeTab) + const unstakeTransactionSteps = useTransactionSteps([unstakeStep], false) + const lstUnstakeTxHash = unstakeTransactionSteps.lastTransaction?.result?.data?.transactionHash + const lstUnstakeTxConfirmed = unstakeTransactionSteps.lastTransactionConfirmed + + const { step: withdrawStep } = useLstWithdrawStep(CHAIN, isWithdrawTab, withdrawId) + const withdrawTransactionSteps = useTransactionSteps([withdrawStep], false) + const lstWithdrawTxHash = withdrawTransactionSteps.lastTransaction?.result?.data?.transactionHash + const lstWithdrawTxConfirmed = withdrawTransactionSteps.lastTransactionConfirmed + + const hasStakedAssetValidationError = hasValidationError(stakedAsset) + const hasNativeAssetValidationError = hasValidationError(nativeAsset) + + const disabledConditions: [boolean, string][] = [ + [!isConnected, LABELS.walletNotConnected], + [isStakeTab && (!amountAssets || bn(amountAssets).lt(0.01)), 'Minimum amount to stake is 0.01'], + [ + isUnstakeTab && (!amountShares || bn(amountShares).lte(0)), + 'Please enter an amount to unstake', + ], + [isStakeTab && hasNativeAssetValidationError, getValidationError(nativeAsset)], + [isUnstakeTab && hasStakedAssetValidationError, getValidationError(stakedAsset)], + ] + + const { isDisabled, disabledReason } = isDisabledWithReason(...disabledConditions) + + const { data: rate, isLoading: isRateLoading } = useGetRate(CHAIN) + + function getAmountShares(amountAssets: string) { + if (amountAssets === '') return '0' + + const amountShares = (parseUnits(amountAssets, 18) * 10n ** 18n) / (rate || 1n) + + return formatUnits(amountShares, 18) + } + + function getAmountAssets(amountShares: string) { + if (amountShares === '') return '0' + + const amountAssets = (parseUnits(amountShares, 18) * (rate || 1n)) / 10n ** 18n + + return formatUnits(amountAssets, 18) + } + + return { + activeTab, + setActiveTab, + stakeTransactionSteps, + amountAssets, + setAmountAssets, + amountShares, + setAmountShares, + chain: CHAIN, + lstStakeTxHash, + lstStakeTxConfirmed, + nativeAsset, + stakedAsset, + unstakeTransactionSteps, + lstUnstakeTxHash, + lstUnstakeTxConfirmed, + isDisabled, + disabledReason, + isStakeTab, + isUnstakeTab, + isWithdrawTab, + withdrawDelay: WITHDRAW_DELAY, + pagination, + setPagination, + first, + skip, + withdrawTransactionSteps, + lstWithdrawTxHash, + lstWithdrawTxConfirmed, + withdrawId, + setWithdrawId, + getAmountShares, + getAmountAssets, + isRateLoading, + amountWithdraw, + setAmountWithdraw, + } +} + +export type Result = ReturnType<typeof _useLst> +export const LstContext = createContext<Result | null>(null) + +export function LstProvider({ children }: PropsWithChildren) { + const Lst = _useLst() + + return <LstContext.Provider value={Lst}>{children}</LstContext.Provider> +} + +export const useLst = (): Result => useMandatoryContext(LstContext, 'Lst') diff --git a/apps/beets-frontend-v3/lib/modules/lst/LstProvidersLayout.tsx b/apps/beets-frontend-v3/lib/modules/lst/LstProvidersLayout.tsx new file mode 100644 index 000000000..0deaf6496 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/LstProvidersLayout.tsx @@ -0,0 +1,35 @@ +'use client' + +import { TokenBalancesProvider } from '@repo/lib/modules/tokens/TokenBalancesProvider' +import { useTokens } from '@repo/lib/modules/tokens/TokensProvider' +import { PropsWithChildren } from 'react' +import sonicNetworkConfig from '@repo/lib/config/networks/sonic' +import { TokenInputsValidationProvider } from '@repo/lib/modules/tokens/TokenInputsValidationProvider' +import { PriceImpactProvider } from '@repo/lib/modules/price-impact/PriceImpactProvider' +import { LstProvider } from './LstProvider' +import { TransactionStateProvider } from '@repo/lib/modules/transactions/transaction-steps/TransactionStateProvider' + +export default function LstProvidersLayout({ children }: PropsWithChildren) { + const { tokens } = useTokens() + + const stakingTokens = tokens.filter( + t => + (t.address === sonicNetworkConfig.tokens.nativeAsset.address && + t.chainId === sonicNetworkConfig.chainId) || + t.address === sonicNetworkConfig.tokens.stakedAsset?.address + ) + + if (stakingTokens.length === 0) throw new Error('Staking tokens not found') + + return ( + <TransactionStateProvider> + <TokenBalancesProvider initTokens={stakingTokens}> + <TokenInputsValidationProvider> + <LstProvider> + <PriceImpactProvider>{children}</PriceImpactProvider> + </LstProvider> + </TokenInputsValidationProvider> + </TokenBalancesProvider> + </TransactionStateProvider> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/components/LstFaq.tsx b/apps/beets-frontend-v3/lib/modules/lst/components/LstFaq.tsx new file mode 100644 index 000000000..e09159b94 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/components/LstFaq.tsx @@ -0,0 +1,75 @@ +import { + Box, + Card, + CardHeader, + HStack, + Heading, + CardBody, + VStack, + Accordion, + AccordionItem, + AccordionButton, + AccordionIcon, + AccordionPanel, +} from '@chakra-ui/react' + +const FAQ_ITEMS = [ + { + question: 'What is stS?', + answer: + 'stS is a liquid-staked token that users receive when they stake $S on the Beets platform. The value of stS naturally appreciates in relation to $S thanks to native network staking rewards from validator delegation being automatically compounded within the token.', + }, + { + question: 'What are the stS fees?', + answer: + 'Due to the management of underlying nodes, validators earn 15% of the overall stS staking rewards. Beets also takes a 10% protocol fee on the rewards after the validator fees. The APY displayed on the UI is the APY the user receives (all fees have been subtracted automatically).', + }, + { + question: 'How do I get stS tokens?', + answer: + 'To stake, users simply need to head to the stS page and select how much $S they wish to deposit. As an alternative to staking, users can swap into stS on DEXs by swapping their $S for stS on the Swap Page.', + }, + { + question: 'How do I unstake stS for $S?', + answer: + 'Unstaking stS involves a 14-day unbonding period aligned with staking on Sonic. After initiating the unstake, users will need to return to the UI after 14 days to claim $S. For instant liquidity, users can swap stS for $S directly on DEXs via the Swap Page. However, note that swapping may offer a less favorable exchange rate than unstaking, depending on the pool’s liquidity.', + }, + { + question: 'Where can I use stS tokens?', + answer: + 'stS is fully liquid, meaning you can use stS seamlessly across DeFi and access lending markets, liquidity pools, and more without pausing your rewards.', + }, + { + question: 'What is the stS exchange rate and how does it change?', + answer: + 'The stS token accrues staking rewards via delegating the underlying $S to trustworthy validators on the network. Every time staking rewards are added to the pool, the stS exchange rate to $S increases.', + }, +] + +export function LstFaq() { + return ( + <Card rounded="xl" w="full"> + <CardHeader as={HStack} justify="space-between" w="full"> + <Heading as="h2" size="lg"> + FAQ + </Heading> + </CardHeader> + <CardBody align="start" as={VStack} /> + <Accordion allowToggle bg="transparent" variant="button"> + {FAQ_ITEMS.map(item => ( + <AccordionItem key={item.question} mb="sm"> + <h2> + <AccordionButton> + <Box as="span" flex="1" textAlign="left"> + {item.question} + </Box> + <AccordionIcon /> + </AccordionButton> + </h2> + <AccordionPanel pb="md">{item.answer}</AccordionPanel> + </AccordionItem> + ))} + </Accordion> + </Card> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/components/LstStake.tsx b/apps/beets-frontend-v3/lib/modules/lst/components/LstStake.tsx new file mode 100644 index 000000000..697ee9dec --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/components/LstStake.tsx @@ -0,0 +1,15 @@ +import { useLst } from '../LstProvider' +import { TokenInput } from '@repo/lib/modules/tokens/TokenInput/TokenInput' + +export function LstStake() { + const { amountAssets, setAmountAssets, chain, nativeAsset } = useLst() + + return ( + <TokenInput + address={nativeAsset?.address || ''} + chain={chain} + onChange={e => setAmountAssets(e.currentTarget.value)} + value={amountAssets} + /> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/components/LstStakeSummary.tsx b/apps/beets-frontend-v3/lib/modules/lst/components/LstStakeSummary.tsx new file mode 100644 index 000000000..588f732f4 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/components/LstStakeSummary.tsx @@ -0,0 +1,52 @@ +import { Card } from '@chakra-ui/react' +import { AnimateHeightChange } from '@repo/lib/shared/components/animations/AnimateHeightChange' +import { useBreakpoints } from '@repo/lib/shared/hooks/useBreakpoints' +import { MobileStepTracker } from '@repo/lib/modules/transactions/transaction-steps/step-tracker/MobileStepTracker' +import { useLst } from '../LstProvider' +import { LstStakeReceiptResult } from '@repo/lib/modules/transactions/transaction-steps/receipts/receipt.hooks' +import { LstTokenRow } from './LstTokenRow' +import { useGetConvertToShares } from '../hooks/useGetConvertToShares' +import { formatUnits, parseUnits } from 'viem' + +export function LstStakeSummary({ + isLoading: isLoadingReceipt, + receivedToken, +}: LstStakeReceiptResult) { + const { isMobile } = useBreakpoints() + + const { chain, stakeTransactionSteps, lstStakeTxHash, nativeAsset, stakedAsset, amountAssets } = + useLst() + + const { sharesAmount, isLoading: isLoadingSharesAmount } = useGetConvertToShares( + parseUnits(amountAssets, 18), + chain + ) + + const shouldShowReceipt = !!lstStakeTxHash && !isLoadingReceipt && !!receivedToken + + return ( + <AnimateHeightChange spacing="sm" w="full"> + {isMobile && <MobileStepTracker chain={chain} transactionSteps={stakeTransactionSteps} />} + <Card variant="modalSubSection"> + <LstTokenRow + chain={chain} + isLoading={isLoadingSharesAmount} + label={shouldShowReceipt ? 'You staked' : 'You stake'} + tokenAddress={nativeAsset?.address || ''} + tokenAmount={amountAssets} + /> + </Card> + <Card variant="modalSubSection"> + <LstTokenRow + chain={chain} + isLoading={isLoadingSharesAmount || isLoadingReceipt} + label={shouldShowReceipt ? 'You received' : 'You receive'} + tokenAddress={stakedAsset?.address || ''} + tokenAmount={ + shouldShowReceipt ? receivedToken.humanAmount : formatUnits(sharesAmount, 18) + } + /> + </Card> + </AnimateHeightChange> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/components/LstStats.tsx b/apps/beets-frontend-v3/lib/modules/lst/components/LstStats.tsx new file mode 100644 index 000000000..7fb765661 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/components/LstStats.tsx @@ -0,0 +1,120 @@ +'use client' + +import { Box, BoxProps, Card, Flex, Grid, GridItem, Skeleton, Text } from '@chakra-ui/react' +import { useCurrency } from '@repo/lib/shared/hooks/useCurrency' +import { StsByTheNumbersSvg } from './StsByTheNumbersSvg' +import { NoisyCard } from '@repo/lib/shared/components/containers/NoisyCard' +import { ZenGarden } from '@repo/lib/shared/components/zen/ZenGarden' +import { useGetStakedSonicData } from '../hooks/useGetStakedSonicData' +import { fNum } from '@repo/lib/shared/utils/numbers' +import { useTokens } from '@repo/lib/modules/tokens/TokensProvider' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' +import networkConfigs from '@repo/lib/config/networks' +import { Address } from 'viem' + +const CHAIN = GqlChain.Sonic + +const COMMON_NOISY_CARD_PROPS: { contentProps: BoxProps; cardProps: BoxProps } = { + contentProps: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + borderBottomLeftRadius: 'none', + borderTopLeftRadius: 'none', + borderBottomRightRadius: 'none', + rounded: 'lg', + overflow: 'hidden', + }, + cardProps: { + position: 'relative', + height: 'full', + rounded: 'lg', + overflow: 'hidden', + }, +} + +function GlobalStatsCard({ + label, + value, + isLoading, +}: { + label: string + value: string + isLoading: boolean +}) { + return ( + <Flex alignItems="flex-end" mx="md" my="sm"> + <Box color="font.highlight" flex="1" fontWeight="semibold" textAlign="left"> + {label} + </Box> + <Box> + {isLoading ? ( + <Skeleton color="white" h="40px" w="full" /> + ) : ( + <Text fontSize="4xl">{value}</Text> + )} + </Box> + </Flex> + ) +} + +export function LstStats() { + const lstAddress = (networkConfigs[CHAIN].contracts.beets?.lstStakingProxy || '') as Address + const { getToken, usdValueForToken } = useTokens() + const lstToken = getToken(lstAddress, CHAIN) + const { toCurrency } = useCurrency() + const { data: stakedSonicData, loading: isStakedSonicDataLoading } = useGetStakedSonicData() + const stakingApr = stakedSonicData?.stsGetGqlStakedSonicData.stakingApr || '0' + const stakedSonic = stakedSonicData?.stsGetGqlStakedSonicData.totalAssets || '0' + + return ( + <Card rounded="xl" w="full"> + <NoisyCard + cardProps={COMMON_NOISY_CARD_PROPS.cardProps} + contentProps={COMMON_NOISY_CARD_PROPS.contentProps} + > + <Box bottom={0} left={0} overflow="hidden" position="absolute" right={0} top={0}> + <ZenGarden sizePx="280px" subdued variant="circle" /> + </Box> + <Box bg="rgba(0, 0, 0, 0.1)" display="flex" w="full"> + <Grid + gap="sm" + px="lg" + py="lg" + templateColumns={{ + base: '1fr', + lg: '1fr', + xl: '1.25fr 1fr 1fr 1fr', + }} + w="full" + > + <GridItem alignItems="center" display="flex"> + <StsByTheNumbersSvg /> + </GridItem> + <GridItem bg="rgba(0, 0, 0, 0.2)" borderRadius="lg"> + <GlobalStatsCard + isLoading={isStakedSonicDataLoading} + label="APR" + value={fNum('apr', stakingApr)} + /> + </GridItem> + <GridItem bg="rgba(0, 0, 0, 0.2)" borderRadius="lg"> + <GlobalStatsCard + isLoading={isStakedSonicDataLoading} + label="TVL" + value={toCurrency(usdValueForToken(lstToken, stakedSonic))} + /> + </GridItem> + <GridItem bg="rgba(0, 0, 0, 0.2)" borderRadius="lg"> + <GlobalStatsCard + isLoading={isStakedSonicDataLoading} + label="Total $S" + value={fNum('token', stakedSonic)} + /> + </GridItem> + </Grid> + </Box> + </NoisyCard> + </Card> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/components/LstTokenRow.tsx b/apps/beets-frontend-v3/lib/modules/lst/components/LstTokenRow.tsx new file mode 100644 index 000000000..8565190d3 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/components/LstTokenRow.tsx @@ -0,0 +1,35 @@ +import { VStack, HStack, Text } from '@chakra-ui/react' +import TokenRow from '@repo/lib/modules/tokens/TokenRow/TokenRow' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' +import { Address } from 'viem' + +export function LstTokenRow({ + label, + chain, + tokenAmount, + tokenAddress, + isLoading, +}: { + label: string + chain: GqlChain + tokenAmount: string + tokenAddress: string + isLoading: boolean +}) { + return ( + <VStack align="start" spacing="md"> + <HStack justify="space-between" w="full"> + <Text color="font.primary" variant="primaryGradient"> + {label} + </Text> + </HStack> + <TokenRow + abbreviated={false} + address={tokenAddress as Address} + chain={chain} + isLoading={isLoading} + value={tokenAmount} + /> + </VStack> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/components/LstUnstake.tsx b/apps/beets-frontend-v3/lib/modules/lst/components/LstUnstake.tsx new file mode 100644 index 000000000..4b5afffbb --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/components/LstUnstake.tsx @@ -0,0 +1,15 @@ +import { useLst } from '../LstProvider' +import { TokenInput } from '@repo/lib/modules/tokens/TokenInput/TokenInput' + +export function LstUnstake() { + const { amountShares, setAmountShares, chain, stakedAsset } = useLst() + + return ( + <TokenInput + address={stakedAsset?.address || ''} + chain={chain} + onChange={e => setAmountShares(e.currentTarget.value)} + value={amountShares} + /> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/components/LstUnstakeSummary.tsx b/apps/beets-frontend-v3/lib/modules/lst/components/LstUnstakeSummary.tsx new file mode 100644 index 000000000..125445526 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/components/LstUnstakeSummary.tsx @@ -0,0 +1,56 @@ +import { Card } from '@chakra-ui/react' +import { AnimateHeightChange } from '@repo/lib/shared/components/animations/AnimateHeightChange' +import { useBreakpoints } from '@repo/lib/shared/hooks/useBreakpoints' +import { MobileStepTracker } from '@repo/lib/modules/transactions/transaction-steps/step-tracker/MobileStepTracker' +import { useLst } from '../LstProvider' +import { LstTokenRow } from './LstTokenRow' +import { useGetConvertToAssets } from '../hooks/useGetConvertToAssets' +import { formatUnits, parseUnits } from 'viem' +import { BalAlert } from '@repo/lib/shared/components/alerts/BalAlert' +import { BalAlertContent } from '@repo/lib/shared/components/alerts/BalAlertContent' + +export function LstUnstakeSummary() { + const { isMobile } = useBreakpoints() + + const { chain, stakeTransactionSteps, lstUnstakeTxHash, nativeAsset, stakedAsset, amountShares } = + useLst() + + const { assetsAmount, isLoading } = useGetConvertToAssets(parseUnits(amountShares, 18), chain) + + const shouldShowReceipt = !!lstUnstakeTxHash + + return ( + <AnimateHeightChange spacing="sm" w="full"> + {isMobile && <MobileStepTracker chain={chain} transactionSteps={stakeTransactionSteps} />} + <Card variant="modalSubSection"> + <LstTokenRow + chain={chain} + isLoading={isLoading} + label={shouldShowReceipt ? 'You unstaked' : 'You unstake'} + tokenAddress={stakedAsset?.address || ''} + tokenAmount={amountShares} + /> + </Card> + <Card variant="modalSubSection"> + <LstTokenRow + chain={chain} + isLoading={isLoading} + label="You will receive (estimated)" + tokenAddress={nativeAsset?.address || ''} + tokenAmount={formatUnits(assetsAmount, 18)} + /> + </Card> + <BalAlert + content={ + <BalAlertContent + // eslint-disable-next-line max-len + description="After initiating the unstake, you will need to return to the UI after 14 days to claim $S on the Withdraw tab" + forceColumnMode + title="Please note" + /> + } + status="info" + /> + </AnimateHeightChange> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/components/LstWithdraw.tsx b/apps/beets-frontend-v3/lib/modules/lst/components/LstWithdraw.tsx new file mode 100644 index 000000000..96a838b25 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/components/LstWithdraw.tsx @@ -0,0 +1,72 @@ +import { useLst } from '../LstProvider' +import { PaginatedTable } from '@repo/lib/shared/components/tables/PaginatedTable' +import { LstWithdrawTableRow } from './LstWithdrawTableRow' +import { LstWithdrawTableHeader } from './LstWithdrawTableHeader' +import { orderBy } from 'lodash' +import { getPaginationProps } from '@repo/lib/shared/components/pagination/getPaginationProps' +import { useEffect } from 'react' +import { useState } from 'react' +import { LstWithdrawModal } from '../modals/LstWithdrawModal' +import { useDisclosure } from '@chakra-ui/react' +import { UserWithdraw } from '../hooks/useGetUserWithdraws' + +export function LstWithdraw({ + withdrawalsData, + isLoading, +}: { + withdrawalsData: UserWithdraw[] + isLoading: boolean +}) { + const { stakedAsset, pagination, setPagination, first, skip, chain } = useLst() + const { isOpen, onOpen, onClose } = useDisclosure() + + const withdrawalsDataOrdered = orderBy(withdrawalsData, 'requestTimestamp', 'desc') + const count = withdrawalsDataOrdered.length + const paginationProps = getPaginationProps(count || 0, pagination, setPagination, false, true) + const showPagination = !!count && count > pagination.pageSize + + const [withdrawalsView, setWithdrawalsView] = useState(withdrawalsDataOrdered.slice(skip, first)) + + useEffect(() => { + if (withdrawalsDataOrdered.length < first) { + setWithdrawalsView(withdrawalsDataOrdered.slice(skip)) + } else { + setWithdrawalsView(withdrawalsDataOrdered.slice(skip, first + skip)) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [skip, withdrawalsData]) + + const rowProps = { + px: { base: 'sm', sm: '0' }, + gridTemplateColumns: '100px 1fr 100px', + alignItems: 'center', + gap: { base: 'xxs', xl: 'lg' }, + } + + return ( + <> + <PaginatedTable + alignItems="flex-start" + getRowId={(withdrawal: UserWithdraw) => + `${withdrawal.requestTimestamp}-${withdrawal.validatorId}` + } + items={withdrawalsView} + loading={isLoading} + noItemsFoundLabel="No requests found" + paginationProps={{ ...paginationProps, mt: 'auto' }} + renderTableHeader={() => <LstWithdrawTableHeader {...rowProps} />} + renderTableRow={(withdrawal: any, index) => ( + <LstWithdrawTableRow + keyValue={index} + withdrawal={withdrawal} + {...rowProps} + onOpen={onOpen} + token={stakedAsset} + /> + )} + showPagination={showPagination} + /> + <LstWithdrawModal chain={chain} isOpen={isOpen} onClose={onClose} /> + </> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/components/LstWithdrawSummary.tsx b/apps/beets-frontend-v3/lib/modules/lst/components/LstWithdrawSummary.tsx new file mode 100644 index 000000000..51ab0c0e5 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/components/LstWithdrawSummary.tsx @@ -0,0 +1,36 @@ +import { Card } from '@chakra-ui/react' +import { AnimateHeightChange } from '@repo/lib/shared/components/animations/AnimateHeightChange' +import { useBreakpoints } from '@repo/lib/shared/hooks/useBreakpoints' +import { MobileStepTracker } from '@repo/lib/modules/transactions/transaction-steps/step-tracker/MobileStepTracker' +import { useLst } from '../LstProvider' +import { LstWithdrawReceiptResult } from '@repo/lib/modules/transactions/transaction-steps/receipts/receipt.hooks' +import { LstTokenRow } from './LstTokenRow' +import { formatUnits } from 'viem' + +export function LstWithdrawSummary({ + isLoading: isLoadingReceipt, + receivedToken, +}: LstWithdrawReceiptResult) { + const { isMobile } = useBreakpoints() + const { chain, withdrawTransactionSteps, lstWithdrawTxHash, nativeAsset, amountWithdraw } = + useLst() + + const shouldShowReceipt = !!lstWithdrawTxHash && !isLoadingReceipt && !!receivedToken + const isLoading = isLoadingReceipt + + return ( + <AnimateHeightChange spacing="sm" w="full"> + {isMobile && <MobileStepTracker chain={chain} transactionSteps={withdrawTransactionSteps} />} + <Card variant="modalSubSection"> + <LstTokenRow + chain={chain} + isLoading={isLoading} + label={shouldShowReceipt ? 'You withdrew' : 'You withdraw'} + tokenAddress={nativeAsset?.address || ''} + tokenAmount={formatUnits(amountWithdraw, nativeAsset?.decimals || 18).toString()} + /> + {/* TODO: add received amount */} + </Card> + </AnimateHeightChange> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/components/LstWithdrawTableHeader.tsx b/apps/beets-frontend-v3/lib/modules/lst/components/LstWithdrawTableHeader.tsx new file mode 100644 index 000000000..0ce3e32d3 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/components/LstWithdrawTableHeader.tsx @@ -0,0 +1,19 @@ +'use client' + +import { Grid, GridItem, Text } from '@chakra-ui/react' + +export function LstWithdrawTableHeader({ ...rest }) { + return ( + <Grid {...rest} borderBottom="1px solid" borderColor="border.base" p={['sm', 'md']} w="full"> + <GridItem> + <Text fontWeight="bold">Amount</Text> + </GridItem> + <GridItem justifySelf="start"> + <Text fontWeight="bold" textAlign="left"> + Withdrawable after + </Text> + </GridItem> + <GridItem /> {/* intentionally empty */} + </Grid> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/components/LstWithdrawTableRow.tsx b/apps/beets-frontend-v3/lib/modules/lst/components/LstWithdrawTableRow.tsx new file mode 100644 index 000000000..a4f0463ec --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/components/LstWithdrawTableRow.tsx @@ -0,0 +1,74 @@ +import { Box, Button, Grid, GridItem, GridProps, HStack, Text } from '@chakra-ui/react' +import FadeInOnView from '@repo/lib/shared/components/containers/FadeInOnView' +import { format } from 'date-fns' +import { useLst } from '../LstProvider' +import { TokenIcon } from '@repo/lib/modules/tokens/TokenIcon' +import { UserWithdraw } from '../hooks/useGetUserWithdraws' +import { formatUnits } from 'viem' +import { ApiToken } from '@repo/lib/modules/pool/pool.types' +import { fNum } from '@repo/lib/shared/utils/numbers' + +interface Props extends GridProps { + withdrawal: UserWithdraw + keyValue: number + token: ApiToken | undefined + onOpen(): void +} + +export function LstWithdrawTableRow({ withdrawal, keyValue, token, onOpen, ...rest }: Props) { + const { withdrawDelay, setWithdrawId, setAmountWithdraw } = useLst() + + const requestTimestamp = Number(withdrawal.requestTimestamp) + withdrawDelay + const now = new Date().getTime() / 1000 + + function onHandleClick() { + setWithdrawId(withdrawal.id) + setAmountWithdraw(withdrawal.assetAmount) + onOpen() + } + + return ( + <FadeInOnView> + <Box + _hover={{ + bg: 'background.level0', + }} + key={keyValue} + px={{ base: '0', sm: 'md' }} + rounded="md" + transition="all 0.2s ease-in-out" + w="full" + > + <Grid {...rest} pr="4" py={{ base: 'ms', md: 'md' }}> + <GridItem> + <HStack gap={['xs', 'sm']}> + {token && ( + <TokenIcon + address={token.address} + alt={token.symbol} + chain={token.chain} + size={24} + /> + )} + <Text>{fNum('token', formatUnits(withdrawal.assetAmount, 18))}</Text> + </HStack> + </GridItem> + <GridItem>{format(new Date(requestTimestamp * 1000), 'dd MMMM yyyy HH:mm')}</GridItem> + <GridItem> + {/* <Tooltip label={isDisabled ? disabledReason : ''}> */} + <Button + isDisabled={withdrawal.isWithdrawn || now < requestTimestamp} + onClick={onHandleClick} + size="xxs" + variant="primary" + w="full" + > + {withdrawal.isWithdrawn ? 'Withdrawn' : 'Withdraw'} + </Button> + {/* </Tooltip> */} + </GridItem> + </Grid> + </Box> + </FadeInOnView> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/components/StsByTheNumbersSvg.tsx b/apps/beets-frontend-v3/lib/modules/lst/components/StsByTheNumbersSvg.tsx new file mode 100644 index 000000000..be0fa905c --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/components/StsByTheNumbersSvg.tsx @@ -0,0 +1,122 @@ +import React from 'react' + +/* eslint-disable max-len */ +export function StsByTheNumbersSvg() { + return ( + <svg + fill="none" + height="48" + viewBox="0 0 283 48" + width="283" + xmlns="http://www.w3.org/2000/svg" + > + <path + d="M79.1596 34.2503V23.6803H76.5996V20.9303H79.1596V16.7803H82.4496V20.9303H85.0396V23.6803H82.4496V34.2503H79.1596Z" + fill="white" + /> + <path + d="M67.7396 29.8802C67.7696 31.0402 68.6296 31.7702 70.1396 31.7702C71.6496 31.7702 72.5096 31.1502 72.5096 30.1802C72.5096 29.5102 72.1596 29.0202 70.9696 28.7502L68.5696 28.1802C66.1696 27.6402 65.0096 26.5102 65.0096 24.3802C65.0096 21.7602 67.2196 20.2002 70.2896 20.2002C73.3596 20.2002 75.2996 21.9302 75.3296 24.5102H72.1996C72.1696 23.3802 71.4196 22.6502 70.1496 22.6502C68.8796 22.6502 68.0996 23.2402 68.0996 24.2402C68.0996 24.9902 68.6896 25.4802 69.8296 25.7502L72.2296 26.3202C74.4696 26.8302 75.5996 27.8602 75.5996 29.9102C75.5996 32.6102 73.3096 34.2802 70.0196 34.2802C66.7296 34.2802 64.5996 32.5002 64.5996 29.8902H67.7296L67.7396 29.8802Z" + fill="white" + /> + <path + d="M107.61 34.2502V14.2002H110.9V22.8802C111.76 21.4002 113.54 20.5102 115.56 20.5102C119.36 20.5102 121.68 23.4802 121.68 27.6802C121.68 31.8802 119.17 34.6102 115.34 34.6102C113.34 34.6102 111.65 33.7202 110.86 32.1802L110.64 34.2602H107.59L107.61 34.2502ZM114.68 31.5902C117 31.5902 118.37 29.9202 118.37 27.5502C118.37 25.1802 116.99 23.4802 114.68 23.4802C112.37 23.4802 110.93 25.1502 110.93 27.5502C110.93 29.9502 112.41 31.5902 114.68 31.5902Z" + fill="#05D690" + /> + <path + d="M121.28 37.6807H123.25C124.54 37.6807 125.35 37.3807 125.92 35.8207L126.3 34.8207L120.93 20.9307H124.41L127.83 30.6407L131.44 20.9307H134.84L128.31 37.2207C127.31 39.7007 125.91 40.7207 123.73 40.7207C122.81 40.7207 122 40.6107 121.28 40.4207V37.6707V37.6807Z" + fill="#05D690" + /> + <path + d="M142.529 34.2503V23.6803H139.969V20.9303H142.529V16.7803H145.819V20.9303H148.409V23.6803H145.819V34.2503H142.529Z" + fill="#05D690" + /> + <path + d="M149.11 34.2502V14.2002H152.43V22.6702C153.27 21.3802 154.83 20.5402 156.74 20.5402C160.03 20.5402 161.75 22.6202 161.75 26.0702V34.2702H158.46V26.8602C158.46 24.6202 157.35 23.5402 155.68 23.5402C153.6 23.5402 152.39 25.0002 152.39 26.9902V34.2702H149.1L149.11 34.2502Z" + fill="#05D690" + /> + <path + d="M162.859 27.6C162.859 23.42 165.579 20.54 169.489 20.54C173.399 20.54 176.019 23.21 176.019 27.36V28.36L165.989 28.39C166.229 30.74 167.469 31.92 169.659 31.92C171.469 31.92 172.649 31.22 173.029 29.95H176.079C175.509 32.86 173.089 34.61 169.609 34.61C165.649 34.61 162.869 31.72 162.869 27.6H162.859ZM166.069 26.27H172.759C172.759 24.44 171.489 23.22 169.519 23.22C167.549 23.22 166.389 24.27 166.069 26.27Z" + fill="#05D690" + /> + <path + d="M183.25 34.2503V20.9303H186.3L186.57 22.6603C187.41 21.3103 189.02 20.5303 190.83 20.5303C194.17 20.5303 195.9 22.6103 195.9 26.0603V34.2603H192.61V26.8503C192.61 24.6103 191.5 23.5303 189.81 23.5303C187.79 23.5303 186.55 24.9303 186.55 27.0903V34.2603H183.26L183.25 34.2503Z" + fill="#05D690" + /> + <path + d="M210.099 20.9404V34.2604H207.049L206.809 32.4804C205.999 33.7504 204.279 34.6104 202.499 34.6104C199.429 34.6104 197.619 32.5304 197.619 29.2704V20.9404H200.909V28.1104C200.909 30.6404 201.909 31.6704 203.739 31.6704C205.819 31.6704 206.809 30.4604 206.809 27.9204V20.9404H210.099Z" + fill="#05D690" + /> + <path + d="M212.148 34.2505V20.9305H215.168L215.438 22.4905C216.108 21.3805 217.458 20.5205 219.378 20.5205C221.398 20.5205 222.798 21.5205 223.508 23.0505C224.178 21.5105 225.748 20.5205 227.768 20.5205C231.008 20.5205 232.778 22.4605 232.778 25.5305V34.2405H229.518V26.3905C229.518 24.4805 228.498 23.4805 226.928 23.4805C225.358 23.4805 224.128 24.5005 224.128 26.6905V34.2405H220.838V26.3705C220.838 24.5105 219.838 23.5105 218.278 23.5105C216.718 23.5105 215.448 24.5305 215.448 26.6905V34.2405H212.158L212.148 34.2505Z" + fill="#05D690" + /> + <path + d="M234.668 34.2502V14.2002H237.958V22.8802C238.818 21.4002 240.598 20.5102 242.618 20.5102C246.418 20.5102 248.738 23.4802 248.738 27.6802C248.738 31.8802 246.228 34.6102 242.398 34.6102C240.398 34.6102 238.708 33.7202 237.918 32.1802L237.698 34.2602H234.648L234.668 34.2502ZM241.728 31.5902C244.048 31.5902 245.418 29.9202 245.418 27.5502C245.418 25.1802 244.038 23.4802 241.728 23.4802C239.418 23.4802 237.978 25.1502 237.978 27.5502C237.978 29.9502 239.458 31.5902 241.728 31.5902Z" + fill="#05D690" + /> + <path + d="M249.229 27.6C249.229 23.42 251.948 20.54 255.858 20.54C259.768 20.54 262.379 23.21 262.379 27.36V28.36L252.349 28.39C252.589 30.74 253.828 31.92 256.018 31.92C257.828 31.92 259.008 31.22 259.388 29.95H262.439C261.869 32.86 259.449 34.61 255.969 34.61C252.009 34.61 249.229 31.72 249.229 27.6ZM252.439 26.27H259.129C259.129 24.44 257.858 23.22 255.888 23.22C253.918 23.22 252.759 24.27 252.439 26.27Z" + fill="#05D690" + /> + <path + d="M272.04 23.9302H270.83C268.46 23.9302 266.97 25.2002 266.97 27.7902V34.2602H263.68V20.9702H266.78L266.97 22.9102C267.54 21.5902 268.8 20.7002 270.58 20.7002C271.04 20.7002 271.5 20.7502 272.04 20.8902V23.9402V23.9302Z" + fill="#05D690" + /> + <path + d="M275.038 30.2103C275.068 31.3703 275.928 32.1003 277.438 32.1003C278.948 32.1003 279.808 31.4803 279.808 30.5103C279.808 29.8403 279.458 29.3503 278.268 29.0803L275.868 28.5103C273.468 27.9703 272.308 26.8403 272.308 24.7103C272.308 22.0903 274.518 20.5303 277.588 20.5303C280.658 20.5303 282.598 22.2603 282.628 24.8403H279.498C279.468 23.7103 278.718 22.9803 277.448 22.9803C276.178 22.9803 275.398 23.5703 275.398 24.5703C275.398 25.3203 275.988 25.8103 277.128 26.0803L279.528 26.6503C281.768 27.1603 282.898 28.1903 282.898 30.2403C282.898 32.9403 280.608 34.6103 277.318 34.6103C274.028 34.6103 271.898 32.8303 271.898 30.2203H275.028L275.038 30.2103Z" + fill="#05D690" + /> + <path + d="M86.9203 20.298C86.9203 16.97 89.6763 14.656 93.6803 14.656C97.5283 14.656 99.9723 16.788 100.076 20.22H96.7483C96.6703 18.582 95.5003 17.62 93.6283 17.62C91.5743 17.62 90.2483 18.608 90.2483 20.194C90.2483 21.546 90.9763 22.3 92.5623 22.664L95.5523 23.314C98.8023 24.016 100.388 25.68 100.388 28.514C100.388 32.05 97.6323 34.338 93.4463 34.338C89.3903 34.338 86.7383 32.18 86.6603 28.774H89.9883C90.0143 30.386 91.3143 31.348 93.4463 31.348C95.6563 31.348 97.0603 30.386 97.0603 28.8C97.0603 27.526 96.4103 26.772 94.8503 26.434L91.8343 25.758C88.6103 25.056 86.9203 23.21 86.9203 20.298Z" + fill="white" + /> + <g clipPath="url(#clip0_28844_102)"> + <path + d="M23.8 47.6C36.9444 47.6 47.6 36.9444 47.6 23.8C47.6 10.6556 36.9444 0 23.8 0C10.6556 0 0 10.6556 0 23.8C0 36.9444 10.6556 47.6 23.8 47.6Z" + fill="#1A1A1A" + /> + <path + d="M30.9281 23.7995L41.4125 34.2839C39.6655 37.2094 37.2103 39.6646 34.2848 41.4125L23.8005 30.9281L13.3151 41.4125C10.3906 39.6655 7.93442 37.2094 6.1875 34.2848L16.6719 23.7995L6.1875 13.3151C7.93537 10.3896 10.3906 7.93442 13.3161 6.1875L23.8005 16.6719L34.2839 6.1875C37.2094 7.93442 39.6655 10.3906 41.4125 13.3161L30.9281 23.7995Z" + fill="url(#paint0_radial_28844_102)" + opacity="0.5" + /> + <path + d="M36.6383 23.8004C36.6383 24.3354 36.6059 24.8637 36.5412 25.3816C29.5354 26.882 23.713 30.2997 18.9749 35.7004C18.337 35.4433 17.7249 35.1349 17.1432 34.7807C19.6232 31.8114 22.5458 29.3696 25.8007 27.3056C21.8175 28.529 18.0552 30.1531 14.8851 33.0395C14.4081 32.5807 13.9683 32.0847 13.5666 31.5554C17.3593 28.1872 21.8623 26.3022 26.5842 24.8123H11C10.9743 24.4782 10.9609 24.1402 10.9609 23.7994C10.9609 23.4586 10.9752 23.1111 11.0009 22.7722H26.6537C21.9213 21.2957 17.3888 19.4221 13.5732 16.0359C13.9826 15.498 14.4319 14.9934 14.9184 14.5288C18.1362 17.4648 21.9775 19.0889 26.0111 20.3608C22.6772 18.3197 19.6908 15.8759 17.1347 12.8238C17.7192 12.4678 18.3351 12.1584 18.9758 11.8994C23.7139 17.3001 29.5364 20.7178 36.5421 22.2181C36.6059 22.736 36.6392 23.2634 36.6392 23.7994L36.6383 23.8004Z" + fill="white" + /> + <path + d="M16.8147 37.9138L13.3161 41.4124C10.3915 39.6655 7.93537 37.2083 6.1875 34.2857L9.6861 30.7871C11.2169 33.8735 13.7283 36.3849 16.8147 37.9138Z" + fill="#FF0000" + /> + <path + d="M13.317 6.18845L16.8147 9.68705C13.7283 11.216 11.2169 13.7283 9.6861 16.8137L6.1875 13.3161C7.93632 10.3896 10.3915 7.93537 13.317 6.1875V6.18845Z" + fill="#FF0000" + /> + <path + d="M30.7871 9.68708L34.2848 6.18848C37.2093 7.93635 39.6664 10.3925 41.4133 13.318L37.9147 16.8157C36.3858 13.7293 33.8735 11.2179 30.7881 9.68708H30.7871Z" + fill="#FF0000" + /> + <path + d="M37.9138 30.7861L41.4124 34.2847C39.6655 37.2093 37.2103 39.6654 34.2857 41.4133L30.7871 37.9147C33.8735 36.3839 36.3849 33.8725 37.9138 30.7861Z" + fill="#FF0000" + /> + </g> + <defs> + <radialGradient + cx="0" + cy="0" + gradientTransform="translate(23.8005 23.8005) scale(17.612)" + gradientUnits="userSpaceOnUse" + id="paint0_radial_28844_102" + r="1" + > + <stop stopColor="#1A1A1A" /> + <stop offset="0.81" stopColor="#FF0000" /> + </radialGradient> + <clipPath id="clip0_28844_102"> + <rect fill="white" height="47.6" width="47.6" /> + </clipPath> + </defs> + </svg> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetAmountDelegatedPerValidator.tsx b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetAmountDelegatedPerValidator.tsx new file mode 100644 index 000000000..37f2d2bb1 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetAmountDelegatedPerValidator.tsx @@ -0,0 +1,96 @@ +'use client' + +import { getChainId, getNetworkConfig } from '@repo/lib/config/app.config' +import { useMulticall } from '@repo/lib/modules/web3/contracts/useMulticall' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { GqlChain, GqlStakedSonicData } from '@repo/lib/shared/services/api/generated/graphql' +import { useGetRate } from './useGetRate' +import { useGetStakedSonicData } from './useGetStakedSonicData' +import { useMemo } from 'react' +import { sfcAbi } from '@repo/lib/modules/web3/contracts/abi/beets/generated' +import { zeroAddress } from 'viem' + +type Result = { + [key: string]: { + result: bigint + status: string + } +} + +type Validator = GqlStakedSonicData['delegatedValidators'][0] + +export function useGetAmountDelegatedPerValidator(chain: GqlChain) { + const { isConnected } = useUserAccount() + const { rate } = useGetRate(chain) + const { data, loading } = useGetStakedSonicData() + + const chainId = getChainId(chain) + const config = getNetworkConfig(chainId) + + const validatorIds: string[] = useMemo(() => { + if (!loading && data) { + return data.stsGetGqlStakedSonicData.delegatedValidators.map((v: Validator) => v.validatorId) + } + + return [] + }, [data, loading]) + + const getStakeRequests = validatorIds.map(validatorId => { + return { + chainId, + id: validatorId, + abi: sfcAbi, + address: config.contracts.beets?.sfcProxy || zeroAddress, + functionName: 'getStake', + args: [config.contracts.beets?.lstStakingProxy, validatorId], + enabled: isConnected, + } + }) + + const { + results: stakeRequests, + refetchAll, + isLoading, + } = useMulticall(getStakeRequests, { + enabled: isConnected, + }) + + const amountResults = useMemo(() => { + const results = stakeRequests[chainId] + if (results?.isSuccess) { + return results?.data as Result + } + + return {} + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [stakeRequests, isLoading]) + + const amountDelegatedPerValidator = validatorIds.map(validatorId => ({ + validatorId, + amountDelegated: amountResults[validatorId]?.result ?? 0n, + })) + + function chooseValidatorsForUnstakeAmount(unstakeAmountShares: bigint) { + const unstakeAmountAssets = (unstakeAmountShares * rate) / 10n ** 18n + + const validator = amountDelegatedPerValidator.find( + validator => validator.amountDelegated > unstakeAmountAssets + ) + + // TODO: we should split the unstake amount across several validators down the line + return [ + { + validatorId: validator?.validatorId || '1', + unstakeAmountShares, + }, + ] + } + + return { + amountDelegatedPerValidator, + stakeRequests, + refetchAll, + isLoading, + chooseValidatorsForUnstakeAmount, + } +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetConvertToAssets.tsx b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetConvertToAssets.tsx new file mode 100644 index 000000000..70a4dfb60 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetConvertToAssets.tsx @@ -0,0 +1,30 @@ +'use client' + +import { getChainId, getNetworkConfig } from '@repo/lib/config/app.config' +import { useChainSwitch } from '@repo/lib/modules/web3/useChainSwitch' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { useReadContract } from 'wagmi' +import { sonicStakingAbi } from '@repo/lib/modules/web3/contracts/abi/beets/generated' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' + +export function useGetConvertToAssets(sharesAmount: bigint, chain: GqlChain) { + const { isConnected } = useUserAccount() + const chainId = getChainId(chain) + + const { shouldChangeNetwork } = useChainSwitch(chainId) + const config = getNetworkConfig(chainId) + + const query = useReadContract({ + chainId, + abi: sonicStakingAbi, + address: config.contracts.beets?.lstStakingProxy, + functionName: 'convertToAssets', + args: [sharesAmount], + query: { enabled: isConnected && !shouldChangeNetwork && !!sharesAmount }, + }) + + return { + ...query, + assetsAmount: query.data ?? 0n, + } +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetConvertToShares.tsx b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetConvertToShares.tsx new file mode 100644 index 000000000..f2616694c --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetConvertToShares.tsx @@ -0,0 +1,30 @@ +'use client' + +import { getChainId, getNetworkConfig } from '@repo/lib/config/app.config' +import { useChainSwitch } from '@repo/lib/modules/web3/useChainSwitch' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { useReadContract } from 'wagmi' +import { sonicStakingAbi } from '@repo/lib/modules/web3/contracts/abi/beets/generated' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' + +export function useGetConvertToShares(assetAmount: bigint, chain: GqlChain) { + const { isConnected } = useUserAccount() + const chainId = getChainId(chain) + + const { shouldChangeNetwork } = useChainSwitch(chainId) + const config = getNetworkConfig(chainId) + + const query = useReadContract({ + chainId, + abi: sonicStakingAbi, + address: config.contracts.beets?.lstStakingProxy, + functionName: 'convertToShares', + args: [assetAmount], + query: { enabled: isConnected && !shouldChangeNetwork && !!assetAmount }, + }) + + return { + ...query, + sharesAmount: query.data ?? 0n, + } +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetRate.tsx b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetRate.tsx new file mode 100644 index 000000000..6c67b6dd3 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetRate.tsx @@ -0,0 +1,25 @@ +'use client' + +import { getChainId, getNetworkConfig } from '@repo/lib/config/app.config' +import { sonicStakingAbi } from '@repo/lib/modules/web3/contracts/abi/beets/generated' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' +import { useReadContract } from 'wagmi' + +export function useGetRate(chain: GqlChain) { + const chainId = getChainId(chain) + const config = getNetworkConfig(chainId) + + const query = useReadContract({ + chainId, + abi: sonicStakingAbi, + address: config.contracts.beets?.lstStakingProxy, + functionName: 'getRate', + args: [], + query: { enabled: true }, + }) + + return { + ...query, + rate: query.data ?? 10n ** 18n, + } +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetStakedSonicData.tsx b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetStakedSonicData.tsx new file mode 100644 index 000000000..d4bbd3248 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetStakedSonicData.tsx @@ -0,0 +1,9 @@ +import { GetStakedSonicDataDocument } from '@repo/lib/shared/services/api/generated/graphql' +import { useQuery } from '@apollo/client' +import minutesToMilliseconds from 'date-fns/minutesToMilliseconds' + +export function useGetStakedSonicData() { + return useQuery(GetStakedSonicDataDocument, { + pollInterval: minutesToMilliseconds(5), + }) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetUserNumWithdraws.tsx b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetUserNumWithdraws.tsx new file mode 100644 index 000000000..48196cbc6 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetUserNumWithdraws.tsx @@ -0,0 +1,30 @@ +'use client' + +import { getChainId, getNetworkConfig } from '@repo/lib/config/app.config' +import { useChainSwitch } from '@repo/lib/modules/web3/useChainSwitch' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { useReadContract } from 'wagmi' +import { sonicStakingAbi } from '@repo/lib/modules/web3/contracts/abi/beets/generated' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' + +export function useGetUserNumWithdraws(chain: GqlChain) { + const { isConnected, userAddress } = useUserAccount() + const chainId = getChainId(chain) + + const { shouldChangeNetwork } = useChainSwitch(chainId) + const config = getNetworkConfig(chainId) + + const query = useReadContract({ + chainId, + abi: sonicStakingAbi, + address: config.contracts.beets?.lstStakingProxy, + functionName: 'userNumWithdraws', + args: [userAddress], + query: { enabled: isConnected && !shouldChangeNetwork && !!userAddress }, + }) + + return { + ...query, + userNumWithdraws: query.data, + } +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetUserWithdraws.tsx b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetUserWithdraws.tsx new file mode 100644 index 000000000..542cf0689 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/hooks/useGetUserWithdraws.tsx @@ -0,0 +1,40 @@ +'use client' + +import { getChainId, getNetworkConfig } from '@repo/lib/config/app.config' +import { useChainSwitch } from '@repo/lib/modules/web3/useChainSwitch' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { useReadContract } from 'wagmi' +import { sonicStakingWithdrawRequestHelperAbi } from '@repo/lib/modules/web3/contracts/abi/beets/generated' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' + +export type UserWithdraw = { + id: bigint + assetAmount: bigint + isWithdrawn: boolean + kind: number // 0 = POOL + requestTimestamp: bigint + user: string + validatorId: bigint +} + +export function useGetUserWithdraws(chain: GqlChain, userNumWithdraws: bigint | undefined) { + const { isConnected, userAddress } = useUserAccount() + const chainId = getChainId(chain) + + const { shouldChangeNetwork } = useChainSwitch(chainId) + const config = getNetworkConfig(chainId) + + const query = useReadContract({ + chainId, + abi: sonicStakingWithdrawRequestHelperAbi, + address: config.contracts.beets?.lstWithdrawRequestHelper, + functionName: 'getUserWithdraws', + args: [userAddress, 0n, userNumWithdraws || 0n, false], + query: { enabled: isConnected && !shouldChangeNetwork && !!userAddress && !!userNumWithdraws }, + }) + + return { + ...query, + userWithdraws: (query.data as UserWithdraw[]) ?? [], + } +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/hooks/useLstStakeStep.tsx b/apps/beets-frontend-v3/lib/modules/lst/hooks/useLstStakeStep.tsx new file mode 100644 index 000000000..88ab976b3 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/hooks/useLstStakeStep.tsx @@ -0,0 +1,71 @@ +'use client' + +import { getChainId } from '@repo/lib/config/app.config' +import networkConfigs from '@repo/lib/config/networks' +import { ManagedTransactionButton } from '@repo/lib/modules/transactions/transaction-steps/TransactionButton' +import { useTransactionState } from '@repo/lib/modules/transactions/transaction-steps/TransactionStateProvider' +import { + TransactionLabels, + TransactionStep, +} from '@repo/lib/modules/transactions/transaction-steps/lib' +import { sentryMetaForWagmiSimulation } from '@repo/lib/shared/utils/query-errors' +import { useMemo } from 'react' +import { ManagedTransactionInput } from '@repo/lib/modules/web3/contracts/useManagedTransaction' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { parseUnits } from 'viem' +import { BPT_DECIMALS } from '@repo/lib/modules/pool/pool.constants' +import { noop } from 'lodash' +import { bn } from '@repo/lib/shared/utils/numbers' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' +import { useTokenBalances } from '@repo/lib/modules/tokens/TokenBalancesProvider' + +export function useLstStakeStep(humanAmount: string, chain: GqlChain, enabled: boolean) { + const { getTransaction } = useTransactionState() + const { isConnected } = useUserAccount() + const { refetchBalances } = useTokenBalances() + + const labels: TransactionLabels = { + init: 'Stake', + title: 'Stake', + confirming: 'Confirming stake...', + confirmed: 'Staked!', + tooltip: 'tooltip', + } + + const txSimulationMeta = sentryMetaForWagmiSimulation( + 'Error in wagmi tx simulation (LST staking transaction)', + {} + ) + + const props: ManagedTransactionInput = { + labels, + chainId: getChainId(chain), + contractId: 'beets.lstStaking', + contractAddress: networkConfigs[chain].contracts.beets?.lstStakingProxy || '', + functionName: 'deposit', + args: [], + value: parseUnits(humanAmount, BPT_DECIMALS), + enabled: bn(humanAmount).gte(0.01) && isConnected && enabled, + txSimulationMeta, + } + + const transaction = getTransaction('stakeLst') + + const isComplete = () => isConnected && !!transaction?.result.isSuccess + + const step = useMemo( + (): TransactionStep => ({ + id: 'stakeLst', + labels, + stepType: 'stakeLst', + isComplete, + onActivated: noop, + onDeactivated: noop, + onSuccess: () => refetchBalances(), + renderAction: () => <ManagedTransactionButton id="stakeLst" {...props} />, + }), + // eslint-disable-next-line react-hooks/exhaustive-deps + [transaction] + ) + return { step } +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/hooks/useLstUnstakeStep.tsx b/apps/beets-frontend-v3/lib/modules/lst/hooks/useLstUnstakeStep.tsx new file mode 100644 index 000000000..849d97c2d --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/hooks/useLstUnstakeStep.tsx @@ -0,0 +1,85 @@ +'use client' + +import { getChainId } from '@repo/lib/config/app.config' +import networkConfigs from '@repo/lib/config/networks' +import { ManagedTransactionButton } from '@repo/lib/modules/transactions/transaction-steps/TransactionButton' +import { useTransactionState } from '@repo/lib/modules/transactions/transaction-steps/TransactionStateProvider' +import { + TransactionLabels, + TransactionStep, +} from '@repo/lib/modules/transactions/transaction-steps/lib' +import { sentryMetaForWagmiSimulation } from '@repo/lib/shared/utils/query-errors' +import { useMemo } from 'react' +import { ManagedTransactionInput } from '@repo/lib/modules/web3/contracts/useManagedTransaction' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { parseUnits } from 'viem' +import { noop } from 'lodash' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' +import { useTokenBalances } from '@repo/lib/modules/tokens/TokenBalancesProvider' +import { useGetUserWithdraws } from './useGetUserWithdraws' +import { useGetUserNumWithdraws } from './useGetUserNumWithdraws' +import { useGetAmountDelegatedPerValidator } from './useGetAmountDelegatedPerValidator' + +export function useLstUnstakeStep(sharesAmount: string, chain: GqlChain, enabled: boolean) { + const { getTransaction } = useTransactionState() + const { isConnected } = useUserAccount() + const { refetchBalances } = useTokenBalances() + const { userNumWithdraws, refetch: refetchUserNumWithdraws } = useGetUserNumWithdraws(chain) + const { refetch: refetchWithdrawals } = useGetUserWithdraws(chain, userNumWithdraws) + const { chooseValidatorsForUnstakeAmount } = useGetAmountDelegatedPerValidator(chain) + const validators = chooseValidatorsForUnstakeAmount(parseUnits(sharesAmount, 18)) + + function onSuccess() { + refetchBalances() + refetchUserNumWithdraws() + refetchWithdrawals() + } + + const labels: TransactionLabels = { + init: 'Unstake', + title: 'Unstake', + confirming: 'Confirming unstake...', + confirmed: 'Unstaked!', + tooltip: 'tooltip', + } + + const txSimulationMeta = sentryMetaForWagmiSimulation( + 'Error in wagmi tx simulation (LST unstaking transaction)', + {} + ) + + const props: ManagedTransactionInput = { + labels, + chainId: getChainId(chain), + contractId: 'beets.lstStaking', + contractAddress: networkConfigs[chain].contracts.beets?.lstStakingProxy || '', + functionName: 'undelegateMany', + //args: [[BigInt(1)], [parseUnits(sharesAmount, 18)]], // TODO: make dynamic + args: [ + validators.map(validator => BigInt(validator.validatorId)), + validators.map(validator => validator.unstakeAmountShares), + ], + enabled: isConnected && !!sharesAmount && enabled, + txSimulationMeta, + } + + const transaction = getTransaction('unstakeLst') + + const isComplete = () => isConnected && !!transaction?.result.isSuccess + + const step = useMemo( + (): TransactionStep => ({ + id: 'unstakeLst', + labels, + stepType: 'unstakeLst', + isComplete, + onActivated: noop, + onDeactivated: noop, + onSuccess, + renderAction: () => <ManagedTransactionButton id="unstakeLst" {...props} />, + }), + // eslint-disable-next-line react-hooks/exhaustive-deps + [transaction] + ) + return { step } +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/hooks/useLstWithdrawStep.tsx b/apps/beets-frontend-v3/lib/modules/lst/hooks/useLstWithdrawStep.tsx new file mode 100644 index 000000000..dbaea1b63 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/hooks/useLstWithdrawStep.tsx @@ -0,0 +1,81 @@ +'use client' + +import { getChainId } from '@repo/lib/config/app.config' +import networkConfigs from '@repo/lib/config/networks' +import { ManagedTransactionButton } from '@repo/lib/modules/transactions/transaction-steps/TransactionButton' +import { useTransactionState } from '@repo/lib/modules/transactions/transaction-steps/TransactionStateProvider' +import { + TransactionLabels, + TransactionStep, +} from '@repo/lib/modules/transactions/transaction-steps/lib' +import { sentryMetaForWagmiSimulation } from '@repo/lib/shared/utils/query-errors' +import { useMemo } from 'react' +import { ManagedTransactionInput } from '@repo/lib/modules/web3/contracts/useManagedTransaction' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { noop } from 'lodash' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' +import { useTokenBalances } from '@repo/lib/modules/tokens/TokenBalancesProvider' +import { useGetUserNumWithdraws } from './useGetUserNumWithdraws' +import { useGetUserWithdraws } from './useGetUserWithdraws' + +export function useLstWithdrawStep( + chain: GqlChain, + enabled: boolean, + withdrawId: bigint | undefined +) { + const { getTransaction } = useTransactionState() + const { isConnected } = useUserAccount() + const { refetchBalances } = useTokenBalances() + const { userNumWithdraws, refetch: refetchUserNumWithdraws } = useGetUserNumWithdraws(chain) + const { refetch: refetchWithdrawals } = useGetUserWithdraws(chain, userNumWithdraws) + + const labels: TransactionLabels = { + init: 'Withdraw', + title: 'Withdraw', + confirming: 'Confirming withdraw...', + confirmed: 'Withdrawn!', + tooltip: 'tooltip', + } + + const txSimulationMeta = sentryMetaForWagmiSimulation( + 'Error in wagmi tx simulation (LST withdrawing transaction)', + {} + ) + + const props: ManagedTransactionInput = { + labels, + chainId: getChainId(chain), + contractId: 'beets.lstStaking', + contractAddress: networkConfigs[chain].contracts.beets?.lstStakingProxy || '', + functionName: 'withdraw', + args: [withdrawId || 0n, false], + enabled: isConnected && enabled && !!withdrawId, + txSimulationMeta, + } + + const transaction = getTransaction('withdrawLst') + + const isComplete = () => isConnected && !!transaction?.result.isSuccess + + function onSuccess() { + refetchBalances() + refetchUserNumWithdraws() + refetchWithdrawals() + } + + const step = useMemo( + (): TransactionStep => ({ + id: 'withdrawLst', + labels, + stepType: 'withdrawLst', + isComplete, + onActivated: noop, + onDeactivated: noop, + onSuccess, + renderAction: () => <ManagedTransactionButton id="withdrawLst" {...props} />, + }), + // eslint-disable-next-line react-hooks/exhaustive-deps + [transaction] + ) + return { step } +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/modals/LstStakeModal.tsx b/apps/beets-frontend-v3/lib/modules/lst/modals/LstStakeModal.tsx new file mode 100644 index 000000000..3f3adcaad --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/modals/LstStakeModal.tsx @@ -0,0 +1,85 @@ +/* eslint-disable max-len */ +/* eslint-disable react-hooks/exhaustive-deps */ +'use client' + +import { Modal, ModalBody, ModalCloseButton, ModalContent, ModalProps } from '@chakra-ui/react' +import { RefObject, useEffect, useRef } from 'react' +import { DesktopStepTracker } from '@repo/lib/modules/transactions/transaction-steps/step-tracker/DesktopStepTracker' +import { useBreakpoints } from '@repo/lib/shared/hooks/useBreakpoints' +import { ActionModalFooter } from '@repo/lib/shared/components/modals/ActionModalFooter' +import { TransactionModalHeader } from '@repo/lib/shared/components/modals/TransactionModalHeader' +import { getStylesForModalContentWithStepTracker } from '@repo/lib/modules/transactions/transaction-steps/step-tracker/step-tracker.utils' +import { SuccessOverlay } from '@repo/lib/shared/components/modals/SuccessOverlay' +import { useResetStepIndexOnOpen } from '@repo/lib/modules/pool/actions/useResetStepIndexOnOpen' +import { useOnUserAccountChanged } from '@repo/lib/modules/web3/useOnUserAccountChanged' +import { useLstStakeReceipt } from '@repo/lib/modules/transactions/transaction-steps/receipts/receipt.hooks' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { useTokens } from '@repo/lib/modules/tokens/TokensProvider' +import { useLst } from '../LstProvider' +import { LstStakeSummary } from '../components/LstStakeSummary' + +type Props = { + isOpen: boolean + onClose(): void + onOpen(): void + finalFocusRef?: RefObject<HTMLInputElement> +} + +export function LstStakeModal({ + isOpen, + onClose, + finalFocusRef, + ...rest +}: Props & Omit<ModalProps, 'children'>) { + const { isDesktop } = useBreakpoints() + const initialFocusRef = useRef(null) + const { userAddress } = useUserAccount() + const { stopTokenPricePolling } = useTokens() + const { stakeTransactionSteps, chain, lstStakeTxHash } = useLst() + + useResetStepIndexOnOpen(isOpen, stakeTransactionSteps) + + const lstStakeReceipt = useLstStakeReceipt({ + txHash: lstStakeTxHash, + userAddress, + chain, + protocolVersion: 2, // TODO: make this optional + }) + + useEffect(() => { + if (isOpen) { + // stop polling for token prices when modal is opened to prevent unwanted re-renders + stopTokenPricePolling() + } + }, [isOpen]) + + useOnUserAccountChanged(onClose) + + return ( + <Modal + finalFocusRef={finalFocusRef} + initialFocusRef={initialFocusRef} + isCentered + isOpen={isOpen} + onClose={onClose} + preserveScrollBarGap + {...rest} + > + <SuccessOverlay startAnimation={!!lstStakeTxHash} /> + <ModalContent {...getStylesForModalContentWithStepTracker(isDesktop)}> + {isDesktop && <DesktopStepTracker chain={chain} transactionSteps={stakeTransactionSteps} />} + <TransactionModalHeader chain={chain} isReceiptLoading label="Review stake" txHash="0x" /> + <ModalCloseButton /> + <ModalBody> + <LstStakeSummary {...lstStakeReceipt} /> + </ModalBody> + <ActionModalFooter + currentStep={stakeTransactionSteps.currentStep} + isSuccess={!!lstStakeTxHash && !lstStakeReceipt.isLoading} + returnAction={onClose} + returnLabel="Stake again" + /> + </ModalContent> + </Modal> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/modals/LstUnstakeModal.tsx b/apps/beets-frontend-v3/lib/modules/lst/modals/LstUnstakeModal.tsx new file mode 100644 index 000000000..561b9dbd9 --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/modals/LstUnstakeModal.tsx @@ -0,0 +1,77 @@ +/* eslint-disable max-len */ +/* eslint-disable react-hooks/exhaustive-deps */ +'use client' + +import { Modal, ModalBody, ModalCloseButton, ModalContent, ModalProps } from '@chakra-ui/react' +import { RefObject, useEffect, useRef } from 'react' +import { DesktopStepTracker } from '@repo/lib/modules/transactions/transaction-steps/step-tracker/DesktopStepTracker' +import { useBreakpoints } from '@repo/lib/shared/hooks/useBreakpoints' +import { ActionModalFooter } from '@repo/lib/shared/components/modals/ActionModalFooter' +import { TransactionModalHeader } from '@repo/lib/shared/components/modals/TransactionModalHeader' +import { getStylesForModalContentWithStepTracker } from '@repo/lib/modules/transactions/transaction-steps/step-tracker/step-tracker.utils' +import { SuccessOverlay } from '@repo/lib/shared/components/modals/SuccessOverlay' +import { useResetStepIndexOnOpen } from '@repo/lib/modules/pool/actions/useResetStepIndexOnOpen' +import { useOnUserAccountChanged } from '@repo/lib/modules/web3/useOnUserAccountChanged' +import { useTokens } from '@repo/lib/modules/tokens/TokensProvider' +import { useLst } from '../LstProvider' +import { LstUnstakeSummary } from '../components/LstUnstakeSummary' + +type Props = { + isOpen: boolean + onClose(): void + onOpen(): void + finalFocusRef?: RefObject<HTMLInputElement> +} + +export function LstUnstakeModal({ + isOpen, + onClose, + finalFocusRef, + ...rest +}: Props & Omit<ModalProps, 'children'>) { + const { isDesktop } = useBreakpoints() + const initialFocusRef = useRef(null) + const { stopTokenPricePolling } = useTokens() + const { unstakeTransactionSteps, chain, lstUnstakeTxHash } = useLst() + + useResetStepIndexOnOpen(isOpen, unstakeTransactionSteps) + + useEffect(() => { + if (isOpen) { + // stop polling for token prices when modal is opened to prevent unwanted re-renders + stopTokenPricePolling() + } + }, [isOpen]) + + useOnUserAccountChanged(onClose) + + return ( + <Modal + finalFocusRef={finalFocusRef} + initialFocusRef={initialFocusRef} + isCentered + isOpen={isOpen} + onClose={onClose} + preserveScrollBarGap + {...rest} + > + <SuccessOverlay startAnimation={!!lstUnstakeTxHash} /> + <ModalContent {...getStylesForModalContentWithStepTracker(isDesktop)}> + {isDesktop && ( + <DesktopStepTracker chain={chain} transactionSteps={unstakeTransactionSteps} /> + )} + <TransactionModalHeader chain={chain} isReceiptLoading label="Review unstake" txHash="0x" /> + <ModalCloseButton /> + <ModalBody> + <LstUnstakeSummary /> + </ModalBody> + <ActionModalFooter + currentStep={unstakeTransactionSteps.currentStep} + isSuccess={!!lstUnstakeTxHash} + returnAction={onClose} + returnLabel="Unstake again" + /> + </ModalContent> + </Modal> + ) +} diff --git a/apps/beets-frontend-v3/lib/modules/lst/modals/LstWithdrawModal.tsx b/apps/beets-frontend-v3/lib/modules/lst/modals/LstWithdrawModal.tsx new file mode 100644 index 000000000..725cd919c --- /dev/null +++ b/apps/beets-frontend-v3/lib/modules/lst/modals/LstWithdrawModal.tsx @@ -0,0 +1,70 @@ +'use client' + +import { Modal, ModalBody, ModalCloseButton, ModalContent, ModalProps } from '@chakra-ui/react' +import { useBreakpoints } from '@repo/lib/shared/hooks/useBreakpoints' +// eslint-disable-next-line max-len +import { getStylesForModalContentWithStepTracker } from '@repo/lib/modules/transactions/transaction-steps/step-tracker/step-tracker.utils' +import { DesktopStepTracker } from '@repo/lib/modules/transactions/transaction-steps/step-tracker/DesktopStepTracker' +import { TransactionModalHeader } from '@repo/lib/shared/components/modals/TransactionModalHeader' +import { ActionModalFooter } from '@repo/lib/shared/components/modals/ActionModalFooter' +import { SuccessOverlay } from '@repo/lib/shared/components/modals/SuccessOverlay' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' +import { useLst } from '../LstProvider' +import { LstWithdrawSummary } from '../components/LstWithdrawSummary' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { useLstWithdrawReceipt } from '@repo/lib/modules/transactions/transaction-steps/receipts/receipt.hooks' +import { useResetStepIndexOnOpen } from '@repo/lib/modules/pool/actions/useResetStepIndexOnOpen' + +type Props = { + isOpen: boolean + onClose(): void + chain: GqlChain +} + +export function LstWithdrawModal({ + isOpen, + onClose, + chain, + ...rest +}: Props & Omit<ModalProps, 'children' | 'onClose'>) { + const { isDesktop } = useBreakpoints() + const { userAddress } = useUserAccount() + const { withdrawTransactionSteps, lstWithdrawTxHash, setWithdrawId } = useLst() + + const lstWithdrawReceipt = useLstWithdrawReceipt({ + txHash: lstWithdrawTxHash, + userAddress, + chain, + protocolVersion: 2, // TODO: make this optional + }) + + useResetStepIndexOnOpen(isOpen, withdrawTransactionSteps) + + function handleOnClose() { + withdrawTransactionSteps.resetTransactionSteps() + setWithdrawId(0n) + onClose() + } + + return ( + <Modal isCentered isOpen={isOpen} onClose={handleOnClose} preserveScrollBarGap {...rest}> + <SuccessOverlay startAnimation={!!lstWithdrawTxHash} /> + <ModalContent {...getStylesForModalContentWithStepTracker(isDesktop)}> + {isDesktop && ( + <DesktopStepTracker chain={chain} transactionSteps={withdrawTransactionSteps} /> + )} + <TransactionModalHeader chain={chain} label="Withdraw" txHash={lstWithdrawTxHash} /> + <ModalCloseButton /> + <ModalBody> + <LstWithdrawSummary {...lstWithdrawReceipt} /> + </ModalBody> + <ActionModalFooter + currentStep={withdrawTransactionSteps.currentStep} + isSuccess={!!lstWithdrawTxHash} + returnAction={handleOnClose} + returnLabel="Return to withdraw" + /> + </ModalContent> + </Modal> + ) +} diff --git a/apps/beets-frontend-v3/lib/services/chakra/themes/beets/beets.theme.ts b/apps/beets-frontend-v3/lib/services/chakra/themes/beets/beets.theme.ts index a9aafef24..c9bc1c8a1 100644 --- a/apps/beets-frontend-v3/lib/services/chakra/themes/beets/beets.theme.ts +++ b/apps/beets-frontend-v3/lib/services/chakra/themes/beets/beets.theme.ts @@ -1,19 +1,32 @@ import { ThemeTypings, extendTheme } from '@chakra-ui/react' import { colors, primaryTextColor } from './colors' -import { getTokens } from '@repo/lib/shared/services/chakra/themes/base/tokens' import { getComponents } from '@repo/lib/shared/services/chakra/themes/base/components' import { config, fonts, styles } from '@repo/lib/shared/services/chakra/themes/base/foundations' import { getSemanticTokens } from '@repo/lib/shared/services/chakra/themes/base/semantic-tokens' import { proseTheme } from '@repo/lib/shared/services/chakra/themes/base/prose' +import { getBeetsTokens } from './tokens' -const tokens = getTokens(colors, primaryTextColor) +const tokens = getBeetsTokens(colors, primaryTextColor) const components = getComponents(tokens, primaryTextColor) const semanticTokens = getSemanticTokens(tokens, colors) +semanticTokens.colors.font.dark = '#111111' +semanticTokens.colors.font.light = '#FFFFFF' +semanticTokens.colors.grayText._dark = '#BBBBBB' + +components.Button.variants.buttonGroupActive._dark.color = '#363636' + export const beetsTheme = { config, fonts, - styles, + styles: { + global: { + ...styles.global, + body: { + background: 'linear-gradient(90deg, #111111 0%, #333333 100%)', + }, + }, + }, colors, semanticTokens, components, diff --git a/apps/beets-frontend-v3/lib/services/chakra/themes/beets/colors.ts b/apps/beets-frontend-v3/lib/services/chakra/themes/beets/colors.ts index eaf82d175..d1b847c72 100644 --- a/apps/beets-frontend-v3/lib/services/chakra/themes/beets/colors.ts +++ b/apps/beets-frontend-v3/lib/services/chakra/themes/beets/colors.ts @@ -4,10 +4,10 @@ import { colors as baseColors } from '@repo/lib/shared/services/chakra/themes/ba export const colors = { ...baseColors, base: { - light: 'background.level1', - hslLight: '44,22%,90%', - dark: 'blue', - hslDark: '216,12%,25%', + light: '#E6F9C4', + hslLight: '103, 49%, 71%', + dark: '#363636', + hslDark: '0, 0%, 17%', }, } diff --git a/apps/beets-frontend-v3/lib/services/chakra/themes/beets/tokens.ts b/apps/beets-frontend-v3/lib/services/chakra/themes/beets/tokens.ts new file mode 100644 index 000000000..62d622d5d --- /dev/null +++ b/apps/beets-frontend-v3/lib/services/chakra/themes/beets/tokens.ts @@ -0,0 +1,95 @@ +import tinycolor from 'tinycolor2' +import { getTokens } from '@repo/lib/shared/services/chakra/themes/base/tokens' + +export function getBeetsTokens(colors: any, primaryTextColor: any) { + const baseTokens = getTokens(colors, primaryTextColor) + + return { + ...baseTokens, + colors: { + ...baseTokens.colors, + light: { + ...baseTokens.colors.light, + background: { + ...baseTokens.colors.light.background, + level0: '#DDF7B5', + level1: '#E6F9C4', + level2: '#F5FDE8', + level3: '#F9FEF1', + level4: '#FFFFFF', + base: '#E6F9C4', + baseWithOpacity: 'hsla(83, 81%, 87%, 0.75)', + special: colors.gradient.dawnLight, + level0WithOpacity: 'rgba(213, 245, 163, 0.96)', + }, + + border: { + ...baseTokens.colors.light.border, + base: '#F9FEF1', + divider: '#D4F7A1', + subduedZen: 'hsla(88, 63%, 59%, 0.2)', + }, + button: { + ...baseTokens.colors.light.button, + background: { + primary: 'linear-gradient(90deg, #BCEC79 0%, #81C91C 100%)', + secondary: '#BCEC79', + }, + }, + text: { + ...baseTokens.colors.light.text, + primary: '#194D05', + secondary: '#827474', + link: '#408A13', + linkHover: colors.gray['900'], + special: 'linear-gradient(90deg, #194D05 0%, #30940A 100%)', + }, + input: { + ...baseTokens.colors.light.input, + fontDefault: '#194D05', + fontPlaceholder: tinycolor(colors.gray['900']).setAlpha(0.5), + borderDefault: '#FDFFFA', + borderHover: colors.gray['700'], + borderFocus: colors.gray['500'], + }, + }, + dark: { + ...baseTokens.colors.dark, + background: { + ...baseTokens.colors.dark.background, + level0: '#363636', + level1: '#3d3d3d', + level2: '#454545', + level3: '#4c4c4c', + level4: '#545454', + level0WithOpacity: 'rgba(30, 30, 30, 0.96)', + }, + border: { + ...baseTokens.colors.dark.border, + divider: '#040E01', + subduedZen: 'hsla(83, 81%, 80%, 0.03)', + }, + button: { + ...baseTokens.colors.dark.button, + background: { + primary: 'linear-gradient(90deg, #91E2C1 0%, #05D690 100%)', + secondary: '#05D690', + }, + }, + text: { + ...baseTokens.colors.dark.text, + primary: '#FFFFFF', + secondary: '#DDDDDD', + link: '#91e2c1', + linkHover: '#91e2c1', + special: 'linear-gradient(90deg, #78EABC 0%, #18B575 100%)', + highlight: '#05D690', + }, + input: { + ...baseTokens.colors.dark.input, + borderHover: '#91e2c1', + }, + }, + }, + } +} diff --git a/apps/beets-frontend-v3/next.config.js b/apps/beets-frontend-v3/next.config.js index 52eb6ebeb..704fea9b8 100644 --- a/apps/beets-frontend-v3/next.config.js +++ b/apps/beets-frontend-v3/next.config.js @@ -25,6 +25,15 @@ const nextConfig = { // Safe App setup headers: manifestHeaders, + redirects() { + return [ + { + source: '/discord', + destination: 'https://discord.gg/kbPnYJjvwZ', + permanent: false, + }, + ] + }, } module.exports = withSentryConfig(nextConfig, sentryOptions) diff --git a/apps/beets-frontend-v3/package.json b/apps/beets-frontend-v3/package.json index 3783b628f..c214949bd 100644 --- a/apps/beets-frontend-v3/package.json +++ b/apps/beets-frontend-v3/package.json @@ -18,6 +18,8 @@ "postinstall": "npm run gen:theme-typings" }, "dependencies": { + "@apollo/client": "^3.11.8", + "@balancer/sdk": "1.0.2", "@chakra-ui/hooks": "^2.2.1", "@chakra-ui/react": "^2.8.2", "@chakra-ui/theme-tools": "^2.1.2", @@ -25,7 +27,8 @@ "@repo/lib": "workspace:*", "@sentry/nextjs": "^8.13.0", "@studio-freight/react-lenis": "^0.0.47", - "@vercel/speed-insights": "1.1.0", + "@tanstack/react-query": "^5.56.2", + "@vercel/speed-insights": "^1.0.1", "framer-motion": "^10.13.0", "lodash": "^4.17.21", "next": "14.2.15", @@ -33,9 +36,11 @@ "nextjs-toploader": "^1.6.4", "react": "18.2.0", "react-dom": "18.2.0", + "react-feather": "^2.0.10", "react-use-measure": "^2.1.1", + "tinycolor2": "^1.6.0", "viem": "2.21.55", - "wagmi": "^2.12.16" + "wagmi": "2.13.3" }, "devDependencies": { "@chakra-ui/cli": "^2.4.1", @@ -49,6 +54,7 @@ "@types/node": "20.10.2", "@types/react": "18.2.34", "@types/react-dom": "18.2.6", + "@types/tinycolor2": "^1.4.6", "@typescript-eslint/eslint-plugin": "^5.60.1", "@typescript-eslint/parser": "^5.60.1", "@wagmi/cli": "2.1.22", diff --git a/apps/beets-frontend-v3/public/favicon-dark.png b/apps/beets-frontend-v3/public/favicon-dark.png deleted file mode 100644 index 8087d2680..000000000 Binary files a/apps/beets-frontend-v3/public/favicon-dark.png and /dev/null differ diff --git a/apps/beets-frontend-v3/public/favicon-light.png b/apps/beets-frontend-v3/public/favicon-light.png deleted file mode 100644 index 9d84fcd2a..000000000 Binary files a/apps/beets-frontend-v3/public/favicon-light.png and /dev/null differ diff --git a/apps/beets-frontend-v3/public/favicon.ico b/apps/beets-frontend-v3/public/favicon.ico index 722e240e8..e02f1eb52 100644 Binary files a/apps/beets-frontend-v3/public/favicon.ico and b/apps/beets-frontend-v3/public/favicon.ico differ diff --git a/apps/beets-frontend-v3/public/images/chains/SONIC.svg b/apps/beets-frontend-v3/public/images/chains/SONIC.svg new file mode 100644 index 000000000..904f8550d --- /dev/null +++ b/apps/beets-frontend-v3/public/images/chains/SONIC.svg @@ -0,0 +1,15 @@ +<svg width="150" height="150" viewBox="0 0 150 150" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g clip-path="url(#clip0_16090_6561)"> +<path d="M90.1978 93.2521C62.1058 101.688 38.8678 113.994 24.3178 128.412L23.6758 129.054C27.5458 132.714 31.7878 135.99 36.3718 138.774L37.3558 137.568C41.3278 132.714 45.5878 128.028 50.0218 123.612C61.9258 111.75 75.5458 101.484 90.2098 93.2401L90.1918 93.2521H90.1978Z" fill="white"/> +<path d="M0.710938 80.7542C1.83294 95.7962 7.41894 109.59 16.185 120.81L16.587 120.408C25.5929 111.522 37.3169 103.446 51.4589 96.4081C63.8549 90.2341 78.0869 84.9362 93.4289 80.7542H0.710938Z" fill="white"/> +<path d="M57.8832 18.9301C83.0172 43.9741 114.649 60.5341 149.347 66.8161C145.159 29.6881 113.557 0.804077 75.1632 0.804077C65.0232 0.804077 55.3573 2.82608 46.5312 6.47408C50.1133 10.7881 53.9412 14.9881 57.8832 18.9301Z" fill="white"/> +<path d="M24.3196 21.9961C38.8696 36.4321 62.1076 48.7201 90.1996 57.1741C75.5356 48.9181 61.9156 38.6641 50.0116 26.8021C45.5896 22.3981 41.3356 17.7121 37.3456 12.8461L36.3616 11.6401C31.7776 14.4241 27.5356 17.6941 23.6836 21.3541L24.3256 21.9961H24.3196Z" fill="white"/> +<path d="M57.8832 131.478C53.9232 135.42 50.1012 139.62 46.5312 143.934C55.3453 147.582 65.0232 149.604 75.1632 149.604C113.563 149.604 145.165 120.72 149.359 83.5801C114.667 89.8621 83.0352 106.422 57.8952 131.466L57.8832 131.478Z" fill="white"/> +<path d="M51.4589 54.0001C37.3169 46.9621 25.5929 38.8801 16.587 30.0001L16.185 29.5981C7.41894 40.8181 1.83294 54.6121 0.710938 69.6541H93.4109C78.0749 65.472 63.8549 60.174 51.4409 53.982L51.4529 54.0001H51.4589Z" fill="white"/> +</g> +<defs> +<clipPath id="clip0_16090_6561"> +<rect width="150" height="150" fill="white"/> +</clipPath> +</defs> +</svg> diff --git a/apps/beets-frontend-v3/public/images/icons/beets-icon-light.png b/apps/beets-frontend-v3/public/images/icons/beets-icon-light.png new file mode 100644 index 000000000..11c6b82e0 Binary files /dev/null and b/apps/beets-frontend-v3/public/images/icons/beets-icon-light.png differ diff --git a/apps/beets-frontend-v3/public/images/icons/beets-icon-light.svg b/apps/beets-frontend-v3/public/images/icons/beets-icon-light.svg new file mode 100644 index 000000000..98bd5b320 --- /dev/null +++ b/apps/beets-frontend-v3/public/images/icons/beets-icon-light.svg @@ -0,0 +1,15 @@ +<svg width="500" height="500" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g clip-path="url(#clip0_27522_46)"> +<path d="M250 500C388.071 500 500 388.071 500 250C500 111.929 388.071 0 250 0C111.929 0 0 111.929 0 250C0 388.071 111.929 500 250 500Z" fill="white"/> +<path d="M250 115C180.96 115 125 170.96 125 240V365H375V240C375 170.96 319.04 115 250 115Z" fill="#1A1A1A"/> +<path d="M296.869 342.19C314.128 342.19 328.119 328.199 328.119 310.94C328.119 293.681 314.128 279.69 296.869 279.69C279.61 279.69 265.619 293.681 265.619 310.94C265.619 328.199 279.61 342.19 296.869 342.19Z" fill="white"/> +<path d="M203.119 342.19C220.378 342.19 234.369 328.199 234.369 310.94C234.369 293.681 220.378 279.69 203.119 279.69C185.86 279.69 171.869 293.681 171.869 310.94C171.869 328.199 185.86 342.19 203.119 342.19Z" fill="white"/> +<path d="M296.876 320.71C302.269 320.71 306.641 316.338 306.641 310.945C306.641 305.552 302.269 301.18 296.876 301.18C291.483 301.18 287.111 305.552 287.111 310.945C287.111 316.338 291.483 320.71 296.876 320.71Z" fill="#05D690"/> +<path d="M203.126 320.71C208.519 320.71 212.891 316.338 212.891 310.945C212.891 305.552 208.519 301.18 203.126 301.18C197.733 301.18 193.361 305.552 193.361 310.945C193.361 316.338 197.733 320.71 203.126 320.71Z" fill="#FF0000"/> +</g> +<defs> +<clipPath id="clip0_27522_46"> +<rect width="500" height="500" fill="white"/> +</clipPath> +</defs> +</svg> diff --git a/apps/beets-frontend-v3/public/images/icons/sonic-logo.png b/apps/beets-frontend-v3/public/images/icons/sonic-logo.png new file mode 100644 index 000000000..b0f6d6069 Binary files /dev/null and b/apps/beets-frontend-v3/public/images/icons/sonic-logo.png differ diff --git a/apps/beets-frontend-v3/public/images/misc/bal-v3.png b/apps/beets-frontend-v3/public/images/misc/bal-v3.png new file mode 100644 index 000000000..b381c18b8 Binary files /dev/null and b/apps/beets-frontend-v3/public/images/misc/bal-v3.png differ diff --git a/apps/beets-frontend-v3/public/images/misc/banner1.png b/apps/beets-frontend-v3/public/images/misc/banner1.png new file mode 100644 index 000000000..055efedd4 Binary files /dev/null and b/apps/beets-frontend-v3/public/images/misc/banner1.png differ diff --git a/apps/beets-frontend-v3/public/images/misc/beets-social-club.png b/apps/beets-frontend-v3/public/images/misc/beets-social-club.png new file mode 100644 index 000000000..11b2d979c Binary files /dev/null and b/apps/beets-frontend-v3/public/images/misc/beets-social-club.png differ diff --git a/apps/beets-frontend-v3/public/images/misc/pattern-sml-7@2x.webp b/apps/beets-frontend-v3/public/images/misc/pattern-sml-7@2x.webp new file mode 100644 index 000000000..dd92ef650 Binary files /dev/null and b/apps/beets-frontend-v3/public/images/misc/pattern-sml-7@2x.webp differ diff --git a/apps/beets-frontend-v3/public/images/misc/pools-banner.png b/apps/beets-frontend-v3/public/images/misc/pools-banner.png new file mode 100644 index 000000000..236f5086a Binary files /dev/null and b/apps/beets-frontend-v3/public/images/misc/pools-banner.png differ diff --git a/apps/beets-frontend-v3/public/images/misc/staking-bg.png b/apps/beets-frontend-v3/public/images/misc/staking-bg.png new file mode 100644 index 000000000..25edf7224 Binary files /dev/null and b/apps/beets-frontend-v3/public/images/misc/staking-bg.png differ diff --git a/apps/beets-frontend-v3/tsconfig.json b/apps/beets-frontend-v3/tsconfig.json index d17c2f937..30a137a84 100644 --- a/apps/beets-frontend-v3/tsconfig.json +++ b/apps/beets-frontend-v3/tsconfig.json @@ -12,12 +12,12 @@ "@/*": ["./*"], "@repo/*": ["../../packages/*"] }, - "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" + "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json", + "jsx": "preserve" }, "include": [ "**/*.ts", "**/*.tsx", - "global.d.ts", "next-env.d.ts", ".next/types/**/*.ts", "../../packages/lib/global.d.ts" diff --git a/apps/beets-frontend-v3/wagmi.config.ts b/apps/beets-frontend-v3/wagmi.config.ts index 1743b1d9f..cdd062a87 100644 --- a/apps/beets-frontend-v3/wagmi.config.ts +++ b/apps/beets-frontend-v3/wagmi.config.ts @@ -1,7 +1,7 @@ import { defineConfig, loadEnv } from '@wagmi/cli' import { etherscan } from '@wagmi/cli/plugins' import mainnetNetworkConfig from '@repo/lib/config/networks/mainnet' - +import sonicNetworkConfig from '@repo/lib/config/networks/sonic' import { erc20Abi } from 'viem' const CONTRACTS: Array<{ name: string; abi: any }> = [ @@ -18,7 +18,7 @@ export default defineConfig(() => { }) return { - out: 'lib/modules/web3/contracts/abi/generated.ts', + out: '../../packages/lib/modules/web3/contracts/abi/beets/generated.ts', contracts: CONTRACTS, plugins: [ etherscan({ @@ -74,6 +74,24 @@ export default defineConfig(() => { }, ], }), + etherscan({ + apiKey: env.SONICSCAN_API_KEY, + chainId: 146, + contracts: [ + { + name: 'SonicStaking', + address: sonicNetworkConfig.contracts.beets?.lstStaking, + }, + { + name: 'SFC', + address: sonicNetworkConfig.contracts.beets?.sfc, + }, + { + name: 'SonicStakingWithdrawRequestHelper', + address: sonicNetworkConfig.contracts.beets?.lstWithdrawRequestHelper, + }, + ], + }), ], } }) diff --git a/apps/frontend-v3/app/api/rpc/[chain]/route.ts b/apps/frontend-v3/app/api/rpc/[chain]/route.ts index b7be2b2d7..f6dadffd6 100644 --- a/apps/frontend-v3/app/api/rpc/[chain]/route.ts +++ b/apps/frontend-v3/app/api/rpc/[chain]/route.ts @@ -25,7 +25,7 @@ const chainToRpcMap: Record<GqlChain, string | undefined> = { [GqlChain.Gnosis]: dRpcUrl('gnosis'), [GqlChain.Mode]: dRpcUrl('mode'), [GqlChain.Zkevm]: dRpcUrl('polygon-zkevm'), - [GqlChain.Sonic]: '', //TODO: groninge will fix it in another PR + [GqlChain.Sonic]: dRpcUrl('sonic'), } function getRpcUrl(chain: string) { diff --git a/apps/frontend-v3/lib/components/navs/NavBarContainer.tsx b/apps/frontend-v3/lib/components/navs/NavBarContainer.tsx index 1c3af9133..33a2584b0 100644 --- a/apps/frontend-v3/lib/components/navs/NavBarContainer.tsx +++ b/apps/frontend-v3/lib/components/navs/NavBarContainer.tsx @@ -7,6 +7,9 @@ import { NavLogo } from './NavLogo' import { MobileNav } from '@repo/lib/shared/components/navs/MobileNav' import { useNav } from '@repo/lib/shared/components/navs/useNav' import { BalancerLogoType } from '../imgs/BalancerLogoType' +import { VeBalLink } from '@repo/lib/modules/vebal/VebalRedirectModal' +import { Box } from '@chakra-ui/react' +import { fadeIn } from '@repo/lib/shared/utils/animations' export function NavBarContainer() { const { appLinks, ecosystemLinks, getSocialLinks } = useNavData() @@ -22,10 +25,16 @@ export function NavBarContainer() { > <NavBar appLinks={allAppLinks} + customLinks={ + <Box as={motion.div} variants={fadeIn}> + <VeBalLink /> + </Box> + } mobileNav={ <MobileNav LogoType={BalancerLogoType} appLinks={allAppLinks} + customLinks={<VeBalLink fontSize="xl" />} ecosystemLinks={ecosystemLinks} socialLinks={getSocialLinks()} /> diff --git a/packages/lib/config/app.config.ts b/packages/lib/config/app.config.ts index 0409be3fb..e4a8a2c01 100644 --- a/packages/lib/config/app.config.ts +++ b/packages/lib/config/app.config.ts @@ -24,10 +24,14 @@ const networksByChainId = keyBy(config.networks, 'chainId') /** * Fetches network config by chainId or network name type from API (GqlChain). If chain - * param is not provided or incorrect, it will return mainnet config. + * param is not provided or incorrect, it will return the defaultNetwork config. */ -export function getNetworkConfig(chain?: GqlChain | number): NetworkConfig { - if (!chain) return config.networks.MAINNET +export function getNetworkConfig( + chain?: GqlChain | number, + defaultNetwork?: GqlChain +): NetworkConfig { + // cannot get default network directly from config here + if (!chain) return config.networks[defaultNetwork || GqlChain.Mainnet] if (typeof chain === 'number') { return networksByChainId[chain] || config.networks.MAINNET diff --git a/packages/lib/config/config.types.ts b/packages/lib/config/config.types.ts index 6d277bc57..24114fa11 100644 --- a/packages/lib/config/config.types.ts +++ b/packages/lib/config/config.types.ts @@ -18,6 +18,12 @@ export interface TokensConfig { symbol: string decimals: number } + stakedAsset?: { + name: string + address: Address + symbol: string + decimals: number + } supportedWrappers?: { baseToken: Address wrappedToken: Address @@ -33,6 +39,7 @@ export interface TokensConfig { export interface ContractsConfig { multicall2: Address + multicall3?: Address balancer: { vaultV2: Address // TODO: make it required when v3 is deployed in all networks @@ -48,6 +55,14 @@ export interface ContractsConfig { minter: Address WeightedPool2TokensFactory?: Address } + beets?: { + lstStaking: Address + lstStakingProxy: Address + // TODO: make it required when fantom is removed + sfcProxy?: Address + sfc?: Address + lstWithdrawRequestHelper?: Address + } feeDistributor?: Address veDelegationProxy?: Address veBAL?: Address diff --git a/packages/lib/config/networks/fantom.ts b/packages/lib/config/networks/fantom.ts index 87f4f9832..98b35e623 100644 --- a/packages/lib/config/networks/fantom.ts +++ b/packages/lib/config/networks/fantom.ts @@ -25,6 +25,12 @@ const networkConfig: NetworkConfig = { symbol: 'FTM', decimals: 18, }, + stakedAsset: { + name: 'sFTMx', + address: '0xd7028092c830b5c8fce061af2e593413ebbc1fc1', + symbol: 'sFTMx', + decimals: 18, + }, defaultSwapTokens: { tokenIn: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', }, @@ -36,6 +42,11 @@ const networkConfig: NetworkConfig = { relayerV6: '0x0faa25293a36241c214f3760c6ff443e1b731981', minter: zeroAddress, }, + beets: { + lstStaking: '0x310A1f7bd9dDE18CCFD701A796Ecb83CcbedE21A', + lstStakingProxy: '0xB458BfC855ab504a8a327720FcEF98886065529b', + sfc: '0xFC00FACE00000000000000000000000000000000', + }, }, pools: convertHexToLowerCase({ issues: {} }), } diff --git a/packages/lib/config/networks/index.ts b/packages/lib/config/networks/index.ts index 8c7430686..8ac7e74e7 100644 --- a/packages/lib/config/networks/index.ts +++ b/packages/lib/config/networks/index.ts @@ -11,6 +11,7 @@ import base from './base' import sepolia from './sepolia' import mode from './mode' import fraxtal from './fraxtal' +import sonic from './sonic' const networkConfigs = { [GqlChain.Arbitrum]: arbitrum, @@ -25,7 +26,7 @@ const networkConfigs = { [GqlChain.Mode]: mode, [GqlChain.Fraxtal]: fraxtal, [GqlChain.Fantom]: fantom, - [GqlChain.Sonic]: fantom, // TODO: groninge will fix it in another PR + [GqlChain.Sonic]: sonic, } export default networkConfigs diff --git a/packages/lib/config/networks/sonic.ts b/packages/lib/config/networks/sonic.ts new file mode 100644 index 000000000..916e450c0 --- /dev/null +++ b/packages/lib/config/networks/sonic.ts @@ -0,0 +1,58 @@ +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' +import { NetworkConfig } from '../config.types' +import { zeroAddress } from 'viem' +import { convertHexToLowerCase } from '@repo/lib/shared/utils/objects' +import { emptyAddress } from '@repo/lib/modules/web3/contracts/wagmi-helpers' + +const networkConfig: NetworkConfig = { + chainId: 146, + name: 'Sonic', + shortName: 'Sonic', + chain: GqlChain.Sonic, + iconPath: '/images/chains/SONIC.svg', + blockExplorer: { + baseUrl: 'https://sonicscan.org', + name: 'SonicScan', + }, + tokens: { + addresses: { + bal: emptyAddress, + wNativeAsset: '0x039e2fb66102314ce7b64ce5ce3e5183bc94ad38', + }, + nativeAsset: { + name: 'Sonic', + address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', + symbol: 'S', + decimals: 18, + }, + stakedAsset: { + name: 'Beets Staked Sonic', + address: '0xe5da20f15420ad15de0fa650600afc998bbe3955', + symbol: 'stS', + decimals: 18, + }, + defaultSwapTokens: { + tokenIn: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', + }, + }, + contracts: { + multicall2: '0xc07500b9fe7bea9efd5b54341d0aa3658a33d39a', + multicall3: '0xcA11bde05977b3631167028862bE2a173976CA11', + balancer: { + vaultV2: '0xba12222222228d8ba445958a75a0704d566bf2c8', + relayerV6: '0x7b52D5ef006E59e3227629f97F182D6442380bb6', + minter: zeroAddress, + }, + veDelegationProxy: zeroAddress, // TODO: fix this dependency for Beets + beets: { + lstStaking: '0xd5f7fc8ba92756a34693baa386edcc8dd5b3f141', + lstStakingProxy: '0xe5da20f15420ad15de0fa650600afc998bbe3955', + sfcProxy: '0xFC00FACE00000000000000000000000000000000', + sfc: '0x0aB8f3b709A52c096f33702fE8153776472305ed', + lstWithdrawRequestHelper: '0x52b16e3d7d25ba64f242e59f9a74799ecc432d78', + }, + }, + pools: convertHexToLowerCase({ issues: {} }), +} + +export default networkConfig diff --git a/packages/lib/config/projects/beets.ts b/packages/lib/config/projects/beets.ts index 489a150cd..2796c7a27 100644 --- a/packages/lib/config/projects/beets.ts +++ b/packages/lib/config/projects/beets.ts @@ -1,16 +1,16 @@ import { ProjectConfig } from '@repo/lib/config/config.types' import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' -export const beetsSupportedNetworks = [GqlChain.Fantom, GqlChain.Optimism] +export const beetsSupportedNetworks = [GqlChain.Optimism, GqlChain.Sonic] // as const satisifies GqlChain[] export const ProjectConfigBeets: ProjectConfig = { projectId: 'beets', projectName: 'Beets', supportedNetworks: beetsSupportedNetworks, - corePoolId: '0x9e4341acef4147196e99d648c5e43b3fc9d026780002000000000000000005ec', // maBEETS BEETS8020 (Fresh BEETS) pool on Fantom - defaultNetwork: GqlChain.Fantom, - ensNetwork: GqlChain.Fantom, + corePoolId: '0x10ac2f9dae6539e77e372adb14b1bf8fbd16b3e8000200000000000000000005', // maBEETS BEETS8020 (Fresh BEETS) pool on Sonic + defaultNetwork: GqlChain.Sonic, + ensNetwork: GqlChain.Sonic, delegateOwner: '0xba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1b', // TODO update this for sonic & optimism, externalLinks: { discordUrl: 'https://beets.fi/discord', diff --git a/packages/lib/config/useNetworkConfig.ts b/packages/lib/config/useNetworkConfig.ts index 5f2e79d86..2c58a257f 100644 --- a/packages/lib/config/useNetworkConfig.ts +++ b/packages/lib/config/useNetworkConfig.ts @@ -2,13 +2,20 @@ import { getNetworkConfig } from '@repo/lib/config/app.config' import { setTag } from '@sentry/nextjs' import { useEffect } from 'react' import { useUserAccount } from '../modules/web3/UserAccountProvider' +import { PROJECT_CONFIG } from './getProjectConfig' export function useNetworkConfig() { + let defaultNetwork + const { chain } = useUserAccount() + if (!chain) { + defaultNetwork = PROJECT_CONFIG.defaultNetwork + } + useEffect(() => { setTag('walletNetwork', chain?.name) }, [chain]) - return getNetworkConfig(chain?.id) + return getNetworkConfig(chain?.id, defaultNetwork) } diff --git a/packages/lib/modules/marketing/useEcosystemPoolActivity.tsx b/packages/lib/modules/marketing/useEcosystemPoolActivity.tsx index dbdf06db4..4657b88a4 100644 --- a/packages/lib/modules/marketing/useEcosystemPoolActivity.tsx +++ b/packages/lib/modules/marketing/useEcosystemPoolActivity.tsx @@ -78,11 +78,6 @@ export const gradientMap: Record<GqlChain, { from: string; to: string }> = { from: '#7D84FF', to: '#5468FF', }, - [GqlChain.Sonic]: { - //TODO: groninge will fix it in another PR - from: '#7D84FF', - to: '#5468FF', - }, [GqlChain.Fraxtal]: { from: '#E0E7FF', to: '#8C9EFF', @@ -95,6 +90,10 @@ export const gradientMap: Record<GqlChain, { from: string; to: string }> = { from: '#D1B3FF', to: '#A384FF', }, + [GqlChain.Sonic]: { + from: '#D1B3FF', + to: '#A384FF', + }, } function getDefaultChainMeta() { @@ -108,10 +107,10 @@ function getDefaultChainMeta() { [GqlChain.Gnosis]: [], [GqlChain.Avalanche]: [], [GqlChain.Fantom]: [], - [GqlChain.Sonic]: [], [GqlChain.Fraxtal]: [], [GqlChain.Mode]: [], [GqlChain.Sepolia]: [], + [GqlChain.Sonic]: [], } } diff --git a/packages/lib/modules/pool/PoolDetail/PoolHeader/PoolBreadcrumbs.tsx b/packages/lib/modules/pool/PoolDetail/PoolHeader/PoolBreadcrumbs.tsx index 1a9a70c80..f0271591b 100644 --- a/packages/lib/modules/pool/PoolDetail/PoolHeader/PoolBreadcrumbs.tsx +++ b/packages/lib/modules/pool/PoolDetail/PoolHeader/PoolBreadcrumbs.tsx @@ -2,6 +2,7 @@ import { Box, Breadcrumb, BreadcrumbItem, BreadcrumbLink, Button } from '@chakra import { usePool } from '../../PoolProvider' import { ChevronRight, Home } from 'react-feather' import { isCowAmmPool } from '../../pool.helpers' +import { isBeetsProject } from '@repo/lib/config/getProjectConfig' export function PoolBreadcrumbs() { const { pool } = usePool() @@ -31,7 +32,7 @@ export function PoolBreadcrumbs() { <BreadcrumbLink href={poolsHref}>{poolsLabel}</BreadcrumbLink> </BreadcrumbItem> <BreadcrumbItem isCurrentPage> - <BreadcrumbLink href="#">{pool.symbol}</BreadcrumbLink> + <BreadcrumbLink href="#">{isBeetsProject ? pool.name : pool.symbol}</BreadcrumbLink> </BreadcrumbItem> </Breadcrumb> ) diff --git a/packages/lib/modules/pool/PoolDetail/PoolInfo/PoolContracts.tsx b/packages/lib/modules/pool/PoolDetail/PoolInfo/PoolContracts.tsx index 017010c4d..597eccce4 100644 --- a/packages/lib/modules/pool/PoolDetail/PoolInfo/PoolContracts.tsx +++ b/packages/lib/modules/pool/PoolDetail/PoolInfo/PoolContracts.tsx @@ -132,7 +132,7 @@ export function PoolContracts({ ...props }: CardProps) { if (hasGaugeAddress) { contracts.push({ - label: 'veBAL gauge', + label: 'Incentives gauge', address: gaugeAddress, explorerLink: gaugeExplorerLink, }) diff --git a/packages/lib/modules/pool/PoolDetail/PoolStats/PoolCharts/usePoolCharts.tsx b/packages/lib/modules/pool/PoolDetail/PoolStats/PoolCharts/usePoolCharts.tsx index d5d1d2694..0b1d7cb91 100644 --- a/packages/lib/modules/pool/PoolDetail/PoolStats/PoolCharts/usePoolCharts.tsx +++ b/packages/lib/modules/pool/PoolDetail/PoolStats/PoolCharts/usePoolCharts.tsx @@ -71,7 +71,7 @@ const dataRangeToDaysMap: { [key in GqlPoolSnapshotDataRange]?: number } = { [GqlPoolSnapshotDataRange.OneHundredEightyDays]: 180, } -const getDefaultPoolChartOptions = ( +export const getDefaultPoolChartOptions = ( currencyFormatter: NumberFormatter, nextTheme: ColorMode = 'dark', theme: any // TODO: type this diff --git a/packages/lib/modules/pool/PoolDetail/PoolUserEvents/PoolUserEvents.tsx b/packages/lib/modules/pool/PoolDetail/PoolUserEvents/PoolUserEvents.tsx index e8ebdf428..91ea0928d 100644 --- a/packages/lib/modules/pool/PoolDetail/PoolUserEvents/PoolUserEvents.tsx +++ b/packages/lib/modules/pool/PoolDetail/PoolUserEvents/PoolUserEvents.tsx @@ -29,6 +29,7 @@ import { calcTotalStakedBalance, getUserTotalBalance } from '../../user-balance. import { fNum, bn } from '@repo/lib/shared/utils/numbers' import { isEmpty } from 'lodash' import { BoostText } from './BoostText' +import { isBalancerProject } from '@repo/lib/config/getProjectConfig' import { getBlockExplorerTxUrl } from '@repo/lib/shared/utils/blockExplorer' type PoolEventRowProps = { @@ -185,7 +186,8 @@ export default function PoolUserEvents({ const { toCurrency } = useCurrency() const isVeBal = pool.staking?.type === GqlPoolStakingType.Vebal - const showBoostValue = pool.staking?.type === GqlPoolStakingType.Gauge && !isVeBal + const showBoostValue = + pool.staking?.type === GqlPoolStakingType.Gauge && !isVeBal && isBalancerProject // keep this card the same height as the 'My liquidity' section useLayoutEffect(() => { diff --git a/packages/lib/modules/pool/PoolList/PoolList.tsx b/packages/lib/modules/pool/PoolList/PoolList.tsx index c75aef868..a0f602c93 100644 --- a/packages/lib/modules/pool/PoolList/PoolList.tsx +++ b/packages/lib/modules/pool/PoolList/PoolList.tsx @@ -1,6 +1,6 @@ import { PoolListProvider } from '@repo/lib/modules/pool/PoolList/PoolListProvider' import { PoolListLayout } from './PoolListLayout' -import { GqlPoolType } from '@repo/lib/shared/services/api/generated/graphql' +import { GqlPoolType, GqlChain } from '@repo/lib/shared/services/api/generated/graphql' import { PoolListDisplayType } from '../pool.types' export async function PoolList({ @@ -9,16 +9,19 @@ export async function PoolList({ hideProtocolVersion = [], hidePoolTypes = [], hidePoolTags = [], + fixedChains, }: { displayType?: PoolListDisplayType fixedPoolTypes?: GqlPoolType[] hideProtocolVersion?: string[] hidePoolTypes?: GqlPoolType[] hidePoolTags?: string[] + fixedChains?: GqlChain[] }) { return ( <PoolListProvider displayType={displayType} + fixedChains={fixedChains} fixedPoolTypes={fixedPoolTypes} hidePoolTags={hidePoolTags} hidePoolTypes={hidePoolTypes} diff --git a/packages/lib/modules/pool/PoolList/PoolListFilters.tsx b/packages/lib/modules/pool/PoolList/PoolListFilters.tsx index 02c61d1b9..b1aa4c7b0 100644 --- a/packages/lib/modules/pool/PoolList/PoolListFilters.tsx +++ b/packages/lib/modules/pool/PoolList/PoolListFilters.tsx @@ -31,7 +31,7 @@ import { VStack, } from '@chakra-ui/react' import { PoolListSearch } from './PoolListSearch' -import { getProjectConfig } from '@repo/lib/config/getProjectConfig' +import { getProjectConfig, isBeetsProject } from '@repo/lib/config/getProjectConfig' import { PROTOCOL_VERSION_TABS } from './usePoolListQueryState' import { PoolFilterType, poolTagFilters, PoolTagType, poolTypeFilters } from '../pool.types' import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' @@ -462,6 +462,10 @@ export function PoolListFilters() { setActiveProtocolVersionTab(PROTOCOL_VERSION_TABS[0]) } + const poolCreatorUrl = isBeetsProject + ? 'https://ma.beets.fi/compose' + : `https://pool-creator.balancer.fi/${isCowPath ? 'cow' : 'v3'}` + return ( <VStack w="full"> <HStack gap="0" justify="end" spacing="none" w="full"> @@ -565,7 +569,7 @@ export function PoolListFilters() { as={Link} display="flex" gap="2" - href={`https://pool-creator.balancer.fi/${isCowPath ? 'cow' : 'v3'}`} + href={poolCreatorUrl} ml="ms" rel="" target="_blank" diff --git a/packages/lib/modules/pool/PoolList/PoolListProvider.tsx b/packages/lib/modules/pool/PoolList/PoolListProvider.tsx index cd76c0835..186a20ecc 100644 --- a/packages/lib/modules/pool/PoolList/PoolListProvider.tsx +++ b/packages/lib/modules/pool/PoolList/PoolListProvider.tsx @@ -2,7 +2,11 @@ 'use client' import { createContext, PropsWithChildren, useEffect } from 'react' -import { GetPoolsDocument, GqlPoolType } from '@repo/lib/shared/services/api/generated/graphql' +import { + GetPoolsDocument, + GqlChain, + GqlPoolType, +} from '@repo/lib/shared/services/api/generated/graphql' import { useQuery } from '@apollo/client' import { usePoolListQueryState } from './usePoolListQueryState' import { useMandatoryContext } from '@repo/lib/shared/utils/contexts' @@ -16,12 +20,14 @@ export function _usePoolList({ hideProtocolVersion = [], hidePoolTypes = [], hidePoolTags = [], + fixedChains, }: { fixedPoolTypes?: GqlPoolType[] displayType?: PoolListDisplayType hideProtocolVersion?: string[] hidePoolTypes?: GqlPoolType[] hidePoolTags?: string[] + fixedChains?: GqlChain[] } = {}) { const queryState = usePoolListQueryState() const { userAddress } = useUserAccount() @@ -33,6 +39,7 @@ export function _usePoolList({ where: { ...queryVariables.where, poolTypeIn: fixedPoolTypes || queryVariables.where.poolTypeIn, + chainIn: fixedChains || queryVariables.where.chainIn, }, } @@ -79,6 +86,7 @@ export function PoolListProvider({ hideProtocolVersion, hidePoolTypes, hidePoolTags, + fixedChains, children, }: PropsWithChildren<{ fixedPoolTypes?: GqlPoolType[] @@ -86,6 +94,7 @@ export function PoolListProvider({ hideProtocolVersion: string[] hidePoolTypes: GqlPoolType[] hidePoolTags: string[] + fixedChains?: GqlChain[] }>) { const hook = _usePoolList({ fixedPoolTypes, @@ -93,6 +102,7 @@ export function PoolListProvider({ hideProtocolVersion, hidePoolTypes, hidePoolTags, + fixedChains, }) return <PoolListContext.Provider value={hook}>{children}</PoolListContext.Provider> diff --git a/packages/lib/modules/pool/actions/remove-liquidity/handlers/RecoveryRemoveLiquidity.handler.ts b/packages/lib/modules/pool/actions/remove-liquidity/handlers/RecoveryRemoveLiquidity.handler.ts index dfdeb5cc5..91b09a1ec 100644 --- a/packages/lib/modules/pool/actions/remove-liquidity/handlers/RecoveryRemoveLiquidity.handler.ts +++ b/packages/lib/modules/pool/actions/remove-liquidity/handlers/RecoveryRemoveLiquidity.handler.ts @@ -40,7 +40,10 @@ export class RecoveryRemoveLiquidityHandler { userAddress, }: QueryRemoveLiquidityInput): Promise<SdkQueryRemoveLiquidityOutput> { const removeLiquidity = new RemoveLiquidity() - const removeLiquidityInput = this.constructSdkInput(bptIn, userAddress) + const removeLiquidityInput: RemoveLiquidityRecoveryInput = this.constructSdkInput( + bptIn, + userAddress + ) const sdkQueryOutput = await removeLiquidity.query( removeLiquidityInput, diff --git a/packages/lib/modules/pool/pool.helpers.ts b/packages/lib/modules/pool/pool.helpers.ts index 34cd3c197..b9671d971 100644 --- a/packages/lib/modules/pool/pool.helpers.ts +++ b/packages/lib/modules/pool/pool.helpers.ts @@ -30,6 +30,7 @@ import { GetTokenFn } from '../tokens/TokensProvider' import { vaultV3Abi } from '@balancer/sdk' import { TokenCore, PoolListItem, ApiToken } from './pool.types' import { Pool } from './PoolProvider' +import { isBeetsProject, PROJECT_CONFIG } from '@repo/lib/config/getProjectConfig' import { getBlockExplorerAddressUrl } from '@repo/lib/shared/utils/blockExplorer' /** @@ -258,12 +259,12 @@ export function hasReviewedRateProvider(token: GqlPoolTokenDetail): boolean { } export function hasRateProvider(token: GqlPoolTokenDetail): boolean { - const isPriceRateProvider = + const hasNoPriceRateProvider = isNil(token.priceRateProvider) || // if null, we consider rate provider as zero address token.priceRateProvider === zeroAddress || token.priceRateProvider === token.nestedPool?.address - return !isPriceRateProvider && !isNil(token.priceRateProviderData) + return !hasNoPriceRateProvider && !isNil(token.priceRateProviderData) } export function hasReviewedHook(hook: GqlHook): boolean { @@ -291,6 +292,9 @@ export function shouldBlockAddLiquidity(pool: Pool) { // avoid blocking Sepolia pools if (pool.chain === GqlChain.Sepolia) return false + // don't add liquidity to the maBEETS pool thru the pool page + if (isBeetsProject && pool.id === PROJECT_CONFIG.corePoolId) return true + const poolTokens = pool.poolTokens as GqlPoolTokenDetail[] // If pool is an LBP, paused or in recovery mode, we should block adding liquidity @@ -339,6 +343,11 @@ export function getPoolAddBlockedReason(pool: Pool): string { if (pool.dynamicData.isPaused) return 'Paused pool' if (pool.dynamicData.isInRecoveryMode) return 'Pool in recovery' + // don't add liquidity to the maBEETS pool thru the pool page + if (isBeetsProject && pool.id === PROJECT_CONFIG.corePoolId) { + return 'Please manage your liquidity on the maBEETS page.' + } + if (pool.hook && !hasReviewedHook(pool.hook)) { return 'Unreviewed hook' } diff --git a/packages/lib/modules/pool/pool.utils.ts b/packages/lib/modules/pool/pool.utils.ts index 210e6339c..40a8d139b 100644 --- a/packages/lib/modules/pool/pool.utils.ts +++ b/packages/lib/modules/pool/pool.utils.ts @@ -40,6 +40,7 @@ export enum ChainSlug { Sepolia = 'sepolia', Mode = 'mode', Fraxtal = 'fraxtal', + Sonic = 'sonic', } // Maps GraphQL chain enum to URL slug @@ -49,7 +50,6 @@ export const chainToSlugMap: Record<GqlChain, ChainSlug> = { [GqlChain.Polygon]: ChainSlug.Polygon, [GqlChain.Avalanche]: ChainSlug.Avalanche, [GqlChain.Fantom]: ChainSlug.Fantom, - [GqlChain.Sonic]: ChainSlug.Fantom, //TODO: groninge will fix it in another PR [GqlChain.Base]: ChainSlug.Base, [GqlChain.Optimism]: ChainSlug.Optimisim, [GqlChain.Zkevm]: ChainSlug.Zkevm, @@ -57,6 +57,7 @@ export const chainToSlugMap: Record<GqlChain, ChainSlug> = { [GqlChain.Sepolia]: ChainSlug.Sepolia, [GqlChain.Mode]: ChainSlug.Mode, [GqlChain.Fraxtal]: ChainSlug.Fraxtal, + [GqlChain.Sonic]: ChainSlug.Sonic, } export function getChainSlug(chainSlug: ChainSlug): GqlChain { @@ -147,7 +148,8 @@ export function getTotalApr( } if (item.type === GqlPoolAprItemType.MabeetsEmissions) { - minTotal = bn(item.apr).plus(minTotal) // only add min here, max is already added thru staking boost + minTotal = bn(item.apr).plus(minTotal) + maxTotal = bn(item.apr).plus(maxTotal) return } diff --git a/packages/lib/modules/swap/swap.helpers.ts b/packages/lib/modules/swap/swap.helpers.ts index 1ef7b5114..ccef6abc0 100644 --- a/packages/lib/modules/swap/swap.helpers.ts +++ b/packages/lib/modules/swap/swap.helpers.ts @@ -9,6 +9,7 @@ import { import { isSameAddress } from '@repo/lib/shared/utils/addresses' import { isMainnet } from '../chains/chain.utils' import { SwapSimulationQueryResult } from './queries/useSimulateSwapQuery' +import { getProjectConfig } from '@repo/lib/config/getProjectConfig' export function swapActionPastTense(action: SwapAction): string { switch (action) { @@ -26,7 +27,7 @@ export function swapActionPastTense(action: SwapAction): string { const swapErrorPatterns = [ { pattern: /must contain at least 1 path/, - message: "There's not enough liquidity on Balancer connecting these tokens to route this swap.", + message: `There's not enough liquidity on ${getProjectConfig().projectName} connecting these tokens to route this swap.`, }, { pattern: /WrapAmountTooSmall/, diff --git a/packages/lib/modules/tokens/TokenRow/TokenRow.tsx b/packages/lib/modules/tokens/TokenRow/TokenRow.tsx index c8caf1aa7..84038204b 100644 --- a/packages/lib/modules/tokens/TokenRow/TokenRow.tsx +++ b/packages/lib/modules/tokens/TokenRow/TokenRow.tsx @@ -42,6 +42,7 @@ export type TokenInfoProps = { isNestedBpt?: boolean isNestedPoolToken?: boolean iconSize?: number + logoURI?: string } function TokenInfo({ @@ -57,6 +58,7 @@ function TokenInfo({ isBpt = false, isNestedPoolToken = false, iconSize = 40, + logoURI, }: TokenInfoProps) { const tokenSymbol = isBpt ? 'LP token' : token?.symbol || symbol || displayToken?.symbol const tokenName = isBpt ? pool?.name : token?.name || displayToken?.name @@ -79,7 +81,13 @@ function TokenInfo({ return ( <HStack spacing="sm"> {!isBpt && ( - <TokenIcon address={address} alt={token?.symbol || address} chain={chain} size={iconSize} /> + <TokenIcon + address={address} + alt={token?.symbol || address} + chain={chain} + logoURI={logoURI} + size={iconSize} + /> )} <VStack alignItems="flex-start" spacing="none"> <HStack spacing="none"> @@ -124,6 +132,7 @@ export type TokenRowProps = { showZeroAmountAsDash?: boolean toggleTokenSelect?: () => void iconSize?: number + logoURI?: string } export default function TokenRow({ @@ -144,6 +153,7 @@ export default function TokenRow({ showZeroAmountAsDash = false, toggleTokenSelect, iconSize, + logoURI, }: TokenRowProps) { const { getToken, usdValueForToken, usdValueForBpt } = useTokens() const { toCurrency } = useCurrency() @@ -163,6 +173,7 @@ export default function TokenRow({ iconSize, isNestedPoolToken, symbol, + logoURI, } useEffect(() => { diff --git a/packages/lib/modules/transactions/RecentTransactionsProvider.tsx b/packages/lib/modules/transactions/RecentTransactionsProvider.tsx index 7cef192e0..dcade6618 100644 --- a/packages/lib/modules/transactions/RecentTransactionsProvider.tsx +++ b/packages/lib/modules/transactions/RecentTransactionsProvider.tsx @@ -15,11 +15,13 @@ import { useConfig, usePublicClient } from 'wagmi' import { waitForTransactionReceipt } from 'wagmi/actions' import { getWaitForReceiptTimeout } from '../web3/contracts/wagmi-helpers' import { TransactionStatus as SafeTxStatus } from '@safe-global/safe-apps-sdk' +import { PROJECT_CONFIG } from '@repo/lib/config/getProjectConfig' import { getBlockExplorerTxUrl } from '@repo/lib/shared/utils/blockExplorer' export type RecentTransactionsResponse = ReturnType<typeof _useRecentTransactions> export const TransactionsContext = createContext<RecentTransactionsResponse | null>(null) const NUM_RECENT_TRANSACTIONS = 20 +const RECENT_TRANSACTIONS_KEY = `${PROJECT_CONFIG.projectId}.recentTransactions` // confirming = transaction has not been mined // confirmed = transaction has been mined and is present on chain @@ -133,7 +135,7 @@ export function _useRecentTransactions() { // fetch recent transactions from local storage useEffect(() => { - const _recentTransactions = localStorage.getItem('balancer.recentTransactions') + const _recentTransactions = localStorage.getItem(RECENT_TRANSACTIONS_KEY) if (_recentTransactions) { const recentTransactions = JSON.parse(_recentTransactions) setTransactions(recentTransactions) @@ -241,10 +243,7 @@ export function _useRecentTransactions() { } function updateLocalStorage(customUpdate?: Record<string, TrackedTransaction>) { - localStorage.setItem( - 'balancer.recentTransactions', - JSON.stringify(customUpdate || transactions) - ) + localStorage.setItem(RECENT_TRANSACTIONS_KEY, JSON.stringify(customUpdate || transactions)) } function addTrackedTransaction(trackedTransaction: TrackedTransaction) { diff --git a/packages/lib/modules/transactions/transaction-steps/lib.tsx b/packages/lib/modules/transactions/transaction-steps/lib.tsx index a4507dcc3..0abe4f990 100644 --- a/packages/lib/modules/transactions/transaction-steps/lib.tsx +++ b/packages/lib/modules/transactions/transaction-steps/lib.tsx @@ -46,6 +46,9 @@ export type StepType = | LockActionType | 'signPermit' | 'signPermit2' + | 'stakeLst' + | 'unstakeLst' + | 'withdrawLst' export type TxActionId = | 'SignBatchRelayer' diff --git a/packages/lib/modules/transactions/transaction-steps/receipts/receipt-parsers.ts b/packages/lib/modules/transactions/transaction-steps/receipts/receipt-parsers.ts index 148f4805b..4e41b5602 100644 --- a/packages/lib/modules/transactions/transaction-steps/receipts/receipt-parsers.ts +++ b/packages/lib/modules/transactions/transaction-steps/receipts/receipt-parsers.ts @@ -3,15 +3,7 @@ import { BPT_DECIMALS } from '@repo/lib/modules/pool/pool.constants' import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' import { bn } from '@repo/lib/shared/utils/numbers' import { HumanAmount } from '@balancer/sdk' -import { - Address, - Log, - erc20Abi, - formatUnits, - parseAbiItem, - parseEventLogs, - zeroAddress, -} from 'viem' +import { Address, Log, erc20Abi, formatUnits, parseAbiItem, parseEventLogs } from 'viem' import { HumanTokenAmount } from '../../../tokens/token.types' import { emptyAddress } from '../../../web3/contracts/wagmi-helpers' import { ApiToken, ProtocolVersion } from '@repo/lib/modules/pool/pool.types' @@ -30,6 +22,8 @@ export type ParseReceipt = | typeof parseAddLiquidityReceipt | typeof parseRemoveLiquidityReceipt | typeof parseSwapReceipt + | typeof parseLstStakeReceipt + | typeof parseLstWithdrawReceipt export function parseAddLiquidityReceipt({ chain, @@ -149,6 +143,20 @@ export function parseSwapReceipt({ } } +export function parseLstStakeReceipt({ receiptLogs, userAddress }: ParseProps) { + const amount = getIncomingLogsLstDeposited(receiptLogs, userAddress) + + return { + receivedToken: _toHumanAmount('0xe5da20f15420ad15de0fa650600afc998bbe3955', amount, 18), // TODO: removed hardcoded address + } +} + +export function parseLstWithdrawReceipt({ receiptLogs, userAddress, chain }: ParseProps) { + const amount = getIncomingLogsLstWithdrawn(receiptLogs, userAddress) + return { + receivedToken: _toHumanAmount(getNativeAssetAddress(chain), amount, 18), + } +} /* rawValue and tokenDecimals should always be valid so we use default values to avoid complex error handling */ @@ -199,22 +207,37 @@ function getIncomingWithdrawals( ? networkConfig.contracts.balancer.batchRouter : networkConfig.contracts.balancer.vaultV2 - // Fantom uses the Transfer event instead of Withdrawal - if (chain === GqlChain.Fantom) { - return parseEventLogs({ - abi: [ - parseAbiItem('event Transfer(address indexed from, address indexed to, uint256 value)'), - ], - args: { from: from, to: zeroAddress }, - logs: logs, - })[0]?.args?.value - } else { - // Catches when the wNativeAsset is withdrawn from the vault, assumption is - // that his means the user is getting the same value in the native asset. - return parseEventLogs({ - abi: [parseAbiItem('event Withdrawal(address indexed src, uint256 wad)')], - args: { src: from }, - logs: logs, - })[0]?.args?.wad - } + // Catches when the wNativeAsset is withdrawn from the vault, assumption is + // that his means the user is getting the same value in the native asset. + return parseEventLogs({ + abi: [parseAbiItem('event Withdrawal(address indexed src, uint256 wad)')], + args: { src: from }, + logs: logs, + })[0]?.args?.wad +} + +function getIncomingLogsLstDeposited(logs: Log[], userAddress?: Address) { + return parseEventLogs({ + abi: [ + parseAbiItem( + 'event Deposited(address indexed user, uint256 amountAssets, uint256 amountShares)' + ), + ], + args: { user: userAddress }, + logs, + })[0]?.args?.amountShares +} + +function getIncomingLogsLstWithdrawn(logs: Log[], userAddress?: Address) { + const test = parseEventLogs({ + abi: [ + parseAbiItem( + 'event Withdrawn(address indexed user, uint256 withdrawId, uint256 amountAssets, uint8 kind, bool emergency)' + ), + ], + args: { user: userAddress }, + logs, + }) + + return test[0]?.args?.amountAssets } diff --git a/packages/lib/modules/transactions/transaction-steps/receipts/receipt.hooks.integration.spec.ts b/packages/lib/modules/transactions/transaction-steps/receipts/receipt.hooks.integration.spec.ts index caaf17e6e..6fc7b30d0 100644 --- a/packages/lib/modules/transactions/transaction-steps/receipts/receipt.hooks.integration.spec.ts +++ b/packages/lib/modules/transactions/transaction-steps/receipts/receipt.hooks.integration.spec.ts @@ -6,7 +6,13 @@ import { ethAddress, polAddress } from '@repo/lib/debug-helpers' import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' import { Address, Hash } from 'viem' import { gnosis, polygon } from 'viem/chains' -import { useAddLiquidityReceipt, useRemoveLiquidityReceipt, useSwapReceipt } from './receipt.hooks' +import { + useAddLiquidityReceipt, + useLstStakeReceipt, + useLstWithdrawReceipt, + useRemoveLiquidityReceipt, + useSwapReceipt, +} from './receipt.hooks' import { ProtocolVersion } from '@repo/lib/modules/pool/pool.types' async function testAddReceipt( @@ -60,6 +66,40 @@ async function testSwapReceipt( return result } +async function testLstStakeReceipt( + userAddress: Address, + txHash: Hash, + chain: GqlChain, + protocolVersion: ProtocolVersion = 3 +) { + const { result } = testHook(() => { + return useLstStakeReceipt({ + txHash, + userAddress, + chain, + protocolVersion, + }) + }) + return result +} + +async function testLstWithdrawReceipt( + userAddress: Address, + txHash: Hash, + chain: GqlChain, + protocolVersion: ProtocolVersion = 3 +) { + const { result } = testHook(() => { + return useLstWithdrawReceipt({ + txHash, + userAddress, + chain, + protocolVersion, + }) + }) + return result +} + test('queries add liquidity transaction', async () => { // https://etherscan.io/tx/0x887f144bdfe73c7e585b0630361038bda9665aa213933f637d1d6fae9046652e const userAddress = '0x2a88a454A7b0C29d36D5A121b7Cf582db01bfCEC' @@ -253,13 +293,51 @@ describe('queries swap transaction', () => { tokenAddress: ethAddress, }) }) -}) -test('returns is loading when user is not provided', async () => { - const userAddress = '' as Address - const txHash = '0x887f144bdfe73c7e585b0630361038bda9665aa213933f637d1d6fae9046652e' + test('returns is loading when user is not provided', async () => { + const userAddress = '' as Address + const txHash = '0x887f144bdfe73c7e585b0630361038bda9665aa213933f637d1d6fae9046652e' - const result = await testAddReceipt(userAddress, txHash) + const result = await testAddReceipt(userAddress, txHash) + + await waitFor(() => expect(result.current.isLoading).toBeTruthy()) + }) + + describe('queries Sonic stake TX', () => { + const sTsAddress = '0xe5da20f15420ad15de0fa650600afc998bbe3955' // staked sonic + + test('when staking S to get stS', async () => { + const userAddress = '0x35f391873F5ecAc80f46a6A1080c4E4743c7aC7D' + // https://sonicscan.org/tx/0x75f34af99a5afc39412bc5305aee1d77da5bd4a963c11a2ac5d7ae9f564d2c77 + const txHash = '0x75f34af99a5afc39412bc5305aee1d77da5bd4a963c11a2ac5d7ae9f564d2c77' - await waitFor(() => expect(result.current.isLoading).toBeTruthy()) + const result = await testLstStakeReceipt(userAddress, txHash, GqlChain.Sonic) + + await waitFor(() => expect(result.current.isLoading).toBeFalsy()) + + expect(result.current.receivedToken).toEqual({ + humanAmount: '19.932125314218435816', + tokenAddress: sTsAddress, + }) + }) + }) + + describe('queries stS withdraw TX', () => { + const sonicAddress = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' // Sonic + + test('when withdrawing stS to get S', async () => { + const userAddress = '0xDb04eE8ec3946BAC366AD8711F2e7610f45c0c42' + // https://sonicscan.org/tx/0x70ffae9f3ed4eb134dbd60b550f4da01b808bc5e5538832a30bf2cd61fcc4a46 + const txHash = '0x70ffae9f3ed4eb134dbd60b550f4da01b808bc5e5538832a30bf2cd61fcc4a46' + + const result = await testLstWithdrawReceipt(userAddress, txHash, GqlChain.Sonic) + + await waitFor(() => expect(result.current.isLoading).toBeFalsy()) + + expect(result.current.receivedToken).toEqual({ + humanAmount: '1385.824287592362834227', + tokenAddress: sonicAddress, + }) + }) + }) }) diff --git a/packages/lib/modules/transactions/transaction-steps/receipts/receipt.hooks.ts b/packages/lib/modules/transactions/transaction-steps/receipts/receipt.hooks.ts index 804fee1ad..9b7e5646c 100644 --- a/packages/lib/modules/transactions/transaction-steps/receipts/receipt.hooks.ts +++ b/packages/lib/modules/transactions/transaction-steps/receipts/receipt.hooks.ts @@ -8,6 +8,8 @@ import { parseAddLiquidityReceipt, parseRemoveLiquidityReceipt, parseSwapReceipt, + parseLstStakeReceipt, + parseLstWithdrawReceipt, } from './receipt-parsers' import { ProtocolVersion } from '@repo/lib/modules/pool/pool.types' @@ -60,6 +62,29 @@ export function useSwapReceipt(props: BaseReceiptProps) { } } +export type LstStakeReceiptResult = ReturnType<typeof useLstStakeReceipt> + +export function useLstStakeReceipt(props: BaseReceiptProps) { + const result = useTxReceipt({ ...props, parseReceipt: parseLstStakeReceipt }) + const data = result.data as ReturnType<typeof parseLstStakeReceipt> | undefined + + return { + ...result, + receivedToken: data?.receivedToken, + } +} +export type LstWithdrawReceiptResult = ReturnType<typeof useLstWithdrawReceipt> + +export function useLstWithdrawReceipt(props: BaseReceiptProps) { + const result = useTxReceipt({ ...props, parseReceipt: parseLstWithdrawReceipt }) + const data = result.data as ReturnType<typeof parseLstWithdrawReceipt> | undefined + + return { + ...result, + receivedToken: data?.receivedToken, + } +} + function useTxReceipt({ txHash, chain, userAddress, parseReceipt, protocolVersion }: ReceiptProps) { const { getToken, isLoadingTokenPrices } = useTokens() const chainId = getChainId(chain) diff --git a/packages/lib/modules/web3/AcceptPoliciesModal.tsx b/packages/lib/modules/web3/AcceptPoliciesModal.tsx index 9fd4cae95..d7ba1f937 100644 --- a/packages/lib/modules/web3/AcceptPoliciesModal.tsx +++ b/packages/lib/modules/web3/AcceptPoliciesModal.tsx @@ -21,7 +21,7 @@ import { useUserSettings } from '../user/settings/UserSettingsProvider' import { useUserAccount } from './UserAccountProvider' import { useDisconnect } from 'wagmi' import NextLink from 'next/link' -import { getProjectConfig } from '@repo/lib/config/getProjectConfig' +import { PROJECT_CONFIG, isBalancerProject } from '@repo/lib/config/getProjectConfig' export function AcceptPoliciesModal() { const { isOpen, onOpen, onClose } = useDisclosure() @@ -32,8 +32,6 @@ export function AcceptPoliciesModal() { const isAddressInAcceptedPolicies = acceptedPolicies.includes(userAddress.toLowerCase()) - const projectConfig = getProjectConfig() - useEffect(() => { if (!isLoading && isConnected && !isAddressInAcceptedPolicies && !isBlocked) { onOpen() @@ -66,7 +64,7 @@ export function AcceptPoliciesModal() { <Modal isCentered isOpen={isOpen} onClose={handleOnClose} preserveScrollBarGap> <ModalOverlay /> <ModalContent> - <ModalHeader>{`Accept ${projectConfig.projectName} policies`}</ModalHeader> + <ModalHeader>{`Accept ${PROJECT_CONFIG.projectName} policies`}</ModalHeader> <ModalCloseButton /> <ModalBody> <VStack align="flex-start" gap="md"> @@ -76,32 +74,39 @@ export function AcceptPoliciesModal() { onChange={e => setIsChecked(e.target.checked)} size="lg" > - <Box color="font.primary" fontSize="md" mt="-3px"> - By connecting my wallet, I agree to{' '} - {projectConfig.projectId === 'balancer' - ? "Balancer Foundation's " - : `${projectConfig.projectName} `} - <Link as={NextLink} href="/terms-of-use"> - Terms of Use - </Link> - ,{' '} - <Link as={NextLink} href="/risks"> - Risks - </Link> - ,{' '} - <Link as={NextLink} href="/cookies-policy"> - Cookies Policy - </Link> - , use of{' '} - <Link as={NextLink} href="/3rd-party-services"> - 3rd party services - </Link>{' '} - and{' '} - <Link as={NextLink} href="/privacy-policy"> - Privacy Policy - </Link> - . - </Box> + {isBalancerProject ? ( + <Box color="font.primary" fontSize="md" mt="-3px"> + By connecting my wallet, I agree to Balancer Foundation's{' '} + <Link as={NextLink} href="/terms-of-use"> + Terms of Use + </Link> + ,{' '} + <Link as={NextLink} href="/risks"> + Risks + </Link> + ,{' '} + <Link as={NextLink} href="/cookies-policy"> + Cookies Policy + </Link> + , use of{' '} + <Link as={NextLink} href="/3rd-party-services"> + 3rd party services + </Link>{' '} + and{' '} + <Link as={NextLink} href="/privacy-policy"> + Privacy Policy + </Link> + . + </Box> + ) : ( + <Box color="font.primary" fontSize="md" mt="-3px"> + By connecting my wallet, I agree to Beets'{' '} + <Link as={NextLink} href="/terms-of-service"> + Terms of Service + </Link> + . + </Box> + )} </Checkbox> </VStack> </ModalBody> diff --git a/packages/lib/modules/web3/ChainConfig.tsx b/packages/lib/modules/web3/ChainConfig.tsx index b2058d6af..ad6ca14fb 100644 --- a/packages/lib/modules/web3/ChainConfig.tsx +++ b/packages/lib/modules/web3/ChainConfig.tsx @@ -14,6 +14,7 @@ import { polygon, polygonZkEvm, sepolia, + sonic, } from 'wagmi/chains' import { getProjectConfig } from '@repo/lib/config/getProjectConfig' @@ -30,7 +31,6 @@ export const rpcFallbacks: Record<GqlChain, string | undefined> = { [GqlChain.Base]: 'https://base.llamarpc.com', [GqlChain.Avalanche]: 'https://avalanche.drpc.org', [GqlChain.Fantom]: 'https://1rpc.io/ftm', - [GqlChain.Sonic]: 'https://1rpc.io/ftm', //TODO: groninge will fix it in another PR [GqlChain.Gnosis]: 'https://gnosis.drpc.org', [GqlChain.Optimism]: 'https://optimism.drpc.org', [GqlChain.Polygon]: 'https://polygon.llamarpc.com', @@ -38,6 +38,7 @@ export const rpcFallbacks: Record<GqlChain, string | undefined> = { [GqlChain.Sepolia]: 'https://sepolia.gateway.tenderly.co', [GqlChain.Mode]: 'https://mode.drpc.org', [GqlChain.Fraxtal]: 'https://fraxtal.drpc.org', + [GqlChain.Sonic]: 'https://rpc.soniclabs.com', } const baseUrl = getBaseUrl() @@ -49,7 +50,6 @@ export const rpcOverrides: Record<GqlChain, string | undefined> = { [GqlChain.Base]: getPrivateRpcUrl(GqlChain.Base), [GqlChain.Avalanche]: getPrivateRpcUrl(GqlChain.Avalanche), [GqlChain.Fantom]: getPrivateRpcUrl(GqlChain.Fantom), - [GqlChain.Sonic]: getPrivateRpcUrl(GqlChain.Fantom), //TODO: groninge will fix it in another PR [GqlChain.Gnosis]: getPrivateRpcUrl(GqlChain.Gnosis), [GqlChain.Optimism]: getPrivateRpcUrl(GqlChain.Optimism), [GqlChain.Polygon]: getPrivateRpcUrl(GqlChain.Polygon), @@ -57,6 +57,7 @@ export const rpcOverrides: Record<GqlChain, string | undefined> = { [GqlChain.Sepolia]: getPrivateRpcUrl(GqlChain.Sepolia), [GqlChain.Mode]: getPrivateRpcUrl(GqlChain.Mode), [GqlChain.Fraxtal]: getPrivateRpcUrl(GqlChain.Fraxtal), + [GqlChain.Sonic]: getPrivateRpcUrl(GqlChain.Sonic), } const gqlChainToWagmiChainMap = { @@ -65,7 +66,6 @@ const gqlChainToWagmiChainMap = { [GqlChain.Base]: { iconUrl: '/images/chains/BASE.svg', ...base }, [GqlChain.Avalanche]: { iconUrl: '/images/chains/AVALANCHE.svg', ...avalanche }, [GqlChain.Fantom]: { iconUrl: '/images/chains/FANTOM.svg', ...fantom }, - [GqlChain.Sonic]: { iconUrl: '/images/chains/FANTOM.svg', ...fantom }, //TODO: groninge will fix it in another PR [GqlChain.Gnosis]: { iconUrl: '/images/chains/GNOSIS.svg', ...gnosis }, [GqlChain.Optimism]: { iconUrl: '/images/chains/OPTIMISM.svg', ...optimism }, [GqlChain.Polygon]: { iconUrl: '/images/chains/POLYGON.svg', ...polygon }, @@ -73,6 +73,7 @@ const gqlChainToWagmiChainMap = { [GqlChain.Sepolia]: { iconUrl: '/images/chains/SEPOLIA.svg', ...sepolia }, [GqlChain.Mode]: { iconUrl: '/images/chains/MODE.svg', ...mode }, [GqlChain.Fraxtal]: { iconUrl: '/images/chains/FRAXTAL.svg', ...fraxtal }, + [GqlChain.Sonic]: { iconUrl: '/images/chains/SONIC.svg', ...sonic }, } as const satisfies Record<GqlChain, Chain> export const supportedNetworks = getProjectConfig().supportedNetworks diff --git a/packages/lib/modules/web3/contracts/AbiMap.ts b/packages/lib/modules/web3/contracts/AbiMap.ts index 70b1b3a21..f000396e8 100644 --- a/packages/lib/modules/web3/contracts/AbiMap.ts +++ b/packages/lib/modules/web3/contracts/AbiMap.ts @@ -12,6 +12,7 @@ import { veDelegationProxyAbi, } from './abi/generated' import { VeDelegationProxyL2Abi } from './abi/veDelegationProxyL2' +import { sfcAbi, sonicStakingAbi } from './abi/beets/generated' export const AbiMap = { 'balancer.vaultV2': balancerV2VaultAbi, @@ -26,6 +27,8 @@ export const AbiMap = { 'balancer.veBAL': veBalAbi, 'balancer.LiquidityGauge': LiquidityGaugeAbi, 'balancer.omniVotingEscrowAbi': OmniVotingEscrowAbi, + 'beets.lstStaking': sonicStakingAbi, + 'beets.sfc': sfcAbi, } export type AbiMapType = keyof typeof AbiMap | undefined diff --git a/packages/lib/modules/web3/contracts/abi/beets/generated.ts b/packages/lib/modules/web3/contracts/abi/beets/generated.ts new file mode 100644 index 000000000..43ee7b547 --- /dev/null +++ b/packages/lib/modules/web3/contracts/abi/beets/generated.ts @@ -0,0 +1,7132 @@ +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BalancerMinter +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x239e55F427D44C3cc793f49bFB507ebe76638a2b) + */ +export const balancerMinterAbi = [ + { + type: 'constructor', + inputs: [ + { + name: 'tokenAdmin', + internalType: 'contract IBalancerTokenAdmin', + type: 'address', + }, + { + name: 'gaugeController', + internalType: 'contract IGaugeController', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'recipient', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'gauge', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'minted', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Minted', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'user', internalType: 'address', type: 'address', indexed: true }, + { + name: 'minter', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approval', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'MinterApprovalSet', + }, + { + type: 'function', + inputs: [ + { name: 'minter', internalType: 'address', type: 'address' }, + { name: 'user', internalType: 'address', type: 'address' }, + ], + name: 'allowed_to_mint_for', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getBalancerToken', + outputs: [{ name: '', internalType: 'contract IERC20', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getBalancerTokenAdmin', + outputs: [ + { + name: '', + internalType: 'contract IBalancerTokenAdmin', + type: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getDomainSeparator', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getGaugeController', + outputs: [{ name: '', internalType: 'contract IGaugeController', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'minter', internalType: 'address', type: 'address' }, + { name: 'user', internalType: 'address', type: 'address' }, + ], + name: 'getMinterApproval', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'user', internalType: 'address', type: 'address' }], + name: 'getNextNonce', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'gauge', internalType: 'address', type: 'address' }], + name: 'mint', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'gauge', internalType: 'address', type: 'address' }, + { name: 'user', internalType: 'address', type: 'address' }, + ], + name: 'mintFor', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'gauges', internalType: 'address[]', type: 'address[]' }], + name: 'mintMany', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'gauges', internalType: 'address[]', type: 'address[]' }, + { name: 'user', internalType: 'address', type: 'address' }, + ], + name: 'mintManyFor', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'gauge', internalType: 'address', type: 'address' }, + { name: 'user', internalType: 'address', type: 'address' }, + ], + name: 'mint_for', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'gauges', internalType: 'address[8]', type: 'address[8]' }], + name: 'mint_many', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'gauge', internalType: 'address', type: 'address' }, + ], + name: 'minted', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'minter', internalType: 'address', type: 'address' }, + { name: 'approval', internalType: 'bool', type: 'bool' }, + ], + name: 'setMinterApproval', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'minter', internalType: 'address', type: 'address' }, + { name: 'approval', internalType: 'bool', type: 'bool' }, + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'setMinterApprovalWithSignature', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'minter', internalType: 'address', type: 'address' }], + name: 'toggle_approve_mint', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x239e55F427D44C3cc793f49bFB507ebe76638a2b) + */ +export const balancerMinterAddress = { + 1: '0x239e55F427D44C3cc793f49bFB507ebe76638a2b', +} as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x239e55F427D44C3cc793f49bFB507ebe76638a2b) + */ +export const balancerMinterConfig = { + address: balancerMinterAddress, + abi: balancerMinterAbi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BalancerV2BalancerRelayerV6 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x35Cea9e57A393ac66Aaa7E25C391D52C74B5648f) + */ +export const balancerV2BalancerRelayerV6Abi = [ + { + type: 'constructor', + inputs: [ + { name: 'vault', internalType: 'contract IVault', type: 'address' }, + { name: 'libraryAddress', internalType: 'address', type: 'address' }, + { name: 'queryLibrary', internalType: 'address', type: 'address' }, + { name: 'version', internalType: 'string', type: 'string' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'getLibrary', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getQueryLibrary', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getVault', + outputs: [{ name: '', internalType: 'contract IVault', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'data', internalType: 'bytes[]', type: 'bytes[]' }], + name: 'multicall', + outputs: [{ name: 'results', internalType: 'bytes[]', type: 'bytes[]' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [{ name: 'data', internalType: 'bytes[]', type: 'bytes[]' }], + name: 'vaultActionsQueryMulticall', + outputs: [{ name: 'results', internalType: 'bytes[]', type: 'bytes[]' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'version', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { type: 'receive', stateMutability: 'payable' }, +] as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x35Cea9e57A393ac66Aaa7E25C391D52C74B5648f) + */ +export const balancerV2BalancerRelayerV6Address = { + 1: '0x35Cea9e57A393ac66Aaa7E25C391D52C74B5648f', +} as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x35Cea9e57A393ac66Aaa7E25C391D52C74B5648f) + */ +export const balancerV2BalancerRelayerV6Config = { + address: balancerV2BalancerRelayerV6Address, + abi: balancerV2BalancerRelayerV6Abi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BalancerV2BatchRelayerLibrary +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xea66501df1a00261e3bb79d1e90444fc6a186b62) + */ +export const balancerV2BatchRelayerLibraryAbi = [ + { + type: 'constructor', + inputs: [ + { name: 'vault', internalType: 'contract IVault', type: 'address' }, + { name: 'wstETH', internalType: 'contract IERC20', type: 'address' }, + { + name: 'minter', + internalType: 'contract IBalancerMinter', + type: 'address', + }, + { name: 'canCallUserCheckpoint', internalType: 'bool', type: 'bool' }, + { name: 'version', internalType: 'string', type: 'string' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approveVault', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'kind', internalType: 'enum IVault.SwapKind', type: 'uint8' }, + { + name: 'swaps', + internalType: 'struct IVault.BatchSwapStep[]', + type: 'tuple[]', + components: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'assetInIndex', internalType: 'uint256', type: 'uint256' }, + { name: 'assetOutIndex', internalType: 'uint256', type: 'uint256' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + }, + { name: 'assets', internalType: 'contract IAsset[]', type: 'address[]' }, + { + name: 'funds', + internalType: 'struct IVault.FundManagement', + type: 'tuple', + components: [ + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'fromInternalBalance', internalType: 'bool', type: 'bool' }, + { + name: 'recipient', + internalType: 'address payable', + type: 'address', + }, + { name: 'toInternalBalance', internalType: 'bool', type: 'bool' }, + ], + }, + { name: 'limits', internalType: 'int256[]', type: 'int256[]' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { + name: 'outputReferences', + internalType: 'struct VaultActions.OutputReference[]', + type: 'tuple[]', + components: [ + { name: 'index', internalType: 'uint256', type: 'uint256' }, + { name: 'key', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'batchSwap', + outputs: [{ name: 'results', internalType: 'int256[]', type: 'int256[]' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [], + name: 'canCallUserCheckpoint', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'kind', + internalType: 'enum VaultActions.PoolKind', + type: 'uint8', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address payable', type: 'address' }, + { + name: 'request', + internalType: 'struct IVault.ExitPoolRequest', + type: 'tuple', + components: [ + { + name: 'assets', + internalType: 'contract IAsset[]', + type: 'address[]', + }, + { + name: 'minAmountsOut', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + { name: 'toInternalBalance', internalType: 'bool', type: 'bool' }, + ], + }, + { + name: 'outputReferences', + internalType: 'struct VaultActions.OutputReference[]', + type: 'tuple[]', + components: [ + { name: 'index', internalType: 'uint256', type: 'uint256' }, + { name: 'key', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'exitPool', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'user', internalType: 'address', type: 'address' }, + { + name: 'gauges', + internalType: 'contract IStakingLiquidityGauge[]', + type: 'address[]', + }, + ], + name: 'gaugeCheckpoint', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'gauges', + internalType: 'contract IStakingLiquidityGauge[]', + type: 'address[]', + }, + ], + name: 'gaugeClaimRewards', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'gauge', + internalType: 'contract IStakingLiquidityGauge', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'gaugeDeposit', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'gauges', internalType: 'address[]', type: 'address[]' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'gaugeMint', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'approval', internalType: 'bool', type: 'bool' }, + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'gaugeSetMinterApproval', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'gauge', + internalType: 'contract IStakingLiquidityGauge', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'gaugeWithdraw', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [], + name: 'getEntrypoint', + outputs: [{ name: '', internalType: 'contract IBalancerRelayer', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getVault', + outputs: [{ name: '', internalType: 'contract IVault', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'kind', + internalType: 'enum VaultActions.PoolKind', + type: 'uint8', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { + name: 'request', + internalType: 'struct IVault.JoinPoolRequest', + type: 'tuple', + components: [ + { + name: 'assets', + internalType: 'contract IAsset[]', + type: 'address[]', + }, + { + name: 'maxAmountsIn', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + { name: 'fromInternalBalance', internalType: 'bool', type: 'bool' }, + ], + }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'joinPool', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'ops', + internalType: 'struct IVault.UserBalanceOp[]', + type: 'tuple[]', + components: [ + { + name: 'kind', + internalType: 'enum IVault.UserBalanceOpKind', + type: 'uint8', + }, + { name: 'asset', internalType: 'contract IAsset', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'sender', internalType: 'address', type: 'address' }, + { + name: 'recipient', + internalType: 'address payable', + type: 'address', + }, + ], + }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { + name: 'outputReferences', + internalType: 'struct VaultActions.OutputReference[]', + type: 'tuple[]', + components: [ + { name: 'index', internalType: 'uint256', type: 'uint256' }, + { name: 'key', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'manageUserBalance', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [{ name: 'ref', internalType: 'uint256', type: 'uint256' }], + name: 'peekChainedReferenceValue', + outputs: [{ name: 'value', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'relayer', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + { name: 'authorisation', internalType: 'bytes', type: 'bytes' }, + ], + name: 'setRelayerApproval', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'stakeETH', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'stakeETHAndWrap', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'singleSwap', + internalType: 'struct IVault.SingleSwap', + type: 'tuple', + components: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'kind', internalType: 'enum IVault.SwapKind', type: 'uint8' }, + { name: 'assetIn', internalType: 'contract IAsset', type: 'address' }, + { + name: 'assetOut', + internalType: 'contract IAsset', + type: 'address', + }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + }, + { + name: 'funds', + internalType: 'struct IVault.FundManagement', + type: 'tuple', + components: [ + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'fromInternalBalance', internalType: 'bool', type: 'bool' }, + { + name: 'recipient', + internalType: 'address payable', + type: 'address', + }, + { name: 'toInternalBalance', internalType: 'bool', type: 'bool' }, + ], + }, + { name: 'limit', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'swap', + outputs: [{ name: 'result', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'staticToken', + internalType: 'contract IStaticATokenLM', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'toUnderlying', internalType: 'bool', type: 'bool' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'unwrapAaveStaticToken', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract ICToken', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'unwrapCompoundV2', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract IERC4626', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'unwrapERC4626', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract IEulerToken', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'unwrapEuler', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract IGearboxDieselToken', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'dieselAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'unwrapGearbox', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'vaultToken', + internalType: 'contract IReaperTokenVault', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'unwrapReaperVaultToken', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract IShareToken', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'unwrapShareToken', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract ITetuSmartVault', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'unwrapTetu', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrapperToken', + internalType: 'contract IUnbuttonToken', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'unwrapUnbuttonToken', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'unwrapWstETH', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract IYearnTokenVault', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'unwrapYearn', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20Permit', type: 'address' }, + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'vaultPermit', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'token', + internalType: 'contract IERC20PermitDAI', + type: 'address', + }, + { name: 'holder', internalType: 'address', type: 'address' }, + { name: 'nonce', internalType: 'uint256', type: 'uint256' }, + { name: 'expiry', internalType: 'uint256', type: 'uint256' }, + { name: 'allowed', internalType: 'bool', type: 'bool' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'vaultPermitDAI', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'staticToken', + internalType: 'contract IStaticATokenLM', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'fromUnderlying', internalType: 'bool', type: 'bool' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'wrapAaveDynamicToken', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract ICToken', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'wrapCompoundV2', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract IERC4626', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'wrapERC4626', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract IEulerToken', + type: 'address', + }, + { name: 'eulerProtocol', internalType: 'address', type: 'address' }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'wrapEuler', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract IGearboxDieselToken', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'mainAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'wrapGearbox', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'vaultToken', + internalType: 'contract IReaperTokenVault', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'wrapReaperVaultToken', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract IShareToken', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'wrapShareToken', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'wrapStETH', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract ITetuSmartVault', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'wrapTetu', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrapperToken', + internalType: 'contract IUnbuttonToken', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'uAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'wrapUnbuttonToken', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'wrappedToken', + internalType: 'contract IYearnTokenVault', + type: 'address', + }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'outputReference', internalType: 'uint256', type: 'uint256' }, + ], + name: 'wrapYearn', + outputs: [], + stateMutability: 'payable', + }, +] as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xea66501df1a00261e3bb79d1e90444fc6a186b62) + */ +export const balancerV2BatchRelayerLibraryAddress = { + 1: '0xeA66501dF1A00261E3bB79D1E90444fc6A186B62', +} as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xea66501df1a00261e3bb79d1e90444fc6a186b62) + */ +export const balancerV2BatchRelayerLibraryConfig = { + address: balancerV2BatchRelayerLibraryAddress, + abi: balancerV2BatchRelayerLibraryAbi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BalancerV2ComposableStablePoolV5 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xdacf5fa19b1f720111609043ac67a9818262850c) + */ +export const balancerV2ComposableStablePoolV5Abi = [ + { + type: 'constructor', + inputs: [ + { + name: 'params', + internalType: 'struct ComposableStablePool.NewPoolParams', + type: 'tuple', + components: [ + { name: 'vault', internalType: 'contract IVault', type: 'address' }, + { + name: 'protocolFeeProvider', + internalType: 'contract IProtocolFeePercentagesProvider', + type: 'address', + }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'symbol', internalType: 'string', type: 'string' }, + { + name: 'tokens', + internalType: 'contract IERC20[]', + type: 'address[]', + }, + { + name: 'rateProviders', + internalType: 'contract IRateProvider[]', + type: 'address[]', + }, + { + name: 'tokenRateCacheDurations', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { + name: 'exemptFromYieldProtocolFeeFlag', + internalType: 'bool', + type: 'bool', + }, + { + name: 'amplificationParameter', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'swapFeePercentage', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'pauseWindowDuration', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'bufferPeriodDuration', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'version', internalType: 'string', type: 'string' }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'startValue', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'endValue', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'startTime', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'endTime', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'AmpUpdateStarted', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'currentValue', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'AmpUpdateStopped', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'spender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [{ name: 'paused', internalType: 'bool', type: 'bool', indexed: false }], + name: 'PausedStateChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'feeType', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'protocolFeePercentage', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ProtocolFeePercentageCacheUpdated', + }, + { + type: 'event', + anonymous: false, + inputs: [{ name: 'enabled', internalType: 'bool', type: 'bool', indexed: false }], + name: 'RecoveryModeStateChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'swapFeePercentage', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'SwapFeePercentageChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenIndex', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'rate', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'TokenRateCacheUpdated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'tokenIndex', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'provider', + internalType: 'contract IRateProvider', + type: 'address', + indexed: true, + }, + { + name: 'cacheDuration', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'TokenRateProviderSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [], + name: 'DELEGATE_PROTOCOL_SWAP_FEES_SENTINEL', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'disableRecoveryMode', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'enableRecoveryMode', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'getActionId', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getActualSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getAmplificationParameter', + outputs: [ + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { name: 'isUpdating', internalType: 'bool', type: 'bool' }, + { name: 'precision', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getAuthorizer', + outputs: [{ name: '', internalType: 'contract IAuthorizer', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getBptIndex', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getDomainSeparator', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getLastJoinExitData', + outputs: [ + { + name: 'lastJoinExitAmplification', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'lastPostJoinExitInvariant', + internalType: 'uint256', + type: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getMinimumBpt', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'getNextNonce', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getOwner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPausedState', + outputs: [ + { name: 'paused', internalType: 'bool', type: 'bool' }, + { name: 'pauseWindowEndTime', internalType: 'uint256', type: 'uint256' }, + { name: 'bufferPeriodEndTime', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPoolId', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'feeType', internalType: 'uint256', type: 'uint256' }], + name: 'getProtocolFeePercentageCache', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getProtocolFeesCollector', + outputs: [ + { + name: '', + internalType: 'contract IProtocolFeesCollector', + type: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getProtocolSwapFeeDelegation', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getRate', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getRateProviders', + outputs: [{ name: '', internalType: 'contract IRateProvider[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getScalingFactors', + outputs: [{ name: '', internalType: 'uint256[]', type: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getSwapFeePercentage', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'token', internalType: 'contract IERC20', type: 'address' }], + name: 'getTokenRate', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'token', internalType: 'contract IERC20', type: 'address' }], + name: 'getTokenRateCache', + outputs: [ + { name: 'rate', internalType: 'uint256', type: 'uint256' }, + { name: 'oldRate', internalType: 'uint256', type: 'uint256' }, + { name: 'duration', internalType: 'uint256', type: 'uint256' }, + { name: 'expires', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getVault', + outputs: [{ name: '', internalType: 'contract IVault', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'inRecoveryMode', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'addedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'isExemptFromYieldProtocolFee', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'token', internalType: 'contract IERC20', type: 'address' }], + name: 'isTokenExemptFromYieldProtocolFee', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'nonces', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'balances', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'lastChangeBlock', internalType: 'uint256', type: 'uint256' }, + { + name: 'protocolSwapFeePercentage', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + name: 'onExitPool', + outputs: [ + { name: '', internalType: 'uint256[]', type: 'uint256[]' }, + { name: '', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'balances', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'lastChangeBlock', internalType: 'uint256', type: 'uint256' }, + { + name: 'protocolSwapFeePercentage', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + name: 'onJoinPool', + outputs: [ + { name: '', internalType: 'uint256[]', type: 'uint256[]' }, + { name: '', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'swapRequest', + internalType: 'struct IPoolSwapStructs.SwapRequest', + type: 'tuple', + components: [ + { name: 'kind', internalType: 'enum IVault.SwapKind', type: 'uint8' }, + { name: 'tokenIn', internalType: 'contract IERC20', type: 'address' }, + { + name: 'tokenOut', + internalType: 'contract IERC20', + type: 'address', + }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'lastChangeBlock', internalType: 'uint256', type: 'uint256' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + }, + { name: 'balances', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'indexIn', internalType: 'uint256', type: 'uint256' }, + { name: 'indexOut', internalType: 'uint256', type: 'uint256' }, + ], + name: 'onSwap', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'balances', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'lastChangeBlock', internalType: 'uint256', type: 'uint256' }, + { + name: 'protocolSwapFeePercentage', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + name: 'queryExit', + outputs: [ + { name: 'bptIn', internalType: 'uint256', type: 'uint256' }, + { name: 'amountsOut', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'balances', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'lastChangeBlock', internalType: 'uint256', type: 'uint256' }, + { + name: 'protocolSwapFeePercentage', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + name: 'queryJoin', + outputs: [ + { name: 'bptOut', internalType: 'uint256', type: 'uint256' }, + { name: 'amountsIn', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'poolConfig', internalType: 'bytes', type: 'bytes' }, + ], + name: 'setAssetManagerPoolConfig', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'swapFeePercentage', internalType: 'uint256', type: 'uint256' }], + name: 'setSwapFeePercentage', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'duration', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setTokenRateCacheDuration', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'rawEndValue', internalType: 'uint256', type: 'uint256' }, + { name: 'endTime', internalType: 'uint256', type: 'uint256' }, + ], + name: 'startAmplificationParameterUpdate', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'stopAmplificationParameterUpdate', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'updateProtocolFeePercentageCache', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'token', internalType: 'contract IERC20', type: 'address' }], + name: 'updateTokenRateCache', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'version', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, +] as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xdacf5fa19b1f720111609043ac67a9818262850c) + */ +export const balancerV2ComposableStablePoolV5Address = { + 1: '0xDACf5Fa19b1f720111609043ac67A9818262850c', +} as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xdacf5fa19b1f720111609043ac67a9818262850c) + */ +export const balancerV2ComposableStablePoolV5Config = { + address: balancerV2ComposableStablePoolV5Address, + abi: balancerV2ComposableStablePoolV5Abi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BalancerV2GaugeV5 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xbc02ef87f4e15ef78a571f3b2adcc726fee70d8b) + */ +export const balancerV2GaugeV5Abi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'provider', type: 'address', indexed: true }, + { name: 'value', type: 'uint256', indexed: false }, + ], + name: 'Deposit', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'provider', type: 'address', indexed: true }, + { name: 'value', type: 'uint256', indexed: false }, + ], + name: 'Withdraw', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'user', type: 'address', indexed: true }, + { name: 'original_balance', type: 'uint256', indexed: false }, + { name: 'original_supply', type: 'uint256', indexed: false }, + { name: 'working_balance', type: 'uint256', indexed: false }, + { name: 'working_supply', type: 'uint256', indexed: false }, + ], + name: 'UpdateLiquidityLimit', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: '_from', type: 'address', indexed: true }, + { name: '_to', type: 'address', indexed: true }, + { name: '_value', type: 'uint256', indexed: false }, + ], + name: 'Transfer', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: '_owner', type: 'address', indexed: true }, + { name: '_spender', type: 'address', indexed: true }, + { name: '_value', type: 'uint256', indexed: false }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'reward_token', type: 'address', indexed: true }, + { name: 'distributor', type: 'address', indexed: false }, + ], + name: 'RewardDistributorUpdated', + }, + { + type: 'event', + anonymous: false, + inputs: [{ name: 'new_relative_weight_cap', type: 'uint256', indexed: false }], + name: 'RelativeWeightCapChanged', + }, + { + type: 'constructor', + inputs: [ + { name: 'minter', type: 'address' }, + { name: 'veBoostProxy', type: 'address' }, + { name: 'authorizerAdaptor', type: 'address' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: '_value', type: 'uint256' }], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_value', type: 'uint256' }, + { name: '_addr', type: 'address' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_value', type: 'uint256' }, + { name: '_addr', type: 'address' }, + { name: '_claim_rewards', type: 'bool' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: '_value', type: 'uint256' }], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_value', type: 'uint256' }, + { name: '_claim_rewards', type: 'bool' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'claim_rewards', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: '_addr', type: 'address' }], + name: 'claim_rewards', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_addr', type: 'address' }, + { name: '_receiver', type: 'address' }, + ], + name: 'claim_rewards', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_to', type: 'address' }, + { name: '_value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_spender', type: 'address' }, + { name: '_value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_owner', type: 'address' }, + { name: '_spender', type: 'address' }, + { name: '_value', type: 'uint256' }, + { name: '_deadline', type: 'uint256' }, + { name: '_v', type: 'uint8' }, + { name: '_r', type: 'bytes32' }, + { name: '_s', type: 'bytes32' }, + ], + name: 'permit', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_spender', type: 'address' }, + { name: '_added_value', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_spender', type: 'address' }, + { name: '_subtracted_value', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'addr', type: 'address' }], + name: 'user_checkpoint', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: '_receiver', type: 'address' }], + name: 'set_rewards_receiver', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'addr', type: 'address' }], + name: 'kick', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_reward_token', type: 'address' }, + { name: '_amount', type: 'uint256' }, + ], + name: 'deposit_reward_token', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_reward_token', type: 'address' }, + { name: '_distributor', type: 'address' }, + ], + name: 'add_reward', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_reward_token', type: 'address' }, + { name: '_distributor', type: 'address' }, + ], + name: 'set_reward_distributor', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'killGauge', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'unkillGauge', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_addr', type: 'address' }, + { name: '_token', type: 'address' }, + ], + name: 'claimed_reward', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: '_user', type: 'address' }, + { name: '_reward_token', type: 'address' }, + ], + name: 'claimable_reward', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'addr', type: 'address' }], + name: 'claimable_tokens', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'integrate_checkpoint', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'future_epoch_time', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'inflation_rate', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'version', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: '_lp_token', type: 'address' }, + { name: 'relative_weight_cap', type: 'uint256' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'relative_weight_cap', type: 'uint256' }], + name: 'setRelativeWeightCap', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'getRelativeWeightCap', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'time', type: 'uint256' }], + name: 'getCappedRelativeWeight', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getMaxRelativeWeightCap', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ name: '', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'address' }], + name: 'nonces', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'lp_token', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'is_killed', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'reward_count', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'address' }], + name: 'reward_data', + outputs: [ + { + name: '', + type: 'tuple', + components: [ + { name: 'token', type: 'address' }, + { name: 'distributor', type: 'address' }, + { name: 'period_finish', type: 'uint256' }, + { name: 'rate', type: 'uint256' }, + { name: 'last_update', type: 'uint256' }, + { name: 'integral', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'address' }], + name: 'rewards_receiver', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'arg0', type: 'address' }, + { name: 'arg1', type: 'address' }, + ], + name: 'reward_integral_for', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'address' }], + name: 'working_balances', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'working_supply', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'address' }], + name: 'integrate_inv_supply_of', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'address' }], + name: 'integrate_checkpoint_of', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'address' }], + name: 'integrate_fraction', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'period', + outputs: [{ name: '', type: 'int128' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'uint256' }], + name: 'reward_tokens', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'uint256' }], + name: 'period_timestamp', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'uint256' }], + name: 'integrate_inv_supply', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, +] as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xbc02ef87f4e15ef78a571f3b2adcc726fee70d8b) + */ +export const balancerV2GaugeV5Address = { + 1: '0xBC02eF87f4E15EF78A571f3B2aDcC726Fee70d8b', +} as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xbc02ef87f4e15ef78a571f3b2adcc726fee70d8b) + */ +export const balancerV2GaugeV5Config = { + address: balancerV2GaugeV5Address, + abi: balancerV2GaugeV5Abi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BalancerV2Vault +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xBA12222222228d8Ba445958a75a0704d566BF2C8) + */ +export const balancerV2VaultAbi = [ + { + type: 'constructor', + inputs: [ + { + name: 'authorizer', + internalType: 'contract IAuthorizer', + type: 'address', + }, + { name: 'weth', internalType: 'contract IWETH', type: 'address' }, + { name: 'pauseWindowDuration', internalType: 'uint256', type: 'uint256' }, + { + name: 'bufferPeriodDuration', + internalType: 'uint256', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newAuthorizer', + internalType: 'contract IAuthorizer', + type: 'address', + indexed: true, + }, + ], + name: 'AuthorizerChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'token', + internalType: 'contract IERC20', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'recipient', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ExternalBalanceTransfer', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'recipient', + internalType: 'contract IFlashLoanRecipient', + type: 'address', + indexed: true, + }, + { + name: 'token', + internalType: 'contract IERC20', + type: 'address', + indexed: true, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'feeAmount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'FlashLoan', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'user', internalType: 'address', type: 'address', indexed: true }, + { + name: 'token', + internalType: 'contract IERC20', + type: 'address', + indexed: true, + }, + { name: 'delta', internalType: 'int256', type: 'int256', indexed: false }, + ], + name: 'InternalBalanceChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [{ name: 'paused', internalType: 'bool', type: 'bool', indexed: false }], + name: 'PausedStateChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'poolId', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + { + name: 'liquidityProvider', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokens', + internalType: 'contract IERC20[]', + type: 'address[]', + indexed: false, + }, + { + name: 'deltas', + internalType: 'int256[]', + type: 'int256[]', + indexed: false, + }, + { + name: 'protocolFeeAmounts', + internalType: 'uint256[]', + type: 'uint256[]', + indexed: false, + }, + ], + name: 'PoolBalanceChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'poolId', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + { + name: 'assetManager', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'token', + internalType: 'contract IERC20', + type: 'address', + indexed: true, + }, + { + name: 'cashDelta', + internalType: 'int256', + type: 'int256', + indexed: false, + }, + { + name: 'managedDelta', + internalType: 'int256', + type: 'int256', + indexed: false, + }, + ], + name: 'PoolBalanceManaged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'poolId', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + { + name: 'poolAddress', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'specialization', + internalType: 'enum IVault.PoolSpecialization', + type: 'uint8', + indexed: false, + }, + ], + name: 'PoolRegistered', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'relayer', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'RelayerApprovalChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'poolId', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + { + name: 'tokenIn', + internalType: 'contract IERC20', + type: 'address', + indexed: true, + }, + { + name: 'tokenOut', + internalType: 'contract IERC20', + type: 'address', + indexed: true, + }, + { + name: 'amountIn', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'amountOut', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Swap', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'poolId', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + { + name: 'tokens', + internalType: 'contract IERC20[]', + type: 'address[]', + indexed: false, + }, + ], + name: 'TokensDeregistered', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'poolId', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + { + name: 'tokens', + internalType: 'contract IERC20[]', + type: 'address[]', + indexed: false, + }, + { + name: 'assetManagers', + internalType: 'address[]', + type: 'address[]', + indexed: false, + }, + ], + name: 'TokensRegistered', + }, + { + type: 'function', + inputs: [], + name: 'WETH', + outputs: [{ name: '', internalType: 'contract IWETH', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'kind', internalType: 'enum IVault.SwapKind', type: 'uint8' }, + { + name: 'swaps', + internalType: 'struct IVault.BatchSwapStep[]', + type: 'tuple[]', + components: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'assetInIndex', internalType: 'uint256', type: 'uint256' }, + { name: 'assetOutIndex', internalType: 'uint256', type: 'uint256' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + }, + { name: 'assets', internalType: 'contract IAsset[]', type: 'address[]' }, + { + name: 'funds', + internalType: 'struct IVault.FundManagement', + type: 'tuple', + components: [ + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'fromInternalBalance', internalType: 'bool', type: 'bool' }, + { + name: 'recipient', + internalType: 'address payable', + type: 'address', + }, + { name: 'toInternalBalance', internalType: 'bool', type: 'bool' }, + ], + }, + { name: 'limits', internalType: 'int256[]', type: 'int256[]' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + ], + name: 'batchSwap', + outputs: [{ name: 'assetDeltas', internalType: 'int256[]', type: 'int256[]' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'tokens', internalType: 'contract IERC20[]', type: 'address[]' }, + ], + name: 'deregisterTokens', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address payable', type: 'address' }, + { + name: 'request', + internalType: 'struct IVault.ExitPoolRequest', + type: 'tuple', + components: [ + { + name: 'assets', + internalType: 'contract IAsset[]', + type: 'address[]', + }, + { + name: 'minAmountsOut', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + { name: 'toInternalBalance', internalType: 'bool', type: 'bool' }, + ], + }, + ], + name: 'exitPool', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'recipient', + internalType: 'contract IFlashLoanRecipient', + type: 'address', + }, + { name: 'tokens', internalType: 'contract IERC20[]', type: 'address[]' }, + { name: 'amounts', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + name: 'flashLoan', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'getActionId', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getAuthorizer', + outputs: [{ name: '', internalType: 'contract IAuthorizer', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getDomainSeparator', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'tokens', internalType: 'contract IERC20[]', type: 'address[]' }, + ], + name: 'getInternalBalance', + outputs: [{ name: 'balances', internalType: 'uint256[]', type: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'user', internalType: 'address', type: 'address' }], + name: 'getNextNonce', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPausedState', + outputs: [ + { name: 'paused', internalType: 'bool', type: 'bool' }, + { name: 'pauseWindowEndTime', internalType: 'uint256', type: 'uint256' }, + { name: 'bufferPeriodEndTime', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'poolId', internalType: 'bytes32', type: 'bytes32' }], + name: 'getPool', + outputs: [ + { name: '', internalType: 'address', type: 'address' }, + { + name: '', + internalType: 'enum IVault.PoolSpecialization', + type: 'uint8', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + ], + name: 'getPoolTokenInfo', + outputs: [ + { name: 'cash', internalType: 'uint256', type: 'uint256' }, + { name: 'managed', internalType: 'uint256', type: 'uint256' }, + { name: 'lastChangeBlock', internalType: 'uint256', type: 'uint256' }, + { name: 'assetManager', internalType: 'address', type: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'poolId', internalType: 'bytes32', type: 'bytes32' }], + name: 'getPoolTokens', + outputs: [ + { name: 'tokens', internalType: 'contract IERC20[]', type: 'address[]' }, + { name: 'balances', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'lastChangeBlock', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getProtocolFeesCollector', + outputs: [ + { + name: '', + internalType: 'contract ProtocolFeesCollector', + type: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'relayer', internalType: 'address', type: 'address' }, + ], + name: 'hasApprovedRelayer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { + name: 'request', + internalType: 'struct IVault.JoinPoolRequest', + type: 'tuple', + components: [ + { + name: 'assets', + internalType: 'contract IAsset[]', + type: 'address[]', + }, + { + name: 'maxAmountsIn', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + { name: 'fromInternalBalance', internalType: 'bool', type: 'bool' }, + ], + }, + ], + name: 'joinPool', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { + name: 'ops', + internalType: 'struct IVault.PoolBalanceOp[]', + type: 'tuple[]', + components: [ + { + name: 'kind', + internalType: 'enum IVault.PoolBalanceOpKind', + type: 'uint8', + }, + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], + name: 'managePoolBalance', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'ops', + internalType: 'struct IVault.UserBalanceOp[]', + type: 'tuple[]', + components: [ + { + name: 'kind', + internalType: 'enum IVault.UserBalanceOpKind', + type: 'uint8', + }, + { name: 'asset', internalType: 'contract IAsset', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'sender', internalType: 'address', type: 'address' }, + { + name: 'recipient', + internalType: 'address payable', + type: 'address', + }, + ], + }, + ], + name: 'manageUserBalance', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'kind', internalType: 'enum IVault.SwapKind', type: 'uint8' }, + { + name: 'swaps', + internalType: 'struct IVault.BatchSwapStep[]', + type: 'tuple[]', + components: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'assetInIndex', internalType: 'uint256', type: 'uint256' }, + { name: 'assetOutIndex', internalType: 'uint256', type: 'uint256' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + }, + { name: 'assets', internalType: 'contract IAsset[]', type: 'address[]' }, + { + name: 'funds', + internalType: 'struct IVault.FundManagement', + type: 'tuple', + components: [ + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'fromInternalBalance', internalType: 'bool', type: 'bool' }, + { + name: 'recipient', + internalType: 'address payable', + type: 'address', + }, + { name: 'toInternalBalance', internalType: 'bool', type: 'bool' }, + ], + }, + ], + name: 'queryBatchSwap', + outputs: [{ name: '', internalType: 'int256[]', type: 'int256[]' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'specialization', + internalType: 'enum IVault.PoolSpecialization', + type: 'uint8', + }, + ], + name: 'registerPool', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'tokens', internalType: 'contract IERC20[]', type: 'address[]' }, + { name: 'assetManagers', internalType: 'address[]', type: 'address[]' }, + ], + name: 'registerTokens', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'newAuthorizer', + internalType: 'contract IAuthorizer', + type: 'address', + }, + ], + name: 'setAuthorizer', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'paused', internalType: 'bool', type: 'bool' }], + name: 'setPaused', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'relayer', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + ], + name: 'setRelayerApproval', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'singleSwap', + internalType: 'struct IVault.SingleSwap', + type: 'tuple', + components: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'kind', internalType: 'enum IVault.SwapKind', type: 'uint8' }, + { name: 'assetIn', internalType: 'contract IAsset', type: 'address' }, + { + name: 'assetOut', + internalType: 'contract IAsset', + type: 'address', + }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + }, + { + name: 'funds', + internalType: 'struct IVault.FundManagement', + type: 'tuple', + components: [ + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'fromInternalBalance', internalType: 'bool', type: 'bool' }, + { + name: 'recipient', + internalType: 'address payable', + type: 'address', + }, + { name: 'toInternalBalance', internalType: 'bool', type: 'bool' }, + ], + }, + { name: 'limit', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + ], + name: 'swap', + outputs: [{ name: 'amountCalculated', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { type: 'receive', stateMutability: 'payable' }, +] as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xBA12222222228d8Ba445958a75a0704d566BF2C8) + */ +export const balancerV2VaultAddress = { + 1: '0xBA12222222228d8Ba445958a75a0704d566BF2C8', +} as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xBA12222222228d8Ba445958a75a0704d566BF2C8) + */ +export const balancerV2VaultConfig = { + address: balancerV2VaultAddress, + abi: balancerV2VaultAbi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BalancerV2WeightedPoolV4 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x3ff3a210e57cfe679d9ad1e9ba6453a716c56a2e) + */ +export const balancerV2WeightedPoolV4Abi = [ + { + type: 'constructor', + inputs: [ + { + name: 'params', + internalType: 'struct WeightedPool.NewPoolParams', + type: 'tuple', + components: [ + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'symbol', internalType: 'string', type: 'string' }, + { + name: 'tokens', + internalType: 'contract IERC20[]', + type: 'address[]', + }, + { + name: 'normalizedWeights', + internalType: 'uint256[]', + type: 'uint256[]', + }, + { + name: 'rateProviders', + internalType: 'contract IRateProvider[]', + type: 'address[]', + }, + { + name: 'assetManagers', + internalType: 'address[]', + type: 'address[]', + }, + { + name: 'swapFeePercentage', + internalType: 'uint256', + type: 'uint256', + }, + ], + }, + { name: 'vault', internalType: 'contract IVault', type: 'address' }, + { + name: 'protocolFeeProvider', + internalType: 'contract IProtocolFeePercentagesProvider', + type: 'address', + }, + { name: 'pauseWindowDuration', internalType: 'uint256', type: 'uint256' }, + { + name: 'bufferPeriodDuration', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'version', internalType: 'string', type: 'string' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'spender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [{ name: 'paused', internalType: 'bool', type: 'bool', indexed: false }], + name: 'PausedStateChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'feeType', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'protocolFeePercentage', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ProtocolFeePercentageCacheUpdated', + }, + { + type: 'event', + anonymous: false, + inputs: [{ name: 'enabled', internalType: 'bool', type: 'bool', indexed: false }], + name: 'RecoveryModeStateChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'swapFeePercentage', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'SwapFeePercentageChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [], + name: 'DELEGATE_PROTOCOL_SWAP_FEES_SENTINEL', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'disableRecoveryMode', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'enableRecoveryMode', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'getATHRateProduct', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'getActionId', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getActualSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getAuthorizer', + outputs: [{ name: '', internalType: 'contract IAuthorizer', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getDomainSeparator', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getInvariant', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getLastPostJoinExitInvariant', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'getNextNonce', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getNormalizedWeights', + outputs: [{ name: '', internalType: 'uint256[]', type: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getOwner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPausedState', + outputs: [ + { name: 'paused', internalType: 'bool', type: 'bool' }, + { name: 'pauseWindowEndTime', internalType: 'uint256', type: 'uint256' }, + { name: 'bufferPeriodEndTime', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPoolId', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'feeType', internalType: 'uint256', type: 'uint256' }], + name: 'getProtocolFeePercentageCache', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getProtocolFeesCollector', + outputs: [ + { + name: '', + internalType: 'contract IProtocolFeesCollector', + type: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getProtocolSwapFeeDelegation', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getRateProviders', + outputs: [{ name: '', internalType: 'contract IRateProvider[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getScalingFactors', + outputs: [{ name: '', internalType: 'uint256[]', type: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getSwapFeePercentage', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getVault', + outputs: [{ name: '', internalType: 'contract IVault', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'inRecoveryMode', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'addedValue', internalType: 'uint256', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'nonces', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'balances', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'lastChangeBlock', internalType: 'uint256', type: 'uint256' }, + { + name: 'protocolSwapFeePercentage', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + name: 'onExitPool', + outputs: [ + { name: '', internalType: 'uint256[]', type: 'uint256[]' }, + { name: '', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'balances', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'lastChangeBlock', internalType: 'uint256', type: 'uint256' }, + { + name: 'protocolSwapFeePercentage', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + name: 'onJoinPool', + outputs: [ + { name: '', internalType: 'uint256[]', type: 'uint256[]' }, + { name: '', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'request', + internalType: 'struct IPoolSwapStructs.SwapRequest', + type: 'tuple', + components: [ + { name: 'kind', internalType: 'enum IVault.SwapKind', type: 'uint8' }, + { name: 'tokenIn', internalType: 'contract IERC20', type: 'address' }, + { + name: 'tokenOut', + internalType: 'contract IERC20', + type: 'address', + }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'lastChangeBlock', internalType: 'uint256', type: 'uint256' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + }, + { name: 'balanceTokenIn', internalType: 'uint256', type: 'uint256' }, + { name: 'balanceTokenOut', internalType: 'uint256', type: 'uint256' }, + ], + name: 'onSwap', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'balances', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'lastChangeBlock', internalType: 'uint256', type: 'uint256' }, + { + name: 'protocolSwapFeePercentage', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + name: 'queryExit', + outputs: [ + { name: 'bptIn', internalType: 'uint256', type: 'uint256' }, + { name: 'amountsOut', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'poolId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'balances', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'lastChangeBlock', internalType: 'uint256', type: 'uint256' }, + { + name: 'protocolSwapFeePercentage', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'userData', internalType: 'bytes', type: 'bytes' }, + ], + name: 'queryJoin', + outputs: [ + { name: 'bptOut', internalType: 'uint256', type: 'uint256' }, + { name: 'amountsIn', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'poolConfig', internalType: 'bytes', type: 'bytes' }, + ], + name: 'setAssetManagerPoolConfig', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'swapFeePercentage', internalType: 'uint256', type: 'uint256' }], + name: 'setSwapFeePercentage', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'updateProtocolFeePercentageCache', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'version', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, +] as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x3ff3a210e57cfe679d9ad1e9ba6453a716c56a2e) + */ +export const balancerV2WeightedPoolV4Address = { + 1: '0x3ff3a210e57cFe679D9AD1e9bA6453A716C56a2e', +} as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x3ff3a210e57cfe679d9ad1e9ba6453a716c56a2e) + */ +export const balancerV2WeightedPoolV4Config = { + address: balancerV2WeightedPoolV4Address, + abi: balancerV2WeightedPoolV4Abi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SFC +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * [__View Contract on Sonic Sonic Explorer__](https://explorer.soniclabs.com/address/0x0aB8f3b709A52c096f33702fE8153776472305ed) + */ +export const sfcAbi = [ + { type: 'constructor', inputs: [], stateMutability: 'nonpayable' }, + { + type: 'error', + inputs: [{ name: 'target', internalType: 'address', type: 'address' }], + name: 'AddressEmptyCode', + }, + { type: 'error', inputs: [], name: 'AlreadyRedirected' }, + { + type: 'error', + inputs: [{ name: 'implementation', internalType: 'address', type: 'address' }], + name: 'ERC1967InvalidImplementation', + }, + { type: 'error', inputs: [], name: 'ERC1967NonPayable' }, + { type: 'error', inputs: [], name: 'FailedCall' }, + { type: 'error', inputs: [], name: 'InsufficientSelfStake' }, + { type: 'error', inputs: [], name: 'InvalidInitialization' }, + { type: 'error', inputs: [], name: 'MalformedPubkey' }, + { type: 'error', inputs: [], name: 'NoUnresolvedTreasuryFees' }, + { type: 'error', inputs: [], name: 'NotAuthorized' }, + { type: 'error', inputs: [], name: 'NotDeactivatedStatus' }, + { type: 'error', inputs: [], name: 'NotDriverAuth' }, + { type: 'error', inputs: [], name: 'NotEnoughEpochsPassed' }, + { type: 'error', inputs: [], name: 'NotEnoughTimePassed' }, + { type: 'error', inputs: [], name: 'NotInitializing' }, + { type: 'error', inputs: [], name: 'NothingToStash' }, + { + type: 'error', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'OwnableInvalidOwner', + }, + { + type: 'error', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'OwnableUnauthorizedAccount', + }, + { type: 'error', inputs: [], name: 'PubkeyUsedByOtherValidator' }, + { type: 'error', inputs: [], name: 'Redirected' }, + { type: 'error', inputs: [], name: 'RefundRatioTooHigh' }, + { type: 'error', inputs: [], name: 'RequestExists' }, + { type: 'error', inputs: [], name: 'RequestNotExists' }, + { type: 'error', inputs: [], name: 'SameAddress' }, + { type: 'error', inputs: [], name: 'SameRedirectionAuthorizer' }, + { type: 'error', inputs: [], name: 'StakeIsFullySlashed' }, + { type: 'error', inputs: [], name: 'StakeSubscriberFailed' }, + { type: 'error', inputs: [], name: 'TransferFailed' }, + { type: 'error', inputs: [], name: 'TransfersNotAllowed' }, + { type: 'error', inputs: [], name: 'TreasuryNotSet' }, + { type: 'error', inputs: [], name: 'UUPSUnauthorizedCallContext' }, + { + type: 'error', + inputs: [{ name: 'slot', internalType: 'bytes32', type: 'bytes32' }], + name: 'UUPSUnsupportedProxiableUUID', + }, + { type: 'error', inputs: [], name: 'ValidatorDelegationLimitExceeded' }, + { type: 'error', inputs: [], name: 'ValidatorExists' }, + { type: 'error', inputs: [], name: 'ValidatorNotActive' }, + { type: 'error', inputs: [], name: 'ValidatorNotExists' }, + { type: 'error', inputs: [], name: 'ValidatorNotSlashed' }, + { type: 'error', inputs: [], name: 'ValueTooLarge' }, + { type: 'error', inputs: [], name: 'ZeroAddress' }, + { type: 'error', inputs: [], name: 'ZeroAmount' }, + { type: 'error', inputs: [], name: 'ZeroRewards' }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + ], + name: 'AnnouncedRedirection', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'BurntNativeTokens', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'validatorID', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'status', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ChangedValidatorStatus', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'toValidatorID', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'rewards', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'ClaimedRewards', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'validatorID', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { name: 'auth', internalType: 'address', type: 'address', indexed: true }, + { + name: 'createdEpoch', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'createdTime', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'CreatedValidator', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'validatorID', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'deactivatedEpoch', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'deactivatedTime', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'DeactivatedValidator', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'toValidatorID', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Delegated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'version', + internalType: 'uint64', + type: 'uint64', + indexed: false, + }, + ], + name: 'Initialized', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'validatorID', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'RefundedSlashedLegacyDelegation', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'toValidatorID', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'rewards', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'RestakedRewards', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'TreasuryFeesResolved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'toValidatorID', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { name: 'wrID', internalType: 'uint256', type: 'uint256', indexed: true }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Undelegated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'validatorID', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'refundRatio', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'UpdatedSlashingRefundRatio', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'implementation', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'Upgraded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'toValidatorID', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { name: 'wrID', internalType: 'uint256', type: 'uint256', indexed: true }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'penalty', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Withdrawn', + }, + { + type: 'function', + inputs: [], + name: 'UPGRADE_INTERFACE_VERSION', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + { name: 'syncPubkey', internalType: 'bool', type: 'bool' }, + ], + name: '_syncValidator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'to', internalType: 'address', type: 'address' }], + name: 'announceRedirection', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'burnNativeTokens', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [{ name: 'toValidatorID', internalType: 'uint256', type: 'uint256' }], + name: 'claimRewards', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'constsAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pubkey', internalType: 'bytes', type: 'bytes' }], + name: 'createValidator', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [], + name: 'currentEpoch', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'currentSealedEpoch', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + { name: 'status', internalType: 'uint256', type: 'uint256' }, + ], + name: 'deactivateValidator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'toValidatorID', internalType: 'uint256', type: 'uint256' }], + name: 'delegate', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'epoch', internalType: 'uint256', type: 'uint256' }, + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getEpochAccumulatedOriginatedTxsFee', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'epoch', internalType: 'uint256', type: 'uint256' }, + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getEpochAccumulatedRewardPerToken', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'epoch', internalType: 'uint256', type: 'uint256' }, + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getEpochAccumulatedUptime', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'epoch', internalType: 'uint256', type: 'uint256' }, + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getEpochAverageUptime', + outputs: [{ name: '', internalType: 'uint64', type: 'uint64' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'epoch', internalType: 'uint256', type: 'uint256' }], + name: 'getEpochEndBlock', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'epoch', internalType: 'uint256', type: 'uint256' }, + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getEpochOfflineBlocks', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'epoch', internalType: 'uint256', type: 'uint256' }, + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getEpochOfflineTime', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'epoch', internalType: 'uint256', type: 'uint256' }, + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getEpochReceivedStake', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'epoch', internalType: 'uint256', type: 'uint256' }], + name: 'getEpochSnapshot', + outputs: [ + { name: 'endTime', internalType: 'uint256', type: 'uint256' }, + { name: 'endBlock', internalType: 'uint256', type: 'uint256' }, + { name: 'epochFee', internalType: 'uint256', type: 'uint256' }, + { name: 'baseRewardPerSecond', internalType: 'uint256', type: 'uint256' }, + { name: 'totalStake', internalType: 'uint256', type: 'uint256' }, + { name: 'totalSupply', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'epoch', internalType: 'uint256', type: 'uint256' }], + name: 'getEpochValidatorIDs', + outputs: [{ name: '', internalType: 'uint256[]', type: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'delegator', internalType: 'address', type: 'address' }], + name: 'getRedirection', + outputs: [{ name: 'receiver', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'delegator', internalType: 'address', type: 'address' }], + name: 'getRedirectionRequest', + outputs: [{ name: 'receiver', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'validatorID', internalType: 'uint256', type: 'uint256' }], + name: 'getSelfStake', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'delegator', internalType: 'address', type: 'address' }, + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getStake', + outputs: [{ name: 'stake', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'validatorID', internalType: 'uint256', type: 'uint256' }], + name: 'getValidator', + outputs: [ + { name: 'status', internalType: 'uint256', type: 'uint256' }, + { name: 'receivedStake', internalType: 'uint256', type: 'uint256' }, + { name: 'auth', internalType: 'address', type: 'address' }, + { name: 'createdEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'createdTime', internalType: 'uint256', type: 'uint256' }, + { name: 'deactivatedTime', internalType: 'uint256', type: 'uint256' }, + { name: 'deactivatedEpoch', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'auth', internalType: 'address', type: 'address' }], + name: 'getValidatorID', + outputs: [{ name: 'validatorID', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'validatorID', internalType: 'uint256', type: 'uint256' }], + name: 'getValidatorPubkey', + outputs: [{ name: 'pubkey', internalType: 'bytes', type: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'delegator', internalType: 'address', type: 'address' }, + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + { name: 'wrID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getWithdrawalRequest', + outputs: [ + { name: 'epoch', internalType: 'uint256', type: 'uint256' }, + { name: 'time', internalType: 'uint256', type: 'uint256' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'sealedEpoch', internalType: 'uint256', type: 'uint256' }, + { name: '_totalSupply', internalType: 'uint256', type: 'uint256' }, + { name: 'nodeDriver', internalType: 'address', type: 'address' }, + { name: '_c', internalType: 'address', type: 'address' }, + { name: 'owner', internalType: 'address', type: 'address' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + ], + name: 'initiateRedirection', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'validatorID', internalType: 'uint256', type: 'uint256' }], + name: 'isSlashed', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'amount', internalType: 'uint256', type: 'uint256' }], + name: 'issueTokens', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'lastValidatorID', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'delegator', internalType: 'address', type: 'address' }, + { name: 'toValidatorID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'pendingRewards', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'proxiableUUID', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'pubkeyAddress', internalType: 'address', type: 'address' }], + name: 'pubkeyAddressToValidatorID', + outputs: [{ name: 'validatorID', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'to', internalType: 'address', type: 'address' }], + name: 'redirect', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'redirectionAuthorizer', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'resolveTreasuryFees', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'toValidatorID', internalType: 'uint256', type: 'uint256' }], + name: 'restakeRewards', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'delegator', internalType: 'address', type: 'address' }, + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'rewardsStash', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'offlineTime', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'offlineBlocks', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'uptimes', internalType: 'uint256[]', type: 'uint256[]' }, + { + name: 'originatedTxsFee', + internalType: 'uint256[]', + type: 'uint256[]', + }, + ], + name: 'sealEpoch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'nextValidatorIDs', + internalType: 'uint256[]', + type: 'uint256[]', + }, + ], + name: 'sealEpochValidators', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'delegator', internalType: 'address', type: 'address' }, + { name: 'toValidatorID', internalType: 'uint256', type: 'uint256' }, + { name: 'stake', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setGenesisDelegation', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'auth', internalType: 'address', type: 'address' }, + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + { name: 'pubkey', internalType: 'bytes', type: 'bytes' }, + { name: 'createdTime', internalType: 'uint256', type: 'uint256' }, + ], + name: 'setGenesisValidator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'v', internalType: 'address', type: 'address' }], + name: 'setRedirectionAuthorizer', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'validatorID', internalType: 'uint256', type: 'uint256' }], + name: 'slashingRefundRatio', + outputs: [{ name: 'refundRatio', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'stakeSubscriberAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'delegator', internalType: 'address', type: 'address' }, + { name: 'toValidatorID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'stashRewards', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'delegator', internalType: 'address', type: 'address' }, + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'stashedRewardsUntilEpoch', + outputs: [{ name: 'epoch', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalActiveStake', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalStake', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'treasuryAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'toValidatorID', internalType: 'uint256', type: 'uint256' }, + { name: 'wrID', internalType: 'uint256', type: 'uint256' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'undelegate', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'unresolvedTreasuryFees', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'v', internalType: 'address', type: 'address' }], + name: 'updateConstsAddress', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'validatorID', internalType: 'uint256', type: 'uint256' }, + { name: 'refundRatio', internalType: 'uint256', type: 'uint256' }, + ], + name: 'updateSlashingRefundRatio', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'v', internalType: 'address', type: 'address' }], + name: 'updateStakeSubscriberAddress', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'v', internalType: 'address', type: 'address' }], + name: 'updateTreasuryAddress', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'newImplementation', internalType: 'address', type: 'address' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'upgradeToAndCall', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [], + name: 'version', + outputs: [{ name: '', internalType: 'bytes3', type: 'bytes3' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [ + { name: 'toValidatorID', internalType: 'uint256', type: 'uint256' }, + { name: 'wrID', internalType: 'uint256', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, + { type: 'receive', stateMutability: 'payable' }, +] as const + +/** + * [__View Contract on Sonic Sonic Explorer__](https://explorer.soniclabs.com/address/0x0aB8f3b709A52c096f33702fE8153776472305ed) + */ +export const sfcAddress = { + 146: '0x0aB8f3b709A52c096f33702fE8153776472305ed', +} as const + +/** + * [__View Contract on Sonic Sonic Explorer__](https://explorer.soniclabs.com/address/0x0aB8f3b709A52c096f33702fE8153776472305ed) + */ +export const sfcConfig = { address: sfcAddress, abi: sfcAbi } as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SonicStaking +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * [__View Contract on Sonic Sonic Explorer__](https://explorer.soniclabs.com/address/0xd5f7fc8ba92756a34693baa386edcc8dd5b3f141) + */ +export const sonicStakingAbi = [ + { type: 'constructor', inputs: [], stateMutability: 'nonpayable' }, + { type: 'error', inputs: [], name: 'AccessControlBadConfirmation' }, + { + type: 'error', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'neededRole', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'AccessControlUnauthorizedAccount', + }, + { + type: 'error', + inputs: [{ name: 'target', internalType: 'address', type: 'address' }], + name: 'AddressEmptyCode', + }, + { type: 'error', inputs: [], name: 'ArrayLengthMismatch' }, + { type: 'error', inputs: [], name: 'DelegateAmountCannotBeZero' }, + { type: 'error', inputs: [], name: 'DepositPaused' }, + { type: 'error', inputs: [], name: 'DepositTooSmall' }, + { type: 'error', inputs: [], name: 'DonationAmountCannotBeZero' }, + { type: 'error', inputs: [], name: 'DonationAmountTooSmall' }, + { type: 'error', inputs: [], name: 'ECDSAInvalidSignature' }, + { + type: 'error', + inputs: [{ name: 'length', internalType: 'uint256', type: 'uint256' }], + name: 'ECDSAInvalidSignatureLength', + }, + { + type: 'error', + inputs: [{ name: 's', internalType: 'bytes32', type: 'bytes32' }], + name: 'ECDSAInvalidSignatureS', + }, + { + type: 'error', + inputs: [{ name: 'implementation', internalType: 'address', type: 'address' }], + name: 'ERC1967InvalidImplementation', + }, + { type: 'error', inputs: [], name: 'ERC1967NonPayable' }, + { + type: 'error', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'allowance', internalType: 'uint256', type: 'uint256' }, + { name: 'needed', internalType: 'uint256', type: 'uint256' }, + ], + name: 'ERC20InsufficientAllowance', + }, + { + type: 'error', + inputs: [ + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'balance', internalType: 'uint256', type: 'uint256' }, + { name: 'needed', internalType: 'uint256', type: 'uint256' }, + ], + name: 'ERC20InsufficientBalance', + }, + { + type: 'error', + inputs: [{ name: 'approver', internalType: 'address', type: 'address' }], + name: 'ERC20InvalidApprover', + }, + { + type: 'error', + inputs: [{ name: 'receiver', internalType: 'address', type: 'address' }], + name: 'ERC20InvalidReceiver', + }, + { + type: 'error', + inputs: [{ name: 'sender', internalType: 'address', type: 'address' }], + name: 'ERC20InvalidSender', + }, + { + type: 'error', + inputs: [{ name: 'spender', internalType: 'address', type: 'address' }], + name: 'ERC20InvalidSpender', + }, + { + type: 'error', + inputs: [{ name: 'deadline', internalType: 'uint256', type: 'uint256' }], + name: 'ERC2612ExpiredSignature', + }, + { + type: 'error', + inputs: [ + { name: 'signer', internalType: 'address', type: 'address' }, + { name: 'owner', internalType: 'address', type: 'address' }, + ], + name: 'ERC2612InvalidSigner', + }, + { type: 'error', inputs: [], name: 'FailedCall' }, + { + type: 'error', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'currentNonce', internalType: 'uint256', type: 'uint256' }, + ], + name: 'InvalidAccountNonce', + }, + { type: 'error', inputs: [], name: 'InvalidInitialization' }, + { type: 'error', inputs: [], name: 'NativeTransferFailed' }, + { + type: 'error', + inputs: [{ name: 'validatorId', internalType: 'uint256', type: 'uint256' }], + name: 'NoDelegationForValidator', + }, + { type: 'error', inputs: [], name: 'NotInitializing' }, + { + type: 'error', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'OwnableInvalidOwner', + }, + { + type: 'error', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'OwnableUnauthorizedAccount', + }, + { type: 'error', inputs: [], name: 'PausedValueDidNotChange' }, + { type: 'error', inputs: [], name: 'ProtocolFeeTooHigh' }, + { type: 'error', inputs: [], name: 'ProtocolFeeTransferFailed' }, + { type: 'error', inputs: [], name: 'ReentrancyGuardReentrantCall' }, + { type: 'error', inputs: [], name: 'RewardsClaimedTooSmall' }, + { type: 'error', inputs: [], name: 'SFCAddressCannotBeZero' }, + { type: 'error', inputs: [], name: 'SenderNotSFC' }, + { + type: 'error', + inputs: [{ name: 'refundRatio', internalType: 'uint256', type: 'uint256' }], + name: 'SfcSlashMustBeAccepted', + }, + { type: 'error', inputs: [], name: 'TreasuryAddressCannotBeZero' }, + { type: 'error', inputs: [], name: 'UUPSUnauthorizedCallContext' }, + { + type: 'error', + inputs: [{ name: 'slot', internalType: 'bytes32', type: 'bytes32' }], + name: 'UUPSUnsupportedProxiableUUID', + }, + { + type: 'error', + inputs: [{ name: 'withdrawId', internalType: 'uint256', type: 'uint256' }], + name: 'UnauthorizedWithdraw', + }, + { type: 'error', inputs: [], name: 'UndelegateAmountCannotBeZero' }, + { + type: 'error', + inputs: [{ name: 'validatorId', internalType: 'uint256', type: 'uint256' }], + name: 'UndelegateAmountExceedsDelegated', + }, + { type: 'error', inputs: [], name: 'UndelegateAmountExceedsPool' }, + { type: 'error', inputs: [], name: 'UndelegateAmountTooSmall' }, + { type: 'error', inputs: [], name: 'UndelegateFromPoolPaused' }, + { type: 'error', inputs: [], name: 'UndelegatePaused' }, + { type: 'error', inputs: [], name: 'UnsupportedWithdrawKind' }, + { type: 'error', inputs: [], name: 'UserWithdrawsMaxSizeCannotBeZero' }, + { type: 'error', inputs: [], name: 'UserWithdrawsSkipTooLarge' }, + { + type: 'error', + inputs: [{ name: 'withdrawId', internalType: 'uint256', type: 'uint256' }], + name: 'WithdrawAlreadyProcessed', + }, + { + type: 'error', + inputs: [{ name: 'withdrawId', internalType: 'uint256', type: 'uint256' }], + name: 'WithdrawDelayNotElapsed', + }, + { + type: 'error', + inputs: [{ name: 'withdrawId', internalType: 'uint256', type: 'uint256' }], + name: 'WithdrawIdDoesNotExist', + }, + { type: 'error', inputs: [], name: 'WithdrawsPaused' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'spender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'validatorId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'amountAssets', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Delegated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'newValue', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'DepositPausedUpdated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'user', internalType: 'address', type: 'address', indexed: true }, + { + name: 'amountAssets', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'amountShares', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Deposited', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'user', internalType: 'address', type: 'address', indexed: true }, + { + name: 'amountAssets', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Donated', + }, + { type: 'event', anonymous: false, inputs: [], name: 'EIP712DomainChanged' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'version', + internalType: 'uint64', + type: 'uint64', + indexed: false, + }, + ], + name: 'Initialized', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'withdrawId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'amountAssetsWithdrawn', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { name: 'emergency', internalType: 'bool', type: 'bool', indexed: true }, + ], + name: 'OperatorClawBackExecuted', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'withdrawId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'validatorId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'amountAssets', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'OperatorClawBackInitiated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newFeeBIPS', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'ProtocolFeeUpdated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'amountClaimed', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'protocolFee', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'RewardsClaimed', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'previousAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + { + name: 'newAdminRole', + internalType: 'bytes32', + type: 'bytes32', + indexed: true, + }, + ], + name: 'RoleAdminChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleGranted', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32', indexed: true }, + { + name: 'account', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'sender', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'RoleRevoked', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Transfer', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newTreasury', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'TreasuryUpdated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'newValue', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'UndelegateFromPoolPausedUpdated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'newValue', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'UndelegatePausedUpdated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'user', internalType: 'address', type: 'address', indexed: true }, + { + name: 'withdrawId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'validatorId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'amountAssets', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'kind', + internalType: 'enum SonicStaking.WithdrawKind', + type: 'uint8', + indexed: false, + }, + ], + name: 'Undelegated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'implementation', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'Upgraded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'delay', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'WithdrawDelaySet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'newValue', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'WithdrawPausedUpdated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'user', internalType: 'address', type: 'address', indexed: true }, + { + name: 'withdrawId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'amountAssets', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'kind', + internalType: 'enum SonicStaking.WithdrawKind', + type: 'uint8', + indexed: false, + }, + { name: 'emergency', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'Withdrawn', + }, + { + type: 'function', + inputs: [], + name: 'CLAIM_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'DEFAULT_ADMIN_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'MAX_PROTOCOL_FEE_BIPS', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'MIN_CLAIM_REWARDS_AMOUNT', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'MIN_DEPOSIT', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'MIN_DONATION_AMOUNT', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'MIN_UNDELEGATE_AMOUNT_SHARES', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'OPERATOR_ROLE', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'SFC', + outputs: [{ name: '', internalType: 'contract ISFC', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'UPGRADE_INTERFACE_VERSION', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'value', internalType: 'uint256', type: 'uint256' }], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + ], + name: 'burnFrom', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'validatorIds', internalType: 'uint256[]', type: 'uint256[]' }], + name: 'claimRewards', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'sharesAmount', internalType: 'uint256', type: 'uint256' }], + name: 'convertToAssets', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'assetAmount', internalType: 'uint256', type: 'uint256' }], + name: 'convertToShares', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'validatorId', internalType: 'uint256', type: 'uint256' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'delegate', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'deposit', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [], + name: 'depositPaused', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'donate', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [], + name: 'eip712Domain', + outputs: [ + { name: 'fields', internalType: 'bytes1', type: 'bytes1' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'version', internalType: 'string', type: 'string' }, + { name: 'chainId', internalType: 'uint256', type: 'uint256' }, + { name: 'verifyingContract', internalType: 'address', type: 'address' }, + { name: 'salt', internalType: 'bytes32', type: 'bytes32' }, + { name: 'extensions', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getRate', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'role', internalType: 'bytes32', type: 'bytes32' }], + name: 'getRoleAdmin', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'skip', internalType: 'uint256', type: 'uint256' }, + { name: 'maxSize', internalType: 'uint256', type: 'uint256' }, + { name: 'reverseOrder', internalType: 'bool', type: 'bool' }, + ], + name: 'getUserWithdraws', + outputs: [ + { + name: '', + internalType: 'struct SonicStaking.WithdrawRequest[]', + type: 'tuple[]', + components: [ + { + name: 'kind', + internalType: 'enum SonicStaking.WithdrawKind', + type: 'uint8', + }, + { name: 'validatorId', internalType: 'uint256', type: 'uint256' }, + { name: 'assetAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'isWithdrawn', internalType: 'bool', type: 'bool' }, + { + name: 'requestTimestamp', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'user', internalType: 'address', type: 'address' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'withdrawId', internalType: 'uint256', type: 'uint256' }], + name: 'getWithdrawRequest', + outputs: [ + { + name: '', + internalType: 'struct SonicStaking.WithdrawRequest', + type: 'tuple', + components: [ + { + name: 'kind', + internalType: 'enum SonicStaking.WithdrawKind', + type: 'uint8', + }, + { name: 'validatorId', internalType: 'uint256', type: 'uint256' }, + { name: 'assetAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'isWithdrawn', internalType: 'bool', type: 'bool' }, + { + name: 'requestTimestamp', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'user', internalType: 'address', type: 'address' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'grantRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'hasRole', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: '_sfc', internalType: 'contract ISFC', type: 'address' }, + { name: '_treasury', internalType: 'address', type: 'address' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'nonces', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'withdrawId', internalType: 'uint256', type: 'uint256' }, + { name: 'emergency', internalType: 'bool', type: 'bool' }, + ], + name: 'operatorExecuteClawBack', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'validatorId', internalType: 'uint256', type: 'uint256' }, + { name: 'amountAssets', internalType: 'uint256', type: 'uint256' }, + ], + name: 'operatorInitiateClawBack', + outputs: [ + { name: 'withdrawId', internalType: 'uint256', type: 'uint256' }, + { + name: 'actualAmountUndelegated', + internalType: 'uint256', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'pendingClawBackAmount', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'protocolFeeBIPS', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'proxiableUUID', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'callerConfirmation', internalType: 'address', type: 'address' }, + ], + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'role', internalType: 'bytes32', type: 'bytes32' }, + { name: 'account', internalType: 'address', type: 'address' }, + ], + name: 'revokeRole', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'newValue', internalType: 'bool', type: 'bool' }], + name: 'setDepositPaused', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'newFeeBIPS', internalType: 'uint256', type: 'uint256' }], + name: 'setProtocolFeeBIPS', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'newTreasury', internalType: 'address', type: 'address' }], + name: 'setTreasury', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'newValue', internalType: 'bool', type: 'bool' }], + name: 'setUndelegateFromPoolPaused', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'newValue', internalType: 'bool', type: 'bool' }], + name: 'setUndelegatePaused', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'delay', internalType: 'uint256', type: 'uint256' }], + name: 'setWithdrawDelay', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'newValue', internalType: 'bool', type: 'bool' }], + name: 'setWithdrawPaused', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalAssets', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalDelegated', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalPool', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'treasury', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'validatorId', internalType: 'uint256', type: 'uint256' }, + { name: 'amountShares', internalType: 'uint256', type: 'uint256' }, + ], + name: 'undelegate', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'amountShares', internalType: 'uint256', type: 'uint256' }], + name: 'undelegateFromPool', + outputs: [{ name: 'withdrawId', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'undelegateFromPoolPaused', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'validatorIds', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'amountShares', internalType: 'uint256[]', type: 'uint256[]' }, + ], + name: 'undelegateMany', + outputs: [{ name: 'withdrawIds', internalType: 'uint256[]', type: 'uint256[]' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'undelegatePaused', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'newImplementation', internalType: 'address', type: 'address' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'upgradeToAndCall', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [{ name: 'user', internalType: 'address', type: 'address' }], + name: 'userNumWithdraws', + outputs: [{ name: 'numWithdraws', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'index', internalType: 'uint256', type: 'uint256' }, + ], + name: 'userWithdraws', + outputs: [{ name: 'withdrawId', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'withdrawId', internalType: 'uint256', type: 'uint256' }, + { name: 'emergency', internalType: 'bool', type: 'bool' }, + ], + name: 'withdraw', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'withdrawCounter', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'withdrawDelay', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'withdrawIds', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'emergency', internalType: 'bool', type: 'bool' }, + ], + name: 'withdrawMany', + outputs: [ + { + name: 'amountsWithdrawn', + internalType: 'uint256[]', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'withdrawPaused', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { type: 'receive', stateMutability: 'payable' }, +] as const + +/** + * [__View Contract on Sonic Sonic Explorer__](https://explorer.soniclabs.com/address/0xd5f7fc8ba92756a34693baa386edcc8dd5b3f141) + */ +export const sonicStakingAddress = { + 146: '0xD5F7FC8ba92756a34693bAA386Edcc8Dd5B3F141', +} as const + +/** + * [__View Contract on Sonic Sonic Explorer__](https://explorer.soniclabs.com/address/0xd5f7fc8ba92756a34693baa386edcc8dd5b3f141) + */ +export const sonicStakingConfig = { + address: sonicStakingAddress, + abi: sonicStakingAbi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SonicStakingWithdrawRequestHelper +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * [__View Contract on Sonic Sonic Explorer__](https://explorer.soniclabs.com/address/0x52b16e3d7d25ba64f242e59f9a74799ecc432d78) + */ +export const sonicStakingWithdrawRequestHelperAbi = [ + { + type: 'constructor', + inputs: [ + { + name: '_sonicStaking', + internalType: 'address payable', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + }, + { type: 'error', inputs: [], name: 'UserWithdrawsMaxSizeCannotBeZero' }, + { type: 'error', inputs: [], name: 'UserWithdrawsSkipTooLarge' }, + { + type: 'function', + inputs: [ + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'skip', internalType: 'uint256', type: 'uint256' }, + { name: 'maxSize', internalType: 'uint256', type: 'uint256' }, + { name: 'reverseOrder', internalType: 'bool', type: 'bool' }, + ], + name: 'getUserWithdraws', + outputs: [ + { + name: 'withdraws', + internalType: 'struct SonicStakingWithdrawRequestHelper.WithdrawRequest[]', + type: 'tuple[]', + components: [ + { name: 'id', internalType: 'uint256', type: 'uint256' }, + { + name: 'kind', + internalType: 'enum SonicStaking.WithdrawKind', + type: 'uint8', + }, + { name: 'validatorId', internalType: 'uint256', type: 'uint256' }, + { name: 'assetAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'isWithdrawn', internalType: 'bool', type: 'bool' }, + { + name: 'requestTimestamp', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'user', internalType: 'address', type: 'address' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'user', internalType: 'address', type: 'address' }], + name: 'getUserWithdrawsCount', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'withdrawId', internalType: 'uint256', type: 'uint256' }], + name: 'getWithdrawRequest', + outputs: [ + { + name: '', + internalType: 'struct SonicStakingWithdrawRequestHelper.WithdrawRequest', + type: 'tuple', + components: [ + { name: 'id', internalType: 'uint256', type: 'uint256' }, + { + name: 'kind', + internalType: 'enum SonicStaking.WithdrawKind', + type: 'uint8', + }, + { name: 'validatorId', internalType: 'uint256', type: 'uint256' }, + { name: 'assetAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'isWithdrawn', internalType: 'bool', type: 'bool' }, + { + name: 'requestTimestamp', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'user', internalType: 'address', type: 'address' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'sonicStaking', + outputs: [{ name: '', internalType: 'contract SonicStaking', type: 'address' }], + stateMutability: 'view', + }, +] as const + +/** + * [__View Contract on Sonic Sonic Explorer__](https://explorer.soniclabs.com/address/0x52b16e3d7d25ba64f242e59f9a74799ecc432d78) + */ +export const sonicStakingWithdrawRequestHelperAddress = { + 146: '0x52B16e3D7d25bA64F242e59f9A74799ecC432d78', +} as const + +/** + * [__View Contract on Sonic Sonic Explorer__](https://explorer.soniclabs.com/address/0x52b16e3d7d25ba64f242e59f9a74799ecc432d78) + */ +export const sonicStakingWithdrawRequestHelperConfig = { + address: sonicStakingWithdrawRequestHelperAddress, + abi: sonicStakingWithdrawRequestHelperAbi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// erc20 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +export const erc20Abi = [ + { + type: 'event', + inputs: [ + { name: 'owner', type: 'address', indexed: true }, + { name: 'spender', type: 'address', indexed: true }, + { name: 'value', type: 'uint256', indexed: false }, + ], + name: 'Approval', + }, + { + type: 'event', + inputs: [ + { name: 'from', type: 'address', indexed: true }, + { name: 'to', type: 'address', indexed: true }, + { name: 'value', type: 'uint256', indexed: false }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'recipient', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'sender', type: 'address' }, + { name: 'recipient', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ type: 'bool' }], + stateMutability: 'nonpayable', + }, +] as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// feeDistributor +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xD3cf852898b21fc233251427c2DC93d3d604F3BB) + */ +export const feeDistributorAbi = [ + { + type: 'constructor', + inputs: [ + { + name: 'votingEscrow', + internalType: 'contract IVotingEscrow', + type: 'address', + }, + { name: 'startTime', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'user', + internalType: 'address', + type: 'address', + indexed: false, + }, + { name: 'enabled', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'OnlyCallerOptIn', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'token', + internalType: 'contract IERC20', + type: 'address', + indexed: false, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'lastCheckpointTimestamp', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'TokenCheckpointed', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'user', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'token', + internalType: 'contract IERC20', + type: 'address', + indexed: false, + }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'userTokenTimeCursor', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'TokensClaimed', + }, + { + type: 'function', + inputs: [], + name: 'checkpoint', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'token', internalType: 'contract IERC20', type: 'address' }], + name: 'checkpointToken', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'tokens', internalType: 'contract IERC20[]', type: 'address[]' }], + name: 'checkpointTokens', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'user', internalType: 'address', type: 'address' }], + name: 'checkpointUser', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + ], + name: 'claimToken', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'tokens', internalType: 'contract IERC20[]', type: 'address[]' }, + ], + name: 'claimTokens', + outputs: [{ name: '', internalType: 'uint256[]', type: 'uint256[]' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'depositToken', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'tokens', internalType: 'contract IERC20[]', type: 'address[]' }, + { name: 'amounts', internalType: 'uint256[]', type: 'uint256[]' }, + ], + name: 'depositTokens', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'getDomainSeparator', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'getNextNonce', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getTimeCursor', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'token', internalType: 'contract IERC20', type: 'address' }], + name: 'getTokenLastBalance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'token', internalType: 'contract IERC20', type: 'address' }], + name: 'getTokenTimeCursor', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'timestamp', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getTokensDistributedInWeek', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'timestamp', internalType: 'uint256', type: 'uint256' }], + name: 'getTotalSupplyAtTimestamp', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'timestamp', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getUserBalanceAtTimestamp', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'user', internalType: 'address', type: 'address' }], + name: 'getUserTimeCursor', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + ], + name: 'getUserTokenTimeCursor', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getVotingEscrow', + outputs: [{ name: '', internalType: 'contract IVotingEscrow', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'user', internalType: 'address', type: 'address' }], + name: 'isOnlyCallerEnabled', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'enabled', internalType: 'bool', type: 'bool' }], + name: 'setOnlyCallerCheck', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'user', internalType: 'address', type: 'address' }, + { name: 'enabled', internalType: 'bool', type: 'bool' }, + { name: 'signature', internalType: 'bytes', type: 'bytes' }, + ], + name: 'setOnlyCallerCheckWithSignature', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xD3cf852898b21fc233251427c2DC93d3d604F3BB) + */ +export const feeDistributorAddress = { + 1: '0xD3cf852898b21fc233251427c2DC93d3d604F3BB', +} as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xD3cf852898b21fc233251427c2DC93d3d604F3BB) + */ +export const feeDistributorConfig = { + address: feeDistributorAddress, + abi: feeDistributorAbi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// veBal +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xC128a9954e6c874eA3d62ce62B468bA073093F25) + */ +export const veBalAbi = [ + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'provider', type: 'address', indexed: true }, + { name: 'value', type: 'uint256', indexed: false }, + { name: 'locktime', type: 'uint256', indexed: true }, + { name: 'type', type: 'int128', indexed: false }, + { name: 'ts', type: 'uint256', indexed: false }, + ], + name: 'Deposit', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'provider', type: 'address', indexed: true }, + { name: 'value', type: 'uint256', indexed: false }, + { name: 'ts', type: 'uint256', indexed: false }, + ], + name: 'Withdraw', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'prevSupply', type: 'uint256', indexed: false }, + { name: 'supply', type: 'uint256', indexed: false }, + ], + name: 'Supply', + }, + { + type: 'constructor', + inputs: [ + { name: 'token_addr', type: 'address' }, + { name: '_name', type: 'string' }, + { name: '_symbol', type: 'string' }, + { name: '_authorizer_adaptor', type: 'address' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'token', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'admin', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'addr', type: 'address' }], + name: 'commit_smart_wallet_checker', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'apply_smart_wallet_checker', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'addr', type: 'address' }], + name: 'get_last_user_slope', + outputs: [{ name: '', type: 'int128' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: '_addr', type: 'address' }, + { name: '_idx', type: 'uint256' }, + ], + name: 'user_point_history__ts', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_addr', type: 'address' }], + name: 'locked__end', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'checkpoint', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_addr', type: 'address' }, + { name: '_value', type: 'uint256' }, + ], + name: 'deposit_for', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '_value', type: 'uint256' }, + { name: '_unlock_time', type: 'uint256' }, + ], + name: 'create_lock', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: '_value', type: 'uint256' }], + name: 'increase_amount', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: '_unlock_time', type: 'uint256' }], + name: 'increase_unlock_time', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'addr', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'addr', type: 'address' }, + { name: '_t', type: 'uint256' }, + ], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'addr', type: 'address' }, + { name: '_block', type: 'uint256' }, + ], + name: 'balanceOfAt', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 't', type: 'uint256' }], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: '_block', type: 'uint256' }], + name: 'totalSupplyAt', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'supply', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'address' }], + name: 'locked', + outputs: [ + { + name: '', + type: 'tuple', + components: [ + { name: 'amount', type: 'int128' }, + { name: 'end', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'epoch', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'uint256' }], + name: 'point_history', + outputs: [ + { + name: '', + type: 'tuple', + components: [ + { name: 'bias', type: 'int128' }, + { name: 'slope', type: 'int128' }, + { name: 'ts', type: 'uint256' }, + { name: 'blk', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'arg0', type: 'address' }, + { name: 'arg1', type: 'uint256' }, + ], + name: 'user_point_history', + outputs: [ + { + name: '', + type: 'tuple', + components: [ + { name: 'bias', type: 'int128' }, + { name: 'slope', type: 'int128' }, + { name: 'ts', type: 'uint256' }, + { name: 'blk', type: 'uint256' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'address' }], + name: 'user_point_epoch', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'arg0', type: 'uint256' }], + name: 'slope_changes', + outputs: [{ name: '', type: 'int128' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'future_smart_wallet_checker', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'smart_wallet_checker', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + }, +] as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xC128a9954e6c874eA3d62ce62B468bA073093F25) + */ +export const veBalAddress = { + 1: '0xC128a9954e6c874eA3d62ce62B468bA073093F25', +} as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0xC128a9954e6c874eA3d62ce62B468bA073093F25) + */ +export const veBalConfig = { address: veBalAddress, abi: veBalAbi } as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// veDelegationProxy +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x6f5a2eE11E7a772AeB5114A20d0D7c0ff61EB8A0) + */ +export const veDelegationProxyAbi = [ + { + type: 'constructor', + inputs: [ + { name: 'vault', internalType: 'contract IVault', type: 'address' }, + { + name: 'votingEscrow', + internalType: 'contract IERC20', + type: 'address', + }, + { + name: 'delegation', + internalType: 'contract IVeDelegation', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'newImplementation', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'DelegationImplementationUpdated', + }, + { + type: 'function', + inputs: [{ name: 'user', internalType: 'address', type: 'address' }], + name: 'adjustedBalanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'user', internalType: 'address', type: 'address' }], + name: 'adjusted_balance_of', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'selector', internalType: 'bytes4', type: 'bytes4' }], + name: 'getActionId', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getAuthorizer', + outputs: [{ name: '', internalType: 'contract IAuthorizer', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getDelegationImplementation', + outputs: [{ name: '', internalType: 'contract IVeDelegation', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getVault', + outputs: [{ name: '', internalType: 'contract IVault', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getVotingEscrow', + outputs: [{ name: '', internalType: 'contract IERC20', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'killDelegation', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'delegation', + internalType: 'contract IVeDelegation', + type: 'address', + }, + ], + name: 'setDelegation', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x6f5a2eE11E7a772AeB5114A20d0D7c0ff61EB8A0) + */ +export const veDelegationProxyAddress = { + 1: '0x6f5a2eE11E7a772AeB5114A20d0D7c0ff61EB8A0', +} as const + +/** + * [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x6f5a2eE11E7a772AeB5114A20d0D7c0ff61EB8A0) + */ +export const veDelegationProxyConfig = { + address: veDelegationProxyAddress, + abi: veDelegationProxyAbi, +} as const diff --git a/packages/lib/modules/web3/contracts/useManagedTransaction.ts b/packages/lib/modules/web3/contracts/useManagedTransaction.ts index 49b35ecd9..36bead982 100644 --- a/packages/lib/modules/web3/contracts/useManagedTransaction.ts +++ b/packages/lib/modules/web3/contracts/useManagedTransaction.ts @@ -39,6 +39,7 @@ export interface ManagedTransactionInput { args?: ContractFunctionArgs<IAbiMap[AbiMapKey], WriteAbiMutability> | null txSimulationMeta?: Record<string, unknown> enabled: boolean + value?: bigint } export function useManagedTransaction({ @@ -50,6 +51,7 @@ export function useManagedTransaction({ args, txSimulationMeta, enabled = true, + value, }: ManagedTransactionInput) { const { minConfirmations } = useNetworkConfig() const { shouldChangeNetwork } = useChainSwitch(chainId) @@ -67,6 +69,7 @@ export function useManagedTransaction({ // In chains like polygon, we don't want background refetches while waiting for min block confirmations ...onlyExplicitRefetch, }, + value, }) const { mockedTxHash, setMockedTxHash } = useMockedTxHash() diff --git a/packages/lib/modules/web3/contracts/useMulticall.ts b/packages/lib/modules/web3/contracts/useMulticall.ts index adde60999..74895ed12 100644 --- a/packages/lib/modules/web3/contracts/useMulticall.ts +++ b/packages/lib/modules/web3/contracts/useMulticall.ts @@ -5,6 +5,9 @@ import { multicall } from 'wagmi/actions' import { useCallback } from 'react' import { useConfig } from 'wagmi' import { SupportedChainId } from '@repo/lib/config/config.types' +import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' +import sonicNetworkConfig from '@repo/lib/config/networks/sonic' +import { getChainId } from '@repo/lib/config/app.config' export type ChainContractConfig = ContractFunctionParameters & { chainId: SupportedChainId @@ -33,6 +36,9 @@ export function useMulticall(multicallRequests: ChainContractConfig[], options: const results = await multicall(config, { contracts: multicalls, chainId: Number(chain), + ...(Number(chain) === getChainId(GqlChain.Sonic) && { + multicallAddress: sonicNetworkConfig.contracts.multicall3, + }), }) // map the result to its id based on the call index diff --git a/packages/lib/package.json b/packages/lib/package.json index 6ebcaf15f..704c58acf 100644 --- a/packages/lib/package.json +++ b/packages/lib/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "@apollo/client": "^3.11.8", - "@balancer/sdk": "1.0.1", + "@balancer/sdk": "1.0.2", "@chakra-ui/anatomy": "^2.2.2", "@chakra-ui/clickable": "^2.1.0", "@chakra-ui/hooks": "^2.2.1", @@ -112,7 +112,7 @@ "@typescript-eslint/parser": "^5.60.1", "@viem/anvil": "^0.0.10", "@vitejs/plugin-react": "^4.2.1", - "@vitest/coverage-v8": "^1.3.0", + "@vitest/coverage-v8": "2.1.8", "@wagmi/cli": "2.1.22", "autoprefixer": "^10.4.14", "concurrently": "^8.2.2", diff --git a/packages/lib/shared/components/animations/LettersPullUp.tsx b/packages/lib/shared/components/animations/LettersPullUp.tsx index 2217b19f9..28aefb55c 100644 --- a/packages/lib/shared/components/animations/LettersPullUp.tsx +++ b/packages/lib/shared/components/animations/LettersPullUp.tsx @@ -7,12 +7,16 @@ import * as React from 'react' export function LettersPullUp({ text, initialColor = '#457dff', + finalColorLight = '#000000', + finalColorDark = '#ffffff', }: { text: string initialColor?: string + finalColorLight?: string + finalColorDark?: string }) { const splittedText = text.split('') - const finalColor = useColorModeValue('#2D3748', '#E5D3BE') + const finalColor = useColorModeValue(finalColorLight, finalColorDark) const pullupVariant = { initial: { y: -20, x: -10, opacity: 0, color: initialColor, filter: 'blur(10px)' }, diff --git a/packages/lib/shared/components/imgs/SpearbitLogo.tsx b/packages/lib/shared/components/imgs/SpearbitLogo.tsx index 4020b5b58..b0e72924c 100644 --- a/packages/lib/shared/components/imgs/SpearbitLogo.tsx +++ b/packages/lib/shared/components/imgs/SpearbitLogo.tsx @@ -1,5 +1,7 @@ +import { SVGProps } from 'react' + /* eslint-disable max-len */ -export function SpearbitLogo() { +export function SpearbitLogo({ ...props }: SVGProps<SVGSVGElement>) { return ( <svg fill="none" @@ -7,6 +9,7 @@ export function SpearbitLogo() { viewBox="0 0 200 41" width="200" xmlns="http://www.w3.org/2000/svg" + {...props} > <g clipPath="url(#clip0_2001_143)"> <path diff --git a/packages/lib/shared/components/modals/ActionModalFooter.tsx b/packages/lib/shared/components/modals/ActionModalFooter.tsx index 15ff7d503..2b93c0a4e 100644 --- a/packages/lib/shared/components/modals/ActionModalFooter.tsx +++ b/packages/lib/shared/components/modals/ActionModalFooter.tsx @@ -8,7 +8,7 @@ import Link from 'next/link' import { PropsWithChildren } from 'react' import { CornerDownLeft, MessageSquare, ThumbsUp } from 'react-feather' import { TransactionStep } from '../../../modules/transactions/transaction-steps/lib' -import { getProjectConfig } from '@repo/lib/config/getProjectConfig' +import { PROJECT_CONFIG, isBalancerProject } from '@repo/lib/config/getProjectConfig' export function SuccessActions({ returnLabel, @@ -31,12 +31,19 @@ export function SuccessActions({ > {returnLabel} </Button> - <Button leftIcon={<ThumbsUp size="14" />} onClick={openNpsModal} size="xs" variant="ghost"> - Give feedback - </Button> + {isBalancerProject && ( + <Button + leftIcon={<ThumbsUp size="14" />} + onClick={openNpsModal} + size="xs" + variant="ghost" + > + Give feedback + </Button> + )} <Button as={Link} - href={getProjectConfig().externalLinks.discordUrl} + href={PROJECT_CONFIG.externalLinks.discordUrl} leftIcon={<MessageSquare size="14" />} size="xs" target="_blank" diff --git a/packages/lib/shared/components/navs/MobileNav.tsx b/packages/lib/shared/components/navs/MobileNav.tsx index 27ee582eb..e4987932f 100644 --- a/packages/lib/shared/components/navs/MobileNav.tsx +++ b/packages/lib/shared/components/navs/MobileNav.tsx @@ -1,29 +1,29 @@ import { useDisclosure } from '@chakra-ui/hooks' import { + Box, Button, + Divider, Drawer, - DrawerOverlay, - DrawerContent, - DrawerCloseButton, - DrawerHeader, DrawerBody, + DrawerCloseButton, + DrawerContent, DrawerFooter, - VStack, + DrawerHeader, + DrawerOverlay, + HStack, Link, - Divider, - Box, Text, - HStack, + VStack, } from '@chakra-ui/react' +import NextLink from 'next/link' +import { useRouter } from 'next/navigation' import { useRef } from 'react' import { ArrowUpRight, Menu } from 'react-feather' import { AppLink, useNav } from './useNav' -import NextLink from 'next/link' -import { useRouter } from 'next/navigation' -import { VeBalLink } from '@repo/lib/modules/vebal/VebalRedirectModal' type NavLinkProps = { appLinks: AppLink[] + customLinks?: React.ReactNode onClick?: () => void } @@ -39,7 +39,7 @@ type MobileNavProps = NavLinkProps & EcosystemLinkProps & SocialLinkProps & { LogoType: React.FC<any> } -function NavLinks({ appLinks, onClick }: NavLinkProps) { +function NavLinks({ appLinks, onClick, customLinks }: NavLinkProps) { const { linkColorFor } = useNav() return ( @@ -58,7 +58,7 @@ function NavLinks({ appLinks, onClick }: NavLinkProps) { {link.label} </Link> ))} - <VeBalLink fontSize="xl" /> + {customLinks} </VStack> ) } @@ -101,7 +101,13 @@ function SocialLinks({ socialLinks }: SocialLinkProps) { ) } -export function MobileNav({ appLinks, ecosystemLinks, socialLinks, LogoType }: MobileNavProps) { +export function MobileNav({ + appLinks, + ecosystemLinks, + socialLinks, + LogoType, + customLinks, +}: MobileNavProps) { const { isOpen, onOpen, onClose } = useDisclosure() const btnRef = useRef(null) const router = useRouter() @@ -124,7 +130,7 @@ export function MobileNav({ appLinks, ecosystemLinks, socialLinks, LogoType }: M <LogoType onClick={homeRedirect} width="106px" /> </DrawerHeader> <DrawerBody> - <NavLinks appLinks={appLinks} onClick={onClose} /> + <NavLinks appLinks={appLinks} customLinks={customLinks} onClick={onClose} /> <Divider my={4} /> <EcosystemLinks ecosystemLinks={ecosystemLinks} /> </DrawerBody> diff --git a/packages/lib/shared/components/navs/NavBar.tsx b/packages/lib/shared/components/navs/NavBar.tsx index e83f5e269..df55aa7d5 100644 --- a/packages/lib/shared/components/navs/NavBar.tsx +++ b/packages/lib/shared/components/navs/NavBar.tsx @@ -1,19 +1,18 @@ 'use client' +import { Box, BoxProps, Button, HStack, Link } from '@chakra-ui/react' +import { isDev, isStaging } from '@repo/lib/config/app.config' +import { UserSettings } from '@repo/lib/modules/user/settings/UserSettings' +import { ConnectWallet } from '@repo/lib/modules/web3/ConnectWallet' +import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' +import { fadeIn, staggeredFadeIn } from '@repo/lib/shared/utils/animations' +import { motion, useMotionTemplate, useMotionValue, useScroll, useTransform } from 'framer-motion' import NextLink from 'next/link' +import { usePathname } from 'next/navigation' +import { ReactNode, useEffect, useMemo, useState } from 'react' import DarkModeToggle from '../btns/DarkModeToggle' -import { Box, HStack, BoxProps, Link, Button } from '@chakra-ui/react' -import { ConnectWallet } from '@repo/lib/modules/web3/ConnectWallet' -import { UserSettings } from '@repo/lib/modules/user/settings/UserSettings' import RecentTransactions from '../other/RecentTransactions' -import { isDev, isStaging } from '@repo/lib/config/app.config' -import { staggeredFadeIn, fadeIn } from '@repo/lib/shared/utils/animations' -import { motion, useMotionTemplate, useMotionValue, useScroll, useTransform } from 'framer-motion' -import { VeBalLink } from '@repo/lib/modules/vebal/VebalRedirectModal' import { AppLink, useNav } from './useNav' -import { ReactNode, useEffect, useMemo, useState } from 'react' -import { usePathname } from 'next/navigation' -import { useUserAccount } from '@repo/lib/modules/web3/UserAccountProvider' type Props = { mobileNav?: ReactNode @@ -22,6 +21,7 @@ type Props = { leftSlot?: ReactNode rightSlot?: ReactNode disableBlur?: boolean + customLinks?: ReactNode } const clamp = (number: number, min: number, max: number) => Math.min(Math.max(number, min), max) @@ -44,7 +44,14 @@ function useBoundedScroll(threshold: number) { return { scrollYBounded, scrollYBoundedProgress } } -function NavLinks({ appLinks, ...props }: BoxProps & { appLinks: AppLink[] }) { +function NavLinks({ + appLinks, + customLinks, + ...props +}: BoxProps & { + appLinks: AppLink[] + customLinks?: ReactNode +}) { const { linkColorFor } = useNav() return ( @@ -55,6 +62,7 @@ function NavLinks({ appLinks, ...props }: BoxProps & { appLinks: AppLink[] }) { as={NextLink} color={linkColorFor(link.href)} href={link.href} + isExternal={link.isExternal} prefetch variant="nav" > @@ -62,9 +70,7 @@ function NavLinks({ appLinks, ...props }: BoxProps & { appLinks: AppLink[] }) { </Link> </Box> ))} - <Box as={motion.div} variants={fadeIn}> - <VeBalLink /> - </Box> + {customLinks} {(isDev || isStaging) && ( <Box as={motion.div} variants={fadeIn}> {/* <Link as={NextLink} color={linkColorFor('/debug')} href="/debug" prefetch variant="nav"> @@ -85,7 +91,13 @@ function NavLinks({ appLinks, ...props }: BoxProps & { appLinks: AppLink[] }) { ) } -function NavActions({ mobileNav }: { mobileNav: ReactNode }) { +export function NavActions({ + mobileNav, + hideDarkModeToggle, +}: { + mobileNav: ReactNode + hideDarkModeToggle?: boolean +}) { const pathname = usePathname() const { isConnected } = useUserAccount() @@ -93,7 +105,7 @@ function NavActions({ mobileNav }: { mobileNav: ReactNode }) { if (pathname === '/') { return [ { - el: <DarkModeToggle />, + el: hideDarkModeToggle ? null : <DarkModeToggle />, display: { base: 'none', lg: 'block' }, }, { @@ -117,7 +129,7 @@ function NavActions({ mobileNav }: { mobileNav: ReactNode }) { display: { base: 'none', lg: 'block' }, }, { - el: <DarkModeToggle />, + el: hideDarkModeToggle ? null : <DarkModeToggle />, display: { base: 'none', lg: 'block' }, }, { @@ -146,12 +158,15 @@ function NavActions({ mobileNav }: { mobileNav: ReactNode }) { return ( <> - {actions.map(({ el, display }, i) => ( - // eslint-disable-next-line react/no-array-index-key - <Box as={motion.div} display={display} key={i} variants={fadeIn}> - {el} - </Box> - ))} + {actions.map( + ({ el, display }, i) => + el && ( + // eslint-disable-next-line react/no-array-index-key + <Box as={motion.div} display={display} key={i} variants={fadeIn}> + {el} + </Box> + ) + )} </> ) } @@ -163,6 +178,7 @@ export function NavBar({ appLinks, navLogo, mobileNav, + customLinks, ...rest }: Props & BoxProps) { const [showShadow, setShowShadow] = useState(false) @@ -230,7 +246,13 @@ export function NavBar({ {leftSlot || ( <> {navLogo} - {appLinks && <NavLinks appLinks={appLinks} display={{ base: 'none', lg: 'flex' }} />} + {appLinks && ( + <NavLinks + appLinks={appLinks} + customLinks={customLinks} + display={{ base: 'none', lg: 'flex' }} + /> + )} </> )} </HStack> diff --git a/packages/lib/shared/components/navs/useNav.tsx b/packages/lib/shared/components/navs/useNav.tsx index 1f705a5e4..39f2a4e75 100644 --- a/packages/lib/shared/components/navs/useNav.tsx +++ b/packages/lib/shared/components/navs/useNav.tsx @@ -12,6 +12,7 @@ export type AppLink = { href: string label?: string icon?: ReactNode + isExternal?: boolean } export function useNav() { diff --git a/packages/lib/shared/components/pagination/Pagination.tsx b/packages/lib/shared/components/pagination/Pagination.tsx index 261292440..b791980a5 100644 --- a/packages/lib/shared/components/pagination/Pagination.tsx +++ b/packages/lib/shared/components/pagination/Pagination.tsx @@ -13,6 +13,7 @@ interface Props { setPageSize: (page: number) => void pageSize: number changeSize?: boolean + hideDropdown?: boolean } export function Pagination({ @@ -27,10 +28,16 @@ export function Pagination({ setPageSize, pageSize, changeSize = true, + hideDropdown = false, ...rest }: Props) { return ( - <Stack direction={{ base: 'column', lg: 'row' }} justify="space-between" w="full" {...rest}> + <Stack + direction={{ base: 'column', lg: 'row' }} + justify={hideDropdown ? 'center' : 'space-between'} + w="full" + {...rest} + > <HStack> <IconButton aria-label="first page" @@ -76,22 +83,24 @@ export function Pagination({ size="sm" /> </HStack> - <Select - disabled={!changeSize} - onChange={e => { - setPageSize(Number(e.target.value)) - }} - size="sm" - value={pageSize} - variant="tertiary" - w="32" - > - {[10, 20, 30, 40, 50].map(pageSize => ( - <option key={pageSize} value={pageSize}> - {`Show ${pageSize}`} - </option> - ))} - </Select> + {!hideDropdown && ( + <Select + disabled={!changeSize} + onChange={e => { + setPageSize(Number(e.target.value)) + }} + size="sm" + value={pageSize} + variant="tertiary" + w="32" + > + {[10, 20, 30, 40, 50].map(pageSize => ( + <option key={pageSize} value={pageSize}> + {`Show ${pageSize}`} + </option> + ))} + </Select> + )} </Stack> ) } diff --git a/packages/lib/shared/components/pagination/getPaginationProps.ts b/packages/lib/shared/components/pagination/getPaginationProps.ts index 38978a32a..e4e33d152 100644 --- a/packages/lib/shared/components/pagination/getPaginationProps.ts +++ b/packages/lib/shared/components/pagination/getPaginationProps.ts @@ -4,7 +4,8 @@ export function getPaginationProps( totalRowCount: number, pagination: PaginationState, setPagination: (pagination: PaginationState) => void, - changeSize = true + changeSize = true, + hideDropdown = false ) { const totalPageCount = totalRowCount % pagination.pageSize === 0 @@ -38,5 +39,6 @@ export function getPaginationProps( goToPreviousPage, setPageSize, changeSize, + hideDropdown, } } diff --git a/packages/lib/shared/components/tooltips/apr-tooltip/BaseAprTooltip.tsx b/packages/lib/shared/components/tooltips/apr-tooltip/BaseAprTooltip.tsx index 86fbdd464..b7e8f176c 100644 --- a/packages/lib/shared/components/tooltips/apr-tooltip/BaseAprTooltip.tsx +++ b/packages/lib/shared/components/tooltips/apr-tooltip/BaseAprTooltip.tsx @@ -316,7 +316,7 @@ function BaseAprTooltip({ fontWeight={500} pl={6} pt={3} - title="Max maBEETS APR" + title="Extra BEETS (max maturity boost)" tooltipText={maBeetsRewardTooltipText} /> <TooltipAprItem @@ -326,7 +326,7 @@ function BaseAprTooltip({ fontColor={colorMode == 'light' ? 'gray.600' : 'gray.400'} fontWeight={500} pl={6} - title="Max Voting APR" + title="Extra Voting APR" tooltipText={maBeetsVotingRewardsTooltipText} /> <Divider /> diff --git a/packages/lib/shared/hooks/useAprTooltip.ts b/packages/lib/shared/hooks/useAprTooltip.ts index bbf84453f..790c37aef 100644 --- a/packages/lib/shared/hooks/useAprTooltip.ts +++ b/packages/lib/shared/hooks/useAprTooltip.ts @@ -32,7 +32,7 @@ export const votingIncentivesTooltipText = `Vote incentives are offered to veBAL const stakingBalTooltipText = `The base APR all stakers in this pool get (determined by weekly gauge voting). In addition, veBAL holders can get an extra boost of up to 2.5x.` -const stakingTokenTooltipText = '3rd party incentives (outside the veBAL system)' +const stakingTokenTooltipText = `3rd party incentives (outside the ${isBalancerProject ? 'veBAL' : 'gauge bounty'} system)` const maBeetsVotingRewardsTooltipText = 'To receive Voting APR you must vote for incentivized pools in the bi-weekly gauge vote. APR is dependent on your vote distribution.' @@ -160,6 +160,8 @@ export function useAprTooltip({ ) const maBeetsTotalAprDisplayed = bn(swapFeesDisplayed) + .plus(yieldBearingTokensAprDisplayed) + .plus(maBeetsRewardsDisplayed) .plus(maxMaBeetsRewardDisplayed) .plus(maxMaBeetsVotingRewardDisplayed) diff --git a/packages/lib/shared/services/api/protocol-stats.graphql b/packages/lib/shared/services/api/protocol-stats.graphql index d82a41a47..97792ea59 100644 --- a/packages/lib/shared/services/api/protocol-stats.graphql +++ b/packages/lib/shared/services/api/protocol-stats.graphql @@ -7,3 +7,17 @@ query GetProtocolStats($chains: [GqlChain!]) { poolCount } } + +query GetProtocolStatsPerChain($chain: GqlChain) { + protocolMetricsChain(chain: $chain) { + chainId + numLiquidityProviders + poolCount + swapFee24h + swapVolume24h + totalLiquidity + totalSwapFee + totalSwapVolume + yieldCapture24h + } +} diff --git a/packages/lib/shared/services/api/staked-sonic.graphql b/packages/lib/shared/services/api/staked-sonic.graphql new file mode 100644 index 000000000..bac85af7c --- /dev/null +++ b/packages/lib/shared/services/api/staked-sonic.graphql @@ -0,0 +1,13 @@ +query GetStakedSonicData { + stsGetGqlStakedSonicData { + delegatedValidators { + assetsDelegated + validatorId + } + exchangeRate + stakingApr + totalAssets + totalAssetsDelegated + totalAssetsPool + } +} diff --git a/packages/lib/test/anvil/anvil-setup.ts b/packages/lib/test/anvil/anvil-setup.ts index d7c7eb474..517d20b6a 100644 --- a/packages/lib/test/anvil/anvil-setup.ts +++ b/packages/lib/test/anvil/anvil-setup.ts @@ -1,8 +1,8 @@ import { Address, Hex } from 'viem' import { privateKeyToAccount } from 'viem/accounts' -import { gnosis, mainnet, polygon, sepolia } from 'viem/chains' +import { fantom, gnosis, mainnet, polygon, sepolia, sonic } from 'viem/chains' -const networksWithFork = [mainnet, polygon, sepolia, gnosis] as const +const networksWithFork = [mainnet, polygon, sepolia, gnosis, fantom, sonic] as const export type NetworksWithFork = (typeof networksWithFork)[number]['name'] export type NetworkSetup = { @@ -41,7 +41,9 @@ const ANVIL_PORTS: Record<NetworksWithFork, number> = { Ethereum: 8645, Polygon: 8745, Sepolia: 8845, + Fantom: 8945, Gnosis: 9045, + Sonic: 9145, } export const ANVIL_NETWORKS: Record<NetworksWithFork, NetworkSetup> = { @@ -68,12 +70,23 @@ export const ANVIL_NETWORKS: Record<NetworksWithFork, NetworkSetup> = { // For now we will use the last block until v3 deployments are final // forkBlockNumber: 6679621n, }, + Fantom: { + networkName: 'Fantom', + fallBackRpc: 'https://gateway.tenderly.co/public/fantom', + port: ANVIL_PORTS.Fantom, + forkBlockNumber: 99471829n, + }, + Sonic: { + networkName: 'Sonic', + fallBackRpc: 'https://gateway.tenderly.co/public/sonic', + port: ANVIL_PORTS.Sonic, + forkBlockNumber: 2687659n, + }, Gnosis: { networkName: 'Gnosis', fallBackRpc: 'https://gnosis.drpc.org', port: ANVIL_PORTS.Gnosis, - // For now we will use the last block until v3 deployments are final - // forkBlockNumber: , + forkBlockNumber: 37902207n, }, } @@ -113,6 +126,12 @@ export function getForkUrl(networkName: NetworksWithFork, verbose = false): stri if (network.networkName === 'Sepolia') { return dRpcUrl('sepolia') } + if (network.networkName === 'Fantom') { + return dRpcUrl('fantom') + } + if (network.networkName === 'Sonic') { + return dRpcUrl('sonic') + } if (network.networkName === 'Gnosis') { return dRpcUrl('gnosis') } diff --git a/packages/lib/test/anvil/testWagmiConfig.tsx b/packages/lib/test/anvil/testWagmiConfig.tsx index da880b41b..133418ce7 100644 --- a/packages/lib/test/anvil/testWagmiConfig.tsx +++ b/packages/lib/test/anvil/testWagmiConfig.tsx @@ -1,6 +1,6 @@ import { NetworksWithFork, getTestRpcSetup, testAccounts } from '@repo/lib/test/anvil/anvil-setup' import { Address, Chain, http } from 'viem' -import { gnosis, mainnet, polygon, sepolia } from 'viem/chains' +import { gnosis, mainnet, polygon, sepolia, fantom, sonic } from 'viem/chains' import { createConfig } from 'wagmi' import { mock } from 'wagmi/connectors' @@ -19,12 +19,29 @@ export const sepoliaTest = { ...getTestRpcUrls('Sepolia'), } as const satisfies Chain +export const fantomTest = { + ...fantom, + ...getTestRpcUrls('Fantom'), +} as const satisfies Chain + export const gnosisTest = { ...gnosis, ...getTestRpcUrls('Gnosis'), } as const satisfies Chain -export const testChains = [mainnetTest, polygonTest, sepoliaTest, gnosisTest] as const +export const sonicTest = { + ...sonic, + ...getTestRpcUrls('Sonic'), +} as const satisfies Chain + +export const testChains = [ + mainnetTest, + polygonTest, + sepoliaTest, + gnosisTest, + fantomTest, + sonicTest, +] as const function getTestRpcUrls(networkName: NetworksWithFork) { const { port, rpcUrl } = getTestRpcSetup(networkName) @@ -54,7 +71,9 @@ function createTestWagmiConfig() { [mainnetTest.id]: http(), [polygonTest.id]: http(), [sepoliaTest.id]: http(), + [fantomTest.id]: http(), [gnosisTest.id]: http(), + [sonicTest.id]: http(), }, ssr: false, }) diff --git a/packages/lib/test/utils/wagmi/wagmi-test-clients.ts b/packages/lib/test/utils/wagmi/wagmi-test-clients.ts index c4dee04a5..2f35d1a6d 100644 --- a/packages/lib/test/utils/wagmi/wagmi-test-clients.ts +++ b/packages/lib/test/utils/wagmi/wagmi-test-clients.ts @@ -1,8 +1,8 @@ import { testWagmiConfig } from '@repo/lib/test/anvil/testWagmiConfig' import { publicActions, testActions, walletActions } from 'viem' -import { gnosis, mainnet, polygon, sepolia } from 'viem/chains' +import { gnosis, mainnet, polygon, sepolia, fantom } from 'viem/chains' -export function createTestHttpClient(chainId: 1 | 137 | 11155111 | 100) { +export function createTestHttpClient(chainId: 1 | 137 | 11155111 | 100 | 250) { return testWagmiConfig .getClient({ chainId }) .extend(testActions({ mode: 'anvil' })) @@ -13,4 +13,5 @@ export function createTestHttpClient(chainId: 1 | 137 | 11155111 | 100) { export const mainnetTestPublicClient = createTestHttpClient(mainnet.id) export const polygonTestPublicClient = createTestHttpClient(polygon.id) export const sepoliaTestPublicClient = createTestHttpClient(sepolia.id) +export const fantomTestPublicClient = createTestHttpClient(fantom.id) export const gnosisTestPublicClient = createTestHttpClient(gnosis.id) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44f063e27..2c2393c1d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,12 @@ importers: apps/beets-frontend-v3: dependencies: + '@apollo/client': + specifier: ^3.11.8 + version: 3.11.8(@types/react@18.2.34)(graphql-ws@5.16.0(graphql@16.10.0))(graphql@16.10.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@balancer/sdk': + specifier: 1.0.2 + version: 1.0.2(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1) '@chakra-ui/hooks': specifier: ^2.2.1 version: 2.2.1(react@18.2.0) @@ -55,13 +61,16 @@ importers: version: link:../../packages/lib '@sentry/nextjs': specifier: ^8.13.0 - version: 8.30.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.53.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@14.2.15(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(webpack@5.94.0(esbuild@0.19.12)) + version: 8.30.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.53.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@14.2.15(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(webpack@5.94.0) '@studio-freight/react-lenis': specifier: ^0.0.47 version: 0.0.47(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@tanstack/react-query': + specifier: ^5.56.2 + version: 5.56.2(react@18.2.0) '@vercel/speed-insights': - specifier: 1.1.0 - version: 1.1.0(next@14.2.15(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0) + specifier: ^1.0.1 + version: 1.1.0(next@14.2.15(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0) framer-motion: specifier: ^10.13.0 version: 10.18.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -70,28 +79,34 @@ importers: version: 4.17.21 next: specifier: 14.2.15 - version: 14.2.15(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 14.2.15(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) next-themes: specifier: ^0.3.0 version: 0.3.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) nextjs-toploader: specifier: ^1.6.4 - version: 1.6.12(next@14.2.15(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 1.6.12(next@14.2.15(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 react-dom: specifier: 18.2.0 version: 18.2.0(react@18.2.0) + react-feather: + specifier: ^2.0.10 + version: 2.0.10(react@18.2.0) react-use-measure: specifier: ^2.1.1 version: 2.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + tinycolor2: + specifier: ^1.6.0 + version: 1.6.0 viem: specifier: 2.21.55 version: 2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1) wagmi: - specifier: ^2.12.16 - version: 2.12.17(@tanstack/query-core@5.56.2)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.26.0)(@babel/preset-env@7.25.4(@babel/core@7.26.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@3.29.4)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1))(zod@3.24.1) + specifier: 2.13.3 + version: 2.13.3(@tanstack/query-core@5.56.2)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1))(zod@3.24.1) devDependencies: '@chakra-ui/cli': specifier: ^2.4.1 @@ -126,6 +141,9 @@ importers: '@types/react-dom': specifier: 18.2.6 version: 18.2.6 + '@types/tinycolor2': + specifier: ^1.4.6 + version: 1.4.6 '@typescript-eslint/eslint-plugin': specifier: ^5.60.1 version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.43.0)(typescript@5.4.5))(eslint@8.43.0)(typescript@5.4.5) @@ -182,7 +200,7 @@ importers: version: link:../../packages/lib '@sentry/nextjs': specifier: ^8.13.0 - version: 8.30.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.53.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@14.2.15(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(webpack@5.94.0) + version: 8.30.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.53.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@14.2.15(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(webpack@5.94.0(esbuild@0.19.12)) '@studio-freight/react-lenis': specifier: ^0.0.47 version: 0.0.47(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -227,7 +245,7 @@ importers: version: 2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1) wagmi: specifier: ^2.12.16 - version: 2.12.17(@tanstack/query-core@5.56.2)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.26.0)(@babel/preset-env@7.25.4(@babel/core@7.26.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.3)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1))(zod@3.24.1) + version: 2.12.17(@tanstack/query-core@5.56.2)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.26.0)(@babel/preset-env@7.25.4(@babel/core@7.26.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@3.29.4)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1))(zod@3.24.1) devDependencies: '@chakra-ui/cli': specifier: ^2.4.1 @@ -338,8 +356,8 @@ importers: specifier: ^3.11.8 version: 3.11.8(@types/react@18.2.34)(graphql-ws@5.16.0(graphql@16.10.0))(graphql@16.10.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@balancer/sdk': - specifier: 1.0.1 - version: 1.0.1(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1) + specifier: 1.0.2 + version: 1.0.2(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1) '@chakra-ui/anatomy': specifier: ^2.2.2 version: 2.2.2 @@ -384,7 +402,7 @@ importers: version: 2.2.1(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.34)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1))(wagmi@2.13.3(@tanstack/query-core@5.56.2)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1))(zod@3.24.1)) '@react-three/drei': specifier: ^9.117.3 - version: 9.117.3(@react-three/fiber@8.17.10(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0)(three@0.170.0))(@types/react@18.2.34)(@types/three@0.170.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(three@0.170.0)(use-sync-external-store@1.2.0(react@18.2.0)) + version: 9.117.3(@react-three/fiber@8.17.10(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0)(three@0.170.0))(@types/react@18.2.34)(@types/three@0.170.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(three@0.170.0)(use-sync-external-store@1.2.2(react@18.2.0)) '@react-three/fiber': specifier: ^8.17.10 version: 8.17.10(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0)(three@0.170.0) @@ -612,8 +630,8 @@ importers: specifier: ^4.2.1 version: 4.3.1(vite@5.4.5(@types/node@20.10.2)(terser@5.37.0)) '@vitest/coverage-v8': - specifier: ^1.3.0 - version: 1.6.0(vitest@2.1.8(@types/node@20.10.2)(happy-dom@15.11.7)(msw@2.0.10(typescript@5.4.5))(terser@5.37.0)) + specifier: 2.1.8 + version: 2.1.8(vitest@2.1.8(@types/node@20.10.2)(happy-dom@15.11.7)(msw@2.0.10(typescript@5.4.5))(terser@5.37.0)) '@wagmi/cli': specifier: 2.1.22 version: 2.1.22(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10) @@ -767,10 +785,6 @@ packages: resolution: {integrity: sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.24.7': - resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} - engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.25.9': resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} engines: {node: '>=6.9.0'} @@ -787,12 +801,6 @@ packages: resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.25.4': - resolution: {integrity: sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-create-class-features-plugin@7.25.9': resolution: {integrity: sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==} engines: {node: '>=6.9.0'} @@ -822,10 +830,6 @@ packages: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} - '@babel/helper-member-expression-to-functions@7.24.8': - resolution: {integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==} - engines: {node: '>=6.9.0'} - '@babel/helper-member-expression-to-functions@7.25.9': resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} engines: {node: '>=6.9.0'} @@ -860,10 +864,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.24.7': - resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} - engines: {node: '>=6.9.0'} - '@babel/helper-optimise-call-expression@7.25.9': resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} engines: {node: '>=6.9.0'} @@ -882,12 +882,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.25.0': - resolution: {integrity: sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.25.9': resolution: {integrity: sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==} engines: {node: '>=6.9.0'} @@ -902,10 +896,6 @@ packages: resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} engines: {node: '>=6.9.0'} - '@babel/helper-skip-transparent-expression-wrappers@7.24.7': - resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} - engines: {node: '>=6.9.0'} - '@babel/helper-skip-transparent-expression-wrappers@7.25.9': resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==} engines: {node: '>=6.9.0'} @@ -1091,12 +1081,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-flow@7.24.7': - resolution: {integrity: sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-flow@7.26.0': resolution: {integrity: sha512-B+O2DnPc0iG+YXFqOxv2WNuNU97ToWjOomUQ78DouOENWUaM5sVrmet9mcomUGQFwpJd//gvUagXBSdzO1fRKg==} engines: {node: '>=6.9.0'} @@ -1131,12 +1115,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.24.7': - resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.25.9': resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} engines: {node: '>=6.9.0'} @@ -1197,12 +1175,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-arrow-functions@7.24.7': - resolution: {integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-arrow-functions@7.25.9': resolution: {integrity: sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==} engines: {node: '>=6.9.0'} @@ -1221,24 +1193,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoped-functions@7.24.7': - resolution: {integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoped-functions@7.25.9': resolution: {integrity: sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.25.0': - resolution: {integrity: sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.25.9': resolution: {integrity: sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==} engines: {node: '>=6.9.0'} @@ -1257,36 +1217,18 @@ packages: peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.25.4': - resolution: {integrity: sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-classes@7.25.9': resolution: {integrity: sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.24.7': - resolution: {integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.25.9': resolution: {integrity: sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-destructuring@7.24.8': - resolution: {integrity: sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-destructuring@7.25.9': resolution: {integrity: sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==} engines: {node: '>=6.9.0'} @@ -1329,36 +1271,18 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-flow-strip-types@7.25.2': - resolution: {integrity: sha512-InBZ0O8tew5V0K6cHcQ+wgxlrjOw1W4wDXLkOTjLRD8GYhTSkxTVBtdy3MMtvYBrbAWa1Qm3hNoTc1620Yj+Mg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-flow-strip-types@7.25.9': resolution: {integrity: sha512-/VVukELzPDdci7UUsWQaSkhgnjIWXnIyRpM02ldxaVoFK96c41So8JcKT3m0gYjyv7j5FNPGS5vfELrWalkbDA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-for-of@7.24.7': - resolution: {integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-for-of@7.25.9': resolution: {integrity: sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-function-name@7.25.1': - resolution: {integrity: sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-function-name@7.25.9': resolution: {integrity: sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==} engines: {node: '>=6.9.0'} @@ -1371,12 +1295,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-literals@7.25.2': - resolution: {integrity: sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-literals@7.25.9': resolution: {integrity: sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==} engines: {node: '>=6.9.0'} @@ -1389,12 +1307,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-member-expression-literals@7.24.7': - resolution: {integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-member-expression-literals@7.25.9': resolution: {integrity: sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==} engines: {node: '>=6.9.0'} @@ -1407,12 +1319,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.24.8': - resolution: {integrity: sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.26.3': resolution: {integrity: sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==} engines: {node: '>=6.9.0'} @@ -1461,12 +1367,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-super@7.24.7': - resolution: {integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-super@7.25.9': resolution: {integrity: sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==} engines: {node: '>=6.9.0'} @@ -1485,12 +1385,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-parameters@7.24.7': - resolution: {integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-parameters@7.25.9': resolution: {integrity: sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==} engines: {node: '>=6.9.0'} @@ -1509,24 +1403,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-property-literals@7.24.7': - resolution: {integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-property-literals@7.25.9': resolution: {integrity: sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-display-name@7.24.7': - resolution: {integrity: sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-display-name@7.25.9': resolution: {integrity: sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==} engines: {node: '>=6.9.0'} @@ -1557,12 +1439,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx@7.25.2': - resolution: {integrity: sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx@7.25.9': resolution: {integrity: sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==} engines: {node: '>=6.9.0'} @@ -1587,24 +1463,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-shorthand-properties@7.24.7': - resolution: {integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-shorthand-properties@7.25.9': resolution: {integrity: sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-spread@7.24.7': - resolution: {integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-spread@7.25.9': resolution: {integrity: sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==} engines: {node: '>=6.9.0'} @@ -1617,12 +1481,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-template-literals@7.24.7': - resolution: {integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-template-literals@7.25.9': resolution: {integrity: sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==} engines: {node: '>=6.9.0'} @@ -1738,8 +1596,8 @@ packages: resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} engines: {node: '>=6.9.0'} - '@balancer/sdk@1.0.1': - resolution: {integrity: sha512-/nbqzTWZdZjoHr8MKMBLOQewojdwqmIFYdVVv3NXUmnAi3Va27bo5mAKZ2n5yo/bJ4w5wtkXDEm2BixkUXWRvw==} + '@balancer/sdk@1.0.2': + resolution: {integrity: sha512-OACHj2IjJxX+fjnTPZcI+bP2bUfe+VrHAYm/SnpVCm3W/uE1ESLOIZaQ/HAHrAevF4enwrr5mduulULk1dRudQ==} engines: {node: '>=18.x'} '@bcoe/v8-coverage@0.2.3': @@ -3076,6 +2934,12 @@ packages: peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@graphql-tools/batch-execute@9.0.11': + resolution: {integrity: sha512-v9b618cj3hIrRGTDrOotYzpK+ZigvNcKdXK3LNBM4g/uA7pND0d4GOnuOSBQGKKN6kT/1nsz4ZpUxCoUvWPbzg==} + engines: {node: '>=18.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@graphql-tools/batch-execute@9.0.4': resolution: {integrity: sha512-kkebDLXgDrep5Y0gK1RN3DMUlLqNhg60OAz0lTCqrYeja6DshxLtLkj+zV4mVbBA4mQOEoBmw6g1LZs3dA84/w==} engines: {node: '>=16.0.0'} @@ -3094,6 +2958,12 @@ packages: peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@graphql-tools/delegate@10.2.9': + resolution: {integrity: sha512-JlD/IdC26tyqopYvgXo48XwlDnpYPVs523dq5tg/u8kxJe3PtBmEUoE6EQ4CEMk0mB/r5ck+ZXTHt/wiOCWKhw==} + engines: {node: '>=18.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@graphql-tools/documents@1.0.1': resolution: {integrity: sha512-aweoMH15wNJ8g7b2r4C4WRuJxZ0ca8HtNO54rkye/3duxTkW4fGBEutCx03jCIr5+a1l+4vFJNP859QnAVBVCA==} engines: {node: '>=16.0.0'} @@ -3124,6 +2994,12 @@ packages: peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@graphql-tools/executor@1.3.11': + resolution: {integrity: sha512-7Q1IwIuSgarDeaCOZ1VMZvGaWY7cD2jj+uTNn/PsenYYKqFWKH30UylEK67ZTpVMXqBJctFaxVnPP7KM0+LPWg==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@graphql-tools/git-loader@8.0.7': resolution: {integrity: sha512-+s23lxHR24+zLDk9/Hfl7/8Qcal8Q1yJ8armRp1fvcJyuc0RTZv97ZoZb0tArTfME74z+kJ92Mx4SfZMd7mHSQ==} engines: {node: '>=16.0.0'} @@ -3166,6 +3042,12 @@ packages: peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@graphql-tools/merge@9.0.16': + resolution: {integrity: sha512-Ek2ee3e4qMsMM2pBBZpDmL7j51b3F5qYsHtckO05e8zvOWuS28yBu+VhZYOtUPr/q+lBWhL+0rvFXaUwHZEuQQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@graphql-tools/merge@9.0.7': resolution: {integrity: sha512-lbTrIuXIbUSmSumHkPRY1QX0Z8JEtmRhnIrkH7vkfeEmf0kNn/nCWvJwqokm5U7L+a+DA1wlRM4slIlbfXjJBA==} engines: {node: '>=16.0.0'} @@ -3200,6 +3082,12 @@ packages: peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@graphql-tools/schema@10.0.15': + resolution: {integrity: sha512-QAD9XeC/iaVugMYWet73Vz/4wp1qmKHYPj1z/TyIW/fX41oNmNSBGNqdstMsvSG97PWLhFgbUqVCvY+1KesQKw==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@graphql-tools/schema@10.0.6': resolution: {integrity: sha512-EIJgPRGzpvDFEjVp+RF1zNNYIC36BYuIeZ514jFoJnI6IdxyVyIRDLx/ykgMdaa1pKQerpfdqDnsF4JnZoDHSQ==} engines: {node: '>=16.0.0'} @@ -3218,6 +3106,12 @@ packages: peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@graphql-tools/utils@10.7.1': + resolution: {integrity: sha512-mpHAA5EddtxvnkHIBEEon5++tvL5T+j3OeOP4CAXbguAK2RBRM9DVVsoc9U68vSPLJjBRGp+b5NjlRn04g9rMA==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@graphql-tools/utils@8.13.1': resolution: {integrity: sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==} peerDependencies: @@ -3228,9 +3122,9 @@ packages: peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - '@graphql-tools/wrap@10.0.5': - resolution: {integrity: sha512-Cbr5aYjr3HkwdPvetZp1cpDWTGdD1Owgsb3z/ClzhmrboiK86EnQDxDvOJiQkDCPWE9lNBwj8Y4HfxroY0D9DQ==} - engines: {node: '>=16.0.0'} + '@graphql-tools/wrap@10.0.27': + resolution: {integrity: sha512-UikYBknzYgJKhzIXrzA58EO8IZ+jlX/iPmfUactK6aypc7iKCJzGD31Ha8rDI9GiHPn1F8PUAB4cTlGJ1qRh3w==} + engines: {node: '>=18.0.0'} peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 @@ -3294,10 +3188,6 @@ packages: resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jridgewell/gen-mapping@0.3.3': - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} - engines: {node: '>=6.0.0'} - '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -3310,10 +3200,6 @@ packages: resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.1.2': - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.2.1': resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} @@ -3324,9 +3210,6 @@ packages: '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@jridgewell/trace-mapping@0.3.20': - resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} - '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} @@ -4922,10 +4805,14 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 - '@vitest/coverage-v8@1.6.0': - resolution: {integrity: sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==} + '@vitest/coverage-v8@2.1.8': + resolution: {integrity: sha512-2Y7BPlKH18mAZYAW1tYByudlCYrQyl5RGvnnDYJKW5tCiO5qg3KSAy3XAxcxKz900a0ZXxWtKrMuZLe3lKBpJw==} peerDependencies: - vitest: 1.6.0 + '@vitest/browser': 2.1.8 + vitest: 2.1.8 + peerDependenciesMeta: + '@vitest/browser': + optional: true '@vitest/expect@2.1.8': resolution: {integrity: sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==} @@ -5138,6 +5025,10 @@ packages: '@webgpu/types@0.1.51': resolution: {integrity: sha512-ktR3u64NPjwIViNCck+z9QeyN0iPkQCUOQ07ZCV1RzlkfP+olLTeEZ95O1QHS+v4w9vJeY9xj/uJuSphsHy5rQ==} + '@whatwg-node/disposablestack@0.0.5': + resolution: {integrity: sha512-9lXugdknoIequO4OYvIjhygvfSEgnO8oASLqLelnDhkRjgBZhc39shC3QSlZuyDO9bgYSIVa2cHAiN+St3ty4w==} + engines: {node: '>=18.0.0'} + '@whatwg-node/events@0.0.3': resolution: {integrity: sha512-IqnKIDWfXBJkvy/k6tzskWTc2NK3LcqHlb+KHGCrjOCH4jfQckRX0NAiIcC/vIqQkzLYw2r2CTSwAxcrtcD6lA==} @@ -6007,6 +5898,9 @@ packages: dataloader@2.2.2: resolution: {integrity: sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==} + dataloader@2.2.3: + resolution: {integrity: sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==} + date-fns@2.30.0: resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} engines: {node: '>=0.11'} @@ -7590,9 +7484,6 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-tokens@9.0.0: - resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} - js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -9483,9 +9374,6 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - std-env@3.7.0: - resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} - std-env@3.8.0: resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} @@ -9569,9 +9457,6 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@2.1.0: - resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} - strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} @@ -9699,9 +9584,9 @@ packages: engines: {node: '>=10'} hasBin: true - test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -9854,9 +9739,6 @@ packages: tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} - tslib@2.8.0: - resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} - tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -10636,8 +10518,8 @@ snapshots: '@ampproject/remapping@2.2.1': dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.20 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 '@ampproject/remapping@2.3.0': dependencies: @@ -10665,7 +10547,7 @@ snapshots: response-iterator: 0.2.6 symbol-observable: 4.0.0 ts-invariant: 0.10.3 - tslib: 2.7.0 + tslib: 2.8.1 zen-observable-ts: 1.2.5 optionalDependencies: graphql-ws: 5.16.0(graphql@16.10.0) @@ -10683,13 +10565,13 @@ snapshots: '@ardatan/relay-compiler@12.0.0(graphql@16.10.0)': dependencies: - '@babel/core': 7.25.2 - '@babel/generator': 7.25.6 - '@babel/parser': 7.25.6 + '@babel/core': 7.26.0 + '@babel/generator': 7.26.3 + '@babel/parser': 7.26.3 '@babel/runtime': 7.26.0 - '@babel/traverse': 7.25.6 - '@babel/types': 7.25.6 - babel-preset-fbjs: 3.4.0(@babel/core@7.25.2) + '@babel/traverse': 7.26.4 + '@babel/types': 7.26.3 + babel-preset-fbjs: 3.4.0(@babel/core@7.26.0) chalk: 4.1.2 fb-watchman: 2.0.2 fbjs: 3.0.5 @@ -10804,8 +10686,8 @@ snapshots: '@babel/generator@7.23.3': dependencies: '@babel/types': 7.23.3 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.20 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 '@babel/generator@7.25.6': @@ -10823,10 +10705,6 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 - '@babel/helper-annotate-as-pure@7.24.7': - dependencies: - '@babel/types': 7.25.6 - '@babel/helper-annotate-as-pure@7.25.9': dependencies: '@babel/types': 7.26.3 @@ -10855,32 +10733,6 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.25.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-member-expression-to-functions': 7.24.8 - '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/traverse': 7.25.6 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/helper-create-class-features-plugin@7.25.4(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-member-expression-to-functions': 7.24.8 - '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/helper-replace-supers': 7.25.0(@babel/core@7.26.0) - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/traverse': 7.25.6 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/helper-create-class-features-plugin@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -10951,18 +10803,11 @@ snapshots: '@babel/helper-function-name@7.23.0': dependencies: '@babel/template': 7.22.15 - '@babel/types': 7.23.3 + '@babel/types': 7.26.3 '@babel/helper-hoist-variables@7.22.5': dependencies: - '@babel/types': 7.23.3 - - '@babel/helper-member-expression-to-functions@7.24.8': - dependencies: - '@babel/traverse': 7.25.6 - '@babel/types': 7.25.6 - transitivePeerDependencies: - - supports-color + '@babel/types': 7.26.3 '@babel/helper-member-expression-to-functions@7.25.9': dependencies: @@ -10973,12 +10818,12 @@ snapshots: '@babel/helper-module-imports@7.22.15': dependencies: - '@babel/types': 7.23.3 + '@babel/types': 7.26.3 '@babel/helper-module-imports@7.24.7': dependencies: '@babel/traverse': 7.25.6 - '@babel/types': 7.25.6 + '@babel/types': 7.26.3 transitivePeerDependencies: - supports-color @@ -11027,10 +10872,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-optimise-call-expression@7.24.7': - dependencies: - '@babel/types': 7.25.6 - '@babel/helper-optimise-call-expression@7.25.9': dependencies: '@babel/types': 7.26.3 @@ -11058,24 +10899,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.25.0(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-member-expression-to-functions': 7.24.8 - '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/traverse': 7.25.6 - transitivePeerDependencies: - - supports-color - - '@babel/helper-replace-supers@7.25.0(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-member-expression-to-functions': 7.24.8 - '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/traverse': 7.25.6 - transitivePeerDependencies: - - supports-color - '@babel/helper-replace-supers@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11097,19 +10920,12 @@ snapshots: '@babel/helper-simple-access@7.22.5': dependencies: - '@babel/types': 7.23.3 + '@babel/types': 7.26.3 '@babel/helper-simple-access@7.24.7': dependencies: '@babel/traverse': 7.25.6 - '@babel/types': 7.25.6 - transitivePeerDependencies: - - supports-color - - '@babel/helper-skip-transparent-expression-wrappers@7.24.7': - dependencies: - '@babel/traverse': 7.25.6 - '@babel/types': 7.25.6 + '@babel/types': 7.26.3 transitivePeerDependencies: - supports-color @@ -11122,7 +10938,7 @@ snapshots: '@babel/helper-split-export-declaration@7.22.6': dependencies: - '@babel/types': 7.23.3 + '@babel/types': 7.26.3 '@babel/helper-string-parser@7.22.5': {} @@ -11161,7 +10977,7 @@ snapshots: '@babel/helpers@7.25.6': dependencies: '@babel/template': 7.25.0 - '@babel/types': 7.25.6 + '@babel/types': 7.26.3 '@babel/helpers@7.26.0': dependencies: @@ -11176,7 +10992,7 @@ snapshots: '@babel/highlight@7.24.7': dependencies: - '@babel/helper-validator-identifier': 7.24.7 + '@babel/helper-validator-identifier': 7.25.9 chalk: 2.4.2 js-tokens: 4.0.0 picocolors: 1.1.1 @@ -11187,7 +11003,7 @@ snapshots: '@babel/parser@7.25.6': dependencies: - '@babel/types': 7.25.6 + '@babel/types': 7.26.3 '@babel/parser@7.26.3': dependencies: @@ -11268,19 +11084,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - transitivePeerDependencies: - - supports-color - '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 transitivePeerDependencies: - supports-color @@ -11301,14 +11109,14 @@ snapshots: '@babel/helper-plugin-utils': 7.25.9 '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.26.0) - '@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.25.2)': + '@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.26.0)': dependencies: - '@babel/compat-data': 7.25.4 - '@babel/core': 7.25.2 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) + '@babel/compat-data': 7.26.3 + '@babel/core': 7.26.0 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.26.0) + '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.0) '@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.26.0)': dependencies: @@ -11342,12 +11150,13 @@ snapshots: '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-plugin-utils': 7.25.9 '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)': dependencies: @@ -11393,11 +11202,6 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-flow@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-flow@7.26.0(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11458,11 +11262,6 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11510,12 +11309,13 @@ snapshots: '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-plugin-utils': 7.25.9 '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)': dependencies: @@ -11585,11 +11385,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-arrow-functions@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11639,11 +11434,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-block-scoped-functions@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11655,11 +11445,6 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-block-scoping@7.25.0(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-block-scoping@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11705,18 +11490,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.25.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) - '@babel/traverse': 7.25.6 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-classes@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11742,12 +11515,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/template': 7.25.0 - '@babel/plugin-transform-computed-properties@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11761,11 +11528,6 @@ snapshots: '@babel/helper-plugin-utils': 7.25.9 '@babel/template': 7.25.9 - '@babel/plugin-transform-destructuring@7.24.8(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-destructuring@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11847,12 +11609,6 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-flow-strip-types@7.25.2(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-flow': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-flow-strip-types@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11866,14 +11622,6 @@ snapshots: '@babel/helper-plugin-utils': 7.25.9 '@babel/plugin-syntax-flow': 7.26.0(@babel/core@7.26.0) - '@babel/plugin-transform-for-of@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-for-of@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11891,15 +11639,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.25.1(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/traverse': 7.25.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-function-name@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11930,11 +11669,6 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-literals@7.25.2(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-literals@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11957,11 +11691,6 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-member-expression-literals@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-member-expression-literals@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -11990,15 +11719,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.24.8(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-simple-access': 7.24.7 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-modules-commonjs@7.26.3(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -12115,14 +11835,6 @@ snapshots: '@babel/helper-plugin-utils': 7.25.9 '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-object-super@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-object-super@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -12168,11 +11880,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-parameters@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -12220,11 +11927,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-property-literals@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -12236,11 +11938,6 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-react-display-name@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-react-display-name@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -12284,17 +11981,6 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-react-jsx@7.25.2(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) - '@babel/types': 7.25.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -12367,11 +12053,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-shorthand-properties@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-shorthand-properties@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -12383,14 +12064,6 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-spread@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-spread@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -12419,11 +12092,6 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-transform-template-literals@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-template-literals@7.25.9(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -12785,9 +12453,9 @@ snapshots: dependencies: '@babel/code-frame': 7.24.7 '@babel/generator': 7.25.6 - '@babel/parser': 7.25.6 + '@babel/parser': 7.26.3 '@babel/template': 7.25.0 - '@babel/types': 7.25.6 + '@babel/types': 7.26.3 debug: 4.4.0 globals: 11.12.0 transitivePeerDependencies: @@ -12822,7 +12490,7 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - '@balancer/sdk@1.0.1(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1)': + '@balancer/sdk@1.0.2(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1)': dependencies: decimal.js-light: 2.5.1 lodash.clonedeep: 4.5.0 @@ -14356,6 +14024,13 @@ snapshots: transitivePeerDependencies: - encoding + '@graphql-tools/batch-execute@9.0.11(graphql@16.10.0)': + dependencies: + '@graphql-tools/utils': 10.7.1(graphql@16.10.0) + dataloader: 2.2.3 + graphql: 16.10.0 + tslib: 2.8.1 + '@graphql-tools/batch-execute@9.0.4(graphql@16.10.0)': dependencies: '@graphql-tools/utils': 10.5.4(graphql@16.10.0) @@ -14386,6 +14061,18 @@ snapshots: graphql: 16.10.0 tslib: 2.8.1 + '@graphql-tools/delegate@10.2.9(graphql@16.10.0)': + dependencies: + '@graphql-tools/batch-execute': 9.0.11(graphql@16.10.0) + '@graphql-tools/executor': 1.3.11(graphql@16.10.0) + '@graphql-tools/schema': 10.0.15(graphql@16.10.0) + '@graphql-tools/utils': 10.7.1(graphql@16.10.0) + '@repeaterjs/repeater': 3.0.6 + dataloader: 2.2.3 + dset: 3.1.4 + graphql: 16.10.0 + tslib: 2.8.1 + '@graphql-tools/documents@1.0.1(graphql@16.10.0)': dependencies: graphql: 16.10.0 @@ -14439,6 +14126,16 @@ snapshots: tslib: 2.8.1 value-or-promise: 1.0.12 + '@graphql-tools/executor@1.3.11(graphql@16.10.0)': + dependencies: + '@graphql-tools/utils': 10.7.1(graphql@16.10.0) + '@graphql-typed-document-node/core': 3.2.0(graphql@16.10.0) + '@repeaterjs/repeater': 3.0.6 + '@whatwg-node/disposablestack': 0.0.5 + graphql: 16.10.0 + tslib: 2.8.1 + value-or-promise: 1.0.12 + '@graphql-tools/git-loader@8.0.7(graphql@16.10.0)': dependencies: '@graphql-tools/graphql-tag-pluck': 8.3.2(graphql@16.10.0) @@ -14478,10 +14175,10 @@ snapshots: '@graphql-tools/graphql-tag-pluck@8.3.2(graphql@16.10.0)': dependencies: '@babel/core': 7.25.2 - '@babel/parser': 7.25.6 + '@babel/parser': 7.26.3 '@babel/plugin-syntax-import-assertions': 7.25.6(@babel/core@7.25.2) '@babel/traverse': 7.25.6 - '@babel/types': 7.25.6 + '@babel/types': 7.26.3 '@graphql-tools/utils': 10.5.4(graphql@16.10.0) graphql: 16.10.0 tslib: 2.8.1 @@ -14511,6 +14208,12 @@ snapshots: p-limit: 3.1.0 tslib: 2.7.0 + '@graphql-tools/merge@9.0.16(graphql@16.10.0)': + dependencies: + '@graphql-tools/utils': 10.7.1(graphql@16.10.0) + graphql: 16.10.0 + tslib: 2.8.1 + '@graphql-tools/merge@9.0.7(graphql@16.10.0)': dependencies: '@graphql-tools/utils': 10.5.4(graphql@16.10.0) @@ -14573,6 +14276,14 @@ snapshots: - encoding - supports-color + '@graphql-tools/schema@10.0.15(graphql@16.10.0)': + dependencies: + '@graphql-tools/merge': 9.0.16(graphql@16.10.0) + '@graphql-tools/utils': 10.7.1(graphql@16.10.0) + graphql: 16.10.0 + tslib: 2.8.1 + value-or-promise: 1.0.12 + '@graphql-tools/schema@10.0.6(graphql@16.10.0)': dependencies: '@graphql-tools/merge': 9.0.7(graphql@16.10.0) @@ -14589,7 +14300,7 @@ snapshots: '@graphql-tools/executor-http': 1.1.6(@types/node@20.10.2)(graphql@16.10.0) '@graphql-tools/executor-legacy-ws': 1.1.0(bufferutil@4.0.8)(graphql@16.10.0)(utf-8-validate@5.0.10) '@graphql-tools/utils': 10.5.4(graphql@16.10.0) - '@graphql-tools/wrap': 10.0.5(graphql@16.10.0) + '@graphql-tools/wrap': 10.0.27(graphql@16.10.0) '@types/ws': 8.5.12 '@whatwg-node/fetch': 0.9.21 graphql: 16.10.0 @@ -14611,6 +14322,14 @@ snapshots: graphql: 16.10.0 tslib: 2.7.0 + '@graphql-tools/utils@10.7.1(graphql@16.10.0)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.10.0) + cross-inspect: 1.0.1 + dset: 3.1.4 + graphql: 16.10.0 + tslib: 2.8.1 + '@graphql-tools/utils@8.13.1(graphql@16.10.0)': dependencies: graphql: 16.10.0 @@ -14622,14 +14341,13 @@ snapshots: graphql: 16.10.0 tslib: 2.8.1 - '@graphql-tools/wrap@10.0.5(graphql@16.10.0)': + '@graphql-tools/wrap@10.0.27(graphql@16.10.0)': dependencies: - '@graphql-tools/delegate': 10.0.21(graphql@16.10.0) - '@graphql-tools/schema': 10.0.6(graphql@16.10.0) - '@graphql-tools/utils': 10.5.4(graphql@16.10.0) + '@graphql-tools/delegate': 10.2.9(graphql@16.10.0) + '@graphql-tools/schema': 10.0.15(graphql@16.10.0) + '@graphql-tools/utils': 10.7.1(graphql@16.10.0) graphql: 16.10.0 tslib: 2.8.1 - value-or-promise: 1.0.12 '@graphql-typed-document-node/core@3.2.0(graphql@16.10.0)': dependencies: @@ -14707,12 +14425,6 @@ snapshots: '@types/yargs': 17.0.33 chalk: 4.1.2 - '@jridgewell/gen-mapping@0.3.3': - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.20 - '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -14727,8 +14439,6 @@ snapshots: '@jridgewell/resolve-uri@3.1.1': {} - '@jridgewell/set-array@1.1.2': {} - '@jridgewell/set-array@1.2.1': {} '@jridgewell/source-map@0.3.6': @@ -14738,11 +14448,6 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.0': {} - '@jridgewell/trace-mapping@0.3.20': - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.1 @@ -14911,42 +14616,6 @@ snapshots: - supports-color - utf-8-validate - '@metamask/sdk@0.28.4(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.26.0)(@babel/preset-env@7.25.4(@babel/core@7.26.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.3)(utf-8-validate@5.0.10)': - dependencies: - '@metamask/onboarding': 1.0.1 - '@metamask/providers': 16.1.0 - '@metamask/sdk-communication-layer': 0.28.2(cross-fetch@4.0.0)(eciesjs@0.3.20)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.7.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@metamask/sdk-install-modal-web': 0.28.1(i18next@23.11.5)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.26.0)(@babel/preset-env@7.25.4(@babel/core@7.26.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0) - '@types/dom-screen-wake-lock': 1.0.3 - '@types/uuid': 10.0.0 - bowser: 2.11.0 - cross-fetch: 4.0.0 - debug: 4.4.0 - eciesjs: 0.3.20 - eth-rpc-errors: 4.0.3 - eventemitter2: 6.4.9 - i18next: 23.11.5 - i18next-browser-languagedetector: 7.1.0 - obj-multiplex: 1.0.0 - pump: 3.0.2 - qrcode-terminal-nooctal: 0.12.1 - react-native-webview: 11.26.1(react-native@0.75.3(@babel/core@7.26.0)(@babel/preset-env@7.25.4(@babel/core@7.26.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0) - readable-stream: 3.6.2 - rollup-plugin-visualizer: 5.12.0(rollup@4.21.3) - socket.io-client: 4.7.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) - util: 0.12.5 - uuid: 8.3.2 - optionalDependencies: - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - transitivePeerDependencies: - - bufferutil - - encoding - - react-native - - rollup - - supports-color - - utf-8-validate - '@metamask/sdk@0.31.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: '@babel/runtime': 7.26.0 @@ -15941,7 +15610,7 @@ snapshots: '@react-spring/types@9.7.5': {} - '@react-three/drei@9.117.3(@react-three/fiber@8.17.10(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0)(three@0.170.0))(@types/react@18.2.34)(@types/three@0.170.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(three@0.170.0)(use-sync-external-store@1.2.0(react@18.2.0))': + '@react-three/drei@9.117.3(@react-three/fiber@8.17.10(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0)(three@0.170.0))(@types/react@18.2.34)(@types/three@0.170.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(three@0.170.0)(use-sync-external-store@1.2.2(react@18.2.0))': dependencies: '@babel/runtime': 7.26.0 '@mediapipe/tasks-vision': 0.10.17 @@ -15968,7 +15637,7 @@ snapshots: tunnel-rat: 0.1.2(@types/react@18.2.34)(react@18.2.0) utility-types: 3.11.0 uuid: 9.0.1 - zustand: 5.0.1(@types/react@18.2.34)(react@18.2.0)(use-sync-external-store@1.2.0(react@18.2.0)) + zustand: 5.0.1(@types/react@18.2.34)(react@18.2.0)(use-sync-external-store@1.2.2(react@18.2.0)) optionalDependencies: react-dom: 18.2.0(react@18.2.0) transitivePeerDependencies: @@ -16166,7 +15835,7 @@ snapshots: '@sentry/bundler-plugin-core@2.22.3': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.0 '@sentry/babel-plugin-component-annotate': 2.22.3 '@sentry/cli': 2.36.1 dotenv: 16.4.7 @@ -16281,7 +15950,7 @@ snapshots: - react - supports-color - '@sentry/nextjs@8.30.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.53.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@14.2.15(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(webpack@5.94.0)': + '@sentry/nextjs@8.30.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.53.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@14.2.15(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(webpack@5.94.0)': dependencies: '@opentelemetry/instrumentation-http': 0.53.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.27.0 @@ -16295,7 +15964,7 @@ snapshots: '@sentry/vercel-edge': 8.30.0 '@sentry/webpack-plugin': 2.22.3(webpack@5.94.0) chalk: 3.0.0 - next: 14.2.15(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + next: 14.2.15(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) resolve: 1.22.8 rollup: 3.29.4 stacktrace-parser: 0.1.10 @@ -16600,16 +16269,16 @@ snapshots: '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.25.6 + '@babel/types': 7.26.3 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.25.6 - '@babel/types': 7.25.6 + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.25.6 + '@babel/types': 7.26.3 '@types/connect@3.4.36': dependencies: @@ -17111,6 +16780,11 @@ snapshots: next: 14.2.15(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 + '@vercel/speed-insights@1.1.0(next@14.2.15(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)': + optionalDependencies: + next: 14.2.15(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react: 18.2.0 + '@vercel/style-guide@5.2.0(@next/eslint-plugin-next@14.2.6)(eslint@8.43.0)(prettier@3.4.2)(typescript@5.3.3)': dependencies: '@babel/core': 7.23.3 @@ -17165,21 +16839,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@1.6.0(vitest@2.1.8(@types/node@20.10.2)(happy-dom@15.11.7)(msw@2.0.10(typescript@5.4.5))(terser@5.37.0))': + '@vitest/coverage-v8@2.1.8(vitest@2.1.8(@types/node@20.10.2)(happy-dom@15.11.7)(msw@2.0.10(typescript@5.4.5))(terser@5.37.0))': dependencies: - '@ampproject/remapping': 2.2.1 + '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 - debug: 4.3.7 + debug: 4.4.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.1.7 - magic-string: 0.30.11 + magic-string: 0.30.17 magicast: 0.3.5 - picocolors: 1.1.0 - std-env: 3.7.0 - strip-literal: 2.1.0 - test-exclude: 6.0.0 + std-env: 3.8.0 + test-exclude: 7.0.1 + tinyrainbow: 1.2.0 vitest: 2.1.8(@types/node@20.10.2)(happy-dom@15.11.7)(msw@2.0.10(typescript@5.4.5))(terser@5.37.0) transitivePeerDependencies: - supports-color @@ -17290,45 +16963,6 @@ snapshots: - utf-8-validate - zod - '@wagmi/connectors@5.1.15(@types/react@18.2.34)(@wagmi/core@2.13.8(@tanstack/query-core@5.56.2)(@types/react@18.2.34)(react@18.2.0)(typescript@5.4.5)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1)))(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.26.0)(@babel/preset-env@7.25.4(@babel/core@7.26.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.3)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1))(zod@3.24.1)': - dependencies: - '@coinbase/wallet-sdk': 4.0.4 - '@metamask/sdk': 0.28.4(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.26.0)(@babel/preset-env@7.25.4(@babel/core@7.26.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.3)(utf-8-validate@5.0.10) - '@safe-global/safe-apps-provider': 0.18.3(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1) - '@wagmi/core': 2.13.8(@tanstack/query-core@5.56.2)(@types/react@18.2.34)(react@18.2.0)(typescript@5.4.5)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1)) - '@walletconnect/ethereum-provider': 2.17.0(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10) - '@walletconnect/modal': 2.7.0(@types/react@18.2.34)(react@18.2.0) - cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - viem: 2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/kv' - - bufferutil - - encoding - - ioredis - - react - - react-dom - - react-native - - rollup - - supports-color - - uWebSockets.js - - utf-8-validate - - zod - '@wagmi/connectors@5.5.3(@types/react@18.2.34)(@wagmi/core@2.15.2(@tanstack/query-core@5.56.2)(@types/react@18.2.34)(react@18.2.0)(typescript@5.4.5)(use-sync-external-store@1.2.0(react@18.2.0))(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1)))(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1))(zod@3.24.1)': dependencies: '@coinbase/wallet-sdk': 4.2.3 @@ -17788,6 +17422,10 @@ snapshots: '@webgpu/types@0.1.51': {} + '@whatwg-node/disposablestack@0.0.5': + dependencies: + tslib: 2.8.1 + '@whatwg-node/events@0.0.3': {} '@whatwg-node/fetch@0.8.8': @@ -17820,7 +17458,7 @@ snapshots: '@wry/caches@1.0.1': dependencies: - tslib: 2.7.0 + tslib: 2.8.1 '@wry/context@0.7.4': dependencies: @@ -17828,7 +17466,7 @@ snapshots: '@wry/equality@0.5.7': dependencies: - tslib: 2.7.0 + tslib: 2.8.1 '@wry/trie@0.4.3': dependencies: @@ -17836,7 +17474,7 @@ snapshots: '@wry/trie@0.5.0': dependencies: - tslib: 2.7.0 + tslib: 2.8.1 '@xtuc/ieee754@1.2.0': {} @@ -18174,35 +17812,35 @@ snapshots: transitivePeerDependencies: - '@babel/core' - babel-preset-fbjs@3.4.0(@babel/core@7.25.2): + babel-preset-fbjs@3.4.0(@babel/core@7.26.0): dependencies: - '@babel/core': 7.25.2 - '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.25.2) - '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.25.2) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) - '@babel/plugin-syntax-flow': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-block-scoped-functions': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-block-scoping': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-transform-classes': 7.25.4(@babel/core@7.25.2) - '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-destructuring': 7.24.8(@babel/core@7.25.2) - '@babel/plugin-transform-flow-strip-types': 7.25.2(@babel/core@7.25.2) - '@babel/plugin-transform-for-of': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-function-name': 7.25.1(@babel/core@7.25.2) - '@babel/plugin-transform-literals': 7.25.2(@babel/core@7.25.2) - '@babel/plugin-transform-member-expression-literals': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.25.2) - '@babel/plugin-transform-object-super': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-property-literals': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-react-display-name': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-react-jsx': 7.25.2(@babel/core@7.25.2) - '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-template-literals': 7.24.7(@babel/core@7.25.2) + '@babel/core': 7.26.0 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.26.0) + '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.26.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.26.0) + '@babel/plugin-syntax-flow': 7.26.0(@babel/core@7.26.0) + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.26.0) + '@babel/plugin-transform-arrow-functions': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-block-scoped-functions': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-block-scoping': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-classes': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-computed-properties': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-destructuring': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-flow-strip-types': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-for-of': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-function-name': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-literals': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-member-expression-literals': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-modules-commonjs': 7.26.3(@babel/core@7.26.0) + '@babel/plugin-transform-object-super': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-property-literals': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-react-display-name': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-shorthand-properties': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-spread': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-template-literals': 7.25.9(@babel/core@7.26.0) babel-plugin-syntax-trailing-function-commas: 7.0.0-beta.0 transitivePeerDependencies: - supports-color @@ -18805,6 +18443,8 @@ snapshots: dataloader@2.2.2: {} + dataloader@2.2.3: {} + date-fns@2.30.0: dependencies: '@babel/runtime': 7.25.6 @@ -20526,7 +20166,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.25 - debug: 4.3.7 + debug: 4.4.0 istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -20640,8 +20280,6 @@ snapshots: js-tokens@4.0.0: {} - js-tokens@9.0.0: {} - js-yaml@3.14.1: dependencies: argparse: 1.0.10 @@ -20835,7 +20473,7 @@ snapshots: mlly: 1.7.1 node-forge: 1.3.1 pathe: 1.1.2 - std-env: 3.7.0 + std-env: 3.8.0 ufo: 1.5.4 untun: 0.1.3 uqr: 0.1.2 @@ -20999,8 +20637,8 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.25.6 - '@babel/types': 7.25.6 + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 source-map-js: 1.2.1 make-dir@2.1.0: @@ -21304,7 +20942,7 @@ snapshots: mlly@1.7.1: dependencies: - acorn: 8.13.0 + acorn: 8.14.0 pathe: 1.1.2 pkg-types: 1.2.0 ufo: 1.5.4 @@ -21435,6 +21073,32 @@ snapshots: - '@babel/core' - babel-plugin-macros + next@14.2.15(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@next/env': 14.2.15 + '@swc/helpers': 0.5.5 + busboy: 1.6.0 + caniuse-lite: 1.0.30001689 + graceful-fs: 4.2.11 + postcss: 8.4.31 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + styled-jsx: 5.1.1(react@18.2.0) + optionalDependencies: + '@next/swc-darwin-arm64': 14.2.15 + '@next/swc-darwin-x64': 14.2.15 + '@next/swc-linux-arm64-gnu': 14.2.15 + '@next/swc-linux-arm64-musl': 14.2.15 + '@next/swc-linux-x64-gnu': 14.2.15 + '@next/swc-linux-x64-musl': 14.2.15 + '@next/swc-win32-arm64-msvc': 14.2.15 + '@next/swc-win32-ia32-msvc': 14.2.15 + '@next/swc-win32-x64-msvc': 14.2.15 + '@opentelemetry/api': 1.9.0 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + nextjs-toploader@1.6.12(next@14.2.15(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: next: 14.2.15(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -21451,6 +21115,14 @@ snapshots: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) + nextjs-toploader@1.6.12(next@14.2.15(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + next: 14.2.15(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + nprogress: 0.2.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + no-case@3.0.4: dependencies: lower-case: 2.0.2 @@ -21634,7 +21306,7 @@ snapshots: '@wry/caches': 1.0.1 '@wry/context': 0.7.4 '@wry/trie': 0.4.3 - tslib: 2.7.0 + tslib: 2.8.1 optionator@0.9.4: dependencies: @@ -22245,7 +21917,7 @@ snapshots: react: 18.2.0 react-remove-scroll-bar: 2.3.6(@types/react@18.2.34)(react@18.2.0) react-style-singleton: 2.2.1(@types/react@18.2.34)(react@18.2.0) - tslib: 2.8.0 + tslib: 2.8.1 use-callback-ref: 1.3.2(@types/react@18.2.34)(react@18.2.0) use-sidecar: 1.1.2(@types/react@18.2.34)(react@18.2.0) optionalDependencies: @@ -22471,7 +22143,7 @@ snapshots: resolve@1.22.8: dependencies: - is-core-module: 2.13.1 + is-core-module: 2.16.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -22520,15 +22192,6 @@ snapshots: optionalDependencies: rollup: 3.29.4 - rollup-plugin-visualizer@5.12.0(rollup@4.21.3): - dependencies: - open: 8.4.2 - picomatch: 2.3.1 - source-map: 0.7.4 - yargs: 17.7.2 - optionalDependencies: - rollup: 4.21.3 - rollup@3.29.4: optionalDependencies: fsevents: 2.3.3 @@ -22882,8 +22545,6 @@ snapshots: statuses@2.0.1: {} - std-env@3.7.0: {} - std-env@3.8.0: {} stream-shift@1.0.3: {} @@ -22972,10 +22633,6 @@ snapshots: strip-json-comments@3.1.1: {} - strip-literal@2.1.0: - dependencies: - js-tokens: 9.0.0 - strnum@1.0.5: {} styled-jsx@5.1.1(@babel/core@7.25.2)(babel-plugin-macros@3.1.0)(react@18.2.0): @@ -22993,6 +22650,11 @@ snapshots: optionalDependencies: '@babel/core': 7.26.0 + styled-jsx@5.1.1(react@18.2.0): + dependencies: + client-only: 0.0.1 + react: 18.2.0 + stylelint-config-recommended@14.0.1(stylelint@16.10.0(typescript@5.4.5)): dependencies: stylelint: 16.10.0(typescript@5.4.5) @@ -23137,11 +22799,11 @@ snapshots: commander: 2.20.3 source-map-support: 0.5.21 - test-exclude@6.0.0: + test-exclude@7.0.1: dependencies: '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 + glob: 10.4.5 + minimatch: 9.0.5 text-table@0.2.0: {} @@ -23244,7 +22906,7 @@ snapshots: ts-invariant@0.10.3: dependencies: - tslib: 2.7.0 + tslib: 2.8.1 ts-log@2.2.5: {} @@ -23267,8 +22929,6 @@ snapshots: tslib@2.7.0: {} - tslib@2.8.0: {} - tslib@2.8.1: {} tsutils@3.21.0(typescript@5.3.3): @@ -23691,43 +23351,6 @@ snapshots: - utf-8-validate - zod - wagmi@2.12.17(@tanstack/query-core@5.56.2)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.26.0)(@babel/preset-env@7.25.4(@babel/core@7.26.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.3)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1))(zod@3.24.1): - dependencies: - '@tanstack/react-query': 5.56.2(react@18.2.0) - '@wagmi/connectors': 5.1.15(@types/react@18.2.34)(@wagmi/core@2.13.8(@tanstack/query-core@5.56.2)(@types/react@18.2.34)(react@18.2.0)(typescript@5.4.5)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1)))(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.3(@babel/core@7.26.0)(@babel/preset-env@7.25.4(@babel/core@7.26.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.3)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1))(zod@3.24.1) - '@wagmi/core': 2.13.8(@tanstack/query-core@5.56.2)(@types/react@18.2.34)(react@18.2.0)(typescript@5.4.5)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1)) - react: 18.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) - viem: 2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@tanstack/query-core' - - '@types/react' - - '@upstash/redis' - - '@vercel/kv' - - bufferutil - - encoding - - immer - - ioredis - - react-dom - - react-native - - rollup - - supports-color - - uWebSockets.js - - utf-8-validate - - zod - wagmi@2.13.3(@tanstack/query-core@5.56.2)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.34)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.21.55(bufferutil@4.0.8)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.24.1))(zod@3.24.1): dependencies: '@tanstack/react-query': 5.56.2(react@18.2.0) @@ -24072,8 +23695,8 @@ snapshots: react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) - zustand@5.0.1(@types/react@18.2.34)(react@18.2.0)(use-sync-external-store@1.2.0(react@18.2.0)): + zustand@5.0.1(@types/react@18.2.34)(react@18.2.0)(use-sync-external-store@1.2.2(react@18.2.0)): optionalDependencies: '@types/react': 18.2.34 react: 18.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) + use-sync-external-store: 1.2.2(react@18.2.0) diff --git a/turbo.json b/turbo.json index c93b708c7..2adb4246f 100644 --- a/turbo.json +++ b/turbo.json @@ -14,7 +14,8 @@ "NODE_ENV", "SILENT_TESTS", "NEXT_PUBLIC_SENTRY_DSN", - "NEXT_RUNTIME" + "NEXT_RUNTIME", + "NEXT_PRIVATE_ALCHEMY_KEY" ], "tasks": { "dev": {