diff --git a/.env.example b/.env.example
index ece6795..7f594bd 100644
--- a/.env.example
+++ b/.env.example
@@ -1,2 +1,4 @@
NEXT_PUBLIC_REOWN_PROJECTID=
NEXT_PUBLIC_GNOSIS_RPC=
+# https://thegraph.com/explorer/subgraphs/AAA1vYjxwFHzbt6qKwLHNcDSASyr1J1xVViDH8gTMFMR?view=Query&chain=arbitrum-one
+NEXT_PUBLIC_ALGEBRA_SUBGRAPH=
diff --git a/.eslintrc.json b/.eslintrc.json
index 84e1f88..d9dd64a 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -5,7 +5,7 @@
"plugin:prettier/recommended",
"prettier"
],
- "ignorePatterns": ["**/**/generated.ts"],
+ "ignorePatterns": ["**/generated.ts", "src/hooks/liquidity/gql/*"],
"rules": {
"max-len": [
"warn",
diff --git a/.gitignore b/.gitignore
index 8cd6d95..09e6c75 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,3 +37,6 @@ next-env.d.ts
# wagmi generated
/src/generated.ts
+
+# gql
+/src/hooks/liquidity/gql
diff --git a/codegen.ts b/codegen.ts
new file mode 100644
index 0000000..538db2d
--- /dev/null
+++ b/codegen.ts
@@ -0,0 +1,29 @@
+import { CodegenConfig } from "@graphql-codegen/cli";
+
+const config: CodegenConfig = {
+ overwrite: true,
+ schema: [process.env.NEXT_PUBLIC_ALGEBRA_SUBGRAPH!],
+ documents: ["src/hooks/liquidity/swapr.graphql"],
+ generates: {
+ "./src/hooks/liquidity/gql/gql.ts": {
+ // preset: "client",
+ plugins: [
+ "typescript",
+ "typescript-operations",
+ "typescript-graphql-request",
+ ],
+ config: {
+ strictScalars: true,
+ scalars: {
+ BigDecimal: "string",
+ BigInt: "string",
+ Int8: "string",
+ Bytes: "`0x${string}`",
+ Timestamp: "string",
+ },
+ },
+ },
+ },
+};
+
+export default config;
diff --git a/package.json b/package.json
index 73f1964..f6413cf 100644
--- a/package.json
+++ b/package.json
@@ -4,10 +4,11 @@
"private": true,
"scripts": {
"dev": "yarn generate && next dev",
- "build": "next build",
+ "build": "yarn generate && next build",
"start": "next start",
"lint": "next lint --fix",
- "generate": "wagmi generate"
+ "generate": "wagmi generate && yarn generate:gql",
+ "generate:gql": "dotenv -e .env.local -- graphql-codegen"
},
"dependencies": {
"@cowprotocol/cow-sdk": "^5.10.3",
@@ -17,10 +18,13 @@
"@swapr/sdk": "https://github.com/seer-pm/swapr-sdk#6dea7e63f7e05c84a4374717ee1ad5baca86f7de",
"@tanstack/react-query": "^5.74.4",
"@wagmi/core": "^2.17.3",
+ "@yornaath/batshit": "^0.11.1",
"clsx": "^2.1.1",
"ethers": "5.8.0",
+ "graphql-request": "^7.3.1",
"graphql-tag": "^2.12.6",
"lightweight-charts": "^5.0.8",
+ "micro-memoize": "^4.2.0",
"next": "14.2.28",
"next-themes": "^0.4.6",
"pino-pretty": "^13.0.0",
@@ -33,12 +37,17 @@
"wagmi": "^2.15.6"
},
"devDependencies": {
+ "@graphql-codegen/cli": "^5.0.2",
+ "@graphql-codegen/typescript": "^5.0.2",
+ "@graphql-codegen/typescript-graphql-request": "^6.3.0",
+ "@graphql-codegen/typescript-operations": "^5.0.2",
"@svgr/webpack": "^8.1.0",
"@tailwindcss/postcss": "^4.1.4",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"@wagmi/cli": "^2.3.1",
+ "dotenv-cli": "^10.0.0",
"eslint": "^8",
"eslint-config-next": "14.2.28",
"eslint-config-prettier": "^10.1.2",
diff --git a/src/app/(homepage)/components/AdvancedSection.tsx b/src/app/(homepage)/components/AdvancedSection.tsx
index 26760ee..da7a2bb 100644
--- a/src/app/(homepage)/components/AdvancedSection.tsx
+++ b/src/app/(homepage)/components/AdvancedSection.tsx
@@ -31,7 +31,7 @@ const AdvancedSection: React.FC = () => {
rel="noreferrer noopener"
className="text-klerosUIComponentsPrimaryBlue items-center text-sm"
>
- Check it out
+ Check it out
diff --git a/src/app/(homepage)/components/ParticipateSection/Mint/AmountInput.tsx b/src/app/(homepage)/components/ParticipateSection/Mint/AmountInput.tsx
index 41cbfe1..83fb537 100644
--- a/src/app/(homepage)/components/ParticipateSection/Mint/AmountInput.tsx
+++ b/src/app/(homepage)/components/ParticipateSection/Mint/AmountInput.tsx
@@ -1,34 +1,47 @@
-import { BigNumberField, DropdownSelect } from "@kleros/ui-components-library";
+import { useMemo } from "react";
+
+import { BigNumberField } from "@kleros/ui-components-library";
import clsx from "clsx";
import { parseUnits, formatUnits } from "viem";
-import DAIIcon from "@/assets/svg/dai.svg";
+import LightButton from "@/components/LightButton";
+
+import { formatValue, isUndefined } from "@/utils";
-export enum TokenType {
- sDAI,
- xDAI,
-}
interface IAmountInput {
setAmount: (amount: bigint) => void;
- setSelectedToken: (token: TokenType) => void;
- notEnoughBalance: boolean;
defaultValue?: bigint;
value?: bigint;
+ balance?: bigint;
+ isMerge?: boolean;
}
const AmountInput: React.FC = ({
setAmount,
- setSelectedToken,
- notEnoughBalance,
defaultValue,
value,
+ balance,
+ isMerge = false,
}) => {
+ const notEnoughBalance = useMemo(() => {
+ if (isMerge) return false;
+ if (!isUndefined(value) && !isUndefined(balance) && value > balance)
+ return true;
+ return false;
+ }, [value, balance, isMerge]);
+
+ const handleMaxClick = () => {
+ if (!isUndefined(balance)) {
+ setAmount(balance);
+ }
+ };
+
return (
-
+
{
@@ -44,37 +57,30 @@ const AmountInput: React.FC = ({
value={
typeof value !== "undefined" ? formatUnits(value, 18) : undefined
}
- isDisabled={typeof value !== "undefined"}
- />
- button]:bg-klerosUIComponentsMediumBlue [&>button]:h-11.25 [&>button]:w-fit",
- "[&>button]:border-none [&>button]:focus:shadow-none",
- "[&>button]:rounded-l-none",
- )}
- callback={(item) => {
- setSelectedToken(item.itemValue);
- }}
- defaultSelectedKey={TokenType.sDAI}
- items={[
- {
- text: "sDAI",
- itemValue: TokenType.sDAI,
- id: TokenType.sDAI,
- icon: ,
- },
- {
- text: "xDAI",
- itemValue: TokenType.xDAI,
- id: TokenType.xDAI,
- icon: ,
- },
- ]}
+ isDisabled={isMerge}
/>
{notEnoughBalance ? "Not enough balance." : undefined}
+ {!notEnoughBalance && (
+
+ {!isUndefined(balance)
+ ? `Available: ${formatValue(balance)}`
+ : "Loading..."}
+
+ )}
+ {isMerge ? null : (
+
+ )}
);
};
diff --git a/src/app/(homepage)/components/ParticipateSection/Mint/MergeButton.tsx b/src/app/(homepage)/components/ParticipateSection/Mint/MergeButton.tsx
index 9bd89be..cdb807d 100644
--- a/src/app/(homepage)/components/ParticipateSection/Mint/MergeButton.tsx
+++ b/src/app/(homepage)/components/ParticipateSection/Mint/MergeButton.tsx
@@ -1,151 +1,31 @@
-import React, { useMemo } from "react";
+import React from "react";
import { Button } from "@kleros/ui-components-library";
-import { waitForTransactionReceipt } from "@wagmi/core";
-import { encodeFunctionData, erc20Abi, Address } from "viem";
-import { useConfig, useSendCalls, useCapabilities } from "wagmi";
+import { Address } from "viem";
-import {
- gnosisRouterAddress,
- gnosisRouterAbi,
- sDaiAddress,
- useWriteErc20Approve,
- useWriteGnosisRouterMergePositions,
-} from "@/generated";
-
-import { useTokenAllowances } from "@/hooks/useTokenAllowances";
-
-import { parentMarket, invalidMarket, markets } from "@/consts/markets";
+import { useTradeExecutorMerge } from "@/hooks/tradeWallet/useTradeExecutorMerge";
interface IMergeButton {
amount: bigint;
- isMinting: boolean;
- toggleIsMinting: (value: boolean) => void;
- refetchSDai: () => void;
- refetchBalances: () => void;
+ tradeExecutor: Address;
}
-const MergeButton: React.FC
= ({
- amount,
- isMinting,
- toggleIsMinting,
- refetchSDai,
- refetchBalances,
-}) => {
- const wagmiConfig = useConfig();
- const { sendCalls } = useSendCalls();
-
- const atomicSupport = false;
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- const { data: capabilities } = useCapabilities();
- // const atomicSupport = useMemo(
- // () =>
- // ["ready", "supported"].includes(capabilities?.[100].atomic?.status ?? ""),
- // [capabilities],
- // );
-
- const allowances = useTokenAllowances(
- markets
- .map(({ underlyingToken }) => underlyingToken)
- .concat([invalidMarket]),
- gnosisRouterAddress,
- );
-
- const needApproval = useMemo(() => {
- const queryKey = allowances.queryKey as readonly [
- unknown,
- { contracts: { address: Address }[] },
- ];
- if (typeof allowances?.data !== "undefined") {
- return allowances.data
- .map(({ result }, i) => ({
- address: queryKey[1].contracts[i].address,
- result,
- }))
- .filter(({ result }) => typeof result === "bigint" && result < amount)
- .map(({ address }) => address);
- }
- return [];
- }, [allowances, amount]);
+const MergeButton: React.FC = ({ amount, tradeExecutor }) => {
+ const tradeExecutorMerge = useTradeExecutorMerge();
- const calls = useMemo(() => {
- const calls = needApproval.map((address) => ({
- to: address,
- value: 0n,
- data: encodeFunctionData({
- abi: erc20Abi,
- functionName: "approve",
- args: [gnosisRouterAddress, amount],
- }),
- }));
- calls.push({
- to: gnosisRouterAddress,
- value: 0n,
- data: encodeFunctionData({
- abi: gnosisRouterAbi,
- functionName: "mergePositions",
- args: [sDaiAddress, parentMarket, amount],
- }),
+ const handleSubmit = () => {
+ tradeExecutorMerge.mutate({
+ tradeExecutor,
+ amount,
});
- return calls;
- }, [amount, needApproval]);
-
- const { writeContractAsync: approve } = useWriteErc20Approve();
- const { writeContractAsync: mergePositions } =
- useWriteGnosisRouterMergePositions();
-
+ };
return (
{
- toggleIsMinting(true);
- if (atomicSupport && typeof calls !== "undefined") {
- sendCalls(
- { calls },
- {
- onSettled: () => {
- refetchSDai();
- toggleIsMinting(false);
- },
- },
- );
- } else if (needApproval.length > 0) {
- try {
- const hash = await approve({
- address: needApproval[0],
- args: [gnosisRouterAddress, amount],
- });
- await waitForTransactionReceipt(wagmiConfig, {
- hash,
- confirmations: 2,
- });
- allowances.refetch();
- } finally {
- toggleIsMinting(false);
- }
- } else {
- try {
- const hash = await mergePositions({
- args: [sDaiAddress, parentMarket, amount],
- });
- await waitForTransactionReceipt(wagmiConfig, {
- hash,
- confirmations: 2,
- });
- } finally {
- refetchSDai();
- refetchBalances();
- toggleIsMinting(false);
- }
- }
- }}
+ text="Merge to sDAI"
+ onPress={handleSubmit}
/>
);
};
diff --git a/src/app/(homepage)/components/ParticipateSection/Mint/SDaiButton.tsx b/src/app/(homepage)/components/ParticipateSection/Mint/SDaiButton.tsx
index d91c5b7..2ce438b 100644
--- a/src/app/(homepage)/components/ParticipateSection/Mint/SDaiButton.tsx
+++ b/src/app/(homepage)/components/ParticipateSection/Mint/SDaiButton.tsx
@@ -1,99 +1,32 @@
-import React, { useMemo } from "react";
+import React from "react";
import { Button } from "@kleros/ui-components-library";
-import { waitForTransactionReceipt } from "@wagmi/core";
-import { useAccount, useConfig } from "wagmi";
+import { Address } from "viem";
-import {
- useSimulateGnosisRouterSplitPosition,
- useWriteGnosisRouterSplitPosition,
- gnosisRouterAddress,
- useReadSDaiAllowance,
- sDaiAddress,
- useWriteSDaiApprove,
-} from "@/generated";
-
-import { parentMarket } from "@/consts/markets";
+import { useTradeExecutorSplit } from "@/hooks/tradeWallet/useTradeExecutorSplit";
interface ISDaiButton {
amount: bigint;
- isMinting: boolean;
- toggleIsMinting: (value: boolean) => void;
- refetchSDai: () => void;
- refetchXDai: () => void;
- refetchBalances: () => void;
+ tradeExecutor: Address;
}
-const SDaiButton: React.FC = ({
- amount,
- isMinting,
- toggleIsMinting,
- refetchXDai,
- refetchSDai,
- refetchBalances,
-}) => {
- const { address } = useAccount();
-
- const {
- data: result,
- isLoading,
- isError,
- refetch: refetchSimulation,
- } = useSimulateGnosisRouterSplitPosition({
- args: [sDaiAddress, parentMarket, amount],
- query: {
- enabled: typeof address !== "undefined" && amount > 0n,
- },
- });
-
- const { writeContractAsync } = useWriteGnosisRouterSplitPosition();
-
- const wagmiConfig = useConfig();
-
- const { data: allowance, refetch: refetchAllowance } = useReadSDaiAllowance({
- args: [address!, gnosisRouterAddress],
- });
-
- const isAllowance = useMemo(
- () => amount > (allowance ?? 0n),
- [amount, allowance],
- );
+const SDaiButton: React.FC = ({ amount, tradeExecutor }) => {
+ const tradeExecutorSplit = useTradeExecutorSplit();
- const { writeContractAsync: increaseAllowance } = useWriteSDaiApprove();
+ const handleSplit = () => {
+ tradeExecutorSplit.mutate({
+ amount,
+ tradeExecutor,
+ });
+ };
return (
{
- toggleIsMinting(true);
- try {
- if (isAllowance) {
- const hash = await increaseAllowance({
- args: [gnosisRouterAddress, amount],
- });
- await waitForTransactionReceipt(wagmiConfig, {
- hash,
- confirmations: 2,
- });
- refetchAllowance();
- refetchSimulation();
- } else if (typeof result !== "undefined") {
- const tx = await writeContractAsync(result.request);
- await waitForTransactionReceipt(wagmiConfig, { hash: tx });
- refetchSDai();
- refetchXDai();
- refetchAllowance();
- refetchBalances();
- }
- } finally {
- toggleIsMinting(false);
- }
- }}
+ text={"Convert to Movie Tokens"}
+ onPress={handleSplit}
/>
);
};
diff --git a/src/app/(homepage)/components/ParticipateSection/Mint/TopLeftInfo.tsx b/src/app/(homepage)/components/ParticipateSection/Mint/TopLeftInfo.tsx
index ff264d8..93ca795 100644
--- a/src/app/(homepage)/components/ParticipateSection/Mint/TopLeftInfo.tsx
+++ b/src/app/(homepage)/components/ParticipateSection/Mint/TopLeftInfo.tsx
@@ -4,20 +4,17 @@ import WalletIcon from "@/assets/svg/wallet.svg";
import { formatValue } from "@/utils";
-const TopLeftInfo: React.FC<{ balance: bigint; isSDaiSelected: boolean }> = ({
- balance,
- isSDaiSelected,
-}) => {
+const TopLeftInfo: React.FC<{ balance: bigint }> = ({ balance }) => {
return (
1st {" "}
- Convert sDAI or xDAI into Project Tokens
+ Convert sDAI into Project Tokens
@@ -26,7 +23,7 @@ const TopLeftInfo: React.FC<{ balance: bigint; isSDaiSelected: boolean }> = ({
Total:
- {formatValue(balance ?? 0n)} {isSDaiSelected ? "sDAI" : "xDAI"}
+ {formatValue(balance ?? 0n)} sDAI
diff --git a/src/app/(homepage)/components/ParticipateSection/Mint/XDaiButton.tsx b/src/app/(homepage)/components/ParticipateSection/Mint/XDaiButton.tsx
deleted file mode 100644
index 2b7b44e..0000000
--- a/src/app/(homepage)/components/ParticipateSection/Mint/XDaiButton.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import React from "react";
-
-import { Button } from "@kleros/ui-components-library";
-import { waitForTransactionReceipt } from "@wagmi/core";
-import { useConfig } from "wagmi";
-
-import {
- useSimulateGnosisRouterSplitFromBase,
- useWriteGnosisRouterSplitFromBase,
-} from "@/generated";
-
-import { parentMarket } from "@/consts/markets";
-
-interface IXDaiButton {
- amount: bigint;
- isMinting: boolean;
- toggleIsMinting: (value: boolean) => void;
- refetchSDai: () => void;
- refetchXDai: () => void;
- refetchBalances: () => void;
-}
-
-const XDaiButton: React.FC = ({
- amount,
- isMinting,
- toggleIsMinting,
- refetchXDai,
- refetchSDai,
- refetchBalances,
-}) => {
- const {
- data: result,
- isLoading,
- isError,
- } = useSimulateGnosisRouterSplitFromBase({
- args: [parentMarket],
- value: amount,
- query: {
- enabled: amount > 0,
- },
- });
- const { writeContractAsync } = useWriteGnosisRouterSplitFromBase();
-
- const config = useConfig();
-
- return (
- {
- toggleIsMinting(true);
- try {
- if (typeof result !== "undefined") {
- const tx = await writeContractAsync(result.request);
- await waitForTransactionReceipt(config, { hash: tx });
- refetchSDai();
- refetchXDai();
- refetchBalances();
- }
- } finally {
- toggleIsMinting(false);
- }
- }}
- />
- );
-};
-
-export default XDaiButton;
diff --git a/src/app/(homepage)/components/ParticipateSection/Mint/index.tsx b/src/app/(homepage)/components/ParticipateSection/Mint/index.tsx
index 939266f..bbcdec9 100644
--- a/src/app/(homepage)/components/ParticipateSection/Mint/index.tsx
+++ b/src/app/(homepage)/components/ParticipateSection/Mint/index.tsx
@@ -1,62 +1,49 @@
import React, { useState, useMemo } from "react";
-import { Card } from "@kleros/ui-components-library";
+import { Accordion, Card } from "@kleros/ui-components-library";
import clsx from "clsx";
import { useToggle } from "react-use";
-import { useAccount, useBalance } from "wagmi";
+import { type Address } from "viem";
-import {
- useSimulateSDaiAdapterDepositXdai,
- useReadSDaiBalanceOf,
-} from "@/generated";
-
-import { useTokenBalances } from "@/hooks/useTokenBalances";
+import { useTokenBalance } from "@/hooks/useTokenBalance";
+import { useTokensBalances } from "@/hooks/useTokenBalances";
import ArrowDownIcon from "@/assets/svg/arrow-down.svg";
+import { isUndefined } from "@/utils";
+
+import { collateral } from "@/consts";
import { markets } from "@/consts/markets";
-import AmountInput, { TokenType } from "./AmountInput";
+import AmountInput from "./AmountInput";
import MergeButton from "./MergeButton";
import ProjectAmount from "./ProjectAmount";
import SDaiButton from "./SDaiButton";
import TopLeftInfo from "./TopLeftInfo";
-import XDaiButton from "./XDaiButton";
-const Mint: React.FC = () => {
- const { address } = useAccount();
- const { data: balanceXDai, refetch: refetchXDai } = useBalance({
- address,
- });
- const { data: balanceSDai, refetch: refetchSDai } = useReadSDaiBalanceOf({
- args: [address!],
+interface IMint {
+ tradeExecutor: Address;
+}
+const Mint: React.FC = ({ tradeExecutor }) => {
+ const { data: balanceSDaiData } = useTokenBalance({
+ address: tradeExecutor,
+ token: collateral.address,
});
const [amount, setAmount] = useState(0n);
- const [selectedToken, setSelectedToken] = useState(TokenType.sDAI);
- const [isMinting, toggleIsMinting] = useToggle(false);
const [isSplit, toggleIsSplit] = useToggle(true);
- const resultDeposit = useSimulateSDaiAdapterDepositXdai({
- args: [address!],
- value: amount,
- query: {
- enabled: typeof address !== "undefined" && amount > 0,
- retry: false,
- },
- });
-
- const marketBalances = useTokenBalances(
+ const { data: marketBalances } = useTokensBalances(
+ tradeExecutor,
markets.map(({ underlyingToken }) => underlyingToken),
);
const minMarketBalance = useMemo(() => {
- if (typeof marketBalances.data !== "undefined") {
- if (marketBalances.data.some(({ result }) => typeof result !== "bigint"))
+ if (!isUndefined(marketBalances)) {
+ if (marketBalances.some((result) => typeof result !== "bigint"))
return 0n;
- const flatResults = marketBalances.data.map(({ result }) => result);
- const minResult = flatResults.reduce((acc, curr) =>
+ const minResult = marketBalances.reduce((acc, curr) =>
curr! < acc! ? curr : acc,
);
return minResult as bigint;
@@ -64,22 +51,6 @@ const Mint: React.FC = () => {
return 0n;
}, [marketBalances]);
- const isSDaiSelected = useMemo(
- () => selectedToken === TokenType.sDAI,
- [selectedToken],
- );
-
- const notEnoughBalance = useMemo(() => {
- if (
- typeof amount === "undefined" ||
- typeof balanceXDai === "undefined" ||
- typeof balanceSDai === "undefined"
- )
- return false;
- else if (isSDaiSelected) return amount > balanceSDai;
- else return amount > balanceXDai.value;
- }, [balanceXDai, balanceSDai, amount, isSDaiSelected]);
-
return (
{
)}
>
-
+
{isSplit ? (
) : (
)}
{
)}
/>
- {markets.map(({ name, color }, i) => (
- {
- if (!isSplit) {
- if (minMarketBalance) {
- return minMarketBalance;
- }
- } else if (isSDaiSelected) {
- return amount;
- } else if (resultDeposit.data) {
- return resultDeposit.data.result;
- }
- return 0n;
- })()}
- />
- ))}
+ div]:my-0",
+ )}
+ items={[
+ {
+ title: "",
+ body: (
+
+ {markets.map(({ name, color }, i) => (
+
{
+ if (!isSplit) {
+ if (minMarketBalance) {
+ return minMarketBalance;
+ }
+ } else {
+ return amount;
+ }
+ return 0n;
+ })()}
+ />
+ ))}
+
+ ),
+ },
+ ]}
+ />
+
{isSplit ? (
- isSDaiSelected ? (
-
- ) : (
-
- )
- ) : (
-
+ ) : (
+
)}
diff --git a/src/app/(homepage)/components/ParticipateSection/RedeemParentMarket.tsx b/src/app/(homepage)/components/ParticipateSection/RedeemParentMarket.tsx
deleted file mode 100644
index 68e2b36..0000000
--- a/src/app/(homepage)/components/ParticipateSection/RedeemParentMarket.tsx
+++ /dev/null
@@ -1,187 +0,0 @@
-import React, { useMemo } from "react";
-
-import { Card, Button } from "@kleros/ui-components-library";
-import { waitForTransactionReceipt } from "@wagmi/core";
-import clsx from "clsx";
-import { useToggle } from "react-use";
-import { formatUnits } from "viem";
-import { useConfig } from "wagmi";
-
-import {
- gnosisRouterAddress,
- useReadGnosisRouterGetWinningOutcomes,
- useWriteGnosisRouterRedeemPositions,
- useWriteErc20Approve,
- sDaiAddress,
-} from "@/generated";
-
-import { useNeedsApproval } from "@/hooks/useNeedsApproval";
-import { useTokenBalances } from "@/hooks/useTokenBalances";
-
-import { shortenName, isUndefined } from "@/utils";
-
-import { markets, parentConditionId, parentMarket } from "@/consts/markets";
-
-const RedeemParentMarket: React.FC = () => {
- const [isLoading, setIsLoading] = useToggle(false);
- const wagmiConfig = useConfig();
-
- const { data: winningOutcomes, isLoading: winningOutcomesLoading } =
- useReadGnosisRouterGetWinningOutcomes({
- args: [parentConditionId],
- });
-
- const numberOutcomes = useMemo(
- () =>
- winningOutcomes?.reduce((acc, outcome) => (outcome ? acc + 1 : acc), 0),
- [winningOutcomes],
- );
-
- const winningTokens = useMemo(() => {
- if (!winningOutcomesLoading && !isUndefined(winningOutcomes)) {
- return markets
- .map((market, i) => ({ ...market, index: i }))
- .filter((_, i) => winningOutcomes[i])
- .map(({ underlyingToken, index }) => ({ underlyingToken, index }));
- }
- }, [winningOutcomesLoading, winningOutcomes]);
-
- const {
- data: balances,
- isLoading: balancesLoading,
- refetch: refetchBalances,
- } = useTokenBalances(
- winningTokens?.map(({ underlyingToken }) => underlyingToken) ?? [],
- );
-
- const winningTokensWithBalance = useMemo(
- () =>
- winningTokens
- ?.map(({ underlyingToken, index }, i) => ({
- address: underlyingToken,
- index,
- balance: balances?.[i].result as bigint,
- }))
- .filter(({ balance }) => balance > 0n),
- [balances, winningTokens],
- );
-
- const totalValue = useMemo(() => {
- const totalBalance = winningTokensWithBalance?.reduce(
- (acc, { balance }) => acc + balance,
- 0n,
- );
-
- if (
- !isUndefined(totalBalance) &&
- !isUndefined(winningTokensWithBalance) &&
- !isUndefined(numberOutcomes)
- ) {
- const formattedAmount = parseFloat(
- formatUnits(totalBalance / BigInt(numberOutcomes), 18),
- ).toFixed(2);
- if (formattedAmount !== "0.00") {
- return formattedAmount;
- } else if (totalBalance > 0n) {
- return "< 0.01";
- }
- }
- }, [winningTokensWithBalance, numberOutcomes]);
-
- const { needsApproval, refetch: refetchNeedsApproval } = useNeedsApproval(
- winningTokensWithBalance?.map(({ address }) => address) ?? [],
- winningTokensWithBalance?.map(({ balance }) => (balance as bigint) ?? 0n) ??
- [],
- gnosisRouterAddress,
- );
-
- const approvalsWithBalance = useMemo(
- () =>
- winningTokensWithBalance?.filter(({ address }) =>
- needsApproval.includes(address),
- ) ?? [],
- [winningTokensWithBalance, needsApproval],
- );
-
- const { writeContractAsync: approve } = useWriteErc20Approve();
- const { writeContractAsync: redeem } = useWriteGnosisRouterRedeemPositions();
-
- const nextApprovalName = useMemo(() => {
- const targetMarket = markets.find(
- ({ underlyingToken }) =>
- underlyingToken === approvalsWithBalance.at(0)?.address,
- );
- if (targetMarket) {
- return shortenName(targetMarket.name);
- }
- }, [approvalsWithBalance]);
-
- if (winningTokensWithBalance?.length ?? 0 > 0) {
- return (
-
-
-
- {`You have tokens from the selected projects that were not spent. You can redeem up to ${totalValue} sDAI.`}
-
-
- {
- setIsLoading(true);
- if (approvalsWithBalance.length > 0) {
- try {
- const hash = await approve({
- address: approvalsWithBalance[0].address,
- args: [gnosisRouterAddress, approvalsWithBalance[0].balance],
- });
- await waitForTransactionReceipt(wagmiConfig, {
- hash,
- confirmations: 2,
- });
- } finally {
- refetchNeedsApproval();
- setIsLoading(false);
- }
- } else {
- try {
- const hash = await redeem({
- args: [
- sDaiAddress,
- parentMarket,
- winningTokensWithBalance?.map(({ index }) =>
- BigInt(index),
- ) ?? [],
- winningTokensWithBalance?.map(({ balance }) => balance) ??
- [],
- ],
- });
- await waitForTransactionReceipt(wagmiConfig, {
- hash,
- confirmations: 2,
- });
- } finally {
- refetchBalances();
- setIsLoading(false);
- }
- }
- }}
- />
-
- );
- }
-};
-
-export default RedeemParentMarket;
diff --git a/src/app/(homepage)/components/ParticipateSection/index.tsx b/src/app/(homepage)/components/ParticipateSection/index.tsx
index c6d1ad0..904be4b 100644
--- a/src/app/(homepage)/components/ParticipateSection/index.tsx
+++ b/src/app/(homepage)/components/ParticipateSection/index.tsx
@@ -1,16 +1,19 @@
import { Card } from "@kleros/ui-components-library";
+import { useTradeWallet } from "@/context/TradeWalletContext";
+
import Mint from "./Mint";
-import RedeemParentMarket from "./RedeemParentMarket";
const ParticipateSection: React.FC = () => {
+ const { tradeExecutor } = useTradeWallet();
+
return (
-
+
Participate
-
+ {tradeExecutor ? : null}
{
you want to predict.
-
);
};
diff --git a/src/app/(homepage)/components/ProjectFunding/PositionValue.tsx b/src/app/(homepage)/components/ProjectFunding/PositionValue.tsx
index 66bf822..7d60b1f 100644
--- a/src/app/(homepage)/components/ProjectFunding/PositionValue.tsx
+++ b/src/app/(homepage)/components/ProjectFunding/PositionValue.tsx
@@ -2,12 +2,10 @@ import React, { useMemo } from "react";
import clsx from "clsx";
import { formatUnits, Address, formatEther } from "viem";
-import { useAccount } from "wagmi";
-
-import { useReadErc20BalanceOf } from "@/generated";
import { useMarketContext } from "@/context/MarketContext";
import { useMarketPrice } from "@/hooks/useMarketPrice";
+import { useTokenBalance } from "@/hooks/useTokenBalance";
import { formatValue, isUndefined } from "@/utils";
@@ -19,15 +17,15 @@ interface IPositionValue {
upToken: Address;
downToken: Address;
underlyingToken: Address;
+ tradeExecutor: Address;
}
const PositionValue: React.FC
= ({
upToken,
downToken,
underlyingToken,
+ tradeExecutor,
}) => {
- const { address } = useAccount();
-
const {
isLoadingMarketPrice,
isResolved,
@@ -40,14 +38,14 @@ const PositionValue: React.FC = ({
value: upValue,
balance: upBalance,
price: upPrice,
- } = useTokenPositionValue(upToken, underlyingToken, address ?? "0x", {
+ } = useTokenPositionValue(upToken, underlyingToken, tradeExecutor ?? "0x", {
isUp: true,
});
const {
value: downValue,
balance: downBalance,
price: downPrice,
- } = useTokenPositionValue(downToken, underlyingToken, address ?? "0x", {
+ } = useTokenPositionValue(downToken, underlyingToken, tradeExecutor ?? "0x", {
isUp: false,
});
const totalValue = upValue + downValue;
@@ -125,7 +123,7 @@ const PositionValue: React.FC = ({
{totalValue.toFixed(2)} sDAI
- {isResolved ? : null}
+ {isResolved ? : null}
);
};
@@ -138,14 +136,11 @@ const useTokenPositionValue = (
) => {
const { hasLiquidity, marketPrice } = useMarketContext();
- const { data: balance } = useReadErc20BalanceOf({
- address: token,
- args: [address ?? "0x"],
- query: {
- staleTime: 5000,
- enabled: typeof address !== "undefined",
- },
+ const { data: balanceData } = useTokenBalance({
+ token: token,
+ address: address,
});
+ const balance = balanceData?.value;
const { data } = useMarketPrice(
token,
diff --git a/src/app/(homepage)/components/ProjectFunding/PredictButton.tsx b/src/app/(homepage)/components/ProjectFunding/PredictButton.tsx
index 1a92cca..b7d1dd8 100644
--- a/src/app/(homepage)/components/ProjectFunding/PredictButton.tsx
+++ b/src/app/(homepage)/components/ProjectFunding/PredictButton.tsx
@@ -1,128 +1,115 @@
-import React from "react";
-import { useMemo } from "react";
+"use client";
+import React, { useEffect, useState } from "react";
-import { Button, Modal } from "@kleros/ui-components-library";
-import { useToggle } from "react-use";
-import { formatUnits } from "viem";
+import { Button } from "@kleros/ui-components-library";
+import { useQueryClient } from "@tanstack/react-query";
+import { Address } from "viem";
import { useCardInteraction } from "@/context/CardInteractionContext";
import { useMarketContext } from "@/context/MarketContext";
-import { useBalance } from "@/hooks/useBalance";
-import { useMarketQuote } from "@/hooks/useMarketQuote";
+import { useTradeExecutorPredict } from "@/hooks/tradeWallet/useTradeExecutorPredict";
+import { useGetQuotes } from "@/hooks/useGetQuotes";
+import { useProcessMarkets } from "@/hooks/useProcessMarkets";
+import { useTokenBalance } from "@/hooks/useTokenBalance";
-import LightButton from "@/components/LightButton";
+import { formatError } from "@/utils/formatError";
-import CloseIcon from "@/assets/svg/close-icon.svg";
+interface IPredictButton {
+ tradeExecutor: Address;
+ setErrorMessage: (message: string | undefined) => void;
+}
-import { isUndefined } from "@/utils";
+const PredictButton: React.FC = ({
+ tradeExecutor,
+ setErrorMessage,
+}) => {
+ const queryClient = useQueryClient();
+ const { activeCardId } = useCardInteraction();
+ const { market } = useMarketContext();
-import DefaultPredictButton from "./PredictPopup/ActionButtons/DefaultPredictButton";
-import TradeButton from "./PredictPopup/ActionButtons/TradeButton";
+ const [pendingPrediction, setPendingPrediction] = useState(false);
-import PredictPopup from "./PredictPopup";
+ const { underlyingToken, marketId } = market;
+ const shouldFetch = activeCardId === marketId;
-const PredictButton: React.FC = () => {
- const [isOpen, toggleIsOpen] = useToggle(false);
- const [isPopUpOpen, toggleIsPopUpOpen] = useToggle(false);
-
- const { setActiveCardId } = useCardInteraction();
+ const processedMarkets = useProcessMarkets({
+ tradeExecutor,
+ enabled: shouldFetch,
+ });
const {
- market,
- isUpPredict,
- differenceBetweenRoutes,
- isLoading: isLoadingComplexRoute,
- hasLiquidity,
- refetchQuotes,
- } = useMarketContext();
-
- const { upToken, downToken, underlyingToken, marketId } = market;
-
- const { data: underlyingBalance } = useBalance(underlyingToken);
- const { data: upBalance } = useBalance(upToken);
- const { data: downBalance } = useBalance(downToken);
-
- const needsSelling = useMemo(
- () =>
- isUpPredict
- ? !isUndefined(downBalance) && downBalance > 0
- : !isUndefined(upBalance) && upBalance > 0,
- [isUpPredict, downBalance, upBalance],
+ data: getQuotesResult,
+ isLoading: isLoadingQuotes,
+ error: getQuotesError,
+ } = useGetQuotes(
+ {
+ account: tradeExecutor,
+ processedMarkets: processedMarkets!,
+ },
+ shouldFetch,
);
- const sellToken = isUpPredict ? downToken : upToken;
- const sellTokenBalance = isUpPredict ? downBalance : upBalance;
- const { data: sellQuote } = useMarketQuote(
- underlyingToken,
- sellToken,
- sellTokenBalance ? formatUnits(sellTokenBalance, 18) : "1",
- );
+ const { data: underlyingTokenBalanceData, isLoading: isLoadingBalance } =
+ useTokenBalance({
+ address: tradeExecutor,
+ token: underlyingToken,
+ });
+
+ const tradeExecutorPredict = useTradeExecutorPredict(() => {
+ setErrorMessage(undefined);
+ queryClient.refetchQueries({
+ queryKey: ["useTicksData", underlyingToken],
+ });
+ });
+
+ useEffect(() => {
+ if (getQuotesError) {
+ setErrorMessage(formatError(getQuotesError));
+ } else if (tradeExecutorPredict.error) {
+ setErrorMessage(formatError(tradeExecutorPredict.error));
+ } else {
+ setErrorMessage(undefined);
+ }
+ }, [getQuotesError, tradeExecutorPredict.error, setErrorMessage]);
+
+ // send the transaction once the loading is done and user had clicked on predict
+ useEffect(() => {
+ if (pendingPrediction && getQuotesResult && underlyingTokenBalanceData) {
+ tradeExecutorPredict.mutate({
+ market,
+ amount: underlyingTokenBalanceData.value ?? 0n,
+ tradeExecutor,
+ getQuotesResult,
+ });
+ setPendingPrediction(false);
+ }
+ }, [pendingPrediction, getQuotesResult, underlyingTokenBalanceData]);
+
+ const handlePredict = () => {
+ if (!tradeExecutor || !underlyingTokenBalanceData) return;
+
+ if (getQuotesResult) {
+ // Quotes are already available, go straight to txn
+ tradeExecutorPredict.mutate({
+ market,
+ amount: underlyingTokenBalanceData.value ?? 0n,
+ tradeExecutor,
+ getQuotesResult,
+ });
+ } else {
+ // Quotes still loading, wait until available
+ setPendingPrediction(true);
+ }
+ };
- // if no previous position, carry with the default behaviour
- if (!needsSelling)
- return (
- <>
- {differenceBetweenRoutes > 0 ? (
- {
- setActiveCardId(marketId);
- toggleIsPopUpOpen();
- }}
- />
- ) : (
-
- )}
-
- >
- );
-
- // if previous prediction present, liquidate that to set a new prediction
return (
- <>
-
-
-
- }
- onPress={toggleIsOpen}
- />
-
-
- You have a previous prediction with {isUpPredict ? "DOWN" : "UP"}{" "}
- tokens,
- Sell those tokens to make a new prediction.
-
-
{
- toggleIsOpen();
- refetchQuotes();
- }}
- />
-
-
- >
+
);
};
export default PredictButton;
diff --git a/src/app/(homepage)/components/ProjectFunding/PredictPopup/ActionButtons/DefaultPredictButton.tsx b/src/app/(homepage)/components/ProjectFunding/PredictPopup/ActionButtons/DefaultPredictButton.tsx
deleted file mode 100644
index 60ec009..0000000
--- a/src/app/(homepage)/components/ProjectFunding/PredictPopup/ActionButtons/DefaultPredictButton.tsx
+++ /dev/null
@@ -1,131 +0,0 @@
-import { useCallback, useMemo } from "react";
-
-import { Button } from "@kleros/ui-components-library";
-import { sendTransaction, waitForTransactionReceipt } from "@wagmi/core";
-import { useToggle } from "react-use";
-import { useAccount, useConfig } from "wagmi";
-
-import { useWriteErc20Approve } from "@/generated";
-
-import { useMarketContext } from "@/context/MarketContext";
-import { useAllowance } from "@/hooks/useAllowance";
-import { useBalance } from "@/hooks/useBalance";
-
-import { isUndefined } from "@/utils";
-
-import { SWAPR_CONTRACT } from "@/consts";
-
-const DefaultPredictButton: React.FC<{ toggleIsOpen?: () => void }> = ({
- toggleIsOpen,
-}) => {
- const {
- marketQuote,
- marketDownQuote,
- isUpPredict,
- market,
- isLoading,
- hasLiquidity,
- } = useMarketContext();
- const { underlyingToken } = market;
-
- const wagmiConfig = useConfig();
- const { address } = useAccount();
- const [userInteracting, toggleUserInteracting] = useToggle(false);
- const { data: allowance, refetch: refetchAllowance } =
- useAllowance(underlyingToken);
-
- const { data: underlyingBalance, refetch: refetchBalance } =
- useBalance(underlyingToken);
-
- const isAllowance = useMemo(
- () =>
- typeof allowance !== "undefined" &&
- typeof underlyingBalance !== "undefined" &&
- allowance < underlyingBalance,
- [allowance, underlyingBalance],
- );
-
- const { writeContractAsync: increaseAllowance } = useWriteErc20Approve();
-
- const handleAllowance = useCallback(async () => {
- try {
- if (!isUndefined(underlyingBalance)) {
- const hash = await increaseAllowance({
- address: underlyingToken,
- args: [SWAPR_CONTRACT, underlyingBalance],
- });
- await waitForTransactionReceipt(wagmiConfig, {
- hash,
- confirmations: 2,
- });
- refetchAllowance();
- }
- } catch (err) {
- console.log("handleAllowance:", err);
- }
- }, [
- wagmiConfig,
- increaseAllowance,
- refetchAllowance,
- underlyingBalance,
- underlyingToken,
- ]);
-
- const handlePredict = useCallback(async () => {
- try {
- const tx = await (
- isUpPredict ? marketQuote : marketDownQuote
- )?.swapTransaction({
- recipient: address!,
- });
- const hash = await sendTransaction(wagmiConfig, {
- to: tx!.to as `0x${string}`,
- data: tx!.data!.toString() as `0x${string}`,
- value: BigInt(tx?.value?.toString() || 0),
- });
- await waitForTransactionReceipt(wagmiConfig, { hash, confirmations: 2 });
- refetchBalance();
- toggleIsOpen?.();
- } catch (err) {
- console.log("handlePredict:", err);
- }
- }, [
- address,
- marketQuote,
- marketDownQuote,
- wagmiConfig,
- isUpPredict,
- refetchBalance,
- toggleIsOpen,
- ]);
- return (
- {
- toggleUserInteracting(true);
- try {
- if (isAllowance) {
- await handleAllowance();
- } else {
- await handlePredict();
- }
- } finally {
- toggleUserInteracting(false);
- }
- }}
- />
- );
-};
-
-export default DefaultPredictButton;
diff --git a/src/app/(homepage)/components/ProjectFunding/PredictPopup/ActionButtons/SplitButton.tsx b/src/app/(homepage)/components/ProjectFunding/PredictPopup/ActionButtons/SplitButton.tsx
deleted file mode 100644
index ec117d8..0000000
--- a/src/app/(homepage)/components/ProjectFunding/PredictPopup/ActionButtons/SplitButton.tsx
+++ /dev/null
@@ -1,120 +0,0 @@
-import React, { useMemo, useCallback } from "react";
-
-import { Button } from "@kleros/ui-components-library";
-import { waitForTransactionReceipt } from "@wagmi/core";
-import { useToggle } from "react-use";
-import { Address } from "viem";
-import { useConfig, useAccount } from "wagmi";
-
-import {
- useWriteErc20Approve,
- gnosisRouterAddress,
- useWriteGnosisRouterSplitPosition,
- sDaiAddress,
-} from "@/generated";
-
-import { useAllowance } from "@/hooks/useAllowance";
-import { useBalance } from "@/hooks/useBalance";
-
-import { isUndefined } from "@/utils";
-
-interface ISplitButton {
- marketId: `0x${string}`;
- underlyingToken: Address;
- setNextStep: () => void;
-}
-
-const SplitButton: React.FC = ({
- marketId,
- underlyingToken,
- setNextStep,
-}) => {
- const wagmiConfig = useConfig();
- const { address } = useAccount();
- const [isInteracting, toggleIsInteracting] = useToggle(false);
-
- const { data: underlyingBalance } = useBalance(underlyingToken);
-
- const { data: allowance, refetch: refetchAllowance } = useAllowance(
- underlyingToken,
- gnosisRouterAddress,
- );
- const isAllowance = useMemo(
- () =>
- !isUndefined(allowance) &&
- !isUndefined(underlyingBalance) &&
- allowance < underlyingBalance,
- [allowance, underlyingBalance],
- );
-
- const { writeContractAsync: increaseAllowance } = useWriteErc20Approve();
-
- const handleAllowance = useCallback(async () => {
- try {
- if (!isUndefined(underlyingBalance)) {
- const hash = await increaseAllowance({
- address: underlyingToken,
- args: [gnosisRouterAddress, underlyingBalance],
- });
- await waitForTransactionReceipt(wagmiConfig, {
- hash,
- confirmations: 2,
- });
- refetchAllowance();
- }
- } catch (err) {
- console.log("handleAllowance:", err);
- }
- }, [
- wagmiConfig,
- increaseAllowance,
- refetchAllowance,
- underlyingBalance,
- underlyingToken,
- ]);
-
- const { writeContractAsync: splitPosition } =
- useWriteGnosisRouterSplitPosition();
-
- const handleSplit = useCallback(async () => {
- try {
- if (!isUndefined(underlyingBalance)) {
- const hash = await splitPosition({
- args: [sDaiAddress, marketId, underlyingBalance],
- });
- await waitForTransactionReceipt(wagmiConfig, {
- hash,
- confirmations: 2,
- });
- setNextStep();
- }
- } catch (err) {
- console.log("handleSplit:", err);
- }
- }, [splitPosition, marketId, underlyingBalance, setNextStep, wagmiConfig]);
-
- return (
- {
- toggleIsInteracting(true);
- try {
- if (isAllowance) {
- await handleAllowance();
- } else {
- await handleSplit();
- }
- } finally {
- toggleIsInteracting(false);
- }
- }}
- />
- );
-};
-
-export default SplitButton;
diff --git a/src/app/(homepage)/components/ProjectFunding/PredictPopup/ActionButtons/TradeButton.tsx b/src/app/(homepage)/components/ProjectFunding/PredictPopup/ActionButtons/TradeButton.tsx
deleted file mode 100644
index a93ed3b..0000000
--- a/src/app/(homepage)/components/ProjectFunding/PredictPopup/ActionButtons/TradeButton.tsx
+++ /dev/null
@@ -1,121 +0,0 @@
-import { useCallback, useMemo } from "react";
-
-import { Button } from "@kleros/ui-components-library";
-import { SwaprV3Trade } from "@swapr/sdk";
-import { sendTransaction, waitForTransactionReceipt } from "@wagmi/core";
-import { useToggle } from "react-use";
-import { Address, parseUnits } from "viem";
-import { useAccount, useConfig } from "wagmi";
-
-import { useWriteErc20Approve } from "@/generated";
-
-import { useAllowance } from "@/hooks/useAllowance";
-
-import { isUndefined } from "@/utils";
-
-import { SWAPR_CONTRACT } from "@/consts";
-
-interface ITradeButton {
- sellToken: Address;
- quote?: SwaprV3Trade | null;
- setNextStep: () => void;
-}
-
-const TradeButton: React.FC = ({
- sellToken,
- quote,
- setNextStep,
-}) => {
- const { address } = useAccount();
- const wagmiConfig = useConfig();
- const [userInteracting, toggleUserInteracting] = useToggle(false);
-
- const { data: allowance, refetch: refetchAllowance } =
- useAllowance(sellToken);
-
- const amountToTrade = useMemo(
- () =>
- isUndefined(quote)
- ? undefined
- : parseUnits(quote.inputAmount.toExact(), 18),
- [quote],
- );
-
- const isAllowance = useMemo(
- () =>
- !isUndefined(allowance) &&
- !isUndefined(amountToTrade) &&
- allowance < amountToTrade,
- [allowance, amountToTrade],
- );
-
- const { writeContractAsync: increaseAllowance } = useWriteErc20Approve();
-
- const handleAllowance = useCallback(async () => {
- try {
- if (!isUndefined(amountToTrade)) {
- // approve swapr router
- const hash = await increaseAllowance({
- address: sellToken,
- args: [SWAPR_CONTRACT, amountToTrade ?? 0],
- });
- await waitForTransactionReceipt(wagmiConfig, {
- hash,
- confirmations: 2,
- });
- refetchAllowance();
- }
- } catch (err) {
- console.log("handleAllowance:", err);
- }
- }, [
- wagmiConfig,
- increaseAllowance,
- refetchAllowance,
- sellToken,
- amountToTrade,
- ]);
-
- const handleTrade = useCallback(async () => {
- try {
- const tx = await quote?.swapTransaction({
- recipient: address!,
- });
-
- const hash = await sendTransaction(wagmiConfig, {
- to: tx!.to as `0x${string}`,
- data: tx!.data!.toString() as `0x${string}`,
- value: BigInt(tx?.value?.toString() || 0),
- });
- await waitForTransactionReceipt(wagmiConfig, { hash, confirmations: 2 });
- setNextStep();
- } catch (err) {
- console.log("handleTrade:", err);
- }
- }, [address, wagmiConfig, quote, setNextStep]);
-
- return (
- {
- toggleUserInteracting(true);
- try {
- if (isAllowance) {
- await handleAllowance();
- } else {
- await handleTrade();
- }
- } finally {
- toggleUserInteracting(false);
- }
- }}
- />
- );
-};
-
-export default TradeButton;
diff --git a/src/app/(homepage)/components/ProjectFunding/PredictPopup/DefaultPredict.tsx b/src/app/(homepage)/components/ProjectFunding/PredictPopup/DefaultPredict.tsx
deleted file mode 100644
index bfcdaac..0000000
--- a/src/app/(homepage)/components/ProjectFunding/PredictPopup/DefaultPredict.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import { Card } from "@kleros/ui-components-library";
-import clsx from "clsx";
-
-import { useMarketContext } from "@/context/MarketContext";
-
-import DefaultPredictButton from "./ActionButtons/DefaultPredictButton";
-
-import SkeletonCard from "./SkeletonCard";
-
-import { Route } from ".";
-
-interface IDefaultPredict {
- isSelected: boolean;
- setIsSelected: (val: Route) => void;
- toggleIsOpen: () => void;
-}
-const DefaultPredict: React.FC = ({
- isSelected,
- setIsSelected,
- toggleIsOpen,
-}) => {
- const { isUpPredict, expectedFromDefaultRoute, isLoading } =
- useMarketContext();
-
- const tokenSymbol = isUpPredict ? "UP" : "DOWN";
-
- if (isLoading) {
- return ;
- }
- return (
- setIsSelected(Route.Default)}
- >
-
-
- Default
-
-
- Buy {tokenSymbol} Tokens.
-
-
-
-
-
-
- Expected Return: {expectedFromDefaultRoute?.toFixed(2)}{" "}
- {tokenSymbol} tokens
-
-
-
- 2 steps required
-
-
-
-
-
- );
-};
-export default DefaultPredict;
diff --git a/src/app/(homepage)/components/ProjectFunding/PredictPopup/MintSell.tsx b/src/app/(homepage)/components/ProjectFunding/PredictPopup/MintSell.tsx
deleted file mode 100644
index 3832710..0000000
--- a/src/app/(homepage)/components/ProjectFunding/PredictPopup/MintSell.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-import { Button, Card } from "@kleros/ui-components-library";
-import clsx from "clsx";
-
-import { useMarketContext } from "@/context/MarketContext";
-
-import SkeletonCard from "./SkeletonCard";
-
-import { Route } from ".";
-
-interface IMintSell {
- isSelected: boolean;
- setIsSelected: (val: Route) => void;
- setIsMintScreen: (val: boolean) => void;
-}
-
-const MintSell: React.FC = ({
- isSelected,
- setIsSelected,
- setIsMintScreen,
-}) => {
- const {
- isUpPredict,
- expectedFromMintRoute,
- isLoading,
- percentageIncrease,
- differenceBetweenRoutes,
- } = useMarketContext();
-
- const tokenSymbol = isUpPredict ? "UP" : "DOWN";
-
- if (isLoading) {
- return ;
- }
- return (
- setIsSelected(Route.MintSell)}
- >
-
-
- Mint and Sell
-
-
- Mint UP and DOWN Tokens, Sell {isUpPredict ? "DOWN" : "UP"} tokens,
- and buy more {tokenSymbol} Tokens.
-
-
-
-
-
-
- Expected Return: {expectedFromMintRoute?.toFixed(2)} {tokenSymbol}{" "}
- tokens
-
-
= 0
- ? "text-klerosUIComponentsSuccess"
- : "text-klerosUIComponentsError",
- )}
- >
-
- {differenceBetweenRoutes > 0 && <>⏶>}
- {differenceBetweenRoutes < 0 && <>▼>} {percentageIncrease}
- %
-
-
-
- 6 steps required
-
-
-
setIsMintScreen(true)} />
-
-
- );
-};
-export default MintSell;
diff --git a/src/app/(homepage)/components/ProjectFunding/PredictPopup/MintSellSteps.tsx b/src/app/(homepage)/components/ProjectFunding/PredictPopup/MintSellSteps.tsx
deleted file mode 100644
index cefdde1..0000000
--- a/src/app/(homepage)/components/ProjectFunding/PredictPopup/MintSellSteps.tsx
+++ /dev/null
@@ -1,109 +0,0 @@
-import { useRef, useState } from "react";
-
-import { Button, Steps } from "@kleros/ui-components-library";
-import clsx from "clsx";
-
-import { useMarketContext } from "@/context/MarketContext";
-
-import SplitButton from "./ActionButtons/SplitButton";
-import TradeButton from "./ActionButtons/TradeButton";
-
-enum Step {
- Mint,
- Sell,
- Buy,
-}
-
-interface IMintSellSteps {
- close: () => void;
- toggleIsOpen: () => void;
-}
-const MintSellSteps: React.FC = ({ close, toggleIsOpen }) => {
- const [currentStep, setCurrentStep] = useState(Step.Mint);
- const initialBalanceRef = useRef(null);
- const {
- expectedFromMintRoute,
- isUpPredict,
- market,
- mintReBuyQuote,
- mintSellQuote,
- } = useMarketContext();
- const { marketId, underlyingToken, downToken, upToken } = market;
-
- const steps = [
- {
- title: "Mint",
- subitems: ["Approve in gnosisRouter", "Split position"],
- },
-
- {
- title: "Sell",
- subitems: [
- "Approve token counter in Swapr",
- "Sell token counter to position",
- ],
- },
- {
- title: "Buy",
- },
- ];
- const tokenSymbol = isUpPredict ? "UP" : "DOWN";
- return (
-
-
- Mint, sell, and buy.
-
-
-
- Expected Return: {expectedFromMintRoute?.toFixed(2)} {tokenSymbol}{" "}
- tokens
-
-
-
-
-
- {currentStep === Step.Mint && (
- setCurrentStep(Step.Sell)}
- />
- )}
- {currentStep === Step.Sell && (
- // if user was initially buying upToken, we need to sell downToken,
- // to obtain underlyingToken to further buy more upToken. Vice versa
- setCurrentStep(Step.Buy)}
- />
- )}
- {currentStep === Step.Buy && (
- // buy the upToken/downToken with the underlyingToken acquired from above trade
- {
- toggleIsOpen();
- }}
- />
- )}
-
-
- );
-};
-export default MintSellSteps;
diff --git a/src/app/(homepage)/components/ProjectFunding/PredictPopup/SkeletonCard.tsx b/src/app/(homepage)/components/ProjectFunding/PredictPopup/SkeletonCard.tsx
deleted file mode 100644
index a367400..0000000
--- a/src/app/(homepage)/components/ProjectFunding/PredictPopup/SkeletonCard.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import clsx from "clsx";
-
-import { Skeleton } from "@/components/Skeleton";
-
-const SkeletonCard: React.FC = () => {
- return (
-
- );
-};
-
-export default SkeletonCard;
diff --git a/src/app/(homepage)/components/ProjectFunding/PredictPopup/index.tsx b/src/app/(homepage)/components/ProjectFunding/PredictPopup/index.tsx
deleted file mode 100644
index e9d9489..0000000
--- a/src/app/(homepage)/components/ProjectFunding/PredictPopup/index.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import { useState } from "react";
-
-import { Modal } from "@kleros/ui-components-library";
-
-import LightButton from "@/components/LightButton";
-
-import CloseIcon from "@/assets/svg/close-icon.svg";
-
-import DefaultPredict from "./DefaultPredict";
-import MintSell from "./MintSell";
-import MintSellSteps from "./MintSellSteps";
-
-export enum Route {
- Default,
- MintSell,
-}
-interface IPredictPopup {
- isOpen?: boolean;
- toggleIsOpen: () => void;
-}
-const PredictPopup: React.FC = ({ isOpen, toggleIsOpen }) => {
- const [selectedRoute, setSelectedRoute] = useState();
- const [isMinting, setIsMinting] = useState(false);
- return (
-
-
- }
- onPress={toggleIsOpen}
- />
- {isMinting ? (
- setIsMinting(false)}
- {...{ toggleIsOpen }}
- />
- ) : (
-
-
-
- Predict
-
-
- Choose between the default or enhanced option below:
-
-
-
-
-
-
-
- )}
-
- );
-};
-
-export default PredictPopup;
diff --git a/src/app/(homepage)/components/ProjectFunding/RedeemButton.tsx b/src/app/(homepage)/components/ProjectFunding/RedeemButton.tsx
index ebc5d55..6235d72 100644
--- a/src/app/(homepage)/components/ProjectFunding/RedeemButton.tsx
+++ b/src/app/(homepage)/components/ProjectFunding/RedeemButton.tsx
@@ -1,143 +1,51 @@
-import { useMemo, useState } from "react";
-
import { Button } from "@kleros/ui-components-library";
-import { useQueryClient } from "@tanstack/react-query";
-import { waitForTransactionReceipt } from "@wagmi/core";
-import { useConfig } from "wagmi";
-
-import {
- conditionalRouterAddress,
- sDaiAddress,
- useSimulateConditionalRouterRedeemConditionalToCollateral,
- useWriteConditionalRouterRedeemConditionalToCollateral,
-} from "@/generated";
+import { Address } from "viem";
import { useMarketContext } from "@/context/MarketContext";
-import { useAllowance } from "@/hooks/useAllowance";
-import { useBalance } from "@/hooks/useBalance";
-
-import ApproveButton from "@/components/ApproveButton";
+import { useRedeemToTradeExecutor } from "@/hooks/tradeWallet/useRedeemToTradeExecutor";
+import { useTokenBalance } from "@/hooks/useTokenBalance";
import { isUndefined } from "@/utils";
-import { marketsParentOutcome } from "@/consts/markets";
-
-const RedeemButton: React.FC = () => {
- const wagmiConfig = useConfig();
- const queryClient = useQueryClient();
+interface IRedeemButton {
+ tradeExecutor: Address;
+}
- const [isSending, setIsSending] = useState(false);
+const RedeemButton: React.FC = ({ tradeExecutor }) => {
const { market } = useMarketContext();
- const { upToken, downToken, marketId } = market;
+ const { upToken, downToken, marketId, parentMarketOutcome } = market;
- const { data: upBalance } = useBalance(upToken);
- const { data: downBalance } = useBalance(downToken);
+ const { data: upBalanceData, isLoading: isLoadingUpBalance } =
+ useTokenBalance({ token: upToken, address: tradeExecutor });
+ const { data: downBalanceData, isLoading: isLoadingDownBalance } =
+ useTokenBalance({ token: downToken, address: tradeExecutor });
- const { data: upAllowance } = useAllowance(upToken, conditionalRouterAddress);
- const { data: downAllowance } = useAllowance(
- downToken,
- conditionalRouterAddress,
- );
-
- // we only redeem one direction, the app works so as the user only has stake in one direction.
- // if a user happens to have both UP and DOWN tokens somehow, from Seer, they can claim twice.
- const { outcomeIndex, amount, approvalConfig } = useMemo(() => {
+ const redeemToTradeExecutor = useRedeemToTradeExecutor();
+ const handleRedeem = async () => {
if (
- isUndefined(upBalance) ||
- isUndefined(downBalance) ||
- isUndefined(upAllowance) ||
- isUndefined(downAllowance)
+ isUndefined(upBalanceData?.value) ||
+ isUndefined(downBalanceData?.value)
)
- return {
- outcomeIndex: undefined,
- amount: undefined,
- approvalConfig: undefined,
- };
-
- if (upBalance > 0) {
- // 1 index is UP
- return {
- outcomeIndex: BigInt(1),
- amount: upBalance,
- approvalConfig:
- upBalance > upAllowance
- ? { token: upToken, name: "UP", amount: upBalance - upAllowance }
- : undefined,
- };
- }
- if (downBalance > 0) {
- // 0 index is DOWN
- return {
- outcomeIndex: BigInt(0),
- amount: downBalance,
- approvalConfig:
- downBalance > downAllowance
- ? {
- token: downToken,
- name: "DOWN",
- amount: downBalance - downAllowance,
- }
- : undefined,
- };
- }
- return {
- outcomeIndex: undefined,
- amount: undefined,
- approvalConfig: undefined,
- };
- }, [upBalance, upAllowance, downBalance, downAllowance, upToken, downToken]);
-
- const {
- data: redeemPositionConfig,
- isLoading,
- isError,
- } = useSimulateConditionalRouterRedeemConditionalToCollateral({
- query: {
- enabled:
- !isUndefined(outcomeIndex) &&
- !isUndefined(amount) &&
- isUndefined(approvalConfig),
- },
- args: [
- sDaiAddress,
+ return;
+
+ redeemToTradeExecutor.mutate({
+ tradeExecutor,
+ tokens: [upToken, downToken],
+ amounts: [upBalanceData.value, downBalanceData.value],
+ outcomeIndexes: [1n, 0n],
+ parentMarketOutcome: BigInt(parentMarketOutcome),
marketId,
- [outcomeIndex ?? 0n],
- [marketsParentOutcome],
- [amount ?? 0n],
- ],
- });
-
- const { writeContractAsync: redeemPosition } =
- useWriteConditionalRouterRedeemConditionalToCollateral();
-
- const handleRedeem = async () => {
- if (isUndefined(redeemPositionConfig)) return;
- setIsSending(true);
-
- const hash = await redeemPosition(redeemPositionConfig.request);
- await waitForTransactionReceipt(wagmiConfig, {
- hash,
- confirmations: 2,
});
- setIsSending(false);
};
- if (upBalance === 0n && downBalance === 0n) return null;
+ if (isLoadingUpBalance || isLoadingDownBalance) return null;
- return approvalConfig ? (
- {
- queryClient.invalidateQueries();
- }}
- />
- ) : (
+ return (
);
};
diff --git a/src/app/(homepage)/components/ProjectFunding/index.tsx b/src/app/(homepage)/components/ProjectFunding/index.tsx
index 759c923..908abef 100644
--- a/src/app/(homepage)/components/ProjectFunding/index.tsx
+++ b/src/app/(homepage)/components/ProjectFunding/index.tsx
@@ -1,10 +1,11 @@
-import React from "react";
+import React, { useState } from "react";
import { Card, Accordion, NumberField } from "@kleros/ui-components-library";
import clsx from "clsx";
import { useCardInteraction } from "@/context/CardInteractionContext";
import { useMarketContext } from "@/context/MarketContext";
+import { useTradeWallet } from "@/context/TradeWalletContext";
import { isUndefined } from "@/utils";
@@ -13,7 +14,7 @@ import PositionValue from "./PositionValue";
import PredictButton from "./PredictButton";
import PredictionSlider from "./PredictionSlider";
-const ProjectFunding: React.FC = ({}) => {
+const ProjectFunding: React.FC = () => {
const { setActiveCardId } = useCardInteraction();
const {
isUpPredict,
@@ -32,8 +33,13 @@ const ProjectFunding: React.FC = ({}) => {
details,
marketId,
underlyingToken,
+ minValue,
+ maxValue,
} = market;
+ const { tradeExecutor } = useTradeWallet();
+ const [errorMessage, setErrorMessage] = useState();
+
return (
{
isDisabled={!hasLiquidity}
aria-label="Prediction"
className="w-auto [&_input]:border-none"
+ minValue={minValue}
+ maxValue={maxValue}
value={
!isUndefined(prediction) ? prediction / precision : undefined
}
onChange={(e) => setPrediction(e * precision)}
/>
-
+
-
- {!hasLiquidity
- ? "There isn't enough liquidity"
- : `${isUpPredict ? "↑ Higher" : "↓ Lower"} than the market`}
-
+ {errorMessage ? (
+
+ {errorMessage}
+
+ ) : (
+
+ {!hasLiquidity
+ ? "There isn't enough liquidity"
+ : `${isUpPredict ? "↑ Higher" : "↓ Lower"} than the market`}
+
+ )}
void;
+ tradeExecutor: Address;
+}
+
+export const DepositInterface: React.FC = ({
+ tradeExecutor,
+ isOpen,
+ toggleIsOpen,
+}) => {
+ const [amount, setAmount] = useState();
+ const [selectedToken, setSelectedToken] = useState(TokenType.sDAI);
+
+ const { address: account } = useAccount();
+
+ const { data: balanceSDaiData, isLoading: isBalanceLoading } =
+ useTokenBalance({
+ address: account,
+ token: collateral.address,
+ });
+ const { data: balanceXDai, refetch: refetchXDai } = useBalance({
+ address: account,
+ });
+
+ const depositToTradeExecutor = useDepositToTradeExecutor(() => {
+ toggleIsOpen();
+ refetchXDai();
+ });
+
+ const onSubmit = (e: FormEvent) => {
+ e.preventDefault();
+ if (isUndefined(amount)) return;
+
+ depositToTradeExecutor.mutate({
+ token: collateral.address,
+ amount,
+ tradeExecutor,
+ isXDai: selectedToken === TokenType.xDAI,
+ });
+ };
+
+ return (
+
+
+ }
+ onPress={toggleIsOpen}
+ />
+
+
+
+
+ Deposit
+
+
+ Deposit from your account to trade wallet
+
+
+
+
+
+ );
+};
diff --git a/src/app/(homepage)/components/TradeWallet/RedeemInterface.tsx b/src/app/(homepage)/components/TradeWallet/RedeemInterface.tsx
new file mode 100644
index 0000000..7a26765
--- /dev/null
+++ b/src/app/(homepage)/components/TradeWallet/RedeemInterface.tsx
@@ -0,0 +1,173 @@
+import React, { useMemo } from "react";
+
+import { Button, Modal } from "@kleros/ui-components-library";
+import { Address, formatUnits } from "viem";
+
+import { useReadGnosisRouterGetWinningOutcomes } from "@/generated";
+
+import { useRedeemParentsToTradeExecutor } from "@/hooks/tradeWallet/useRedeemParentsToTradeExecutor";
+import { useTokensBalances } from "@/hooks/useTokenBalances";
+
+import LightButton from "@/components/LightButton";
+
+import CloseIcon from "@/assets/svg/close-icon.svg";
+
+import { isUndefined } from "@/utils";
+
+import { markets, parentConditionId } from "@/consts/markets";
+
+interface RedeemParentsInterfaceProps {
+ isOpen: boolean;
+ toggleIsOpen: () => void;
+ tradeExecutor: Address;
+}
+
+export const RedeemParentsInterface: React.FC = ({
+ tradeExecutor,
+ isOpen,
+ toggleIsOpen,
+}) => {
+ const { data: winningOutcomes, isLoading: winningOutcomesLoading } =
+ useReadGnosisRouterGetWinningOutcomes({
+ args: [parentConditionId],
+ });
+
+ const numberOutcomes = useMemo(
+ () =>
+ winningOutcomes?.reduce((acc, outcome) => (outcome ? acc + 1 : acc), 0),
+ [winningOutcomes],
+ );
+
+ const winningTokens = useMemo(() => {
+ if (!winningOutcomesLoading && !isUndefined(winningOutcomes)) {
+ return markets
+ .filter(
+ ({ parentMarketOutcome }) => winningOutcomes[parentMarketOutcome],
+ )
+ .map(({ underlyingToken, parentMarketOutcome }) => ({
+ underlyingToken,
+ index: parentMarketOutcome,
+ }));
+ }
+ }, [winningOutcomesLoading, winningOutcomes]);
+
+ const { data: balances, isLoading: balancesLoading } = useTokensBalances(
+ tradeExecutor,
+ winningTokens?.map(({ underlyingToken }) => underlyingToken) ?? [],
+ );
+
+ const winningTokensWithBalance = useMemo(
+ () =>
+ winningTokens
+ ?.map(({ underlyingToken, index }, i) => ({
+ address: underlyingToken,
+ index,
+ balance: balances?.[i] as bigint,
+ }))
+ .filter(({ balance }) => balance > 0n),
+ [balances, winningTokens],
+ );
+
+ const isCheckingStatus =
+ winningOutcomesLoading ||
+ balancesLoading ||
+ isUndefined(numberOutcomes) ||
+ isUndefined(winningTokensWithBalance);
+
+ // if there is value to be redeemed, its redeemable
+ const isRedeemable = useMemo(() => {
+ if (isCheckingStatus) return;
+ if (isUndefined(numberOutcomes) && numberOutcomes === 0) return false;
+ const totalBalance = winningTokensWithBalance.reduce(
+ (acc, { balance }) => acc + balance,
+ 0n,
+ );
+ return totalBalance > 0n;
+ }, [numberOutcomes, winningTokensWithBalance, isCheckingStatus]);
+
+ // estimatted value of tokens based on number of winning outcomes
+ const totalValue = useMemo(() => {
+ // can be zero if market not resolved yet
+ if (numberOutcomes === 0) return;
+ const totalBalance = winningTokensWithBalance?.reduce(
+ (acc, { balance }) => acc + balance,
+ 0n,
+ );
+
+ if (
+ !isUndefined(totalBalance) &&
+ !isUndefined(winningTokensWithBalance) &&
+ !isUndefined(numberOutcomes)
+ ) {
+ const formattedAmount = parseFloat(
+ formatUnits(totalBalance / BigInt(numberOutcomes), 18),
+ ).toFixed(2);
+ if (formattedAmount !== "0.00") {
+ return formattedAmount;
+ } else if (totalBalance > 0n) {
+ return "< 0.01";
+ }
+ }
+ }, [winningTokensWithBalance, numberOutcomes]);
+
+ const redeemParentsFromTradeExecutor = useRedeemParentsToTradeExecutor(() => {
+ toggleIsOpen();
+ });
+
+ const handleRedeem = () => {
+ if (isUndefined(balances)) return;
+
+ redeemParentsFromTradeExecutor.mutate({
+ tokens: markets.map(({ marketId }) => marketId),
+ outcomeIndexes: markets.map(({ parentMarketOutcome }) =>
+ BigInt(parentMarketOutcome),
+ ),
+ amounts: balances,
+ tradeExecutor,
+ });
+ };
+
+ return (
+
+
+ }
+ onPress={toggleIsOpen}
+ />
+
+
+
+
+ Redeem Tokens
+
+
+ {isCheckingStatus
+ ? "Checking redemptions..."
+ : isRedeemable
+ ? `You have tokens from the selected projects that were not spent.
+ You can redeem up to ${totalValue} sDAI.`
+ : "Nothing to redeem."}
+
+
+
+
+
+
+ );
+};
diff --git a/src/app/(homepage)/components/TradeWallet/TradeWalletSkeleton.tsx b/src/app/(homepage)/components/TradeWallet/TradeWalletSkeleton.tsx
new file mode 100644
index 0000000..d0bbc82
--- /dev/null
+++ b/src/app/(homepage)/components/TradeWallet/TradeWalletSkeleton.tsx
@@ -0,0 +1,21 @@
+import { Card } from "@kleros/ui-components-library";
+import clsx from "clsx";
+
+import { Skeleton } from "@/components/Skeleton";
+
+const TradeWalletSkeleton: React.FC = () => {
+ return (
+
+
+
+
+
+ );
+};
+
+export default TradeWalletSkeleton;
diff --git a/src/app/(homepage)/components/TradeWallet/WithdrawInterface.tsx b/src/app/(homepage)/components/TradeWallet/WithdrawInterface.tsx
new file mode 100644
index 0000000..d605f31
--- /dev/null
+++ b/src/app/(homepage)/components/TradeWallet/WithdrawInterface.tsx
@@ -0,0 +1,145 @@
+import React, { FormEvent, useState } from "react";
+
+import {
+ BigNumberField,
+ Button,
+ Form,
+ Modal,
+} from "@kleros/ui-components-library";
+import clsx from "clsx";
+import { Address, formatUnits, parseUnits } from "viem";
+import { useAccount } from "wagmi";
+
+import { useWithdrawFromTradeExecutor } from "@/hooks/tradeWallet/useWithdrawFromTradeExecutor";
+import { useTokenBalance } from "@/hooks/useTokenBalance";
+
+import LightButton from "@/components/LightButton";
+
+import CloseIcon from "@/assets/svg/close-icon.svg";
+
+import { formatValue } from "@/utils";
+
+import { collateral } from "@/consts";
+
+interface WithdrawInterfaceProps {
+ isOpen: boolean;
+ toggleIsOpen: () => void;
+ tradeExecutor: Address;
+}
+
+export const WithdrawInterface: React.FC = ({
+ tradeExecutor,
+ isOpen,
+ toggleIsOpen,
+}) => {
+ const [amount, setAmount] = useState();
+
+ const { address: account } = useAccount();
+
+ const { data: balanceData, isLoading: isBalanceLoading } = useTokenBalance({
+ address: tradeExecutor,
+ token: collateral.address,
+ });
+ const balance =
+ balanceData && formatUnits(balanceData.value, balanceData.decimals);
+
+ const withdrawFromTradeExecutor = useWithdrawFromTradeExecutor(() => {
+ toggleIsOpen();
+ });
+
+ const onSubmit = (e: FormEvent) => {
+ e.preventDefault();
+ const data = Object.fromEntries(new FormData(e.currentTarget));
+ const depositAmount = data["amount"];
+
+ if (!account) return;
+
+ withdrawFromTradeExecutor.mutate({
+ account,
+ tokens: [collateral.address],
+ amounts: [parseUnits(depositAmount as string, collateral.decimals)],
+ tradeExecutor,
+ });
+ };
+
+ const handleMaxClick = () => {
+ if (balance) {
+ setAmount(balance);
+ }
+ };
+
+ return (
+
+
+ }
+ onPress={toggleIsOpen}
+ />
+
+
+
+
+ Withdraw sDAI
+
+
+ Withdraw from trade wallet to your account
+
+
+
+
+
+ );
+};
diff --git a/src/app/(homepage)/components/TradeWallet/index.tsx b/src/app/(homepage)/components/TradeWallet/index.tsx
new file mode 100644
index 0000000..f9d06c6
--- /dev/null
+++ b/src/app/(homepage)/components/TradeWallet/index.tsx
@@ -0,0 +1,164 @@
+import { Button, Card } from "@kleros/ui-components-library";
+import clsx from "clsx";
+import Link from "next/link";
+import { useToggle } from "react-use";
+import { formatUnits } from "viem";
+import { useAccount } from "wagmi";
+
+import { useCheckTradeExecutorCreated } from "@/hooks/tradeWallet/useCheckTradeExecutorCreated";
+import { useCreateTradeExecutor } from "@/hooks/tradeWallet/useCreateTradeExecutor";
+import { useTokenBalance } from "@/hooks/useTokenBalance";
+
+import WithHelpTooltip from "@/components/WithHelpTooltip";
+
+import ExternalArrow from "@/assets/svg/external-arrow.svg";
+
+import { collateral } from "@/consts";
+
+import { DepositInterface } from "./DepositInterface";
+import { RedeemParentsInterface } from "./RedeemInterface";
+import TradeWalletSkeleton from "./TradeWalletSkeleton";
+import { WithdrawInterface } from "./WithdrawInterface";
+
+export const TradeWallet = () => {
+ const [isDepositOpen, toggleIsDepositOpen] = useToggle(false);
+ const [isWithdrawOpen, toggleIsWithdrawOpen] = useToggle(false);
+ const [isRedeemOpen, toggleIsRedeemOpen] = useToggle(false);
+
+ const { address: account, chain } = useAccount();
+ const { data: checkTradeExecutorResult, isLoading: isLoadingTradeWallet } =
+ useCheckTradeExecutorCreated(account);
+ const createTradeExecutorMutate = useCreateTradeExecutor();
+
+ const { data: balanceData, isLoading: isBalanceLoading } = useTokenBalance({
+ address: checkTradeExecutorResult?.predictedAddress,
+ token: collateral.address,
+ });
+ const balance = balanceData
+ ? Number(formatUnits(balanceData.value, balanceData.decimals))
+ : 0;
+
+ const blockExplorerUrl = chain?.blockExplorers?.default?.url;
+
+ return (
+ <>
+ {isLoadingTradeWallet ? : null}
+ {account &&
+ !isLoadingTradeWallet &&
+ !checkTradeExecutorResult?.isCreated && (
+
+
+ Trade Wallet
+
+
+ Create a trade wallet to make multiple predictions and redeem
+ tokens in a single transaction.
+
+ createTradeExecutorMutate.mutate({ account })}
+ isDisabled={createTradeExecutorMutate.isPending}
+ isLoading={createTradeExecutorMutate.isPending}
+ text="Create Wallet"
+ />
+
+ )}
+ {account && checkTradeExecutorResult?.isCreated && (
+
+ {/* Left side: title + buttons */}
+
+
+
+
+ Trade Wallet
+
+
+
+
+ {checkTradeExecutorResult?.predictedAddress}
+
+
+
+
+
+
+
+
+
+ toggleIsRedeemOpen()}
+ variant="secondary"
+ small
+ text="Redeem outcome tokens"
+ />
+
+
+
+ {/* Right side: balance */}
+
+
+ sDai Balance
+
+
+ {isBalanceLoading ? (
+ Loading...
+ ) : (
+ {balance.toFixed(2)}
+ )}
+
+
+
+ )}
+
+
+
+ >
+ );
+};
diff --git a/src/app/(homepage)/page.tsx b/src/app/(homepage)/page.tsx
index 7394a00..7bcd645 100644
--- a/src/app/(homepage)/page.tsx
+++ b/src/app/(homepage)/page.tsx
@@ -6,6 +6,7 @@ import { useReadGnosisRouterGetWinningOutcomes } from "@/generated";
import { CardInteractionProvider } from "@/context/CardInteractionContext";
import MarketContextProvider from "@/context/MarketContext";
+import { TradeWalletProvider } from "@/context/TradeWalletContext";
import { useChartData } from "@/hooks/useChartData";
import EnsureChain from "@/components/EnsureChain";
@@ -20,10 +21,10 @@ import Chart from "./components/Chart";
import Header from "./components/Header";
import ParticipateSection from "./components/ParticipateSection";
import ProjectFunding from "./components/ProjectFunding";
+import { TradeWallet } from "./components/TradeWallet";
export default function Home() {
- const { data: chartData, isLoading: isLoadingChartData } =
- useChartData(markets);
+ const { data: chartData } = useChartData(markets);
const { data: winningOutcomes } = useReadGnosisRouterGetWinningOutcomes({
args: [parentConditionId],
@@ -45,22 +46,25 @@ export default function Home() {
-
-
-
- {markets.map((market, i) => (
-
-
-
- ))}
-
-
+
+
+
+
+
+
+
+ {markets.map((market, i) => (
+
+
+
+ ))}
+
+
+
diff --git a/src/components/AmountInput.tsx b/src/components/AmountInput.tsx
new file mode 100644
index 0000000..ba3800b
--- /dev/null
+++ b/src/components/AmountInput.tsx
@@ -0,0 +1,117 @@
+import { useMemo } from "react";
+
+import { BigNumberField, DropdownSelect } from "@kleros/ui-components-library";
+import clsx from "clsx";
+import { parseUnits, formatUnits } from "viem";
+
+import DAIIcon from "@/assets/svg/dai.svg";
+
+import { formatValue, isUndefined } from "@/utils";
+
+import LightButton from "./LightButton";
+
+export enum TokenType {
+ sDAI,
+ xDAI,
+}
+interface IAmountInput {
+ setAmount: (amount: bigint) => void;
+ setSelectedToken: (token: TokenType) => void;
+ defaultValue?: bigint;
+ value?: bigint;
+ balance?: bigint;
+ selectedToken: TokenType;
+}
+
+const AmountInput: React.FC
= ({
+ setAmount,
+ selectedToken,
+ setSelectedToken,
+ defaultValue,
+ value,
+ balance,
+}) => {
+ const notEnoughBalance = useMemo(() => {
+ if (!isUndefined(value) && !isUndefined(balance) && value > balance)
+ return true;
+ return false;
+ }, [value, balance]);
+
+ const handleMaxClick = () => {
+ if (!isUndefined(balance)) {
+ setAmount(balance);
+ }
+ };
+
+ return (
+
+
+ {
+ setAmount(parseUnits(e.toString(), 18));
+ }}
+ minValue={"0"}
+ variant={notEnoughBalance ? "error" : undefined}
+ defaultValue={
+ typeof defaultValue !== "undefined"
+ ? formatUnits(defaultValue, 18)
+ : "0"
+ }
+ value={
+ typeof value !== "undefined" ? formatUnits(value, 18) : undefined
+ }
+ />
+ button]:bg-klerosUIComponentsMediumBlue [&>button]:h-11.25 [&>button]:w-fit",
+ "[&>button]:border-none [&>button]:focus:shadow-none",
+ "[&>button]:rounded-l-none",
+ )}
+ callback={(item) => {
+ setSelectedToken(item.itemValue);
+ }}
+ defaultSelectedKey={selectedToken}
+ items={[
+ {
+ text: "sDAI",
+ itemValue: TokenType.sDAI,
+ id: TokenType.sDAI,
+ icon: ,
+ },
+ {
+ text: "xDAI",
+ itemValue: TokenType.xDAI,
+ id: TokenType.xDAI,
+ icon: ,
+ },
+ ]}
+ />
+
+
+ {!notEnoughBalance && (
+
+ {!isUndefined(balance)
+ ? `Available: ${formatValue(balance)}`
+ : "Loading..."}
+
+ )}
+
+ {notEnoughBalance ? "Not enough balance." : undefined}
+
+
+ );
+};
+export default AmountInput;
diff --git a/src/consts/index.ts b/src/consts/index.ts
index e8d4985..b741535 100644
--- a/src/consts/index.ts
+++ b/src/consts/index.ts
@@ -1,4 +1,4 @@
-import { type Abi } from "viem";
+import { Address, type Abi } from "viem";
import { gnosis } from "viem/chains";
import { CondtionalRouterAbi } from "@/abi/ConditionalRouter";
@@ -54,3 +54,14 @@ export const cowSwapAppCode = "futarchy-test";
export const DEFAULT_CHAIN = gnosis;
export const SWAPR_CONTRACT = "0xffb643e73f280b97809a8b41f7232ab401a04ee1";
+
+// trade wallet specific
+export const GNOSIS_CREATE_CALL = "0xBE202e30F21083619F9e8e62440CDe71903b94C4";
+export const SALT_KEY = "TradeExecutorV1";
+export const collateral = {
+ // sDAI
+ address: "0xaf204776c7245bF4147c2612BF6e5972Ee483701" as Address,
+ decimals: 18,
+};
+export const DECIMALS = 18;
+export const VOLUME_MIN = 0.01;
diff --git a/src/consts/markets.ts b/src/consts/markets.ts
index 4607bf5..daf389e 100644
--- a/src/consts/markets.ts
+++ b/src/consts/markets.ts
@@ -1,17 +1,16 @@
import { Address } from "viem";
-export const projectsChosen = 2;
-
-export const marketsParentOutcome = 4n;
+// TODO: update to latest
+export const projectsChosen = 6;
export const parentMarket: Address =
- "0x582d1692198561a7594c5034e57340bc10621e86";
+ "0x6f7ae2815e7e13c14a6560f4b382ae78e7b1493e";
export const parentConditionId =
- "0x4fa791cbbddce9857e1331094273e3834a4a08df5ff4e947027ca3c5eb87751c";
+ "0x0d6c99d7eb9fa657236905b6cf464eaa938371ae5ce8cf153af450321377241d";
export const invalidMarket: Address =
- "0xBF9696d9a921a9F79f3d6f07556Fb7E7052a0B1D";
+ "0x45F2d1Bfa638E0A5f04dFacAAdbDbd0c2044eae8";
export const endTime: number = 1755561599;
@@ -27,93 +26,381 @@ export interface IMarket {
upToken: Address;
downToken: Address;
underlyingToken: Address;
+ invalidToken: Address;
minValue: number;
maxValue: number;
precision: number;
marketId: Address;
+ parentMarketOutcome: number;
details: IDetails;
conditionId: `0x${string}`;
}
export const markets: Array = [
{
- name: "Armenian lentil soup by chef Carl and Sharfy",
+ name: "Judge Dredd (1995)",
color: "#E6194B",
- upToken: "0x4d14D2c9cfa9Fbad1a2c37e861613B39811b5930",
- downToken: "0x1e28C4aA38b58075995303AB65f43351381F44e5",
- underlyingToken: "0xA208E85696Cd7723e7FFBf7394977929ecb848eE",
+ upToken: "0x0ee25eb2e22c01fa832dd5fea5637fba4cd5e870",
+ downToken: "0x4abea4bf9e35f4e957695374c388cee9f83ca1d0",
+ underlyingToken: "0xb72a1271caa3d84d3fbbbcbb0f63ee358b94f96a",
+ invalidToken: "0x11463F43181eB643bA8a584756CCB27a9B8f7B98",
minValue: 0,
- maxValue: 10,
+ maxValue: 100,
precision: 1,
- marketId: "0x966A88Fb357FAc86004beB9618Fb76B39aaD146d",
+ marketId: "0x105d957043ee12f7705efa072af11e718f8c5b83",
+ parentMarketOutcome: 0,
conditionId:
- "0x1998e68781b600d412d5e7dc5f5600a1fe061020cb08b793391faf08cd4551d3",
+ "0x3d963acd72df546f58bf4ea76fda6957c830e6e3f8965517c396fc76dc2c08a3",
details: {
- summary: "Meal prepared by chef Carl and Sharfy on Tuesday 28th of July.",
+ imdbURL:
+ "https://www.imdb.com/title/tt0113492/?ref_=nv_sr_srsg_0_tt_8_nm_0_in_0_q_judge%2520dredd",
+ posterURL:
+ "https://resizing.flixster.com/BsX7kI5BwBsc9xSQPEt5ddA3PI4=/206x305/v2/https://resizing.flixster.com/-XZAfHZM39UwaGJIFWKAE8fS0ak=/v3/t/assets/p16918_p_v8_ae.jpg",
+ summary:
+ "In a dystopian future, Joseph Dredd, the most famous Judge (a police officer with instant field judiciary powers), is convicted for a crime he did not commit and must face his murderous counterpart.",
},
},
{
- name: "Rests by chef Nidhi",
+ name: "Bacurau (2019)",
color: "#3CB44B",
- upToken: "0xAc0d139040CA273348b87fA7cE5a29313e71DdC3",
- downToken: "0x6f3d0aF35C1593659db3f53D51399D58B8729f43",
- underlyingToken: "0x9D92FD3E34b05110988F7e69ee1C8980016aA6C4",
+ upToken: "0x028ec9938471bbad5167c2e5281144a94d1acbe9",
+ downToken: "0x53f82c3f6836dcba9d35450d906286a6ea089a26",
+ underlyingToken: "0xcb1f243baaf93199742e09dc98b16fc8b714b67c",
+ invalidToken: "0x971bd2446cc32dFa26410Cc46978AA0c371Bc48e",
+ minValue: 0,
+ maxValue: 100,
+ precision: 1,
+ marketId: "0x68af0afe82dda5c9c26e6a458a143caad35708d6",
+ parentMarketOutcome: 1,
+ conditionId:
+ "0xa4cc97a4e4f6e02c546a5b3bb49e2c411dcb4c6dcd478cef9cd0c86605c59878",
+ details: {
+ imdbURL:
+ "https://www.imdb.com/title/tt2762506/?ref_=nv_sr_srsg_0_tt_7_nm_1_in_0_q_bacura",
+ posterURL:
+ "https://resizing.flixster.com/MUNwK1o6mdxwkgj-2v86bWf6xXM=/206x305/v2/https://resizing.flixster.com/-cGVSNCtYaLQDwteIiI9LUMoqJ0=/ems.cHJkLWVtcy1hc3NldHMvbW92aWVzL2Y3NWE5YWNjLTRlNzktNGEzYi05NTg5LWNhOTBiYTJlODM1OC53ZWJw",
+ summary:
+ "After the death of her grandmother, Teresa comes home to her matriarchal village in a near-future Brazil to find a succession of sinister events that mobilizes all of its residents.",
+ },
+ },
+ {
+ name: "The Hitchhiker's Guide to the Galaxy (2005)",
+ color: "#FFD93D",
+ upToken: "0xad2248b8eaa3e3a405c1ba79dd436947f8b427df",
+ downToken: "0xdd510abc6a848662371c3455717949035cc24019",
+ underlyingToken: "0xfb06c25e59302d8a0318d6df41a2f29deeea1c8a",
+ invalidToken: "0x43D6E82de1E64531b5E47891b186227edA566344",
+ minValue: 0,
+ maxValue: 100,
+ precision: 1,
+ marketId: "0xfdd8af90af2722d5fe39adf1002fbd069b8a76c0",
+ parentMarketOutcome: 2,
+ conditionId:
+ "0xe97f19928d4143377d3cb97043c90408ccb9c51788447f42d2df9d65694c8171",
+ details: {
+ imdbURL:
+ "https://www.imdb.com/title/tt0371724/?ref_=nv_sr_srsg_0_tt_7_nm_1_in_0_q_the%2520hitch",
+ posterURL:
+ "https://resizing.flixster.com/otfSVWc26cetfV0acq5Z5-E9A60=/206x305/v2/https://resizing.flixster.com/-XZAfHZM39UwaGJIFWKAE8fS0ak=/v3/t/assets/p35755_p_v8_am.jpg",
+ summary: `Mere seconds before the Earth is to be demolished by an alien construction crew, journeyman Arthur Dent is swept off the planet by his friend Ford Prefect, a researcher penning a new edition of "The Hitchhiker's Guide to the Galaxy."`,
+ },
+ },
+ {
+ name: "Everything, Everywhere, All At Once (2022)",
+ color: "#6BCB77",
+ upToken: "0xfa020fcd05e0b91dae83a2a08c5b5533edf8c851",
+ downToken: "0x372d0798ffe8c3aa982a15258c0fea22c6a768df",
+ underlyingToken: "0xe85d556d1aaae2f6027336e468e9c981251a4bef",
+ invalidToken: "0x3Aa738505C22e670a074e60566bD7264e7D682B1",
+ minValue: 0,
+ maxValue: 100,
+ precision: 1,
+ marketId: "0x1f2e76d66047e7f8e0deea373a0c04ffecab31df",
+ parentMarketOutcome: 3,
+ conditionId:
+ "0xdc8f8277da182ee2d5293c754a1cfb8d3761720259cf17a65df61b7cb6983721",
+ details: {
+ imdbURL: "https://www.imdb.com/title/tt6710474/?ref_=fn_all_ttl_1",
+ posterURL:
+ "https://resizing.flixster.com/I2Z0zDTKJdvO7Akh819HROIhZQ4=/206x305/v2/https://resizing.flixster.com/mx-agGjjsUK1QMyuv3AJhHI3hgo=/ems.cHJkLWVtcy1hc3NldHMvbW92aWVzLzA3ZjU2MGU1LWMxODItNDlkMC1hYzJhLTY2YzMwOGZkMDhiZi5qcGc=",
+ summary:
+ "A middle-aged Chinese immigrant is swept up into an insane adventure in which she alone can save existence by exploring other universes and connecting with the lives she could have led.",
+ },
+ },
+ {
+ name: "12 angry men (1957)",
+ color: "#4D96FF",
+ upToken: "0x7ee3806d16dc6a76bef2b11880b70cc70f74fa1a",
+ downToken: "0x34f8572eab463606a014c37ff68b78ac9361cacc",
+ underlyingToken: "0xb3933fd994af5db7ae985a0d62ed2dda918a839b",
+ invalidToken: "0x12c91f543a48F58e3E54c398f19BEc4b62aFD617",
+ minValue: 0,
+ maxValue: 100,
+ precision: 1,
+ marketId: "0x2338ca7d59b7e15bd03dd81cf5f5bb59b6c6c6d4",
+ parentMarketOutcome: 4,
+ conditionId:
+ "0xf857ab39ef39d99f00d38ab07a5676406dfd5382f6d2177c44642e147d8dd0ad",
+ details: {
+ imdbURL:
+ "https://www.imdb.com/title/tt0050083/?ref_=nv_sr_srsg_0_tt_8_nm_0_in_0_q_12%2520angry",
+ posterURL:
+ "https://resizing.flixster.com/FDNKxkwCqhqdzh-IvaGBfzqRb74=/206x305/v2/https://resizing.flixster.com/-XZAfHZM39UwaGJIFWKAE8fS0ak=/v3/t/assets/p2084_p_v8_ar.jpg",
+ summary:
+ "The jury in a New York City murder trial is frustrated by a single member whose skeptical caution forces them to more carefully consider the evidence before jumping to a hasty verdict.",
+ },
+ },
+ {
+ name: "Alien (1979)",
+ color: "#845EC2",
+ upToken: "0x37e70bae5e87327feece73a7c227446571f92137",
+ downToken: "0x31e3d82a613e5aeea7c3a65c3d657cacaaaf2674",
+ underlyingToken: "0x6d0407b5ae419fdd92ffdc64abf04c5f28950e02",
+ invalidToken: "0xe54422171C40aA14B0fc935DEA7AFb85BE15357d",
+ minValue: 0,
+ maxValue: 100,
+ precision: 1,
+ marketId: "0x9a274ea86665d872fc58c8f26fd97a18b844c6ac",
+ parentMarketOutcome: 5,
+ conditionId:
+ "0x8054990ae8221c8a08581381a0d2e3e5f23144a4d18a2398858be52dd94cc8c9",
+ details: {
+ imdbURL:
+ "https://www.imdb.com/title/tt0078748/?ref_=nv_sr_srsg_3_tt_8_nm_0_in_0_q_alien",
+ posterURL:
+ "https://resizing.flixster.com/5R4bkJZC-W_K-YjmIMKAXCbts5Y=/206x305/v2/https://resizing.flixster.com/-XZAfHZM39UwaGJIFWKAE8fS0ak=/v3/t/assets/p2571_p_v8_aw.jpg",
+ summary:
+ "After investigating a mysterious transmission of unknown origin, the crew of a commercial spacecraft encounters a deadly lifeform.",
+ },
+ },
+ {
+ name: "Demolition Man (1993)",
+ color: "#FF9671",
+ upToken: "0x53a9011c5570bfb8148954c4f49a6625dc44077b",
+ downToken: "0x64974d3bf944fafec6fa19a900f3679a716b3a86",
+ underlyingToken: "0x20025021e440edd39d486f3c6a1d7adb9c269faf",
+ invalidToken: "0x406B8Ee2DF07c644414E852542dAB98BdDf39234",
+ minValue: 0,
+ maxValue: 100,
+ precision: 1,
+ marketId: "0xc25af7d4a5cb36bb3ce9faf652a5f7f989a1d57a",
+ parentMarketOutcome: 6,
+ conditionId:
+ "0xe35db6fb9992ab689e21751f036ccc9a8548b71dec3089874cf4a19a13cd34bb",
+ details: {
+ imdbURL:
+ "https://www.imdb.com/title/tt0106697/?ref_=nv_sr_srsg_0_tt_8_nm_0_in_0_q_demolition%2520man",
+ posterURL:
+ "https://resizing.flixster.com/e3iHOpnnUZKRPz_xHJVoLz8TkGM=/206x305/v2/https://resizing.flixster.com/-XZAfHZM39UwaGJIFWKAE8fS0ak=/v3/t/assets/p15098_p_v10_ab.jpg",
+ summary:
+ "A police officer is brought out of suspended animation in prison to pursue an old ultra-violent nemesis who is loose in a non-violent future society.",
+ },
+ },
+ {
+ name: "Barbie (2023)",
+ color: "#0081CF",
+ upToken: "0xaed0fad91e7149ec84bb4d0a2a77be819169275f",
+ downToken: "0x044e1b6d8aacbda5699423578bd200484f7473c3",
+ underlyingToken: "0x67d0f938ea12e7e30b8ccc24dd031d656cc3927d",
+ invalidToken: "0xA9099Baa3b74c1d602aCe8CeaC5933a16A0456C5",
+ minValue: 0,
+ maxValue: 100,
+ precision: 1,
+ marketId: "0xd31d05158722f64b6a49e25bccc47d3203eecbe9",
+ parentMarketOutcome: 7,
+ conditionId:
+ "0x3c102db4f274983b648bd27a4092866e1b81dbc08b8738a5c694a8d8c3948a81",
+ details: {
+ imdbURL:
+ "https://www.imdb.com/title/tt1517268/?ref_=nv_sr_srsg_1_tt_6_nm_1_in_0_q_barbie",
+ posterURL:
+ "https://resizing.flixster.com/r409CsU-O1gEcAP0VtU6tDD9sKI=/206x305/v2/https://resizing.flixster.com/-XZAfHZM39UwaGJIFWKAE8fS0ak=/v3/t/assets/p13472534_p_v8_am.jpg",
+ summary:
+ "Barbie and Ken are having the time of their lives in the seemingly perfect world of Barbie Land. However, when they get a chance to go to the outside world, they soon discover the joys and perils of living among regular humans.",
+ },
+ },
+ {
+ name: "Eduardo e Mônica (2020)",
+ color: "#FFC75F",
+ upToken: "0x9d64a3e7e55880f3c8f9c584ed32397bb6f0b9f6",
+ downToken: "0xe9d025d3cbd783d6a92626b650a32f7cbaca0e7d",
+ underlyingToken: "0x58ce7a53abeca1db90cec0e6b7dcbe3a36d986c4",
+ invalidToken: "0xcA4c82fd178aaf4b72ECe35774ce04B7Aa2E5361",
+ minValue: 0,
+ maxValue: 100,
+ precision: 1,
+ marketId: "0x13d48a73811c01f574e1bfa4c58b7d95d2f590e4",
+ parentMarketOutcome: 8,
+ conditionId:
+ "0x2dcf754f36437ea0c298e5d27a0f3904dc2335a6e239b15a104f3ca7787c5926",
+ details: {
+ imdbURL:
+ "https://www.imdb.com/title/tt8747460/?ref_=nv_sr_srsg_0_tt_2_nm_0_in_0_q_Eduardo%2520e%2520M%25C3%25B4nica%2520(2020)",
+ posterURL:
+ "https://resizing.flixster.com/IaXbRF4gIPh9jireK_4VCPNfdKc=/200x0/v2/https://resizing.flixster.com/-XZAfHZM39UwaGJIFWKAE8fS0ak=/v3/t/assets/p18824656_k_v8_aa.jpg",
+ summary:
+ "On an unusual day, a series of coincidences lead Eduardo to meet Monica at a party. Curiosity is aroused between the two and, despite not being alike, they fall madly in love. This love needs to mature and learn to overcome differences.",
+ },
+ },
+ {
+ name: "Thor: The Dark World (2013)",
+ color: "#00C9A7",
+ upToken: "0x0c569fbc021119b778ea160efd718a5d592ef46c",
+ downToken: "0xd8d2dfe1912239451b5a4a0462006e95393f2151",
+ underlyingToken: "0x72ec9aade867b5b41705c6a83f66bc56485669b5",
+ invalidToken: "0xFa2e53b2E33309CEE9255b440f143308F92BbA83",
+ minValue: 0,
+ maxValue: 100,
+ precision: 1,
+ marketId: "0x878a332b5efc0a4bf983036beece050352baa73d",
+ parentMarketOutcome: 9,
+ conditionId:
+ "0xb223aad8405c321b761e3cba872e556c1de3a8b552a38249d626bc5aff7c6ba2",
+ details: {
+ imdbURL:
+ "https://www.imdb.com/title/tt1981115/?ref_=nv_sr_srsg_0_tt_8_nm_0_in_0_q_thor%2520the%2520dark",
+ posterURL:
+ "https://resizing.flixster.com/HtozfP_2NYit3_l7s-cbtsiuWps=/206x305/v2/https://resizing.flixster.com/-XZAfHZM39UwaGJIFWKAE8fS0ak=/v3/t/assets/p9530219_p_v13_aa.jpg",
+ summary:
+ "When the Dark Elves attempt to plunge the universe into darkness, Thor must embark on a perilous and personal journey that will reunite him with doctor Jane Foster.",
+ },
+ },
+ {
+ name: "Talk to me (2022)",
+ color: "#C34A36",
+ upToken: "0xf3c17e909bd1f9367ecdc786d137465d7ee96b6a",
+ downToken: "0xf99be182b6b0e6d994509ecdced281b94100435f",
+ underlyingToken: "0x2b3a8ac53ba42da13f542a867d2859642fb1db44",
+ invalidToken: "0x94b6580034e1FFf008Ac8370dF69E180740469b0",
+ minValue: 0,
+ maxValue: 100,
+ precision: 1,
+ marketId: "0xee4a77447069f32f555f3d75aaba18a4acb54ac4",
+ parentMarketOutcome: 10,
+ conditionId:
+ "0x715f9e8ccc373f85e2f9ec02bba8d23c5f87090b729750ca8adac5b0f969213e",
+ details: {
+ imdbURL:
+ "https://www.imdb.com/title/tt10638522/?ref_=nv_sr_srsg_0_tt_8_nm_0_in_0_q_talk%2520to%2520me",
+ posterURL:
+ "https://resizing.flixster.com/ejS3S8JOBfvZr_fQ_--6SyKKJpQ=/206x305/v2/https://resizing.flixster.com/9WxKriao1BmRamIaqig2k8hd5uM=/ems.cHJkLWVtcy1hc3NldHMvbW92aWVzL2YyZDQwYTM2LWZmYzEtNGUwMC05NzRkLTA3ODM0NThiNDE4Ny5qcGc=",
+ summary:
+ "When a group of friends discover how to conjure spirits using an embalmed hand, they become hooked on the new thrill, until one of them goes too far and unleashes terrifying supernatural forces.",
+ },
+ },
+ {
+ name: "Fast & Furious 6 (2013)",
+ color: "#9B51E0",
+ upToken: "0x850d2ffa4475296cfbbd76247894a773e3b1be6c",
+ downToken: "0xb28c716f63b0dd272f62e25765a914baeebab8c2",
+ underlyingToken: "0x71c3df5edcab48cfb6a1a99255eff063f33b6265",
+ invalidToken: "0xb3cE80d6b30DcC4d605B290f4dC1Fc3B8C2bcC3b",
+ minValue: 0,
+ maxValue: 100,
+ precision: 1,
+ marketId: "0x38a2923cc391b9cd926e5a2d07462dc7d189c407",
+ parentMarketOutcome: 11,
+ conditionId:
+ "0x27f341cdecacbd7ff0e4bb7b28add74ddaa388ff9f16bc749e2828a71fe6a5f6",
+ details: {
+ imdbURL:
+ "https://www.imdb.com/title/tt1905041/?ref_=nv_sr_srsg_0_tt_8_nm_0_in_0_q_fast%2520%2526%2520furious%25206",
+ posterURL:
+ "https://resizing.flixster.com/dJUU6CNK8IBSjsImW4nXCxxUVwU=/206x305/v2/https://resizing.flixster.com/-XZAfHZM39UwaGJIFWKAE8fS0ak=/v3/t/assets/p9573130_p_v7_ab.jpg",
+ summary:
+ "Hobbs has Dominic and Brian reassemble their crew to take down a team of mercenaries, but Dominic unexpectedly gets sidetracked with facing his presumed deceased girlfriend, Letty.",
+ },
+ },
+ {
+ name: "Elysium (2013)",
+ color: "#2D4059",
+ upToken: "0xe9427a7a32daad2d29db2aad809b2a44060d8fc8",
+ downToken: "0x75b5cd86828f7c9009e30619a83b1b2da67f1342",
+ underlyingToken: "0xf52e0e144b73a0d5748bc53667efe3ba62fe5695",
+ invalidToken: "0x69641B6664a493ecF467D4D9aAB595A8b9Cc4a66",
minValue: 0,
- maxValue: 10,
+ maxValue: 100,
precision: 1,
- marketId: "0xbD77A9454f4dBB99a22eEa1FEbd4a0380f9Ff5B7",
+ marketId: "0xc0dab34c6c2008391bdc742cec0bd0afb60d4d59",
+ parentMarketOutcome: 12,
conditionId:
- "0xe164ff8c0eb2ce35e7577c834450b0f7c5a400384bbaac608614f0b6234b5d7f",
+ "0x2d2ee6e67d4ffa2c2a14898a29d0afe3d3cdd8ad362811aad64770a90553cb3a",
details: {
- summary: "Meal prepared by chef Nidhi on Thursday 29th of July.",
+ imdbURL:
+ "https://www.imdb.com/title/tt1535108/?ref_=nv_sr_srsg_0_tt_8_nm_0_in_0_q_elysium",
+ posterURL:
+ "https://resizing.flixster.com/WlkdhZWddtMIv8U2Tmlb74rmBZ4=/206x305/v2/https://resizing.flixster.com/-XZAfHZM39UwaGJIFWKAE8fS0ak=/v3/t/assets/p9360879_p_v10_ar.jpg",
+ summary:
+ "In the year 2154, the very wealthy live on a man-made space station while the rest of the population resides on a ruined Earth. A man takes on a mission that could bring equality to the polarized worlds.",
},
},
{
- name: "Crêpes by chef Clément",
- color: "#FFA500",
- upToken: "0xa12B6c17068BbeD4D67898FbC9630B5A32e02319",
- downToken: "0x34802E9d1C06b846d4B6b3e56FfA2Bde4259E582",
- underlyingToken: "0x73ADB9f2907839833A96721b41AEAE4Ba37BfC09",
+ name: "Session 9 (2001)",
+ color: "#F9F871",
+ upToken: "0xe080c03ad6bc9f8fd5b45b5d3bf14ebcfa1ec0b5",
+ downToken: "0x76cce8491785789c2c5542f043ec6c35b12cd909",
+ underlyingToken: "0x1086a95c224dd586809a7f4d875b4f09d2ac9290",
+ invalidToken: "0x4F2b7EC3aAC8Bb0Ffb272a4B27B758D2FFC31bc6",
minValue: 0,
- maxValue: 10,
+ maxValue: 100,
precision: 1,
- marketId: "0xF681F411466bdBDA81384Da94C9FFD4D53e807e4",
+ marketId: "0xa7cf69c4c93d2f6811a394e92320979c3cf86b37",
+ parentMarketOutcome: 13,
conditionId:
- "0xa656847808341964a1223418a18b519df76566b48ee32c65d0a30897284f41cf",
+ "0x6bc6c6fd532a02ec128e7c8dfe3e496295f677c861405a88b7da503f1882eef8",
details: {
- summary: "Meal prepared by chef Clément on Friday 30th of July.",
+ imdbURL:
+ "https://www.imdb.com/title/tt0261983/?ref_=nv_sr_srsg_0_tt_8_nm_0_in_0_q_session%25209",
+ posterURL:
+ "https://resizing.flixster.com/pMiw8blJew0YXddZivo7mtYlUDg=/206x305/v2/https://resizing.flixster.com/-XZAfHZM39UwaGJIFWKAE8fS0ak=/v3/t/assets/p28177_p_v13_ac.jpg",
+ summary:
+ "Tensions rise within an asbestos cleaning crew as they work in an abandoned mental hospital with a horrific past that seems to be coming back.",
},
},
{
- name: "Takeout Sandwiches",
- color: "#911EB4",
- upToken: "0x808000c9001BE6665F9Aa2Ac608C908830DFD0bC",
- downToken: "0xC418B2885925Dfe063BdAa0ad801104788a5105F",
- underlyingToken: "0x7cf8005B84ea5413f339Cdc711F918a834A52110",
+ name: "Mamma Mia! (2008)",
+ color: "#B0A8B9",
+ upToken: "0xfa82984fc8ddeb71fdb2e6e471f30995178ad5f0",
+ downToken: "0x5d528dbec7e37927d8af41bfb1b54e7641dd3ccb",
+ underlyingToken: "0x11ed86c399f455819f495cda1256e9b52afd0971",
+ invalidToken: "0x756de0795875f925AC95ba37472D26bC4375c6a4",
minValue: 0,
- maxValue: 10,
+ maxValue: 100,
precision: 1,
- marketId: "0x93D5F295f714f4b425E3E74523eD6FDF75754B1a",
+ marketId: "0x96638d67ac5bc5f8223f9e2d60e92f4d8dcf3147",
+ parentMarketOutcome: 14,
conditionId:
- "0xeed90eb06cd31126b544abb589b320107b4aae29fc19562b01764ba6a056add2",
+ "0x6e5b27306498d2917cdde6a3ea4791cd5a6fe8d8bf33d491c97524c431eda325",
details: {
- summary: "Takeout sandwiches on Monday 4th of August.",
+ imdbURL:
+ "https://www.imdb.com/title/tt0795421/?ref_=nv_sr_srsg_0_tt_7_nm_1_in_0_q_mamma%2520mia",
+ posterURL:
+ "https://resizing.flixster.com/sD29k0EMFXDWY0DPiFoQsaxqDNU=/206x305/v2/https://resizing.flixster.com/-XZAfHZM39UwaGJIFWKAE8fS0ak=/v3/t/assets/p176344_p_v8_al.jpg",
+ summary:
+ "Donna, an independent hotelier, is preparing for her daughter's wedding with the help of two old friends. Meanwhile Sophie, the spirited bride, has a plan. She invites three men from her mother's past in hope of meeting her real father.",
},
},
{
- name: "Indian-Spanish fusion by Nidhi/Carlos/David.",
- color: "#46F0F0",
- upToken: "0x2D14505D0551F58236469c09945d9114aFF22bdc",
- downToken: "0x4A82570C62f57C25228D694a1616C17B1e2fd894",
- underlyingToken: "0x81b1d03fD5Ca06A801ECa2259446D2c9b2237d1C",
+ name: "Ethereum (2022)",
+ color: "#FF8066",
+ upToken: "0xf8313845248f2392a39bdcd50be0781c7cf497c1",
+ downToken: "0x3befdfbd7c2a7139acafc3005369d30ff2cd8f9a",
+ underlyingToken: "0x78c2edb5639af0ed4351f001c728c9026820887e",
+ invalidToken: "0x8eB59F4590fF6a0037a159ea1601D9d309aEa598",
minValue: 0,
- maxValue: 10,
+ maxValue: 100,
precision: 1,
- marketId: "0xe93b7cE7911B16f5E72C2Bb347fBcE8f81BAc69F",
+ marketId: "0x002c70343ddef063d0ad8da91104934318800d30",
+ parentMarketOutcome: 15,
conditionId:
- "0xaffd86c9d68bf40f00a54e97709f37d2cb937ae3e406553911be1779174fec71",
+ "0x2b9e73d1da8dc051ffe4972114f59e61ad1bfd65fda93d88bcfb6644ffb07f4b",
details: {
- summary: "Meal prepared by Nidhi/Carlos/David on Tuesday 5th of August.",
+ imdbURL:
+ "https://www.imdb.com/title/tt22069858/?ref_=nv_sr_srsg_2_tt_8_nm_0_in_0_q_ethereum",
+ posterURL:
+ "https://play-lh.googleusercontent.com/ARlYF4lUWeSFL9CgcKmHIesZwjsRjB0qkCKyIcLYckxYdrAkmvz1RKLQ_RFPRQuedofL8xOeCBtz-MIStG8=w240-h480-rw",
+ summary:
+ "Learn About the hottest cryptocurrency around, Ethereum. This amazing documentary explores the history of Ethereum, a decentralized, open-source blockchain with smart contract functionality.",
},
},
];
diff --git a/src/context/MarketContext.tsx b/src/context/MarketContext.tsx
index 17a108b..ab621d9 100644
--- a/src/context/MarketContext.tsx
+++ b/src/context/MarketContext.tsx
@@ -7,130 +7,87 @@ import React, {
useMemo,
useState,
useEffect,
- useCallback,
} from "react";
-import { SwaprV3Trade } from "@swapr/sdk";
-import { formatUnits } from "viem";
+import { useDebounce } from "react-use";
-import { useAlternateRoute } from "@/hooks/useAlternateRoute";
-import { useBalance } from "@/hooks/useBalance";
-import { IChartData } from "@/hooks/useChartData";
+import { useCurrentMarketPrices } from "@/hooks/liquidity/useCurrentMarketPrices";
import { useGetWinningOutcomes } from "@/hooks/useGetWinningOutcomes";
import { useMarketPrice } from "@/hooks/useMarketPrice";
-import { useMarketQuote } from "@/hooks/useMarketQuote";
import { isUndefined } from "@/utils";
import { IMarket, parentConditionId } from "@/consts/markets";
-import { useCardInteraction } from "./CardInteractionContext";
-
interface IMarketContext {
upPrice: number;
downPrice: number;
marketPrice: number;
marketEstimate: number;
- marketQuote: SwaprV3Trade | null | undefined;
- marketDownQuote: SwaprV3Trade | null | undefined;
- mintSellQuote: SwaprV3Trade | null | undefined;
- mintReBuyQuote: SwaprV3Trade | null | undefined;
- expectedFromMintRoute?: number;
- expectedFromDefaultRoute?: number;
- percentageIncrease: string;
isUpPredict: boolean;
- differenceBetweenRoutes: number;
prediction: number | undefined;
setPrediction: (prediction: number) => void;
market: IMarket;
- isLoading: boolean;
isLoadingMarketPrice: boolean;
showEstimateVariant: boolean;
hasLiquidity: boolean | undefined;
- refetchQuotes: () => void;
isResolved: boolean;
isParentResolved: boolean;
+ // if this market was selected
selected?: boolean;
+ predictedPrice: number;
}
const MarketContext = createContext(undefined);
interface IMarketContextProvider extends IMarket {
children: ReactNode;
- lastDataPoint: IChartData[string]["data"][number] | undefined;
- isLoadingChartData: boolean;
selected?: boolean;
}
const MarketContextProvider: React.FC = ({
children,
- lastDataPoint,
selected,
- isLoadingChartData,
...market
}) => {
- const { activeCardId } = useCardInteraction();
+ // const { activeCardId } = useCardInteraction();
- const { underlyingToken, upToken, downToken, maxValue, precision, marketId } =
- market;
+ const { underlyingToken, upToken, downToken, maxValue, precision } = market;
const [prediction, setPrediction] = useState(undefined);
- const [isRefetching, setIsRefetching] = useState(false);
+ const [debouncedPrediction, setDebouncedPrediction] = useState();
+
+ useDebounce(
+ () => {
+ setDebouncedPrediction(prediction);
+ },
+ 500,
+ [prediction],
+ );
- const { data: underlyingBalance, refetch: refetchUnderlyingBalance } =
- useBalance(underlyingToken);
+ // const { data: underlyingBalance } = useBalance(underlyingToken);
- const shouldFetch =
- marketId === activeCardId &&
- !isUndefined(underlyingBalance) &&
- underlyingBalance !== 0n;
+ // const shouldFetch =
+ // marketId === activeCardId &&
+ // !isUndefined(underlyingBalance) &&
+ // underlyingBalance !== 0n;
- const { data: marketPriceRaw, isLoading: isLoadingMarketPrice } =
- useMarketPrice(upToken, underlyingToken);
+ const { data: marketPriceRaw } = useMarketPrice(upToken, underlyingToken);
- const {
- data: marketQuote,
- isLoading: isLoadingMarketQuote,
- refetch: refetchMarktetUpQuote,
- } = useMarketQuote(
- upToken,
+ const currentPrices = useCurrentMarketPrices(
underlyingToken,
- underlyingBalance ? formatUnits(underlyingBalance, 18) : "1",
- shouldFetch,
- );
-
- const upPrice = useMemo(
- () => 1 / parseFloat(marketQuote?.executionPrice.toFixed(4) ?? "0"),
- [marketQuote],
+ upToken,
+ downToken,
);
- const hasLiquidity = useMemo(() => marketPriceRaw?.status, [marketPriceRaw]);
+ const isLoadingMarketPrice = isUndefined(currentPrices);
- const marketPrice = useMemo(() => {
- if (hasLiquidity) {
- return parseFloat(marketPriceRaw?.price ?? "0");
- } else if (!isUndefined(lastDataPoint?.value)) {
- return lastDataPoint?.value / maxValue;
- } else {
- return 0;
- }
- }, [marketPriceRaw, hasLiquidity, lastDataPoint, maxValue]);
+ const marketPrice = currentPrices?.upPrice ?? 0;
- const {
- data: marketDownQuote,
- isLoading: isLoadingMarketDownQuote,
- refetch: refetchMarktetDownQuote,
- } = useMarketQuote(
- downToken,
- underlyingToken,
- underlyingBalance ? formatUnits(underlyingBalance, 18) : "1",
- shouldFetch,
- );
+ const hasLiquidity = useMemo(() => marketPriceRaw?.status, [marketPriceRaw]);
- const downPrice = useMemo(
- () => 1 / parseFloat(marketDownQuote?.executionPrice.toFixed(4) ?? "0"),
- [marketDownQuote],
- );
+ const upPrice = marketPrice;
+ const downPrice = currentPrices?.downPrice ?? 0;
const marketEstimate = useMemo(
() =>
@@ -140,6 +97,15 @@ const MarketContextProvider: React.FC = ({
[marketPrice, maxValue, precision],
);
+ const isUpPredict = (prediction ?? 0) > marketEstimate;
+
+ // adjusts the price based on predicted direction, for DOWN predictedPrice = 1 - estimateMade
+ const predictedPrice = useMemo(() => {
+ if (typeof debouncedPrediction === "undefined") return 0;
+
+ return debouncedPrediction / (maxValue * precision);
+ }, [debouncedPrediction, maxValue, precision]);
+
useEffect(() => {
if (
isUndefined(prediction) &&
@@ -152,8 +118,6 @@ const MarketContextProvider: React.FC = ({
}
}, [prediction, marketEstimate, market.precision]);
- const isUpPredict = (prediction ?? 0) > marketEstimate;
-
const showEstimateVariant = useMemo(() => {
if (isUndefined(prediction) || !hasLiquidity) return false;
return (
@@ -162,111 +126,6 @@ const MarketContextProvider: React.FC = ({
);
}, [prediction, market, marketEstimate, hasLiquidity]);
- const {
- data: upToDownAlternateRoute,
- isLoading: isLoadingUpAlternateRoute,
- refetch: refetchUpAlternateRoute,
- } = useAlternateRoute(
- upToken,
- downToken,
- underlyingToken,
- formatUnits(underlyingBalance ?? 0n, 18),
- shouldFetch,
- );
-
- const {
- data: downToUpAlternateRoute,
- isLoading: isLoadingDownAlternateRoute,
- refetch: refetchDownAlternateRoute,
- } = useAlternateRoute(
- downToken,
- upToken,
- underlyingToken,
- formatUnits(underlyingBalance ?? 0n, 18),
- shouldFetch,
- );
-
- const refetchQuotes = useCallback(() => {
- setIsRefetching(true);
- refetchUnderlyingBalance().then(async () => {
- await Promise.all([
- refetchUpAlternateRoute(),
- refetchDownAlternateRoute(),
- refetchMarktetUpQuote(),
- refetchMarktetDownQuote(),
- ]);
-
- setIsRefetching(false);
- });
- }, [
- refetchUnderlyingBalance,
- refetchDownAlternateRoute,
- refetchUpAlternateRoute,
- refetchMarktetDownQuote,
- refetchMarktetUpQuote,
- ]);
-
- const expectedFromMintRoute = useMemo(
- () =>
- isUpPredict
- ? upToDownAlternateRoute?.amountAcquired
- : downToUpAlternateRoute?.amountAcquired,
- [isUpPredict, upToDownAlternateRoute, downToUpAlternateRoute],
- );
-
- const expectedFromDefaultRoute = useMemo(
- () =>
- isUpPredict
- ? Number(marketQuote?.outputAmount.toExact())
- : Number(marketDownQuote?.outputAmount.toExact()),
- [isUpPredict, marketQuote, marketDownQuote],
- );
-
- const mintSellQuote = useMemo(
- () =>
- isUpPredict
- ? upToDownAlternateRoute?.sellQuote
- : downToUpAlternateRoute?.sellQuote,
- [isUpPredict, upToDownAlternateRoute, downToUpAlternateRoute],
- );
-
- const mintReBuyQuote = useMemo(
- () =>
- isUpPredict
- ? upToDownAlternateRoute?.reBuyQuote
- : downToUpAlternateRoute?.reBuyQuote,
- [isUpPredict, upToDownAlternateRoute, downToUpAlternateRoute],
- );
-
- const percentageIncrease = useMemo(() => {
- if (
- isUndefined(expectedFromMintRoute) ||
- isUndefined(expectedFromDefaultRoute)
- )
- return "0%";
- return (
- ((expectedFromMintRoute - expectedFromDefaultRoute) /
- expectedFromDefaultRoute) *
- 100
- ).toFixed(2);
- }, [expectedFromMintRoute, expectedFromDefaultRoute]);
-
- const differenceBetweenRoutes = useMemo(() => {
- if (
- isUndefined(expectedFromMintRoute) ||
- isUndefined(expectedFromDefaultRoute)
- )
- return 0;
- return expectedFromMintRoute - expectedFromDefaultRoute;
- }, [expectedFromMintRoute, expectedFromDefaultRoute]);
-
- const isLoading =
- isLoadingMarketQuote ||
- isLoadingMarketDownQuote ||
- isLoadingUpAlternateRoute ||
- isLoadingDownAlternateRoute ||
- isRefetching;
-
const { data: winningOutcomes } = useGetWinningOutcomes(market.conditionId);
const isResolved = useMemo(
() =>
@@ -292,55 +151,34 @@ const MarketContextProvider: React.FC = ({
downPrice,
marketPrice,
marketEstimate,
- marketQuote,
- marketDownQuote,
- mintSellQuote,
- mintReBuyQuote,
- expectedFromMintRoute,
- percentageIncrease,
isUpPredict,
- differenceBetweenRoutes,
prediction,
setPrediction,
market,
- isLoading,
- isLoadingMarketPrice: hasLiquidity
- ? isLoadingMarketPrice
- : isLoadingChartData,
- expectedFromDefaultRoute,
+ isLoadingMarketPrice,
showEstimateVariant,
hasLiquidity,
- refetchQuotes,
isResolved,
isParentResolved,
selected,
+ predictedPrice,
}),
[
upPrice,
downPrice,
marketPrice,
marketEstimate,
- marketQuote,
- marketDownQuote,
- mintSellQuote,
- mintReBuyQuote,
- expectedFromMintRoute,
- percentageIncrease,
isUpPredict,
- differenceBetweenRoutes,
prediction,
setPrediction,
market,
- isLoading,
isLoadingMarketPrice,
- expectedFromDefaultRoute,
showEstimateVariant,
hasLiquidity,
- refetchQuotes,
isResolved,
isParentResolved,
selected,
- isLoadingChartData,
+ predictedPrice,
],
);
diff --git a/src/context/TradeWalletContext.tsx b/src/context/TradeWalletContext.tsx
new file mode 100644
index 0000000..171e99c
--- /dev/null
+++ b/src/context/TradeWalletContext.tsx
@@ -0,0 +1,56 @@
+import { createContext, useContext, useMemo } from "react";
+
+import { Address, zeroAddress } from "viem";
+import { useAccount } from "wagmi";
+
+import { useCheckTradeExecutorCreated } from "@/hooks/tradeWallet/useCheckTradeExecutorCreated";
+
+import { isUndefined } from "@/utils";
+
+interface ITradeWalletContext {
+ tradeExecutor: Address;
+}
+const TradeWalletContext = createContext(
+ undefined,
+);
+
+export const useTradeWallet = (): ITradeWalletContext => {
+ const context = useContext(TradeWalletContext);
+ if (!context) throw Error("TradeWallet not initialized");
+
+ return context;
+};
+
+export const TradeWalletProvider = ({
+ children,
+}: {
+ children: React.ReactNode;
+}) => {
+ const { address } = useAccount();
+ const { data: checkTradeWalletResult } =
+ useCheckTradeExecutorCreated(address);
+
+ const tradeExecutor = checkTradeWalletResult?.predictedAddress ?? zeroAddress;
+ // const isCreated = checkTradeWalletResult?.isCreated;
+
+ const value = useMemo(() => ({ tradeExecutor }), [tradeExecutor]);
+ return (
+
+ {/* {isLoading ? (
+
+ Fetching trade wallet...
+
+ ) : null} */}
+
+ {/* {!isUndefined(isCreated) && !isCreated ? (
+
+ Please create a trade wallet to start predicting.
+
+ ) : null} */}
+
+ {!isUndefined(tradeExecutor) && tradeExecutor !== zeroAddress
+ ? children
+ : null}
+
+ );
+};
diff --git a/src/contracts/CreateCall.sol b/src/contracts/CreateCall.sol
new file mode 100644
index 0000000..13838d8
--- /dev/null
+++ b/src/contracts/CreateCall.sol
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: MIT
+pragma solidity 0.8.24;
+
+contract CreateCall {
+ /// @notice Emitted when a new contract is created
+ event ContractCreation(address indexed newContract);
+
+ /**
+ * @notice Deploys a new contract using the create2 opcode.
+ * @param value The value in wei to be sent with the contract creation.
+ * @param deploymentData The initialisation code of the contract to be created.
+ * @param salt The salt value to use for the contract creation.
+ * @return newContract The address of the newly created contract.
+ */
+ function performCreate2(uint256 value, bytes memory deploymentData, bytes32 salt) public returns (address newContract) {
+
+ assembly {
+ newContract := create2(value, add(0x20, deploymentData), mload(deploymentData), salt)
+ }
+ require(newContract != address(0), "Could not deploy contract");
+ emit ContractCreation(newContract);
+ }
+}
\ No newline at end of file
diff --git a/src/contracts/TradeExecutor.sol b/src/contracts/TradeExecutor.sol
new file mode 100644
index 0000000..88e0ab4
--- /dev/null
+++ b/src/contracts/TradeExecutor.sol
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: MIT
+pragma solidity 0.8.30;
+
+contract TradeExecutor {
+ struct Call {
+ address to;
+ bytes data;
+ }
+
+ struct ValueCall {
+ address to;
+ uint256 value;
+ bytes data;
+ }
+
+ /// @dev Contract owner
+ address public immutable owner;
+
+ /// @dev Modifier to restrict access to owner only
+ modifier onlyOwner() {
+ require(msg.sender == owner, "Caller is not the owner");
+ _;
+ }
+
+ /// @dev Constructor.
+ /// @param _owner Immutable owner of the contract.
+ constructor(
+ address _owner
+ ) {
+ owner = _owner;
+ }
+
+ /// @dev Execute calls in a single transaction. Only callable by owner.
+ /// @param calls Array of calls to execute
+ function batchExecute(Call[] calldata calls) external onlyOwner {
+ for (uint i = 0; i < calls.length; i++) {
+ (bool success,) = calls[i].to.call(calls[i].data);
+ require(success, "Call failed");
+ }
+ }
+
+ /// @dev Execute calls with value in a single transaction. Only callable by owner.
+ /// @param calls Array of calls to execute
+ function batchValueExecute(ValueCall[] calldata calls) external payable onlyOwner {
+ for (uint i = 0; i < calls.length; i++) {
+ (bool success,) = calls[i].to.call{value: calls[i].value}(calls[i].data);
+ require(success, "Call failed");
+ }
+ }
+
+ /// @dev Receive ETH.
+ receive() external payable { }
+}
\ No newline at end of file
diff --git a/src/contracts/abis/CreateCallAbi.ts b/src/contracts/abis/CreateCallAbi.ts
new file mode 100644
index 0000000..ee4417e
--- /dev/null
+++ b/src/contracts/abis/CreateCallAbi.ts
@@ -0,0 +1,44 @@
+export const CreateCallAbi = [
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: true,
+ internalType: "address",
+ name: "newContract",
+ type: "address",
+ },
+ ],
+ name: "ContractCreation",
+ type: "event",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint256",
+ name: "value",
+ type: "uint256",
+ },
+ {
+ internalType: "bytes",
+ name: "deploymentData",
+ type: "bytes",
+ },
+ {
+ internalType: "bytes32",
+ name: "salt",
+ type: "bytes32",
+ },
+ ],
+ name: "performCreate2",
+ outputs: [
+ {
+ internalType: "address",
+ name: "newContract",
+ type: "address",
+ },
+ ],
+ stateMutability: "nonpayable",
+ type: "function",
+ },
+];
diff --git a/src/contracts/abis/TradeExecutorAbi.ts b/src/contracts/abis/TradeExecutorAbi.ts
new file mode 100644
index 0000000..a3b06de
--- /dev/null
+++ b/src/contracts/abis/TradeExecutorAbi.ts
@@ -0,0 +1,88 @@
+export const TradeExecutorAbi = [
+ {
+ inputs: [
+ {
+ internalType: "address",
+ name: "_owner",
+ type: "address",
+ },
+ ],
+ stateMutability: "nonpayable",
+ type: "constructor",
+ },
+ {
+ inputs: [
+ {
+ components: [
+ {
+ internalType: "address",
+ name: "to",
+ type: "address",
+ },
+ {
+ internalType: "bytes",
+ name: "data",
+ type: "bytes",
+ },
+ ],
+ internalType: "struct TradeExecutor.Call[]",
+ name: "calls",
+ type: "tuple[]",
+ },
+ ],
+ name: "batchExecute",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ components: [
+ {
+ internalType: "address",
+ name: "to",
+ type: "address",
+ },
+ {
+ internalType: "uint256",
+ name: "value",
+ type: "uint256",
+ },
+ {
+ internalType: "bytes",
+ name: "data",
+ type: "bytes",
+ },
+ ],
+ internalType: "struct TradeExecutor.ValueCall[]",
+ name: "calls",
+ type: "tuple[]",
+ },
+ ],
+ name: "batchValueExecute",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "owner",
+ outputs: [
+ {
+ internalType: "address",
+ name: "",
+ type: "address",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ stateMutability: "payable",
+ type: "receive",
+ },
+];
+
+export const TradeExecutorBytecode =
+ "60a060405234801561000f575f5ffd5b506040516109ee3803806109ee833981810160405281019061003191906100c9565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506100f4565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100988261006f565b9050919050565b6100a88161008e565b81146100b2575f5ffd5b50565b5f815190506100c38161009f565b92915050565b5f602082840312156100de576100dd61006b565b5b5f6100eb848285016100b5565b91505092915050565b6080516108d66101185f395f818160b20152818160d6015261029801526108d65ff3fe608060405260043610610037575f3560e01c80638da5cb5b14610042578063b1bdad271461006c578063fc792715146100945761003e565b3661003e57005b5f5ffd5b34801561004d575f5ffd5b506100566100b0565b60405161006391906104c1565b60405180910390f35b348015610077575f5ffd5b50610092600480360381019061008d9190610543565b6100d4565b005b6100ae60048036038101906100a991906105e3565b610296565b005b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610162576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161015990610688565b60405180910390fd5b5f5f90505b82829050811015610291575f838383818110610186576101856106a6565b5b905060200281019061019891906106df565b5f0160208101906101a99190610730565b73ffffffffffffffffffffffffffffffffffffffff168484848181106101d2576101d16106a6565b5b90506020028101906101e491906106df565b80602001906101f3919061075b565b6040516102019291906107f9565b5f604051808303815f865af19150503d805f811461023a576040519150601f19603f3d011682016040523d82523d5f602084013e61023f565b606091505b5050905080610283576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027a9061085b565b60405180910390fd5b508080600101915050610167565b505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610324576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031b90610688565b60405180910390fd5b5f5f90505b8282905081101561047d575f838383818110610348576103476106a6565b5b905060200281019061035a9190610879565b5f01602081019061036b9190610730565b73ffffffffffffffffffffffffffffffffffffffff16848484818110610394576103936106a6565b5b90506020028101906103a69190610879565b602001358585858181106103bd576103bc6106a6565b5b90506020028101906103cf9190610879565b80604001906103de919061075b565b6040516103ec9291906107f9565b5f6040518083038185875af1925050503d805f8114610426576040519150601f19603f3d011682016040523d82523d5f602084013e61042b565b606091505b505090508061046f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104669061085b565b60405180910390fd5b508080600101915050610329565b505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6104ab82610482565b9050919050565b6104bb816104a1565b82525050565b5f6020820190506104d45f8301846104b2565b92915050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f840112610503576105026104e2565b5b8235905067ffffffffffffffff8111156105205761051f6104e6565b5b60208301915083602082028301111561053c5761053b6104ea565b5b9250929050565b5f5f60208385031215610559576105586104da565b5b5f83013567ffffffffffffffff811115610576576105756104de565b5b610582858286016104ee565b92509250509250929050565b5f5f83601f8401126105a3576105a26104e2565b5b8235905067ffffffffffffffff8111156105c0576105bf6104e6565b5b6020830191508360208202830111156105dc576105db6104ea565b5b9250929050565b5f5f602083850312156105f9576105f86104da565b5b5f83013567ffffffffffffffff811115610616576106156104de565b5b6106228582860161058e565b92509250509250929050565b5f82825260208201905092915050565b7f43616c6c6572206973206e6f7420746865206f776e65720000000000000000005f82015250565b5f61067260178361062e565b915061067d8261063e565b602082019050919050565b5f6020820190508181035f83015261069f81610666565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f823560016040038336030381126106fa576106f96106d3565b5b80830191505092915050565b61070f816104a1565b8114610719575f5ffd5b50565b5f8135905061072a81610706565b92915050565b5f60208284031215610745576107446104da565b5b5f6107528482850161071c565b91505092915050565b5f5f83356001602003843603038112610777576107766106d3565b5b80840192508235915067ffffffffffffffff821115610799576107986106d7565b5b6020830192506001820236038313156107b5576107b46106db565b5b509250929050565b5f81905092915050565b828183375f83830152505050565b5f6107e083856107bd565b93506107ed8385846107c7565b82840190509392505050565b5f6108058284866107d5565b91508190509392505050565b7f43616c6c206661696c65640000000000000000000000000000000000000000005f82015250565b5f610845600b8361062e565b915061085082610811565b602082019050919050565b5f6020820190508181035f83015261087281610839565b9050919050565b5f82356001606003833603038112610894576108936106d3565b5b8083019150509291505056fea26469706673582212209acee26af9ddc0af3038daa5c3ab8f63390e2ad5a7e7a5b701e2bfb8411df8eb64736f6c634300081e0033";
diff --git a/src/hooks/liquidity/getTicksData.ts b/src/hooks/liquidity/getTicksData.ts
new file mode 100644
index 0000000..a85ba94
--- /dev/null
+++ b/src/hooks/liquidity/getTicksData.ts
@@ -0,0 +1,74 @@
+import { Address } from "viem";
+
+import {
+ OrderDirection,
+ Tick_OrderBy,
+ getSdk as getSwaprSdk,
+ GetTicksQuery,
+} from "./gql/gql";
+
+import { PoolInfo, getPools } from "./useMarketPools";
+import { getSwaprClient } from "./utils";
+
+async function getTicks(poolId: string) {
+ const graphQLClient = getSwaprClient();
+ if (!graphQLClient) {
+ throw new Error("Subgraph not available");
+ }
+
+ const graphQLSdk = getSwaprSdk;
+ let total: GetTicksQuery["ticks"] = [];
+ let tickIdx = "";
+ while (true) {
+ const { ticks } = await graphQLSdk(graphQLClient).GetTicks({
+ first: 1000,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ orderBy: Tick_OrderBy.TickIdx as any,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ orderDirection: OrderDirection.Asc as any,
+ where: {
+ poolAddress: poolId,
+ // liquidityNet_not: "0",
+ ...(tickIdx && { tickIdx_gt: tickIdx }),
+ },
+ });
+ total = total.concat(ticks);
+ tickIdx = ticks[ticks.length - 1]?.tickIdx;
+ if (ticks.length < 1000) {
+ break;
+ }
+ }
+ return total;
+}
+
+export async function getPoolAndTicksData(token0: Address, token1: Address) {
+ try {
+ const pools = await getPools().fetch({ token0, token1 });
+
+ const ticksByPool = await Promise.all(
+ pools.map((pool) => getTicks(pool.id)),
+ );
+
+ return pools.reduce(
+ (acc, curr, index) => {
+ acc[curr.id] = {
+ ticks: ticksByPool[index],
+ poolInfo: pools[index],
+ };
+ return acc;
+ },
+ {} as {
+ [key: string]: {
+ ticks: {
+ tickIdx: string;
+ liquidityNet: string;
+ }[];
+ poolInfo: PoolInfo;
+ };
+ },
+ );
+ } catch (e) {
+ console.error("getTicksData", e);
+ return {};
+ }
+}
diff --git a/src/hooks/liquidity/swapr.graphql b/src/hooks/liquidity/swapr.graphql
new file mode 100644
index 0000000..50597ff
--- /dev/null
+++ b/src/hooks/liquidity/swapr.graphql
@@ -0,0 +1,76 @@
+query GetPools(
+ $skip: Int = 0
+ $first: Int
+ $orderBy: Pool_orderBy
+ $orderDirection: OrderDirection
+ $where: Pool_filter
+ $block: Block_height
+ $subgraphError: _SubgraphErrorPolicy_! = deny
+) {
+ pools(
+ skip: $skip
+ first: $first
+ orderBy: $orderBy
+ orderDirection: $orderDirection
+ where: $where
+ block: $block
+ subgraphError: $subgraphError
+ ) {
+ id
+ fee
+ liquidity
+ tickSpacing
+ sqrtPrice
+ tick
+ token0 {
+ id
+ symbol
+ name
+ decimals
+ __typename
+ }
+ token1 {
+ id
+ symbol
+ name
+ decimals
+ __typename
+ }
+ token0Price
+ token1Price
+ volumeToken0
+ volumeToken1
+ volumeUSD
+ txCount
+ totalValueLockedToken0
+ totalValueLockedToken1
+ totalValueLockedUSD
+ totalValueLockedUSDUntracked
+ untrackedVolumeUSD
+ feesUSD
+ __typename
+ }
+}
+
+query GetTicks(
+ $skip: Int = 0
+ $first: Int
+ $where: Tick_filter
+ $orderBy: Tick_orderBy
+ $orderDirection: OrderDirection
+ $block: Block_height
+ $subgraphError: _SubgraphErrorPolicy_! = deny
+) {
+ ticks(
+ skip: $skip
+ first: $first
+ orderBy: $orderBy
+ orderDirection: $orderDirection
+ where: $where
+ block: $block
+ subgraphError: $subgraphError
+ ) {
+ tickIdx
+ liquidityNet
+ }
+}
diff --git a/src/hooks/liquidity/useCurrentMarketPrices.ts b/src/hooks/liquidity/useCurrentMarketPrices.ts
new file mode 100644
index 0000000..91e7207
--- /dev/null
+++ b/src/hooks/liquidity/useCurrentMarketPrices.ts
@@ -0,0 +1,46 @@
+import { useMemo } from "react";
+
+import { Address } from "viem";
+
+import { useTicksData } from "./useTicksData";
+import { tickToPrice, isTwoStringsEqual } from "./utils";
+
+interface MarketPrices {
+ upPrice: number;
+ downPrice: number;
+}
+
+/**
+ * Returns current UP and DOWN market prices from Uniswap pool.
+ *
+ * @param underlying The collateral/underlying token address.
+ * @param upToken The UP outcome token address.
+ * @param downToken The DOWN outcome token address.
+ */
+export function useCurrentMarketPrices(
+ underlying: Address,
+ upToken: Address,
+ downToken: Address,
+): MarketPrices | undefined {
+ const { data: upPoolData } = useTicksData(underlying, upToken);
+ const { data: downPoolData } = useTicksData(underlying, downToken);
+
+ return useMemo(() => {
+ if (!upPoolData || !downPoolData) return undefined;
+
+ const { poolInfo: upPool } = Object.values(upPoolData)[0];
+ const { poolInfo: downPool } = Object.values(downPoolData)[0];
+
+ const upPriceArr = tickToPrice(upPool.tick);
+ const downPriceArr = tickToPrice(downPool.tick);
+
+ const upPrice = Number(
+ upPriceArr[isTwoStringsEqual(upPool.token0, upToken) ? 0 : 1],
+ );
+ const downPrice = Number(
+ downPriceArr[isTwoStringsEqual(downPool.token0, downToken) ? 0 : 1],
+ );
+
+ return { upPrice, downPrice };
+ }, [upToken, downToken, upPoolData, downPoolData]);
+}
diff --git a/src/hooks/liquidity/useMarketPools.ts b/src/hooks/liquidity/useMarketPools.ts
new file mode 100644
index 0000000..72c8add
--- /dev/null
+++ b/src/hooks/liquidity/useMarketPools.ts
@@ -0,0 +1,86 @@
+import * as batshit from "@yornaath/batshit";
+import memoize from "micro-memoize";
+import { Address } from "viem";
+
+import {
+ OrderDirection,
+ Pool_OrderBy as SwaprPool_OrderBy,
+ getSdk as getSwaprSdk,
+ GetPoolsQuery,
+} from "./gql/gql";
+
+import { getSwaprClient } from "./utils";
+
+export interface PoolInfo {
+ id: Address;
+ dex: string;
+ fee: number;
+ token0: Address;
+ token1: Address;
+ token0Price: number;
+ token1Price: number;
+ token0Symbol: string;
+ token1Symbol: string;
+ totalValueLockedToken0: number;
+ totalValueLockedToken1: number;
+ liquidity: bigint;
+ tick: number;
+ tickSpacing: number;
+}
+
+async function getSwaprPools(
+ tokens: { token0: Address; token1: Address }[],
+): Promise {
+ const algebraClient = getSwaprClient();
+
+ if (!algebraClient) {
+ throw new Error("Subgraph not available");
+ }
+
+ const { pools } = await getSwaprSdk(algebraClient).GetPools({
+ where: {
+ or: tokens.map((t) => ({
+ token0: t.token0.toLocaleLowerCase(),
+ token1: t.token1.toLocaleLowerCase(),
+ })),
+ },
+ orderBy: SwaprPool_OrderBy.TotalValueLockedUsd,
+ orderDirection: OrderDirection.Desc,
+ first: 1000,
+ });
+
+ return await Promise.all(
+ pools.map(async (pool: GetPoolsQuery["pools"][number]) => ({
+ id: pool.id as Address,
+ dex: "Swapr",
+ fee: Number(pool.fee),
+ token0: pool.token0.id as Address,
+ token1: pool.token1.id as Address,
+ token0Price: Number(pool.token0Price),
+ token1Price: Number(pool.token1Price),
+ liquidity: BigInt(pool.liquidity),
+ tick: Number(pool.tick),
+ tickSpacing: Number(pool.tickSpacing),
+ token0Symbol: pool.token0.symbol,
+ token1Symbol: pool.token1.symbol,
+ totalValueLockedToken0: Number(pool.totalValueLockedToken0),
+ totalValueLockedToken1: Number(pool.totalValueLockedToken1),
+ })),
+ );
+}
+
+export const getPools = memoize(() => {
+ return batshit.create({
+ name: "getPools",
+ fetcher: async (tokens: { token0: Address; token1: Address }[]) => {
+ return getSwaprPools(tokens);
+ },
+ scheduler: batshit.windowScheduler(10),
+ resolver: (pools, tokens) =>
+ pools.filter(
+ (p) =>
+ p.token0 === tokens.token0.toLocaleLowerCase() &&
+ p.token1 === tokens.token1.toLocaleLowerCase(),
+ ),
+ });
+});
diff --git a/src/hooks/liquidity/useTicksData.ts b/src/hooks/liquidity/useTicksData.ts
new file mode 100644
index 0000000..de4ea8f
--- /dev/null
+++ b/src/hooks/liquidity/useTicksData.ts
@@ -0,0 +1,28 @@
+import { useQuery } from "@tanstack/react-query";
+import { Address } from "viem";
+
+import { getPoolAndTicksData } from "./getTicksData";
+import { PoolInfo } from "./useMarketPools";
+import { getToken0Token1 } from "./utils";
+
+export const useTicksData = (underlying: Address, outcome: Address) => {
+ return useQuery<
+ | {
+ [key: string]: {
+ ticks: {
+ tickIdx: string;
+ liquidityNet: string;
+ }[];
+ poolInfo: PoolInfo;
+ };
+ }
+ | undefined,
+ Error
+ >({
+ queryKey: ["useTicksData", underlying, outcome],
+ queryFn: async () => {
+ const { token0, token1 } = getToken0Token1(underlying, outcome);
+ return await getPoolAndTicksData(token0, token1);
+ },
+ });
+};
diff --git a/src/hooks/liquidity/useVolumeUntilPrice.ts b/src/hooks/liquidity/useVolumeUntilPrice.ts
new file mode 100644
index 0000000..b27a519
--- /dev/null
+++ b/src/hooks/liquidity/useVolumeUntilPrice.ts
@@ -0,0 +1,150 @@
+import { TickMath, encodeSqrtRatioX96 } from "@uniswap/v3-sdk";
+import { Address, formatUnits } from "viem";
+
+import { useTicksData } from "./useTicksData";
+import { decimalToFraction, tickToPrice, isTwoStringsEqual } from "./utils";
+
+function getVolumeWithinRange(
+ currentSqrtPriceX96: bigint,
+ targetSqrtPriceX96: bigint,
+ liquidity: bigint,
+ isOutcomeToken0: boolean,
+ swapType: "buy" | "sell",
+): number {
+ if (swapType === "buy") {
+ if (isOutcomeToken0) {
+ // Buy token0: price goes UP, we're trading token1 for token0
+ // Amount of token0 we get: Δx = L * (√P_target - √P_current) / (√P_target * √P_current)
+ const amount0 =
+ (liquidity * (1n << 96n) * (targetSqrtPriceX96 - currentSqrtPriceX96)) /
+ (targetSqrtPriceX96 * currentSqrtPriceX96);
+ return Number(formatUnits(amount0, 18));
+ }
+ // Buy token1: price goes DOWN, we're trading token0 for token1
+ // Amount of token1 we get: Δy = L * (√P_current - √P_target) / (2^96)
+ const amount1 =
+ (liquidity * (currentSqrtPriceX96 - targetSqrtPriceX96)) / (1n << 96n);
+ return Number(formatUnits(amount1, 18));
+ }
+ if (isOutcomeToken0) {
+ // Sell token0: price goes DOWN, we're trading token0 for token1
+ // Amount of token0 we sell: Δx = L * (√P_current - √P_target) / (√P_target * √P_current)
+ const amount0 =
+ (liquidity * (1n << 96n) * (currentSqrtPriceX96 - targetSqrtPriceX96)) /
+ (targetSqrtPriceX96 * currentSqrtPriceX96);
+ return Number(formatUnits(amount0, 18));
+ }
+ // Sell token1: price goes UP, we're trading token1 for token0
+ // Amount of token1 we sell: Δy = L * (√P_target - √P_current) / (2^96)
+ const amount1 =
+ (liquidity * (targetSqrtPriceX96 - currentSqrtPriceX96)) / (1n << 96n);
+ return Number(formatUnits(amount1, 18));
+}
+
+export function getVolumeUntilPrice(
+ pool: {
+ liquidity: bigint;
+ tickSpacing: number;
+ tick: number;
+ token0: Address;
+ token1: Address;
+ },
+ ticks: { liquidityNet: string; tickIdx: string }[],
+ targetPrice: number,
+ outcome: Address,
+ swapType: "buy" | "sell",
+): number {
+ const isOutcomeToken0 = isTwoStringsEqual(pool.token0, outcome);
+ // Exact sqrt prices for current and target
+ let currentSqrtPriceX96 = BigInt(
+ TickMath.getSqrtRatioAtTick(pool.tick).toString(),
+ );
+ const [num, den] = decimalToFraction(
+ isOutcomeToken0 ? targetPrice : 1 / targetPrice,
+ );
+ const targetSqrtPriceX96 = BigInt(encodeSqrtRatioX96(num, den).toString());
+
+ // Determine direction and filter/sort ticks
+ const movingUp =
+ (isOutcomeToken0 && swapType === "buy") ||
+ (!isOutcomeToken0 && swapType === "sell");
+ if (movingUp && targetSqrtPriceX96 <= currentSqrtPriceX96) return 0;
+ if (!movingUp && targetSqrtPriceX96 >= currentSqrtPriceX96) return 0;
+
+ let relevantTicks: { liquidityNet: string; tickIdx: string }[];
+ if (movingUp) {
+ relevantTicks = ticks
+ .filter((tick) => Number(tick.tickIdx) > pool.tick)
+ .sort((a, b) => Number(a.tickIdx) - Number(b.tickIdx));
+ } else {
+ relevantTicks = ticks
+ .filter((tick) => Number(tick.tickIdx) < pool.tick)
+ .sort((a, b) => Number(b.tickIdx) - Number(a.tickIdx));
+ }
+
+ let volume = 0;
+ let liquidity = pool.liquidity;
+
+ for (let i = 0; i < relevantTicks.length; i++) {
+ const tick = Number(relevantTicks[i].tickIdx);
+ const sqrtAtTick = BigInt(TickMath.getSqrtRatioAtTick(tick).toString());
+
+ // Check if target price is between current position and this tick
+ let targetWithinRange = false;
+ if (movingUp) {
+ targetWithinRange = targetSqrtPriceX96 <= sqrtAtTick;
+ } else {
+ targetWithinRange = targetSqrtPriceX96 >= sqrtAtTick;
+ }
+
+ if (targetWithinRange) {
+ // Target is within this range, calculate partial volume and stop
+ volume += getVolumeWithinRange(
+ currentSqrtPriceX96,
+ targetSqrtPriceX96,
+ liquidity,
+ isOutcomeToken0,
+ swapType,
+ );
+ break;
+ }
+
+ // Otherwise, swap to tick boundary fully
+ volume += getVolumeWithinRange(
+ currentSqrtPriceX96,
+ sqrtAtTick,
+ liquidity,
+ isOutcomeToken0,
+ swapType,
+ );
+
+ // Move state to next tick
+ currentSqrtPriceX96 = sqrtAtTick;
+ liquidity += BigInt(relevantTicks[i].liquidityNet) * (movingUp ? 1n : -1n);
+ }
+
+ return volume;
+}
+
+export function useVolumeUntilPrice(
+ underlying: Address,
+ outcome: Address,
+ swapType: "buy" | "sell",
+ targetPrice: number | undefined,
+) {
+ const { data: ticksByPool } = useTicksData(underlying, outcome);
+ if (!ticksByPool || !targetPrice || targetPrice > 1 || targetPrice < 0) {
+ return;
+ }
+
+ const { ticks, poolInfo } = Object.values(ticksByPool)[0];
+ const currentPrice = Number(
+ tickToPrice(poolInfo.tick)[
+ isTwoStringsEqual(poolInfo.token0, outcome) ? 0 : 1
+ ],
+ );
+ if (currentPrice === targetPrice) {
+ return;
+ }
+ return getVolumeUntilPrice(poolInfo, ticks, targetPrice, outcome, swapType);
+}
diff --git a/src/hooks/liquidity/useVolumeUntilPriceDual.ts b/src/hooks/liquidity/useVolumeUntilPriceDual.ts
new file mode 100644
index 0000000..4d2edd2
--- /dev/null
+++ b/src/hooks/liquidity/useVolumeUntilPriceDual.ts
@@ -0,0 +1,205 @@
+import { useQuery } from "@tanstack/react-query";
+import { TickMath, encodeSqrtRatioX96 } from "@uniswap/v3-sdk";
+import { Address, formatUnits } from "viem";
+
+import { clamp, isUndefined } from "@/utils";
+
+import { useTicksData } from "./useTicksData";
+import { decimalToFraction, isTwoStringsEqual, tickToPrice } from "./utils";
+
+const MIN_PRICE = 0.0001;
+const MAX_PRICE = 0.9999;
+
+function getVolumeWithinRangeDual(
+ currentSqrtPriceX96: bigint,
+ targetSqrtPriceX96: bigint,
+ liquidity: bigint,
+ isOutcomeToken0: boolean,
+ swapType: "buy" | "sell",
+): { outcomeVolume: number; collateralVolume: number } {
+ // initialize both to zero
+ let outcomeVolume = 0;
+ let collateralVolume = 0;
+
+ if (swapType === "buy") {
+ if (isOutcomeToken0) {
+ // Buying token0 (outcome), paying token1 (collateral)
+ // Δx (outcome bought) = L * (√P_target - √P_current) / (√P_target * √P_current)
+ // Δy (collateral spent) = L * (√P_target - √P_current)
+ const deltaSqrt = targetSqrtPriceX96 - currentSqrtPriceX96;
+ const amountOutcome =
+ (liquidity * (1n << 96n) * deltaSqrt) /
+ (targetSqrtPriceX96 * currentSqrtPriceX96);
+ const amountCollateral = (liquidity * deltaSqrt) / (1n << 96n);
+
+ outcomeVolume = Number(formatUnits(amountOutcome, 18));
+ collateralVolume = Number(formatUnits(amountCollateral, 18));
+ } else {
+ // Buying token1 (outcome), paying token0 (collateral)
+ // Δy (outcome bought) = L * (√P_current - √P_target) / (2^96)
+ // Δx (collateral spent) = L * (√P_current - √P_target) / (√P_current * √P_target)
+ const deltaSqrt = currentSqrtPriceX96 - targetSqrtPriceX96;
+ const amountOutcome = (liquidity * deltaSqrt) / (1n << 96n);
+ const amountCollateral =
+ (liquidity * (1n << 96n) * deltaSqrt) /
+ (targetSqrtPriceX96 * currentSqrtPriceX96);
+
+ outcomeVolume = Number(formatUnits(amountOutcome, 18));
+ collateralVolume = Number(formatUnits(amountCollateral, 18));
+ }
+ } else {
+ if (isOutcomeToken0) {
+ // Selling token0 (outcome), receiving token1 (collateral)
+ // Δx (outcome sold) = L * (√P_current - √P_target) / (√P_target * √P_current)
+ // Δy (collateral received) = L * (√P_current - √P_target)
+ const deltaSqrt = currentSqrtPriceX96 - targetSqrtPriceX96;
+ const amountOutcome =
+ (liquidity * (1n << 96n) * deltaSqrt) /
+ (targetSqrtPriceX96 * currentSqrtPriceX96);
+ const amountCollateral = (liquidity * deltaSqrt) / (1n << 96n);
+
+ outcomeVolume = Number(formatUnits(amountOutcome, 18));
+ collateralVolume = Number(formatUnits(amountCollateral, 18));
+ } else {
+ // Selling token1 (outcome), receiving token0 (collateral)
+ // Δy (outcome sold) = L * (√P_target - √P_current) / (2^96)
+ // Δx (collateral received) = L * (√P_target - √P_current) / (√P_target * √P_current)
+ const deltaSqrt = targetSqrtPriceX96 - currentSqrtPriceX96;
+ const amountOutcome = (liquidity * deltaSqrt) / (1n << 96n);
+ const amountCollateral =
+ (liquidity * (1n << 96n) * deltaSqrt) /
+ (targetSqrtPriceX96 * currentSqrtPriceX96);
+
+ outcomeVolume = Number(formatUnits(amountOutcome, 18));
+ collateralVolume = Number(formatUnits(amountCollateral, 18));
+ }
+ }
+
+ return { outcomeVolume, collateralVolume };
+}
+
+export function getVolumeUntilPriceDual(
+ pool: {
+ liquidity: bigint;
+ tickSpacing: number;
+ tick: number;
+ token0: Address;
+ token1: Address;
+ },
+ ticks: { liquidityNet: string; tickIdx: string }[],
+ targetPrice: number,
+ outcome: Address,
+ swapType: "buy" | "sell",
+): { outcomeVolume: number; collateralVolume: number } {
+ const clampedTarget = clamp(targetPrice, MIN_PRICE, MAX_PRICE);
+
+ const isOutcomeToken0 = isTwoStringsEqual(pool.token0, outcome);
+ let currentSqrtPriceX96 = BigInt(
+ TickMath.getSqrtRatioAtTick(pool.tick).toString(),
+ );
+ const [num, den] = decimalToFraction(
+ isOutcomeToken0 ? clampedTarget : 1 / clampedTarget,
+ );
+ const targetSqrtPriceX96 = BigInt(encodeSqrtRatioX96(num, den).toString());
+
+ const movingUp =
+ (isOutcomeToken0 && swapType === "buy") ||
+ (!isOutcomeToken0 && swapType === "sell");
+ if (movingUp && targetSqrtPriceX96 <= currentSqrtPriceX96)
+ return { outcomeVolume: 0, collateralVolume: 0 };
+ if (!movingUp && targetSqrtPriceX96 >= currentSqrtPriceX96)
+ return { outcomeVolume: 0, collateralVolume: 0 };
+
+ const relevantTicks = ticks
+ .filter((tick) =>
+ movingUp
+ ? Number(tick.tickIdx) > pool.tick
+ : Number(tick.tickIdx) < pool.tick,
+ )
+ .sort((a, b) =>
+ movingUp
+ ? Number(a.tickIdx) - Number(b.tickIdx)
+ : Number(b.tickIdx) - Number(a.tickIdx),
+ );
+
+ let totalOutcome = 0;
+ let totalCollateral = 0;
+ let liquidity = pool.liquidity;
+
+ for (let i = 0; i < relevantTicks.length; i++) {
+ const tick = Number(relevantTicks[i].tickIdx);
+ const sqrtAtTick = BigInt(TickMath.getSqrtRatioAtTick(tick).toString());
+
+ const targetWithinRange = movingUp
+ ? targetSqrtPriceX96 <= sqrtAtTick
+ : targetSqrtPriceX96 >= sqrtAtTick;
+
+ const rangeEnd = targetWithinRange ? targetSqrtPriceX96 : sqrtAtTick;
+ const { outcomeVolume, collateralVolume } = getVolumeWithinRangeDual(
+ currentSqrtPriceX96,
+ rangeEnd,
+ liquidity,
+ isOutcomeToken0,
+ swapType,
+ );
+
+ totalOutcome += outcomeVolume;
+ totalCollateral += collateralVolume;
+
+ if (targetWithinRange) break;
+
+ currentSqrtPriceX96 = sqrtAtTick;
+ liquidity += BigInt(relevantTicks[i].liquidityNet) * (movingUp ? 1n : -1n);
+ }
+
+ return { outcomeVolume: totalOutcome, collateralVolume: totalCollateral };
+}
+
+/**
+ * @returns "{collateral, outcome}" - Gives the amount of collateral and outcome volume/token
+ * you would need to reach the target price, whether it's buy or sell
+ */
+
+export function useVolumeUntilPriceDual(
+ underlying: Address,
+ outcome: Address,
+ swapType: "buy" | "sell",
+ targetPrice: number | undefined,
+ enabled = true,
+) {
+ const { data: ticksByPool } = useTicksData(underlying, outcome);
+
+ return useQuery({
+ queryKey: [
+ "volumeUntilPriceDual",
+ underlying,
+ outcome,
+ swapType,
+ targetPrice,
+ ],
+ enabled:
+ !!ticksByPool &&
+ !isUndefined(targetPrice) &&
+ targetPrice >= 0 &&
+ targetPrice <= 1 &&
+ enabled,
+ queryFn: async () => {
+ const { ticks, poolInfo } = Object.values(ticksByPool!)[0];
+ const currentPrice = Number(
+ tickToPrice(poolInfo.tick)[
+ isTwoStringsEqual(poolInfo.token0, outcome) ? 0 : 1
+ ],
+ );
+ if (currentPrice === targetPrice)
+ return { outcomeVolume: 0, collateralVolume: 0 };
+
+ return getVolumeUntilPriceDual(
+ poolInfo,
+ ticks,
+ targetPrice!,
+ outcome,
+ swapType,
+ );
+ },
+ });
+}
diff --git a/src/hooks/liquidity/utils.ts b/src/hooks/liquidity/utils.ts
new file mode 100644
index 0000000..6fc5dcb
--- /dev/null
+++ b/src/hooks/liquidity/utils.ts
@@ -0,0 +1,225 @@
+import { TickMath } from "@uniswap/v3-sdk";
+import { BigNumber } from "ethers";
+import { GraphQLClient } from "graphql-request";
+import { Address, formatUnits } from "viem";
+
+export function tickToPrice(
+ tick: number,
+ decimals = 18,
+ keepPrecision = false,
+) {
+ const sqrtPriceX96 = BigInt(TickMath.getSqrtRatioAtTick(tick).toString());
+ const bn = BigNumber.from(sqrtPriceX96);
+
+ const TWO_POW_96 = BigNumber.from(2).pow(96);
+
+ const price0 = bn
+ .mul(bn) // square it
+ .mul(BigNumber.from(10).pow(decimals))
+ .div(TWO_POW_96)
+ .div(TWO_POW_96)
+ .toBigInt();
+ const price1 = TWO_POW_96.mul(TWO_POW_96)
+ .mul(BigNumber.from(10).pow(decimals))
+ .div(bn)
+ .div(bn)
+ .toBigInt();
+ if (keepPrecision) {
+ return [formatUnits(price0, 18), formatUnits(price1, 18)];
+ }
+ return [
+ Number(formatUnits(price0, 18)).toFixed(4),
+ Number(formatUnits(price1, 18)).toFixed(4),
+ ];
+}
+
+export function sqrtPriceX96ToPrice(
+ sqrtPriceX96: bigint,
+ decimals = 18,
+ keepPrecision = false,
+) {
+ const bn = BigNumber.from(sqrtPriceX96);
+
+ const TWO_POW_96 = BigNumber.from(2).pow(96);
+
+ const price0 = bn
+ .mul(bn) // square it
+ .mul(BigNumber.from(10).pow(decimals))
+ .div(TWO_POW_96)
+ .div(TWO_POW_96)
+ .toBigInt();
+ const price1 = TWO_POW_96.mul(TWO_POW_96)
+ .mul(BigNumber.from(10).pow(decimals))
+ .div(bn)
+ .div(bn)
+ .toBigInt();
+ if (keepPrecision) {
+ return [formatUnits(price0, 18), formatUnits(price1, 18)];
+ }
+ return [
+ Number(formatUnits(price0, 18)).toFixed(4),
+ Number(formatUnits(price1, 18)).toFixed(4),
+ ];
+}
+
+export function decimalToFraction(x: number): [string, string] {
+ const str = x.toString();
+ if (!str.includes(".")) return [String(x), "1"];
+ const decimals = str.split(".")[1].length;
+ const numerator = Math.round(x * 10 ** decimals);
+ const denominator = 10 ** decimals;
+ return [String(numerator), String(denominator)];
+}
+
+export const getGraphUrl = () => {
+ const coreUrl =
+ process.env.NEXT_PUBLIC_ALGEBRA_SUBGRAPH ??
+ "Environment variables NEXT_PUBLIC_ALGEBRA_SUBGRAPH not set.";
+
+ return coreUrl;
+};
+
+export const getSwaprClient = () => {
+ return new GraphQLClient(getGraphUrl());
+};
+
+// ===
+export interface Question {
+ id: `0x${string}`;
+ arbitrator: Address;
+ opening_ts: number;
+ timeout: number;
+ finalize_ts: number;
+ is_pending_arbitration: boolean;
+ best_answer: `0x${string}`;
+ bond: bigint;
+ min_bond: bigint;
+ base_question: `0x${string}`;
+}
+
+export type VerificationStatus =
+ | "verified"
+ | "verifying"
+ | "challenged"
+ | "not_verified";
+export type VerificationResult = {
+ status: VerificationStatus;
+ itemID?: string;
+ deadline?: number;
+};
+export type MarketOffChainFields = {
+ factory?: Address;
+ outcomesSupply: bigint;
+ liquidityUSD: number;
+ incentive: number;
+ hasLiquidity: boolean;
+ categories: string[];
+ poolBalance: ({
+ token0: {
+ symbol: string;
+ balance: number;
+ };
+ token1: {
+ symbol: string;
+ balance: number;
+ };
+ } | null)[];
+ odds: (number | null)[];
+ creator?: string | null;
+ blockTimestamp?: number;
+ verification?: VerificationResult;
+ images?: { market: string; outcomes: string[] } | undefined;
+ index?: number;
+ url: string;
+};
+
+export enum MarketStatus {
+ NOT_OPEN = "not_open",
+ OPEN = "open",
+ ANSWER_NOT_FINAL = "answer_not_final",
+ IN_DISPUTE = "in_dispute",
+ PENDING_EXECUTION = "pending_execution",
+ CLOSED = "closed",
+}
+
+export type Market = MarketOffChainFields & {
+ id: Address;
+ type: "Generic" | "Futarchy";
+ marketName: string;
+ outcomes: readonly string[];
+ collateralToken: Address;
+ collateralToken1: Address;
+ collateralToken2: Address;
+ wrappedTokens: Address[];
+ parentMarket: {
+ id: Address;
+ conditionId: `0x${string}`;
+ payoutReported: boolean;
+ payoutNumerators: readonly bigint[];
+ };
+ parentOutcome: bigint;
+ //MarketView's outcomesSupply is buggy
+ //outcomesSupply: bigint;
+ parentCollectionId: `0x${string}`;
+ conditionId: `0x${string}`;
+ questionId: `0x${string}`;
+ templateId: bigint;
+ questions: readonly Question[];
+ openingTs: number;
+ finalizeTs: number;
+ encodedQuestions: readonly string[];
+ lowerBound: bigint;
+ upperBound: bigint;
+ payoutReported: boolean;
+ payoutNumerators: readonly bigint[];
+};
+
+export type Token0Token1 = { token1: Address; token0: Address };
+
+export function getToken0Token1(
+ token0: Address,
+ token1: Address,
+): Token0Token1 {
+ return token0.toLocaleLowerCase() > token1.toLocaleLowerCase()
+ ? {
+ token0: token1.toLocaleLowerCase() as Address,
+ token1: token0.toLocaleLowerCase() as Address,
+ }
+ : {
+ token0: token0.toLocaleLowerCase() as Address,
+ token1: token1.toLocaleLowerCase() as Address,
+ };
+}
+
+// outcome0 pairs with outcome2
+// outcome1 pairs with outcome3
+// outcome2 pairs with outcome0
+// outcome3 pairs with outcome1
+export const FUTARCHY_LP_PAIRS_MAPPING = [2, 3, 0, 1];
+
+export function getLiquidityPair(
+ market: Market,
+ outcomeIndex: number,
+): Token0Token1 {
+ if (market.type === "Generic") {
+ return getToken0Token1(
+ market.wrappedTokens[outcomeIndex],
+ market.collateralToken,
+ );
+ }
+
+ return getToken0Token1(
+ market.wrappedTokens[outcomeIndex],
+ market.wrappedTokens[FUTARCHY_LP_PAIRS_MAPPING[outcomeIndex]],
+ );
+}
+
+export function isTwoStringsEqual(
+ str1: string | undefined | null,
+ str2: string | undefined | null,
+) {
+ return (
+ !!str1?.trim() &&
+ str2?.trim()?.toLocaleLowerCase() === str1?.trim()?.toLocaleLowerCase()
+ );
+}
diff --git a/src/hooks/tradeWallet/useCheckTradeExecutorCreated.ts b/src/hooks/tradeWallet/useCheckTradeExecutorCreated.ts
new file mode 100644
index 0000000..23b9c07
--- /dev/null
+++ b/src/hooks/tradeWallet/useCheckTradeExecutorCreated.ts
@@ -0,0 +1,13 @@
+import { useQuery } from "@tanstack/react-query";
+import { Address } from "viem";
+
+import { checkTradeExecutorCreated } from "@/utils/tradeWallet/deployTradeExecutor";
+
+export const useCheckTradeExecutorCreated = (account: Address | undefined) => {
+ return useQuery({
+ enabled: !!account,
+ queryKey: ["useCheckTradeExecutorCreated", account],
+ staleTime: Infinity,
+ queryFn: () => checkTradeExecutorCreated(account!),
+ });
+};
diff --git a/src/hooks/tradeWallet/useCreateTradeExecutor.ts b/src/hooks/tradeWallet/useCreateTradeExecutor.ts
new file mode 100644
index 0000000..4b114d8
--- /dev/null
+++ b/src/hooks/tradeWallet/useCreateTradeExecutor.ts
@@ -0,0 +1,18 @@
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { Address } from "viem";
+
+import { initTradeExecutor } from "@/utils/tradeWallet/deployTradeExecutor";
+
+export const useCreateTradeExecutor = (onSuccess?: () => unknown) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: ({ account }: { account: Address }) =>
+ initTradeExecutor(account),
+ onSuccess() {
+ onSuccess?.();
+ queryClient.refetchQueries({
+ queryKey: ["useCheckTradeExecutorCreated"],
+ });
+ },
+ });
+};
diff --git a/src/hooks/tradeWallet/useDepositToTradeExecutor.ts b/src/hooks/tradeWallet/useDepositToTradeExecutor.ts
new file mode 100644
index 0000000..04cd4dc
--- /dev/null
+++ b/src/hooks/tradeWallet/useDepositToTradeExecutor.ts
@@ -0,0 +1,59 @@
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { writeContract } from "@wagmi/core";
+import { Address, erc20Abi } from "viem";
+
+import { sDaiAdapterAddress } from "@/generated";
+import { config } from "@/wagmiConfig";
+
+import { waitForTransaction } from "@/utils/waitForTransaction";
+
+import { sDAIAdapterAbi } from "@/abi/sDAIAdapter";
+import { DEFAULT_CHAIN } from "@/consts";
+
+interface DepositProps {
+ tradeExecutor: Address;
+ token: Address;
+ amount: bigint;
+ isXDai: boolean;
+}
+
+async function depositToTradeExecutor({
+ tradeExecutor,
+ token,
+ amount,
+ isXDai,
+}: DepositProps) {
+ const writePromise = isXDai
+ ? writeContract(config, {
+ address: sDaiAdapterAddress,
+ abi: sDAIAdapterAbi,
+ functionName: "depositXDAI",
+ chainId: DEFAULT_CHAIN.id,
+ args: [tradeExecutor],
+ value: amount,
+ })
+ : writeContract(config, {
+ address: token,
+ abi: erc20Abi,
+ functionName: "transfer",
+ chainId: DEFAULT_CHAIN.id,
+ args: [tradeExecutor, amount],
+ });
+
+ const result = await waitForTransaction(() => writePromise);
+ if (!result.status) {
+ throw result.error;
+ }
+ return result;
+}
+
+export const useDepositToTradeExecutor = (onSuccess?: () => unknown) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: (props: DepositProps) => depositToTradeExecutor(props),
+ onSuccess() {
+ onSuccess?.();
+ queryClient.refetchQueries({ queryKey: ["useTokenBalance"] });
+ },
+ });
+};
diff --git a/src/hooks/tradeWallet/useRedeemParentsToTradeExecutor.ts b/src/hooks/tradeWallet/useRedeemParentsToTradeExecutor.ts
new file mode 100644
index 0000000..b6ea9c3
--- /dev/null
+++ b/src/hooks/tradeWallet/useRedeemParentsToTradeExecutor.ts
@@ -0,0 +1,76 @@
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { writeContract } from "@wagmi/core";
+import { Address, encodeFunctionData, erc20Abi } from "viem";
+
+import { TradeExecutorAbi } from "@/contracts/abis/TradeExecutorAbi";
+import { gnosisRouterAbi, gnosisRouterAddress } from "@/generated";
+import { config } from "@/wagmiConfig";
+
+import { waitForTransaction } from "@/utils/waitForTransaction";
+
+import { collateral, DEFAULT_CHAIN } from "@/consts";
+import { parentMarket } from "@/consts/markets";
+
+interface RedeemProps {
+ tradeExecutor: Address;
+ tokens: Address[];
+ amounts: bigint[];
+ outcomeIndexes: bigint[];
+}
+
+async function redeemParentsToTradeExecutor({
+ tradeExecutor,
+ tokens,
+ amounts,
+ outcomeIndexes,
+}: RedeemProps) {
+ const approveCalls = tokens.map((token, index) => ({
+ to: token,
+ data: encodeFunctionData({
+ abi: erc20Abi,
+ functionName: "approve",
+ args: [gnosisRouterAddress, amounts[index]],
+ }),
+ }));
+
+ const redeemCall = {
+ to: gnosisRouterAddress,
+ data: encodeFunctionData({
+ abi: gnosisRouterAbi,
+ functionName: "redeemPositions",
+ args: [collateral.address, parentMarket, outcomeIndexes, amounts],
+ }),
+ };
+
+ const calls = [redeemCall, ...approveCalls];
+
+ const writePromise = writeContract(config, {
+ address: tradeExecutor,
+ abi: TradeExecutorAbi,
+ functionName: "batchExecute",
+ args: [calls],
+ value: 0n,
+ chainId: DEFAULT_CHAIN.id,
+ });
+
+ const result = await waitForTransaction(() => writePromise);
+ if (!result.status) {
+ throw result.error;
+ }
+ return result;
+}
+
+/**
+ *
+ * @returns Redeems leftover market tokens directly to collateral (sDAI)
+ */
+export const useRedeemParentsToTradeExecutor = (onSuccess?: () => unknown) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: (props: RedeemProps) => redeemParentsToTradeExecutor(props),
+ onSuccess() {
+ onSuccess?.();
+ queryClient.refetchQueries({ queryKey: ["useTokenBalance"] });
+ },
+ });
+};
diff --git a/src/hooks/tradeWallet/useRedeemToTradeExecutor.ts b/src/hooks/tradeWallet/useRedeemToTradeExecutor.ts
new file mode 100644
index 0000000..116f99f
--- /dev/null
+++ b/src/hooks/tradeWallet/useRedeemToTradeExecutor.ts
@@ -0,0 +1,86 @@
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { writeContract } from "@wagmi/core";
+import { Address, encodeFunctionData, erc20Abi } from "viem";
+
+import { TradeExecutorAbi } from "@/contracts/abis/TradeExecutorAbi";
+import { conditionalRouterAbi, conditionalRouterAddress } from "@/generated";
+import { config } from "@/wagmiConfig";
+
+import { waitForTransaction } from "@/utils/waitForTransaction";
+
+import { collateral, DEFAULT_CHAIN } from "@/consts";
+
+interface RedeemProps {
+ tradeExecutor: Address;
+ tokens: Address[];
+ amounts: bigint[];
+ outcomeIndexes: bigint[];
+ marketId: `0x${string}`;
+ // the index set of the parent market token
+ parentMarketOutcome: bigint;
+}
+
+async function redeemToTradeExecutor({
+ tradeExecutor,
+ tokens,
+ amounts,
+ outcomeIndexes,
+ marketId,
+ parentMarketOutcome,
+}: RedeemProps) {
+ const approveCalls = tokens.map((token, index) => ({
+ to: token,
+ data: encodeFunctionData({
+ abi: erc20Abi,
+ functionName: "approve",
+ args: [conditionalRouterAddress, amounts[index]],
+ }),
+ }));
+
+ const redeemCall = {
+ to: conditionalRouterAddress,
+ data: encodeFunctionData({
+ abi: conditionalRouterAbi,
+ functionName: "redeemConditionalToCollateral",
+ args: [
+ collateral.address,
+ marketId,
+ outcomeIndexes,
+ [parentMarketOutcome],
+ amounts,
+ ],
+ }),
+ };
+
+ const calls = [redeemCall, ...approveCalls];
+
+ const writePromise = writeContract(config, {
+ address: tradeExecutor,
+ abi: TradeExecutorAbi,
+ functionName: "batchExecute",
+ args: [calls],
+ value: 0n,
+ chainId: DEFAULT_CHAIN.id,
+ });
+
+ const result = await waitForTransaction(() => writePromise);
+ if (!result.status) {
+ throw result.error;
+ }
+ return result;
+}
+
+/**
+ *
+ * @returns Redeems the UP-DOWN tokens directly to collateral (sDAI)
+ */
+export const useRedeemToTradeExecutor = (onSuccess?: () => unknown) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: (props: RedeemProps) => redeemToTradeExecutor(props),
+ onSuccess() {
+ onSuccess?.();
+ queryClient.refetchQueries({ queryKey: ["useTokenBalance"] });
+ },
+ });
+};
diff --git a/src/hooks/tradeWallet/useTradeExecutorMerge.ts b/src/hooks/tradeWallet/useTradeExecutorMerge.ts
new file mode 100644
index 0000000..4953230
--- /dev/null
+++ b/src/hooks/tradeWallet/useTradeExecutorMerge.ts
@@ -0,0 +1,76 @@
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { writeContract } from "@wagmi/core";
+import { Address, encodeFunctionData, erc20Abi } from "viem";
+
+import { TradeExecutorAbi } from "@/contracts/abis/TradeExecutorAbi";
+import { gnosisRouterAbi, gnosisRouterAddress } from "@/generated";
+import { config } from "@/wagmiConfig";
+
+import { waitForTransaction } from "@/utils/waitForTransaction";
+
+import { collateral, DEFAULT_CHAIN } from "@/consts";
+import { invalidMarket, markets, parentMarket } from "@/consts/markets";
+
+interface MergeProps {
+ tradeExecutor: Address;
+ amount: bigint;
+}
+
+async function mergeFromTradeExecutor({ tradeExecutor, amount }: MergeProps) {
+ const approveCalls = [
+ ...markets.map((market) => ({
+ to: market.underlyingToken,
+ data: encodeFunctionData({
+ abi: erc20Abi,
+ functionName: "approve",
+ args: [gnosisRouterAddress, amount],
+ }),
+ })),
+ {
+ to: invalidMarket,
+ data: encodeFunctionData({
+ abi: erc20Abi,
+ functionName: "approve",
+ args: [gnosisRouterAddress, amount],
+ }),
+ },
+ ];
+
+ const mergeCall = {
+ to: gnosisRouterAddress,
+ data: encodeFunctionData({
+ abi: gnosisRouterAbi,
+ functionName: "mergePositions",
+ args: [collateral.address, parentMarket, amount],
+ }),
+ };
+ const calls = [...approveCalls, mergeCall];
+ console.log({ calls });
+
+ const writePromise = writeContract(config, {
+ address: tradeExecutor,
+ abi: TradeExecutorAbi,
+ functionName: "batchExecute",
+ args: [calls],
+ value: 0n,
+ chainId: DEFAULT_CHAIN.id,
+ });
+
+ const result = await waitForTransaction(() => writePromise);
+ if (!result.status) {
+ throw result.error;
+ }
+ return result;
+}
+
+export const useTradeExecutorMerge = (onSuccess?: () => unknown) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: (props: MergeProps) => mergeFromTradeExecutor(props),
+ onSuccess() {
+ onSuccess?.();
+ queryClient.refetchQueries({ queryKey: ["useTokenBalance"] });
+ queryClient.refetchQueries({ queryKey: ["useTokensBalances"] });
+ },
+ });
+};
diff --git a/src/hooks/tradeWallet/useTradeExecutorPredict.ts b/src/hooks/tradeWallet/useTradeExecutorPredict.ts
new file mode 100644
index 0000000..d60c2b7
--- /dev/null
+++ b/src/hooks/tradeWallet/useTradeExecutorPredict.ts
@@ -0,0 +1,232 @@
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { writeContract } from "@wagmi/core";
+import { Address, encodeFunctionData, erc20Abi, parseUnits } from "viem";
+
+import { TradeExecutorAbi } from "@/contracts/abis/TradeExecutorAbi";
+import { gnosisRouterAbi, gnosisRouterAddress } from "@/generated";
+import { config } from "@/wagmiConfig";
+
+import { GetQuotesResult } from "@/utils/getQuotes";
+import { waitForTransaction } from "@/utils/waitForTransaction";
+
+import { collateral, DECIMALS, DEFAULT_CHAIN } from "@/consts";
+import { IMarket } from "@/consts/markets";
+
+interface PredictProps {
+ tradeExecutor: Address;
+ amount: bigint;
+ market: IMarket;
+ getQuotesResult: GetQuotesResult;
+}
+
+function splitFromRouter(marketId: Address, amount: bigint) {
+ return {
+ to: gnosisRouterAddress,
+ value: 0n,
+ data: encodeFunctionData({
+ abi: gnosisRouterAbi,
+ functionName: "splitPosition",
+ args: [collateral.address, marketId, amount],
+ }),
+ };
+}
+
+function mergeFromRouter(marketId: Address, amount: bigint) {
+ return {
+ to: gnosisRouterAddress,
+ value: 0n,
+ data: encodeFunctionData({
+ abi: gnosisRouterAbi,
+ functionName: "mergePositions",
+ args: [collateral.address, marketId, amount],
+ }),
+ };
+}
+
+const getApproveCalls = async ({
+ amount,
+ market,
+ getQuotesResult,
+}: Omit) => {
+ const { quotes, mergeAmount } = getQuotesResult;
+ const { sellQuotes, buyQuotes } = quotes;
+
+ // approve the gnosisRouter to split underlying tokens
+ const splitApproveCall =
+ amount > 0
+ ? [
+ {
+ to: market.underlyingToken,
+ data: encodeFunctionData({
+ abi: erc20Abi,
+ functionName: "approve",
+ args: [gnosisRouterAddress, amount],
+ }),
+ },
+ ]
+ : [];
+
+ // sell approve calls
+ const sellApproveCalls = sellQuotes.map((quote) => ({
+ to: quote.inputAmount.currency.address!,
+ data: encodeFunctionData({
+ abi: erc20Abi,
+ functionName: "approve",
+ args: [
+ quote.approveAddress as Address,
+ parseUnits(quote.maximumAmountIn().toExact(), DECIMALS),
+ ],
+ }),
+ }));
+
+ // approve gnosis router to merge UP and DOWN tokens
+ const mergeApproveCalls =
+ mergeAmount > 0n
+ ? [
+ {
+ to: market.upToken,
+ data: encodeFunctionData({
+ abi: erc20Abi,
+ functionName: "approve",
+ args: [gnosisRouterAddress, mergeAmount],
+ }),
+ },
+ {
+ to: market.downToken,
+ data: encodeFunctionData({
+ abi: erc20Abi,
+ functionName: "approve",
+ args: [gnosisRouterAddress, mergeAmount],
+ }),
+ },
+ {
+ to: market.invalidToken,
+ data: encodeFunctionData({
+ abi: erc20Abi,
+ functionName: "approve",
+ args: [gnosisRouterAddress, mergeAmount],
+ }),
+ },
+ ]
+ : [];
+
+ // buy approve calls
+ const buyApproveCalls = buyQuotes.map((quote) => ({
+ to: quote.inputAmount.currency.address!,
+ data: encodeFunctionData({
+ abi: erc20Abi,
+ functionName: "approve",
+ args: [
+ quote.approveAddress as Address,
+ parseUnits(quote.maximumAmountIn().toExact(), DECIMALS),
+ ],
+ }),
+ }));
+
+ return {
+ splitApproveCall,
+ sellApproveCalls,
+ mergeApproveCalls,
+ buyApproveCalls,
+ };
+};
+
+async function getTradeExecutorCalls({
+ tradeExecutor,
+ market,
+ amount,
+ getQuotesResult,
+}: PredictProps) {
+ const { quotes, mergeAmount } = getQuotesResult;
+ const { sellQuotes, buyQuotes } = quotes;
+ const calls = [];
+
+ const {
+ splitApproveCall,
+ sellApproveCalls,
+ mergeApproveCalls,
+ buyApproveCalls,
+ } = await getApproveCalls({
+ amount,
+ market,
+ getQuotesResult,
+ });
+
+ if (amount > 0n) {
+ calls.push(...splitApproveCall);
+ calls.push(splitFromRouter(market.marketId, amount));
+ }
+
+ const sellSwapTransactions = (
+ await Promise.all(
+ sellQuotes.map((quote) =>
+ quote.swapTransaction({ recipient: tradeExecutor }),
+ ),
+ )
+ ).map((txn) => ({ to: txn.to!, data: txn.data! }));
+
+ calls.push(...sellApproveCalls);
+ calls.push(...sellSwapTransactions);
+
+ if (mergeAmount > 0n) {
+ calls.push(...mergeApproveCalls);
+ calls.push(mergeFromRouter(market.marketId, mergeAmount));
+ }
+
+ const buySwapTransactions = (
+ await Promise.all(
+ buyQuotes.map((quote) =>
+ quote.swapTransaction({ recipient: tradeExecutor }),
+ ),
+ )
+ ).map((txn) => ({ to: txn.to!, data: txn.data! }));
+
+ calls.push(...buyApproveCalls);
+ calls.push(...buySwapTransactions);
+
+ return calls;
+}
+
+async function predictFromTradeExecutor({
+ tradeExecutor,
+ amount,
+ market,
+ getQuotesResult,
+}: PredictProps) {
+ const calls = await getTradeExecutorCalls({
+ tradeExecutor,
+ amount,
+ market,
+ getQuotesResult,
+ });
+
+ const writePromise = writeContract(config, {
+ address: tradeExecutor,
+ abi: TradeExecutorAbi,
+ functionName: "batchExecute",
+ args: [calls],
+ value: 0n,
+ chainId: DEFAULT_CHAIN.id,
+ });
+
+ const result = await waitForTransaction(() => writePromise);
+ if (!result.status) {
+ throw result.error;
+ }
+ return result;
+}
+
+export const useTradeExecutorPredict = (onSuccess?: () => unknown) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: (props: PredictProps) => predictFromTradeExecutor(props),
+ onSuccess() {
+ onSuccess?.();
+ setTimeout(() => {
+ queryClient.refetchQueries({ queryKey: ["useTokenBalance"] });
+ queryClient.refetchQueries({ queryKey: ["useTokensBalances"] });
+ queryClient.invalidateQueries({ queryKey: ["useGetQuotes"] });
+ }, 3000);
+ },
+ });
+};
diff --git a/src/hooks/tradeWallet/useTradeExecutorSplit.ts b/src/hooks/tradeWallet/useTradeExecutorSplit.ts
new file mode 100644
index 0000000..d699b1a
--- /dev/null
+++ b/src/hooks/tradeWallet/useTradeExecutorSplit.ts
@@ -0,0 +1,64 @@
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { writeContract } from "@wagmi/core";
+import { Address, encodeFunctionData, erc20Abi } from "viem";
+
+import { TradeExecutorAbi } from "@/contracts/abis/TradeExecutorAbi";
+import { gnosisRouterAbi, gnosisRouterAddress } from "@/generated";
+import { config } from "@/wagmiConfig";
+
+import { waitForTransaction } from "@/utils/waitForTransaction";
+
+import { collateral, DEFAULT_CHAIN } from "@/consts";
+import { parentMarket } from "@/consts/markets";
+
+interface SplitProps {
+ tradeExecutor: Address;
+ amount: bigint;
+}
+
+async function splitFromTradeExecutor({ tradeExecutor, amount }: SplitProps) {
+ const approveCall = {
+ to: collateral.address,
+ data: encodeFunctionData({
+ abi: erc20Abi,
+ functionName: "approve",
+ args: [gnosisRouterAddress, amount],
+ }),
+ };
+ const splitCall = {
+ to: gnosisRouterAddress,
+ data: encodeFunctionData({
+ abi: gnosisRouterAbi,
+ functionName: "splitPosition",
+ args: [collateral.address, parentMarket, amount],
+ }),
+ };
+ const calls = [approveCall, splitCall];
+
+ const writePromise = writeContract(config, {
+ address: tradeExecutor,
+ abi: TradeExecutorAbi,
+ functionName: "batchExecute",
+ args: [calls],
+ value: 0n,
+ chainId: DEFAULT_CHAIN.id,
+ });
+
+ const result = await waitForTransaction(() => writePromise);
+ if (!result.status) {
+ throw result.error;
+ }
+ return result;
+}
+
+export const useTradeExecutorSplit = (onSuccess?: () => unknown) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: (props: SplitProps) => splitFromTradeExecutor(props),
+ onSuccess() {
+ onSuccess?.();
+ queryClient.refetchQueries({ queryKey: ["useTokenBalance"] });
+ queryClient.refetchQueries({ queryKey: ["useTokensBalances"] });
+ },
+ });
+};
diff --git a/src/hooks/tradeWallet/useWithdrawFromTradeExecutor.ts b/src/hooks/tradeWallet/useWithdrawFromTradeExecutor.ts
new file mode 100644
index 0000000..97f991f
--- /dev/null
+++ b/src/hooks/tradeWallet/useWithdrawFromTradeExecutor.ts
@@ -0,0 +1,60 @@
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { writeContract } from "@wagmi/core";
+import { Address, encodeFunctionData, erc20Abi } from "viem";
+
+import { TradeExecutorAbi } from "@/contracts/abis/TradeExecutorAbi";
+import { config } from "@/wagmiConfig";
+
+import { waitForTransaction } from "@/utils/waitForTransaction";
+
+import { DEFAULT_CHAIN } from "@/consts";
+
+interface WithdrawProps {
+ account: Address;
+ tradeExecutor: Address;
+ tokens: Address[];
+ amounts: bigint[];
+}
+
+async function withdrawFromTradeExecutor({
+ account,
+ tradeExecutor,
+ tokens,
+ amounts,
+}: WithdrawProps) {
+ const calls = tokens.map((token, index) => {
+ return {
+ to: token,
+ data: encodeFunctionData({
+ abi: erc20Abi,
+ functionName: "transfer",
+ args: [account, amounts[index]],
+ }),
+ };
+ });
+ const writePromise = writeContract(config, {
+ address: tradeExecutor,
+ abi: TradeExecutorAbi,
+ functionName: "batchExecute",
+ args: [calls],
+ value: 0n,
+ chainId: DEFAULT_CHAIN.id,
+ });
+
+ const result = await waitForTransaction(() => writePromise);
+ if (!result.status) {
+ throw result.error;
+ }
+ return result;
+}
+
+export const useWithdrawFromTradeExecutor = (onSuccess?: () => unknown) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: (props: WithdrawProps) => withdrawFromTradeExecutor(props),
+ onSuccess() {
+ onSuccess?.();
+ queryClient.refetchQueries({ queryKey: ["useTokenBalance"] });
+ },
+ });
+};
diff --git a/src/hooks/useAlternateRoute.ts b/src/hooks/useAlternateRoute.ts
index 5739be7..2a6de31 100644
--- a/src/hooks/useAlternateRoute.ts
+++ b/src/hooks/useAlternateRoute.ts
@@ -14,9 +14,7 @@ export const useAlternateRoute = (
const { address } = useAccount();
return useQuery({
enabled: enabled && !isUndefined(amount) && !isUndefined(address),
- queryKey: [
- `market-alternate-route-${targetToken.toLowerCase()}-${oppositeToken.toLowerCase()}`,
- ],
+ queryKey: [`market-alternate-route`, targetToken, oppositeToken, amount],
// we only call this once while determining best route and use the quote from this query too
staleTime: Infinity,
retry: (failureCount) => failureCount < 3,
diff --git a/src/hooks/useCappedBalance.ts b/src/hooks/useCappedBalance.ts
new file mode 100644
index 0000000..a50358b
--- /dev/null
+++ b/src/hooks/useCappedBalance.ts
@@ -0,0 +1,56 @@
+import { Address, parseUnits } from "viem";
+
+import { isUndefined } from "@/utils";
+
+import { useVolumeUntilPrice } from "./liquidity/useVolumeUntilPrice";
+
+import { useBalance } from "./useBalance";
+import { useMarketLimitQuote } from "./useMarketLimitQuote";
+
+/**
+ * @dev This hook returns the capped amount of underlying tokens that can be traded without
+ * overshooting the predicted price. [Min(tokensAmountThatOvershoot, userUnderlyingBalance)]
+ * @param underlyingToken
+ * @param targetToken
+ * @param predictedPrice
+ * @param shouldFetch
+ * @returns capped underlying tokens amount
+ */
+const useCappedBalance = (
+ underlyingToken: Address,
+ targetToken: Address,
+ predictedPrice: number,
+ shouldFetch: boolean,
+) => {
+ const { data: underlyingBalance } = useBalance(underlyingToken);
+
+ const data = useVolumeUntilPrice(
+ underlyingToken,
+ targetToken,
+ "buy",
+ predictedPrice,
+ );
+
+ const { data: fillToPriceQuote, isLoading } = useMarketLimitQuote(
+ targetToken,
+ underlyingToken,
+ data?.toString() ?? "1",
+ !isUndefined(data) && shouldFetch,
+ );
+
+ const amountRequiredToOvershoot = !isUndefined(fillToPriceQuote)
+ ? parseUnits(
+ fillToPriceQuote.inputAmount.toExact() ?? "0",
+ fillToPriceQuote.details?.input.decimals ?? 18,
+ )
+ : undefined;
+
+ const cappedUnderlyingAmount =
+ (underlyingBalance ?? 0) > (amountRequiredToOvershoot ?? 0)
+ ? amountRequiredToOvershoot
+ : underlyingBalance;
+
+ return { cappedUnderlyingAmount, isLoading };
+};
+
+export default useCappedBalance;
diff --git a/src/hooks/useGetQuotes.ts b/src/hooks/useGetQuotes.ts
new file mode 100644
index 0000000..5c245d9
--- /dev/null
+++ b/src/hooks/useGetQuotes.ts
@@ -0,0 +1,25 @@
+import { useQuery } from "@tanstack/react-query";
+
+import { isUndefined } from "@/utils";
+import { GetQuoteProps, getQuotes } from "@/utils/getQuotes";
+
+export const useGetQuotes = (quoteProps: GetQuoteProps, enabled: boolean) => {
+ const { account, processedMarkets } = quoteProps;
+ return useQuery({
+ enabled: !isUndefined(account) && !isUndefined(processedMarkets) && enabled,
+ queryKey: [
+ "useGetQuotes",
+ account,
+ JSON.stringify(
+ processedMarkets?.map((market) => ({
+ ...market,
+ balance: market.balance.toString(),
+ underlyingBalance: market.underlyingBalance.toString(),
+ })),
+ ),
+ ],
+ queryFn: () => {
+ return getQuotes({ account, processedMarkets });
+ },
+ });
+};
diff --git a/src/hooks/useMarketLimitQuote.ts b/src/hooks/useMarketLimitQuote.ts
new file mode 100644
index 0000000..3acb39c
--- /dev/null
+++ b/src/hooks/useMarketLimitQuote.ts
@@ -0,0 +1,31 @@
+import { useQuery } from "@tanstack/react-query";
+import { gnosis } from "viem/chains";
+import { useAccount } from "wagmi";
+
+import { getSwaprQuoteExactOut } from "@/utils/swapr";
+
+export const useMarketLimitQuote = (
+ token: string,
+ collateralToken: string,
+ amountOut?: string,
+ enabled: boolean = true,
+) => {
+ const { address } = useAccount();
+ return useQuery({
+ enabled,
+ queryKey: [`market-limit`, token, collateralToken, amountOut],
+ staleTime: 10000,
+ retry: (failureCount) => failureCount < 3,
+ queryFn: async () => {
+ await new Promise((resolve) => setTimeout(resolve, Math.random() * 1000));
+
+ return await getSwaprQuoteExactOut({
+ address,
+ chain: gnosis.id,
+ outcomeToken: token,
+ collateralToken,
+ amount: amountOut ?? "1",
+ });
+ },
+ });
+};
diff --git a/src/hooks/useMarketPrice.ts b/src/hooks/useMarketPrice.ts
index 6d5bc9e..6216920 100644
--- a/src/hooks/useMarketPrice.ts
+++ b/src/hooks/useMarketPrice.ts
@@ -19,11 +19,11 @@ import { SwaprQuoter } from "@/abi/SwaprQuoter";
export const useMarketPrice = (
targetToken: Address,
baseToken: Address,
- amount = "1",
+ amount = "0.001",
) => {
const publicClient = usePublicClient();
return useQuery<{ price: string; status: boolean }>({
- queryKey: ["market-price", baseToken, targetToken, amount],
+ queryKey: ["useMarketPrice", baseToken, targetToken, amount],
refetchInterval: 10_000,
enabled: amount !== "0",
queryFn: async () => {
diff --git a/src/hooks/useMarketQuote.ts b/src/hooks/useMarketQuote.ts
index b9e1b66..5b6ed78 100644
--- a/src/hooks/useMarketQuote.ts
+++ b/src/hooks/useMarketQuote.ts
@@ -13,7 +13,7 @@ export const useMarketQuote = (
const { address } = useAccount();
return useQuery({
enabled,
- queryKey: [`market-${token.toLowerCase()}`, amount],
+ queryKey: [`market`, token, collateralToken, amount],
staleTime: 10000,
retry: (failureCount) => failureCount < 3,
queryFn: async () => {
diff --git a/src/hooks/useProcessMarkets.ts b/src/hooks/useProcessMarkets.ts
new file mode 100644
index 0000000..f5a5d2f
--- /dev/null
+++ b/src/hooks/useProcessMarkets.ts
@@ -0,0 +1,118 @@
+import { useMemo } from "react";
+
+import { Address } from "viem";
+
+import { useMarketContext } from "@/context/MarketContext";
+
+import { isUndefined } from "@/utils";
+
+import { useVolumeUntilPriceDual } from "./liquidity/useVolumeUntilPriceDual";
+
+import { useTokenBalance } from "./useTokenBalance";
+
+export type ProcessedMarket = {
+ action: string;
+ underlyingBalance: bigint;
+ balance: bigint;
+ volumeUntilPrice: {
+ outcomeVolume: number;
+ collateralVolume: number;
+ };
+ underlyingToken: Address;
+ token: Address;
+ difference: number;
+};
+
+interface IProcessMarkets {
+ tradeExecutor?: Address;
+ enabled?: boolean;
+}
+
+export const useProcessMarkets = ({
+ tradeExecutor,
+ enabled = true,
+}: IProcessMarkets): ProcessedMarket[] | undefined => {
+ const { predictedPrice, market, upPrice, downPrice } = useMarketContext();
+ const { underlyingToken, upToken, downToken } = market;
+ const { data: underlyingBalanceData } = useTokenBalance({
+ address: tradeExecutor,
+ token: underlyingToken,
+ });
+ const { data: upBalanceData } = useTokenBalance({
+ address: tradeExecutor,
+ token: upToken,
+ });
+ const { data: downBalanceData } = useTokenBalance({
+ address: tradeExecutor,
+ token: downToken,
+ });
+
+ // tells if we should buy or sell UP/DOWN based on predictionPrice
+ const upDirection = predictedPrice > upPrice ? "buy" : "sell";
+ const downDirection = 1 - predictedPrice > downPrice ? "buy" : "sell";
+
+ // gives us the amount of collateral
+ const { data: upMarketVolumeData } = useVolumeUntilPriceDual(
+ underlyingToken,
+ upToken,
+ upDirection,
+ predictedPrice,
+ enabled,
+ );
+
+ const { data: downMarketVolumeData } = useVolumeUntilPriceDual(
+ underlyingToken,
+ downToken,
+ downDirection,
+ 1 - predictedPrice,
+ enabled,
+ );
+
+ const isReady =
+ upPrice !== Infinity &&
+ downPrice !== Infinity &&
+ !isUndefined(underlyingBalanceData?.value) &&
+ !isUndefined(upBalanceData?.value) &&
+ !isUndefined(downBalanceData?.value) &&
+ !isUndefined(upMarketVolumeData) &&
+ !isUndefined(downMarketVolumeData);
+
+ return useMemo(() => {
+ if (!isReady) return;
+ return [
+ {
+ action: upDirection,
+ underlyingBalance: underlyingBalanceData.value,
+ balance: upBalanceData.value,
+ volumeUntilPrice: upMarketVolumeData,
+ underlyingToken,
+ token: upToken,
+ difference: Math.abs(upPrice - predictedPrice),
+ },
+ {
+ action: downDirection,
+ underlyingBalance: underlyingBalanceData.value,
+ balance: downBalanceData.value,
+ volumeUntilPrice: downMarketVolumeData,
+ underlyingToken,
+ token: downToken,
+ difference: Math.abs(downPrice - (1 - predictedPrice)),
+ },
+ ];
+ }, [
+ isReady,
+ downDirection,
+ upDirection,
+ upBalanceData?.value,
+ downBalanceData?.value,
+ underlyingBalanceData?.value,
+ underlyingToken,
+ upToken,
+ downToken,
+ downMarketVolumeData,
+ upMarketVolumeData,
+ upPrice,
+ downPrice,
+ predictedPrice,
+ ]);
+};
diff --git a/src/hooks/useTokenBalance.ts b/src/hooks/useTokenBalance.ts
new file mode 100644
index 0000000..7b33673
--- /dev/null
+++ b/src/hooks/useTokenBalance.ts
@@ -0,0 +1,29 @@
+import { useQuery } from "@tanstack/react-query";
+import { getBalance } from "@wagmi/core";
+import { Address } from "viem";
+
+import { config } from "@/wagmiConfig";
+
+import { DEFAULT_CHAIN } from "@/consts";
+
+const fetchTokenBalance = async (account: Address, token: Address) => {
+ return await getBalance(config, {
+ address: account,
+ token,
+ chainId: DEFAULT_CHAIN.id,
+ });
+};
+
+export const useTokenBalance = ({
+ address,
+ token,
+}: {
+ address: Address | undefined;
+ token: Address;
+}) => {
+ return useQuery({
+ enabled: !!address,
+ queryKey: ["useTokenBalance", address, token],
+ queryFn: () => fetchTokenBalance(address!, token),
+ });
+};
diff --git a/src/hooks/useTokenBalances.ts b/src/hooks/useTokenBalances.ts
index 2bee167..c1880dd 100644
--- a/src/hooks/useTokenBalances.ts
+++ b/src/hooks/useTokenBalances.ts
@@ -1,18 +1,39 @@
+import { useQuery } from "@tanstack/react-query";
+import { readContracts } from "@wagmi/core";
import { Address, erc20Abi } from "viem";
-import { useAccount, useReadContracts } from "wagmi";
-export const useTokenBalances = (tokens: Array) => {
- const { address } = useAccount();
- return useReadContracts({
- contracts: tokens.map((token) => ({
- address: token,
- abi: erc20Abi,
- functionName: "balanceOf",
- args: [address],
- })),
- query: {
- staleTime: 5000,
- enabled: typeof address !== "undefined",
- },
+import { config } from "@/wagmiConfig";
+
+import { DEFAULT_CHAIN } from "@/consts";
+
+export const fetchTokensBalances = async (
+ account: Address,
+ tokens: Address[],
+): Promise => {
+ try {
+ const balances = (await readContracts(config, {
+ allowFailure: false,
+ contracts: tokens.map((token) => ({
+ address: token,
+ abi: erc20Abi,
+ functionName: "balanceOf",
+ chainId: DEFAULT_CHAIN.id,
+ args: [account],
+ })),
+ })) as bigint[];
+ return balances;
+ } catch {
+ return [];
+ }
+};
+
+export const useTokensBalances = (
+ account: Address | undefined,
+ tokens: Address[] | undefined,
+) => {
+ return useQuery({
+ enabled: !!account && tokens && tokens.length > 0,
+ queryKey: ["useTokensBalances", account, tokens],
+ queryFn: () => fetchTokensBalances(account!, tokens!),
});
};
diff --git a/src/utils/formatError.ts b/src/utils/formatError.ts
new file mode 100644
index 0000000..9a9906b
--- /dev/null
+++ b/src/utils/formatError.ts
@@ -0,0 +1,23 @@
+import { BaseError } from "viem";
+
+interface Cause {
+ data?: {
+ message?: string;
+ };
+}
+
+export const formatError = (error: Error | null): string | undefined => {
+ if (!error) {
+ return undefined;
+ }
+
+ if (error instanceof BaseError) {
+ const cause = error.cause as Cause;
+ if (cause?.data?.message) {
+ return cause.data.message;
+ }
+ return error.shortMessage;
+ }
+
+ return error.message;
+};
diff --git a/src/utils/getQuotes.ts b/src/utils/getQuotes.ts
new file mode 100644
index 0000000..896f965
--- /dev/null
+++ b/src/utils/getQuotes.ts
@@ -0,0 +1,181 @@
+import { SwaprV3Trade } from "@swapr/sdk";
+import { Address, formatUnits, parseUnits } from "viem";
+
+import { ProcessedMarket } from "@/hooks/useProcessMarkets";
+
+import { DECIMALS, DEFAULT_CHAIN, VOLUME_MIN } from "@/consts";
+
+import { getSwaprQuote } from "./swapr";
+
+import { minBigIntArray } from ".";
+
+export type GetQuoteProps = {
+ // account that will trade, tradeExecutor in this case
+ account: Address;
+ // amount of underlyingBalance, if non-zero, the flow will mint and provide more liquidity to trade with
+ // amount: number; we use the underlyingBalance directly from processed market data
+ processedMarkets: ProcessedMarket[];
+};
+
+export type GetQuotesResult = {
+ quotes: {
+ sellQuotes: SwaprV3Trade[];
+ buyQuotes: SwaprV3Trade[];
+ };
+ mergeAmount: bigint;
+};
+
+export const getQuotes = async ({
+ account,
+ processedMarkets,
+}: GetQuoteProps) => {
+ const [buyMarkets, sellMarkets] = processedMarkets.reduce(
+ (acc, curr) => {
+ acc[curr.action === "buy" ? 0 : 1].push(curr);
+ return acc;
+ },
+ [[], []] as [ProcessedMarket[], ProcessedMarket[]],
+ );
+
+ // getting sell quotes
+ const sellPromises = sellMarkets.reduce(
+ (promises, market) => {
+ // if underlying balance is non-zero, then the previous step will have minted this much tokens already
+ // so we have that available, hence added here
+ const availableSellVolume = market.underlyingBalance + market.balance;
+
+ // calculating the max amount of tokens we can sell
+ const volume =
+ parseUnits(market.volumeUntilPrice.outcomeVolume.toString(), DECIMALS) >
+ availableSellVolume
+ ? formatUnits(availableSellVolume, DECIMALS)
+ : market.volumeUntilPrice.outcomeVolume.toString();
+ if (Number(volume) < VOLUME_MIN) {
+ return promises;
+ }
+
+ promises.push(
+ getSwaprQuote({
+ address: account,
+ chain: DEFAULT_CHAIN.id,
+ // we are want collateral as outcome here
+ outcomeToken: market.underlyingToken,
+ // we are giving in the UP or DOWN token
+ collateralToken: market.token,
+ amount: volume,
+ }).catch((e) => {
+ throw e;
+ }),
+ );
+
+ return promises;
+ },
+ [] as Promise[],
+ );
+
+ // means there were sell markets but no route was found
+ if (!sellPromises.length && sellMarkets.length > 0) {
+ throw new Error("Quote Info: No sell route found");
+ }
+
+ const sellTokenMapping: { [key: string]: bigint } = {};
+ const sellQuoteResults = await Promise.allSettled(sellPromises);
+ const sellQuotes = sellQuoteResults.reduce((quotes, result) => {
+ if (result.status === "fulfilled" && result.value) {
+ quotes.push(result.value);
+ sellTokenMapping[
+ // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
+ result.value.inputAmount.currency.address?.toLowerCase()!
+ ] = parseUnits(result.value.inputAmount.toExact(), DECIMALS);
+ }
+ return quotes;
+ }, [] as SwaprV3Trade[]);
+
+ const collateralFromSell = sellQuotes.reduce(
+ (acc, curr) => acc + parseUnits(curr!.outputAmount.toExact(), DECIMALS),
+ 0n,
+ );
+
+ //get new balances
+ const newBalances = processedMarkets.map(
+ (market) =>
+ // keep in mind underlying balance here is to denote the amount we minted
+ (market.balance ?? 0n) +
+ market.underlyingBalance -
+ (sellTokenMapping[market.token.toLowerCase()] ?? 0n),
+ );
+
+ //get collateral from merge
+ const collateralFromMerge = minBigIntArray(newBalances);
+
+ const totalCollateral = collateralFromSell + collateralFromMerge;
+
+ if (!totalCollateral) {
+ throw new Error(`Quote Error: Cannot sell to Underlying token`);
+ }
+
+ // get buy quotes
+ const sumBuyDifference = buyMarkets.reduce(
+ (acc, curr) => acc + curr.difference,
+ 0,
+ );
+ const buyPromises = buyMarkets.reduce(
+ (promises, market) => {
+ // here we allocate the collateral based on the weight of prediction,
+ // so if a market has high difference they get more collateral to utilize
+ const availableBuyVolume =
+ (parseUnits(market.difference.toString(), DECIMALS) * totalCollateral) /
+ parseUnits(sumBuyDifference.toString(), DECIMALS);
+
+ const volume =
+ // note that here we use collateral volume, instead of sellToken volume like above
+ parseUnits(
+ market.volumeUntilPrice.collateralVolume.toString(),
+ DECIMALS,
+ ) > availableBuyVolume
+ ? formatUnits(availableBuyVolume, DECIMALS)
+ : market.volumeUntilPrice.collateralVolume.toString();
+
+ if (Number(volume) < VOLUME_MIN) {
+ return promises;
+ }
+
+ // get quote
+ promises.push(
+ getSwaprQuote({
+ address: account,
+ chain: DEFAULT_CHAIN.id,
+ // we are want UP/DOWN as outcome here
+ outcomeToken: market.token,
+ // we are giving in the underlying token
+ collateralToken: market.underlyingToken,
+ amount: volume,
+ }).catch((e) => {
+ throw e;
+ }),
+ );
+ return promises;
+ },
+ [] as Promise[],
+ );
+
+ if (!buyPromises.length && buyMarkets.length > 0) {
+ throw new Error("Quote Error: Amount too small or No Buy Route found");
+ }
+
+ const buyQuoteResult = await Promise.allSettled(buyPromises);
+ const buyQuotes = buyQuoteResult.reduce((quotes, result) => {
+ if (result.status === "fulfilled" && result.value) {
+ quotes.push(result.value);
+ }
+ return quotes;
+ }, [] as SwaprV3Trade[]);
+
+ if (!buyQuotes) {
+ throw new Error(`Quote Error: Cannot buy from Underlying token`);
+ }
+ return {
+ quotes: { sellQuotes, buyQuotes },
+ mergeAmount: collateralFromMerge,
+ };
+};
diff --git a/src/utils/index.ts b/src/utils/index.ts
index bcbcf53..4923fff 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -1,6 +1,6 @@
import { ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
-import { Address, formatUnits } from "viem";
+import { Address, formatUnits, type Hex } from "viem";
import { type UseSimulateContractReturnType } from "wagmi";
type ExtendedWagmiError = UseSimulateContractReturnType["error"] & {
@@ -98,3 +98,27 @@ export function commify(value: string | number): string {
export const shortenName = (name: string) =>
name.length > 16 ? `${name.slice(0, 12)}...` : name;
+
+export function formatBytecode(bytecode: string): Hex {
+ // Remove any whitespace
+ const cleaned = bytecode.trim();
+
+ // Add 0x prefix if not present
+ if (!cleaned.startsWith("0x")) {
+ return `0x${cleaned}` as Hex;
+ }
+
+ return cleaned as Hex;
+}
+
+export function minBigIntArray(values: bigint[]): bigint {
+ if (values.length === 0) {
+ throw new Error("Cannot compute min of empty array");
+ }
+ return values.reduce((min, v) => (v < min ? v : min));
+}
+
+export function clamp(value: number, min: number, max: number): number {
+ if (Number.isNaN(value)) return min;
+ return Math.min(Math.max(value, min), max);
+}
diff --git a/src/utils/swapr.ts b/src/utils/swapr.ts
index 0cf10b1..2080aae 100644
--- a/src/utils/swapr.ts
+++ b/src/utils/swapr.ts
@@ -9,6 +9,7 @@ import {
import { gnosis } from "viem/chains";
import { getTradeArgs } from "./trade";
+import { getTradeExactOutArgs } from "./tradeExactOut";
type GetQuoteArgs = {
address?: Address;
@@ -46,6 +47,34 @@ export const getSwaprQuote = async ({
);
};
+export const getSwaprQuoteExactOut = async ({
+ address,
+ chain = gnosis.id,
+ outcomeToken,
+ collateralToken,
+ amount = "1",
+}: GetQuoteArgs) => {
+ const args = getTradeExactOutArgs(
+ chain,
+ amount,
+ outcomeToken,
+ collateralToken,
+ "buy",
+ );
+
+ return await SwaprV3Trade.getQuote(
+ {
+ amount: args.currencyAmountOut,
+ quoteCurrency: args.currencyIn,
+ recipient: address,
+ tradeType: TradeType.EXACT_OUTPUT,
+ maximumSlippage: args.maximumSlippage,
+ },
+ undefined,
+ false,
+ );
+};
+
const POOL_DEPLOYER_ADDRESS = "0xC1b576AC6Ec749d5Ace1787bF9Ec6340908ddB47";
export const SWAPR_QUOTER_ADDRESS =
"0xcBaD9FDf0D2814659Eb26f600EFDeAF005Eda0F7";
diff --git a/src/utils/tradeExactOut.ts b/src/utils/tradeExactOut.ts
new file mode 100644
index 0000000..07c9eaf
--- /dev/null
+++ b/src/utils/tradeExactOut.ts
@@ -0,0 +1,61 @@
+import {
+ TokenAmount,
+ Token as SwaprToken,
+ CurrencyAmount,
+ Currency,
+ Percent,
+} from "@swapr/sdk";
+import { parseUnits } from "viem";
+
+export function getTradeExactOutArgs(
+ chainId: number,
+ amount: string,
+ outcomeToken: string,
+ collateralToken: string,
+ swapType: "buy" | "sell",
+) {
+ const [buyToken, sellToken] =
+ swapType === "buy"
+ ? [outcomeToken, collateralToken]
+ : ([collateralToken, outcomeToken] as const);
+
+ const { currencyIn, currencyOut, currencyAmountOut } =
+ getCurrenciesFromTokens(chainId, buyToken, sellToken, amount);
+
+ const maximumSlippage = new Percent("1", "100");
+
+ return {
+ buyToken,
+ sellToken,
+ currencyIn,
+ currencyOut,
+ currencyAmountOut,
+ maximumSlippage,
+ };
+}
+
+function getCurrenciesFromTokens(
+ chainId: number,
+ buyToken: string,
+ sellToken: string,
+ amount: string,
+): {
+ currencyIn: Currency;
+ currencyOut: Currency;
+ currencyAmountOut: CurrencyAmount;
+} {
+ const currencyIn: Currency = new SwaprToken(chainId, sellToken, 18);
+
+ const currencyOut = new SwaprToken(chainId, buyToken, 18);
+
+ const currencyAmountOut = new TokenAmount(
+ currencyOut,
+ parseUnits(String(amount), currencyOut.decimals),
+ );
+
+ return {
+ currencyIn,
+ currencyOut,
+ currencyAmountOut,
+ };
+}
diff --git a/src/utils/tradeWallet/deployTradeExecutor.ts b/src/utils/tradeWallet/deployTradeExecutor.ts
new file mode 100644
index 0000000..ef7d347
--- /dev/null
+++ b/src/utils/tradeWallet/deployTradeExecutor.ts
@@ -0,0 +1,141 @@
+import { getBytecode, writeContract } from "@wagmi/core";
+import {
+ Address,
+ encodeAbiParameters,
+ encodePacked,
+ Hex,
+ keccak256,
+} from "viem";
+
+import { CreateCallAbi } from "@/contracts/abis/CreateCallAbi";
+import { TradeExecutorBytecode } from "@/contracts/abis/TradeExecutorAbi";
+import { config } from "@/wagmiConfig";
+
+import { DEFAULT_CHAIN, GNOSIS_CREATE_CALL, SALT_KEY } from "@/consts";
+
+import { formatBytecode } from "..";
+import { waitForTransaction } from "../waitForTransaction";
+
+interface FactoryDeployParams {
+ factoryAddress: Address;
+ ownerAddress: Address;
+ bytecode: Hex;
+ constructorData: Hex;
+}
+
+function generateSalt(ownerAddress: Address): Hex {
+ return keccak256(
+ encodePacked(["string", "address"], [SALT_KEY, ownerAddress]),
+ );
+}
+
+function predictFactoryAddress({
+ factoryAddress,
+ salt,
+ deploymentData,
+}: {
+ factoryAddress: Address;
+ salt: Address;
+ deploymentData: Hex;
+}): Address {
+ const initCodeHash = keccak256(deploymentData);
+
+ const create2Input = encodePacked(
+ ["bytes1", "address", "bytes32", "bytes32"],
+ ["0xff", factoryAddress, salt, initCodeHash],
+ );
+
+ const hash = keccak256(create2Input);
+ return `0x${hash.slice(-40)}` as Address;
+}
+
+async function checkContractCreated({
+ factoryAddress,
+ ownerAddress,
+ bytecode,
+ constructorData,
+}: Omit) {
+ const deploymentData = `${bytecode}${constructorData.slice(2)}` as Hex;
+ const salt = generateSalt(ownerAddress);
+
+ // Predict contract address
+ const predictedAddress = predictFactoryAddress({
+ factoryAddress,
+ salt,
+ deploymentData,
+ });
+
+ // Check if already deployed
+ const code = await getBytecode(config, {
+ address: predictedAddress,
+ });
+
+ if (code && code !== "0x") {
+ return { isCreated: true, predictedAddress };
+ }
+ return { isCreated: false };
+}
+
+async function checkAndDeployWithFactory({
+ factoryAddress,
+ ownerAddress,
+ bytecode,
+ constructorData,
+}: FactoryDeployParams) {
+ const deploymentData = `${bytecode}${constructorData.slice(2)}` as Hex;
+ const salt = generateSalt(ownerAddress);
+
+ // Predict contract address
+ const predictedAddress = predictFactoryAddress({
+ factoryAddress,
+ salt,
+ deploymentData,
+ });
+
+ // Check if already deployed
+ const { isCreated } = await checkContractCreated({
+ factoryAddress,
+ ownerAddress,
+ bytecode,
+ constructorData,
+ });
+
+ if (isCreated) {
+ return { predictedAddress };
+ }
+
+ try {
+ await waitForTransaction(() =>
+ writeContract(config, {
+ address: factoryAddress,
+ abi: CreateCallAbi,
+ functionName: "performCreate2",
+ args: [0n, deploymentData, salt],
+ chainId: DEFAULT_CHAIN.id,
+ }),
+ );
+ } catch (err: unknown) {
+ console.log("Trade executor deployment error:", err);
+ }
+ return { predictedAddress };
+}
+
+export async function initTradeExecutor(account: Address) {
+ const constructorData = encodeAbiParameters([{ type: "address" }], [account]);
+ return await checkAndDeployWithFactory({
+ factoryAddress: GNOSIS_CREATE_CALL,
+ ownerAddress: account,
+ bytecode: formatBytecode(TradeExecutorBytecode),
+ constructorData,
+ });
+}
+
+export async function checkTradeExecutorCreated(account: Address) {
+ const constructorData = encodeAbiParameters([{ type: "address" }], [account]);
+ return await checkContractCreated({
+ factoryAddress: GNOSIS_CREATE_CALL,
+ ownerAddress: account,
+ bytecode: formatBytecode(TradeExecutorBytecode),
+ constructorData,
+ });
+}
diff --git a/src/utils/waitForTransaction.ts b/src/utils/waitForTransaction.ts
new file mode 100644
index 0000000..e6db739
--- /dev/null
+++ b/src/utils/waitForTransaction.ts
@@ -0,0 +1,52 @@
+import { waitForTransactionReceipt } from "@wagmi/core";
+
+import { config } from "@/wagmiConfig";
+
+type TransactionFn = () => Promise<`0x${string}` | undefined>;
+
+export type TransactionResult =
+ | {
+ status: true;
+ hash: `0x${string}`;
+ }
+ | {
+ status: false;
+ hash?: `0x${string}`;
+ error: Error;
+ };
+
+/**
+ * Wraps a wagmi write contract call to wait for the transaction to be confirmed.
+ * @param transactionFn A function that calls wagmi's writeContract or writeContractAsync and
+ * returns a promise for the transaction hash.
+ * @returns A promise that resolves with the transaction result.
+ */
+export const waitForTransaction = async (
+ transactionFn: TransactionFn,
+): Promise => {
+ try {
+ const hash = await transactionFn();
+
+ if (!hash) {
+ const error = new Error("Transaction failed to send or was rejected.");
+ return { status: false, error };
+ }
+
+ const receipt = await waitForTransactionReceipt(config, {
+ hash,
+ confirmations: 2,
+ });
+
+ if (receipt.status === "reverted") {
+ const error = new Error("Transaction was reverted.");
+ return { status: false, hash, error };
+ }
+
+ return { status: true, hash };
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ } catch (e: any) {
+ const error =
+ e instanceof Error ? e : new Error(String(e.shortMessage ?? e.message));
+ return { status: false, error };
+ }
+};
diff --git a/yarn.lock b/yarn.lock
index 0a02c4b..93c0960 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -29,6 +29,57 @@ __metadata:
languageName: node
linkType: hard
+"@ardatan/relay-compiler@npm:12.0.0":
+ version: 12.0.0
+ resolution: "@ardatan/relay-compiler@npm:12.0.0"
+ dependencies:
+ "@babel/core": "npm:^7.14.0"
+ "@babel/generator": "npm:^7.14.0"
+ "@babel/parser": "npm:^7.14.0"
+ "@babel/runtime": "npm:^7.0.0"
+ "@babel/traverse": "npm:^7.14.0"
+ "@babel/types": "npm:^7.0.0"
+ babel-preset-fbjs: "npm:^3.4.0"
+ chalk: "npm:^4.0.0"
+ fb-watchman: "npm:^2.0.0"
+ fbjs: "npm:^3.0.0"
+ glob: "npm:^7.1.1"
+ immutable: "npm:~3.7.6"
+ invariant: "npm:^2.2.4"
+ nullthrows: "npm:^1.1.1"
+ relay-runtime: "npm:12.0.0"
+ signedsource: "npm:^1.0.0"
+ yargs: "npm:^15.3.1"
+ peerDependencies:
+ graphql: "*"
+ bin:
+ relay-compiler: bin/relay-compiler
+ checksum: 10c0/7207d65dd39d3a6202fcee81b03338409642a0ff4e7f799b4a074025429ce2b17b6c71c9579a6328b0f4548763ba4efbff0436cddbcad934af00cc4dbc7ac4e1
+ languageName: node
+ linkType: hard
+
+"@ardatan/relay-compiler@npm:^12.0.3":
+ version: 12.0.3
+ resolution: "@ardatan/relay-compiler@npm:12.0.3"
+ dependencies:
+ "@babel/generator": "npm:^7.26.10"
+ "@babel/parser": "npm:^7.26.10"
+ "@babel/runtime": "npm:^7.26.10"
+ chalk: "npm:^4.0.0"
+ fb-watchman: "npm:^2.0.0"
+ immutable: "npm:~3.7.6"
+ invariant: "npm:^2.2.4"
+ nullthrows: "npm:^1.1.1"
+ relay-runtime: "npm:12.0.0"
+ signedsource: "npm:^1.0.0"
+ peerDependencies:
+ graphql: "*"
+ bin:
+ relay-compiler: bin/relay-compiler
+ checksum: 10c0/f0a69bc448733c594af896d8d51eefec7afde470d67093d419d58ec93270e22781571a7d621edeba18fd61d44fe68bfa72dc0a9bc95c54fe845817adf0883eca
+ languageName: node
+ linkType: hard
+
"@assemblyscript/loader@npm:^0.9.4":
version: 0.9.4
resolution: "@assemblyscript/loader@npm:0.9.4"
@@ -47,6 +98,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/compat-data@npm:^7.20.5":
+ version: 7.28.5
+ resolution: "@babel/compat-data@npm:7.28.5"
+ checksum: 10c0/702a25de73087b0eba325c1d10979eed7c9b6662677386ba7b5aa6eace0fc0676f78343bae080a0176ae26f58bd5535d73b9d0fbb547fef377692e8b249353a7
+ languageName: node
+ linkType: hard
+
"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.27.2":
version: 7.27.5
resolution: "@babel/compat-data@npm:7.27.5"
@@ -54,6 +112,29 @@ __metadata:
languageName: node
linkType: hard
+"@babel/core@npm:^7.14.0, @babel/core@npm:^7.26.10":
+ version: 7.28.5
+ resolution: "@babel/core@npm:7.28.5"
+ dependencies:
+ "@babel/code-frame": "npm:^7.27.1"
+ "@babel/generator": "npm:^7.28.5"
+ "@babel/helper-compilation-targets": "npm:^7.27.2"
+ "@babel/helper-module-transforms": "npm:^7.28.3"
+ "@babel/helpers": "npm:^7.28.4"
+ "@babel/parser": "npm:^7.28.5"
+ "@babel/template": "npm:^7.27.2"
+ "@babel/traverse": "npm:^7.28.5"
+ "@babel/types": "npm:^7.28.5"
+ "@jridgewell/remapping": "npm:^2.3.5"
+ convert-source-map: "npm:^2.0.0"
+ debug: "npm:^4.1.0"
+ gensync: "npm:^1.0.0-beta.2"
+ json5: "npm:^2.2.3"
+ semver: "npm:^6.3.1"
+ checksum: 10c0/535f82238027621da6bdffbdbe896ebad3558b311d6f8abc680637a9859b96edbf929ab010757055381570b29cf66c4a295b5618318d27a4273c0e2033925e72
+ languageName: node
+ linkType: hard
+
"@babel/core@npm:^7.21.3":
version: 7.27.4
resolution: "@babel/core@npm:7.27.4"
@@ -77,6 +158,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/generator@npm:^7.14.0, @babel/generator@npm:^7.18.13, @babel/generator@npm:^7.26.10, @babel/generator@npm:^7.28.5":
+ version: 7.28.5
+ resolution: "@babel/generator@npm:7.28.5"
+ dependencies:
+ "@babel/parser": "npm:^7.28.5"
+ "@babel/types": "npm:^7.28.5"
+ "@jridgewell/gen-mapping": "npm:^0.3.12"
+ "@jridgewell/trace-mapping": "npm:^0.3.28"
+ jsesc: "npm:^3.0.2"
+ checksum: 10c0/9f219fe1d5431b6919f1a5c60db8d5d34fe546c0d8f5a8511b32f847569234ffc8032beb9e7404649a143f54e15224ecb53a3d11b6bb85c3203e573d91fca752
+ languageName: node
+ linkType: hard
+
"@babel/generator@npm:^7.27.3":
version: 7.27.5
resolution: "@babel/generator@npm:7.27.5"
@@ -90,7 +184,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/helper-annotate-as-pure@npm:^7.27.1":
+"@babel/helper-annotate-as-pure@npm:^7.27.1, @babel/helper-annotate-as-pure@npm:^7.27.3":
version: 7.27.3
resolution: "@babel/helper-annotate-as-pure@npm:7.27.3"
dependencies:
@@ -99,7 +193,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.27.1, @babel/helper-compilation-targets@npm:^7.27.2":
+"@babel/helper-compilation-targets@npm:^7.20.7, @babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.27.1, @babel/helper-compilation-targets@npm:^7.27.2":
version: 7.27.2
resolution: "@babel/helper-compilation-targets@npm:7.27.2"
dependencies:
@@ -112,6 +206,23 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-create-class-features-plugin@npm:^7.18.6":
+ version: 7.28.5
+ resolution: "@babel/helper-create-class-features-plugin@npm:7.28.5"
+ dependencies:
+ "@babel/helper-annotate-as-pure": "npm:^7.27.3"
+ "@babel/helper-member-expression-to-functions": "npm:^7.28.5"
+ "@babel/helper-optimise-call-expression": "npm:^7.27.1"
+ "@babel/helper-replace-supers": "npm:^7.27.1"
+ "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1"
+ "@babel/traverse": "npm:^7.28.5"
+ semver: "npm:^6.3.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10c0/786a6514efcf4514aaad85beed419b9184d059f4c9a9a95108f320142764999827252a851f7071de19f29424d369616573ecbaa347f1ce23fb12fc6827d9ff56
+ languageName: node
+ linkType: hard
+
"@babel/helper-create-class-features-plugin@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/helper-create-class-features-plugin@npm:7.27.1"
@@ -157,6 +268,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-globals@npm:^7.28.0":
+ version: 7.28.0
+ resolution: "@babel/helper-globals@npm:7.28.0"
+ checksum: 10c0/5a0cd0c0e8c764b5f27f2095e4243e8af6fa145daea2b41b53c0c1414fe6ff139e3640f4e2207ae2b3d2153a1abd346f901c26c290ee7cb3881dd922d4ee9232
+ languageName: node
+ linkType: hard
+
"@babel/helper-member-expression-to-functions@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/helper-member-expression-to-functions@npm:7.27.1"
@@ -167,6 +285,16 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-member-expression-to-functions@npm:^7.28.5":
+ version: 7.28.5
+ resolution: "@babel/helper-member-expression-to-functions@npm:7.28.5"
+ dependencies:
+ "@babel/traverse": "npm:^7.28.5"
+ "@babel/types": "npm:^7.28.5"
+ checksum: 10c0/4e6e05fbf4dffd0bc3e55e28fcaab008850be6de5a7013994ce874ec2beb90619cda4744b11607a60f8aae0227694502908add6188ceb1b5223596e765b44814
+ languageName: node
+ linkType: hard
+
"@babel/helper-module-imports@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/helper-module-imports@npm:7.27.1"
@@ -190,6 +318,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-module-transforms@npm:^7.28.3":
+ version: 7.28.3
+ resolution: "@babel/helper-module-transforms@npm:7.28.3"
+ dependencies:
+ "@babel/helper-module-imports": "npm:^7.27.1"
+ "@babel/helper-validator-identifier": "npm:^7.27.1"
+ "@babel/traverse": "npm:^7.28.3"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10c0/549be62515a6d50cd4cfefcab1b005c47f89bd9135a22d602ee6a5e3a01f27571868ada10b75b033569f24dc4a2bb8d04bfa05ee75c16da7ade2d0db1437fcdb
+ languageName: node
+ linkType: hard
+
"@babel/helper-optimise-call-expression@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/helper-optimise-call-expression@npm:7.27.1"
@@ -199,7 +340,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.27.1":
+"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.8.0":
version: 7.27.1
resolution: "@babel/helper-plugin-utils@npm:7.27.1"
checksum: 10c0/94cf22c81a0c11a09b197b41ab488d416ff62254ce13c57e62912c85700dc2e99e555225787a4099ff6bae7a1812d622c80fbaeda824b79baa10a6c5ac4cf69b
@@ -256,6 +397,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-validator-identifier@npm:^7.28.5":
+ version: 7.28.5
+ resolution: "@babel/helper-validator-identifier@npm:7.28.5"
+ checksum: 10c0/42aaebed91f739a41f3d80b72752d1f95fd7c72394e8e4bd7cdd88817e0774d80a432451bcba17c2c642c257c483bf1d409dd4548883429ea9493a3bc4ab0847
+ languageName: node
+ linkType: hard
+
"@babel/helper-validator-option@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/helper-validator-option@npm:7.27.1"
@@ -284,6 +432,27 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helpers@npm:^7.28.4":
+ version: 7.28.4
+ resolution: "@babel/helpers@npm:7.28.4"
+ dependencies:
+ "@babel/template": "npm:^7.27.2"
+ "@babel/types": "npm:^7.28.4"
+ checksum: 10c0/aaa5fb8098926dfed5f223adf2c5e4c7fbba4b911b73dfec2d7d3083f8ba694d201a206db673da2d9b3ae8c01793e795767654558c450c8c14b4c2175b4fcb44
+ languageName: node
+ linkType: hard
+
+"@babel/parser@npm:^7.14.0, @babel/parser@npm:^7.26.10, @babel/parser@npm:^7.28.5":
+ version: 7.28.5
+ resolution: "@babel/parser@npm:7.28.5"
+ dependencies:
+ "@babel/types": "npm:^7.28.5"
+ bin:
+ parser: ./bin/babel-parser.js
+ checksum: 10c0/5bbe48bf2c79594ac02b490a41ffde7ef5aa22a9a88ad6bcc78432a6ba8a9d638d531d868bd1f104633f1f6bba9905746e15185b8276a3756c42b765d131b1ef
+ languageName: node
+ linkType: hard
+
"@babel/parser@npm:^7.27.2, @babel/parser@npm:^7.27.4, @babel/parser@npm:^7.27.5":
version: 7.27.5
resolution: "@babel/parser@npm:7.27.5"
@@ -354,6 +523,33 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-proposal-class-properties@npm:^7.0.0":
+ version: 7.18.6
+ resolution: "@babel/plugin-proposal-class-properties@npm:7.18.6"
+ dependencies:
+ "@babel/helper-create-class-features-plugin": "npm:^7.18.6"
+ "@babel/helper-plugin-utils": "npm:^7.18.6"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10c0/d5172ac6c9948cdfc387e94f3493ad86cb04035cf7433f86b5d358270b1b9752dc25e176db0c5d65892a246aca7bdb4636672e15626d7a7de4bc0bd0040168d9
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-proposal-object-rest-spread@npm:^7.0.0":
+ version: 7.20.7
+ resolution: "@babel/plugin-proposal-object-rest-spread@npm:7.20.7"
+ dependencies:
+ "@babel/compat-data": "npm:^7.20.5"
+ "@babel/helper-compilation-targets": "npm:^7.20.7"
+ "@babel/helper-plugin-utils": "npm:^7.20.2"
+ "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3"
+ "@babel/plugin-transform-parameters": "npm:^7.20.7"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10c0/b9818749bb49d8095df64c45db682448d04743d96722984cbfd375733b2585c26d807f84b4fdb28474f2d614be6a6ffe3d96ffb121840e9e5345b2ccc0438bd8
+ languageName: node
+ linkType: hard
+
"@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2":
version: 7.21.0-placeholder-for-preset-env.2
resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2"
@@ -363,7 +559,29 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-syntax-import-assertions@npm:^7.27.1":
+"@babel/plugin-syntax-class-properties@npm:^7.0.0":
+ version: 7.12.13
+ resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.12.13"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10c0/95168fa186416195280b1264fb18afcdcdcea780b3515537b766cb90de6ce042d42dd6a204a39002f794ae5845b02afb0fd4861a3308a861204a55e68310a120
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-flow@npm:^7.0.0, @babel/plugin-syntax-flow@npm:^7.27.1":
+ version: 7.27.1
+ resolution: "@babel/plugin-syntax-flow@npm:7.27.1"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.27.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10c0/4d34ca47044398665cbe0293baea7be230ca4090bc7981ffba5273402a215c95976c6f811c7b32f10b326cc6aab6886f26c29630c429aa45c3f350c5ccdfdbbf
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-syntax-import-assertions@npm:^7.26.0, @babel/plugin-syntax-import-assertions@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-syntax-import-assertions@npm:7.27.1"
dependencies:
@@ -385,7 +603,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-syntax-jsx@npm:^7.27.1":
+"@babel/plugin-syntax-jsx@npm:^7.0.0, @babel/plugin-syntax-jsx@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-syntax-jsx@npm:7.27.1"
dependencies:
@@ -396,6 +614,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-syntax-object-rest-spread@npm:^7.0.0, @babel/plugin-syntax-object-rest-spread@npm:^7.8.3":
+ version: 7.8.3
+ resolution: "@babel/plugin-syntax-object-rest-spread@npm:7.8.3"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.8.0"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10c0/ee1eab52ea6437e3101a0a7018b0da698545230015fc8ab129d292980ec6dff94d265e9e90070e8ae5fed42f08f1622c14c94552c77bcac784b37f503a82ff26
+ languageName: node
+ linkType: hard
+
"@babel/plugin-syntax-typescript@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-syntax-typescript@npm:7.27.1"
@@ -419,7 +648,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-arrow-functions@npm:^7.27.1":
+"@babel/plugin-transform-arrow-functions@npm:^7.0.0, @babel/plugin-transform-arrow-functions@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-arrow-functions@npm:7.27.1"
dependencies:
@@ -456,7 +685,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-block-scoped-functions@npm:^7.27.1":
+"@babel/plugin-transform-block-scoped-functions@npm:^7.0.0, @babel/plugin-transform-block-scoped-functions@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.27.1"
dependencies:
@@ -467,6 +696,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-block-scoping@npm:^7.0.0":
+ version: 7.28.5
+ resolution: "@babel/plugin-transform-block-scoping@npm:7.28.5"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.27.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10c0/6b098887b375c23813ccee7a00179501fc5f709b4ee5a4b2a5c5c9ef3b44cee49e240214b1a9b4ad2bd1911fab3335eac2f0a3c5f014938a1b61bec84cec4845
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-block-scoping@npm:^7.27.1":
version: 7.27.5
resolution: "@babel/plugin-transform-block-scoping@npm:7.27.5"
@@ -502,6 +742,22 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-classes@npm:^7.0.0":
+ version: 7.28.4
+ resolution: "@babel/plugin-transform-classes@npm:7.28.4"
+ dependencies:
+ "@babel/helper-annotate-as-pure": "npm:^7.27.3"
+ "@babel/helper-compilation-targets": "npm:^7.27.2"
+ "@babel/helper-globals": "npm:^7.28.0"
+ "@babel/helper-plugin-utils": "npm:^7.27.1"
+ "@babel/helper-replace-supers": "npm:^7.27.1"
+ "@babel/traverse": "npm:^7.28.4"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10c0/76687ed37216ff012c599870dc00183fb716f22e1a02fe9481943664c0e4d0d88c3da347dc3fe290d4728f4d47cd594ffa621d23845e2bb8ab446e586308e066
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-classes@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-classes@npm:7.27.1"
@@ -518,7 +774,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-computed-properties@npm:^7.27.1":
+"@babel/plugin-transform-computed-properties@npm:^7.0.0, @babel/plugin-transform-computed-properties@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-computed-properties@npm:7.27.1"
dependencies:
@@ -530,6 +786,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-destructuring@npm:^7.0.0":
+ version: 7.28.5
+ resolution: "@babel/plugin-transform-destructuring@npm:7.28.5"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.27.1"
+ "@babel/traverse": "npm:^7.28.5"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10c0/288207f488412b23bb206c7c01ba143714e2506b72a9ec09e993f28366cc8188d121bde714659b3437984a86d2881d9b1b06de3089d5582823ccf2f3b3eaa2c4
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-destructuring@npm:^7.27.1, @babel/plugin-transform-destructuring@npm:^7.27.3":
version: 7.27.3
resolution: "@babel/plugin-transform-destructuring@npm:7.27.3"
@@ -609,7 +877,19 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-for-of@npm:^7.27.1":
+"@babel/plugin-transform-flow-strip-types@npm:^7.0.0":
+ version: 7.27.1
+ resolution: "@babel/plugin-transform-flow-strip-types@npm:7.27.1"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.27.1"
+ "@babel/plugin-syntax-flow": "npm:^7.27.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10c0/c61c43244aacdcd479ad9ba618e1c095a5db7e4eadc3d19249602febc4e97153230273c014933f5fe4e92062fa56dab9bed4bc430197d5b2ffeb2158a4bf6786
+ languageName: node
+ linkType: hard
+
+"@babel/plugin-transform-for-of@npm:^7.0.0, @babel/plugin-transform-for-of@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-for-of@npm:7.27.1"
dependencies:
@@ -621,7 +901,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-function-name@npm:^7.27.1":
+"@babel/plugin-transform-function-name@npm:^7.0.0, @babel/plugin-transform-function-name@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-function-name@npm:7.27.1"
dependencies:
@@ -645,7 +925,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-literals@npm:^7.27.1":
+"@babel/plugin-transform-literals@npm:^7.0.0, @babel/plugin-transform-literals@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-literals@npm:7.27.1"
dependencies:
@@ -667,7 +947,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-member-expression-literals@npm:^7.27.1":
+"@babel/plugin-transform-member-expression-literals@npm:^7.0.0, @babel/plugin-transform-member-expression-literals@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-member-expression-literals@npm:7.27.1"
dependencies:
@@ -690,7 +970,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-modules-commonjs@npm:^7.27.1":
+"@babel/plugin-transform-modules-commonjs@npm:^7.0.0, @babel/plugin-transform-modules-commonjs@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-modules-commonjs@npm:7.27.1"
dependencies:
@@ -787,7 +1067,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-object-super@npm:^7.27.1":
+"@babel/plugin-transform-object-super@npm:^7.0.0, @babel/plugin-transform-object-super@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-object-super@npm:7.27.1"
dependencies:
@@ -822,6 +1102,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-parameters@npm:^7.0.0, @babel/plugin-transform-parameters@npm:^7.20.7":
+ version: 7.27.7
+ resolution: "@babel/plugin-transform-parameters@npm:7.27.7"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.27.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10c0/f2da3804e047d9f1cfb27be6c014e2c7f6cf5e1e38290d1cb3cb2607859e3d6facb4ee8c8c1e336e9fbb440091a174ce95ce156582d7e8bf9c0e735d11681f0f
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-parameters@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-parameters@npm:7.27.1"
@@ -858,7 +1149,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-property-literals@npm:^7.27.1":
+"@babel/plugin-transform-property-literals@npm:^7.0.0, @babel/plugin-transform-property-literals@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-property-literals@npm:7.27.1"
dependencies:
@@ -880,6 +1171,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/plugin-transform-react-display-name@npm:^7.0.0":
+ version: 7.28.0
+ resolution: "@babel/plugin-transform-react-display-name@npm:7.28.0"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.27.1"
+ peerDependencies:
+ "@babel/core": ^7.0.0-0
+ checksum: 10c0/f5f86d2ad92be3e962158f344c2e385e23e2dfae7c8c7dc32138fb2cc46f63f5e50386c9f6c6fc16dbf1792c7bb650ad92c18203d0c2c0bd875bc28b0b80ef30
+ languageName: node
+ linkType: hard
+
"@babel/plugin-transform-react-display-name@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-react-display-name@npm:7.27.1"
@@ -902,7 +1204,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-react-jsx@npm:^7.27.1":
+"@babel/plugin-transform-react-jsx@npm:^7.0.0, @babel/plugin-transform-react-jsx@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-react-jsx@npm:7.27.1"
dependencies:
@@ -963,7 +1265,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-shorthand-properties@npm:^7.27.1":
+"@babel/plugin-transform-shorthand-properties@npm:^7.0.0, @babel/plugin-transform-shorthand-properties@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-shorthand-properties@npm:7.27.1"
dependencies:
@@ -974,7 +1276,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-spread@npm:^7.27.1":
+"@babel/plugin-transform-spread@npm:^7.0.0, @babel/plugin-transform-spread@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-spread@npm:7.27.1"
dependencies:
@@ -997,7 +1299,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-template-literals@npm:^7.27.1":
+"@babel/plugin-transform-template-literals@npm:^7.0.0, @babel/plugin-transform-template-literals@npm:^7.27.1":
version: 7.27.1
resolution: "@babel/plugin-transform-template-literals@npm:7.27.1"
dependencies:
@@ -1204,6 +1506,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.26.10":
+ version: 7.28.4
+ resolution: "@babel/runtime@npm:7.28.4"
+ checksum: 10c0/792ce7af9750fb9b93879cc9d1db175701c4689da890e6ced242ea0207c9da411ccf16dc04e689cc01158b28d7898c40d75598f4559109f761c12ce01e959bf7
+ languageName: node
+ linkType: hard
+
"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.26.0":
version: 7.27.6
resolution: "@babel/runtime@npm:7.27.6"
@@ -1211,7 +1520,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2":
+"@babel/template@npm:^7.18.10, @babel/template@npm:^7.20.7, @babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2":
version: 7.27.2
resolution: "@babel/template@npm:7.27.2"
dependencies:
@@ -1222,6 +1531,21 @@ __metadata:
languageName: node
linkType: hard
+"@babel/traverse@npm:^7.14.0, @babel/traverse@npm:^7.26.10, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4, @babel/traverse@npm:^7.28.5":
+ version: 7.28.5
+ resolution: "@babel/traverse@npm:7.28.5"
+ dependencies:
+ "@babel/code-frame": "npm:^7.27.1"
+ "@babel/generator": "npm:^7.28.5"
+ "@babel/helper-globals": "npm:^7.28.0"
+ "@babel/parser": "npm:^7.28.5"
+ "@babel/template": "npm:^7.27.2"
+ "@babel/types": "npm:^7.28.5"
+ debug: "npm:^4.3.1"
+ checksum: 10c0/f6c4a595993ae2b73f2d4cd9c062f2e232174d293edd4abe1d715bd6281da8d99e47c65857e8d0917d9384c65972f4acdebc6749a7c40a8fcc38b3c7fb3e706f
+ languageName: node
+ linkType: hard
+
"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.27.3, @babel/traverse@npm:^7.27.4":
version: 7.27.4
resolution: "@babel/traverse@npm:7.27.4"
@@ -1237,6 +1561,16 @@ __metadata:
languageName: node
linkType: hard
+"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.13, @babel/types@npm:^7.26.10, @babel/types@npm:^7.28.4, @babel/types@npm:^7.28.5":
+ version: 7.28.5
+ resolution: "@babel/types@npm:7.28.5"
+ dependencies:
+ "@babel/helper-string-parser": "npm:^7.27.1"
+ "@babel/helper-validator-identifier": "npm:^7.28.5"
+ checksum: 10c0/a5a483d2100befbf125793640dec26b90b95fd233a94c19573325898a5ce1e52cdfa96e495c7dcc31b5eca5b66ce3e6d4a0f5a4a62daec271455959f208ab08a
+ languageName: node
+ linkType: hard
+
"@babel/types@npm:^7.21.3, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.27.6, @babel/types@npm:^7.4.4":
version: 7.27.6
resolution: "@babel/types@npm:7.27.6"
@@ -1353,6 +1687,38 @@ __metadata:
languageName: node
linkType: hard
+"@envelop/core@npm:^5.2.3, @envelop/core@npm:^5.3.0":
+ version: 5.3.2
+ resolution: "@envelop/core@npm:5.3.2"
+ dependencies:
+ "@envelop/instrumentation": "npm:^1.0.0"
+ "@envelop/types": "npm:^5.2.1"
+ "@whatwg-node/promise-helpers": "npm:^1.2.4"
+ tslib: "npm:^2.5.0"
+ checksum: 10c0/280c80472381d059d0cadee342d4f75399156a3fb8eac799f52684a1d7a2ffdb91b456d83d1e50c66a185dad3716838d3dbcad1735a2b78abcb8ed77f3277f01
+ languageName: node
+ linkType: hard
+
+"@envelop/instrumentation@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "@envelop/instrumentation@npm:1.0.0"
+ dependencies:
+ "@whatwg-node/promise-helpers": "npm:^1.2.1"
+ tslib: "npm:^2.5.0"
+ checksum: 10c0/134df1ac481fb392aafc4522a22bcdc6ef0701f2d15d51b16207f3c9a4c7d3760adfa5f5bcc84f0c0ec7b011d84bcd40fff671eb471bed54bd928c165994b4e3
+ languageName: node
+ linkType: hard
+
+"@envelop/types@npm:^5.2.1":
+ version: 5.2.1
+ resolution: "@envelop/types@npm:5.2.1"
+ dependencies:
+ "@whatwg-node/promise-helpers": "npm:^1.0.0"
+ tslib: "npm:^2.5.0"
+ checksum: 10c0/2cdbb29d98350d957e18aff38ddf95670c249df894afab7fc888e2a02b43ca029fde96ca2829e5350bf83b982bc0267a5c8f7ee3ed9d353d4f145ebc0dc0b1e0
+ languageName: node
+ linkType: hard
+
"@esbuild/aix-ppc64@npm:0.25.5":
version: 0.25.5
resolution: "@esbuild/aix-ppc64@npm:0.25.5"
@@ -2035,6 +2401,13 @@ __metadata:
languageName: node
linkType: hard
+"@fastify/busboy@npm:^3.1.1":
+ version: 3.2.0
+ resolution: "@fastify/busboy@npm:3.2.0"
+ checksum: 10c0/3e4fb00a27e3149d1c68de8ff14007d2bbcbbc171a9d050d0a8772e836727329d4d3f130995ebaa19cf537d5d2f5ce2a88000366e6192e751457bfcc2125f351
+ languageName: node
+ linkType: hard
+
"@formatjs/ecma402-abstract@npm:2.3.4":
version: 2.3.4
resolution: "@formatjs/ecma402-abstract@npm:2.3.4"
@@ -2086,7 +2459,804 @@ __metadata:
languageName: node
linkType: hard
-"@graphql-typed-document-node/core@npm:^3.1.1":
+"@graphql-codegen/add@npm:^5.0.3":
+ version: 5.0.3
+ resolution: "@graphql-codegen/add@npm:5.0.3"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^5.0.3"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/2ddb8b57a0b445f109b1d8e5611e838ff590dc3c6c210ba1c31e3967e6a58097bceaef79b501eace700cd6210dca0d1ef3d28519ed7b5a4f3ce6cfc8f1508c90
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/cli@npm:^5.0.2":
+ version: 5.0.7
+ resolution: "@graphql-codegen/cli@npm:5.0.7"
+ dependencies:
+ "@babel/generator": "npm:^7.18.13"
+ "@babel/template": "npm:^7.18.10"
+ "@babel/types": "npm:^7.18.13"
+ "@graphql-codegen/client-preset": "npm:^4.8.2"
+ "@graphql-codegen/core": "npm:^4.0.2"
+ "@graphql-codegen/plugin-helpers": "npm:^5.1.1"
+ "@graphql-tools/apollo-engine-loader": "npm:^8.0.0"
+ "@graphql-tools/code-file-loader": "npm:^8.0.0"
+ "@graphql-tools/git-loader": "npm:^8.0.0"
+ "@graphql-tools/github-loader": "npm:^8.0.0"
+ "@graphql-tools/graphql-file-loader": "npm:^8.0.0"
+ "@graphql-tools/json-file-loader": "npm:^8.0.0"
+ "@graphql-tools/load": "npm:^8.1.0"
+ "@graphql-tools/prisma-loader": "npm:^8.0.0"
+ "@graphql-tools/url-loader": "npm:^8.0.0"
+ "@graphql-tools/utils": "npm:^10.0.0"
+ "@whatwg-node/fetch": "npm:^0.10.0"
+ chalk: "npm:^4.1.0"
+ cosmiconfig: "npm:^8.1.3"
+ debounce: "npm:^1.2.0"
+ detect-indent: "npm:^6.0.0"
+ graphql-config: "npm:^5.1.1"
+ inquirer: "npm:^8.0.0"
+ is-glob: "npm:^4.0.1"
+ jiti: "npm:^1.17.1"
+ json-to-pretty-yaml: "npm:^1.2.2"
+ listr2: "npm:^4.0.5"
+ log-symbols: "npm:^4.0.0"
+ micromatch: "npm:^4.0.5"
+ shell-quote: "npm:^1.7.3"
+ string-env-interpolation: "npm:^1.0.1"
+ ts-log: "npm:^2.2.3"
+ tslib: "npm:^2.4.0"
+ yaml: "npm:^2.3.1"
+ yargs: "npm:^17.0.0"
+ peerDependencies:
+ "@parcel/watcher": ^2.1.0
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ peerDependenciesMeta:
+ "@parcel/watcher":
+ optional: true
+ bin:
+ gql-gen: cjs/bin.js
+ graphql-code-generator: cjs/bin.js
+ graphql-codegen: cjs/bin.js
+ graphql-codegen-esm: esm/bin.js
+ checksum: 10c0/e7ac4e5291a82f73418cfa4167a8585b46172f405bcfec029bd3436f2b1a812272573691352a57de09220cad15cf9d73888df9c15ee6e0bd6ef372f4c25f7103
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/client-preset@npm:^4.8.2":
+ version: 4.8.3
+ resolution: "@graphql-codegen/client-preset@npm:4.8.3"
+ dependencies:
+ "@babel/helper-plugin-utils": "npm:^7.20.2"
+ "@babel/template": "npm:^7.20.7"
+ "@graphql-codegen/add": "npm:^5.0.3"
+ "@graphql-codegen/gql-tag-operations": "npm:4.0.17"
+ "@graphql-codegen/plugin-helpers": "npm:^5.1.1"
+ "@graphql-codegen/typed-document-node": "npm:^5.1.2"
+ "@graphql-codegen/typescript": "npm:^4.1.6"
+ "@graphql-codegen/typescript-operations": "npm:^4.6.1"
+ "@graphql-codegen/visitor-plugin-common": "npm:^5.8.0"
+ "@graphql-tools/documents": "npm:^1.0.0"
+ "@graphql-tools/utils": "npm:^10.0.0"
+ "@graphql-typed-document-node/core": "npm:3.2.0"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ graphql-sock: ^1.0.0
+ peerDependenciesMeta:
+ graphql-sock:
+ optional: true
+ checksum: 10c0/048b5b465d81aa08ea43956837fe43057b3ca771dbaf92fe453512f5f9ef38719aa00eba3980d6c3a769bb61b77056fbdc9c7cf69255977e053b5c3419deef53
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/core@npm:^4.0.2":
+ version: 4.0.2
+ resolution: "@graphql-codegen/core@npm:4.0.2"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^5.0.3"
+ "@graphql-tools/schema": "npm:^10.0.0"
+ "@graphql-tools/utils": "npm:^10.0.0"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/8387a91dd852e8c45e76843453fc50dba4e63079f1ecfe2242f3c49561d229d55d1083905f46049ddd7f9f94b8e55a96e6deeac8a0c1db34a7312f5f216ca229
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/gql-tag-operations@npm:4.0.17":
+ version: 4.0.17
+ resolution: "@graphql-codegen/gql-tag-operations@npm:4.0.17"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^5.1.0"
+ "@graphql-codegen/visitor-plugin-common": "npm:5.8.0"
+ "@graphql-tools/utils": "npm:^10.0.0"
+ auto-bind: "npm:~4.0.0"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/15f65a0449f167a5b3176e71cdb6b1c1b48528deac9da379ece6b84f1a112d00b3b0e3bd5cc48b52927bbe4fc7fdd6832532a3475bc4e214077f546704494b92
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/plugin-helpers@npm:^3.0.0, @graphql-codegen/plugin-helpers@npm:^3.1.2":
+ version: 3.1.2
+ resolution: "@graphql-codegen/plugin-helpers@npm:3.1.2"
+ dependencies:
+ "@graphql-tools/utils": "npm:^9.0.0"
+ change-case-all: "npm:1.0.15"
+ common-tags: "npm:1.8.2"
+ import-from: "npm:4.0.0"
+ lodash: "npm:~4.17.0"
+ tslib: "npm:~2.4.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/fbe326270aef17792b326ad8d8ae3e82acf1b60f3137a4d99eb605c0c8d709830537fec112705484b5fd2c9ee1d0588fbf4269f31c9a5852567c5d4c0c7057b7
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/plugin-helpers@npm:^5.0.3, @graphql-codegen/plugin-helpers@npm:^5.1.0, @graphql-codegen/plugin-helpers@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "@graphql-codegen/plugin-helpers@npm:5.1.1"
+ dependencies:
+ "@graphql-tools/utils": "npm:^10.0.0"
+ change-case-all: "npm:1.0.15"
+ common-tags: "npm:1.8.2"
+ import-from: "npm:4.0.0"
+ lodash: "npm:~4.17.0"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/1c2cfb83cf8d1fc99b55d72524f1e105950a6ab7d65c86bca9fc9f3068a579fc0c47eb5a8cf2164eec5ffc408c0f72dbab5d005e8bd539d97cd790e6ad3ce26e
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/plugin-helpers@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "@graphql-codegen/plugin-helpers@npm:6.0.0"
+ dependencies:
+ "@graphql-tools/utils": "npm:^10.0.0"
+ change-case-all: "npm:1.0.15"
+ common-tags: "npm:1.8.2"
+ import-from: "npm:4.0.0"
+ lodash: "npm:~4.17.0"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/82a790409ad96968892364aa347bb21dee270b28c0dd95d293bd6e9abfc8ea6690cd0e2ef651dc07a776f4b243df168076bf59969330305f78170dd673607b1c
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/schema-ast@npm:^4.0.2":
+ version: 4.1.0
+ resolution: "@graphql-codegen/schema-ast@npm:4.1.0"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^5.0.3"
+ "@graphql-tools/utils": "npm:^10.0.0"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/ff7ab73f46f1ae4882eda0af8c3f78d37e904108aba37d52288028ee34e9bc56236b6a032a1e2fe1283030ba5f6a5f75224285af12b3f56a76e90843e1eff0e0
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/schema-ast@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "@graphql-codegen/schema-ast@npm:5.0.0"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^6.0.0"
+ "@graphql-tools/utils": "npm:^10.0.0"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/d2eb0a72e74403fb144b278fb0769a2a949f8dc70f64992912826e42ca1f5e6bca3633cc625f3b9bb422bd7de97afeb21d3493887532f84dce9bf0d1bcd52523
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/typed-document-node@npm:^5.1.2":
+ version: 5.1.2
+ resolution: "@graphql-codegen/typed-document-node@npm:5.1.2"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^5.1.0"
+ "@graphql-codegen/visitor-plugin-common": "npm:5.8.0"
+ auto-bind: "npm:~4.0.0"
+ change-case-all: "npm:1.0.15"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/51bc87f2d9e32d4ef15d878820b8fe2ebb44006631c963395a7001ae2e7a8ba6ed402e67726605c692ea589ee256dc45d5f4c0270a75ebea61fec777ecdd0685
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/typescript-graphql-request@npm:^6.3.0":
+ version: 6.3.0
+ resolution: "@graphql-codegen/typescript-graphql-request@npm:6.3.0"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^3.0.0"
+ "@graphql-codegen/visitor-plugin-common": "npm:2.13.8"
+ auto-bind: "npm:~4.0.0"
+ tslib: "npm:^2.8.1"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ graphql-request: ^6.0.0 || ^7.0.0
+ graphql-tag: ^2.0.0
+ checksum: 10c0/6823640b577a63df8590e9e41a9508b97885a7f0c280ad67922e1a05592960c697bbdb6207dad21aa59e6ca31cfc417dba2574505423eb220de7054f0ea85a16
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/typescript-operations@npm:^4.6.1":
+ version: 4.6.1
+ resolution: "@graphql-codegen/typescript-operations@npm:4.6.1"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^5.1.0"
+ "@graphql-codegen/typescript": "npm:^4.1.6"
+ "@graphql-codegen/visitor-plugin-common": "npm:5.8.0"
+ auto-bind: "npm:~4.0.0"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ graphql-sock: ^1.0.0
+ peerDependenciesMeta:
+ graphql-sock:
+ optional: true
+ checksum: 10c0/3bfba383ba7c10e4612047559524d754d82ebe86a5c82f998e9236d5396e9172658902748243e112349392c5f2104ae7ea85185199c2c7800df55a66ff481b29
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/typescript-operations@npm:^5.0.2":
+ version: 5.0.2
+ resolution: "@graphql-codegen/typescript-operations@npm:5.0.2"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^6.0.0"
+ "@graphql-codegen/typescript": "npm:^5.0.2"
+ "@graphql-codegen/visitor-plugin-common": "npm:6.1.0"
+ auto-bind: "npm:~4.0.0"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ graphql-sock: ^1.0.0
+ peerDependenciesMeta:
+ graphql-sock:
+ optional: true
+ checksum: 10c0/c3012666de69b1fc39a881f648b8a755904813223aaf9c7b5836f8cf5b40966171cbac645e0725cb7debcf30c73c9a262f4fbfe8f6a81cd9cd8791fd5aabe116
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/typescript@npm:^4.1.6":
+ version: 4.1.6
+ resolution: "@graphql-codegen/typescript@npm:4.1.6"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^5.1.0"
+ "@graphql-codegen/schema-ast": "npm:^4.0.2"
+ "@graphql-codegen/visitor-plugin-common": "npm:5.8.0"
+ auto-bind: "npm:~4.0.0"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/5cc56b795d1c65b676251f07534296246a2de2936df6db83effd1e18a1150f739fe67d5b3ad19b75804cad2925e9957cfcd32cb6469e48c6544c498974acf351
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/typescript@npm:^5.0.2":
+ version: 5.0.2
+ resolution: "@graphql-codegen/typescript@npm:5.0.2"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^6.0.0"
+ "@graphql-codegen/schema-ast": "npm:^5.0.0"
+ "@graphql-codegen/visitor-plugin-common": "npm:6.1.0"
+ auto-bind: "npm:~4.0.0"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/012cae805f94d4a6a1df34b0c0a44328418f374e9002b327a26edf6c08050e453eaa17ed56158cc0335061d8fb25b674d28377fd8c0e4d290ee3876d0468aacd
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/visitor-plugin-common@npm:2.13.8":
+ version: 2.13.8
+ resolution: "@graphql-codegen/visitor-plugin-common@npm:2.13.8"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^3.1.2"
+ "@graphql-tools/optimize": "npm:^1.3.0"
+ "@graphql-tools/relay-operation-optimizer": "npm:^6.5.0"
+ "@graphql-tools/utils": "npm:^9.0.0"
+ auto-bind: "npm:~4.0.0"
+ change-case-all: "npm:1.0.15"
+ dependency-graph: "npm:^0.11.0"
+ graphql-tag: "npm:^2.11.0"
+ parse-filepath: "npm:^1.0.2"
+ tslib: "npm:~2.4.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/daed6e5260170991cef7c9eae3d94a7d432d273aae7d721f51051fa3e1e478d0e3515b4e444ad9d8bf605d5c1551713f09d3c59fa598249388abd7b9f05f7f66
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/visitor-plugin-common@npm:5.8.0, @graphql-codegen/visitor-plugin-common@npm:^5.8.0":
+ version: 5.8.0
+ resolution: "@graphql-codegen/visitor-plugin-common@npm:5.8.0"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^5.1.0"
+ "@graphql-tools/optimize": "npm:^2.0.0"
+ "@graphql-tools/relay-operation-optimizer": "npm:^7.0.0"
+ "@graphql-tools/utils": "npm:^10.0.0"
+ auto-bind: "npm:~4.0.0"
+ change-case-all: "npm:1.0.15"
+ dependency-graph: "npm:^0.11.0"
+ graphql-tag: "npm:^2.11.0"
+ parse-filepath: "npm:^1.0.2"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/7f3284f5b4c6a9bac873081c308c3386f3cfcb3ebcd5ba296506b1cce4c142ef7699336047dc0ef3b82d6db9a66eb449ddacd89732b3c08de683e496696d7fbb
+ languageName: node
+ linkType: hard
+
+"@graphql-codegen/visitor-plugin-common@npm:6.1.0":
+ version: 6.1.0
+ resolution: "@graphql-codegen/visitor-plugin-common@npm:6.1.0"
+ dependencies:
+ "@graphql-codegen/plugin-helpers": "npm:^6.0.0"
+ "@graphql-tools/optimize": "npm:^2.0.0"
+ "@graphql-tools/relay-operation-optimizer": "npm:^7.0.0"
+ "@graphql-tools/utils": "npm:^10.0.0"
+ auto-bind: "npm:~4.0.0"
+ change-case-all: "npm:1.0.15"
+ dependency-graph: "npm:^1.0.0"
+ graphql-tag: "npm:^2.11.0"
+ parse-filepath: "npm:^1.0.2"
+ tslib: "npm:~2.6.0"
+ peerDependencies:
+ graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ checksum: 10c0/120c1a0ad82d179c2ccd16dd6b556d93b658355d80b8fcf2efb55711466705d7fe8401ae020eef33ba57629a39affbf3d7fb84659de7191c07b79b182050126f
+ languageName: node
+ linkType: hard
+
+"@graphql-hive/signal@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "@graphql-hive/signal@npm:1.0.0"
+ checksum: 10c0/5c771417b29fa793b93d5060753ff9470425dbafe186d2a652b464e9a2a58e5e885a0cdf84d8316acc30bd6c05608b778686bb482bfe311ca410349dcaa7731f
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/apollo-engine-loader@npm:^8.0.0":
+ version: 8.0.22
+ resolution: "@graphql-tools/apollo-engine-loader@npm:8.0.22"
+ dependencies:
+ "@graphql-tools/utils": "npm:^10.9.1"
+ "@whatwg-node/fetch": "npm:^0.10.0"
+ sync-fetch: "npm:0.6.0-2"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/1fbd5501dfb72ee33b4d09109a2caca50e4dc84ebed050afa65a5d8f1dcdfefb1489d6731595068ff17d55098532b202d44ff35d55bffb96bb15aabce635612d
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/batch-execute@npm:^9.0.19":
+ version: 9.0.19
+ resolution: "@graphql-tools/batch-execute@npm:9.0.19"
+ dependencies:
+ "@graphql-tools/utils": "npm:^10.9.1"
+ "@whatwg-node/promise-helpers": "npm:^1.3.0"
+ dataloader: "npm:^2.2.3"
+ tslib: "npm:^2.8.1"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/1e3598896492113572d6e586f89bb8856ccc21e3a915e75bd67b1d02e7deaf33e011a21b9ceaacb3abbe63c83ea3d982e106e71e5c7c84f965c114dfe46d10bd
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/code-file-loader@npm:^8.0.0":
+ version: 8.1.22
+ resolution: "@graphql-tools/code-file-loader@npm:8.1.22"
+ dependencies:
+ "@graphql-tools/graphql-tag-pluck": "npm:8.3.21"
+ "@graphql-tools/utils": "npm:^10.9.1"
+ globby: "npm:^11.0.3"
+ tslib: "npm:^2.4.0"
+ unixify: "npm:^1.0.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/e07a7b2cbafd69b2b99aaf9f098c4744f810669bcb428c683fb3cb2b358be7281d0b434849409060ecb1b43d8a43875651be8a2cf70b53fa0ccdde0cf5b7ec10
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/delegate@npm:^10.2.23":
+ version: 10.2.23
+ resolution: "@graphql-tools/delegate@npm:10.2.23"
+ dependencies:
+ "@graphql-tools/batch-execute": "npm:^9.0.19"
+ "@graphql-tools/executor": "npm:^1.4.9"
+ "@graphql-tools/schema": "npm:^10.0.25"
+ "@graphql-tools/utils": "npm:^10.9.1"
+ "@repeaterjs/repeater": "npm:^3.0.6"
+ "@whatwg-node/promise-helpers": "npm:^1.3.0"
+ dataloader: "npm:^2.2.3"
+ dset: "npm:^3.1.2"
+ tslib: "npm:^2.8.1"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/bcc917cad5f8d21c593ca3382e1808b19c75ed3161ab42b2b69cb43eb53183408d27d1c77d9bf9c6f71971cd9c48109eb78183d2451ab28834a63f7fe855e788
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/documents@npm:^1.0.0":
+ version: 1.0.1
+ resolution: "@graphql-tools/documents@npm:1.0.1"
+ dependencies:
+ lodash.sortby: "npm:^4.7.0"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/df24738f8ffd844a4727884f7825d7009456d7dcb24fa91169efdc061bb72a29527abeb2e23ccf9effed195104485fa286919c33452d8744cb659ad721f17586
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/executor-common@npm:^0.0.4":
+ version: 0.0.4
+ resolution: "@graphql-tools/executor-common@npm:0.0.4"
+ dependencies:
+ "@envelop/core": "npm:^5.2.3"
+ "@graphql-tools/utils": "npm:^10.8.1"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/4cda40687e3c42f0fefc9950f5e3d89021007101c3d6aa5dba2a07e6a0ef14cc0d04424aa8777e74476d5165fb22219de175dff8a4826e520fdbee8be0d4a81d
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/executor-common@npm:^0.0.6":
+ version: 0.0.6
+ resolution: "@graphql-tools/executor-common@npm:0.0.6"
+ dependencies:
+ "@envelop/core": "npm:^5.3.0"
+ "@graphql-tools/utils": "npm:^10.9.1"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/2f7dda600983a69f0f1524965f2c665195c46d986fb88e4e2fe4653c70e95c59b09a263a2fee3f8ebc4b8107180c9fa16d472454119f5e10f7745b9c1eb589d2
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/executor-graphql-ws@npm:^2.0.1":
+ version: 2.0.7
+ resolution: "@graphql-tools/executor-graphql-ws@npm:2.0.7"
+ dependencies:
+ "@graphql-tools/executor-common": "npm:^0.0.6"
+ "@graphql-tools/utils": "npm:^10.9.1"
+ "@whatwg-node/disposablestack": "npm:^0.0.6"
+ graphql-ws: "npm:^6.0.6"
+ isomorphic-ws: "npm:^5.0.0"
+ tslib: "npm:^2.8.1"
+ ws: "npm:^8.18.3"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/6f94c2ec9ca5866bdfc6c8a95acba69e24991960323a8b5066e19cd6aa38142db56cf4324a077bbc02b6518a50c2ca8eba9b8b018d4655c520c7806c4736ad35
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/executor-http@npm:^1.1.9":
+ version: 1.3.3
+ resolution: "@graphql-tools/executor-http@npm:1.3.3"
+ dependencies:
+ "@graphql-hive/signal": "npm:^1.0.0"
+ "@graphql-tools/executor-common": "npm:^0.0.4"
+ "@graphql-tools/utils": "npm:^10.8.1"
+ "@repeaterjs/repeater": "npm:^3.0.4"
+ "@whatwg-node/disposablestack": "npm:^0.0.6"
+ "@whatwg-node/fetch": "npm:^0.10.4"
+ "@whatwg-node/promise-helpers": "npm:^1.3.0"
+ meros: "npm:^1.2.1"
+ tslib: "npm:^2.8.1"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/317259d5e4e08baea728aecdfcce56cac77fd4f68b34975befca94d74d9d989d168230a735e51426a94740335ece9a93ab6fce280196ecf993a4ea1c0097c083
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/executor-legacy-ws@npm:^1.1.19":
+ version: 1.1.19
+ resolution: "@graphql-tools/executor-legacy-ws@npm:1.1.19"
+ dependencies:
+ "@graphql-tools/utils": "npm:^10.9.1"
+ "@types/ws": "npm:^8.0.0"
+ isomorphic-ws: "npm:^5.0.0"
+ tslib: "npm:^2.4.0"
+ ws: "npm:^8.17.1"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/e2df5c77e74af87c252f66e72d3276b8714e94656cc27311b878d935abe5a74e4311ce1da0e7f7935afa651b535c26bf073e71f7829b9d155b67aec65ec60ea6
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/executor@npm:^1.4.9":
+ version: 1.4.9
+ resolution: "@graphql-tools/executor@npm:1.4.9"
+ dependencies:
+ "@graphql-tools/utils": "npm:^10.9.1"
+ "@graphql-typed-document-node/core": "npm:^3.2.0"
+ "@repeaterjs/repeater": "npm:^3.0.4"
+ "@whatwg-node/disposablestack": "npm:^0.0.6"
+ "@whatwg-node/promise-helpers": "npm:^1.0.0"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/71c8818915e62cdeaf5aec3ffbb6a98d158aacb809258059a0f7695c456a8457f9fd0a007924869f72cca4196cbe0076c5f520c7c7e493b85deba1d3610b1b93
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/git-loader@npm:^8.0.0":
+ version: 8.0.26
+ resolution: "@graphql-tools/git-loader@npm:8.0.26"
+ dependencies:
+ "@graphql-tools/graphql-tag-pluck": "npm:8.3.21"
+ "@graphql-tools/utils": "npm:^10.9.1"
+ is-glob: "npm:4.0.3"
+ micromatch: "npm:^4.0.8"
+ tslib: "npm:^2.4.0"
+ unixify: "npm:^1.0.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/8c33228090b26698cd726364d63ce2a1bf1dabf9fafe347e4d901e0c78cd8d1f81c231e091a495933c59b188f473fc59b0ece359ecbdc7bf31f8c89de8f10619
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/github-loader@npm:^8.0.0":
+ version: 8.0.22
+ resolution: "@graphql-tools/github-loader@npm:8.0.22"
+ dependencies:
+ "@graphql-tools/executor-http": "npm:^1.1.9"
+ "@graphql-tools/graphql-tag-pluck": "npm:^8.3.21"
+ "@graphql-tools/utils": "npm:^10.9.1"
+ "@whatwg-node/fetch": "npm:^0.10.0"
+ "@whatwg-node/promise-helpers": "npm:^1.0.0"
+ sync-fetch: "npm:0.6.0-2"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/a5571731045b37dff53999a0b9146fe5a02ac3e642d5902f6d7030cd13dac5ff5f6cefb13e63ddba2d150b95764e5471a9798a292ee0c8eea2f123ad531875a9
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/graphql-file-loader@npm:^8.0.0":
+ version: 8.1.2
+ resolution: "@graphql-tools/graphql-file-loader@npm:8.1.2"
+ dependencies:
+ "@graphql-tools/import": "npm:7.1.2"
+ "@graphql-tools/utils": "npm:^10.9.1"
+ globby: "npm:^11.0.3"
+ tslib: "npm:^2.4.0"
+ unixify: "npm:^1.0.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/a9a268dc8206437d1b434df5d0a42d27475e219ac262eada1ba62e932a5d7ce76ae43ed462de61f07811082eee1917a984c9f00eb478b91e9818c0bd6167636b
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/graphql-tag-pluck@npm:8.3.21, @graphql-tools/graphql-tag-pluck@npm:^8.3.21":
+ version: 8.3.21
+ resolution: "@graphql-tools/graphql-tag-pluck@npm:8.3.21"
+ dependencies:
+ "@babel/core": "npm:^7.26.10"
+ "@babel/parser": "npm:^7.26.10"
+ "@babel/plugin-syntax-import-assertions": "npm:^7.26.0"
+ "@babel/traverse": "npm:^7.26.10"
+ "@babel/types": "npm:^7.26.10"
+ "@graphql-tools/utils": "npm:^10.9.1"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/1e40267c2f35c3707bba42c0d210324e292555fe3bfd1890dd17cc7c4be2565240094bcd5c82fd452bf56ca0fda40744dd70a6e085238dc78696eeb83710d9dd
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/import@npm:7.1.2":
+ version: 7.1.2
+ resolution: "@graphql-tools/import@npm:7.1.2"
+ dependencies:
+ "@graphql-tools/utils": "npm:^10.9.1"
+ "@theguild/federation-composition": "npm:^0.20.1"
+ resolve-from: "npm:5.0.0"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/dfdb6984a03a88b88e357a45c065a3d4fd2e1e3a77f2c85ef7346b56f68665fc9d35f6cc0d93ef4ced3cd8e03073c3f4be3b227b941bcdb58b5c8e083ed0c27c
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/json-file-loader@npm:^8.0.0":
+ version: 8.0.20
+ resolution: "@graphql-tools/json-file-loader@npm:8.0.20"
+ dependencies:
+ "@graphql-tools/utils": "npm:^10.9.1"
+ globby: "npm:^11.0.3"
+ tslib: "npm:^2.4.0"
+ unixify: "npm:^1.0.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/9a4adda1e8d2b58f35e61f7c6e1d5d9b2baeea9b588b1e024a942135f4f3bde4e789cf5444fbfa56944d505e6cc8805dd2e80df8f20db1650b2bdc31a7d464f3
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/load@npm:^8.1.0":
+ version: 8.1.2
+ resolution: "@graphql-tools/load@npm:8.1.2"
+ dependencies:
+ "@graphql-tools/schema": "npm:^10.0.25"
+ "@graphql-tools/utils": "npm:^10.9.1"
+ p-limit: "npm:3.1.0"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/748a5a2e77514dbd7f3353e97f6bf54916cc298601d4a92c662777f6920e7d1a52bc0134e9b4e6ae427fb1ca42d217f1e063b307cdcd6dcaf05e5c9ca465767e
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/merge@npm:^9.0.0, @graphql-tools/merge@npm:^9.1.1":
+ version: 9.1.1
+ resolution: "@graphql-tools/merge@npm:9.1.1"
+ dependencies:
+ "@graphql-tools/utils": "npm:^10.9.1"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/61464f3cd3989101400cc0258cef700ad9763f2fc6b42638e26aeca6f641441aa1690649ea6a7c4d7183762a93654d92c64abcd8e057815056e51767659ce0a4
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/optimize@npm:^1.3.0":
+ version: 1.4.0
+ resolution: "@graphql-tools/optimize@npm:1.4.0"
+ dependencies:
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/10be773b0082fe54b9505469a89925f1a5e33f866453b88cd411261951e8718f8720451e07c56cbfb762970b56b9b45c7c748d62afcdcf9414ec64533e94e543
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/optimize@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "@graphql-tools/optimize@npm:2.0.0"
+ dependencies:
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/db4ac0a2b0c89126ee7746e5615ae003d8665b684b17fb35956a7633fefb0e329a047f32a975cfbdf83f0f5ac4ae09fe469834fd71fdd49d8ed932fda79012fd
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/prisma-loader@npm:^8.0.0":
+ version: 8.0.17
+ resolution: "@graphql-tools/prisma-loader@npm:8.0.17"
+ dependencies:
+ "@graphql-tools/url-loader": "npm:^8.0.15"
+ "@graphql-tools/utils": "npm:^10.5.6"
+ "@types/js-yaml": "npm:^4.0.0"
+ "@whatwg-node/fetch": "npm:^0.10.0"
+ chalk: "npm:^4.1.0"
+ debug: "npm:^4.3.1"
+ dotenv: "npm:^16.0.0"
+ graphql-request: "npm:^6.0.0"
+ http-proxy-agent: "npm:^7.0.0"
+ https-proxy-agent: "npm:^7.0.0"
+ jose: "npm:^5.0.0"
+ js-yaml: "npm:^4.0.0"
+ lodash: "npm:^4.17.20"
+ scuid: "npm:^1.1.0"
+ tslib: "npm:^2.4.0"
+ yaml-ast-parser: "npm:^0.0.43"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/3943be980624e3b34e0609ad1d29f9f4ce3803adf42a5eaeaf4191ecc859643fd5af8e493858e120b6641f89e28f4cd22e166afe6456e6d42f9f2e55d99490e8
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/relay-operation-optimizer@npm:^6.5.0":
+ version: 6.5.18
+ resolution: "@graphql-tools/relay-operation-optimizer@npm:6.5.18"
+ dependencies:
+ "@ardatan/relay-compiler": "npm:12.0.0"
+ "@graphql-tools/utils": "npm:^9.2.1"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/9d74d65da8bf474e256ff0cfb77afb442a968451ded6a92b8348d8ac1bca3b2c13a578ab29ac869d10d53e0101219fe8283d485fff920aa7abcc68fcbbdd9a36
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/relay-operation-optimizer@npm:^7.0.0":
+ version: 7.0.21
+ resolution: "@graphql-tools/relay-operation-optimizer@npm:7.0.21"
+ dependencies:
+ "@ardatan/relay-compiler": "npm:^12.0.3"
+ "@graphql-tools/utils": "npm:^10.9.1"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/a799f184825be478e3c779777c1c6a6204f66d553e5f00d652dbd02a2a8ad327c0282674b2500cd6b02e106085f89717fcbf9ad658a05b3423736d8fa6f7f9c8
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/schema@npm:^10.0.0, @graphql-tools/schema@npm:^10.0.25":
+ version: 10.0.25
+ resolution: "@graphql-tools/schema@npm:10.0.25"
+ dependencies:
+ "@graphql-tools/merge": "npm:^9.1.1"
+ "@graphql-tools/utils": "npm:^10.9.1"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/13c41119a2b01fecd9b863175b888987de045cf794561582bed921f167b6c4d0ac43d05115359a31dfce5222ddc659ea49179b62064da575e16028827e9b9db8
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/url-loader@npm:^8.0.0, @graphql-tools/url-loader@npm:^8.0.15":
+ version: 8.0.33
+ resolution: "@graphql-tools/url-loader@npm:8.0.33"
+ dependencies:
+ "@graphql-tools/executor-graphql-ws": "npm:^2.0.1"
+ "@graphql-tools/executor-http": "npm:^1.1.9"
+ "@graphql-tools/executor-legacy-ws": "npm:^1.1.19"
+ "@graphql-tools/utils": "npm:^10.9.1"
+ "@graphql-tools/wrap": "npm:^10.0.16"
+ "@types/ws": "npm:^8.0.0"
+ "@whatwg-node/fetch": "npm:^0.10.0"
+ "@whatwg-node/promise-helpers": "npm:^1.0.0"
+ isomorphic-ws: "npm:^5.0.0"
+ sync-fetch: "npm:0.6.0-2"
+ tslib: "npm:^2.4.0"
+ ws: "npm:^8.17.1"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/d63dda8c10d0505ea28d95648ca86aefd6328082fc46a2afbc3bfc173f712b50c8aa56d67d1ad50c0b0d4621c9d64453eec3cb36e7f811a731bbf8cf6a8662be
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/utils@npm:^10.0.0, @graphql-tools/utils@npm:^10.5.6, @graphql-tools/utils@npm:^10.8.1, @graphql-tools/utils@npm:^10.9.1":
+ version: 10.9.1
+ resolution: "@graphql-tools/utils@npm:10.9.1"
+ dependencies:
+ "@graphql-typed-document-node/core": "npm:^3.1.1"
+ "@whatwg-node/promise-helpers": "npm:^1.0.0"
+ cross-inspect: "npm:1.0.1"
+ dset: "npm:^3.1.4"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/97199f52d0235124d4371f7f54cc0df5ce9df6d8aae716ac05d8ebeda4b5ee3faf1fca94d5d1c521a565e152f8e02a1abfb9c2629ffe805c14468aec0c3d41cf
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/utils@npm:^9.0.0, @graphql-tools/utils@npm:^9.2.1":
+ version: 9.2.1
+ resolution: "@graphql-tools/utils@npm:9.2.1"
+ dependencies:
+ "@graphql-typed-document-node/core": "npm:^3.1.1"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/37a7bd7e14d28ff1bacc007dca84bc6cef2d7d7af9a547b5dbe52fcd134afddd6d4a7b2148cfbaff5ddba91a868453d597da77bd0457fb0be15928f916901606
+ languageName: node
+ linkType: hard
+
+"@graphql-tools/wrap@npm:^10.0.16":
+ version: 10.1.4
+ resolution: "@graphql-tools/wrap@npm:10.1.4"
+ dependencies:
+ "@graphql-tools/delegate": "npm:^10.2.23"
+ "@graphql-tools/schema": "npm:^10.0.25"
+ "@graphql-tools/utils": "npm:^10.9.1"
+ "@whatwg-node/promise-helpers": "npm:^1.3.0"
+ tslib: "npm:^2.8.1"
+ peerDependencies:
+ graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
+ checksum: 10c0/a89d92930b243683b4a7ae5a0104d75ae9b9e3e4cf030f9a25daa04760c7ff05861c108d1e50199091ce036e96cd85bf253a891aa2a87ef737a946b6bb99fd63
+ languageName: node
+ linkType: hard
+
+"@graphql-typed-document-node/core@npm:3.2.0, @graphql-typed-document-node/core@npm:^3.1.1, @graphql-typed-document-node/core@npm:^3.2.0":
version: 3.2.0
resolution: "@graphql-typed-document-node/core@npm:3.2.0"
peerDependencies:
@@ -2120,6 +3290,21 @@ __metadata:
languageName: node
linkType: hard
+"@inquirer/external-editor@npm:^1.0.0":
+ version: 1.0.2
+ resolution: "@inquirer/external-editor@npm:1.0.2"
+ dependencies:
+ chardet: "npm:^2.1.0"
+ iconv-lite: "npm:^0.7.0"
+ peerDependencies:
+ "@types/node": ">=18"
+ peerDependenciesMeta:
+ "@types/node":
+ optional: true
+ checksum: 10c0/414a3a2a9733459c57452d84ef19ff002222303d19041580685681153132d2a30af8f90f269b3967c30c670fa689dbb7d4fc25a86dc66f029eebe90dc7467b0a
+ languageName: node
+ linkType: hard
+
"@internationalized/date@npm:^3.7.0, @internationalized/date@npm:^3.8.2":
version: 3.8.2
resolution: "@internationalized/date@npm:3.8.2"
@@ -2180,6 +3365,16 @@ __metadata:
languageName: node
linkType: hard
+"@jridgewell/gen-mapping@npm:^0.3.12":
+ version: 0.3.13
+ resolution: "@jridgewell/gen-mapping@npm:0.3.13"
+ dependencies:
+ "@jridgewell/sourcemap-codec": "npm:^1.5.0"
+ "@jridgewell/trace-mapping": "npm:^0.3.24"
+ checksum: 10c0/9a7d65fb13bd9aec1fbab74cda08496839b7e2ceb31f5ab922b323e94d7c481ce0fc4fd7e12e2610915ed8af51178bdc61e168e92a8c8b8303b030b03489b13b
+ languageName: node
+ linkType: hard
+
"@jridgewell/gen-mapping@npm:^0.3.5":
version: 0.3.8
resolution: "@jridgewell/gen-mapping@npm:0.3.8"
@@ -2191,6 +3386,16 @@ __metadata:
languageName: node
linkType: hard
+"@jridgewell/remapping@npm:^2.3.5":
+ version: 2.3.5
+ resolution: "@jridgewell/remapping@npm:2.3.5"
+ dependencies:
+ "@jridgewell/gen-mapping": "npm:^0.3.5"
+ "@jridgewell/trace-mapping": "npm:^0.3.24"
+ checksum: 10c0/3de494219ffeb2c5c38711d0d7bb128097edf91893090a2dbc8ee0b55d092bb7347b1fd0f478486c5eab010e855c73927b1666f2107516d472d24a73017d1194
+ languageName: node
+ linkType: hard
+
"@jridgewell/resolve-uri@npm:^3.1.0":
version: 3.1.2
resolution: "@jridgewell/resolve-uri@npm:3.1.2"
@@ -2222,6 +3427,16 @@ __metadata:
languageName: node
linkType: hard
+"@jridgewell/trace-mapping@npm:^0.3.28":
+ version: 0.3.31
+ resolution: "@jridgewell/trace-mapping@npm:0.3.31"
+ dependencies:
+ "@jridgewell/resolve-uri": "npm:^3.1.0"
+ "@jridgewell/sourcemap-codec": "npm:^1.4.14"
+ checksum: 10c0/4b30ec8cd56c5fd9a661f088230af01e0c1a3888d11ffb6b47639700f71225be21d1f7e168048d6d4f9449207b978a235c07c8f15c07705685d16dc06280e9d9
+ languageName: node
+ linkType: hard
+
"@juggle/resize-observer@npm:^3.3.1":
version: 3.4.0
resolution: "@juggle/resize-observer@npm:3.4.0"
@@ -4854,6 +6069,13 @@ __metadata:
languageName: node
linkType: hard
+"@repeaterjs/repeater@npm:^3.0.4, @repeaterjs/repeater@npm:^3.0.6":
+ version: 3.0.6
+ resolution: "@repeaterjs/repeater@npm:3.0.6"
+ checksum: 10c0/c3915e2603927c7d6a9eb09673bc28fc49ab3a86947ec191a74663b33deebee2fcc4b03c31cc663ff27bd6db9e6c9487639b6935e265d601ce71b8c497f5f4a8
+ languageName: node
+ linkType: hard
+
"@rtsao/scc@npm:^1.1.0":
version: 1.1.0
resolution: "@rtsao/scc@npm:1.1.0"
@@ -5401,6 +6623,20 @@ __metadata:
languageName: node
linkType: hard
+"@theguild/federation-composition@npm:^0.20.1":
+ version: 0.20.2
+ resolution: "@theguild/federation-composition@npm:0.20.2"
+ dependencies:
+ constant-case: "npm:^3.0.4"
+ debug: "npm:4.4.3"
+ json5: "npm:^2.2.3"
+ lodash.sortby: "npm:^4.7.0"
+ peerDependencies:
+ graphql: ^16.0.0
+ checksum: 10c0/ee5c02abce6e6d9eb6e67f4dc280ebf5d81fc45055e839e3709f32c5ef5c67c847f54f2e2a9e9a6eafbc8e9b68db5f8b4dcb89c8b87dd3acc586e9e260962e7d
+ languageName: node
+ linkType: hard
+
"@trysound/sax@npm:0.2.0":
version: 0.2.0
resolution: "@trysound/sax@npm:0.2.0"
@@ -5433,6 +6669,13 @@ __metadata:
languageName: node
linkType: hard
+"@types/js-yaml@npm:^4.0.0":
+ version: 4.0.9
+ resolution: "@types/js-yaml@npm:4.0.9"
+ checksum: 10c0/24de857aa8d61526bbfbbaa383aa538283ad17363fcd5bb5148e2c7f604547db36646440e739d78241ed008702a8920665d1add5618687b6743858fae00da211
+ languageName: node
+ linkType: hard
+
"@types/json5@npm:^0.0.29":
version: 0.0.29
resolution: "@types/json5@npm:0.0.29"
@@ -5519,6 +6762,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/ws@npm:^8.0.0":
+ version: 8.18.1
+ resolution: "@types/ws@npm:8.18.1"
+ dependencies:
+ "@types/node": "npm:*"
+ checksum: 10c0/61aff1129143fcc4312f083bc9e9e168aa3026b7dd6e70796276dcfb2c8211c4292603f9c4864fae702f2ed86e4abd4d38aa421831c2fd7f856c931a481afbab
+ languageName: node
+ linkType: hard
+
"@typescript-eslint/eslint-plugin@npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0":
version: 8.34.1
resolution: "@typescript-eslint/eslint-plugin@npm:8.34.1"
@@ -6591,6 +7843,47 @@ __metadata:
languageName: node
linkType: hard
+"@whatwg-node/disposablestack@npm:^0.0.6":
+ version: 0.0.6
+ resolution: "@whatwg-node/disposablestack@npm:0.0.6"
+ dependencies:
+ "@whatwg-node/promise-helpers": "npm:^1.0.0"
+ tslib: "npm:^2.6.3"
+ checksum: 10c0/e751da9f8552728f28a140fd78c1da88be167ee8a5688371da88e024a2bf151298d194a61c9750b44bbbb4cf5c687959d495d41b1388e4cfcfe9dbe3584c79b3
+ languageName: node
+ linkType: hard
+
+"@whatwg-node/fetch@npm:^0.10.0, @whatwg-node/fetch@npm:^0.10.4":
+ version: 0.10.11
+ resolution: "@whatwg-node/fetch@npm:0.10.11"
+ dependencies:
+ "@whatwg-node/node-fetch": "npm:^0.8.0"
+ urlpattern-polyfill: "npm:^10.0.0"
+ checksum: 10c0/d64fd5b545313f3d5cd362aa5700de5f6a25684ac7b74d8dd809ac27b67d3fc99cf5e47124dcc6623bbfef55ee87394c423933298feedc13c29aa6061f0cb894
+ languageName: node
+ linkType: hard
+
+"@whatwg-node/node-fetch@npm:^0.8.0":
+ version: 0.8.1
+ resolution: "@whatwg-node/node-fetch@npm:0.8.1"
+ dependencies:
+ "@fastify/busboy": "npm:^3.1.1"
+ "@whatwg-node/disposablestack": "npm:^0.0.6"
+ "@whatwg-node/promise-helpers": "npm:^1.3.2"
+ tslib: "npm:^2.6.3"
+ checksum: 10c0/6bfdc2eab750ef1f7fd89acac635c5a2f57e2da9bce537ae80300f3dd804ff4f6c0842490d421671065589f8f165827a1ba9a17043ae28642b6f01ad67e1e04b
+ languageName: node
+ linkType: hard
+
+"@whatwg-node/promise-helpers@npm:^1.0.0, @whatwg-node/promise-helpers@npm:^1.2.1, @whatwg-node/promise-helpers@npm:^1.2.4, @whatwg-node/promise-helpers@npm:^1.3.0, @whatwg-node/promise-helpers@npm:^1.3.2":
+ version: 1.3.2
+ resolution: "@whatwg-node/promise-helpers@npm:1.3.2"
+ dependencies:
+ tslib: "npm:^2.6.3"
+ checksum: 10c0/d20e8d740cfa1f0eac7dce11e8a7a84f1567513a8ff0bd1772724b581a8ca77df3f9600a95047c0d2628335626113fa98367517abd01c1ff49817fccf225a29a
+ languageName: node
+ linkType: hard
+
"@xobotyi/scrollbar-width@npm:^1.9.5":
version: 1.9.5
resolution: "@xobotyi/scrollbar-width@npm:1.9.5"
@@ -6598,6 +7891,22 @@ __metadata:
languageName: node
linkType: hard
+"@yornaath/batshit-devtools@npm:^1.7.1":
+ version: 1.7.1
+ resolution: "@yornaath/batshit-devtools@npm:1.7.1"
+ checksum: 10c0/99702781cf1af69e52234578336e619215dcba1d9f2e716469f25a5554a21a3ebc6148c597e576de4dfa0e849f80d7e28b86c2699cdd3613392c6e2e51505a2a
+ languageName: node
+ linkType: hard
+
+"@yornaath/batshit@npm:^0.11.1":
+ version: 0.11.1
+ resolution: "@yornaath/batshit@npm:0.11.1"
+ dependencies:
+ "@yornaath/batshit-devtools": "npm:^1.7.1"
+ checksum: 10c0/720dba75d969c8bd607d7ea2f74fee85808cf2aeef54bfe8dbed6561b2cfe08de121afd0833223ab7ee8b12341789b010628da7470b42b648d98680ac884c07a
+ languageName: node
+ linkType: hard
+
"abbrev@npm:^3.0.0":
version: 3.0.1
resolution: "abbrev@npm:3.0.1"
@@ -6661,6 +7970,16 @@ __metadata:
languageName: node
linkType: hard
+"aggregate-error@npm:^3.0.0":
+ version: 3.1.0
+ resolution: "aggregate-error@npm:3.1.0"
+ dependencies:
+ clean-stack: "npm:^2.0.0"
+ indent-string: "npm:^4.0.0"
+ checksum: 10c0/a42f67faa79e3e6687a4923050e7c9807db3848a037076f791d10e092677d65c1d2d863b7848560699f40fc0502c19f40963fb1cd1fb3d338a7423df8e45e039
+ languageName: node
+ linkType: hard
+
"ajv@npm:^6.12.4":
version: 6.12.6
resolution: "ajv@npm:6.12.6"
@@ -6685,6 +8004,15 @@ __metadata:
languageName: node
linkType: hard
+"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0":
+ version: 4.3.2
+ resolution: "ansi-escapes@npm:4.3.2"
+ dependencies:
+ type-fest: "npm:^0.21.3"
+ checksum: 10c0/da917be01871525a3dfcf925ae2977bc59e8c513d4423368645634bf5d4ceba5401574eb705c1e92b79f7292af5a656f78c5725a4b0e1cec97c4b413705c1d50
+ languageName: node
+ linkType: hard
+
"ansi-regex@npm:^5.0.1":
version: 5.0.1
resolution: "ansi-regex@npm:5.0.1"
@@ -6765,6 +8093,13 @@ __metadata:
languageName: node
linkType: hard
+"array-union@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "array-union@npm:2.1.0"
+ checksum: 10c0/429897e68110374f39b771ec47a7161fc6a8fc33e196857c0a396dc75df0b5f65e4d046674db764330b6bb66b39ef48dd7c53b6a2ee75cfb0681e0c1a7033962
+ languageName: node
+ linkType: hard
+
"array.prototype.findlast@npm:^1.2.5":
version: 1.2.5
resolution: "array.prototype.findlast@npm:1.2.5"
@@ -6853,6 +8188,13 @@ __metadata:
languageName: node
linkType: hard
+"asap@npm:~2.0.3":
+ version: 2.0.6
+ resolution: "asap@npm:2.0.6"
+ checksum: 10c0/c6d5e39fe1f15e4b87677460bd66b66050cd14c772269cee6688824c1410a08ab20254bb6784f9afb75af9144a9f9a7692d49547f4d19d715aeb7c0318f3136d
+ languageName: node
+ linkType: hard
+
"ast-types-flow@npm:^0.0.8":
version: 0.0.8
resolution: "ast-types-flow@npm:0.0.8"
@@ -6860,6 +8202,13 @@ __metadata:
languageName: node
linkType: hard
+"astral-regex@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "astral-regex@npm:2.0.0"
+ checksum: 10c0/f63d439cc383db1b9c5c6080d1e240bd14dae745f15d11ec5da863e182bbeca70df6c8191cffef5deba0b566ef98834610a68be79ac6379c95eeb26e1b310e25
+ languageName: node
+ linkType: hard
+
"async-function@npm:^1.0.0":
version: 1.0.0
resolution: "async-function@npm:1.0.0"
@@ -6899,6 +8248,13 @@ __metadata:
languageName: node
linkType: hard
+"auto-bind@npm:~4.0.0":
+ version: 4.0.0
+ resolution: "auto-bind@npm:4.0.0"
+ checksum: 10c0/12f70745d081ba990dca028ecfa70de25d4baa9a8b74a5bef3ab293da56cba32ff8276c3ff8e5fe6d9f370547bf3fa71486befbfefe272af7e722c21d0c25530
+ languageName: node
+ linkType: hard
+
"available-typed-arrays@npm:^1.0.7":
version: 1.0.7
resolution: "available-typed-arrays@npm:1.0.7"
@@ -6974,6 +8330,50 @@ __metadata:
languageName: node
linkType: hard
+"babel-plugin-syntax-trailing-function-commas@npm:^7.0.0-beta.0":
+ version: 7.0.0-beta.0
+ resolution: "babel-plugin-syntax-trailing-function-commas@npm:7.0.0-beta.0"
+ checksum: 10c0/67e3d6a706637097526b2d3046d3124d3efd3aac28b47af940c2f8df01b8d7ffeb4cdf5648f3b5eac3f098f5b61c4845e306f34301c869e5e14db6ae8b77f699
+ languageName: node
+ linkType: hard
+
+"babel-preset-fbjs@npm:^3.4.0":
+ version: 3.4.0
+ resolution: "babel-preset-fbjs@npm:3.4.0"
+ dependencies:
+ "@babel/plugin-proposal-class-properties": "npm:^7.0.0"
+ "@babel/plugin-proposal-object-rest-spread": "npm:^7.0.0"
+ "@babel/plugin-syntax-class-properties": "npm:^7.0.0"
+ "@babel/plugin-syntax-flow": "npm:^7.0.0"
+ "@babel/plugin-syntax-jsx": "npm:^7.0.0"
+ "@babel/plugin-syntax-object-rest-spread": "npm:^7.0.0"
+ "@babel/plugin-transform-arrow-functions": "npm:^7.0.0"
+ "@babel/plugin-transform-block-scoped-functions": "npm:^7.0.0"
+ "@babel/plugin-transform-block-scoping": "npm:^7.0.0"
+ "@babel/plugin-transform-classes": "npm:^7.0.0"
+ "@babel/plugin-transform-computed-properties": "npm:^7.0.0"
+ "@babel/plugin-transform-destructuring": "npm:^7.0.0"
+ "@babel/plugin-transform-flow-strip-types": "npm:^7.0.0"
+ "@babel/plugin-transform-for-of": "npm:^7.0.0"
+ "@babel/plugin-transform-function-name": "npm:^7.0.0"
+ "@babel/plugin-transform-literals": "npm:^7.0.0"
+ "@babel/plugin-transform-member-expression-literals": "npm:^7.0.0"
+ "@babel/plugin-transform-modules-commonjs": "npm:^7.0.0"
+ "@babel/plugin-transform-object-super": "npm:^7.0.0"
+ "@babel/plugin-transform-parameters": "npm:^7.0.0"
+ "@babel/plugin-transform-property-literals": "npm:^7.0.0"
+ "@babel/plugin-transform-react-display-name": "npm:^7.0.0"
+ "@babel/plugin-transform-react-jsx": "npm:^7.0.0"
+ "@babel/plugin-transform-shorthand-properties": "npm:^7.0.0"
+ "@babel/plugin-transform-spread": "npm:^7.0.0"
+ "@babel/plugin-transform-template-literals": "npm:^7.0.0"
+ babel-plugin-syntax-trailing-function-commas: "npm:^7.0.0-beta.0"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10c0/2be440c0fd7d1df247417be35644cb89f40a300e7fcdc44878b737ec49b04380eff422e4ebdc7bb5efd5ecfef45b634fc5fe11c3a409a50c9084e81083037902
+ languageName: node
+ linkType: hard
+
"balanced-match@npm:^1.0.0":
version: 1.0.2
resolution: "balanced-match@npm:1.0.2"
@@ -7037,6 +8437,17 @@ __metadata:
languageName: node
linkType: hard
+"bl@npm:^4.1.0":
+ version: 4.1.0
+ resolution: "bl@npm:4.1.0"
+ dependencies:
+ buffer: "npm:^5.5.0"
+ inherits: "npm:^2.0.4"
+ readable-stream: "npm:^3.4.0"
+ checksum: 10c0/02847e1d2cb089c9dc6958add42e3cdeaf07d13f575973963335ac0fdece563a50ac770ac4c8fa06492d2dd276f6cc3b7f08c7cd9c7a7ad0f8d388b2a28def5f
+ languageName: node
+ linkType: hard
+
"bl@npm:^5.0.0":
version: 5.1.0
resolution: "bl@npm:5.1.0"
@@ -7141,6 +8552,15 @@ __metadata:
languageName: node
linkType: hard
+"bser@npm:2.1.1":
+ version: 2.1.1
+ resolution: "bser@npm:2.1.1"
+ dependencies:
+ node-int64: "npm:^0.4.0"
+ checksum: 10c0/24d8dfb7b6d457d73f32744e678a60cc553e4ec0e9e1a01cf614b44d85c3c87e188d3cc78ef0442ce5032ee6818de20a0162ba1074725c0d08908f62ea979227
+ languageName: node
+ linkType: hard
+
"buffer@npm:6.0.3, buffer@npm:^6.0.3":
version: 6.0.3
resolution: "buffer@npm:6.0.3"
@@ -7151,6 +8571,16 @@ __metadata:
languageName: node
linkType: hard
+"buffer@npm:^5.5.0":
+ version: 5.7.1
+ resolution: "buffer@npm:5.7.1"
+ dependencies:
+ base64-js: "npm:^1.3.1"
+ ieee754: "npm:^1.1.13"
+ checksum: 10c0/27cac81cff434ed2876058d72e7c4789d11ff1120ef32c9de48f59eab58179b66710c488987d295ae89a228f835fc66d088652dffeb8e3ba8659f80eb091d55e
+ languageName: node
+ linkType: hard
+
"bufferutil@npm:^4.0.8":
version: 4.0.9
resolution: "bufferutil@npm:4.0.9"
@@ -7281,6 +8711,16 @@ __metadata:
languageName: node
linkType: hard
+"camel-case@npm:^4.1.2":
+ version: 4.1.2
+ resolution: "camel-case@npm:4.1.2"
+ dependencies:
+ pascal-case: "npm:^3.1.2"
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/bf9eefaee1f20edbed2e9a442a226793bc72336e2b99e5e48c6b7252b6f70b080fc46d8246ab91939e2af91c36cdd422e0af35161e58dd089590f302f8f64c8a
+ languageName: node
+ linkType: hard
+
"camelcase-keys@npm:^6.2.2":
version: 6.2.2
resolution: "camelcase-keys@npm:6.2.2"
@@ -7329,6 +8769,17 @@ __metadata:
languageName: node
linkType: hard
+"capital-case@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "capital-case@npm:1.0.4"
+ dependencies:
+ no-case: "npm:^3.0.4"
+ tslib: "npm:^2.0.3"
+ upper-case-first: "npm:^2.0.2"
+ checksum: 10c0/6a034af73401f6e55d91ea35c190bbf8bda21714d4ea8bb8f1799311d123410a80f0875db4e3236dc3f97d74231ff4bf1c8783f2be13d7733c7d990c57387281
+ languageName: node
+ linkType: hard
+
"cbw-sdk@npm:@coinbase/wallet-sdk@3.9.3":
version: 3.9.3
resolution: "@coinbase/wallet-sdk@npm:3.9.3"
@@ -7346,7 +8797,7 @@ __metadata:
languageName: node
linkType: hard
-"chalk@npm:^4.0.0":
+"chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.1":
version: 4.1.2
resolution: "chalk@npm:4.1.2"
dependencies:
@@ -7356,6 +8807,44 @@ __metadata:
languageName: node
linkType: hard
+"change-case-all@npm:1.0.15":
+ version: 1.0.15
+ resolution: "change-case-all@npm:1.0.15"
+ dependencies:
+ change-case: "npm:^4.1.2"
+ is-lower-case: "npm:^2.0.2"
+ is-upper-case: "npm:^2.0.2"
+ lower-case: "npm:^2.0.2"
+ lower-case-first: "npm:^2.0.2"
+ sponge-case: "npm:^1.0.1"
+ swap-case: "npm:^2.0.2"
+ title-case: "npm:^3.0.3"
+ upper-case: "npm:^2.0.2"
+ upper-case-first: "npm:^2.0.2"
+ checksum: 10c0/0de81690de866aa8c477f8b5b08c6f9dbce4a078cffa5f014858f49fda548a9a6524b61f62f2940acce9f1fdcfeef3a7124090684e86e731f55d26c22713e2d7
+ languageName: node
+ linkType: hard
+
+"change-case@npm:^4.1.2":
+ version: 4.1.2
+ resolution: "change-case@npm:4.1.2"
+ dependencies:
+ camel-case: "npm:^4.1.2"
+ capital-case: "npm:^1.0.4"
+ constant-case: "npm:^3.0.4"
+ dot-case: "npm:^3.0.4"
+ header-case: "npm:^2.0.4"
+ no-case: "npm:^3.0.4"
+ param-case: "npm:^3.0.4"
+ pascal-case: "npm:^3.1.2"
+ path-case: "npm:^3.0.4"
+ sentence-case: "npm:^3.0.4"
+ snake-case: "npm:^3.0.4"
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/95a6e48563cd393241ce18470c7310a8a050304a64b63addac487560ab039ce42b099673d1d293cc10652324d92060de11b5d918179fe3b5af2ee521fb03ca58
+ languageName: node
+ linkType: hard
+
"change-case@npm:^5.4.4":
version: 5.4.4
resolution: "change-case@npm:5.4.4"
@@ -7363,6 +8852,13 @@ __metadata:
languageName: node
linkType: hard
+"chardet@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "chardet@npm:2.1.0"
+ checksum: 10c0/d1b03e47371851ed72741a898281d58f8a9b577aeea6fdfa75a86832898b36c550b3ad057e66d50d774a9cebd9f56c66b6880e4fe75e387794538ba7565b0b6f
+ languageName: node
+ linkType: hard
+
"chokidar@npm:4.0.1":
version: 4.0.1
resolution: "chokidar@npm:4.0.1"
@@ -7419,6 +8915,46 @@ __metadata:
languageName: node
linkType: hard
+"clean-stack@npm:^2.0.0":
+ version: 2.2.0
+ resolution: "clean-stack@npm:2.2.0"
+ checksum: 10c0/1f90262d5f6230a17e27d0c190b09d47ebe7efdd76a03b5a1127863f7b3c9aec4c3e6c8bb3a7bbf81d553d56a1fd35728f5a8ef4c63f867ac8d690109742a8c1
+ languageName: node
+ linkType: hard
+
+"cli-cursor@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "cli-cursor@npm:3.1.0"
+ dependencies:
+ restore-cursor: "npm:^3.1.0"
+ checksum: 10c0/92a2f98ff9037d09be3dfe1f0d749664797fb674bf388375a2207a1203b69d41847abf16434203e0089212479e47a358b13a0222ab9fccfe8e2644a7ccebd111
+ languageName: node
+ linkType: hard
+
+"cli-spinners@npm:^2.5.0":
+ version: 2.9.2
+ resolution: "cli-spinners@npm:2.9.2"
+ checksum: 10c0/907a1c227ddf0d7a101e7ab8b300affc742ead4b4ebe920a5bf1bc6d45dce2958fcd195eb28fa25275062fe6fa9b109b93b63bc8033396ed3bcb50297008b3a3
+ languageName: node
+ linkType: hard
+
+"cli-truncate@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "cli-truncate@npm:2.1.0"
+ dependencies:
+ slice-ansi: "npm:^3.0.0"
+ string-width: "npm:^4.2.0"
+ checksum: 10c0/dfaa3df675bcef7a3254773de768712b590250420345a4c7ac151f041a4bacb4c25864b1377bee54a39b5925a030c00eabf014e312e3a4ac130952ed3b3879e9
+ languageName: node
+ linkType: hard
+
+"cli-width@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "cli-width@npm:3.0.0"
+ checksum: 10c0/125a62810e59a2564268c80fdff56c23159a7690c003e34aeb2e68497dccff26911998ff49c33916fcfdf71e824322cc3953e3f7b48b27267c7a062c81348a9a
+ languageName: node
+ linkType: hard
+
"client-only@npm:0.0.1, client-only@npm:^0.0.1":
version: 0.0.1
resolution: "client-only@npm:0.0.1"
@@ -7437,6 +8973,17 @@ __metadata:
languageName: node
linkType: hard
+"cliui@npm:^8.0.1":
+ version: 8.0.1
+ resolution: "cliui@npm:8.0.1"
+ dependencies:
+ string-width: "npm:^4.2.0"
+ strip-ansi: "npm:^6.0.1"
+ wrap-ansi: "npm:^7.0.0"
+ checksum: 10c0/4bda0f09c340cbb6dfdc1ed508b3ca080f12992c18d68c6be4d9cf51756033d5266e61ec57529e610dacbf4da1c634423b0c1b11037709cc6b09045cbd815df5
+ languageName: node
+ linkType: hard
+
"clone@npm:2.x":
version: 2.1.2
resolution: "clone@npm:2.1.2"
@@ -7444,6 +8991,13 @@ __metadata:
languageName: node
linkType: hard
+"clone@npm:^1.0.2":
+ version: 1.0.4
+ resolution: "clone@npm:1.0.4"
+ checksum: 10c0/2176952b3649293473999a95d7bebfc9dc96410f6cbd3d2595cf12fd401f63a4bf41a7adbfd3ab2ff09ed60cb9870c58c6acdd18b87767366fabfc163700f13b
+ languageName: node
+ linkType: hard
+
"clsx@npm:^1.2.1":
version: 1.2.1
resolution: "clsx@npm:1.2.1"
@@ -7474,7 +9028,7 @@ __metadata:
languageName: node
linkType: hard
-"colorette@npm:^2.0.7":
+"colorette@npm:^2.0.16, colorette@npm:^2.0.7":
version: 2.0.20
resolution: "colorette@npm:2.0.20"
checksum: 10c0/e94116ff33b0ff56f3b83b9ace895e5bf87c2a7a47b3401b8c3f3226e050d5ef76cf4072fb3325f9dc24d1698f9b730baf4e05eeaf861d74a1883073f4c98a40
@@ -7497,6 +9051,13 @@ __metadata:
languageName: node
linkType: hard
+"common-tags@npm:1.8.2":
+ version: 1.8.2
+ resolution: "common-tags@npm:1.8.2"
+ checksum: 10c0/23efe47ff0a1a7c91489271b3a1e1d2a171c12ec7f9b35b29b2fce51270124aff0ec890087e2bc2182c1cb746e232ab7561aaafe05f1e7452aea733d2bfe3f63
+ languageName: node
+ linkType: hard
+
"concat-map@npm:0.0.1":
version: 0.0.1
resolution: "concat-map@npm:0.0.1"
@@ -7504,6 +9065,17 @@ __metadata:
languageName: node
linkType: hard
+"constant-case@npm:^3.0.4":
+ version: 3.0.4
+ resolution: "constant-case@npm:3.0.4"
+ dependencies:
+ no-case: "npm:^3.0.4"
+ tslib: "npm:^2.0.3"
+ upper-case: "npm:^2.0.2"
+ checksum: 10c0/91d54f18341fcc491ae66d1086642b0cc564be3e08984d7b7042f8b0a721c8115922f7f11d6a09f13ed96ff326eabae11f9d1eb0335fa9d8b6e39e4df096010e
+ languageName: node
+ linkType: hard
+
"convert-source-map@npm:^2.0.0":
version: 2.0.0
resolution: "convert-source-map@npm:2.0.0"
@@ -7550,7 +9122,7 @@ __metadata:
languageName: node
linkType: hard
-"cosmiconfig@npm:^8.1.3":
+"cosmiconfig@npm:^8.1.0, cosmiconfig@npm:^8.1.3":
version: 8.3.6
resolution: "cosmiconfig@npm:8.3.6"
dependencies:
@@ -7594,6 +9166,15 @@ __metadata:
languageName: node
linkType: hard
+"cross-inspect@npm:1.0.1":
+ version: 1.0.1
+ resolution: "cross-inspect@npm:1.0.1"
+ dependencies:
+ tslib: "npm:^2.4.0"
+ checksum: 10c0/2493ee47a801b46ede1c42ca6242b8d2059f7319b5baf23887bbaf46a6ea8e536d2e271d0990176c05092f67b32d084ffd8c93e7c1227eff4a06cceadb49af47
+ languageName: node
+ linkType: hard
+
"cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.6":
version: 7.0.6
resolution: "cross-spawn@npm:7.0.6"
@@ -7706,6 +9287,13 @@ __metadata:
languageName: node
linkType: hard
+"data-uri-to-buffer@npm:^4.0.0":
+ version: 4.0.1
+ resolution: "data-uri-to-buffer@npm:4.0.1"
+ checksum: 10c0/20a6b93107597530d71d4cb285acee17f66bcdfc03fd81040921a81252f19db27588d87fc8fc69e1950c55cfb0bf8ae40d0e5e21d907230813eb5d5a7f9eb45b
+ languageName: node
+ linkType: hard
+
"data-view-buffer@npm:^1.0.2":
version: 1.0.2
resolution: "data-view-buffer@npm:1.0.2"
@@ -7739,6 +9327,13 @@ __metadata:
languageName: node
linkType: hard
+"dataloader@npm:^2.2.3":
+ version: 2.2.3
+ resolution: "dataloader@npm:2.2.3"
+ checksum: 10c0/9b9a056fbc863ca86da87d59e053e871e263b4966aa4d55e40d61a65e96815fae5530ca220629064ca5f8e3000c0c4ec93292e170c38ff393fb34256b4d7c1aa
+ languageName: node
+ linkType: hard
+
"date-fns@npm:^2.29.3":
version: 2.30.0
resolution: "date-fns@npm:2.30.0"
@@ -7762,6 +9357,13 @@ __metadata:
languageName: node
linkType: hard
+"debounce@npm:^1.2.0":
+ version: 1.2.1
+ resolution: "debounce@npm:1.2.1"
+ checksum: 10c0/6c9320aa0973fc42050814621a7a8a78146c1975799b5b3cc1becf1f77ba9a5aa583987884230da0842a03f385def452fad5d60db97c3d1c8b824e38a8edf500
+ languageName: node
+ linkType: hard
+
"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.0":
version: 4.4.1
resolution: "debug@npm:4.4.1"
@@ -7774,6 +9376,18 @@ __metadata:
languageName: node
linkType: hard
+"debug@npm:4.4.3":
+ version: 4.4.3
+ resolution: "debug@npm:4.4.3"
+ dependencies:
+ ms: "npm:^2.1.3"
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ checksum: 10c0/d79136ec6c83ecbefd0f6a5593da6a9c91ec4d7ddc4b54c883d6e71ec9accb5f67a1a5e96d00a328196b5b5c86d365e98d8a3a70856aaf16b4e7b1985e67f5a6
+ languageName: node
+ linkType: hard
+
"debug@npm:^3.2.7":
version: 3.2.7
resolution: "debug@npm:3.2.7"
@@ -7854,6 +9468,15 @@ __metadata:
languageName: node
linkType: hard
+"defaults@npm:^1.0.3":
+ version: 1.0.4
+ resolution: "defaults@npm:1.0.4"
+ dependencies:
+ clone: "npm:^1.0.2"
+ checksum: 10c0/9cfbe498f5c8ed733775db62dfd585780387d93c17477949e1670bfcfb9346e0281ce8c4bf9f4ac1fc0f9b851113bd6dc9e41182ea1644ccd97de639fa13c35a
+ languageName: node
+ linkType: hard
+
"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4":
version: 1.1.4
resolution: "define-data-property@npm:1.1.4"
@@ -7890,6 +9513,20 @@ __metadata:
languageName: node
linkType: hard
+"dependency-graph@npm:^0.11.0":
+ version: 0.11.0
+ resolution: "dependency-graph@npm:0.11.0"
+ checksum: 10c0/9e6968d1534fdb502f7f3a25a3819b499f9d60f8389193950ed0b4d1618f1341b36b5d039f2cee256cfe10c9e8198ace16b271e370df06a93fac206e81602e7c
+ languageName: node
+ linkType: hard
+
+"dependency-graph@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "dependency-graph@npm:1.0.0"
+ checksum: 10c0/10d1e248ab68a33654335559bae5ec142c51959cbff1cba8b35cdccfdc12eb8d136227df85c31b71b9ee9fed1b2bfbd01721661b4f927e12d890d13c4230788f
+ languageName: node
+ linkType: hard
+
"derive-valtio@npm:0.1.0":
version: 0.1.0
resolution: "derive-valtio@npm:0.1.0"
@@ -7913,6 +9550,13 @@ __metadata:
languageName: node
linkType: hard
+"detect-indent@npm:^6.0.0":
+ version: 6.1.0
+ resolution: "detect-indent@npm:6.1.0"
+ checksum: 10c0/dd83cdeda9af219cf77f5e9a0dc31d828c045337386cfb55ce04fad94ba872ee7957336834154f7647b89b899c3c7acc977c57a79b7c776b506240993f97acc7
+ languageName: node
+ linkType: hard
+
"detect-libc@npm:^2.0.3, detect-libc@npm:^2.0.4":
version: 2.0.4
resolution: "detect-libc@npm:2.0.4"
@@ -7927,6 +9571,15 @@ __metadata:
languageName: node
linkType: hard
+"dir-glob@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "dir-glob@npm:3.0.1"
+ dependencies:
+ path-type: "npm:^4.0.0"
+ checksum: 10c0/dcac00920a4d503e38bb64001acb19df4efc14536ada475725e12f52c16777afdee4db827f55f13a908ee7efc0cb282e2e3dbaeeb98c0993dd93d1802d3bf00c
+ languageName: node
+ linkType: hard
+
"doctrine@npm:^2.1.0":
version: 2.1.0
resolution: "doctrine@npm:2.1.0"
@@ -7993,6 +9646,20 @@ __metadata:
languageName: node
linkType: hard
+"dotenv-cli@npm:^10.0.0":
+ version: 10.0.0
+ resolution: "dotenv-cli@npm:10.0.0"
+ dependencies:
+ cross-spawn: "npm:^7.0.6"
+ dotenv: "npm:^17.1.0"
+ dotenv-expand: "npm:^11.0.0"
+ minimist: "npm:^1.2.6"
+ bin:
+ dotenv: cli.js
+ checksum: 10c0/c469e65167fc3d1ef7bc6f90c8b7a0accd245ad1cdb73da8c72b32ddb308550dc4d5bfcdae964ab1f8a247957d756afc7b050d0f88fa5868c05ff6d3dfb4c1ba
+ languageName: node
+ linkType: hard
+
"dotenv-expand@npm:^10.0.0":
version: 10.0.0
resolution: "dotenv-expand@npm:10.0.0"
@@ -8000,6 +9667,15 @@ __metadata:
languageName: node
linkType: hard
+"dotenv-expand@npm:^11.0.0":
+ version: 11.0.7
+ resolution: "dotenv-expand@npm:11.0.7"
+ dependencies:
+ dotenv: "npm:^16.4.5"
+ checksum: 10c0/d80b8a7be085edf351270b96ac0e794bc3ddd7f36157912939577cb4d33ba6492ebee349d59798b71b90e36f498d24a2a564fb4aa00073b2ef4c2a3a49c467b1
+ languageName: node
+ linkType: hard
+
"dotenv@npm:^14.2.0":
version: 14.3.2
resolution: "dotenv@npm:14.3.2"
@@ -8007,6 +9683,13 @@ __metadata:
languageName: node
linkType: hard
+"dotenv@npm:^16.0.0, dotenv@npm:^16.4.5":
+ version: 16.6.1
+ resolution: "dotenv@npm:16.6.1"
+ checksum: 10c0/15ce56608326ea0d1d9414a5c8ee6dcf0fffc79d2c16422b4ac2268e7e2d76ff5a572d37ffe747c377de12005f14b3cc22361e79fc7f1061cce81f77d2c973dc
+ languageName: node
+ linkType: hard
+
"dotenv@npm:^16.3.1":
version: 16.5.0
resolution: "dotenv@npm:16.5.0"
@@ -8014,6 +9697,20 @@ __metadata:
languageName: node
linkType: hard
+"dotenv@npm:^17.1.0":
+ version: 17.2.3
+ resolution: "dotenv@npm:17.2.3"
+ checksum: 10c0/c884403209f713214a1b64d4d1defa4934c2aa5b0002f5a670ae298a51e3c3ad3ba79dfee2f8df49f01ae74290fcd9acdb1ab1d09c7bfb42b539036108bb2ba0
+ languageName: node
+ linkType: hard
+
+"dset@npm:^3.1.2, dset@npm:^3.1.4":
+ version: 3.1.4
+ resolution: "dset@npm:3.1.4"
+ checksum: 10c0/b67bbd28dd8a539e90c15ffb61100eb64ef995c5270a124d4f99bbb53f4d82f55a051b731ba81f3215dd9dce2b4c8d69927dc20b3be1c5fc88bab159467aa438
+ languageName: node
+ linkType: hard
+
"dtrace-provider@npm:~0.8":
version: 0.8.8
resolution: "dtrace-provider@npm:0.8.8"
@@ -8499,13 +10196,20 @@ __metadata:
languageName: node
linkType: hard
-"escalade@npm:3.2.0, escalade@npm:^3.2.0":
+"escalade@npm:3.2.0, escalade@npm:^3.1.1, escalade@npm:^3.2.0":
version: 3.2.0
resolution: "escalade@npm:3.2.0"
checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65
languageName: node
linkType: hard
+"escape-string-regexp@npm:^1.0.5":
+ version: 1.0.5
+ resolution: "escape-string-regexp@npm:1.0.5"
+ checksum: 10c0/a968ad453dd0c2724e14a4f20e177aaf32bb384ab41b674a8454afe9a41c5e6fe8903323e0a1052f56289d04bd600f81278edf140b0fcc02f5cac98d0f5b5371
+ languageName: node
+ linkType: hard
+
"escape-string-regexp@npm:^4.0.0":
version: 4.0.0
resolution: "escape-string-regexp@npm:4.0.0"
@@ -9040,7 +10744,7 @@ __metadata:
languageName: node
linkType: hard
-"fast-glob@npm:^3.3.2":
+"fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2":
version: 3.3.3
resolution: "fast-glob@npm:3.3.3"
dependencies:
@@ -9111,6 +10815,37 @@ __metadata:
languageName: node
linkType: hard
+"fb-watchman@npm:^2.0.0":
+ version: 2.0.2
+ resolution: "fb-watchman@npm:2.0.2"
+ dependencies:
+ bser: "npm:2.1.1"
+ checksum: 10c0/feae89ac148adb8f6ae8ccd87632e62b13563e6fb114cacb5265c51f585b17e2e268084519fb2edd133872f1d47a18e6bfd7e5e08625c0d41b93149694187581
+ languageName: node
+ linkType: hard
+
+"fbjs-css-vars@npm:^1.0.0":
+ version: 1.0.2
+ resolution: "fbjs-css-vars@npm:1.0.2"
+ checksum: 10c0/dfb64116b125a64abecca9e31477b5edb9a2332c5ffe74326fe36e0a72eef7fc8a49b86adf36c2c293078d79f4524f35e80f5e62546395f53fb7c9e69821f54f
+ languageName: node
+ linkType: hard
+
+"fbjs@npm:^3.0.0":
+ version: 3.0.5
+ resolution: "fbjs@npm:3.0.5"
+ dependencies:
+ cross-fetch: "npm:^3.1.5"
+ fbjs-css-vars: "npm:^1.0.0"
+ loose-envify: "npm:^1.0.0"
+ object-assign: "npm:^4.1.0"
+ promise: "npm:^7.1.1"
+ setimmediate: "npm:^1.0.5"
+ ua-parser-js: "npm:^1.0.35"
+ checksum: 10c0/66d0a2fc9a774f9066e35ac2ac4bf1245931d27f3ac287c7d47e6aa1fc152b243c2109743eb8f65341e025621fb51a12038fadb9fd8fda2e3ddae04ebab06f91
+ languageName: node
+ linkType: hard
+
"fdir@npm:^6.1.1, fdir@npm:^6.4.4":
version: 6.4.6
resolution: "fdir@npm:6.4.6"
@@ -9123,6 +10858,25 @@ __metadata:
languageName: node
linkType: hard
+"fetch-blob@npm:^3.1.2, fetch-blob@npm:^3.1.4":
+ version: 3.2.0
+ resolution: "fetch-blob@npm:3.2.0"
+ dependencies:
+ node-domexception: "npm:^1.0.0"
+ web-streams-polyfill: "npm:^3.0.3"
+ checksum: 10c0/60054bf47bfa10fb0ba6cb7742acec2f37c1f56344f79a70bb8b1c48d77675927c720ff3191fa546410a0442c998d27ab05e9144c32d530d8a52fbe68f843b69
+ languageName: node
+ linkType: hard
+
+"figures@npm:^3.0.0":
+ version: 3.2.0
+ resolution: "figures@npm:3.2.0"
+ dependencies:
+ escape-string-regexp: "npm:^1.0.5"
+ checksum: 10c0/9c421646ede432829a50bc4e55c7a4eb4bcb7cc07b5bab2f471ef1ab9a344595bbebb6c5c21470093fbb730cd81bbca119624c40473a125293f656f49cb47629
+ languageName: node
+ linkType: hard
+
"file-entry-cache@npm:^6.0.1":
version: 6.0.1
resolution: "file-entry-cache@npm:6.0.1"
@@ -9227,6 +10981,15 @@ __metadata:
languageName: node
linkType: hard
+"formdata-polyfill@npm:^4.0.10":
+ version: 4.0.10
+ resolution: "formdata-polyfill@npm:4.0.10"
+ dependencies:
+ fetch-blob: "npm:^3.1.2"
+ checksum: 10c0/5392ec484f9ce0d5e0d52fb5a78e7486637d516179b0eb84d81389d7eccf9ca2f663079da56f761355c0a65792810e3b345dc24db9a8bbbcf24ef3c8c88570c6
+ languageName: node
+ linkType: hard
+
"fs-minipass@npm:^3.0.0":
version: 3.0.3
resolution: "fs-minipass@npm:3.0.3"
@@ -9295,6 +11058,10 @@ __metadata:
resolution: "futarchy-poc-14@workspace:."
dependencies:
"@cowprotocol/cow-sdk": "npm:^5.10.3"
+ "@graphql-codegen/cli": "npm:^5.0.2"
+ "@graphql-codegen/typescript": "npm:^5.0.2"
+ "@graphql-codegen/typescript-graphql-request": "npm:^6.3.0"
+ "@graphql-codegen/typescript-operations": "npm:^5.0.2"
"@kleros/ui-components-library": "npm:^3.6.0"
"@reown/appkit": "npm:^1.7.11"
"@reown/appkit-adapter-wagmi": "npm:^1.7.11"
@@ -9307,14 +11074,18 @@ __metadata:
"@types/react-dom": "npm:^18"
"@wagmi/cli": "npm:^2.3.1"
"@wagmi/core": "npm:^2.17.3"
+ "@yornaath/batshit": "npm:^0.11.1"
clsx: "npm:^2.1.1"
+ dotenv-cli: "npm:^10.0.0"
eslint: "npm:^8"
eslint-config-next: "npm:14.2.28"
eslint-config-prettier: "npm:^10.1.2"
eslint-plugin-prettier: "npm:^5.2.6"
ethers: "npm:5.8.0"
+ graphql-request: "npm:^7.3.1"
graphql-tag: "npm:^2.12.6"
lightweight-charts: "npm:^5.0.8"
+ micro-memoize: "npm:^4.2.0"
next: "npm:14.2.28"
next-themes: "npm:^0.4.6"
pino-pretty: "npm:^13.0.0"
@@ -9340,7 +11111,7 @@ __metadata:
languageName: node
linkType: hard
-"get-caller-file@npm:^2.0.1":
+"get-caller-file@npm:^2.0.1, get-caller-file@npm:^2.0.5":
version: 2.0.5
resolution: "get-caller-file@npm:2.0.5"
checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde
@@ -9457,7 +11228,7 @@ __metadata:
languageName: node
linkType: hard
-"glob@npm:^7.1.3":
+"glob@npm:^7.1.1, glob@npm:^7.1.3":
version: 7.2.3
resolution: "glob@npm:7.2.3"
dependencies:
@@ -9497,6 +11268,20 @@ __metadata:
languageName: node
linkType: hard
+"globby@npm:^11.0.3":
+ version: 11.1.0
+ resolution: "globby@npm:11.1.0"
+ dependencies:
+ array-union: "npm:^2.1.0"
+ dir-glob: "npm:^3.0.1"
+ fast-glob: "npm:^3.2.9"
+ ignore: "npm:^5.2.0"
+ merge2: "npm:^1.4.1"
+ slash: "npm:^3.0.0"
+ checksum: 10c0/b39511b4afe4bd8a7aead3a27c4ade2b9968649abab0a6c28b1a90141b96ca68ca5db1302f7c7bd29eab66bf51e13916b8e0a3d0ac08f75e1e84a39b35691189
+ languageName: node
+ linkType: hard
+
"gopd@npm:^1.0.1, gopd@npm:^1.2.0":
version: 1.2.0
resolution: "gopd@npm:1.2.0"
@@ -9518,6 +11303,31 @@ __metadata:
languageName: node
linkType: hard
+"graphql-config@npm:^5.1.1":
+ version: 5.1.5
+ resolution: "graphql-config@npm:5.1.5"
+ dependencies:
+ "@graphql-tools/graphql-file-loader": "npm:^8.0.0"
+ "@graphql-tools/json-file-loader": "npm:^8.0.0"
+ "@graphql-tools/load": "npm:^8.1.0"
+ "@graphql-tools/merge": "npm:^9.0.0"
+ "@graphql-tools/url-loader": "npm:^8.0.0"
+ "@graphql-tools/utils": "npm:^10.0.0"
+ cosmiconfig: "npm:^8.1.0"
+ jiti: "npm:^2.0.0"
+ minimatch: "npm:^9.0.5"
+ string-env-interpolation: "npm:^1.0.1"
+ tslib: "npm:^2.4.0"
+ peerDependencies:
+ cosmiconfig-toml-loader: ^1.0.0
+ graphql: ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
+ peerDependenciesMeta:
+ cosmiconfig-toml-loader:
+ optional: true
+ checksum: 10c0/05e2a895dd899709da0a6f24c0248d858c23767c4848f27f68935a6fe44d00dfd804c38ef59157193ad30e54d4e0773d9ec562842fe00ce7aaa0330bca5053cd
+ languageName: node
+ linkType: hard
+
"graphql-request@npm:^3.4.0":
version: 3.7.0
resolution: "graphql-request@npm:3.7.0"
@@ -9558,7 +11368,30 @@ __metadata:
languageName: node
linkType: hard
-"graphql-tag@npm:^2.12.6":
+"graphql-request@npm:^6.0.0":
+ version: 6.1.0
+ resolution: "graphql-request@npm:6.1.0"
+ dependencies:
+ "@graphql-typed-document-node/core": "npm:^3.2.0"
+ cross-fetch: "npm:^3.1.5"
+ peerDependencies:
+ graphql: 14 - 16
+ checksum: 10c0/f8167925a110e8e1de93d56c14245e7e64391dc8dce5002dd01bf24a3059f345d4ca1bb6ce2040e2ec78264211b0704e75da3e63984f0f74d2042f697a4e8cc6
+ languageName: node
+ linkType: hard
+
+"graphql-request@npm:^7.3.1":
+ version: 7.3.1
+ resolution: "graphql-request@npm:7.3.1"
+ dependencies:
+ "@graphql-typed-document-node/core": "npm:^3.2.0"
+ peerDependencies:
+ graphql: 14 - 16
+ checksum: 10c0/7764cdd965a17d102c1730f627396bf1e57337a4cd6a149d7c24cf0c3a753b79027bfc2f6f592ac655567d650faa954f2272f5bccb05bec84aea9e70a298ac69
+ languageName: node
+ linkType: hard
+
+"graphql-tag@npm:^2.11.0, graphql-tag@npm:^2.12.6":
version: 2.12.6
resolution: "graphql-tag@npm:2.12.6"
dependencies:
@@ -9569,6 +11402,28 @@ __metadata:
languageName: node
linkType: hard
+"graphql-ws@npm:^6.0.6":
+ version: 6.0.6
+ resolution: "graphql-ws@npm:6.0.6"
+ peerDependencies:
+ "@fastify/websocket": ^10 || ^11
+ crossws: ~0.3
+ graphql: ^15.10.1 || ^16
+ uWebSockets.js: ^20
+ ws: ^8
+ peerDependenciesMeta:
+ "@fastify/websocket":
+ optional: true
+ crossws:
+ optional: true
+ uWebSockets.js:
+ optional: true
+ ws:
+ optional: true
+ checksum: 10c0/4d1f18245fd2c56670156d910bc45a6fd456291b6e9b96d98e3d7fd464e1b406cfb4e68b4aafeb875c366d63d8f204b488b57729d622cd8d97e0387d0cd38dcf
+ languageName: node
+ linkType: hard
+
"graphql@npm:^15.5.0":
version: 15.10.1
resolution: "graphql@npm:15.10.1"
@@ -9695,6 +11550,16 @@ __metadata:
languageName: node
linkType: hard
+"header-case@npm:^2.0.4":
+ version: 2.0.4
+ resolution: "header-case@npm:2.0.4"
+ dependencies:
+ capital-case: "npm:^1.0.4"
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/c9f295d9d8e38fa50679281fd70d80726962256e888a76c8e72e526453da7a1832dcb427caa716c1ad5d79841d4537301b90156fa30298fefd3d68f4ea2181bb
+ languageName: node
+ linkType: hard
+
"help-me@npm:^5.0.0":
version: 5.0.0
resolution: "help-me@npm:5.0.0"
@@ -9746,7 +11611,7 @@ __metadata:
languageName: node
linkType: hard
-"https-proxy-agent@npm:^7.0.1":
+"https-proxy-agent@npm:^7.0.0, https-proxy-agent@npm:^7.0.1":
version: 7.0.6
resolution: "https-proxy-agent@npm:7.0.6"
dependencies:
@@ -9772,6 +11637,15 @@ __metadata:
languageName: node
linkType: hard
+"iconv-lite@npm:^0.7.0":
+ version: 0.7.0
+ resolution: "iconv-lite@npm:0.7.0"
+ dependencies:
+ safer-buffer: "npm:>= 2.1.2 < 3.0.0"
+ checksum: 10c0/2382400469071c55b6746c531eed5fa4d033e5db6690b7331fb2a5f59a30d7a9782932e92253db26df33c1cf46fa200a3fbe524a2a7c62037c762283f188ec2f
+ languageName: node
+ linkType: hard
+
"idb-keyval@npm:^6.2.1":
version: 6.2.2
resolution: "idb-keyval@npm:6.2.2"
@@ -9779,7 +11653,7 @@ __metadata:
languageName: node
linkType: hard
-"ieee754@npm:^1.2.1":
+"ieee754@npm:^1.1.13, ieee754@npm:^1.2.1":
version: 1.2.1
resolution: "ieee754@npm:1.2.1"
checksum: 10c0/b0782ef5e0935b9f12883a2e2aa37baa75da6e66ce6515c168697b42160807d9330de9a32ec1ed73149aea02e0d822e572bca6f1e22bdcbd2149e13b050b17bb
@@ -9800,6 +11674,13 @@ __metadata:
languageName: node
linkType: hard
+"immutable@npm:~3.7.6":
+ version: 3.7.6
+ resolution: "immutable@npm:3.7.6"
+ checksum: 10c0/efe2bbb2620aa897afbb79545b9eda4dd3dc072e05ae7004895a7efb43187e4265612a88f8723f391eb1c87c46c52fd11e2d1968e42404450c63e49558d7ca4e
+ languageName: node
+ linkType: hard
+
"import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0":
version: 3.3.1
resolution: "import-fresh@npm:3.3.1"
@@ -9810,6 +11691,13 @@ __metadata:
languageName: node
linkType: hard
+"import-from@npm:4.0.0":
+ version: 4.0.0
+ resolution: "import-from@npm:4.0.0"
+ checksum: 10c0/7fd98650d555e418c18341fef49ae11afc833f5ae70b7043e99684187cba6ac6b52e4118a491bd9f856045495bef5bdda7321095e65bcb2ef70ce2adf9f0d8d1
+ languageName: node
+ linkType: hard
+
"imurmurhash@npm:^0.1.4":
version: 0.1.4
resolution: "imurmurhash@npm:0.1.4"
@@ -9850,6 +11738,29 @@ __metadata:
languageName: node
linkType: hard
+"inquirer@npm:^8.0.0":
+ version: 8.2.7
+ resolution: "inquirer@npm:8.2.7"
+ dependencies:
+ "@inquirer/external-editor": "npm:^1.0.0"
+ ansi-escapes: "npm:^4.2.1"
+ chalk: "npm:^4.1.1"
+ cli-cursor: "npm:^3.1.0"
+ cli-width: "npm:^3.0.0"
+ figures: "npm:^3.0.0"
+ lodash: "npm:^4.17.21"
+ mute-stream: "npm:0.0.8"
+ ora: "npm:^5.4.1"
+ run-async: "npm:^2.4.0"
+ rxjs: "npm:^7.5.5"
+ string-width: "npm:^4.1.0"
+ strip-ansi: "npm:^6.0.0"
+ through: "npm:^2.3.6"
+ wrap-ansi: "npm:^6.0.1"
+ checksum: 10c0/75aa594231769d292102615da3199320359bfb566e96dae0f89a5773a18e21c676709d9f5a9fb1372f7d2cf25c551a4efe53691ff436d941f95336931777c15d
+ languageName: node
+ linkType: hard
+
"interface-ipld-format@npm:^1.0.0":
version: 1.0.1
resolution: "interface-ipld-format@npm:1.0.1"
@@ -9884,6 +11795,15 @@ __metadata:
languageName: node
linkType: hard
+"invariant@npm:^2.2.4":
+ version: 2.2.4
+ resolution: "invariant@npm:2.2.4"
+ dependencies:
+ loose-envify: "npm:^1.0.0"
+ checksum: 10c0/5af133a917c0bcf65e84e7f23e779e7abc1cd49cb7fdc62d00d1de74b0d8c1b5ee74ac7766099fb3be1b05b26dfc67bab76a17030d2fe7ea2eef867434362dfc
+ languageName: node
+ linkType: hard
+
"ip-address@npm:^9.0.5":
version: 9.0.5
resolution: "ip-address@npm:9.0.5"
@@ -9960,6 +11880,16 @@ __metadata:
languageName: node
linkType: hard
+"is-absolute@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "is-absolute@npm:1.0.0"
+ dependencies:
+ is-relative: "npm:^1.0.0"
+ is-windows: "npm:^1.0.1"
+ checksum: 10c0/422302ce879d4f3ca6848499b6f3ddcc8fd2dc9f3e9cad3f6bcedff58cdfbbbd7f4c28600fffa7c59a858f1b15c27fb6cfe1d5275e58a36d2bf098a44ef5abc4
+ languageName: node
+ linkType: hard
+
"is-arguments@npm:^1.0.4":
version: 1.2.0
resolution: "is-arguments@npm:1.2.0"
@@ -10110,7 +12040,7 @@ __metadata:
languageName: node
linkType: hard
-"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1":
+"is-glob@npm:4.0.3, is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1":
version: 4.0.3
resolution: "is-glob@npm:4.0.3"
dependencies:
@@ -10119,6 +12049,22 @@ __metadata:
languageName: node
linkType: hard
+"is-interactive@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "is-interactive@npm:1.0.0"
+ checksum: 10c0/dd47904dbf286cd20aa58c5192161be1a67138485b9836d5a70433b21a45442e9611b8498b8ab1f839fc962c7620667a50535fdfb4a6bc7989b8858645c06b4d
+ languageName: node
+ linkType: hard
+
+"is-lower-case@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "is-lower-case@npm:2.0.2"
+ dependencies:
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/c045e6a52dcc7c3857e2f8c850ded604cdc5269ff94625b03881cefc73bfc02f5099a1bc9bafa67793656711a40d4ab3e26e285a848e728506df20ead0ce8e2f
+ languageName: node
+ linkType: hard
+
"is-map@npm:^2.0.3":
version: 2.0.3
resolution: "is-map@npm:2.0.3"
@@ -10190,6 +12136,15 @@ __metadata:
languageName: node
linkType: hard
+"is-relative@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "is-relative@npm:1.0.0"
+ dependencies:
+ is-unc-path: "npm:^1.0.0"
+ checksum: 10c0/61157c4be8594dd25ac6f0ef29b1218c36667259ea26698367a4d9f39ff9018368bc365c490b3c79be92dfb1e389e43c4b865c95709e7b3bc72c5932f751fb60
+ languageName: node
+ linkType: hard
+
"is-set@npm:^2.0.3":
version: 2.0.3
resolution: "is-set@npm:2.0.3"
@@ -10243,6 +12198,31 @@ __metadata:
languageName: node
linkType: hard
+"is-unc-path@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "is-unc-path@npm:1.0.0"
+ dependencies:
+ unc-path-regex: "npm:^0.1.2"
+ checksum: 10c0/ac1b78f9b748196e3be3d0e722cd4b0f98639247a130a8f2473a58b29baf63fdb1b1c5a12c830660c5ee6ef0279c5418ca8e346f98cbe1a29e433d7ae531d42e
+ languageName: node
+ linkType: hard
+
+"is-unicode-supported@npm:^0.1.0":
+ version: 0.1.0
+ resolution: "is-unicode-supported@npm:0.1.0"
+ checksum: 10c0/00cbe3455c3756be68d2542c416cab888aebd5012781d6819749fefb15162ff23e38501fe681b3d751c73e8ff561ac09a5293eba6f58fdf0178462ce6dcb3453
+ languageName: node
+ linkType: hard
+
+"is-upper-case@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "is-upper-case@npm:2.0.2"
+ dependencies:
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/2236f416484a2643d55a07cc95443cecf96cbc5fb0de7f24c506a8bc5cc4c4de885ab56c5ec946eadd95b3b7960bff7ed51cc88511fa8e8a9d92f2f8969622d9
+ languageName: node
+ linkType: hard
+
"is-weakmap@npm:^2.0.2":
version: 2.0.2
resolution: "is-weakmap@npm:2.0.2"
@@ -10269,6 +12249,13 @@ __metadata:
languageName: node
linkType: hard
+"is-windows@npm:^1.0.1":
+ version: 1.0.2
+ resolution: "is-windows@npm:1.0.2"
+ checksum: 10c0/b32f418ab3385604a66f1b7a3ce39d25e8881dee0bd30816dc8344ef6ff9df473a732bcc1ec4e84fe99b2f229ae474f7133e8e93f9241686cfcf7eebe53ba7a5
+ languageName: node
+ linkType: hard
+
"isarray@npm:^2.0.5":
version: 2.0.5
resolution: "isarray@npm:2.0.5"
@@ -10304,6 +12291,15 @@ __metadata:
languageName: node
linkType: hard
+"isomorphic-ws@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "isomorphic-ws@npm:5.0.0"
+ peerDependencies:
+ ws: "*"
+ checksum: 10c0/a058ac8b5e6efe9e46252cb0bc67fd325005d7216451d1a51238bc62d7da8486f828ef017df54ddf742e0fffcbe4b1bcc2a66cc115b027ed0180334cd18df252
+ languageName: node
+ linkType: hard
+
"isows@npm:1.0.6":
version: 1.0.6
resolution: "isows@npm:1.0.6"
@@ -10403,6 +12399,24 @@ __metadata:
languageName: node
linkType: hard
+"jiti@npm:^1.17.1":
+ version: 1.21.7
+ resolution: "jiti@npm:1.21.7"
+ bin:
+ jiti: bin/jiti.js
+ checksum: 10c0/77b61989c758ff32407cdae8ddc77f85e18e1a13fc4977110dbd2e05fc761842f5f71bce684d9a01316e1c4263971315a111385759951080bbfe17cbb5de8f7a
+ languageName: node
+ linkType: hard
+
+"jiti@npm:^2.0.0":
+ version: 2.6.1
+ resolution: "jiti@npm:2.6.1"
+ bin:
+ jiti: lib/jiti-cli.mjs
+ checksum: 10c0/79b2e96a8e623f66c1b703b98ec1b8be4500e1d217e09b09e343471bbb9c105381b83edbb979d01cef18318cc45ce6e153571b6c83122170eefa531c64b6789b
+ languageName: node
+ linkType: hard
+
"jiti@npm:^2.4.2":
version: 2.4.2
resolution: "jiti@npm:2.4.2"
@@ -10412,6 +12426,13 @@ __metadata:
languageName: node
linkType: hard
+"jose@npm:^5.0.0":
+ version: 5.10.0
+ resolution: "jose@npm:5.10.0"
+ checksum: 10c0/e20d9fc58d7e402f2e5f04e824b8897d5579aae60e64cb88ebdea1395311c24537bf4892f7de413fab1acf11e922797fb1b42269bc8fc65089a3749265ccb7b0
+ languageName: node
+ linkType: hard
+
"joycon@npm:^3.1.1":
version: 3.1.1
resolution: "joycon@npm:3.1.1"
@@ -10440,7 +12461,7 @@ __metadata:
languageName: node
linkType: hard
-"js-yaml@npm:^4.1.0":
+"js-yaml@npm:^4.0.0, js-yaml@npm:^4.1.0":
version: 4.1.0
resolution: "js-yaml@npm:4.1.0"
dependencies:
@@ -10542,6 +12563,16 @@ __metadata:
languageName: node
linkType: hard
+"json-to-pretty-yaml@npm:^1.2.2":
+ version: 1.2.2
+ resolution: "json-to-pretty-yaml@npm:1.2.2"
+ dependencies:
+ remedial: "npm:^1.0.7"
+ remove-trailing-spaces: "npm:^1.0.6"
+ checksum: 10c0/d28891860a7ae034873ac8ec5f69f5493106afed9a86295f1642a40b27a48df717c63966439a1dec5b8a4b30e99b86cd1b4ca7d979bb8048ffd7f7c67bfd88a3
+ languageName: node
+ linkType: hard
+
"json5@npm:^1.0.2":
version: 1.0.2
resolution: "json5@npm:1.0.2"
@@ -10784,6 +12815,27 @@ __metadata:
languageName: node
linkType: hard
+"listr2@npm:^4.0.5":
+ version: 4.0.5
+ resolution: "listr2@npm:4.0.5"
+ dependencies:
+ cli-truncate: "npm:^2.1.0"
+ colorette: "npm:^2.0.16"
+ log-update: "npm:^4.0.0"
+ p-map: "npm:^4.0.0"
+ rfdc: "npm:^1.3.0"
+ rxjs: "npm:^7.5.5"
+ through: "npm:^2.3.8"
+ wrap-ansi: "npm:^7.0.0"
+ peerDependencies:
+ enquirer: ">= 2.3.0 < 3"
+ peerDependenciesMeta:
+ enquirer:
+ optional: true
+ checksum: 10c0/0e64dc5e66fbd4361f6b35c49489ed842a1d7de30cf2b5c06bf4569669449288698b8ea93f7842aaf3c510963a1e554bca31376b9054d1521445d1ce4c917ea1
+ languageName: node
+ linkType: hard
+
"lit-element@npm:^4.2.0":
version: 4.2.0
resolution: "lit-element@npm:4.2.0"
@@ -10868,6 +12920,13 @@ __metadata:
languageName: node
linkType: hard
+"lodash.sortby@npm:^4.7.0":
+ version: 4.7.0
+ resolution: "lodash.sortby@npm:4.7.0"
+ checksum: 10c0/fc48fb54ff7669f33bb32997cab9460757ee99fafaf72400b261c3e10fde21538e47d8cfcbe6a25a31bcb5b7b727c27d52626386fc2de24eb059a6d64a89cdf5
+ languageName: node
+ linkType: hard
+
"lodash.throttle@npm:^4.1.1":
version: 4.1.1
resolution: "lodash.throttle@npm:4.1.1"
@@ -10875,13 +12934,35 @@ __metadata:
languageName: node
linkType: hard
-"lodash@npm:^4.17.21":
+"lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:~4.17.0":
version: 4.17.21
resolution: "lodash@npm:4.17.21"
checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c
languageName: node
linkType: hard
+"log-symbols@npm:^4.0.0, log-symbols@npm:^4.1.0":
+ version: 4.1.0
+ resolution: "log-symbols@npm:4.1.0"
+ dependencies:
+ chalk: "npm:^4.1.0"
+ is-unicode-supported: "npm:^0.1.0"
+ checksum: 10c0/67f445a9ffa76db1989d0fa98586e5bc2fd5247260dafb8ad93d9f0ccd5896d53fb830b0e54dade5ad838b9de2006c826831a3c528913093af20dff8bd24aca6
+ languageName: node
+ linkType: hard
+
+"log-update@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "log-update@npm:4.0.0"
+ dependencies:
+ ansi-escapes: "npm:^4.3.0"
+ cli-cursor: "npm:^3.1.0"
+ slice-ansi: "npm:^4.0.0"
+ wrap-ansi: "npm:^6.2.0"
+ checksum: 10c0/18b299e230432a156f2535660776406d15ba8bb7817dd3eaadd58004b363756d4ecaabcd658f9949f90b62ea7d3354423be3fdeb7a201ab951ec0e8d6139af86
+ languageName: node
+ linkType: hard
+
"long@npm:^4.0.0":
version: 4.0.0
resolution: "long@npm:4.0.0"
@@ -10889,7 +12970,7 @@ __metadata:
languageName: node
linkType: hard
-"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0":
+"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0":
version: 1.4.0
resolution: "loose-envify@npm:1.4.0"
dependencies:
@@ -10900,6 +12981,15 @@ __metadata:
languageName: node
linkType: hard
+"lower-case-first@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "lower-case-first@npm:2.0.2"
+ dependencies:
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/22253389fa0693ec1ba09b9394be3a8228304bf21d074703db2eef97c16cda9c66462d88f9b91d4ad0186493d23cad99c63d38ebc13f9a808bc83aad539ff404
+ languageName: node
+ linkType: hard
+
"lower-case@npm:^2.0.2":
version: 2.0.2
resolution: "lower-case@npm:2.0.2"
@@ -10971,6 +13061,13 @@ __metadata:
languageName: node
linkType: hard
+"map-cache@npm:^0.2.0":
+ version: 0.2.2
+ resolution: "map-cache@npm:0.2.2"
+ checksum: 10c0/05e3eb005c1b80b9f949ca007687640e8c5d0fc88dc45c3c3ab4902a3bec79d66a58f3e3b04d6985d90cd267c629c7b46c977e9c34433e8c11ecfcbb9f0fa290
+ languageName: node
+ linkType: hard
+
"map-obj@npm:^1.0.0":
version: 1.0.1
resolution: "map-obj@npm:1.0.1"
@@ -11058,13 +13155,25 @@ __metadata:
languageName: node
linkType: hard
-"merge2@npm:^1.3.0":
+"merge2@npm:^1.3.0, merge2@npm:^1.4.1":
version: 1.4.1
resolution: "merge2@npm:1.4.1"
checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb
languageName: node
linkType: hard
+"meros@npm:^1.2.1":
+ version: 1.3.2
+ resolution: "meros@npm:1.3.2"
+ peerDependencies:
+ "@types/node": ">=13"
+ peerDependenciesMeta:
+ "@types/node":
+ optional: true
+ checksum: 10c0/ebb0e462e4aeccaf569593c714f738e6f941dcf10b537c6aa1acec92ce8894cc76f6a995ecaac89b0bcefe240ec20539ade4d7fe897845cd815de1bf78099836
+ languageName: node
+ linkType: hard
+
"micro-ftch@npm:^0.3.1":
version: 0.3.1
resolution: "micro-ftch@npm:0.3.1"
@@ -11072,7 +13181,14 @@ __metadata:
languageName: node
linkType: hard
-"micromatch@npm:^4.0.8":
+"micro-memoize@npm:^4.2.0":
+ version: 4.2.0
+ resolution: "micro-memoize@npm:4.2.0"
+ checksum: 10c0/e8bc7252d7424b68276ec346b5f21802633f753c3927e73b60e311d734e8645917ff619728f91b8f49d5f1f1d9285e6f0abf2c378b02bf33e2decb1de8e5cc14
+ languageName: node
+ linkType: hard
+
+"micromatch@npm:^4.0.5, micromatch@npm:^4.0.8":
version: 4.0.8
resolution: "micromatch@npm:4.0.8"
dependencies:
@@ -11098,6 +13214,13 @@ __metadata:
languageName: node
linkType: hard
+"mimic-fn@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "mimic-fn@npm:2.1.0"
+ checksum: 10c0/b26f5479d7ec6cc2bce275a08f146cf78f5e7b661b18114e2506dd91ec7ec47e7a25bf4360e5438094db0560bcc868079fb3b1fb3892b833c1ecbf63f80c95a4
+ languageName: node
+ linkType: hard
+
"min-indent@npm:^1.0.0":
version: 1.0.1
resolution: "min-indent@npm:1.0.1"
@@ -11128,7 +13251,7 @@ __metadata:
languageName: node
linkType: hard
-"minimatch@npm:^9.0.1, minimatch@npm:^9.0.4":
+"minimatch@npm:^9.0.1, minimatch@npm:^9.0.4, minimatch@npm:^9.0.5":
version: 9.0.5
resolution: "minimatch@npm:9.0.5"
dependencies:
@@ -11344,6 +13467,13 @@ __metadata:
languageName: node
linkType: hard
+"mute-stream@npm:0.0.8":
+ version: 0.0.8
+ resolution: "mute-stream@npm:0.0.8"
+ checksum: 10c0/18d06d92e5d6d45e2b63c0e1b8f25376af71748ac36f53c059baa8b76ffac31c5ab225480494e7d35d30215ecdb18fed26ec23cafcd2f7733f2f14406bcd19e2
+ languageName: node
+ linkType: hard
+
"mv@npm:~2":
version: 2.1.1
resolution: "mv@npm:2.1.1"
@@ -11536,6 +13666,13 @@ __metadata:
languageName: node
linkType: hard
+"node-domexception@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "node-domexception@npm:1.0.0"
+ checksum: 10c0/5e5d63cda29856402df9472335af4bb13875e1927ad3be861dc5ebde38917aecbf9ae337923777af52a48c426b70148815e890a5d72760f1b4d758cc671b1a2b
+ languageName: node
+ linkType: hard
+
"node-fetch-native@npm:^1.6.4, node-fetch-native@npm:^1.6.6":
version: 1.6.6
resolution: "node-fetch-native@npm:1.6.6"
@@ -11557,6 +13694,17 @@ __metadata:
languageName: node
linkType: hard
+"node-fetch@npm:^3.3.2":
+ version: 3.3.2
+ resolution: "node-fetch@npm:3.3.2"
+ dependencies:
+ data-uri-to-buffer: "npm:^4.0.0"
+ fetch-blob: "npm:^3.1.4"
+ formdata-polyfill: "npm:^4.0.10"
+ checksum: 10c0/f3d5e56190562221398c9f5750198b34cf6113aa304e34ee97c94fd300ec578b25b2c2906edba922050fce983338fde0d5d34fcb0fc3336ade5bd0e429ad7538
+ languageName: node
+ linkType: hard
+
"node-gyp-build@npm:^4.2.0, node-gyp-build@npm:^4.3.0":
version: 4.8.4
resolution: "node-gyp-build@npm:4.8.4"
@@ -11588,6 +13736,13 @@ __metadata:
languageName: node
linkType: hard
+"node-int64@npm:^0.4.0":
+ version: 0.4.0
+ resolution: "node-int64@npm:0.4.0"
+ checksum: 10c0/a6a4d8369e2f2720e9c645255ffde909c0fbd41c92ea92a5607fc17055955daac99c1ff589d421eee12a0d24e99f7bfc2aabfeb1a4c14742f6c099a51863f31a
+ languageName: node
+ linkType: hard
+
"node-mock-http@npm:^1.0.0":
version: 1.0.0
resolution: "node-mock-http@npm:1.0.0"
@@ -11637,6 +13792,15 @@ __metadata:
languageName: node
linkType: hard
+"normalize-path@npm:^2.1.1":
+ version: 2.1.1
+ resolution: "normalize-path@npm:2.1.1"
+ dependencies:
+ remove-trailing-separator: "npm:^1.0.1"
+ checksum: 10c0/db814326ff88057437233361b4c7e9cac7b54815b051b57f2d341ce89b1d8ec8cbd43e7fa95d7652b3b69ea8fcc294b89b8530d556a84d1bdace94229e1e9a8b
+ languageName: node
+ linkType: hard
+
"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0":
version: 3.0.0
resolution: "normalize-path@npm:3.0.0"
@@ -11653,6 +13817,13 @@ __metadata:
languageName: node
linkType: hard
+"nullthrows@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "nullthrows@npm:1.1.1"
+ checksum: 10c0/56f34bd7c3dcb3bd23481a277fa22918120459d3e9d95ca72976c72e9cac33a97483f0b95fc420e2eb546b9fe6db398273aba9a938650cdb8c98ee8f159dcb30
+ languageName: node
+ linkType: hard
+
"obj-multiplex@npm:^1.0.0":
version: 1.0.0
resolution: "obj-multiplex@npm:1.0.0"
@@ -11664,7 +13835,7 @@ __metadata:
languageName: node
linkType: hard
-"object-assign@npm:^4.1.1":
+"object-assign@npm:^4.1.0, object-assign@npm:^4.1.1":
version: 4.1.1
resolution: "object-assign@npm:4.1.1"
checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414
@@ -11787,6 +13958,15 @@ __metadata:
languageName: node
linkType: hard
+"onetime@npm:^5.1.0":
+ version: 5.1.2
+ resolution: "onetime@npm:5.1.2"
+ dependencies:
+ mimic-fn: "npm:^2.1.0"
+ checksum: 10c0/ffcef6fbb2692c3c40749f31ea2e22677a876daea92959b8a80b521d95cca7a668c884d8b2045d1d8ee7d56796aa405c405462af112a1477594cc63531baeb8f
+ languageName: node
+ linkType: hard
+
"optionator@npm:^0.9.3":
version: 0.9.4
resolution: "optionator@npm:0.9.4"
@@ -11801,6 +13981,23 @@ __metadata:
languageName: node
linkType: hard
+"ora@npm:^5.4.1":
+ version: 5.4.1
+ resolution: "ora@npm:5.4.1"
+ dependencies:
+ bl: "npm:^4.1.0"
+ chalk: "npm:^4.1.0"
+ cli-cursor: "npm:^3.1.0"
+ cli-spinners: "npm:^2.5.0"
+ is-interactive: "npm:^1.0.0"
+ is-unicode-supported: "npm:^0.1.0"
+ log-symbols: "npm:^4.1.0"
+ strip-ansi: "npm:^6.0.0"
+ wcwidth: "npm:^1.0.1"
+ checksum: 10c0/10ff14aace236d0e2f044193362b22edce4784add08b779eccc8f8ef97195cae1248db8ec1ec5f5ff076f91acbe573f5f42a98c19b78dba8c54eefff983cae85
+ languageName: node
+ linkType: hard
+
"own-keys@npm:^1.0.1":
version: 1.0.1
resolution: "own-keys@npm:1.0.1"
@@ -11874,6 +14071,15 @@ __metadata:
languageName: node
linkType: hard
+"p-limit@npm:3.1.0, p-limit@npm:^3.0.2":
+ version: 3.1.0
+ resolution: "p-limit@npm:3.1.0"
+ dependencies:
+ yocto-queue: "npm:^0.1.0"
+ checksum: 10c0/9db675949dbdc9c3763c89e748d0ef8bdad0afbb24d49ceaf4c46c02c77d30db4e0652ed36d0a0a7a95154335fab810d95c86153105bb73b3a90448e2bb14e1a
+ languageName: node
+ linkType: hard
+
"p-limit@npm:^2.2.0":
version: 2.3.0
resolution: "p-limit@npm:2.3.0"
@@ -11883,15 +14089,6 @@ __metadata:
languageName: node
linkType: hard
-"p-limit@npm:^3.0.2":
- version: 3.1.0
- resolution: "p-limit@npm:3.1.0"
- dependencies:
- yocto-queue: "npm:^0.1.0"
- checksum: 10c0/9db675949dbdc9c3763c89e748d0ef8bdad0afbb24d49ceaf4c46c02c77d30db4e0652ed36d0a0a7a95154335fab810d95c86153105bb73b3a90448e2bb14e1a
- languageName: node
- linkType: hard
-
"p-locate@npm:^4.1.0":
version: 4.1.0
resolution: "p-locate@npm:4.1.0"
@@ -11910,6 +14107,15 @@ __metadata:
languageName: node
linkType: hard
+"p-map@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "p-map@npm:4.0.0"
+ dependencies:
+ aggregate-error: "npm:^3.0.0"
+ checksum: 10c0/592c05bd6262c466ce269ff172bb8de7c6975afca9b50c975135b974e9bdaafbfe80e61aaaf5be6d1200ba08b30ead04b88cfa7e25ff1e3b93ab28c9f62a2c75
+ languageName: node
+ linkType: hard
+
"p-map@npm:^7.0.2":
version: 7.0.3
resolution: "p-map@npm:7.0.3"
@@ -11931,6 +14137,16 @@ __metadata:
languageName: node
linkType: hard
+"param-case@npm:^3.0.4":
+ version: 3.0.4
+ resolution: "param-case@npm:3.0.4"
+ dependencies:
+ dot-case: "npm:^3.0.4"
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/ccc053f3019f878eca10e70ec546d92f51a592f762917dafab11c8b532715dcff58356118a6f350976e4ab109e321756f05739643ed0ca94298e82291e6f9e76
+ languageName: node
+ linkType: hard
+
"parent-module@npm:^1.0.0":
version: 1.0.1
resolution: "parent-module@npm:1.0.1"
@@ -11940,6 +14156,17 @@ __metadata:
languageName: node
linkType: hard
+"parse-filepath@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "parse-filepath@npm:1.0.2"
+ dependencies:
+ is-absolute: "npm:^1.0.0"
+ map-cache: "npm:^0.2.0"
+ path-root: "npm:^0.1.1"
+ checksum: 10c0/37bbd225fa864257246777efbdf72a9305c4ae12110bf467d11994e93f8be60dd309dcef68124a2c78c5d3b4e64e1c36fcc2560e2ea93fd97767831e7a446805
+ languageName: node
+ linkType: hard
+
"parse-json@npm:^5.0.0, parse-json@npm:^5.2.0":
version: 5.2.0
resolution: "parse-json@npm:5.2.0"
@@ -11952,6 +14179,26 @@ __metadata:
languageName: node
linkType: hard
+"pascal-case@npm:^3.1.2":
+ version: 3.1.2
+ resolution: "pascal-case@npm:3.1.2"
+ dependencies:
+ no-case: "npm:^3.0.4"
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/05ff7c344809fd272fc5030ae0ee3da8e4e63f36d47a1e0a4855ca59736254192c5a27b5822ed4bae96e54048eec5f6907713cfcfff7cdf7a464eaf7490786d8
+ languageName: node
+ linkType: hard
+
+"path-case@npm:^3.0.4":
+ version: 3.0.4
+ resolution: "path-case@npm:3.0.4"
+ dependencies:
+ dot-case: "npm:^3.0.4"
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/b6b14637228a558793f603aaeb2fcd981e738b8b9319421b713532fba96d75aa94024b9f6b9ae5aa33d86755144a5b36697d28db62ae45527dbd672fcc2cf0b7
+ languageName: node
+ linkType: hard
+
"path-exists@npm:^4.0.0":
version: 4.0.0
resolution: "path-exists@npm:4.0.0"
@@ -11980,6 +14227,22 @@ __metadata:
languageName: node
linkType: hard
+"path-root-regex@npm:^0.1.0":
+ version: 0.1.2
+ resolution: "path-root-regex@npm:0.1.2"
+ checksum: 10c0/27651a234f280c70d982dd25c35550f74a4284cde6b97237aab618cb4b5745682d18cdde1160617bb4a4b6b8aec4fbc911c4a2ad80d01fa4c7ee74dae7af2337
+ languageName: node
+ linkType: hard
+
+"path-root@npm:^0.1.1":
+ version: 0.1.1
+ resolution: "path-root@npm:0.1.1"
+ dependencies:
+ path-root-regex: "npm:^0.1.0"
+ checksum: 10c0/aed5cd290df84c46c7730f6a363e95e47a23929b51ab068a3818d69900da3e89dc154cdfd0c45c57b2e02f40c094351bc862db70c2cb00b7e6bd47039a227813
+ languageName: node
+ linkType: hard
+
"path-scurry@npm:^1.10.1, path-scurry@npm:^1.11.1":
version: 1.11.1
resolution: "path-scurry@npm:1.11.1"
@@ -12287,6 +14550,15 @@ __metadata:
languageName: node
linkType: hard
+"promise@npm:^7.1.1":
+ version: 7.3.1
+ resolution: "promise@npm:7.3.1"
+ dependencies:
+ asap: "npm:~2.0.3"
+ checksum: 10c0/742e5c0cc646af1f0746963b8776299701ad561ce2c70b49365d62c8db8ea3681b0a1bf0d4e2fe07910bf72f02d39e51e8e73dc8d7503c3501206ac908be107f
+ languageName: node
+ linkType: hard
+
"prop-types@npm:^15.6.1, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1":
version: 15.8.1
resolution: "prop-types@npm:15.8.1"
@@ -12811,6 +15083,38 @@ __metadata:
languageName: node
linkType: hard
+"relay-runtime@npm:12.0.0":
+ version: 12.0.0
+ resolution: "relay-runtime@npm:12.0.0"
+ dependencies:
+ "@babel/runtime": "npm:^7.0.0"
+ fbjs: "npm:^3.0.0"
+ invariant: "npm:^2.2.4"
+ checksum: 10c0/f5d29b5c2f3c8a3438d43dcbc3022bd454c4ecbd4f0b10616df08bedc62d8aaa84f155f23e374053cf9f4a8238b93804e37a5b37ed9dc7ad01436d62d1b01d53
+ languageName: node
+ linkType: hard
+
+"remedial@npm:^1.0.7":
+ version: 1.0.8
+ resolution: "remedial@npm:1.0.8"
+ checksum: 10c0/ca1e22d2958e3f0f2fdb5f1c23fecadab5d83a0b1e291c67474c806ce07801212f1d2006995bdcfb592803ead7666e2b1fbb9281b3f32d4a87ff2335b3777725
+ languageName: node
+ linkType: hard
+
+"remove-trailing-separator@npm:^1.0.1":
+ version: 1.1.0
+ resolution: "remove-trailing-separator@npm:1.1.0"
+ checksum: 10c0/3568f9f8f5af3737b4aee9e6e1e8ec4be65a92da9cb27f989e0893714d50aa95ed2ff02d40d1fa35e1b1a234dc9c2437050ef356704a3999feaca6667d9e9bfc
+ languageName: node
+ linkType: hard
+
+"remove-trailing-spaces@npm:^1.0.6":
+ version: 1.0.9
+ resolution: "remove-trailing-spaces@npm:1.0.9"
+ checksum: 10c0/56810d5106319e79d9cda7af4e3356e8e52d026ce0777c04031978ce1368c2a4b6b4cbbdf57215986ce18faab305adcf230c1067d1245a9e7fb25aff3ca14721
+ languageName: node
+ linkType: hard
+
"require-directory@npm:^2.1.1":
version: 2.1.1
resolution: "require-directory@npm:2.1.1"
@@ -12839,6 +15143,13 @@ __metadata:
languageName: node
linkType: hard
+"resolve-from@npm:5.0.0":
+ version: 5.0.0
+ resolution: "resolve-from@npm:5.0.0"
+ checksum: 10c0/b21cb7f1fb746de8107b9febab60095187781137fd803e6a59a76d421444b1531b641bba5857f5dc011974d8a5c635d61cec49e6bd3b7fc20e01f0fafc4efbf2
+ languageName: node
+ linkType: hard
+
"resolve-from@npm:^4.0.0":
version: 4.0.0
resolution: "resolve-from@npm:4.0.0"
@@ -12905,6 +15216,16 @@ __metadata:
languageName: node
linkType: hard
+"restore-cursor@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "restore-cursor@npm:3.1.0"
+ dependencies:
+ onetime: "npm:^5.1.0"
+ signal-exit: "npm:^3.0.2"
+ checksum: 10c0/8051a371d6aa67ff21625fa94e2357bd81ffdc96267f3fb0fc4aaf4534028343836548ef34c240ffa8c25b280ca35eb36be00b3cb2133fa4f51896d7e73c6b4f
+ languageName: node
+ linkType: hard
+
"retry@npm:0.13.1":
version: 0.13.1
resolution: "retry@npm:0.13.1"
@@ -12926,6 +15247,13 @@ __metadata:
languageName: node
linkType: hard
+"rfdc@npm:^1.3.0":
+ version: 1.4.1
+ resolution: "rfdc@npm:1.4.1"
+ checksum: 10c0/4614e4292356cafade0b6031527eea9bc90f2372a22c012313be1dcc69a3b90c7338158b414539be863fa95bfcb2ddcd0587be696841af4e6679d85e62c060c7
+ languageName: node
+ linkType: hard
+
"rimraf@npm:^3.0.2":
version: 3.0.2
resolution: "rimraf@npm:3.0.2"
@@ -12957,6 +15285,13 @@ __metadata:
languageName: node
linkType: hard
+"run-async@npm:^2.4.0":
+ version: 2.4.1
+ resolution: "run-async@npm:2.4.1"
+ checksum: 10c0/35a68c8f1d9664f6c7c2e153877ca1d6e4f886e5ca067c25cdd895a6891ff3a1466ee07c63d6a9be306e9619ff7d509494e6d9c129516a36b9fd82263d579ee1
+ languageName: node
+ linkType: hard
+
"run-parallel@npm:^1.1.9":
version: 1.2.0
resolution: "run-parallel@npm:1.2.0"
@@ -12966,6 +15301,15 @@ __metadata:
languageName: node
linkType: hard
+"rxjs@npm:^7.5.5":
+ version: 7.8.2
+ resolution: "rxjs@npm:7.8.2"
+ dependencies:
+ tslib: "npm:^2.1.0"
+ checksum: 10c0/1fcd33d2066ada98ba8f21fcbbcaee9f0b271de1d38dc7f4e256bfbc6ffcdde68c8bfb69093de7eeb46f24b1fb820620bf0223706cff26b4ab99a7ff7b2e2c45
+ languageName: node
+ linkType: hard
+
"safe-array-concat@npm:^1.1.3":
version: 1.1.3
resolution: "safe-array-concat@npm:1.1.3"
@@ -13058,6 +15402,13 @@ __metadata:
languageName: node
linkType: hard
+"scuid@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "scuid@npm:1.1.0"
+ checksum: 10c0/01c6bd2657ceaa148ead0c836df6251f561166142059261022a38dba429b30141e27ab3c0eca1012b88912f51a9e848e475fe1b6259ef1c61a0a7f6eb54fb261
+ languageName: node
+ linkType: hard
+
"secure-json-parse@npm:^2.4.0":
version: 2.7.0
resolution: "secure-json-parse@npm:2.7.0"
@@ -13092,6 +15443,17 @@ __metadata:
languageName: node
linkType: hard
+"sentence-case@npm:^3.0.4":
+ version: 3.0.4
+ resolution: "sentence-case@npm:3.0.4"
+ dependencies:
+ no-case: "npm:^3.0.4"
+ tslib: "npm:^2.0.3"
+ upper-case-first: "npm:^2.0.2"
+ checksum: 10c0/9a90527a51300cf5faea7fae0c037728f9ddcff23ac083883774c74d180c0a03c31aab43d5c3347512e8c1b31a0d4712512ec82beb71aa79b85149f9abeb5467
+ languageName: node
+ linkType: hard
+
"set-blocking@npm:^2.0.0":
version: 2.0.0
resolution: "set-blocking@npm:2.0.0"
@@ -13143,6 +15505,13 @@ __metadata:
languageName: node
linkType: hard
+"setimmediate@npm:^1.0.5":
+ version: 1.0.5
+ resolution: "setimmediate@npm:1.0.5"
+ checksum: 10c0/5bae81bfdbfbd0ce992893286d49c9693c82b1bcc00dcaaf3a09c8f428fdeacf4190c013598b81875dfac2b08a572422db7df779a99332d0fce186d15a3e4d49
+ languageName: node
+ linkType: hard
+
"sha.js@npm:^2.4.11":
version: 2.4.11
resolution: "sha.js@npm:2.4.11"
@@ -13171,6 +15540,13 @@ __metadata:
languageName: node
linkType: hard
+"shell-quote@npm:^1.7.3":
+ version: 1.8.3
+ resolution: "shell-quote@npm:1.8.3"
+ checksum: 10c0/bee87c34e1e986cfb4c30846b8e6327d18874f10b535699866f368ade11ea4ee45433d97bf5eada22c4320c27df79c3a6a7eb1bf3ecfc47f2c997d9e5e2672fd
+ languageName: node
+ linkType: hard
+
"side-channel-list@npm:^1.0.0":
version: 1.0.0
resolution: "side-channel-list@npm:1.0.0"
@@ -13219,6 +15595,13 @@ __metadata:
languageName: node
linkType: hard
+"signal-exit@npm:^3.0.2":
+ version: 3.0.7
+ resolution: "signal-exit@npm:3.0.7"
+ checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912
+ languageName: node
+ linkType: hard
+
"signal-exit@npm:^4.0.1":
version: 4.1.0
resolution: "signal-exit@npm:4.1.0"
@@ -13226,6 +15609,13 @@ __metadata:
languageName: node
linkType: hard
+"signedsource@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "signedsource@npm:1.0.0"
+ checksum: 10c0/dbb4ade9c94888e83c16d23ef1a43195799de091d366d130be286415e8aeb97b3f25b14fd26fc5888e1335d703ad561374fddee32e43b7cea04751b93d178a47
+ languageName: node
+ linkType: hard
+
"simplebar-react@npm:^2.3.6":
version: 2.4.3
resolution: "simplebar-react@npm:2.4.3"
@@ -13253,6 +15643,35 @@ __metadata:
languageName: node
linkType: hard
+"slash@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "slash@npm:3.0.0"
+ checksum: 10c0/e18488c6a42bdfd4ac5be85b2ced3ccd0224773baae6ad42cfbb9ec74fc07f9fa8396bd35ee638084ead7a2a0818eb5e7151111544d4731ce843019dab4be47b
+ languageName: node
+ linkType: hard
+
+"slice-ansi@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "slice-ansi@npm:3.0.0"
+ dependencies:
+ ansi-styles: "npm:^4.0.0"
+ astral-regex: "npm:^2.0.0"
+ is-fullwidth-code-point: "npm:^3.0.0"
+ checksum: 10c0/88083c9d0ca67d09f8b4c78f68833d69cabbb7236b74df5d741ad572bbf022deaf243fa54009cd434350622a1174ab267710fcc80a214ecc7689797fe00cb27c
+ languageName: node
+ linkType: hard
+
+"slice-ansi@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "slice-ansi@npm:4.0.0"
+ dependencies:
+ ansi-styles: "npm:^4.0.0"
+ astral-regex: "npm:^2.0.0"
+ is-fullwidth-code-point: "npm:^3.0.0"
+ checksum: 10c0/6c25678db1270d4793e0327620f1e0f9f5bea4630123f51e9e399191bc52c87d6e6de53ed33538609e5eacbd1fab769fae00f3705d08d029f02102a540648918
+ languageName: node
+ linkType: hard
+
"smart-buffer@npm:^4.2.0":
version: 4.2.0
resolution: "smart-buffer@npm:4.2.0"
@@ -13407,6 +15826,15 @@ __metadata:
languageName: node
linkType: hard
+"sponge-case@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "sponge-case@npm:1.0.1"
+ dependencies:
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/dbe42f300ae9f7fbd83c40f71c2a61ecf9c86b927b5668bae067d1e516e314671cc85166f87017e51b56938409b1fc042719eb46a6d5bb30cc1cf23252a82761
+ languageName: node
+ linkType: hard
+
"sprintf-js@npm:^1.1.3":
version: 1.1.3
resolution: "sprintf-js@npm:1.1.3"
@@ -13521,7 +15949,14 @@ __metadata:
languageName: node
linkType: hard
-"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0":
+"string-env-interpolation@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "string-env-interpolation@npm:1.0.1"
+ checksum: 10c0/410046e621e71678e71816377d799b40ba88d236708c0ad015114137fa3575f1b3cf14bfd63ec5eaa35ea43ac582308e60a8e1a3839a10f475b8db73470105bc
+ languageName: node
+ linkType: hard
+
+"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3":
version: 4.2.3
resolution: "string-width@npm:4.2.3"
dependencies:
@@ -13752,6 +16187,26 @@ __metadata:
languageName: node
linkType: hard
+"swap-case@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "swap-case@npm:2.0.2"
+ dependencies:
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/6a47c1926e06395ead750905e103be388aeec8c9697f20b14bc3e1e86fcb4fc78e5033197afe6cc8bbed80f0a4ee1f184b0fa22eec7f4a767bdfd278683d52eb
+ languageName: node
+ linkType: hard
+
+"sync-fetch@npm:0.6.0-2":
+ version: 0.6.0-2
+ resolution: "sync-fetch@npm:0.6.0-2"
+ dependencies:
+ node-fetch: "npm:^3.3.2"
+ timeout-signal: "npm:^2.0.0"
+ whatwg-mimetype: "npm:^4.0.0"
+ checksum: 10c0/1b3e96dfe12de520d9530abb0765baa3ce5921b6fc33ff23171cf838916a58956e755eb359669fba59bfba9b0eefd7e5b6eed737db0ba03bc2cb98a93de5cdb3
+ languageName: node
+ linkType: hard
+
"synckit@npm:^0.11.7":
version: 0.11.8
resolution: "synckit@npm:0.11.8"
@@ -13828,6 +16283,20 @@ __metadata:
languageName: node
linkType: hard
+"through@npm:^2.3.6, through@npm:^2.3.8":
+ version: 2.3.8
+ resolution: "through@npm:2.3.8"
+ checksum: 10c0/4b09f3774099de0d4df26d95c5821a62faee32c7e96fb1f4ebd54a2d7c11c57fe88b0a0d49cf375de5fee5ae6bf4eb56dbbf29d07366864e2ee805349970d3cc
+ languageName: node
+ linkType: hard
+
+"timeout-signal@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "timeout-signal@npm:2.0.0"
+ checksum: 10c0/dd0a41712552fd45e075664edbdb5d1715a0791e6a206f1d00f5808b954b18046f87b71a7b9216a5030ba772516212b696bbbfb3115bf81b3277b04f62aab135
+ languageName: node
+ linkType: hard
+
"timers-ext@npm:^0.1.7":
version: 0.1.8
resolution: "timers-ext@npm:0.1.8"
@@ -13862,6 +16331,15 @@ __metadata:
languageName: node
linkType: hard
+"title-case@npm:^3.0.3":
+ version: 3.0.3
+ resolution: "title-case@npm:3.0.3"
+ dependencies:
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/face56f686060f777b43a180d371407124d201eb4238c19d9e97030fd54859696ca4e2ca499cc232f8700f24f2414cc08aab9fdf6d39acff055dd825a4d86d6a
+ languageName: node
+ linkType: hard
+
"to-regex-range@npm:^5.0.1":
version: 5.0.1
resolution: "to-regex-range@npm:5.0.1"
@@ -13915,6 +16393,13 @@ __metadata:
languageName: node
linkType: hard
+"ts-log@npm:^2.2.3":
+ version: 2.2.7
+ resolution: "ts-log@npm:2.2.7"
+ checksum: 10c0/2c63a7ccdea6dad774f51ba031d9b8d7242833733a1122e20be7e2817556f8e5691bd589860940068073c3859f8cdd8b99e2f65934b95a3552e97a60066ea7f3
+ languageName: node
+ linkType: hard
+
"tsconfig-paths@npm:^3.15.0":
version: 3.15.0
resolution: "tsconfig-paths@npm:3.15.0"
@@ -13934,13 +16419,27 @@ __metadata:
languageName: node
linkType: hard
-"tslib@npm:^2.0.0, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.6.0, tslib@npm:^2.8.0":
+"tslib@npm:^2.0.0, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.0, tslib@npm:^2.6.3, tslib@npm:^2.8.0, tslib@npm:^2.8.1":
version: 2.8.1
resolution: "tslib@npm:2.8.1"
checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62
languageName: node
linkType: hard
+"tslib@npm:~2.4.0":
+ version: 2.4.1
+ resolution: "tslib@npm:2.4.1"
+ checksum: 10c0/9ac0e4fd1033861f0b4f0d848dc3009ebcc3aa4757a06e8602a2d8a7aed252810e3540e54e70709f06c0f95311faa8584f769bcbede48aff785eb7e4d399b9ec
+ languageName: node
+ linkType: hard
+
+"tslib@npm:~2.6.0":
+ version: 2.6.3
+ resolution: "tslib@npm:2.6.3"
+ checksum: 10c0/2598aef53d9dbe711af75522464b2104724d6467b26a60f2bdac8297d2b5f1f6b86a71f61717384aa8fd897240467aaa7bcc36a0700a0faf751293d1331db39a
+ languageName: node
+ linkType: hard
+
"type-check@npm:^0.4.0, type-check@npm:~0.4.0":
version: 0.4.0
resolution: "type-check@npm:0.4.0"
@@ -13964,6 +16463,13 @@ __metadata:
languageName: node
linkType: hard
+"type-fest@npm:^0.21.3":
+ version: 0.21.3
+ resolution: "type-fest@npm:0.21.3"
+ checksum: 10c0/902bd57bfa30d51d4779b641c2bc403cdf1371fb9c91d3c058b0133694fcfdb817aef07a47f40faf79039eecbaa39ee9d3c532deff244f3a19ce68cea71a61e8
+ languageName: node
+ linkType: hard
+
"type-fest@npm:^0.6.0":
version: 0.6.0
resolution: "type-fest@npm:0.6.0"
@@ -14078,6 +16584,15 @@ __metadata:
languageName: node
linkType: hard
+"ua-parser-js@npm:^1.0.35":
+ version: 1.0.41
+ resolution: "ua-parser-js@npm:1.0.41"
+ bin:
+ ua-parser-js: script/cli.js
+ checksum: 10c0/45dc1f7f3ce8248e0e64640d2e29c65c0ea1fc9cb105594de84af80e2a57bba4f718b9376098ca7a5b0ffe240f8995b0fa3714afa9d36861c41370a378f1a274
+ languageName: node
+ linkType: hard
+
"ufo@npm:^1.5.4, ufo@npm:^1.6.1":
version: 1.6.1
resolution: "ufo@npm:1.6.1"
@@ -14124,6 +16639,13 @@ __metadata:
languageName: node
linkType: hard
+"unc-path-regex@npm:^0.1.2":
+ version: 0.1.2
+ resolution: "unc-path-regex@npm:0.1.2"
+ checksum: 10c0/bf9c781c4e2f38e6613ea17a51072e4b416840fbe6eeb244597ce9b028fac2fb6cfd3dde1f14111b02c245e665dc461aab8168ecc30b14364d02caa37f812996
+ languageName: node
+ linkType: hard
+
"uncrypto@npm:^0.1.3":
version: 0.1.3
resolution: "uncrypto@npm:0.1.3"
@@ -14194,6 +16716,15 @@ __metadata:
languageName: node
linkType: hard
+"unixify@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "unixify@npm:1.0.0"
+ dependencies:
+ normalize-path: "npm:^2.1.1"
+ checksum: 10c0/8b89100619ebde9f0ab4024a4d402316fb7b1d4853723410fc828944e8d3d01480f210cddf94d9a1699559f8180d861eb6323da8011b7bcc1bbaf6a11a5b1f1e
+ languageName: node
+ linkType: hard
+
"unrs-resolver@npm:^1.6.2":
version: 1.9.1
resolution: "unrs-resolver@npm:1.9.1"
@@ -14347,6 +16878,24 @@ __metadata:
languageName: node
linkType: hard
+"upper-case-first@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "upper-case-first@npm:2.0.2"
+ dependencies:
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/ccad6a0b143310ebfba2b5841f30bef71246297385f1329c022c902b2b5fc5aee009faf1ac9da5ab3ba7f615b88f5dc1cd80461b18a8f38cb1d4c3eb92538ea9
+ languageName: node
+ linkType: hard
+
+"upper-case@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "upper-case@npm:2.0.2"
+ dependencies:
+ tslib: "npm:^2.0.3"
+ checksum: 10c0/5ac176c9d3757abb71400df167f9abb46d63152d5797c630d1a9f083fbabd89711fb4b3dc6de06ff0138fe8946fa5b8518b4fcdae9ca8a3e341417075beae069
+ languageName: node
+ linkType: hard
+
"uri-js@npm:^4.2.2":
version: 4.4.1
resolution: "uri-js@npm:4.4.1"
@@ -14356,6 +16905,13 @@ __metadata:
languageName: node
linkType: hard
+"urlpattern-polyfill@npm:^10.0.0":
+ version: 10.1.0
+ resolution: "urlpattern-polyfill@npm:10.1.0"
+ checksum: 10c0/5b124fd8d0ae920aa2a48b49a7a3b9ad1643b5ce7217b808fb6877826e751cabc01897fd4c85cd1989c4e729072b63aad5c3ba1c1325e4433e0d2f6329156bf1
+ languageName: node
+ linkType: hard
+
"use-sync-external-store@npm:1.2.0":
version: 1.2.0
resolution: "use-sync-external-store@npm:1.2.0"
@@ -14567,6 +17123,22 @@ __metadata:
languageName: node
linkType: hard
+"wcwidth@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "wcwidth@npm:1.0.1"
+ dependencies:
+ defaults: "npm:^1.0.3"
+ checksum: 10c0/5b61ca583a95e2dd85d7078400190efd452e05751a64accb8c06ce4db65d7e0b0cde9917d705e826a2e05cc2548f61efde115ffa374c3e436d04be45c889e5b4
+ languageName: node
+ linkType: hard
+
+"web-streams-polyfill@npm:^3.0.3":
+ version: 3.3.3
+ resolution: "web-streams-polyfill@npm:3.3.3"
+ checksum: 10c0/64e855c47f6c8330b5436147db1c75cb7e7474d924166800e8e2aab5eb6c76aac4981a84261dd2982b3e754490900b99791c80ae1407a9fa0dcff74f82ea3a7f
+ languageName: node
+ linkType: hard
+
"webextension-polyfill@npm:>=0.10.0 <1.0":
version: 0.12.0
resolution: "webextension-polyfill@npm:0.12.0"
@@ -14588,6 +17160,13 @@ __metadata:
languageName: node
linkType: hard
+"whatwg-mimetype@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "whatwg-mimetype@npm:4.0.0"
+ checksum: 10c0/a773cdc8126b514d790bdae7052e8bf242970cebd84af62fb2f35a33411e78e981f6c0ab9ed1fe6ec5071b09d5340ac9178e05b52d35a9c4bcf558ba1b1551df
+ languageName: node
+ linkType: hard
+
"whatwg-url@npm:^5.0.0":
version: 5.0.0
resolution: "whatwg-url@npm:5.0.0"
@@ -14695,7 +17274,7 @@ __metadata:
languageName: node
linkType: hard
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0":
version: 7.0.0
resolution: "wrap-ansi@npm:7.0.0"
dependencies:
@@ -14706,7 +17285,7 @@ __metadata:
languageName: node
linkType: hard
-"wrap-ansi@npm:^6.2.0":
+"wrap-ansi@npm:^6.0.1, wrap-ansi@npm:^6.2.0":
version: 6.2.0
resolution: "wrap-ansi@npm:6.2.0"
dependencies:
@@ -14780,6 +17359,21 @@ __metadata:
languageName: node
linkType: hard
+"ws@npm:^8.17.1, ws@npm:^8.18.3":
+ version: 8.18.3
+ resolution: "ws@npm:8.18.3"
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: ">=5.0.2"
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+ checksum: 10c0/eac918213de265ef7cb3d4ca348b891a51a520d839aa51cdb8ca93d4fa7ff9f6ccb339ccee89e4075324097f0a55157c89fa3f7147bde9d8d7e90335dc087b53
+ languageName: node
+ linkType: hard
+
"ws@npm:~8.17.1":
version: 8.17.1
resolution: "ws@npm:8.17.1"
@@ -14816,6 +17410,13 @@ __metadata:
languageName: node
linkType: hard
+"y18n@npm:^5.0.5":
+ version: 5.0.8
+ resolution: "y18n@npm:5.0.8"
+ checksum: 10c0/4df2842c36e468590c3691c894bc9cdbac41f520566e76e24f59401ba7d8b4811eb1e34524d57e54bc6d864bcb66baab7ffd9ca42bf1eda596618f9162b91249
+ languageName: node
+ linkType: hard
+
"yallist@npm:^3.0.2":
version: 3.1.1
resolution: "yallist@npm:3.1.1"
@@ -14837,6 +17438,22 @@ __metadata:
languageName: node
linkType: hard
+"yaml-ast-parser@npm:^0.0.43":
+ version: 0.0.43
+ resolution: "yaml-ast-parser@npm:0.0.43"
+ checksum: 10c0/4d2f1e761067b2c6abdd882279a406f879258787af470a6d4a659cb79cb2ab056b870b25f1f80f46ed556e8b499d611d247806376f53edf3412f72c0a8ea2e98
+ languageName: node
+ linkType: hard
+
+"yaml@npm:^2.3.1":
+ version: 2.8.1
+ resolution: "yaml@npm:2.8.1"
+ bin:
+ yaml: bin.mjs
+ checksum: 10c0/7c587be00d9303d2ae1566e03bc5bc7fe978ba0d9bf39cc418c3139d37929dfcb93a230d9749f2cb578b6aa5d9ebebc322415e4b653cb83acd8bc0bc321707f3
+ languageName: node
+ linkType: hard
+
"yargs-parser@npm:^18.1.2":
version: 18.1.3
resolution: "yargs-parser@npm:18.1.3"
@@ -14854,6 +17471,13 @@ __metadata:
languageName: node
linkType: hard
+"yargs-parser@npm:^21.1.1":
+ version: 21.1.1
+ resolution: "yargs-parser@npm:21.1.1"
+ checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2
+ languageName: node
+ linkType: hard
+
"yargs@npm:^15.3.1":
version: 15.4.1
resolution: "yargs@npm:15.4.1"
@@ -14873,6 +17497,21 @@ __metadata:
languageName: node
linkType: hard
+"yargs@npm:^17.0.0":
+ version: 17.7.2
+ resolution: "yargs@npm:17.7.2"
+ dependencies:
+ cliui: "npm:^8.0.1"
+ escalade: "npm:^3.1.1"
+ get-caller-file: "npm:^2.0.5"
+ require-directory: "npm:^2.1.1"
+ string-width: "npm:^4.2.3"
+ y18n: "npm:^5.0.5"
+ yargs-parser: "npm:^21.1.1"
+ checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05
+ languageName: node
+ linkType: hard
+
"yocto-queue@npm:^0.1.0":
version: 0.1.0
resolution: "yocto-queue@npm:0.1.0"