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

fix: json rpc errors because of nonce out of sync #2833

Merged
merged 2 commits into from
May 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"react-virtuoso": "^4.3.5",
"remark-breaks": "^3.0.2",
"remark-linkify-regex": "^1.2.1",
"shared-zustand": "^2.0.0",
"snapshot": "workspace:*",
"strip-markdown": "^5.0.0",
"tlds": "^1.238.0",
Expand Down
2 changes: 0 additions & 2 deletions apps/web/src/components/Common/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ interface LayoutProps {
const Layout: FC<LayoutProps> = ({ children }) => {
const { resolvedTheme } = useTheme();
const setProfiles = useAppStore((state) => state.setProfiles);
const setUserSigNonce = useAppStore((state) => state.setUserSigNonce);
const currentProfile = useAppStore((state) => state.currentProfile);
const setCurrentProfile = useAppStore((state) => state.setCurrentProfile);
const profileId = useAppPersistStore((state) => state.profileId);
Expand Down Expand Up @@ -64,7 +63,6 @@ const Layout: FC<LayoutProps> = ({ children }) => {
setProfiles(profiles as Profile[]);
setCurrentProfile(selectedUser as Profile);
setProfileId(selectedUser?.id);
setUserSigNonce(data?.userSigNonces?.lensHubOnChainSigNonce);
},
onError: () => {
setProfileId(null);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useUserSigNoncesQuery } from 'lens';
import type { FC } from 'react';
import { isSupported, share } from 'shared-zustand';
import { useAppPersistStore } from 'src/store/app';
import { useNonceStore } from 'src/store/nonce';

const UserSigNoncesProvider: FC = () => {
const profileId = useAppPersistStore((state) => state.profileId);
const setUserSigNonce = useNonceStore((state) => state.setUserSigNonce);

if (isSupported()) {
share('userSigNonce', useNonceStore);
}

// Sync nonce every 10 seconds
useUserSigNoncesQuery({
skip: !profileId,
onCompleted: ({ userSigNonces }) => {
setUserSigNonce(userSigNonces.lensHubOnChainSigNonce);
},
pollInterval: 10000
});

return null;
};

export default UserSigNoncesProvider;
2 changes: 2 additions & 0 deletions apps/web/src/components/Common/Providers/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import Layout from '../Layout';
import FeatureFlagsProvider from './FeatureFlagsProvider';
import LanguageProvider from './LanguageProvider';
import TelemetryProvider from './TelemetryProvider';
import UserSigNoncesProvider from './UserSigNoncesProvider';

const { chains, provider } = configureChains(
[IS_MAINNET ? polygon : polygonMumbai, mainnet],
Expand Down Expand Up @@ -61,6 +62,7 @@ const Providers = ({ children }: { children: ReactNode }) => {
<TelemetryProvider />
<WagmiConfig client={wagmiClient}>
<ApolloProvider client={apolloClient}>
<UserSigNoncesProvider />
<QueryClientProvider client={queryClient}>
<LivepeerConfig client={livepeerClient} theme={getLivepeerTheme}>
<ThemeProvider defaultTheme="light" attribute="class">
Expand Down
12 changes: 8 additions & 4 deletions apps/web/src/components/Composer/NewPublication.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import { OptmisticPublicationType } from 'src/enums';
import { useAccessSettingsStore } from 'src/store/access-settings';
import { useAppStore } from 'src/store/app';
import { useCollectModuleStore } from 'src/store/collect-module';
import { useNonceStore } from 'src/store/nonce';
import { usePublicationStore } from 'src/store/publication';
import { useReferenceModuleStore } from 'src/store/reference-module';
import { useTransactionPersistStore } from 'src/store/transaction';
Expand Down Expand Up @@ -132,8 +133,8 @@ const NewPublication: FC<NewPublicationProps> = ({ publication }) => {
const { cache } = useApolloClient();

// App store
const userSigNonce = useAppStore((state) => state.userSigNonce);
const setUserSigNonce = useAppStore((state) => state.setUserSigNonce);
const userSigNonce = useNonceStore((state) => state.userSigNonce);
const setUserSigNonce = useNonceStore((state) => state.setUserSigNonce);
const currentProfile = useAppStore((state) => state.currentProfile);

// Publication store
Expand Down Expand Up @@ -311,12 +312,16 @@ const NewPublication: FC<NewPublicationProps> = ({ publication }) => {
mode: 'recklesslyUnprepared',
onSuccess: ({ hash }) => {
onCompleted();
setUserSigNonce(userSigNonce + 1);
setTxnQueue([
generateOptimisticPublication({ txHash: hash }),
...txnQueue
]);
},
onError
onError: (error) => {
onError(error);
setUserSigNonce(userSigNonce - 1);
}
});

const [broadcastDataAvailability] = useBroadcastDataAvailabilityMutation({
Expand Down Expand Up @@ -404,7 +409,6 @@ const NewPublication: FC<NewPublicationProps> = ({ publication }) => {
});
}

setUserSigNonce(userSigNonce + 1);
const { data } = await broadcast({
variables: { request: { id, signature } }
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import type { Dispatch, FC } from 'react';
import { useEffect, useState } from 'react';
import toast from 'react-hot-toast';
import { useAppStore } from 'src/store/app';
import { useNonceStore } from 'src/store/nonce';
import { PUBLICATION } from 'src/tracking';
import { Button, Modal, Spinner, Tooltip, WarningMessage } from 'ui';
import {
Expand All @@ -71,8 +72,8 @@ const CollectModule: FC<CollectModuleProps> = ({
publication,
electedMirror
}) => {
const userSigNonce = useAppStore((state) => state.userSigNonce);
const setUserSigNonce = useAppStore((state) => state.setUserSigNonce);
const userSigNonce = useNonceStore((state) => state.userSigNonce);
const setUserSigNonce = useNonceStore((state) => state.setUserSigNonce);
const currentProfile = useAppStore((state) => state.currentProfile);
const [isLoading, setIsLoading] = useState(false);
const [revenue, setRevenue] = useState(0);
Expand Down Expand Up @@ -144,8 +145,14 @@ const CollectModule: FC<CollectModuleProps> = ({
abi: LensHub,
functionName: 'collectWithSig',
mode: 'recklesslyUnprepared',
onSuccess: () => onCompleted(),
onError
onSuccess: () => {
onCompleted();
setUserSigNonce(userSigNonce + 1);
},
onError: (error) => {
onError(error);
setUserSigNonce(userSigNonce - 1);
}
});

const percentageCollected = (count / parseInt(collectLimit)) * 100;
Expand Down Expand Up @@ -232,7 +239,6 @@ const CollectModule: FC<CollectModuleProps> = ({
data: collectData,
sig
};
setUserSigNonce(userSigNonce + 1);
const { data } = await broadcast({
variables: { request: { id, signature } }
});
Expand Down
16 changes: 11 additions & 5 deletions apps/web/src/components/Publication/Actions/Mirror.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import type { FC } from 'react';
import { useState } from 'react';
import toast from 'react-hot-toast';
import { useAppStore } from 'src/store/app';
import { useNonceStore } from 'src/store/nonce';
import { PUBLICATION } from 'src/tracking';
import { Spinner, Tooltip } from 'ui';
import { useContractWrite, useSignTypedData } from 'wagmi';
Expand All @@ -38,8 +39,8 @@ interface MirrorProps {

const Mirror: FC<MirrorProps> = ({ publication, showCount }) => {
const isMirror = publication.__typename === 'Mirror';
const userSigNonce = useAppStore((state) => state.userSigNonce);
const setUserSigNonce = useAppStore((state) => state.setUserSigNonce);
const userSigNonce = useNonceStore((state) => state.userSigNonce);
const setUserSigNonce = useNonceStore((state) => state.setUserSigNonce);
const currentProfile = useAppStore((state) => state.currentProfile);
const [isLoading, setIsLoading] = useState(false);
const count = isMirror
Expand Down Expand Up @@ -102,8 +103,14 @@ const Mirror: FC<MirrorProps> = ({ publication, showCount }) => {
abi: LensHub,
functionName: 'mirrorWithSig',
mode: 'recklesslyUnprepared',
onSuccess: () => onCompleted(),
onError
onSuccess: () => {
onCompleted();
setUserSigNonce(userSigNonce + 1);
},
onError: (error) => {
onError(error);
setUserSigNonce(userSigNonce - 1);
}
});

const [broadcast] = useBroadcastMutation({
Expand Down Expand Up @@ -134,7 +141,6 @@ const Mirror: FC<MirrorProps> = ({ publication, showCount }) => {
referenceModuleInitData,
sig
};
setUserSigNonce(userSigNonce + 1);
const { data } = await broadcast({
variables: { request: { id, signature } }
});
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/components/Settings/Account/SetProfile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ import { useEffect, useState } from 'react';
import toast from 'react-hot-toast';
import Custom404 from 'src/pages/404';
import { useAppStore } from 'src/store/app';
import { useNonceStore } from 'src/store/nonce';
import { SETTINGS } from 'src/tracking';
import { Button, Card, ErrorMessage, Spinner } from 'ui';
import { useAccount, useContractWrite, useSignTypedData } from 'wagmi';

const SetProfile: FC = () => {
const profiles = useAppStore((state) => state.profiles);
const currentProfile = useAppStore((state) => state.currentProfile);
const userSigNonce = useAppStore((state) => state.userSigNonce);
const setUserSigNonce = useAppStore((state) => state.setUserSigNonce);
const userSigNonce = useNonceStore((state) => state.userSigNonce);
const setUserSigNonce = useNonceStore((state) => state.setUserSigNonce);
const [selectedUser, setSelectedUser] = useState('');
const [isLoading, setIsLoading] = useState(false);
const { address } = useAccount();
Expand Down
16 changes: 11 additions & 5 deletions apps/web/src/components/Settings/Account/SuperFollow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import type { FC } from 'react';
import { useState } from 'react';
import toast from 'react-hot-toast';
import { useAppStore } from 'src/store/app';
import { useNonceStore } from 'src/store/nonce';
import { SETTINGS } from 'src/tracking';
import { Button, Card, Form, Input, Spinner, useZodForm } from 'ui';
import { useContractWrite, useSignTypedData } from 'wagmi';
Expand All @@ -34,8 +35,8 @@ const newSuperFollowSchema = object({
});

const SuperFollow: FC = () => {
const userSigNonce = useAppStore((state) => state.userSigNonce);
const setUserSigNonce = useAppStore((state) => state.setUserSigNonce);
const userSigNonce = useNonceStore((state) => state.userSigNonce);
const setUserSigNonce = useNonceStore((state) => state.setUserSigNonce);
const currentProfile = useAppStore((state) => state.currentProfile);
const [isLoading, setIsLoading] = useState(false);
const [selectedCurrency, setSelectedCurrency] = useState(
Expand Down Expand Up @@ -75,8 +76,14 @@ const SuperFollow: FC = () => {
abi: LensHub,
functionName: 'setFollowModuleWithSig',
mode: 'recklesslyUnprepared',
onSuccess: () => onCompleted(),
onError
onSuccess: () => {
onCompleted();
setUserSigNonce(userSigNonce + 1);
},
onError: (error) => {
onError(error);
setUserSigNonce(userSigNonce - 1);
}
});

const form = useZodForm({
Expand Down Expand Up @@ -104,7 +111,6 @@ const SuperFollow: FC = () => {
followModuleInitData,
sig
};
setUserSigNonce(userSigNonce + 1);
const { data } = await broadcast({
variables: { request: { id, signature } }
});
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/components/Settings/Delete/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { useEffect, useState } from 'react';
import toast from 'react-hot-toast';
import Custom404 from 'src/pages/404';
import { useAppPersistStore, useAppStore } from 'src/store/app';
import { useNonceStore } from 'src/store/nonce';
import { PAGEVIEW } from 'src/tracking';
import {
Button,
Expand All @@ -33,8 +34,8 @@ import SettingsSidebar from '../Sidebar';

const DeleteSettings: FC = () => {
const [showWarningModal, setShowWarningModal] = useState(false);
const userSigNonce = useAppStore((state) => state.userSigNonce);
const setUserSigNonce = useAppStore((state) => state.setUserSigNonce);
const userSigNonce = useNonceStore((state) => state.userSigNonce);
const setUserSigNonce = useNonceStore((state) => state.setUserSigNonce);
const currentProfile = useAppStore((state) => state.currentProfile);
const setCurrentProfile = useAppStore((state) => state.setCurrentProfile);
const setProfileId = useAppPersistStore((state) => state.setProfileId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type { FC } from 'react';
import { useState } from 'react';
import toast from 'react-hot-toast';
import { useAppStore } from 'src/store/app';
import { useNonceStore } from 'src/store/nonce';
import { SETTINGS } from 'src/tracking';
import { Button, Spinner } from 'ui';
import { useContractWrite, useSignTypedData } from 'wagmi';
Expand All @@ -26,8 +27,8 @@ interface ToggleDispatcherProps {
}

const ToggleDispatcher: FC<ToggleDispatcherProps> = ({ buttonSize = 'md' }) => {
const userSigNonce = useAppStore((state) => state.userSigNonce);
const setUserSigNonce = useAppStore((state) => state.setUserSigNonce);
const userSigNonce = useNonceStore((state) => state.userSigNonce);
const setUserSigNonce = useNonceStore((state) => state.setUserSigNonce);
const currentProfile = useAppStore((state) => state.currentProfile);
const [isLoading, setIsLoading] = useState(false);
const canUseRelay = getIsDispatcherEnabled(currentProfile);
Expand Down Expand Up @@ -62,8 +63,14 @@ const ToggleDispatcher: FC<ToggleDispatcherProps> = ({ buttonSize = 'md' }) => {
abi: LensHub,
functionName: 'setDispatcherWithSig',
mode: 'recklesslyUnprepared',
onSuccess: () => onCompleted(),
onError
onSuccess: () => {
onCompleted();
setUserSigNonce(userSigNonce + 1);
},
onError: (error) => {
onError(error);
setUserSigNonce(userSigNonce - 1);
}
});

const [broadcast, { data: broadcastData }] = useBroadcastMutation({
Expand All @@ -82,7 +89,6 @@ const ToggleDispatcher: FC<ToggleDispatcherProps> = ({ buttonSize = 'md' }) => {
dispatcher,
sig
};
setUserSigNonce(userSigNonce + 1);
const { data } = await broadcast({
variables: { request: { id, signature } }
});
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/components/Settings/Profile/NftPicture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type { FC } from 'react';
import { useState } from 'react';
import toast from 'react-hot-toast';
import { useAppStore } from 'src/store/app';
import { useNonceStore } from 'src/store/nonce';
import { SETTINGS } from 'src/tracking';
import { Button, ErrorMessage, Form, Input, Spinner, useZodForm } from 'ui';
import { useContractWrite, useSignMessage, useSignTypedData } from 'wagmi';
Expand All @@ -35,8 +36,8 @@ interface NftPictureProps {
}

const NftPicture: FC<NftPictureProps> = ({ profile }) => {
const userSigNonce = useAppStore((state) => state.userSigNonce);
const setUserSigNonce = useAppStore((state) => state.setUserSigNonce);
const userSigNonce = useNonceStore((state) => state.userSigNonce);
const setUserSigNonce = useNonceStore((state) => state.setUserSigNonce);
const currentProfile = useAppStore((state) => state.currentProfile);
const [isLoading, setIsLoading] = useState(false);
const [chainId, setChainId] = useState<number>(
Expand Down
16 changes: 11 additions & 5 deletions apps/web/src/components/Settings/Profile/Picture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import type { ChangeEvent, FC } from 'react';
import { useState } from 'react';
import toast from 'react-hot-toast';
import { useAppStore } from 'src/store/app';
import { useNonceStore } from 'src/store/nonce';
import { SETTINGS } from 'src/tracking';
import { Button, ErrorMessage, Image, Modal, Spinner } from 'ui';
import { useContractWrite, useSignTypedData } from 'wagmi';
Expand All @@ -38,8 +39,8 @@ interface PictureProps {
}

const Picture: FC<PictureProps> = ({ profile }) => {
const userSigNonce = useAppStore((state) => state.userSigNonce);
const setUserSigNonce = useAppStore((state) => state.setUserSigNonce);
const userSigNonce = useNonceStore((state) => state.userSigNonce);
const setUserSigNonce = useNonceStore((state) => state.setUserSigNonce);
const currentProfile = useAppStore((state) => state.currentProfile);
const [avatarDataUrl, setAvatarDataUrl] = useState('');
const [isLoading, setIsLoading] = useState(false);
Expand Down Expand Up @@ -74,8 +75,14 @@ const Picture: FC<PictureProps> = ({ profile }) => {
abi: LensHub,
functionName: 'setProfileImageURIWithSig',
mode: 'recklesslyUnprepared',
onSuccess: () => onCompleted(),
onError
onSuccess: () => {
onCompleted();
setUserSigNonce(userSigNonce + 1);
},
onError: (error) => {
onError(error);
setUserSigNonce(userSigNonce - 1);
}
});

const [broadcast] = useBroadcastMutation({
Expand All @@ -94,7 +101,6 @@ const Picture: FC<PictureProps> = ({ profile }) => {
imageURI,
sig
};
setUserSigNonce(userSigNonce + 1);
const { data } = await broadcast({
variables: { request: { id, signature } }
});
Expand Down
Loading