-
Notifications
You must be signed in to change notification settings - Fork 5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integration ENS with IPFS #4405
Changes from all commits
695b157
88a6b4e
8b8cc94
86ead43
829deac
384cb12
181a11e
68d119c
4e14313
77d17f2
cc5bdad
f90d070
8a571ec
11736e6
595447c
13b03ec
f38dc03
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<html> | ||
<head> | ||
<title>MetaMask</title> | ||
<style> | ||
*{ | ||
padding: 0; | ||
margin: 0; | ||
box-sizing: border-box; | ||
} | ||
img{ | ||
display: block; | ||
} | ||
html, body{ | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
width: 100%; | ||
height: 100%; | ||
} | ||
.app{ | ||
position: relative; | ||
width: 100%; | ||
height: auto; | ||
overflow: hidden; | ||
} | ||
img{ | ||
display: block; | ||
width: 100%; | ||
height: auto; | ||
} | ||
h2{ | ||
display: block; | ||
width: 100%; | ||
overflow: hidden; | ||
position: absolute; | ||
bottom: 20%; | ||
left: 0; | ||
color: #1b243d; | ||
text-align: center; | ||
} | ||
h2 > a{ | ||
color: #1b243d; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div class="app"> | ||
<img src="./images/404.png" alt=""> | ||
<h2>Powered by <a href="https://www.portal.network/">Portal Network</a></h2> | ||
</div> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<html> | ||
<head> | ||
<title>MetaMask Error</title> | ||
<link href="https://fonts.googleapis.com/css?family=Rokkitt" rel="stylesheet"> | ||
<style> | ||
*{ | ||
padding: 0; | ||
margin: 0; | ||
box-sizing: border-box; | ||
} | ||
img{ | ||
display: block; | ||
} | ||
html, body{ | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
width: 100%; | ||
height: 100%; | ||
} | ||
@keyframes logoAmin{ | ||
from {transform: scale(1);} | ||
50%{transform: scale(1.1);} | ||
to {transform: scale(1);} | ||
} | ||
.errorBox{ | ||
width: 70%; | ||
height: auto; | ||
overflow: hidden; | ||
background-image: url("./images/deadface.png"); | ||
background-repeat: no-repeat; | ||
background-position: 100% 50%; | ||
background-size: auto 90%; | ||
padding: 5px; | ||
} | ||
.errorBox > img{ | ||
width: 100px; | ||
height: auto; | ||
margin-bottom: 25px; | ||
animation: logoAmin 1s infinite linear; | ||
} | ||
.errorBox > h1, .errorBox > h2{ | ||
letter-spacing: 2px; | ||
} | ||
.errorBox > h1{ | ||
color: #9b9b9b; | ||
font-size: 40px; | ||
} | ||
.errorBox > h2{ | ||
color: #1b243d; | ||
font-size: 20px; | ||
padding-top: 5px; | ||
} | ||
.errorBox > h2 >a{ | ||
color: #1b243d; | ||
} | ||
.errorBox > h2 >a:hover{ | ||
color: #44588e; | ||
} | ||
|
||
.errorBox > h1 > span{ | ||
color: #33559f; | ||
} | ||
|
||
</style> | ||
</head> | ||
<body> | ||
<div class="errorBox"> | ||
<img src="./images/logo.png" alt=""> | ||
<h1><span id="name"></span> not found</h1> | ||
<h2>Powered by <a href="https://www.portal.network/">Portal Network</a></h2> | ||
</div> | ||
<script> | ||
let index = location.href.lastIndexOf("?name=") | ||
let name = location.href.slice(index + 6) | ||
document.getElementById("name").innerHTML = name | ||
</script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<html> | ||
<head> | ||
<title>MetaMask Loading</title> | ||
<style> | ||
#div-logo { | ||
position: absolute; | ||
top: 50%; | ||
left: 50%; | ||
transform: translate(-50%, -50%); | ||
width: 256px; | ||
} | ||
#logo { | ||
width: 100%; | ||
animation: pulse 1s ease-in-out infinite; | ||
} | ||
@keyframes pulse { | ||
0% { | ||
opacity: 1; | ||
} | ||
50% { | ||
opacity: 0.5; | ||
transform: scale(0.95, 0.95); | ||
} | ||
100% { | ||
opacity: 1; | ||
} | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div id="div-logo"> | ||
<img id="logo" src="./images/loginglogo.svg"> | ||
</div> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,7 +59,10 @@ | |
"unlimitedStorage", | ||
"clipboardWrite", | ||
"http://localhost:8545/", | ||
"https://*.infura.io/" | ||
"https://*.infura.io/", | ||
"activeTab", | ||
"webRequest", | ||
"*://*.eth/" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to appear in permissions dialog for Chrome as "eth websites" without an indication it's talking about a TLD. Leaving the user wondering "What is an eth website?" |
||
], | ||
"web_accessible_resources": [ | ||
"inpage.js" | ||
|
@@ -72,4 +75,4 @@ | |
"*" | ||
] | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,8 @@ const setupMetamaskMeshMetrics = require('./lib/setupMetamaskMeshMetrics') | |
const EdgeEncryptor = require('./edge-encryptor') | ||
const getFirstPreferredLangCode = require('./lib/get-first-preferred-lang-code') | ||
const getObjStructure = require('./lib/getObjStructure') | ||
const ipfsContent = require('./lib/ipfsContent.js') | ||
|
||
const { | ||
ENVIRONMENT_TYPE_POPUP, | ||
ENVIRONMENT_TYPE_NOTIFICATION, | ||
|
@@ -66,6 +68,7 @@ initialize().catch(log.error) | |
// setup metamask mesh testing container | ||
setupMetamaskMeshMetrics() | ||
|
||
|
||
/** | ||
* An object representing a transaction, in whatever state it is in. | ||
* @typedef TransactionMeta | ||
|
@@ -155,6 +158,7 @@ async function initialize () { | |
const initLangCode = await getFirstPreferredLangCode() | ||
await setupController(initState, initLangCode) | ||
log.debug('MetaMask initialization complete.') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @danfinlay For the first time can not connect with, the issue that the The fix code look likes: let defaultProvider = initState.NetworkController === undefined ? { type: "mainnet" } : initState.NetworkController.provider;
ipfsContent(defaultProvider); |
||
ipfsContent(initState.NetworkController.provider) | ||
} | ||
|
||
// | ||
|
@@ -258,6 +262,7 @@ function setupController (initState, initLangCode) { | |
}) | ||
global.metamaskController = controller | ||
|
||
|
||
// report failed transactions to Sentry | ||
controller.txController.on(`tx:status-update`, (txId, status) => { | ||
if (status !== 'failed') return | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
const extension = require('extensionizer') | ||
const resolver = require('./resolver.js') | ||
|
||
module.exports = function (provider) { | ||
extension.webRequest.onBeforeRequest.addListener(details => { | ||
const urlhttpreplace = details.url.replace(/\w+?:\/\//, '') | ||
const url = urlhttpreplace.replace(/[\\/].*/g, '') // eslint-disable-line no-useless-escape | ||
let domainhtml = urlhttpreplace.match(/[\\/].*/g) // eslint-disable-line no-useless-escape | ||
let clearTime = null | ||
const name = url.replace(/\/$/g, '') | ||
if (domainhtml === null) domainhtml = [''] | ||
extension.tabs.getSelected(null, tab => { | ||
extension.tabs.update(tab.id, { url: 'loading.html' }) | ||
|
||
clearTime = setTimeout(() => { | ||
return extension.tabs.update(tab.id, { url: '404.html' }) | ||
}, 60000) | ||
|
||
resolver.resolve(name, provider).then(ipfsHash => { | ||
clearTimeout(clearTime) | ||
let url = 'https://ipfs.infura.io/ipfs/' + ipfsHash + domainhtml[0] | ||
return fetch(url, { method: 'HEAD' }).then(response => response.status).then(statusCode => { | ||
if (statusCode !== 200) return extension.tabs.update(tab.id, { url: '404.html' }) | ||
extension.tabs.update(tab.id, { url: url }) | ||
}) | ||
.catch(err => { | ||
url = 'https://ipfs.infura.io/ipfs/' + ipfsHash + domainhtml[0] | ||
extension.tabs.update(tab.id, {url: url}) | ||
return err | ||
}) | ||
}) | ||
.catch(err => { | ||
clearTimeout(clearTime) | ||
const url = err === 'unsupport' ? 'unsupport' : 'error' | ||
extension.tabs.update(tab.id, {url: `${url}.html?name=${name}`}) | ||
}) | ||
}) | ||
return { cancel: true } | ||
}, {urls: ['*://*.eth/', '*://*.eth/*']}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
const namehash = require('eth-ens-namehash') | ||
const multihash = require('multihashes') | ||
const HttpProvider = require('ethjs-provider-http') | ||
const Eth = require('ethjs-query') | ||
const EthContract = require('ethjs-contract') | ||
const registrarAbi = require('./contracts/registrar') | ||
const resolverAbi = require('./contracts/resolver') | ||
|
||
function ens (name, provider) { | ||
const eth = new Eth(new HttpProvider(getProvider(provider.type))) | ||
const hash = namehash.hash(name) | ||
const contract = new EthContract(eth) | ||
const Registrar = contract(registrarAbi).at(getRegistrar(provider.type)) | ||
return new Promise((resolve, reject) => { | ||
if (provider.type === 'mainnet' || provider.type === 'ropsten') { | ||
Registrar.resolver(hash).then((address) => { | ||
if (address === '0x0000000000000000000000000000000000000000') { | ||
reject(null) | ||
} else { | ||
const Resolver = contract(resolverAbi).at(address['0']) | ||
return Resolver.content(hash) | ||
} | ||
}).then((contentHash) => { | ||
if (contentHash['0'] === '0x0000000000000000000000000000000000000000000000000000000000000000') reject(null) | ||
if (contentHash.ret !== '0x') { | ||
const hex = contentHash['0'].substring(2) | ||
const buf = multihash.fromHexString(hex) | ||
resolve(multihash.toB58String(multihash.encode(buf, 'sha2-256'))) | ||
} else { | ||
reject(null) | ||
} | ||
}) | ||
} else { | ||
return reject('unsupport') | ||
} | ||
}) | ||
} | ||
|
||
function getProvider (type) { | ||
switch (type) { | ||
case 'mainnet': | ||
return 'https://mainnet.infura.io/' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would rather we use the user's provider, provided by MetaMask, to reduce our number of blockchain connections, but for this feature, I can see the benefit of this simplicity, there aren't other chains w/ the ENS resolver anyway, this could be optimized later... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No problem, we will keep updating this part in the future. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yo no estoy de acuerdo en la utilización de trezor, para poder retirar mi fondos |
||
case 'ropsten': | ||
return 'https://ropsten.infura.io/' | ||
default: | ||
return 'http://localhost:8545/' | ||
} | ||
} | ||
|
||
function getRegistrar (type) { | ||
switch (type) { | ||
case 'mainnet': | ||
return '0x314159265dd8dbb310642f98f50c066173c1259b' | ||
case 'ropsten': | ||
return '0x112234455c3a32fd11230c42e7bccd4a84e02010' | ||
default: | ||
return '0x0000000000000000000000000000000000000000' | ||
} | ||
} | ||
|
||
module.exports.resolve = function (name, provider) { | ||
const path = name.split('.') | ||
const tld = path[path.length - 1] | ||
if (tld === 'eth') { | ||
return ens(name, provider) | ||
} else { | ||
return new Promise((resolve, reject) => { | ||
reject(null) | ||
}) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>MetaMask</title> | ||
</head> | ||
<style> | ||
*{ | ||
padding: 0; | ||
margin: 0; | ||
box-sizing: border-box; | ||
} | ||
img{ | ||
display: block; | ||
} | ||
html, body{ | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
width: 100%; | ||
height: 100%; | ||
} | ||
@keyframes logoAmin{ | ||
from {transform: scale(1);} | ||
50%{transform: scale(1.1);} | ||
to {transform: scale(1);} | ||
} | ||
.unsupport{ | ||
width: 80%; | ||
height: auto; | ||
overflow: hidden; | ||
padding: 10px; | ||
} | ||
.unsupport > img{ | ||
margin: 0 auto 31px auto; | ||
width: 136px; | ||
height: auto; | ||
animation: logoAmin 1s infinite linear; | ||
} | ||
.unsupport > h1{ | ||
text-align: center; | ||
font-family: Gotham; | ||
font-size: 18px; | ||
font-weight: 500; | ||
font-style: normal; | ||
font-stretch: normal; | ||
line-height: normal; | ||
letter-spacing: 1.3px; | ||
color: #33559f; | ||
} | ||
|
||
</style> | ||
<body> | ||
<div class="unsupport"> | ||
<img src="./images/cancel.png" alt=""> | ||
<h1>ENS resolver only support on Ethereum mainnet</h1> | ||
</div> | ||
</body> | ||
</html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure how I felt about this at first, but you know, getting credit for what you do seems pretty fair. I'm fine leaving it up, at least for a while. The same way we link to 409H for the phishing detector.