diff --git a/jest.config.js b/jest.config.js index 95acdb90..6fc5cddf 100644 --- a/jest.config.js +++ b/jest.config.js @@ -41,10 +41,10 @@ module.exports = { // An object that configures minimum threshold enforcement for coverage results coverageThreshold: { global: { - branches: 68.06, + branches: 65.42, functions: 88.57, - lines: 81.29, - statements: 81.21, + lines: 81.63, + statements: 81.55, }, }, diff --git a/src/ledger-iframe-bridge.test.ts b/src/ledger-iframe-bridge.test.ts index c2c69dae..161eaf69 100644 --- a/src/ledger-iframe-bridge.test.ts +++ b/src/ledger-iframe-bridge.test.ts @@ -1,7 +1,6 @@ import { hasProperty } from '@metamask/utils'; import { - type IFrameMessageResponse, IFrameMessageAction, LedgerIframeBridge, } from './ledger-iframe-bridge'; @@ -63,7 +62,7 @@ describe('LedgerIframeBridge', function () { */ function stubKeyringIFramePostMessage( bridgeInstance: LedgerIframeBridge, - fn: (message: IFrameMessageResponse) => void, + fn: (message: any) => void, ) { if (!isIFrameValid(bridgeInstance.iframe)) { throw new Error('the iframe is not valid'); diff --git a/src/ledger-iframe-bridge.ts b/src/ledger-iframe-bridge.ts index efdb9b83..a5ffe5f8 100644 --- a/src/ledger-iframe-bridge.ts +++ b/src/ledger-iframe-bridge.ts @@ -22,58 +22,46 @@ export enum IFrameMessageAction { LedgerSignTypedData = 'ledger-sign-typed-data', } -type IFrameMessageResponseStub< - SuccessResult extends Record, - FailureResult = Error, -> = { +type IFrameMessageResponse = { + action: TAction; messageId: number; } & ( - | { success: true; payload: SuccessResult } - | { success: false; payload: { error: FailureResult } } + | { + action: IFrameMessageAction.LedgerConnectionChange; + payload: { connected: boolean }; + } + | ({ + action: IFrameMessageAction.LedgerMakeApp; + } & ({ success: true } | { success: false; error?: unknown })) + | { + action: IFrameMessageAction.LedgerUpdateTransport; + success: boolean; + } + | ({ + action: IFrameMessageAction.LedgerUnlock; + } & ( + | { success: true; payload: GetPublicKeyResponse } + | { success: false; payload: { error: Error } } + )) + | ({ + action: IFrameMessageAction.LedgerSignTransaction; + } & ( + | { success: true; payload: LedgerSignTransactionResponse } + | { success: false; payload: { error: Error } } + )) + | ({ + action: + | IFrameMessageAction.LedgerSignPersonalMessage + | IFrameMessageAction.LedgerSignTypedData; + } & ( + | { + success: true; + payload: LedgerSignMessageResponse | LedgerSignTypedDataResponse; + } + | { success: false; payload: { error: Error } } + )) ); -type LedgerConnectionChangeActionResponse = { - messageId: number; - action: IFrameMessageAction.LedgerConnectionChange; - payload: { connected: boolean }; -}; - -type LedgerMakeAppActionResponse = { - messageId: number; - action: IFrameMessageAction.LedgerMakeApp; -} & ({ success: true } | { success: false; error?: unknown }); - -type LedgerUpdateTransportActionResponse = { - messageId: number; - action: IFrameMessageAction.LedgerUpdateTransport; - success: boolean; -}; - -type LedgerUnlockActionResponse = { - action: IFrameMessageAction.LedgerUnlock; -} & IFrameMessageResponseStub; - -type LedgerSignTransactionActionResponse = { - action: IFrameMessageAction.LedgerSignTransaction; -} & IFrameMessageResponseStub; - -type LedgerSignPersonalMessageActionResponse = { - action: IFrameMessageAction.LedgerSignPersonalMessage; -} & IFrameMessageResponseStub; - -type LedgerSignTypedDataActionResponse = { - action: IFrameMessageAction.LedgerSignTypedData; -} & IFrameMessageResponseStub; - -export type IFrameMessageResponse = - | LedgerConnectionChangeActionResponse - | LedgerMakeAppActionResponse - | LedgerUpdateTransportActionResponse - | LedgerUnlockActionResponse - | LedgerSignTransactionActionResponse - | LedgerSignPersonalMessageActionResponse - | LedgerSignTypedDataActionResponse; - type IFrameMessage = { action: TAction; params?: Readonly>; @@ -92,15 +80,17 @@ export class LedgerIframeBridge implements LedgerBridge { eventListener?: (eventMessage: { origin: string; - data: IFrameMessageResponse; + data: IFrameMessageResponse; }) => void; isDeviceConnected = false; currentMessageId = 0; - messageCallbacks: Record void> = - {}; + messageCallbacks: Record< + number, + (response: IFrameMessageResponse) => void + > = {}; delayedPromise?: { resolve: (value: boolean) => void; @@ -129,12 +119,10 @@ export class LedgerIframeBridge implements LedgerBridge { action: IFrameMessageAction.LedgerMakeApp, }, (response) => { - if ('success' in response && response.success) { + if (response.success) { resolve(true); - } else if ('error' in response) { - reject(response.error); } else { - reject(new Error('Unknown error occurred')); + reject(response.error); } }, ); @@ -159,8 +147,8 @@ export class LedgerIframeBridge implements LedgerBridge { action: IFrameMessageAction.LedgerUpdateTransport, params: { transportType }, }, - (response) => { - if ('success' in response && response.success) { + ({ success }) => { + if (success) { return resolve(true); } return reject(new Error('Ledger transport could not be updated')); @@ -235,16 +223,11 @@ export class LedgerIframeBridge implements LedgerBridge { action, params, }, - (response) => { - if ('payload' in response && response.payload) { - if ('success' in response && response.success) { - return resolve(response.payload); - } - if ('error' in response.payload) { - return reject(response.payload.error); - } + ({ success, payload }) => { + if (success) { + return resolve(payload); } - return reject(new Error('Unknown error occurred')); + return reject(payload.error); }, ); }); @@ -284,7 +267,7 @@ export class LedgerIframeBridge implements LedgerBridge { bridgeUrl: string, eventMessage: { origin: string; - data: IFrameMessageResponse; + data: IFrameMessageResponse; }, ) { if (eventMessage.origin !== this.#getOrigin(bridgeUrl)) { @@ -306,7 +289,7 @@ export class LedgerIframeBridge implements LedgerBridge { #sendMessage( message: IFrameMessage, - callback: (response: IFrameMessageResponse) => void, + callback: (response: IFrameMessageResponse) => void, ) { this.currentMessageId += 1; @@ -316,7 +299,9 @@ export class LedgerIframeBridge implements LedgerBridge { target: LEDGER_IFRAME_ID, }; - this.messageCallbacks[this.currentMessageId] = callback; + this.messageCallbacks[this.currentMessageId] = callback as ( + response: IFrameMessageResponse, + ) => void; if (!this.iframeLoaded || !this.iframe || !this.iframe.contentWindow) { throw new Error('The iframe is not loaded yet');