1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-22 11:22:43 +02:00

Display decimal chain ID in network form (#9780)

* Display network form chain ID in decimal

* Hide chainId tooltip in view mode

* Display chain ID error message in entered format

* Update locale messages

* Rename on change chain ID validator
This commit is contained in:
Erik Marks 2020-11-03 20:10:52 -08:00 committed by GitHub
parent 026a06b39d
commit ad838df3e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 108 additions and 69 deletions

View File

@ -731,7 +731,7 @@
"optionalBlockExplorerUrl": {
"message": "ኤክስፕሎረር URL አግድ (አማራጭ)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "ምልክት (አማራጭ)"
},
"orderOneHere": {

View File

@ -727,7 +727,7 @@
"optionalBlockExplorerUrl": {
"message": "العنوان الإلكتروني لمستكشف البلوكات (اختياري)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "الرمز (اختياري)"
},
"orderOneHere": {

View File

@ -730,7 +730,7 @@
"optionalBlockExplorerUrl": {
"message": "Блокиране на Explorer URL (по избор)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Символ (по избор)"
},
"orderOneHere": {

View File

@ -734,7 +734,7 @@
"optionalBlockExplorerUrl": {
"message": "এক্সপ্লোরার URL ব্লক করুন (ঐচ্ছিক)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "প্রতীক (ঐচ্ছিক)"
},
"orderOneHere": {

View File

@ -718,7 +718,7 @@
"optionalBlockExplorerUrl": {
"message": "Bloqueja l'URL d'Explorer (opcional)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Símbol (opcional)"
},
"orderOneHere": {

View File

@ -718,7 +718,7 @@
"optionalBlockExplorerUrl": {
"message": "Blok-stifinder-URL (valgfrit)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Symbol (valgfrit)"
},
"orderOneHere": {

View File

@ -731,7 +731,7 @@
"optionalBlockExplorerUrl": {
"message": "Διεύθυνση URL Εξερευνητή Μπλοκ (προαιρετικό)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Σύμβολο (προαιρετικό)"
},
"orderOneHere": {

View File

@ -869,7 +869,7 @@
"message": "Invalid IPFS Gateway: The value must be a valid URL"
},
"invalidNumber": {
"message": "Invalid number. Enter a decimal or hexadecimal number."
"message": "Invalid number. Enter a decimal or '0x'-prefixed hexadecimal number."
},
"invalidNumberLeadingZeros": {
"message": "Invalid number. Remove any leading zeros."
@ -1031,7 +1031,7 @@
"message": "Network Name"
},
"networkSettingsChainIdDescription": {
"message": "The chain ID is used for signing transactions. It must match the chain ID returned by the network. Enter a decimal or hexadecimal number starting with '0x'."
"message": "The chain ID is used for signing transactions. It must match the chain ID returned by the network. You can enter a decimal or '0x'-prefixed hexadecimal number, but we will display the number in decimal."
},
"networkSettingsDescription": {
"message": "Add and edit custom RPC networks"
@ -1150,8 +1150,8 @@
"optionalBlockExplorerUrl": {
"message": "Block Explorer URL (optional)"
},
"optionalSymbol": {
"message": "Symbol (optional)"
"optionalCurrencySymbol": {
"message": "Currency Symbol (optional)"
},
"orderOneHere": {
"message": "Order a Trezor or Ledger and keep your funds in cold storage"

View File

@ -574,7 +574,7 @@
"ofTextNofM": {
"message": "de"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Símbolo (opcional)"
},
"orderOneHere": {

View File

@ -719,7 +719,7 @@
"optionalBlockExplorerUrl": {
"message": "Bloquear la URL de Explorer (opcional)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Símbolo (opcional)"
},
"orderOneHere": {

View File

@ -724,7 +724,7 @@
"optionalBlockExplorerUrl": {
"message": "Blokeeri Exploreri URL (valikuline)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Sümbol (valikuline)"
},
"orderOneHere": {

View File

@ -734,7 +734,7 @@
"optionalBlockExplorerUrl": {
"message": "بلاک کردن مرورگر URL (انتخابی)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "سمبول (انتخابی)"
},
"orderOneHere": {

View File

@ -731,7 +731,7 @@
"optionalBlockExplorerUrl": {
"message": "Estä Explorerin URL-osoite (valinnainen)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Symboli (valinnainen)"
},
"orderOneHere": {

View File

@ -665,7 +665,7 @@
"optionalBlockExplorerUrl": {
"message": "Block Explorer URL (opsyonal)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Simbolo (opsyonal)"
},
"orderOneHere": {

View File

@ -716,7 +716,7 @@
"optionalBlockExplorerUrl": {
"message": "Bloquer l'URL de l'explorateur (facultatif)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Symbole (facultatif)"
},
"orderOneHere": {

View File

@ -731,7 +731,7 @@
"optionalBlockExplorerUrl": {
"message": "חסום כתובת URL של אקספלורר (אופציונלי)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "סמל (אופציונלי)"
},
"orderOneHere": {

View File

@ -731,7 +731,7 @@
"optionalBlockExplorerUrl": {
"message": "एक्सप्लोरर यूआरएल ब्लॉक (वैकल्पिक)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "सिम्बल (वैकल्पिक)"
},
"orderOneHere": {

View File

@ -727,7 +727,7 @@
"optionalBlockExplorerUrl": {
"message": "Blokiraj Explorerov URL (neobavezno)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Simbol (neobavezno)"
},
"orderOneHere": {

View File

@ -727,7 +727,7 @@
"optionalBlockExplorerUrl": {
"message": "Explorer URL letiltása (nem kötelező)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Szimbólum (opcionális)"
},
"orderOneHere": {

View File

@ -718,7 +718,7 @@
"optionalBlockExplorerUrl": {
"message": "Blokir URL Penjelajah (opsional)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Simbol (opsional)"
},
"orderOneHere": {

View File

@ -1050,7 +1050,7 @@
"optionalBlockExplorerUrl": {
"message": "URL del Block Explorer (opzionale)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Simbolo (opzionale)"
},
"orderOneHere": {

View File

@ -734,7 +734,7 @@
"optionalBlockExplorerUrl": {
"message": "ಅನ್ವೇಷಕ URL ಅನ್ನು ನಿರ್ಬಂಧಿಸಿ (ಐಚ್ಛಿಕ)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "ಚಿಹ್ನೆ (ಐಚ್ಛಿಕ)"
},
"orderOneHere": {

View File

@ -728,7 +728,7 @@
"optionalBlockExplorerUrl": {
"message": "익스플로러 URL 차단 (선택 사항)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Symbol (선택)"
},
"orderOneHere": {

View File

@ -734,7 +734,7 @@
"optionalBlockExplorerUrl": {
"message": "Blokuoti naršyklės URL (pasirinktinai)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Simbolis (nebūtinas)"
},
"orderOneHere": {

View File

@ -730,7 +730,7 @@
"optionalBlockExplorerUrl": {
"message": "Bloķēt Explorer URL (pēc izvēles)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Simbols (neobligāti)"
},
"orderOneHere": {

View File

@ -711,7 +711,7 @@
"optionalBlockExplorerUrl": {
"message": "Sekat URL Explorer (pilihan)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Simbol (pilihan)"
},
"orderOneHere": {

View File

@ -721,7 +721,7 @@
"optionalBlockExplorerUrl": {
"message": "Blokker Explorer URL (valgfritt)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Symbol (valgfritt)"
},
"orderOneHere": {

View File

@ -728,7 +728,7 @@
"optionalBlockExplorerUrl": {
"message": "Adres URL przeglądarki łańcucha bloków (opcjonalnie)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Symbol (opcjonalnie)"
},
"orderOneHere": {

View File

@ -722,7 +722,7 @@
"optionalBlockExplorerUrl": {
"message": "URL exploradora de blocos (opcional)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Símbolo (opcional)"
},
"orderOneHere": {

View File

@ -721,7 +721,7 @@
"optionalBlockExplorerUrl": {
"message": "URL explorator bloc (opțional)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Simbol (opțional)"
},
"orderOneHere": {

View File

@ -763,7 +763,7 @@
"optionalBlockExplorerUrl": {
"message": "URL блок-эксплорера (необязательно)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Символ (необязательно)"
},
"orderOneHere": {

View File

@ -703,7 +703,7 @@
"optionalBlockExplorerUrl": {
"message": "Blokovať URL Explorera (voliteľné)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Symbol (voliteľné)"
},
"orderOneHere": {

View File

@ -719,7 +719,7 @@
"optionalBlockExplorerUrl": {
"message": "Blokiraj URL Explorerja (poljubno)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Simbol (nezahtevano)"
},
"orderOneHere": {

View File

@ -725,7 +725,7 @@
"optionalBlockExplorerUrl": {
"message": "Blokirajte URL Explorer-a (opciono)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Simbol (opciono)"
},
"orderOneHere": {

View File

@ -718,7 +718,7 @@
"optionalBlockExplorerUrl": {
"message": "Block Explorer URL (valfritt)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Symbol (frivillig)"
},
"orderOneHere": {

View File

@ -712,7 +712,7 @@
"optionalBlockExplorerUrl": {
"message": "URL ya Block Explorer URL (hiari)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Ishara (hiari)"
},
"orderOneHere": {

View File

@ -734,7 +734,7 @@
"optionalBlockExplorerUrl": {
"message": "Блокувати Explorer URL (не обов'язково)"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Символ (не обов'язково)"
},
"orderOneHere": {

View File

@ -716,7 +716,7 @@
"optionalBlockExplorerUrl": {
"message": "屏蔽管理器 URL选填"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "符号(选填)"
},
"orderOneHere": {

View File

@ -725,7 +725,7 @@
"optionalBlockExplorerUrl": {
"message": "區塊鏈瀏覽器 URL非必要"
},
"optionalSymbol": {
"optionalCurrencySymbol": {
"message": "Symbol (可選)"
},
"orderOneHere": {

View File

@ -35,7 +35,7 @@ export default class NetworkForm extends PureComponent {
state = {
rpcUrl: this.props.rpcUrl,
chainId: this.props.chainId,
chainId: this.getDisplayChainIdFromProps(),
ticker: this.props.ticker,
networkName: this.props.networkName,
blockExplorerUrl: this.props.blockExplorerUrl,
@ -49,7 +49,6 @@ export default class NetworkForm extends PureComponent {
} = prevProps
const {
rpcUrl,
chainId,
ticker,
networkName,
networksTabIsInAddMode,
@ -68,7 +67,7 @@ export default class NetworkForm extends PureComponent {
} else if (prevRpcUrl !== rpcUrl) {
this.setState({
rpcUrl,
chainId,
chainId: this.getDisplayChainIdFromProps(),
ticker,
networkName,
blockExplorerUrl,
@ -94,17 +93,11 @@ export default class NetworkForm extends PureComponent {
}
resetForm() {
const {
rpcUrl,
chainId,
ticker,
networkName,
blockExplorerUrl,
} = this.props
const { rpcUrl, ticker, networkName, blockExplorerUrl } = this.props
this.setState({
rpcUrl,
chainId,
chainId: this.getDisplayChainIdFromProps(),
ticker,
networkName,
blockExplorerUrl,
@ -112,6 +105,28 @@ export default class NetworkForm extends PureComponent {
})
}
/**
* Ensures that the chainId is always displayed in decimal, even though
* it's stored in hexadecimal.
*
* Should be called to get the chainId whenever props are used to set the
* component's state.
*
* @returns {string} The props chainId in decimal.
*/
getDisplayChainIdFromProps() {
const { chainId: propsChainId } = this.props
if (
!propsChainId ||
typeof propsChainId !== 'string' ||
!propsChainId.startsWith('0x')
) {
return propsChainId
}
return new BigNumber(propsChainId, 16).toString(10)
}
onSubmit = async () => {
const {
setRpcTarget,
@ -129,13 +144,14 @@ export default class NetworkForm extends PureComponent {
blockExplorerUrl,
} = this.state
const formChainId = stateChainId.trim().toLowerCase()
// Ensure chainId is a 0x-prefixed, lowercase hex string
let chainId = stateChainId.trim().toLowerCase()
let chainId = formChainId
if (!chainId.startsWith('0x')) {
chainId = `0x${new BigNumber(chainId, 10).toString(16)}`
}
if (!(await this.validateChainIdOnSubmit(chainId, rpcUrl))) {
if (!(await this.validateChainIdOnSubmit(formChainId, chainId, rpcUrl))) {
return
}
@ -153,6 +169,10 @@ export default class NetworkForm extends PureComponent {
if (networksTabIsInAddMode) {
onClear()
} else {
this.setState({
chainId: this.getDisplayChainIdFromProps(),
})
}
}
@ -178,13 +198,7 @@ export default class NetworkForm extends PureComponent {
}
stateIsUnchanged() {
const {
rpcUrl,
chainId,
ticker,
networkName,
blockExplorerUrl,
} = this.props
const { rpcUrl, ticker, networkName, blockExplorerUrl } = this.props
const {
rpcUrl: stateRpcUrl,
@ -196,7 +210,7 @@ export default class NetworkForm extends PureComponent {
return (
stateRpcUrl === rpcUrl &&
stateChainId === chainId &&
stateChainId === this.getDisplayChainIdFromProps() &&
stateTicker === ticker &&
stateNetworkName === networkName &&
stateBlockExplorerUrl === blockExplorerUrl
@ -260,7 +274,7 @@ export default class NetworkForm extends PureComponent {
})
}
validateChainId = (chainIdArg = '') => {
validateChainIdOnChange = (chainIdArg = '') => {
const chainId = chainIdArg.trim()
let errorMessage = ''
@ -279,7 +293,17 @@ export default class NetworkForm extends PureComponent {
this.setErrorTo('chainId', errorMessage)
}
validateChainIdOnSubmit = async (chainId, rpcUrl) => {
/**
* Validates the chain ID by checking it against the `eth_chainId` return
* value from the given RPC URL.
* Assumes that all strings are non-empty and correctly formatted.
*
* @param {string} formChainId - Non-empty, hex or decimal number string from
* the form.
* @param {string} parsedChainId - The parsed, hex string chain ID.
* @param {string} rpcUrl - The RPC URL from the form.
*/
validateChainIdOnSubmit = async (formChainId, parsedChainId, rpcUrl) => {
const { t } = this.context
let errorMessage
let endpointChainId
@ -294,7 +318,22 @@ export default class NetworkForm extends PureComponent {
if (providerError || typeof endpointChainId !== 'string') {
errorMessage = t('failedToFetchChainId')
} else if (chainId !== endpointChainId) {
} else if (parsedChainId !== endpointChainId) {
// Here, we are in an error state. The endpoint should always return a
// hexadecimal string. If the user entered a decimal string, we attempt
// to convert the endpoint's return value to decimal before rendering it
// in an error message in the form.
if (!formChainId.startsWith('0x')) {
try {
endpointChainId = new BigNumber(endpointChainId, 16).toString(10)
} catch (err) {
log.warn(
'Failed to convert endpoint chain ID to decimal',
endpointChainId,
)
}
}
errorMessage = t('endpointReturnedDifferentChainId', [
endpointChainId.length <= 12
? endpointChainId
@ -394,17 +433,17 @@ export default class NetworkForm extends PureComponent {
{this.renderFormTextField(
'chainId',
'chainId',
this.setStateWithValue('chainId', this.validateChainId),
this.setStateWithValue('chainId', this.validateChainIdOnChange),
chainId,
null,
t('networkSettingsChainIdDescription'),
viewOnly ? null : t('networkSettingsChainIdDescription'),
)}
{this.renderFormTextField(
'symbol',
'network-ticker',
this.setStateWithValue('ticker'),
ticker,
'optionalSymbol',
'optionalCurrencySymbol',
)}
{this.renderFormTextField(
'blockExplorerUrl',