Skip to content

Commit

Permalink
fix(devx): Fix CTF Challenge 0 (#5371)
Browse files Browse the repository at this point in the history
* popup.tst:
* fix path props
* use false for setShowPopUp on close always

mint-leap-frog-nft.tsx:
* add digest prop and use it for PopUp

ctf-utils.ts
* fix spacing
* rename Error to Response
* add digest to response

ctf-verifier.tsx
* rename Error to Response
* removed unused imports and constants

* rename popup component

* Update docs/site/src/components/CTF/ctf-verifier.tsx

* Update docs/site/src/utils/ctf-utils.ts

Co-authored-by: vivekjain23 <[email protected]>

* Update docs/site/src/components/CTF/ctf-verifier.tsx

Co-authored-by: vivekjain23 <[email protected]>

---------

Co-authored-by: vivekjain23 <[email protected]>
  • Loading branch information
lucas-tortora and vivekjain23 authored Feb 14, 2025
1 parent 823e9d9 commit 88045a8
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 89 deletions.
13 changes: 5 additions & 8 deletions docs/site/src/components/CTF/ctf-verifier.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { getFullnodeUrl } from '@iota/iota-sdk/client';
import clsx from 'clsx';
import { useConnectWallet, useWallets } from '@iota/dapp-kit';
import Popup from './popup';
import { handleChallengeSubmit } from "../../utils/ctf-utils"

interface ChallengeVerifierProps {
Expand All @@ -28,9 +27,9 @@ const ChallengeVerifier: React.FC<ChallengeVerifierProps> = ({
}) => {
const [inputText, setInputText] = useState('');
const [coins, setCoins] = useState<string | null>(null);
const [showPopup, setShowPopup] = useState<boolean>(false);
const [setShowPopIn] = useState<boolean>(false);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<{
const [response, setResponse] = useState<{
status: 'success' | 'error';
description: string;
title: string;
Expand All @@ -43,7 +42,6 @@ const ChallengeVerifier: React.FC<ChallengeVerifierProps> = ({
const wallets = useWallets();
const { mutate } = useConnectWallet();
const { mutate: signAndExecuteTransaction} = useSignAndExecuteTransaction();
const [digest,setDigest] = useState<string>('');
const handleSubmit = async () => {
await handleChallengeSubmit({
inputText,
Expand All @@ -55,9 +53,8 @@ const ChallengeVerifier: React.FC<ChallengeVerifierProps> = ({
signAndExecuteTransaction,
setLoading,
setCoins,
setError,
setShowPopup,
setDigest
setResponse,
setShowPopIn,
});
};

Expand All @@ -73,7 +70,7 @@ const ChallengeVerifier: React.FC<ChallengeVerifierProps> = ({
placeholder="Enter Flag Object Id"
className="input-field"
/>
{<p className={`text-red-500 mb-0 mt-1 text-sm ${error.description!=='' ? 'visible' : 'invisible'}`}>{error.description}</p>}
{<p className={`text-red-500 mb-0 mt-1 text-sm ${response.description!=='' ? 'visible' : 'invisible'}`}>{response.description}</p>}
<button
onClick={handleSubmit}
className={`${clsx("button", { "button-disabled": inputText=='' || loading })} min-w-28 mt-4`}
Expand Down
27 changes: 15 additions & 12 deletions docs/site/src/components/CTF/mint-leap-frog-nft.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { getFullnodeUrl } from '@iota/iota-sdk/client';
import clsx from 'clsx';
import { useConnectWallet, useWallets } from '@iota/dapp-kit';
import Popup from './popup';
import PopIn from './pop-in';
import { handleMintLeapFrogSubmit } from "../../utils/ctf-utils"

const NETWORKS = {
Expand All @@ -23,16 +23,18 @@ const MintLeapFrogNFT: React.FC = () => {
address:''
});
const [coins, setCoins] = useState<string | null>(null);
const [showPopup, setShowPopup] = useState<boolean>(false);
const [showPopIn, setShowPopIn] = useState<boolean>(false);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<{
const [response, setResponse] = useState<{
status: 'success' | 'error';
description: string;
title: string;
digest: string;
}>({
status: 'success',
description: '',
title: '',
digest: ''
});
const [isValidIotaAddress,setIsValidIotaAddress] = useState<boolean>(true);
const wallets = useWallets();
Expand All @@ -47,8 +49,8 @@ const MintLeapFrogNFT: React.FC = () => {
signAndExecuteTransaction,
setLoading,
setCoins,
setError,
setShowPopup,
setResponse,
setShowPopIn,
});
};

Expand Down Expand Up @@ -115,13 +117,14 @@ const MintLeapFrogNFT: React.FC = () => {
<div className="flex items-center">
{coins && !loading && <pre className="mt-2 mb-0 p-3">{coins}</pre>}
</div>
{showPopup && (
<Popup
status={error.status}
description={error.description}
title={error.title}
setShowPopup={setShowPopup}
showPopup={showPopup}
{showPopIn && (
<PopIn
status={response.status}
description={response.description}
title={response.title}
setShowPopIn={setShowPopIn}
digest={response.digest}
showPopIn={showPopIn}
/>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ interface PropTypes {
status: 'success' | 'error',
description: string,
title: string,
setShowPopup: React.Dispatch<React.SetStateAction<boolean>>,
showPopup: boolean,
setShowPopIn: React.Dispatch<React.SetStateAction<boolean>>,
showPopIn: boolean,
digest:string
}

const Popup = ({ status, description, title, setShowPopup, showPopup,digest }: PropTypes) => {
const PopIn = ({ status, description, title, setShowPopIn, digest }: PropTypes) => {
return (
<div className="relative z-10" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div className="fixed inset-0 dark:bg-gray-500/75 bg-gray-200/75 transition-opacity" aria-hidden="true"></div>
Expand All @@ -18,13 +18,13 @@ const Popup = ({ status, description, title, setShowPopup, showPopup,digest }: P
<div className="relative transform overflow-hidden rounded-lg bg-white text-center shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-md">
<div className="bg-[#ffffff] px-6 py-10">
<div className={`${status !== 'success' && 'hidden'} mx-auto mb-6 flex size-16 items-center justify-center rounded-full bg-green-100`}>
<svg className="size-8 text-green-500" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" />
<svg className="size-8 text-green-500" fill="none" viewBox="0 0 24 24" strokeWidth="2" stroke="currentColor" aria-hidden="true">
<path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
</svg>
</div>
<div className={`${status === 'success' && 'hidden'} mx-auto mb-6 flex size-16 items-center justify-center rounded-full bg-red-100`}>
<svg className="size-6 text-red-600" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" />
<svg className="size-6 text-red-600" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon">
<path strokeLinecap="round" strokeLinejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" />
</svg>
</div>
<h3 className="text-lg font-semibold text-gray-900 mb-2" id="modal-title">
Expand All @@ -46,7 +46,7 @@ const Popup = ({ status, description, title, setShowPopup, showPopup,digest }: P
<button
type="button"
className="inline-flex cursor-pointer w-full border-none justify-center rounded-md bg-[#017195] px-4 py-2 text-sm font-semibold text-white hover:text-black"
onClick={() => setShowPopup(!showPopup)}
onClick={() => setShowPopIn(false)}
>
Close
</button>
Expand All @@ -63,4 +63,4 @@ const Popup = ({ status, description, title, setShowPopup, showPopup,digest }: P
)
}

export default Popup
export default PopIn
120 changes: 60 additions & 60 deletions docs/site/src/utils/ctf-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ export const handleChallengeSubmit = async ({
signAndExecuteTransaction,
setLoading,
setCoins,
setError,
setShowPopup,
setDigest
setResponse,
setShowPopIn,
}: any) => {
setLoading(true);
setError({
setResponse({
status: 'success',
description: '',
title: '',
Expand Down Expand Up @@ -59,24 +58,24 @@ export const handleChallengeSubmit = async ({
onSuccess: ({ digest }: any) => {
client.waitForTransaction({ digest, options: { showEffects: true } }).then(() => {
setDigest(digest)
setError({
setResponse({
status: 'success',
description: 'An NFT reward was minted and transferred to your IOTA wallet address for completing the challenge.',
title: 'NFT Minted',
});
setCoins(message);
setLoading(false);
setShowPopup(true);
setShowPopIn(true);
});
},
onError: (error: any) => {
setError({
setResponse({
status: 'error',
description: `Failed to execute transaction : ${error}`,
title: 'Submission failed',
});
setLoading(false);
setShowPopup(true);
setShowPopIn(true);
},
}
);
Expand All @@ -87,7 +86,7 @@ export const handleChallengeSubmit = async ({
setCoins('Invalid Flag Object Id. Please try again.');
}
} catch (err: any) {
setError({
setResponse({
status: 'error',
description: err.message || 'An error occurred. Please try again.',
title: 'Submission failed',
Expand All @@ -103,11 +102,11 @@ export const handleMintLeapFrogSubmit = async ({
signAndExecuteTransaction,
setLoading,
setCoins,
setError,
setShowPopup,
setResponse,
setShowPopIn,
}: any) => {
setLoading(true);
setError({
setResponse({
status: 'success',
description: '',
title: '',
Expand All @@ -121,59 +120,60 @@ export const handleMintLeapFrogSubmit = async ({
const NFTPackageAddress = "0x649884331fa662235b2c06c6eb488e5327105dded1331f6b7541ef4fdbd9eeca"
const client = new IotaClient({ url: NETWORKS.testnet.url });

const message = 'Congratulations! You have successfully completed this level!';
const wallet = wallets[0];
const message = 'Congratulations! You have successfully completed this level!';
const wallet = wallets[0];

mutate(
{ wallet },
{
onSuccess: () => {
const tx = () => {
const tx = new Transaction();
const arg0 = new TextEncoder().encode(nft.name);
const arg1 = new TextEncoder().encode(nft.description);
const arg2 = new TextEncoder().encode(nft.url);
tx.setGasBudget(50000000);
tx.moveCall({
target: `${NFTPackageAddress}::leap_frog_nft::mint_to_sender`,
arguments: [tx.pure.vector('u8', arg0), tx.pure.vector('u8', arg1), tx.pure.vector('u8', arg2), tx.pure.address(nft.address)],
});
return tx;
};
mutate(
{ wallet },
{
onSuccess: () => {
const tx = () => {
const tx = new Transaction();
const arg0 = new TextEncoder().encode(nft.name);
const arg1 = new TextEncoder().encode(nft.description);
const arg2 = new TextEncoder().encode(nft.url);
tx.setGasBudget(50000000);
tx.moveCall({
target: `${NFTPackageAddress}::leap_frog_nft::mint_to_sender`,
arguments: [tx.pure.vector('u8', arg0), tx.pure.vector('u8', arg1), tx.pure.vector('u8', arg2), tx.pure.address(nft.address)],
});
return tx;
};

signAndExecuteTransaction(
{
transaction: tx(),
},
{
onSuccess: ({ digest }: any) => {
client.waitForTransaction({ digest, options: { showEffects: true } }).then(() => {
setError({
status: 'success',
description: 'An NFT reward is minted to your IOTA wallet address upon completing the challenge.',
title: 'NFT Minted',
});
setCoins(message);
setLoading(false);
setShowPopup(true);
});
},
onError: (error: any) => {
setError({
status: 'error',
description: `Failed to execute transaction : ${error}`,
title: 'Submission failed',
signAndExecuteTransaction(
{
transaction: tx(),
},
{
onSuccess: ({ digest }: any) => {
client.waitForTransaction({ digest, options: { showEffects: true } }).then(() => {
setResponse({
status: 'success',
description: 'An NFT reward is minted to your IOTA wallet address upon completing the challenge.',
title: 'NFT Minted',
digest: digest
});
setCoins(message);
setLoading(false);
setShowPopup(true);
},
}
);
},
}
);
setShowPopIn(true);
});
},
onError: (error: any) => {
setResponse({
status: 'error',
description: `Failed to execute transaction : ${error}`,
title: 'Submission failed',
});
setLoading(false);
setShowPopIn(true);
},
}
);
},
}
);
} catch (err: any) {
setError({
setResponse({
status: 'error',
description: err.message || 'An error occurred. Please try again.',
title: 'Submission failed',
Expand Down

0 comments on commit 88045a8

Please sign in to comment.