Commit 917189c4 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Numbers over 16(?) digits are rounded in contract method fields (#1761)

* Numbers over 16(?) digits are rounded in contract method fields

Fixes #1750

* Update values.yaml.gotmpl

Changed public rpc to Sepolia

* Set NEXT_PUBLIC_NETWORK_ID

---------
Co-authored-by: default avatarYan Vaskov <72267126+yvaskov@users.noreply.github.com>
parent 36f9de66
......@@ -4,7 +4,7 @@ imagePullSecrets:
- name: regcred
config:
network:
id: 5
id: 11155111
name: Blockscout
shortname: Blockscout
currency:
......@@ -67,7 +67,8 @@ frontend:
NEXT_PUBLIC_MARKETPLACE_SECURITY_REPORTS_URL: https://gist.githubusercontent.com/maxaleks/ce5c7e3de53e8f5b240b88265daf5839/raw/328383c958a8f7ecccf6d50c953bcdf8ab3faa0a/security_reports_goerli_test.json
NEXT_PUBLIC_LOGOUT_URL: https://blockscoutcom.us.auth0.com/v2/logout
NEXT_PUBLIC_HOMEPAGE_CHARTS: "['daily_txs','coin_price','market_cap']"
NEXT_PUBLIC_NETWORK_RPC_URL: https://rpc.ankr.com/eth_goerli
NEXT_PUBLIC_NETWORK_RPC_URL: https://eth-sepolia.public.blastapi.io
NEXT_PUBLIC_NETWORK_ID: '11155111'
NEXT_PUBLIC_NETWORK_EXPLORERS: "[{'title':'Bitquery','baseUrl':'https://explorer.bitquery.io/','paths':{'tx':'/goerli/tx','address':'/goerli/address','token':'/goerli/token','block':'/goerli/block'}},{'title':'Etherscan','logo':'https://github.com/blockscout/frontend-configs/blob/main/configs/explorer-logos/etherscan.png?raw=true','baseUrl':'https://goerli.etherscan.io/','paths':{'tx':'/tx','address':'/address','token':'/token','block':'/block'}}]"
NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL: https://raw.githubusercontent.com/blockscout/frontend-configs/dev/configs/marketplace-categories/default.json
NEXT_PUBLIC_GRAPHIQL_TRANSACTION: 0xf7d4972356e6ae44ae948d0cf19ef2beaf0e574c180997e969a2837da15e349d
......
......@@ -9,8 +9,8 @@ interface Params {
export interface MatchInt {
isUnsigned: boolean;
power: string;
min: number;
max: number;
min: bigint;
max: bigint;
}
export default function useArgTypeMatchInt({ argType }: Params): MatchInt | null {
......
......@@ -17,8 +17,11 @@ export default function useFormatFieldValue({ argType, argTypeMatchInt }: Params
}
if (argTypeMatchInt) {
// we have to store all numbers as strings to avoid precision loss
// and we cannot store them as BigInt because the NumberFormat component will not work properly
// so we just remove all white spaces here otherwise the `viem` library will throw an error on attempt to write value to a contract
const formattedString = value.replace(/\s/g, '');
return parseInt(formattedString);
return formattedString;
}
if (argType === 'bool') {
......
......@@ -20,7 +20,7 @@ export default function useValidateField({ isOptional, argType, argTypeMatchInt
// some values are formatted before they are sent to the validator
// see ./useFormatFieldValue.tsx hook
return React.useCallback((value: string | number | boolean | undefined) => {
return React.useCallback((value: string | boolean | undefined) => {
if (value === undefined || value === '') {
return isOptional ? true : 'Field is required';
}
......@@ -41,11 +41,19 @@ export default function useValidateField({ isOptional, argType, argTypeMatchInt
}
if (argTypeMatchInt) {
if (typeof value !== 'number' || Object.is(value, NaN)) {
const valueBi = (() => {
try {
return BigInt(value);
} catch (error) {
return null;
}
})();
if (typeof value !== 'string' || valueBi === null) {
return 'Invalid integer format';
}
if (value > argTypeMatchInt.max || value < argTypeMatchInt.min) {
if (valueBi > argTypeMatchInt.max || valueBi < argTypeMatchInt.min) {
const lowerBoundary = argTypeMatchInt.isUnsigned ? '0' : `-1 * 2 ^ ${ Number(argTypeMatchInt.power) - 1 }`;
const upperBoundary = argTypeMatchInt.isUnsigned ? `2 ^ ${ argTypeMatchInt.power } - 1` : `2 ^ ${ Number(argTypeMatchInt.power) - 1 } - 1`;
return `Value should be in range from "${ lowerBoundary }" to "${ upperBoundary }" inclusively`;
......
......@@ -2,7 +2,7 @@ import _set from 'lodash/set';
import type { SmartContractMethodInput } from 'types/api/contract';
export type ContractMethodFormFields = Record<string, string | boolean | number | undefined>;
export type ContractMethodFormFields = Record<string, string | boolean | undefined>;
export const INT_REGEXP = /^(u)?int(\d+)?$/i;
......@@ -11,9 +11,9 @@ export const BYTES_REGEXP = /^bytes(\d+)?$/i;
export const ARRAY_REGEXP = /^(.*)\[(\d*)\]$/;
export const getIntBoundaries = (power: number, isUnsigned: boolean) => {
const maxUnsigned = 2 ** power;
const max = isUnsigned ? maxUnsigned - 1 : maxUnsigned / 2 - 1;
const min = isUnsigned ? 0 : -maxUnsigned / 2;
const maxUnsigned = BigInt(2 ** power);
const max = isUnsigned ? maxUnsigned - BigInt(1) : maxUnsigned / BigInt(2) - BigInt(1);
const min = isUnsigned ? BigInt(0) : -maxUnsigned / BigInt(2);
return [ min, max ];
};
......
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