Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement/1483 chainspacing #1496

Merged
merged 17 commits into from
Mar 29, 2024
Merged

Enhancement/1483 chainspacing #1496

merged 17 commits into from
Mar 29, 2024

Conversation

adamgall
Copy link
Member

@adamgall adamgall commented Mar 27, 2024

Closes #1483
Closes #1336

This PR implements chainspacing in the URL.

All URLs that exist in the context of a Safe have a network ID (same ones that the Safe UI uses) prefixed to the address.

Additionally, error page logic has been separated to clearly identify the two scenarios that might occur for a Safe being unable to be loaded:

  • The given address simply isn't a Safe on the expected (as per the network prefix) Safe.
  • The app is connected to a different network than what the Safe is expecting (as per the network prefix).

Additionally, stronger typing has been enforced in the many places were navigation links exist. This stronger typing required early-exiting rendering attempts where either the network prefix or address are not available yet (e.g. as a Safe is loading), so special review and testing should be taken to ensure that the logical changes around rendering links was implemented correctly.

Testing

Functional changes in this PR include:

  • Safes will only load if they include a network prefix in the new query param-based address.
  • automatically applying a network prefix to the address in the new query param-based url only when redirecting from the old path-based URL.
  • fixing all internal links and navigation in the app to apply and utilize the new query param-based safe addresses.
  • splitting the "can't load Safe" error screen into three distinct messages
    • for when there is a problem with the format of the address query param
    • for when the app is connected to a different network than the network prefix in the address query param
    • for when the syntax and network are all good, but the Safe can't load because of actual loading issues, like the Safe API is down or the address just isn't an actual Safe.

@adamgall adamgall linked an issue Mar 27, 2024 that may be closed by this pull request
@adamgall adamgall self-assigned this Mar 27, 2024
@adamgall adamgall force-pushed the enhancement/1483-chainspacing branch 2 times, most recently from 307c8c7 to 789573e Compare March 27, 2024 03:36
@adamgall adamgall linked an issue Mar 27, 2024 that may be closed by this pull request
Copy link
Member Author

@adamgall adamgall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a handful of comments on some implementation details. Would love more eyes and brains on this.

src/constants/routes.ts Outdated Show resolved Hide resolved
src/main.tsx Show resolved Hide resolved
src/pages/DAOController.tsx Outdated Show resolved Hide resolved
src/pages/daos/[daoAddress]/edit/governance/index.tsx Outdated Show resolved Hide resolved
src/pages/daos/[daoAddress]/hierarchy/index.tsx Outdated Show resolved Hide resolved
Comment on lines +78 to +83
onClick={() => {
onClickView();
if (closeDrawer) closeDrawer();
action.resetDAO();
navigate(DAO_ROUTES.dao.relative(addressPrefix, address));
}}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not super related to this PR, but I snuck this change in here anyway. Basically, made it so that only the button in the search result list is clickable, not the whole element.

src/components/pages/DaoDashboard/Info/index.tsx Outdated Show resolved Hide resolved
src/components/pages/DaoDashboard/Info/index.tsx Outdated Show resolved Hide resolved
src/components/Proposals/ProposalCard/ProposalCard.tsx Outdated Show resolved Hide resolved
@tomstuart123 tomstuart123 self-requested a review March 27, 2024 13:19
Base automatically changed from enhancement/1492-dao-identifier-query-param to develop March 27, 2024 13:42
Copy link

netlify bot commented Mar 27, 2024

Deploy Preview for fractal-dev ready!

Name Link
🔨 Latest commit 9396909
🔍 Latest deploy log https://app.netlify.com/sites/fractal-dev/deploys/660723ff93476f00087479e9
😎 Deploy Preview https://deploy-preview-1496.app.dev.fractalframework.xyz
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@adamgall adamgall marked this pull request as ready for review March 27, 2024 13:43
Copy link
Contributor

@Da-Colon Da-Colon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Answer to your big question and one requested change in ManageDAOMenu

src/components/pages/DaoDashboard/Info/index.tsx Outdated Show resolved Hide resolved
@@ -45,6 +47,7 @@ export function FavoritesList() {
{favoritesList.map(favorite => (
<Favorite
key={favorite}
network={addressPrefix}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've talked before about revisiting LocalStorage setup. Should a card be made to start noting this?

src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx Outdated Show resolved Hide resolved
src/constants/routes.ts Outdated Show resolved Hide resolved
src/hooks/DAO/proposal/useSubmitProposal.ts Show resolved Hide resolved
src/hooks/DAO/useDAOController.ts Outdated Show resolved Hide resolved
src/main.tsx Show resolved Hide resolved
src/types/fractal.ts Outdated Show resolved Hide resolved
@adamgall adamgall force-pushed the enhancement/1483-chainspacing branch from acb4008 to b02998b Compare March 28, 2024 23:07
Copy link
Member Author

@adamgall adamgall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a couple new comments as per my most recent pushed work.

In general, the majority of my new updates tackle:

  1. Fixing the unintentional bug I introduced in ManageDAOMenu (thanks @Da-Colon for finding that)
  2. removing daoNetwork from Fractal state, and just using the value from useNetworkConfig instead, throughout the app.

src/hooks/DAO/loaders/useFractalNode.ts Outdated Show resolved Hide resolved
src/hooks/DAO/loaders/useFractalNode.ts Outdated Show resolved Hide resolved
src/hooks/DAO/useDAOController.ts Outdated Show resolved Hide resolved
@adamgall adamgall force-pushed the enhancement/1483-chainspacing branch 2 times, most recently from 4be13e7 to 86a01a9 Compare March 29, 2024 02:21
@adamgall adamgall force-pushed the enhancement/1483-chainspacing branch from 86a01a9 to 5525e40 Compare March 29, 2024 02:24
src/i18n/locales/en/common.json Outdated Show resolved Hide resolved
Comment on lines -11 to -33
function InvalidSafe() {
const { name } = useNetworkConfig();
const { t } = useTranslation('common');

return (
<Center
padding="3rem"
textColor="grayscale.100"
>
<VStack>
<Text
paddingTop="3rem"
textStyle="text-6xl-mono-regular"
>
{t('errorSentryFallbackTitle')}
</Text>
<Text>{t('invalidSafe1', { chain: name })}</Text>
<Text paddingBottom="1rem">{t('invalidSafe2')}</Text>
<Button onClick={() => window.location.reload()}>{t('refresh')}</Button>
</VStack>
</Center>
);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pulled into own File and made generic so we can throw any of the three error types at it


export default function DAOController() {
const { node } = useFractal();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need this

@@ -59,7 +32,6 @@ export default function DAOController() {
return theme;
}, [daoMetadata]);

const validSafe = node.safe;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need this, we simply assume the address is a valid safe until it's not.

Comment on lines +150 to 152
if (addressPrefix + daoAddress !== currentValidSafe.current) {
setDAO(addressPrefix, daoAddress);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And now, if we got here, we only want to call setDAO if we haven't done so yet for the given address

Comment on lines +101 to +105
"invalidSafe2": "Please double check the address then try again.",
"wrongNetwork1": "Fractal is currently connected to {{chain}}.",
"wrongNetwork2": "Try switching the app to the correct chain for your Safe.",
"badQueryParam1": "The Safe address in the URL isn't formatted correctly",
"badQueryParam2": "",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better error strings for the various kinds of initial loading issues that might occur

Comment on lines +100 to +130

let safeInfo;

try {
if (!safeAPI) throw new Error('SafeAPI not set');

safeInfo = await requestWithRetries(
() => safeAPI.getSafeInfo(utils.getAddress(_daoAddress)),
5,
);
} catch (e) {
reset({ error: true });
return;
}
setNodeLoading(false);

if (!safeInfo) {
reset({ error: true });
return;
}

// if here, we have a valid Safe!

action.dispatch({
type: NodeAction.SET_FRACTAL_MODULES,
payload: await lookupModules(safeInfo.modules),
});

action.dispatch({
type: NodeAction.SET_SAFE_INFO,
payload: safeInfo,
});
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was mostly just a flattening of logic and moving all non-get-data stuff out of this file and back into useDAOController. This useFractalNode hook is now only used for fetching stuff, no more checking if input data is valid, if it's in here (and not undefined) we should use it to go start fetching.

Comment on lines +136 to +138
if (skip || addressPrefix === undefined || daoAddress === undefined) {
reset({ error: false });
return;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If skip is true, that means there was an error with the address or formatting or we're on the wrong network. If addressPrefix of daoAddress is undefined, then damn the App is still standing up. In either case, just reset state and GTFO.

Comment on lines +16 to +31
const addressWithPrefix = searchParams.get('dao');
const validDaoQueryString = /^[^\s:]+:[^\s:]+$/;

const prefixAndAddress = addressWithPrefix?.split(':');
const addressPrefix = prefixAndAddress?.[0];
const daoAddress = prefixAndAddress?.[1];

const invalidQuery =
addressWithPrefix === null ||
!validDaoQueryString.test(addressWithPrefix) ||
!utils.isAddress(daoAddress || '');

const { addressPrefix: connectedAddressPrefix } = useNetworkConfig();
const wrongNetwork = addressPrefix !== connectedAddressPrefix;

const skip = invalidQuery || wrongNetwork;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fun. Do all the things needed to validate that:

  1. we have a query string of the correct key
    • dao
  2. the value of that key is formatted correctly
    • string-without-whitespace followed by ":" followed by string-without-whitespace
  3. the ethereum address portion is formatted correctly
    • right length, checksum is valid if exists, etc
  4. the network identified in the query param matches the network the app is currently on
    • so if the user is trying to load a sep:0xabc dao, the app must be on Sepolia

If any of those things fail, we don't try to load anything and show the appropriate error screen.

@adamgall
Copy link
Member Author

adamgall commented Mar 29, 2024

@Da-Colon @mudrila @tomstuart123 I have just pushed a bunch of fixes and nice QoL improvements, this is ready for review again.

@Da-Colon i've addressed all of your comments and done more testing, things seem smooth as butter

@tomstuart123
Copy link

Tried the new netlify link with 4 prior DAOs.

TLDR

  • All mainnet prior DAO links worked when on the right chain already and were reformated correctly
  • All sepolia prior dao links didn't work when on the right chain already and were given this
Screenshot 2024-03-29 at 13 08 53 - When on sepolia (different chain), all mainnet prior DAO links saw the below message which I believe is the intended error message Screenshot 2024-03-29 at 13 11 07

Mainnet DAO links tried

  1. Decent multisig (mainnet) - https://app.dev.fractalframework.xyz/daos/0xD26c85D435F02DaB8B220cd4D2d398f6f646e235
  2. Decent's tokenvoting (mainnet) - https://app.dev.fractalframework.xyz/daos/0xB98d45F9021D71E6Fc30b43FD37FB3b1Bf12c064
  3. Shutter's token voting (mainnet)- https://app.dev.fractalframework.xyz/daos/0x36bD3044ab68f600f6d3e081056F34f2a58432c4
  4. AwakeVCs - https://app.dev.fractalframework.xyz/daos/0xdD6CeFA62239272f1eDf755ba6471eacb7DF2Fa5

Sepolia DAO links tried

  1. Myosin multisig - https://app.dev.fractalframework.xyz/home?dao=0xdef90A94273a1A1A72B33D39129fa41E6C08Be3a
  2. One of my sepolia test dao s- https://app.dev.fractalframework.xyz/home?dao=0xA287241240B5C8fce743Fb291D4F38cD669298d4

@adamgall
Copy link
Member Author

@tomstuart123 the Sepolia links you tried are indeed formatted incorrectly. Notice how they are the new query params, but don't include the network prefix. This is invalid as per this new PR.

@tomstuart123
Copy link

got ya. My bad for not double chekcing the new address. Forgot the new PR had gone to dev

Okay now retested with the links below

Sepolia
app.dev.fractalframework.xyz/daos/0xdef90A94273a1A1A72B33D39129fa41E6C08Be3a
app.dev.fractalframework.xyz/daos/0xA287241240B5C8fce743Fb291D4F38cD669298d4

All redirected well

I also managed to play with two of the error message

This appeared when being on ethereum using an old sepolia link
Screenshot 2024-03-29 at 13 31 48
This appeared when being on ethereum using a new sepolia link
Screenshot 2024-03-29 at 13 31 53

both should be working as intended so I'll give this an approve from me. Thanks @adamgall

Copy link
Contributor

@Da-Colon Da-Colon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good thanks for the changes!

@adamgall adamgall merged commit 785eff5 into develop Mar 29, 2024
7 checks passed
@adamgall adamgall deleted the enhancement/1483-chainspacing branch March 29, 2024 20:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Chainspacing the URL Oops! Couldn't find a Safe...
3 participants