From 75ecd2e65a05666e75ed71d04d49fc87ab4c99fe Mon Sep 17 00:00:00 2001 From: Paras Garg Date: Thu, 16 Jan 2025 23:10:45 +0530 Subject: [PATCH] feat: adding new form for unsinged sweep for MPCv2 EVM coins. Ticket: WIN-4290 --- .../BuildUnsignedSweepCoin.tsx | 80 +++++++++ .../BuildUnsignedSweepCoin/EthLikeFormTSS.tsx | 153 ++++++++++++++++++ 2 files changed, 233 insertions(+) create mode 100644 src/containers/BuildUnsignedSweepCoin/EthLikeFormTSS.tsx diff --git a/src/containers/BuildUnsignedSweepCoin/BuildUnsignedSweepCoin.tsx b/src/containers/BuildUnsignedSweepCoin/BuildUnsignedSweepCoin.tsx index 8574ecd5..5b251430 100644 --- a/src/containers/BuildUnsignedSweepCoin/BuildUnsignedSweepCoin.tsx +++ b/src/containers/BuildUnsignedSweepCoin/BuildUnsignedSweepCoin.tsx @@ -24,6 +24,7 @@ import { BitcoinForm } from './BitcoinForm'; import { BitcoinABCForm } from './BitcoinABCForm'; import { EthLikeTokenForm } from './EthLikeTokenForm'; import { EthLikeForm } from './EthLikeForm'; +import { EthLikeFormTSS } from './EthLikeFormTSS'; import { EthereumWForm } from './EthereumWForm'; import { LitecoinForm } from './LitecoinForm'; import { PolygonForm } from './PolygonForm'; @@ -187,6 +188,85 @@ function Form() { { encoding: 'utf-8' } ); + navigate( + `/${bitGoEnvironment}/build-unsigned-sweep/${coin}/success` + ); + } catch (err) { + if (err instanceof Error) { + setAlert(err.message); + } else { + console.error(err); + } + setSubmitting(false); + } + }} + /> + ); + case 'coredao': + case 'tcoredao': + case 'oas': + case 'toas': + return ( + { + setAlert(undefined); + setSubmitting(true); + try { + await window.commands.setBitGoEnvironment( + bitGoEnvironment, + coin, + values.apiKey + ); + const chainData = await window.queries.getChain(coin); + + const { maxFeePerGas, maxPriorityFeePerGas, ...rest } = values; + const recoverData = await window.commands.recover(coin, { + ...rest, + userKey: values.commonKeyChain, + backupKey: values.commonKeyChain, + eip1559: getEip1559Params( + coin, + maxFeePerGas, + maxPriorityFeePerGas + ), + replayProtectionOptions: { + chain: getEthLikeRecoveryChainId(coin, bitGoEnvironment), + hardfork: 'london', + }, + bitgoKey: '', + ignoreAddressTypes: [], + }); + assert( + isRecoveryTransaction(recoverData), + 'Fully-signed recovery transaction not detected.' + ); + + const showSaveDialogData = await window.commands.showSaveDialog({ + filters: [ + { + name: 'Custom File Type', + extensions: ['json'], + }, + ], + defaultPath: `~/${chainData}-unsigned-sweep-${Date.now()}.json`, + }); + + if (!showSaveDialogData.filePath) { + throw new Error('No file path selected'); + } + + await window.commands.writeFile( + showSaveDialogData.filePath, + JSON.stringify( + recoverData, + null, + 2 + ), + { encoding: 'utf-8' } + ); + navigate( `/${bitGoEnvironment}/build-unsigned-sweep/${coin}/success` ); diff --git a/src/containers/BuildUnsignedSweepCoin/EthLikeFormTSS.tsx b/src/containers/BuildUnsignedSweepCoin/EthLikeFormTSS.tsx new file mode 100644 index 00000000..2c78800a --- /dev/null +++ b/src/containers/BuildUnsignedSweepCoin/EthLikeFormTSS.tsx @@ -0,0 +1,153 @@ +import { Form, FormikHelpers, FormikProvider, useFormik } from 'formik'; +import { Link } from 'react-router-dom'; +import * as Yup from 'yup'; +import { Button, FormikTextfield } from '~/components'; +import { allCoinMetas } from '~/helpers/config'; + +const validationSchema = Yup.object({ + apiKey: Yup.string().required(), + commonKeyChain: Yup.string().required(), + derivationPath: Yup.string(), + derivationSeed: Yup.string(), + gasLimit: Yup.number() + .typeError('Gas limit must be a number') + .integer() + .positive('Gas limit must be a positive integer') + .required(), + maxFeePerGas: Yup.number().required(), + maxPriorityFeePerGas: Yup.number().required(), + recoveryDestination: Yup.string().required(), + walletContractAddress: Yup.string().required(), + isTss: Yup.boolean(), +}).required(); + +export type EthLikeFormTSSProps = { + coinName: string; + onSubmit: ( + values: EthLikeFormTSSValues, + formikHelpers: FormikHelpers + ) => void | Promise; +}; + +type EthLikeFormTSSValues = Yup.Asserts; + +export function EthLikeFormTSS({ onSubmit, coinName }: EthLikeFormTSSProps) { + const formik = useFormik({ + onSubmit, + initialValues: { + apiKey: '', + commonKeyChain: '', + derivationPath: '', + derivationSeed: '', + gasLimit: allCoinMetas[coinName]?.defaultGasLimitNum ?? 500000, + maxFeePerGas: 20, + maxPriorityFeePerGas: 10, + recoveryDestination: '', + walletContractAddress: '', + isTss: true, + }, + validationSchema, + }); + + return ( + +
+

+ Self-managed cold wallet details +

+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+
+ ); +}