Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Hemanthghs committed Nov 27, 2024
1 parent 28bd211 commit 525943d
Show file tree
Hide file tree
Showing 12 changed files with 486 additions and 179 deletions.
126 changes: 113 additions & 13 deletions frontend/src/app/(routes)/multisig/components/common/BroadCastTxn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ import {
} from '@/store/features/multisig/multisigSlice';
import { RootState } from '@/store/store';
import { MultisigAddressPubkey, Txn } from '@/types/multisig';
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import { FAILED_TO_BROADCAST_ERROR } from '@/utils/errors';
import useVerifyAccount from '@/custom-hooks/useVerifyAccount';
import CustomButton from '@/components/common/CustomButton';
import { useRouter } from 'next/navigation';
import CustomDialog from '@/components/common/CustomDialog';
import { Dialog, DialogContent } from '@mui/material';
import Image from 'next/image';
import { DELETE_ILLUSTRATION } from '@/constants/image-names';

interface BroadCastTxnProps {
txn: Txn;
Expand All @@ -23,6 +27,11 @@ interface BroadCastTxnProps {
isMember: boolean;
disableBroadcast?: boolean;
isOverview?: boolean;
broadcastInfo?: {
disable: boolean;
isSequenceLess: boolean;
isSequenceGreater: boolean;
};
}

const BroadCastTxn: React.FC<BroadCastTxnProps> = (props) => {
Expand All @@ -35,6 +44,7 @@ const BroadCastTxn: React.FC<BroadCastTxnProps> = (props) => {
isMember,
disableBroadcast,
isOverview,
broadcastInfo,
} = props;
const dispatch = useAppDispatch();
const { getChainInfo } = useGetChainInfo();
Expand Down Expand Up @@ -88,20 +98,110 @@ const BroadCastTxn: React.FC<BroadCastTxnProps> = (props) => {
})
);
};
const [pendingSeqOpen, setPendingSeqOpen] = useState(false);
const [seqNotSyncOpen, setSeqNotSyncOpen] = useState(false);
const handleBroadcast = () => {
if (isOverview) {
router.push(`/multisig/${chainName}/${multisigAddress}`);
} else if (broadcastInfo) {
if (broadcastInfo.isSequenceLess) {
// alert('Sequence is not in sync');
setSeqNotSyncOpen(true);
} else if (broadcastInfo.isSequenceGreater) {
setPendingSeqOpen(true);
setSeqNotSyncOpen(true);
// alert(
// 'There is a transaction that needs to be broadcasted before this'
// );
} else if (!broadcastInfo.disable) {
broadcastTxn();
}
}
};
return (
<CustomButton
btnText="Broadcast"
btnOnClick={() => {
if (isOverview) {
router.push(`/multisig/${chainName}/${multisigAddress}`);
} else {
broadcastTxn();
}
}}
btnDisabled={!isMember || disableBroadcast}
btnStyles="w-[115px]"
/>
<>
<CustomButton
btnText="Broadcast"
btnOnClick={handleBroadcast}
btnDisabled={!isMember}
btnStyles="w-[115px]"
/>
<DialogSequenceMissMatch
open={seqNotSyncOpen}
onClose={() => setSeqNotSyncOpen(false)}
onUpdateSequence={() => console.log('update')}
/>
</>
);
};

export default BroadCastTxn;

const DialogSequenceMissMatch = ({
open,
onClose,
onUpdateSequence,
}: {
open: boolean;
onClose: () => void;
onUpdateSequence: () => void;
}) => {
return (
<Dialog
open={open}
onClose={onClose}
maxWidth="lg"
sx={{
'& .MuiDialog-paper': {
color: 'white',
},
}}
PaperProps={{
sx: {
borderRadius: '16px',
background: '#1C1C20',
},
}}
>
<DialogContent sx={{ padding: 0 }}>
<div className="w-[550px] p-4 relative">
<button
className="absolute top-6 right-6 hover:bg-[#ffffff10] w-8 h-8 rounded-full flex items-center justify-center"
onClick={onClose}
>
<Image src="/close.svg" width={20} height={20} alt="close-icon" />
</button>
<div className="px-10 py-20 space-y-10">
<div className="flex flex-col items-center gap-6">
<div className="border-[4px] bg-[#F3B2AD] border-[#933A42] rounded-full w-16 h-16 mx-auto flex justify-center items-center">
<div className="p-6 leading-none font-bold text-[48px] text-[#933A42] select-none">
!
</div>
</div>
<div className="flex items-center flex-col gap-2">
<div className="text-h2 !font-bold">Sequence Outdated</div>
<div className="text-b1-light text-center">
Transaction sequence is outdated. To broadcast this
transaction, the sequence number needs to be updated.
</div>
<div className="text-b1-light text-center">
Would you like to update?
</div>
</div>
</div>
<div className="space-y-6">
<div className="text-b1-light !font-normal rounded-lg bg-[#ffffff0d] p-2 !text-red-400">
After this action all the signers will be required to re-sign.
</div>
<CustomButton
btnOnClick={onUpdateSequence}
btnText="Update Sequence"
btnStyles="w-full !border-[#D92101] !bg-[#D921011A] delete-multisig-btn"
/>
</div>
</div>
</div>
</DialogContent>
</Dialog>
);
};
13 changes: 13 additions & 0 deletions frontend/src/app/(routes)/multisig/components/common/SignTxn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ const SignTxn: React.FC<SignTxnProps> = (props) => {
const router = useRouter();

const txnsCount = useAppSelector((state) => state.multisig.txns.Count);
const allTxns = useAppSelector((state) => state.multisig.txns.list);
const multisigAccount = useAppSelector(
(state) => state.multisig.multisigAccount
);

const partiallySigned = allTxns.filter(
(tx) =>
tx.signatures.length > 0 &&
tx.signatures.length < multisigAccount.account.threshold
);

const getCount = (option: string) => {
let count = 0;
/* eslint-disable @typescript-eslint/no-explicit-any */
Expand All @@ -56,7 +67,9 @@ const SignTxn: React.FC<SignTxnProps> = (props) => {
unSignedTxn,
walletAddress,
rpcURLs,
txnSequence: unSignedTxn.txn_sequence,
toBeBroadcastedCount,
partiallySignedCount: partiallySigned?.length
})
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const TxnsCard = ({
allowRepeat,
disableBroadcast,
isOverview,
broadcastInfo,
}: {
txn: Txn;
currency: Currency;
Expand All @@ -53,6 +54,11 @@ export const TxnsCard = ({
allowRepeat?: boolean;
disableBroadcast?: boolean;
isOverview?: boolean;
broadcastInfo?: {
disable: boolean;
isSequenceLess: boolean;
isSequenceGreater: boolean;
};
}) => {
const dispatch = useAppDispatch();
const { getChainInfo } = useGetChainInfo();
Expand Down Expand Up @@ -274,6 +280,7 @@ export const TxnsCard = ({
isMember={isMember}
disableBroadcast={disableBroadcast}
isOverview={isOverview}
broadcastInfo={broadcastInfo}
/>
) : (
<SignTxn
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
resetsignTransactionRes,
resetUpdateTxnState,
setVerifyDialogOpen,
getSequenceNumber,
resetSequenceNumber,
} from '@/store/features/multisig/multisigSlice';
import { useEffect, useState } from 'react';
import MultisigAccountHeader from './MultisigAccountHeader';
Expand Down Expand Up @@ -71,6 +73,10 @@ const MultisigAccount = ({
);
const members = multisigAccount.pubkeys.map((pubkey) => pubkey.address);

const broadcastTxnStatus = useAppSelector(
(state) => state.multisig.broadcastTxnRes.status
);

const { name: multisigName, created_at: createdTime } =
multisigAccount.account;

Expand Down Expand Up @@ -110,6 +116,20 @@ const MultisigAccount = ({
dispatch(resetsignTransactionRes());
}, []);

useEffect(() => {
if (multisigAddress) {
dispatch(
getSequenceNumber({ baseURLs: restURLs, chainID, multisigAddress })
);
}
}, [broadcastTxnStatus, multisigAddress]);

useEffect(() => {
return () => {
dispatch(resetSequenceNumber());
};
}, []);

const createNewTxn = () => {
if (!isAccountVerified()) {
dispatch(setVerifyDialogOpen(true));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { useAppDispatch, useAppSelector } from '@/custom-hooks/StateHooks';
import { getTxns } from '@/store/features/multisig/multisigSlice';
import {
getSequenceNumber,
getTxns,
} from '@/store/features/multisig/multisigSlice';
import { Txn } from '@/types/multisig';
import React, { useEffect, useState } from 'react';
import { TxStatus } from '@/types/enums';
Expand All @@ -8,6 +11,7 @@ import useFetchTxns from '@/custom-hooks/multisig/useFetchTxns';
import NoData from '@/components/common/NoData';
import TransactionsLoading from '../loaders/TransactionsLoading';
import DialogTxnFailed from './DialogTxnFailed';
import useGetChainInfo from '@/custom-hooks/useGetChainInfo';

const TXNS_TYPES = [
{ option: 'to-sign', value: 'To be Signed' },
Expand All @@ -28,6 +32,8 @@ const Transactions = ({
threshold: number;
}) => {
const dispatch = useAppDispatch();
const { getChainInfo } = useGetChainInfo();
const { restURLs } = getChainInfo(chainID);
const txnsState = useAppSelector((state) => state.multisig.txns.list);

const [txnsList, setTxnsList] = useState<Txn[]>([]);
Expand Down Expand Up @@ -244,12 +250,15 @@ const TransactionsList = ({
setErrMsg(errMsg);
setViewErrorDialogOpen(true);
};
const currentSequenceNumber = useAppSelector(
(state) => state.multisig.multisigAccountSequenceNumber.value
);
const sortedTxns = [...txns].sort((a, b) => {
const dateA = new Date(
txnsType === 'to-broadcast' ? a.signed_at : a.created_at
txnsType === 'to-broadcast' ? a.txn_sequence ?? a.signed_at : a.created_at
).getTime();
const dateB = new Date(
txnsType === 'to-broadcast' ? b.signed_at : b.created_at
txnsType === 'to-broadcast' ? b.txn_sequence ?? b.signed_at : b.created_at
).getTime();
return txnsType === 'to-broadcast' ? dateA - dateB : dateB - dateA;
});
Expand All @@ -267,7 +276,25 @@ const TransactionsList = ({
isHistory={isHistory}
onViewError={onViewError}
allowRepeat={txnsType === 'completed'}
disableBroadcast={txnsType === 'to-broadcast' && index > 0}
disableBroadcast={
txnsType === 'to-broadcast' &&
currentSequenceNumber !== txn.txn_sequence
}
broadcastInfo={{
disable:
txnsType === 'to-broadcast' &&
currentSequenceNumber !== null &&
txn.txn_sequence !== null &&
currentSequenceNumber !== txn.txn_sequence,
isSequenceLess:
txn.txn_sequence !== null &&
currentSequenceNumber !== null &&
txn.txn_sequence < currentSequenceNumber,
isSequenceGreater:
txn.txn_sequence !== null &&
currentSequenceNumber !== null &&
txn.txn_sequence > currentSequenceNumber,
}}
/>
))}
<DialogTxnFailed
Expand Down
10 changes: 8 additions & 2 deletions frontend/src/app/(routes)/multisig/utils/multisigSigning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ const signTransaction = async (
unSignedTxn: Txn,
walletAddress: string,
rpcURLs: string[],
toBeBroadcastedCount: number
toBeBroadcastedCount: number,
partiallySignedCount: number,
txnSequence: number | null
) => {
try {
window.wallet.defaultOptions = {
Expand All @@ -45,10 +47,13 @@ const signTransaction = async (
if (!multisigAcc) {
throw new Error('Multisig account does not exist on chain');
}
const updatedTxnSequence =
txnSequence ??
multisigAcc?.sequence + toBeBroadcastedCount + partiallySignedCount;

const signerData = {
accountNumber: multisigAcc?.accountNumber,
sequence: multisigAcc?.sequence + toBeBroadcastedCount,
sequence: updatedTxnSequence,
chainId: chainID,
};

Expand All @@ -67,6 +72,7 @@ const signTransaction = async (
txId: unSignedTxn.id || NaN,
address: multisigAddress,
signature: toBase64(signatures[0]),
txnSequence: updatedTxnSequence
};

return payload;
Expand Down
Loading

0 comments on commit 525943d

Please sign in to comment.