Skip to content

Conversation

@hanzel98
Copy link
Contributor

@hanzel98 hanzel98 commented Nov 14, 2025

Description

Fixes #464 - Gator permissions with expiry were displaying "No expiration" in the UI.

Root Cause: The expiry timestamp is not stored directly on the permission object. Instead, it's encoded within the permissionResponse.context field as part of the delegation's TimestampEnforcer caveat.

Solution:

  • Decode the permissionContext using decodeDelegations() from @metamask/delegation-core
  • Find the TimestampEnforcer caveat in the delegation
  • Extract the last 32 hex characters from the 64-character terms field (uint128 encoding)
  • Convert to BigInt and format as a human-readable date

Changelog

CHANGELOG entry: Fixed gator permissions displaying "No expiration" when expiry timestamp exists

Related issues

Fixes: #464

Manual testing steps

  1. Create a gator permission with an expiry timestamp from jeff.dripfund.xyz
  2. Navigate to Settings → Permissions → All Permissions
  3. Locate the gator permission from jeff.dripfund.xyz
  4. Expand the permission details
  5. Verify the expiration date displays correctly (e.g., "11/13/2026") instead of "No expiration"

Screenshots/Recordings

Before

Permission showed "No expiration" despite having an expiry timestamp in the delegation context.

After

Permission now correctly displays the expiration date (e.g., "11/13/2026") extracted from the TimestampEnforcer caveat.

Pre-merge author checklist

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.
image

Note

Derives gator permission expiration from delegation context (TimestampEnforcer) and updates UI to show the correct UTC date.

  • Shared utils (shared/lib/gator-permissions/time-utils.ts):
    • Add extractExpiryTimestampFromDelegation(permissionContext, chainId) using decodeDelegations and getDeleGatorEnvironment to parse TimestampEnforcer terms and return expiry or 0.
    • Change convertTimestampToReadableDate to format in UTC.
  • UI (review-gator-permission-item.tsx):
    • Replace rules-based expiry with extractExpiryTimestampFromDelegation and render formatted expiration or "No expiration".
  • Tests:
    • Add comprehensive unit tests for expiry extraction (valid, none, multiple/zero delegations, invalid terms, zero timestamp, errors, case-insensitive enforcer).
    • Update UI tests to mock expiry extraction and validate correct dates across native/ERC20 stream/periodic permissions and no-expiration case.

Written by Cursor Bugbot for commit 8596ba0. This will update automatically on new commits. Configure here.

Fixes #464 - Permission with expiry showing 'No expiration'

- Extract expiry timestamp from permissionResponse.context by decoding delegation
- Find TimestampEnforcer caveat and decode the terms field (last 32 hex chars)
- Convert BigInt timestamp to readable date format
- Add comprehensive test coverage for all edge cases:
  - Valid expiry extraction
  - No TimestampEnforcer caveat
  - Invalid delegation count (0 or >1)
  - Invalid terms length
  - Zero timestamp
  - Decoding errors
- Remove unused imports and debug logs
@hanzel98 hanzel98 requested a review from a team as a code owner November 14, 2025 19:21
@github-actions
Copy link
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-delegation MetaMask Delegation Team label Nov 14, 2025
@metamaskbot
Copy link
Collaborator

metamaskbot commented Nov 14, 2025

✨ Files requiring CODEOWNER review ✨

👨‍🔧 @MetaMask/core-extension-ux (2 files, +169 -30)
  • 📁 ui/
    • 📁 components/
      • 📁 multichain/
        • 📁 pages/
          • 📁 gator-permissions/
            • 📁 components/
              • 📄 review-gator-permission-item.test.tsx +152 -3
              • 📄 review-gator-permission-item.tsx +17 -27

@metamaskbot
Copy link
Collaborator

