Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
zerts committed Jul 25, 2024
1 parent 1d5e01c commit 2ca35a1
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 166 deletions.
115 changes: 46 additions & 69 deletions src/ui/components/SignMessageButton/SignMessageButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
import type { TypedData } from 'src/modules/ethereum/message-signing/TypedData';
import { HStack } from 'src/ui/ui-kit/HStack';
import CheckIcon from 'jsx:src/ui/assets/checkmark-checked.svg';
import { wait } from 'src/shared/wait';
import { WithReadonlyWarningDialog } from '../SignTransactionButton/ReadonlyWarningDialog';

type PersonalSignParams = MessageContextParams & {
Expand Down Expand Up @@ -50,100 +49,89 @@ export const SignMessageButton = React.forwardRef(function SignMessageButton(
) {
const hardwareSignRef = useRef<SignMessageHandle | null>(null);

const { mutateAsync: personalSignInner, ...personalSignMutationInner } =
useMutation({
mutationFn: async (params: PersonalSignParams) => {
if (isDeviceAccount(wallet)) {
const { params: methodParams, ...messageContextParams } = params;
const [message] = methodParams;
invariant(
hardwareSignRef.current,
'HardwareSignMessage must be mounted'
);
const signature = await hardwareSignRef.current.personalSign(message);
walletPort.request('registerPersonalSign', {
message,
address: wallet.address,
...messageContextParams,
});
return signature;
} else {
return await walletPort.request('personalSign', params);
}
},
});

const { mutateAsync: personalSign, ...personalSignMutation } = useMutation({
mutationFn: async (params: PersonalSignParams) => {
const result = await personalSignInner(params);
if (!isDeviceAccount(wallet) && holdToSign) {
await wait(500);
}
return result;
},
});

const {
mutateAsync: signTypedData_v4Inner,
...signTypedData_v4MutationInner
} = useMutation({
mutationFn: async (params: SignTypedDataParams) => {
if (isDeviceAccount(wallet)) {
const { typedData, ...messageContextParams } = params;
const { params: methodParams, ...messageContextParams } = params;
const [message] = methodParams;
invariant(
hardwareSignRef.current,
'HardwareSignMessage must be mounted'
);
const signature = await hardwareSignRef.current.signTypedData_v4(
typedData
);
walletPort.request('registerTypedDataSign', {
typedData,
const signature = await hardwareSignRef.current.personalSign(message);
walletPort.request('registerPersonalSign', {
message,
address: wallet.address,
...messageContextParams,
});
return signature;
} else {
return await walletPort.request('signTypedData_v4', params);
return await walletPort.request('personalSign', params);
}
},
});

const { mutateAsync: signTypedData_v4, ...signTypedData_v4Mutation } =
useMutation({
mutationFn: async (params: SignTypedDataParams) => {
const result = await signTypedData_v4Inner(params);
if (!isDeviceAccount(wallet) && holdToSign) {
await wait(500);
if (isDeviceAccount(wallet)) {
const { typedData, ...messageContextParams } = params;
invariant(
hardwareSignRef.current,
'HardwareSignMessage must be mounted'
);
const signature = await hardwareSignRef.current.signTypedData_v4(
typedData
);
walletPort.request('registerTypedDataSign', {
typedData,
address: wallet.address,
...messageContextParams,
});
return signature;
} else {
return await walletPort.request('signTypedData_v4', params);
}
return result;
},
});

useImperativeHandle(ref, () => ({ personalSign, signTypedData_v4 }));

const isLoading =
personalSignMutation.isLoading || signTypedData_v4Mutation.isLoading;
const isLoadingInner =
personalSignMutationInner.isLoading ||
signTypedData_v4MutationInner.isLoading;
const isSuccess =
personalSignMutationInner.isSuccess ||
signTypedData_v4MutationInner.isSuccess;
personalSignMutation.isSuccess || signTypedData_v4Mutation.isSuccess;
const isError =
personalSignMutation.isError || signTypedData_v4Mutation.isError;

// we have small delay after using holdable button
const disabled = isLoading || isSuccess;

const title = buttonTitle || 'Sign';

const successTitle = (
<HStack gap={4} alignItems="center">
<CheckIcon
style={{
width: 20,
height: 20,
color: 'var(--positive-500)',
}}
/>
<span>Sent</span>
</HStack>
);

return isDeviceAccount(wallet) ? (
<HardwareSignMessage
ref={hardwareSignRef}
derivationPath={wallet.derivationPath}
isSigning={isLoading}
children={children}
buttonTitle={buttonTitle}
buttonTitle={isSuccess ? successTitle : buttonTitle}
buttonKind={buttonKind}
onClick={onClick}
disabled={disabled}
{...buttonProps}
/>
) : (
Expand All @@ -154,30 +142,19 @@ export const SignMessageButton = React.forwardRef(function SignMessageButton(
holdToSign ? (
<HoldableButton
text={`Hold to ${title}`}
successText={
<HStack gap={4} alignItems="center">
<CheckIcon
style={{
width: 20,
height: 20,
color: 'var(--positive-500)',
}}
/>
<span>Signed</span>
</HStack>
}
successText={successTitle}
submittingText="Sending..."
onClick={handleClick}
success={isSuccess}
submitting={isLoadingInner}
disabled={isLoading}
submitting={isLoading}
disabled={disabled}
error={isError}
kind={buttonKind}
{...buttonProps}
/>
) : (
<Button
disabled={isLoading}
disabled={disabled}
onClick={handleClick}
kind={buttonKind}
{...buttonProps}
Expand Down
107 changes: 49 additions & 58 deletions src/ui/components/SignTransactionButton/SignTransactionButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import {
} from 'src/ui/ui-kit/Button';
import CheckIcon from 'jsx:src/ui/assets/checkmark-checked.svg';
import { HStack } from 'src/ui/ui-kit/HStack';
import { wait } from 'src/shared/wait';
import { usePreferences } from 'src/ui/features/preferences';
import { WithReadonlyWarningDialog } from './ReadonlyWarningDialog';

type SendTxParams = TransactionContextParams & {
Expand All @@ -43,102 +41,95 @@ export const SignTransactionButton = React.forwardRef(
buttonKind = 'primary',
isLoading: isLoadingProp,
disabled: disabledAttr,
holdToSignAllowed,
holdToSign,
...buttonProps
}: React.ButtonHTMLAttributes<HTMLButtonElement> & {
wallet: ExternallyOwnedAccount;
buttonTitle?: React.ReactNode;
buttonKind?: ButtonKind;
isLoading?: boolean;
holdToSignAllowed: boolean;
holdToSign: boolean;
},
ref: React.Ref<SendTxBtnHandle>
) {
const { preferences } = usePreferences();
const holdToSign = holdToSignAllowed && preferences?.enableHoldToSignButton;
const hardwareSignRef = useRef<SignTransactionHandle | null>(null);
const { mutateAsync: sendTransactionInner, ...sendTxMutationInner } =
useMutation({
mutationFn: async ({ transaction, ...params }: SendTxParams) => {
if (isDeviceAccount(wallet)) {
invariant(
hardwareSignRef.current,
'HardwareSignTransaction must be mounted'
);
const signedTx = await hardwareSignRef.current.signTransaction({
transaction,
chain: createChain(params.chain),
address: wallet.address,
});
return walletPort.request('sendSignedTransaction', {
serialized: signedTx,
...params,
});
} else {
return await walletPort.request('signAndSendTransaction', [
transaction,
params,
]);
}
},
});

const { mutateAsync: sendTransaction, ...sendTxMutation } = useMutation({
mutationFn: async (params: SendTxParams) => {
const result = await sendTransactionInner(params);
if (!isDeviceAccount(wallet) && holdToSign) {
await wait(500);
mutationFn: async ({ transaction, ...params }: SendTxParams) => {
if (isDeviceAccount(wallet)) {
invariant(
hardwareSignRef.current,
'HardwareSignTransaction must be mounted'
);
const signedTx = await hardwareSignRef.current.signTransaction({
transaction,
chain: createChain(params.chain),
address: wallet.address,
});
return walletPort.request('sendSignedTransaction', {
serialized: signedTx,
...params,
});
} else {
return await walletPort.request('signAndSendTransaction', [
transaction,
params,
]);
}
return result;
},
});

useImperativeHandle(ref, () => ({ sendTransaction }));

const isLoading = isLoadingProp || sendTxMutation.isLoading;
const isSending = sendTxMutation.isLoading;
const disabled = isLoading || disabledAttr;
const disabled = isLoading || sendTxMutation.isSuccess || disabledAttr;
const title = buttonTitle || 'Confirm';

const successTitle = (
<HStack gap={4} alignItems="center">
<CheckIcon
style={{
width: 20,
height: 20,
color: 'var(--positive-500)',
}}
/>
<span>Sent</span>
</HStack>
);

return isDeviceAccount(wallet) ? (
<HardwareSignTransaction
ref={hardwareSignRef}
derivationPath={wallet.derivationPath}
isSending={isSending}
children={children}
buttonTitle={isLoadingProp ? 'Preparing...' : buttonTitle}
buttonTitle={
sendTxMutation.isSuccess
? successTitle
: isLoadingProp
? 'Preparing...'
: buttonTitle
}
buttonKind={buttonKind}
onClick={onClick}
disabled={disabledAttr}
disabled={disabled}
{...buttonProps}
/>
) : (
<WithReadonlyWarningDialog
address={wallet.address}
onClick={onClick}
render={({ handleClick }) => {
if (!preferences) {
return null;
}
return holdToSign ? (
<HoldableButton
text={`Hold to ${title}`}
successText={
<HStack gap={4} alignItems="center">
<CheckIcon
style={{
width: 20,
height: 20,
color: 'var(--positive-500)',
}}
/>
<span>Sent</span>
</HStack>
}
successText={successTitle}
submittingText="Sending..."
onClick={handleClick}
success={sendTxMutationInner.isSuccess}
submitting={sendTxMutationInner.isLoading}
error={sendTxMutationInner.isError}
success={sendTxMutation.isSuccess}
submitting={sendTxMutation.isLoading}
error={sendTxMutation.isError}
disabled={disabled}
kind={buttonKind}
{...buttonProps}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import type {
} from 'src/modules/ethereum/types/IncomingTransaction';
import { getError } from 'src/shared/errors/getError';
import { CircleSpinner } from 'src/ui/ui-kit/CircleSpinner';
import { wait } from 'src/shared/wait';
import { usePreferences } from 'src/ui/features/preferences';
import { NetworkFee } from '../../../SendTransaction/NetworkFee';
import { useTransactionFee } from '../../../SendTransaction/TransactionConfiguration/useTransactionFee';
import {
Expand All @@ -57,6 +59,7 @@ function CancelTxContent({
onSuccess: () => void;
}) {
const { address } = wallet;
const { preferences } = usePreferences();
const { transaction: originalTransaction } = addressAction;
const [configuration, setConfiguration] = useState(DEFAULT_CONFIGURATION);
const chain = createChain(originalTransaction.chain);
Expand Down Expand Up @@ -115,7 +118,12 @@ function CancelTxContent({
// a global onError handler (src/ui/shared/requests/queryClient.ts)
// TODO: refactor to just emit error directly from the mutationFn
onMutate: () => 'sendTransaction',
onSuccess,
onSuccess: async () => {
if (preferences?.enableHoldToSignButton) {
await wait(500);
}
onSuccess();
},
});
return (
<>
Expand Down Expand Up @@ -205,12 +213,14 @@ function CancelTxContent({
>
Back
</Button>
<SignTransactionButton
wallet={wallet}
ref={signTxBtnRef}
onClick={() => sendTransaction()}
holdToSignAllowed={true}
/>
{preferences ? (
<SignTransactionButton
wallet={wallet}
ref={signTxBtnRef}
onClick={() => sendTransaction()}
holdToSign={Boolean(preferences.enableHoldToSignButton)}
/>
) : null}
</div>
</VStack>
</VStack>
Expand Down
Loading

0 comments on commit 2ca35a1

Please sign in to comment.