Skip to content

Commit 8ac2e6f

Browse files
yehor-podporinovYehor Podporinov
andauthored
Feature/Tuple array (#54)
* 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]>
1 parent 00708bb commit 8ac2e6f

File tree

4 files changed

+62
-14
lines changed

4 files changed

+62
-14
lines changed

enums/ethereum-types.enum.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export enum ETHEREUM_TYPES {
7272
string = 'string',
7373
stringArray = 'string[]',
7474
tuple = 'tuple()',
75+
tupleArray = 'tuple()[]',
7576
uint = 'uint',
7677
uintArray = 'uint[]',
7778
uint8 = 'uint8',

forms/AbiEncodeForm.vue

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,17 @@
3636
/>
3737
<div class="abi-encode-form__value-wrp">
3838
<input-field
39-
v-if="arg.type === ETHEREUM_TYPES.tuple"
39+
v-if="LIST_OF_TYPES_WITH_SUBTYPE.includes(arg.type)"
4040
:model-value="arg.subtype"
4141
:label="$t('abi-encode-form.arg-subtype-label')"
4242
:placeholder="
43-
$t('abi-encode-form.arg-subtype-placeholder--tuple')
43+
$t(
44+
`abi-encode-form.arg-subtype-placeholder--${
45+
arg.type === ETHEREUM_TYPES.tupleArray
46+
? 'tupleArray'
47+
: 'tuple'
48+
}`,
49+
)
4450
"
4551
:error-message="getFieldErrorMessage(`args[${idx}].subtype`)"
4652
@blur="touchField(`args[${idx}].subtype`)"
@@ -77,7 +83,7 @@
7783
v-model="arg.value"
7884
size="small"
7985
:label="
80-
arg.type !== ETHEREUM_TYPES.tuple
86+
!LIST_OF_TYPES_WITH_SUBTYPE.includes(arg.type)
8187
? $t('abi-encode-form.arg-value-label')
8288
: ''
8389
"
@@ -98,7 +104,7 @@
98104
/>
99105
</button>
100106
<button
101-
v-if="arg.type !== ETHEREUM_TYPES.tuple"
107+
v-if="!LIST_OF_TYPES_WITH_SUBTYPE.includes(arg.type)"
102108
class="abi-encode-form__field-btn"
103109
:class="{ 'abi-encode-form__field-btn--filled': arg.value }"
104110
@click="removeArg(arg.id)"
@@ -166,6 +172,7 @@ import {
166172
createFunctionSignature,
167173
ethereumBaseType,
168174
ethereumBaseTypeValue,
175+
ethereumTupleArrayType,
169176
formatArgSubtype,
170177
getDefaultSubtypeOfType,
171178
getDefaultValueOfType,
@@ -208,6 +215,11 @@ const ENCODE_MODE_OPTIONS = [
208215
},
209216
]
210217
218+
const LIST_OF_TYPES_WITH_SUBTYPE: Array<AbiForm.FuncArg['type']> = [
219+
ETHEREUM_TYPES.tuple,
220+
ETHEREUM_TYPES.tupleArray,
221+
]
222+
211223
const abiEncoding = ref('')
212224
const funcSignature = ref('')
213225
@@ -232,14 +244,17 @@ const rules = computed(() => ({
232244
[idx]: {
233245
type: { required },
234246
subtype: {
247+
...(LIST_OF_TYPES_WITH_SUBTYPE.includes(arg.type) && { required }),
235248
...(arg.type === ETHEREUM_TYPES.tuple && {
236-
required,
237249
ethereumBaseType: ethereumBaseType('tuple'),
238250
}),
251+
...(arg.type === ETHEREUM_TYPES.tupleArray && {
252+
ethereumTupleArrayType,
253+
}),
239254
},
240255
value: {
241256
...(arg.type !== ETHEREUM_TYPES.string && { required }),
242-
...(arg.type === ETHEREUM_TYPES.tuple && { json }),
257+
...(LIST_OF_TYPES_WITH_SUBTYPE.includes(arg.type) && { json }),
243258
ethereumBaseTypeValue: ethereumBaseTypeValue(),
244259
withinSizeOfEthereumType: withinSizeOfEthereumType(),
245260
},
@@ -293,7 +308,7 @@ const onFormChange = () => {
293308
294309
try {
295310
const types = form.args.map(arg =>
296-
arg.type === ETHEREUM_TYPES.tuple ? arg.subtype : arg.type,
311+
LIST_OF_TYPES_WITH_SUBTYPE.includes(arg.type) ? arg.subtype : arg.type,
297312
)
298313
const values = form.args.map(parseFuncArgToValueOfEncode)
299314

helpers/abi-form.helpers.ts

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,26 @@ export const ethereumBaseType = (baseType: string): ValidationRule => {
3737
}
3838
}
3939

40+
export const ethereumTupleArrayType: ValidationRule = {
41+
$validator: (value: string) => {
42+
try {
43+
const paramType = ParamType.from(value)
44+
45+
const openingSquareBracketCount = value.split('[').length - 1
46+
const closingSquareBracketCount = value.split(']').length - 1
47+
48+
return (
49+
paramType.type.startsWith('tuple') &&
50+
paramType.type.endsWith(')[]') &&
51+
openingSquareBracketCount === closingSquareBracketCount
52+
)
53+
} catch {
54+
return false
55+
}
56+
},
57+
$message: t('validations.field-error_ethereumTupleArrayType'),
58+
}
59+
4060
export function ethereumBaseTypeValue(): ValidationRule {
4161
let _arg: AbiForm.FuncArg
4262
let _baseType: string
@@ -64,6 +84,7 @@ export function ethereumBaseTypeValue(): ValidationRule {
6484
case ETHEREUM_TYPES.stringArray:
6585
return checkIsStringArrayJsonString(arg.value)
6686
case ETHEREUM_TYPES.tuple:
87+
case ETHEREUM_TYPES.tupleArray:
6788
try {
6889
return Boolean(
6990
abiCoder.encode(
@@ -91,13 +112,16 @@ export function ethereumBaseTypeValue(): ValidationRule {
91112
case _arg.type === ETHEREUM_TYPES.bool:
92113
case _arg.type === ETHEREUM_TYPES.boolArray:
93114
case _arg.type === ETHEREUM_TYPES.stringArray:
94-
case _arg.type === ETHEREUM_TYPES.tuple:
95115
return t(
96116
`validations.field-error_ethereumBaseTypeValue--${_arg.type.replace(
97117
'[]',
98118
'Array',
99119
)}`,
100120
)
121+
case _arg.type === ETHEREUM_TYPES.tuple:
122+
return t('validations.field-error_ethereumBaseTypeValue--tuple')
123+
case _arg.type === ETHEREUM_TYPES.tupleArray:
124+
return t('validations.field-error_ethereumBaseTypeValue--tupleArray')
101125

102126
case _baseType === ETHEREUM_TYPES.bytes:
103127
case _baseType === ETHEREUM_TYPES.bytesArray:
@@ -111,7 +135,7 @@ export function ethereumBaseTypeValue(): ValidationRule {
111135
{ type: _baseType.replace('[]', '') },
112136
)
113137
default:
114-
return ''
138+
return t('validations.field-error_ethereumBaseTypeValue')
115139
}
116140
},
117141
}
@@ -183,6 +207,7 @@ export const parseFuncArgToValueOfEncode = (arg: AbiForm.FuncArg): unknown => {
183207
switch (true) {
184208
case isArrayType:
185209
case arg.type === ETHEREUM_TYPES.tuple:
210+
case arg.type === ETHEREUM_TYPES.tupleArray:
186211
return JSON.parse(arg.value as string)
187212
case arg.type === ETHEREUM_TYPES.bool:
188213
return arg.value === 'true'
@@ -198,11 +223,14 @@ export const formatArgSubtype = (subtype: AbiForm.FuncArg['subtype']) => {
198223
export const getDefaultSubtypeOfType = (
199224
type: AbiForm.FuncArg['type'],
200225
): string => {
201-
if (type === ETHEREUM_TYPES.tuple) {
202-
return 'tuple()'
226+
switch (type) {
227+
case ETHEREUM_TYPES.tuple:
228+
return 'tuple()'
229+
case ETHEREUM_TYPES.tupleArray:
230+
return 'tuple()[]'
231+
default:
232+
return ''
203233
}
204-
205-
return ''
206234
}
207235

208236
export const getDefaultValueOfType = (

plugins/localization/resources/en.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,19 @@
1919
"field-error_functionSignature": "Field must be a valid function signature",
2020
"field-error_minLength": "Field must be greater than {min} symbols",
2121
"field-error_ethereumBaseType": "Field must be a valid {baseType} type",
22+
"field-error_ethereumBaseTypeValue": "Field must be a valid value",
2223
"field-error_ethereumBaseTypeValue--address": "Field must be a valid address",
2324
"field-error_ethereumBaseTypeValue--addressArray": "Field must be a valid JSON array of addresses",
2425
"field-error_ethereumBaseTypeValue--bool": "Field must be true or false",
2526
"field-error_ethereumBaseTypeValue--boolArray": "Field must be a valid JSON array of booleans",
2627
"field-error_ethereumBaseTypeValue--bytes": "Field must be a valid {type} like",
2728
"field-error_ethereumBaseTypeValue--bytesArray": "Field must be a valid JSON array of {type}",
2829
"field-error_ethereumBaseTypeValue--stringArray": "Field must be a valid JSON array of strings",
29-
"field-error_ethereumBaseTypeValue--tuple()": "Field must match tuple type",
30+
"field-error_ethereumBaseTypeValue--tuple": "Field must match tuple type",
31+
"field-error_ethereumBaseTypeValue--tupleArray": "Field must match tuple array type",
3032
"field-error_ethereumBaseTypeValue--uint": "Field must be a valid {type} like",
3133
"field-error_ethereumBaseTypeValue--uintArray": "Field must be a valid JSON array of {type} like",
34+
"field-error_ethereumTupleArrayType": "Field must be a valid tuple array type",
3235
"field-error_withinSizeOfEthereumType--uint": "Field must have a value in the range",
3336
"field-error_withinSizeOfEthereumType--uintArray": "Field must have a values in the range",
3437
"field-error_withinSizeOfEthereumType--bytes": "Field must have a valid amount of bytes",
@@ -107,6 +110,7 @@
107110
"arg-type-placeholder": "Select type",
108111
"arg-subtype-label": "Value",
109112
"arg-subtype-placeholder--tuple": "Enter type, e.g. tuple(address, tuple(uint256))",
113+
"arg-subtype-placeholder--tupleArray": "Enter type, e.g. tuple(address, tuple(uint256))[]",
110114
"add-arg-btn": "Add argument",
111115
"encoding-label--standard": "Abi encoding",
112116
"encoding-label--packed": "Packed encoding",

0 commit comments

Comments
 (0)