Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

interface AbiMethodInputProps {
input: AbiParameter;
handleUpdate: (value: any) => void;
handleUpdate: (value: any, error?: string) => void;
value: any;
error?: string;
}
Expand All @@ -43,16 +43,14 @@
error,
}) => {
switch (true) {
case input.type.endsWith('[][]'):
return (
<JsonInput
isTupleArray={true}
handleUpdate={handleUpdate}
value={value}
/>
);
// handle tuples in arrays
case input.type.startsWith('tuple'):
// Handle tuples and arrays of tuples (complex data structures)
case input.type.startsWith('tuple') || input.type.endsWith('[][]'):
if (value !== undefined && typeof value !== 'object') {
throw new Error(

Check warning on line 49 in packages/website/src/features/Packages/AbiMethod/AbiContractMethodInputType.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/AbiContractMethodInputType.tsx#L49

Added line #L49 was not covered by tests
'Expected object or array for tuple or nested arrays, got ' +
typeof value
);
}
return (
<JsonInput
isTupleArray={input.type.includes('[]')}
Expand All @@ -79,7 +77,9 @@
`Expected string, string array or undefined for address type, got ${typeof value}`
);
}
return <AddressInput handleUpdate={handleUpdate} value={value} />;
return (
<AddressInput handleUpdate={handleUpdate} value={value} error={error} />
);
case input.type.startsWith('int') || input.type.startsWith('uint'):
if (!isBigInt(value) && value !== undefined) {
throw new Error(
Expand All @@ -95,9 +95,9 @@
/>
);
case input.type.startsWith('bytes'): {
if (!isString(value) && !isStringArray(value) && value !== undefined) {
if (!isString(value) && value !== undefined) {
throw new Error(
`Expected string, string array or undefined for bytes type, got ${typeof value}`
`Expected string or undefined for bytes type, got ${typeof value}`
);
}
// Extract the number of bytes from the type string (e.g., 'bytes32' -> 32)
Expand All @@ -106,6 +106,7 @@
<ByteInput
handleUpdate={handleUpdate}
value={value}
error={error}
byte={isNaN(byteSize) ? undefined : byteSize}
/>
);
Expand All @@ -116,6 +117,8 @@
`Expected string, string array or undefined for default type, got ${typeof value}`
);
}
return <DefaultInput handleUpdate={handleUpdate} value={value} />;
return (
<DefaultInput handleUpdate={handleUpdate} value={value} error={error} />
);
}
};
38 changes: 25 additions & 13 deletions packages/website/src/features/Packages/AbiMethod/ByteInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,15 @@
value: string,
byte?: number
): string | undefined => {
// For dynamic bytes (bytes), no length validation needed
// For dynamic bytes (bytes), validate hex format and odd length
if (!byte) {
if (value.startsWith('0x')) {
// Only check odd length if the hex part contains only valid hex characters
const hexPart = value.slice(2); // Remove '0x' prefix

Check warning on line 26 in packages/website/src/features/Packages/AbiMethod/ByteInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/ByteInput.tsx#L26

Added line #L26 was not covered by tests
if (/^[0-9a-fA-F]*$/.test(hexPart) && hexPart.length % 2 === 1) {
return 'Hex string must have even number of characters after 0x prefix';

Check warning on line 28 in packages/website/src/features/Packages/AbiMethod/ByteInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/ByteInput.tsx#L28

Added line #L28 was not covered by tests
}
}
return undefined;
}

Expand Down Expand Up @@ -53,35 +60,40 @@
// Create a dynamic regex based on the byte size
const hexRegex = byte
? new RegExp(`^0x[0-9a-fA-F]{${byte * 2}}$`) // Fixed size: exact length
: /^0x[0-9a-fA-F]*$/; // Dynamic: any length hex string
: /^0x([0-9a-fA-F]{2})*$/; // Dynamic: any even length hex string

Check warning on line 63 in packages/website/src/features/Packages/AbiMethod/ByteInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/ByteInput.tsx#L63

Added line #L63 was not covered by tests

const handleChange = (inputValue: string) => {
const getHandleUpdateValues = (
inputValue: string,
byte?: number
): [string | undefined, string?] => {
const validationError = validateByteInput(inputValue, byte);

// Allow empty input
if (!inputValue) {
handleUpdate(undefined);
setInputValue('');
return;
return [undefined];

Check warning on line 73 in packages/website/src/features/Packages/AbiMethod/ByteInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/ByteInput.tsx#L73

Added line #L73 was not covered by tests
}

if (!hexRegex.test(inputValue)) {
if (inputValue.startsWith('0x')) {
// If it starts with 0x but isn't a valid hex, pass it through as is
// This allows partial hex inputs while typing
handleUpdate(undefined, validationError);
// Invalid hex format - only return error if it's a validation error (like odd length)
return validationError ? [undefined, validationError] : [undefined];
} else {
// If it's not a hex string at all, convert it to hex
// Convert string to hex
const hexValue = stringToHex(
inputValue,
byte ? { size: byte } : undefined
);
handleUpdate(hexValue, validationError);
return validationError ? [hexValue, validationError] : [hexValue];
}
} else {
// If it's already a valid hex string, pass it through
handleUpdate(inputValue, validationError);
// Valid hex string
return [inputValue];
}
};

const handleChange = (inputValue: string) => {
const updateValues = getHandleUpdateValues(inputValue, byte);
handleUpdate(...updateValues);
setInputValue(inputValue);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
error,
}) => {
const [inputValue, setInputValue] = useState(
Array.isArray(value) ? JSON.stringify(value) : value || ''
Array.isArray(value) || (typeof value === 'object' && value !== null)
? JSON.stringify(value)
: value || ''

Check warning on line 26 in packages/website/src/features/Packages/AbiMethod/JsonInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/JsonInput.tsx#L25-L26

Added lines #L25 - L26 were not covered by tests
);

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
Expand Down
66 changes: 45 additions & 21 deletions packages/website/src/features/Packages/AbiMethod/NumberInput.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { FC, useRef, ChangeEvent, useState } from 'react';
import { Input } from '@/components/ui/input';
import { cn } from '@/lib/utils';
import { parseUnits } from 'viem';
import { parseUnits, formatUnits } from 'viem';

interface NumberInputProps {
handleUpdate: (value: any, error?: string) => void;
value: any;
handleUpdate: (value: string | undefined, error?: string) => void;
value: bigint | undefined;
error?: string;
suffix?: string;
showWeiValue?: boolean;
Expand All @@ -20,7 +20,13 @@
showWeiValue = false,
fixedDecimals = 0,
}) => {
const [inputValue, setInputValue] = useState(value || '');
const [inputValue, setInputValue] = useState(() => {
if (value === undefined) return '';
if (fixedDecimals > 0) {
return formatUnits(value, fixedDecimals);
}
return value.toString();

Check warning on line 28 in packages/website/src/features/Packages/AbiMethod/NumberInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/NumberInput.tsx#L28

Added line #L28 was not covered by tests
});
const decimals = fixedDecimals;
const inputRef = useRef<HTMLInputElement>(null);

Expand All @@ -36,26 +42,37 @@
const _value = event.target.value;

if (_value === '') {
handleUpdate(undefined);
setInputValue('');
handleUpdate(undefined);

Check warning on line 46 in packages/website/src/features/Packages/AbiMethod/NumberInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/NumberInput.tsx#L46

Added line #L46 was not covered by tests
return;
}

// if (!checkDecimalPlaces(inputValue)) {
// handleUpdate({
// inputValue,
// parsedValue: undefined,
// error: `Input has more decimal places than allowed (max: ${decimals})`,
// });
// return;
// }

try {
parseUnits(_value, decimals);
handleUpdate(_value);
// Si fixedDecimals > 0, permitimos decimales
if (fixedDecimals > 0) {
setInputValue(_value);
} catch {
handleUpdate(undefined, 'Invalid number format');
try {

Check warning on line 53 in packages/website/src/features/Packages/AbiMethod/NumberInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/NumberInput.tsx#L53

Added line #L53 was not covered by tests
// Convertir a wei
parseUnits(_value, decimals);
handleUpdate(_value);

Check warning on line 56 in packages/website/src/features/Packages/AbiMethod/NumberInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/NumberInput.tsx#L55-L56

Added lines #L55 - L56 were not covered by tests
} catch (error) {
handleUpdate(undefined, 'Invalid number format');

Check warning on line 58 in packages/website/src/features/Packages/AbiMethod/NumberInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/NumberInput.tsx#L58

Added line #L58 was not covered by tests
}
return;

Check warning on line 60 in packages/website/src/features/Packages/AbiMethod/NumberInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/NumberInput.tsx#L60

Added line #L60 was not covered by tests
} else {
// Si fixedDecimals = 0, solo permitimos números enteros
if (!/^\d+$/.test(_value)) {
setInputValue(_value);
handleUpdate(undefined, 'Invalid number format');
return;

Check warning on line 66 in packages/website/src/features/Packages/AbiMethod/NumberInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/NumberInput.tsx#L64-L66

Added lines #L64 - L66 were not covered by tests
}

try {
setInputValue(_value);
handleUpdate(_value);
} catch {
setInputValue(_value);
handleUpdate(undefined, 'Invalid number format');

Check warning on line 74 in packages/website/src/features/Packages/AbiMethod/NumberInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/NumberInput.tsx#L73-L74

Added lines #L73 - L74 were not covered by tests
}
}
};

Expand Down Expand Up @@ -151,13 +168,20 @@
</Popover>
)} */}
{suffix && (
<div className="flex items-center px-3 py-1 bg-background text-gray-300 border border-l-0 border-border rounded-r-md h-10">
<div

Check warning on line 171 in packages/website/src/features/Packages/AbiMethod/NumberInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/NumberInput.tsx#L171

Added line #L171 was not covered by tests
className="flex items-center px-3 py-1 bg-background text-gray-300 border border-l-0 border-border rounded-r-md h-10"
data-testid="suffix"
>
{suffix}
</div>
)}
</div>
{showWeiValue && inputValue && (
<p className="text-xs text-muted-foreground mt-1">{inputValue} wei</p>
<p className="text-xs text-muted-foreground mt-1">
{fixedDecimals > 0
? `${parseUnits(inputValue, decimals).toString()} wei`

Check warning on line 182 in packages/website/src/features/Packages/AbiMethod/NumberInput.tsx

View check run for this annotation

Codecov / codecov/patch

packages/website/src/features/Packages/AbiMethod/NumberInput.tsx#L182

Added line #L182 was not covered by tests
: `${inputValue} wei`}
</p>
)}
</div>
);
Expand Down
Loading
Loading