diff options
| author | Sebastian <sebasjm@gmail.com> | 2022-12-21 16:21:25 -0300 | 
|---|---|---|
| committer | Sebastian <sebasjm@gmail.com> | 2022-12-21 16:24:18 -0300 | 
| commit | 7873571d225347aa2174b6d8943d9df820f8817c (patch) | |
| tree | 44bea29c1e2d0b270d745e8eaf0247d477d50b8c /packages | |
| parent | 8a98a5f880b9559312779232b6086016c008969b (diff) | |
add typecheck to background operations
Diffstat (limited to 'packages')
9 files changed, 290 insertions, 216 deletions
| diff --git a/packages/taler-wallet-webextension/src/hooks/useAutoOpenPermissions.ts b/packages/taler-wallet-webextension/src/hooks/useAutoOpenPermissions.ts index cb90ec853..e375f4958 100644 --- a/packages/taler-wallet-webextension/src/hooks/useAutoOpenPermissions.ts +++ b/packages/taler-wallet-webextension/src/hooks/useAutoOpenPermissions.ts @@ -34,7 +34,10 @@ export function useAutoOpenPermissions(): ToggleHandler {    useEffect(() => {      async function getValue(): Promise<void> { -      const res = await api.background.containsHeaderListener(); +      const res = await api.background.call( +        "containsHeaderListener", +        undefined, +      );        setEnabled(res.newValue);      }      getValue(); @@ -63,12 +66,12 @@ async function handleAutoOpenPerm(        onChange(false);        throw lastError;      } -    const res = await background.toggleHeaderListener(granted); +    const res = await background.call("toggleHeaderListener", granted);      onChange(res.newValue);    } else {      try {        await background -        .toggleHeaderListener(false) +        .call("toggleHeaderListener", false)          .then((r) => onChange(r.newValue));      } catch (e) {        console.log(e); diff --git a/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts b/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts index eda2afd8d..3f2824d6b 100644 --- a/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts +++ b/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts @@ -35,7 +35,10 @@ export function useClipboardPermissions(): ToggleHandler {    useEffect(() => {      async function getValue(): Promise<void> { -      const res = await api.background.containsHeaderListener(); +      const res = await api.background.call( +        "containsHeaderListener", +        undefined, +      );        setEnabled(res.newValue);      }      getValue(); @@ -71,7 +74,7 @@ async function handleClipboardPerm(    } else {      try {        await background -        .toggleHeaderListener(false) +        .call("toggleHeaderListener", false)          .then((r) => onChange(r.newValue));      } catch (e) {        console.log(e); diff --git a/packages/taler-wallet-webextension/src/hooks/useDiagnostics.ts b/packages/taler-wallet-webextension/src/hooks/useDiagnostics.ts index 1f36ca6c0..fcd31b3c6 100644 --- a/packages/taler-wallet-webextension/src/hooks/useDiagnostics.ts +++ b/packages/taler-wallet-webextension/src/hooks/useDiagnostics.ts @@ -34,7 +34,7 @@ export function useDiagnostics(): [WalletDiagnostics | undefined, boolean] {        }      }, 1000);      const doFetch = async (): Promise<void> => { -      const d = await api.background.getDiagnostics(); +      const d = await api.background.call("getDiagnostics", undefined);        gotDiagnostics = true;        setDiagnostics(d);      }; diff --git a/packages/taler-wallet-webextension/src/platform/api.ts b/packages/taler-wallet-webextension/src/platform/api.ts index 37546d2df..7df190303 100644 --- a/packages/taler-wallet-webextension/src/platform/api.ts +++ b/packages/taler-wallet-webextension/src/platform/api.ts @@ -15,6 +15,8 @@   */  import { CoreApiResponse, NotificationType } from "@gnu-taler/taler-util"; +import { WalletOperations } from "@gnu-taler/taler-wallet-core"; +import { BackgroundOperations } from "../wxApi.js";  export interface Permissions {    /** @@ -50,6 +52,30 @@ export type MessageFromBackend = {    type: NotificationType;  }; +export type MessageFromFrontend< +  Op extends BackgroundOperations | WalletOperations, +> = Op extends BackgroundOperations +  ? MessageFromFrontendBackground<keyof BackgroundOperations> +  : Op extends WalletOperations +  ? MessageFromFrontendWallet<keyof WalletOperations> +  : never; + +export type MessageFromFrontendBackground< +  Op extends keyof BackgroundOperations, +> = { +  channel: "background"; +  operation: Op; +  payload: BackgroundOperations[Op]["request"]; +}; + +export type MessageFromFrontendWallet<Op extends keyof WalletOperations> = { +  channel: "wallet"; +  operation: Op; +  payload: WalletOperations[Op]["request"]; +}; + +export type MessageResponse = CoreApiResponse; +  export interface WalletWebExVersion {    version_name?: string | undefined;    version: string; @@ -183,10 +209,9 @@ export interface PlatformAPI {     *     * @return response from the backend     */ -  sendMessageToWalletBackground( -    operation: string, -    payload: any, -  ): Promise<CoreApiResponse>; +  sendMessageToBackground<Op extends WalletOperations | BackgroundOperations>( +    message: MessageFromFrontend<Op>, +  ): Promise<MessageResponse>;    /**     * Used from the frontend to receive notifications about new information @@ -204,11 +229,9 @@ export interface PlatformAPI {     * @param onNewMessage     */    listenToAllChannels( -    onNewMessage: ( -      message: any, -      sender: any, -      sendResponse: (r: CoreApiResponse) => void, -    ) => void, +    notifyNewMessage: <Op extends WalletOperations | BackgroundOperations>( +      message: MessageFromFrontend<Op> & { id: string }, +    ) => Promise<MessageResponse>,    ): void;    /** diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts b/packages/taler-wallet-webextension/src/platform/chrome.ts index 7785e19ef..f951685d2 100644 --- a/packages/taler-wallet-webextension/src/platform/chrome.ts +++ b/packages/taler-wallet-webextension/src/platform/chrome.ts @@ -20,9 +20,13 @@ import {    Logger,    TalerUriType,  } from "@gnu-taler/taler-util"; +import { WalletOperations } from "@gnu-taler/taler-wallet-core"; +import { BackgroundOperations } from "../wxApi.js";  import {    CrossBrowserPermissionsApi,    MessageFromBackend, +  MessageFromFrontend, +  MessageResponse,    Permissions,    PlatformAPI,  } from "./api.js"; @@ -41,11 +45,11 @@ const api: PlatformAPI = {    redirectTabToWalletPage,    registerAllIncomingConnections,    registerOnInstalled, -  listenToAllChannels, +  listenToAllChannels: listenToAllChannels as any,    registerReloadOnNewVersion,    registerTalerHeaderListener,    sendMessageToAllChannels, -  sendMessageToWalletBackground, +  sendMessageToBackground,    useServiceWorkerAsBackgroundProcess,    containsTalerHeaderListener,    keepAlive, @@ -302,30 +306,22 @@ function openWalletPageFromPopup(page: string): void {  let i = 0; -async function sendMessageToWalletBackground( -  operation: string, -  payload: any, -): Promise<any> { -  return new Promise<any>((resolve, reject) => { -    logger.trace("send operation to the wallet background", operation); -    chrome.runtime.sendMessage( -      { operation, payload, id: `id_${i++ % 1000}` }, -      (backgroundResponse) => { -        logger.trace( -          "BUG: got response from background", -          backgroundResponse, -          chrome.runtime.lastError, -        ); +async function sendMessageToBackground< +  Op extends WalletOperations | BackgroundOperations, +>(message: MessageFromFrontend<Op>): Promise<MessageResponse> { +  const messageWithId = { ...message, id: `id_${i++ % 1000}` }; -        if (chrome.runtime.lastError) { -          reject(chrome.runtime.lastError.message); -        } else { -          resolve(backgroundResponse); -        } -        // return true to keep the channel open -        return true; -      }, -    ); +  return new Promise<any>((resolve, reject) => { +    logger.trace("send operation to the wallet background", message); +    chrome.runtime.sendMessage(messageWithId, (backgroundResponse) => { +      if (chrome.runtime.lastError) { +        reject(chrome.runtime.lastError.message); +      } else { +        resolve(backgroundResponse); +      } +      // return true to keep the channel open +      return true; +    });    });  } @@ -377,21 +373,27 @@ function registerAllIncomingConnections(): void {  }  function listenToAllChannels( -  cb: ( -    message: any, -    sender: any, -    callback: (r: CoreApiResponse) => void, -  ) => void, +  notifyNewMessage: <Op extends WalletOperations | BackgroundOperations>( +    message: MessageFromFrontend<Op> & { id: string }, +  ) => Promise<MessageResponse>,  ): void { -  chrome.runtime.onMessage.addListener((m, s, c) => { -    cb(m, s, (apiResponse) => { -      logger.trace("BUG: sending response to client", apiResponse); -      try { -        c(apiResponse); -      } catch (e) { -        logger.error("wallet operation ended with error", e); -      } -    }); +  chrome.runtime.onMessage.addListener((message, sender, reply) => { +    notifyNewMessage(message) +      .then((apiResponse) => { +        try { +          reply(apiResponse); +        } catch (e) { +          logger.error( +            "sending response to frontend failed", +            message, +            apiResponse, +            e, +          ); +        } +      }) +      .catch((e) => { +        logger.error("notify to background failed", e); +      });      // keep the connection open      return true; diff --git a/packages/taler-wallet-webextension/src/platform/dev.ts b/packages/taler-wallet-webextension/src/platform/dev.ts index 8a410b062..df40b29e7 100644 --- a/packages/taler-wallet-webextension/src/platform/dev.ts +++ b/packages/taler-wallet-webextension/src/platform/dev.ts @@ -15,7 +15,14 @@   */  import { CoreApiResponse } from "@gnu-taler/taler-util"; -import { MessageFromBackend, PlatformAPI } from "./api.js"; +import { WalletOperations } from "@gnu-taler/taler-wallet-core"; +import { BackgroundOperations } from "../wxApi.js"; +import { +  MessageFromBackend, +  MessageFromFrontend, +  MessageResponse, +  PlatformAPI, +} from "./api.js";  const frames = ["popup", "wallet"]; @@ -121,12 +128,17 @@ const api: PlatformAPI = {        window.parent.removeEventListener("message", listener);      };    }, -  sendMessageToWalletBackground: async (operation: string, payload: any) => { + +  sendMessageToBackground: async < +    Op extends WalletOperations | BackgroundOperations, +  >( +    payload: MessageFromFrontend<Op>, +  ): Promise<MessageResponse> => {      const replyMe = `reply-${Math.floor(Math.random() * 100000)}`;      const message: IframeMessageCommand = {        type: "command",        header: { replyMe }, -      body: { operation, payload, id: "(none)" }, +      body: payload,      };      window.parent.postMessage(message); @@ -150,6 +162,7 @@ type IframeMessageType =    | IframeMessageNotification    | IframeMessageResponse    | IframeMessageCommand; +  interface IframeMessageNotification {    type: "notification";    header: Record<string, never>; @@ -160,7 +173,7 @@ interface IframeMessageResponse {    header: {      responseId: string;    }; -  body: CoreApiResponse; +  body: MessageResponse;  }  interface IframeMessageCommand { @@ -168,11 +181,7 @@ interface IframeMessageCommand {    header: {      replyMe: string;    }; -  body: { -    operation: any; -    id: string; -    payload: any; -  }; +  body: MessageFromFrontend<any>;  }  export default api; diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx index c42798c8f..cbf6b1c0a 100644 --- a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx @@ -177,7 +177,7 @@ export function View({              onClick={() =>                confirmReset(                  i18n.str`Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?`, -                () => api.background.resetDb(), +                () => api.background.call("resetDb", undefined),                )              }            > @@ -190,7 +190,7 @@ export function View({              onClick={() =>                confirmReset(                  i18n.str`TESTING: This may delete all your coin, proceed with caution`, -                () => api.background.runGarbageCollector(), +                () => api.background.call("runGarbageCollector", undefined),                )              }            > diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts index 991cbb5fe..ea087fc5d 100644 --- a/packages/taler-wallet-webextension/src/wxApi.ts +++ b/packages/taler-wallet-webextension/src/wxApi.ts @@ -34,70 +34,100 @@ import {    WalletCoreRequestType,    WalletCoreResponseType,  } from "@gnu-taler/taler-wallet-core"; -import { MessageFromBackend, platform } from "./platform/api.js"; -import { nullFunction } from "./test-utils.js"; +import { +  MessageFromBackend, +  MessageFromFrontendBackground, +  MessageFromFrontendWallet, +  platform, +} from "./platform/api.js";  /**   * - * @author Florian Dold   * @author sebasjm   */ +const logger = new Logger("wxApi"); +  export interface ExtendedPermissionsResponse {    newValue: boolean;  } -const logger = new Logger("wxApi"); -/** - * Response with information about available version upgrades. - */ -export interface UpgradeResponse { -  /** -   * Is a reset required because of a new DB version -   * that can't be automatically upgraded? -   */ -  dbResetRequired: boolean; - -  /** -   * Current database version. -   */ -  currentDbVersion: string; - -  /** -   * Old db version (if applicable). -   */ -  oldDbVersion: string; +export interface BackgroundOperations { +  resetDb: { +    request: void; +    response: void; +  }; +  containsHeaderListener: { +    request: void; +    response: ExtendedPermissionsResponse; +  }; +  getDiagnostics: { +    request: void; +    response: WalletDiagnostics; +  }; +  toggleHeaderListener: { +    request: boolean; +    response: ExtendedPermissionsResponse; +  }; +  runGarbageCollector: { +    request: void; +    response: void; +  }; +} + +export interface BackgroundApiClient { +  call<Op extends keyof BackgroundOperations>( +    operation: Op, +    payload: BackgroundOperations[Op]["request"], +  ): Promise<BackgroundOperations[Op]["response"]>;  }  /** - * @deprecated Use {@link WxWalletCoreApiClient} instead. + * BackgroundApiClient integration with browser platform   */ -async function callBackend(operation: string, payload: any): Promise<any> { -  let response: CoreApiResponse; -  try { -    response = await platform.sendMessageToWalletBackground(operation, payload); -  } catch (e) { -    console.log("Error calling backend"); -    throw new Error(`Error contacting backend: ${e}`); -  } -  logger.info("got response", response); -  if (response.type === "error") { -    throw TalerError.fromUncheckedDetail(response.error); +class BackgroundApiClientImpl implements BackgroundApiClient { +  async call<Op extends keyof BackgroundOperations>( +    operation: Op, +    payload: BackgroundOperations[Op]["request"], +  ): Promise<BackgroundOperations[Op]["response"]> { +    let response: CoreApiResponse; + +    const message: MessageFromFrontendBackground<Op> = { +      channel: "background", +      operation, +      payload, +    }; + +    try { +      response = await platform.sendMessageToBackground(message); +    } catch (e) { +      console.log("Error calling backend"); +      throw new Error(`Error contacting backend: ${e}`); +    } +    logger.info("got response", response); +    if (response.type === "error") { +      throw TalerError.fromUncheckedDetail(response.error); +    } +    return response.result as any;    } -  return response.result;  } -export class WxWalletCoreApiClient implements WalletCoreApiClient { +/** + * WalletCoreApiClient integration with browser platform + */ +class WalletApiClientImpl implements WalletCoreApiClient {    async call<Op extends WalletCoreOpKeys>(      operation: Op,      payload: WalletCoreRequestType<Op>,    ): Promise<WalletCoreResponseType<Op>> {      let response: CoreApiResponse;      try { -      response = await platform.sendMessageToWalletBackground( +      const message: MessageFromFrontendWallet<Op> = { +        channel: "wallet",          operation,          payload, -      ); +      }; +      response = await platform.sendMessageToBackground(message);      } catch (e) {        console.log("Error calling backend");        throw new Error(`Error contacting backend: ${e}`); @@ -110,29 +140,6 @@ export class WxWalletCoreApiClient implements WalletCoreApiClient {    }  } -export class BackgroundApiClient { -  public resetDb(): Promise<void> { -    return callBackend("reset-db", {}); -  } - -  public containsHeaderListener(): Promise<ExtendedPermissionsResponse> { -    return callBackend("containsHeaderListener", {}); -  } - -  public getDiagnostics(): Promise<WalletDiagnostics> { -    return callBackend("wxGetDiagnostics", {}); -  } - -  public toggleHeaderListener( -    value: boolean, -  ): Promise<ExtendedPermissionsResponse> { -    return callBackend("toggleHeaderListener", { value }); -  } - -  public runGarbageCollector(): Promise<void> { -    return callBackend("run-gc", {}); -  } -}  function onUpdateNotification(    messageTypes: Array<NotificationType>,    doCallback: undefined | (() => void), @@ -160,8 +167,8 @@ export type WxApiType = {  };  export const wxApi = { -  wallet: new WxWalletCoreApiClient(), -  background: new BackgroundApiClient(), +  wallet: new WalletApiClientImpl(), +  background: new BackgroundApiClientImpl(),    listener: {      onUpdateNotification,    }, diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts index 28adfa037..c94b390ff 100644 --- a/packages/taler-wallet-webextension/src/wxBackend.ts +++ b/packages/taler-wallet-webextension/src/wxBackend.ts @@ -25,8 +25,6 @@   */  import {    classifyTalerUri, -  CoreApiResponse, -  CoreApiResponseSuccess,    Logger,    TalerErrorCode,    TalerUriType, @@ -36,20 +34,27 @@ import {    DbAccess,    deleteTalerDatabase,    exportDb, +  getErrorDetailFromException,    importDb,    makeErrorDetail,    OpenedPromise,    openPromise,    openTalerDatabase, +  SetTimeoutTimerAPI,    Wallet, +  WalletOperations,    WalletStoresV1,  } from "@gnu-taler/taler-wallet-core"; -import { SetTimeoutTimerAPI } from "@gnu-taler/taler-wallet-core"; -import { BrowserCryptoWorkerFactory } from "./browserCryptoWorkerFactory.js";  import { BrowserHttpLib } from "./browserHttpLib.js"; -import { MessageFromBackend, platform } from "./platform/api.js"; +import { +  MessageFromBackend, +  MessageFromFrontend, +  MessageResponse, +  platform, +} from "./platform/api.js";  import { SynchronousCryptoWorkerFactory } from "./serviceWorkerCryptoWorkerFactory.js";  import { ServiceWorkerHttpLib } from "./serviceWorkerHttpLib.js"; +import { BackgroundOperations, ExtendedPermissionsResponse } from "./wxApi.js";  /**   * Currently active wallet instance.  Might be unloaded and @@ -107,92 +112,115 @@ async function getDiagnostics(): Promise<WalletDiagnostics> {    return diagnostics;  } -async function dispatch( -  req: any, -  sender: any, -  sendResponse: any, -): Promise<void> { -  let r: CoreApiResponse; +type BackendHandlerType = { +  [Op in keyof BackgroundOperations]: ( +    req: BackgroundOperations[Op]["request"], +  ) => Promise<BackgroundOperations[Op]["response"]>; +}; + +async function containsHeaderListener(): Promise<ExtendedPermissionsResponse> { +  const result = await platform.containsTalerHeaderListener(); +  return { newValue: result }; +} + +async function resetDb(): Promise<void> { +  await deleteTalerDatabase(indexedDB as any); +  await reinitWallet(); +} + +async function runGarbageCollector(): Promise<void> { +  const dbBeforeGc = currentDatabase; +  if (!dbBeforeGc) { +    throw Error("no current db before running gc"); +  } +  const dump = await exportDb(dbBeforeGc.idbHandle()); + +  await deleteTalerDatabase(indexedDB as any); +  logger.info("cleaned"); +  await reinitWallet(); +  logger.info("init"); + +  const dbAfterGc = currentDatabase; +  if (!dbAfterGc) { +    throw Error("no current db before running gc"); +  } +  await importDb(dbAfterGc.idbHandle(), dump); +  logger.info("imported"); +} + +async function toggleHeaderListener( +  newVal: boolean, +): Promise<ExtendedPermissionsResponse> { +  logger.trace("new extended permissions value", newVal); +  if (newVal) { +    platform.registerTalerHeaderListener(parseTalerUriAndRedirect); +    return { newValue: true }; +  } + +  const rem = await platform.getPermissionsApi().removeHostPermissions(); +  logger.trace("permissions removed:", rem); +  return { newValue: false }; +} -  const wrapResponse = (result: unknown): CoreApiResponseSuccess => { +const backendHandlers: BackendHandlerType = { +  containsHeaderListener, +  getDiagnostics, +  resetDb, +  runGarbageCollector, +  toggleHeaderListener, +}; + +async function dispatch<Op extends WalletOperations | BackgroundOperations>( +  req: MessageFromFrontend<Op> & { id: string }, +): Promise<MessageResponse> { +  if (req.channel === "background") { +    const handler = backendHandlers[req.operation] as (req: any) => any; +    if (!handler) { +      return { +        type: "error", +        id: req.id, +        operation: String(req.operation), +        error: getErrorDetailFromException( +          Error(`unknown background operation`), +        ), +      }; +    } +    const result = await handler(req.payload);      return {        type: "response",        id: req.id, -      operation: req.operation, +      operation: String(req.operation),        result,      }; -  }; +  } -  try { -    switch (req.operation) { -      case "wxGetDiagnostics": { -        r = wrapResponse(await getDiagnostics()); -        break; -      } -      case "reset-db": { -        await deleteTalerDatabase(indexedDB as any); -        r = wrapResponse(await reinitWallet()); -        break; -      } -      case "run-gc": { -        logger.info("gc"); -        const dump = await exportDb(currentDatabase!.idbHandle()); -        await deleteTalerDatabase(indexedDB as any); -        logger.info("cleaned"); -        await reinitWallet(); -        logger.info("init"); -        await importDb(currentDatabase!.idbHandle(), dump); -        logger.info("imported"); -        r = wrapResponse({ result: true }); -        break; -      } -      case "containsHeaderListener": { -        const res = await platform.containsTalerHeaderListener(); -        r = wrapResponse({ newValue: res }); -        break; -      } -      //FIXME: implement type checked api like WalletCoreApi -      case "toggleHeaderListener": { -        const newVal = req.payload.value; -        logger.trace("new extended permissions value", newVal); -        if (newVal) { -          platform.registerTalerHeaderListener(parseTalerUriAndRedirect); -          r = wrapResponse({ newValue: true }); -        } else { -          const rem = await platform -            .getPermissionsApi() -            .removeHostPermissions(); -          logger.trace("permissions removed:", rem); -          r = wrapResponse({ newVal: false }); -        } -        break; -      } -      default: { -        const w = currentWallet; -        if (!w) { -          r = { -            type: "error", -            id: req.id, -            operation: req.operation, -            error: makeErrorDetail( -              TalerErrorCode.WALLET_CORE_NOT_AVAILABLE, -              {}, -              "wallet core not available", -            ), -          }; -          break; -        } -        r = await w.handleCoreApiRequest(req.operation, req.id, req.payload); -        console.log("response received from wallet", r); -        break; -      } +  if (req.channel === "wallet") { +    const w = currentWallet; +    if (!w) { +      return { +        type: "error", +        id: req.id, +        operation: req.operation, +        error: makeErrorDetail( +          TalerErrorCode.WALLET_CORE_NOT_AVAILABLE, +          {}, +          "wallet core not available", +        ), +      };      } -    sendResponse(r); -  } catch (e) { -    logger.error(`Error sending operation: ${req.operation}`, e); -    // might fail if tab disconnected +    return await w.handleCoreApiRequest(req.operation, req.id, req.payload);    } + +  const anyReq = req as any; +  return { +    type: "error", +    id: anyReq.id, +    operation: String(anyReq.operation), +    error: getErrorDetailFromException( +      Error(`unknown channel ${anyReq.channel}`), +    ), +  };  }  async function reinitWallet(): Promise<void> { @@ -328,12 +356,11 @@ export async function wxMain(): Promise<void> {    // Handlers for messages coming directly from the content    // script on the page -  platform.listenToAllChannels((message, sender, callback) => { -    afterWalletIsInitialized.then(() => { -      dispatch(message, sender, (response: CoreApiResponse) => { -        callback(response); -      }); -    }); +  platform.listenToAllChannels(async (message) => { +    //wait until wallet is initialized +    await afterWalletIsInitialized; +    const result = await dispatch(message); +    return result;    });    platform.registerAllIncomingConnections(); | 
