From b29ece688940af3d3edc74da872ca47c97e4ba18 Mon Sep 17 00:00:00 2001
From: Logan Nguyen <logan.nguyen@swirldslabs.com>
Date: Wed, 6 Mar 2024 12:10:35 -0500
Subject: [PATCH] feat: updated System Contract DApp UI to adapt feeAmount
 parameter

Signed-off-by: Logan Nguyen <logan.nguyen@swirldslabs.com>
---
 .../methods/handleSanitizeFormInputs.tsx      |  6 ++-
 .../methods/FungibleTokenCreate/index.tsx     | 45 ++++++++++++-----
 .../methods/NonFungibleTokenCreate/index.tsx  | 49 +++++++++++++------
 .../HTS/token-create-custom/constant.ts       |  7 +++
 4 files changed, 78 insertions(+), 29 deletions(-)

diff --git a/system-contract-dapp-playground/src/components/common/methods/handleSanitizeFormInputs.tsx b/system-contract-dapp-playground/src/components/common/methods/handleSanitizeFormInputs.tsx
index bfa548184..1e834e263 100644
--- a/system-contract-dapp-playground/src/components/common/methods/handleSanitizeFormInputs.tsx
+++ b/system-contract-dapp-playground/src/components/common/methods/handleSanitizeFormInputs.tsx
@@ -39,6 +39,7 @@ interface ParamsProps {
   spenderAddress?: string;
   withCustomFee?: boolean;
   accountAddress?: string;
+  feeTokenAmount?: number;
   serialNumbers?: number[];
   receiverAddress?: string;
   feeTokenAddress?: string;
@@ -47,8 +48,8 @@ interface ParamsProps {
   autoRenewAccount?: string;
   tokenAddresses?: string[];
   recipientAddress?: string;
-  associatingAddress?: string;
   tokenAddressToMint?: string;
+  associatingAddress?: string;
   hederaTokenAddress?: string;
   fungibleReceivers?: string[];
   nonFungibleReceivers?: string[];
@@ -101,6 +102,7 @@ export const handleSanitizeHederaFormInputs = ({
   senderAddress,
   withCustomFee,
   serialNumbers,
+  feeTokenAmount,
   spenderAddress,
   accountAddress,
   tokenAddresses,
@@ -133,6 +135,8 @@ export const handleSanitizeHederaFormInputs = ({
       sanitizeErr = 'Invalid denomination token ID';
     } else if (!isAddress(treasury)) {
       sanitizeErr = 'Invalid treasury account address';
+    } else if (withCustomFee && Number(feeTokenAmount) <= 0) {
+      sanitizeErr = 'Custom fee amount must be positive';
     }
     // sanitize keys
     if (!sanitizeErr && keys) {
diff --git a/system-contract-dapp-playground/src/components/contract-interaction/hts/token-create-custom/methods/FungibleTokenCreate/index.tsx b/system-contract-dapp-playground/src/components/contract-interaction/hts/token-create-custom/methods/FungibleTokenCreate/index.tsx
index cb232ebce..ed56787e2 100644
--- a/system-contract-dapp-playground/src/components/contract-interaction/hts/token-create-custom/methods/FungibleTokenCreate/index.tsx
+++ b/system-contract-dapp-playground/src/components/contract-interaction/hts/token-create-custom/methods/FungibleTokenCreate/index.tsx
@@ -84,6 +84,7 @@ const FungibleTokenCreate = ({ baseContract }: PageProps) => {
     maxSupply: '',
     initSupply: '',
     feeTokenAddress: '',
+    feeTokenAmount: '',
     freezeStatus: false,
   };
   const [paramValues, setParamValues] = useState<any>(initialParamValues);
@@ -128,6 +129,7 @@ const FungibleTokenCreate = ({ baseContract }: PageProps) => {
       maxSupply,
       initSupply,
       freezeStatus,
+      feeTokenAmount,
       feeTokenAddress,
     } = paramValues;
 
@@ -143,6 +145,7 @@ const FungibleTokenCreate = ({ baseContract }: PageProps) => {
       maxSupply,
       initSupply,
       withCustomFee,
+      feeTokenAmount,
       feeTokenAddress,
     });
 
@@ -168,7 +171,8 @@ const FungibleTokenCreate = ({ baseContract }: PageProps) => {
       treasury,
       keys,
       feeValue,
-      withCustomFee ? feeTokenAddress : undefined
+      withCustomFee ? feeTokenAddress : undefined,
+      withCustomFee ? Number(feeTokenAmount) : undefined
     );
 
     // turn is loading off
@@ -318,18 +322,33 @@ const FungibleTokenCreate = ({ baseContract }: PageProps) => {
 
         {/* fee token address */}
         {withCustomFee && (
-          <SharedFormInputField
-            param={'feeTokenAddress'}
-            handleInputOnChange={handleInputOnChange}
-            paramValue={paramValues['feeTokenAddress']}
-            paramKey={(htsTokenCreateParamFields as any)['feeTokenAddress'].paramKey}
-            paramType={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputType}
-            paramSize={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputSize}
-            explanation={(htsTokenCreateParamFields as any)['feeTokenAddress'].explanation}
-            paramClassName={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputClassname}
-            paramPlaceholder={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputPlaceholder}
-            paramFocusColor={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputFocusBorderColor}
-          />
+          <>
+            <SharedFormInputField
+              param={'feeTokenAddress'}
+              handleInputOnChange={handleInputOnChange}
+              paramValue={paramValues['feeTokenAddress']}
+              paramKey={(htsTokenCreateParamFields as any)['feeTokenAddress'].paramKey}
+              paramType={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputType}
+              paramSize={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputSize}
+              explanation={(htsTokenCreateParamFields as any)['feeTokenAddress'].explanation}
+              paramClassName={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputClassname}
+              paramPlaceholder={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputPlaceholder}
+              paramFocusColor={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputFocusBorderColor}
+            />
+
+            <SharedFormInputField
+              param={'feeTokenAmount'}
+              handleInputOnChange={handleInputOnChange}
+              paramValue={paramValues['feeTokenAmount']}
+              paramKey={(htsTokenCreateParamFields as any)['feeTokenAmount'].paramKey}
+              paramType={(htsTokenCreateParamFields as any)['feeTokenAmount'].inputType}
+              paramSize={(htsTokenCreateParamFields as any)['feeTokenAmount'].inputSize}
+              explanation={(htsTokenCreateParamFields as any)['feeTokenAmount'].explanation}
+              paramClassName={(htsTokenCreateParamFields as any)['feeTokenAmount'].inputClassname}
+              paramPlaceholder={(htsTokenCreateParamFields as any)['feeTokenAmount'].inputPlaceholder}
+              paramFocusColor={(htsTokenCreateParamFields as any)['feeTokenAmount'].inputFocusBorderColor}
+            />
+          </>
         )}
 
         {/* treasury */}
diff --git a/system-contract-dapp-playground/src/components/contract-interaction/hts/token-create-custom/methods/NonFungibleTokenCreate/index.tsx b/system-contract-dapp-playground/src/components/contract-interaction/hts/token-create-custom/methods/NonFungibleTokenCreate/index.tsx
index 6da74ebe9..15f763101 100644
--- a/system-contract-dapp-playground/src/components/contract-interaction/hts/token-create-custom/methods/NonFungibleTokenCreate/index.tsx
+++ b/system-contract-dapp-playground/src/components/contract-interaction/hts/token-create-custom/methods/NonFungibleTokenCreate/index.tsx
@@ -78,6 +78,7 @@ const NonFungibleTokenCreate = ({ baseContract }: PageProps) => {
     treasury: '',
     feeValue: '',
     maxSupply: '',
+    feeTokenAmount: '',
     feeTokenAddress: '',
   };
   const [paramValues, setParamValues] = useState<any>(initialParamValues);
@@ -112,7 +113,8 @@ const NonFungibleTokenCreate = ({ baseContract }: PageProps) => {
 
   /** @dev handle invoking the API to interact with smart contract and create non fungible token */
   const handleCreatingNonFungibleToken = async () => {
-    const { name, symbol, memo, maxSupply, treasury, feeTokenAddress, feeValue } = paramValues;
+    const { name, symbol, memo, maxSupply, treasury, feeTokenAddress, feeValue, feeTokenAmount } =
+      paramValues;
 
     // sanitize params
     const sanitizeErr = handleSanitizeHederaFormInputs({
@@ -124,6 +126,7 @@ const NonFungibleTokenCreate = ({ baseContract }: PageProps) => {
       treasury,
       maxSupply,
       withCustomFee,
+      feeTokenAmount,
       feeTokenAddress,
     });
 
@@ -146,7 +149,8 @@ const NonFungibleTokenCreate = ({ baseContract }: PageProps) => {
       treasury,
       keys,
       feeValue,
-      withCustomFee ? feeTokenAddress : undefined
+      withCustomFee ? feeTokenAddress : undefined,
+      withCustomFee ? Number(feeTokenAmount) : undefined
     );
 
     // turn is loading off
@@ -248,18 +252,33 @@ const NonFungibleTokenCreate = ({ baseContract }: PageProps) => {
 
         {/* fee token address */}
         {withCustomFee && (
-          <SharedFormInputField
-            param={'feeTokenAddress'}
-            handleInputOnChange={handleInputOnChange}
-            paramValue={paramValues['feeTokenAddress']}
-            paramKey={(htsTokenCreateParamFields as any)['feeTokenAddress'].paramKey}
-            paramType={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputType}
-            paramSize={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputSize}
-            explanation={(htsTokenCreateParamFields as any)['feeTokenAddress'].explanation}
-            paramClassName={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputClassname}
-            paramPlaceholder={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputPlaceholder}
-            paramFocusColor={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputFocusBorderColor}
-          />
+          <>
+            <SharedFormInputField
+              param={'feeTokenAddress'}
+              handleInputOnChange={handleInputOnChange}
+              paramValue={paramValues['feeTokenAddress']}
+              paramKey={(htsTokenCreateParamFields as any)['feeTokenAddress'].paramKey}
+              paramType={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputType}
+              paramSize={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputSize}
+              explanation={(htsTokenCreateParamFields as any)['feeTokenAddress'].explanation}
+              paramClassName={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputClassname}
+              paramPlaceholder={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputPlaceholder}
+              paramFocusColor={(htsTokenCreateParamFields as any)['feeTokenAddress'].inputFocusBorderColor}
+            />
+
+            <SharedFormInputField
+              param={'feeTokenAmount'}
+              handleInputOnChange={handleInputOnChange}
+              paramValue={paramValues['feeTokenAmount']}
+              paramKey={(htsTokenCreateParamFields as any)['feeTokenAmount'].paramKey}
+              paramType={(htsTokenCreateParamFields as any)['feeTokenAmount'].inputType}
+              paramSize={(htsTokenCreateParamFields as any)['feeTokenAmount'].inputSize}
+              explanation={(htsTokenCreateParamFields as any)['feeTokenAmount'].explanation}
+              paramClassName={(htsTokenCreateParamFields as any)['feeTokenAmount'].inputClassname}
+              paramPlaceholder={(htsTokenCreateParamFields as any)['feeTokenAmount'].inputPlaceholder}
+              paramFocusColor={(htsTokenCreateParamFields as any)['feeTokenAmount'].inputFocusBorderColor}
+            />
+          </>
         )}
 
         {/* keys */}
@@ -281,7 +300,7 @@ const NonFungibleTokenCreate = ({ baseContract }: PageProps) => {
           feeType={'SERVICE'}
           paramValues={paramValues.feeValue}
           placeHolder={'Service fee...'}
-          executeBtnTitle={'Create Fungible Token'}
+          executeBtnTitle={'Create Non Fungible Token'}
           handleInputOnChange={handleInputOnChange}
           explanation={
             'Represents the fee in HBAR directly paid to the contract system of the Hedera Token Service'
diff --git a/system-contract-dapp-playground/src/utils/contract-interactions/HTS/token-create-custom/constant.ts b/system-contract-dapp-playground/src/utils/contract-interactions/HTS/token-create-custom/constant.ts
index fe8e72ae5..af7ed1899 100644
--- a/system-contract-dapp-playground/src/utils/contract-interactions/HTS/token-create-custom/constant.ts
+++ b/system-contract-dapp-playground/src/utils/contract-interactions/HTS/token-create-custom/constant.ts
@@ -107,6 +107,13 @@ export const htsTokenCreateParamFields = {
     inputPlaceholder: 'The denomination token ID...',
     explanation: 'represents the ID of token that is used for fixed fee denomination',
   },
+  feeTokenAmount: {
+    ...HEDERA_SHARED_PARAM_INPUT_FIELDS,
+    inputType: 'number',
+    paramKey: 'feeTokenAmount',
+    inputPlaceholder: 'The fee amount...',
+    explanation: 'represents the number of units to assess as a fee',
+  },
   customFee: {
     paramKey: 'customFee',
     explanation: {