Skip to content

feat: added authenticated user storage#8260

Open
dovydas55 wants to merge 30 commits intomainfrom
MCA-83
Open

feat: added authenticated user storage#8260
dovydas55 wants to merge 30 commits intomainfrom
MCA-83

Conversation

@dovydas55
Copy link
Copy Markdown
Contributor

@dovydas55 dovydas55 commented Mar 20, 2026

Note

Medium Risk
Introduces a new SDK that makes authenticated HTTP requests using bearer tokens and validates server responses; mistakes here could surface as auth/header or schema/compatibility issues. Existing packages are largely untouched aside from monorepo wiring and ownership metadata.

Overview
Adds a new @metamask/authenticated-user-storage package that wraps the Authenticated User Storage API with an AuthenticatedUserStorage client exposing delegations (list/create/revoke) and preferences (get/put notifications), including bearer-token auth, optional X-Client-Type header support, runtime response validation via @metamask/superstruct, and consistent AuthenticatedUserStorageError wrapping.

Wires the package into the monorepo (TypeScript project references, yarn.lock workspace entry), adds Jest tests with nock fixtures/mocks, and updates CODEOWNERS/teams.json to assign ownership to Auth Team plus release-file codeowners.

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

@dovydas55 dovydas55 requested a review from a team as a code owner March 20, 2026 10:50
@dovydas55 dovydas55 requested a review from a team as a code owner March 20, 2026 10:54
@dovydas55 dovydas55 marked this pull request as draft March 20, 2026 15:50
@dovydas55 dovydas55 marked this pull request as ready for review March 24, 2026 11:56
/** Keccak-256 hash uniquely identifying the delegation (0x-prefixed). */
delegationHash: string;
/** Chain ID in hex format (0x-prefixed). */
chainIdHex: string;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

q - do we only support EVM?

Wondering if we can change the format to use CAIP-19 to support non-evm? That way we could remove chainId and tokenAddress and just have 1 field for assetId.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@V00D00-child what do you think? i believe cash accounts team already implemted they v1. However we could look into using CAIP-10

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

do we only support EVM

Yes, the Delegation Framework is only supported on EVM, so I think we should leave out using CAIP-19 for these types

V00D00-child
V00D00-child previously approved these changes Mar 26, 2026
@dovydas55 dovydas55 requested a review from mathieuartu March 27, 2026 15:00
@dovydas55 dovydas55 dismissed stale reviews from Prithpal-Sooriya and V00D00-child via d319cb3 March 27, 2026 15:00
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Copy link
Copy Markdown
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

Hey! We recently introduced some new patterns for data services which I think would directly apply here. I've left some notes below. Let me know if you have any questions.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What do you think about moving this from src/ to tests/? We've been using tests/ conventionally in other packages to hold helpers, mocks, fixtures, etc. for tests. This directory is not only consistent with other packages but is also excluded automatically from the final build.

Also, is there a reason why __fixtures__ has two underscores around it? Usually this is used for Jest-specific directories like __snapshots__ or __tests__ but as far as I know Jest doesn't recognize this directory. So what do you think about moving it to tests/fixtures or tests/helpers?

error: string;
};

export class AuthenticatedUserStorage {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks like a data service class (i.e. a class that represents an external API). Our team recently released the BaseDataService class under @metamask/base-data-service. This superclass is designed to represent our latest patterns and best practices for fetching data that we've developed in collaboration with other teams. Would you mind implementing this in your class?

The main things are:

  • Data services inherit from BaseDataService.
  • They have a messenger associated with them. This allows the service to used anywhere within a client without needing a direct reference to the instance of the class itself. SampleGasPricesService has an example of how to set up the types for this as well as the constructor and expose methods on your class through the messenger.
  • In each method you are making a request, you do this:
    • Use fetchQuery and pass a queryKey that matches the name of the method in <ServiceName>:<method> format.
    • Inside of the queryFn, you call fetch, throwing if the response is not 200. (If there is an HTTP error you want to represent, use HttpError from @metamask/controller-utils:
      export class HttpError extends Error {
      )
    • Outside of fetchQuery call, you validate the response and throw an error if it is not valid.
    • If there are any errors, you are strongly encouraged to let them bubble up to the caller unless there is a really good reason to hide them.

@@ -0,0 +1,126 @@
import type { Env } from './env';

export type Hex = `0x${string}`;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is already defined in @metamask/utils, what do you think about using this instead? https://metamask.github.io/utils/latest/types/Hex.html


import type { DelegationResponse, NotificationPreferences } from './types';

const HexSchema = define<`0x${string}`>(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

// An object that configures minimum threshold enforcement for coverage results
coverageThreshold: {
global: {
branches: 50,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there a reason why only 50% of this library is being tested? We highly encourage 100% test coverage because if the coverage tool fails in the future it's going to make it very difficult to find and understand why.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same for src/__fixtures__ — what do you think about moving this to tests/mocks?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants