From 8cc065e0419b571aa4f71eb66d0145bd325e8fc5 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Thu, 12 Oct 2023 12:26:22 +0300 Subject: [PATCH 01/47] Add reading feature skeleton --- front-end-tools/CHANGELOG.md | 4 + front-end-tools/package.json | 2 +- front-end-tools/src/Main.tsx | 274 ++++++++++++++++++ front-end-tools/src/constants.ts | 2 + .../src/reading_from_blockchain.ts | 49 ++++ 5 files changed, 330 insertions(+), 1 deletion(-) create mode 100644 front-end-tools/src/reading_from_blockchain.ts diff --git a/front-end-tools/CHANGELOG.md b/front-end-tools/CHANGELOG.md index 0927b048..4a00204e 100644 --- a/front-end-tools/CHANGELOG.md +++ b/front-end-tools/CHANGELOG.md @@ -1,5 +1,9 @@ ## Unreleased changes +## 3.0.0 + +- Add reading from smart contract and writing to smart contract feature + ## 2.2.0 - Add warning box if module references in step 1 and step 2 are not the same. Add warning box if embedded schema indicates an input parameter but no input parameter is provided. diff --git a/front-end-tools/package.json b/front-end-tools/package.json index 84d513fb..718ffb1c 100644 --- a/front-end-tools/package.json +++ b/front-end-tools/package.json @@ -1,7 +1,7 @@ { "name": "front-end-tools", "packageManager": "yarn@3.2.0", - "version": "2.2.0", + "version": "3.0.0", "license": "Apache-2.0", "engines": { "node": ">=16.x" diff --git a/front-end-tools/src/Main.tsx b/front-end-tools/src/Main.tsx index 894643fd..baee8e80 100644 --- a/front-end-tools/src/Main.tsx +++ b/front-end-tools/src/Main.tsx @@ -22,6 +22,7 @@ import { import { WalletConnectionTypeButton } from './WalletConnectorTypeButton'; import { initialize, deploy } from './writing_to_blockchain'; +import { read } from './reading_from_blockchain'; import { BROWSER_WALLET, REFRESH_INTERVAL, EXAMPLE_ARRAYS, EXAMPLE_JSON_OBJECT } from './constants'; @@ -87,6 +88,11 @@ export default function Main(props: ConnectionProps) { const [uploadedModuleSchemaBase64, setUploadedModuleSchemaBase64] = useState(''); const [dropDown, setDropDown] = useState('number'); const [smartContractIndex, setSmartContractIndex] = useState(''); + const [smartContractIndexInputField, setSmartContractIndexInputFiled] = useState(1999n); + const [entryPoint, setEntryPoint] = useState(''); + const [returnValue, setReturnValue] = useState(''); + const [readError, setReadError] = useState(''); + const [maxContractExecutionEnergy, setMaxContractExecutionEnergy] = useState(''); const [useModuleFromStep1, setUseModuleFromStep1] = useState(false); const [contracts, setContracts] = useState([]); @@ -106,6 +112,7 @@ export default function Main(props: ConnectionProps) { const useModuleReferenceFromStep1Ref = useRef(null); const moduleReferenceRef = useRef(null); const inputParameterFieldRef = useRef(null); + const smartContractIndexRef = useRef(null); function arraysEqual(a: Uint8Array, b: Uint8Array) { if (a === b) return true; @@ -167,6 +174,16 @@ export default function Main(props: ConnectionProps) { setCCDAmount(target.value); }, []); + const changeSmartContractHandler = useCallback((event: ChangeEvent) => { + const target = event.target as HTMLTextAreaElement; + setSmartContractIndexInputFiled(BigInt(target.value)); + }, []); + + const changeEntryPointHandler = useCallback((event: ChangeEvent) => { + const target = event.target as HTMLTextAreaElement; + setEntryPoint(target.value); + }, []); + const changeMaxExecutionEnergyHandler = useCallback((event: ChangeEvent) => { const target = event.target as HTMLTextAreaElement; setMaxContractExecutionEnergy(target.value); @@ -1094,6 +1111,263 @@ export default function Main(props: ConnectionProps) { )} + {/* Additional helpers: */} + + + {useModuleFromStep1 && + displayContracts.length > 0 && + (moduleReferenceDeployed !== '' || moduleReferenceCalculated !== '') ? ( + + ) : ( + + )} + +
+
+ +
+
+ +
+ {hasInputParameter && ( +
+ {!useModuleFromStep1 && uploadedModuleSchemaBase64 && ( +
+ Schema in base64: +
{uploadedModuleSchemaBase64.toString().slice(0, 30)} ...
+
+ )} + {uploadError2 !== '' && ( +
+ Error: {uploadError2}. +
+ )} + {schemaError !== '' && ( +
+ Error: {schemaError}. +
+ )} + {inputParameterTemplate && ( +
+ Input Parameter Template: +
+                                                    {JSON.stringify(JSON.parse(inputParameterTemplate), undefined, 2)}
+                                                
+
+ )} + +
+ {(dropDown === 'object' || dropDown === 'array') && ( + + )} + {(dropDown === 'string' || dropDown === 'number') && ( + + )} + {parsingError && ( +
+ Error: {parsingError}. +
+ )} +
+ )} +
+
+ +
+
+ {returnValue && ( +
+ Read value: +
{returnValue}
+
+ )} + {readError && ( +
+ Error: {readError}. +
+ )} +
+ + +
Date: Thu, 12 Oct 2023 15:33:58 +0300 Subject: [PATCH 02/47] Add support for input parameter when querying data from the blockchain --- front-end-tools/src/Main.tsx | 82 +++++++++++++------ .../src/reading_from_blockchain.ts | 71 ++++++++++++++-- 2 files changed, 120 insertions(+), 33 deletions(-) diff --git a/front-end-tools/src/Main.tsx b/front-end-tools/src/Main.tsx index baee8e80..25c276cb 100644 --- a/front-end-tools/src/Main.tsx +++ b/front-end-tools/src/Main.tsx @@ -18,6 +18,7 @@ import { sha256, toBuffer, getInitContractParameterSchema, + getUpdateContractParameterSchema, } from '@concordium/web-sdk'; import { WalletConnectionTypeButton } from './WalletConnectorTypeButton'; @@ -92,6 +93,7 @@ export default function Main(props: ConnectionProps) { const [entryPoint, setEntryPoint] = useState(''); const [returnValue, setReturnValue] = useState(''); const [readError, setReadError] = useState(''); + const [entryPointTemplate, setEntryPointTemplate] = useState(''); const [maxContractExecutionEnergy, setMaxContractExecutionEnergy] = useState(''); const [useModuleFromStep1, setUseModuleFromStep1] = useState(false); @@ -113,6 +115,7 @@ export default function Main(props: ConnectionProps) { const moduleReferenceRef = useRef(null); const inputParameterFieldRef = useRef(null); const smartContractIndexRef = useRef(null); + const inputParameterReadTextAreaRef = useRef(null); function arraysEqual(a: Uint8Array, b: Uint8Array) { if (a === b) return true; @@ -366,39 +369,59 @@ export default function Main(props: ConnectionProps) { useEffect(() => { setSchemaError(''); setInputParameterTemplate(''); + setEntryPointTemplate(''); - let template = ''; + let initTemplate = ''; + let receiveTemplate = ''; if (contractName !== '' && (useModuleFromStep1 || uploadedModuleSchemaBase64 !== '')) { try { + const updateContractParameterSchemaBuffer = getUpdateContractParameterSchema( + toBuffer(useModuleFromStep1 ? embeddedModuleSchemaBase64 : uploadedModuleSchemaBase64, 'base64'), + contractName, + entryPoint + ); + + receiveTemplate = displayTypeSchemaTemplate(updateContractParameterSchemaBuffer); + + setEntryPointTemplate(receiveTemplate); + const inputParamterTypeSchemaBuffer = getInitContractParameterSchema( toBuffer(useModuleFromStep1 ? embeddedModuleSchemaBase64 : uploadedModuleSchemaBase64, 'base64'), contractName, 2 ); - template = displayTypeSchemaTemplate(inputParamterTypeSchemaBuffer); + initTemplate = displayTypeSchemaTemplate(inputParamterTypeSchemaBuffer); - setInputParameterTemplate(template); + setInputParameterTemplate(initTemplate); } catch (e) { if (useModuleFromStep1) { setSchemaError( - `Could not get embedded input parameter schema from the uploaded module. \nUncheck "Use Module from Step 1" checkbox to manually upload a schema. Original error: ${e}` + `Could not get embedded schema from the uploaded module. \nUncheck "Use Module from Step 1" checkbox to manually upload a schema. Original error: ${e}` ); } else { - setSchemaError(`Could not get input parameter schema from uploaded schema. Original error: ${e}`); + setSchemaError(`Could not get schema from uploaded schema. Original error: ${e}`); } } } if (dropDown === 'array') { const element = inputParameterTextAreaRef.current as unknown as HTMLSelectElement; - element.value = getArrayExample(template); + element.value = getArrayExample(initTemplate); } else if (dropDown === 'object') { const element = inputParameterTextAreaRef.current as unknown as HTMLSelectElement; - element.value = getObjectExample(template); + element.value = getObjectExample(initTemplate); + } + + if (dropDown === 'array') { + const element = inputParameterReadTextAreaRef.current as unknown as HTMLSelectElement; + element.value = getArrayExample(receiveTemplate); + } else if (dropDown === 'object') { + const element = inputParameterReadTextAreaRef.current as unknown as HTMLSelectElement; + element.value = getObjectExample(receiveTemplate); } - }, [hasInputParameter, useModuleFromStep1, contractName, uploadedModuleSchemaBase64, dropDown]); + }, [entryPoint, hasInputParameter, useModuleFromStep1, contractName, uploadedModuleSchemaBase64, dropDown]); useEffect(() => { if (connection && client && account) { @@ -901,6 +924,7 @@ export default function Main(props: ConnectionProps) { accept=".bin" onChange={async () => { setUploadError(''); + setUploadedModuleSchemaBase64(''); const hTMLInputElement = schemaFileRef.current as unknown as HTMLInputElement; @@ -1182,6 +1206,7 @@ export default function Main(props: ConnectionProps) { accept=".bin" onChange={async () => { setUploadError(''); + setUploadedModuleSchemaBase64(''); const hTMLInputElement = schemaFileRef.current as unknown as HTMLInputElement; @@ -1213,14 +1238,14 @@ export default function Main(props: ConnectionProps) { { - setParsingError(''); - setInputParameter(''); - setUploadedModuleSchemaBase64(''); - setTransactionErrorInit(''); - setDropDown('number'); + // setParsingError(''); + // setInputParameter(''); + // setUploadedModuleSchemaBase64(''); + // setTransactionErrorInit(''); + // setDropDown('number'); setHasInputParameter(!hasInputParameter); - setInputParameterTemplate(''); - setSchemaError(''); + // setInputParameterTemplate(''); + // setSchemaError(''); }} /> {' Has Input Parameter'} @@ -1234,6 +1259,7 @@ export default function Main(props: ConnectionProps) {
{uploadedModuleSchemaBase64.toString().slice(0, 30)} ...
)} +
{uploadError2 !== '' && (
Error: {uploadError2}. @@ -1244,11 +1270,11 @@ export default function Main(props: ConnectionProps) { Error: {schemaError}.
)} - {inputParameterTemplate && ( + {entryPointTemplate && (
- Input Parameter Template: + Parameter Template:
-                                                    {JSON.stringify(JSON.parse(inputParameterTemplate), undefined, 2)}
+                                                    {JSON.stringify(JSON.parse(entryPointTemplate), undefined, 2)}
                                                 
)} @@ -1275,20 +1301,20 @@ export default function Main(props: ConnectionProps) {
{dropDown === 'array' && ( )} {dropDown === 'object' && ( )} @@ -1327,7 +1353,11 @@ export default function Main(props: ConnectionProps) { contractName, smartContractIndexInputField, entryPoint, - uploadedModuleSchemaBase64 // view_return_value_schema, + uploadedModuleSchemaBase64, + inputParameter, + dropDown, + hasInputParameter, + useModuleFromStep1 ); promise @@ -1344,7 +1374,7 @@ export default function Main(props: ConnectionProps) { {returnValue && (
Read value: -
{returnValue}
+
{JSON.stringify(JSON.parse(returnValue), undefined, 2)}
)} {readError && ( diff --git a/front-end-tools/src/reading_from_blockchain.ts b/front-end-tools/src/reading_from_blockchain.ts index 925a797a..ddb6270e 100644 --- a/front-end-tools/src/reading_from_blockchain.ts +++ b/front-end-tools/src/reading_from_blockchain.ts @@ -1,4 +1,10 @@ -import { toBuffer, deserializeTypeValue, ConcordiumGRPCClient, AccountAddress } from '@concordium/web-sdk'; +import { + toBuffer, + ConcordiumGRPCClient, + AccountAddress, + deserializeReceiveReturnValue, + serializeUpdateContractParameters, +} from '@concordium/web-sdk'; import { CONTRACT_SUB_INDEX } from './constants'; @@ -7,15 +13,60 @@ export async function read( contractName: string, contractIndex: bigint, entryPoint: string, - module_schema: string | undefined + moduleSchema: string | undefined, + inputParameter: string, + dropDown: string, + hasInputParameter: boolean, + useModuleFromStep1: boolean ) { if (rpcClient === undefined) { throw new Error(`rpcClient undefined`); } + let param = toBuffer('', 'hex'); + + if (hasInputParameter) { + if (!useModuleFromStep1 && moduleSchema === undefined) { + throw new Error(`Set schema`); + } else if (useModuleFromStep1 && moduleSchema === undefined) { + throw new Error(`No embedded module schema found in module`); + } + + let inputParameterFormated; + + if (hasInputParameter) { + switch (dropDown) { + case 'number': + inputParameterFormated = Number(inputParameter); + break; + case 'string': + inputParameterFormated = inputParameter; + break; + case 'object': + inputParameterFormated = JSON.parse(inputParameter); + break; + case 'array': + inputParameterFormated = JSON.parse(inputParameter); + break; + default: + throw new Error(`Dropdown option does not exist`); + } + } + + if (moduleSchema !== undefined) { + param = serializeUpdateContractParameters( + contractName, + entryPoint, + inputParameterFormated, + toBuffer(moduleSchema, 'base64') + ); + } + } + const res = await rpcClient.invokeContract({ method: `${contractName}.${entryPoint}`, contract: { index: contractIndex, subindex: CONTRACT_SUB_INDEX }, + parameter: param, }); if (!res || res.tag === 'failure' || !res.returnValue) { @@ -24,19 +75,25 @@ export async function read( ); } - if (module_schema === undefined || module_schema === '') { + if (moduleSchema === undefined || moduleSchema === '') { // If no schema is provided return the raw bytes - return res.returnValue; + return JSON.stringify(res.returnValue); } + // If schema is provided deserialize return value - const state = deserializeTypeValue(toBuffer(res.returnValue, 'hex'), toBuffer(module_schema, 'base64')); + const returnValue = deserializeReceiveReturnValue( + toBuffer(res.returnValue, 'hex'), + toBuffer(moduleSchema, 'base64'), + contractName, + entryPoint + ); - if (state === undefined) { + if (returnValue === undefined) { throw new Error( `Deserializing the returnValue from the '${contractName}.${entryPoint}' method of contract '${contractIndex}' failed` ); } else { - return JSON.stringify(state); + return JSON.stringify(returnValue); } } From 7af8a553e866732f93918f558089e23f64b0960e Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Sun, 15 Oct 2023 12:52:06 +0300 Subject: [PATCH 03/47] Add write transaction flow --- front-end-tools/src/Main.tsx | 304 ++++++++++++++++++- front-end-tools/src/writing_to_blockchain.ts | 82 +++++ 2 files changed, 381 insertions(+), 5 deletions(-) diff --git a/front-end-tools/src/Main.tsx b/front-end-tools/src/Main.tsx index 25c276cb..913d637e 100644 --- a/front-end-tools/src/Main.tsx +++ b/front-end-tools/src/Main.tsx @@ -22,7 +22,7 @@ import { } from '@concordium/web-sdk'; import { WalletConnectionTypeButton } from './WalletConnectorTypeButton'; -import { initialize, deploy } from './writing_to_blockchain'; +import { initialize, deploy, write } from './writing_to_blockchain'; import { read } from './reading_from_blockchain'; import { BROWSER_WALLET, REFRESH_INTERVAL, EXAMPLE_ARRAYS, EXAMPLE_JSON_OBJECT } from './constants'; @@ -60,6 +60,8 @@ export default function Main(props: ConnectionProps) { const [viewErrorModuleReference, setViewErrorModuleReference] = useState(''); const [transactionErrorDeploy, setTransactionErrorDeploy] = useState(''); const [transactionErrorInit, setTransactionErrorInit] = useState(''); + const [transactionErrorUpdate, setTransactionErrorUpdate] = useState(''); + const [uploadError, setUploadError] = useState(''); const [uploadError2, setUploadError2] = useState(''); const [parsingError, setParsingError] = useState(''); @@ -79,6 +81,7 @@ export default function Main(props: ConnectionProps) { const [txHashDeploy, setTxHashDeploy] = useState(''); const [txHashInit, setTxHashInit] = useState(''); + const [txHashUpdate, setTxHashUpdate] = useState(''); const [accountBalance, setAccountBalance] = useState(''); const [inputParameter, setInputParameter] = useState(''); @@ -1385,18 +1388,309 @@ export default function Main(props: ConnectionProps) { + {useModuleFromStep1 && + displayContracts.length > 0 && + (moduleReferenceDeployed !== '' || moduleReferenceCalculated !== '') ? ( + + ) : ( + + )} + + +
+
+
+ +
+ {isPayable && ( +
+ +
+ )} +
+
+ +
+ {hasInputParameter && ( +
+ + + {!useModuleFromStep1 && uploadedModuleSchemaBase64 && ( + <> +
+
+
+ Schema in base64: +
{uploadedModuleSchemaBase64.toString().slice(0, 30)} ...
+
+ + )} +
+ {uploadError2 !== '' && ( +
+ Error: {uploadError2}. +
+ )} + {schemaError !== '' && ( +
+ Error: {schemaError}. +
+ )} + {entryPointTemplate && ( +
+ Parameter Template: +
+                                                    {JSON.stringify(JSON.parse(entryPointTemplate), undefined, 2)}
+                                                
+
+ )} + +
+ {(dropDown === 'object' || dropDown === 'array') && ( + + )} + {(dropDown === 'string' || dropDown === 'number') && ( + + )} + {parsingError && ( +
+ Error: {parsingError}. +
+ )} +
+ )} +
+
+ +
+
+ {!txHashUpdate && transactionErrorUpdate && ( +
+ Error: {transactionErrorUpdate}. +
+ )} + {txHashUpdate && ( + <> +
+ Transaction hash:{' '} + + {txHashUpdate} + +
+
+
+ CCDScan will take a moment to pick up the above transaction, hence the above + link will work in a bit. +
+ + )}
Date: Mon, 16 Oct 2023 00:03:00 +0300 Subject: [PATCH 04/47] Remove placeholder values --- front-end-tools/src/Main.tsx | 125 ++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 47 deletions(-) diff --git a/front-end-tools/src/Main.tsx b/front-end-tools/src/Main.tsx index 913d637e..2a6c0ce7 100644 --- a/front-end-tools/src/Main.tsx +++ b/front-end-tools/src/Main.tsx @@ -85,20 +85,22 @@ export default function Main(props: ConnectionProps) { const [accountBalance, setAccountBalance] = useState(''); const [inputParameter, setInputParameter] = useState(''); - const [contractName, setContractName] = useState(''); - const [moduleReference, setModuleReference] = useState(''); - const [cCDAmount, setCCDAmount] = useState(''); + const [contractName, setContractName] = useState('myContract'); + const [moduleReference, setModuleReference] = useState( + '91225f9538ac2903466cc4ab07b6eb607a2cd349549f357dfdf4e6042dde0693' + ); + const [cCDAmount, setCCDAmount] = useState('0'); const [base64Module, setBase64Module] = useState(''); const [uploadedModuleSchemaBase64, setUploadedModuleSchemaBase64] = useState(''); const [dropDown, setDropDown] = useState('number'); const [smartContractIndex, setSmartContractIndex] = useState(''); const [smartContractIndexInputField, setSmartContractIndexInputFiled] = useState(1999n); - const [entryPoint, setEntryPoint] = useState(''); + const [entryPoint, setEntryPoint] = useState('view'); const [returnValue, setReturnValue] = useState(''); const [readError, setReadError] = useState(''); const [entryPointTemplate, setEntryPointTemplate] = useState(''); - const [maxContractExecutionEnergy, setMaxContractExecutionEnergy] = useState(''); + const [maxContractExecutionEnergy, setMaxContractExecutionEnergy] = useState('30000'); const [useModuleFromStep1, setUseModuleFromStep1] = useState(false); const [contracts, setContracts] = useState([]); const [displayContracts, setDisplayContracts] = useState([]); @@ -106,8 +108,11 @@ export default function Main(props: ConnectionProps) { const [embeddedModuleSchemaBase64, setEmbeddedModuleSchemaBase64] = useState(''); const [isWaitingForTransaction, setWaitingForUser] = useState(false); - const [hasInputParameter, setHasInputParameter] = useState(false); - const [isPayable, setIsPayable] = useState(false); + const [hasInputParameterInitFunction, setHasInputParameterInitFunction] = useState(false); + const [hasInputParameterReadFunction, setHasInputParameterReadFunction] = useState(false); + const [hasInputParameterWriteFunction, setHasInputParameterWriteFunction] = useState(false); + const [isPayableInitFunction, setIsPayableInitFunction] = useState(false); + const [isPayableWriteFunction, setIsPayableWriteFunction] = useState(false); const moduleFileRef = useRef(null); const inputParameterDropDownRef = useRef(null); @@ -362,12 +367,28 @@ export default function Main(props: ConnectionProps) { }, [moduleReference, moduleReferenceCalculated]); useEffect(() => { - if (inputParameterTemplate !== '' && hasInputParameter === false) { + if (inputParameterTemplate !== '' && hasInputParameterInitFunction === false) { + setShouldWarnInputParameterInSchemaIgnored(true); + } else { + setShouldWarnInputParameterInSchemaIgnored(false); + } + }, [inputParameterTemplate, hasInputParameterInitFunction]); + + useEffect(() => { + if (inputParameterTemplate !== '' && hasInputParameterReadFunction === false) { + setShouldWarnInputParameterInSchemaIgnored(true); + } else { + setShouldWarnInputParameterInSchemaIgnored(false); + } + }, [inputParameterTemplate, hasInputParameterReadFunction]); + + useEffect(() => { + if (inputParameterTemplate !== '' && hasInputParameterWriteFunction === false) { setShouldWarnInputParameterInSchemaIgnored(true); } else { setShouldWarnInputParameterInSchemaIgnored(false); } - }, [inputParameterTemplate, hasInputParameter]); + }, [inputParameterTemplate, hasInputParameterWriteFunction]); useEffect(() => { setSchemaError(''); @@ -424,7 +445,16 @@ export default function Main(props: ConnectionProps) { const element = inputParameterReadTextAreaRef.current as unknown as HTMLSelectElement; element.value = getObjectExample(receiveTemplate); } - }, [entryPoint, hasInputParameter, useModuleFromStep1, contractName, uploadedModuleSchemaBase64, dropDown]); + }, [ + entryPoint, + hasInputParameterInitFunction, + hasInputParameterReadFunction, + hasInputParameterWriteFunction, + useModuleFromStep1, + contractName, + uploadedModuleSchemaBase64, + dropDown, + ]); useEffect(() => { if (connection && client && account) { @@ -813,7 +843,7 @@ export default function Main(props: ConnectionProps) { ref={moduleReferenceRef} disabled={useModuleFromStep1} type="text" - placeholder="91225f9538ac2903466cc4ab07b6eb607a2cd349549f357dfdf4e6042dde0693" + value={moduleReference} onChange={changeModuleReferenceHandler} /> @@ -824,7 +854,7 @@ export default function Main(props: ConnectionProps) { className="inputFieldStyle" id="maxContractExecutionEnergy" type="text" - placeholder="30000" + value={maxContractExecutionEnergy} onChange={changeMaxExecutionEnergyHandler} /> @@ -854,7 +884,7 @@ export default function Main(props: ConnectionProps) { className="inputFieldStyle" id="contractName" type="text" - placeholder="myContract" + value={contractName} onChange={changeContractNameHandler} /> @@ -871,13 +901,13 @@ export default function Main(props: ConnectionProps) { { - setIsPayable(!isPayable); + setIsPayableInitFunction(!isPayableInitFunction); }} /> {' Is Payable'} - {isPayable && ( + {isPayableInitFunction && (
@@ -903,15 +933,14 @@ export default function Main(props: ConnectionProps) { setUploadedModuleSchemaBase64(''); setTransactionErrorInit(''); setDropDown('number'); - setHasInputParameter(!hasInputParameter); + setHasInputParameterInitFunction(!hasInputParameterInitFunction); setInputParameterTemplate(''); setSchemaError(''); }} /> {' Has Input Parameter'} -
- {hasInputParameter && ( + {hasInputParameterInitFunction && (
{!useModuleFromStep1 && ( <> @@ -976,7 +1005,6 @@ export default function Main(props: ConnectionProps) { Error: {schemaError}.
)} -
{inputParameterTemplate && (
Input Parameter Template: @@ -1064,7 +1092,7 @@ export default function Main(props: ConnectionProps) { moduleReference, inputParameter, contractName, - hasInputParameter, + hasInputParameterInitFunction, useModuleFromStep1, useModuleFromStep1 ? embeddedModuleSchemaBase64 @@ -1145,11 +1173,11 @@ export default function Main(props: ConnectionProps) {
@@ -1179,7 +1207,7 @@ export default function Main(props: ConnectionProps) { className="inputFieldStyle" id="contractName" type="text" - placeholder="myContract" + value={contractName} onChange={changeContractNameHandler} /> @@ -1191,7 +1219,7 @@ export default function Main(props: ConnectionProps) { className="inputFieldStyle" id="entryPoint" type="text" - placeholder="view" + value={entryPoint} onChange={changeEntryPointHandler} /> @@ -1246,15 +1274,14 @@ export default function Main(props: ConnectionProps) { // setUploadedModuleSchemaBase64(''); // setTransactionErrorInit(''); // setDropDown('number'); - setHasInputParameter(!hasInputParameter); + setHasInputParameterReadFunction(!hasInputParameterReadFunction); // setInputParameterTemplate(''); // setSchemaError(''); }} /> {' Has Input Parameter'} -
- {hasInputParameter && ( + {hasInputParameterReadFunction && (
{!useModuleFromStep1 && uploadedModuleSchemaBase64 && (
@@ -1262,7 +1289,6 @@ export default function Main(props: ConnectionProps) {
{uploadedModuleSchemaBase64.toString().slice(0, 30)} ...
)} -
{uploadError2 !== '' && (
Error: {uploadError2}. @@ -1274,12 +1300,16 @@ export default function Main(props: ConnectionProps) {
)} {entryPointTemplate && ( -
- Parameter Template: -
-                                                    {JSON.stringify(JSON.parse(entryPointTemplate), undefined, 2)}
-                                                
-
+ <> +
+
+
+ Parameter Template: +
+                                                        {JSON.stringify(JSON.parse(entryPointTemplate), undefined, 2)}
+                                                    
+
+ )} @@ -1426,7 +1456,7 @@ export default function Main(props: ConnectionProps) { className="inputFieldStyle" id="contractName" type="text" - placeholder="myContract" + value={contractName} onChange={changeContractNameHandler} /> @@ -1438,7 +1468,7 @@ export default function Main(props: ConnectionProps) { className="inputFieldStyle" id="entryPoint" type="text" - placeholder="set" + value={entryPoint} onChange={changeEntryPointHandler} /> @@ -1449,7 +1479,7 @@ export default function Main(props: ConnectionProps) { className="inputFieldStyle" id="maxContractExecutionEnergy" type="text" - placeholder="30000" + value={maxContractExecutionEnergy} onChange={changeMaxExecutionEnergyHandler} /> @@ -1460,13 +1490,13 @@ export default function Main(props: ConnectionProps) { { - setIsPayable(!isPayable); + setIsPayableWriteFunction(!isPayableWriteFunction); }} /> {' Is Payable'}
- {isPayable && ( + {isPayableWriteFunction && (
@@ -1492,7 +1522,7 @@ export default function Main(props: ConnectionProps) { // setUploadedModuleSchemaBase64(''); // setTransactionErrorInit(''); // setDropDown('number'); - setHasInputParameter(!hasInputParameter); + setHasInputParameterWriteFunction(!hasInputParameterWriteFunction); // setInputParameterTemplate(''); // setSchemaError(''); }} @@ -1500,7 +1530,7 @@ export default function Main(props: ConnectionProps) { {' Has Input Parameter'}
- {hasInputParameter && ( + {hasInputParameterWriteFunction && (
Schema in base64:
{uploadedModuleSchemaBase64.toString().slice(0, 30)} ...
@@ -1646,7 +1677,7 @@ export default function Main(props: ConnectionProps) { inputParameter, contractName, entryPoint, - hasInputParameter, + hasInputParameterWriteFunction, useModuleFromStep1, uploadedModuleSchemaBase64, dropDown, From 601a8398e2c09550c40c2c549b5c88ac53f2a223 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Mon, 16 Oct 2023 10:50:50 +0300 Subject: [PATCH 05/47] Use undefined instead of empty strings for defaults --- front-end-tools/src/Main.tsx | 270 +++++++++--------- .../src/reading_from_blockchain.ts | 15 +- front-end-tools/src/writing_to_blockchain.ts | 174 +++++------ 3 files changed, 239 insertions(+), 220 deletions(-) diff --git a/front-end-tools/src/Main.tsx b/front-end-tools/src/Main.tsx index 2a6c0ce7..b483143a 100644 --- a/front-end-tools/src/Main.tsx +++ b/front-end-tools/src/Main.tsx @@ -56,56 +56,56 @@ export default function Main(props: ConnectionProps) { const { connect, isConnecting, connectError } = useConnect(activeConnector, setConnection); const client = useGrpcClient(isTestnet ? TESTNET : MAINNET); - const [viewErrorAccountInfo, setViewErrorAccountInfo] = useState(''); - const [viewErrorModuleReference, setViewErrorModuleReference] = useState(''); - const [transactionErrorDeploy, setTransactionErrorDeploy] = useState(''); - const [transactionErrorInit, setTransactionErrorInit] = useState(''); - const [transactionErrorUpdate, setTransactionErrorUpdate] = useState(''); - - const [uploadError, setUploadError] = useState(''); - const [uploadError2, setUploadError2] = useState(''); - const [parsingError, setParsingError] = useState(''); - const [smartContractIndexError, setSmartContractIndexError] = useState(''); - const [moduleReferenceError, setModuleReferenceError] = useState(''); - const [moduleReferenceLengthError, setModuleReferenceLengthError] = useState(''); - const [schemaError, setSchemaError] = useState(''); + const [viewErrorAccountInfo, setViewErrorAccountInfo] = useState(undefined); + const [viewErrorModuleReference, setViewErrorModuleReference] = useState(undefined); + const [transactionErrorDeploy, setTransactionErrorDeploy] = useState(undefined); + const [transactionErrorInit, setTransactionErrorInit] = useState(undefined); + const [transactionErrorUpdate, setTransactionErrorUpdate] = useState(undefined); + + const [uploadError, setUploadError] = useState(undefined); + const [uploadError2, setUploadError2] = useState(undefined); + const [parsingError, setParsingError] = useState(undefined); + const [smartContractIndexError, setSmartContractIndexError] = useState(undefined); + const [moduleReferenceError, setModuleReferenceError] = useState(undefined); + const [moduleReferenceLengthError, setModuleReferenceLengthError] = useState(undefined); + const [schemaError, setSchemaError] = useState(undefined); const [accountExistsOnNetwork, setAccountExistsOnNetwork] = useState(true); - const [moduleReferenceCalculated, setModuleReferenceCalculated] = useState(''); + const [moduleReferenceCalculated, setModuleReferenceCalculated] = useState(undefined); const [isModuleReferenceAlreadyDeployedStep1, setIsModuleReferenceAlreadyDeployedStep1] = useState(false); const [isModuleReferenceAlreadyDeployedStep2, setIsModuleReferenceAlreadyDeployedStep2] = useState(false); - const [moduleReferenceDeployed, setModuleReferenceDeployed] = useState(''); + const [moduleReferenceDeployed, setModuleReferenceDeployed] = useState(undefined); const [shouldWarnDifferenceModuleReferences, setShouldWarnDifferenceModuleReferences] = useState(false); const [shouldWarnInputParameterInSchemaIgnored, setShouldWarnInputParameterInSchemaIgnored] = useState(false); - const [txHashDeploy, setTxHashDeploy] = useState(''); - const [txHashInit, setTxHashInit] = useState(''); - const [txHashUpdate, setTxHashUpdate] = useState(''); + const [txHashDeploy, setTxHashDeploy] = useState(undefined); + const [txHashInit, setTxHashInit] = useState(undefined); + const [txHashUpdate, setTxHashUpdate] = useState(undefined); - const [accountBalance, setAccountBalance] = useState(''); - const [inputParameter, setInputParameter] = useState(''); - const [contractName, setContractName] = useState('myContract'); - const [moduleReference, setModuleReference] = useState( + const [accountBalance, setAccountBalance] = useState(undefined); + const [inputParameter, setInputParameter] = useState(undefined); + const [contractName, setContractName] = useState('myContract'); + const [moduleReference, setModuleReference] = useState( '91225f9538ac2903466cc4ab07b6eb607a2cd349549f357dfdf4e6042dde0693' ); const [cCDAmount, setCCDAmount] = useState('0'); - const [base64Module, setBase64Module] = useState(''); - const [uploadedModuleSchemaBase64, setUploadedModuleSchemaBase64] = useState(''); + const [base64Module, setBase64Module] = useState(undefined); + const [uploadedModuleSchemaBase64, setUploadedModuleSchemaBase64] = useState(undefined); const [dropDown, setDropDown] = useState('number'); - const [smartContractIndex, setSmartContractIndex] = useState(''); + const [smartContractIndex, setSmartContractIndex] = useState(undefined); const [smartContractIndexInputField, setSmartContractIndexInputFiled] = useState(1999n); const [entryPoint, setEntryPoint] = useState('view'); - const [returnValue, setReturnValue] = useState(''); - const [readError, setReadError] = useState(''); - const [entryPointTemplate, setEntryPointTemplate] = useState(''); + const [returnValue, setReturnValue] = useState(undefined); + const [readError, setReadError] = useState(undefined); + const [entryPointTemplate, setEntryPointTemplate] = useState(undefined); const [maxContractExecutionEnergy, setMaxContractExecutionEnergy] = useState('30000'); const [useModuleFromStep1, setUseModuleFromStep1] = useState(false); const [contracts, setContracts] = useState([]); const [displayContracts, setDisplayContracts] = useState([]); - const [inputParameterTemplate, setInputParameterTemplate] = useState(''); - const [embeddedModuleSchemaBase64, setEmbeddedModuleSchemaBase64] = useState(''); + const [inputParameterTemplate, setInputParameterTemplate] = useState(undefined); + const [embeddedModuleSchemaBase64, setEmbeddedModuleSchemaBase64] = useState(undefined); const [isWaitingForTransaction, setWaitingForUser] = useState(false); const [hasInputParameterInitFunction, setHasInputParameterInitFunction] = useState(false); @@ -136,20 +136,20 @@ export default function Main(props: ConnectionProps) { return true; } - function getObjectExample(template: string) { - return template !== '' + function getObjectExample(template: string | undefined) { + return template !== undefined ? JSON.stringify(JSON.parse(template), undefined, 2) : JSON.stringify(EXAMPLE_JSON_OBJECT, undefined, 2); } - function getArrayExample(template: string) { - return template !== '' ? JSON.stringify(JSON.parse(template), undefined, 2) : EXAMPLE_ARRAYS; + function getArrayExample(template: string | undefined) { + return template !== undefined ? JSON.stringify(JSON.parse(template), undefined, 2) : EXAMPLE_ARRAYS; } const changeModuleReferenceHandler = useCallback((event: ChangeEvent) => { - setTransactionErrorInit(''); - setModuleReferenceLengthError(''); - setModuleReference(''); + setTransactionErrorInit(undefined); + setModuleReferenceLengthError(undefined); + setModuleReference(undefined); const target = event.target as HTMLTextAreaElement; @@ -163,9 +163,9 @@ export default function Main(props: ConnectionProps) { }, []); const changeInputParameterDropDownHandler = useCallback(() => { - setParsingError(''); - setInputParameter(''); - setTransactionErrorInit(''); + setParsingError(undefined); + setInputParameter(undefined); + setTransactionErrorInit(undefined); const e = inputParameterDropDownRef.current as unknown as HTMLSelectElement; const sel = e.selectedIndex; const { value } = e.options[sel]; @@ -173,7 +173,7 @@ export default function Main(props: ConnectionProps) { }, []); const changeSmarContractDropDownHandler = useCallback(() => { - setTransactionErrorInit(''); + setTransactionErrorInit(undefined); const e = contractNameDropDownRef.current as unknown as HTMLSelectElement; const sel = e.selectedIndex; const { value } = e.options[sel]; @@ -201,21 +201,21 @@ export default function Main(props: ConnectionProps) { }, []); const changeContractNameHandler = useCallback((event: ChangeEvent) => { - setTransactionErrorInit(''); + setTransactionErrorInit(undefined); const target = event.target as HTMLTextAreaElement; setContractName(target.value); }, []); const changeInputParameterFieldHandler = useCallback((event: ChangeEvent) => { - setParsingError(''); - setTransactionErrorInit(''); + setParsingError(undefined); + setTransactionErrorInit(undefined); const target = event.target as HTMLTextAreaElement; setInputParameter(target.value); }, []); const changeInputParameterTextAreaHandler = useCallback((event: ChangeEvent) => { - setParsingError(''); - setTransactionErrorInit(''); + setParsingError(undefined); + setTransactionErrorInit(undefined); const inputTextArea = inputParameterTextAreaRef.current as unknown as HTMLTextAreaElement; inputTextArea?.setAttribute('style', `height:${inputTextArea.scrollHeight}px;overflow-y:hidden;`); const target = event.target as HTMLTextAreaElement; @@ -245,10 +245,10 @@ export default function Main(props: ConnectionProps) { } else { setAccountExistsOnNetwork(false); } - setViewErrorAccountInfo(''); + setViewErrorAccountInfo(undefined); }) .catch((e) => { - setAccountBalance(''); + setAccountBalance(undefined); setViewErrorAccountInfo((e as Error).message.replaceAll('%20', ' ')); setAccountExistsOnNetwork(false); }); @@ -260,14 +260,14 @@ export default function Main(props: ConnectionProps) { // Refresh moduleReference periodically. // eslint-disable-next-line consistent-return useEffect(() => { - if (connection && client && account && txHashDeploy !== '') { + if (connection && client && account && txHashDeploy !== undefined) { const interval = setInterval(() => { console.log('refreshing_moduleReference'); client .getBlockItemStatus(txHashDeploy) .then((report) => { if (report !== undefined) { - setViewErrorModuleReference(''); + setViewErrorModuleReference(undefined); if ( report.status === 'finalized' && report.outcome.summary.type === TransactionSummaryType.AccountTransaction && @@ -278,7 +278,7 @@ export default function Main(props: ConnectionProps) { } }) .catch((e) => { - setModuleReferenceDeployed(''); + setModuleReferenceDeployed(undefined); setViewErrorModuleReference((e as Error).message); }); }, REFRESH_INTERVAL.asMilliseconds()); @@ -289,14 +289,14 @@ export default function Main(props: ConnectionProps) { // Refresh smartContractIndex periodically. // eslint-disable-next-line consistent-return useEffect(() => { - if (connection && client && account && txHashInit !== '') { + if (connection && client && account && txHashInit !== undefined) { const interval = setInterval(() => { console.log('refreshing_smartContractIndex'); client .getBlockItemStatus(txHashInit) .then((report) => { if (report !== undefined) { - setViewErrorModuleReference(''); + setViewErrorModuleReference(undefined); if (report.status === 'finalized') { if ( report.outcome.summary.type === TransactionSummaryType.AccountTransaction && @@ -312,7 +312,7 @@ export default function Main(props: ConnectionProps) { } }) .catch((e) => { - setModuleReferenceDeployed(''); + setModuleReferenceDeployed(undefined); setViewErrorModuleReference((e as Error).message); }); }, REFRESH_INTERVAL.asMilliseconds()); @@ -356,8 +356,8 @@ export default function Main(props: ConnectionProps) { useEffect(() => { if ( - moduleReference !== '' && - moduleReferenceCalculated !== '' && + moduleReference !== undefined && + moduleReferenceCalculated !== undefined && moduleReferenceCalculated !== moduleReference ) { setShouldWarnDifferenceModuleReferences(true); @@ -367,7 +367,7 @@ export default function Main(props: ConnectionProps) { }, [moduleReference, moduleReferenceCalculated]); useEffect(() => { - if (inputParameterTemplate !== '' && hasInputParameterInitFunction === false) { + if (inputParameterTemplate !== undefined && hasInputParameterInitFunction === false) { setShouldWarnInputParameterInSchemaIgnored(true); } else { setShouldWarnInputParameterInSchemaIgnored(false); @@ -375,7 +375,7 @@ export default function Main(props: ConnectionProps) { }, [inputParameterTemplate, hasInputParameterInitFunction]); useEffect(() => { - if (inputParameterTemplate !== '' && hasInputParameterReadFunction === false) { + if (inputParameterTemplate !== undefined && hasInputParameterReadFunction === false) { setShouldWarnInputParameterInSchemaIgnored(true); } else { setShouldWarnInputParameterInSchemaIgnored(false); @@ -383,7 +383,7 @@ export default function Main(props: ConnectionProps) { }, [inputParameterTemplate, hasInputParameterReadFunction]); useEffect(() => { - if (inputParameterTemplate !== '' && hasInputParameterWriteFunction === false) { + if (inputParameterTemplate !== undefined && hasInputParameterWriteFunction === false) { setShouldWarnInputParameterInSchemaIgnored(true); } else { setShouldWarnInputParameterInSchemaIgnored(false); @@ -391,17 +391,28 @@ export default function Main(props: ConnectionProps) { }, [inputParameterTemplate, hasInputParameterWriteFunction]); useEffect(() => { - setSchemaError(''); - setInputParameterTemplate(''); - setEntryPointTemplate(''); + setSchemaError(undefined); + setInputParameterTemplate(undefined); + setEntryPointTemplate(undefined); - let initTemplate = ''; - let receiveTemplate = ''; + let initTemplate; + let receiveTemplate; - if (contractName !== '' && (useModuleFromStep1 || uploadedModuleSchemaBase64 !== '')) { + if ( + contractName !== undefined && + (useModuleFromStep1 !== undefined || uploadedModuleSchemaBase64 !== undefined) + ) { try { + let schema = ''; + + const schemaFromModule = useModuleFromStep1 ? embeddedModuleSchemaBase64 : uploadedModuleSchemaBase64; + + if (schemaFromModule !== undefined) { + schema = schemaFromModule; + } + const updateContractParameterSchemaBuffer = getUpdateContractParameterSchema( - toBuffer(useModuleFromStep1 ? embeddedModuleSchemaBase64 : uploadedModuleSchemaBase64, 'base64'), + toBuffer(schema, 'base64'), contractName, entryPoint ); @@ -411,7 +422,7 @@ export default function Main(props: ConnectionProps) { setEntryPointTemplate(receiveTemplate); const inputParamterTypeSchemaBuffer = getInitContractParameterSchema( - toBuffer(useModuleFromStep1 ? embeddedModuleSchemaBase64 : uploadedModuleSchemaBase64, 'base64'), + toBuffer(schema, 'base64'), contractName, 2 ); @@ -467,11 +478,11 @@ export default function Main(props: ConnectionProps) { } else { setAccountExistsOnNetwork(false); } - setViewErrorAccountInfo(''); + setViewErrorAccountInfo(undefined); }) .catch((e) => { setViewErrorAccountInfo((e as Error).message.replaceAll('%20', ' ')); - setAccountBalance(''); + setAccountBalance(undefined); setAccountExistsOnNetwork(false); }); } @@ -554,8 +565,12 @@ export default function Main(props: ConnectionProps) {

-
Your account balance:
-
{accountBalance.replace(/(\d)(?=(\d\d\d\d\d\d)+(?!\d))/g, '$1.')} CCD
+ {accountBalance && ( + <> +
Your account balance:
+
{accountBalance.replace(/(\d)(?=(\d\d\d\d\d\d)+(?!\d))/g, '$1.')} CCD
+ + )} - {uploadError !== '' && ( + {uploadError !== undefined && (
Error: {uploadError}.
@@ -689,11 +704,11 @@ export default function Main(props: ConnectionProps) { className="btn btn-primary" type="button" onClick={() => { - setTxHashDeploy(''); - setTransactionErrorDeploy(''); + setTxHashDeploy(undefined); + setTransactionErrorDeploy(undefined); const tx = deploy(connection, account, base64Module); tx.then((txHash) => { - setModuleReferenceDeployed(''); + setModuleReferenceDeployed(undefined); setTxHashDeploy(txHash); }).catch((err: Error) => setTransactionErrorDeploy((err as Error).message) @@ -759,10 +774,10 @@ export default function Main(props: ConnectionProps) { id="useModuleReferenceFromStep1" ref={useModuleReferenceFromStep1Ref} onChange={() => { - setModuleReferenceError(''); - setModuleReference(''); - setContractName(''); - setUploadedModuleSchemaBase64(''); + setModuleReferenceError(undefined); + setModuleReference(undefined); + setContractName(undefined); + setUploadedModuleSchemaBase64(undefined); const checkboxElement = useModuleReferenceFromStep1Ref.current as unknown as HTMLInputElement; @@ -776,26 +791,21 @@ export default function Main(props: ConnectionProps) { if ( checkboxElement.checked && - moduleReferenceDeployed === '' && - moduleReferenceCalculated === '' + moduleReferenceDeployed === undefined && + moduleReferenceCalculated === undefined ) { setModuleReferenceError('Module reference is not set in step 1'); } - if ( - checkboxElement.checked && - (moduleReferenceDeployed !== '' || moduleReferenceCalculated !== '') - ) { - element.value = - moduleReferenceDeployed !== '' - ? moduleReferenceDeployed - : moduleReferenceCalculated; - - setModuleReference( - moduleReferenceDeployed !== '' - ? moduleReferenceDeployed - : moduleReferenceCalculated - ); + const newModuleReference = + moduleReferenceDeployed !== undefined + ? moduleReferenceDeployed + : moduleReferenceCalculated; + + if (checkboxElement.checked && newModuleReference !== undefined) { + element.value = newModuleReference; + + setModuleReference(newModuleReference); setDisplayContracts(contracts); setContractName(contracts[0]); @@ -860,7 +870,7 @@ export default function Main(props: ConnectionProps) { {useModuleFromStep1 && displayContracts.length > 0 && - (moduleReferenceDeployed !== '' || moduleReferenceCalculated !== '') ? ( + (moduleReferenceDeployed !== undefined || moduleReferenceCalculated !== undefined) ? ( {useModuleFromStep1 && displayContracts.length > 0 && - (moduleReferenceDeployed !== '' || moduleReferenceCalculated !== '') ? ( + (moduleReferenceDeployed !== undefined || moduleReferenceCalculated !== undefined) ? (
@@ -1309,14 +1340,18 @@ export default function Main(props: ConnectionProps) { Error: {schemaError}.
)} - {entryPointTemplate && ( + {entryPointTemplateReadFunction && ( <>

Parameter Template:
-                                                        {JSON.stringify(JSON.parse(entryPointTemplate), undefined, 2)}
+                                                        {JSON.stringify(
+                                                            JSON.parse(entryPointTemplateReadFunction),
+                                                            undefined,
+                                                            2
+                                                        )}
                                                     
@@ -1348,7 +1383,7 @@ export default function Main(props: ConnectionProps) { ref={inputParameterReadTextAreaRef} onChange={changeInputParameterTextAreaHandler} > - {getArrayExample(entryPointTemplate)} + {getArrayExample(entryPointTemplateReadFunction)} )} {dropDown === 'object' && ( @@ -1357,7 +1392,7 @@ export default function Main(props: ConnectionProps) { ref={inputParameterReadTextAreaRef} onChange={changeInputParameterTextAreaHandler} > - {getObjectExample(entryPointTemplate)} + {getObjectExample(entryPointTemplateReadFunction)} )} @@ -1395,7 +1430,7 @@ export default function Main(props: ConnectionProps) { client, contractName, smartContractIndexInputField, - entryPoint, + entryPointReadFunction, uploadedModuleSchemaBase64, inputParameter, dropDown, @@ -1478,8 +1513,8 @@ export default function Main(props: ConnectionProps) { className="inputFieldStyle" id="entryPoint" type="text" - value={entryPoint} - onChange={changeEntryPointHandler} + value={entryPointWriteFunction} + onChange={changeEntryPointWriteFunctionHandler} />
)} - {entryPointTemplate && ( + {entryPointTemplateWriteFunction && (
Parameter Template:
-                                                    {JSON.stringify(JSON.parse(entryPointTemplate), undefined, 2)}
+                                                    {JSON.stringify(
+                                                        JSON.parse(entryPointTemplateWriteFunction),
+                                                        undefined,
+                                                        2
+                                                    )}
                                                 
)} @@ -1634,20 +1673,20 @@ export default function Main(props: ConnectionProps) {
{dropDown === 'array' && ( )} {dropDown === 'object' && ( )} @@ -1686,7 +1725,7 @@ export default function Main(props: ConnectionProps) { account, inputParameter, contractName, - entryPoint, + entryPointWriteFunction, hasInputParameterWriteFunction, useModuleFromStep1, uploadedModuleSchemaBase64, diff --git a/front-end-tools/src/reading_from_blockchain.ts b/front-end-tools/src/reading_from_blockchain.ts index a9c48042..3052ec84 100644 --- a/front-end-tools/src/reading_from_blockchain.ts +++ b/front-end-tools/src/reading_from_blockchain.ts @@ -1,7 +1,6 @@ import { toBuffer, ConcordiumGRPCClient, - AccountAddress, deserializeReceiveReturnValue, serializeUpdateContractParameters, } from '@concordium/web-sdk'; @@ -37,26 +36,26 @@ export async function read( let inputParameterFormated; - if (inputParameter === undefined) { - throw new Error(`Set input parameter`); - } + if (inputParameter === undefined) { + throw new Error(`Set input parameter`); + } - switch (dropDown) { - case 'number': - inputParameterFormated = Number(inputParameter); - break; - case 'string': - inputParameterFormated = inputParameter; - break; - case 'object': - inputParameterFormated = JSON.parse(inputParameter); - break; - case 'array': - inputParameterFormated = JSON.parse(inputParameter); - break; - default: - throw new Error(`Dropdown option does not exist`); - } + switch (dropDown) { + case 'number': + inputParameterFormated = Number(inputParameter); + break; + case 'string': + inputParameterFormated = inputParameter; + break; + case 'object': + inputParameterFormated = JSON.parse(inputParameter); + break; + case 'array': + inputParameterFormated = JSON.parse(inputParameter); + break; + default: + throw new Error(`Dropdown option does not exist`); + } if (moduleSchema !== undefined) { param = serializeUpdateContractParameters( @@ -101,11 +100,3 @@ export async function read( return JSON.stringify(returnValue); } } - -export async function accountInfo(rpcClient: ConcordiumGRPCClient, account: string) { - return rpcClient.getAccountInfo(new AccountAddress(account)); -} - -// export async function smartContractInfo(rpcClient: ConcordiumGRPCClient) { -// return rpcClient.getInstanceInfo({ index: CONTRACT_INDEX, subindex: CONTRACT_SUB_INDEX }); -// } From 8eeea6ab392907222df0e3648c7956dbe957d206 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Mon, 16 Oct 2023 12:27:33 +0300 Subject: [PATCH 07/47] Change just one connect button --- front-end-tools/src/Main.tsx | 42 ++++++++-------- .../src/WalletConnectorTypeButton.tsx | 48 ------------------- 2 files changed, 22 insertions(+), 68 deletions(-) delete mode 100644 front-end-tools/src/WalletConnectorTypeButton.tsx diff --git a/front-end-tools/src/Main.tsx b/front-end-tools/src/Main.tsx index 6f7efb92..bbb305c9 100644 --- a/front-end-tools/src/Main.tsx +++ b/front-end-tools/src/Main.tsx @@ -7,6 +7,7 @@ import { useGrpcClient, TESTNET, MAINNET, + useWalletConnectorSelector, } from '@concordium/react-components'; import { Buffer } from 'buffer'; import { @@ -20,7 +21,6 @@ import { getInitContractParameterSchema, getUpdateContractParameterSchema, } from '@concordium/web-sdk'; -import { WalletConnectionTypeButton } from './WalletConnectorTypeButton'; import { initialize, deploy, write } from './writing_to_blockchain'; import { read } from './reading_from_blockchain'; @@ -48,12 +48,15 @@ interface ConnectionProps { export default function Main(props: ConnectionProps) { const { walletConnectionProps, isTestnet } = props; - const { activeConnectorType, activeConnector, activeConnectorError, connectedAccounts, genesisHashes } = walletConnectionProps; - const { connection, setConnection, account } = useConnection(connectedAccounts, genesisHashes); - const { connect, isConnecting, connectError } = useConnect(activeConnector, setConnection); + const { isConnected, select } = useWalletConnectorSelector(BROWSER_WALLET, connection, { + ...walletConnectionProps, + }); + + const { connect, connectError } = useConnect(activeConnector, setConnection); + const client = useGrpcClient(isTestnet ? TESTNET : MAINNET); const [viewErrorAccountInfo, setViewErrorAccountInfo] = useState(undefined); @@ -111,7 +114,6 @@ export default function Main(props: ConnectionProps) { const [inputParameterTemplate, setInputParameterTemplate] = useState(undefined); const [embeddedModuleSchemaBase64, setEmbeddedModuleSchemaBase64] = useState(undefined); - const [isWaitingForTransaction, setWaitingForUser] = useState(false); const [hasInputParameterInitFunction, setHasInputParameterInitFunction] = useState(false); const [hasInputParameterReadFunction, setHasInputParameterReadFunction] = useState(false); const [hasInputParameterWriteFunction, setHasInputParameterWriteFunction] = useState(false); @@ -519,23 +521,20 @@ export default function Main(props: ConnectionProps) { } }, [connection, account, client]); + useEffect(() => { + select(); + }, []); + return (

- {activeConnectorError && (

Connector Error: {activeConnectorError}.

)} - {!activeConnectorError && !isWaitingForTransaction && activeConnectorType && !activeConnector && ( + {!activeConnectorError && activeConnectorType && !activeConnector && (

Loading connector...

@@ -545,13 +544,16 @@ export default function Main(props: ConnectionProps) { Connect Error: {connectError}.

)} - {!connection && !isWaitingForTransaction && activeConnectorType && activeConnector && ( -

- -

+ {!isConnected && ( + )} {connection && !accountExistsOnNetwork && ( <> diff --git a/front-end-tools/src/WalletConnectorTypeButton.tsx b/front-end-tools/src/WalletConnectorTypeButton.tsx deleted file mode 100644 index b02cbeba..00000000 --- a/front-end-tools/src/WalletConnectorTypeButton.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React, { useCallback } from 'react'; -import { - ConnectorType, - useWalletConnectorSelector, - WalletConnection, - WalletConnectionProps, -} from '@concordium/react-components'; - -function connectorTypeStyle(isSelected: boolean, isConnected: boolean) { - if (isConnected) { - return { backgroundColor: '#823030', border: '1px solid #520C0C' }; - } - if (isSelected) { - return { backgroundColor: '#174039', border: '1px solid #0c221f' }; - } - return {}; -} - -interface Props extends WalletConnectionProps { - connectorType: ConnectorType; - connectorName: string; - setWaitingForUser: (v: boolean) => void; - connection: WalletConnection | undefined; -} - -export function WalletConnectionTypeButton(props: Props) { - const { connectorType, connectorName, setWaitingForUser, connection } = props; - const { isSelected, isConnected, isDisabled, select } = useWalletConnectorSelector( - connectorType, - connection, - props - ); - const onClick = useCallback(() => { - setWaitingForUser(false); - select(); - }, [select]); - return ( - - ); -} From 09a4dc87ead7a9c810d07329496d7591b375e909 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Mon, 23 Oct 2023 14:06:07 +0300 Subject: [PATCH 08/47] Separate init, read, and write functions even further --- front-end-tools/src/Main.tsx | 399 +++++++++++++++++++++++++---------- 1 file changed, 289 insertions(+), 110 deletions(-) diff --git a/front-end-tools/src/Main.tsx b/front-end-tools/src/Main.tsx index bbb305c9..de77b740 100644 --- a/front-end-tools/src/Main.tsx +++ b/front-end-tools/src/Main.tsx @@ -46,6 +46,12 @@ interface ConnectionProps { isTestnet: boolean; } +interface FunctionState { + initFunction: undefined | string; + readFunction: undefined | string; + writeFunction: undefined | string; +} + export default function Main(props: ConnectionProps) { const { walletConnectionProps, isTestnet } = props; const { activeConnectorType, activeConnector, activeConnectorError, connectedAccounts, genesisHashes } = @@ -71,7 +77,11 @@ export default function Main(props: ConnectionProps) { const [smartContractIndexError, setSmartContractIndexError] = useState(undefined); const [moduleReferenceError, setModuleReferenceError] = useState(undefined); const [moduleReferenceLengthError, setModuleReferenceLengthError] = useState(undefined); - const [schemaError, setSchemaError] = useState(undefined); + const [schemaError, setSchemaError] = useState({ + initFunction: undefined, + readFunction: undefined, + writeFunction: undefined, + }); const [accountExistsOnNetwork, setAccountExistsOnNetwork] = useState(true); const [moduleReferenceCalculated, setModuleReferenceCalculated] = useState(undefined); @@ -80,7 +90,11 @@ export default function Main(props: ConnectionProps) { const [moduleReferenceDeployed, setModuleReferenceDeployed] = useState(undefined); const [shouldWarnDifferenceModuleReferences, setShouldWarnDifferenceModuleReferences] = useState(false); - const [shouldWarnInputParameterInSchemaIgnored, setShouldWarnInputParameterInSchemaIgnored] = useState(false); + const [shouldWarnInputParameterInSchemaIgnored, setShouldWarnInputParameterInSchemaIgnored] = useState({ + initFunction: false, + readFunction: false, + writeFunction: false, + }); const [txHashDeploy, setTxHashDeploy] = useState(undefined); const [txHashInit, setTxHashInit] = useState(undefined); @@ -94,7 +108,13 @@ export default function Main(props: ConnectionProps) { ); const [cCDAmount, setCCDAmount] = useState('0'); const [base64Module, setBase64Module] = useState(undefined); - const [uploadedModuleSchemaBase64, setUploadedModuleSchemaBase64] = useState(undefined); + const [uploadedModuleSchemaBase64Initialization, setUploadedModuleSchemaBase64Initialization] = useState< + string | undefined + >(undefined); + const [uploadedModuleSchemaBase64Read, setUploadedModuleSchemaBase64Read] = useState(undefined); + const [uploadedModuleSchemaBase64Write, setUploadedModuleSchemaBase64Write] = useState( + undefined + ); const [dropDown, setDropDown] = useState('number'); const [smartContractIndex, setSmartContractIndex] = useState(undefined); const [smartContractIndexInputField, setSmartContractIndexInputFiled] = useState(1999n); @@ -102,6 +122,8 @@ export default function Main(props: ConnectionProps) { const [entryPointWriteFunction, setEntryPointWriteFunction] = useState('set'); const [returnValue, setReturnValue] = useState(undefined); const [readError, setReadError] = useState(undefined); + + const [inputParameterTemplate, setInputParameterTemplate] = useState(undefined); const [entryPointTemplateReadFunction, setEntryPointTemplateReadFunction] = useState(undefined); const [entryPointTemplateWriteFunction, setEntryPointTemplateWriteFunction] = useState( undefined @@ -111,7 +133,7 @@ export default function Main(props: ConnectionProps) { const [useModuleFromStep1, setUseModuleFromStep1] = useState(false); const [contracts, setContracts] = useState([]); const [displayContracts, setDisplayContracts] = useState([]); - const [inputParameterTemplate, setInputParameterTemplate] = useState(undefined); + const [embeddedModuleSchemaBase64, setEmbeddedModuleSchemaBase64] = useState(undefined); const [hasInputParameterInitFunction, setHasInputParameterInitFunction] = useState(false); @@ -225,22 +247,25 @@ export default function Main(props: ConnectionProps) { setInputParameter(target.value); }, []); - const changeInputParameterTextAreaHandler = useCallback((event: ChangeEvent) => { - setParsingError(undefined); - setTransactionErrorInit(undefined); - const inputTextArea = inputParameterTextAreaRef.current as unknown as HTMLTextAreaElement; - inputTextArea?.setAttribute('style', `height:${inputTextArea.scrollHeight}px;overflow-y:hidden;`); - const target = event.target as HTMLTextAreaElement; + const changeInputParameterTextAreaHandler = useCallback( + (event: ChangeEvent, textAreaRef: React.MutableRefObject) => { + setParsingError(undefined); + setTransactionErrorInit(undefined); + const inputTextArea = textAreaRef.current as unknown as HTMLTextAreaElement; + inputTextArea?.setAttribute('style', `height:${inputTextArea.scrollHeight}px;overflow-y:hidden;`); + const target = event.target as HTMLTextAreaElement; - try { - JSON.parse(target.value); - } catch (e) { - setParsingError((e as Error).message); - return; - } + try { + JSON.parse(target.value); + } catch (e) { + setParsingError((e as Error).message); + return; + } - setInputParameter(JSON.stringify(JSON.parse(target.value))); - }, []); + setInputParameter(JSON.stringify(JSON.parse(target.value))); + }, + [] + ); // Refresh accountInfo periodically. // eslint-disable-next-line consistent-return @@ -380,61 +405,67 @@ export default function Main(props: ConnectionProps) { useEffect(() => { if (inputParameterTemplate !== undefined && hasInputParameterInitFunction === false) { - setShouldWarnInputParameterInSchemaIgnored(true); + setShouldWarnInputParameterInSchemaIgnored({ + ...shouldWarnInputParameterInSchemaIgnored, + initFunction: true, + }); } else { - setShouldWarnInputParameterInSchemaIgnored(false); + setShouldWarnInputParameterInSchemaIgnored({ + ...shouldWarnInputParameterInSchemaIgnored, + initFunction: false, + }); } }, [inputParameterTemplate, hasInputParameterInitFunction]); useEffect(() => { - if (inputParameterTemplate !== undefined && hasInputParameterReadFunction === false) { - setShouldWarnInputParameterInSchemaIgnored(true); + if (entryPointTemplateReadFunction !== undefined && hasInputParameterReadFunction === false) { + setShouldWarnInputParameterInSchemaIgnored({ + ...shouldWarnInputParameterInSchemaIgnored, + readFunction: true, + }); } else { - setShouldWarnInputParameterInSchemaIgnored(false); + setShouldWarnInputParameterInSchemaIgnored({ + ...shouldWarnInputParameterInSchemaIgnored, + readFunction: false, + }); } - }, [inputParameterTemplate, hasInputParameterReadFunction]); + }, [entryPointTemplateReadFunction, hasInputParameterReadFunction]); useEffect(() => { - if (inputParameterTemplate !== undefined && hasInputParameterWriteFunction === false) { - setShouldWarnInputParameterInSchemaIgnored(true); + if (entryPointTemplateWriteFunction !== undefined && hasInputParameterWriteFunction === false) { + setShouldWarnInputParameterInSchemaIgnored({ + ...shouldWarnInputParameterInSchemaIgnored, + writeFunction: true, + }); } else { - setShouldWarnInputParameterInSchemaIgnored(false); + setShouldWarnInputParameterInSchemaIgnored({ + ...shouldWarnInputParameterInSchemaIgnored, + writeFunction: false, + }); } - }, [inputParameterTemplate, hasInputParameterWriteFunction]); + }, [entryPointTemplateWriteFunction, hasInputParameterWriteFunction]); useEffect(() => { - setSchemaError(undefined); - setInputParameterTemplate(undefined); + setSchemaError({ ...schemaError, writeFunction: undefined }); setEntryPointTemplateWriteFunction(undefined); - setEntryPointTemplateReadFunction(undefined); - let initTemplate; let receiveTemplateWriteFunction; - let receiveTemplateReadFunction; if ( contractName !== undefined && - (useModuleFromStep1 !== undefined || uploadedModuleSchemaBase64 !== undefined) + (useModuleFromStep1 !== undefined || uploadedModuleSchemaBase64Write !== undefined) ) { try { let schema = ''; - const schemaFromModule = useModuleFromStep1 ? embeddedModuleSchemaBase64 : uploadedModuleSchemaBase64; + const schemaFromModule = useModuleFromStep1 + ? embeddedModuleSchemaBase64 + : uploadedModuleSchemaBase64Write; if (schemaFromModule !== undefined) { schema = schemaFromModule; } - const readFunctionTemplate = getUpdateContractParameterSchema( - toBuffer(schema, 'base64'), - contractName, - entryPointReadFunction - ); - - receiveTemplateReadFunction = displayTypeSchemaTemplate(readFunctionTemplate); - - setEntryPointTemplateReadFunction(receiveTemplateReadFunction); - const writeFunctionTemplate = getUpdateContractParameterSchema( toBuffer(schema, 'base64'), contractName, @@ -444,6 +475,59 @@ export default function Main(props: ConnectionProps) { receiveTemplateWriteFunction = displayTypeSchemaTemplate(writeFunctionTemplate); setEntryPointTemplateWriteFunction(receiveTemplateWriteFunction); + } catch (e) { + if (useModuleFromStep1) { + setSchemaError({ + ...schemaError, + writeFunction: `Could not get embedded schema from the uploaded module. \nUncheck "Use Module from Step 1" checkbox to manually upload a schema. Original error: ${e}`, + }); + } else { + setSchemaError({ + ...schemaError, + writeFunction: `Could not get schema from uploaded schema. Original error: ${e}`, + }); + } + } + } + + if (receiveTemplateWriteFunction) { + if (dropDown === 'array') { + const element = inputParameterWriteTextAreaRef.current as unknown as HTMLSelectElement; + element.value = getArrayExample(receiveTemplateWriteFunction); + } else if (dropDown === 'object') { + const element = inputParameterWriteTextAreaRef.current as unknown as HTMLSelectElement; + element.value = getObjectExample(receiveTemplateWriteFunction); + } + } + }, [ + entryPointWriteFunction, + hasInputParameterWriteFunction, + useModuleFromStep1, + contractName, + uploadedModuleSchemaBase64Write, + dropDown, + ]); + + useEffect(() => { + setSchemaError({ ...schemaError, initFunction: undefined }); + setInputParameterTemplate(undefined); + + let initTemplate; + + if ( + contractName !== undefined && + (useModuleFromStep1 !== undefined || uploadedModuleSchemaBase64Initialization !== undefined) + ) { + try { + let schema = ''; + + const schemaFromModule = useModuleFromStep1 + ? embeddedModuleSchemaBase64 + : uploadedModuleSchemaBase64Initialization; + + if (schemaFromModule !== undefined) { + schema = schemaFromModule; + } const inputParamterTypeSchemaBuffer = getInitContractParameterSchema( toBuffer(schema, 'base64'), @@ -456,47 +540,95 @@ export default function Main(props: ConnectionProps) { setInputParameterTemplate(initTemplate); } catch (e) { if (useModuleFromStep1) { - setSchemaError( - `Could not get embedded schema from the uploaded module. \nUncheck "Use Module from Step 1" checkbox to manually upload a schema. Original error: ${e}` - ); + setSchemaError({ + ...schemaError, + initFunction: `Could not get embedded schema from the uploaded module. \nUncheck "Use Module from Step 1" checkbox to manually upload a schema. Original error: ${e}`, + }); } else { - setSchemaError(`Could not get schema from uploaded schema. Original error: ${e}`); + setSchemaError({ + ...schemaError, + initFunction: `Could not get schema from uploaded schema. Original error: ${e}`, + }); } } } - if (dropDown === 'array') { - const element = inputParameterTextAreaRef.current as unknown as HTMLSelectElement; - element.value = getArrayExample(initTemplate); - } else if (dropDown === 'object') { - const element = inputParameterTextAreaRef.current as unknown as HTMLSelectElement; - element.value = getObjectExample(initTemplate); + if (initTemplate) { + if (dropDown === 'array') { + const element = inputParameterTextAreaRef.current as unknown as HTMLSelectElement; + element.value = getArrayExample(initTemplate); + } else if (dropDown === 'object') { + const element = inputParameterTextAreaRef.current as unknown as HTMLSelectElement; + element.value = getObjectExample(initTemplate); + } } + }, [ + hasInputParameterInitFunction, + useModuleFromStep1, + contractName, + uploadedModuleSchemaBase64Initialization, + dropDown, + ]); - if (dropDown === 'array') { - const element = inputParameterReadTextAreaRef.current as unknown as HTMLSelectElement; - element.value = getArrayExample(receiveTemplateReadFunction); - } else if (dropDown === 'object') { - const element = inputParameterReadTextAreaRef.current as unknown as HTMLSelectElement; - element.value = getObjectExample(receiveTemplateReadFunction); - } + useEffect(() => { + setSchemaError({ ...schemaError, readFunction: undefined }); + setEntryPointTemplateReadFunction(undefined); + + let receiveTemplateReadFunction; - if (dropDown === 'array') { - const element = inputParameterWriteTextAreaRef.current as unknown as HTMLSelectElement; - element.value = getArrayExample(receiveTemplateWriteFunction); - } else if (dropDown === 'object') { - const element = inputParameterWriteTextAreaRef.current as unknown as HTMLSelectElement; - element.value = getObjectExample(receiveTemplateWriteFunction); + if ( + contractName !== undefined && + (useModuleFromStep1 !== undefined || uploadedModuleSchemaBase64Read !== undefined) + ) { + try { + let schema = ''; + + const schemaFromModule = useModuleFromStep1 + ? embeddedModuleSchemaBase64 + : uploadedModuleSchemaBase64Read; + + if (schemaFromModule !== undefined) { + schema = schemaFromModule; + } + + const readFunctionTemplate = getUpdateContractParameterSchema( + toBuffer(schema, 'base64'), + contractName, + entryPointReadFunction + ); + + receiveTemplateReadFunction = displayTypeSchemaTemplate(readFunctionTemplate); + + setEntryPointTemplateReadFunction(receiveTemplateReadFunction); + } catch (e) { + if (useModuleFromStep1) { + setSchemaError({ + ...schemaError, + readFunction: `Could not get embedded schema from the uploaded module. \nUncheck "Use Module from Step 1" checkbox to manually upload a schema. Original error: ${e}`, + }); + } else { + setSchemaError({ + ...schemaError, + readFunction: `Could not get schema from uploaded schema. Original error: ${e}`, + }); + } + } + } + if (receiveTemplateReadFunction) { + if (dropDown === 'array') { + const element = inputParameterReadTextAreaRef.current as unknown as HTMLSelectElement; + element.value = getArrayExample(receiveTemplateReadFunction); + } else if (dropDown === 'object') { + const element = inputParameterReadTextAreaRef.current as unknown as HTMLSelectElement; + element.value = getObjectExample(receiveTemplateReadFunction); + } } }, [ entryPointReadFunction, - entryPointWriteFunction, - hasInputParameterInitFunction, hasInputParameterReadFunction, - hasInputParameterWriteFunction, useModuleFromStep1, contractName, - uploadedModuleSchemaBase64, + uploadedModuleSchemaBase64Read, dropDown, ]); @@ -810,7 +942,7 @@ export default function Main(props: ConnectionProps) { setModuleReferenceError(undefined); setModuleReference(undefined); setContractName(undefined); - setUploadedModuleSchemaBase64(undefined); + setUploadedModuleSchemaBase64Initialization(undefined); const checkboxElement = useModuleReferenceFromStep1Ref.current as unknown as HTMLInputElement; @@ -973,12 +1105,12 @@ export default function Main(props: ConnectionProps) { onChange={() => { setParsingError(undefined); setInputParameter(undefined); - setUploadedModuleSchemaBase64(undefined); + setUploadedModuleSchemaBase64Initialization(undefined); setTransactionErrorInit(undefined); setDropDown('number'); setHasInputParameterInitFunction(!hasInputParameterInitFunction); setInputParameterTemplate(undefined); - setSchemaError(undefined); + setSchemaError({ ...schemaError, initFunction: undefined }); }} /> {' Has Input Parameter'} @@ -999,7 +1131,7 @@ export default function Main(props: ConnectionProps) { accept=".bin" onChange={async () => { setUploadError2(undefined); - setUploadedModuleSchemaBase64(undefined); + setUploadedModuleSchemaBase64Initialization(undefined); const hTMLInputElement = schemaFileRef.current as unknown as HTMLInputElement; @@ -1018,7 +1150,7 @@ export default function Main(props: ConnectionProps) { }, '') ); - setUploadedModuleSchemaBase64(schema); + setUploadedModuleSchemaBase64Initialization(schema); } else { setUploadError2('Upload schema file is undefined'); } @@ -1028,11 +1160,14 @@ export default function Main(props: ConnectionProps) {

- {uploadedModuleSchemaBase64 && ( + {uploadedModuleSchemaBase64Initialization && (
Schema in base64:
- {uploadedModuleSchemaBase64.toString().slice(0, 30)} ... + {uploadedModuleSchemaBase64Initialization + .toString() + .slice(0, 30)}{' '} + ...
)} @@ -1043,9 +1178,9 @@ export default function Main(props: ConnectionProps) { Error: {uploadError2}.
)} - {schemaError !== undefined && ( + {schemaError.initFunction !== undefined && (
- Error: {schemaError}. + Error: {schemaError.initFunction}.
)} {inputParameterTemplate && ( @@ -1081,7 +1216,12 @@ export default function Main(props: ConnectionProps) { @@ -1090,7 +1230,12 @@ export default function Main(props: ConnectionProps) { @@ -1139,7 +1284,7 @@ export default function Main(props: ConnectionProps) { useModuleFromStep1, useModuleFromStep1 ? embeddedModuleSchemaBase64 - : uploadedModuleSchemaBase64, + : uploadedModuleSchemaBase64Initialization, dropDown, maxContractExecutionEnergy, cCDAmount @@ -1158,7 +1303,7 @@ export default function Main(props: ConnectionProps) { Warning: Module references in step 1 and step 2 are different.
)} - {shouldWarnInputParameterInSchemaIgnored && ( + {shouldWarnInputParameterInSchemaIgnored.initFunction && (
Warning: Input parameter schema found but "Has Input Parameter" checkbox is unchecked. @@ -1196,7 +1341,6 @@ export default function Main(props: ConnectionProps) { )}
-
{smartContractIndexError !== undefined && (
Error: {smartContractIndexError}. @@ -1280,8 +1424,8 @@ export default function Main(props: ConnectionProps) { accept=".bin" onChange={async () => { setUploadError2(undefined); - setUploadedModuleSchemaBase64(undefined); - + setUploadedModuleSchemaBase64Read(undefined); + const hTMLInputElement = schemaFileRef.current as unknown as HTMLInputElement; @@ -1298,8 +1442,7 @@ export default function Main(props: ConnectionProps) { return data + String.fromCharCode(byte); }, '') ); - - setUploadedModuleSchemaBase64(schema); + setUploadedModuleSchemaBase64Read(schema); } else { setUploadError2('Upload schema file is undefined'); } @@ -1326,10 +1469,10 @@ export default function Main(props: ConnectionProps) { {hasInputParameterReadFunction && (
- {!useModuleFromStep1 && uploadedModuleSchemaBase64 && ( + {!useModuleFromStep1 && uploadedModuleSchemaBase64Read && (
Schema in base64: -
{uploadedModuleSchemaBase64.toString().slice(0, 30)} ...
+
{uploadedModuleSchemaBase64Read.toString().slice(0, 30)} ...
)} {uploadError2 !== undefined && ( @@ -1337,9 +1480,9 @@ export default function Main(props: ConnectionProps) { Error: {uploadError2}.
)} - {schemaError !== undefined && ( + {schemaError.readFunction !== undefined && (
- Error: {schemaError}. + Error: {schemaError.readFunction}.
)} {entryPointTemplateReadFunction && ( @@ -1383,7 +1526,12 @@ export default function Main(props: ConnectionProps) { @@ -1392,7 +1540,12 @@ export default function Main(props: ConnectionProps) { @@ -1433,7 +1586,7 @@ export default function Main(props: ConnectionProps) { contractName, smartContractIndexInputField, entryPointReadFunction, - uploadedModuleSchemaBase64, + uploadedModuleSchemaBase64Read, inputParameter, dropDown, hasInputParameterReadFunction, @@ -1449,6 +1602,12 @@ export default function Main(props: ConnectionProps) { > Read Smart Contract + {shouldWarnInputParameterInSchemaIgnored.readFunction && ( +
+ Warning: Input parameter schema found but "Has Input Parameter" + checkbox is unchecked. +
+ )}

{returnValue && ( @@ -1591,7 +1750,7 @@ export default function Main(props: ConnectionProps) { accept=".bin" onChange={async () => { setUploadError2(undefined); - setUploadedModuleSchemaBase64(undefined); + setUploadedModuleSchemaBase64Write(undefined); const hTMLInputElement = schemaFileRef.current as unknown as HTMLInputElement; @@ -1610,7 +1769,7 @@ export default function Main(props: ConnectionProps) { }, '') ); - setUploadedModuleSchemaBase64(schema); + setUploadedModuleSchemaBase64Write(schema); } else { setUploadError2('Upload schema file is undefined'); } @@ -1618,26 +1777,31 @@ export default function Main(props: ConnectionProps) { /> - {!useModuleFromStep1 && uploadedModuleSchemaBase64 && ( + {!useModuleFromStep1 && uploadedModuleSchemaBase64Write && ( <>

Schema in base64: -
{uploadedModuleSchemaBase64.toString().slice(0, 30)} ...
+
+ {uploadedModuleSchemaBase64Write.toString().slice(0, 30)} ... +
)}
{uploadError2 !== undefined && ( -
- Error: {uploadError2}. -
+ <> +
+
+ Error: {uploadError2}. +
+ )} - {schemaError !== undefined && ( + {schemaError.writeFunction !== undefined && (
- Error: {schemaError}. + Error: {schemaError.writeFunction}.
)} {entryPointTemplateWriteFunction && ( @@ -1677,7 +1841,12 @@ export default function Main(props: ConnectionProps) { @@ -1686,7 +1855,12 @@ export default function Main(props: ConnectionProps) { @@ -1715,7 +1889,6 @@ export default function Main(props: ConnectionProps) {
)}
-
+ {shouldWarnInputParameterInSchemaIgnored.writeFunction && ( +
+ Warning: Input parameter schema found but "Has Input Parameter" + checkbox is unchecked. +
+ )}

{!txHashUpdate && transactionErrorUpdate && ( From 1e32e0f6cb981f24569d52feb5484f2df72c6d82 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Mon, 23 Oct 2023 16:06:34 +0300 Subject: [PATCH 09/47] Add write transaction outcome --- front-end-tools/src/Main.tsx | 71 ++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/front-end-tools/src/Main.tsx b/front-end-tools/src/Main.tsx index de77b740..19b34893 100644 --- a/front-end-tools/src/Main.tsx +++ b/front-end-tools/src/Main.tsx @@ -133,6 +133,7 @@ export default function Main(props: ConnectionProps) { const [useModuleFromStep1, setUseModuleFromStep1] = useState(false); const [contracts, setContracts] = useState([]); const [displayContracts, setDisplayContracts] = useState([]); + const [writeTransactionOutcome, setWriteTransactionOutcome] = useState(undefined); const [embeddedModuleSchemaBase64, setEmbeddedModuleSchemaBase64] = useState(undefined); @@ -333,7 +334,7 @@ export default function Main(props: ConnectionProps) { .getBlockItemStatus(txHashInit) .then((report) => { if (report !== undefined) { - setViewErrorModuleReference(undefined); + setSmartContractIndex(undefined); if (report.status === 'finalized') { if ( report.outcome.summary.type === TransactionSummaryType.AccountTransaction && @@ -349,14 +350,46 @@ export default function Main(props: ConnectionProps) { } }) .catch((e) => { - setModuleReferenceDeployed(undefined); - setViewErrorModuleReference((e as Error).message); + setSmartContractIndex(undefined); + setSmartContractIndexError((e as Error).message); }); }, REFRESH_INTERVAL.asMilliseconds()); return () => clearInterval(interval); } }, [connection, account, client, txHashInit]); + // Refresh writeTransactionOutcome periodically. + // eslint-disable-next-line consistent-return + useEffect(() => { + if (connection && client && account && txHashUpdate !== undefined) { + const interval = setInterval(() => { + console.log('refreshing_writeTransactionOutcome'); + client + .getBlockItemStatus(txHashUpdate) + .then((report) => { + if (report !== undefined) { + // setViewErrorModuleReference(undefined); + if (report.status === 'finalized') { + if ( + report.outcome.summary.type === TransactionSummaryType.AccountTransaction && + report.outcome.summary.transactionType === TransactionKindString.Update + ) { + setWriteTransactionOutcome('Success'); + } else { + setWriteTransactionOutcome('Fail'); + } + } + } + }) + .catch((e) => { + setWriteTransactionOutcome(`Fail: ${(e as Error).message}`); + // setViewErrorModuleReference((e as Error).message); + }); + }, REFRESH_INTERVAL.asMilliseconds()); + return () => clearInterval(interval); + } + }, [connection, account, client, txHashUpdate]); + useEffect(() => { if (connection && client && account && moduleReferenceCalculated) { client @@ -446,7 +479,10 @@ export default function Main(props: ConnectionProps) { }, [entryPointTemplateWriteFunction, hasInputParameterWriteFunction]); useEffect(() => { - setSchemaError({ ...schemaError, writeFunction: undefined }); + setSchemaError({ + ...schemaError, + writeFunction: undefined, + }); setEntryPointTemplateWriteFunction(undefined); let receiveTemplateWriteFunction; @@ -1425,7 +1461,7 @@ export default function Main(props: ConnectionProps) { onChange={async () => { setUploadError2(undefined); setUploadedModuleSchemaBase64Read(undefined); - + const hTMLInputElement = schemaFileRef.current as unknown as HTMLInputElement; @@ -1895,6 +1931,7 @@ export default function Main(props: ConnectionProps) { onClick={() => { setTxHashUpdate(undefined); setTransactionErrorUpdate(undefined); + setWriteTransactionOutcome(undefined); const tx = write( connection, account, @@ -1917,14 +1954,14 @@ export default function Main(props: ConnectionProps) { > Write Smart Contract +
+
{shouldWarnInputParameterInSchemaIgnored.writeFunction && (
Warning: Input parameter schema found but "Has Input Parameter" checkbox is unchecked.
)} -
-
{!txHashUpdate && transactionErrorUpdate && (
Error: {transactionErrorUpdate}. @@ -1948,7 +1985,25 @@ export default function Main(props: ConnectionProps) {
CCDScan will take a moment to pick up the above transaction, hence the above - link will work in a bit. + link will work in a bit. The outcome of the transaction will be displayed + below. +
+ + )} + {writeTransactionOutcome === 'Success' && ( + <> +
+
+ Outcome of transaction: +
{writeTransactionOutcome}
+
+ + )} + {writeTransactionOutcome !== undefined && writeTransactionOutcome !== 'Success' && ( + <> +
+
+ Error: {writeTransactionOutcome}.
)} From 60e9e9d1c7487123428e6cc753428a4a4135608d Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Mon, 23 Oct 2023 16:43:15 +0300 Subject: [PATCH 10/47] Separate the contract name into a contract name for read, write, and init respectively --- front-end-tools/src/Main.tsx | 85 ++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 32 deletions(-) diff --git a/front-end-tools/src/Main.tsx b/front-end-tools/src/Main.tsx index 19b34893..2bae801a 100644 --- a/front-end-tools/src/Main.tsx +++ b/front-end-tools/src/Main.tsx @@ -102,7 +102,9 @@ export default function Main(props: ConnectionProps) { const [accountBalance, setAccountBalance] = useState(undefined); const [inputParameter, setInputParameter] = useState(undefined); - const [contractName, setContractName] = useState('myContract'); + const [contractNameInit, setContractNameInit] = useState('myContract'); + const [contractNameRead, setContractNameRead] = useState('myContract'); + const [contractNameWrite, setContractNameWrite] = useState('myContract'); const [moduleReference, setModuleReference] = useState( '91225f9538ac2903466cc4ab07b6eb607a2cd349549f357dfdf4e6042dde0693' ); @@ -202,7 +204,7 @@ export default function Main(props: ConnectionProps) { setDropDown(value); }, []); - const changeSmarContractDropDownHandler = useCallback(() => { + const changeSmarContractDropDownHandler = useCallback((setContractName: (arg0: string) => void) => { setTransactionErrorInit(undefined); const e = contractNameDropDownRef.current as unknown as HTMLSelectElement; const sel = e.selectedIndex; @@ -235,7 +237,7 @@ export default function Main(props: ConnectionProps) { setMaxContractExecutionEnergy(target.value); }, []); - const changeContractNameHandler = useCallback((event: ChangeEvent) => { + const changeContractNameHandler = useCallback((event: ChangeEvent, setContractName: (arg0: string) => void) => { setTransactionErrorInit(undefined); const target = event.target as HTMLTextAreaElement; setContractName(target.value); @@ -488,7 +490,7 @@ export default function Main(props: ConnectionProps) { let receiveTemplateWriteFunction; if ( - contractName !== undefined && + contractNameWrite !== undefined && (useModuleFromStep1 !== undefined || uploadedModuleSchemaBase64Write !== undefined) ) { try { @@ -504,7 +506,7 @@ export default function Main(props: ConnectionProps) { const writeFunctionTemplate = getUpdateContractParameterSchema( toBuffer(schema, 'base64'), - contractName, + contractNameWrite, entryPointWriteFunction ); @@ -539,7 +541,7 @@ export default function Main(props: ConnectionProps) { entryPointWriteFunction, hasInputParameterWriteFunction, useModuleFromStep1, - contractName, + contractNameWrite, uploadedModuleSchemaBase64Write, dropDown, ]); @@ -551,7 +553,7 @@ export default function Main(props: ConnectionProps) { let initTemplate; if ( - contractName !== undefined && + contractNameInit !== undefined && (useModuleFromStep1 !== undefined || uploadedModuleSchemaBase64Initialization !== undefined) ) { try { @@ -567,7 +569,7 @@ export default function Main(props: ConnectionProps) { const inputParamterTypeSchemaBuffer = getInitContractParameterSchema( toBuffer(schema, 'base64'), - contractName, + contractNameInit, 2 ); @@ -601,7 +603,7 @@ export default function Main(props: ConnectionProps) { }, [ hasInputParameterInitFunction, useModuleFromStep1, - contractName, + contractNameInit, uploadedModuleSchemaBase64Initialization, dropDown, ]); @@ -613,7 +615,7 @@ export default function Main(props: ConnectionProps) { let receiveTemplateReadFunction; if ( - contractName !== undefined && + contractNameRead !== undefined && (useModuleFromStep1 !== undefined || uploadedModuleSchemaBase64Read !== undefined) ) { try { @@ -629,7 +631,7 @@ export default function Main(props: ConnectionProps) { const readFunctionTemplate = getUpdateContractParameterSchema( toBuffer(schema, 'base64'), - contractName, + contractNameRead, entryPointReadFunction ); @@ -663,7 +665,7 @@ export default function Main(props: ConnectionProps) { entryPointReadFunction, hasInputParameterReadFunction, useModuleFromStep1, - contractName, + contractNameRead, uploadedModuleSchemaBase64Read, dropDown, ]); @@ -977,7 +979,7 @@ export default function Main(props: ConnectionProps) { onChange={() => { setModuleReferenceError(undefined); setModuleReference(undefined); - setContractName(undefined); + setContractNameInit(undefined); setUploadedModuleSchemaBase64Initialization(undefined); const checkboxElement = @@ -1009,7 +1011,7 @@ export default function Main(props: ConnectionProps) { setModuleReference(newModuleReference); setDisplayContracts(contracts); - setContractName(contracts[0]); + setContractNameInit(contracts[0]); } }} /> @@ -1080,7 +1082,9 @@ export default function Main(props: ConnectionProps) { name="contractNameDropDown" id="contractNameDropDown" ref={contractNameDropDownRef} - onChange={changeSmarContractDropDownHandler} + onChange={() => { + changeSmarContractDropDownHandler(setContractNameInit); + }} > {displayContracts?.map((contract) => ( @@ -1095,8 +1099,10 @@ export default function Main(props: ConnectionProps) { className="inputFieldStyle" id="contractName" type="text" - value={contractName} - onChange={changeContractNameHandler} + value={contractNameInit} + onChange={(event) => { + changeContractNameHandler(event, setContractNameInit); + }} /> )} @@ -1220,12 +1226,19 @@ export default function Main(props: ConnectionProps) {
)} {inputParameterTemplate && ( -
- Input Parameter Template: -
-                                                    {JSON.stringify(JSON.parse(inputParameterTemplate), undefined, 2)}
-                                                
-
+ <> +
+
+ Input Parameter Template: +
+                                                        {JSON.stringify(
+                                                            JSON.parse(inputParameterTemplate),
+                                                            undefined,
+                                                            2
+                                                        )}
+                                                    
+
+ )} )} @@ -1619,7 +1636,7 @@ export default function Main(props: ConnectionProps) { setReturnValue(undefined); const promise = read( client, - contractName, + contractNameRead, smartContractIndexInputField, entryPointReadFunction, uploadedModuleSchemaBase64Read, @@ -1683,7 +1700,9 @@ export default function Main(props: ConnectionProps) { name="contractNameDropDown" id="contractNameDropDown" ref={contractNameDropDownRef} - onChange={changeSmarContractDropDownHandler} + onChange={() => { + changeSmarContractDropDownHandler(setContractNameWrite); + }} > {displayContracts?.map((contract) => ( @@ -1698,8 +1717,10 @@ export default function Main(props: ConnectionProps) { className="inputFieldStyle" id="contractName" type="text" - value={contractName} - onChange={changeContractNameHandler} + value={contractNameWrite} + onChange={(event) => { + changeContractNameHandler(event, setContractNameWrite); + }} /> )} @@ -1936,7 +1957,7 @@ export default function Main(props: ConnectionProps) { connection, account, inputParameter, - contractName, + contractNameWrite, entryPointWriteFunction, hasInputParameterWriteFunction, useModuleFromStep1, From 791d169abbc101fef14815dfd00ec23d46f05a69 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Tue, 24 Oct 2023 10:03:30 +0300 Subject: [PATCH 11/47] Fix schema upload --- front-end-tools/src/Main.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/front-end-tools/src/Main.tsx b/front-end-tools/src/Main.tsx index 2bae801a..9cd92442 100644 --- a/front-end-tools/src/Main.tsx +++ b/front-end-tools/src/Main.tsx @@ -148,7 +148,9 @@ export default function Main(props: ConnectionProps) { const moduleFileRef = useRef(null); const inputParameterDropDownRef = useRef(null); const contractNameDropDownRef = useRef(null); - const schemaFileRef = useRef(null); + const schemaFileRefInit = useRef(null); + const schemaFileRefRead = useRef(null); + const schemaFileRefWrite = useRef(null); const inputParameterTextAreaRef = useRef(null); const useModuleReferenceFromStep1Ref = useRef(null); const moduleReferenceRef = useRef(null); @@ -1169,14 +1171,14 @@ export default function Main(props: ConnectionProps) { className="btn btn-primary" type="file" id="schemaFile" - ref={schemaFileRef} + ref={schemaFileRefInit} accept=".bin" onChange={async () => { setUploadError2(undefined); setUploadedModuleSchemaBase64Initialization(undefined); const hTMLInputElement = - schemaFileRef.current as unknown as HTMLInputElement; + schemaFileRefInit.current as unknown as HTMLInputElement; if ( hTMLInputElement.files !== undefined && @@ -1473,14 +1475,14 @@ export default function Main(props: ConnectionProps) { className="btn btn-primary" type="file" id="schemaFile" - ref={schemaFileRef} + ref={schemaFileRefRead} accept=".bin" onChange={async () => { setUploadError2(undefined); setUploadedModuleSchemaBase64Read(undefined); const hTMLInputElement = - schemaFileRef.current as unknown as HTMLInputElement; + schemaFileRefRead.current as unknown as HTMLInputElement; if ( hTMLInputElement.files !== undefined && @@ -1803,14 +1805,14 @@ export default function Main(props: ConnectionProps) { className="btn btn-primary" type="file" id="schemaFile" - ref={schemaFileRef} + ref={schemaFileRefWrite} accept=".bin" onChange={async () => { setUploadError2(undefined); setUploadedModuleSchemaBase64Write(undefined); const hTMLInputElement = - schemaFileRef.current as unknown as HTMLInputElement; + schemaFileRefWrite.current as unknown as HTMLInputElement; if ( hTMLInputElement.files !== undefined && From 341c4b6f6f3ea2a69010637c90efc9b2c6556039 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Tue, 24 Oct 2023 11:16:46 +0300 Subject: [PATCH 12/47] Part 1: autofill read values from contract index --- front-end-tools/src/Main.tsx | 291 ++++++++++++------ .../src/reading_from_blockchain.ts | 19 +- front-end-tools/src/writing_to_blockchain.ts | 6 +- 3 files changed, 216 insertions(+), 100 deletions(-) diff --git a/front-end-tools/src/Main.tsx b/front-end-tools/src/Main.tsx index 9cd92442..47881d3d 100644 --- a/front-end-tools/src/Main.tsx +++ b/front-end-tools/src/Main.tsx @@ -23,7 +23,7 @@ import { } from '@concordium/web-sdk'; import { initialize, deploy, write } from './writing_to_blockchain'; -import { read } from './reading_from_blockchain'; +import { read, getEmbeddedSchema } from './reading_from_blockchain'; import { BROWSER_WALLET, REFRESH_INTERVAL, EXAMPLE_ARRAYS, EXAMPLE_JSON_OBJECT } from './constants'; @@ -120,8 +120,8 @@ export default function Main(props: ConnectionProps) { const [dropDown, setDropDown] = useState('number'); const [smartContractIndex, setSmartContractIndex] = useState(undefined); const [smartContractIndexInputField, setSmartContractIndexInputFiled] = useState(1999n); - const [entryPointReadFunction, setEntryPointReadFunction] = useState('view'); - const [entryPointWriteFunction, setEntryPointWriteFunction] = useState('set'); + const [entryPointReadFunction, setEntryPointReadFunction] = useState('view'); + const [entryPointWriteFunction, setEntryPointWriteFunction] = useState('set'); const [returnValue, setReturnValue] = useState(undefined); const [readError, setReadError] = useState(undefined); @@ -139,6 +139,7 @@ export default function Main(props: ConnectionProps) { const [embeddedModuleSchemaBase64, setEmbeddedModuleSchemaBase64] = useState(undefined); + const [deriveFromSmartContractIndex, setDeriveFromSmartContractIndex] = useState(false); const [hasInputParameterInitFunction, setHasInputParameterInitFunction] = useState(false); const [hasInputParameterReadFunction, setHasInputParameterReadFunction] = useState(false); const [hasInputParameterWriteFunction, setHasInputParameterWriteFunction] = useState(false); @@ -158,6 +159,7 @@ export default function Main(props: ConnectionProps) { const smartContractIndexRef = useRef(null); const inputParameterReadTextAreaRef = useRef(null); const inputParameterWriteTextAreaRef = useRef(null); + const deriveFromSmartContractIndexRef = useRef(null); function arraysEqual(a: Uint8Array, b: Uint8Array) { if (a === b) return true; @@ -491,42 +493,43 @@ export default function Main(props: ConnectionProps) { let receiveTemplateWriteFunction; - if ( - contractNameWrite !== undefined && - (useModuleFromStep1 !== undefined || uploadedModuleSchemaBase64Write !== undefined) - ) { - try { - let schema = ''; + try { + if (entryPointWriteFunction === undefined) { + throw new Error('Set entry point name'); + } + + if (contractNameWrite === undefined) { + throw new Error('Set smart contract name'); + } - const schemaFromModule = useModuleFromStep1 - ? embeddedModuleSchemaBase64 - : uploadedModuleSchemaBase64Write; + let schema = ''; - if (schemaFromModule !== undefined) { - schema = schemaFromModule; - } + const schemaFromModule = useModuleFromStep1 ? embeddedModuleSchemaBase64 : uploadedModuleSchemaBase64Write; - const writeFunctionTemplate = getUpdateContractParameterSchema( - toBuffer(schema, 'base64'), - contractNameWrite, - entryPointWriteFunction - ); + if (schemaFromModule !== undefined) { + schema = schemaFromModule; + } - receiveTemplateWriteFunction = displayTypeSchemaTemplate(writeFunctionTemplate); + const writeFunctionTemplate = getUpdateContractParameterSchema( + toBuffer(schema, 'base64'), + contractNameWrite, + entryPointWriteFunction + ); - setEntryPointTemplateWriteFunction(receiveTemplateWriteFunction); - } catch (e) { - if (useModuleFromStep1) { - setSchemaError({ - ...schemaError, - writeFunction: `Could not get embedded schema from the uploaded module. \nUncheck "Use Module from Step 1" checkbox to manually upload a schema. Original error: ${e}`, - }); - } else { - setSchemaError({ - ...schemaError, - writeFunction: `Could not get schema from uploaded schema. Original error: ${e}`, - }); - } + receiveTemplateWriteFunction = displayTypeSchemaTemplate(writeFunctionTemplate); + + setEntryPointTemplateWriteFunction(receiveTemplateWriteFunction); + } catch (e) { + if (useModuleFromStep1) { + setSchemaError({ + ...schemaError, + writeFunction: `Could not get embedded schema from the uploaded module. \nUncheck "Use Module from Step 1" checkbox to manually upload a schema. Original error: ${e}`, + }); + } else { + setSchemaError({ + ...schemaError, + writeFunction: `Could not get schema from uploaded schema. Original error: ${e}`, + }); } } @@ -554,42 +557,41 @@ export default function Main(props: ConnectionProps) { let initTemplate; - if ( - contractNameInit !== undefined && - (useModuleFromStep1 !== undefined || uploadedModuleSchemaBase64Initialization !== undefined) - ) { - try { - let schema = ''; + try { + if (contractNameInit === undefined) { + throw new Error('Set smart contract name'); + } - const schemaFromModule = useModuleFromStep1 - ? embeddedModuleSchemaBase64 - : uploadedModuleSchemaBase64Initialization; + let schema = ''; - if (schemaFromModule !== undefined) { - schema = schemaFromModule; - } + const schemaFromModule = useModuleFromStep1 + ? embeddedModuleSchemaBase64 + : uploadedModuleSchemaBase64Initialization; - const inputParamterTypeSchemaBuffer = getInitContractParameterSchema( - toBuffer(schema, 'base64'), - contractNameInit, - 2 - ); + if (schemaFromModule !== undefined) { + schema = schemaFromModule; + } - initTemplate = displayTypeSchemaTemplate(inputParamterTypeSchemaBuffer); + const inputParamterTypeSchemaBuffer = getInitContractParameterSchema( + toBuffer(schema, 'base64'), + contractNameInit, + 2 + ); - setInputParameterTemplate(initTemplate); - } catch (e) { - if (useModuleFromStep1) { - setSchemaError({ - ...schemaError, - initFunction: `Could not get embedded schema from the uploaded module. \nUncheck "Use Module from Step 1" checkbox to manually upload a schema. Original error: ${e}`, - }); - } else { - setSchemaError({ - ...schemaError, - initFunction: `Could not get schema from uploaded schema. Original error: ${e}`, - }); - } + initTemplate = displayTypeSchemaTemplate(inputParamterTypeSchemaBuffer); + + setInputParameterTemplate(initTemplate); + } catch (e) { + if (useModuleFromStep1) { + setSchemaError({ + ...schemaError, + initFunction: `Could not get embedded schema from the uploaded module. \nUncheck "Use Module from Step 1" checkbox to manually upload a schema. Original error: ${e}`, + }); + } else { + setSchemaError({ + ...schemaError, + initFunction: `Could not get schema from uploaded schema. Original error: ${e}`, + }); } } @@ -616,44 +618,46 @@ export default function Main(props: ConnectionProps) { let receiveTemplateReadFunction; - if ( - contractNameRead !== undefined && - (useModuleFromStep1 !== undefined || uploadedModuleSchemaBase64Read !== undefined) - ) { - try { - let schema = ''; + try { + if (entryPointReadFunction === undefined) { + throw new Error('Set entry point name'); + } - const schemaFromModule = useModuleFromStep1 - ? embeddedModuleSchemaBase64 - : uploadedModuleSchemaBase64Read; + if (contractNameRead === undefined) { + throw new Error('Set smart contract name'); + } - if (schemaFromModule !== undefined) { - schema = schemaFromModule; - } + let schema = ''; - const readFunctionTemplate = getUpdateContractParameterSchema( - toBuffer(schema, 'base64'), - contractNameRead, - entryPointReadFunction - ); + const schemaFromModule = useModuleFromStep1 ? embeddedModuleSchemaBase64 : uploadedModuleSchemaBase64Read; - receiveTemplateReadFunction = displayTypeSchemaTemplate(readFunctionTemplate); + if (schemaFromModule !== undefined) { + schema = schemaFromModule; + } - setEntryPointTemplateReadFunction(receiveTemplateReadFunction); - } catch (e) { - if (useModuleFromStep1) { - setSchemaError({ - ...schemaError, - readFunction: `Could not get embedded schema from the uploaded module. \nUncheck "Use Module from Step 1" checkbox to manually upload a schema. Original error: ${e}`, - }); - } else { - setSchemaError({ - ...schemaError, - readFunction: `Could not get schema from uploaded schema. Original error: ${e}`, - }); - } + const readFunctionTemplate = getUpdateContractParameterSchema( + toBuffer(schema, 'base64'), + contractNameRead, + entryPointReadFunction + ); + + receiveTemplateReadFunction = displayTypeSchemaTemplate(readFunctionTemplate); + + setEntryPointTemplateReadFunction(receiveTemplateReadFunction); + } catch (e) { + if (useModuleFromStep1) { + setSchemaError({ + ...schemaError, + readFunction: `Could not get embedded schema from the uploaded module. \nUncheck "Use Module from Step 1" checkbox to manually upload a schema. Original error: ${e}`, + }); + } else { + setSchemaError({ + ...schemaError, + readFunction: `Could not get schema from uploaded schema. Original error: ${e}`, + }); } } + if (receiveTemplateReadFunction) { if (dropDown === 'array') { const element = inputParameterReadTextAreaRef.current as unknown as HTMLSelectElement; @@ -978,6 +982,7 @@ export default function Main(props: ConnectionProps) { type="checkbox" id="useModuleReferenceFromStep1" ref={useModuleReferenceFromStep1Ref} + value={useModuleFromStep1.toString()} onChange={() => { setModuleReferenceError(undefined); setModuleReference(undefined); @@ -1119,6 +1124,7 @@ export default function Main(props: ConnectionProps) {