Commit 16ba4c33 authored by tom's avatar tom

update address and bytes validation

parent aeea2e45
export default function bytesToHexString(bytes: Uint8Array) {
return Array.from(bytes, (byte) => {
return ('0' + (byte & 0xff).toString(16)).slice(-2);
}).join('');
}
export default function stringToBytes(str: string) {
const utf8Encode = new TextEncoder();
return utf8Encode.encode(str);
}
......@@ -9,12 +9,11 @@ import React from 'react';
import type { Control, ControllerRenderProps, FieldError, UseFormGetValues, UseFormSetValue, UseFormStateReturn } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import { NumericFormat } from 'react-number-format';
import { isAddress } from 'viem';
import { isAddress, isHex, getAddress } from 'viem';
import type { MethodFormFields } from './types';
import type { SmartContractMethodArgType } from 'types/api/contract';
import stringToBytes from 'lib/stringToBytes';
import ClearButton from 'ui/shared/ClearButton';
import ContractMethodFieldZeroes from './ContractMethodFieldZeroes';
......@@ -122,7 +121,18 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
}
if (argType === 'address') {
return !isAddress(value) ? 'Invalid address format' : true;
if (!isAddress(value)) {
return 'Invalid address format';
}
// all lowercase addresses are valid
const isInLowerCase = value === value.toLowerCase();
if (isInLowerCase) {
return true;
}
// check if address checksum is valid
return getAddress(value) === value ? true : 'Invalid address checksum';
}
if (intMatch) {
......@@ -151,14 +161,12 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
if (bytesMatch) {
const [ , length ] = bytesMatch;
if (value.startsWith('0x')) {
if (value.replace('0x', '').length % 2 !== 0) {
return 'Invalid bytes format';
}
if (!isHex(value)) {
return 'Invalid bytes format';
}
if (length) {
const valueLengthInBytes = value.startsWith('0x') ? value.replace('0x', '').length / 2 : stringToBytes(value).length;
const valueLengthInBytes = value.replace('0x', '').length / 2;
return valueLengthInBytes > Number(length) ? `Value should be a maximum of ${ length } bytes` : true;
}
......
......@@ -109,10 +109,10 @@ describe('function formatFieldValues()', () => {
'1',
'true',
],
'_l2OutputIndex%1': '1',
'_l2OutputIndex%1': '0xaeff',
'_paused%2': '0',
'_withdrawalProof%3': [
'xxx',
'0x0f',
'0x02',
],
};
......@@ -150,10 +150,10 @@ describe('function formatFieldValues()', () => {
true,
true,
],
'_l2OutputIndex%1': '0x31',
'_l2OutputIndex%1': '0xaeff',
'_paused%2': false,
'_withdrawalProof%3': [
'0x787878',
'0x0f',
'0x02',
],
});
......
......@@ -4,9 +4,6 @@ import _mapValues from 'lodash/mapValues';
import type { MethodArgType, MethodFormFields, MethodFormFieldsFormatted } from './types';
import type { SmartContractMethodArgType, SmartContractMethodInput, SmartContractWriteMethod } from 'types/api/contract';
import bytesToHexString from 'lib/bytesToHexString';
import stringToBytes from 'lib/stringToBytes';
export const INT_REGEXP = /^(u)?int(\d+)?$/i;
export const BYTES_REGEXP = /^bytes(\d+)?$/i;
......@@ -131,16 +128,6 @@ function castValue(value: string, type: SmartContractMethodArgType) {
return value.replaceAll(' ', '');
}
const bytesMatch = type.match(BYTES_REGEXP);
if (bytesMatch) {
if (value.startsWith('0x')) {
return value;
}
const bytesArray = stringToBytes(value);
return `0x${ bytesToHexString(bytesArray) }`;
}
const isNestedArray = (type.match(/\[/g) || []).length > 1;
if (isNestedArray) {
return parseArrayValue(value) || value;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment