-
-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add mobile bridge #198
feat: add mobile bridge #198
Conversation
stanleyyconsensys
commented
Oct 4, 2023
- add mobile bridge
- decouple the transport middleware from the bridge, for mobile, the transport middleware is a interface to connect to ledger eth app and the transport layer; for desktop, it is refer to iframe
- adding setter / getter method for metadata from the bridge as a generic method to store different data on different bridge, hence the serialize and deserialize method from the highlevel module will serialize/deserialize the metadata together with the low level module (bridge)
- move bridgeUrl into low level module (bridge)
- enhance time complexity in deserialize, #migrateAccountDetails method by use Set, rather than array include
- reduce the number of traversal in removeAccount
- remove exportAccount due to eth keyring has throw an exception, should not create another exception type
- add mobile bridge - decouple the transport middleware from the bridge, for mobile, the transport middleware is a interface to connect to ledger eth app and the transport layer; for desktop, it is refer to iframe - adding setter / getter method for metadata from the bridge as a generic method to store different data on different bridge, hence the serialize and deserialize method from the highlevel module will serialize/deserialize the metadata together with the low level module (bridge) - move bridgeUrl into low level module (bridge) - enhance time complexity in deserialize, #migrateAccountDetails method by use Set, rather than array include - reduce the number of traversal in removeAccount - remove exportAccount due to eth keyring has throw an exception, should not create another exception type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this solution of implementing a new bridge for mobile alongside the LedgerIframeBridge
is very functional and practical. I left some minor comments for some API details, but it overall looks good
src/ledger-iframe-bridge.ts
Outdated
setOptions(opts: LedgerIframeBridgeOptions): void { | ||
this.bridgeUrl = opts.bridgeUrl ?? BRIDGE_URL; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When calling setOptions
and changing the bridgeUrl
we should do something to load another iframe, destroying the old one: this looks like destroying the bridge and re-initialising it (so that we don't end up having multiple event listeners that could lead to unpredictable results)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i thought setOptions and getOption is mainly to support serialize deserialize, thats why i was using metadata, rather than option
if setOptions has to kick off some side action, it may has some unexpected behaviour in current implementation, which setOptions is couple with deserialize
one of the example
submitEncryptionKey -> unlockKeyrings -> #restoreKeyring-> #newKeyring -> deserialize + init
it will deserialize the keyring object , then trigger init
and some high level methods (verifySeedPhrase), they may just wanna to update the data for keyring via deserialize, but do nothing
may be we can just leave setOptions as a setter, for side action, just do it separately? (for iframe usecase, call init after setOptions) ?
or
we create methods deserializeData
, serializeData
in bridge to support high level module deserialize
and serialize
, and leave the setOptions
and getOptions
to something that fit to your idea?
the advantage is :
- bridge can have custom data to serialize , rather than couple with its options
- if configuration change will auto wire up with side action, i will prefer using setXXXX (e.g setBridgeUrl) rather than setOptions?
setOptions(opts: LedgerIframeBridgeOptions): void { | |
this.bridgeUrl = opts.bridgeUrl ?? BRIDGE_URL; | |
} | |
someOtherData = 0; | |
async deserializeData(serializeData: Record<string, unknown>) { | |
for (const key in serializeData) { | |
if (key === 'bridgeUrl') { | |
this.bridgeUrl = serializeData[key] as string; | |
} | |
if (key === 'someOtherData') { | |
this.someOtherData = serializeData[key] as number; | |
} | |
} | |
} | |
async serializeData(): Promise<Record<string, unknown>> { | |
return { | |
"someOtherData": this.someOtherData, | |
"bridgeUrl": this.bridgeUrl | |
} | |
} | |
async setBridgeUrl(bridgeUrl): Promise<void> { | |
if (bridgeUrl && this.bridgeUrl !== bridgeUrl) { | |
this.bridgeUrl = bridgeUrl | |
await this.destroy(); | |
await this.init(); | |
} | |
} |
src/ledger-mobile-bridge.ts
Outdated
setOptions(opts: LedgerMobileBridgeOptions): void { | ||
this.deviceId = opts.deviceId ?? ''; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happens to the bridge is the deviceId
here is changed to another value? do we need to take some side-actions or we are good to go?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i leave it to setDeviceId, and setOption mainly set back the data from the deserialize
Blocked by:
|
These changes sound like they are orthogonal to adding the mobile bridge - would it be possible to break them out as separate PR(s) to keep the changes in this PR focused? :) Could also consider breaking this apart in at least two major PRs:
|
agree, i will create
but i have a doubt on 1 thing, is there any side affect if i change the keyring serialization structure?
to
|
@stanleyyconsensys As I read it here, that would be a breaking change (which in itself isn't necessarily a problem, just have to be more considerate about timing and ordering for merging and releasing such changes). One way we could make it non-breaking would be something like:
...and then the implementation would do something like:
that way we can allow users to stay on old behavior and migrate , by paying a price of increased complexity. Then the |
@legobeat 1 last question regarding on making changes non breaking as i found that the current bridge implementation on extension is really old extension yarn.log
it is still using a version that tight couple everything
current 1.0 version
the new version
so is it still a case that we need to take care the breaking changes? or becoz it is public repo, we assume every one is using 1.0, hence we have to make a transition step, and make sure the client who using the library should not necessary to change their 1.0 implementation? just wanna confirm the reason, hence i can refactor the class in a correct way 1 more thing, if what we are referring on non breaking is something that i mentioned above, we should also taking care the use case of how client implementing the bridgeUrl? e.g, in that case we have to keep the bridgeUrl in high level class
|