Skip to content

Commit

Permalink
implement send and delegate txns
Browse files Browse the repository at this point in the history
  • Loading branch information
Hemanthghs committed Sep 24, 2024
1 parent 6aeccae commit 612d4ee
Show file tree
Hide file tree
Showing 7 changed files with 408 additions and 80 deletions.
3 changes: 2 additions & 1 deletion frontend/src/components/interchain-agent/ChatInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ const ChatInput = ({
const currentSessionID = useAppSelector(
(state) => state.agent.currentSessionID
);
const currentSession = useAppSelector((state) => state.agent.currentSession);

useEffect(() => {
if (inputRef.current) {
inputRef.current.focus();
}
}, [currentSessionID]);
}, [currentSessionID, currentSession]);

return (
<form
Expand Down
234 changes: 157 additions & 77 deletions frontend/src/components/interchain-agent/InterchainAgentDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import React, { useEffect, useState } from 'react';
import AgentSidebar from './AgentSidebar';
import ChatComponent from './ChatComponent';
import { v4 as uuidv4 } from 'uuid';
import useTransactions from '@/custom-hooks/interchain-agent/useTransactions';
import { TxStatus } from '@/types/enums';
import { getTxnURLOnResolute } from '@/utils/util';
import { resetGenericTxStatus } from '@/store/features/common/commonSlice';

interface InterchainAgentDialogProps {
apiUrl: string;
Expand All @@ -21,6 +25,25 @@ interface InterchainAgentDialogProps {
subscriber: string;
}

function parseTransaction(input: string): { type: string; data: any } | null {
const regex = /^(\w+)\s+(\d+(?:\.\d+)?)\s+(\w+)\s+to\s+([a-zA-Z0-9]+)$/i;
const match = input.match(regex);

if (match) {
const [, type, amount, denom, address] = match;
return {
type: type,
data: {
amount: amount,
denom: denom.toUpperCase(),
address,
},
};
}

return null;
}

const InterchainAgentDialog = ({
accessToken,
apiUrl,
Expand All @@ -31,97 +54,31 @@ const InterchainAgentDialog = ({
subscriber,
}: InterchainAgentDialogProps) => {
const dispatch = useAppDispatch();

const agentDialogOpen = useAppSelector((state) => state.agent.agentOpen);
const currentSessionID = useAppSelector(
(state) => state.agent.currentSessionID
);

const [sidebarOpen, setSidebarOpen] = useState(true);
const [userInput, setUserInput] = useState('');

const { validateParsedTxnData, initiateTransaction } = useTransactions({
userInput,
});

const [inputDisabled, setInputDisabled] = useState<boolean>(false);
const [currentAccessToken, setCurrentAccessToken] =
useState<string>(accessToken);
const [isRefreshing, setIsRefreshing] = useState<boolean>(false);
const txStatus = useAppSelector((state) => state.common.genericTransaction);
const tx = useAppSelector((state) => state.common.txSuccess.tx);

useEffect(() => {
if (agentDialogOpen) {
document.body.classList.add('overflow-hidden');
} else {
document.body.classList.remove('overflow-hidden');
}

return () => {
document.body.classList.remove('overflow-hidden');
};
}, [agentDialogOpen]);

const toggleSidebar = () => {
setSidebarOpen((prev) => !prev);
};

const toggleAgent = () => {
dispatch(toggleAgentDialog());
const resetInputState = () => {
setUserInput('');
setInputDisabled(false);
};

useEffect(() => {
if (agentDialogOpen) {
const newSessionID = uuidv4();
dispatch(setCurrentSessionID(newSessionID));
setUserInput('');
setInputDisabled(false);
}
}, [agentDialogOpen]);

useEffect(() => {
if (currentSessionID) {
setUserInput('');
setInputDisabled(false);
const storedState = localStorage.getItem('queries');
if (storedState) {
const parsed = JSON.parse(storedState);
if (parsed[currentSessionID]) {
dispatch(setCurrentSession({ data: parsed }));
dispatch(
setCurrentSession({
data: parsed[currentSessionID],
})
);
} else {
dispatch(
setCurrentSession({
data: {
date: new Date().toISOString(),
requests: {},
},
})
);
}
} else {
dispatch(
setCurrentSession({
data: {
date: new Date().toISOString(),
requests: {},
},
})
);
}
} else {
dispatch(
setCurrentSession({
data: {
date: new Date().toISOString(),
requests: {},
},
})
);
}
}, [currentSessionID]);

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

const refreshTokenRequest = async () => {
try {
const response = await fetch(`${apiUrl}/refresh-token`, {
Expand Down Expand Up @@ -150,9 +107,31 @@ const InterchainAgentDialog = ({
}
};

const dispatchSessionItem = (
userInput: string,
status: string,
result: string,
errMessage: string
) => {
dispatch(
addSessionItem({
request: {
[userInput]: {
errMessage,
result,
status,
date: new Date().toISOString(),
},
},
sessionID: currentSessionID,
})
);
};

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setInputDisabled(true);
dispatch(resetGenericTxStatus());
if (userInput.trim() !== '') {
setInputDisabled(true);

Expand All @@ -170,6 +149,18 @@ const InterchainAgentDialog = ({
})
);

const parsedTransaction = parseTransaction(userInput.trim());
if (parsedTransaction) {
const error = validateParsedTxnData({ parsedData: parsedTransaction });
if (error.length) {
dispatchSessionItem(userInput, 'error', error, error);
resetInputState();
return;
}
initiateTransaction({ parsedData: parsedTransaction });
return;
}

try {
setUserInput('');
let response = await fetch(`${apiUrl}`, {
Expand Down Expand Up @@ -311,6 +302,95 @@ const InterchainAgentDialog = ({
setUserInput(value);
};

useEffect(() => {
if (agentDialogOpen) {
document.body.classList.add('overflow-hidden');
} else {
document.body.classList.remove('overflow-hidden');
}

return () => {
document.body.classList.remove('overflow-hidden');
};
}, [agentDialogOpen]);

const toggleSidebar = () => {
setSidebarOpen((prev) => !prev);
};

const toggleAgent = () => {
dispatch(toggleAgentDialog());
};

useEffect(() => {
if (agentDialogOpen) {
const newSessionID = uuidv4();
dispatch(setCurrentSessionID(newSessionID));
setUserInput('');
setInputDisabled(false);
}
}, [agentDialogOpen]);

useEffect(() => {
if (currentSessionID) {
setUserInput('');
setInputDisabled(false);
const storedState = localStorage.getItem('queries');
if (storedState) {
const parsed = JSON.parse(storedState);
if (parsed[currentSessionID]) {
dispatch(setCurrentSession({ data: parsed }));
dispatch(
setCurrentSession({
data: parsed[currentSessionID],
})
);
} else {
dispatch(
setCurrentSession({
data: {
date: new Date().toISOString(),
requests: {},
},
})
);
}
} else {
dispatch(
setCurrentSession({
data: {
date: new Date().toISOString(),
requests: {},
},
})
);
}
} else {
dispatch(
setCurrentSession({
data: {
date: new Date().toISOString(),
requests: {},
},
})
);
}
}, [currentSessionID]);

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

useEffect(() => {
if (
txStatus.status === TxStatus.IDLE ||
txStatus.status === TxStatus.REJECTED
) {
resetInputState();
dispatch(resetGenericTxStatus());
}
}, [txStatus]);

if (!agentDialogOpen) {
return null;
}
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/main-layout/FixedLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const FixedLayout = ({ children }: { children: React.ReactNode }) => {
const isLoading = useAppSelector((state) => state.wallet.isLoading);

const walletState = useAppSelector((state) => state.wallet.status);
const interchainAgentOpen = useAppSelector((state) => state.agent.agentOpen);

const tryConnectWallet = async (walletName: string) => {
if (walletName === 'metamask') {
Expand Down Expand Up @@ -155,7 +156,7 @@ const FixedLayout = ({ children }: { children: React.ReactNode }) => {
</section>
</div>
</main>
<TransactionStatusPopup />
{interchainAgentOpen ? null : <TransactionStatusPopup />}
<IBCSwapTxStatus />
<InterchainAgent />
</div>
Expand Down
Loading

0 comments on commit 612d4ee

Please sign in to comment.