diff --git a/cypress/integration/nameDetail.spec.js b/cypress/integration/nameDetail.spec.js index 0b947ab13..b83833e9f 100644 --- a/cypress/integration/nameDetail.spec.js +++ b/cypress/integration/nameDetail.spec.js @@ -358,6 +358,19 @@ describe('Name detail view', () => { ]) }) + it('cannot change deprecated ipns contenthash', () => { + const url = `${NAME_ROOT}/abittooawesome4.eth` + cy.visit(url) + const DEPRECATED_CONTENT_HASH = 'ipns://app.uniswap.org' + cy.queryByText(DEPRECATED_CONTENT_HASH, { timeout: 10000 }).should('exist') + + cy.getByTestId('name-details', { timeout: 10000 }).within(container => { + cy.getByText('Add/Edit Record').click({ force: true }) + cy.wait(2000) + cy.queryByTestId('content-record-input-invalid') + }) + }) + it('can delete records', () => { cy.visit(`${NAME_ROOT}/notsoawesome.eth`) cy.getByTestId('name-details').within(container => { diff --git a/package.json b/package.json index 792bbe049..eab8a379d 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,9 @@ "@toruslabs/torus-embed": "^1.8.6", "@walletconnect/web3-provider": "^1.3.1", "@ensdomains/address-encoder": "^0.2.6", - "@ensdomains/mock": "^2.0.34", + "@ensdomains/mock": "^2.0.36", "@ensdomains/react-ens-address": "^0.0.27", - "@ensdomains/ui": "^3.0.58", + "@ensdomains/ui": "^3.0.62", "apollo-cache-inmemory": "^1.2.9", "apollo-client": "^2.4.5", "apollo-link": "^1.2.2", diff --git a/public/locales/cn.json b/public/locales/cn.json index 9b15b55cb..676063c17 100644 --- a/public/locales/cn.json +++ b/public/locales/cn.json @@ -66,8 +66,8 @@ "warning": "警告" }, "certificate": { - "button": "Request SSL certificate", - "warning": "SSL certificate for {{ name }}.link is not created yet" + "button": "请求 SSL 证书", + "warning": "{{ name }}.link 的 SSL 证书还没有创建" }, "childDomainItem": { "notmigrated": "暂未迁移" @@ -127,7 +127,7 @@ "title": "如何使用 ENS" }, "whatisens": { - "body": "以太坊名称服务(Ethereum Name Service)是一个基于以太坊区块链的分布式、开放和可扩展的命名系统。ENS 域名让人们不用再复制或输入冗长的区块链地址。通俗地说,ENS 就是区块链中的域名系统。", + "body": "以太坊名称服务(Ethereum Name Service)是一个基于以太坊区块链的分布式、开放和可扩展的域名系统。ENS 域名让人们不用再复制或输入冗长的区块链地址。通俗地说,ENS 就是区块链中的域名系统。", "title": "ENS 是什么" } }, @@ -159,11 +159,11 @@ "text": "等待交易被打包" }, "pricer": { - "gasDescription": "Estimated Gas Price (Step 1 + Step 3). The gas price will flucuate.", + "gasDescription": "预估的 Gas 价格(第 1 步 + 第 3 步)。Gas 价格存在波动。", "pricePerAmount": "当前选定时长的注册价格", "registrationPeriodLabel": "注册期", - "registrationPriceLabel": "Registration price to pay", - "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiSlow}}-{{gasPriceToGweiFast}} Gwei.", + "registrationPriceLabel": "注册费用", + "totalDescription": "预估的总费用(注册费 + Gas)。The gas price is based at {{gasPriceToGweiFast}} Gwei", "totalPriceLabel": "支付总额", "yearUnit": "年份" }, @@ -173,7 +173,7 @@ "manage": "管理域名", "register": "注册", "request": "请求注册", - "warning": "点击“注册”进入第三步" + "warning": "点击“注册”进入第 3 步" }, "favourite": "* 您可以收藏喜欢的域名,以便于浏览器关闭以后重新查看这个域名。", "notifications": { @@ -192,7 +192,7 @@ "step1": { "label": "第 1 步", "text": "需要在钱包中确认一笔交易,这是完成域名注册所需的两笔交易中的第一笔。", - "text2": "If the second transaction is not processed within 24 hours of the first, you will need to start again from step 1.", + "text2": "如果第 1 步完成之后的 24 小时内没有进行第 2 步,则需要从第 1 步重新开始。", "title": "请求注册" }, "step2": { @@ -206,7 +206,7 @@ "title": "完成注册" }, "titles": [ - "注册一个域名需要三个步骤", + "注册一个域名需要 3 个步骤", "您很快就可以完成域名注册", "您已经完成域名注册,现在可以管理域名了!" ] @@ -316,9 +316,9 @@ "closeEdit": "关闭 添加/编辑 记录", "messages": { "explanation": "反向解析将地址转换为域名。它能让 dapp 在其界面上显示 “{{name}}”,而不是 “{{account}}” 这个冗长的地址。如果您想为另一个账户设置反向解析,请先在 dapp 浏览器中切换帐户。", - "explanation2": "You can only select names you set this Ethereum Address as.", + "explanation2": "您只能选择已经解析至这个以太坊地址的域名。", "notSet": "反向记录:未设置", - "selectPlaceholder": "Select your ENS name", + "selectPlaceholder": "选择您的 ENS 域名", "setTo": "反向记录:解析至 ", "setToDifferent": "反向记录:已解析至另一个域名:" }, diff --git a/public/locales/de.json b/public/locales/de.json index 1756fd311..ac6fa39e2 100644 --- a/public/locales/de.json +++ b/public/locales/de.json @@ -167,7 +167,7 @@ "pricePerAmount": "Price per amount of time selected", "registrationPeriodLabel": "Registration Period", "registrationPriceLabel": "Registration price to pay", - "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiSlow}}-{{gasPriceToGweiFast}} Gwei.", + "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiFast}} Gwei", "totalPriceLabel": "Gesamtpreis", "yearUnit": "Jahr" }, diff --git a/public/locales/en.json b/public/locales/en.json index ec21b260c..d7d848a20 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -167,7 +167,7 @@ "pricePerAmount": "Price per amount of time selected", "registrationPeriodLabel": "Registration Period", "registrationPriceLabel": "Registration price to pay", - "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiSlow}}-{{gasPriceToGweiFast}} Gwei.", + "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiFast}} Gwei", "totalPriceLabel": "Total price to pay", "yearUnit": "year" }, diff --git a/public/locales/es.json b/public/locales/es.json index cb7f444f7..2cbae77f9 100644 --- a/public/locales/es.json +++ b/public/locales/es.json @@ -167,7 +167,7 @@ "pricePerAmount": "Price per amount of time selected", "registrationPeriodLabel": "Periodo de registración", "registrationPriceLabel": "Registration price to pay", - "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiSlow}}-{{gasPriceToGweiFast}} Gwei.", + "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiFast}} Gwei", "totalPriceLabel": "Precio total a pagar", "yearUnit": "año" }, diff --git a/public/locales/fr.json b/public/locales/fr.json index 51a22d68c..c9864a280 100644 --- a/public/locales/fr.json +++ b/public/locales/fr.json @@ -167,7 +167,7 @@ "pricePerAmount": "Price per amount of time selected", "registrationPeriodLabel": "Période d'enregistrement", "registrationPriceLabel": "Registration price to pay", - "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiSlow}}-{{gasPriceToGweiFast}} Gwei.", + "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiFast}} Gwei", "totalPriceLabel": "Prix ​​total à payer", "yearUnit": "année" }, diff --git a/public/locales/ja.json b/public/locales/ja.json index 8993c74ee..0301eb885 100644 --- a/public/locales/ja.json +++ b/public/locales/ja.json @@ -165,7 +165,7 @@ "pricePerAmount": "Price per amount of time selected", "registrationPeriodLabel": "登録期間", "registrationPriceLabel": "Registration price to pay", - "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiSlow}}-{{gasPriceToGweiFast}} Gwei.", + "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiFast}} Gwei", "totalPriceLabel": "お支払合計額", "yearUnit": "年" }, diff --git a/public/locales/ko.json b/public/locales/ko.json index 3c05e3f9f..df0919bdf 100644 --- a/public/locales/ko.json +++ b/public/locales/ko.json @@ -165,7 +165,7 @@ "pricePerAmount": "Price per amount of time selected", "registrationPeriodLabel": "등록 기간", "registrationPriceLabel": "Registration price to pay", - "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiSlow}}-{{gasPriceToGweiFast}} Gwei.", + "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiFast}} Gwei", "totalPriceLabel": "결제할 총 금액", "yearUnit": "년" }, diff --git a/public/locales/pl.json b/public/locales/pl.json index 8384df2ff..82520037f 100644 --- a/public/locales/pl.json +++ b/public/locales/pl.json @@ -169,7 +169,7 @@ "pricePerAmount": "Price per amount of time selected", "registrationPeriodLabel": "Czas rejestracji", "registrationPriceLabel": "Registration price to pay", - "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiSlow}}-{{gasPriceToGweiFast}} Gwei.", + "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiFast}} Gwei", "totalPriceLabel": "Łączna kwota do zapłaty", "yearUnit": "rok" }, diff --git a/public/locales/ru.json b/public/locales/ru.json index b94bf39be..ff68371d7 100644 --- a/public/locales/ru.json +++ b/public/locales/ru.json @@ -169,7 +169,7 @@ "pricePerAmount": "Price per amount of time selected", "registrationPeriodLabel": "Срок регистрации", "registrationPriceLabel": "Registration price to pay", - "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiSlow}}-{{gasPriceToGweiFast}} Gwei.", + "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiFast}} Gwei", "totalPriceLabel": "Общие сумма к оплате", "yearUnit": "год" }, diff --git a/public/locales/vi.json b/public/locales/vi.json index 9e9b9afeb..8314aecfa 100644 --- a/public/locales/vi.json +++ b/public/locales/vi.json @@ -165,7 +165,7 @@ "pricePerAmount": "Price per amount of time selected", "registrationPeriodLabel": "Thời gian đăng ký", "registrationPriceLabel": "Registration price to pay", - "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiSlow}}-{{gasPriceToGweiFast}} Gwei.", + "totalDescription": "Estimated Total (Price + Gas). The gas price is based at {{gasPriceToGweiFast}} Gwei", "totalPriceLabel": "Tổng giá thanh toán", "yearUnit": "Năm" }, diff --git a/src/api/manager/resolvers.js b/src/api/manager/resolvers.js index 5a2e159af..7e837ca7d 100644 --- a/src/api/manager/resolvers.js +++ b/src/api/manager/resolvers.js @@ -654,7 +654,7 @@ const resolvers = { records.content === '' ? emptyAddress : records.content - ? encodeContenthash(records.content) + ? encodeContenthash(records.content)?.encoded : undefined, records.textRecords, records.coins @@ -807,7 +807,8 @@ const resolvers = { provider }) const content = await resolverInstanceWithoutSigner.content(namehash) - return encodeContenthash('bzz://' + content) + const { encoded } = encodeContenthash('bzz://' + content) + return encoded } async function getContenthash(name) { diff --git a/src/components/Forms/Select.js b/src/components/Forms/Select.js index 591eb2675..5c10b61b3 100644 --- a/src/components/Forms/Select.js +++ b/src/components/Forms/Select.js @@ -29,10 +29,10 @@ const styles = { // : null, backgroundColor: 'white', textTransform: 'uppercase', - fontWeight: '700', + fontWeight: isSelected ? 700 : 500, fontSize: '12px', letterSpacing: '0.5px', - color: isDisabled ? '#ccc' : isSelected ? 'black' : '#ccc', + color: isDisabled ? '#ccc' : isSelected ? 'black' : '#666', cursor: isDisabled ? 'not-allowed' : 'default' } }, diff --git a/src/components/Links/ContentHashLink.js b/src/components/Links/ContentHashLink.js index 638891df1..5773300e4 100644 --- a/src/components/Links/ContentHashLink.js +++ b/src/components/Links/ContentHashLink.js @@ -1,7 +1,7 @@ import React from 'react' import styled from '@emotion/styled/macro' import { ReactComponent as ExternalLinkIcon } from '../Icons/externalLink.svg' -import { decodeContenthash, encodeContenthash } from '@ensdomains/ui' +import { getProtocolType } from '@ensdomains/ui' const ContentHashLinkContainer = styled('a')` display: inline-block; @@ -22,22 +22,12 @@ const ContentHashLinkContainer = styled('a')` } ` -const DecodedError = styled('div')` - white-space: normal; - overflow: scroll; -` - const ContentHashLink = ({ value, contentType, domain }) => { - if (contentType === 'oldcontent') { + if (contentType === 'oldcontent' || !value) { return
{value}
} - - const encoded = encodeContenthash(value) - const { protocolType, decoded, error } = decodeContenthash(encoded) + const { protocolType, decoded } = getProtocolType(value) let externalLink, url - if (error) { - return {error} - } if (protocolType === 'ipfs') { externalLink = `https://dweb.link/ipfs/${decoded}` // using ipfs's secured origin gateway url = `ipfs://${decoded}` @@ -50,6 +40,9 @@ const ContentHashLink = ({ value, contentType, domain }) => { } else if (protocolType === 'onion' || protocolType === 'onion3') { externalLink = `http://${decoded}.onion` url = `onion://${decoded}` + } else if (protocolType === 'sia') { + externalLink = `https://siasky.net/${decoded}` + url = `sia://${decoded}` } else { console.warn(`Unsupported protocol ${protocolType}`) } diff --git a/src/components/SingleName/NameRegister/EthRegistrationGasPrice.js b/src/components/SingleName/NameRegister/EthRegistrationGasPrice.js index a51221b92..1b392381b 100644 --- a/src/components/SingleName/NameRegister/EthRegistrationGasPrice.js +++ b/src/components/SingleName/NameRegister/EthRegistrationGasPrice.js @@ -73,13 +73,12 @@ const EthRegistrationGasPrice = ({ price, ethUsdPrice, gasPrice }) => { return ( - {ethVal.toFixed(3)} ETH + {registerGasSlow.toFixed(3)}- - {registerGasFast.toFixed(3)} ETH = {totalSlow.toFixed(3)}- - {totalFast.toFixed(3)} ETH + {ethVal.toFixed(3)} ETH + at least {registerGasFast.toFixed(3)} ETH gas + fee = at least {totalFast.toFixed(3)} ETH {ethVal && ethUsdPrice && ( {' '} - ${totalInUsdSlow.toFixed(2)}-${totalInUsdFast.toFixed(2)} + ${totalInUsdFast.toFixed(2)} USD )} diff --git a/src/components/SingleName/ResolverAndRecords/AddRecord.js b/src/components/SingleName/ResolverAndRecords/AddRecord.js index 976e7b48c..589ca3c62 100644 --- a/src/components/SingleName/ResolverAndRecords/AddRecord.js +++ b/src/components/SingleName/ResolverAndRecords/AddRecord.js @@ -125,6 +125,19 @@ const AddRecordButton = styled('div')` justify-content: flex-end; ` +const textRecordOptions = TEXT_RECORD_KEYS.slice() + .sort() + .map(key => ({ + label: key, + value: key + })) +const coinOptions = COIN_LIST.slice() + .sort() + .map(key => ({ + label: key, + value: key + })) + function TextRecordInput({ selectedRecord, updateValue, @@ -141,10 +154,7 @@ function TextRecordInput({ handleChange={setSelectedKey} placeholder="Key" addNewKey={true} - options={TEXT_RECORD_KEYS.map(key => ({ - label: key, - value: key - }))} + options={textRecordOptions} /> ({ - label: key, - value: key - }))} + options={coinOptions} /> { const value = event.target.value setUpdatedRecords(records => ({ diff --git a/src/utils/records.js b/src/utils/records.js index 342759bd5..d7343168a 100644 --- a/src/utils/records.js +++ b/src/utils/records.js @@ -15,8 +15,8 @@ export function validateRecord({ type, value, contentType, selectedKey }) { return isAddress case 'content': if (value === EMPTY_ADDRESS) return true // delete record - const encoded = encodeContenthash(value) - if (encoded) { + const { encoded, error: encodeError } = encodeContenthash(value) + if (!encodeError && encoded) { return isValidContenthash(encoded) } else { return false @@ -45,7 +45,7 @@ export function getPlaceholder(recordType, contentType) { return 'Enter an Ethereum address' case 'content': if (contentType === 'contenthash') { - return 'Enter a content hash (eg: /ipfs/..., ipfs://..., /ipns/..., ipns://..., bzz://..., onion://..., onion3://...)' + return 'Enter a content hash (eg: /ipfs/..., ipfs://..., /ipns/..., ipns://..., bzz://..., onion://..., onion3://..., sia://...)' } else { return 'Enter a content' } diff --git a/yarn.lock b/yarn.lock index 9d7525180..3acbf721d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1385,6 +1385,15 @@ multicodec "^1.0.4" multihashes "^2.0.0" +"@ensdomains/content-hash@^2.5.5": + version "2.5.5" + resolved "https://registry.yarnpkg.com/@ensdomains/content-hash/-/content-hash-2.5.5.tgz#3efb64ced7bc8c76d883648519fdcaa312ad6ae9" + integrity sha512-g97tsnHku7fC+uyWAPj71TlLmgI2TsMtDEsiXAGvK73eC67aTVCsEagk6sPIZbB7+iKV3DY2wTQQos2VGBLMTw== + dependencies: + cids "^0.8.3" + multicodec "^1.0.4" + multihashes "^2.0.0" + "@ensdomains/contracts@0.0.1", "@ensdomains/contracts@^0.0.1": version "0.0.1" resolved "https://registry.yarnpkg.com/@ensdomains/contracts/-/contracts-0.0.1.tgz#edb841955adbd6f86bddaf9d05f6d239d25d5ab7" @@ -1429,6 +1438,24 @@ table "^5.4.6" web3 "^1.3.0" +"@ensdomains/mock@^2.0.36": + version "2.0.36" + resolved "https://registry.yarnpkg.com/@ensdomains/mock/-/mock-2.0.36.tgz#308eb17b86b58a68990a89a872d1ba249cac5d55" + integrity sha512-JNtXo4m9wfDL0SHFHbAPQbWVNEagLbNKq+UzHlUTx+OWa9wZK6wNwJFi63o2p0IQiTpQJs1zc5MC/HQATH76Vg== + dependencies: + "@0xproject/utils" "^2.0.2" + "@babel/runtime" "^7.4.4" + "@ensdomains/contracts" "^0.0.1" + "@ensdomains/dnssec-oracle-anchors" "^0.0.1" + chalk "^3.0.0" + cross-fetch "^3.0.2" + dns-packet "^5.2.1" + eth-ens-namehash "^2.0.8" + lodash "^4.17.11" + moment "^2.26.0" + table "^5.4.6" + web3 "^1.3.0" + "@ensdomains/react-ens-address@^0.0.27": version "0.0.27" resolved "https://registry.yarnpkg.com/@ensdomains/react-ens-address/-/react-ens-address-0.0.27.tgz#42ba9a4563ad60b146bdb2b0c260b2a1f86baa8b" @@ -1465,16 +1492,16 @@ lodash "^4.17.11" web3 "^1.3.0" -"@ensdomains/ui@^3.0.58": - version "3.0.58" - resolved "https://registry.yarnpkg.com/@ensdomains/ui/-/ui-3.0.58.tgz#b028b190f036c4151e771e2c74e91b8e279af006" - integrity sha512-EUWB2QtZQ/q8WFvk/MaxPiVB7EWaQktqTICmLYAI7MtTPSgOoxxAV/v0j2b5J+yeXzylYLavJSv9c6eHaw+JSw== +"@ensdomains/ui@^3.0.61": + version "3.0.61" + resolved "https://registry.yarnpkg.com/@ensdomains/ui/-/ui-3.0.61.tgz#8263cce026eb4496b44618de843fac42ab0fbdaa" + integrity sha512-QrweOs7dfjX0h0DG1kybm+lMEBEt2da6R9JnPxvaYLSVesN0ikT3CWwum0WopJw8p7d7D/1T4+gkHGD/o7vxkA== dependencies: "@0xproject/utils" "^2.0.2" "@babel/plugin-proposal-class-properties" "^7.8.3" "@babel/runtime" "^7.4.4" "@ensdomains/address-encoder" "^0.2.5" - "@ensdomains/content-hash" "^2.5.3" + "@ensdomains/content-hash" "^2.5.5" "@ensdomains/contracts" "^0.0.1" "@ensdomains/dnsprovejs" "^0.2.0" "@ensdomains/mock" "^2.0.34"