Skip to content

Commit

Permalink
Feature/Tuple array (#54)
Browse files Browse the repository at this point in the history
* added tuple array type

* fix error message for tuple array value

* fix brackets in key names of en.json

---------

Co-authored-by: Yehor Podporinov <[email protected]>
  • Loading branch information
yehor-podporinov and Yehor Podporinov authored Nov 13, 2023
1 parent 00708bb commit 8ac2e6f
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 14 deletions.
1 change: 1 addition & 0 deletions enums/ethereum-types.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export enum ETHEREUM_TYPES {
string = 'string',
stringArray = 'string[]',
tuple = 'tuple()',
tupleArray = 'tuple()[]',
uint = 'uint',
uintArray = 'uint[]',
uint8 = 'uint8',
Expand Down
29 changes: 22 additions & 7 deletions forms/AbiEncodeForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,17 @@
/>
<div class="abi-encode-form__value-wrp">
<input-field
v-if="arg.type === ETHEREUM_TYPES.tuple"
v-if="LIST_OF_TYPES_WITH_SUBTYPE.includes(arg.type)"
:model-value="arg.subtype"
:label="$t('abi-encode-form.arg-subtype-label')"
:placeholder="
$t('abi-encode-form.arg-subtype-placeholder--tuple')
$t(
`abi-encode-form.arg-subtype-placeholder--${
arg.type === ETHEREUM_TYPES.tupleArray
? 'tupleArray'
: 'tuple'
}`,
)
"
:error-message="getFieldErrorMessage(`args[${idx}].subtype`)"
@blur="touchField(`args[${idx}].subtype`)"
Expand Down Expand Up @@ -77,7 +83,7 @@
v-model="arg.value"
size="small"
:label="
arg.type !== ETHEREUM_TYPES.tuple
!LIST_OF_TYPES_WITH_SUBTYPE.includes(arg.type)
? $t('abi-encode-form.arg-value-label')
: ''
"
Expand All @@ -98,7 +104,7 @@
/>
</button>
<button
v-if="arg.type !== ETHEREUM_TYPES.tuple"
v-if="!LIST_OF_TYPES_WITH_SUBTYPE.includes(arg.type)"
class="abi-encode-form__field-btn"
:class="{ 'abi-encode-form__field-btn--filled': arg.value }"
@click="removeArg(arg.id)"
Expand Down Expand Up @@ -166,6 +172,7 @@ import {
createFunctionSignature,
ethereumBaseType,
ethereumBaseTypeValue,
ethereumTupleArrayType,
formatArgSubtype,
getDefaultSubtypeOfType,
getDefaultValueOfType,
Expand Down Expand Up @@ -208,6 +215,11 @@ const ENCODE_MODE_OPTIONS = [
},
]
const LIST_OF_TYPES_WITH_SUBTYPE: Array<AbiForm.FuncArg['type']> = [
ETHEREUM_TYPES.tuple,
ETHEREUM_TYPES.tupleArray,
]
const abiEncoding = ref('')
const funcSignature = ref('')
Expand All @@ -232,14 +244,17 @@ const rules = computed(() => ({
[idx]: {
type: { required },
subtype: {
...(LIST_OF_TYPES_WITH_SUBTYPE.includes(arg.type) && { required }),
...(arg.type === ETHEREUM_TYPES.tuple && {
required,
ethereumBaseType: ethereumBaseType('tuple'),
}),
...(arg.type === ETHEREUM_TYPES.tupleArray && {
ethereumTupleArrayType,
}),
},
value: {
...(arg.type !== ETHEREUM_TYPES.string && { required }),
...(arg.type === ETHEREUM_TYPES.tuple && { json }),
...(LIST_OF_TYPES_WITH_SUBTYPE.includes(arg.type) && { json }),
ethereumBaseTypeValue: ethereumBaseTypeValue(),
withinSizeOfEthereumType: withinSizeOfEthereumType(),
},
Expand Down Expand Up @@ -293,7 +308,7 @@ const onFormChange = () => {
try {
const types = form.args.map(arg =>
arg.type === ETHEREUM_TYPES.tuple ? arg.subtype : arg.type,
LIST_OF_TYPES_WITH_SUBTYPE.includes(arg.type) ? arg.subtype : arg.type,
)
const values = form.args.map(parseFuncArgToValueOfEncode)
Expand Down
40 changes: 34 additions & 6 deletions helpers/abi-form.helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,26 @@ export const ethereumBaseType = (baseType: string): ValidationRule => {
}
}

export const ethereumTupleArrayType: ValidationRule = {
$validator: (value: string) => {
try {
const paramType = ParamType.from(value)

const openingSquareBracketCount = value.split('[').length - 1
const closingSquareBracketCount = value.split(']').length - 1

return (
paramType.type.startsWith('tuple') &&
paramType.type.endsWith(')[]') &&
openingSquareBracketCount === closingSquareBracketCount
)
} catch {
return false
}
},
$message: t('validations.field-error_ethereumTupleArrayType'),
}

export function ethereumBaseTypeValue(): ValidationRule {
let _arg: AbiForm.FuncArg
let _baseType: string
Expand Down Expand Up @@ -64,6 +84,7 @@ export function ethereumBaseTypeValue(): ValidationRule {
case ETHEREUM_TYPES.stringArray:
return checkIsStringArrayJsonString(arg.value)
case ETHEREUM_TYPES.tuple:
case ETHEREUM_TYPES.tupleArray:
try {
return Boolean(
abiCoder.encode(
Expand Down Expand Up @@ -91,13 +112,16 @@ export function ethereumBaseTypeValue(): ValidationRule {
case _arg.type === ETHEREUM_TYPES.bool:
case _arg.type === ETHEREUM_TYPES.boolArray:
case _arg.type === ETHEREUM_TYPES.stringArray:
case _arg.type === ETHEREUM_TYPES.tuple:
return t(
`validations.field-error_ethereumBaseTypeValue--${_arg.type.replace(
'[]',
'Array',
)}`,
)
case _arg.type === ETHEREUM_TYPES.tuple:
return t('validations.field-error_ethereumBaseTypeValue--tuple')
case _arg.type === ETHEREUM_TYPES.tupleArray:
return t('validations.field-error_ethereumBaseTypeValue--tupleArray')

case _baseType === ETHEREUM_TYPES.bytes:
case _baseType === ETHEREUM_TYPES.bytesArray:
Expand All @@ -111,7 +135,7 @@ export function ethereumBaseTypeValue(): ValidationRule {
{ type: _baseType.replace('[]', '') },
)
default:
return ''
return t('validations.field-error_ethereumBaseTypeValue')
}
},
}
Expand Down Expand Up @@ -183,6 +207,7 @@ export const parseFuncArgToValueOfEncode = (arg: AbiForm.FuncArg): unknown => {
switch (true) {
case isArrayType:
case arg.type === ETHEREUM_TYPES.tuple:
case arg.type === ETHEREUM_TYPES.tupleArray:
return JSON.parse(arg.value as string)
case arg.type === ETHEREUM_TYPES.bool:
return arg.value === 'true'
Expand All @@ -198,11 +223,14 @@ export const formatArgSubtype = (subtype: AbiForm.FuncArg['subtype']) => {
export const getDefaultSubtypeOfType = (
type: AbiForm.FuncArg['type'],
): string => {
if (type === ETHEREUM_TYPES.tuple) {
return 'tuple()'
switch (type) {
case ETHEREUM_TYPES.tuple:
return 'tuple()'
case ETHEREUM_TYPES.tupleArray:
return 'tuple()[]'
default:
return ''
}

return ''
}

export const getDefaultValueOfType = (
Expand Down
6 changes: 5 additions & 1 deletion plugins/localization/resources/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,19 @@
"field-error_functionSignature": "Field must be a valid function signature",
"field-error_minLength": "Field must be greater than {min} symbols",
"field-error_ethereumBaseType": "Field must be a valid {baseType} type",
"field-error_ethereumBaseTypeValue": "Field must be a valid value",
"field-error_ethereumBaseTypeValue--address": "Field must be a valid address",
"field-error_ethereumBaseTypeValue--addressArray": "Field must be a valid JSON array of addresses",
"field-error_ethereumBaseTypeValue--bool": "Field must be true or false",
"field-error_ethereumBaseTypeValue--boolArray": "Field must be a valid JSON array of booleans",
"field-error_ethereumBaseTypeValue--bytes": "Field must be a valid {type} like",
"field-error_ethereumBaseTypeValue--bytesArray": "Field must be a valid JSON array of {type}",
"field-error_ethereumBaseTypeValue--stringArray": "Field must be a valid JSON array of strings",
"field-error_ethereumBaseTypeValue--tuple()": "Field must match tuple type",
"field-error_ethereumBaseTypeValue--tuple": "Field must match tuple type",
"field-error_ethereumBaseTypeValue--tupleArray": "Field must match tuple array type",
"field-error_ethereumBaseTypeValue--uint": "Field must be a valid {type} like",
"field-error_ethereumBaseTypeValue--uintArray": "Field must be a valid JSON array of {type} like",
"field-error_ethereumTupleArrayType": "Field must be a valid tuple array type",
"field-error_withinSizeOfEthereumType--uint": "Field must have a value in the range",
"field-error_withinSizeOfEthereumType--uintArray": "Field must have a values in the range",
"field-error_withinSizeOfEthereumType--bytes": "Field must have a valid amount of bytes",
Expand Down Expand Up @@ -107,6 +110,7 @@
"arg-type-placeholder": "Select type",
"arg-subtype-label": "Value",
"arg-subtype-placeholder--tuple": "Enter type, e.g. tuple(address, tuple(uint256))",
"arg-subtype-placeholder--tupleArray": "Enter type, e.g. tuple(address, tuple(uint256))[]",
"add-arg-btn": "Add argument",
"encoding-label--standard": "Abi encoding",
"encoding-label--packed": "Packed encoding",
Expand Down

0 comments on commit 8ac2e6f

Please sign in to comment.