Skip to content

Commit

Permalink
feat: parse argument value by custom type
Browse files Browse the repository at this point in the history
  • Loading branch information
alexruzenhack committed Aug 21, 2024
1 parent 6d7b713 commit 0ebc917
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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(() => {
Expand All @@ -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.
Expand Down Expand Up @@ -109,7 +115,7 @@ export const NanoContractMethodArgs = ({ blueprintId, method, ncArgs }) => {
&& (
<View style={[commonStyles.card]}>
<View style={[commonStyles.cardStack]}>
{argEntries.map(([argName, argValue]) => (
{argEntries.map(([argName, argValue, argType]) => (
<View
key={argName}
style={commonStyles.cardStackItem}
Expand All @@ -118,7 +124,9 @@ export const NanoContractMethodArgs = ({ blueprintId, method, ncArgs }) => {
<Text style={styles.argPositionText}>{argName}</Text>
</View>
<View style={styles.argValue}>
<Text style={styles.argValueText}>{argValue}</Text>
<Text style={styles.argValueText}>
<ArgValue type={argType} value={argValue} />
</Text>
</View>
</View>
))}
Expand All @@ -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,
Expand Down
26 changes: 26 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

0 comments on commit 0ebc917

Please sign in to comment.