Skip to content
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

Fetch Extension Metadata on eth_requestAccounts #7039

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion app/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@
"activeTab",
"webRequest",
"*://*.eth/",
"notifications"
"notifications",
"management"
],
"web_accessible_resources": [
"inpage.js",
Expand Down
7 changes: 5 additions & 2 deletions app/scripts/controllers/provider-approval.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ProviderApprovalController extends SafeEventEmitter {
*
* @param {object} opts - opts for the middleware contains the origin for the middleware
*/
createMiddleware ({ origin, getSiteMetadata }) {
createMiddleware ({ origin, getSiteMetadata, getExtensionMetadata }) {
return createAsyncMiddleware(async (req, res, next) => {
// only handle requestAccounts
if (req.method !== 'eth_requestAccounts') return next()
Expand All @@ -40,8 +40,11 @@ class ProviderApprovalController extends SafeEventEmitter {
res.result = [this.preferencesController.getSelectedAddress()]
return
}

// get metadata from origin if extension or site
const metadata = await getExtensionMetadata(origin) || await getSiteMetadata(origin)

// register the provider request
const metadata = await getSiteMetadata(origin)
this._handleProviderRequest(origin, metadata.name, metadata.icon)
// wait for resolution of request
const approved = await new Promise(resolve => this.once(`resolvedRequest:${origin}`, ({ approved }) => resolve(approved)))
Expand Down
33 changes: 29 additions & 4 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -1358,9 +1358,9 @@ module.exports = class MetamaskController extends EventEmitter {
* @param {*} outStream - The stream to provide over.
* @param {string} origin - The URI of the requesting resource.
*/
setupProviderConnection (outStream, origin, publicApi) {
const getSiteMetadata = publicApi && publicApi.getSiteMetadata
const engine = this.setupProviderEngine(origin, getSiteMetadata)
setupProviderConnection (outStream, origin, publicApi = {}) {
const {getSiteMetadata, getExtensionMetadata} = publicApi
const engine = this.setupProviderEngine(origin, getSiteMetadata, getExtensionMetadata)

// setup connection
const providerStream = createEngineStream({ engine })
Expand All @@ -1384,7 +1384,7 @@ module.exports = class MetamaskController extends EventEmitter {
/**
* A method for creating a provider that is safely restricted for the requesting domain.
**/
setupProviderEngine (origin, getSiteMetadata) {
setupProviderEngine (origin, getSiteMetadata, getExtensionMetadata) {
// setup json rpc engine stack
const engine = new RpcEngine()
const provider = this.provider
Expand All @@ -1409,6 +1409,7 @@ module.exports = class MetamaskController extends EventEmitter {
engine.push(this.providerApprovalController.createMiddleware({
origin,
getSiteMetadata,
getExtensionMetadata,
}))
// forward to metamask primary provider
engine.push(providerAsMiddleware(provider))
Expand Down Expand Up @@ -1470,6 +1471,30 @@ module.exports = class MetamaskController extends EventEmitter {
const remote = await getRemote()
return await pify(remote.getSiteMetadata)()
},

getExtensionMetadata: (extensionId) => {
return new Promise((resolve) => {
if (!window.chrome || !window.chrome.management) {
return resolve(null)
}

window.chrome.management.getAll(extensions => {
if (!extensions) {
return resolve(null)
}

const extension = extensions.find(({enabled, id}) => enabled && id === extensionId)

if (!extension) {
return resolve(null)
}

const icon = extension.icons.reduce((largestIcon, icon) => icon.size > largestIcon.size ? icon : largestIcon, { size: 0 })

return resolve({name: extension.name, icon: icon.url})
})
})
},
}

return publicApi
Expand Down