From a8743400e4aa11a263e7a140b53c54ad3162e75f Mon Sep 17 00:00:00 2001 From: Nick Lionis Date: Mon, 16 Dec 2024 20:44:46 +0200 Subject: [PATCH] fix: make manager safe app compatible (#3737) * fix: make manager safe app compatible * adds missing dependency to tests * add missing deps for tests --- packages/round-manager/package.json | 2 + .../round-manager/public/manager-logo.svg | 31 +++++ packages/round-manager/public/manifest.json | 36 ++++++ packages/round-manager/setUpProxy.js | 14 +++ packages/round-manager/src/app/wagmi.ts | 54 +++++++-- .../__tests__/ReadProgramContext.test.tsx | 3 +- .../__tests__/ReclaimFundsContext.test.tsx | 3 +- .../round/__tests__/RoundContext.test.tsx | 3 +- .../__tests__/UpdateRoundContext.test.tsx | 3 +- .../src/features/api/SafeAutoConnect.tsx | 29 +++++ .../src/features/api/__tests__/round.test.ts | 3 +- .../common/__tests__/ErrorModal.test.tsx | 2 +- .../__tests__/CreateProgramPage.test.tsx | 2 +- .../__tests__/ListProgramPage.test.tsx | 3 +- .../__tests__/ViewProgramPage.test.tsx | 2 +- .../features/round/ViewApplicationPage.tsx | 11 +- .../ApplicationsToApproveReject.test.tsx | 3 +- .../__tests__/ApplicationsToReview.test.tsx | 3 +- .../round/__tests__/CreateRoundPage.test.tsx | 7 +- .../round/__tests__/FundContract.test.tsx | 6 +- .../__tests__/QuadraticFundingForm.test.tsx | 3 +- .../round/__tests__/ReclaimFunds.test.tsx | 2 +- .../__tests__/RoundApplicationForm.test.tsx | 10 +- .../round/__tests__/RoundDetailForm.test.tsx | 3 +- .../__tests__/ViewApplicationPage.test.tsx | 2 +- .../round/__tests__/ViewFundGrantees.test.tsx | 3 +- .../round/__tests__/ViewRoundPage.test.tsx | 2 +- .../round/__tests__/ViewRoundResults.test.tsx | 2 +- .../__tests__/ViewRoundSettings.test.tsx | 2 +- packages/round-manager/src/index.tsx | 112 +++++++++--------- pnpm-lock.yaml | 47 ++++++++ 31 files changed, 303 insertions(+), 105 deletions(-) create mode 100644 packages/round-manager/public/manager-logo.svg create mode 100644 packages/round-manager/public/manifest.json create mode 100644 packages/round-manager/setUpProxy.js create mode 100644 packages/round-manager/src/features/api/SafeAutoConnect.tsx diff --git a/packages/round-manager/package.json b/packages/round-manager/package.json index 58168e6b4..447aeb134 100644 --- a/packages/round-manager/package.json +++ b/packages/round-manager/package.json @@ -38,6 +38,8 @@ "@openzeppelin/merkle-tree": "^1.0.2", "@rainbow-me/rainbowkit": "2.1.2", "@reduxjs/toolkit": "^1.8.1", + "@safe-global/safe-apps-provider": "^0.18.5", + "@safe-global/safe-apps-react-sdk": "^4.7.2", "@sentry/integrations": "^7.28.0", "@sentry/react": "^7.27.0", "@sentry/tracing": "^7.26.0", diff --git a/packages/round-manager/public/manager-logo.svg b/packages/round-manager/public/manager-logo.svg new file mode 100644 index 000000000..4d8c9aa66 --- /dev/null +++ b/packages/round-manager/public/manager-logo.svg @@ -0,0 +1,31 @@ + + + + + + diff --git a/packages/round-manager/public/manifest.json b/packages/round-manager/public/manifest.json new file mode 100644 index 000000000..e346590ea --- /dev/null +++ b/packages/round-manager/public/manifest.json @@ -0,0 +1,36 @@ +{ + "short_name": "Manager", + "name": "Gitcoin Safe App Manager", + "description": "Gitcoin Safe App Manager", + "icons": [ + { + "src": "manager-logo.svg", + "sizes": "any", + "type": "image/svg+xml" + }, + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#FFFFFF", + "background_color": "#FFFFFF" + } \ No newline at end of file diff --git a/packages/round-manager/setUpProxy.js b/packages/round-manager/setUpProxy.js new file mode 100644 index 000000000..3437cc0b8 --- /dev/null +++ b/packages/round-manager/setUpProxy.js @@ -0,0 +1,14 @@ +// App is an express application, we can add an express middleware that will set headers for manifest.json request +// https://create-react-app.dev/docs/proxying-api-requests-in-development/#configuring-the-proxy-manually + +module.exports = function (app) { + app.use("/manifest.json", function (req, res, next) { + res.set({ + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "GET", + "Access-Control-Allow-Headers": + "X-Requested-With, content-type, Authorization", + }); + next(); + }); +}; diff --git a/packages/round-manager/src/app/wagmi.ts b/packages/round-manager/src/app/wagmi.ts index 59d53f1b1..be0c9b677 100644 --- a/packages/round-manager/src/app/wagmi.ts +++ b/packages/round-manager/src/app/wagmi.ts @@ -1,26 +1,58 @@ import "@rainbow-me/rainbowkit/styles.css"; import { QueryClient } from "@tanstack/react-query"; -import { Chain as RChain, getDefaultConfig } from "@rainbow-me/rainbowkit"; import { allNetworks, mainnetNetworks } from "common/src/chains"; import { getClient, getConnectorClient } from "@wagmi/core"; import { providers } from "ethers"; -import { type Account, type Chain, type Client, type Transport } from "viem"; +import { + http, + type Account, + type Chain, + type Client, + type Transport, +} from "viem"; import { Connector } from "wagmi"; - -export const allChains: RChain[] = - process.env.REACT_APP_ENV === "development" ? allNetworks : mainnetNetworks; +import { + rainbowWallet, + safeWallet, + walletConnectWallet, + coinbaseWallet, +} from "@rainbow-me/rainbowkit/wallets"; +import { connectorsForWallets } from "@rainbow-me/rainbowkit"; /* TODO: remove hardcoded value once we have environment variables validation */ const projectId = process.env.REACT_APP_WALLETCONNECT_PROJECT_ID ?? "2685061cae0bcaf2b244446153eda9e1"; +const connectors = connectorsForWallets( + [ + { + groupName: "Popular", + wallets: [safeWallet, rainbowWallet, walletConnectWallet, coinbaseWallet], + }, + ], + { + appName: "Gitcoin Manager", + projectId, + } +); +export const allChains: Chain[] = + process.env.REACT_APP_ENV === "development" ? allNetworks : mainnetNetworks; + +import { createConfig } from "wagmi"; + +const transports = allChains.reduce( + (acc, chain) => { + acc[chain.id] = http(); + return acc; + }, + {} as Record> +); -export const config = getDefaultConfig({ - appName: "Gitcoin Manager", - projectId, - chains: [...allChains] as [Chain, ...Chain[]], - // eslint-disable-next-line @typescript-eslint/no-explicit-any -}) as any; +export const config = createConfig({ + chains: [...allChains] as unknown as readonly [Chain, ...Chain[]], + connectors, + transports, +}); const queryClient = new QueryClient(); diff --git a/packages/round-manager/src/context/program/__tests__/ReadProgramContext.test.tsx b/packages/round-manager/src/context/program/__tests__/ReadProgramContext.test.tsx index 970b7c06a..14456fba8 100644 --- a/packages/round-manager/src/context/program/__tests__/ReadProgramContext.test.tsx +++ b/packages/round-manager/src/context/program/__tests__/ReadProgramContext.test.tsx @@ -26,10 +26,11 @@ jest.mock("wagmi", () => ({ chainId: 1, address: "0x0", }), + createConfig: jest.fn(), })); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("data-layer", () => ({ ...jest.requireActual("data-layer"), diff --git a/packages/round-manager/src/context/round/__tests__/ReclaimFundsContext.test.tsx b/packages/round-manager/src/context/round/__tests__/ReclaimFundsContext.test.tsx index fc1283d70..470baf4ab 100644 --- a/packages/round-manager/src/context/round/__tests__/ReclaimFundsContext.test.tsx +++ b/packages/round-manager/src/context/round/__tests__/ReclaimFundsContext.test.tsx @@ -12,6 +12,7 @@ jest.mock("wagmi", () => ({ useAccount: () => ({ chainId: 1, }), + createConfig: jest.fn(), })); jest.mock("../../../features/api/payoutStrategy/payoutStrategy"); @@ -23,7 +24,6 @@ jest.mock("viem", () => ({ jest.mock("common", () => ({ ...jest.requireActual("common"), useAllo: jest.fn(), - })); const alloBackend = new AlloV1({ @@ -37,7 +37,6 @@ const alloBackend = new AlloV1({ transactionSender: createMockTransactionSender(), }); - const testParams: ReclaimFundsParams = { allo: alloBackend, payoutStrategy: "0x0000000000000000000000000000000000000001", diff --git a/packages/round-manager/src/context/round/__tests__/RoundContext.test.tsx b/packages/round-manager/src/context/round/__tests__/RoundContext.test.tsx index 3bdc36161..82d30f91c 100644 --- a/packages/round-manager/src/context/round/__tests__/RoundContext.test.tsx +++ b/packages/round-manager/src/context/round/__tests__/RoundContext.test.tsx @@ -12,10 +12,11 @@ jest.mock("wagmi", () => ({ useAccount: () => ({ chainId: 1, }), + createConfig: jest.fn(), })); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("../../../features/common/Auth", () => ({ useWallet: () => mockWallet, diff --git a/packages/round-manager/src/context/round/__tests__/UpdateRoundContext.test.tsx b/packages/round-manager/src/context/round/__tests__/UpdateRoundContext.test.tsx index 79900d22e..85f31e3a1 100644 --- a/packages/round-manager/src/context/round/__tests__/UpdateRoundContext.test.tsx +++ b/packages/round-manager/src/context/round/__tests__/UpdateRoundContext.test.tsx @@ -31,10 +31,11 @@ jest.mock("wagmi", () => ({ useAccount: () => ({ chainId: 1, }), + createConfig: jest.fn(), })); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("../../../features/api/round"); diff --git a/packages/round-manager/src/features/api/SafeAutoConnect.tsx b/packages/round-manager/src/features/api/SafeAutoConnect.tsx new file mode 100644 index 000000000..06d699412 --- /dev/null +++ b/packages/round-manager/src/features/api/SafeAutoConnect.tsx @@ -0,0 +1,29 @@ +import { useEffect } from "react"; + +import { useConnect, useAccount } from "wagmi"; + +const AUTOCONNECTED_CONNECTOR_IDS = ["safe"]; + +function useAutoConnect() { + const { connect, connectors } = useConnect(); + const { address } = useAccount(); + + useEffect(() => { + AUTOCONNECTED_CONNECTOR_IDS.forEach((connector) => { + const connectorInstance = connectors.find((c) => c.id === connector); + const isIframe = window.top !== window.self; + if (connectorInstance && isIframe) { + connect({ connector: connectorInstance }); + } + }); + }, [connect, connectors, address]); +} + +export const SafeAutoConnect = ({ + children, +}: { + children: JSX.Element | JSX.Element[]; +}) => { + useAutoConnect(); + return <>{children}; +}; diff --git a/packages/round-manager/src/features/api/__tests__/round.test.ts b/packages/round-manager/src/features/api/__tests__/round.test.ts index bf3bf1a59..14112f502 100644 --- a/packages/round-manager/src/features/api/__tests__/round.test.ts +++ b/packages/round-manager/src/features/api/__tests__/round.test.ts @@ -20,10 +20,11 @@ jest.mock("wagmi", () => ({ useAccount: () => ({ chainId: 1, }), + createConfig: jest.fn(), })); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); describe("TransactionBuilder", () => { diff --git a/packages/round-manager/src/features/common/__tests__/ErrorModal.test.tsx b/packages/round-manager/src/features/common/__tests__/ErrorModal.test.tsx index c7b985305..43ebf3f9c 100644 --- a/packages/round-manager/src/features/common/__tests__/ErrorModal.test.tsx +++ b/packages/round-manager/src/features/common/__tests__/ErrorModal.test.tsx @@ -5,7 +5,7 @@ import ErrorModal from "../../common/ErrorModal"; jest.mock("../../common/Auth"); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); describe("", () => { diff --git a/packages/round-manager/src/features/program/__tests__/CreateProgramPage.test.tsx b/packages/round-manager/src/features/program/__tests__/CreateProgramPage.test.tsx index 8d05c48ef..4618723b6 100644 --- a/packages/round-manager/src/features/program/__tests__/CreateProgramPage.test.tsx +++ b/packages/round-manager/src/features/program/__tests__/CreateProgramPage.test.tsx @@ -18,7 +18,7 @@ jest.mock("../../api/ipfs"); jest.mock("../../common/Auth"); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("../../../constants", () => ({ diff --git a/packages/round-manager/src/features/program/__tests__/ListProgramPage.test.tsx b/packages/round-manager/src/features/program/__tests__/ListProgramPage.test.tsx index 22e89ecc9..d92a471ce 100644 --- a/packages/round-manager/src/features/program/__tests__/ListProgramPage.test.tsx +++ b/packages/round-manager/src/features/program/__tests__/ListProgramPage.test.tsx @@ -14,10 +14,11 @@ jest.mock("wagmi", () => ({ useAccount: () => ({ chainId: 1, }), + createConfig: jest.fn(), })); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("data-layer", () => ({ ...jest.requireActual("data-layer"), diff --git a/packages/round-manager/src/features/program/__tests__/ViewProgramPage.test.tsx b/packages/round-manager/src/features/program/__tests__/ViewProgramPage.test.tsx index e5ccd5a2d..4c8a7905d 100644 --- a/packages/round-manager/src/features/program/__tests__/ViewProgramPage.test.tsx +++ b/packages/round-manager/src/features/program/__tests__/ViewProgramPage.test.tsx @@ -23,7 +23,7 @@ jest.mock("../../common/Auth"); jest.mock("../../api/program"); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("react-router-dom", () => ({ ...jest.requireActual("react-router-dom"), diff --git a/packages/round-manager/src/features/round/ViewApplicationPage.tsx b/packages/round-manager/src/features/round/ViewApplicationPage.tsx index b3efe50a9..df3a5982d 100644 --- a/packages/round-manager/src/features/round/ViewApplicationPage.tsx +++ b/packages/round-manager/src/features/round/ViewApplicationPage.tsx @@ -170,7 +170,7 @@ export default function ViewApplicationPage() { }; if (roundChainId) fetchApplications(); - }, [roundChainId, roundId]); + }, [roundChainId, roundId, id, dataLayer]); useEffect(() => { if (contractUpdatingStatus === ProgressStatus.IS_ERROR) { @@ -334,7 +334,10 @@ export default function ViewApplicationPage() { if (application?.answers && application.answers.length > 0) { for (let _answerBlock of application.answers) { - if (_answerBlock.encryptedAnswer && !isLitUnavailable(round.chainId!)) { + if ( + _answerBlock.encryptedAnswer && + !isLitUnavailable(round.chainId!) + ) { try { const encryptedAnswer = _answerBlock.encryptedAnswer; const base64EncryptedString = [ @@ -349,7 +352,7 @@ export default function ViewApplicationPage() { chainId: Number(roundChainId!), contract: roundId.startsWith("0x") ? roundId - : round?.payoutStrategy.id ?? "", + : (round?.payoutStrategy.id ?? ""), }); const decryptedString = await lit.decryptString( @@ -816,7 +819,7 @@ export default function ViewApplicationPage() { answerBlocks?.map((block: AnswerBlock) => { const answerText = Array.isArray(block.answer) ? block.answer.join(", ") - : block.answer ?? ""; + : (block.answer ?? ""); return (
diff --git a/packages/round-manager/src/features/round/__tests__/ApplicationsToApproveReject.test.tsx b/packages/round-manager/src/features/round/__tests__/ApplicationsToApproveReject.test.tsx index a2ab2cdab..7a8cf3969 100644 --- a/packages/round-manager/src/features/round/__tests__/ApplicationsToApproveReject.test.tsx +++ b/packages/round-manager/src/features/round/__tests__/ApplicationsToApproveReject.test.tsx @@ -29,10 +29,11 @@ jest.mock("wagmi", () => ({ useAccount: () => ({ chainId: 1, }), + createConfig: jest.fn(), })); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("../../api/application"); jest.mock("../../common/Auth", () => ({ diff --git a/packages/round-manager/src/features/round/__tests__/ApplicationsToReview.test.tsx b/packages/round-manager/src/features/round/__tests__/ApplicationsToReview.test.tsx index 36508e5fb..878a5b6dd 100644 --- a/packages/round-manager/src/features/round/__tests__/ApplicationsToReview.test.tsx +++ b/packages/round-manager/src/features/round/__tests__/ApplicationsToReview.test.tsx @@ -30,11 +30,12 @@ jest.mock("wagmi", () => ({ useAccount: () => ({ chainId: 1, }), + createConfig: jest.fn(), })); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("common/src/allo/backends/allo-v1"); diff --git a/packages/round-manager/src/features/round/__tests__/CreateRoundPage.test.tsx b/packages/round-manager/src/features/round/__tests__/CreateRoundPage.test.tsx index 6b6a8dd51..211fb517c 100644 --- a/packages/round-manager/src/features/round/__tests__/CreateRoundPage.test.tsx +++ b/packages/round-manager/src/features/round/__tests__/CreateRoundPage.test.tsx @@ -12,10 +12,11 @@ jest.mock("wagmi", () => ({ useAccount: () => ({ chainId: 1, }), + createConfig: jest.fn(), })); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("../../common/Navbar"); jest.mock("../../common/Auth"); @@ -33,9 +34,7 @@ jest.mock("react-router-dom", () => ({ })); describe("", () => { - beforeEach(() => { - - }); + beforeEach(() => {}); it("sends program to form wizard", () => { const programs = [makeProgramData({ id: programId })]; diff --git a/packages/round-manager/src/features/round/__tests__/FundContract.test.tsx b/packages/round-manager/src/features/round/__tests__/FundContract.test.tsx index 910faf94d..b85851a19 100644 --- a/packages/round-manager/src/features/round/__tests__/FundContract.test.tsx +++ b/packages/round-manager/src/features/round/__tests__/FundContract.test.tsx @@ -37,7 +37,7 @@ jest.mock("../../../app/wagmi", () => ({ })); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("react-router-dom", () => ({ @@ -105,18 +105,14 @@ describe("fund contract tabr", () => { // ) // ) // ); - // const fundContractTab = screen.getByTestId("fund-contract"); // fireEvent.click(fundContractTab); - // expect(screen.getByText("Details")).toBeInTheDocument(); - // if (process.env.REACT_APP_ALLO_VERSION === "allo-v1") { // expect(screen.getByText("Contract Address:")).toBeInTheDocument(); // expect(screen.getByTestId("fund-contract-btn")).toBeInTheDocument(); // expect(screen.getByTestId("view-contract-btn")).toBeInTheDocument(); // } - // expect(screen.getByText("Payout token:")).toBeInTheDocument(); // expect(screen.getByText("Matching pool size:")).toBeInTheDocument(); // expect(screen.getByText("Protocol fee:")).toBeInTheDocument(); diff --git a/packages/round-manager/src/features/round/__tests__/QuadraticFundingForm.test.tsx b/packages/round-manager/src/features/round/__tests__/QuadraticFundingForm.test.tsx index 427649a95..0c377c920 100644 --- a/packages/round-manager/src/features/round/__tests__/QuadraticFundingForm.test.tsx +++ b/packages/round-manager/src/features/round/__tests__/QuadraticFundingForm.test.tsx @@ -9,12 +9,13 @@ import QuadraticFundingForm from "../QuadraticFundingForm"; jest.mock("../../common/Auth"); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("wagmi", () => ({ useAccount: () => ({ chainId: 10, }), + createConfig: jest.fn(), })); jest.mock("../../../constants", () => ({ ...jest.requireActual("../../../constants"), diff --git a/packages/round-manager/src/features/round/__tests__/ReclaimFunds.test.tsx b/packages/round-manager/src/features/round/__tests__/ReclaimFunds.test.tsx index ba47112f8..059fe0ca0 100644 --- a/packages/round-manager/src/features/round/__tests__/ReclaimFunds.test.tsx +++ b/packages/round-manager/src/features/round/__tests__/ReclaimFunds.test.tsx @@ -32,7 +32,7 @@ jest.mock("../../common/Auth"); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("../../../app/wagmi", () => ({ diff --git a/packages/round-manager/src/features/round/__tests__/RoundApplicationForm.test.tsx b/packages/round-manager/src/features/round/__tests__/RoundApplicationForm.test.tsx index ed635e1fe..504959aa9 100644 --- a/packages/round-manager/src/features/round/__tests__/RoundApplicationForm.test.tsx +++ b/packages/round-manager/src/features/round/__tests__/RoundApplicationForm.test.tsx @@ -14,10 +14,7 @@ import { RoundCategory } from "data-layer"; import { errorModalDelayMs } from "../../../constants"; import { useCreateRoundStore } from "../../../stores/createRoundStore"; import { saveToIPFS } from "../../api/ipfs"; -import { - ApplicationMetadata, - ProgressStatus, -} from "../../api/types"; +import { ApplicationMetadata, ProgressStatus } from "../../api/types"; import { FormStepper } from "../../common/FormStepper"; import { FormContext } from "../../common/FormWizard"; import { @@ -31,7 +28,7 @@ jest.mock("../../common/Auth"); jest.mock("../../api/payoutStrategy/payoutStrategy"); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("wagmi", () => ({ useAccount: () => ({ @@ -48,6 +45,7 @@ jest.mock("wagmi", () => ({ ], }), useProvider: () => ({}), + createConfig: jest.fn(), })); jest.mock("../../../constants", () => ({ ...jest.requireActual("../../../constants"), @@ -193,7 +191,6 @@ describe("", () => { }); describe("Application Form Builder", () => { - it("displays the four default questions", () => { renderWithContext( { }); }); describe("Project Socials", () => { - it("displays the Project Socials", () => { renderWithContext( ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("../../../constants", () => ({ @@ -20,7 +20,6 @@ jest.mock("../../../constants", () => ({ errorModalDelayMs: 0, // NB: use smaller delay for faster tests })); - describe("", () => { it("renders round name input", async () => { renderWrapped(); diff --git a/packages/round-manager/src/features/round/__tests__/ViewApplicationPage.test.tsx b/packages/round-manager/src/features/round/__tests__/ViewApplicationPage.test.tsx index 55bc9da22..1428179bc 100644 --- a/packages/round-manager/src/features/round/__tests__/ViewApplicationPage.test.tsx +++ b/packages/round-manager/src/features/round/__tests__/ViewApplicationPage.test.tsx @@ -94,7 +94,7 @@ jest.mock("react-router-dom", () => ({ jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("../../common/useApplicationsByRoundId"); diff --git a/packages/round-manager/src/features/round/__tests__/ViewFundGrantees.test.tsx b/packages/round-manager/src/features/round/__tests__/ViewFundGrantees.test.tsx index 127ae5c3c..9cd2fdda7 100644 --- a/packages/round-manager/src/features/round/__tests__/ViewFundGrantees.test.tsx +++ b/packages/round-manager/src/features/round/__tests__/ViewFundGrantees.test.tsx @@ -28,11 +28,12 @@ jest.mock("wagmi", () => ({ useAccount: () => ({ chainId: 1, }), + createConfig: jest.fn(), })); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); Object.assign(navigator, { diff --git a/packages/round-manager/src/features/round/__tests__/ViewRoundPage.test.tsx b/packages/round-manager/src/features/round/__tests__/ViewRoundPage.test.tsx index 2613135a3..e5720b7c7 100644 --- a/packages/round-manager/src/features/round/__tests__/ViewRoundPage.test.tsx +++ b/packages/round-manager/src/features/round/__tests__/ViewRoundPage.test.tsx @@ -42,7 +42,7 @@ jest.mock("../../../app/wagmi", () => ({ jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("data-layer", () => ({ diff --git a/packages/round-manager/src/features/round/__tests__/ViewRoundResults.test.tsx b/packages/round-manager/src/features/round/__tests__/ViewRoundResults.test.tsx index ad31c727c..ad5c37d6a 100644 --- a/packages/round-manager/src/features/round/__tests__/ViewRoundResults.test.tsx +++ b/packages/round-manager/src/features/round/__tests__/ViewRoundResults.test.tsx @@ -26,7 +26,7 @@ jest.mock("../../api/round"); jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); const mockNetwork = { diff --git a/packages/round-manager/src/features/round/__tests__/ViewRoundSettings.test.tsx b/packages/round-manager/src/features/round/__tests__/ViewRoundSettings.test.tsx index 222f64a54..9fe83c466 100644 --- a/packages/round-manager/src/features/round/__tests__/ViewRoundSettings.test.tsx +++ b/packages/round-manager/src/features/round/__tests__/ViewRoundSettings.test.tsx @@ -44,7 +44,7 @@ jest.mock("../../../app/wagmi", () => ({ jest.mock("@rainbow-me/rainbowkit", () => ({ ConnectButton: jest.fn(), - getDefaultConfig: jest.fn(), + connectorsForWallets: jest.fn(), })); jest.mock("../../common/Auth", () => ({ diff --git a/packages/round-manager/src/index.tsx b/packages/round-manager/src/index.tsx index 7b12e1b20..1252fc064 100644 --- a/packages/round-manager/src/index.tsx +++ b/packages/round-manager/src/index.tsx @@ -35,6 +35,7 @@ import { UpdateRoundProvider } from "./context/round/UpdateRoundContext"; import { UpdateRolesProvider } from "./context/round/UpdateRolesContext"; import { UpdateRolesProvider as UpdateRolesProviderProgram } from "./context/program/UpdateRolesContext"; import AlloWrapper from "./features/api/AlloWrapper"; +import { SafeAutoConnect } from "./features/api/SafeAutoConnect"; import { DataLayer, DataLayerProvider } from "data-layer"; import { getConfig } from "common/src/config"; import { initPosthog } from "./posthog"; @@ -126,59 +127,64 @@ root.render( }, }} > - - - - - {/* Protected Routes */} - }> - {/* Default Route */} - - - {/* Round Routes */} - - - - } - /> - - - - - - {/* Program Routes */} - } - /> - - - - {/* Access Denied */} - } /> - - {/* 404 */} - } /> - - - - - + + + + + + {/* Protected Routes */} + }> + {/* Default Route */} + + + {/* Round Routes */} + + + + } + /> + + + + + + {/* Program Routes */} + } + /> + + + + {/* Access Denied */} + } + /> + + {/* 404 */} + } /> + + + + + + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3128a2b5b..436bbd00c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1030,6 +1030,12 @@ importers: '@reduxjs/toolkit': specifier: ^1.8.1 version: 1.9.7(react-redux@8.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react-native@0.76.1(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(@types/react@18.3.12)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(redux@4.2.1))(react@18.3.1) + '@safe-global/safe-apps-provider': + specifier: ^0.18.5 + version: 0.18.5(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) + '@safe-global/safe-apps-react-sdk': + specifier: ^4.7.2 + version: 4.7.2(bufferutil@4.0.8)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) '@sentry/integrations': specifier: ^7.28.0 version: 7.114.0 @@ -4757,6 +4763,14 @@ packages: '@safe-global/safe-apps-provider@0.18.1': resolution: {integrity: sha512-V4a05A3EgJcriqtDoJklDz1BOinWhC6P0hjUSxshA4KOZM7rGPCTto/usXs09zr1vvL28evl/NldSTv97j2bmg==} + '@safe-global/safe-apps-provider@0.18.5': + resolution: {integrity: sha512-9v9wjBi3TwLsEJ3C2ujYoexp3pFJ0omDLH/GX91e2QB+uwCKTBYyhxFSrTQ9qzoyQd+bfsk4gjOGW87QcJhf7g==} + + '@safe-global/safe-apps-react-sdk@4.7.2': + resolution: {integrity: sha512-du7Bp3yPT2nQ8HhbfiyGit/ItcYwZ1tLEG5fbajMe8tjgr2D2YQMgNcNFmBpgHFyq+FpoA4a+toEKMEifQCMPg==} + peerDependencies: + react: 16.x.x || 17.x.x || 18.x.x + '@safe-global/safe-apps-sdk@7.11.0': resolution: {integrity: sha512-RDamzPM1Lhhiiz0O+Dn6FkFqIh47jmZX+HCV/BBnBBOSKfBJE//IGD3+02zMgojXHTikQAburdPes9qmH1SA1A==} @@ -4766,6 +4780,9 @@ packages: '@safe-global/safe-apps-sdk@8.1.0': resolution: {integrity: sha512-XJbEPuaVc7b9n23MqlF6c+ToYIS3f7P2Sel8f3cSBQ9WORE4xrSuvhMpK9fDSFqJ7by/brc+rmJR/5HViRr0/w==} + '@safe-global/safe-apps-sdk@9.1.0': + resolution: {integrity: sha512-N5p/ulfnnA2Pi2M3YeWjULeWbjo7ei22JwU/IXnhoHzKq3pYCN6ynL9mJBOlvDVv892EgLPCWCOwQk/uBT2v0Q==} + '@safe-global/safe-gateway-typescript-sdk@3.22.2': resolution: {integrity: sha512-Y0yAxRaB98LFp2Dm+ACZqBSdAmI3FlpH/LjxOZ94g/ouuDJecSq0iR26XZ5QDuEL8Rf+L4jBJaoDC08CD0KkJw==} engines: {node: '>=16'} @@ -21655,6 +21672,26 @@ snapshots: - utf-8-validate - zod + '@safe-global/safe-apps-provider@0.18.5(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8)': + dependencies: + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) + events: 3.3.0 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-apps-react-sdk@4.7.2(bufferutil@4.0.8)(react@18.3.1)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8)': + dependencies: + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) + react: 18.3.1 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + '@safe-global/safe-apps-sdk@7.11.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.22.2 @@ -21681,6 +21718,16 @@ snapshots: - utf-8-validate - zod + '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8)': + dependencies: + '@safe-global/safe-gateway-typescript-sdk': 3.22.2 + viem: 2.13.10(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + '@safe-global/safe-gateway-typescript-sdk@3.22.2': {} '@scure/base@1.1.9': {}