@metamask/ppom-validator
Advanced tools
Comparing version 0.12.0 to 0.13.0
@@ -9,2 +9,8 @@ # Changelog | ||
## [0.13.0] | ||
### Changed | ||
- Refactoring and code cleanup in PPOMController ([#103](https://github.com/MetaMask/ppom-validator/pull/103)) | ||
- Start fetching files for mainnet as blockaid preference is enabled ([#102](https://github.com/MetaMask/ppom-validator/pull/102)) | ||
- PPOM instance to stay when user switch the network ([#101](https://github.com/MetaMask/ppom-validator/pull/101)) | ||
## [0.12.0] | ||
@@ -89,3 +95,4 @@ ### Changed | ||
[Unreleased]: https://github.com/MetaMask/ppom-validator/compare/v0.12.0...HEAD | ||
[Unreleased]: https://github.com/MetaMask/ppom-validator/compare/v0.13.0...HEAD | ||
[0.13.0]: https://github.com/MetaMask/ppom-validator/compare/v0.12.0...v0.13.0 | ||
[0.12.0]: https://github.com/MetaMask/ppom-validator/compare/v0.11.0...v0.12.0 | ||
@@ -92,0 +99,0 @@ [0.11.0]: https://github.com/MetaMask/ppom-validator/compare/v0.10.0...v0.11.0 |
@@ -13,3 +13,3 @@ "use strict"; | ||
}; | ||
var _PPOMController_instances, _PPOMController_ppom, _PPOMController_ppomInitError, _PPOMController_provider, _PPOMController_storage, _PPOMController_refreshDataInterval, _PPOMController_fileScheduleInterval, _PPOMController_ppomMutex, _PPOMController_ppomProvider, _PPOMController_cdnBaseUrl, _PPOMController_providerRequestLimit, _PPOMController_providerRequests, _PPOMController_chainId, _PPOMController_dataUpdateDuration, _PPOMController_fileFetchScheduleDuration, _PPOMController_securityAlertsEnabled, _PPOMController_providerRequestsCount, _PPOMController_blockaidPublicKey, _PPOMController_ppomInitialised, _PPOMController_ppomInitialisationCallback, _PPOMController_initialisePPOM, _PPOMController_chainStatusIncludeSupportedNetworks, _PPOMController_networkIsSupported, _PPOMController_clearDataFetchIntervals, _PPOMController_resetToInactiveState, _PPOMController_onNetworkChange, _PPOMController_onPreferenceChange, _PPOMController_registerMessageHandlers, _PPOMController_resetPPOM, _PPOMController_reinitPPOM, _PPOMController_reinitPPOMForNetworkIfRequired, _PPOMController_isDataRequiredForCurrentChain, _PPOMController_updatePPOM, _PPOMController_updateVersionInfo, _PPOMController_checkFilePresentInStorage, _PPOMController_checkFilePath, _PPOMController_getFile, _PPOMController_setChainIdDataFetched, _PPOMController_getNewFilesForCurrentChain, _PPOMController_getListOfFilesToBeFetched, _PPOMController_deleteOldChainIds, _PPOMController_getNewFilesForAllChains, _PPOMController_getAPIResponse, _PPOMController_checkIfVersionInfoETagChanged, _PPOMController_fetchVersionInfo, _PPOMController_fetchBlob, _PPOMController_jsonRpcRequest, _PPOMController_getPPOM, _PPOMController_onDataUpdateDuration, _PPOMController_checkScheduleFileDownloadForAllChains; | ||
var _PPOMController_instances, _PPOMController_ppom, _PPOMController_ppomInitError, _PPOMController_provider, _PPOMController_storage, _PPOMController_refreshDataInterval, _PPOMController_fileScheduleInterval, _PPOMController_ppomMutex, _PPOMController_ppomProvider, _PPOMController_cdnBaseUrl, _PPOMController_providerRequestLimit, _PPOMController_providerRequests, _PPOMController_chainId, _PPOMController_dataUpdateDuration, _PPOMController_fileFetchScheduleDuration, _PPOMController_securityAlertsEnabled, _PPOMController_providerRequestsCount, _PPOMController_blockaidPublicKey, _PPOMController_ppomInitialised, _PPOMController_ppomInitialisationCallback, _PPOMController_initialisePPOM, _PPOMController_networkIsSupported, _PPOMController_clearDataFetchIntervals, _PPOMController_resetToInactiveState, _PPOMController_onNetworkChange, _PPOMController_onPreferenceChange, _PPOMController_registerMessageHandlers, _PPOMController_resetPPOM, _PPOMController_reinitPPOM, _PPOMController_reinitPPOMForNetworkIfRequired, _PPOMController_isDataRequiredForCurrentChain, _PPOMController_updatePPOM, _PPOMController_updateVersionInfo, _PPOMController_checkFilePresentInStorage, _PPOMController_checkFilePath, _PPOMController_getFile, _PPOMController_setChainIdDataFetched, _PPOMController_getNewFilesForChain, _PPOMController_getListOfFilesToBeFetched, _PPOMController_deleteOldChainIds, _PPOMController_getNewFilesForAllChains, _PPOMController_getAPIResponse, _PPOMController_checkIfVersionInfoETagChanged, _PPOMController_fetchVersionInfo, _PPOMController_fetchBlob, _PPOMController_jsonRpcRequest, _PPOMController_getPPOM, _PPOMController_onDataUpdateDuration, _PPOMController_checkScheduleFileDownloadForAllChains; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -110,2 +110,3 @@ exports.PPOMController = exports.NETWORK_CACHE_DURATION = exports.REFRESH_TIME_INTERVAL = void 0; | ||
}, | ||
versionFileETag: state?.versionFileETag ?? '', | ||
}; | ||
@@ -180,4 +181,18 @@ super({ | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_registerMessageHandlers).call(this); | ||
// start scheduled task to fetch data files | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_checkScheduleFileDownloadForAllChains).call(this); | ||
if (securityAlertsEnabled) { | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_updateVersionInfo).call(this) | ||
.then(async () => { | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_getNewFilesForChain).call(this, ETHEREUM_CHAIN_ID); | ||
// start scheduled task to fetch data files | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_checkScheduleFileDownloadForAllChains).call(this); | ||
}) | ||
.catch((error) => { | ||
console.error(`Error in initialising: ${error.message}`); | ||
}) | ||
.finally(() => { | ||
if (__classPrivateFieldGet(this, _PPOMController_ppomInitialisationCallback, "f")) { | ||
__classPrivateFieldGet(this, _PPOMController_ppomInitialisationCallback, "f").call(this); | ||
} | ||
}); | ||
} | ||
} | ||
@@ -193,8 +208,2 @@ /** | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_deleteOldChainIds).call(this); | ||
// If none of the networks in chainStatus are supported we stop fetching data files | ||
// and inactivate functionality by reseting PPOM | ||
if (!__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_chainStatusIncludeSupportedNetworks).call(this)) { | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_resetToInactiveState).call(this); | ||
return; | ||
} | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_updatePPOM).call(this); | ||
@@ -251,13 +260,4 @@ } | ||
throw error; | ||
}) | ||
.finally(() => { | ||
if (__classPrivateFieldGet(this, _PPOMController_ppomInitialisationCallback, "f")) { | ||
__classPrivateFieldGet(this, _PPOMController_ppomInitialisationCallback, "f").call(this); | ||
} | ||
}); | ||
} | ||
}, _PPOMController_chainStatusIncludeSupportedNetworks = function _PPOMController_chainStatusIncludeSupportedNetworks() { | ||
const networkIsSupported = __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_networkIsSupported).bind(this); | ||
return (this.state?.chainStatus && | ||
Object.keys(this.state?.chainStatus)?.some(networkIsSupported)); | ||
}, _PPOMController_networkIsSupported = function _PPOMController_networkIsSupported(chainId) { | ||
@@ -295,3 +295,2 @@ return chainId === ETHEREUM_CHAIN_ID; | ||
const existingNetworkObject = chainStatus[id]; | ||
const oldChainId = __classPrivateFieldGet(this, _PPOMController_chainId, "f"); | ||
__classPrivateFieldSet(this, _PPOMController_chainId, id, "f"); | ||
@@ -312,12 +311,2 @@ chainStatus = { | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_checkScheduleFileDownloadForAllChains).call(this); | ||
if (oldChainId !== id) { | ||
if (chainStatus[id]?.dataFetched) { | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_reinitPPOM).call(this).catch(() => { | ||
console.error('Error in re-init of PPOM'); | ||
}); | ||
} | ||
else { | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_resetPPOM).call(this); | ||
} | ||
} | ||
}, _PPOMController_onPreferenceChange = function _PPOMController_onPreferenceChange(preferenceControllerState) { | ||
@@ -330,5 +319,15 @@ const blockaidEnabled = preferenceControllerState.securityAlertsEnabled; | ||
if (blockaidEnabled) { | ||
// eslint-disable-next-line @typescript-eslint/no-floating-promises | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_initialisePPOM).call(this); | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_checkScheduleFileDownloadForAllChains).call(this); | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_updateVersionInfo).call(this) | ||
.then(async () => { | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_checkScheduleFileDownloadForAllChains).call(this); | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_getNewFilesForChain).call(this, ETHEREUM_CHAIN_ID); | ||
}) | ||
.catch((error) => { | ||
console.error(`Error in initialising: ${error.message}`); | ||
}) | ||
.finally(() => { | ||
if (__classPrivateFieldGet(this, _PPOMController_ppomInitialisationCallback, "f")) { | ||
__classPrivateFieldGet(this, _PPOMController_ppomInitialisationCallback, "f").call(this); | ||
} | ||
}); | ||
} | ||
@@ -350,5 +349,5 @@ else { | ||
*/ | ||
async function _PPOMController_reinitPPOM() { | ||
async function _PPOMController_reinitPPOM(chainId, files) { | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_resetPPOM).call(this); | ||
__classPrivateFieldSet(this, _PPOMController_ppom, await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_getPPOM).call(this), "f"); | ||
__classPrivateFieldSet(this, _PPOMController_ppom, await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_getPPOM).call(this, chainId, files), "f"); | ||
}, _PPOMController_reinitPPOMForNetworkIfRequired = | ||
@@ -363,3 +362,3 @@ /** | ||
if (__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_isDataRequiredForCurrentChain).call(this)) { | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_getNewFilesForCurrentChain).call(this); | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_getNewFilesForChain).call(this, __classPrivateFieldGet(this, _PPOMController_chainId, "f")); | ||
} | ||
@@ -407,8 +406,7 @@ }, _PPOMController_isDataRequiredForCurrentChain = function _PPOMController_isDataRequiredForCurrentChain() { | ||
*/ | ||
async function _PPOMController_getFile(fileVersionInfo, storageFoundCorrupted) { | ||
async function _PPOMController_getFile(fileVersionInfo) { | ||
const { storageMetadata } = this.state; | ||
// do not fetch file if the storage version is latest | ||
if (!storageFoundCorrupted && | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_checkFilePresentInStorage).call(this, storageMetadata, fileVersionInfo)) { | ||
return undefined; | ||
if (__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_checkFilePresentInStorage).call(this, storageMetadata, fileVersionInfo)) { | ||
return await __classPrivateFieldGet(this, _PPOMController_storage, "f").readFile(fileVersionInfo.name, fileVersionInfo.chainId); | ||
} | ||
@@ -435,16 +433,14 @@ // validate file path for valid characters | ||
if (chainIdObject) { | ||
if (!chainIdObject.dataFetched) { | ||
this.update((draftState) => { | ||
draftState.chainStatus = { | ||
...chainStatus, | ||
[chainId]: { | ||
...chainIdObject, | ||
dataFetched: true, | ||
versionInfo: versionInfoForChain, | ||
}, | ||
}; | ||
}); | ||
} | ||
this.update((draftState) => { | ||
draftState.chainStatus = { | ||
...chainStatus, | ||
[chainId]: { | ||
...chainIdObject, | ||
dataFetched: true, | ||
versionInfo: versionInfoForChain, | ||
}, | ||
}; | ||
}); | ||
} | ||
}, _PPOMController_getNewFilesForCurrentChain = | ||
}, _PPOMController_getNewFilesForChain = | ||
/* | ||
@@ -455,13 +451,17 @@ * Fetches new files for current network and save them to storage. | ||
*/ | ||
async function _PPOMController_getNewFilesForCurrentChain() { | ||
for (const fileVersionInfo of this.state.versionInfo) { | ||
if (fileVersionInfo.chainId !== __classPrivateFieldGet(this, _PPOMController_chainId, "f")) { | ||
continue; | ||
async function _PPOMController_getNewFilesForChain(chainId) { | ||
const versionInfoForCurrentChain = this.state.versionInfo.filter(({ chainId: id }) => id === chainId); | ||
let files = await Promise.all(versionInfoForCurrentChain.map(async (fileVersionInfo) => { | ||
let data; | ||
try { | ||
data = await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_getFile).call(this, fileVersionInfo); | ||
} | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_getFile).call(this, fileVersionInfo).catch((exp) => { | ||
catch (exp) { | ||
console.error(`Error in getting file ${fileVersionInfo.filePath}: ${exp.message}`); | ||
}); | ||
} | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_setChainIdDataFetched).call(this, __classPrivateFieldGet(this, _PPOMController_chainId, "f")); | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_reinitPPOM).call(this); | ||
} | ||
return [fileVersionInfo.name, data ? new Uint8Array(data) : undefined]; | ||
})); | ||
files = files.filter((data) => data?.[1] !== undefined); | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_setChainIdDataFetched).call(this, chainId); | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_reinitPPOM).call(this, chainId, files); | ||
}, _PPOMController_getListOfFilesToBeFetched = | ||
@@ -502,3 +502,3 @@ /* | ||
const currentTimestamp = new Date().getTime(); | ||
const chainIds = Object.keys(this.state.chainStatus); | ||
const chainIds = Object.keys(this.state.chainStatus).filter((id) => id !== ETHEREUM_CHAIN_ID); | ||
const oldChaninIds = chainIds.filter((chainId) => this.state.chainStatus[chainId].lastVisited < | ||
@@ -555,4 +555,4 @@ currentTimestamp - exports.NETWORK_CACHE_DURATION && | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_setChainIdDataFetched).call(this, fileVersionInfo.chainId); | ||
if (fileVersionInfo.chainId === __classPrivateFieldGet(this, _PPOMController_chainId, "f")) { | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_reinitPPOM).call(this); | ||
if (fileVersionInfo.chainId === ETHEREUM_CHAIN_ID) { | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_reinitPPOM).call(this, ETHEREUM_CHAIN_ID); | ||
} | ||
@@ -667,48 +667,53 @@ } | ||
*/ | ||
async function _PPOMController_getPPOM() { | ||
// For some reason ppom initialisation in contrructor fails for react native | ||
// thus it is added here to prevent validation from failing. | ||
// eslint-disable-next-line @typescript-eslint/no-floating-promises | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_initialisePPOM).call(this); | ||
__classPrivateFieldSet(this, _PPOMController_ppomInitError, undefined, "f"); | ||
const { chainStatus } = this.state; | ||
const chainInfo = chainStatus[__classPrivateFieldGet(this, _PPOMController_chainId, "f")]; | ||
if (!chainInfo?.versionInfo?.length) { | ||
__classPrivateFieldSet(this, _PPOMController_ppomInitError, `Aborting validation as no files are found for the network with chainId: ${__classPrivateFieldGet(this, _PPOMController_chainId, "f")}`, "f"); | ||
return undefined; | ||
} | ||
// Get all the files for the chainId | ||
let files = await Promise.all(chainInfo.versionInfo.map(async (file) => { | ||
let data; | ||
try { | ||
// First try to get file from storage | ||
data = await __classPrivateFieldGet(this, _PPOMController_storage, "f").readFile(file.name, file.chainId); | ||
async function _PPOMController_getPPOM(chainId, newFiles) { | ||
try { | ||
let files; | ||
__classPrivateFieldSet(this, _PPOMController_ppomInitError, undefined, "f"); | ||
// For some reason ppom initialisation in contrructor fails for react native | ||
// thus it is added here to prevent validation from failing. | ||
await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_initialisePPOM).call(this); | ||
const { chainStatus } = this.state; | ||
const versionInfo = chainStatus[chainId]?.versionInfo ?? | ||
this.state.versionInfo.filter(({ chainId: id }) => id === chainId); | ||
if (!versionInfo?.length) { | ||
__classPrivateFieldSet(this, _PPOMController_ppomInitError, `Aborting validation as no files are found for the network with chainId: ${chainId}`, "f"); | ||
return undefined; | ||
} | ||
catch { | ||
try { | ||
// Get the file from CDN if it is not found in storage | ||
data = await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_getFile).call(this, file, true); | ||
} | ||
catch (exp) { | ||
console.error(`Error in getting file ${file.filePath}: ${exp.message}`); | ||
} | ||
if (newFiles?.length) { | ||
files = newFiles; | ||
} | ||
if (data) { | ||
return [file.name, new Uint8Array(data)]; | ||
else { | ||
// Get all the files for the chainId | ||
files = await Promise.all(versionInfo.map(async (file) => { | ||
let data; | ||
try { | ||
data = await __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_getFile).call(this, file); | ||
} | ||
catch (exp) { | ||
console.error(`Error in getting file ${file.filePath}: ${exp.message}`); | ||
} | ||
if (data) { | ||
return [file.name, new Uint8Array(data)]; | ||
} | ||
return undefined; | ||
})); | ||
} | ||
files = files?.filter((data) => data?.[1] !== undefined); | ||
// The following code throw error if no data files are found for the chainId. | ||
// This check has been put in place after suggestion of security team. | ||
// If we want to disable ppom validation on all instances of Metamask, | ||
// this can be achieved by returning empty data from version file. | ||
if (files?.length !== versionInfo?.length) { | ||
__classPrivateFieldSet(this, _PPOMController_ppomInitError, `Aborting validation as not all files could not be downloaded for the network with chainId: ${chainId}`, "f"); | ||
return undefined; | ||
} | ||
return await __classPrivateFieldGet(this, _PPOMController_ppomMutex, "f").use(async () => { | ||
const { PPOM } = __classPrivateFieldGet(this, _PPOMController_ppomProvider, "f"); | ||
return PPOM.new(__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_jsonRpcRequest).bind(this), files); | ||
}); | ||
} | ||
catch (error) { | ||
__classPrivateFieldSet(this, _PPOMController_ppomInitError, error?.message, "f"); | ||
return undefined; | ||
})); | ||
files = files.filter((data) => data !== undefined); | ||
// The following code throw error if no data files are found for the chainId. | ||
// This check has been put in place after suggestion of security team. | ||
// If we want to disable ppom validation on all instances of Metamask, | ||
// this can be achieved by returning empty data from version file. | ||
if (files.length !== chainInfo?.versionInfo?.length) { | ||
__classPrivateFieldSet(this, _PPOMController_ppomInitError, `Aborting validation as not all files could not be downloaded for the network with chainId: ${__classPrivateFieldGet(this, _PPOMController_chainId, "f")}`, "f"); | ||
return undefined; | ||
} | ||
return await __classPrivateFieldGet(this, _PPOMController_ppomMutex, "f").use(async () => { | ||
const { PPOM } = __classPrivateFieldGet(this, _PPOMController_ppomProvider, "f"); | ||
return PPOM.new(__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_jsonRpcRequest).bind(this), files); | ||
}); | ||
}, _PPOMController_onDataUpdateDuration = function _PPOMController_onDataUpdateDuration() { | ||
@@ -719,4 +724,3 @@ this.updatePPOM().catch((exp) => { | ||
}, _PPOMController_checkScheduleFileDownloadForAllChains = function _PPOMController_checkScheduleFileDownloadForAllChains() { | ||
if (__classPrivateFieldGet(this, _PPOMController_securityAlertsEnabled, "f") && | ||
__classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_chainStatusIncludeSupportedNetworks).call(this)) { | ||
if (__classPrivateFieldGet(this, _PPOMController_securityAlertsEnabled, "f")) { | ||
if (!__classPrivateFieldGet(this, _PPOMController_refreshDataInterval, "f")) { | ||
@@ -723,0 +727,0 @@ __classPrivateFieldGet(this, _PPOMController_instances, "m", _PPOMController_onDataUpdateDuration).call(this); |
{ | ||
"name": "@metamask/ppom-validator", | ||
"version": "0.12.0", | ||
"version": "0.13.0", | ||
"description": "This module has code to integrate Blockaid PPOM with MetaMask", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/MetaMask/ppom-validator#readme", |
Sorry, the diff of this file is not supported yet
147040
1242