mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-23 10:30:04 +01:00
2301d9980e
* eth_requestAccounts: wait on unlock return error on duplicate eth_requestAccounts add getUnlockPromise mock to permissions unit tests * only await unlock if already permitted * add notification badge for wait on unlock * fixup * more fixup * cleanup * update keyring controller, us its unlock event * move keyring update unlock logic to unlock event handler * fix unit tests * delete onUnlock handler * fix eth-keyring-controller resolution * update eth-keyring-controller
110 lines
2.8 KiB
JavaScript
110 lines
2.8 KiB
JavaScript
import createAsyncMiddleware from 'json-rpc-engine/src/createAsyncMiddleware'
|
|
import { ethErrors } from 'eth-json-rpc-errors'
|
|
|
|
/**
|
|
* Create middleware for handling certain methods and preprocessing permissions requests.
|
|
*/
|
|
export default function createMethodMiddleware ({
|
|
getAccounts,
|
|
getUnlockPromise,
|
|
hasPermission,
|
|
requestAccountsPermission,
|
|
store,
|
|
storeKey,
|
|
}) {
|
|
|
|
let isProcessingRequestAccounts = false
|
|
|
|
return createAsyncMiddleware(async (req, res, next) => {
|
|
|
|
switch (req.method) {
|
|
|
|
// Intercepting eth_accounts requests for backwards compatibility:
|
|
// The getAccounts call below wraps the rpc-cap middleware, and returns
|
|
// an empty array in case of errors (such as 4100:unauthorized)
|
|
case 'eth_accounts':
|
|
|
|
res.result = await getAccounts()
|
|
return
|
|
|
|
case 'eth_requestAccounts':
|
|
|
|
if (isProcessingRequestAccounts) {
|
|
res.error = ethErrors.rpc.resourceUnavailable(
|
|
'Already processing eth_requestAccounts. Please wait.'
|
|
)
|
|
return
|
|
}
|
|
|
|
if (hasPermission('eth_accounts')) {
|
|
isProcessingRequestAccounts = true
|
|
await getUnlockPromise()
|
|
isProcessingRequestAccounts = false
|
|
}
|
|
|
|
// first, just try to get accounts
|
|
let accounts = await getAccounts()
|
|
if (accounts.length > 0) {
|
|
res.result = accounts
|
|
return
|
|
}
|
|
|
|
// if no accounts, request the accounts permission
|
|
try {
|
|
await requestAccountsPermission()
|
|
} catch (err) {
|
|
res.error = err
|
|
return
|
|
}
|
|
|
|
// get the accounts again
|
|
accounts = await getAccounts()
|
|
/* istanbul ignore else: too hard to induce, see below comment */
|
|
if (accounts.length > 0) {
|
|
res.result = accounts
|
|
} else {
|
|
// this should never happen, because it should be caught in the
|
|
// above catch clause
|
|
res.error = ethErrors.rpc.internal(
|
|
'Accounts unexpectedly unavailable. Please report this bug.'
|
|
)
|
|
}
|
|
|
|
return
|
|
|
|
// custom method for getting metadata from the requesting domain,
|
|
// sent automatically by the inpage provider
|
|
case 'wallet_sendDomainMetadata':
|
|
|
|
const storeState = store.getState()[storeKey]
|
|
const extensionId = storeState[req.origin]
|
|
? storeState[req.origin].extensionId
|
|
: undefined
|
|
|
|
if (
|
|
req.domainMetadata &&
|
|
typeof req.domainMetadata.name === 'string'
|
|
) {
|
|
|
|
store.updateState({
|
|
[storeKey]: {
|
|
...storeState,
|
|
[req.origin]: {
|
|
extensionId,
|
|
...req.domainMetadata,
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
res.result = true
|
|
return
|
|
|
|
default:
|
|
break
|
|
}
|
|
|
|
next()
|
|
})
|
|
}
|