{"version":3,"file":"ledger-iframe-bridge.cjs","sourceRoot":"","sources":["../src/ledger-iframe-bridge.ts"],"names":[],"mappings":"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","sourcesContent":["import { createDeferredPromise, DeferredPromise } from '@metamask/utils';\n\nimport {\n  AppConfigurationResponse,\n  GetAppNameAndVersionResponse,\n  GetPublicKeyParams,\n  GetPublicKeyResponse,\n  LedgerBridge,\n  LedgerSignDelegationAuthorizationParams,\n  LedgerSignDelegationAuthorizationResponse,\n  LedgerSignMessageParams,\n  LedgerSignMessageResponse,\n  LedgerSignTransactionParams,\n  LedgerSignTransactionResponse,\n  LedgerSignTypedDataParams,\n  LedgerSignTypedDataResponse,\n} from './ledger-bridge';\n\nconst LEDGER_IFRAME_ID = 'LEDGER-IFRAME';\n\nconst IFRAME_MESSAGE_TIMEOUT = 8000;\n\nexport enum IFrameMessageAction {\n  LedgerIsIframeReady = 'ledger-is-iframe-ready',\n  LedgerConnectionChange = 'ledger-connection-change',\n  LedgerUnlock = 'ledger-unlock',\n  LedgerMakeApp = 'ledger-make-app',\n  LedgerUpdateTransport = 'ledger-update-transport',\n  LedgerSignTransaction = 'ledger-sign-transaction',\n  LedgerSignPersonalMessage = 'ledger-sign-personal-message',\n  LedgerSignTypedData = 'ledger-sign-typed-data',\n  LedgerGetAppNameAndVersion = 'ledger-get-app-name-and-version',\n  LedgerGetAppConfiguration = 'ledger-get-app-configuration',\n}\n\ntype IFrameMessageResponseStub<\n  SuccessResult extends Record<string, unknown>,\n  FailureResult = Error,\n> = {\n  messageId: number;\n} & (\n  | { success: true; payload: SuccessResult }\n  | { success: false; payload: { error: FailureResult } }\n);\n\ntype LedgerConnectionChangeActionResponse = {\n  messageId: number;\n  action: IFrameMessageAction.LedgerConnectionChange;\n  payload: { connected: boolean };\n};\n\ntype LedgerMakeAppActionResponse = {\n  messageId: number;\n  action: IFrameMessageAction.LedgerMakeApp;\n} & ({ success: true } | { success: false; error?: unknown });\n\ntype LedgerUpdateTransportActionResponse = {\n  messageId: number;\n  action: IFrameMessageAction.LedgerUpdateTransport;\n  success: boolean;\n};\n\ntype LedgerUnlockActionResponse = {\n  action: IFrameMessageAction.LedgerUnlock;\n} & IFrameMessageResponseStub<GetPublicKeyResponse>;\n\ntype LedgerSignTransactionActionResponse = {\n  action: IFrameMessageAction.LedgerSignTransaction;\n} & IFrameMessageResponseStub<LedgerSignTransactionResponse>;\n\ntype LedgerSignPersonalMessageActionResponse = {\n  action: IFrameMessageAction.LedgerSignPersonalMessage;\n} & IFrameMessageResponseStub<LedgerSignMessageResponse>;\n\ntype LedgerSignTypedDataActionResponse = {\n  action: IFrameMessageAction.LedgerSignTypedData;\n} & IFrameMessageResponseStub<LedgerSignTypedDataResponse>;\n\ntype LedgerGetAppNameAndVersionActionResponse = {\n  action: IFrameMessageAction.LedgerGetAppNameAndVersion;\n} & IFrameMessageResponseStub<GetAppNameAndVersionResponse>;\n\ntype LedgerGetAppConfigurationActionResponse = {\n  action: IFrameMessageAction.LedgerGetAppConfiguration;\n} & IFrameMessageResponseStub<AppConfigurationResponse>;\n\nexport type IFrameMessageResponse =\n  | LedgerConnectionChangeActionResponse\n  | LedgerMakeAppActionResponse\n  | LedgerUpdateTransportActionResponse\n  | LedgerUnlockActionResponse\n  | LedgerSignTransactionActionResponse\n  | LedgerSignPersonalMessageActionResponse\n  | LedgerSignTypedDataActionResponse\n  | LedgerGetAppNameAndVersionActionResponse\n  | LedgerGetAppConfigurationActionResponse;\n\ntype IFrameMessage<TAction extends IFrameMessageAction> = {\n  action: TAction;\n  params?: Readonly<Record<string, unknown>>;\n};\n\ntype IFramePostMessage<TAction extends IFrameMessageAction> =\n  IFrameMessage<TAction> & {\n    messageId: number;\n    target: typeof LEDGER_IFRAME_ID;\n  };\n\nexport type LedgerIframeBridgeOptions = {\n  bridgeUrl: string;\n};\n\nexport class LedgerIframeBridge implements LedgerBridge<LedgerIframeBridgeOptions> {\n  iframe?: HTMLIFrameElement;\n\n  iframeLoaded = false;\n\n  readonly #opts: LedgerIframeBridgeOptions;\n\n  eventListener?: (eventMessage: {\n    origin: string;\n    data: IFrameMessageResponse;\n  }) => void;\n\n  isDeviceConnected = false;\n\n  currentMessageId = 0;\n\n  readonly #messageResponseHandles: Map<\n    number,\n    DeferredPromise<IFrameMessageResponse>\n  > = new Map();\n\n  constructor(\n    opts: LedgerIframeBridgeOptions = {\n      bridgeUrl: 'https://metamask.github.io/eth-ledger-bridge-keyring',\n    },\n  ) {\n    this.#validateConfiguration(opts);\n    this.#opts = {\n      bridgeUrl: opts?.bridgeUrl,\n    };\n  }\n\n  async init(): Promise<void> {\n    await this.#setupIframe(this.#opts.bridgeUrl);\n\n    this.eventListener = this.#eventListener.bind(this, this.#opts.bridgeUrl);\n\n    window.addEventListener('message', this.eventListener);\n  }\n\n  async destroy(): Promise<void> {\n    if (this.eventListener) {\n      window.removeEventListener('message', this.eventListener);\n    }\n  }\n\n  async getOptions(): Promise<LedgerIframeBridgeOptions> {\n    return this.#opts;\n  }\n\n  async setOptions(opts: LedgerIframeBridgeOptions): Promise<void> {\n    this.#validateConfiguration(opts);\n    if (this.#opts?.bridgeUrl !== opts.bridgeUrl) {\n      this.#opts.bridgeUrl = opts.bridgeUrl;\n      await this.destroy();\n      await this.init();\n    }\n  }\n\n  async attemptMakeApp(): Promise<boolean> {\n    const response = await this.#sendMessage(\n      {\n        action: IFrameMessageAction.LedgerMakeApp,\n      },\n      { timeout: IFRAME_MESSAGE_TIMEOUT },\n    );\n\n    if ('success' in response && response.success) {\n      return true;\n    } else if ('error' in response) {\n      // Assuming this is using an `Error` type:\n      throw response.error;\n    } else {\n      throw new Error('Unknown error occurred');\n    }\n  }\n\n  async updateTransportMethod(transportType: string): Promise<boolean> {\n    if (!this.iframeLoaded) {\n      throw new Error('The iframe is not loaded yet');\n    }\n\n    const response = await this.#sendMessage(\n      {\n        action: IFrameMessageAction.LedgerUpdateTransport,\n        params: { transportType },\n      },\n      { timeout: IFRAME_MESSAGE_TIMEOUT },\n    );\n\n    if ('success' in response && response.success) {\n      return true;\n    }\n\n    throw new Error('Ledger transport could not be updated');\n  }\n\n  async getPublicKey(\n    params: GetPublicKeyParams,\n  ): Promise<GetPublicKeyResponse> {\n    return this.#deviceActionMessage(IFrameMessageAction.LedgerUnlock, params);\n  }\n\n  async deviceSignTransaction(\n    params: LedgerSignTransactionParams,\n  ): Promise<LedgerSignTransactionResponse> {\n    return this.#deviceActionMessage(\n      IFrameMessageAction.LedgerSignTransaction,\n      params,\n    );\n  }\n\n  async deviceSignMessage(\n    params: LedgerSignMessageParams,\n  ): Promise<LedgerSignMessageResponse> {\n    return this.#deviceActionMessage(\n      IFrameMessageAction.LedgerSignPersonalMessage,\n      params,\n    );\n  }\n\n  async deviceSignTypedData(\n    params: LedgerSignTypedDataParams,\n  ): Promise<LedgerSignTypedDataResponse> {\n    return this.#deviceActionMessage(\n      IFrameMessageAction.LedgerSignTypedData,\n      params,\n    );\n  }\n\n  async deviceSignDelegationAuthorization(\n    _params: LedgerSignDelegationAuthorizationParams,\n  ): Promise<LedgerSignDelegationAuthorizationResponse> {\n    throw new Error(\n      'Ledger: signDelegationAuthorization is not supported via iframe bridge',\n    );\n  }\n\n  async getAppNameAndVersion(): Promise<GetAppNameAndVersionResponse> {\n    return this.#deviceActionMessage(\n      IFrameMessageAction.LedgerGetAppNameAndVersion,\n      {},\n    );\n  }\n\n  async getAppConfiguration(): Promise<AppConfigurationResponse> {\n    return this.#deviceActionMessage(\n      IFrameMessageAction.LedgerGetAppConfiguration,\n      {},\n    );\n  }\n\n  async #deviceActionMessage(\n    action: IFrameMessageAction.LedgerUnlock,\n    params: GetPublicKeyParams,\n  ): Promise<GetPublicKeyResponse>;\n\n  async #deviceActionMessage(\n    action: IFrameMessageAction.LedgerSignTransaction,\n    params: LedgerSignTransactionParams,\n  ): Promise<LedgerSignTransactionResponse>;\n\n  async #deviceActionMessage(\n    action: IFrameMessageAction.LedgerSignPersonalMessage,\n    params: LedgerSignMessageParams,\n  ): Promise<LedgerSignMessageResponse>;\n\n  async #deviceActionMessage(\n    action: IFrameMessageAction.LedgerSignTypedData,\n    params: LedgerSignTypedDataParams,\n  ): Promise<LedgerSignTypedDataResponse>;\n\n  async #deviceActionMessage(\n    action: IFrameMessageAction.LedgerGetAppNameAndVersion,\n    params: Record<string, never>,\n  ): Promise<GetAppNameAndVersionResponse>;\n\n  async #deviceActionMessage(\n    action: IFrameMessageAction.LedgerGetAppConfiguration,\n    params: Record<string, never>,\n  ): Promise<AppConfigurationResponse>;\n\n  async #deviceActionMessage(\n    ...[action, params]:\n      | [IFrameMessageAction.LedgerUnlock, GetPublicKeyParams]\n      | [IFrameMessageAction.LedgerSignTransaction, LedgerSignTransactionParams]\n      | [IFrameMessageAction.LedgerSignPersonalMessage, LedgerSignMessageParams]\n      | [IFrameMessageAction.LedgerSignTypedData, LedgerSignTypedDataParams]\n      | [IFrameMessageAction.LedgerGetAppNameAndVersion, Record<string, never>]\n      | [IFrameMessageAction.LedgerGetAppConfiguration, Record<string, never>]\n  ): Promise<\n    | GetPublicKeyResponse\n    | LedgerSignTransactionResponse\n    | LedgerSignMessageResponse\n    | LedgerSignTypedDataResponse\n    | GetAppNameAndVersionResponse\n    | AppConfigurationResponse\n  > {\n    const response = await this.#sendMessage({ action, params });\n\n    if ('payload' in response && response.payload) {\n      if ('success' in response && response.success) {\n        return response.payload;\n      }\n      if ('error' in response.payload) {\n        throw response.payload.error;\n      }\n    }\n\n    throw new Error('Unknown error occurred');\n  }\n\n  async #setupIframe(bridgeUrl: string): Promise<void> {\n    return new Promise((resolve) => {\n      this.iframe = document.createElement('iframe');\n      this.iframe.src = bridgeUrl;\n      this.iframe.allow = `hid 'src'`;\n      this.iframe.onload = async (): Promise<void> => {\n        this.iframeLoaded = true;\n        resolve();\n      };\n      document.head.appendChild(this.iframe);\n    });\n  }\n\n  #getOrigin(bridgeUrl: string): string {\n    const tmp = bridgeUrl.split('/');\n    tmp.splice(-1, 1);\n    return tmp.join('/');\n  }\n\n  #eventListener(\n    bridgeUrl: string,\n    eventMessage: {\n      origin: string;\n      data: IFrameMessageResponse;\n    },\n  ): void {\n    const { origin, data } = eventMessage;\n\n    if (origin !== this.#getOrigin(bridgeUrl)) {\n      return;\n    }\n\n    if (data) {\n      const messageResponseHandle = this.#messageResponseHandles.get(\n        data.messageId,\n      );\n      if (messageResponseHandle) {\n        messageResponseHandle.resolve(data);\n        this.#messageResponseHandles.delete(data.messageId);\n      } else if (data.action === IFrameMessageAction.LedgerConnectionChange) {\n        this.isDeviceConnected = data.payload.connected;\n      }\n    }\n  }\n\n  async #sendMessage<TAction extends IFrameMessageAction>(\n    message: IFrameMessage<TAction>,\n    { timeout }: { timeout?: number } = {},\n  ): Promise<IFrameMessageResponse> {\n    this.currentMessageId += 1;\n\n    const postMsg: IFramePostMessage<TAction> = {\n      ...message,\n      messageId: this.currentMessageId,\n      target: LEDGER_IFRAME_ID,\n    };\n\n    const messageResponseHandle =\n      createDeferredPromise<IFrameMessageResponse>();\n\n    this.#messageResponseHandles.set(\n      this.currentMessageId,\n      messageResponseHandle,\n    );\n\n    if (!this.iframeLoaded || !this.iframe?.contentWindow) {\n      throw new Error('The iframe is not loaded yet');\n    }\n\n    if (timeout) {\n      setTimeout(() => {\n        if (this.#messageResponseHandles.has(postMsg.messageId)) {\n          this.#messageResponseHandles.delete(postMsg.messageId);\n          messageResponseHandle.reject(\n            new Error('Ledger iframe message timeout'),\n          );\n        }\n      }, timeout);\n    }\n\n    this.iframe.contentWindow.postMessage(postMsg, '*');\n\n    return messageResponseHandle.promise;\n  }\n\n  #validateConfiguration(opts: LedgerIframeBridgeOptions): void {\n    if (typeof opts.bridgeUrl !== 'string' || opts.bridgeUrl.length === 0) {\n      throw new Error('bridgeURL is not a valid URL');\n    }\n  }\n}\n"]}