eth-ledger-bridge-keyring
eth-ledger-bridge-keyring copied to clipboard
Handling Multiple Init's
Issues:
-
LedgerBridgeKeyringcan accidentally be initialised twice on the same client, resulting in silent failures (e.g. messages be either duplicated or resolved prematurely/incorrectly). - Now that set-up logic is being moved to a separate
initfunction, there's a possibility that the same instance isinit'ed twice, and thus requires appropriate handling and fail-safes
-
setupIframeto throw an error if it detects a duplicateiframe -
this.currentMessageIdto be removed and replaced withnanoid- Ensures that two different clients sending messages to the same bridge URL will always have a unique (instead of being 0-indexed and incrementing)
- Reduces code complexity
- Prevent
this.bridgeUrlfrom being null before the iframe is created, or at least update the iframe if the keyring is deserialized with a newbridgeUrl- See this ticket for more details: https://github.com/MetaMask/eth-ledger-bridge-keyring/issues/161
- Safe-proofing delayed promise: https://github.com/MetaMask/eth-ledger-bridge-keyring/issues/162
-
this._eventListenerwill be mutated if the keyring is init'ed twice, which would interfere with:-
window.removeEventListener('message', this._eventListener) - Solution to this may be to just remove
this._eventListenercompletely, and replace it with something like this:
-
type WindowEventHandlerTuple = readonly [
keyof WindowEventHandlersEventMap,
(this: WindowEventHandlers, ev: WindowEventHandlersEventMap[keyof WindowEventHandlersEventMap]) => any
];
class LedgerBridgeKeyring extends EventEmitter {
_windowEventListeners: ReadonlyArray<WindowEventHandlerTuple> = [];
_setupListener () {
const messageListener = ({ origin, data }) => {
// ...
}
this._addWindowEventListener(['message', messageListener])
}
_addWindowEventListener(windowEventHandler: WindowEventHandlerTuple){
window.addListener(...windowEventHandler);
this._windowEventListeners = [...this._windowEventListeners, windowEventHandler];
}
destroy(){
for(const listener of this._windowEventListeners){
window.removeListener(...listener);
}
}
}