Builds ready [542ada2]
UI Startup Metrics (1214 ± 97 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup1214104816179712941352
load105591314269011191182
domContentLoaded104990914178911101176
domInteractive221494181879
firstPaint682107142242910861179
backgroundConnect23121829810234243
firstReactRender28194763040
getState23981122755
initialActions105112
loadScripts824678117088883950
setupStore1062431119
numNetworkReqs1367419671
BrowserifyPower User HomeuiStartup22351833271525325722715
load1190997170823214901708
domContentLoaded1171982169223514821692
domInteractive682023070164230
firstPaint738111161647110821616
backgroundConnect2532392658261265
firstReactRender78461432385143
getState26216944582315445
initialActions101011
loadScripts938749144923212511449
setupStore25656102956
numNetworkReqs1269219836174198
WebpackStandard HomeuiStartup8377101210908431039
load61256398679609809
domContentLoaded60455797276602790
domInteractive181278141557
firstPaint21959975204212604
backgroundConnect251291142555
firstReactRender3319185183646
getState1162031216
initialActions102112
loadScripts60155596073600780
setupStore1254061325
numNetworkReqs1367720871
WebpackPower User HomeuiStartup1026832172828812881728
load617514907153813907
domContentLoaded601504886145796886
domInteractive33121153679115
firstPaint36075891307528891
backgroundConnect58102156673215
firstReactRender39354423944
getState1227813821134138
initialActions101011
loadScripts598502878142786878
setupStore1062461124
numNetworkReqs826113427118134
FirefoxBrowserifyStandard HomeuiStartup15011322208415615281858
load1248113415859512801483
domContentLoaded1248113415839512801483
domInteractive51331843249147
firstPaint------
backgroundConnect43251582447107
firstReactRender29225472944
getState137194191225
initialActions207123
loadScripts1223111614768612501420
setupStore167190211454
numNetworkReqs1266916761
BrowserifyPower User HomeuiStartup34542699451756842564517
load15821295205424619222054
domContentLoaded15821295205424619212054
domInteractive23472549167477549
firstPaint------
backgroundConnect791159129333610631293
firstReactRender945816527115165
getState1409119629165196
initialActions328138
loadScripts15311243202325318512023
setupStore793123155124231
numNetworkReqs1237623759219237
WebpackStandard HomeuiStartup16131424207014216581968
load13671206172911113901642
domContentLoaded13671206172911113901641
domInteractive59322623266113
firstPaint------
backgroundConnect45201111951102
firstReactRender32247583346
getState137140141223
initialActions203122
loadScripts13391190169610313601575
setupStore16697151549
numNetworkReqs1367118866
WebpackPower User HomeuiStartup32492589482055333914820
load16801452213823019562138
domContentLoaded16791452213823019562138
domInteractive23274541175506541
firstPaint------
backgroundConnect52611311203568161120
firstReactRender905511619106116
getState1529822535175225
initialActions214124
loadScripts16281407209123719342091
setupStore11839514109142514
numNetworkReqs1288124852187248
📊 Page Load Benchmark Results

Current Commit: 542ada2 | Date: 11/14/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.05s (±45ms) 🟡 | historical mean value: 1.03s ⬆️ (historical data)
  • domContentLoaded-> current mean value: 732ms (±41ms) 🟢 | historical mean value: 718ms ⬆️ (historical data)
  • firstContentfulPaint-> current mean value: 78ms (±11ms) 🟢 | historical mean value: 77ms ⬆️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.05s 45ms 1.02s 1.40s 1.07s 1.40s
domContentLoaded 732ms 41ms 710ms 1.04s 750ms 1.04s
firstPaint 78ms 11ms 60ms 172ms 92ms 172ms
firstContentfulPaint 78ms 11ms 60ms 172ms 92ms 172ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: -8.12 KiB (-0.17%)
  • ui: 16.38 KiB (0.22%)
  • common: 11.07 KiB (0.13%)

…missionItem tests

- Add beforeEach hooks to configure decodeDelegations and getDeleGatorEnvironment mocks for NATIVE and ERC20 token test suites
- Update test assertions to verify actual expiration date content instead of just element presence
- Fix variable naming conflicts in edge case tests to avoid scope shadowing
- Ensures tests correctly validate expiration date extraction from delegation context
@metamaskbot
Copy link
Collaborator

Builds ready [9261685]
UI Startup Metrics (1261 ± 86 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup1261110014318613281392
load109194712457711461223
domContentLoaded108394212267611391213
domInteractive2415100192082
firstPaint67190126243711141227
backgroundConnect23722236415240254
firstReactRender3119118113150
getState2275292841
initialActions106114
loadScripts85372099877912983
setupStore1172641120
numNetworkReqs1367619669
BrowserifyPower User HomeuiStartup21841809306930323543069
load1130965146015613071460
domContentLoaded1110948144815912911448
domInteractive611718156138181
firstPaint738105132640710451326
backgroundConnect25423132321264323
firstReactRender72501131788113
getState25318841059303410
initialActions104124
loadScripts879722119115210701191
setupStore311757113757
numNetworkReqs1279619734175197
WebpackStandard HomeuiStartup8427251274938411101
load615565102283610869
domContentLoaded60855999379604840
domInteractive1911139181558
firstPaint161591024142171574
backgroundConnect261281142862
firstReactRender3220144143638
getState1163231316
initialActions103111
loadScripts60555798277601829
setupStore1264551319
numNetworkReqs1367619671
WebpackPower User HomeuiStartup1076904154719612621547
load647557961117760961
domContentLoaded62254785287726852
domInteractive301397313397
firstPaint32164855263571855
backgroundConnect641022972152229
firstReactRender40364634246
getState1419218327154183
initialActions101011
loadScripts61854584283715842
setupStore1362782427
numNetworkReqs826413926103139
FirefoxBrowserifyStandard HomeuiStartup14591297196913814981780
load1217111414598012701414
domContentLoaded1217111414598012701413
domInteractive51341593053138
firstPaint------
backgroundConnect4225215234981
firstReactRender28225472849
getState1073841116
initialActions104122
loadScripts1194109614407612391366
setupStore167207271236
numNetworkReqs1266214752
BrowserifyPower User HomeuiStartup32162717409932834094099
load15391275196721816981967
domContentLoaded15391275196621816981966
domInteractive24171620190415620
firstPaint------
backgroundConnect54212211713329271171
firstReactRender884912922106129
getState21089569149221569
initialActions213133
loadScripts14801241192320416251923
setupStore982833773112337
numNetworkReqs1257723054148230
WebpackStandard HomeuiStartup16451452215015116461972
load13941239175211414131657
domContentLoaded13941239175211414121657
domInteractive57301592766111
firstPaint------
backgroundConnect48251192254108
firstReactRender32257473543
getState13753111250
initialActions204123
loadScripts13621185167610713881602
setupStore16695161458
numNetworkReqs1366617863
WebpackPower User HomeuiStartup29892486402035430744020
load16401401202319918532023
domContentLoaded16391400202319918522023
domInteractive24194588168414588
firstPaint------
backgroundConnect389143761220597761
firstReactRender75461021691102
getState1538519629182196
initialActions404110241
loadScripts15861376200219618172002
setupStore12537422110154422
numNetworkReqs1257323349186233
📊 Page Load Benchmark Results

Current Commit: 9261685 | Date: 11/14/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.04s (±44ms) 🟡 | historical mean value: 1.03s ⬆️ (historical data)
  • domContentLoaded-> current mean value: 728ms (±61ms) 🟢 | historical mean value: 718ms ⬆️ (historical data)
  • firstContentfulPaint-> current mean value: 89ms (±127ms) 🟢 | historical mean value: 77ms ⬆️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.04s 44ms 1.02s 1.40s 1.08s 1.40s
domContentLoaded 728ms 61ms 706ms 1.29s 750ms 1.29s
firstPaint 89ms 127ms 64ms 1.36s 88ms 1.36s
firstContentfulPaint 89ms 127ms 64ms 1.36s 88ms 1.36s
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: -8.12 KiB (-0.17%)
  • ui: 27.71 KiB (0.37%)
  • common: 11.26 KiB (0.13%)

Copy link
Contributor

@MoMannn MoMannn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some tests are failing. Run yarn test:unit:coverage --shard=4/6 locally to check.

if (!rules) {
const getExpirationDate = useCallback((): string => {
try {
const delegations = decodeDelegations(permissionContext);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it might be usable in different places. Could we wrap it into a reusable function that returns expiry or 0 and move it to: gator-permissions-utils file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then you can also move most of the test to utils testing the function and only basic test that shows or shows no expiration in the item tests.

@MoMannn
Copy link
Contributor

MoMannn commented Nov 17, 2025

Would it make sense to merge this into: #37768 and have a single PR?

- Created extractExpiryTimestampFromDelegation() in time-utils.ts
- Returns expiry timestamp or 0, making it reusable across components
- Simplified review-gator-permission-item.tsx from ~60 lines to ~10 lines
- Moved comprehensive tests from component to utility tests
- Component tests now focus on UI behavior only
@metamaskbot
Copy link
Collaborator

Builds ready [741e6c2]
UI Startup Metrics (1213 ± 79 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup1213106813987912721358
load105093012467311051185
domContentLoaded104492512277110991172
domInteractive231491171972
firstPaint628163126240610491126
backgroundConnect23121827210235254
firstReactRender27205162841
getState2085282538
initialActions102112
loadScripts81970198870867938
setupStore1072021016
numNetworkReqs1367620674
BrowserifyPower User HomeuiStartup21671899312329622143123
load1141986173721513791737
domContentLoaded1121967172321913721723
domInteractive531816451108164
firstPaint730133144542110431445
backgroundConnect25023027512257275
firstReactRender705086107986
getState24416934357286343
initialActions103113
loadScripts893746146321211481463
setupStore281761103261
numNetworkReqs1249519235160192
WebpackStandard HomeuiStartup86373112771018661117
load631573103996625893
domContentLoaded624567101992619869
domInteractive1912105151556
firstPaint197621022203202751
backgroundConnect271271143063
firstReactRender31205373640
getState1151831316
initialActions102111
loadScripts621565100889617858
setupStore1161831416
numNetworkReqs1367619872
WebpackPower User HomeuiStartup1083945155720313051557
load68258110441467421044
domContentLoaded667570986134732986
domInteractive33141143472114
firstPaint2486510502493341050
backgroundConnect44101814682181
firstReactRender43385844458
getState1408417428158174
initialActions101011
loadScripts663568975131722975
setupStore86213821
numNetworkReqs80641382389138
FirefoxBrowserifyStandard HomeuiStartup14701322189511915051720
load1247113215638512861428
domContentLoaded1247113215638512851428
domInteractive60332394162165
firstPaint------
backgroundConnect4026115154669
firstReactRender26215962643
getState1073541017
initialActions103122
loadScripts1223109715448212611400
setupStore1177381024
numNetworkReqs1266414754
BrowserifyPower User HomeuiStartup33392438461663639544616
load15951347230929217372309
domContentLoaded15951347230929217372309
domInteractive28882707208548707
firstPaint------
backgroundConnect550111123140110791231
firstReactRender916412817103128
getState1587924945185249
initialActions41317331
loadScripts15561296228029617102280
setupStore10431537117123537
numNetworkReqs1287325564223255
WebpackStandard HomeuiStartup16231456223814616691937
load13731216172210814121617
domContentLoaded13731216172210814121617
domInteractive59302253265129
firstPaint------
backgroundConnect47242383050115
firstReactRender332481103445
getState1175061220
initialActions103123
loadScripts1343119616609813781576
setupStore14675121449
numNetworkReqs1366917762
WebpackPower User HomeuiStartup33392628446958738974469
load17271485232225319952322
domContentLoaded17271485232225319952322
domInteractive23173572184516572
firstPaint------
backgroundConnect54416310733208801073
firstReactRender905412016105120
getState1768741071193410
initialActions318238
loadScripts16661395214924019092149
setupStore973618945117189
numNetworkReqs1317725662206256
📊 Page Load Benchmark Results

Current Commit: 741e6c2 | Date: 11/18/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.06s (±37ms) 🟡 | historical mean value: 1.04s ⬆️ (historical data)
  • domContentLoaded-> current mean value: 736ms (±35ms) 🟢 | historical mean value: 726ms ⬆️ (historical data)
  • firstContentfulPaint-> current mean value: 80ms (±12ms) 🟢 | historical mean value: 77ms ⬆️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.06s 37ms 1.03s 1.33s 1.09s 1.33s
domContentLoaded 736ms 35ms 710ms 997ms 764ms 997ms
firstPaint 80ms 12ms 60ms 184ms 88ms 184ms
firstContentfulPaint 80ms 12ms 60ms 184ms 88ms 184ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: -6.56 KiB (-0.14%)
  • ui: 37.77 KiB (0.51%)
  • common: 33.55 KiB (0.38%)

Jest's it() function doesn't accept timeout as third parameter with async callbacks.
Removed invalid timeout arguments from two test cases that were causing TypeScript errors.

if (!expiry || expiry === 0) {
return 0;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Timestamp Overflow Leads to Conversion Crash

Converting a uint128 value larger than Number.MAX_SAFE_INTEGER to Number produces Infinity, which passes the validation checks and gets returned. When convertTimestampToReadableDate receives Infinity, it throws an uncaught error. The function should check for Infinity and return 0, or validate that the timestamp is within a reasonable range before conversion.

Fix in Cursor Fix in Web

@metamaskbot
Copy link
Collaborator

Builds ready [d790d8a]
UI Startup Metrics (1223 ± 91 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup1223110116479112771380
load105592314108011061177
domContentLoaded104992014048011011170
domInteractive231494172075
firstPaint60083119942010651168
backgroundConnect2342222849237248
firstReactRender30195883447
getState22771102541
initialActions107113
loadScripts821688116180877944
setupStore1173551223
numNetworkReqs1367619670
BrowserifyPower User HomeuiStartup------
load------
domContentLoaded------
domInteractive------
firstPaint------
backgroundConnect------
firstReactRender------
getState------
initialActions------
loadScripts------
setupStore------
numNetworkReqs------
WebpackStandard HomeuiStartup87073512451048731160
load63656998593629925
domContentLoaded62956596890624910
domInteractive1912155191557
firstPaint21457947227193846
backgroundConnect251185132757
firstReactRender322085103842
getState1162031316
initialActions102011
loadScripts62656395787622899
setupStore1263141419
numNetworkReqs1367519870
WebpackPower User HomeuiStartup1041906139817312811398
load67056410031447621003
domContentLoaded654554972136756972
domInteractive33131063481106
firstPaint33060960290586960
backgroundConnect341099254899
firstReactRender40374424244
getState1368617825149178
initialActions101011
loadScripts650552962133746962
setupStore1262982429
numNetworkReqs786112321100123
FirefoxBrowserifyStandard HomeuiStartup15551326218415016111856
load12961135159710013501506
domContentLoaded12961135159710013501506
domInteractive57342054050176
firstPaint------
backgroundConnect4826159225496
firstReactRender30235983052
getState1273751321
initialActions213123
loadScripts1267111515649413071477
setupStore177218231536
numNetworkReqs1266516759
BrowserifyPower User HomeuiStartup33002511457463541404574
load15011321191319817231913
domContentLoaded15011321191319817221913
domInteractive24693603180367603
firstPaint------
backgroundConnect585133139540510191395
firstReactRender81571211795121
getState1617645685194456
initialActions214134
loadScripts14481264186820116261868
setupStore15836504141237504
numNetworkReqs1276624565227245
WebpackStandard HomeuiStartup16801438222915417322029
load14191237173911114791693
domContentLoaded14191237173911114791692
domInteractive56311632864125
firstPaint------
backgroundConnect54221543055128
firstReactRender352587123581
getState148196221217
initialActions203123
loadScripts13851223165810214571611
setupStore15682161372
numNetworkReqs1366817764
WebpackPower User HomeuiStartup33362696428251538674282
load17321431205221519902052
domContentLoaded17321431205221519902052
domInteractive265102577175461577
firstPaint------
backgroundConnect4098410823107041082
firstReactRender944715026111150
getState197103457102222457
initialActions216126
loadScripts16701402200419918862004
setupStore13339541133107541
numNetworkReqs1287322146159221
📊 Page Load Benchmark Results

Current Commit: d790d8a | Date: 11/18/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.03s (±38ms) 🟡 | historical mean value: 1.04s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 720ms (±36ms) 🟢 | historical mean value: 729ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 76ms (±12ms) 🟢 | historical mean value: 78ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.03s 38ms 1.01s 1.32s 1.06s 1.32s
domContentLoaded 720ms 36ms 700ms 994ms 741ms 994ms
firstPaint 76ms 12ms 60ms 184ms 84ms 184ms
firstContentfulPaint 76ms 12ms 60ms 184ms 84ms 184ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: -6.56 KiB (-0.14%)
  • ui: 37.77 KiB (0.51%)
  • common: 36.72 KiB (0.42%)

Jest's beforeAll/afterAll don't accept timeout as second parameter with async callbacks.
Removed invalid timeout arguments that were causing issues.
@metamaskbot
Copy link
Collaborator

Builds ready [8596ba0]
UI Startup Metrics (1242 ± 101 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup12421067173210113041396
load107693214678911311200
domContentLoaded107092214378811251193
domInteractive231481162069
firstPaint58196148441810581178
backgroundConnect23422029611236254
firstReactRender29205273346
getState238100132650
initialActions103112
loadScripts842677118187898971
setupStore1162241220
numNetworkReqs1367520672
BrowserifyPower User HomeuiStartup22472013299424324202994
load1167986171422414421714
domContentLoaded1142970170623014321706
domInteractive591920858123208
firstPaint625219155641210261556
backgroundConnect25823829615268296
firstReactRender77551011184101
getState24618335750291357
initialActions105125
loadScripts912745144522412001445
setupStore301271133571
numNetworkReqs1249520435173204
WebpackStandard HomeuiStartup88674012521048991166
load648572101088643918
domContentLoaded64056799485636898
domInteractive2012144181659
firstPaint21759997220208780
backgroundConnect271170143063
firstReactRender32206283741
getState1266971418
initialActions102111
loadScripts63756598282634888
setupStore1264251318
numNetworkReqs1367419870
WebpackPower User HomeuiStartup1110936162122213241621
load70358910871659071087
domContentLoaded685586982145884982
domInteractive37141444074144
firstPaint3236310093286241009
backgroundConnect4291784846178
firstReactRender42394724347
getState1408716726156167
initialActions101011
loadScripts681584969141873969
setupStore16637112737
numNetworkReqs76621332076133
FirefoxBrowserifyStandard HomeuiStartup15121364204312915321805
load1266116916228712871487
domContentLoaded1266116916228712871487
domInteractive55352213554152
firstPaint------
backgroundConnect4426159234997
firstReactRender27234742833
getState147225231124
initialActions203122
loadScripts1241115115868012611459
setupStore1386981329
numNetworkReqs1266115756
BrowserifyPower User HomeuiStartup31352398443560232564435
load14771255191921517851919
domContentLoaded14771255191921517851919
domInteractive23378621180411621
firstPaint------
backgroundConnect47012111703669201170
firstReactRender85611231799123
getState21881589140239589
initialActions318238
loadScripts14391218184520717071845
setupStore1213836191142361
numNetworkReqs1277625463212254
WebpackStandard HomeuiStartup16461445205714216661988
load13981254176210614121671
domContentLoaded13981254176110614121670
domInteractive58321762667115
firstPaint------
backgroundConnect48261472554112
firstReactRender332581103464
getState1275271226
initialActions203122
loadScripts1367123616619413801605
setupStore167189201338
numNetworkReqs1366818866
WebpackPower User HomeuiStartup34252655473661636954736
load17301520211120619832111
domContentLoaded17291520211020619832110
domInteractive23175643174425643
firstPaint------
backgroundConnect48917910312937581031
firstReactRender1017914118110141
getState196132613110189613
initialActions223033
loadScripts16751491208520619512085
setupStore853018145134181
numNetworkReqs1256924258192242
📊 Page Load Benchmark Results

Current Commit: 8596ba0 | Date: 11/19/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.02s (±40ms) 🟡 | historical mean value: 1.04s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 713ms (±37ms) 🟢 | historical mean value: 728ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 76ms (±14ms) 🟢 | historical mean value: 77ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.02s 40ms 999ms 1.34s 1.05s 1.34s
domContentLoaded 713ms 37ms 691ms 999ms 732ms 999ms
firstPaint 76ms 14ms 60ms 208ms 84ms 208ms
firstContentfulPaint 76ms 14ms 60ms 208ms 84ms 208ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: -6.56 KiB (-0.14%)
  • ui: 38.12 KiB (0.51%)
  • common: 36.72 KiB (0.42%)

}

const dateTime = DateTime.fromSeconds(timestamp);
const dateTime = DateTime.fromSeconds(timestamp, { zone: 'utc' });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used in multiple places, is it ok to change to UTC generally?

* @param chainId - The chain ID hex string
* @returns The expiration timestamp in seconds, or 0 if no expiration exists
*/
export const extractExpiryTimestampFromDelegation = (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We talked also about possibly moving this to the core gator permissions controller package. Looking more carefully I think that would be best. Since logic for this is already in the core but seems it does not work correctly: https://github.com/MetaMask/core/blob/33179969f4aa3df91b31a6ec18ba67da6b574c82/packages/gator-permissions-controller/src/decodePermission/decodePermission.ts#L124 I think it would be best to fix that logic there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size-L team-delegation MetaMask Delegation Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants