-
-
Notifications
You must be signed in to change notification settings - Fork 9
feat: add OneKey keyring #353
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
base: main
Are you sure you want to change the base?
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
2dc83be to
a18c779
Compare
|
@metamaskbot publish-preview |
|
Preview builds have been published. See these instructions (from the Expand for full list of packages and versions. |
|
@metamaskbot publish-preview |
|
Preview builds have been published. See these instructions (from the Expand for full list of packages and versions. |
|
@metamaskbot publish-preview |
|
Preview builds have been published. See these instructions (from the Expand for full list of packages and versions. |
|
@metamaskbot publish-preview |
2 similar comments
|
@metamaskbot publish-preview |
|
@metamaskbot publish-preview |
|
Preview builds have been published. See these instructions (from the Expand for full list of packages and versions. |
a9761e5 to
8508712
Compare
|
@metamaskbot publish-preview |
|
Preview builds have been published. See these instructions (from the Expand for full list of packages and versions. |
| reject(new Error('signature doesnt match the right address')); | ||
| } | ||
| // eslint-disable-next-line promise/no-multiple-resolved | ||
| resolve(signature); |
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.
Bug: Missing return after reject causes dual promise settlement
In signPersonalMessage, when the recovered address doesn't match the expected account, reject() is called but execution continues without returning. This causes resolve(signature) on line 427 to also be called. The eslint-disable-next-line promise/no-multiple-resolved comment explicitly suppresses the linter warning about this issue rather than fixing it. While Promise semantics make only the first settlement effective, calling both reject() and resolve() is a control flow error indicating the code doesn't properly stop execution after detecting the address mismatch.
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.
Same as above.
| async dispose(): Promise<void> { | ||
| this.sdk?.dispose(); | ||
| return Promise.resolve(); | ||
| } |
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.
Bug: Dispose leaves bridge in inconsistent reinitialization state
The dispose() method calls this.sdk?.dispose() but doesn't reset isSDKInitialized or sdk. When keyring.destroy() calls bridge.dispose(), the bridge is left in an inconsistent state where isSDKInitialized remains true and sdk still references the disposed SDK. If init() is called afterward, it returns early because isSDKInitialized is true, preventing reinitialization. Subsequent operations will then use the disposed SDK. The destroy() method properly resets state but is never called by the keyring.
Additional Locations (1)
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.
Cursor's comment here make sense. We should add this.isSDKInitialized = false;.
| return await this.sdk | ||
| .evmGetPublicKey('', '', { ...params, skipPassphraseCheck: true }) | ||
| .then((result) => { |
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.
Can we avoid mixing .then().catch() with async/awaits? Can we use async/await only to improve readability?
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.
ok, I'll make some revisions.
| }, | ||
| }; | ||
| } | ||
| return await this.sdk.getPassphraseState('').then((result) => { |
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.
similar to my other comment, can we use a more consistent pattern with promises?
| ...params, | ||
| skipPassphraseCheck: true, | ||
| }) | ||
| .then((result) => { |
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.
similar to other comments, can we use async/await only?
| ...params, | ||
| skipPassphraseCheck: true, | ||
| }) | ||
| .then((result) => { |
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.
Can we use async/await?
| ...params, | ||
| skipPassphraseCheck: true, | ||
| }) | ||
| .then((result) => { |
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.
can we use async/await?
8508712 to
2d94f20
Compare
| reject(new Error('signature doesnt match the right address')); | ||
| } | ||
| // eslint-disable-next-line promise/no-multiple-resolved | ||
| resolve(signature); |
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.
Bug: Missing return after reject causes promise to resolve erroneously
In signPersonalMessage, when the signature address doesn't match the expected account, reject() is called but execution continues and resolve() is also called on line 427. The eslint-disable comment for promise/no-multiple-resolved acknowledges this issue but doesn't fix it - a return statement is needed after the reject() call. This causes the promise to resolve with the signature even when it should be rejected, allowing invalid signatures to be returned to callers.
| { | ||
| debug: false, | ||
| fetchConfig: false, | ||
| connectSrc: 'https://jssdk.onekey.so/1.1.0/', |
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.
Bug: Test expects wrong SDK version in connectSrc assertion
The test asserts that init() is called with connectSrc: 'https://jssdk.onekey.so/1.1.0/', but the actual implementation in onekey-web-bridge.ts uses version 1.1.17 ('https://jssdk.onekey.so/1.1.17/'). This version mismatch will cause the test to fail since the expected connectSrc value doesn't match what the code actually passes.
2d94f20 to
07316d7
Compare
| reject(new Error('signature doesnt match the right address')); | ||
| } | ||
| // eslint-disable-next-line promise/no-multiple-resolved | ||
| resolve(signature); |
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.
Bug: Missing return after reject causes promise multiple resolution
In signPersonalMessage, when the signature address verification fails, reject() is called but execution continues to also call resolve(signature) because there's no return statement. This causes both rejection and resolution of the same promise. The eslint-disable comment promise/no-multiple-resolved acknowledges this issue was suppressed rather than fixed. Compare to signTypedData which correctly uses throw for the same scenario. This could cause the potentially invalid signature to be returned despite the verification failure.
07316d7 to
ca02a28
Compare
| reject(new Error('signature doesnt match the right address')); | ||
| } | ||
| // eslint-disable-next-line promise/no-multiple-resolved | ||
| resolve(signature); |
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.
Bug: Missing return after reject causes both reject and resolve
In signPersonalMessage, when the signature address verification fails (lines 420-424), reject() is called but execution continues to resolve(signature) on line 427 because there's no return statement after the reject(). The ESLint comment promise/no-multiple-resolved explicitly acknowledges this issue but suppresses the warning rather than fixing it. While the promise will technically reject (since reject is called first), both reject and resolve are invoked in the same code path, which indicates unintended control flow.
|
@metamaskbot publish-preview |
|
Preview builds have been published. See these instructions (from the Expand for full list of packages and versions. |
ca02a28 to
89518ee
Compare
|
@SocketSecurity ignore npm/async-function |
89518ee to
ca5bb42
Compare
|
@metamaskbot publish-preview |
|
Preview builds have been published. See these instructions (from the Expand for full list of packages and versions. |
| reject(new Error('signature doesnt match the right address')); | ||
| } | ||
| // eslint-disable-next-line promise/no-multiple-resolved | ||
| resolve(signature); |
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.
Missing return after reject causes double promise resolution
Medium Severity
In signPersonalMessage, when the recovered signature address doesn't match the expected account, reject() is called but execution continues and resolve(signature) is also invoked. The eslint-disable-next-line promise/no-multiple-resolved comment confirms this was caught by the linter but suppressed rather than fixed. While Promise semantics mean the rejection wins, calling both reject and resolve on the same promise is incorrect behavior and could lead to confusion or bugs if the code is modified later. A return statement is needed after the reject() call.
| #onUIEvent?: ((event: Unsuccessful['payload']) => void) | undefined; | ||
|
|
||
| #handleBlockErrorEvent(payload: Unsuccessful): void { | ||
| const { code } = payload.payload; |
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.
Missing null check causes crash in error handler
Medium Severity
The #handleBlockErrorEvent method immediately destructures payload.payload without a null check, but callers pass result after checking result?.success with optional chaining. This inconsistency means if an SDK method returns null or undefined, the optional chaining check passes (since undefined?.success is falsy), but then #handleBlockErrorEvent(result) crashes with a TypeError when accessing undefined.payload. The pattern repeats in getPublicKey, getPassphraseState, ethereumSignTransaction, ethereumSignMessage, and ethereumSignTypedData.
Additional Locations (2)
|
@SocketSecurity ignore npm/async-function@1.0.0 |
| reject(new Error('signature doesnt match the right address')); | ||
| } | ||
| // eslint-disable-next-line promise/no-multiple-resolved | ||
| resolve(signature); |
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.
Missing return after reject causes multiple promise settlements
Medium Severity
In signPersonalMessage, when the recovered address doesn't match the expected address, reject() is called but execution continues and resolve(signature) is also called. The eslint-disable comment for promise/no-multiple-resolved acknowledges this issue but masks it rather than fixing it. A return statement is needed after the reject() call to prevent the promise from being settled twice and to avoid returning an invalid signature path.
| }, | ||
| }); | ||
| } | ||
| }); |
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.
UI_EVENT subscription never removed causes memory leak
Medium Severity
The UI_EVENT event listener added via this.sdk?.on('UI_EVENT', ...) in init() is never unsubscribed. Neither destroy() nor dispose() removes this listener before clearing the SDK reference. The callback closure holds references to this (the bridge instance), causing memory to accumulate if the bridge is initialized and destroyed multiple times during the application lifecycle.
Additional Locations (1)
| async dispose(): Promise<void> { | ||
| this.sdk?.dispose(); | ||
| return Promise.resolve(); | ||
| } |
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.
dispose() doesn't reset state preventing SDK re-initialization
Medium Severity
The dispose() method calls sdk.dispose() but doesn't reset isSDKInitialized or sdk. Since OneKeyKeyring.destroy() calls bridge.dispose() (not bridge.destroy()), the bridge is left in an inconsistent state where isSDKInitialized remains true but the SDK is disposed. Subsequent calls to init() return early without re-initializing, and SDK method calls will fail on the disposed SDK.
Additional Locations (1)
|
@metamaskbot publish-preview |
|
Preview builds have been published. See these instructions (from the Expand for full list of packages and versions. |
Adds OneKey keyring based on OneKey libraries.
Note
Adds a new hardware keyring package and wires it into the monorepo.
@metamask/eth-onekey-keyringwithOneKeyKeyringandOneKeyWebBridgeintegrating OneKey’s@onekeyfe/hd-*SDKssignTransaction,signPersonalMessage/signMessage, andsignTypedData(EIP-712), plus account paging, unlock, HD path management, and serializationtsconfig.json/tsconfig.build.jsonreferences, and workspace dependenciesWritten by Cursor Bugbot for commit e40d1ad. This will update automatically on new commits. Configure here.