Commit 8cfa941
authored
fix: [Mobile] Perps KEYRING_LOCKED error in HyperLiquidWalletService (#30077)
## **Description**
Fixes Perps `KEYRING_LOCKED` handling when HyperLiquid wraps wallet
signing failures. The provider now walks the `Error.cause` chain so
wrapped keyring-lock errors use the retry-later path instead of being
reported as generic setup failures.
Follow-up considered: preflight-gating Perps signing setup until the
keyring is unlocked/available. That may avoid entering SDK signing paths
that cannot succeed, but it changes initialization timing and retry
behavior. This PR keeps the existing retry-later flow and fixes the
concrete error-boundary bug: HyperLiquid SDK wraps `KEYRING_LOCKED` as
the error `cause`, so provider catches must inspect the cause chain. We
will monitor Sentry after release; if locked signing events remain
meaningful, the next step is a keyring-availability gate before
signing-dependent setup.
## **Changelog**
CHANGELOG entry: Fixed a Perps setup error that could report
locked-keyring retries as failures
## **Related issues**
Fixes:
[TAT-3176](https://consensyssoftware.atlassian.net/browse/TAT-3176)
## **Manual testing steps**
```gherkin
Feature: Perps keyring lock retry
Scenario: wrapped keyring lock is handled as retry-later
Given HyperLiquid setup receives a wrapped signing error with cause.message KEYRING_LOCKED
When the provider classifies the setup error
Then the provider uses the keyring-locked retry-later branch
And the generic Sentry failure branch is not used
```
## **Screenshots/Recordings**
No visual evidence selected for publication.
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [x] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [x] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [x] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
## **Validation Recipe**
<details>
<summary>recipe.json</summary>
```json
{
"pr": "",
"title": "TAT-3176 wrapped KEYRING_LOCKED classifier",
"jira": "TAT-3176",
"acceptance_criteria": [
"Wrapped KEYRING_LOCKED errors whose cause.message is KEYRING_LOCKED are classified as keyring-locked retry-later errors instead of falling through to generic logger.error/Sentry, failed AccountSetup analytics, or failure caches."
],
"validate": {
"workflow": {
"entry": "ac1-assert-wrapped-keyring-locked",
"nodes": {
"ac1-assert-wrapped-keyring-locked": {
"action": "eval_sync",
"expression": "(function(){var mods=globalThis.__r.getModules();var moduleId=null;mods.forEach(function(v,k){if(v&&v.verboseName==='app/controllers/perps/utils/errorUtils.ts'){moduleId=k;}});var errorUtils=globalThis.__r(moduleId);var cause=new Error('KEYRING_LOCKED');var wrapped=new Error('Failed to sign typed data with viem wallet');wrapped.cause=cause;return JSON.stringify({moduleFound:moduleId!==null,classified:errorUtils.isKeyringLockedError(wrapped)});})()",
"assert": {
"operator": "eq",
"field": "classified",
"value": true
},
"next": "done"
},
"done": {
"action": "end",
"status": "pass"
}
}
}
}
}
```
</details>
## **Recipe Workflow**
<details>
<summary>workflow.mmd</summary>
```mermaid
flowchart TD
ac1["ac1-assert-wrapped-keyring-locked"]
done["done"]
ac1 --> done
```
</details>
[TAT-3176]:
https://consensyssoftware.atlassian.net/browse/TAT-3176?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes error classification for keyring-locked signing failures,
affecting retry/caching and whether failures get logged/reported;
mistakes here could cause repeated prompts or suppressed retries in
trading setup.
>
> **Overview**
> Prevents HyperLiquid SDK-wrapped signing failures from being treated
as generic setup errors by introducing `isKeyringLockedError()` (walks
the `Error.cause` chain) and using it in HyperLiquid unified account
enablement, builder-fee approval, and referral setup.
>
> Adds test coverage ensuring wrapped `KEYRING_LOCKED` errors do **not**
populate failure caches (`TradingReadinessCache`/`PerpsSigningCache`) or
trigger error logging, while still releasing in-flight locks and
allowing the order/setup flow to proceed.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
4fdd74f. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->1 parent d4d4dfa commit 8cfa941
4 files changed
Lines changed: 191 additions & 10 deletions
File tree
- app/controllers/perps
- providers
- utils
Lines changed: 128 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5969 | 5969 | | |
5970 | 5970 | | |
5971 | 5971 | | |
| 5972 | + | |
| 5973 | + | |
| 5974 | + | |
| 5975 | + | |
| 5976 | + | |
| 5977 | + | |
| 5978 | + | |
| 5979 | + | |
| 5980 | + | |
| 5981 | + | |
| 5982 | + | |
| 5983 | + | |
| 5984 | + | |
| 5985 | + | |
| 5986 | + | |
| 5987 | + | |
| 5988 | + | |
| 5989 | + | |
| 5990 | + | |
| 5991 | + | |
| 5992 | + | |
| 5993 | + | |
| 5994 | + | |
| 5995 | + | |
| 5996 | + | |
| 5997 | + | |
| 5998 | + | |
| 5999 | + | |
| 6000 | + | |
| 6001 | + | |
| 6002 | + | |
| 6003 | + | |
| 6004 | + | |
| 6005 | + | |
| 6006 | + | |
| 6007 | + | |
| 6008 | + | |
| 6009 | + | |
| 6010 | + | |
| 6011 | + | |
| 6012 | + | |
| 6013 | + | |
| 6014 | + | |
| 6015 | + | |
| 6016 | + | |
| 6017 | + | |
5972 | 6018 | | |
5973 | 6019 | | |
5974 | 6020 | | |
| |||
6007 | 6053 | | |
6008 | 6054 | | |
6009 | 6055 | | |
| 6056 | + | |
| 6057 | + | |
| 6058 | + | |
| 6059 | + | |
| 6060 | + | |
| 6061 | + | |
| 6062 | + | |
| 6063 | + | |
| 6064 | + | |
| 6065 | + | |
| 6066 | + | |
| 6067 | + | |
| 6068 | + | |
| 6069 | + | |
| 6070 | + | |
| 6071 | + | |
| 6072 | + | |
| 6073 | + | |
| 6074 | + | |
| 6075 | + | |
| 6076 | + | |
| 6077 | + | |
| 6078 | + | |
| 6079 | + | |
| 6080 | + | |
| 6081 | + | |
| 6082 | + | |
| 6083 | + | |
| 6084 | + | |
| 6085 | + | |
| 6086 | + | |
| 6087 | + | |
| 6088 | + | |
| 6089 | + | |
| 6090 | + | |
| 6091 | + | |
| 6092 | + | |
| 6093 | + | |
| 6094 | + | |
| 6095 | + | |
| 6096 | + | |
| 6097 | + | |
| 6098 | + | |
| 6099 | + | |
| 6100 | + | |
| 6101 | + | |
| 6102 | + | |
6010 | 6103 | | |
6011 | 6104 | | |
6012 | 6105 | | |
| |||
9325 | 9418 | | |
9326 | 9419 | | |
9327 | 9420 | | |
| 9421 | + | |
| 9422 | + | |
| 9423 | + | |
| 9424 | + | |
| 9425 | + | |
| 9426 | + | |
| 9427 | + | |
| 9428 | + | |
| 9429 | + | |
| 9430 | + | |
| 9431 | + | |
| 9432 | + | |
| 9433 | + | |
| 9434 | + | |
| 9435 | + | |
| 9436 | + | |
| 9437 | + | |
| 9438 | + | |
| 9439 | + | |
| 9440 | + | |
| 9441 | + | |
| 9442 | + | |
| 9443 | + | |
| 9444 | + | |
| 9445 | + | |
| 9446 | + | |
| 9447 | + | |
| 9448 | + | |
| 9449 | + | |
| 9450 | + | |
| 9451 | + | |
| 9452 | + | |
| 9453 | + | |
| 9454 | + | |
| 9455 | + | |
9328 | 9456 | | |
9329 | 9457 | | |
9330 | 9458 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
128 | 128 | | |
129 | 129 | | |
130 | 130 | | |
131 | | - | |
| 131 | + | |
132 | 132 | | |
133 | 133 | | |
134 | 134 | | |
| |||
814 | 814 | | |
815 | 815 | | |
816 | 816 | | |
817 | | - | |
818 | | - | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
819 | 820 | | |
820 | 821 | | |
821 | 822 | | |
| |||
2650 | 2651 | | |
2651 | 2652 | | |
2652 | 2653 | | |
2653 | | - | |
2654 | | - | |
| 2654 | + | |
| 2655 | + | |
| 2656 | + | |
2655 | 2657 | | |
2656 | 2658 | | |
2657 | 2659 | | |
| |||
8468 | 8470 | | |
8469 | 8471 | | |
8470 | 8472 | | |
8471 | | - | |
8472 | | - | |
| 8473 | + | |
| 8474 | + | |
| 8475 | + | |
8473 | 8476 | | |
8474 | 8477 | | |
8475 | 8478 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
74 | 98 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
3 | | - | |
| 2 | + | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
| 8 | + | |
7 | 9 | | |
8 | 10 | | |
9 | 11 | | |
| |||
23 | 25 | | |
24 | 26 | | |
25 | 27 | | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
26 | 52 | | |
27 | 53 | | |
28 | 54 | | |
| |||
0 commit comments