- Stack trace
+ {'Stack trace'}
@@ -87,16 +87,17 @@ export default function TestRpcPage() {
return (
-
Test RPC - Succès
-
✅ initializeProviders réussi
+
{'Test RPC - Succès'}
+
{'✅ initializeProviders réussi'}
- Durée: {results.duration}ms
+ {'Durée:'} {results.duration}
+ {'ms\r'}
- Gnosis RPC: {results.providers?.gnosisUrl}
+ {'Gnosis RPC:'} {results.providers?.gnosisUrl}
- Ethereum RPC: {results.providers?.ethereumUrl}
+ {'Ethereum RPC:'} {results.providers?.ethereumUrl}
)
diff --git a/src/repositories/RpcProvider.ts b/src/repositories/RpcProvider.ts
index 9e6168b6..f09a602d 100644
--- a/src/repositories/RpcProvider.ts
+++ b/src/repositories/RpcProvider.ts
@@ -1,4 +1,5 @@
import { CHAINS as RealtCommonsDefaultChainsConfig } from '@realtoken/realt-commons'
+
import {
Contract,
JsonRpcProvider,
@@ -10,10 +11,10 @@ import {
import { ERC20ABI } from 'src/utils/blockchain/abi/ERC20ABI'
import {
CHAINS_NAMES,
- CHAIN_ID_ETHEREUM,
- CHAIN_ID_GNOSIS_XDAI,
- REG_ContractAddress,
-} from 'src/utils/blockchain/consts/otherTokens'
+ CHAIN_ID__ETHEREUM,
+ CHAIN_ID__GNOSIS_XDAI,
+} from 'src/utils/blockchain/consts/misc'
+import { REG_ContractAddress } from 'src/utils/blockchain/consts/otherTokens'
import { batchCallOneContractOneFunctionMultipleParams } from 'src/utils/blockchain/contract'
import { wait } from 'src/utils/general'
import { WaitingQueue } from 'src/utils/waitingQueue'
@@ -39,17 +40,17 @@ const getRpcUrls = (chainId: number): string[] => {
let defaultUrls: string[] = []
switch (chainId) {
- case CHAIN_ID_ETHEREUM:
+ case CHAIN_ID__ETHEREUM:
envVarName = 'RPC_URLS_ETH_MAINNET'
// Use the default Ethereum RPC URLs from realt-commons config
defaultUrls = DEFAULT_ETHEREUM_RPC_URLS.concat(
- RealtCommonsDefaultChainsConfig[CHAIN_ID_ETHEREUM].rpcUrl,
+ RealtCommonsDefaultChainsConfig[CHAIN_ID__ETHEREUM].rpcUrl,
)
break
- case CHAIN_ID_GNOSIS_XDAI:
+ case CHAIN_ID__GNOSIS_XDAI:
envVarName = 'RPC_URLS_GNOSIS_MAINNET'
defaultUrls = DEFAULT_GNOSIS_RPC_URLS.concat(
- RealtCommonsDefaultChainsConfig[CHAIN_ID_GNOSIS_XDAI].rpcUrl,
+ RealtCommonsDefaultChainsConfig[CHAIN_ID__GNOSIS_XDAI].rpcUrl,
)
break
// TODO: Polygon
@@ -258,7 +259,7 @@ export interface ProvidersWithUrls extends Providers {
}
let initializeProvidersQueue: WaitingQueue | null = null
-let providers: ProvidersWithUrls | undefined = undefined
+// let providers: ProvidersWithUrls | undefined = undefined
export const initializeProviders = async (): Promise => {
if (initializeProvidersQueue) {
@@ -273,7 +274,7 @@ export const initializeProviders = async (): Promise => {
])
} catch (error) {
initializeProvidersQueue = null
- providers = undefined
+ // providers = undefined
// Relaunch directly without queue
return await initializeProvidersDirect()
}
@@ -295,8 +296,8 @@ async function initializeProvidersDirect(): Promise {
try {
const [GnosisRpcProviderWithUrl, EthereumRpcProviderWithUrl] =
await Promise.all([
- getWorkingRpc(CHAIN_ID_GNOSIS_XDAI),
- getWorkingRpc(CHAIN_ID_ETHEREUM),
+ getWorkingRpc(CHAIN_ID__GNOSIS_XDAI),
+ getWorkingRpc(CHAIN_ID__ETHEREUM),
])
return {
diff --git a/src/repositories/realtoken.repository.ts b/src/repositories/realtoken.repository.ts
index cd683244..ee5f383a 100644
--- a/src/repositories/realtoken.repository.ts
+++ b/src/repositories/realtoken.repository.ts
@@ -1,5 +1,9 @@
import _sortBy from 'lodash/sortBy'
+import {
+ APIRealTokenPitsBI,
+ APIRealTokenPitsBI_ExtraData,
+} from 'src/types/APIPitsBI'
import { APIRealToken } from 'src/types/APIRealToken'
import { APIRealTokenHistory } from 'src/types/APIRealTokenHistory'
import { RealToken, RealTokenRentStatus } from 'src/types/RealToken'
@@ -21,6 +25,18 @@ export const RealtokenRepository = {
),
}))
},
+ async getTokensPitsBiExtraData(): Promise {
+ const [tokensExtraData] = await Promise.all([
+ fetchTokenListPitsBiExtraData(),
+ ])
+ return tokensExtraData.map((tokenExtraData: APIRealTokenPitsBI) => {
+ return {
+ uuid: tokenExtraData.uuid,
+ actions: tokenExtraData.actions,
+ historic: tokenExtraData.historic,
+ }
+ })
+ },
}
async function fetchTokenList() {
@@ -30,6 +46,13 @@ async function fetchTokenList() {
: Promise.reject(response.statusText)
}
+async function fetchTokenListPitsBiExtraData() {
+ const response = await fetch('/api/pitsBiExtraProperties', { method: 'GET' })
+ return response.ok
+ ? (response.json() as Promise)
+ : Promise.reject(response.statusText)
+}
+
async function fetchHistoryList() {
const response = await fetch('/api/history', { method: 'GET' })
return response.ok
diff --git a/src/states/index.ts b/src/states/index.ts
index 66984504..9ea46ac5 100644
--- a/src/states/index.ts
+++ b/src/states/index.ts
@@ -1,6 +1,8 @@
import { atomWithStorage } from 'jotai/utils'
import {
+ AssetIssuePriorityType,
+ AssetIssueStatusType,
AssetProductType,
AssetRentStatusType,
AssetRmmStatusType,
@@ -25,6 +27,8 @@ export interface AssetsViewFilterType {
rentStatus: AssetRentStatusType
rmmStatus: AssetRmmStatusType
userProtocol: AssetUserProtocolType
+ issueStatus: AssetIssueStatusType
+ issuePriority: AssetIssuePriorityType
}
export const assetsViewDefaultFilter: AssetsViewFilterType = {
@@ -36,6 +40,8 @@ export const assetsViewDefaultFilter: AssetsViewFilterType = {
rentStatus: AssetRentStatusType.ALL,
rmmStatus: AssetRmmStatusType.ALL,
userProtocol: AssetUserProtocolType.ALL,
+ issueStatus: AssetIssueStatusType.ALL,
+ issuePriority: AssetIssuePriorityType.ALL,
}
export const assetsViewFilterAtom = atomWithStorage(
diff --git a/src/store/features/realtokens/realtokensSelector.ts b/src/store/features/realtokens/realtokensSelector.ts
index c07eb77e..0126f665 100644
--- a/src/store/features/realtokens/realtokensSelector.ts
+++ b/src/store/features/realtokens/realtokensSelector.ts
@@ -7,6 +7,11 @@ export const selectRealtokensIsLoading = createSelector(
(state) => state.isLoading,
)
+export const selectRealtokensIsLoadingExtraData = createSelector(
+ (state: RootState) => state.realtokens,
+ (state) => state.isLoadingExtraData,
+)
+
export const selectRealtokens = createSelector(
(state: RootState) => state.realtokens,
(realtokens) => realtokens.realtokens,
diff --git a/src/store/features/realtokens/realtokensSlice.ts b/src/store/features/realtokens/realtokensSlice.ts
index a5f43913..6f3de56a 100644
--- a/src/store/features/realtokens/realtokensSlice.ts
+++ b/src/store/features/realtokens/realtokensSlice.ts
@@ -1,19 +1,36 @@
+import { useSelector } from 'react-redux'
+
import { createAction, createReducer } from '@reduxjs/toolkit'
+import { forEach } from 'lodash'
+
import { RealtokenRepository } from 'src/repositories'
+import { selectUserDisplayAdditionalData } from 'src/store/features/settings/settingsSelector'
import { AppDispatch, RootState } from 'src/store/store'
-import { APIRealTokenProductType } from 'src/types/APIRealToken'
+import { APIRealTokenPitsBI_ExtraData } from 'src/types/APIPitsBI'
+import { APIRealToken, APIRealTokenProductType } from 'src/types/APIRealToken'
import { RealToken } from 'src/types/RealToken'
interface RealtokenInitialStateType {
realtokens: RealToken[]
isLoading: boolean
+ isLoadingExtraData: boolean
+ isExtraDataLoaded: boolean
}
const realtokenInitialState: RealtokenInitialStateType = {
realtokens: [],
isLoading: false,
+ isLoadingExtraData: false,
+ isExtraDataLoaded: false,
}
+// Filter function for product types
+export const filterProductType = (item: APIRealToken) =>
+ [
+ APIRealTokenProductType.RealEstateRental,
+ APIRealTokenProductType.LoanIncome,
+ APIRealTokenProductType.Factoring,
+ ].includes(item.productType)
// DISPATCH TYPE
export const realtokensChangedDispatchType = 'realtokens/realtokensChanged'
@@ -27,23 +44,64 @@ export const realtokensIsLoading = createAction(
realtokensIsLoadingDispatchType,
)
+// DISPATCH TYPE
+export const realtokensExtraDataChangedDispatchType =
+ 'realtokens/realtokensExtraDataChanged'
+export const realtokensExtraDataIsLoadingDispatchType =
+ 'realtokens/realtokensExtraDataIsLoading'
+export const realtokensExtraDataLoadedDispatchType =
+ 'realtokens/realtokensExtraDataLoaded'
+
+// ACTIONS
+export const realtokensExtraDataChanged = createAction(
+ realtokensExtraDataChangedDispatchType,
+)
+export const realtokensExtraDataIsLoading = createAction(
+ realtokensExtraDataIsLoadingDispatchType,
+)
+export const realtokensExtraDataLoaded = createAction(
+ realtokensExtraDataLoadedDispatchType,
+)
+
// THUNKS
export function fetchRealtokens() {
return async (dispatch: AppDispatch, getState: () => RootState) => {
- const isLoading = getState().realtokens.isLoading
+ const { isLoading } = getState().realtokens
if (isLoading) return
dispatch({ type: realtokensIsLoadingDispatchType, payload: true })
try {
const data = await RealtokenRepository.getTokens()
+ // Check for exiting extraData : if PitsBI has been used as fallback datasource
+ // json will already contain 'actions' and 'historic' properties
+ const hasExtraData = data.some(
+ (token) =>
+ (token as unknown as APIRealTokenPitsBI_ExtraData).actions ||
+ (token as unknown as APIRealTokenPitsBI_ExtraData).historic,
+ )
+ if (hasExtraData) {
+ // Reformat APIRealTokenPitsBI_ExtraData data
+ forEach(data, (token: RealToken) => {
+ const { actions, historic } =
+ token as unknown as APIRealTokenPitsBI_ExtraData
+ // Restructure token data: extract PitsBI "extra data"
+ token.extraData = {
+ pitsBI: {
+ actions: actions,
+ historic: historic,
+ },
+ }
+ // Remove 'historic', 'actions' from token
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ delete (token as any).historic
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ delete (token as any).actions
+ })
+ dispatch({ type: realtokensExtraDataLoadedDispatchType, payload: true })
+ }
+ // Dispatch filtered realtokens
dispatch({
type: realtokensChangedDispatchType,
- payload: data.filter((item) =>
- [
- APIRealTokenProductType.RealEstateRental,
- APIRealTokenProductType.LoanIncome,
- APIRealTokenProductType.Factoring,
- ].includes(item.productType),
- ),
+ payload: data.filter(filterProductType),
})
} catch (error) {
console.log(error)
@@ -53,6 +111,54 @@ export function fetchRealtokens() {
}
}
+export function fetchRealtokensExtraData() {
+ return async (dispatch: AppDispatch, getState: () => RootState) => {
+ // Check if user has enabled additional
+ const userDisplayAdditionalData =
+ selectUserDisplayAdditionalData(getState())
+ if (!userDisplayAdditionalData) return
+ const { isLoading, isLoadingExtraData, isExtraDataLoaded } =
+ getState().realtokens
+ // Wait for the initial realtokens to be loaded, skip if already loading or loaded
+ if (isLoading || isLoadingExtraData || isExtraDataLoaded) return
+ dispatch({ type: realtokensExtraDataIsLoadingDispatchType, payload: true })
+
+ try {
+ const pitsBiExtraData =
+ await RealtokenRepository.getTokensPitsBiExtraData()
+ // Build a map of tokensExtraData by uuid
+ const tokensExtraDataMap = new Map()
+ pitsBiExtraData.forEach((item) => {
+ tokensExtraDataMap.set(item.uuid, item)
+ })
+ const existingTokens = await RealtokenRepository.getTokens()
+
+ existingTokens.forEach((token) => {
+ const { actions, historic } = tokensExtraDataMap.get(token.uuid) || {}
+ // Update existing token data with PitsBI "extra data"
+ token.extraData = {
+ pitsBI: {
+ actions: actions,
+ historic: historic,
+ },
+ }
+ })
+ dispatch({
+ type: realtokensExtraDataChangedDispatchType,
+ payload: existingTokens.filter(filterProductType),
+ })
+ dispatch({ type: realtokensExtraDataLoadedDispatchType, payload: true })
+ } catch (error) {
+ console.log(error)
+ } finally {
+ dispatch({
+ type: realtokensExtraDataIsLoadingDispatchType,
+ payload: false,
+ })
+ }
+ }
+}
+
export const realtokensReducers = createReducer(
realtokenInitialState,
(builder) => {
@@ -62,5 +168,14 @@ export const realtokensReducers = createReducer(
builder.addCase(realtokensIsLoading, (state, action) => {
state.isLoading = action.payload
})
+ builder.addCase(realtokensExtraDataChanged, (state, action) => {
+ state.realtokens = action.payload
+ })
+ builder.addCase(realtokensExtraDataIsLoading, (state, action) => {
+ state.isLoadingExtraData = action.payload
+ })
+ builder.addCase(realtokensExtraDataLoaded, (state, action) => {
+ state.isExtraDataLoaded = action.payload
+ })
},
)
diff --git a/src/store/features/settings/settingsSelector.ts b/src/store/features/settings/settingsSelector.ts
index e01b65c1..f0f3a639 100644
--- a/src/store/features/settings/settingsSelector.ts
+++ b/src/store/features/settings/settingsSelector.ts
@@ -16,6 +16,7 @@ export const selectIsLoading = createSelector(
(state, realtokens, wallets, currencies, transfers) =>
!state.isInitialized ||
realtokens.isLoading ||
+ // realtokens.isLoadingExtraData ?
wallets.isLoading ||
currencies.isLoading ||
transfers.isLoading,
@@ -82,3 +83,8 @@ export const selectUserIncludesOtherAssets = createSelector(
(state: RootState) => state.settings,
(state) => state.includesOtherAssets,
)
+
+export const selectUserDisplayAdditionalData = createSelector(
+ (state: RootState) => state.settings,
+ (state) => state.displayAdditionalData,
+)
diff --git a/src/store/features/settings/settingsSlice.ts b/src/store/features/settings/settingsSlice.ts
index 1d35913b..9e070e72 100644
--- a/src/store/features/settings/settingsSlice.ts
+++ b/src/store/features/settings/settingsSlice.ts
@@ -20,6 +20,8 @@ const USER_INCLUDES_ETH_LS_KEY = 'store:settings/includesEth'
const USER_INCLUDES_LEVIN_SWAP_LS_KEY = 'store:settings/includesLevinSwap'
const USER_INCLUDES_RMM_V2_LS_KEY = 'store:settings/includesRmmV2'
const USER_INCLUDES_OTHER_ASSETS_LS_KEY = 'store:settings/includesOtherAssets'
+const USER_DISPLAY_ADDITIONAL_DATA_LS_KEY =
+ 'store:settings/displayAdditionalData'
export interface User {
id: string
@@ -39,6 +41,7 @@ interface SettingsInitialStateType {
includesLevinSwap: boolean
includesRmmV2: boolean
includesOtherAssets: boolean
+ displayAdditionalData: boolean
version?: string
}
@@ -54,6 +57,7 @@ const settingsInitialState: SettingsInitialStateType = {
includesLevinSwap: false,
includesRmmV2: false,
includesOtherAssets: false,
+ displayAdditionalData: false,
}
// DISPATCH TYPE
@@ -69,6 +73,8 @@ export const userIncludesRmmV2ChangedDispatchType =
'settings/includesRmmV2Changed'
export const userIncludesOtherAssetsDispatchType =
'settings/includesOtherAssets'
+export const userDisplayAdditionalDataDispatchType =
+ 'settings/displayAdditionalData'
// ACTIONS
export const initializeSettings = createAction(initializeSettingsDispatchType)
export const userChanged = createAction(userChangedDispatchType)
@@ -96,6 +102,9 @@ export const userIncludesRmmV2Changed = createAction(
export const userIncludesOtherAssetsChanged = createAction(
userIncludesOtherAssetsDispatchType,
)
+export const userDisplayAdditionalDataChanged = createAction(
+ userDisplayAdditionalDataDispatchType,
+)
// THUNKS
export function setUserAddress(address: string) {
return async (dispatch: AppDispatch) => {
@@ -227,6 +236,14 @@ export const settingsReducers = createReducer(
action.payload.toString(),
)
})
+ .addCase(userDisplayAdditionalDataChanged, (state, action) => {
+ state.displayAdditionalData = action.payload
+ localStorage.setItem(
+ USER_DISPLAY_ADDITIONAL_DATA_LS_KEY,
+ action.payload.toString(),
+ )
+ })
+
.addCase(initializeSettings, (state) => {
const user = localStorage.getItem(USER_LS_KEY)
const userCurrency = localStorage.getItem(USER_CURRENCY_LS_KEY)
@@ -243,6 +260,9 @@ export const settingsReducers = createReducer(
const userIncludesOtherAssets = localStorage.getItem(
USER_INCLUDES_OTHER_ASSETS_LS_KEY,
)
+ const userDisplayAdditionalData = localStorage.getItem(
+ USER_DISPLAY_ADDITIONAL_DATA_LS_KEY,
+ )
state.user = user ? JSON.parse(user) : undefined
state.userCurrency = userCurrency
@@ -262,6 +282,7 @@ export const settingsReducers = createReducer(
state.includesLevinSwap = userIncludesLevinSwap === 'true'
state.includesRmmV2 = userIncludesRmmV2 === 'true'
state.includesOtherAssets = userIncludesOtherAssets === 'true'
+ state.displayAdditionalData = userDisplayAdditionalData === 'true'
const { publicRuntimeConfig } = getConfig() as {
publicRuntimeConfig?: { version: string }
diff --git a/src/store/features/wallets/walletsSelector.ts b/src/store/features/wallets/walletsSelector.ts
index 29ea0749..dffbc240 100644
--- a/src/store/features/wallets/walletsSelector.ts
+++ b/src/store/features/wallets/walletsSelector.ts
@@ -20,11 +20,10 @@ import {
import { computeUCP } from 'src/utils/transfer/computeUCP'
import {
- CHAIN_ID_ETHEREUM,
- CHAIN_ID_GNOSIS_XDAI,
- CHAIN_NAME_ETHEREUM,
- CHAIN_NAME_GNOSIS_XDAI,
-} from '../../../utils/blockchain/consts/otherTokens'
+ CHAINS_NAMES,
+ CHAIN_ID__ETHEREUM,
+ CHAIN_ID__GNOSIS_XDAI,
+} from '../../../utils/blockchain/consts/misc'
import { selectRealtokens } from '../realtokens/realtokensSelector'
import { selectUserRentCalculation } from '../settings/settingsSelector'
@@ -88,6 +87,8 @@ export interface RWARealtoken extends OtherRealtoken {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface REGRealtoken extends OtherRealtoken {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
+export interface REUSDGRealtoken extends OtherRealtoken {}
+// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface REGVotingPowertoken extends OtherRealtoken {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
@@ -284,9 +285,9 @@ export const selectRmmDetails = createSelector(
export const getWalletChainName = (chainId: number) => {
switch (chainId) {
- case CHAIN_ID_ETHEREUM:
- return CHAIN_NAME_ETHEREUM
- case CHAIN_ID_GNOSIS_XDAI:
- return CHAIN_NAME_GNOSIS_XDAI
+ case CHAIN_ID__ETHEREUM:
+ return CHAINS_NAMES[CHAIN_ID__ETHEREUM]
+ case CHAIN_ID__GNOSIS_XDAI:
+ return CHAINS_NAMES[CHAIN_ID__GNOSIS_XDAI]
}
}
diff --git a/src/types/APIPitsBI.ts b/src/types/APIPitsBI.ts
new file mode 100644
index 00000000..d5492b27
--- /dev/null
+++ b/src/types/APIPitsBI.ts
@@ -0,0 +1,57 @@
+import { APIRealToken } from './APIRealToken'
+
+export enum APIPitsBiEnv {
+ VERSION = 'PITSBI_API_VERSION',
+ BASE = 'PITSBI_API_BASE',
+ GET_ALLTOKENS = 'PITSBI_API_GET_ALLTOKENS',
+ GET_LASTUPDATE = 'PITSBI_API_GET_LASTUPDATE',
+}
+
+export enum RealTokenToBeRepairedPriority {
+ None = 0,
+ High = 1,
+ Medium = 2,
+ Low = 3,
+}
+
+export enum RealTokenToBeFixedStatus {
+ NoExhibit = 'No Exhibit',
+ UpgradedAndReady = 'Upgraded & Ready',
+ Scheduled = 'Scheduled',
+}
+
+export interface RealTokenPitsBI_Actions {
+ exhibit_number: number // 0 = no exhibit, 1+ = exhibit number
+ volume: number // Volume 0 = no exhibit, 1+ = exhibit volume number
+ priority: RealTokenToBeRepairedPriority // Priority of the action
+ realt_status: RealTokenToBeFixedStatus // Status of the action
+}
+
+export interface RealTokenPitsBI_Historic {
+ yields: {
+ timsync: string
+ yield: number
+ days_rented: number
+ }[]
+ prices: {
+ timsync: string
+ price: number
+ }[]
+ avg_yield: number
+ init_yield: number
+ init_price: number
+}
+
+export interface APIRealTokenPitsBI_ExtraData {
+ // PITS BI is 100% compliant with the APIRealToken structure
+ uuid: string
+ // ...
+ // PITS BI specific fields
+ // Only declare fields useful for us
+ actions: RealTokenPitsBI_Actions
+ historic: RealTokenPitsBI_Historic
+}
+
+export interface APIRealTokenPitsBI
+ extends APIRealToken,
+ APIRealTokenPitsBI_ExtraData {}
diff --git a/src/types/APIRealToken.ts b/src/types/APIRealToken.ts
index b75a866a..4823ae27 100644
--- a/src/types/APIRealToken.ts
+++ b/src/types/APIRealToken.ts
@@ -14,6 +14,15 @@ export enum APIRealTokenProductType {
Factoring = 'factoring_profitshare',
}
+export enum APIRealTokenCommunityEnv {
+ API_KEY = 'REALTOKEN_COMMUNITY_API_KEY',
+ AUTH = 'X-AUTH-REALT-TOKEN',
+ API_BASE = 'REALTOKEN_COMMUNITY_API_BASE',
+ VERSION = 'REALTOKEN_COMMUNITY_API_VERSION',
+ GET_ALLTOKENS = 'REALTOKEN_COMMUNITY_API_GET_ALLTOKENS',
+ API_HISTORY = 'REALTOKEN_COMMUNITY_API_HISTORY_BASE',
+}
+
export interface APIRealTokenDate {
date: string
timezone_type: number
diff --git a/src/types/RealToken.ts b/src/types/RealToken.ts
index 7f3a41ff..3179a125 100644
--- a/src/types/RealToken.ts
+++ b/src/types/RealToken.ts
@@ -1,3 +1,4 @@
+import { RealTokenPitsBI_Actions, RealTokenPitsBI_Historic } from './APIPitsBI'
import { APIRealToken } from './APIRealToken'
import { RealTokenHistoryItem } from './APIRealTokenHistory'
@@ -49,4 +50,10 @@ export interface RealToken extends APIRealToken {
isRmmAvailable: boolean
rentStatus: RealTokenRentStatus
history: RealTokenHistoryItem[]
+ extraData?: {
+ pitsBI?: {
+ actions?: RealTokenPitsBI_Actions
+ historic?: RealTokenPitsBI_Historic
+ }
+ }
}
diff --git a/src/utils/blockchain/abi/UniswapV3PoolABI.ts b/src/utils/blockchain/abi/UniswapV3PoolABI.ts
new file mode 100644
index 00000000..3ab6f908
--- /dev/null
+++ b/src/utils/blockchain/abi/UniswapV3PoolABI.ts
@@ -0,0 +1,644 @@
+// https://api.etherscan.io/v2/api?chainid=100&module=contract&action=getabi&address=0x17183182C4a94A895A8b31133e3B24800aF3c5e4&apikey=yourApiKey
+export const UniswapV3PoolABI = [
+ // Add the ABI definitions for the Uniswap V3 Quoter V2 here
+ { inputs: [], stateMutability: 'nonpayable', type: 'constructor' },
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: true,
+ internalType: 'address',
+ name: 'owner',
+ type: 'address',
+ },
+ {
+ indexed: true,
+ internalType: 'int24',
+ name: 'tickLower',
+ type: 'int24',
+ },
+ {
+ indexed: true,
+ internalType: 'int24',
+ name: 'tickUpper',
+ type: 'int24',
+ },
+ {
+ indexed: false,
+ internalType: 'uint128',
+ name: 'amount',
+ type: 'uint128',
+ },
+ {
+ indexed: false,
+ internalType: 'uint256',
+ name: 'amount0',
+ type: 'uint256',
+ },
+ {
+ indexed: false,
+ internalType: 'uint256',
+ name: 'amount1',
+ type: 'uint256',
+ },
+ ],
+ name: 'Burn',
+ type: 'event',
+ },
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: true,
+ internalType: 'address',
+ name: 'owner',
+ type: 'address',
+ },
+ {
+ indexed: false,
+ internalType: 'address',
+ name: 'recipient',
+ type: 'address',
+ },
+ {
+ indexed: true,
+ internalType: 'int24',
+ name: 'tickLower',
+ type: 'int24',
+ },
+ {
+ indexed: true,
+ internalType: 'int24',
+ name: 'tickUpper',
+ type: 'int24',
+ },
+ {
+ indexed: false,
+ internalType: 'uint128',
+ name: 'amount0',
+ type: 'uint128',
+ },
+ {
+ indexed: false,
+ internalType: 'uint128',
+ name: 'amount1',
+ type: 'uint128',
+ },
+ ],
+ name: 'Collect',
+ type: 'event',
+ },
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: true,
+ internalType: 'address',
+ name: 'sender',
+ type: 'address',
+ },
+ {
+ indexed: true,
+ internalType: 'address',
+ name: 'recipient',
+ type: 'address',
+ },
+ {
+ indexed: false,
+ internalType: 'uint128',
+ name: 'amount0',
+ type: 'uint128',
+ },
+ {
+ indexed: false,
+ internalType: 'uint128',
+ name: 'amount1',
+ type: 'uint128',
+ },
+ ],
+ name: 'CollectProtocol',
+ type: 'event',
+ },
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: true,
+ internalType: 'address',
+ name: 'sender',
+ type: 'address',
+ },
+ {
+ indexed: true,
+ internalType: 'address',
+ name: 'recipient',
+ type: 'address',
+ },
+ {
+ indexed: false,
+ internalType: 'uint256',
+ name: 'amount0',
+ type: 'uint256',
+ },
+ {
+ indexed: false,
+ internalType: 'uint256',
+ name: 'amount1',
+ type: 'uint256',
+ },
+ {
+ indexed: false,
+ internalType: 'uint256',
+ name: 'paid0',
+ type: 'uint256',
+ },
+ {
+ indexed: false,
+ internalType: 'uint256',
+ name: 'paid1',
+ type: 'uint256',
+ },
+ ],
+ name: 'Flash',
+ type: 'event',
+ },
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: false,
+ internalType: 'uint16',
+ name: 'observationCardinalityNextOld',
+ type: 'uint16',
+ },
+ {
+ indexed: false,
+ internalType: 'uint16',
+ name: 'observationCardinalityNextNew',
+ type: 'uint16',
+ },
+ ],
+ name: 'IncreaseObservationCardinalityNext',
+ type: 'event',
+ },
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: false,
+ internalType: 'uint160',
+ name: 'sqrtPriceX96',
+ type: 'uint160',
+ },
+ { indexed: false, internalType: 'int24', name: 'tick', type: 'int24' },
+ ],
+ name: 'Initialize',
+ type: 'event',
+ },
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: false,
+ internalType: 'address',
+ name: 'sender',
+ type: 'address',
+ },
+ {
+ indexed: true,
+ internalType: 'address',
+ name: 'owner',
+ type: 'address',
+ },
+ {
+ indexed: true,
+ internalType: 'int24',
+ name: 'tickLower',
+ type: 'int24',
+ },
+ {
+ indexed: true,
+ internalType: 'int24',
+ name: 'tickUpper',
+ type: 'int24',
+ },
+ {
+ indexed: false,
+ internalType: 'uint128',
+ name: 'amount',
+ type: 'uint128',
+ },
+ {
+ indexed: false,
+ internalType: 'uint256',
+ name: 'amount0',
+ type: 'uint256',
+ },
+ {
+ indexed: false,
+ internalType: 'uint256',
+ name: 'amount1',
+ type: 'uint256',
+ },
+ ],
+ name: 'Mint',
+ type: 'event',
+ },
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: false,
+ internalType: 'uint8',
+ name: 'feeProtocol0Old',
+ type: 'uint8',
+ },
+ {
+ indexed: false,
+ internalType: 'uint8',
+ name: 'feeProtocol1Old',
+ type: 'uint8',
+ },
+ {
+ indexed: false,
+ internalType: 'uint8',
+ name: 'feeProtocol0New',
+ type: 'uint8',
+ },
+ {
+ indexed: false,
+ internalType: 'uint8',
+ name: 'feeProtocol1New',
+ type: 'uint8',
+ },
+ ],
+ name: 'SetFeeProtocol',
+ type: 'event',
+ },
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: true,
+ internalType: 'address',
+ name: 'sender',
+ type: 'address',
+ },
+ {
+ indexed: true,
+ internalType: 'address',
+ name: 'recipient',
+ type: 'address',
+ },
+ {
+ indexed: false,
+ internalType: 'int256',
+ name: 'amount0',
+ type: 'int256',
+ },
+ {
+ indexed: false,
+ internalType: 'int256',
+ name: 'amount1',
+ type: 'int256',
+ },
+ {
+ indexed: false,
+ internalType: 'uint160',
+ name: 'sqrtPriceX96',
+ type: 'uint160',
+ },
+ {
+ indexed: false,
+ internalType: 'uint128',
+ name: 'liquidity',
+ type: 'uint128',
+ },
+ { indexed: false, internalType: 'int24', name: 'tick', type: 'int24' },
+ ],
+ name: 'Swap',
+ type: 'event',
+ },
+ {
+ inputs: [
+ { internalType: 'int24', name: 'tickLower', type: 'int24' },
+ { internalType: 'int24', name: 'tickUpper', type: 'int24' },
+ { internalType: 'uint128', name: 'amount', type: 'uint128' },
+ ],
+ name: 'burn',
+ outputs: [
+ { internalType: 'uint256', name: 'amount0', type: 'uint256' },
+ { internalType: 'uint256', name: 'amount1', type: 'uint256' },
+ ],
+ stateMutability: 'nonpayable',
+ type: 'function',
+ },
+ {
+ inputs: [
+ { internalType: 'address', name: 'recipient', type: 'address' },
+ { internalType: 'int24', name: 'tickLower', type: 'int24' },
+ { internalType: 'int24', name: 'tickUpper', type: 'int24' },
+ { internalType: 'uint128', name: 'amount0Requested', type: 'uint128' },
+ { internalType: 'uint128', name: 'amount1Requested', type: 'uint128' },
+ ],
+ name: 'collect',
+ outputs: [
+ { internalType: 'uint128', name: 'amount0', type: 'uint128' },
+ { internalType: 'uint128', name: 'amount1', type: 'uint128' },
+ ],
+ stateMutability: 'nonpayable',
+ type: 'function',
+ },
+ {
+ inputs: [
+ { internalType: 'address', name: 'recipient', type: 'address' },
+ { internalType: 'uint128', name: 'amount0Requested', type: 'uint128' },
+ { internalType: 'uint128', name: 'amount1Requested', type: 'uint128' },
+ ],
+ name: 'collectProtocol',
+ outputs: [
+ { internalType: 'uint128', name: 'amount0', type: 'uint128' },
+ { internalType: 'uint128', name: 'amount1', type: 'uint128' },
+ ],
+ stateMutability: 'nonpayable',
+ type: 'function',
+ },
+ {
+ inputs: [],
+ name: 'factory',
+ outputs: [{ internalType: 'address', name: '', type: 'address' }],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [],
+ name: 'fee',
+ outputs: [{ internalType: 'uint24', name: '', type: 'uint24' }],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [],
+ name: 'feeGrowthGlobal0X128',
+ outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [],
+ name: 'feeGrowthGlobal1X128',
+ outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [
+ { internalType: 'address', name: 'recipient', type: 'address' },
+ { internalType: 'uint256', name: 'amount0', type: 'uint256' },
+ { internalType: 'uint256', name: 'amount1', type: 'uint256' },
+ { internalType: 'bytes', name: 'data', type: 'bytes' },
+ ],
+ name: 'flash',
+ outputs: [],
+ stateMutability: 'nonpayable',
+ type: 'function',
+ },
+ {
+ inputs: [
+ {
+ internalType: 'uint16',
+ name: 'observationCardinalityNext',
+ type: 'uint16',
+ },
+ ],
+ name: 'increaseObservationCardinalityNext',
+ outputs: [],
+ stateMutability: 'nonpayable',
+ type: 'function',
+ },
+ {
+ inputs: [
+ { internalType: 'uint160', name: 'sqrtPriceX96', type: 'uint160' },
+ ],
+ name: 'initialize',
+ outputs: [],
+ stateMutability: 'nonpayable',
+ type: 'function',
+ },
+ {
+ inputs: [],
+ name: 'liquidity',
+ outputs: [{ internalType: 'uint128', name: '', type: 'uint128' }],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [],
+ name: 'maxLiquidityPerTick',
+ outputs: [{ internalType: 'uint128', name: '', type: 'uint128' }],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [
+ { internalType: 'address', name: 'recipient', type: 'address' },
+ { internalType: 'int24', name: 'tickLower', type: 'int24' },
+ { internalType: 'int24', name: 'tickUpper', type: 'int24' },
+ { internalType: 'uint128', name: 'amount', type: 'uint128' },
+ { internalType: 'bytes', name: 'data', type: 'bytes' },
+ ],
+ name: 'mint',
+ outputs: [
+ { internalType: 'uint256', name: 'amount0', type: 'uint256' },
+ { internalType: 'uint256', name: 'amount1', type: 'uint256' },
+ ],
+ stateMutability: 'nonpayable',
+ type: 'function',
+ },
+ {
+ inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
+ name: 'observations',
+ outputs: [
+ { internalType: 'uint32', name: 'blockTimestamp', type: 'uint32' },
+ { internalType: 'int56', name: 'tickCumulative', type: 'int56' },
+ {
+ internalType: 'uint160',
+ name: 'secondsPerLiquidityCumulativeX128',
+ type: 'uint160',
+ },
+ { internalType: 'bool', name: 'initialized', type: 'bool' },
+ ],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [
+ { internalType: 'uint32[]', name: 'secondsAgos', type: 'uint32[]' },
+ ],
+ name: 'observe',
+ outputs: [
+ { internalType: 'int56[]', name: 'tickCumulatives', type: 'int56[]' },
+ {
+ internalType: 'uint160[]',
+ name: 'secondsPerLiquidityCumulativeX128s',
+ type: 'uint160[]',
+ },
+ ],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }],
+ name: 'positions',
+ outputs: [
+ { internalType: 'uint128', name: 'liquidity', type: 'uint128' },
+ {
+ internalType: 'uint256',
+ name: 'feeGrowthInside0LastX128',
+ type: 'uint256',
+ },
+ {
+ internalType: 'uint256',
+ name: 'feeGrowthInside1LastX128',
+ type: 'uint256',
+ },
+ { internalType: 'uint128', name: 'tokensOwed0', type: 'uint128' },
+ { internalType: 'uint128', name: 'tokensOwed1', type: 'uint128' },
+ ],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [],
+ name: 'protocolFees',
+ outputs: [
+ { internalType: 'uint128', name: 'token0', type: 'uint128' },
+ { internalType: 'uint128', name: 'token1', type: 'uint128' },
+ ],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [
+ { internalType: 'uint8', name: 'feeProtocol0', type: 'uint8' },
+ { internalType: 'uint8', name: 'feeProtocol1', type: 'uint8' },
+ ],
+ name: 'setFeeProtocol',
+ outputs: [],
+ stateMutability: 'nonpayable',
+ type: 'function',
+ },
+ {
+ inputs: [],
+ name: 'slot0',
+ outputs: [
+ { internalType: 'uint160', name: 'sqrtPriceX96', type: 'uint160' },
+ { internalType: 'int24', name: 'tick', type: 'int24' },
+ { internalType: 'uint16', name: 'observationIndex', type: 'uint16' },
+ {
+ internalType: 'uint16',
+ name: 'observationCardinality',
+ type: 'uint16',
+ },
+ {
+ internalType: 'uint16',
+ name: 'observationCardinalityNext',
+ type: 'uint16',
+ },
+ { internalType: 'uint8', name: 'feeProtocol', type: 'uint8' },
+ { internalType: 'bool', name: 'unlocked', type: 'bool' },
+ ],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [
+ { internalType: 'int24', name: 'tickLower', type: 'int24' },
+ { internalType: 'int24', name: 'tickUpper', type: 'int24' },
+ ],
+ name: 'snapshotCumulativesInside',
+ outputs: [
+ { internalType: 'int56', name: 'tickCumulativeInside', type: 'int56' },
+ {
+ internalType: 'uint160',
+ name: 'secondsPerLiquidityInsideX128',
+ type: 'uint160',
+ },
+ { internalType: 'uint32', name: 'secondsInside', type: 'uint32' },
+ ],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [
+ { internalType: 'address', name: 'recipient', type: 'address' },
+ { internalType: 'bool', name: 'zeroForOne', type: 'bool' },
+ { internalType: 'int256', name: 'amountSpecified', type: 'int256' },
+ { internalType: 'uint160', name: 'sqrtPriceLimitX96', type: 'uint160' },
+ { internalType: 'bytes', name: 'data', type: 'bytes' },
+ ],
+ name: 'swap',
+ outputs: [
+ { internalType: 'int256', name: 'amount0', type: 'int256' },
+ { internalType: 'int256', name: 'amount1', type: 'int256' },
+ ],
+ stateMutability: 'nonpayable',
+ type: 'function',
+ },
+ {
+ inputs: [{ internalType: 'int16', name: '', type: 'int16' }],
+ name: 'tickBitmap',
+ outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [],
+ name: 'tickSpacing',
+ outputs: [{ internalType: 'int24', name: '', type: 'int24' }],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [{ internalType: 'int24', name: '', type: 'int24' }],
+ name: 'ticks',
+ outputs: [
+ { internalType: 'uint128', name: 'liquidityGross', type: 'uint128' },
+ { internalType: 'int128', name: 'liquidityNet', type: 'int128' },
+ {
+ internalType: 'uint256',
+ name: 'feeGrowthOutside0X128',
+ type: 'uint256',
+ },
+ {
+ internalType: 'uint256',
+ name: 'feeGrowthOutside1X128',
+ type: 'uint256',
+ },
+ { internalType: 'int56', name: 'tickCumulativeOutside', type: 'int56' },
+ {
+ internalType: 'uint160',
+ name: 'secondsPerLiquidityOutsideX128',
+ type: 'uint160',
+ },
+ { internalType: 'uint32', name: 'secondsOutside', type: 'uint32' },
+ { internalType: 'bool', name: 'initialized', type: 'bool' },
+ ],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [],
+ name: 'token0',
+ outputs: [{ internalType: 'address', name: '', type: 'address' }],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [],
+ name: 'token1',
+ outputs: [{ internalType: 'address', name: '', type: 'address' }],
+ stateMutability: 'view',
+ type: 'function',
+ },
+]
diff --git a/src/utils/blockchain/abi/UniswapV3QuoterV2ABI.ts b/src/utils/blockchain/abi/UniswapV3QuoterV2ABI.ts
new file mode 100644
index 00000000..b8974a75
--- /dev/null
+++ b/src/utils/blockchain/abi/UniswapV3QuoterV2ABI.ts
@@ -0,0 +1,152 @@
+// https://api.etherscan.io/v2/api?chainid=100&module=contract&action=getabi&address=0xb1E835Dc2785b52265711e17fCCb0fd018226a6e&apikey=yourApiKey
+export const UniswapV3QuoterV2ABI = [
+ /*
+ {
+ inputs: [
+ { internalType: 'address', name: '_factory', type: 'address' },
+ { internalType: 'address', name: '_WETH9', type: 'address' },
+ ],
+ stateMutability: 'nonpayable',
+ type: 'constructor',
+ },
+ {
+ inputs: [],
+ name: 'WETH9',
+ outputs: [{ internalType: 'address', name: '', type: 'address' }],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [],
+ name: 'factory',
+ outputs: [{ internalType: 'address', name: '', type: 'address' }],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [
+ { internalType: 'bytes', name: 'path', type: 'bytes' },
+ { internalType: 'uint256', name: 'amountIn', type: 'uint256' },
+ ],
+ name: 'quoteExactInput',
+ outputs: [
+ { internalType: 'uint256', name: 'amountOut', type: 'uint256' },
+ {
+ internalType: 'uint160[]',
+ name: 'sqrtPriceX96AfterList',
+ type: 'uint160[]',
+ },
+ {
+ internalType: 'uint32[]',
+ name: 'initializedTicksCrossedList',
+ type: 'uint32[]',
+ },
+ { internalType: 'uint256', name: 'gasEstimate', type: 'uint256' },
+ ],
+ stateMutability: 'nonpayable',
+ type: 'function',
+ },
+*/
+ {
+ inputs: [
+ {
+ components: [
+ { internalType: 'address', name: 'tokenIn', type: 'address' },
+ { internalType: 'address', name: 'tokenOut', type: 'address' },
+ { internalType: 'uint256', name: 'amountIn', type: 'uint256' },
+ { internalType: 'uint24', name: 'fee', type: 'uint24' },
+ {
+ internalType: 'uint160',
+ name: 'sqrtPriceLimitX96',
+ type: 'uint160',
+ },
+ ],
+ internalType: 'struct IQuoterV2.QuoteExactInputSingleParams',
+ name: 'params',
+ type: 'tuple',
+ },
+ ],
+ name: 'quoteExactInputSingle',
+ outputs: [
+ { internalType: 'uint256', name: 'amountOut', type: 'uint256' },
+ { internalType: 'uint160', name: 'sqrtPriceX96After', type: 'uint160' },
+ {
+ internalType: 'uint32',
+ name: 'initializedTicksCrossed',
+ type: 'uint32',
+ },
+ { internalType: 'uint256', name: 'gasEstimate', type: 'uint256' },
+ ],
+ stateMutability: 'nonpayable',
+ type: 'function',
+ },
+ /*
+ {
+ inputs: [
+ { internalType: 'bytes', name: 'path', type: 'bytes' },
+ { internalType: 'uint256', name: 'amountOut', type: 'uint256' },
+ ],
+ name: 'quoteExactOutput',
+ outputs: [
+ { internalType: 'uint256', name: 'amountIn', type: 'uint256' },
+ {
+ internalType: 'uint160[]',
+ name: 'sqrtPriceX96AfterList',
+ type: 'uint160[]',
+ },
+ {
+ internalType: 'uint32[]',
+ name: 'initializedTicksCrossedList',
+ type: 'uint32[]',
+ },
+ { internalType: 'uint256', name: 'gasEstimate', type: 'uint256' },
+ ],
+ stateMutability: 'nonpayable',
+ type: 'function',
+ },
+ {
+ inputs: [
+ {
+ components: [
+ { internalType: 'address', name: 'tokenIn', type: 'address' },
+ { internalType: 'address', name: 'tokenOut', type: 'address' },
+ { internalType: 'uint256', name: 'amount', type: 'uint256' },
+ { internalType: 'uint24', name: 'fee', type: 'uint24' },
+ {
+ internalType: 'uint160',
+ name: 'sqrtPriceLimitX96',
+ type: 'uint160',
+ },
+ ],
+ internalType: 'struct IQuoterV2.QuoteExactOutputSingleParams',
+ name: 'params',
+ type: 'tuple',
+ },
+ ],
+ name: 'quoteExactOutputSingle',
+ outputs: [
+ { internalType: 'uint256', name: 'amountIn', type: 'uint256' },
+ { internalType: 'uint160', name: 'sqrtPriceX96After', type: 'uint160' },
+ {
+ internalType: 'uint32',
+ name: 'initializedTicksCrossed',
+ type: 'uint32',
+ },
+ { internalType: 'uint256', name: 'gasEstimate', type: 'uint256' },
+ ],
+ stateMutability: 'nonpayable',
+ type: 'function',
+ },
+ {
+ inputs: [
+ { internalType: 'int256', name: 'amount0Delta', type: 'int256' },
+ { internalType: 'int256', name: 'amount1Delta', type: 'int256' },
+ { internalType: 'bytes', name: 'path', type: 'bytes' },
+ ],
+ name: 'uniswapV3SwapCallback',
+ outputs: [],
+ stateMutability: 'view',
+ type: 'function',
+ },
+*/
+]
diff --git a/src/utils/blockchain/consts/misc.ts b/src/utils/blockchain/consts/misc.ts
new file mode 100644
index 00000000..075ef896
--- /dev/null
+++ b/src/utils/blockchain/consts/misc.ts
@@ -0,0 +1,115 @@
+const CHAIN_ID_GNOSIS_XDAI = 100
+const CHAIN_ID_ETHEREUM = 1
+// const CHAIN_ID_POLYGON = 137
+
+const CHAIN_NAME__GNOSIS_XDAI = 'gnosis'
+const CHAIN_NAME__ETHEREUM = 'ethereum'
+// const CHAIN_NAME__POLYGON = 'polygon'
+
+// Array of supported chain IDs
+const SUPPORTED_CHAINS_IDS = [CHAIN_ID_GNOSIS_XDAI, CHAIN_ID_ETHEREUM]
+
+// Mapping chain IDs to their respective names
+const CHAINS_NAMES: { [key: number]: string } = {
+ [CHAIN_ID_GNOSIS_XDAI]: CHAIN_NAME__GNOSIS_XDAI,
+ [CHAIN_ID_ETHEREUM]: CHAIN_NAME__ETHEREUM,
+}
+
+type ChainId = number
+type Address = string
+type Decimals = number
+
+const CHAIN_ID__GNOSIS_XDAI: ChainId = 100
+const CHAIN_ID__ETHEREUM: ChainId = 1
+// const CHAIN_ID__POLYGON: ChainId = 137
+
+// export declare enum ChainIds {
+// GNOSIS_XDAI,
+// ETHEREUM,
+// // POLYGON, // Todo
+// }
+
+// Reg Vault only deployed on Gnosis/xDai
+const REG_Vault_Gnosis_ContractAddress =
+ '0xe1877d33471e37fe0f62d20e60c469eff83fb4a0'
+// Reg Voting Power only deployed on Gnosis/xDai
+
+const HoneySwapFactory_Address = '0xA818b4F111Ccac7AA31D0BCc0806d64F2E0737D7'
+
+// SushiSwap Quoter deployed on Gnosis/xDai
+const SushiSwap_Factory__GnosisXdai_Address =
+ '0xf78031CBCA409F2FB6876BDFDBc1b2df24cF9bEf'
+const SushiSwap_Router__GnosisXdai_Address =
+ '0x4F54dd2F4f30347d841b7783aD08c050d8410a9d'
+const SushiSwap_Quoter__GnosisXdai_Address =
+ '0xb1E835Dc2785b52265711e17fCCb0fd018226a6e'
+
+// interface UniV2DeployedAddresses {
+// factory: Address
+// router: Address
+// }
+
+// interface UniV3DeployedAddresses extends UniV2DeployedAddresses {
+// quoter: Address
+// }
+
+// const SUSHISWAP_DEPLOYMENTS: { [key: ChainId]: UniV3DeployedAddresses } = {
+// [CHAIN_ID__GNOSIS_XDAI]: {
+// factory: SushiSwap_Factory__GnosisXdai_Address,
+// router: SushiSwap_Router__GnosisXdai_Address,
+// quoter: SushiSwap_Quoter__GnosisXdai_Address,
+// },
+// }
+
+interface UniV2DeployedAddresses {
+ factory: Address
+ router: Address
+}
+
+interface UniV3DeployedAddresses extends UniV2DeployedAddresses {
+ quoter: Address
+}
+
+// Define type for deployments
+// export
+type UniV3Deployment = { [key: ChainId]: UniV3DeployedAddresses }
+
+const SUSHISWAP_DEPLOYMENTS: UniV3Deployment = {
+ [CHAIN_ID__GNOSIS_XDAI]: {
+ factory: SushiSwap_Factory__GnosisXdai_Address,
+ router: SushiSwap_Router__GnosisXdai_Address,
+ quoter: SushiSwap_Quoter__GnosisXdai_Address,
+ },
+}
+
+// console.dir(SUSHISWAP_DEPLOYMENTS)
+// console.dir(ChainIds)
+
+// Export type for SUSHISWAP_DEPLOYMENTS
+// export type SushiswapDeployments = typeof SUSHISWAP_DEPLOYMENTS
+
+export {
+ CHAIN_ID__GNOSIS_XDAI,
+ CHAIN_ID__ETHEREUM,
+ // CHAIN_ID__POLYGON,
+ SUPPORTED_CHAINS_IDS,
+ CHAINS_NAMES,
+ REG_Vault_Gnosis_ContractAddress,
+ HoneySwapFactory_Address,
+ SUSHISWAP_DEPLOYMENTS,
+}
+// export declare const SUPPORTED_CHAINS: readonly [
+// // ChainId.GNOSIS_XDAI,
+// // ChainIds.ETHEREUM,
+// CHAIN_ID__GNOSIS_XDAI,
+// CHAIN_ID__ETHEREUM,
+// ]
+
+export type {
+ Address,
+ ChainId,
+ Decimals,
+ UniV2DeployedAddresses,
+ UniV3DeployedAddresses,
+ UniV3Deployment,
+}
diff --git a/src/utils/blockchain/consts/otherTokens.ts b/src/utils/blockchain/consts/otherTokens.ts
index b4b278b3..766b8616 100644
--- a/src/utils/blockchain/consts/otherTokens.ts
+++ b/src/utils/blockchain/consts/otherTokens.ts
@@ -1,18 +1,20 @@
-// Each asset must have a different ID (used as KEY assets view)
-const RWA_asset_ID = 0
-const REG_asset_ID = 1
-const REGVotingPower_asset_ID = 2
-
// Gnosis/xDai, Ethereum
const RWA_ContractAddress = '0x0675e8F4A52eA6c845CB6427Af03616a2af42170'
// Gnosis/xDai, Ethereum
const REG_ContractAddress = '0x0AA1e96D2a46Ec6beB2923dE1E61Addf5F5f1dce'
-// Reg Vault only deployed on Gnosis/xDai
-const REG_Vault_Gnosis_ContractAddress =
- '0xe1877d33471e37fe0f62d20e60c469eff83fb4a0'
// Reg Voting Power only deployed on Gnosis/xDai
const RegVotingPower_Gnosis_ContractAddress =
'0x6382856a731Af535CA6aea8D364FCE67457da438'
+// Gnosis/xDai, Ethereum
+const REUSD_ContractAddress = '0x3390742ac0dce14ea6fcbd5ae02e2303c5d62ad9'
+
+const REUSD_asset_ID = REUSD_ContractAddress
+
+// Asset IDs for RWA, REG, and REG Voting Power
+// Each asset must have a different ID (used as KEY assets view)
+const RWA_asset_ID = RWA_ContractAddress
+const REG_asset_ID = REG_ContractAddress
+const REGVotingPower_asset_ID = RegVotingPower_Gnosis_ContractAddress
// Gnosis/xDai tokens for prices calculation
const WXDAI_ContractAddress = '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d'
@@ -20,6 +22,7 @@ const USDConXdai_ContractAddress = '0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83'
const DEFAULT_RWA_PRICE = 50 // USD
const DEFAULT_REG_PRICE = 0 // USD
+const DEFAULT_REUSD_PRICE = 1 // USD
const DEFAULT_REGVotingPower_PRICE = 0 // USD
const DEFAULT_XDAI_USD_RATE = 1
@@ -28,30 +31,14 @@ const DEFAULT_USDC_USD_RATE = 1
const RWAtokenDecimals = 9
const REGtokenDecimals = 18
const REGVotingPowertokenDecimals = 18
+const REGUSDtokenDecimals = 18
const USDCtokenDecimals = 6
const WXDAItokenDecimals = 18
-const HoneySwapFactory_Address = '0xA818b4F111Ccac7AA31D0BCc0806d64F2E0737D7'
-
-const CHAIN_ID_GNOSIS_XDAI = 100
-const CHAIN_ID_ETHEREUM = 1
-const CHAIN_ID_POLYGON = 137
-
-const CHAIN_NAME_GNOSIS_XDAI = 'gnosis'
-const CHAIN_NAME_ETHEREUM = 'ethereum'
-const CHAIN_NAME_POLYGON = 'polygon'
-
-// Mapping chain IDs to their respective names
-const CHAINS_NAMES: { [key: number]: string } = {
- [CHAIN_ID_GNOSIS_XDAI]: CHAIN_NAME_GNOSIS_XDAI,
- [CHAIN_ID_ETHEREUM]: CHAIN_NAME_ETHEREUM,
- [CHAIN_ID_POLYGON]: CHAIN_NAME_POLYGON,
-}
-
export {
RWA_ContractAddress,
REG_ContractAddress,
- REG_Vault_Gnosis_ContractAddress,
+ REUSD_ContractAddress,
RegVotingPower_Gnosis_ContractAddress,
WXDAI_ContractAddress,
USDConXdai_ContractAddress,
@@ -59,21 +46,23 @@ export {
RWAtokenDecimals,
USDCtokenDecimals,
REGtokenDecimals,
- HoneySwapFactory_Address,
+ REGUSDtokenDecimals,
REGVotingPowertokenDecimals,
DEFAULT_RWA_PRICE,
DEFAULT_REG_PRICE,
+ DEFAULT_REUSD_PRICE,
DEFAULT_REGVotingPower_PRICE,
DEFAULT_XDAI_USD_RATE,
DEFAULT_USDC_USD_RATE,
RWA_asset_ID,
REG_asset_ID,
+ REUSD_asset_ID,
REGVotingPower_asset_ID,
- CHAIN_ID_GNOSIS_XDAI,
- CHAIN_ID_ETHEREUM,
- CHAIN_ID_POLYGON,
- CHAIN_NAME_GNOSIS_XDAI,
- CHAIN_NAME_ETHEREUM,
- CHAIN_NAME_POLYGON,
- CHAINS_NAMES,
+ // CHAIN_ID_GNOSIS_XDAI,
+ // CHAIN_ID_ETHEREUM,
+ // CHAIN_ID_POLYGON,
+ // CHAIN_NAME_GNOSIS_XDAI,
+ // CHAIN_NAME_ETHEREUM,
+ // CHAIN_NAME_POLYGON,
+ // CHAINS_NAMES,
}
diff --git a/src/utils/blockchain/poolPrice.ts b/src/utils/blockchain/poolPrice.ts
index 52fa70f1..9f753e40 100644
--- a/src/utils/blockchain/poolPrice.ts
+++ b/src/utils/blockchain/poolPrice.ts
@@ -1,7 +1,43 @@
+import { Token } from '@uniswap/sdk-core'
+import {
+ FeeAmount,
+ FeeAmount as Univ3FeeAmount,
+ computePoolAddress,
+} from '@uniswap/v3-sdk'
+
import { Contract, JsonRpcProvider, ethers } from 'ethers'
import { LevinswapABI as UniswapV2PairABI } from './abi/LevinswapABI'
import { UniswapV2FactoryABI } from './abi/UniswapV2FactoryABI'
+import { UniswapV3PoolABI as UniV3PoolABI } from './abi/UniswapV3PoolABI'
+import { UniswapV3QuoterV2ABI as Univ3QuoterABI } from './abi/UniswapV3QuoterV2ABI'
+import {
+ Address,
+ ChainId,
+ Decimals,
+ SUPPORTED_CHAINS_IDS,
+ UniV3Deployment,
+} from './consts/misc'
+
+// const FeeAmounts = {
+// LOWEST: Univ3FeeAmount.LOWEST,
+// LOW: Univ3FeeAmount.LOW,
+// MEDIUM: Univ3FeeAmount.MEDIUM,
+// HIGH: Univ3FeeAmount.HIGH,
+// }
+
+const AssetPrice = {
+ TokenA: 0,
+ TokenB: 1,
+}
+
+const FeeAmounts = {
+ // 1e6
+ LOWEST: Univ3FeeAmount.LOWEST,
+ LOW: Univ3FeeAmount.LOW,
+ MEDIUM: Univ3FeeAmount.MEDIUM,
+ HIGH: Univ3FeeAmount.HIGH,
+}
const isAddressLowererThan = (address0: string, address1: string): boolean => {
if (!address0 || !address1) {
@@ -152,4 +188,123 @@ const averageValues = (
return average
}
-export { getUniV2AssetPrice, averageValues }
+const getUniV3PoolAddress = (
+ tokenA_Address: Address,
+ tokenA_Decimals: Decimals,
+ tokenB_Address: Address,
+ tokenB_Decimals: Decimals,
+ fee: number,
+ poolFactoryAddress: Address,
+ chainId: ChainId,
+): string => {
+ // Validate inputs
+ // chainId
+ if (!SUPPORTED_CHAINS_IDS.includes(chainId)) {
+ throw new Error(`Unsupported chainId: ${chainId}`)
+ }
+ // token addresses
+ if (!tokenA_Address || !tokenB_Address || tokenA_Address === tokenB_Address) {
+ throw new Error('Invalid token addresses')
+ }
+ // token decimals
+ if (!tokenA_Decimals || !tokenB_Decimals) {
+ throw new Error('Invalid token decimals')
+ }
+ // fee
+ if (!Object.values(FeeAmounts).includes(fee)) {
+ throw new Error(
+ `Invalid fee: ${fee} - must be one of ${Object.values(FeeAmounts)}`,
+ )
+ }
+ // pool factory address
+ if (!poolFactoryAddress) {
+ throw new Error('Invalid fee or pool factory address')
+ }
+ const tokenA = new Token(chainId, tokenA_Address, tokenA_Decimals)
+ const tokenB = new Token(chainId, tokenB_Address, tokenB_Decimals)
+
+ return computePoolAddress({
+ factoryAddress: poolFactoryAddress,
+ tokenA: tokenA,
+ tokenB: tokenB,
+ fee,
+ })
+}
+
+const getUniV3AssetPrice = async (
+ uniV3Deployment: UniV3Deployment,
+ token0Address: Address,
+ token1Address: Address,
+ token0Decimals: Decimals,
+ token1Decimals: Decimals,
+ provider: JsonRpcProvider,
+ chainId: ChainId,
+ fee = FeeAmount.MEDIUM, // Default to 3000 bips (0.3%)
+ whichAssetPrice = AssetPrice.TokenA, // : 0 for token0 price, 1 for token1 price
+ amountIn = 10, // Amount of token to quote without decimals
+): Promise => {
+ let price: number | null = null
+ try {
+ // Validate inputs
+ if (!uniV3Deployment[chainId]) {
+ throw new Error(`No deployment found for chainId ${chainId}`)
+ }
+ const poolAddress = getUniV3PoolAddress(
+ token0Address,
+ token0Decimals,
+ token1Address,
+ token1Decimals,
+ fee,
+ uniV3Deployment[chainId].factory,
+ chainId,
+ )
+ // Check pool address result
+ if (!poolAddress) {
+ throw new Error('Failed to get pool address')
+ }
+ // Quoter
+ const quoterContract = new Contract(
+ uniV3Deployment[chainId].quoter,
+ Univ3QuoterABI,
+ provider,
+ )
+ // Amounts
+ const amountInBI =
+ BigInt(amountIn) *
+ BigInt(
+ 10 **
+ (whichAssetPrice === AssetPrice.TokenA
+ ? token0Decimals
+ : token1Decimals),
+ )
+
+ const quotedAmountOut =
+ await quoterContract.quoteExactInputSingle.staticCall({
+ tokenIn:
+ whichAssetPrice === AssetPrice.TokenA ? token0Address : token1Address,
+ tokenOut:
+ whichAssetPrice === AssetPrice.TokenA ? token1Address : token0Address,
+ amountIn: amountInBI,
+ fee: fee,
+ sqrtPriceLimitX96: 0n, // No price limit
+ })
+
+ price =
+ Number(quotedAmountOut[0]) /
+ amountIn /
+ 10 **
+ (whichAssetPrice === AssetPrice.TokenA
+ ? token1Decimals
+ : token0Decimals)
+ } catch (error) {
+ console.warn(
+ `Failed to get asset price for factoryAddress ${uniV3Deployment[chainId].factory} token0Address ${token0Address} token1Address ${token1Address} fee ${fee} chainId ${chainId} amountIn ${amountIn} whichAssetPrice ${whichAssetPrice}`,
+ error,
+ provider,
+ )
+ }
+ return price
+}
+
+export { AssetPrice, FeeAmounts }
+export { getUniV2AssetPrice, averageValues, getUniV3AssetPrice }
diff --git a/src/utils/general.ts b/src/utils/general.ts
index 2053daf1..4c218236 100644
--- a/src/utils/general.ts
+++ b/src/utils/general.ts
@@ -1,3 +1,65 @@
const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
-export { wait }
+const FETCH_RETRIES_DEFAULT_COUNT = 2
+const FETCH_RETRIES_DEFAULT_DELAY = 500
+
+/**
+ * fetchWithRetry
+ * @param url
+ * @param options
+ * @param retries
+ * @param delay : number of milliseconds to wait before retrying; zero = no delay, negative = random delay, positive = fixed delay
+ */
+const fetchWithRetry = async (
+ url: string,
+ options = {},
+ retries = FETCH_RETRIES_DEFAULT_COUNT,
+ delay = FETCH_RETRIES_DEFAULT_DELAY,
+): Promise => {
+ if (retries <= 0) {
+ throw new Error('Max retries reached')
+ }
+ try {
+ const response = await fetch(url, options)
+ if (response.ok) {
+ return response
+ } else {
+ // Handle specific error cases if needed
+ // if (response.status === 401) throw ...
+ // if (response.status === 503) throw ...
+ throw response
+ }
+ } catch (error) {
+ const errorMsg =
+ error instanceof Error
+ ? error.message
+ : error instanceof Response
+ ? `error.statusText: ${error.statusText}, error.status: ${error.status}`
+ : String(error)
+ console.error(
+ `Fetch error: ${errorMsg} for URL: ${url}`,
+ `Retries left: ${retries - 1}, Delay: ${delay}ms`,
+ )
+ if (retries - 1 < 0) {
+ throw error
+ }
+ if (delay > 0) {
+ await wait(delay)
+ return fetchWithRetry(url, options, retries - 1, delay)
+ } else if (delay === 0) {
+ return fetchWithRetry(url, options, retries - 1, delay)
+ } else {
+ // Random delay for retry
+ const randomDelay = Math.floor(Math.random() * delay)
+ await wait(randomDelay)
+ return fetchWithRetry(url, options, retries - 1, delay)
+ }
+ }
+}
+
+export {
+ wait,
+ fetchWithRetry,
+ FETCH_RETRIES_DEFAULT_COUNT,
+ FETCH_RETRIES_DEFAULT_DELAY,
+}
diff --git a/yarn.lock b/yarn.lock
index 4d16f6bc..d1676505 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -516,7 +516,7 @@
ethereum-cryptography "^2.0.0"
micro-ftch "^0.3.1"
-"@ethersproject/abi@5.8.0", "@ethersproject/abi@^5.8.0":
+"@ethersproject/abi@5.8.0", "@ethersproject/abi@^5.5.0", "@ethersproject/abi@^5.8.0":
version "5.8.0"
resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.8.0.tgz#e79bb51940ac35fe6f3262d7fe2cdb25ad5f07d9"
integrity sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==
@@ -555,7 +555,7 @@
"@ethersproject/logger" "^5.8.0"
"@ethersproject/properties" "^5.8.0"
-"@ethersproject/address@5.8.0", "@ethersproject/address@^5", "@ethersproject/address@^5.8.0":
+"@ethersproject/address@5.8.0", "@ethersproject/address@^5", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.8.0":
version "5.8.0"
resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.8.0.tgz#3007a2c352eee566ad745dca1dbbebdb50a6a983"
integrity sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==
@@ -590,14 +590,14 @@
"@ethersproject/logger" "^5.8.0"
bn.js "^5.2.1"
-"@ethersproject/bytes@5.8.0", "@ethersproject/bytes@^5.8.0":
+"@ethersproject/bytes@5.8.0", "@ethersproject/bytes@^5.7.0", "@ethersproject/bytes@^5.8.0":
version "5.8.0"
resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.8.0.tgz#9074820e1cac7507a34372cadeb035461463be34"
integrity sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==
dependencies:
"@ethersproject/logger" "^5.8.0"
-"@ethersproject/constants@5.8.0", "@ethersproject/constants@^5.8.0":
+"@ethersproject/constants@5.8.0", "@ethersproject/constants@^5.7.0", "@ethersproject/constants@^5.8.0":
version "5.8.0"
resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.8.0.tgz#12f31c2f4317b113a4c19de94e50933648c90704"
integrity sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==
@@ -672,6 +672,14 @@
aes-js "3.0.0"
scrypt-js "3.0.1"
+"@ethersproject/keccak256@5.7.0":
+ version "5.7.0"
+ resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a"
+ integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==
+ dependencies:
+ "@ethersproject/bytes" "^5.7.0"
+ js-sha3 "0.8.0"
+
"@ethersproject/keccak256@5.8.0", "@ethersproject/keccak256@^5.8.0":
version "5.8.0"
resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.8.0.tgz#d2123a379567faf2d75d2aaea074ffd4df349e6a"
@@ -680,7 +688,7 @@
"@ethersproject/bytes" "^5.8.0"
js-sha3 "0.8.0"
-"@ethersproject/logger@5.8.0", "@ethersproject/logger@^5.8.0":
+"@ethersproject/logger@5.8.0", "@ethersproject/logger@^5.7.0", "@ethersproject/logger@^5.8.0":
version "5.8.0"
resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.8.0.tgz#f0232968a4f87d29623a0481690a2732662713d6"
integrity sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==
@@ -770,7 +778,7 @@
elliptic "6.6.1"
hash.js "1.1.7"
-"@ethersproject/solidity@5.8.0":
+"@ethersproject/solidity@5.8.0", "@ethersproject/solidity@^5.0.9":
version "5.8.0"
resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.8.0.tgz#429bb9fcf5521307a9448d7358c26b93695379b9"
integrity sha512-4CxFeCgmIWamOHwYN9d+QWGxye9qQLilpgTU0XhYs1OahkclF+ewO+3V1U0mvpiuQxm5EHHmv8f7ClVII8EHsA==
@@ -782,6 +790,15 @@
"@ethersproject/sha2" "^5.8.0"
"@ethersproject/strings" "^5.8.0"
+"@ethersproject/strings@5.7.0":
+ version "5.7.0"
+ resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2"
+ integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==
+ dependencies:
+ "@ethersproject/bytes" "^5.7.0"
+ "@ethersproject/constants" "^5.7.0"
+ "@ethersproject/logger" "^5.7.0"
+
"@ethersproject/strings@5.8.0", "@ethersproject/strings@^5.8.0":
version "5.8.0"
resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.8.0.tgz#ad79fafbf0bd272d9765603215ac74fd7953908f"
@@ -1334,6 +1351,16 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
+"@openzeppelin/contracts@3.4.1-solc-0.7-2":
+ version "3.4.1-solc-0.7-2"
+ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz#371c67ebffe50f551c3146a9eec5fe6ffe862e92"
+ integrity sha512-tAG9LWg8+M2CMu7hIsqHPaTyG4uDzjr6mhvH96LvOpLZZj6tgzTluBt+LsCf1/QaYrlis6pITvpIaIhE+iZB+Q==
+
+"@openzeppelin/contracts@3.4.2-solc-0.7":
+ version "3.4.2-solc-0.7"
+ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.2-solc-0.7.tgz#38f4dbab672631034076ccdf2f3201fab1726635"
+ integrity sha512-W6QmqgkADuFcTLzHL8vVoNBtkwjvQRpYIAom7KiUNoLKghyx3FgH0GBjt8NRvigV1ZmMOBllvE1By1C+bi8WpA==
+
"@parcel/watcher-android-arm64@2.5.1":
version "2.5.1"
resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz#507f836d7e2042f798c7d07ad19c3546f9848ac1"
@@ -1580,7 +1607,19 @@
resolved "https://registry.yarnpkg.com/@standard-schema/utils/-/utils-0.3.0.tgz#3d5e608f16c2390c10528e98e59aef6bf73cae7b"
integrity sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==
-"@tabler/icons@^1.119.0", "@tabler/icons@^1.74.0":
+"@tabler/icons-react@^3.34.1":
+ version "3.34.1"
+ resolved "https://registry.yarnpkg.com/@tabler/icons-react/-/icons-react-3.34.1.tgz#852b8efcab5382e44cc0f09b3de7d25ef3cba6f9"
+ integrity sha512-Ld6g0NqOO05kyyHsfU8h787PdHBm7cFmOycQSIrGp45XcXYDuOK2Bs0VC4T2FWSKZ6bx5g04imfzazf/nqtk1A==
+ dependencies:
+ "@tabler/icons" "3.34.1"
+
+"@tabler/icons@3.34.1":
+ version "3.34.1"
+ resolved "https://registry.yarnpkg.com/@tabler/icons/-/icons-3.34.1.tgz#a04a8cf79a5ebdcc44796dfa3de51d04811d2f9f"
+ integrity sha512-9gTnUvd7Fd/DmQgr3MKY+oJLa1RfNsQo8c/ir3TJAWghOuZXodbtbVp0QBY2DxWuuvrSZFys0HEbv1CoiI5y6A==
+
+"@tabler/icons@^1.74.0":
version "1.119.0"
resolved "https://registry.yarnpkg.com/@tabler/icons/-/icons-1.119.0.tgz#8c590bc5a563c8673a78ccd451bedabd584b376e"
integrity sha512-Fk3Qq4w2SXcTjc/n1cuL5bccPkylrOMo7cYpQIf/yw6zP76LQV9dtLcHQUjFiUnaYuswR645CnURIhlafyAh9g==
@@ -1817,6 +1856,87 @@
resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8"
integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==
+"@uniswap/lib@^4.0.1-alpha":
+ version "4.0.1-alpha"
+ resolved "https://registry.yarnpkg.com/@uniswap/lib/-/lib-4.0.1-alpha.tgz#2881008e55f075344675b3bca93f020b028fbd02"
+ integrity sha512-f6UIliwBbRsgVLxIaBANF6w09tYqc6Y/qXdsrbEmXHyFA7ILiKrIwRFXe1yOg8M3cksgVsO9N7yuL2DdCGQKBA==
+
+"@uniswap/sdk-core@^7.7.1", "@uniswap/sdk-core@^7.7.2":
+ version "7.7.2"
+ resolved "https://registry.yarnpkg.com/@uniswap/sdk-core/-/sdk-core-7.7.2.tgz#dc3a9b63b343640754860dce05d06972815eaee6"
+ integrity sha512-0KqXw+y0opBo6eoPAEoLHEkNpOu0NG9gEk7GAYIGok+SHX89WlykWsRYeJKTg9tOwhLpcG9oHg8xZgQ390iOrA==
+ dependencies:
+ "@ethersproject/address" "^5.0.2"
+ "@ethersproject/bytes" "^5.7.0"
+ "@ethersproject/keccak256" "5.7.0"
+ "@ethersproject/strings" "5.7.0"
+ big.js "^5.2.2"
+ decimal.js-light "^2.5.0"
+ jsbi "^3.1.4"
+ tiny-invariant "^1.1.0"
+ toformat "^2.0.0"
+
+"@uniswap/swap-router-contracts@^1.3.0":
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/@uniswap/swap-router-contracts/-/swap-router-contracts-1.3.1.tgz#0ebbb93eb578625618ed9489872de381f9c66fb4"
+ integrity sha512-mh/YNbwKb7Mut96VuEtL+Z5bRe0xVIbjjiryn+iMMrK2sFKhR4duk/86mEz0UO5gSx4pQIw9G5276P5heY/7Rg==
+ dependencies:
+ "@openzeppelin/contracts" "3.4.2-solc-0.7"
+ "@uniswap/v2-core" "^1.0.1"
+ "@uniswap/v3-core" "^1.0.0"
+ "@uniswap/v3-periphery" "^1.4.4"
+ dotenv "^14.2.0"
+ hardhat-watcher "^2.1.1"
+
+"@uniswap/v2-core@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@uniswap/v2-core/-/v2-core-1.0.1.tgz#af8f508bf183204779938969e2e54043e147d425"
+ integrity sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==
+
+"@uniswap/v3-core@1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@uniswap/v3-core/-/v3-core-1.0.0.tgz#6c24adacc4c25dceee0ba3ca142b35adbd7e359d"
+ integrity sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA==
+
+"@uniswap/v3-core@^1.0.0":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@uniswap/v3-core/-/v3-core-1.0.1.tgz#b6d2bdc6ba3c3fbd610bdc502395d86cd35264a0"
+ integrity sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ==
+
+"@uniswap/v3-periphery@^1.0.1", "@uniswap/v3-periphery@^1.1.1", "@uniswap/v3-periphery@^1.4.4":
+ version "1.4.4"
+ resolved "https://registry.yarnpkg.com/@uniswap/v3-periphery/-/v3-periphery-1.4.4.tgz#d2756c23b69718173c5874f37fd4ad57d2f021b7"
+ integrity sha512-S4+m+wh8HbWSO3DKk4LwUCPZJTpCugIsHrWR86m/OrUyvSqGDTXKFfc2sMuGXCZrD1ZqO3rhQsKgdWg3Hbb2Kw==
+ dependencies:
+ "@openzeppelin/contracts" "3.4.2-solc-0.7"
+ "@uniswap/lib" "^4.0.1-alpha"
+ "@uniswap/v2-core" "^1.0.1"
+ "@uniswap/v3-core" "^1.0.0"
+ base64-sol "1.0.1"
+
+"@uniswap/v3-sdk@^3.25.2":
+ version "3.25.2"
+ resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-3.25.2.tgz#cb6ee174b58d86a3b3b18b3ba72f662e58c415da"
+ integrity sha512-0oiyJNGjUVbc958uZmAr+m4XBCjV7PfMs/OUeBv+XDl33MEYF/eH86oBhvqGDM8S/cYaK55tCXzoWkmRUByrHg==
+ dependencies:
+ "@ethersproject/abi" "^5.5.0"
+ "@ethersproject/solidity" "^5.0.9"
+ "@uniswap/sdk-core" "^7.7.1"
+ "@uniswap/swap-router-contracts" "^1.3.0"
+ "@uniswap/v3-periphery" "^1.1.1"
+ "@uniswap/v3-staker" "1.0.0"
+ tiny-invariant "^1.1.0"
+ tiny-warning "^1.0.3"
+
+"@uniswap/v3-staker@1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@uniswap/v3-staker/-/v3-staker-1.0.0.tgz#9a6915ec980852479dfc903f50baf822ff8fa66e"
+ integrity sha512-JV0Qc46Px5alvg6YWd+UIaGH9lDuYG/Js7ngxPit1SPaIP30AlVer1UYB7BRYeUVVxE+byUyIeN5jeQ7LLDjIw==
+ dependencies:
+ "@openzeppelin/contracts" "3.4.1-solc-0.7-2"
+ "@uniswap/v3-core" "1.0.0"
+ "@uniswap/v3-periphery" "^1.0.1"
+
"@walletconnect/core@2.19.1":
version "2.19.1"
resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.19.1.tgz#71738940341b438326b65b3f49226decbe070bae"
@@ -2230,7 +2350,7 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
dependencies:
color-convert "^2.0.1"
-anymatch@^3.1.3:
+anymatch@^3.1.3, anymatch@~3.1.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
@@ -2405,6 +2525,11 @@ base64-js@^1.3.1:
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
+base64-sol@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/base64-sol/-/base64-sol-1.0.1.tgz#91317aa341f0bc763811783c5729f1c2574600f6"
+ integrity sha512-ld3cCNMeXt4uJXmLZBHFGMvVpK9KsLVEhPpFRXnvSVAqABKbuNZg/+dsq3NuM+wxFLb/UrVkz7m1ciWmkMfTbg==
+
bech32@1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9"
@@ -2415,6 +2540,16 @@ big-integer@^1.6.16:
resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85"
integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==
+big.js@^5.2.2:
+ version "5.2.2"
+ resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
+ integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
+
+binary-extensions@^2.0.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
+ integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
+
bn.js@^4.11.9:
version "4.12.1"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.1.tgz#215741fe3c9dba2d7e12c001d0cfdbae43975ba7"
@@ -2433,7 +2568,7 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
-braces@^3.0.3:
+braces@^3.0.3, braces@~3.0.2:
version "3.0.3"
resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz"
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
@@ -2543,6 +2678,21 @@ chalk@^4.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
+chokidar@^3.5.3:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
+ integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
+ dependencies:
+ anymatch "~3.1.2"
+ braces "~3.0.2"
+ glob-parent "~5.1.2"
+ is-binary-path "~2.1.0"
+ is-glob "~4.0.1"
+ normalize-path "~3.0.0"
+ readdirp "~3.6.0"
+ optionalDependencies:
+ fsevents "~2.3.2"
+
chokidar@^4.0.0, chokidar@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30"
@@ -2749,6 +2899,11 @@ 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:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934"
+ integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==
+
decode-uri-component@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
@@ -2866,6 +3021,11 @@ dom-helpers@^5.0.1:
"@babel/runtime" "^7.8.7"
csstype "^3.0.2"
+dotenv@^14.2.0:
+ version "14.3.2"
+ resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-14.3.2.tgz#7c30b3a5f777c79a3429cb2db358eef6751e8369"
+ integrity sha512-vwEppIphpFdvaMCaHfCEv9IgwcxMljMw2TnAQBB4VWPvzXQLTb82jwmdOKzlEVUL3gNFT4l4TPKO+Bn+sqcrVQ==
+
dotenv@^16.0.3:
version "16.4.7"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26"
@@ -3401,10 +3561,10 @@ ethers@^5.6.8:
"@ethersproject/web" "5.8.0"
"@ethersproject/wordlists" "5.8.0"
-ethers@^6.14.1:
- version "6.14.1"
- resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.14.1.tgz#96b5e967d9c3c66c6b64304d8e7669a761d6fca3"
- integrity sha512-JnFiPFi3sK2Z6y7jZ3qrafDMwiXmU+6cNZ0M+kPq+mTy9skqEzwqAdFW3nb/em2xjlIVXX6Lz8ID6i3LmS4+fQ==
+ethers@^6.15.0:
+ version "6.15.0"
+ resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.15.0.tgz#2980f2a3baf0509749b7e21f8692fa8a8349c0e3"
+ integrity sha512-Kf/3ZW54L4UT0pZtsY/rf+EkBU7Qi5nnhonjUb8yTXcxH3cdcWrV2cRyk0Xk/4jK6OoHhxxZHriyhje20If2hQ==
dependencies:
"@adraffy/ens-normalize" "1.10.1"
"@noble/curves" "1.2.0"
@@ -3538,6 +3698,11 @@ fs.realpath@^1.0.0:
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
+fsevents@~2.3.2:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
+ integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
+
function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
@@ -3608,7 +3773,7 @@ get-symbol-description@^1.1.0:
es-errors "^1.3.0"
get-intrinsic "^1.2.6"
-glob-parent@^5.1.2:
+glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
@@ -3727,6 +3892,13 @@ h3@^1.15.0:
ufo "^1.5.4"
uncrypto "^0.1.3"
+hardhat-watcher@^2.1.1:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/hardhat-watcher/-/hardhat-watcher-2.5.0.tgz#3ee76c3cb5b99f2875b78d176207745aa484ed4a"
+ integrity sha512-Su2qcSMIo2YO2PrmJ0/tdkf+6pSt8zf9+4URR5edMVti6+ShI8T3xhPrwugdyTOFuyj8lKHrcTZNKUFYowYiyA==
+ dependencies:
+ chokidar "^3.5.3"
+
has-bigints@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.1.0.tgz#28607e965ac967e03cd2a2c70a2636a1edad49fe"
@@ -3947,6 +4119,13 @@ is-bigint@^1.1.0:
dependencies:
has-bigints "^1.0.2"
+is-binary-path@~2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
+ integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
+ dependencies:
+ binary-extensions "^2.0.0"
+
is-boolean-object@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.2.2.tgz#7067f47709809a393c71ff5bb3e135d8a9215d9e"
@@ -4011,7 +4190,7 @@ is-generator-function@^1.0.10:
has-tostringtag "^1.0.2"
safe-regex-test "^1.1.0"
-is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3:
+is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
@@ -4181,6 +4360,11 @@ js-yaml@^4.1.0:
dependencies:
argparse "^2.0.1"
+jsbi@^3.1.4:
+ version "3.2.5"
+ resolved "https://registry.yarnpkg.com/jsbi/-/jsbi-3.2.5.tgz#b37bb90e0e5c2814c1c2a1bcd8c729888a2e37d6"
+ integrity sha512-aBE4n43IPvjaddScbvWRA2YlTzKEynHzu7MqOyTipdHucf/VxS63ViCjxYRg86M8Rxwbt/GfzHl1kKERkt45fQ==
+
jsesc@^2.5.1:
version "2.5.2"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
@@ -4542,7 +4726,7 @@ node-releases@^2.0.19:
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314"
integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==
-normalize-path@^3.0.0:
+normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
@@ -4792,7 +4976,7 @@ picocolors@^1.0.0, picocolors@^1.1.1:
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
-picomatch@^2.0.4, picomatch@^2.3.1:
+picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
@@ -5113,6 +5297,13 @@ readdirp@^4.0.1:
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d"
integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==
+readdirp@~3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
+ integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
+ dependencies:
+ picomatch "^2.2.1"
+
real-require@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.1.0.tgz#736ac214caa20632847b7ca8c1056a0767df9381"
@@ -5637,6 +5828,16 @@ thread-stream@^0.15.1:
dependencies:
real-require "^0.1.0"
+tiny-invariant@^1.1.0:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127"
+ integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==
+
+tiny-warning@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
+ integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
+
to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
@@ -5649,6 +5850,11 @@ to-regex-range@^5.0.1:
dependencies:
is-number "^7.0.0"
+toformat@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/toformat/-/toformat-2.0.0.tgz#7a043fd2dfbe9021a4e36e508835ba32056739d8"
+ integrity sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==
+
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"