diff --git a/apps/cowswap-frontend/src/modules/hooksStore/cow-shed/constants.ts b/apps/cowswap-frontend/src/modules/hooksStore/cow-shed/constants.ts
new file mode 100644
index 0000000000..5817c045a3
--- /dev/null
+++ b/apps/cowswap-frontend/src/modules/hooksStore/cow-shed/constants.ts
@@ -0,0 +1,128 @@
+export const FACTORY_ABI = [
+ {
+ type: 'function',
+ name: 'executeHooks',
+ inputs: [
+ {
+ name: 'calls',
+ type: 'tuple[]',
+ internalType: 'struct Call[]',
+ components: [
+ {
+ name: 'target',
+ type: 'address',
+ internalType: 'address',
+ },
+ {
+ name: 'value',
+ type: 'uint256',
+ internalType: 'uint256',
+ },
+ {
+ name: 'callData',
+ type: 'bytes',
+ internalType: 'bytes',
+ },
+ {
+ name: 'allowFailure',
+ type: 'bool',
+ internalType: 'bool',
+ },
+ {
+ name: 'isDelegateCall',
+ type: 'bool',
+ internalType: 'bool',
+ },
+ ],
+ },
+ {
+ name: 'nonce',
+ type: 'bytes32',
+ internalType: 'bytes32',
+ },
+ {
+ name: 'deadline',
+ type: 'uint256',
+ internalType: 'uint256',
+ },
+ {
+ name: 'user',
+ type: 'address',
+ internalType: 'address',
+ },
+ {
+ name: 'signature',
+ type: 'bytes',
+ internalType: 'bytes',
+ },
+ ],
+ outputs: [],
+ stateMutability: 'nonpayable',
+ },
+] as const
+
+export const SHED_ABI = [
+ {
+ type: 'function',
+ name: 'executeHooks',
+ inputs: [
+ {
+ name: 'calls',
+ type: 'tuple[]',
+ internalType: 'struct Call[]',
+ components: [
+ {
+ name: 'target',
+ type: 'address',
+ internalType: 'address',
+ },
+ {
+ name: 'value',
+ type: 'uint256',
+ internalType: 'uint256',
+ },
+ {
+ name: 'callData',
+ type: 'bytes',
+ internalType: 'bytes',
+ },
+ {
+ name: 'allowFailure',
+ type: 'bool',
+ internalType: 'bool',
+ },
+ {
+ name: 'isDelegateCall',
+ type: 'bool',
+ internalType: 'bool',
+ },
+ ],
+ },
+ {
+ name: 'nonce',
+ type: 'bytes32',
+ internalType: 'bytes32',
+ },
+ {
+ name: 'deadline',
+ type: 'uint256',
+ internalType: 'uint256',
+ },
+ {
+ name: 'signature',
+ type: 'bytes',
+ internalType: 'bytes',
+ },
+ ],
+ outputs: [],
+ stateMutability: 'nonpayable',
+ },
+] as const
+
+export const PROXY_CREATION_CODE = '0x'
+
+// TODO: update this once the contract is deployed
+export const COW_SHED_FACTORY = '0xBB64Eb2cE6C4Fecc3EE0b18A415c536b147d6727'
+export const COW_SHED_IMPLEMENTATION = '0x0CCb8fDAA217943D52Db003703b75b66523295a1'
+export const proxyInitCode =
+ '0x60a034608e57601f61037138819003918201601f19168301916001600160401b038311848410176093578084926040948552833981010312608e57604b602060458360a9565b920160a9565b6080527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc556040516102b490816100bd8239608051818181608f01526101720152f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203608e5756fe60806040526004361015610018575b3661019457610194565b6000803560e01c908163025b22bc1461003b575063f851a4400361000e5761010d565b3461010a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261010a5773ffffffffffffffffffffffffffffffffffffffff60043581811691828203610106577f0000000000000000000000000000000000000000000000000000000000000000163314600014610101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8280a280f35b61023d565b8380fd5b80fd5b346101645760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610164576020610146610169565b73ffffffffffffffffffffffffffffffffffffffff60405191168152f35b600080fd5b333003610101577f000000000000000000000000000000000000000000000000000000000000000090565b60ff7f68df44b1011761f481358c0f49a711192727fb02c377d697bcb0ea8ff8393ac0541615806101ef575b1561023d5760046040517ff92ee8a9000000000000000000000000000000000000000000000000000000008152fd5b507f400ada75000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000006000351614156101c0565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546000808092368280378136915af43d82803e1561027a573d90f35b3d90fdfea264697066735822122031e6c23049bed9e91b6914ec3a10b4ead2d855cd933d50e8e3635e4e999fe02e64736f6c63430008190033'
diff --git a/apps/cowswap-frontend/src/modules/hooksStore/cow-shed/index.ts b/apps/cowswap-frontend/src/modules/hooksStore/cow-shed/index.ts
new file mode 100644
index 0000000000..3849fad989
--- /dev/null
+++ b/apps/cowswap-frontend/src/modules/hooksStore/cow-shed/index.ts
@@ -0,0 +1,118 @@
+import { ethers, getCreate2Address, solidityPacked, solidityPackedKeccak256, TypedDataEncoder } from 'ethers_v6'
+
+import { FACTORY_ABI, PROXY_CREATION_CODE, SHED_ABI } from './constants'
+
+export interface ISdkOptions {
+ factoryAddress: string
+ proxyCreationCode?: string
+ implementationAddress: string
+ chainId: number
+}
+
+export interface ICall {
+ target: string
+ value: bigint
+ callData: string
+ allowFailure: boolean
+ isDelegateCall: boolean
+}
+
+export interface IExecuteHooks {
+ calls: ICall[]
+ nonce: string
+ deadline: bigint
+}
+
+const ABI_CODER = new ethers.AbiCoder()
+
+const DOMAIN_TYPE = {
+ EIP712Domain: [
+ { type: 'string', name: 'name' },
+ { type: 'string', name: 'version' },
+ { type: 'uint256', name: 'chainId' },
+ { type: 'address', name: 'verifyingContract' },
+ ],
+}
+
+export const COW_SHED_712_TYPES = {
+ ExecuteHooks: [
+ { type: 'Call[]', name: 'calls' },
+ { type: 'bytes32', name: 'nonce' },
+ { type: 'uint256', name: 'deadline' },
+ ],
+ Call: [
+ { type: 'address', name: 'target' },
+ { type: 'uint256', name: 'value' },
+ { type: 'bytes', name: 'callData' },
+ { type: 'bool', name: 'allowFailure' },
+ { type: 'bool', name: 'isDelegateCall' },
+ ],
+}
+const FACTORY_INTERFACE: ethers.Interface = new ethers.Interface(FACTORY_ABI)
+const SHED_INTERFACE: ethers.Interface = new ethers.Interface(SHED_ABI)
+
+export class CowShedSdk {
+ constructor(private options: ISdkOptions) {}
+
+ computeProxyAddress(user: string) {
+ const salt = ABI_CODER.encode(['address'], [user])
+ const initCodeHash = solidityPackedKeccak256(
+ ['bytes', 'bytes'],
+ [this._proxyCreationCode(), ABI_CODER.encode(['address', 'address'], [this.options.implementationAddress, user])]
+ )
+ return getCreate2Address(this.options.factoryAddress, salt, initCodeHash)
+ }
+
+ computeDomainSeparator(proxy: string) {
+ return TypedDataEncoder.hashStruct('EIP712Domain', DOMAIN_TYPE, this._getDomain(proxy))
+ }
+
+ hashToSignWithProxy(calls: ICall[], nonce: string, deadline: bigint, proxy: string) {
+ return this._hashToSign(calls, nonce, deadline, proxy)
+ }
+
+ hashToSignWithUser(calls: ICall[], nonce: string, deadline: bigint, user: string) {
+ return this._hashToSign(calls, nonce, deadline, this.computeProxyAddress(user))
+ }
+
+ static encodeExecuteHooksForFactory(
+ calls: ICall[],
+ nonce: string,
+ deadline: bigint,
+ user: string,
+ signature: string
+ ) {
+ return FACTORY_INTERFACE.encodeFunctionData('executeHooks', [calls, nonce, deadline, user, signature])
+ }
+
+ static encodeExecuteHooksForProxy(calls: ICall[], nonce: string, deadline: bigint, signature: string) {
+ return SHED_INTERFACE.encodeFunctionData('executeHooks', [calls, nonce, deadline, signature])
+ }
+
+ static encodeEOASignature(r: bigint, s: bigint, v: number) {
+ return solidityPacked(['uint', 'uint', 'uint8'], [r, s, v])
+ }
+
+ _hashToSign(calls: ICall[], nonce: string, deadline: bigint, proxy: string) {
+ const message: IExecuteHooks = {
+ calls,
+ nonce,
+ deadline,
+ }
+ return { domain: this._getDomain(proxy), types: COW_SHED_712_TYPES, value: message }
+ }
+
+ private _getDomain(proxy: string) {
+ const domain = {
+ name: 'COWShed',
+ version: '1.0.0',
+ chainId: this.options.chainId,
+ verifyingContract: proxy,
+ }
+ return domain
+ }
+
+ private _proxyCreationCode() {
+ return this.options.proxyCreationCode ?? PROXY_CREATION_CODE
+ }
+}
diff --git a/apps/cowswap-frontend/src/modules/hooksStore/dapps/BalV2HookApp/index.tsx b/apps/cowswap-frontend/src/modules/hooksStore/dapps/BalV2HookApp/index.tsx
new file mode 100644
index 0000000000..f2e6c18215
--- /dev/null
+++ b/apps/cowswap-frontend/src/modules/hooksStore/dapps/BalV2HookApp/index.tsx
@@ -0,0 +1,253 @@
+import { useCallback, useContext, useEffect, useState } from 'react'
+
+import { RPC_URLS } from '@cowprotocol/common-const'
+import { HookDappInternal, HookDappType } from '@cowprotocol/types'
+import { ButtonPrimary, UI } from '@cowprotocol/ui'
+
+import { RemoveLiquidity, RemoveLiquidityKind, Slippage } from '@balancer/sdk'
+import { parseUnits } from 'ethers/lib/utils'
+import styled from 'styled-components/macro'
+
+import { usePoolData, useUserBalancerPool } from 'modules/hooksStore/hooks/useBalancerPool'
+import { PoolData, PoolsData } from 'modules/hooksStore/types/BalancerPool'
+
+import { HookDappContext } from '../../context'
+import balancerLogo from '../../images/balancer.png'
+import { ICall } from 'modules/hooksStore/cow-shed'
+import { useUserTransactionTTL } from 'legacy/state/user/hooks'
+import { CurrencyAmount, Token } from '@uniswap/sdk-core'
+import { useTokenContract } from 'common/hooks/useContract'
+import { useCowShed } from 'modules/hooksStore/hooks/useCowShed'
+
+const TITLE = 'Exit Balancer Pool'
+const DESCRIPTION = 'Allows you to exit a Balancer pool'
+
+const Wrapper = styled.div`
+ display: flex;
+ flex-direction: row;
+ gap: 1.6rem;
+ padding: 1rem;
+ justify-content: start;
+`
+
+const DropdownContainer = styled.div`
+ position: relative;
+ width: 50%;
+ margin: 1.4rem 0;
+`
+
+const DropdownHeader = styled.div`
+ padding: 10px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ font-size: 1.3rem;
+ font-weight: 500;
+ border: 1px solid #e0e0e0;
+ border-radius: 8px;
+`
+
+const DropdownBody = styled.div`
+ position: absolute;
+ top: calc(100% + 1rem);
+ left: 0;
+ width: 100%;
+ border-radius: 1.6rem;
+ padding: 0.6rem;
+ display: flex;
+ flex-flow: column wrap;
+ gap: 0.6rem;
+`
+
+const DropdownOption = styled.div`
+ padding: 1rem;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ font-size: 1.3rem;
+ font-weight: 500;
+
+ &:hover {
+ background-color: black;
+ border-radius: 1rem;
+ }
+`
+
+const ErrorLabel = styled.div`
+ color: var(${UI.COLOR_RED});
+`
+
+const LoadingLabel = styled.div`
+ color: var(${UI.COLOR_TEXT2});
+`
+
+export const PRE_EXIT_BAL_POOL: HookDappInternal = {
+ name: TITLE,
+ description: DESCRIPTION,
+ type: HookDappType.INTERNAL,
+ path: '/hooks-dapps/pre/claim-gno',
+ component: ,
+ image: balancerLogo,
+ version: 'v0.1.1',
+}
+
+export function ExitBalV2App() {
+ const hookDappContext = useContext(HookDappContext)
+ const { data: pools, isLoading: isLoadingPools } = useUserBalancerPool()
+ const [selectedPoolId, setSelectedPoolId] = useState()
+ const { data: poolData, isValidating: isValidatingPoolData } = usePoolData(selectedPoolId)
+ const [userDeadline] = useUserTransactionTTL()
+ const { signCalls, calculateProxyAddress } = useCowShed()
+ const bptContract = useTokenContract(poolData?.address)
+ const [hookCalls, setHookCalls] = useState()
+ const [outputTokens, setOutputTokens] = useState[]>()
+
+ useEffect(() => {
+ const updateHookData = async () => {
+ if (!hookDappContext || !poolData || !hookDappContext.account) return
+
+ const removeLiquidity = new RemoveLiquidity()
+
+ const bptAmount = parseUnits(poolData.userBalance.totalBalance, poolData.decimals).toBigInt()
+ const proxyAddress = calculateProxyAddress(hookDappContext.account) as `0x${string}`
+
+ const exitQuery = await removeLiquidity.query(
+ {
+ chainId: hookDappContext.chainId,
+ kind: RemoveLiquidityKind.Proportional,
+ rpcUrl: RPC_URLS[hookDappContext.chainId],
+ bptIn: {
+ address: poolData.address,
+ decimals: poolData.decimals,
+ rawAmount: bptAmount,
+ },
+ },
+ {
+ id: poolData.id,
+ address: poolData.address,
+ type: poolData.type.charAt(0).toUpperCase() + poolData.type.slice(1).toLowerCase(),
+ protocolVersion: poolData.protocolVersion,
+ tokens: poolData.poolTokens.map((token, index) => ({
+ ...token,
+ index,
+ })),
+ }
+ )
+ const exitCall = removeLiquidity.buildCall({
+ ...exitQuery,
+ slippage: Slippage.fromPercentage('10'),
+ sender: proxyAddress,
+ recipient: hookDappContext.account as `0x${string}`,
+ })
+ setHookCalls([
+ {
+ target: poolData.address,
+ isDelegateCall: false,
+ value: BigInt(0),
+ allowFailure: false,
+ callData: bptContract?.interface.encodeFunctionData('transferFrom', [
+ hookDappContext.account,
+ proxyAddress,
+ bptAmount,
+ ]) as string,
+ },
+ {
+ target: exitCall.to,
+ isDelegateCall: false,
+ value: exitCall.value,
+ allowFailure: false,
+ callData: exitCall.callData,
+ },
+ ])
+ setOutputTokens(
+ exitQuery.amountsOut.map((amount) =>
+ CurrencyAmount.fromRawAmount(
+ new Token(hookDappContext.chainId, amount.token.address, amount.token.decimals, amount.token.symbol),
+ amount.amount.toString()
+ )
+ )
+ )
+ }
+
+ updateHookData()
+ }, [poolData, hookDappContext])
+
+ const clickOnAddHook = useCallback(async () => {
+ if (!hookCalls || !hookDappContext) return
+ const validTo = BigInt(Date.now() + userDeadline * 2)
+
+ const hook = await signCalls(hookCalls, validTo)
+
+ hookDappContext.addHook(
+ {
+ hook,
+ dapp: PRE_EXIT_BAL_POOL,
+ outputTokens,
+ },
+ true
+ )
+ }, [hookCalls, userDeadline, hookDappContext, signCalls, outputTokens])
+
+ if (!hookDappContext?.account) {
+ return 'Connect your wallet first'
+ }
+
+ if (!hookDappContext) {
+ return 'Loading...'
+ }
+
+ return (
+
+
+
+ +Add Pre-hook
+
+
+ )
+}
+
+export function SelectPoolToExit(props: {
+ loading: boolean
+ pools?: PoolsData[]
+ setSelectedPoolId: (poolId: string) => void
+ poolData?: PoolData
+}) {
+ const { loading, pools, setSelectedPoolId, poolData } = props
+ const [isOpen, setIsOpen] = useState(false)
+
+ if (loading) {
+ return Loading...
+ }
+
+ if (!pools) {
+ return None pool found
+ }
+
+ const handleSelect = (pool: PoolsData) => {
+ setSelectedPoolId(pool.id)
+ setIsOpen(false)
+ }
+
+ return (
+
+ setIsOpen(!isOpen)}>
+ {poolData ? poolData.symbol : 'Select the pool to exit'}
+
+ {isOpen && (
+
+ {pools.map((pool) => (
+ handleSelect(pool)} key={pool.id}>
+ {pool.symbol}
+
+ ))}
+
+ )}
+
+ )
+}
diff --git a/apps/cowswap-frontend/src/modules/hooksStore/hookRegistry.tsx b/apps/cowswap-frontend/src/modules/hooksStore/hookRegistry.tsx
index 089ed89421..cff7d621f4 100644
--- a/apps/cowswap-frontend/src/modules/hooksStore/hookRegistry.tsx
+++ b/apps/cowswap-frontend/src/modules/hooksStore/hookRegistry.tsx
@@ -8,6 +8,7 @@ import buildImg from './images/build.png'
import cowAMM from './images/cowAMM.png'
import curveImg from './images/curve.svg'
import daiImg from './images/dai.svg'
+import { PRE_EXIT_BAL_POOL } from './dapps/BalV2HookApp'
const FAKE_URL = 'https://google.com'
@@ -86,10 +87,10 @@ const POST_BUILD: HookDappIframe = {
const POST_HOOK_DAPPS_ALL = [POST_BRIDGE, POST_MAKER, POST_BUILD]
export const PRE_HOOK_REGISTRY: Record = {
- [SupportedChainId.MAINNET]: [PRE_CURVE, PRE_COWAMM, PRE_MAKER, PRE_BUILD],
- [SupportedChainId.GNOSIS_CHAIN]: [PRE_CLAIM_GNO, PRE_CURVE, PRE_COWAMM, PRE_MAKER, PRE_BUILD],
- [SupportedChainId.SEPOLIA]: [PRE_COWAMM, PRE_BUILD],
- [SupportedChainId.ARBITRUM_ONE]: [PRE_COWAMM, PRE_BUILD],
+ [SupportedChainId.MAINNET]: [PRE_CURVE, PRE_COWAMM, PRE_MAKER, PRE_BUILD, PRE_EXIT_BAL_POOL],
+ [SupportedChainId.GNOSIS_CHAIN]: [PRE_CLAIM_GNO, PRE_CURVE, PRE_COWAMM, PRE_MAKER, PRE_BUILD, PRE_EXIT_BAL_POOL],
+ [SupportedChainId.SEPOLIA]: [PRE_COWAMM, PRE_BUILD, PRE_EXIT_BAL_POOL],
+ [SupportedChainId.ARBITRUM_ONE]: [PRE_COWAMM, PRE_BUILD, PRE_EXIT_BAL_POOL],
}
export const POST_HOOK_REGISTRY: Record = {
diff --git a/apps/cowswap-frontend/src/modules/hooksStore/hooks/useBalancerPool.ts b/apps/cowswap-frontend/src/modules/hooksStore/hooks/useBalancerPool.ts
new file mode 100644
index 0000000000..1cc52aca61
--- /dev/null
+++ b/apps/cowswap-frontend/src/modules/hooksStore/hooks/useBalancerPool.ts
@@ -0,0 +1,121 @@
+import { SupportedChainId } from '@cowprotocol/cow-sdk'
+import { useWalletInfo } from '@cowprotocol/wallet'
+
+import { gql, GraphQLClient } from 'graphql-request'
+import useSWR from 'swr'
+
+import { PoolData, PoolsData } from '../types/BalancerPool'
+
+const BalancerChainName: Record = {
+ [SupportedChainId.MAINNET]: 'MAINNET',
+ [SupportedChainId.SEPOLIA]: 'SEPOLIA',
+ [SupportedChainId.ARBITRUM_ONE]: 'ARBITRUM',
+ [SupportedChainId.GNOSIS_CHAIN]: 'GNOSIS',
+}
+
+const USER_POOLS_QUERY = gql`
+ query GetPools(
+ $first: Int
+ $skip: Int
+ $orderBy: GqlPoolOrderBy
+ $orderDirection: GqlPoolOrderDirection
+ $where: GqlPoolFilter
+ $textSearch: String
+ ) {
+ pools: poolGetPools(
+ first: $first
+ skip: $skip
+ orderBy: $orderBy
+ orderDirection: $orderDirection
+ where: $where
+ textSearch: $textSearch
+ ) {
+ address
+ chain
+ protocolVersion
+ id
+ name
+ symbol
+ type
+ decimals
+ userBalance {
+ totalBalance
+ totalBalanceUsd
+ }
+ displayTokens {
+ address
+ symbol
+ }
+ }
+ }
+`
+
+const POOL_QUERY = gql`
+ query GetPool($id: String!, $chain: GqlChain!, $userAddress: String) {
+ pool: poolGetPool(id: $id, chain: $chain, userAddress: $userAddress) {
+ id
+ address
+ decimals
+ symbol
+ type
+ chain
+ protocolVersion
+ userBalance {
+ totalBalance
+ totalBalanceUsd
+ }
+ poolTokens {
+ id
+ address
+ name
+ decimals
+ symbol
+ balance
+ }
+ }
+ }
+`
+
+const BASE_URL = `https://api-v3.balancer.fi/graphql`
+const GQL_CLIENT = new GraphQLClient(BASE_URL)
+
+export function useUserBalancerPool() {
+ const { chainId, account } = useWalletInfo()
+
+ return useSWR([chainId, account], async ([chainId, account]) => {
+ if (!account || !chainId) {
+ return []
+ }
+ const chainName = BalancerChainName[chainId]
+ return await GQL_CLIENT.request<{
+ pools: PoolsData[]
+ }>(USER_POOLS_QUERY, {
+ where: {
+ userAddress: account,
+ chainIn: [chainName],
+ },
+ }).then((result) => {
+ return result.pools
+ })
+ })
+}
+
+export function usePoolData(poolId?: string) {
+ const { chainId, account } = useWalletInfo()
+
+ return useSWR(poolId, async (poolId) => {
+ if (!poolId) {
+ return undefined
+ }
+
+ return await GQL_CLIENT.request<{
+ pool: PoolData
+ }>(POOL_QUERY, {
+ id: poolId,
+ chain: BalancerChainName[chainId],
+ userAddress: account,
+ }).then((result) => {
+ return result.pool
+ })
+ })
+}
diff --git a/apps/cowswap-frontend/src/modules/hooksStore/hooks/useCowShed.ts b/apps/cowswap-frontend/src/modules/hooksStore/hooks/useCowShed.ts
new file mode 100644
index 0000000000..5a4268bdf1
--- /dev/null
+++ b/apps/cowswap-frontend/src/modules/hooksStore/hooks/useCowShed.ts
@@ -0,0 +1,66 @@
+import { useWalletInfo } from '@cowprotocol/wallet'
+import { useWalletProvider } from '@cowprotocol/wallet-provider'
+import { useRequestOrderCancellation } from 'legacy/state/orders/hooks'
+import { useCallback } from 'react'
+import { CowShedSdk, ICall } from '../cow-shed'
+import { COW_SHED_FACTORY, COW_SHED_IMPLEMENTATION, proxyInitCode } from '../cow-shed/constants'
+import { ethers } from 'ethers_v6'
+import { CowHook } from '@cowprotocol/types'
+
+export function useCowShed() {
+ const provider = useWalletProvider()
+ const { account, chainId } = useWalletInfo()
+ const cancelPendingOrder = useRequestOrderCancellation()
+ const shedSdk = new CowShedSdk({
+ factoryAddress: COW_SHED_FACTORY,
+ implementationAddress: COW_SHED_IMPLEMENTATION,
+ proxyCreationCode: proxyInitCode,
+ chainId,
+ })
+
+ const calculateProxyAddress = useCallback(
+ (user: string) => {
+ return shedSdk.computeProxyAddress(user)
+ },
+ [shedSdk]
+ )
+
+ const signCalls = useCallback(
+ async (calls: ICall[], validTo: bigint): Promise => {
+ if (!account || !provider) {
+ throw new Error('No account or provider')
+ }
+
+ const nonce = ethers.encodeBytes32String(Date.now().toString())
+
+ const infoToSign = shedSdk.hashToSignWithUser(calls, nonce, validTo, account)
+
+ const signer = provider.getSigner()
+
+ const signatureRaw = await signer._signTypedData(infoToSign.domain, infoToSign.types, infoToSign.value)
+ const r = BigInt(signatureRaw.slice(0, 66))
+ const s = BigInt(`0x${signatureRaw.slice(66, 130)}`)
+ const v = parseInt(signatureRaw.slice(130, 132), 16)
+
+ const encodedSignature = CowShedSdk.encodeEOASignature(r, s, v)
+
+ const hooksCalldata = CowShedSdk.encodeExecuteHooksForFactory(
+ calls,
+ nonce,
+ BigInt(validTo),
+ account,
+ encodedSignature
+ )
+ const estimateGas = await provider.estimateGas({
+ to: COW_SHED_FACTORY,
+ value: '0',
+ data: hooksCalldata,
+ })
+
+ return { target: COW_SHED_FACTORY, callData: hooksCalldata, gasLimit: estimateGas.add(estimateGas).toString() }
+ },
+ [account, cancelPendingOrder, chainId, provider]
+ )
+
+ return { calculateProxyAddress, signCalls }
+}
diff --git a/apps/cowswap-frontend/src/modules/hooksStore/images/balancer.png b/apps/cowswap-frontend/src/modules/hooksStore/images/balancer.png
new file mode 100644
index 0000000000..fe1b51d0c3
Binary files /dev/null and b/apps/cowswap-frontend/src/modules/hooksStore/images/balancer.png differ
diff --git a/apps/cowswap-frontend/src/modules/hooksStore/types/BalancerPool.ts b/apps/cowswap-frontend/src/modules/hooksStore/types/BalancerPool.ts
new file mode 100644
index 0000000000..6ac33ab7a7
--- /dev/null
+++ b/apps/cowswap-frontend/src/modules/hooksStore/types/BalancerPool.ts
@@ -0,0 +1,40 @@
+export interface PoolsData {
+ address: `0x${string}`
+ chain: string
+ protocolVersion: 1 | 2 | 3
+ id: `0x${string}`
+ name: string
+ symbol: string
+ type: string
+ decimals: number
+ userBalance: {
+ totalBalance: `${number}`
+ totalBalanceUsd: number
+ }
+ displayTokens: {
+ address: `0x${string}`
+ symbol: string
+ }[]
+}
+
+export interface PoolData {
+ id: `0x${string}`
+ address: `0x${string}`
+ decimals: number
+ symbol: string
+ type: string
+ chain: string
+ protocolVersion: 1 | 2 | 3
+ userBalance: {
+ totalBalance: `${number}`
+ totalBalanceUsd: number
+ }
+ poolTokens: {
+ id: `0x${string}`
+ address: `0x${string}`
+ name: string
+ decimals: number
+ symbol: string
+ balance: number
+ }[]
+}
diff --git a/package.json b/package.json
index 0c6b569eac..63f37d9519 100644
--- a/package.json
+++ b/package.json
@@ -65,6 +65,8 @@
"@1inch/permit-signed-approvals-utils": "^1.4.10",
"@apollo/client": "^3.1.5",
"@babel/runtime": "^7.17.0",
+ "@balancer-labs/sdk": "^1.1.5",
+ "@balancer/sdk": "0.22.2",
"@coinbase/wallet-sdk": "^3.3.0",
"@cowprotocol/app-data": "^2.1.0",
"@cowprotocol/cms": "^0.3.1",
@@ -134,6 +136,7 @@
"@web3-react/url": "^8.2.3",
"@web3-react/walletconnect-v2": "^8.5.1",
"@web3modal/ethers5": "^4.1.9",
+ "add": "^2.0.6",
"bnc-sdk": "^4.6.0",
"buffer": "^6.0.3",
"cids": "^1.0.0",
@@ -152,6 +155,7 @@
"date-fns": "^2.29.3",
"dotenv": "^16.4.5",
"ethers": "5.7.2",
+ "ethers_v6": "npm:ethers@^6.12.1",
"eventemitter3": "^4.0.0",
"exponential-backoff": "^3.1.1",
"fast-deep-equal": "^3.1.3",
@@ -229,7 +233,8 @@
"viem": "^1.16.6",
"wagmi": "^1.2",
"web-vitals": "^2.1.4",
- "web3modal": "1.9.0"
+ "web3modal": "1.9.0",
+ "yarn": "^1.22.22"
},
"devDependencies": {
"@babel/preset-react": "^7.14.5",
diff --git a/yarn.lock b/yarn.lock
index d2459f1599..0577c34558 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -26,6 +26,11 @@
resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7"
integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==
+"@adraffy/ens-normalize@1.10.1":
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069"
+ integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==
+
"@alloc/quick-lru@^5.2.0":
version "5.2.0"
resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30"
@@ -2146,6 +2151,43 @@
"@babel/helper-validator-identifier" "^7.22.20"
to-fast-properties "^2.0.0"
+"@balancer-labs/sdk@^1.1.5":
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/@balancer-labs/sdk/-/sdk-1.1.5.tgz#29e70d15d7e98899831b18d8b909b6569e062758"
+ integrity sha512-Hxmo1u8qJureQxdbVAMAkN9qceeZxcKx4QjoevTDMrSGY5H9jc1hX18p9TTZXwlGAkw8n4rdErydUgsdWjWuLA==
+ dependencies:
+ "@balancer-labs/sor" "^4.1.1-beta.16"
+ "@ethersproject/abi" "^5.4.0"
+ "@ethersproject/abstract-signer" "^5.4.0"
+ "@ethersproject/address" "^5.4.0"
+ "@ethersproject/base64" "5.5.0"
+ "@ethersproject/bignumber" "^5.4.0"
+ "@ethersproject/bytes" "^5.4.0"
+ "@ethersproject/constants" "^5.4.0"
+ "@ethersproject/contracts" "^5.4.0"
+ "@ethersproject/providers" "^5.4.5"
+ axios "^0.24.0"
+ graphql "^15.6.1"
+ graphql-request "^3.5.0"
+ json-to-graphql-query "^2.2.4"
+ lodash "^4.17.21"
+
+"@balancer-labs/sor@^4.1.1-beta.16":
+ version "4.1.1-beta.17"
+ resolved "https://registry.yarnpkg.com/@balancer-labs/sor/-/sor-4.1.1-beta.17.tgz#8c404a86174003cccf2bb87d49221cfdcf083246"
+ integrity sha512-JcX/HeppyoIs+Sa3Z/pdZhqMOBAGajOwVkBkFA8rehd1K2qaU/k/a3OkbIidXjs4lQI9sJE1WO8RauCLtuLQfg==
+ dependencies:
+ isomorphic-fetch "^2.2.1"
+
+"@balancer/sdk@0.22.2":
+ version "0.22.2"
+ resolved "https://registry.yarnpkg.com/@balancer/sdk/-/sdk-0.22.2.tgz#d725cf8301948a5e28e4f4e4304e983d160ab8eb"
+ integrity sha512-IF/2Ar10/XSCQ7noGGLlGM8KLp1qx/y8IvnbVB7KpbW1SR2zDsQkxEWRTQiPqcj5e0s40ihHrklcDp8vlspDtA==
+ dependencies:
+ decimal.js-light "^2.5.1"
+ lodash.clonedeep "^4.5.0"
+ viem "^2.12.1"
+
"@bcoe/v8-coverage@^0.2.3":
version "0.2.3"
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
@@ -3279,7 +3321,7 @@
ethereum-cryptography "^2.0.0"
micro-ftch "^0.3.1"
-"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.6.3", "@ethersproject/abi@^5.7.0":
+"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.4.0", "@ethersproject/abi@^5.6.3", "@ethersproject/abi@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449"
integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==
@@ -3307,7 +3349,7 @@
"@ethersproject/transactions" "^5.7.0"
"@ethersproject/web" "^5.7.0"
-"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0":
+"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.4.0", "@ethersproject/abstract-signer@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2"
integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==
@@ -3318,7 +3360,7 @@
"@ethersproject/logger" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
-"@ethersproject/address@5.7.0", "@ethersproject/address@^5", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.7.0":
+"@ethersproject/address@5.7.0", "@ethersproject/address@^5", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.4.0", "@ethersproject/address@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37"
integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==
@@ -3329,6 +3371,13 @@
"@ethersproject/logger" "^5.7.0"
"@ethersproject/rlp" "^5.7.0"
+"@ethersproject/base64@5.5.0":
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.5.0.tgz#881e8544e47ed976930836986e5eb8fab259c090"
+ integrity sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA==
+ dependencies:
+ "@ethersproject/bytes" "^5.5.0"
+
"@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c"
@@ -3344,7 +3393,7 @@
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
-"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0":
+"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.4.0", "@ethersproject/bignumber@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2"
integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==
@@ -3353,21 +3402,21 @@
"@ethersproject/logger" "^5.7.0"
bn.js "^5.2.1"
-"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0":
+"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.4.0", "@ethersproject/bytes@^5.5.0", "@ethersproject/bytes@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d"
integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==
dependencies:
"@ethersproject/logger" "^5.7.0"
-"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.7.0":
+"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.4.0", "@ethersproject/constants@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e"
integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==
dependencies:
"@ethersproject/bignumber" "^5.7.0"
-"@ethersproject/contracts@5.7.0", "@ethersproject/contracts@^5.4.1", "@ethersproject/contracts@^5.7.0":
+"@ethersproject/contracts@5.7.0", "@ethersproject/contracts@^5.4.0", "@ethersproject/contracts@^5.4.1", "@ethersproject/contracts@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e"
integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==
@@ -5115,6 +5164,20 @@
dependencies:
"@noble/hashes" "1.3.2"
+"@noble/curves@1.4.0":
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.0.tgz#f05771ef64da724997f69ee1261b2417a49522d6"
+ integrity sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==
+ dependencies:
+ "@noble/hashes" "1.4.0"
+
+"@noble/curves@^1.4.0", "@noble/curves@~1.4.0":
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.2.tgz#40309198c76ed71bc6dbf7ba24e81ceb4d0d1fe9"
+ integrity sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==
+ dependencies:
+ "@noble/hashes" "1.4.0"
+
"@noble/hashes@1.2.0", "@noble/hashes@~1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12"
@@ -5130,7 +5193,7 @@
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39"
integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==
-"@noble/hashes@^1.3.1":
+"@noble/hashes@1.4.0", "@noble/hashes@^1.3.1", "@noble/hashes@^1.4.0", "@noble/hashes@~1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426"
integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==
@@ -6248,6 +6311,11 @@
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==
+"@scure/base@~1.1.6":
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.7.tgz#fe973311a5c6267846aa131bc72e96c5d40d2b30"
+ integrity sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==
+
"@scure/bip32@1.1.5":
version "1.1.5"
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300"
@@ -6275,6 +6343,15 @@
"@noble/hashes" "~1.3.2"
"@scure/base" "~1.1.2"
+"@scure/bip32@1.4.0":
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.4.0.tgz#4e1f1e196abedcef395b33b9674a042524e20d67"
+ integrity sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==
+ dependencies:
+ "@noble/curves" "~1.4.0"
+ "@noble/hashes" "~1.4.0"
+ "@scure/base" "~1.1.6"
+
"@scure/bip39@1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5"
@@ -6291,6 +6368,14 @@
"@noble/hashes" "~1.3.0"
"@scure/base" "~1.1.0"
+"@scure/bip39@1.3.0":
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.3.0.tgz#0f258c16823ddd00739461ac31398b4e7d6a18c3"
+ integrity sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==
+ dependencies:
+ "@noble/hashes" "~1.4.0"
+ "@scure/base" "~1.1.6"
+
"@sentry-internal/tracing@7.64.0":
version "7.64.0"
resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.64.0.tgz#3e110473b8edf805b799cc91d6ee592830237bb4"
@@ -8187,6 +8272,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.5.tgz#9dc0a5cb1ccce4f7a731660935ab70b9c00a5d69"
integrity sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==
+"@types/node@18.15.13":
+ version "18.15.13"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469"
+ integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==
+
"@types/node@18.16.9":
version "18.16.9"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.9.tgz#e79416d778a8714597342bb87efb5a6e914f7a73"
@@ -10313,6 +10403,11 @@ abitype@1.0.0:
resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.0.tgz#237176dace81d90d018bebf3a45cb42f2a2d9e97"
integrity sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==
+abitype@1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.5.tgz#29d0daa3eea867ca90f7e4123144c1d1270774b6"
+ integrity sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw==
+
abort-controller@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
@@ -10389,6 +10484,11 @@ acorn@^8.11.3:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a"
integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
+add@^2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/add/-/add-2.0.6.tgz#248f0a9f6e5a528ef2295dbeec30532130ae2235"
+ integrity sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q==
+
address@^1.0.1, address@^1.1.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e"
@@ -10407,6 +10507,11 @@ aes-js@3.0.0:
resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d"
integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==
+aes-js@4.0.0-beta.5:
+ version "4.0.0-beta.5"
+ resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873"
+ integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==
+
aes-js@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a"
@@ -11003,6 +11108,13 @@ axios@^0.19.2:
dependencies:
follow-redirects "1.5.10"
+axios@^0.24.0:
+ version "0.24.0"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6"
+ integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==
+ dependencies:
+ follow-redirects "^1.14.4"
+
axios@^1.6.0:
version "1.6.8"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66"
@@ -13086,7 +13198,7 @@ cross-env@^7.0.3:
dependencies:
cross-spawn "^7.0.1"
-cross-fetch@^3.0.4, cross-fetch@^3.1.4, cross-fetch@^3.1.5, cross-fetch@^3.1.6:
+cross-fetch@^3.0.4, cross-fetch@^3.0.6, cross-fetch@^3.1.4, cross-fetch@^3.1.5, cross-fetch@^3.1.6:
version "3.1.8"
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82"
integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==
@@ -14022,7 +14134,7 @@ decamelize@^1.1.0, decamelize@^1.2.0:
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
-decimal.js-light@^2.5.0:
+decimal.js-light@^2.5.0, decimal.js-light@^2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934"
integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==
@@ -15912,6 +16024,19 @@ ethers@5.7.2, ethers@^5.7.0:
"@ethersproject/web" "5.7.1"
"@ethersproject/wordlists" "5.7.0"
+"ethers_v6@npm:ethers@^6.12.1":
+ version "6.13.2"
+ resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.2.tgz#4b67d4b49e69b59893931a032560999e5e4419fe"
+ integrity sha512-9VkriTTed+/27BGuY1s0hf441kqwHJ1wtN2edksEtiRvXx+soxRX3iSXTfFqq2+YwrOqbDoTHjIhQnjJRlzKmg==
+ dependencies:
+ "@adraffy/ens-normalize" "1.10.1"
+ "@noble/curves" "1.2.0"
+ "@noble/hashes" "1.3.2"
+ "@types/node" "18.15.13"
+ aes-js "4.0.0-beta.5"
+ tslib "2.4.0"
+ ws "8.17.1"
+
ethjs-unit@0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699"
@@ -16539,7 +16664,7 @@ follow-redirects@^1.0.0, follow-redirects@^1.15.0:
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
-follow-redirects@^1.15.6:
+follow-redirects@^1.14.4, follow-redirects@^1.15.6:
version "1.15.6"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
@@ -17201,6 +17326,15 @@ graphql-request@4.3.0, graphql-request@^4.3.0:
extract-files "^9.0.0"
form-data "^3.0.0"
+graphql-request@^3.5.0:
+ version "3.7.0"
+ resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-3.7.0.tgz#c7406e537084f8b9788541e3e6704340ca13055b"
+ integrity sha512-dw5PxHCgBneN2DDNqpWu8QkbbJ07oOziy8z+bK/TAXufsOLaETuVO4GkXrbs0WjhdKhBMN3BkpN/RIvUHkmNUQ==
+ dependencies:
+ cross-fetch "^3.0.6"
+ extract-files "^9.0.0"
+ form-data "^3.0.0"
+
graphql-tag@^2.12.6:
version "2.12.6"
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1"
@@ -17208,6 +17342,11 @@ graphql-tag@^2.12.6:
dependencies:
tslib "^2.1.0"
+graphql@^15.6.1:
+ version "15.9.0"
+ resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.9.0.tgz#4e8ca830cfd30b03d44d3edd9cac2b0690304b53"
+ integrity sha512-GCOQdvm7XxV1S4U4CGrsdlEN37245eC8P9zaYCMr6K1BG0IPGy5lUwmJsEOGyl1GD6HXjOtl2keCP9asRBwNvA==
+
graphql@^16.3.0:
version "16.8.1"
resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.1.tgz#1930a965bef1170603702acdb68aedd3f3cf6f07"
@@ -20739,6 +20878,11 @@ json-text-sequence@~0.1.0:
dependencies:
delimit-stream "0.1.0"
+json-to-graphql-query@^2.2.4:
+ version "2.2.5"
+ resolved "https://registry.yarnpkg.com/json-to-graphql-query/-/json-to-graphql-query-2.2.5.tgz#56b072a693b50fd4dc981367b60d52e3dc78f426"
+ integrity sha512-5Nom9inkIMrtY992LMBBG1Zaekrc10JaRhyZgprwHBVMDtRgllTvzl0oBbg13wJsVZoSoFNNMaeIVQs0P04vsA==
+
json5@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
@@ -21318,6 +21462,11 @@ lodash.camelcase@^4.3.0:
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==
+lodash.clonedeep@^4.5.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
+ integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==
+
lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
@@ -28746,6 +28895,11 @@ tslib@1.14.1, tslib@^1.0.0, tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
+tslib@2.4.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
+ integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
+
tslib@2.5.2:
version "2.5.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.2.tgz#1b6f07185c881557b0ffa84b111a0106989e8338"
@@ -29627,6 +29781,21 @@ viem@^2.1.1:
isows "1.0.4"
ws "8.13.0"
+viem@^2.12.1:
+ version "2.19.1"
+ resolved "https://registry.yarnpkg.com/viem/-/viem-2.19.1.tgz#38ccffbacf69d8a2f940ff35be8ea3ac42ea5d61"
+ integrity sha512-a0ca/ACEz3FRZB3OmiSfRUogWZGQh700wu7Pg3GmAWiGD+0PS9bVaWG67JQ+9azFZLq0BU/m0t2CeWd3xi8IzQ==
+ dependencies:
+ "@adraffy/ens-normalize" "1.10.0"
+ "@noble/curves" "1.4.0"
+ "@noble/hashes" "1.4.0"
+ "@scure/bip32" "1.4.0"
+ "@scure/bip39" "1.3.0"
+ abitype "1.0.5"
+ isows "1.0.4"
+ webauthn-p256 "0.0.5"
+ ws "8.17.1"
+
vite-node@0.32.4:
version "0.32.4"
resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-0.32.4.tgz#7b3f94af5a87c631fbc380ba662914bafbd04d80"
@@ -30342,6 +30511,14 @@ web3modal@1.9.0:
styled-components "^5.1.1"
tslib "^1.10.0"
+webauthn-p256@0.0.5:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/webauthn-p256/-/webauthn-p256-0.0.5.tgz#0baebd2ba8a414b21cc09c0d40f9dd0be96a06bd"
+ integrity sha512-drMGNWKdaixZNobeORVIqq7k5DsRC9FnG201K2QjeOoQLmtSDaSsVZdkg6n5jUALJKcAG++zBPJXmv6hy0nWFg==
+ dependencies:
+ "@noble/curves" "^1.4.0"
+ "@noble/hashes" "^1.4.0"
+
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
@@ -31194,6 +31371,11 @@ ws@8.16.0:
resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4"
integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==
+ws@8.17.1:
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b"
+ integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==
+
ws@^3.0.0:
version "3.3.3"
resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"
@@ -31366,6 +31548,11 @@ yargs@^16.2.0:
y18n "^5.0.5"
yargs-parser "^20.2.2"
+yarn@^1.22.22:
+ version "1.22.22"
+ resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.22.tgz#ac34549e6aa8e7ead463a7407e1c7390f61a6610"
+ integrity sha512-prL3kGtyG7o9Z9Sv8IPfBNrWTDmXB4Qbes8A9rEzt6wkJV8mUvoirjU0Mp3GGAU06Y0XQyA3/2/RQFVuK7MTfg==
+
yauzl@^2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"