From 7dfea3f97ec7eaaa5ab6f5a0591ce9a6dbfb7ed3 Mon Sep 17 00:00:00 2001 From: Jyoti Puri Date: Thu, 29 Aug 2024 18:10:52 +0530 Subject: [PATCH] Add support for multichain --- src/ppom-controller.test.ts | 27 +++++++++++++++++++++- src/ppom-controller.ts | 45 ++++++++++++++++++++----------------- 2 files changed, 50 insertions(+), 22 deletions(-) diff --git a/src/ppom-controller.test.ts b/src/ppom-controller.test.ts index 01c6d78..ac8bfdd 100644 --- a/src/ppom-controller.test.ts +++ b/src/ppom-controller.test.ts @@ -89,6 +89,31 @@ describe('PPOMController', () => { expect(result).toStrictEqual(dummyResponse); }); + it('should initialise PPOM on even different network', async () => { + buildFetchSpy({ + status: 200, + json: () => [ + { + name: 'blob', + chainId: '0xa', + version: '1.0.0', + checksum: + '409a7f83ac6b31dc8c77e3ec18038f209bd2f545e0f4177c2e2381aa4e067b49', + signature: + '0x304402206d433e9172960de6717d94ae263e47eefacd3584a3274a452f8f9567b3a797db02201b2e423188fb3f9daa6ce6a8723f69df26bd3ceeee81f77250526b91e093614f', + filePath: 'blob', + }, + ], + }); + const { ppomController } = buildPPOMController(); + + const result = await ppomController.usePPOM(async (ppom: any) => { + expect(ppom).toBeDefined(); + return Promise.resolve(dummyResponse); + }, '0xa'); + expect(result).toStrictEqual(dummyResponse); + }); + it('should not fetch files for network not supported for PPOM validations', async () => { const spy = buildFetchSpy( { @@ -130,7 +155,7 @@ describe('PPOMController', () => { await ppomController.usePPOM(async (ppom: any) => { const result = await ppom.testJsonRPCRequest(); - expect(result).toBe('DUMMY_VALUE'); + expect(result.result).toBe('DUMMY_VALUE'); }); }); diff --git a/src/ppom-controller.ts b/src/ppom-controller.ts index 9aa39ae..4c3cdaf 100644 --- a/src/ppom-controller.ts +++ b/src/ppom-controller.ts @@ -322,29 +322,29 @@ export class PPOMController extends BaseController< * This function receives a callback that will be called with the PPOM. * * @param callback - Callback to be invoked with PPOM. + * @param chainId - ChainId of confirmation. */ async usePPOM( callback: (ppom: PPOM) => Promise, + chainId?: string, ): Promise }> { + const chainIdForRequest = chainId ?? this.#chainId; if (!this.#securityAlertsEnabled) { throw Error('User has securityAlertsEnabled set to false'); } - if (!blockaidValidationSupportedForNetwork(this.#chainId)) { + if (!blockaidValidationSupportedForNetwork(chainIdForRequest)) { throw Error( - `Blockaid validation not available on network with chainId: ${ - this.#chainId - }`, + `Blockaid validation not available on network with chainId: ${chainIdForRequest}`, ); } return await this.#ppomMutex.use(async () => { - await this.#initPPOMIfRequired(); + const ppom = await this.#initPPOMIfRequired(chainIdForRequest); this.#providerRequests = 0; this.#providerRequestsCount = {}; - // `this.#ppom` is defined in `#initPPOMIfRequired` // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const result = await callback(this.#ppom!); + const result = await callback(ppom!); return { ...result, @@ -468,14 +468,22 @@ export class PPOMController extends BaseController< /* * The function will initialise PPOM for the network if required. */ - async #initPPOMIfRequired(): Promise { + async #initPPOMIfRequired(chainId: string): Promise { const versionInfoUpdated = await this.#updateVersionInfo(); + let ppom; if (this.#ppom === undefined || versionInfoUpdated) { - this.#ppom = await this.#getPPOM(); + ppom = await this.#getPPOM(chainId); + if (this.#chainId === chainId) { + if (this.#ppom) { + this.#ppom.free(); + } + this.#ppom = ppom; + } this.#storage.syncMetadata(this.state.versionInfo).catch((exp: Error) => { console.error(`Error while trying to sync metadata: ${exp.message}`); }); } + return ppom; } /* @@ -662,7 +670,9 @@ export class PPOMController extends BaseController< ? Number(this.#providerRequestsCount[method]) + 1 : 1; - return await this.#provider.request(createPayload(method, params)); + const payload = createPayload(method, params); + const result = await this.#provider.request(payload); + return { jsonrpc: '2.0', id: payload.id, result }; } /* @@ -671,12 +681,12 @@ export class PPOMController extends BaseController< * * It will load the data files from storage and pass data files and wasm file to ppom. */ - async #getPPOM(): Promise { + async #getPPOM(chainId: string): Promise { // PPOM initialisation in contructor fails for react native // thus it is added here to prevent validation from failing. await this.#initialisePPOM(); const versionInfo = this.state.versionInfo.filter( - ({ chainId: id }) => id === this.#chainId, + ({ chainId: id }) => id === chainId, ); // The following code throw error if no data files are found for the chainId. @@ -685,9 +695,7 @@ export class PPOMController extends BaseController< // this can be achieved by returning empty data from version file. if (versionInfo?.length === undefined || versionInfo?.length === 0) { throw new Error( - `Aborting initialising PPOM as no files are found for the network with chainId: ${ - this.#chainId - }`, + `Aborting initialising PPOM as no files are found for the network with chainId: ${chainId}`, ); } @@ -696,15 +704,10 @@ export class PPOMController extends BaseController< if (files?.length !== versionInfo?.length) { throw new Error( - `Aborting initialising PPOM as not all files could not be downloaded for the network with chainId: ${ - this.#chainId - }`, + `Aborting initialising PPOM as not all files could not be downloaded for the network with chainId: ${chainId}`, ); } - if (this.#ppom) { - this.#ppom.free(); - } const { PPOM } = this.#ppomProvider; return PPOM.new(this.#jsonRpcRequest.bind(this), files); }