diff --git a/src/components/WalletConnect/NanoContract/NanoContractMethodArgs.js b/src/components/WalletConnect/NanoContract/NanoContractMethodArgs.js index 1c7b945d8..ffb5ad908 100644 --- a/src/components/WalletConnect/NanoContract/NanoContractMethodArgs.js +++ b/src/components/WalletConnect/NanoContract/NanoContractMethodArgs.js @@ -14,12 +14,14 @@ import { import { useDispatch, useSelector } from 'react-redux'; import { t } from 'ttag'; import { get } from 'lodash'; +import { Network } from '@hathor/wallet-lib'; import { COLORS } from '../../../styles/themes'; import { commonStyles } from '../theme'; import { onExceptionCaptured } from '../../../actions'; -import { NANOCONTRACT_BLUEPRINTINFO_STATUS as STATUS } from '../../../constants'; +import { DEFAULT_TOKEN, NANOCONTRACT_BLUEPRINTINFO_STATUS as STATUS } from '../../../constants'; import { FeedbackContent } from '../../FeedbackContent'; import Spinner from '../../Spinner'; +import { getTimestampFormat, parseScriptData, renderValue } from '../../../utils'; /** * Get method info from registered blueprint data. @@ -66,7 +68,11 @@ export const NanoContractMethodArgs = ({ blueprintId, method, ncArgs }) => { const blueprintInfo = useSelector((state) => state.nanoContract.blueprint[blueprintId]); // It results a in a list of entries like: - // >>> [['oracle_script', 'abc'], ['token_uid', '00'], ['date_last_bet', 123]] + // >>>[ + // >>> ['oracle_script', 'abc', 'TxOutputScript'], + // >>> ['token_uid', '00', 'TokenUid'], + // >>> ['date_last_bet', 123, 'Timestamp'] + // >>>] // or a fallback like: // >>> [['Position 0', 'abc'], ['Position 1', '00'], ['Position 2', 123]] const argEntries = useMemo(() => { @@ -76,7 +82,7 @@ export const NanoContractMethodArgs = ({ blueprintId, method, ncArgs }) => { const methodInfo = getMethodInfoFromBlueprint(blueprintInfo, method); if (methodInfo) { - return ncArgs.map((arg, idx) => [methodInfo.args[idx].name, arg]); + return ncArgs.map((arg, idx) => [methodInfo.args[idx].name, arg, methodInfo.args[idx].type]); } // Send this condition to sentry because it should never happen. @@ -109,7 +115,7 @@ export const NanoContractMethodArgs = ({ blueprintId, method, ncArgs }) => { && ( - {argEntries.map(([argName, argValue]) => ( + {argEntries.map(([argName, argValue, argType]) => ( { {argName} - {argValue} + + + ))} @@ -129,6 +137,57 @@ export const NanoContractMethodArgs = ({ blueprintId, method, ncArgs }) => { ) }; +/** + * Component resposible to render the appropriate format for the value + * taking in consideration the type. + * + * Remarks + * The values received in here when derived from 'byte' type like + * 'TxOutputScript', 'TokenUid' and 'VertexId' are already in its + * hexadecimal format. + * + * Values of type 'Address', which also derives from 'byte' are + * in its base58 format. + * + * Values of type 'SignedData[Result]' arrives here using its data + * part already. + * + * @param {Object} props + * @param {string} props.type An argument type + * @param {string} props.value An argument value + */ +const ArgValue = ({ type, value }) => { + const network = useSelector((state) => new Network(state.networkSettings.network)); + if (type === 'Amount') { + return renderValue(value); + } + + if (type === 'Timestamp') { + return getTimestampFormat(value); + } + + if (type === 'TxOutputScript') { + const parsedScript = parseScriptData(value, network); + if (parsedScript && parsedScript.getType() === 'data') { + return parsedScript.data; + } + + if (parsedScript) { + return parsedScript.address.base58; + } + } + + if (type === 'TokenUid') { + if (value === DEFAULT_TOKEN.uid) { + return DEFAULT_TOKEN.symbol; + } + // XXX: We may want to extend to show the token symbol of + // registered tokens. + } + + return value; +}; + const styles = StyleSheet.create({ argPosition: { flexShrink: 10, diff --git a/src/utils.js b/src/utils.js index 212540fa1..ef6ace56e 100644 --- a/src/utils.js +++ b/src/utils.js @@ -485,3 +485,29 @@ export function hasError(invalidModel) { .values({ ...invalidModel }) .reduce((_hasError, currValue) => _hasError || !isEmpty(currValue), false); } + +/** + * Parses a script data to return an instance of script type. + * + * @example + * parseScriptData('P2PKH or P2SH script', networkObj); + * >>> { address, timelock } + * + * @example + * parseScriptData('Data script', networkObj); + * >>> { data } + * + * @param {string} scriptData A script in its hexadecimal format + * @param {Object} network A network object + * + * @return {P2PKH | P2SH | ScriptData | null} Parsed script object + */ +export const parseScriptData = (scriptData, network) => { + try { + const script = hathorLib.bufferUtils.hexToBuffer(scriptData); + return hathorLib.scriptsUtils.parseScript(script, network); + } catch { + // Avoid to throw exception when we can't parse the script no matter the reason + return null; + } +}