diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
index 472092c9..a791487b 100644
--- a/.github/workflows/node.js.yml
+++ b/.github/workflows/node.js.yml
@@ -5,13 +5,12 @@ name: Node.js CI
on:
push:
- branches: [ develop ]
+ branches: [develop]
pull_request:
- branches: [ master, develop ]
+ branches: [master, develop]
jobs:
build:
-
runs-on: ubuntu-latest
strategy:
@@ -20,19 +19,20 @@ jobs:
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- - uses: actions/checkout@v2
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v2
- with:
- node-version: ${{ matrix.node-version }}
- cache: 'yarn'
- - run: yarn install
- - run: yarn workspace @tender/shared build
- - run: yarn workspace @tender/shared lint
- - run: yarn workspace @tender/shared pretty
- - run: yarn workspace @tender/app build
- - run: yarn workspace @tender/app lint
- - run: yarn workspace @tender/app pretty
- - run: yarn workspace @tender/landing build
- - run: yarn workspace @tender/landing lint
- - run: yarn workspace @tender/landing pretty
+ - uses: actions/checkout@v2
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v2
+ with:
+ node-version: ${{ matrix.node-version }}
+ cache: "yarn"
+ - run: yarn install
+ - run: yarn workspace @tender/shared build
+ - run: yarn workspace @tender/shared lint
+ - run: yarn workspace @tender/shared pretty
+ - run: yarn workspace @tender/app build
+ - run: yarn workspace @tender/app test
+ - run: yarn workspace @tender/app lint
+ - run: yarn workspace @tender/app pretty
+ - run: yarn workspace @tender/landing build
+ - run: yarn workspace @tender/landing lint
+ - run: yarn workspace @tender/landing pretty
diff --git a/.gitignore b/.gitignore
index df5db0f4..bbc214dc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,5 +26,6 @@ yarn-error.log*
# subgraph
packages/subgraph/build/
+packages/subgraph/data/
packages/subgraph/src/types/
packages/subgraph/subgraph.yaml
diff --git a/packages/app/jest.config.js b/packages/app/jest.config.js
new file mode 100644
index 00000000..a169f217
--- /dev/null
+++ b/packages/app/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ preset: "ts-jest",
+ transform: { "^.+\\.ts?$": "ts-jest" },
+ testEnvironment: "node",
+ testRegex: "/test/.*\\.(test|spec)?\\.(ts|tsx)$",
+ moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
+ automock: false,
+ setupFiles: ["./setupJest.js"],
+};
diff --git a/packages/app/package.json b/packages/app/package.json
index b652951b..bc425385 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -7,6 +7,7 @@
"startprod": "next start",
"start": "next dev",
"lint": "next lint",
+ "test": "yarn jest",
"eject": "react-scripts eject",
"pretty": "npx prettier --check 'src/**/*.{ts,tsx,js,jsx}'",
"format": "npx prettier --write 'src/**/*.{ts,tsx,js,jsx}'"
@@ -19,7 +20,7 @@
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
- "@types/jest": "^26.0.15",
+ "@types/jest": "^29.2.5",
"@types/lru-cache": "^5.1.1",
"@types/node": "^12.0.0",
"@types/react": "^17.0.0",
@@ -35,6 +36,7 @@
"framer-motion": "^4.1.17",
"grommet": "^2.19.1",
"grommet-icons": "^4.7.0",
+ "jest": "^29.3.1",
"lru-cache": "^6.0.0",
"next": "12.0.8",
"polished": "^4.1.3",
@@ -44,6 +46,7 @@
"react-scripts": "4.0.3",
"styled-components": "^5.3.3",
"swr": "^1.0.1",
+ "ts-jest": "^29.0.3",
"typescript": "^4.6.4",
"utf-8-validate": "^5.0.8",
"web-vitals": "^1.0.1"
diff --git a/packages/app/setupJest.js b/packages/app/setupJest.js
new file mode 100644
index 00000000..e69de29b
diff --git a/packages/app/src/components/BrandedALink.tsx b/packages/app/src/components/BrandedALink.tsx
new file mode 100644
index 00000000..1ba4426f
--- /dev/null
+++ b/packages/app/src/components/BrandedALink.tsx
@@ -0,0 +1,8 @@
+import { theme } from "@tender/shared/src";
+import { normalizeColor } from "grommet/utils";
+import styled from "styled-components";
+
+const brandColor = normalizeColor("brand", theme);
+export const BrandedALink = styled.a`
+ color: ${brandColor};
+`;
diff --git a/packages/app/src/components/ChangeChainWarning.tsx b/packages/app/src/components/ChangeChainWarning.tsx
new file mode 100644
index 00000000..5bb4cc9d
--- /dev/null
+++ b/packages/app/src/components/ChangeChainWarning.tsx
@@ -0,0 +1,28 @@
+import { FC } from "react";
+import { stakers } from "@tender/shared/src/index";
+import { useIsCorrectChain } from "utils/useEnsureRinkebyConnect";
+import { SwitchNetwork } from "components/account/SwitchNetwork";
+import { ProtocolName } from "@tender/shared/src/data/stakers";
+import { Box } from "grommet";
+import { useEthers } from "@usedapp/core";
+
+const ChangeChainWarning: FC<{ protocolName: ProtocolName }> = ({ children, protocolName }) => {
+ const { account } = useEthers();
+
+ const requiredChain = stakers[protocolName].chainId;
+ const isCorrectChain = useIsCorrectChain(requiredChain);
+
+ return (
+ <>
+ {!isCorrectChain && account ? (
+
+
+
+ ) : (
+ <>{children}>
+ )}
+ >
+ );
+};
+
+export default ChangeChainWarning;
diff --git a/packages/app/src/components/account/AccountModal.tsx b/packages/app/src/components/account/AccountModal.tsx
index 9fe6a461..5b4876ff 100644
--- a/packages/app/src/components/account/AccountModal.tsx
+++ b/packages/app/src/components/account/AccountModal.tsx
@@ -3,8 +3,7 @@ import styled from "styled-components";
import { useEthers, useEtherBalance, getChainById, useTokenBalance } from "@usedapp/core";
import { addresses } from "@tender/contracts/src/index";
import { TransactionsList } from "../transactions";
-import { formatEther } from "@ethersproject/units";
-import { BigNumber, constants } from "ethers";
+import { constants } from "ethers";
import { ShareIcon } from "../transactions/Icons";
import { Link } from "../base";
import {
@@ -29,14 +28,7 @@ import {
import { Staker, stakers } from "@tender/shared/src/index";
import { AddToken } from "./AddToken";
import { FormClose } from "grommet-icons";
-
-const formatter = new Intl.NumberFormat("en-us", {
- minimumFractionDigits: 4,
- maximumFractionDigits: 4,
-});
-
-const formatBalance = (balance: BigNumber | undefined) =>
- formatter.format(parseFloat(formatEther(balance ?? BigNumber.from("0"))));
+import { formatBalance } from "components/formatting";
type AccountModalProps = {
showModal: boolean;
diff --git a/packages/app/src/components/deposit/ConfirmDepositModal.tsx b/packages/app/src/components/deposit/ConfirmDepositModal.tsx
index 876cdaeb..0c7f1f13 100644
--- a/packages/app/src/components/deposit/ConfirmDepositModal.tsx
+++ b/packages/app/src/components/deposit/ConfirmDepositModal.tsx
@@ -17,7 +17,7 @@ import {
} from "grommet";
import { FormClose } from "grommet-icons";
-import { stakers, theme } from "@tender/shared/src/index";
+import { stakers } from "@tender/shared/src/index";
import { weiToEthWithDecimals } from "utils/amountFormat";
import { useBalanceValidation } from "utils/inputValidation";
import { AmountInputFooter } from "components/AmountInputFooter";
@@ -26,8 +26,7 @@ import { isPendingTransaction } from "utils/transactions";
import { TransactionStatus } from "@usedapp/core";
import { LoadingButtonContent } from "components/LoadingButtonContent";
import { useCalcDepositOut } from "utils/tenderDepositHooks";
-import styled from "styled-components";
-import { normalizeColor } from "grommet/utils";
+import { BrandedALink } from "components/BrandedALink";
type Props = {
show: boolean;
@@ -142,9 +141,9 @@ const ConfirmDepositModal: FC = ({
Notice: staking GRT infers a 0.5%{" "}
-
+
delegation
- {" "}
+ {" "}
fee towards the Graph Protocol.
@@ -179,8 +178,3 @@ const ConfirmDepositModal: FC = ({
};
export default ConfirmDepositModal;
-
-const brandColor = normalizeColor("brand", theme);
-const StyledA = styled.a`
- color: ${brandColor};
-`;
diff --git a/packages/app/src/components/deposit/UnstakeModal.tsx b/packages/app/src/components/deposit/UnstakeModal.tsx
new file mode 100644
index 00000000..0c0031b8
--- /dev/null
+++ b/packages/app/src/components/deposit/UnstakeModal.tsx
@@ -0,0 +1,156 @@
+import { FC, MouseEventHandler, useState } from "react";
+import { utils, BigNumberish } from "ethers";
+import {
+ Button,
+ Box,
+ Card,
+ CardHeader,
+ CardBody,
+ CardFooter,
+ Layer,
+ Form,
+ FormField,
+ Image,
+ TextInput,
+ Text,
+ Heading,
+} from "grommet";
+
+import { FormClose } from "grommet-icons";
+import { stakers } from "@tender/shared/src/index";
+import { weiToEthWithDecimals } from "utils/amountFormat";
+import { isLargerThanMax, isPositive, useBalanceValidation } from "utils/inputValidation";
+import { AmountInputFooter } from "components/AmountInputFooter";
+import { ProtocolName } from "@tender/shared/src/data/stakers";
+import { useUnstake } from "utils/tenderDepositHooks";
+import { BrandedALink } from "components/BrandedALink";
+
+type Props = {
+ show: boolean;
+ tenderTokenBalance: BigNumberish;
+ protocolName: ProtocolName;
+ onDismiss: () => void;
+};
+
+const UnstakeModal: FC = ({ show, tenderTokenBalance, protocolName, onDismiss }) => {
+ const staker = stakers[protocolName];
+ const symbol = staker.symbol;
+ const bwTenderLogo = `/${staker.bwTenderLogo}`;
+
+ const [unstakeInput, setUnstakeInput] = useState("");
+
+ const { validationMessage } = useBalanceValidation(unstakeInput, tenderTokenBalance, symbol);
+
+ const maxUnstake = () => {
+ setUnstakeInput(utils.formatEther(tenderTokenBalance.toString()));
+ };
+
+ const handleInputChange = (e: any) => {
+ const val = e.target.value;
+ if (val && !val.match(/^(\d+\.?\d*|\.\d+)$/)) return;
+ setUnstakeInput(val);
+ };
+
+ const { unstake } = useUnstake(protocolName);
+
+ const handleUnstake: MouseEventHandler = async (e) => {
+ e.preventDefault();
+ await unstake(utils.parseEther(unstakeInput || "0"));
+ setUnstakeInput("");
+ onDismiss();
+ };
+
+ return (
+ <>
+ {show && (
+
+
+ }
+ onClick={onDismiss}
+ />
+
+
+ {`Unstake t${symbol} for ${symbol}`}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )}
+ >
+ );
+};
+
+export default UnstakeModal;
+
+const getWithdrawLink = (protocolName: ProtocolName): string => {
+ switch (protocolName) {
+ case "audius":
+ return "https://docs.audius.org/token/staking#staking-on-audius";
+ case "graph":
+ return "https://thegraph.com/docs/en/network/delegating/#the-delegation-tax";
+ case "livepeer":
+ return "https://www.figment.io/resources/livepeer-staking-delegation-guide-2";
+ case "matic":
+ return "https://polygon.technology/staking/";
+ }
+};
diff --git a/packages/app/src/components/deposit/WithdrawModal.tsx b/packages/app/src/components/deposit/WithdrawModal.tsx
new file mode 100644
index 00000000..74145f28
--- /dev/null
+++ b/packages/app/src/components/deposit/WithdrawModal.tsx
@@ -0,0 +1,201 @@
+import { FC, useEffect, useState } from "react";
+import {
+ Button,
+ Box,
+ Card,
+ CardHeader,
+ CardBody,
+ CardFooter,
+ Layer,
+ Heading,
+ Table,
+ TableBody,
+ TableCell,
+ TableRow,
+ TextInput,
+ Image,
+ Text,
+ TableHeader,
+} from "grommet";
+
+import { FormClose } from "grommet-icons";
+import { Queries, stakers } from "@tender/shared/src/index";
+import { ProtocolName } from "@tender/shared/src/data/stakers";
+import { Lock } from "./types";
+import { blockTimestampToDate, formatBalance } from "components/formatting";
+import { abis, addresses } from "@tender/contracts/src";
+import { Tenderizer } from "@tender/contracts/gen/types";
+import { Contract, utils } from "ethers";
+import { useEthers } from "@usedapp/core";
+import { useWithdraw } from "utils/tenderDepositHooks";
+import { useQuery } from "@apollo/client";
+import { getUnlockDateForProtocol } from "./helpers";
+
+type Props = {
+ show: boolean;
+ locks: Lock[];
+ protocolName: ProtocolName;
+ onDismiss: () => void;
+};
+
+const WithdrawModal: FC = ({ show, locks, protocolName, onDismiss }) => {
+ const { account } = useEthers();
+ const staker = stakers[protocolName];
+ const symbol = staker.symbol;
+ const [locksUpdated, setLocksUpdated] = useState([]);
+ const { library } = useEthers();
+
+ const { withdraw } = useWithdraw(protocolName);
+
+ const requiredChain = stakers[protocolName].chainId;
+
+ const { data: processUnstakesEvents, refetch: refetchLastGovUnstakeEvent } = useQuery(
+ Queries.GetProcessUnstakes,
+ {
+ variables: {
+ tenderizer: addresses[protocolName].tenderizer.toLowerCase(),
+ },
+ context: { chainId: requiredChain },
+ }
+ );
+
+ useEffect(() => {
+ refetchLastGovUnstakeEvent();
+ }, [refetchLastGovUnstakeEvent, requiredChain, account]);
+
+ useEffect(() => {
+ const simulateWithdraw = async () => {
+ const updatedLocks = await Promise.all(
+ locks.map(async (lock) => {
+ const tenderizer = addresses[protocolName].tenderizer;
+ const contract = new Contract(
+ tenderizer,
+ new utils.Interface(abis.tenderizer),
+ library?.getSigner()
+ ) as Tenderizer;
+ try {
+ await contract.callStatic.withdraw(lock.unstakeLockID);
+ return {
+ ...lock,
+ open: true,
+ };
+ } catch (error) {
+ return {
+ ...lock,
+ open: false,
+ };
+ }
+ })
+ );
+ setLocksUpdated(updatedLocks);
+ };
+ simulateWithdraw();
+ }, [library, locks]);
+
+ return (
+ <>
+ {show && (
+
+
+ }
+ onClick={onDismiss}
+ />
+
+
+ {`Withdraw ${symbol}`}
+
+
+
+
+
+
+
+
+ Asset
+
+
+ Balance
+
+
+ ID
+
+
+ Date
+
+
+ Time Left
+
+
+
+
+
+ {locksUpdated.map((lock) => {
+ return (
+
+
+
+ {symbol}
+
+
+
+
+
+
+
+
+
+
+
+ {lock.unstakeLockID}
+
+
+ {blockTimestampToDate(lock.timestamp).toLocaleDateString("en-US")}
+
+
+
+ {getUnlockDateForProtocol(protocolName, lock, processUnstakesEvents)}
+
+
+
+
+
+ );
+ })}
+
+
+
+
+
+
+
+ )}
+ >
+ );
+};
+
+export default WithdrawModal;
diff --git a/packages/app/src/components/deposit/helpers.ts b/packages/app/src/components/deposit/helpers.ts
new file mode 100644
index 00000000..83be2cea
--- /dev/null
+++ b/packages/app/src/components/deposit/helpers.ts
@@ -0,0 +1,78 @@
+import { Queries } from "@tender/shared/src";
+import { ProtocolName } from "@tender/shared/src/data/stakers";
+import { minutesBetweenDates, blockTimestampToDate } from "../formatting";
+import { Lock } from "./types";
+
+export const getUnlockDateForProtocol = (
+ protocolName: ProtocolName,
+ lock: Lock,
+ processUnstakeEvents: Queries.ProcessUnstakes | undefined,
+ testDate?: Date
+): string => {
+ if (lock.open) {
+ return "Ready";
+ }
+
+ const now = testDate ?? new Date();
+ switch (protocolName) {
+ case "graph": {
+ if (processUnstakeEvents != null) {
+ const lastProcessUnstake = processUnstakeEvents.processUnstakesEvents.reduce((prev, current) => {
+ if (current.timestamp > prev.timestamp) {
+ return current;
+ } else {
+ return prev;
+ }
+ }, processUnstakeEvents.processUnstakesEvents[0]);
+
+ const minutesSinceProcessUnstake = minutesBetweenDates(blockTimestampToDate(lastProcessUnstake.timestamp), now);
+
+ let remainingMinutes = 0;
+ if (lastProcessUnstake == null || lock.timestamp < lastProcessUnstake.timestamp) {
+ remainingMinutes = 28 * 24 * 60 - minutesSinceProcessUnstake;
+ } else {
+ remainingMinutes = 28 * 24 * 60 + 28 * 24 * 60 - minutesSinceProcessUnstake;
+ }
+ return getTimeRemainingLabel(remainingMinutes);
+ } else {
+ return "Loading...";
+ }
+ }
+ case "audius": {
+ const unstakeDate = blockTimestampToDate(lock.timestamp);
+ const unlockDate = new Date(unstakeDate);
+ unlockDate.setDate(unstakeDate.getDate() + 7);
+ const minutesUntilUnlock = minutesBetweenDates(now, unlockDate);
+ return getTimeRemainingLabel(minutesUntilUnlock);
+ }
+ case "livepeer": {
+ const unstakeDate = blockTimestampToDate(lock.timestamp);
+ const unlockDate = new Date(unstakeDate);
+ unlockDate.setDate(unstakeDate.getDate() + 7);
+ const minutesUntilUnlock = minutesBetweenDates(now, unlockDate);
+ return getTimeRemainingLabel(minutesUntilUnlock);
+ }
+ case "matic": {
+ const unstakeDate = blockTimestampToDate(lock.timestamp);
+ const unlockDate = new Date(unstakeDate);
+ unlockDate.setDate(unstakeDate.getDate() + 2);
+ const minutesUntilUnlock = minutesBetweenDates(now, unlockDate);
+ return getTimeRemainingLabel(minutesUntilUnlock);
+ }
+ }
+};
+
+const getTimeRemainingLabel = (remainingMinutes: number) => {
+ if (remainingMinutes < 0) {
+ return `Ready`;
+ } else if (remainingMinutes < 60) {
+ const minutes = remainingMinutes === 0 ? 1 : remainingMinutes;
+ return `~ ${minutes} minute${minutes === 1 ? "" : "s"}`;
+ } else if (remainingMinutes < 24 * 60) {
+ const hours = Math.floor(remainingMinutes / 60);
+ return `~ ${hours} hour${hours === 1 ? "" : "s"}`;
+ } else {
+ const days = Math.floor(remainingMinutes / (60 * 24));
+ return `~ ${days} day${days === 1 ? "" : "s"}`;
+ }
+};
diff --git a/packages/app/src/components/deposit/index.tsx b/packages/app/src/components/deposit/index.tsx
index d3d6138c..65613b5a 100644
--- a/packages/app/src/components/deposit/index.tsx
+++ b/packages/app/src/components/deposit/index.tsx
@@ -1,24 +1,28 @@
-import { FC, MouseEventHandler, useEffect, useState } from "react";
+import { FC, MouseEventHandler, useState } from "react";
import { addresses, contracts } from "@tender/contracts/src/index";
import { useIsGnosisSafe } from "utils/context";
-import { useEthers } from "@usedapp/core";
-import { BigNumber, BigNumberish, utils, constants } from "ethers";
+import { ChainId, useEthers, useNetwork } from "@usedapp/core";
+import { BigNumber, BigNumberish, utils } from "ethers";
import { Button, Box, Form, FormField, Image, Text, TextInput } from "grommet";
-import { useQuery } from "@apollo/client";
import ApproveToken from "components/approve/ApproveToken";
import { useIsTokenApproved } from "components/approve/useIsTokenApproved";
-import { getUnixTimestampQuarter, InfoCard, Queries, stakers, calculateAPY } from "@tender/shared/src/index";
+import { InfoCard, stakers } from "@tender/shared/src/index";
import { AmountInputFooter } from "components/AmountInputFooter";
import { LoadingButtonContent } from "components/LoadingButtonContent";
import { weiToEthWithDecimals } from "utils/amountFormat";
import { isPendingTransaction } from "utils/transactions";
import { isLargerThanMax, isPositive, useBalanceValidation } from "utils/inputValidation";
-import { useIsCorrectChain } from "utils/useEnsureRinkebyConnect";
-import { SwitchNetwork } from "components/account/SwitchNetwork";
import { useDeposit } from "utils/tenderDepositHooks";
import { useResetInputAfterTx } from "utils/useResetInputAfterTx";
import { ProtocolName } from "@tender/shared/src/data/stakers";
import ConfirmDepositModal from "./ConfirmDepositModal";
+import ChangeChainWarning from "components/ChangeChainWarning";
+import UnstakeModal from "./UnstakeModal";
+import WithdrawModal from "./WithdrawModal";
+import Faucet from "components/faucet";
+import { useLocks } from "utils/useUnstakeEvents";
+import { useAPY } from "utils/useAPY";
+import { useRewards } from "utils/useRewards";
type Props = {
protocolName: ProtocolName;
@@ -30,55 +34,27 @@ type Props = {
const Deposit: FC = ({ protocolName, symbol, logo, tokenBalance, tenderTokenBalance }) => {
const { account } = useEthers();
+ const network = useNetwork();
const [depositInput, setDepositInput] = useState("");
const [showConfirm, setShowConfirm] = useState(false);
+ const [showUnstake, setShowUnstake] = useState(false);
+ const [showWithdraw, setShowWithdraw] = useState(false);
- const requiredChain = stakers[protocolName].chainId;
const hasPermit = stakers[protocolName].hasPermit;
- const subgraphName = stakers[protocolName].subgraphId;
- const { data, refetch } = useQuery(Queries.GetUserDeployments, {
- variables: { id: `${account?.toLowerCase()}_${subgraphName}` },
- context: { chainId: requiredChain },
- });
-
- const { data: apyData, refetch: refetchAPY } = useQuery(Queries.GetTenderizerDays, {
- query: Queries.GetTenderizerDays,
- variables: { from: getUnixTimestampQuarter() },
- context: { chainId: requiredChain },
- });
-
- const protocolAPYs = Object.values(calculateAPY(apyData));
- const apy = protocolAPYs.find((staker) => staker.subgraphId === stakers[protocolName].subgraphId)?.apy ?? "";
-
- // update my stake when tokenBalance changes
- useEffect(() => {
- refetch();
- }, [refetch, tokenBalance]);
-
- // update my stake when chainId changes
- useEffect(() => {
- refetchAPY();
- }, [refetchAPY, requiredChain]);
+ const { locks } = useLocks(stakers[protocolName], tenderTokenBalance);
+ const { apy } = useAPY(stakers[protocolName]);
+ const { rewards } = useRewards(stakers[protocolName], tokenBalance, tenderTokenBalance);
+ const isSafeContext = useIsGnosisSafe();
const maxDeposit = () => {
setDepositInput(utils.formatEther(tokenBalance.toString()));
};
- const isCorrectChain = useIsCorrectChain(requiredChain);
-
- const handleInputChange = (e: any) => {
- const val = e.target.value;
- if (val && !val.match(/^(\d+\.?\d*|\.\d+)$/)) return;
- setDepositInput(val);
- };
-
const { tx: depositTx, deposit } = useDeposit(protocolName);
useResetInputAfterTx(depositTx, setDepositInput);
- const isSafeContext = useIsGnosisSafe();
-
const depositTokens: MouseEventHandler = async (e) => {
e.preventDefault();
await deposit(utils.parseEther(depositInput || "0"), isSafeContext);
@@ -95,11 +71,6 @@ const Deposit: FC = ({ protocolName, symbol, logo, tokenBalance, tenderTo
const { validationMessage } = useBalanceValidation(depositInput, tokenBalance);
- const claimedRewards = BigNumber.from(data?.userDeployments?.[0]?.claimedRewards ?? "0");
- const tenderizerStake = BigNumber.from(data?.userDeployments?.[0]?.tenderizerStake ?? "0");
- const myRewards = claimedRewards.add(tenderTokenBalance).sub(tenderizerStake);
- const nonNegativeRewards = myRewards.isNegative() ? constants.Zero : myRewards;
-
return (
@@ -114,23 +85,23 @@ const Deposit: FC = ({ protocolName, symbol, logo, tokenBalance, tenderTo
/>
-
+
- {!isCorrectChain && account ? (
-
-
-
- ) : (
+
- )}
+
+ {network.network.chainId === ChainId.Hardhat && }
= ({ protocolName, symbol, logo, tokenBalance, tenderTo
deposit={depositTokens}
tx={depositTx}
/>
+ setShowUnstake(false)}
+ />
+ setShowWithdraw(false)}
+ />
);
};
diff --git a/packages/app/src/components/deposit/types.ts b/packages/app/src/components/deposit/types.ts
new file mode 100644
index 00000000..d1c06f5a
--- /dev/null
+++ b/packages/app/src/components/deposit/types.ts
@@ -0,0 +1,5 @@
+import { UnstakeEvent } from "@tender/shared/src/queries";
+
+export type Lock = UnstakeEvent & {
+ open: boolean;
+};
diff --git a/packages/app/src/components/formatting.ts b/packages/app/src/components/formatting.ts
new file mode 100644
index 00000000..88a12673
--- /dev/null
+++ b/packages/app/src/components/formatting.ts
@@ -0,0 +1,25 @@
+import { BigNumber, BigNumberish } from "ethers";
+import { formatEther } from "@ethersproject/units";
+
+const formatter = new Intl.NumberFormat("en-US", {
+ minimumFractionDigits: 4,
+ maximumFractionDigits: 4,
+});
+
+export const formatBalance = (balance: BigNumberish | undefined) =>
+ formatter.format(parseFloat(formatEther(balance ?? BigNumber.from("0"))));
+
+export const blockTimestampToDate = (timestamp: string) => new Date(Number(timestamp) * 1000);
+
+export const daysBetweenBlockTimestamps = (timestamp1: string, timestamp2: string) => {
+ return daysBetweenDates(blockTimestampToDate(timestamp1), blockTimestampToDate(timestamp2));
+};
+
+export const daysBetweenDates = (date1: Date, date2: Date): number => {
+ const diff = date2.getTime() - date1.getTime();
+ return Math.floor(diff / (1000 * 3600 * 24));
+};
+
+export const minutesBetweenDates = (date1: Date, date2: Date): number => {
+ return (date2.getTime() - date1.getTime()) / (1000 * 60);
+};
diff --git a/packages/app/src/pages/stakers/[slug].tsx b/packages/app/src/pages/stakers/[slug].tsx
index 21262c41..1164bb9d 100644
--- a/packages/app/src/pages/stakers/[slug].tsx
+++ b/packages/app/src/pages/stakers/[slug].tsx
@@ -219,6 +219,7 @@ const TokenWrapper: FC<{ config?: TenderizeConfig }> = (props) => {
const dappConfig: Config = {
pollingInterval: 2500,
readOnlyUrls: props.config?.chainUrlMapping,
+ multicallAddresses: { [ChainId.Hardhat]: "0x21dF544947ba3E8b3c32561399E88B52Dc8b2823" },
};
if (props.config == null) return null;
@@ -239,12 +240,13 @@ export const getStaticProps = async () => {
const CHAIN_URL_MAPPING = {
[ChainId.Mainnet]: process.env.RPC_ETHEREUM ?? "",
[ChainId.Arbitrum]: process.env.RPC_ARBITRUM ?? "",
+ [ChainId.Hardhat]: "http://localhost:9545" ?? "",
};
const config: TenderizeConfig = {
portisApiKey: process.env.PORTIS_API_KEY ?? "",
- chainUrlMapping: CHAIN_URL_MAPPING ?? "",
- supportedChains: [Mainnet.chainId, Arbitrum.chainId],
+ chainUrlMapping: CHAIN_URL_MAPPING,
+ supportedChains: [Mainnet.chainId, Arbitrum.chainId, ChainId.Hardhat],
};
return {
diff --git a/packages/app/src/utils/tenderDepositHooks.ts b/packages/app/src/utils/tenderDepositHooks.ts
index 96f7df00..51fce91b 100644
--- a/packages/app/src/utils/tenderDepositHooks.ts
+++ b/packages/app/src/utils/tenderDepositHooks.ts
@@ -49,6 +49,26 @@ export const useDeposit = (protocolName: ProtocolName) => {
return { deposit, tx: hasPermit(protocolName) ? depositWithPermitTx : depositTx };
};
+export const useUnstake = (protocolName: ProtocolName) => {
+ const symbol = stakers[protocolName].symbol;
+
+ const { state: unstakeTx, send: unstake } = useContractFunction(contracts[protocolName].tenderizer, "unstake", {
+ transactionName: `Unstake ${symbol}`,
+ });
+
+ return { unstake, tx: unstakeTx };
+};
+
+export const useWithdraw = (protocolName: ProtocolName) => {
+ const symbol = stakers[protocolName].symbol;
+
+ const { state: withdrawTx, send: withdraw } = useContractFunction(contracts[protocolName].tenderizer, "withdraw", {
+ transactionName: `Withdraw ${symbol}`,
+ });
+
+ return { withdraw, tx: withdrawTx };
+};
+
export const useCalcDepositOut = (protocolName: ProtocolName, amount: string) => {
const result = useCall(
protocolName && {
diff --git a/packages/app/src/utils/useAPY.ts b/packages/app/src/utils/useAPY.ts
new file mode 100644
index 00000000..4da45511
--- /dev/null
+++ b/packages/app/src/utils/useAPY.ts
@@ -0,0 +1,21 @@
+import { useQuery } from "@apollo/client";
+import { Queries, getUnixTimestampQuarter, calculateAPY, Staker } from "@tender/shared/src";
+import { useEffect } from "react";
+
+export const useAPY = (staker: Staker) => {
+ const { data: apyData, refetch: refetchAPY } = useQuery(Queries.GetTenderizerDays, {
+ query: Queries.GetTenderizerDays,
+ variables: { from: getUnixTimestampQuarter() },
+ context: { chainId: staker.chainId },
+ });
+
+ const protocolAPYs = Object.values(calculateAPY(apyData));
+ const apy = protocolAPYs.find((v) => v.subgraphId === staker.subgraphId)?.apy ?? "";
+
+ // update when chainId changes
+ useEffect(() => {
+ refetchAPY();
+ }, [refetchAPY, staker.chainId]);
+
+ return { apy };
+};
diff --git a/packages/app/src/utils/useRewards.ts b/packages/app/src/utils/useRewards.ts
new file mode 100644
index 00000000..20a5ccf0
--- /dev/null
+++ b/packages/app/src/utils/useRewards.ts
@@ -0,0 +1,24 @@
+import { useQuery } from "@apollo/client";
+import { Queries, Staker } from "@tender/shared/src";
+import { useEthers } from "@usedapp/core";
+import { BigNumber, BigNumberish, constants } from "ethers";
+import { useEffect } from "react";
+
+export const useRewards = (staker: Staker, tokenBalance: BigNumberish, tenderTokenBalance: BigNumberish) => {
+ const { account } = useEthers();
+ const { data, refetch } = useQuery(Queries.GetUserDeployments, {
+ variables: { id: `${account?.toLowerCase()}_${staker.subgraphId}` },
+ context: { chainId: staker.chainId },
+ });
+ // update my stake when tokenBalance changes
+ useEffect(() => {
+ refetch();
+ }, [refetch, tokenBalance]);
+
+ const claimedRewards = BigNumber.from(data?.userDeployments?.[0]?.claimedRewards ?? "0");
+ const tenderizerStake = BigNumber.from(data?.userDeployments?.[0]?.tenderizerStake ?? "0");
+ const myRewards = claimedRewards.add(tenderTokenBalance).sub(tenderizerStake);
+ const rewards = myRewards.isNegative() ? constants.Zero : myRewards;
+
+ return { rewards };
+};
diff --git a/packages/app/src/utils/useUnstakeEvents.ts b/packages/app/src/utils/useUnstakeEvents.ts
new file mode 100644
index 00000000..5d548edd
--- /dev/null
+++ b/packages/app/src/utils/useUnstakeEvents.ts
@@ -0,0 +1,44 @@
+import { useQuery } from "@apollo/client";
+import { Queries, Staker } from "@tender/shared/src";
+import { useEthers } from "@usedapp/core";
+import { Lock } from "components/deposit/types";
+import { BigNumberish } from "ethers";
+import { useEffect, useState } from "react";
+
+export const useLocks = (staker: Staker, tenderTokenBalance: BigNumberish) => {
+ const { account } = useEthers();
+ const requiredChain = staker.chainId;
+ const [locks, setLocks] = useState([]);
+
+ const { data: unstakeEvents, refetch: refetchUnstakeEvents } = useQuery(
+ Queries.GetPendingWithdrawals,
+ {
+ variables: { from: `${account?.toLowerCase()}` },
+ context: { chainId: requiredChain },
+ }
+ );
+
+ useEffect(() => {
+ refetchUnstakeEvents();
+ }, [refetchUnstakeEvents, requiredChain, account, tenderTokenBalance]);
+
+ useEffect(() => {
+ if (unstakeEvents != null) {
+ const locks = new Array();
+ unstakeEvents.unstakeEvents.forEach((unstakeEvent) => {
+ const withdrawEvent = unstakeEvents.withdrawEvents.find(
+ (withdrawEvent) => withdrawEvent.unstakeLockID === unstakeEvent.unstakeLockID
+ );
+ if (withdrawEvent == null) {
+ locks.push({
+ ...unstakeEvent,
+ open: false,
+ });
+ }
+ });
+ setLocks(locks);
+ }
+ }, [unstakeEvents]);
+
+ return { locks };
+};
diff --git a/packages/app/test/components/deposit/helpers.test.ts b/packages/app/test/components/deposit/helpers.test.ts
new file mode 100644
index 00000000..2e498998
--- /dev/null
+++ b/packages/app/test/components/deposit/helpers.test.ts
@@ -0,0 +1,885 @@
+import { ProcessUnstakes } from "@tender/shared/src/queries";
+import { getUnlockDateForProtocol } from "../../../src/components/deposit/helpers";
+import { Lock } from "../../../src/components/deposit/types";
+
+const SEC = 1000;
+const MINUTE = 60 * SEC;
+const HOUR = 60 * MINUTE;
+const DAY = 24 * HOUR;
+
+describe("audius unlock labels", () => {
+ test("open audius lock should be Ready", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: true,
+ };
+ const label = getUnlockDateForProtocol("audius", lock, undefined, now);
+
+ expect(label).toBe("Ready");
+ });
+
+ test("new audius lock should be 7 days", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+ const label = getUnlockDateForProtocol("audius", lock, undefined, now);
+
+ expect(label).toBe("~ 7 days");
+ });
+
+ test("25 hour old audius lock should be 5 days", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 25 * HOUR);
+ const label = getUnlockDateForProtocol("audius", lock, undefined, now);
+
+ expect(label).toBe("~ 5 days");
+ });
+
+ test("6 days old audius lock should be 1 day", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 6 * DAY);
+ const label = getUnlockDateForProtocol("audius", lock, undefined, now);
+
+ expect(label).toBe("~ 1 day");
+ });
+
+ test("6 days and 1 hour old audius lock should be 23 hours", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 6 * DAY + HOUR);
+ const label = getUnlockDateForProtocol("audius", lock, undefined, now);
+
+ expect(label).toBe("~ 23 hours");
+ });
+
+ test("6 days and 23 hours old audius lock should be 1 hours", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 6 * DAY + 23 * HOUR);
+ const label = getUnlockDateForProtocol("audius", lock, undefined, now);
+
+ expect(label).toBe("~ 1 hour");
+ });
+
+ test("6 days 23 hours and 20 minutes old audius lock should be 40 minutes", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 6 * DAY + 23 * HOUR + 20 * MINUTE);
+ const label = getUnlockDateForProtocol("audius", lock, undefined, now);
+
+ expect(label).toBe("~ 40 minutes");
+ });
+
+ test("7 days old audius lock should be 1 minute", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 7 * DAY);
+ const label = getUnlockDateForProtocol("audius", lock, undefined, now);
+
+ expect(label).toBe("~ 1 minute");
+ });
+
+ test("7 days and 1 second old audius lock should be Ready", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 7 * DAY + SEC);
+ const label = getUnlockDateForProtocol("audius", lock, undefined, now);
+
+ expect(label).toBe("Ready");
+ });
+ test("20 days old audius lock should be Ready", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 20 * DAY);
+ const label = getUnlockDateForProtocol("audius", lock, undefined, now);
+
+ expect(label).toBe("Ready");
+ });
+});
+
+describe("livepeer unlock labels", () => {
+ test("open livepeer lock should be Ready", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: true,
+ };
+ const label = getUnlockDateForProtocol("livepeer", lock, undefined, now);
+
+ expect(label).toBe("Ready");
+ });
+
+ test("new livepeer lock should be 7 days", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+ const label = getUnlockDateForProtocol("livepeer", lock, undefined, now);
+
+ expect(label).toBe("~ 7 days");
+ });
+
+ test("25 hour old livepeer lock should be 5 days", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 25 * HOUR);
+ const label = getUnlockDateForProtocol("livepeer", lock, undefined, now);
+
+ expect(label).toBe("~ 5 days");
+ });
+
+ test("6 days old livepeer lock should be 1 day", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 6 * DAY);
+ const label = getUnlockDateForProtocol("livepeer", lock, undefined, now);
+
+ expect(label).toBe("~ 1 day");
+ });
+
+ test("6 days and 1 hour old livepeer lock should be 23 hours", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 6 * DAY + HOUR);
+ const label = getUnlockDateForProtocol("livepeer", lock, undefined, now);
+
+ expect(label).toBe("~ 23 hours");
+ });
+
+ test("6 days and 23 hours old livepeer lock should be 1 hours", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 6 * DAY + 23 * HOUR);
+ const label = getUnlockDateForProtocol("livepeer", lock, undefined, now);
+
+ expect(label).toBe("~ 1 hour");
+ });
+
+ test("6 days 23 hours and 20 minutes old livepeer lock should be 40 minutes", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 6 * DAY + 23 * HOUR + 20 * MINUTE);
+ const label = getUnlockDateForProtocol("livepeer", lock, undefined, now);
+
+ expect(label).toBe("~ 40 minutes");
+ });
+ test("7 days old livepeer lock should be 1 minute", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 7 * DAY);
+ const label = getUnlockDateForProtocol("livepeer", lock, undefined, now);
+
+ expect(label).toBe("~ 1 minute");
+ });
+
+ test("7 days and 1 second old livepeer lock should be Ready", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 7 * DAY + SEC);
+ const label = getUnlockDateForProtocol("livepeer", lock, undefined, now);
+
+ expect(label).toBe("Ready");
+ });
+
+ test("20 days old livepeer lock should be Ready", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 20 * DAY);
+ const label = getUnlockDateForProtocol("livepeer", lock, undefined, now);
+
+ expect(label).toBe("Ready");
+ });
+});
+
+describe("matic unlock labels", () => {
+ test("open matic lock should be Ready", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: true,
+ };
+ const label = getUnlockDateForProtocol("matic", lock, undefined, now);
+
+ expect(label).toBe("Ready");
+ });
+
+ test("new matic lock should be 2 days", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+ const label = getUnlockDateForProtocol("matic", lock, undefined, now);
+
+ expect(label).toBe("~ 2 days");
+ });
+
+ test("12 hour old matic lock should be 1 day", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 12 * HOUR);
+ const label = getUnlockDateForProtocol("matic", lock, undefined, now);
+
+ expect(label).toBe("~ 1 day");
+ });
+
+ test("1 day old matic lock should be 1 day", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + DAY);
+ const label = getUnlockDateForProtocol("matic", lock, undefined, now);
+
+ expect(label).toBe("~ 1 day");
+ });
+
+ test("1 day and 1 hour old matic lock should be 23 hours", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + DAY + HOUR);
+ const label = getUnlockDateForProtocol("matic", lock, undefined, now);
+
+ expect(label).toBe("~ 23 hours");
+ });
+
+ test("1 day and 23 hours old matic lock should be 1 hours", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + DAY + 23 * HOUR);
+ const label = getUnlockDateForProtocol("matic", lock, undefined, now);
+
+ expect(label).toBe("~ 1 hour");
+ });
+
+ test("1 days 23 hours and 20 minutes old matic lock should be 40 minutes", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + DAY + 23 * HOUR + 20 * MINUTE);
+ const label = getUnlockDateForProtocol("matic", lock, undefined, now);
+
+ expect(label).toBe("~ 40 minutes");
+ });
+
+ test("2 days old matic lock should be 1 minute", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 2 * DAY);
+ const label = getUnlockDateForProtocol("matic", lock, undefined, now);
+
+ expect(label).toBe("~ 1 minute");
+ });
+
+ test("2 days and 1 second old matic lock should be Ready", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 2 * DAY + SEC);
+ const label = getUnlockDateForProtocol("matic", lock, undefined, now);
+
+ expect(label).toBe("Ready");
+ });
+
+ test("20 days old matic lock should be Ready", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ now.setTime(now.getTime() + 20 * DAY);
+ const label = getUnlockDateForProtocol("matic", lock, undefined, now);
+
+ expect(label).toBe("Ready");
+ });
+});
+
+describe("graph unlock labels", () => {
+ test("graph without loaded processUnstakeEvents should be Loading...", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+ const label = getUnlockDateForProtocol("graph", lock, undefined, now);
+
+ expect(label).toBe("Loading...");
+ });
+
+ test("open graph lock should be Ready", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: true,
+ };
+ const label = getUnlockDateForProtocol("graph", lock, undefined, now);
+
+ expect(label).toBe("Ready");
+ });
+
+ test("new graph lock with same time processUnstake should be 56 days", () => {
+ const now = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+ const processUnstakeEvents: ProcessUnstakes = {
+ processUnstakesEvents: [
+ {
+ from: "",
+ node: "",
+ tenderizer: "",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ },
+ ],
+ };
+ const label = getUnlockDateForProtocol("graph", lock, processUnstakeEvents, now);
+
+ expect(label).toBe("~ 56 days");
+ });
+
+ test("graph lock with new processUnstake should be 28 days", () => {
+ const lockTime = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (lockTime.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ const now = new Date();
+ now.setTime(now.getTime() + DAY);
+ const processUnstakeEvents: ProcessUnstakes = {
+ processUnstakesEvents: [
+ {
+ from: "",
+ node: "",
+ tenderizer: "",
+ amount: "100",
+ timestamp: (now.getTime() / 1000).toString(),
+ },
+ ],
+ };
+ const label = getUnlockDateForProtocol("graph", lock, processUnstakeEvents, now);
+
+ expect(label).toBe("~ 28 days");
+ });
+
+ test("2 day old graph lock with 1 day old processUnstakes should be 27 days", () => {
+ const lockTime = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (lockTime.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ const processUnstakesTime = new Date();
+ processUnstakesTime.setTime(processUnstakesTime.getTime() + DAY);
+ const processUnstakeEvents: ProcessUnstakes = {
+ processUnstakesEvents: [
+ {
+ from: "",
+ node: "",
+ tenderizer: "",
+ amount: "100",
+ timestamp: (processUnstakesTime.getTime() / 1000).toString(),
+ },
+ ],
+ };
+ const now = new Date();
+ now.setTime(now.getTime() + 2 * DAY);
+
+ const label = getUnlockDateForProtocol("graph", lock, processUnstakeEvents, now);
+
+ expect(label).toBe("~ 27 days");
+ });
+
+ test("5 day old graph lock with 1 day old processUnstakes should be 27 days", () => {
+ const lockTime = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (lockTime.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ const processUnstakesTime = new Date();
+ processUnstakesTime.setTime(processUnstakesTime.getTime() + 4 * DAY);
+ const processUnstakeEvents: ProcessUnstakes = {
+ processUnstakesEvents: [
+ {
+ from: "",
+ node: "",
+ tenderizer: "",
+ amount: "100",
+ timestamp: (processUnstakesTime.getTime() / 1000).toString(),
+ },
+ ],
+ };
+ const now = new Date();
+ now.setTime(now.getTime() + 5 * DAY);
+
+ const label = getUnlockDateForProtocol("graph", lock, processUnstakeEvents, now);
+
+ expect(label).toBe("~ 27 days");
+ });
+
+ test("29 day old graph lock with 27 day old processUnstakes should be 1 day", () => {
+ const lockTime = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (lockTime.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ const processUnstakesTime = new Date();
+ processUnstakesTime.setTime(processUnstakesTime.getTime() + 2 * DAY);
+ const processUnstakeEvents: ProcessUnstakes = {
+ processUnstakesEvents: [
+ {
+ from: "",
+ node: "",
+ tenderizer: "",
+ amount: "100",
+ timestamp: (processUnstakesTime.getTime() / 1000).toString(),
+ },
+ ],
+ };
+ const now = new Date();
+ now.setTime(now.getTime() + 29 * DAY);
+
+ const label = getUnlockDateForProtocol("graph", lock, processUnstakeEvents, now);
+
+ expect(label).toBe("~ 1 day");
+ });
+
+ test("29 day old graph lock with 27 day and 1 hour old processUnstakes should be 23 hours", () => {
+ const lockTime = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (lockTime.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ const processUnstakesTime = new Date();
+ processUnstakesTime.setTime(processUnstakesTime.getTime() + 2 * DAY);
+ const processUnstakeEvents: ProcessUnstakes = {
+ processUnstakesEvents: [
+ {
+ from: "",
+ node: "",
+ tenderizer: "",
+ amount: "100",
+ timestamp: (processUnstakesTime.getTime() / 1000).toString(),
+ },
+ ],
+ };
+ const now = new Date();
+ now.setTime(now.getTime() + 29 * DAY + 1 * HOUR);
+
+ const label = getUnlockDateForProtocol("graph", lock, processUnstakeEvents, now);
+
+ expect(label).toBe("~ 23 hours");
+ });
+
+ test("29 day old graph lock with 27 day and 23 hour old processUnstakes should be 1 hour", () => {
+ const lockTime = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (lockTime.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ const processUnstakesTime = new Date();
+ processUnstakesTime.setTime(processUnstakesTime.getTime() + 2 * DAY);
+ const processUnstakeEvents: ProcessUnstakes = {
+ processUnstakesEvents: [
+ {
+ from: "",
+ node: "",
+ tenderizer: "",
+ amount: "100",
+ timestamp: (processUnstakesTime.getTime() / 1000).toString(),
+ },
+ ],
+ };
+ const now = new Date();
+ now.setTime(now.getTime() + 29 * DAY + 23 * HOUR);
+
+ const label = getUnlockDateForProtocol("graph", lock, processUnstakeEvents, now);
+
+ expect(label).toBe("~ 1 hour");
+ });
+
+ test("29 day old graph lock with 27 day and 23 hour and 20 minutes old processUnstakes should be 40 minutes", () => {
+ const lockTime = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (lockTime.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ const processUnstakesTime = new Date();
+ processUnstakesTime.setTime(processUnstakesTime.getTime() + 2 * DAY);
+ const processUnstakeEvents: ProcessUnstakes = {
+ processUnstakesEvents: [
+ {
+ from: "",
+ node: "",
+ tenderizer: "",
+ amount: "100",
+ timestamp: (processUnstakesTime.getTime() / 1000).toString(),
+ },
+ ],
+ };
+ const now = new Date();
+ now.setTime(now.getTime() + 29 * DAY + 23 * HOUR + 20 * MINUTE);
+
+ const label = getUnlockDateForProtocol("graph", lock, processUnstakeEvents, now);
+
+ expect(label).toBe("~ 40 minutes");
+ });
+
+ test("29 day old graph lock with 28 days old processUnstakes should be 1 minute", () => {
+ const lockTime = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (lockTime.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ const processUnstakesTime = new Date();
+ processUnstakesTime.setTime(processUnstakesTime.getTime() + 2 * DAY);
+ const processUnstakeEvents: ProcessUnstakes = {
+ processUnstakesEvents: [
+ {
+ from: "",
+ node: "",
+ tenderizer: "",
+ amount: "100",
+ timestamp: (processUnstakesTime.getTime() / 1000).toString(),
+ },
+ ],
+ };
+ const now = new Date();
+ now.setTime(now.getTime() + 30 * DAY);
+
+ const label = getUnlockDateForProtocol("graph", lock, processUnstakeEvents, now);
+
+ expect(label).toBe("~ 1 minute");
+ });
+
+ test("29 day old graph lock with 28 days and 1 second old processUnstakes should be Ready", () => {
+ const lockTime = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (lockTime.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ const processUnstakesTime = new Date();
+ processUnstakesTime.setTime(processUnstakesTime.getTime() + 2 * DAY);
+ const processUnstakeEvents: ProcessUnstakes = {
+ processUnstakesEvents: [
+ {
+ from: "",
+ node: "",
+ tenderizer: "",
+ amount: "100",
+ timestamp: (processUnstakesTime.getTime() / 1000).toString(),
+ },
+ ],
+ };
+ const now = new Date();
+ now.setTime(now.getTime() + 30 * DAY + SEC);
+
+ const label = getUnlockDateForProtocol("graph", lock, processUnstakeEvents, now);
+
+ expect(label).toBe("Ready");
+ });
+
+ test("41 day old graph lock with 40 days old processUnstakes should be Ready", () => {
+ const lockTime = new Date();
+ const lock: Lock = {
+ tenderizer: "",
+ unstakeLockID: "1",
+ amount: "100",
+ timestamp: (lockTime.getTime() / 1000).toString(),
+ from: "0xTEST",
+ open: false,
+ };
+
+ const processUnstakesTime = new Date();
+ processUnstakesTime.setTime(processUnstakesTime.getTime() + DAY);
+ const processUnstakeEvents: ProcessUnstakes = {
+ processUnstakesEvents: [
+ {
+ from: "",
+ node: "",
+ tenderizer: "",
+ amount: "100",
+ timestamp: (processUnstakesTime.getTime() / 1000).toString(),
+ },
+ ],
+ };
+ const now = new Date();
+ now.setTime(now.getTime() + 41 * DAY);
+
+ const label = getUnlockDateForProtocol("graph", lock, processUnstakeEvents, now);
+
+ expect(label).toBe("Ready");
+ });
+});
diff --git a/packages/app/tsconfig.json b/packages/app/tsconfig.json
index d785272b..89aa9d42 100644
--- a/packages/app/tsconfig.json
+++ b/packages/app/tsconfig.json
@@ -7,14 +7,6 @@
"@tender/contracts/*": ["../contracts/src/*"]
}
},
- "include": [
- "next-env.d.ts",
- "react-app/env.d.ts",
- "**/*.ts",
- "**/*.tsx",
- "**/*.js"
- ],
- "exclude": [
- "node_modules"
- ]
+ "include": ["next-env.d.ts", "react-app/env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js", "test/**/*"],
+ "exclude": ["node_modules"]
}
diff --git a/packages/contracts/src/abis/Tenderizer.json b/packages/contracts/src/abis/Tenderizer.json
index ad599c0b..737ccb01 100644
--- a/packages/contracts/src/abis/Tenderizer.json
+++ b/packages/contracts/src/abis/Tenderizer.json
@@ -24,8 +24,20 @@
{
"indexed": false,
"internalType": "string",
- "name": "_param",
+ "name": "param",
"type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "oldValue",
+ "type": "bytes"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "newValue",
+ "type": "bytes"
}
],
"name": "GovernanceUpdate",
@@ -44,6 +56,50 @@
"name": "LiquidityFeeCollected",
"type": "event"
},
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "node",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "ProcessUnstakes",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "ProcessWithdraws",
+ "type": "event"
+ },
{
"anonymous": false,
"inputs": [
@@ -157,29 +213,6 @@
"name": "Withdraw",
"type": "event"
},
- {
- "inputs": [
- {
- "internalType": "address[]",
- "name": "_targets",
- "type": "address[]"
- },
- {
- "internalType": "uint256[]",
- "name": "_values",
- "type": "uint256[]"
- },
- {
- "internalType": "bytes[]",
- "name": "_datas",
- "type": "bytes[]"
- }
- ],
- "name": "batchExecute",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
{
"inputs": [
{
@@ -192,7 +225,7 @@
"outputs": [
{
"internalType": "uint256",
- "name": "amountOut",
+ "name": "",
"type": "uint256"
}
],
@@ -206,32 +239,6 @@
"stateMutability": "nonpayable",
"type": "function"
},
- {
- "inputs": [],
- "name": "collectFees",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "collectLiquidityFees",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "stateMutability": "nonpayable",
- "type": "function"
- },
{
"inputs": [],
"name": "currentPrincipal",
@@ -291,40 +298,70 @@
"stateMutability": "nonpayable",
"type": "function"
},
+ {
+ "inputs": [],
+ "name": "gov",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
{
"inputs": [
+ {
+ "internalType": "contract IERC20",
+ "name": "_steak",
+ "type": "address"
+ },
+ {
+ "internalType": "string",
+ "name": "_symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "contract IGraph",
+ "name": "_graph",
+ "type": "address"
+ },
{
"internalType": "address",
- "name": "_target",
+ "name": "_node",
"type": "address"
},
{
"internalType": "uint256",
- "name": "_value",
+ "name": "_protocolFee",
"type": "uint256"
},
{
- "internalType": "bytes",
- "name": "_data",
- "type": "bytes"
- }
- ],
- "name": "execute",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "gov",
- "outputs": [
+ "internalType": "uint256",
+ "name": "_liquidityFee",
+ "type": "uint256"
+ },
{
- "internalType": "address",
- "name": "",
+ "internalType": "contract ITenderToken",
+ "name": "_tenderTokenTarget",
+ "type": "address"
+ },
+ {
+ "internalType": "contract TenderFarmFactory",
+ "name": "_tenderFarmFactory",
+ "type": "address"
+ },
+ {
+ "internalType": "contract ITenderSwapFactory",
+ "name": "_tenderSwapFactory",
"type": "address"
}
],
- "stateMutability": "view",
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
"type": "function"
},
{
@@ -355,7 +392,21 @@
},
{
"inputs": [],
- "name": "pendingFees",
+ "name": "processUnstake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "processWithdraw",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "protocolFee",
"outputs": [
{
"internalType": "uint256",
@@ -368,7 +419,7 @@
},
{
"inputs": [],
- "name": "pendingLiquidityFees",
+ "name": "rescueUnlock",
"outputs": [
{
"internalType": "uint256",
@@ -376,20 +427,20 @@
"type": "uint256"
}
],
- "stateMutability": "view",
+ "stateMutability": "nonpayable",
"type": "function"
},
{
- "inputs": [],
- "name": "protocolFee",
- "outputs": [
+ "inputs": [
{
"internalType": "uint256",
- "name": "",
+ "name": "_unstakeLockID",
"type": "uint256"
}
],
- "stateMutability": "view",
+ "name": "rescueWithdraw",
+ "outputs": [],
+ "stateMutability": "nonpayable",
"type": "function"
},
{
@@ -561,11 +612,6 @@
},
{
"inputs": [
- {
- "internalType": "address",
- "name": "_account",
- "type": "address"
- },
{
"internalType": "uint256",
"name": "_amount",
@@ -652,37 +698,13 @@
],
"name": "unstake",
"outputs": [
- {
- "internalType": "uint256",
- "name": "unstakeLockID",
- "type": "uint256"
- }
- ],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
- "name": "unstakeLocks",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- },
- {
- "internalType": "address",
- "name": "account",
- "type": "address"
- }
- ],
- "stateMutability": "view",
+ "stateMutability": "nonpayable",
"type": "function"
},
{
@@ -698,4 +720,4 @@
"stateMutability": "nonpayable",
"type": "function"
}
-]
\ No newline at end of file
+]
diff --git a/packages/contracts/src/abis/UniswapQuoter.json b/packages/contracts/src/abis/UniswapQuoter.json
new file mode 100644
index 00000000..95914d4b
--- /dev/null
+++ b/packages/contracts/src/abis/UniswapQuoter.json
@@ -0,0 +1,199 @@
+[
+ {
+ "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"
+ }
+ ],
+ "stateMutability":"nonpayable",
+ "type":"function"
+ },
+ {
+ "inputs":[
+ {
+ "internalType":"address",
+ "name":"tokenIn",
+ "type":"address"
+ },
+ {
+ "internalType":"address",
+ "name":"tokenOut",
+ "type":"address"
+ },
+ {
+ "internalType":"uint24",
+ "name":"fee",
+ "type":"uint24"
+ },
+ {
+ "internalType":"uint256",
+ "name":"amountIn",
+ "type":"uint256"
+ },
+ {
+ "internalType":"uint160",
+ "name":"sqrtPriceLimitX96",
+ "type":"uint160"
+ }
+ ],
+ "name":"quoteExactInputSingle",
+ "outputs":[
+ {
+ "internalType":"uint256",
+ "name":"amountOut",
+ "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"
+ }
+ ],
+ "stateMutability":"nonpayable",
+ "type":"function"
+ },
+ {
+ "inputs":[
+ {
+ "internalType":"address",
+ "name":"tokenIn",
+ "type":"address"
+ },
+ {
+ "internalType":"address",
+ "name":"tokenOut",
+ "type":"address"
+ },
+ {
+ "internalType":"uint24",
+ "name":"fee",
+ "type":"uint24"
+ },
+ {
+ "internalType":"uint256",
+ "name":"amountOut",
+ "type":"uint256"
+ },
+ {
+ "internalType":"uint160",
+ "name":"sqrtPriceLimitX96",
+ "type":"uint160"
+ }
+ ],
+ "name":"quoteExactOutputSingle",
+ "outputs":[
+ {
+ "internalType":"uint256",
+ "name":"amountIn",
+ "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"
+ }
+ ]
\ No newline at end of file
diff --git a/packages/shared/src/graph.ts b/packages/shared/src/graph.ts
index 9fddc57c..e9cb31ae 100644
--- a/packages/shared/src/graph.ts
+++ b/packages/shared/src/graph.ts
@@ -5,6 +5,7 @@ import { MultiAPILink } from "@habx/apollo-multi-endpoint-link";
const ENDPOINTS: Endpoints = {
[ChainId.Arbitrum]: "https://api.thegraph.com/subgraphs/name/tenderize/tenderize-arbitrum",
[ChainId.Mainnet]: "https://api.thegraph.com/subgraphs/name/tenderize/tenderize-ethereum",
+ [ChainId.Hardhat]: "http://127.0.0.1:8000/subgraphs/name/tenderize/tenderize-localhost",
};
interface Endpoints {
diff --git a/packages/shared/src/queries/index.ts b/packages/shared/src/queries/index.ts
index a7b62d3a..1ef22dcf 100644
--- a/packages/shared/src/queries/index.ts
+++ b/packages/shared/src/queries/index.ts
@@ -6,6 +6,31 @@ export type RewardsClaimedEvent = {
oldPrincipal: string;
};
+export type UnstakeEvent = {
+ tenderizer: string;
+ unstakeLockID: string;
+ amount: string;
+ timestamp: string;
+ from: string;
+};
+
+export type ProcessUnstakesEvent = {
+ from: string;
+ node: string;
+ tenderizer: string;
+ amount: string;
+ timestamp: string;
+};
+
+export type ProcessUnstakes = {
+ processUnstakesEvents: ProcessUnstakesEvent[];
+};
+
+export type PendingWithdrawals = {
+ unstakeEvents: UnstakeEvent[];
+ withdrawEvents: UnstakeEvent[];
+};
+
export type TenderizerDaysType = {
tenderizers: {
id: string;
@@ -47,6 +72,37 @@ export type TVLData = {
}[];
};
+export const GetPendingWithdrawals = gql`
+ query GetTVL($from: String) @api(contextKey: "chainId") {
+ unstakeEvents(where: { from: $from }) {
+ unstakeLockID
+ tenderizer
+ amount
+ timestamp
+ from
+ }
+ withdrawEvents(where: { from: $from }) {
+ unstakeLockID
+ tenderizer
+ amount
+ timestamp
+ from
+ }
+ }
+`;
+
+export const GetProcessUnstakes = gql`
+ query GetProcessUnstakes($tenderizer: String) @api(contextKey: "chainId") {
+ processUnstakesEvents(where: { tenderizer: $tenderizer }) {
+ from
+ node
+ tenderizer
+ amount
+ timestamp
+ }
+ }
+`;
+
export const GetUserDeployments = gql`
query GetUserDeployments($id: ID!) @api(contextKey: "chainId") {
userDeployments(where: { id: $id }) {
diff --git a/packages/subgraph/README.md b/packages/subgraph/README.md
index 1e019ee8..027712e2 100644
--- a/packages/subgraph/README.md
+++ b/packages/subgraph/README.md
@@ -38,21 +38,17 @@ Replace `paulrberg/create-eth-app` in the package.json script with your subgraph
You may also want to [read more about the hosted service](https://thegraph.com/docs/quick-start#hosted-service).
-## Learn More
+## Deploy Subgraph Locally
-To learn The Graph, check out the [The Graph documentation](https://thegraph.com/docs).
+1. Install [Docker](https://docs.docker.com) and [Docker Compose](https://docs.docker.com/compose/install/)
+2. Inside `docker-compose.yml`, set the `ethereum` value under the `environment` section to an archive node that has tracing enabled. If you don't have access to an archive node we recommend using [Alchemy](https://alchemyapi.io/).
+3. In the root of this project run `docker-compose up`. This command will look for the `docker-compose.yml` file and automatically provision a server with rust, postgres, and ipfs, and spin up a graph node with a GraphiQL interface at `http://127.0.0.1:8000/`.
----
+4. Run `yarn create:local` to create the subgraph
+5. Run `yarn deploy:local` to deploy it
-1. Generate types
-2. Build distributable files
-3. Deploy to the remote API
-
-## Learn More
-
-You can learn more in the [The Graph documentation](https://thegraph.com/docs).
-
-Also consider joining [The Graph Discord server](https://discord.gg/vtvv7FP), where you can seek out help.
+After downloading the latest blocks from Ethereum, you should begin to see smart contract events flying in. Open a GraphiQL browser at
+localhost:8000 to query the Graph Node.s
## Common Errors
@@ -71,7 +67,7 @@ Make sure that you followed the instructions listed above for [yarn auth](#yarn-
### Failed to Deploy
-> ✖ Failed to deploy to Graph node https://api.thegraph.com/deploy/: Invalid account name or access token
+> ✖ Failed to deploy to Graph node : Invalid account name or access token
Make sure that you:
diff --git a/packages/subgraph/docker-compose.yaml b/packages/subgraph/docker-compose.yaml
new file mode 100644
index 00000000..35de8b2a
--- /dev/null
+++ b/packages/subgraph/docker-compose.yaml
@@ -0,0 +1,37 @@
+version: "3"
+services:
+ graph-node:
+ image: graphprotocol/graph-node:latest
+ container_name: graph-node
+ ports:
+ - "8000:8000"
+ - "8001:8001"
+ - "8020:8020"
+ depends_on:
+ - ipfs
+ - postgres
+ environment:
+ postgres_host: postgres
+ postgres_user: graph-node
+ postgres_pass: let-me-in
+ postgres_db: graph-node
+ ipfs: "ipfs:5001"
+ ethereum: "localhost:http://host.docker.internal:9545/"
+ ipfs:
+ image: ipfs/go-ipfs
+ container_name: ipfs
+ ports:
+ - "5001:5001"
+ volumes:
+ - ./data/ipfs:/data/ipfs
+ postgres:
+ image: postgres
+ container_name: postgres
+ ports:
+ - "5432:5432"
+ environment:
+ POSTGRES_USER: graph-node
+ POSTGRES_PASSWORD: let-me-in
+ POSTGRES_DB: graph-node
+ volumes:
+ - ./data/postgres:/var/lib/postgresql/data
diff --git a/packages/subgraph/networks.yaml b/packages/subgraph/networks.yaml
index bb650536..0149d6cc 100644
--- a/packages/subgraph/networks.yaml
+++ b/packages/subgraph/networks.yaml
@@ -2,8 +2,8 @@ mainnet:
networkName: mainnet
contracts:
registry:
- address: "c1c0472c0c80bccdc7f5d01a376bd97a734b8815"
- startBlock: 500000
+ address: "ac7E1D17C1591de440F2ce3FD8e72d28c0C179f3"
+ startBlock: 14745264
rinkeby:
networkName: rinkeby
contracts:
@@ -15,4 +15,16 @@ arbitrum-rinkeby:
contracts:
registry:
address: "6D0DD63BA7136892154ED57f0F5Fd0080145a385"
- startBlock: 9588525
\ No newline at end of file
+ startBlock: 9588525
+arbitrum-one:
+ networkName: arbitrum-one
+ contracts:
+ registry:
+ address: "87998e0aC7a75f7bac1d5738C997700b0842a42e"
+ startBlock: 11600280
+localhost:
+ networkName: localhost
+ contracts:
+ registry:
+ address: "0x5A569Ad19272Afa97103fD4DbadF33B2FcbaA175" # replace with locally deployed registry address
+ startBlock: 0
diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json
index 7f634ffc..aa53be28 100644
--- a/packages/subgraph/package.json
+++ b/packages/subgraph/package.json
@@ -8,15 +8,19 @@
},
"license": "MIT",
"scripts": {
+ "create:local": "graph create tenderize/tenderize-localhost --node http://127.0.0.1:8020",
"prepare": "node ./templatify.js",
"prepare:rinkeby": "NETWORK_NAME=rinkeby node ./templatify.js",
"prepare:arbitrum-rinkeby": "NETWORK_NAME=arbitrum-rinkeby node ./templatify.js",
+ "prepare:arbitrum": "NETWORK_NAME=arbitrum-one node ./templatify.js",
"prepare:mainnet": "NETWORK_NAME=mainnet node ./templatify.js",
+ "prepare:localhost": "NETWORK_NAME=localhost node ./templatify.js",
"auth": "graph auth https://api.thegraph.com/ $GRAPH_ACCESS_TOKEN",
"build": "graph build",
"codegen": "graph codegen --output-dir src/types/",
"deploy": "graph deploy tenderize/tenderize --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
- "deploy:staging": "graph deploy tenderize/tenderize-staging --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/"
+ "deploy:staging": "graph deploy tenderize/tenderize-staging --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
+ "deploy:local": "graph deploy tenderize/tenderize-localhost --debug --ipfs http://127.0.0.1:5001 --node http://127.0.0.1:8020"
},
"devDependencies": {
"fs-extra": "^10.0.0",
diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql
index 89e730d8..70c49320 100644
--- a/packages/subgraph/schema.graphql
+++ b/packages/subgraph/schema.graphql
@@ -1,16 +1,19 @@
-type TenderizeGlobal @entity { # Global Values/ TODO: better name?
+type TenderizeGlobal
+ @entity { # Global Values/ TODO: better name?
"Fixed ID of '1'"
id: ID!
"List of congifs for all integrations"
configs: [Config!]!
- # TODO: Add global totals
+ # TODO: Add global totals
}
-type Config @entity{
+type Config @entity {
"Name of the protocol eg. 'livepeer'"
id: ID!
"Address of the ERC20 token for integration"
steak: String!
+ "Symbol of the ERC20 token for integration"
+ symbol: String!
"Address of Tenderizer"
tenderizer: String!
"Address of ERC20 Tender Token"
@@ -61,7 +64,9 @@ type Tenderizer @entity {
liquidityFeesUSD: BigDecimal!
"Day data for tenderizer"
- dayData: [TenderizerDay!]
+ dayData: [TenderizerDay!] @derivedFrom(field: "tenderizer")
+
+ rewardsClaimedEvents: [RewardsClaimedEvent!] @derivedFrom(field: "tenderizer")
}
type TenderFarm @entity {
@@ -84,12 +89,14 @@ type TenderFarm @entity {
TVL: BigDecimal!
"Day data for tenderFarm"
- dayData: [TenderFarmDay!]
+ dayData: [TenderFarmDay!] @derivedFrom(field: "tenderfarm")
}
type TenderizerDay @entity {
"_"
id: ID!
+ "Tenderizer"
+ tenderizer: Tenderizer!
"The date beginning at 12:00am UTC"
date: Int!
@@ -101,20 +108,13 @@ type TenderizerDay @entity {
withdrawals: BigInt!
"staking rewards collected from protocol for the day"
rewards: BigInt!
-
- "Principle on the first event of the day"
- startPrinciple: BigInt!
- "Day APY - rewards/dayStartPrinciple"
- DPY: BigDecimal!
- "Last Total Tender Token shares of the day"
- shares: BigInt!
- "Last Total Tender Token supply of the day"
- supply: BigInt!
}
type TenderFarmDay @entity {
"_"
id: ID!
+ "Tenderfam ID"
+ tenderfarm: TenderFarm!
"The date beginning at 12:00am UTC"
date: Int!
@@ -130,7 +130,7 @@ type TenderFarmDay @entity {
"principle in Token (not BPT) value at the start of the day"
startPrinciple: BigDecimal!
"Day APY - total rewards / total volume"
- DPY: BigDecimal!
+ DPY: BigDecimal! # TODO: Remove this?
}
type User @entity {
@@ -140,7 +140,7 @@ type User @entity {
deployments: [UserDeployment!]! @derivedFrom(field: "user")
}
-type UserDeployment @entity {
+type UserDeployment @entity {
"_"
id: ID!
"Protocol"
@@ -160,12 +160,14 @@ type UserDeployment @entity {
shares: BigInt!
"Day data for User"
- dayData: [UserDeploymentDay!]
+ dayData: [UserDeploymentDay!] @derivedFrom(field: "userDeployment")
}
type UserDeploymentDay @entity {
"__"
id: ID!
+ "User deployment ID"
+ userDeployment: UserDeployment!
"The date beginning at 12:00am UTC"
date: Int!
"Last Tender Token shares of the day"
@@ -220,9 +222,19 @@ type WithdrawEvent @entity {
timestamp: BigInt!
}
-type RewardsClaimedEvent @entity {
+type ProcessUnstakesEvent @entity {
id: ID!
tenderizer: String!
+ from: String!
+ amount: BigInt!
+ node: String!
+ timestamp: BigInt!
+}
+
+type RewardsClaimedEvent @entity {
+ id: ID!
+ tenderizer: Tenderizer!
+ tenderizerAddress: String!
rewards: BigInt!
currentPrincipal: BigInt!
oldPrincipal: BigInt!
@@ -481,6 +493,7 @@ type TokenExchange implements Exchange @entity {
tokensBought: BigInt!
soldId: BigInt!
tokensSold: BigInt!
+ steakAddress: Bytes!
block: BigInt!
timestamp: BigInt!
@@ -493,4 +506,4 @@ type Token @entity {
decimals: BigInt!
name: String
symbol: String
-}
\ No newline at end of file
+}
diff --git a/packages/subgraph/src/mappings/config.ts b/packages/subgraph/src/mappings/config.ts
index e3714340..1f7d8f36 100644
--- a/packages/subgraph/src/mappings/config.ts
+++ b/packages/subgraph/src/mappings/config.ts
@@ -1,4 +1,4 @@
// Mainnet addresses
-export const DAI_ADDRESS = '6B175474E89094C44Da98b954EedeAC495271d0F'
-export const LPT_ADDRESS = '58b6A8A3302369DAEc383334672404Ee733aB239'
-export const ONEINCH_ADDRESS = 'c586bef4a0992c495cf22e1aeee4e446cecdee0e'
\ No newline at end of file
+export const USDC_ADDRESS = 'a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
+export const USDC_ADDRESS_ARBITURM = 'FF970A61A04b1cA14834A43f5dE4533eBDDB5CC8'
+export const UNISWAP_QUOTER = 'b27308f9F90D607463bb33eA1BeBb41C27CE5AB6'
\ No newline at end of file
diff --git a/packages/subgraph/src/mappings/registry.ts b/packages/subgraph/src/mappings/registry.ts
index 419f7d2e..d2fd6065 100644
--- a/packages/subgraph/src/mappings/registry.ts
+++ b/packages/subgraph/src/mappings/registry.ts
@@ -16,6 +16,7 @@ import {
import { Address } from "@graphprotocol/graph-ts";
import { TenderToken } from "../types/templates/TenderToken/TenderToken"
import { TenderSwap } from "../types/templates/TenderSwap/TenderSwap"
+import { ERC20 } from "../types/Registry/ERC20"
export function handleTenderizerCreated(config: TenderizerCreated): void {
// Create Config entity and save raw event
@@ -32,6 +33,10 @@ export function handleTenderizerCreated(config: TenderizerCreated): void {
let tenderSwap = TenderSwap.bind(Address.fromString(protocolConfig.tenderSwap))
protocolConfig.lpToken = tenderSwap.lpToken().toHex()
protocolConfigEvent.timestamp = config.block.timestamp
+
+ let underlyingToken = ERC20.bind(params.steak)
+ protocolConfig.symbol = underlyingToken.symbol()
+
protocolConfig.save()
protocolConfigEvent.save()
@@ -63,9 +68,6 @@ export function handleTenderizerCreated(config: TenderizerCreated): void {
// Update day data
let day = loadOrCreateTernderizerDay(config.block.timestamp.toI32(), params.name)
day.deposits = day.deposits.plus(amount)
- let tenderToken = TenderToken.bind(params.tenderToken)
- day.shares = tenderToken.getTotalShares()
- day.supply = tenderToken.getTotalPooledTokens()
day.save()
}
diff --git a/packages/subgraph/src/mappings/tenderFarm.ts b/packages/subgraph/src/mappings/tenderFarm.ts
index 7e1547e2..17db0147 100644
--- a/packages/subgraph/src/mappings/tenderFarm.ts
+++ b/packages/subgraph/src/mappings/tenderFarm.ts
@@ -19,7 +19,7 @@ export function handleFarmEvent(farmEvent: Farm): void {
let tenderFarmAddress = farmEvent.address.toHex()
let protocolId = getProtocolIdByTenderFarmAddress(tenderFarmAddress)
let amount = farmEvent.params.amount
- let usdPrice = getUSDPrice(protocolId)
+ let usdPrice = getUSDPrice(Config.load(protocolId).steak)
// Update User data
let userData = loadOrCreateUserDeployment(farmEvent.params.account.toHex(), protocolId)
@@ -52,7 +52,7 @@ export function handleUnfarmEvent(unfarmEvent: Unfarm): void {
let tenderFarmAddress = unfarmEvent.address.toHex()
let protocolId = getProtocolIdByTenderFarmAddress(tenderFarmAddress)
let amount = unfarmEvent.params.amount
- let usdPrice = getUSDPrice(protocolId)
+ let usdPrice = getUSDPrice(Config.load(protocolId).steak)
// Update User data
let userData = loadOrCreateUserDeployment(unfarmEvent.params.account.toHex(), protocolId)
@@ -85,7 +85,7 @@ export function handleHarvestEvent(harvestEvent: Harvest): void {
let tenderFarmAddress = harvestEvent.address.toHex()
let protocolId = getProtocolIdByTenderFarmAddress(tenderFarmAddress)
let amount = harvestEvent.params.amount
- let usdPrice = getUSDPrice(protocolId)
+ let usdPrice = getUSDPrice(Config.load(protocolId).steak)
// Update User data
let userData = loadOrCreateUserDeployment(harvestEvent.params.account.toHex(), protocolId)
diff --git a/packages/subgraph/src/mappings/tenderSwap.ts b/packages/subgraph/src/mappings/tenderSwap.ts
index a2623cba..5b548539 100644
--- a/packages/subgraph/src/mappings/tenderSwap.ts
+++ b/packages/subgraph/src/mappings/tenderSwap.ts
@@ -162,7 +162,7 @@ export function handleNewAdminFee(event: NewAdminFee): void {
let tokens = swap.tokens
let tokenAmounts: BigInt[] = []
for (let i = 0; i < swap.numTokens; i++) {
- if (event.params.tokenReceived.toHexString() == tokens[i]) {
+ if (event.params.tokenReceived.equals(Address.fromHexString(tokens[i]))) {
tokenAmounts.push(event.params.receivedAmount)
} else {
tokenAmounts.push(BigInt.fromI32(0))
@@ -219,7 +219,7 @@ export function handleNewAdminFee(event: NewAdminFee): void {
let tokens = swap.tokens
let soldId = 1
let boughtId = 0
- if (event.params.tokenSold.toHexString() === tokens[0]){
+ if (event.params.tokenSold.equals(Address.fromHexString(tokens[0]))){
soldId = 0
boughtId = 1
}
@@ -230,6 +230,7 @@ export function handleNewAdminFee(event: NewAdminFee): void {
exchange.tokensSold = event.params.amountSold
exchange.boughtId = BigInt.fromI32(boughtId)
exchange.tokensBought = event.params.amountReceived
+ exchange.steakAddress = Address.fromString(tokens[1])
exchange.block = event.block.number
exchange.timestamp = event.block.timestamp
diff --git a/packages/subgraph/src/mappings/tenderizer.ts b/packages/subgraph/src/mappings/tenderizer.ts
index 3c6d46e9..dd2c99c8 100644
--- a/packages/subgraph/src/mappings/tenderizer.ts
+++ b/packages/subgraph/src/mappings/tenderizer.ts
@@ -5,6 +5,8 @@ import {
ProtocolFeeCollectedEvent,
RewardsClaimedEvent,
UnstakeEvent,
+ ProcessUnstakesEvent,
+
WithdrawEvent,
} from "../types/schema";
import {
@@ -12,6 +14,7 @@ import {
LiquidityFeeCollected,
ProtocolFeeCollected,
RewardsClaimed,
+ ProcessUnstakes,
Unstake,
Withdraw
} from "../types/templates/Tenderizer/Tenderizer"
@@ -33,7 +36,7 @@ export function handleDepositEvent(depositEvent: Deposit): void {
let tenderizerAddress = depositEvent.address.toHex()
let protocolId = getProtocolIdByTenderizerAddress(tenderizerAddress)
let amount = depositEvent.params.amount
- let usdPrice = getUSDPrice(protocolId)
+ let usdPrice = getUSDPrice(Config.load(protocolId).steak)
let config = Config.load(protocolId)
let tenderToken = TenderToken.bind(Address.fromString(config.tenderToken))
let timestamp = depositEvent.block.timestamp.toI32()
@@ -53,8 +56,6 @@ export function handleDepositEvent(depositEvent: Deposit): void {
// Update day data
let day = loadOrCreateTernderizerDay(timestamp, protocolId)
day.deposits = day.deposits.plus(amount)
- day.shares = tenderToken.getTotalShares()
- day.supply = tenderToken.getTotalPooledTokens()
day.save()
// Update Tenderizer data
@@ -106,13 +107,12 @@ export function handleUnstakeEvent(unstakeEvent: Unstake): void {
// Update day data
let day = loadOrCreateTernderizerDay(timestamp, protocolId)
day.unstakes = day.unstakes.plus(amount)
- day.shares = tenderToken.getTotalShares()
- day.supply = tenderToken.getTotalPooledTokens()
day.save()
// Update Tenderizer data
let tenderizer = loadOrCreateTenderizer(protocolId)
- tenderizer.currentPrincipal = tenderizer.currentPrincipal.minus(amount)
+ if(unstakeEvent.params.from.notEqual(unstakeEvent.address))
+ tenderizer.currentPrincipal = tenderizer.currentPrincipal.minus(amount)
tenderizer.save()
// Save raw event
@@ -126,27 +126,38 @@ export function handleUnstakeEvent(unstakeEvent: Unstake): void {
event.save()
}
+export function handleProcessUnstakesEvent(processUnstakesEvent: ProcessUnstakes): void {
+ let tenderizerAddress = processUnstakesEvent.address.toHex()
+ // Save raw event
+ let event = new ProcessUnstakesEvent(processUnstakesEvent.transaction.hash.toHex());
+ event.tenderizer = tenderizerAddress
+ event.from = processUnstakesEvent.params.from.toHex()
+ event.node = processUnstakesEvent.params.node.toHex()
+ event.amount = processUnstakesEvent.params.amount
+ event.timestamp = processUnstakesEvent.block.timestamp
+ event.save()
+}
export function handleWithdrawEvent(withdrawEvent: Withdraw): void {
let tenderizerAddress = withdrawEvent.address.toHex()
let protocolId = getProtocolIdByTenderizerAddress(tenderizerAddress)
let amount = withdrawEvent.params.amount
- let usdPrice = getUSDPrice(protocolId)
+ let usdPrice = getUSDPrice(Config.load(protocolId).steak)
let config = Config.load(protocolId)
let tenderToken = TenderToken.bind(Address.fromString(config.tenderToken))
// Update day data
let day = loadOrCreateTernderizerDay(withdrawEvent.block.timestamp.toI32(), protocolId)
day.withdrawals = day.withdrawals.plus(amount)
- day.shares = tenderToken.getTotalShares()
- day.supply = tenderToken.getTotalPooledTokens()
day.save()
// Update Tenderizer data
- let tenderizer = loadOrCreateTenderizer(protocolId)
- tenderizer.withdrawals = tenderizer.withdrawals.plus(amount)
- tenderizer.TVL = tenderizer.currentPrincipal.divDecimal(exponentToBigDecimal(BI_18)).times(usdPrice)
- tenderizer.save()
+ if(withdrawEvent.params.from.notEqual(withdrawEvent.address)){
+ let tenderizer = loadOrCreateTenderizer(protocolId)
+ tenderizer.withdrawals = tenderizer.withdrawals.plus(amount)
+ tenderizer.TVL = tenderizer.currentPrincipal.divDecimal(exponentToBigDecimal(BI_18)).times(usdPrice)
+ tenderizer.save()
+ }
// Save raw event
let event = new WithdrawEvent(withdrawEvent.transaction.hash.toHex());
@@ -162,20 +173,11 @@ export function handleRewardsClaimedEvent(rewardsClaimedEvent: RewardsClaimed):
let tenderizerAddress = rewardsClaimedEvent.address.toHex()
let protocolId = getProtocolIdByTenderizerAddress(tenderizerAddress)
let amount = rewardsClaimedEvent.params.stakeDiff
- let usdPrice = getUSDPrice(protocolId)
- let config = Config.load(protocolId)
- let tenderToken = TenderToken.bind(Address.fromString(config.tenderToken))
+ let usdPrice = getUSDPrice(Config.load(protocolId).steak)
// Update day data
let day = loadOrCreateTernderizerDay(rewardsClaimedEvent.block.timestamp.toI32(), protocolId)
day.rewards = day.rewards.plus(amount)
- if(day.startPrinciple.gt(BigInt.fromI32(0))) {
- day.DPY = day.rewards.divDecimal(day.startPrinciple.toBigDecimal())
- } else {
- day.DPY = ZERO_BD
- }
- day.shares = tenderToken.getTotalShares()
- day.supply = tenderToken.getTotalPooledTokens()
day.save()
// Update Tenderizer data
@@ -188,18 +190,19 @@ export function handleRewardsClaimedEvent(rewardsClaimedEvent: RewardsClaimed):
// Save raw event
let event = new RewardsClaimedEvent(rewardsClaimedEvent.transaction.hash.toHex());
- event.tenderizer = tenderizerAddress
+ event.tenderizer = tenderizer.id
+ event.tenderizerAddress = tenderizerAddress
event.rewards = rewardsClaimedEvent.params.stakeDiff
event.currentPrincipal = rewardsClaimedEvent.params.currentPrincipal
event.oldPrincipal = rewardsClaimedEvent.params.oldPrincipal
event.timestamp = rewardsClaimedEvent.block.timestamp
- event.save()
+ event.save()
}
export function handleProtocolFeeCollectedEvent(protocolFeeCollectedEvent: ProtocolFeeCollected): void {
let tenderizerAddress = protocolFeeCollectedEvent.address.toHex()
let protocolId = getProtocolIdByTenderizerAddress(tenderizerAddress)
- let usdPrice = getUSDPrice(protocolId)
+ let usdPrice = getUSDPrice(Config.load(protocolId).steak)
// Update Tenderizer totals
let tenderizer = loadOrCreateTenderizer(protocolId)
@@ -218,7 +221,7 @@ export function handleProtocolFeeCollectedEvent(protocolFeeCollectedEvent: Proto
export function handleLiquidityFeeCollectedEvent(liquidityFeeCollectedEvent: LiquidityFeeCollected): void {
let tenderizerAddress = liquidityFeeCollectedEvent.address.toHex()
let protocolId = getProtocolIdByTenderizerAddress(tenderizerAddress)
- let usdPrice = getUSDPrice(protocolId)
+ let usdPrice = getUSDPrice(Config.load(protocolId).steak)
// Update Tenderizer totals
let tenderizer = loadOrCreateTenderizer(protocolId)
diff --git a/packages/subgraph/src/mappings/utils.ts b/packages/subgraph/src/mappings/utils.ts
index 777c97ff..c97ee36e 100644
--- a/packages/subgraph/src/mappings/utils.ts
+++ b/packages/subgraph/src/mappings/utils.ts
@@ -23,7 +23,7 @@ import {
HourlyVolume,
WeeklyVolume
} from "../types/schema";
-import { OneInch } from "../types/templates/Tenderizer/OneInch"
+import { UniswapQuoter } from "../types/templates/Tenderizer/UniswapQuoter"
import * as config from "./config"
import { TenderSwap as TenderSwapContact} from "../types/templates/TenderSwap/TenderSwap"
import { LiquidityPoolToken } from "../types/templates/TenderFarm/LiquidityPoolToken"
@@ -34,6 +34,7 @@ import { decimal } from "@protofire/subgraph-toolkit"
export let ZERO_BI = BigInt.fromI32(0);
export let ONE_BI = BigInt.fromI32(1);
export let ZERO_BD = BigDecimal.fromString('0')
+export let ONE_BD = BigDecimal.fromString('0')
export let BI_18 = BigInt.fromI32(18)
export let BD_100 = BigDecimal.fromString('100')
@@ -79,7 +80,6 @@ export function loadOrCreateTenderizer(id: string): Tenderizer {
tenderizer.protocolFeesUSD = ZERO_BD
tenderizer.liquidityFees = ZERO_BI
tenderizer.liquidityFeesUSD = ZERO_BD
- tenderizer.dayData = []
}
return tenderizer as Tenderizer
@@ -97,7 +97,6 @@ export function loadOrCreateTenderFarm(id: string): TenderFarm {
tenderFarm.currentPrincipal = ZERO_BI
tenderFarm.pendingRewardShares = ZERO_BI
tenderFarm.TVL = ZERO_BD
- tenderFarm.dayData = []
}
return tenderFarm as TenderFarm
@@ -123,7 +122,6 @@ export function loadOrCreateUserDeployment(address: string, protocolName: string
userProtocol.farmAmount = ZERO_BI
userProtocol.farmHarvest = ZERO_BI
userProtocol.shares = ZERO_BI
- userProtocol.dayData = []
// Save derived fields
let user = loadOrCreateUser(address)
@@ -173,6 +171,19 @@ export function getProtocolIdByTenderTokenAddress(address: string): string {
return ''
}
+export function getProtocolIdByTenderSwapAddress(address: string): string {
+ // TODO: Is there a better way to do this?
+ let globals = TenderizeGlobal.load('1')
+ let globalConfigs = globals.configs
+ for (let i = 0; i < globalConfigs.length; i++) {
+ let c = Config.load(globalConfigs[i]) as Config
+ if(c.tenderSwap == address){
+ return c.id
+ }
+ }
+ return ''
+}
+
export function loadOrCreateTernderizerDay(timestamp: i32, protocol: string): TenderizerDay {
let dayTimestamp = timestamp / 86400
let dayID = dayTimestamp.toString() + '_' + protocol
@@ -182,20 +193,12 @@ export function loadOrCreateTernderizerDay(timestamp: i32, protocol: string): Te
if (day == null) {
day = new TenderizerDay(dayID)
let tenderizer = loadOrCreateTenderizer(protocol)
+ day.tenderizer = tenderizer.id
day.date = dayStartTimestamp
day.deposits = ZERO_BI
day.unstakes = ZERO_BI
day.withdrawals = ZERO_BI
day.rewards = ZERO_BI
- day.startPrinciple = tenderizer.currentPrincipal
- day.DPY = ZERO_BD
- day.shares = ZERO_BI
- day.supply = ZERO_BI
-
- let dayList = tenderizer.dayData
- dayList.push(day.id)
- tenderizer.dayData = dayList
- tenderizer.save()
}
return day as TenderizerDay;
}
@@ -209,6 +212,7 @@ export function loadOrCreateTenderFarmDay(timestamp: i32, protocol: string): Ten
if (day == null) {
day = new TenderFarmDay(dayID)
let tenderFarm = loadOrCreateTenderFarm(protocol)
+ day.tenderfarm = tenderFarm.id
day.date = dayStartTimestamp
day.deposits = ZERO_BI
day.withdrawals = ZERO_BI
@@ -217,11 +221,6 @@ export function loadOrCreateTenderFarmDay(timestamp: i32, protocol: string): Ten
day.DPY = ZERO_BD
day.startPrinciple = LPTokenToToken(tenderFarm.currentPrincipal.toBigDecimal(), protocol)
day.save()
-
- let dayList = tenderFarm.dayData
- dayList.push(day.id)
- tenderFarm.dayData = dayList
- tenderFarm.save()
}
return day as TenderFarmDay;
}
@@ -235,6 +234,7 @@ export function loadOrCreateUserDeploymentDay(timestamp: i32, address: string, p
if (day == null) {
day = new UserDeploymentDay(dayID)
let user = loadOrCreateUserDeployment(address, protocol)
+ day.userDeployment = user.id
day.date = dayStartTimestamp
// Initialize data with previous day data
// Not needed for just a single value
@@ -247,32 +247,46 @@ export function loadOrCreateUserDeploymentDay(timestamp: i32, address: string, p
day.shares = previousDay.shares
}
day.save()
-
- dayList = user.dayData
- dayList.push(day.id)
- user.dayData = dayList
- user.save()
}
return day as UserDeploymentDay;
}
-export function getUSDPrice(protocol: string): BigDecimal {
- if(dataSource.network() != 'mainnet'){
+export function getUSDPrice(steakToken: string): BigDecimal {
+ let network = dataSource.network()
+ if(network != 'mainnet' && network != 'arbitrum-one'){
return ZERO_BD
}
- if(protocol == 'livepeer'){
- let daiLptBPool = OneInch.bind(Address.fromString(config.ONEINCH_ADDRESS))
- let res = daiLptBPool.getExpectedReturn(
- Address.fromString(config.DAI_ADDRESS),
- Address.fromString(config.LPT_ADDRESS),
- BigInt.fromI32(100),
- BigInt.fromI32(10),
- ZERO_BI
- )
- return res.value0.divDecimal(BigDecimal.fromString('100'))
+ let usdc: string
+ if(network == 'mainnet'){
+ usdc = config.USDC_ADDRESS
+ } else if(network == 'arbitrum-one'){
+ usdc = config.USDC_ADDRESS_ARBITURM
}
- return ZERO_BD
+
+ let TEN_18 = BigInt.fromI32(10).pow(18)
+ let TEN_24 = BigInt.fromI32(10).pow(24) // 18 + 18 - 12
+
+ let uniQuoter = UniswapQuoter.bind(Address.fromString(config.UNISWAP_QUOTER))
+ let tokenToEth = uniQuoter.try_quoteExactInputSingle(
+ Address.fromString(steakToken),
+ uniQuoter.WETH9(),
+ 3000,
+ TEN_18,
+ BigInt.fromString('0')
+ )
+ if(tokenToEth.reverted) return ZERO_BD
+
+ let ethToUSDC = uniQuoter.try_quoteExactInputSingle(
+ uniQuoter.WETH9(),
+ Address.fromString(usdc),
+ 3000,
+ TEN_18,
+ BigInt.fromString('0')
+ )
+ if(ethToUSDC.reverted) return ZERO_BD
+
+ return tokenToEth.value.times(ethToUSDC.value).divDecimal(TEN_24.toBigDecimal())
}
export function LPTokenToToken(amount: BigDecimal, protocol: string): BigDecimal {
@@ -322,12 +336,13 @@ export function getOrCreateMetaSwap(
block: ethereum.Block,
tx: ethereum.Transaction,
): TenderSwap {
- let swap = TenderSwap.load(address.toHexString())
+ let protocolID = getProtocolIdByTenderSwapAddress(address.toHex())
+ let swap = TenderSwap.load(protocolID)
if (swap == null) {
let info = getMetaSwapInfo(address)
- swap = new TenderSwap(address.toHexString())
+ swap = new TenderSwap(protocolID)
swap.address = address
swap.numTokens = info.tokens.length
swap.tokens = registerTokens(info.tokens, block, tx)
@@ -349,6 +364,14 @@ export function getOrCreateMetaSwap(
let system = getSystemInfo(block, tx)
system.swapCount = system.swapCount.plus(BigInt.fromI32(1))
system.save()
+ } else {
+ let info = getMetaSwapInfo(address)
+ swap.balances = info.balances
+ swap.lpToken = info.lpToken
+ swap.A = info.A
+ swap.swapFee = info.swapFee
+ swap.virtualPrice = info.virtualPrice
+ swap.save()
}
return swap as TenderSwap
diff --git a/packages/subgraph/subgraph.template.yaml b/packages/subgraph/subgraph.template.yaml
index 0919ef60..a455787f 100644
--- a/packages/subgraph/subgraph.template.yaml
+++ b/packages/subgraph/subgraph.template.yaml
@@ -9,7 +9,7 @@ dataSources:
network: {{networkName}}
source:
startBlock: {{contracts.registry.startBlock}}
- address: {{contracts.registry.address}}
+ address: "{{contracts.registry.address}}"
abi: Registry
mapping:
kind: ethereum/events
@@ -23,6 +23,8 @@ dataSources:
file: ../contracts/src/abis/TenderToken.json
- name: TenderSwap
file: ../contracts/src/abis/TenderSwap.json
+ - name: ERC20
+ file: ../contracts/src/abis/ERC20.json
entities:
- TenderizerConfig
eventHandlers:
@@ -31,127 +33,131 @@ dataSources:
file: ./src/mappings/registry.ts
language: wasm/assemblyscript
templates:
- - name: Tenderizer
- kind: ethereum/contract
- network: {{networkName}}
- source:
- abi: Tenderizer
- mapping:
- kind: ethereum/events
- apiVersion: 0.0.1
- language: wasm/assemblyscript
- file: ./src/mappings/tenderizer.ts
- entities:
- - Tenderizer
- abis:
- - name: Tenderizer
- file: ../contracts/src/abis/Tenderizer.json
- - name: OneInch
- file: ../contracts/src/abis/OneInch.json
- - name: TenderToken
- file: ../contracts/src/abis/TenderToken.json
- - name: TenderSwap
- file: ../contracts/src/abis/TenderSwap.json
- eventHandlers:
- - event: Deposit(indexed address,uint256)
- handler: handleDepositEvent
- - event: Unstake(indexed address,indexed address,uint256,uint256)
- handler: handleUnstakeEvent
- - event: Withdraw(indexed address,uint256,uint256)
- handler: handleWithdrawEvent
- - event: RewardsClaimed(int256,uint256,uint256)
- handler: handleRewardsClaimedEvent
- - event: ProtocolFeeCollected(uint256)
- handler: handleProtocolFeeCollectedEvent
- - event: LiquidityFeeCollected(uint256)
- handler: handleLiquidityFeeCollectedEvent
- - name: TenderFarm
- kind: ethereum/contract
- network: {{networkName}}
- source:
- abi: TenderFarm
- mapping:
- kind: ethereum/events
- apiVersion: 0.0.1
- language: wasm/assemblyscript
- file: ./src/mappings/tenderFarm.ts
- entities:
- - Tenderizer
- abis:
- - name: TenderFarm
- file: ../contracts/src/abis/TenderFarm.json
- - name: OneInch
- file: ../contracts/src/abis/OneInch.json
- - name: LiquidityPoolToken
- file: ../contracts/src/abis/LiquidityPoolToken.json
- - name: TenderSwap
- file: ../contracts/src/abis/TenderSwap.json
- - name: TenderToken
- file: ../contracts/src/abis/TenderToken.json
- - name: ERC20
- file: ../contracts/src/abis/erc20.json
- eventHandlers:
- - event: Farm(indexed address,uint256)
- handler: handleFarmEvent
- - event: Unfarm(indexed address,uint256)
- handler: handleUnfarmEvent
- - event: Harvest(indexed address,uint256)
- handler: handleHarvestEvent
- - event: RewardsAdded(uint256)
- handler: handleRewardsAddedEvent
- - name: TenderToken
- kind: ethereum/contract
- network: {{networkName}}
- source:
- abi: TenderToken
- mapping:
- kind: ethereum/events
- apiVersion: 0.0.1
- language: wasm/assemblyscript
- file: ./src/mappings/tenderToken.ts
- entities:
- - Tenderizer
- abis:
- - name: TenderToken
- file: ../contracts/src/abis/TenderToken.json
- - name: TenderSwap
- file: ../contracts/src/abis/TenderSwap.json
- eventHandlers:
- - event: Transfer(indexed address,indexed address,uint256)
- handler: handleTransferEvent
- - name: TenderSwap
- kind: ethereum/contract
- network: {{networkName}}
- source:
- abi: TenderSwap
- mapping:
- kind: ethereum/events
- apiVersion: 0.0.1
- language: wasm/assemblyscript
- file: ./src/mappings/tenderSwap.ts
- entities:
- - Tenderizer
- abis:
- - name: TenderSwap
- file: ../contracts/src/abis/TenderSwap.json
- - name: ERC20
- file: ../contracts/src/abis/erc20.json
- eventHandlers:
- - event: NewAdminFee(uint256)
- handler: handleNewAdminFee
- - event: NewSwapFee(uint256)
- handler: handleNewSwapFee
- - event: RampA(uint256,uint256,uint256,uint256)
- handler: handleRampA
- - event: StopRampA(uint256,uint256)
- handler: handleStopRampA
- - event: AddLiquidity(indexed address,uint256[2],uint256[2],uint256,uint256)
- handler: handleAddLiquidity
- - event: RemoveLiquidity(indexed address,uint256[2],uint256)
- handler: handleRemoveLiquidity
- - event: RemoveLiquidityImbalance(indexed address,uint256[2],uint256[2],uint256,uint256)
- handler: handleRemoveLiquidityImbalance
- - event: RemoveLiquidityOne(indexed address,uint256,uint256,address,uint256)
- handler: handleRemoveLiquidityOne
- - event: Swap(indexed address,address,uint256,uint256)
- handler: handleSwapEvent
+ - name: Tenderizer
+ kind: ethereum/contract
+ network: {{networkName}}
+ source:
+ abi: Tenderizer
+ mapping:
+ kind: ethereum/events
+ apiVersion: 0.0.1
+ language: wasm/assemblyscript
+ file: ./src/mappings/tenderizer.ts
+ entities:
+ - Tenderizer
+ abis:
+ - name: Tenderizer
+ file: ../contracts/src/abis/Tenderizer.json
+ - name: UniswapQuoter
+ file: ../contracts/src/abis/UniswapQuoter.json
+ - name: TenderToken
+ file: ../contracts/src/abis/TenderToken.json
+ - name: TenderSwap
+ file: ../contracts/src/abis/TenderSwap.json
+ - name: ERC20
+ file: ../contracts/src/abis/ERC20.json
+ eventHandlers:
+ - event: Deposit(indexed address,uint256)
+ handler: handleDepositEvent
+ - event: Unstake(indexed address,indexed address,uint256,uint256)
+ handler: handleUnstakeEvent
+ - event: Withdraw(indexed address,uint256,uint256)
+ handler: handleWithdrawEvent
+ - event: RewardsClaimed(int256,uint256,uint256)
+ handler: handleRewardsClaimedEvent
+ - event: ProtocolFeeCollected(uint256)
+ handler: handleProtocolFeeCollectedEvent
+ - event: LiquidityFeeCollected(uint256)
+ handler: handleLiquidityFeeCollectedEvent
+ - event: ProcessUnstakes(indexed address,indexed address,uint256)
+ handler: handleProcessUnstakesEvent
+ - name: TenderFarm
+ kind: ethereum/contract
+ network: {{networkName}}
+ source:
+ abi: TenderFarm
+ mapping:
+ kind: ethereum/events
+ apiVersion: 0.0.1
+ language: wasm/assemblyscript
+ file: ./src/mappings/tenderFarm.ts
+ entities:
+ - Tenderizer
+ abis:
+ - name: TenderFarm
+ file: ../contracts/src/abis/TenderFarm.json
+ - name: UniswapQuoter
+ file: ../contracts/src/abis/UniswapQuoter.json
+ - name: LiquidityPoolToken
+ file: ../contracts/src/abis/LiquidityPoolToken.json
+ - name: TenderSwap
+ file: ../contracts/src/abis/TenderSwap.json
+ - name: TenderToken
+ file: ../contracts/src/abis/TenderToken.json
+ - name: ERC20
+ file: ../contracts/src/abis/ERC20.json
+ eventHandlers:
+ - event: Farm(indexed address,uint256)
+ handler: handleFarmEvent
+ - event: Unfarm(indexed address,uint256)
+ handler: handleUnfarmEvent
+ - event: Harvest(indexed address,uint256)
+ handler: handleHarvestEvent
+ - event: RewardsAdded(uint256)
+ handler: handleRewardsAddedEvent
+ - name: TenderToken
+ kind: ethereum/contract
+ network: {{networkName}}
+ source:
+ abi: TenderToken
+ mapping:
+ kind: ethereum/events
+ apiVersion: 0.0.1
+ language: wasm/assemblyscript
+ file: ./src/mappings/tenderToken.ts
+ entities:
+ - Tenderizer
+ abis:
+ - name: TenderToken
+ file: ../contracts/src/abis/TenderToken.json
+ - name: TenderSwap
+ file: ../contracts/src/abis/TenderSwap.json
+ eventHandlers:
+ - event: Transfer(indexed address,indexed address,uint256)
+ handler: handleTransferEvent
+ - name: TenderSwap
+ kind: ethereum/contract
+ network: {{networkName}}
+ source:
+ abi: TenderSwap
+ mapping:
+ kind: ethereum/events
+ apiVersion: 0.0.1
+ language: wasm/assemblyscript
+ file: ./src/mappings/tenderSwap.ts
+ entities:
+ - Tenderizer
+ abis:
+ - name: TenderSwap
+ file: ../contracts/src/abis/TenderSwap.json
+ - name: ERC20
+ file: ../contracts/src/abis/ERC20.json
+ eventHandlers:
+ - event: NewAdminFee(uint256)
+ handler: handleNewAdminFee
+ - event: NewSwapFee(uint256)
+ handler: handleNewSwapFee
+ - event: RampA(uint256,uint256,uint256,uint256)
+ handler: handleRampA
+ - event: StopRampA(uint256,uint256)
+ handler: handleStopRampA
+ - event: AddLiquidity(indexed address,uint256[2],uint256[2],uint256,uint256)
+ handler: handleAddLiquidity
+ - event: RemoveLiquidity(indexed address,uint256[2],uint256)
+ handler: handleRemoveLiquidity
+ - event: RemoveLiquidityImbalance(indexed address,uint256[2],uint256[2],uint256,uint256)
+ handler: handleRemoveLiquidityImbalance
+ - event: RemoveLiquidityOne(indexed address,uint256,uint256,address,uint256)
+ handler: handleRemoveLiquidityOne
+ - event: Swap(indexed address,address,uint256,uint256)
+ handler: handleSwapEvent
diff --git a/packages/subgraph/templatify.js b/packages/subgraph/templatify.js
index 6c38f533..58a85a02 100644
--- a/packages/subgraph/templatify.js
+++ b/packages/subgraph/templatify.js
@@ -12,10 +12,12 @@ Handlebars.registerHelper("ifEquals", function (arg1, arg2, options) {
function getNetworkNameForSubgraph() {
switch (process.env.SUBGRAPH) {
case undefined:
- case "livepeer/livepeer":
+ case "tenderize/tenderize":
return "mainnet";
- case "livepeer/livepeer-rinkeby":
- return "rinkeby";
+ case "tenderize/tenderize-localhost":
+ return "localhost";
+ case "tenderize/tenderize-arbitrum":
+ return "arbitrum";
default:
return null;
}
@@ -23,26 +25,19 @@ function getNetworkNameForSubgraph() {
(async () => {
const networksFilePath = path.join(__dirname, "networks.yaml");
- const networks = yaml.load(
- await fs.readFile(networksFilePath, { encoding: "utf-8" })
- );
+ const networks = yaml.load(await fs.readFile(networksFilePath, { encoding: "utf-8" }));
const networkName = process.env.NETWORK_NAME || getNetworkNameForSubgraph();
const network = t(networks, networkName).safeObject;
if (t(network).isFalsy) {
- throw new Error(
- 'Please set either a "NETWORK_NAME" or a "SUBGRAPH" environment variable'
- );
+ throw new Error('Please set either a "NETWORK_NAME" or a "SUBGRAPH" environment variable');
}
- const subgraphTemplateFilePath = path.join(
- __dirname,
- "subgraph.template.yaml"
- );
+ const subgraphTemplateFilePath = path.join(__dirname, "subgraph.template.yaml");
const source = await fs.readFile(subgraphTemplateFilePath, "utf-8");
const template = Handlebars.compile(source);
const result = template(network);
await fs.writeFile(path.join(__dirname, "subgraph.yaml"), result);
console.log("🎉 subgraph.yaml successfully generated");
-})();
\ No newline at end of file
+})();
diff --git a/yarn.lock b/yarn.lock
index 2d07481b..dfd0543b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -48,6 +48,13 @@
dependencies:
"@babel/highlight" "^7.14.5"
+"@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a"
+ integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==
+ dependencies:
+ "@babel/highlight" "^7.18.6"
+
"@babel/code-frame@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789"
@@ -65,6 +72,11 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2"
integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==
+"@babel/compat-data@^7.20.5":
+ version "7.20.10"
+ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.10.tgz#9d92fa81b87542fff50e848ed585b4212c1d34ec"
+ integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==
+
"@babel/core@7.12.3":
version "7.12.3"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.3.tgz#1b436884e1e3bff6fb1328dc02b208759de92ad8"
@@ -129,6 +141,27 @@
semver "^6.3.0"
source-map "^0.5.0"
+"@babel/core@^7.11.6":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.7.tgz#37072f951bd4d28315445f66e0ec9f6ae0c8c35f"
+ integrity sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==
+ dependencies:
+ "@ampproject/remapping" "^2.1.0"
+ "@babel/code-frame" "^7.18.6"
+ "@babel/generator" "^7.20.7"
+ "@babel/helper-compilation-targets" "^7.20.7"
+ "@babel/helper-module-transforms" "^7.20.7"
+ "@babel/helpers" "^7.20.7"
+ "@babel/parser" "^7.20.7"
+ "@babel/template" "^7.20.7"
+ "@babel/traverse" "^7.20.7"
+ "@babel/types" "^7.20.7"
+ convert-source-map "^1.7.0"
+ debug "^4.1.0"
+ gensync "^1.0.0-beta.2"
+ json5 "^2.2.1"
+ semver "^6.3.0"
+
"@babel/generator@^7.12.1", "@babel/generator@^7.15.0":
version "7.15.0"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.0.tgz#a7d0c172e0d814974bad5aa77ace543b97917f15"
@@ -147,6 +180,15 @@
jsesc "^2.5.1"
source-map "^0.5.0"
+"@babel/generator@^7.20.7", "@babel/generator@^7.7.2":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.7.tgz#f8ef57c8242665c5929fe2e8d82ba75460187b4a"
+ integrity sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==
+ dependencies:
+ "@babel/types" "^7.20.7"
+ "@jridgewell/gen-mapping" "^0.3.2"
+ jsesc "^2.5.1"
+
"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61"
@@ -182,6 +224,17 @@
browserslist "^4.17.5"
semver "^6.3.0"
+"@babel/helper-compilation-targets@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz#a6cd33e93629f5eb473b021aac05df62c4cd09bb"
+ integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==
+ dependencies:
+ "@babel/compat-data" "^7.20.5"
+ "@babel/helper-validator-option" "^7.18.6"
+ browserslist "^4.21.3"
+ lru-cache "^5.1.1"
+ semver "^6.3.0"
+
"@babel/helper-create-class-features-plugin@^7.12.1", "@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.15.0":
version "7.15.0"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.0.tgz#c9a137a4d137b2d0e2c649acf536d7ba1a76c0f7"
@@ -223,6 +276,11 @@
dependencies:
"@babel/types" "^7.16.7"
+"@babel/helper-environment-visitor@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"
+ integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
+
"@babel/helper-explode-assignable-expression@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz#8aa72e708205c7bb643e45c73b4386cdf2a1f645"
@@ -248,6 +306,14 @@
"@babel/template" "^7.16.7"
"@babel/types" "^7.16.7"
+"@babel/helper-function-name@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c"
+ integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==
+ dependencies:
+ "@babel/template" "^7.18.10"
+ "@babel/types" "^7.19.0"
+
"@babel/helper-get-function-arity@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815"
@@ -276,6 +342,13 @@
dependencies:
"@babel/types" "^7.16.7"
+"@babel/helper-hoist-variables@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678"
+ integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
"@babel/helper-member-expression-to-functions@^7.15.0":
version "7.15.0"
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz#0ddaf5299c8179f27f37327936553e9bba60990b"
@@ -297,6 +370,13 @@
dependencies:
"@babel/types" "^7.16.7"
+"@babel/helper-module-imports@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e"
+ integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.14.5", "@babel/helper-module-transforms@^7.15.0":
version "7.15.0"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz#679275581ea056373eddbe360e1419ef23783b08"
@@ -325,6 +405,20 @@
"@babel/traverse" "^7.17.3"
"@babel/types" "^7.17.0"
+"@babel/helper-module-transforms@^7.20.7":
+ version "7.20.11"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz#df4c7af713c557938c50ea3ad0117a7944b2f1b0"
+ integrity sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==
+ dependencies:
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-module-imports" "^7.18.6"
+ "@babel/helper-simple-access" "^7.20.2"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ "@babel/helper-validator-identifier" "^7.19.1"
+ "@babel/template" "^7.20.7"
+ "@babel/traverse" "^7.20.10"
+ "@babel/types" "^7.20.7"
+
"@babel/helper-optimise-call-expression@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz#f27395a8619e0665b3f0364cddb41c25d71b499c"
@@ -337,6 +431,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9"
integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==
+"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.19.0":
+ version "7.20.2"
+ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629"
+ integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==
+
"@babel/helper-remap-async-to-generator@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz#51439c913612958f54a987a4ffc9ee587a2045d6"
@@ -370,6 +469,13 @@
dependencies:
"@babel/types" "^7.17.0"
+"@babel/helper-simple-access@^7.20.2":
+ version "7.20.2"
+ resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9"
+ integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==
+ dependencies:
+ "@babel/types" "^7.20.2"
+
"@babel/helper-skip-transparent-expression-wrappers@^7.12.1", "@babel/helper-skip-transparent-expression-wrappers@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz#96f486ac050ca9f44b009fbe5b7d394cab3a0ee4"
@@ -391,6 +497,18 @@
dependencies:
"@babel/types" "^7.16.7"
+"@babel/helper-split-export-declaration@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075"
+ integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-string-parser@^7.19.4":
+ version "7.19.4"
+ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63"
+ integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==
+
"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9":
version "7.14.9"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48"
@@ -401,6 +519,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad"
integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==
+"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1":
+ version "7.19.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
+ integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
+
"@babel/helper-validator-option@^7.12.1", "@babel/helper-validator-option@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3"
@@ -411,6 +534,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23"
integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==
+"@babel/helper-validator-option@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
+ integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==
+
"@babel/helper-wrap-function@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz#5919d115bf0fe328b8a5d63bcb610f51601f2bff"
@@ -439,6 +567,15 @@
"@babel/traverse" "^7.17.3"
"@babel/types" "^7.17.0"
+"@babel/helpers@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.7.tgz#04502ff0feecc9f20ecfaad120a18f011a8e6dce"
+ integrity sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==
+ dependencies:
+ "@babel/template" "^7.20.7"
+ "@babel/traverse" "^7.20.7"
+ "@babel/types" "^7.20.7"
+
"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9"
@@ -457,11 +594,25 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
+"@babel/highlight@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf"
+ integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.18.6"
+ chalk "^2.0.0"
+ js-tokens "^4.0.0"
+
"@babel/parser@^7.1.0", "@babel/parser@^7.12.3", "@babel/parser@^7.14.5", "@babel/parser@^7.15.0", "@babel/parser@^7.7.0":
version "7.15.3"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.3.tgz#3416d9bea748052cfcb63dbcc27368105b1ed862"
integrity sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==
+"@babel/parser@^7.14.7", "@babel/parser@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.7.tgz#66fe23b3c8569220817d5feb8b9dcdc95bb4f71b"
+ integrity sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==
+
"@babel/parser@^7.16.7", "@babel/parser@^7.17.3", "@babel/parser@^7.17.8":
version "7.17.8"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.8.tgz#2817fb9d885dd8132ea0f8eb615a6388cca1c240"
@@ -723,6 +874,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
+"@babel/plugin-syntax-jsx@^7.7.2":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0"
+ integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699"
@@ -786,6 +944,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
+"@babel/plugin-syntax-typescript@^7.7.2":
+ version "7.20.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz#4e9a0cfc769c85689b77a2e642d24e9f697fc8c7"
+ integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.19.0"
+
"@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz#f7187d9588a768dd080bf4c9ffe117ea62f7862a"
@@ -1376,6 +1541,15 @@
"@babel/parser" "^7.16.7"
"@babel/types" "^7.16.7"
+"@babel/template@^7.18.10", "@babel/template@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8"
+ integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==
+ dependencies:
+ "@babel/code-frame" "^7.18.6"
+ "@babel/parser" "^7.20.7"
+ "@babel/types" "^7.20.7"
+
"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.15.0", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0":
version "7.15.0"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.0.tgz#4cca838fd1b2a03283c1f38e141f639d60b3fc98"
@@ -1407,6 +1581,22 @@
debug "^4.1.0"
globals "^11.1.0"
+"@babel/traverse@^7.20.10", "@babel/traverse@^7.20.7", "@babel/traverse@^7.7.2":
+ version "7.20.10"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.10.tgz#2bf98239597fcec12f842756f186a9dde6d09230"
+ integrity sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg==
+ dependencies:
+ "@babel/code-frame" "^7.18.6"
+ "@babel/generator" "^7.20.7"
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-function-name" "^7.19.0"
+ "@babel/helper-hoist-variables" "^7.18.6"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ "@babel/parser" "^7.20.7"
+ "@babel/types" "^7.20.7"
+ debug "^4.1.0"
+ globals "^11.1.0"
+
"@babel/types@7.15.0", "@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.6", "@babel/types@^7.14.5", "@babel/types@^7.14.8", "@babel/types@^7.14.9", "@babel/types@^7.15.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
version "7.15.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd"
@@ -1423,6 +1613,15 @@
"@babel/helper-validator-identifier" "^7.16.7"
to-fast-properties "^2.0.0"
+"@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.2", "@babel/types@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.7.tgz#54ec75e252318423fc07fb644dc6a58a64c09b7f"
+ integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==
+ dependencies:
+ "@babel/helper-string-parser" "^7.19.4"
+ "@babel/helper-validator-identifier" "^7.19.1"
+ to-fast-properties "^2.0.0"
+
"@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"
@@ -1483,22 +1682,7 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
-"@ethersproject/abi@5.5.0":
- version "5.5.0"
- resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.5.0.tgz#fb52820e22e50b854ff15ce1647cc508d6660613"
- integrity sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w==
- dependencies:
- "@ethersproject/address" "^5.5.0"
- "@ethersproject/bignumber" "^5.5.0"
- "@ethersproject/bytes" "^5.5.0"
- "@ethersproject/constants" "^5.5.0"
- "@ethersproject/hash" "^5.5.0"
- "@ethersproject/keccak256" "^5.5.0"
- "@ethersproject/logger" "^5.5.0"
- "@ethersproject/properties" "^5.5.0"
- "@ethersproject/strings" "^5.5.0"
-
-"@ethersproject/abi@5.6.0", "@ethersproject/abi@^5.0.1", "@ethersproject/abi@^5.6.0":
+"@ethersproject/abi@5.5.0", "@ethersproject/abi@5.6.0", "@ethersproject/abi@5.6.3", "@ethersproject/abi@^5.0.1", "@ethersproject/abi@^5.6.0":
version "5.6.0"
resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.0.tgz#ea07cbc1eec2374d32485679c12408005895e9f3"
integrity sha512-AhVByTwdXCc2YQ20v300w6KVHle9g2OFc28ZAFCPnJyEpkv1xKXjZcSTgWOlv1i+0dqlgF8RCF2Rn2KC1t+1Vg==
@@ -1513,36 +1697,6 @@
"@ethersproject/properties" "^5.6.0"
"@ethersproject/strings" "^5.6.0"
-"@ethersproject/abi@5.6.3":
- version "5.6.3"
- resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.3.tgz#2d643544abadf6e6b63150508af43475985c23db"
- integrity sha512-CxKTdoZY4zDJLWXG6HzNH6znWK0M79WzzxHegDoecE3+K32pzfHOzuXg2/oGSTecZynFgpkjYXNPOqXVJlqClw==
- dependencies:
- "@ethersproject/address" "^5.6.1"
- "@ethersproject/bignumber" "^5.6.2"
- "@ethersproject/bytes" "^5.6.1"
- "@ethersproject/constants" "^5.6.1"
- "@ethersproject/hash" "^5.6.1"
- "@ethersproject/keccak256" "^5.6.1"
- "@ethersproject/logger" "^5.6.0"
- "@ethersproject/properties" "^5.6.0"
- "@ethersproject/strings" "^5.6.1"
-
-"@ethersproject/abi@^5.5.0", "@ethersproject/abi@^5.6.3":
- version "5.6.4"
- resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.4.tgz#f6e01b6ed391a505932698ecc0d9e7a99ee60362"
- integrity sha512-TTeZUlCeIHG6527/2goZA6gW5F8Emoc7MrZDC7hhP84aRGvW3TEdTnZR08Ls88YXM1m2SuK42Osw/jSi3uO8gg==
- dependencies:
- "@ethersproject/address" "^5.6.1"
- "@ethersproject/bignumber" "^5.6.2"
- "@ethersproject/bytes" "^5.6.1"
- "@ethersproject/constants" "^5.6.1"
- "@ethersproject/hash" "^5.6.1"
- "@ethersproject/keccak256" "^5.6.1"
- "@ethersproject/logger" "^5.6.0"
- "@ethersproject/properties" "^5.6.0"
- "@ethersproject/strings" "^5.6.1"
-
"@ethersproject/abstract-provider@5.5.1", "@ethersproject/abstract-provider@^5.5.0":
version "5.5.1"
resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz#2f1f6e8a3ab7d378d8ad0b5718460f85649710c5"
@@ -1769,23 +1923,7 @@
dependencies:
"@ethersproject/bignumber" "^5.6.2"
-"@ethersproject/contracts@5.5.0":
- version "5.5.0"
- resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.5.0.tgz#b735260d4bd61283a670a82d5275e2a38892c197"
- integrity sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg==
- dependencies:
- "@ethersproject/abi" "^5.5.0"
- "@ethersproject/abstract-provider" "^5.5.0"
- "@ethersproject/abstract-signer" "^5.5.0"
- "@ethersproject/address" "^5.5.0"
- "@ethersproject/bignumber" "^5.5.0"
- "@ethersproject/bytes" "^5.5.0"
- "@ethersproject/constants" "^5.5.0"
- "@ethersproject/logger" "^5.5.0"
- "@ethersproject/properties" "^5.5.0"
- "@ethersproject/transactions" "^5.5.0"
-
-"@ethersproject/contracts@5.6.0":
+"@ethersproject/contracts@5.5.0", "@ethersproject/contracts@5.6.0", "@ethersproject/contracts@5.6.2":
version "5.6.0"
resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.6.0.tgz#60f2cfc7addd99a865c6c8cfbbcec76297386067"
integrity sha512-74Ge7iqTDom0NX+mux8KbRUeJgu1eHZ3iv6utv++sLJG80FVuU9HnHeKVPfjd9s3woFhaFoQGf3B3iH/FrQmgw==
@@ -1801,22 +1939,6 @@
"@ethersproject/properties" "^5.6.0"
"@ethersproject/transactions" "^5.6.0"
-"@ethersproject/contracts@5.6.2":
- version "5.6.2"
- resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.6.2.tgz#20b52e69ebc1b74274ff8e3d4e508de971c287bc"
- integrity sha512-hguUA57BIKi6WY0kHvZp6PwPlWF87MCeB4B7Z7AbUpTxfFXFdn/3b0GmjZPagIHS+3yhcBJDnuEfU4Xz+Ks/8g==
- dependencies:
- "@ethersproject/abi" "^5.6.3"
- "@ethersproject/abstract-provider" "^5.6.1"
- "@ethersproject/abstract-signer" "^5.6.2"
- "@ethersproject/address" "^5.6.1"
- "@ethersproject/bignumber" "^5.6.2"
- "@ethersproject/bytes" "^5.6.1"
- "@ethersproject/constants" "^5.6.1"
- "@ethersproject/logger" "^5.6.0"
- "@ethersproject/properties" "^5.6.0"
- "@ethersproject/transactions" "^5.6.2"
-
"@ethersproject/hash@5.5.0", "@ethersproject/hash@^5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.5.0.tgz#7cee76d08f88d1873574c849e0207dcb32380cc9"
@@ -2759,6 +2881,18 @@
jest-util "^26.6.2"
slash "^3.0.0"
+"@jest/console@^29.3.1":
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.3.1.tgz#3e3f876e4e47616ea3b1464b9fbda981872e9583"
+ integrity sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==
+ dependencies:
+ "@jest/types" "^29.3.1"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ jest-message-util "^29.3.1"
+ jest-util "^29.3.1"
+ slash "^3.0.0"
+
"@jest/core@^26.6.0", "@jest/core@^26.6.3":
version "26.6.3"
resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.6.3.tgz#7639fcb3833d748a4656ada54bde193051e45fad"
@@ -2793,6 +2927,40 @@
slash "^3.0.0"
strip-ansi "^6.0.0"
+"@jest/core@^29.3.1":
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.3.1.tgz#bff00f413ff0128f4debec1099ba7dcd649774a1"
+ integrity sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==
+ dependencies:
+ "@jest/console" "^29.3.1"
+ "@jest/reporters" "^29.3.1"
+ "@jest/test-result" "^29.3.1"
+ "@jest/transform" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ "@types/node" "*"
+ ansi-escapes "^4.2.1"
+ chalk "^4.0.0"
+ ci-info "^3.2.0"
+ exit "^0.1.2"
+ graceful-fs "^4.2.9"
+ jest-changed-files "^29.2.0"
+ jest-config "^29.3.1"
+ jest-haste-map "^29.3.1"
+ jest-message-util "^29.3.1"
+ jest-regex-util "^29.2.0"
+ jest-resolve "^29.3.1"
+ jest-resolve-dependencies "^29.3.1"
+ jest-runner "^29.3.1"
+ jest-runtime "^29.3.1"
+ jest-snapshot "^29.3.1"
+ jest-util "^29.3.1"
+ jest-validate "^29.3.1"
+ jest-watcher "^29.3.1"
+ micromatch "^4.0.4"
+ pretty-format "^29.3.1"
+ slash "^3.0.0"
+ strip-ansi "^6.0.0"
+
"@jest/environment@^26.6.0", "@jest/environment@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.2.tgz#ba364cc72e221e79cc8f0a99555bf5d7577cf92c"
@@ -2803,6 +2971,31 @@
"@types/node" "*"
jest-mock "^26.6.2"
+"@jest/environment@^29.3.1":
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.3.1.tgz#eb039f726d5fcd14698acd072ac6576d41cfcaa6"
+ integrity sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==
+ dependencies:
+ "@jest/fake-timers" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ "@types/node" "*"
+ jest-mock "^29.3.1"
+
+"@jest/expect-utils@^29.3.1":
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.3.1.tgz#531f737039e9b9e27c42449798acb5bba01935b6"
+ integrity sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==
+ dependencies:
+ jest-get-type "^29.2.0"
+
+"@jest/expect@^29.3.1":
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.3.1.tgz#456385b62894349c1d196f2d183e3716d4c6a6cd"
+ integrity sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==
+ dependencies:
+ expect "^29.3.1"
+ jest-snapshot "^29.3.1"
+
"@jest/fake-timers@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad"
@@ -2815,6 +3008,18 @@
jest-mock "^26.6.2"
jest-util "^26.6.2"
+"@jest/fake-timers@^29.3.1":
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.3.1.tgz#b140625095b60a44de820876d4c14da1aa963f67"
+ integrity sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==
+ dependencies:
+ "@jest/types" "^29.3.1"
+ "@sinonjs/fake-timers" "^9.1.2"
+ "@types/node" "*"
+ jest-message-util "^29.3.1"
+ jest-mock "^29.3.1"
+ jest-util "^29.3.1"
+
"@jest/globals@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.2.tgz#5b613b78a1aa2655ae908eba638cc96a20df720a"
@@ -2824,6 +3029,16 @@
"@jest/types" "^26.6.2"
expect "^26.6.2"
+"@jest/globals@^29.3.1":
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.3.1.tgz#92be078228e82d629df40c3656d45328f134a0c6"
+ integrity sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==
+ dependencies:
+ "@jest/environment" "^29.3.1"
+ "@jest/expect" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ jest-mock "^29.3.1"
+
"@jest/reporters@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.6.2.tgz#1f518b99637a5f18307bd3ecf9275f6882a667f6"
@@ -2856,6 +3071,43 @@
optionalDependencies:
node-notifier "^8.0.0"
+"@jest/reporters@^29.3.1":
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.3.1.tgz#9a6d78c109608e677c25ddb34f907b90e07b4310"
+ integrity sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==
+ dependencies:
+ "@bcoe/v8-coverage" "^0.2.3"
+ "@jest/console" "^29.3.1"
+ "@jest/test-result" "^29.3.1"
+ "@jest/transform" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ "@jridgewell/trace-mapping" "^0.3.15"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ collect-v8-coverage "^1.0.0"
+ exit "^0.1.2"
+ glob "^7.1.3"
+ graceful-fs "^4.2.9"
+ istanbul-lib-coverage "^3.0.0"
+ istanbul-lib-instrument "^5.1.0"
+ istanbul-lib-report "^3.0.0"
+ istanbul-lib-source-maps "^4.0.0"
+ istanbul-reports "^3.1.3"
+ jest-message-util "^29.3.1"
+ jest-util "^29.3.1"
+ jest-worker "^29.3.1"
+ slash "^3.0.0"
+ string-length "^4.0.1"
+ strip-ansi "^6.0.0"
+ v8-to-istanbul "^9.0.1"
+
+"@jest/schemas@^29.0.0":
+ version "29.0.0"
+ resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.0.0.tgz#5f47f5994dd4ef067fb7b4188ceac45f77fe952a"
+ integrity sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==
+ dependencies:
+ "@sinclair/typebox" "^0.24.1"
+
"@jest/source-map@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535"
@@ -2865,6 +3117,15 @@
graceful-fs "^4.2.4"
source-map "^0.6.0"
+"@jest/source-map@^29.2.0":
+ version "29.2.0"
+ resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.2.0.tgz#ab3420c46d42508dcc3dc1c6deee0b613c235744"
+ integrity sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==
+ dependencies:
+ "@jridgewell/trace-mapping" "^0.3.15"
+ callsites "^3.0.0"
+ graceful-fs "^4.2.9"
+
"@jest/test-result@^26.6.0", "@jest/test-result@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18"
@@ -2875,6 +3136,16 @@
"@types/istanbul-lib-coverage" "^2.0.0"
collect-v8-coverage "^1.0.0"
+"@jest/test-result@^29.3.1":
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.3.1.tgz#92cd5099aa94be947560a24610aa76606de78f50"
+ integrity sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==
+ dependencies:
+ "@jest/console" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ "@types/istanbul-lib-coverage" "^2.0.0"
+ collect-v8-coverage "^1.0.0"
+
"@jest/test-sequencer@^26.6.3":
version "26.6.3"
resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz#98e8a45100863886d074205e8ffdc5a7eb582b17"
@@ -2886,6 +3157,16 @@
jest-runner "^26.6.3"
jest-runtime "^26.6.3"
+"@jest/test-sequencer@^29.3.1":
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz#fa24b3b050f7a59d48f7ef9e0b782ab65123090d"
+ integrity sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==
+ dependencies:
+ "@jest/test-result" "^29.3.1"
+ graceful-fs "^4.2.9"
+ jest-haste-map "^29.3.1"
+ slash "^3.0.0"
+
"@jest/transform@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b"
@@ -2907,6 +3188,27 @@
source-map "^0.6.1"
write-file-atomic "^3.0.0"
+"@jest/transform@^29.3.1":
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.3.1.tgz#1e6bd3da4af50b5c82a539b7b1f3770568d6e36d"
+ integrity sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==
+ dependencies:
+ "@babel/core" "^7.11.6"
+ "@jest/types" "^29.3.1"
+ "@jridgewell/trace-mapping" "^0.3.15"
+ babel-plugin-istanbul "^6.1.1"
+ chalk "^4.0.0"
+ convert-source-map "^2.0.0"
+ fast-json-stable-stringify "^2.1.0"
+ graceful-fs "^4.2.9"
+ jest-haste-map "^29.3.1"
+ jest-regex-util "^29.2.0"
+ jest-util "^29.3.1"
+ micromatch "^4.0.4"
+ pirates "^4.0.4"
+ slash "^3.0.0"
+ write-file-atomic "^4.0.1"
+
"@jest/types@^26.6.0", "@jest/types@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e"
@@ -2929,11 +3231,47 @@
"@types/yargs" "^16.0.0"
chalk "^4.0.0"
+"@jest/types@^29.3.1":
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.3.1.tgz#7c5a80777cb13e703aeec6788d044150341147e3"
+ integrity sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==
+ dependencies:
+ "@jest/schemas" "^29.0.0"
+ "@types/istanbul-lib-coverage" "^2.0.0"
+ "@types/istanbul-reports" "^3.0.0"
+ "@types/node" "*"
+ "@types/yargs" "^17.0.8"
+ chalk "^4.0.0"
+
+"@jridgewell/gen-mapping@^0.3.2":
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
+ integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
+ dependencies:
+ "@jridgewell/set-array" "^1.0.1"
+ "@jridgewell/sourcemap-codec" "^1.4.10"
+ "@jridgewell/trace-mapping" "^0.3.9"
+
+"@jridgewell/resolve-uri@3.1.0":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
+ integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
+
"@jridgewell/resolve-uri@^3.0.3":
version "3.0.5"
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c"
integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==
+"@jridgewell/set-array@^1.0.1":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
+ integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
+
+"@jridgewell/sourcemap-codec@1.4.14":
+ version "1.4.14"
+ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
+ integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
+
"@jridgewell/sourcemap-codec@^1.4.10":
version "1.4.11"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec"
@@ -2947,6 +3285,14 @@
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
+"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.9":
+ version "0.3.17"
+ resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985"
+ integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==
+ dependencies:
+ "@jridgewell/resolve-uri" "3.1.0"
+ "@jridgewell/sourcemap-codec" "1.4.14"
+
"@metamask/detect-provider@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@metamask/detect-provider/-/detect-provider-1.2.0.tgz#3667a7531f2a682e3c3a43eaf3a1958bdb42a696"
@@ -3269,6 +3615,11 @@
dependencies:
"@sentry/cli" "^1.70.1"
+"@sinclair/typebox@^0.24.1":
+ version "0.24.51"
+ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f"
+ integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==
+
"@sinonjs/commons@^1.7.0":
version "1.8.3"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d"
@@ -3283,6 +3634,13 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
+"@sinonjs/fake-timers@^9.1.2":
+ version "9.1.2"
+ resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c"
+ integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==
+ dependencies:
+ "@sinonjs/commons" "^1.7.0"
+
"@surma/rollup-plugin-off-main-thread@^1.1.1":
version "1.4.2"
resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz#e6786b6af5799f82f7ab3a82e53f6182d2b91a58"
@@ -3467,6 +3825,17 @@
"@types/babel__template" "*"
"@types/babel__traverse" "*"
+"@types/babel__core@^7.1.14":
+ version "7.1.20"
+ resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.20.tgz#e168cdd612c92a2d335029ed62ac94c95b362359"
+ integrity sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==
+ dependencies:
+ "@babel/parser" "^7.1.0"
+ "@babel/types" "^7.0.0"
+ "@types/babel__generator" "*"
+ "@types/babel__template" "*"
+ "@types/babel__traverse" "*"
+
"@types/babel__generator@*":
version "7.6.3"
resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.3.tgz#f456b4b2ce79137f768aa130d2423d2f0ccfaba5"
@@ -3538,7 +3907,7 @@
"@types/minimatch" "*"
"@types/node" "*"
-"@types/graceful-fs@^4.1.2":
+"@types/graceful-fs@^4.1.2", "@types/graceful-fs@^4.1.3":
version "4.1.5"
resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15"
integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==
@@ -3585,13 +3954,13 @@
jest-diff "^27.0.0"
pretty-format "^27.0.0"
-"@types/jest@^26.0.15":
- version "26.0.24"
- resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a"
- integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==
+"@types/jest@^29.2.5":
+ version "29.2.5"
+ resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.2.5.tgz#c27f41a9d6253f288d1910d3c5f09484a56b73c0"
+ integrity sha512-H2cSxkKgVmqNHXP7TC2L/WUorrZu8ZigyRywfVzv6EyBlxj39n4C00hjXYQWsbwqgElaj/CiAeSRmk5GoaKTgw==
dependencies:
- jest-diff "^26.0.0"
- pretty-format "^26.0.0"
+ expect "^29.0.0"
+ pretty-format "^29.0.0"
"@types/json-schema@*", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.7", "@types/json-schema@^7.0.8":
version "7.0.9"
@@ -3655,6 +4024,11 @@
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17"
integrity sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==
+"@types/prettier@^2.1.5":
+ version "2.7.2"
+ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0"
+ integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==
+
"@types/prop-types@*":
version "15.7.4"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
@@ -3803,6 +4177,13 @@
dependencies:
"@types/yargs-parser" "*"
+"@types/yargs@^17.0.8":
+ version "17.0.19"
+ resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.19.tgz#8dbecdc9ab48bee0cb74f6e3327de3fa0d0c98ae"
+ integrity sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ==
+ dependencies:
+ "@types/yargs-parser" "*"
+
"@types/zen-observable@0.8.3":
version "0.8.3"
resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.3.tgz#781d360c282436494b32fe7d9f7f8e64b3118aa3"
@@ -4592,6 +4973,11 @@ ansi-regex@^5.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
+ansi-regex@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+ integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+
ansi-styles@^3.2.0, ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
@@ -4965,6 +5351,19 @@ babel-jest@^26.6.0, babel-jest@^26.6.3:
graceful-fs "^4.2.4"
slash "^3.0.0"
+babel-jest@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.3.1.tgz#05c83e0d128cd48c453eea851482a38782249f44"
+ integrity sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==
+ dependencies:
+ "@jest/transform" "^29.3.1"
+ "@types/babel__core" "^7.1.14"
+ babel-plugin-istanbul "^6.1.1"
+ babel-preset-jest "^29.2.0"
+ chalk "^4.0.0"
+ graceful-fs "^4.2.9"
+ slash "^3.0.0"
+
babel-loader@8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3"
@@ -4994,6 +5393,17 @@ babel-plugin-istanbul@^6.0.0:
istanbul-lib-instrument "^4.0.0"
test-exclude "^6.0.0"
+babel-plugin-istanbul@^6.1.1:
+ version "6.1.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73"
+ integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.0.0"
+ "@istanbuljs/load-nyc-config" "^1.0.0"
+ "@istanbuljs/schema" "^0.1.2"
+ istanbul-lib-instrument "^5.0.4"
+ test-exclude "^6.0.0"
+
babel-plugin-jest-hoist@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d"
@@ -5004,6 +5414,16 @@ babel-plugin-jest-hoist@^26.6.2:
"@types/babel__core" "^7.0.0"
"@types/babel__traverse" "^7.0.6"
+babel-plugin-jest-hoist@^29.2.0:
+ version "29.2.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz#23ee99c37390a98cfddf3ef4a78674180d823094"
+ integrity sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==
+ dependencies:
+ "@babel/template" "^7.3.3"
+ "@babel/types" "^7.3.3"
+ "@types/babel__core" "^7.1.14"
+ "@types/babel__traverse" "^7.0.6"
+
babel-plugin-macros@2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138"
@@ -5101,6 +5521,14 @@ babel-preset-jest@^26.6.2:
babel-plugin-jest-hoist "^26.6.2"
babel-preset-current-node-syntax "^1.0.0"
+babel-preset-jest@^29.2.0:
+ version "29.2.0"
+ resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz#3048bea3a1af222e3505e4a767a974c95a7620dc"
+ integrity sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==
+ dependencies:
+ babel-plugin-jest-hoist "^29.2.0"
+ babel-preset-current-node-syntax "^1.0.0"
+
babel-preset-react-app@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-10.0.0.tgz#689b60edc705f8a70ce87f47ab0e560a317d7045"
@@ -5477,6 +5905,23 @@ browserslist@^4.17.5:
node-releases "^2.0.2"
picocolors "^1.0.0"
+browserslist@^4.21.3:
+ version "4.21.4"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987"
+ integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==
+ dependencies:
+ caniuse-lite "^1.0.30001400"
+ electron-to-chromium "^1.4.251"
+ node-releases "^2.0.6"
+ update-browserslist-db "^1.0.9"
+
+bs-logger@0.x:
+ version "0.2.6"
+ resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8"
+ integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==
+ dependencies:
+ fast-json-stable-stringify "2.x"
+
bs58@^4.0.0, bs58@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a"
@@ -5725,6 +6170,11 @@ caniuse-lite@^1.0.30001317:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001319.tgz#eb4da4eb3ecdd409f7ba1907820061d56096e88f"
integrity sha512-xjlIAFHucBRSMUo1kb5D4LYgcN1M45qdKP++lhqowDpwJwGkpIRTt5qQqnhxjj1vHcI7nrJxWhCC1ATrCEBTcw==
+caniuse-lite@^1.0.30001400:
+ version "1.0.30001441"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz#987437b266260b640a23cd18fbddb509d7f69f3e"
+ integrity sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==
+
capture-exit@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4"
@@ -5838,6 +6288,11 @@ ci-info@^2.0.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
+ci-info@^3.2.0:
+ version "3.7.1"
+ resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.7.1.tgz#708a6cdae38915d597afdf3b145f2f8e1ff55f3f"
+ integrity sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==
+
cids@~0.7.0, cids@~0.7.1:
version "0.7.5"
resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2"
@@ -5873,6 +6328,11 @@ cjs-module-lexer@^0.6.0:
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz#4186fcca0eae175970aee870b9fe2d6cf8d5655f"
integrity sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==
+cjs-module-lexer@^1.0.0:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40"
+ integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==
+
class-is@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825"
@@ -5940,6 +6400,15 @@ cliui@^6.0.0:
strip-ansi "^6.0.0"
wrap-ansi "^6.2.0"
+cliui@^8.0.1:
+ version "8.0.1"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
+ integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
+ dependencies:
+ string-width "^4.2.0"
+ strip-ansi "^6.0.1"
+ wrap-ansi "^7.0.0"
+
clone@^1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
@@ -6199,6 +6668,11 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
dependencies:
safe-buffer "~5.1.1"
+convert-source-map@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a"
+ integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==
+
cookie-signature@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
@@ -6359,7 +6833,7 @@ cross-fetch@^3.1.4, cross-fetch@^3.1.5:
dependencies:
node-fetch "2.6.7"
-cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.2:
+cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
@@ -6910,6 +7384,11 @@ diff-sequences@^27.0.6:
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723"
integrity sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==
+diff-sequences@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.3.1.tgz#104b5b95fe725932421a9c6e5b4bef84c3f2249e"
+ integrity sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==
+
diffie-hellman@^5.0.0:
version "5.0.3"
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
@@ -7143,6 +7622,11 @@ electron-to-chromium@^1.3.564, electron-to-chromium@^1.3.811:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.826.tgz#dbe356b1546b39d83bcd47e675a9c5f61dadaed2"
integrity sha512-bpLc4QU4B8PYmdO4MSu2ZBTMD8lAaEXRS43C09lB31BvYwuk9UxgBRXbY5OJBw7VuMGcg2MZG5FyTaP9u4PQnw==
+electron-to-chromium@^1.4.251:
+ version "1.4.284"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592"
+ integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==
+
electron-to-chromium@^1.4.84:
version "1.4.88"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.88.tgz#ebe6a2573b563680c7a7bf3a51b9e465c9c501db"
@@ -7161,6 +7645,11 @@ elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4:
minimalistic-assert "^1.0.1"
minimalistic-crypto-utils "^1.0.1"
+emittery@^0.13.1:
+ version "0.13.1"
+ resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad"
+ integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==
+
emittery@^0.7.1:
version "0.7.2"
resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82"
@@ -8116,6 +8605,21 @@ execa@^4.0.0:
signal-exit "^3.0.2"
strip-final-newline "^2.0.0"
+execa@^5.0.0:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
+ integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
+ dependencies:
+ cross-spawn "^7.0.3"
+ get-stream "^6.0.0"
+ human-signals "^2.1.0"
+ is-stream "^2.0.0"
+ merge-stream "^2.0.0"
+ npm-run-path "^4.0.1"
+ onetime "^5.1.2"
+ signal-exit "^3.0.3"
+ strip-final-newline "^2.0.0"
+
exit@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
@@ -8151,6 +8655,17 @@ expect@^26.6.0, expect@^26.6.2:
jest-message-util "^26.6.2"
jest-regex-util "^26.0.0"
+expect@^29.0.0, expect@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/expect/-/expect-29.3.1.tgz#92877aad3f7deefc2e3f6430dd195b92295554a6"
+ integrity sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==
+ dependencies:
+ "@jest/expect-utils" "^29.3.1"
+ jest-get-type "^29.2.0"
+ jest-matcher-utils "^29.3.1"
+ jest-message-util "^29.3.1"
+ jest-util "^29.3.1"
+
explain-error@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/explain-error/-/explain-error-1.0.4.tgz#a793d3ac0cad4c6ab571e9968fbbab6cb2532929"
@@ -8271,7 +8786,7 @@ fast-glob@^3.1.1:
merge2 "^1.3.0"
micromatch "^4.0.4"
-fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0:
+fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
@@ -8637,7 +9152,7 @@ fsevents@^1.2.7:
bindings "^1.5.0"
nan "^2.12.1"
-fsevents@^2.1.2, fsevents@^2.1.3, fsevents@~2.3.2:
+fsevents@^2.1.2, fsevents@^2.1.3, fsevents@^2.3.2, fsevents@~2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
@@ -8671,7 +9186,7 @@ gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2:
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
-get-caller-file@^2.0.1:
+get-caller-file@^2.0.1, get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
@@ -8709,6 +9224,11 @@ get-stream@^5.0.0:
dependencies:
pump "^3.0.0"
+get-stream@^6.0.0:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
+ integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
+
get-value@^2.0.3, get-value@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
@@ -8871,6 +9391,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
+graceful-fs@^4.2.9:
+ version "4.2.10"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
+ integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
+
graphql-tag@^2.12.3:
version "2.12.5"
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.5.tgz#5cff974a67b417747d05c8d9f5f3cb4495d0db8f"
@@ -9265,6 +9790,11 @@ human-signals@^1.1.1:
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
+human-signals@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
+ integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
+
iconv-lite@0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@@ -10084,6 +10614,11 @@ istanbul-lib-coverage@^3.0.0:
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec"
integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==
+istanbul-lib-coverage@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3"
+ integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==
+
istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d"
@@ -10094,6 +10629,17 @@ istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3:
istanbul-lib-coverage "^3.0.0"
semver "^6.3.0"
+istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d"
+ integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==
+ dependencies:
+ "@babel/core" "^7.12.3"
+ "@babel/parser" "^7.14.7"
+ "@istanbuljs/schema" "^0.1.2"
+ istanbul-lib-coverage "^3.2.0"
+ semver "^6.3.0"
+
istanbul-lib-report@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6"
@@ -10120,6 +10666,14 @@ istanbul-reports@^3.0.2:
html-escaper "^2.0.0"
istanbul-lib-report "^3.0.0"
+istanbul-reports@^3.1.3:
+ version "3.1.5"
+ resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae"
+ integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==
+ dependencies:
+ html-escaper "^2.0.0"
+ istanbul-lib-report "^3.0.0"
+
iterable-ndjson@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/iterable-ndjson/-/iterable-ndjson-1.1.0.tgz#36f7e8a5bb04fd087d384f29e44fc4280fc014fc"
@@ -10157,6 +10711,14 @@ jest-changed-files@^26.6.2:
execa "^4.0.0"
throat "^5.0.0"
+jest-changed-files@^29.2.0:
+ version "29.2.0"
+ resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.2.0.tgz#b6598daa9803ea6a4dce7968e20ab380ddbee289"
+ integrity sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==
+ dependencies:
+ execa "^5.0.0"
+ p-limit "^3.1.0"
+
jest-circus@26.6.0:
version "26.6.0"
resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-26.6.0.tgz#7d9647b2e7f921181869faae1f90a2629fd70705"
@@ -10184,6 +10746,31 @@ jest-circus@26.6.0:
stack-utils "^2.0.2"
throat "^5.0.0"
+jest-circus@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.3.1.tgz#177d07c5c0beae8ef2937a67de68f1e17bbf1b4a"
+ integrity sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==
+ dependencies:
+ "@jest/environment" "^29.3.1"
+ "@jest/expect" "^29.3.1"
+ "@jest/test-result" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ co "^4.6.0"
+ dedent "^0.7.0"
+ is-generator-fn "^2.0.0"
+ jest-each "^29.3.1"
+ jest-matcher-utils "^29.3.1"
+ jest-message-util "^29.3.1"
+ jest-runtime "^29.3.1"
+ jest-snapshot "^29.3.1"
+ jest-util "^29.3.1"
+ p-limit "^3.1.0"
+ pretty-format "^29.3.1"
+ slash "^3.0.0"
+ stack-utils "^2.0.3"
+
jest-cli@^26.6.0:
version "26.6.3"
resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.6.3.tgz#43117cfef24bc4cd691a174a8796a532e135e92a"
@@ -10203,6 +10790,24 @@ jest-cli@^26.6.0:
prompts "^2.0.1"
yargs "^15.4.1"
+jest-cli@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.3.1.tgz#e89dff427db3b1df50cea9a393ebd8640790416d"
+ integrity sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==
+ dependencies:
+ "@jest/core" "^29.3.1"
+ "@jest/test-result" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ chalk "^4.0.0"
+ exit "^0.1.2"
+ graceful-fs "^4.2.9"
+ import-local "^3.0.2"
+ jest-config "^29.3.1"
+ jest-util "^29.3.1"
+ jest-validate "^29.3.1"
+ prompts "^2.0.1"
+ yargs "^17.3.1"
+
jest-config@^26.6.3:
version "26.6.3"
resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.6.3.tgz#64f41444eef9eb03dc51d5c53b75c8c71f645349"
@@ -10227,7 +10832,35 @@ jest-config@^26.6.3:
micromatch "^4.0.2"
pretty-format "^26.6.2"
-jest-diff@^26.0.0, jest-diff@^26.6.2:
+jest-config@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.3.1.tgz#0bc3dcb0959ff8662957f1259947aedaefb7f3c6"
+ integrity sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==
+ dependencies:
+ "@babel/core" "^7.11.6"
+ "@jest/test-sequencer" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ babel-jest "^29.3.1"
+ chalk "^4.0.0"
+ ci-info "^3.2.0"
+ deepmerge "^4.2.2"
+ glob "^7.1.3"
+ graceful-fs "^4.2.9"
+ jest-circus "^29.3.1"
+ jest-environment-node "^29.3.1"
+ jest-get-type "^29.2.0"
+ jest-regex-util "^29.2.0"
+ jest-resolve "^29.3.1"
+ jest-runner "^29.3.1"
+ jest-util "^29.3.1"
+ jest-validate "^29.3.1"
+ micromatch "^4.0.4"
+ parse-json "^5.2.0"
+ pretty-format "^29.3.1"
+ slash "^3.0.0"
+ strip-json-comments "^3.1.1"
+
+jest-diff@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394"
integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==
@@ -10247,6 +10880,16 @@ jest-diff@^27.0.0:
jest-get-type "^27.0.6"
pretty-format "^27.1.0"
+jest-diff@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.3.1.tgz#d8215b72fed8f1e647aed2cae6c752a89e757527"
+ integrity sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==
+ dependencies:
+ chalk "^4.0.0"
+ diff-sequences "^29.3.1"
+ jest-get-type "^29.2.0"
+ pretty-format "^29.3.1"
+
jest-docblock@^26.0.0:
version "26.0.0"
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5"
@@ -10254,6 +10897,13 @@ jest-docblock@^26.0.0:
dependencies:
detect-newline "^3.0.0"
+jest-docblock@^29.2.0:
+ version "29.2.0"
+ resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.2.0.tgz#307203e20b637d97cee04809efc1d43afc641e82"
+ integrity sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==
+ dependencies:
+ detect-newline "^3.0.0"
+
jest-each@^26.6.0, jest-each@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.6.2.tgz#02526438a77a67401c8a6382dfe5999952c167cb"
@@ -10265,6 +10915,17 @@ jest-each@^26.6.0, jest-each@^26.6.2:
jest-util "^26.6.2"
pretty-format "^26.6.2"
+jest-each@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.3.1.tgz#bc375c8734f1bb96625d83d1ca03ef508379e132"
+ integrity sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==
+ dependencies:
+ "@jest/types" "^29.3.1"
+ chalk "^4.0.0"
+ jest-get-type "^29.2.0"
+ jest-util "^29.3.1"
+ pretty-format "^29.3.1"
+
jest-environment-jsdom@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz#78d09fe9cf019a357009b9b7e1f101d23bd1da3e"
@@ -10290,6 +10951,18 @@ jest-environment-node@^26.6.2:
jest-mock "^26.6.2"
jest-util "^26.6.2"
+jest-environment-node@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.3.1.tgz#5023b32472b3fba91db5c799a0d5624ad4803e74"
+ integrity sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==
+ dependencies:
+ "@jest/environment" "^29.3.1"
+ "@jest/fake-timers" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ "@types/node" "*"
+ jest-mock "^29.3.1"
+ jest-util "^29.3.1"
+
jest-get-type@^26.3.0:
version "26.3.0"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0"
@@ -10300,6 +10973,11 @@ jest-get-type@^27.0.6:
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.6.tgz#0eb5c7f755854279ce9b68a9f1a4122f69047cfe"
integrity sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==
+jest-get-type@^29.2.0:
+ version "29.2.0"
+ resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408"
+ integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==
+
jest-haste-map@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa"
@@ -10321,6 +10999,25 @@ jest-haste-map@^26.6.2:
optionalDependencies:
fsevents "^2.1.2"
+jest-haste-map@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.3.1.tgz#af83b4347f1dae5ee8c2fb57368dc0bb3e5af843"
+ integrity sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==
+ dependencies:
+ "@jest/types" "^29.3.1"
+ "@types/graceful-fs" "^4.1.3"
+ "@types/node" "*"
+ anymatch "^3.0.3"
+ fb-watchman "^2.0.0"
+ graceful-fs "^4.2.9"
+ jest-regex-util "^29.2.0"
+ jest-util "^29.3.1"
+ jest-worker "^29.3.1"
+ micromatch "^4.0.4"
+ walker "^1.0.8"
+ optionalDependencies:
+ fsevents "^2.3.2"
+
jest-jasmine2@^26.6.3:
version "26.6.3"
resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz#adc3cf915deacb5212c93b9f3547cd12958f2edd"
@@ -10353,6 +11050,14 @@ jest-leak-detector@^26.6.2:
jest-get-type "^26.3.0"
pretty-format "^26.6.2"
+jest-leak-detector@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz#95336d020170671db0ee166b75cd8ef647265518"
+ integrity sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==
+ dependencies:
+ jest-get-type "^29.2.0"
+ pretty-format "^29.3.1"
+
jest-matcher-utils@^26.6.0, jest-matcher-utils@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a"
@@ -10363,6 +11068,16 @@ jest-matcher-utils@^26.6.0, jest-matcher-utils@^26.6.2:
jest-get-type "^26.3.0"
pretty-format "^26.6.2"
+jest-matcher-utils@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz#6e7f53512f80e817dfa148672bd2d5d04914a572"
+ integrity sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==
+ dependencies:
+ chalk "^4.0.0"
+ jest-diff "^29.3.1"
+ jest-get-type "^29.2.0"
+ pretty-format "^29.3.1"
+
jest-message-util@^26.6.0, jest-message-util@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07"
@@ -10378,6 +11093,21 @@ jest-message-util@^26.6.0, jest-message-util@^26.6.2:
slash "^3.0.0"
stack-utils "^2.0.2"
+jest-message-util@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.3.1.tgz#37bc5c468dfe5120712053dd03faf0f053bd6adb"
+ integrity sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==
+ dependencies:
+ "@babel/code-frame" "^7.12.13"
+ "@jest/types" "^29.3.1"
+ "@types/stack-utils" "^2.0.0"
+ chalk "^4.0.0"
+ graceful-fs "^4.2.9"
+ micromatch "^4.0.4"
+ pretty-format "^29.3.1"
+ slash "^3.0.0"
+ stack-utils "^2.0.3"
+
jest-mock@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302"
@@ -10386,6 +11116,15 @@ jest-mock@^26.6.2:
"@jest/types" "^26.6.2"
"@types/node" "*"
+jest-mock@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.3.1.tgz#60287d92e5010979d01f218c6b215b688e0f313e"
+ integrity sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==
+ dependencies:
+ "@jest/types" "^29.3.1"
+ "@types/node" "*"
+ jest-util "^29.3.1"
+
jest-pnp-resolver@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c"
@@ -10396,6 +11135,11 @@ jest-regex-util@^26.0.0:
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28"
integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==
+jest-regex-util@^29.2.0:
+ version "29.2.0"
+ resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.2.0.tgz#82ef3b587e8c303357728d0322d48bbfd2971f7b"
+ integrity sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==
+
jest-resolve-dependencies@^26.6.3:
version "26.6.3"
resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz#6680859ee5d22ee5dcd961fe4871f59f4c784fb6"
@@ -10405,6 +11149,14 @@ jest-resolve-dependencies@^26.6.3:
jest-regex-util "^26.0.0"
jest-snapshot "^26.6.2"
+jest-resolve-dependencies@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz#a6a329708a128e68d67c49f38678a4a4a914c3bf"
+ integrity sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==
+ dependencies:
+ jest-regex-util "^29.2.0"
+ jest-snapshot "^29.3.1"
+
jest-resolve@26.6.0:
version "26.6.0"
resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.0.tgz#070fe7159af87b03e50f52ea5e17ee95bbee40e1"
@@ -10433,6 +11185,21 @@ jest-resolve@^26.6.2:
resolve "^1.18.1"
slash "^3.0.0"
+jest-resolve@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.3.1.tgz#9a4b6b65387a3141e4a40815535c7f196f1a68a7"
+ integrity sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==
+ dependencies:
+ chalk "^4.0.0"
+ graceful-fs "^4.2.9"
+ jest-haste-map "^29.3.1"
+ jest-pnp-resolver "^1.2.2"
+ jest-util "^29.3.1"
+ jest-validate "^29.3.1"
+ resolve "^1.20.0"
+ resolve.exports "^1.1.0"
+ slash "^3.0.0"
+
jest-runner@^26.6.0, jest-runner@^26.6.3:
version "26.6.3"
resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.6.3.tgz#2d1fed3d46e10f233fd1dbd3bfaa3fe8924be159"
@@ -10459,6 +11226,33 @@ jest-runner@^26.6.0, jest-runner@^26.6.3:
source-map-support "^0.5.6"
throat "^5.0.0"
+jest-runner@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.3.1.tgz#a92a879a47dd096fea46bb1517b0a99418ee9e2d"
+ integrity sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==
+ dependencies:
+ "@jest/console" "^29.3.1"
+ "@jest/environment" "^29.3.1"
+ "@jest/test-result" "^29.3.1"
+ "@jest/transform" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ emittery "^0.13.1"
+ graceful-fs "^4.2.9"
+ jest-docblock "^29.2.0"
+ jest-environment-node "^29.3.1"
+ jest-haste-map "^29.3.1"
+ jest-leak-detector "^29.3.1"
+ jest-message-util "^29.3.1"
+ jest-resolve "^29.3.1"
+ jest-runtime "^29.3.1"
+ jest-util "^29.3.1"
+ jest-watcher "^29.3.1"
+ jest-worker "^29.3.1"
+ p-limit "^3.1.0"
+ source-map-support "0.5.13"
+
jest-runtime@^26.6.0, jest-runtime@^26.6.3:
version "26.6.3"
resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.6.3.tgz#4f64efbcfac398331b74b4b3c82d27d401b8fa2b"
@@ -10492,6 +11286,34 @@ jest-runtime@^26.6.0, jest-runtime@^26.6.3:
strip-bom "^4.0.0"
yargs "^15.4.1"
+jest-runtime@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.3.1.tgz#21efccb1a66911d6d8591276a6182f520b86737a"
+ integrity sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==
+ dependencies:
+ "@jest/environment" "^29.3.1"
+ "@jest/fake-timers" "^29.3.1"
+ "@jest/globals" "^29.3.1"
+ "@jest/source-map" "^29.2.0"
+ "@jest/test-result" "^29.3.1"
+ "@jest/transform" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ cjs-module-lexer "^1.0.0"
+ collect-v8-coverage "^1.0.0"
+ glob "^7.1.3"
+ graceful-fs "^4.2.9"
+ jest-haste-map "^29.3.1"
+ jest-message-util "^29.3.1"
+ jest-mock "^29.3.1"
+ jest-regex-util "^29.2.0"
+ jest-resolve "^29.3.1"
+ jest-snapshot "^29.3.1"
+ jest-util "^29.3.1"
+ slash "^3.0.0"
+ strip-bom "^4.0.0"
+
jest-serializer@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1"
@@ -10522,6 +11344,36 @@ jest-snapshot@^26.6.0, jest-snapshot@^26.6.2:
pretty-format "^26.6.2"
semver "^7.3.2"
+jest-snapshot@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.3.1.tgz#17bcef71a453adc059a18a32ccbd594b8cc4e45e"
+ integrity sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==
+ dependencies:
+ "@babel/core" "^7.11.6"
+ "@babel/generator" "^7.7.2"
+ "@babel/plugin-syntax-jsx" "^7.7.2"
+ "@babel/plugin-syntax-typescript" "^7.7.2"
+ "@babel/traverse" "^7.7.2"
+ "@babel/types" "^7.3.3"
+ "@jest/expect-utils" "^29.3.1"
+ "@jest/transform" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ "@types/babel__traverse" "^7.0.6"
+ "@types/prettier" "^2.1.5"
+ babel-preset-current-node-syntax "^1.0.0"
+ chalk "^4.0.0"
+ expect "^29.3.1"
+ graceful-fs "^4.2.9"
+ jest-diff "^29.3.1"
+ jest-get-type "^29.2.0"
+ jest-haste-map "^29.3.1"
+ jest-matcher-utils "^29.3.1"
+ jest-message-util "^29.3.1"
+ jest-util "^29.3.1"
+ natural-compare "^1.4.0"
+ pretty-format "^29.3.1"
+ semver "^7.3.5"
+
jest-util@^26.6.0, jest-util@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1"
@@ -10534,6 +11386,18 @@ jest-util@^26.6.0, jest-util@^26.6.2:
is-ci "^2.0.0"
micromatch "^4.0.2"
+jest-util@^29.0.0, jest-util@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.3.1.tgz#1dda51e378bbcb7e3bc9d8ab651445591ed373e1"
+ integrity sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==
+ dependencies:
+ "@jest/types" "^29.3.1"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ ci-info "^3.2.0"
+ graceful-fs "^4.2.9"
+ picomatch "^2.2.3"
+
jest-validate@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec"
@@ -10546,6 +11410,18 @@ jest-validate@^26.6.2:
leven "^3.1.0"
pretty-format "^26.6.2"
+jest-validate@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.3.1.tgz#d56fefaa2e7d1fde3ecdc973c7f7f8f25eea704a"
+ integrity sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==
+ dependencies:
+ "@jest/types" "^29.3.1"
+ camelcase "^6.2.0"
+ chalk "^4.0.0"
+ jest-get-type "^29.2.0"
+ leven "^3.1.0"
+ pretty-format "^29.3.1"
+
jest-watch-typeahead@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-0.6.1.tgz#45221b86bb6710b7e97baaa1640ae24a07785e63"
@@ -10572,6 +11448,20 @@ jest-watcher@^26.3.0, jest-watcher@^26.6.2:
jest-util "^26.6.2"
string-length "^4.0.1"
+jest-watcher@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.3.1.tgz#3341547e14fe3c0f79f9c3a4c62dbc3fc977fd4a"
+ integrity sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==
+ dependencies:
+ "@jest/test-result" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ "@types/node" "*"
+ ansi-escapes "^4.2.1"
+ chalk "^4.0.0"
+ emittery "^0.13.1"
+ jest-util "^29.3.1"
+ string-length "^4.0.1"
+
jest-worker@27.0.0-next.5:
version "27.0.0-next.5"
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.0-next.5.tgz#5985ee29b12a4e191f4aae4bb73b97971d86ec28"
@@ -10598,6 +11488,16 @@ jest-worker@^26.5.0, jest-worker@^26.6.2:
merge-stream "^2.0.0"
supports-color "^7.0.0"
+jest-worker@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.3.1.tgz#e9462161017a9bb176380d721cab022661da3d6b"
+ integrity sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==
+ dependencies:
+ "@types/node" "*"
+ jest-util "^29.3.1"
+ merge-stream "^2.0.0"
+ supports-color "^8.0.0"
+
jest@26.6.0:
version "26.6.0"
resolved "https://registry.yarnpkg.com/jest/-/jest-26.6.0.tgz#546b25a1d8c888569dbbe93cae131748086a4a25"
@@ -10607,6 +11507,16 @@ jest@26.6.0:
import-local "^3.0.2"
jest-cli "^26.6.0"
+jest@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/jest/-/jest-29.3.1.tgz#c130c0d551ae6b5459b8963747fed392ddbde122"
+ integrity sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==
+ dependencies:
+ "@jest/core" "^29.3.1"
+ "@jest/types" "^29.3.1"
+ import-local "^3.0.2"
+ jest-cli "^29.3.1"
+
jose@^4.5.0:
version "4.8.1"
resolved "https://registry.yarnpkg.com/jose/-/jose-4.8.1.tgz#dc7c2660b115ba29b44880e588c5ac313c158247"
@@ -10784,6 +11694,11 @@ json5@^2.1.2:
dependencies:
minimist "^1.2.5"
+json5@^2.2.1:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
+ integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
+
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
@@ -11166,7 +12081,7 @@ lodash.lowerfirst@^4.3.1:
resolved "https://registry.yarnpkg.com/lodash.lowerfirst/-/lodash.lowerfirst-4.3.1.tgz#de3c7b12e02c6524a0059c2f6cb7c5c52655a13d"
integrity sha1-3jx7EuAsZSSgBZwvbLfFxSZVoT0=
-lodash.memoize@^4.1.2:
+lodash.memoize@4.x, lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
@@ -11367,6 +12282,18 @@ make-dir@^3.0.0, make-dir@^3.0.2:
dependencies:
semver "^6.0.0"
+make-error@1.x:
+ version "1.3.6"
+ resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
+ integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
+
+makeerror@1.0.12:
+ version "1.0.12"
+ resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a"
+ integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==
+ dependencies:
+ tmpl "1.0.5"
+
makeerror@1.0.x:
version "1.0.11"
resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
@@ -12077,6 +13004,11 @@ node-releases@^2.0.2:
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01"
integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==
+node-releases@^2.0.6:
+ version "2.0.8"
+ resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.8.tgz#0f349cdc8fcfa39a92ac0be9bc48b7706292b9ae"
+ integrity sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==
+
nodeify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/nodeify/-/nodeify-1.0.1.tgz#64ab69a7bdbaf03ce107b4f0335c87c0b9e91b1d"
@@ -12134,7 +13066,7 @@ npm-run-path@^2.0.0:
dependencies:
path-key "^2.0.0"
-npm-run-path@^4.0.0:
+npm-run-path@^4.0.0, npm-run-path@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
@@ -12312,7 +13244,7 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
dependencies:
wrappy "1"
-onetime@^5.1.0:
+onetime@^5.1.0, onetime@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
@@ -12441,7 +13373,7 @@ p-limit@^2.0.0, p-limit@^2.2.0:
dependencies:
p-try "^2.0.0"
-p-limit@^3.0.2:
+p-limit@^3.0.2, p-limit@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
@@ -12551,7 +13483,7 @@ parse-json@^4.0.0:
error-ex "^1.3.1"
json-parse-better-errors "^1.0.1"
-parse-json@^5.0.0:
+parse-json@^5.0.0, parse-json@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
@@ -12751,6 +13683,11 @@ pirates@^4.0.1:
dependencies:
node-modules-regexp "^1.0.0"
+pirates@^4.0.4:
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b"
+ integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==
+
pkg-dir@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
@@ -13583,7 +14520,7 @@ pretty-error@^2.1.1:
lodash "^4.17.20"
renderkid "^2.0.4"
-pretty-format@^26.0.0, pretty-format@^26.6.0, pretty-format@^26.6.2:
+pretty-format@^26.6.0, pretty-format@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93"
integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==
@@ -13603,6 +14540,15 @@ pretty-format@^27.0.0, pretty-format@^27.1.0:
ansi-styles "^5.0.0"
react-is "^17.0.1"
+pretty-format@^29.0.0, pretty-format@^29.3.1:
+ version "29.3.1"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.3.1.tgz#1841cac822b02b4da8971dacb03e8a871b4722da"
+ integrity sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==
+ dependencies:
+ "@jest/schemas" "^29.0.0"
+ ansi-styles "^5.0.0"
+ react-is "^18.0.0"
+
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -14009,6 +14955,11 @@ react-is@^16.7.0, react-is@^16.8.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+react-is@^18.0.0:
+ version "18.2.0"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
+ integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
+
react-refresh@0.8.3, react-refresh@^0.8.3:
version "0.8.3"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
@@ -14408,6 +15359,11 @@ resolve-url@^0.2.1:
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
+resolve.exports@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9"
+ integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==
+
resolve@1.18.1:
version "1.18.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130"
@@ -14755,6 +15711,13 @@ semver@7.3.2:
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
+semver@7.x:
+ version "7.3.8"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
+ integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
+ dependencies:
+ lru-cache "^6.0.0"
+
semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
@@ -14924,6 +15887,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
+signal-exit@^3.0.3, signal-exit@^3.0.7:
+ version "3.0.7"
+ resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
+ integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
+
signed-varint@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/signed-varint/-/signed-varint-2.0.1.tgz#50a9989da7c98c2c61dad119bc97470ef8528129"
@@ -15058,6 +16026,14 @@ source-map-resolve@^0.6.0:
atob "^2.1.2"
decode-uri-component "^0.2.0"
+source-map-support@0.5.13:
+ version "0.5.13"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932"
+ integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==
+ dependencies:
+ buffer-from "^1.0.0"
+ source-map "^0.6.0"
+
source-map-support@^0.5.11, source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.19:
version "0.5.19"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
@@ -15210,6 +16186,13 @@ stack-utils@^2.0.2:
dependencies:
escape-string-regexp "^2.0.0"
+stack-utils@^2.0.3:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f"
+ integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==
+ dependencies:
+ escape-string-regexp "^2.0.0"
+
stackframe@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303"
@@ -15344,6 +16327,15 @@ string-width@^4.1.0, string-width@^4.2.0:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.0"
+string-width@^4.2.3:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+ integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+ dependencies:
+ emoji-regex "^8.0.0"
+ is-fullwidth-code-point "^3.0.0"
+ strip-ansi "^6.0.1"
+
string.prototype.matchall@^4.0.5:
version "4.0.5"
resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz#59370644e1db7e4c0c045277690cf7b01203c4da"
@@ -15430,6 +16422,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
dependencies:
ansi-regex "^4.1.0"
+strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
@@ -15851,7 +16850,7 @@ tmp@^0.1.0:
dependencies:
rimraf "^2.6.3"
-tmpl@1.0.x:
+tmpl@1.0.5, tmpl@1.0.x:
version "1.0.5"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==
@@ -15976,6 +16975,20 @@ ts-invariant@^0.9.0:
dependencies:
tslib "^2.1.0"
+ts-jest@^29.0.3:
+ version "29.0.3"
+ resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.0.3.tgz#63ea93c5401ab73595440733cefdba31fcf9cb77"
+ integrity sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==
+ dependencies:
+ bs-logger "0.x"
+ fast-json-stable-stringify "2.x"
+ jest-util "^29.0.0"
+ json5 "^2.2.1"
+ lodash.memoize "4.x"
+ make-error "1.x"
+ semver "7.x"
+ yargs-parser "^21.0.1"
+
ts-pnp@1.2.0, ts-pnp@^1.1.6:
version "1.2.0"
resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92"
@@ -16267,6 +17280,14 @@ upath@^1.1.1, upath@^1.1.2, upath@^1.2.0:
resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
+update-browserslist-db@^1.0.9:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3"
+ integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==
+ dependencies:
+ escalade "^3.1.1"
+ picocolors "^1.0.0"
+
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
@@ -16426,6 +17447,15 @@ v8-to-istanbul@^7.0.0:
convert-source-map "^1.6.0"
source-map "^0.7.3"
+v8-to-istanbul@^9.0.1:
+ version "9.0.1"
+ resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4"
+ integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==
+ dependencies:
+ "@jridgewell/trace-mapping" "^0.3.12"
+ "@types/istanbul-lib-coverage" "^2.0.1"
+ convert-source-map "^1.6.0"
+
validate-npm-package-license@^3.0.1:
version "3.0.4"
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
@@ -16484,6 +17514,13 @@ walker@^1.0.7, walker@~1.0.5:
dependencies:
makeerror "1.0.x"
+walker@^1.0.8:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f"
+ integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==
+ dependencies:
+ makeerror "1.0.12"
+
walletlink@^2.1.6:
version "2.1.9"
resolved "https://registry.yarnpkg.com/walletlink/-/walletlink-2.1.9.tgz#c11c834bf0ff802312505704ff1845de89fbae0c"
@@ -17014,6 +18051,15 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
+wrap-ansi@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
+ integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+ dependencies:
+ ansi-styles "^4.0.0"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
@@ -17029,6 +18075,14 @@ write-file-atomic@^3.0.0:
signal-exit "^3.0.2"
typedarray-to-buffer "^3.1.5"
+write-file-atomic@^4.0.1:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd"
+ integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==
+ dependencies:
+ imurmurhash "^0.1.4"
+ signal-exit "^3.0.7"
+
ws@7.4.6:
version "7.4.6"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
@@ -17102,6 +18156,11 @@ y18n@^4.0.0:
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
+y18n@^5.0.5:
+ version "5.0.8"
+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
+ integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
+
yallist@^3.0.2:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
@@ -17141,6 +18200,11 @@ yargs-parser@^18.1.2:
camelcase "^5.0.0"
decamelize "^1.2.0"
+yargs-parser@^21.0.1, yargs-parser@^21.1.1:
+ version "21.1.1"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
+ integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
+
yargs@^13.2.4, yargs@^13.3.2:
version "13.3.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd"
@@ -17174,6 +18238,19 @@ yargs@^15.4.1:
y18n "^4.0.0"
yargs-parser "^18.1.2"
+yargs@^17.3.1:
+ version "17.6.2"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541"
+ integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==
+ dependencies:
+ cliui "^8.0.1"
+ escalade "^3.1.1"
+ get-caller-file "^2.0.5"
+ require-directory "^2.1.1"
+ string-width "^4.2.3"
+ y18n "^5.0.5"
+ yargs-parser "^21.1.1"
+
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"