From 29f09b2b60ab6ad2a8082cbce72eb7a797914f37 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Sun, 3 May 2020 17:20:05 +0100 Subject: [PATCH 1/3] feat: support ipns address translations License: MIT Signed-off-by: Henrique Dias --- CHANGELOG.md | 1 + app/scripts/controllers/preferences.js | 2 +- app/scripts/lib/ens-ipfs/resolver.js | 2 +- app/scripts/lib/ens-ipfs/setup.js | 4 +- app/scripts/migrations/045.js | 32 +++++++++ app/scripts/migrations/index.js | 1 + test/unit/migrations/045-test.js | 92 ++++++++++++++++++++++++++ 7 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 app/scripts/migrations/045.js create mode 100644 test/unit/migrations/045-test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 975a70217ebc..203ad8992c21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Current Develop Branch - [#7912](https://github.com/MetaMask/metamask-extension/pull/7912): Disable import button for empty string/file - [#8246](https://github.com/MetaMask/metamask-extension/pull/8246): Make seed phrase import case-insensitive +- [#8502](https://github.com/MetaMask/metamask-extension/pull/8502): Add support for IPFS address resolution ## 7.7.0 Thu Nov 28 2019 - [#7004](https://github.com/MetaMask/metamask-extension/pull/7004): Connect distinct accounts per site diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 725d9bb90fa6..ccbeab0d7af8 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -61,7 +61,7 @@ export default class PreferencesController { metaMetricsSendCount: 0, // ENS decentralized website resolution - ipfsGateway: 'ipfs.dweb.link', + ipfsGateway: 'dweb.link', }, opts.initState) this.diagnostics = opts.diagnostics diff --git a/app/scripts/lib/ens-ipfs/resolver.js b/app/scripts/lib/ens-ipfs/resolver.js index 7c25278d69b2..14cc045a6a41 100644 --- a/app/scripts/lib/ens-ipfs/resolver.js +++ b/app/scripts/lib/ens-ipfs/resolver.js @@ -32,7 +32,7 @@ export default async function resolveEnsToIpfsContentId ({ provider, name }) { let decodedContentHash = contentHash.decode(rawContentHash) const type = contentHash.getCodec(rawContentHash) - if (type === 'ipfs-ns') { + if (type === 'ipfs-ns' || type === 'ipns-ns') { decodedContentHash = contentHash.helpers.cidV0ToV1Base32(decodedContentHash) } diff --git a/app/scripts/lib/ens-ipfs/setup.js b/app/scripts/lib/ens-ipfs/setup.js index c9b81299efa3..d1fc426744e4 100644 --- a/app/scripts/lib/ens-ipfs/setup.js +++ b/app/scripts/lib/ens-ipfs/setup.js @@ -44,8 +44,8 @@ export default function setupEnsIpfsResolver ({ provider, getCurrentNetwork, get let url = `https://app.ens.domains/name/${name}` try { const { type, hash } = await resolveEnsToIpfsContentId({ provider, name }) - if (type === 'ipfs-ns') { - const resolvedUrl = `https://${hash}.${ipfsGateway}${path}${search || ''}${fragment || ''}` + if (type === 'ipfs-ns' || type === 'ipns-ns') { + const resolvedUrl = `https://${hash}.${type.slice(0, 4)}.${ipfsGateway}${path}${search || ''}${fragment || ''}` try { // check if ipfs gateway has result const response = await window.fetch(resolvedUrl, { method: 'HEAD' }) diff --git a/app/scripts/migrations/045.js b/app/scripts/migrations/045.js new file mode 100644 index 000000000000..1e1dfae9950b --- /dev/null +++ b/app/scripts/migrations/045.js @@ -0,0 +1,32 @@ +const version = 45 +import { cloneDeep } from 'lodash' + +/** + * Replace ipfsGateway by 'dweb.link'. + */ +export default { + version, + migrate: async function (originalVersionedData) { + const versionedData = cloneDeep(originalVersionedData) + versionedData.meta.version = version + const state = versionedData.data + versionedData.data = transformState(state) + return versionedData + }, +} + +const outdatedGateways = [ + 'ipfs.io', + 'ipfs.dweb.link', +] + +function transformState (state) { + if (!state.PreferencesController) { + return state + } + + if (!state.PreferencesController.ipfsGateway || outdatedGateways.includes(state.PreferencesController.ipfsGateway)) { + state.PreferencesController.ipfsGateway = 'dweb.link' + } + return state +} diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index 7a9b0dc5d2dd..b05986dd9181 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -55,6 +55,7 @@ const migrations = [ require('./042').default, require('./043').default, require('./044').default, + require('./045').default, ] export default migrations diff --git a/test/unit/migrations/045-test.js b/test/unit/migrations/045-test.js new file mode 100644 index 000000000000..650e06f38d8e --- /dev/null +++ b/test/unit/migrations/045-test.js @@ -0,0 +1,92 @@ +import assert from 'assert' +import migration45 from '../../../app/scripts/migrations/045' + +describe('migration #45', function () { + it('should update the version metadata', function (done) { + const oldStorage = { + 'meta': { + 'version': 44, + }, + 'data': {}, + } + + migration45.migrate(oldStorage) + .then((newStorage) => { + assert.deepEqual(newStorage.meta, { + 'version': 45, + }) + done() + }) + .catch(done) + }) + + it('should update ipfsGateway value if outdated', function (done) { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + ipfsGateway: 'ipfs.dweb.link', + bar: 'baz', + }, + foo: 'bar', + }, + } + + migration45.migrate(oldStorage) + .then((newStorage) => { + assert.deepEqual(newStorage.data, { + PreferencesController: { + ipfsGateway: 'dweb.link', + bar: 'baz', + }, + foo: 'bar', + }) + done() + }) + .catch(done) + }) + + it('should not update ipfsGateway value if custom set', function (done) { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + ipfsGateway: 'blah', + bar: 'baz', + }, + foo: 'bar', + }, + } + + migration45.migrate(oldStorage) + .then((newStorage) => { + assert.deepEqual(newStorage.data, { + PreferencesController: { + ipfsGateway: 'blah', + bar: 'baz', + }, + foo: 'bar', + }) + done() + }) + .catch(done) + }) + + it('should do nothing if no PreferencesController key', function (done) { + const oldStorage = { + meta: {}, + data: { + foo: 'bar', + }, + } + + migration45.migrate(oldStorage) + .then((newStorage) => { + assert.deepEqual(newStorage.data, { + foo: 'bar', + }) + done() + }) + .catch(done) + }) +}) From e4d6f15860107d429116dd363a18a4661304054d Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 14 May 2020 08:03:53 +0100 Subject: [PATCH 2/3] Update app/scripts/migrations/045.js Co-authored-by: Whymarrh Whitby --- app/scripts/migrations/045.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/migrations/045.js b/app/scripts/migrations/045.js index 1e1dfae9950b..158bfeee96d6 100644 --- a/app/scripts/migrations/045.js +++ b/app/scripts/migrations/045.js @@ -2,7 +2,7 @@ const version = 45 import { cloneDeep } from 'lodash' /** - * Replace ipfsGateway by 'dweb.link'. + * Replaces {@code PreferencesController.ipfsGateway} with 'dweb.link' if set */ export default { version, From e6790b5aaa4de80ea4b0802239b37a8fdb117af0 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 14 May 2020 08:04:04 +0100 Subject: [PATCH 3/3] Update app/scripts/migrations/045.js Co-authored-by: Whymarrh Whitby --- app/scripts/migrations/045.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/scripts/migrations/045.js b/app/scripts/migrations/045.js index 158bfeee96d6..9ff7ded5550b 100644 --- a/app/scripts/migrations/045.js +++ b/app/scripts/migrations/045.js @@ -21,11 +21,7 @@ const outdatedGateways = [ ] function transformState (state) { - if (!state.PreferencesController) { - return state - } - - if (!state.PreferencesController.ipfsGateway || outdatedGateways.includes(state.PreferencesController.ipfsGateway)) { + if (outdatedGateways.includes(state?.PreferencesController?.ipfsGateway)) { state.PreferencesController.ipfsGateway = 'dweb.link' } return state