Skip to content

Commit

Permalink
Add support for multichain
Browse files Browse the repository at this point in the history
  • Loading branch information
jpuri committed Aug 29, 2024
1 parent bcf4762 commit 7dfea3f
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 22 deletions.
27 changes: 26 additions & 1 deletion src/ppom-controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
{
Expand Down Expand Up @@ -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');
});
});

Expand Down
45 changes: 24 additions & 21 deletions src/ppom-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Type>(
callback: (ppom: PPOM) => Promise<Type>,
chainId?: string,
): Promise<Type & { providerRequestsCount: Record<string, number> }> {
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,
Expand Down Expand Up @@ -468,14 +468,22 @@ export class PPOMController extends BaseController<
/*
* The function will initialise PPOM for the network if required.
*/
async #initPPOMIfRequired(): Promise<void> {
async #initPPOMIfRequired(chainId: string): Promise<PPOM | undefined> {
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;
}

/*
Expand Down Expand Up @@ -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 };
}

/*
Expand All @@ -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<PPOM> {
async #getPPOM(chainId: string): Promise<PPOM> {
// 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.
Expand All @@ -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}`,
);
}

Expand All @@ -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);
}
Expand Down

0 comments on commit 7dfea3f

Please sign in to comment.