@metamask/profile-sync-controller 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/dist/{chunk-5SXXO4MV.js → chunk-3TE6M5TV.js} +10 -8
  3. package/dist/chunk-3TE6M5TV.js.map +1 -0
  4. package/dist/{chunk-CSFHMILK.js → chunk-77LSWSGB.js} +8 -8
  5. package/dist/{chunk-CSFHMILK.js.map → chunk-77LSWSGB.js.map} +1 -1
  6. package/dist/{chunk-RT2GRG4S.mjs → chunk-7KMONAQI.mjs} +3 -3
  7. package/dist/{chunk-2XGRQBXI.mjs → chunk-FU7PSGFP.mjs} +10 -8
  8. package/dist/chunk-FU7PSGFP.mjs.map +1 -0
  9. package/dist/{chunk-P52TG263.js → chunk-FUPEFLXB.js} +18 -24
  10. package/dist/chunk-FUPEFLXB.js.map +1 -0
  11. package/dist/chunk-ILIZJQ6X.mjs +40 -0
  12. package/dist/chunk-ILIZJQ6X.mjs.map +1 -0
  13. package/dist/{chunk-3SNLHEYU.mjs → chunk-IQECLCH4.mjs} +5 -5
  14. package/dist/{chunk-3SNLHEYU.mjs.map → chunk-IQECLCH4.mjs.map} +1 -1
  15. package/dist/{chunk-TUMNNWY6.mjs → chunk-LNSB4L7K.mjs} +8 -8
  16. package/dist/chunk-LNSB4L7K.mjs.map +1 -0
  17. package/dist/{chunk-AXWK4Y23.mjs → chunk-NPH5AHLH.mjs} +19 -25
  18. package/dist/chunk-NPH5AHLH.mjs.map +1 -0
  19. package/dist/{chunk-3DMUUTKC.js → chunk-PSR2V3R4.js} +6 -6
  20. package/dist/{chunk-DDOYG42A.js → chunk-R2S3HIDN.js} +10 -10
  21. package/dist/chunk-R2S3HIDN.js.map +1 -0
  22. package/dist/chunk-SLHAVOTE.js +40 -0
  23. package/dist/chunk-SLHAVOTE.js.map +1 -0
  24. package/dist/{chunk-JFVONPMM.mjs → chunk-VYZPOR47.mjs} +15 -1
  25. package/dist/chunk-VYZPOR47.mjs.map +1 -0
  26. package/dist/{chunk-KUTU3NNS.js → chunk-XSSIP3PJ.js} +15 -1
  27. package/dist/chunk-XSSIP3PJ.js.map +1 -0
  28. package/dist/controllers/authentication/AuthenticationController.js +8 -3
  29. package/dist/controllers/authentication/AuthenticationController.mjs +8 -3
  30. package/dist/controllers/authentication/index.js +8 -3
  31. package/dist/controllers/authentication/index.mjs +8 -3
  32. package/dist/controllers/authentication/services.js +8 -3
  33. package/dist/controllers/authentication/services.mjs +8 -3
  34. package/dist/controllers/index.js +12 -12
  35. package/dist/controllers/index.mjs +11 -11
  36. package/dist/controllers/user-storage/UserStorageController.js +11 -11
  37. package/dist/controllers/user-storage/UserStorageController.mjs +10 -10
  38. package/dist/controllers/user-storage/index.js +15 -15
  39. package/dist/controllers/user-storage/index.mjs +14 -14
  40. package/dist/controllers/user-storage/schema.js +4 -2
  41. package/dist/controllers/user-storage/schema.mjs +7 -5
  42. package/dist/controllers/user-storage/services.js +10 -10
  43. package/dist/controllers/user-storage/services.mjs +9 -9
  44. package/dist/index.js +12 -12
  45. package/dist/index.mjs +11 -11
  46. package/dist/sdk/authentication.js +2 -2
  47. package/dist/sdk/authentication.mjs +1 -1
  48. package/dist/sdk/index.js +9 -4
  49. package/dist/sdk/index.mjs +8 -3
  50. package/dist/sdk/user-storage.js +7 -2
  51. package/dist/sdk/user-storage.mjs +6 -1
  52. package/dist/tsconfig.build.tsbuildinfo +1 -1
  53. package/dist/types/controllers/user-storage/UserStorageController.d.ts +6 -6
  54. package/dist/types/controllers/user-storage/UserStorageController.d.ts.map +1 -1
  55. package/dist/types/controllers/user-storage/schema.d.ts +18 -10
  56. package/dist/types/controllers/user-storage/schema.d.ts.map +1 -1
  57. package/dist/types/controllers/user-storage/services.d.ts +2 -2
  58. package/dist/types/controllers/user-storage/services.d.ts.map +1 -1
  59. package/dist/types/sdk/__fixtures__/mock-userstorage.d.ts.map +1 -1
  60. package/dist/types/sdk/authentication.d.ts +1 -0
  61. package/dist/types/sdk/authentication.d.ts.map +1 -1
  62. package/dist/types/sdk/user-storage.d.ts +4 -3
  63. package/dist/types/sdk/user-storage.d.ts.map +1 -1
  64. package/package.json +11 -10
  65. package/dist/chunk-2XGRQBXI.mjs.map +0 -1
  66. package/dist/chunk-5SXXO4MV.js.map +0 -1
  67. package/dist/chunk-AUFUOKJW.mjs +0 -25
  68. package/dist/chunk-AUFUOKJW.mjs.map +0 -1
  69. package/dist/chunk-AXWK4Y23.mjs.map +0 -1
  70. package/dist/chunk-B6CSNLGE.js +0 -25
  71. package/dist/chunk-B6CSNLGE.js.map +0 -1
  72. package/dist/chunk-DDOYG42A.js.map +0 -1
  73. package/dist/chunk-JFVONPMM.mjs.map +0 -1
  74. package/dist/chunk-KUTU3NNS.js.map +0 -1
  75. package/dist/chunk-P52TG263.js.map +0 -1
  76. package/dist/chunk-TUMNNWY6.mjs.map +0 -1
  77. /package/dist/{chunk-RT2GRG4S.mjs.map → chunk-7KMONAQI.mjs.map} +0 -0
  78. /package/dist/{chunk-3DMUUTKC.js.map → chunk-PSR2V3R4.js.map} +0 -0
@@ -2,7 +2,7 @@ import type { RestrictedControllerMessenger } from '@metamask/base-controller';
2
2
  import { BaseController } from '@metamask/base-controller';
3
3
  import type { HandleSnapRequest } from '@metamask/snaps-controllers';
4
4
  import type { AuthenticationControllerGetBearerToken, AuthenticationControllerGetSessionProfile, AuthenticationControllerIsSignedIn, AuthenticationControllerPerformSignIn, AuthenticationControllerPerformSignOut } from '../authentication/AuthenticationController';
5
- import type { UserStorageEntryKeys } from './schema';
5
+ import type { UserStoragePath } from './schema';
6
6
  export declare type NotificationServicesControllerDisableNotificationServices = {
7
7
  type: `NotificationServicesController:disableNotificationServices`;
8
8
  handler: () => Promise<void>;
@@ -16,7 +16,7 @@ export type UserStorageControllerState = {
16
16
  /**
17
17
  * Condition used by UI and to determine if we can use some of the User Storage methods.
18
18
  */
19
- isProfileSyncingEnabled: boolean;
19
+ isProfileSyncingEnabled: boolean | null;
20
20
  /**
21
21
  * Loading state for the profile syncing update
22
22
  */
@@ -61,19 +61,19 @@ export default class UserStorageController extends BaseController<typeof control
61
61
  * Allows retrieval of stored data. Data stored is string formatted.
62
62
  * Developers can extend the entry path and entry name through the `schema.ts` file.
63
63
  *
64
- * @param entryKey - entry key that matches schema
64
+ * @param path - string in the form of `${feature}.${key}` that matches schema
65
65
  * @returns the decrypted string contents found from user storage (or null if not found)
66
66
  */
67
- performGetStorage(entryKey: UserStorageEntryKeys): Promise<string | null>;
67
+ performGetStorage(path: UserStoragePath): Promise<string | null>;
68
68
  /**
69
69
  * Allows storage of user data. Data stored must be string formatted.
70
70
  * Developers can extend the entry path and entry name through the `schema.ts` file.
71
71
  *
72
- * @param entryKey - entry key that matches schema
72
+ * @param path - string in the form of `${feature}.${key}` that matches schema
73
73
  * @param value - The string data you want to store.
74
74
  * @returns nothing. NOTE that an error is thrown if fails to store data.
75
75
  */
76
- performSetStorage(entryKey: UserStorageEntryKeys, value: string): Promise<void>;
76
+ performSetStorage(path: UserStoragePath, value: string): Promise<void>;
77
77
  /**
78
78
  * Retrieves the storage key, for internal use only!
79
79
  *
@@ -1 +1 @@
1
- {"version":3,"file":"UserStorageController.d.ts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/UserStorageController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UserStorageController.d.ts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/UserStorageController.ts"],"names":[],"mappings":"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"}
@@ -1,22 +1,30 @@
1
1
  /**
2
- * The User Storage Endpoint requires a path and an entry name.
3
- * Developers can provide additional paths by extending this variable below
2
+ * The User Storage Endpoint requires a feature name and a namespace key.
3
+ * Developers can provide additional features and keys by extending these types below.
4
4
  */
5
- export declare const USER_STORAGE_ENTRIES: {
6
- notificationSettings: {
7
- path: string;
8
- entryName: string;
9
- };
5
+ export declare const USER_STORAGE_SCHEMA: {
6
+ readonly notifications: readonly ["notificationSettings"];
10
7
  };
11
- export type UserStorageEntryKeys = keyof typeof USER_STORAGE_ENTRIES;
8
+ type UserStorageSchema = typeof USER_STORAGE_SCHEMA;
9
+ type UserStorageFeatures = keyof UserStorageSchema;
10
+ type UserStorageFeatureKeys<Feature extends UserStorageFeatures> = UserStorageSchema[Feature][number];
11
+ type UserStorageFeatureAndKey = {
12
+ feature: UserStorageFeatures;
13
+ key: UserStorageFeatureKeys<UserStorageFeatures>;
14
+ };
15
+ export type UserStoragePath = {
16
+ [K in keyof UserStorageSchema]: `${K}.${UserStorageSchema[K][number]}`;
17
+ }[keyof UserStorageSchema];
18
+ export declare const getFeatureAndKeyFromPath: (path: UserStoragePath) => UserStorageFeatureAndKey;
12
19
  /**
13
20
  * Constructs a unique entry path for a user.
14
21
  * This can be done due to the uniqueness of the storage key (no users will share the same storage key).
15
22
  * The users entry is a unique hash that cannot be reversed.
16
23
  *
17
- * @param entryKey - storage schema entry key
24
+ * @param path - string in the form of `${feature}.${key}` that matches schema
18
25
  * @param storageKey - users storage key
19
26
  * @returns path to store entry
20
27
  */
21
- export declare function createEntryPath(entryKey: UserStorageEntryKeys, storageKey: string): string;
28
+ export declare function createEntryPath(path: UserStoragePath, storageKey: string): string;
29
+ export {};
22
30
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/schema.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;CAKW,CAAC;AAE7C,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,oBAAoB,CAAC;AAErE;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,oBAAoB,EAC9B,UAAU,EAAE,MAAM,GACjB,MAAM,CAQR"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/schema.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,eAAO,MAAM,mBAAmB;;CAEtB,CAAC;AAEX,KAAK,iBAAiB,GAAG,OAAO,mBAAmB,CAAC;AACpD,KAAK,mBAAmB,GAAG,MAAM,iBAAiB,CAAC;AACnD,KAAK,sBAAsB,CAAC,OAAO,SAAS,mBAAmB,IAC7D,iBAAiB,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAErC,KAAK,wBAAwB,GAAG;IAC9B,OAAO,EAAE,mBAAmB,CAAC;IAC7B,GAAG,EAAE,sBAAsB,CAAC,mBAAmB,CAAC,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;KAC3B,CAAC,IAAI,MAAM,iBAAiB,GAAG,GAAG,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE;CACvE,CAAC,MAAM,iBAAiB,CAAC,CAAC;AAE3B,eAAO,MAAM,wBAAwB,SAC7B,eAAe,KACpB,wBA6BF,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,eAAe,EACrB,UAAU,EAAE,MAAM,GACjB,MAAM,CAKR"}
@@ -1,4 +1,4 @@
1
- import type { UserStorageEntryKeys } from './schema';
1
+ import type { UserStoragePath } from './schema';
2
2
  export declare const USER_STORAGE_API: string;
3
3
  export declare const USER_STORAGE_ENDPOINT: string;
4
4
  /**
@@ -9,8 +9,8 @@ export type GetUserStorageResponse = {
9
9
  Data: string;
10
10
  };
11
11
  export type UserStorageOptions = {
12
+ path: UserStoragePath;
12
13
  bearerToken: string;
13
- entryKey: UserStorageEntryKeys;
14
14
  storageKey: string;
15
15
  };
16
16
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/services.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAKrD,eAAO,MAAM,gBAAgB,EAAE,MAAmC,CAAC;AACnE,eAAO,MAAM,qBAAqB,QAA2C,CAAC;AAE9E;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IAEnC,SAAS,EAAE,MAAM,CAAC;IAElB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuCxB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,IAAI,CAAC,CAiBf"}
1
+ {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../../../src/controllers/user-storage/services.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAKhD,eAAO,MAAM,gBAAgB,EAAE,MAAmC,CAAC;AACnE,eAAO,MAAM,qBAAqB,QAA2C,CAAC;AAE9E;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IAEnC,SAAS,EAAE,MAAM,CAAC;IAElB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyCxB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,IAAI,CAAC,CAmBf"}
@@ -1 +1 @@
1
- {"version":3,"file":"mock-userstorage.d.ts","sourceRoot":"","sources":["../../../../src/sdk/__fixtures__/mock-userstorage.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAMxB,KAAK,SAAS,GAAG;IACf,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC;CAClB,CAAC;AAKF,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAGnD,eAAO,MAAM,uBAAuB;;CAAwB,CAAC;AAC7D,eAAO,MAAM,iCAAiC,QAG7C,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;CAGjC,CAAC;AAEF,eAAO,MAAM,wBAAwB,eAAgB,SAAS,eAQ7D,CAAC;AAEF,eAAO,MAAM,wBAAwB,eAAgB,SAAS,eAQ7D,CAAC"}
1
+ {"version":3,"file":"mock-userstorage.d.ts","sourceRoot":"","sources":["../../../../src/sdk/__fixtures__/mock-userstorage.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAMxB,KAAK,SAAS,GAAG;IACf,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC;CAClB,CAAC;AAQF,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAGnD,eAAO,MAAM,uBAAuB;;CAAwB,CAAC;AAC7D,eAAO,MAAM,iCAAiC,QAG7C,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;CAGjC,CAAC;AAEF,eAAO,MAAM,wBAAwB,eAAgB,SAAS,eAQ7D,CAAC;AAEF,eAAO,MAAM,wBAAwB,eAAgB,SAAS,eAQ7D,CAAC"}
@@ -13,6 +13,7 @@ export declare class JwtBearerAuth implements SIWEInterface, SRPInterface {
13
13
  #private;
14
14
  constructor(...args: JwtBearerAuthParams);
15
15
  getAccessToken(): Promise<string>;
16
+ connectSnap(): Promise<string>;
16
17
  getUserProfile(): Promise<UserProfile>;
17
18
  getIdentifier(): Promise<string>;
18
19
  signMessage(message: string): Promise<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"authentication.d.ts","sourceRoot":"","sources":["../../../src/sdk/authentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAKxE,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,mCAAmC,CAAC;AAQ3E,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,KAAK,CAAC;AACvE,KAAK,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAChD,KAAK,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE9C,KAAK,UAAU,GAAG,qBAAqB,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAClE,KAAK,SAAS,GAAG,qBAAqB,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAChE,KAAK,mBAAmB,GAAG,UAAU,GAAG,SAAS,CAAC;AAElD,qBAAa,aAAc,YAAW,aAAa,EAAE,YAAY;;gBAOnD,GAAG,IAAI,EAAE,mBAAmB;IAiBlC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAIjC,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAItC,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAIhC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI7C,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCrD,OAAO,CAAC,MAAM,EAAE;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,EAAE,MAAM,CAAC;KAChB,GAAG,IAAI;CAiBT;AAED,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACxE,cAAc,mCAAmC,CAAC"}
1
+ {"version":3,"file":"authentication.d.ts","sourceRoot":"","sources":["../../../src/sdk/authentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAKxE,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,mCAAmC,CAAC;AAU3E,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,KAAK,CAAC;AACvE,KAAK,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAChD,KAAK,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE9C,KAAK,UAAU,GAAG,qBAAqB,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAClE,KAAK,SAAS,GAAG,qBAAqB,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAChE,KAAK,mBAAmB,GAAG,UAAU,GAAG,SAAS,CAAC;AAElD,qBAAa,aAAc,YAAW,aAAa,EAAE,YAAY;;gBAOnD,GAAG,IAAI,EAAE,mBAAmB;IAiBlC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAIjC,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAS9B,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAItC,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAIhC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI7C,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCrD,OAAO,CAAC,MAAM,EAAE;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,EAAE,MAAM,CAAC;KAChB,GAAG,IAAI;CAiBT;AAED,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACxE,cAAc,mCAAmC,CAAC"}
@@ -1,6 +1,7 @@
1
+ import type { UserStoragePath } from '../controllers/user-storage/schema';
1
2
  import type { IBaseAuth } from './authentication-jwt-bearer/types';
2
3
  import type { Env } from './env';
3
- export declare const STORAGE_URL: (env: Env, feature: string, entry: string) => string;
4
+ export declare const STORAGE_URL: (env: Env, encryptedPath: string) => string;
4
5
  export type UserStorageConfig = {
5
6
  env: Env;
6
7
  auth: Pick<IBaseAuth, 'getAccessToken' | 'getUserProfile' | 'signMessage'>;
@@ -18,8 +19,8 @@ export declare class UserStorage {
18
19
  protected options: UserStorageOptions;
19
20
  protected env: Env;
20
21
  constructor(config: UserStorageConfig, options: UserStorageOptions);
21
- setItem(feature: string, key: string, value: string): Promise<void>;
22
- getItem(feature: string, key: string): Promise<string>;
22
+ setItem(path: UserStoragePath, value: string): Promise<void>;
23
+ getItem(path: UserStoragePath): Promise<string>;
23
24
  getStorageKey(): Promise<string>;
24
25
  }
25
26
  //# sourceMappingURL=user-storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"user-storage.d.ts","sourceRoot":"","sources":["../../../src/sdk/user-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAEnE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAIjC,eAAO,MAAM,WAAW,QAAS,GAAG,WAAW,MAAM,SAAS,MAAM,WACW,CAAC;AAEhF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,aAAa,CAAC,CAAC;CAC5E,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5C,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAOF,qBAAa,WAAW;;IACtB,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAEpC,SAAS,CAAC,OAAO,EAAE,kBAAkB,CAAC;IAEtC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;gBAEP,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,kBAAkB;IAM5D,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOtD,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;CAgHvC"}
1
+ {"version":3,"file":"user-storage.d.ts","sourceRoot":"","sources":["../../../src/sdk/user-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAEnE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAIjC,eAAO,MAAM,WAAW,QAAS,GAAG,iBAAiB,MAAM,WACiB,CAAC;AAE7E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,aAAa,CAAC,CAAC;CAC5E,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5C,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAOF,qBAAa,WAAW;;IACtB,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAEpC,SAAS,CAAC,OAAO,EAAE,kBAAkB,CAAC;IAEtC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;gBAEP,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,kBAAkB;IAM5D,OAAO,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5D,OAAO,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAI/C,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;CA4GvC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/profile-sync-controller",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "The profile sync helps developers synchronize data across multiple clients and devices in a privacy-preserving way. All data saved in the user storage database is encrypted client-side to preserve privacy. The user storage provides a modular design, giving developers the flexibility to construct and manage their storage spaces in a way that best suits their needs",
5
5
  "keywords": [
6
6
  "MetaMask",
@@ -35,15 +35,15 @@
35
35
  "changelog:update": "../../scripts/update-changelog.sh @metamask/profile-sync-controller",
36
36
  "changelog:validate": "../../scripts/validate-changelog.sh @metamask/profile-sync-controller",
37
37
  "publish:preview": "yarn npm publish --tag preview",
38
- "test": "jest --reporters=jest-silent-reporter",
39
- "test:clean": "jest --clearCache",
40
- "test:verbose": "jest --verbose",
41
- "test:watch": "jest --watch"
38
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest --reporters=jest-silent-reporter",
39
+ "test:clean": "NODE_OPTIONS=--experimental-vm-modules jest --clearCache",
40
+ "test:verbose": "NODE_OPTIONS=--experimental-vm-modules jest --verbose",
41
+ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
42
42
  },
43
43
  "dependencies": {
44
- "@metamask/base-controller": "^6.0.1",
45
- "@metamask/snaps-controllers": "^8.1.1",
46
- "@metamask/snaps-sdk": "^4.2.0",
44
+ "@metamask/base-controller": "^6.0.2",
45
+ "@metamask/snaps-sdk": "^6.1.1",
46
+ "@metamask/snaps-utils": "^7.8.1",
47
47
  "@noble/ciphers": "^0.5.2",
48
48
  "@noble/hashes": "^1.4.0",
49
49
  "immer": "^9.0.6",
@@ -53,6 +53,7 @@
53
53
  "devDependencies": {
54
54
  "@lavamoat/allow-scripts": "^3.0.4",
55
55
  "@metamask/auto-changelog": "^3.4.4",
56
+ "@metamask/snaps-controllers": "^9.3.1",
56
57
  "@types/jest": "^27.4.1",
57
58
  "deepmerge": "^4.2.2",
58
59
  "ethers": "^6.12.0",
@@ -62,10 +63,10 @@
62
63
  "ts-jest": "^27.1.4",
63
64
  "typedoc": "^0.24.8",
64
65
  "typedoc-plugin-missing-exports": "^2.0.0",
65
- "typescript": "~4.9.5"
66
+ "typescript": "~5.0.4"
66
67
  },
67
68
  "peerDependencies": {
68
- "@metamask/snaps-controllers": "^8.1.1"
69
+ "@metamask/snaps-controllers": "^9.3.0"
69
70
  },
70
71
  "engines": {
71
72
  "node": "^18.18 || >=20"
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/controllers/user-storage/services.ts"],"sourcesContent":["import log from 'loglevel';\n\nimport { Env, getEnvUrls } from '../../sdk';\nimport encryption from './encryption';\nimport type { UserStorageEntryKeys } from './schema';\nimport { createEntryPath } from './schema';\n\nconst ENV_URLS = getEnvUrls(Env.PRD);\n\nexport const USER_STORAGE_API: string = ENV_URLS.userStorageApiUrl;\nexport const USER_STORAGE_ENDPOINT = `${USER_STORAGE_API}/api/v1/userstorage`;\n\n/**\n * This is the Server Response shape\n */\nexport type GetUserStorageResponse = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n HashedKey: string;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Data: string;\n};\n\nexport type UserStorageOptions = {\n bearerToken: string;\n entryKey: UserStorageEntryKeys;\n storageKey: string;\n};\n\n/**\n * User Storage Service - Get Storage Entry.\n *\n * @param opts - User Storage Options\n * @returns The storage entry, or null if fails to find entry\n */\nexport async function getUserStorage(\n opts: UserStorageOptions,\n): Promise<string | null> {\n try {\n const path = createEntryPath(opts.entryKey, opts.storageKey);\n const url = new URL(`${USER_STORAGE_ENDPOINT}${path}`);\n\n const userStorageResponse = await fetch(url.toString(), {\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${opts.bearerToken}`,\n },\n });\n\n // Acceptable error - since indicates entry does not exist.\n if (userStorageResponse.status === 404) {\n return null;\n }\n\n if (userStorageResponse.status !== 200) {\n throw new Error('Unable to get User Storage');\n }\n\n const userStorage: GetUserStorageResponse | null =\n await userStorageResponse.json();\n const encryptedData = userStorage?.Data ?? null;\n\n if (!encryptedData) {\n return null;\n }\n\n const decryptedData = encryption.decryptString(\n encryptedData,\n opts.storageKey,\n );\n\n return decryptedData;\n } catch (e) {\n log.error('Failed to get user storage', e);\n return null;\n }\n}\n\n/**\n * User Storage Service - Set Storage Entry.\n *\n * @param data - data to store\n * @param opts - storage options\n */\nexport async function upsertUserStorage(\n data: string,\n opts: UserStorageOptions,\n): Promise<void> {\n const encryptedData = encryption.encryptString(data, opts.storageKey);\n const path = createEntryPath(opts.entryKey, opts.storageKey);\n const url = new URL(`${USER_STORAGE_ENDPOINT}${path}`);\n\n const res = await fetch(url.toString(), {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${opts.bearerToken}`,\n },\n body: JSON.stringify({ data: encryptedData }),\n });\n\n if (!res.ok) {\n throw new Error('user-storage - unable to upsert data');\n }\n}\n"],"mappings":";;;;;;;;;;;AAAA,OAAO,SAAS;AAOhB,IAAM,WAAW,0BAAkB;AAE5B,IAAM,mBAA2B,SAAS;AAC1C,IAAM,wBAAwB,GAAG,gBAAgB;AAwBxD,eAAsB,eACpB,MACwB;AACxB,MAAI;AACF,UAAM,OAAO,gBAAgB,KAAK,UAAU,KAAK,UAAU;AAC3D,UAAM,MAAM,IAAI,IAAI,GAAG,qBAAqB,GAAG,IAAI,EAAE;AAErD,UAAM,sBAAsB,MAAM,MAAM,IAAI,SAAS,GAAG;AAAA,MACtD,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,KAAK,WAAW;AAAA,MAC3C;AAAA,IACF,CAAC;AAGD,QAAI,oBAAoB,WAAW,KAAK;AACtC,aAAO;AAAA,IACT;AAEA,QAAI,oBAAoB,WAAW,KAAK;AACtC,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AAEA,UAAM,cACJ,MAAM,oBAAoB,KAAK;AACjC,UAAM,gBAAgB,aAAa,QAAQ;AAE3C,QAAI,CAAC,eAAe;AAClB,aAAO;AAAA,IACT;AAEA,UAAM,gBAAgB,mBAAW;AAAA,MAC/B;AAAA,MACA,KAAK;AAAA,IACP;AAEA,WAAO;AAAA,EACT,SAAS,GAAG;AACV,QAAI,MAAM,8BAA8B,CAAC;AACzC,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,kBACpB,MACA,MACe;AACf,QAAM,gBAAgB,mBAAW,cAAc,MAAM,KAAK,UAAU;AACpE,QAAM,OAAO,gBAAgB,KAAK,UAAU,KAAK,UAAU;AAC3D,QAAM,MAAM,IAAI,IAAI,GAAG,qBAAqB,GAAG,IAAI,EAAE;AAErD,QAAM,MAAM,MAAM,MAAM,IAAI,SAAS,GAAG;AAAA,IACtC,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,eAAe,UAAU,KAAK,WAAW;AAAA,IAC3C;AAAA,IACA,MAAM,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAAA,EAC9C,CAAC;AAED,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/controllers/user-storage/services.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,SAAS;AAOhB,IAAM,WAAW,0BAAkB;AAE5B,IAAM,mBAA2B,SAAS;AAC1C,IAAM,wBAAwB,GAAG,gBAAgB;AAwBxD,eAAsB,eACpB,MACwB;AACxB,MAAI;AACF,UAAM,OAAO,gBAAgB,KAAK,UAAU,KAAK,UAAU;AAC3D,UAAM,MAAM,IAAI,IAAI,GAAG,qBAAqB,GAAG,IAAI,EAAE;AAErD,UAAM,sBAAsB,MAAM,MAAM,IAAI,SAAS,GAAG;AAAA,MACtD,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,KAAK,WAAW;AAAA,MAC3C;AAAA,IACF,CAAC;AAGD,QAAI,oBAAoB,WAAW,KAAK;AACtC,aAAO;AAAA,IACT;AAEA,QAAI,oBAAoB,WAAW,KAAK;AACtC,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AAEA,UAAM,cACJ,MAAM,oBAAoB,KAAK;AACjC,UAAM,gBAAgB,aAAa,QAAQ;AAE3C,QAAI,CAAC,eAAe;AAClB,aAAO;AAAA,IACT;AAEA,UAAM,gBAAgB,mBAAW;AAAA,MAC/B;AAAA,MACA,KAAK;AAAA,IACP;AAEA,WAAO;AAAA,EACT,SAAS,GAAG;AACV,QAAI,MAAM,8BAA8B,CAAC;AACzC,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,kBACpB,MACA,MACe;AACf,QAAM,gBAAgB,mBAAW,cAAc,MAAM,KAAK,UAAU;AACpE,QAAM,OAAO,gBAAgB,KAAK,UAAU,KAAK,UAAU;AAC3D,QAAM,MAAM,IAAI,IAAI,GAAG,qBAAqB,GAAG,IAAI,EAAE;AAErD,QAAM,MAAM,MAAM,MAAM,IAAI,SAAS,GAAG;AAAA,IACtC,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,eAAe,UAAU,KAAK,WAAW;AAAA,IAC3C;AAAA,IACA,MAAM,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAAA,EAC9C,CAAC;AAED,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AACF","sourcesContent":["import log from 'loglevel';\n\nimport { Env, getEnvUrls } from '../../sdk';\nimport encryption from './encryption';\nimport type { UserStorageEntryKeys } from './schema';\nimport { createEntryPath } from './schema';\n\nconst ENV_URLS = getEnvUrls(Env.PRD);\n\nexport const USER_STORAGE_API: string = ENV_URLS.userStorageApiUrl;\nexport const USER_STORAGE_ENDPOINT = `${USER_STORAGE_API}/api/v1/userstorage`;\n\n/**\n * This is the Server Response shape\n */\nexport type GetUserStorageResponse = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n HashedKey: string;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Data: string;\n};\n\nexport type UserStorageOptions = {\n bearerToken: string;\n entryKey: UserStorageEntryKeys;\n storageKey: string;\n};\n\n/**\n * User Storage Service - Get Storage Entry.\n *\n * @param opts - User Storage Options\n * @returns The storage entry, or null if fails to find entry\n */\nexport async function getUserStorage(\n opts: UserStorageOptions,\n): Promise<string | null> {\n try {\n const path = createEntryPath(opts.entryKey, opts.storageKey);\n const url = new URL(`${USER_STORAGE_ENDPOINT}${path}`);\n\n const userStorageResponse = await fetch(url.toString(), {\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${opts.bearerToken}`,\n },\n });\n\n // Acceptable error - since indicates entry does not exist.\n if (userStorageResponse.status === 404) {\n return null;\n }\n\n if (userStorageResponse.status !== 200) {\n throw new Error('Unable to get User Storage');\n }\n\n const userStorage: GetUserStorageResponse | null =\n await userStorageResponse.json();\n const encryptedData = userStorage?.Data ?? null;\n\n if (!encryptedData) {\n return null;\n }\n\n const decryptedData = encryption.decryptString(\n encryptedData,\n opts.storageKey,\n );\n\n return decryptedData;\n } catch (e) {\n log.error('Failed to get user storage', e);\n return null;\n }\n}\n\n/**\n * User Storage Service - Set Storage Entry.\n *\n * @param data - data to store\n * @param opts - storage options\n */\nexport async function upsertUserStorage(\n data: string,\n opts: UserStorageOptions,\n): Promise<void> {\n const encryptedData = encryption.encryptString(data, opts.storageKey);\n const path = createEntryPath(opts.entryKey, opts.storageKey);\n const url = new URL(`${USER_STORAGE_ENDPOINT}${path}`);\n\n const res = await fetch(url.toString(), {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${opts.bearerToken}`,\n },\n body: JSON.stringify({ data: encryptedData }),\n });\n\n if (!res.ok) {\n throw new Error('user-storage - unable to upsert data');\n }\n}\n"]}
@@ -1,25 +0,0 @@
1
- import {
2
- createSHA256Hash
3
- } from "./chunk-K5UKU454.mjs";
4
-
5
- // src/controllers/user-storage/schema.ts
6
- var USER_STORAGE_ENTRIES = {
7
- notificationSettings: {
8
- path: "notifications",
9
- entryName: "notificationSettings"
10
- }
11
- };
12
- function createEntryPath(entryKey, storageKey) {
13
- const entry = USER_STORAGE_ENTRIES[entryKey];
14
- if (!entry) {
15
- throw new Error(`user-storage - invalid entry provided: ${entryKey}`);
16
- }
17
- const hashedKey = createSHA256Hash(entry.entryName + storageKey);
18
- return `/${entry.path}/${hashedKey}`;
19
- }
20
-
21
- export {
22
- USER_STORAGE_ENTRIES,
23
- createEntryPath
24
- };
25
- //# sourceMappingURL=chunk-AUFUOKJW.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/controllers/user-storage/schema.ts"],"sourcesContent":["import { createSHA256Hash } from './encryption';\n\ntype UserStorageEntry = { path: string; entryName: string };\n\n/**\n * The User Storage Endpoint requires a path and an entry name.\n * Developers can provide additional paths by extending this variable below\n */\nexport const USER_STORAGE_ENTRIES = {\n notificationSettings: {\n path: 'notifications',\n entryName: 'notificationSettings',\n },\n} satisfies Record<string, UserStorageEntry>;\n\nexport type UserStorageEntryKeys = keyof typeof USER_STORAGE_ENTRIES;\n\n/**\n * Constructs a unique entry path for a user.\n * This can be done due to the uniqueness of the storage key (no users will share the same storage key).\n * The users entry is a unique hash that cannot be reversed.\n *\n * @param entryKey - storage schema entry key\n * @param storageKey - users storage key\n * @returns path to store entry\n */\nexport function createEntryPath(\n entryKey: UserStorageEntryKeys,\n storageKey: string,\n): string {\n const entry = USER_STORAGE_ENTRIES[entryKey];\n if (!entry) {\n throw new Error(`user-storage - invalid entry provided: ${entryKey}`);\n }\n\n const hashedKey = createSHA256Hash(entry.entryName + storageKey);\n return `/${entry.path}/${hashedKey}`;\n}\n"],"mappings":";;;;;AAQO,IAAM,uBAAuB;AAAA,EAClC,sBAAsB;AAAA,IACpB,MAAM;AAAA,IACN,WAAW;AAAA,EACb;AACF;AAaO,SAAS,gBACd,UACA,YACQ;AACR,QAAM,QAAQ,qBAAqB,QAAQ;AAC3C,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,0CAA0C,QAAQ,EAAE;AAAA,EACtE;AAEA,QAAM,YAAY,iBAAiB,MAAM,YAAY,UAAU;AAC/D,SAAO,IAAI,MAAM,IAAI,IAAI,SAAS;AACpC;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/sdk/user-storage.ts"],"sourcesContent":["import type { IBaseAuth } from './authentication-jwt-bearer/types';\nimport encryption, { createSHA256Hash } from './encryption';\nimport type { Env } from './env';\nimport { getEnvUrls } from './env';\nimport { NotFoundError, UserStorageError, ValidationError } from './errors';\n\nexport const STORAGE_URL = (env: Env, feature: string, entry: string) =>\n `${getEnvUrls(env).userStorageApiUrl}/api/v1/userstorage/${feature}/${entry}`;\n\nexport type UserStorageConfig = {\n env: Env;\n auth: Pick<IBaseAuth, 'getAccessToken' | 'getUserProfile' | 'signMessage'>;\n};\n\nexport type StorageOptions = {\n getStorageKey: () => Promise<string | null>;\n setStorageKey: (val: string) => Promise<void>;\n};\n\nexport type UserStorageOptions = {\n storage?: StorageOptions;\n};\n\ntype ErrorMessage = {\n message: string;\n error: string;\n};\n\nexport class UserStorage {\n protected config: UserStorageConfig;\n\n protected options: UserStorageOptions;\n\n protected env: Env;\n\n constructor(config: UserStorageConfig, options: UserStorageOptions) {\n this.env = config.env;\n this.config = config;\n this.options = options;\n }\n\n async setItem(feature: string, key: string, value: string): Promise<void> {\n if (!feature.trim() || !key.trim()) {\n throw new ValidationError('feature or key cannot be empty strings');\n }\n await this.#upsertUserStorage(feature, key, value);\n }\n\n async getItem(feature: string, key: string): Promise<string> {\n if (!feature.trim() || !key.trim()) {\n throw new ValidationError('feature or key cannot be empty strings');\n }\n return this.#getUserStorage(feature, key);\n }\n\n async getStorageKey(): Promise<string> {\n const storageKey = await this.options.storage?.getStorageKey();\n if (storageKey) {\n return storageKey;\n }\n\n const userProfile = await this.config.auth.getUserProfile();\n const storageKeySignature = await this.config.auth.signMessage(\n `metamask:${userProfile.profileId}`,\n );\n const hashedStorageKeySignature = createSHA256Hash(storageKeySignature);\n await this.options.storage?.setStorageKey(hashedStorageKeySignature);\n return hashedStorageKeySignature;\n }\n\n async #upsertUserStorage(\n feature: string,\n key: string,\n data: string,\n ): Promise<void> {\n try {\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n const encryptedData = encryption.encryptString(data, storageKey);\n const url = new URL(\n STORAGE_URL(this.env, feature, this.#createEntryKey(key, storageKey)),\n );\n\n const response = await fetch(url.toString(), {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({ data: encryptedData }),\n });\n\n if (!response.ok) {\n const responseBody: ErrorMessage = await response.json().catch(() => ({\n message: 'unknown',\n error: 'unknown',\n }));\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n } catch (e) {\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n throw new UserStorageError(\n `failed to upsert user storage for feature '${feature}' and key '${key}'. ${errorMessage}`,\n );\n }\n }\n\n async #getUserStorage(feature: string, key: string): Promise<string> {\n try {\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n const url = new URL(\n STORAGE_URL(this.env, feature, this.#createEntryKey(key, storageKey)),\n );\n\n const response = await fetch(url.toString(), {\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n });\n\n if (response.status === 404) {\n throw new NotFoundError(\n `feature/key set not found for feature '${feature}' and key '${key}'.`,\n );\n }\n\n if (!response.ok) {\n const responseBody = (await response.json()) as ErrorMessage;\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n\n const { Data: encryptedData } = await response.json();\n return encryption.decryptString(encryptedData, storageKey);\n } catch (e) {\n if (e instanceof NotFoundError) {\n throw e;\n }\n\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n\n throw new UserStorageError(\n `failed to get user storage for feature '${feature}' and key '${key}'. ${errorMessage}`,\n );\n }\n }\n\n #createEntryKey(key: string, storageKey: string): string {\n const hashedKey = createSHA256Hash(key + storageKey);\n return hashedKey;\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n async #getAuthorizationHeader(): Promise<{ Authorization: string }> {\n const accessToken = await this.config.auth.getAccessToken();\n return { Authorization: `Bearer ${accessToken}` };\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,25 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
-
3
- var _chunkT3FNDVE3js = require('./chunk-T3FNDVE3.js');
4
-
5
- // src/controllers/user-storage/schema.ts
6
- var USER_STORAGE_ENTRIES = {
7
- notificationSettings: {
8
- path: "notifications",
9
- entryName: "notificationSettings"
10
- }
11
- };
12
- function createEntryPath(entryKey, storageKey) {
13
- const entry = USER_STORAGE_ENTRIES[entryKey];
14
- if (!entry) {
15
- throw new Error(`user-storage - invalid entry provided: ${entryKey}`);
16
- }
17
- const hashedKey = _chunkT3FNDVE3js.createSHA256Hash.call(void 0, entry.entryName + storageKey);
18
- return `/${entry.path}/${hashedKey}`;
19
- }
20
-
21
-
22
-
23
-
24
- exports.USER_STORAGE_ENTRIES = USER_STORAGE_ENTRIES; exports.createEntryPath = createEntryPath;
25
- //# sourceMappingURL=chunk-B6CSNLGE.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/controllers/user-storage/schema.ts"],"names":[],"mappings":";;;;;AAQO,IAAM,uBAAuB;AAAA,EAClC,sBAAsB;AAAA,IACpB,MAAM;AAAA,IACN,WAAW;AAAA,EACb;AACF;AAaO,SAAS,gBACd,UACA,YACQ;AACR,QAAM,QAAQ,qBAAqB,QAAQ;AAC3C,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,0CAA0C,QAAQ,EAAE;AAAA,EACtE;AAEA,QAAM,YAAY,iBAAiB,MAAM,YAAY,UAAU;AAC/D,SAAO,IAAI,MAAM,IAAI,IAAI,SAAS;AACpC","sourcesContent":["import { createSHA256Hash } from './encryption';\n\ntype UserStorageEntry = { path: string; entryName: string };\n\n/**\n * The User Storage Endpoint requires a path and an entry name.\n * Developers can provide additional paths by extending this variable below\n */\nexport const USER_STORAGE_ENTRIES = {\n notificationSettings: {\n path: 'notifications',\n entryName: 'notificationSettings',\n },\n} satisfies Record<string, UserStorageEntry>;\n\nexport type UserStorageEntryKeys = keyof typeof USER_STORAGE_ENTRIES;\n\n/**\n * Constructs a unique entry path for a user.\n * This can be done due to the uniqueness of the storage key (no users will share the same storage key).\n * The users entry is a unique hash that cannot be reversed.\n *\n * @param entryKey - storage schema entry key\n * @param storageKey - users storage key\n * @returns path to store entry\n */\nexport function createEntryPath(\n entryKey: UserStorageEntryKeys,\n storageKey: string,\n): string {\n const entry = USER_STORAGE_ENTRIES[entryKey];\n if (!entry) {\n throw new Error(`user-storage - invalid entry provided: ${entryKey}`);\n }\n\n const hashedKey = createSHA256Hash(entry.entryName + storageKey);\n return `/${entry.path}/${hashedKey}`;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/controllers/user-storage/UserStorageController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n RestrictedControllerMessenger,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\n\nimport { createSnapSignMessageRequest } from '../authentication/auth-snap-requests';\nimport type {\n AuthenticationControllerGetBearerToken,\n AuthenticationControllerGetSessionProfile,\n AuthenticationControllerIsSignedIn,\n AuthenticationControllerPerformSignIn,\n AuthenticationControllerPerformSignOut,\n} from '../authentication/AuthenticationController';\nimport { createSHA256Hash } from './encryption';\nimport type { UserStorageEntryKeys } from './schema';\nimport { getUserStorage, upsertUserStorage } from './services';\n\n// TODO: fix external dependencies\nexport declare type NotificationServicesControllerDisableNotificationServices =\n {\n type: `NotificationServicesController:disableNotificationServices`;\n handler: () => Promise<void>;\n };\n\nexport declare type NotificationServicesControllerSelectIsNotificationServicesEnabled =\n {\n type: `NotificationServicesController:selectIsNotificationServicesEnabled`;\n handler: () => boolean;\n };\n\nconst controllerName = 'UserStorageController';\n\n// State\nexport type UserStorageControllerState = {\n /**\n * Condition used by UI and to determine if we can use some of the User Storage methods.\n */\n isProfileSyncingEnabled: boolean;\n /**\n * Loading state for the profile syncing update\n */\n isProfileSyncingUpdateLoading: boolean;\n};\n\nexport const defaultState: UserStorageControllerState = {\n isProfileSyncingEnabled: true,\n isProfileSyncingUpdateLoading: false,\n};\n\nconst metadata: StateMetadata<UserStorageControllerState> = {\n isProfileSyncingEnabled: {\n persist: true,\n anonymous: true,\n },\n isProfileSyncingUpdateLoading: {\n persist: false,\n anonymous: false,\n },\n};\n\n// Messenger Actions\ntype CreateActionsObj<Controller extends keyof UserStorageController> = {\n [K in Controller]: {\n type: `${typeof controllerName}:${K}`;\n handler: UserStorageController[K];\n };\n};\ntype ActionsObj = CreateActionsObj<\n | 'performGetStorage'\n | 'performSetStorage'\n | 'getStorageKey'\n | 'enableProfileSyncing'\n | 'disableProfileSyncing'\n>;\nexport type Actions = ActionsObj[keyof ActionsObj];\nexport type UserStorageControllerPerformGetStorage =\n ActionsObj['performGetStorage'];\nexport type UserStorageControllerPerformSetStorage =\n ActionsObj['performSetStorage'];\nexport type UserStorageControllerGetStorageKey = ActionsObj['getStorageKey'];\nexport type UserStorageControllerEnableProfileSyncing =\n ActionsObj['enableProfileSyncing'];\nexport type UserStorageControllerDisableProfileSyncing =\n ActionsObj['disableProfileSyncing'];\n\n// Allowed Actions\nexport type AllowedActions =\n // Snap Requests\n | HandleSnapRequest\n // Auth Requests\n | AuthenticationControllerGetBearerToken\n | AuthenticationControllerGetSessionProfile\n | AuthenticationControllerPerformSignIn\n | AuthenticationControllerIsSignedIn\n | AuthenticationControllerPerformSignOut\n // Metamask Notifications\n | NotificationServicesControllerDisableNotificationServices\n | NotificationServicesControllerSelectIsNotificationServicesEnabled;\n\n// Messenger\nexport type UserStorageControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n Actions | AllowedActions,\n never,\n AllowedActions['type'],\n never\n>;\n\n/**\n * Reusable controller that allows any team to store synchronized data for a given user.\n * These can be settings shared cross MetaMask clients, or data we want to persist when uninstalling/reinstalling.\n *\n * NOTE:\n * - data stored on UserStorage is FULLY encrypted, with the only keys stored/managed on the client.\n * - No one can access this data unless they are have the SRP and are able to run the signing snap.\n */\nexport default class UserStorageController extends BaseController<\n typeof controllerName,\n UserStorageControllerState,\n UserStorageControllerMessenger\n> {\n #auth = {\n getBearerToken: async () => {\n return await this.messagingSystem.call(\n 'AuthenticationController:getBearerToken',\n );\n },\n getProfileId: async () => {\n const sessionProfile = await this.messagingSystem.call(\n 'AuthenticationController:getSessionProfile',\n );\n return sessionProfile?.profileId;\n },\n isAuthEnabled: () => {\n return this.messagingSystem.call('AuthenticationController:isSignedIn');\n },\n signIn: async () => {\n return await this.messagingSystem.call(\n 'AuthenticationController:performSignIn',\n );\n },\n signOut: async () => {\n return this.messagingSystem.call(\n 'AuthenticationController:performSignOut',\n );\n },\n };\n\n #notificationServices = {\n disableNotificationServices: async () => {\n return await this.messagingSystem.call(\n 'NotificationServicesController:disableNotificationServices',\n );\n },\n selectIsNotificationServicesEnabled: async () => {\n return this.messagingSystem.call(\n 'NotificationServicesController:selectIsNotificationServicesEnabled',\n );\n },\n };\n\n getMetaMetricsState: () => boolean;\n\n constructor(params: {\n messenger: UserStorageControllerMessenger;\n state?: UserStorageControllerState;\n getMetaMetricsState: () => boolean;\n }) {\n super({\n messenger: params.messenger,\n metadata,\n name: controllerName,\n state: { ...defaultState, ...params.state },\n });\n\n this.getMetaMetricsState = params.getMetaMetricsState;\n this.#registerMessageHandlers();\n }\n\n /**\n * Constructor helper for registering this controller's messaging system\n * actions.\n */\n #registerMessageHandlers(): void {\n this.messagingSystem.registerActionHandler(\n 'UserStorageController:performGetStorage',\n this.performGetStorage.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n 'UserStorageController:performSetStorage',\n this.performSetStorage.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n 'UserStorageController:getStorageKey',\n this.getStorageKey.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n 'UserStorageController:enableProfileSyncing',\n this.enableProfileSyncing.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n 'UserStorageController:disableProfileSyncing',\n this.disableProfileSyncing.bind(this),\n );\n }\n\n public async enableProfileSyncing(): Promise<void> {\n try {\n this.#setIsProfileSyncingUpdateLoading(true);\n\n const authEnabled = this.#auth.isAuthEnabled();\n if (!authEnabled) {\n await this.#auth.signIn();\n }\n\n this.update((state) => {\n state.isProfileSyncingEnabled = true;\n });\n\n this.#setIsProfileSyncingUpdateLoading(false);\n } catch (e) {\n this.#setIsProfileSyncingUpdateLoading(false);\n const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);\n throw new Error(\n `${controllerName} - failed to enable profile syncing - ${errorMessage}`,\n );\n }\n }\n\n public async setIsProfileSyncingEnabled(\n isProfileSyncingEnabled: boolean,\n ): Promise<void> {\n this.update((state) => {\n state.isProfileSyncingEnabled = isProfileSyncingEnabled;\n });\n }\n\n public async disableProfileSyncing(): Promise<void> {\n const isAlreadyDisabled = !this.state.isProfileSyncingEnabled;\n if (isAlreadyDisabled) {\n return;\n }\n\n try {\n this.#setIsProfileSyncingUpdateLoading(true);\n\n const isNotificationServicesEnabled =\n await this.#notificationServices.selectIsNotificationServicesEnabled();\n\n if (isNotificationServicesEnabled) {\n await this.#notificationServices.disableNotificationServices();\n }\n\n const isMetaMetricsParticipation = this.getMetaMetricsState();\n\n if (!isMetaMetricsParticipation) {\n this.messagingSystem.call('AuthenticationController:performSignOut');\n }\n\n this.#setIsProfileSyncingUpdateLoading(false);\n\n this.update((state) => {\n state.isProfileSyncingEnabled = false;\n });\n } catch (e) {\n this.#setIsProfileSyncingUpdateLoading(false);\n const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);\n throw new Error(\n `${controllerName} - failed to disable profile syncing - ${errorMessage}`,\n );\n }\n }\n\n /**\n * Allows retrieval of stored data. Data stored is string formatted.\n * Developers can extend the entry path and entry name through the `schema.ts` file.\n *\n * @param entryKey - entry key that matches schema\n * @returns the decrypted string contents found from user storage (or null if not found)\n */\n public async performGetStorage(\n entryKey: UserStorageEntryKeys,\n ): Promise<string | null> {\n this.#assertProfileSyncingEnabled();\n const { bearerToken, storageKey } =\n await this.#getStorageKeyAndBearerToken();\n const result = await getUserStorage({\n entryKey,\n bearerToken,\n storageKey,\n });\n\n return result;\n }\n\n /**\n * Allows storage of user data. Data stored must be string formatted.\n * Developers can extend the entry path and entry name through the `schema.ts` file.\n *\n * @param entryKey - entry key that matches schema\n * @param value - The string data you want to store.\n * @returns nothing. NOTE that an error is thrown if fails to store data.\n */\n public async performSetStorage(\n entryKey: UserStorageEntryKeys,\n value: string,\n ): Promise<void> {\n this.#assertProfileSyncingEnabled();\n const { bearerToken, storageKey } =\n await this.#getStorageKeyAndBearerToken();\n\n await upsertUserStorage(value, {\n entryKey,\n bearerToken,\n storageKey,\n });\n }\n\n /**\n * Retrieves the storage key, for internal use only!\n *\n * @returns the storage key\n */\n public async getStorageKey(): Promise<string> {\n this.#assertProfileSyncingEnabled();\n const storageKey = await this.#createStorageKey();\n return storageKey;\n }\n\n #assertProfileSyncingEnabled(): void {\n if (!this.state.isProfileSyncingEnabled) {\n throw new Error(\n `${controllerName}: Unable to call method, user is not authenticated`,\n );\n }\n }\n\n /**\n * Utility to get the bearer token and storage key\n */\n async #getStorageKeyAndBearerToken(): Promise<{\n bearerToken: string;\n storageKey: string;\n }> {\n const bearerToken = await this.#auth.getBearerToken();\n if (!bearerToken) {\n throw new Error('UserStorageController - unable to get bearer token');\n }\n const storageKey = await this.#createStorageKey();\n\n return { bearerToken, storageKey };\n }\n\n /**\n * Rather than storing the storage key, we can compute the storage key when needed.\n *\n * @returns the storage key\n */\n async #createStorageKey(): Promise<string> {\n const id: string = await this.#auth.getProfileId();\n if (!id) {\n throw new Error('UserStorageController - unable to create storage key');\n }\n\n const storageKeySignature = await this.#snapSignMessage(`metamask:${id}`);\n const storageKey = createSHA256Hash(storageKeySignature);\n return storageKey;\n }\n\n #_snapSignMessageCache: Record<`metamask:${string}`, string> = {};\n\n /**\n * Signs a specific message using an underlying auth snap.\n *\n * @param message - A specific tagged message to sign.\n * @returns A Signature created by the snap.\n */\n async #snapSignMessage(message: `metamask:${string}`): Promise<string> {\n if (this.#_snapSignMessageCache[message]) {\n return this.#_snapSignMessageCache[message];\n }\n\n const result = (await this.messagingSystem.call(\n 'SnapController:handleRequest',\n createSnapSignMessageRequest(message),\n )) as string;\n\n this.#_snapSignMessageCache[message] = result;\n\n return result;\n }\n\n #setIsProfileSyncingUpdateLoading(\n isProfileSyncingUpdateLoading: boolean,\n ): void {\n this.update((state) => {\n state.isProfileSyncingUpdateLoading = isProfileSyncingUpdateLoading;\n });\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/sdk/authentication.ts"],"sourcesContent":["import { SIWEJwtBearerAuth } from './authentication-jwt-bearer/flow-siwe';\nimport { SRPJwtBearerAuth } from './authentication-jwt-bearer/flow-srp';\nimport {\n getNonce,\n pairIdentifiers,\n} from './authentication-jwt-bearer/services';\nimport type { UserProfile, Pair } from './authentication-jwt-bearer/types';\nimport { AuthType } from './authentication-jwt-bearer/types';\nimport type { Env } from './env';\nimport { PairError, UnsupportedAuthTypeError } from './errors';\n\n// Computing the Classes, so we only get back the public methods for the interface.\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\ntype Compute<T> = T extends infer U ? { [K in keyof U]: U[K] } : never;\ntype SIWEInterface = Compute<SIWEJwtBearerAuth>;\ntype SRPInterface = Compute<SRPJwtBearerAuth>;\n\ntype SiweParams = ConstructorParameters<typeof SIWEJwtBearerAuth>;\ntype SRPParams = ConstructorParameters<typeof SRPJwtBearerAuth>;\ntype JwtBearerAuthParams = SiweParams | SRPParams;\n\nexport class JwtBearerAuth implements SIWEInterface, SRPInterface {\n #type: AuthType;\n\n #env: Env;\n\n #sdk: SIWEJwtBearerAuth | SRPJwtBearerAuth;\n\n constructor(...args: JwtBearerAuthParams) {\n this.#type = args[0].type;\n this.#env = args[0].env;\n\n if (args[0].type === AuthType.SRP) {\n this.#sdk = new SRPJwtBearerAuth(args[0], args[1]);\n return;\n }\n\n if (args[0].type === AuthType.SiWE) {\n this.#sdk = new SIWEJwtBearerAuth(args[0], args[1]);\n return;\n }\n\n throw new UnsupportedAuthTypeError('unsupported auth type');\n }\n\n async getAccessToken(): Promise<string> {\n return await this.#sdk.getAccessToken();\n }\n\n async getUserProfile(): Promise<UserProfile> {\n return await this.#sdk.getUserProfile();\n }\n\n async getIdentifier(): Promise<string> {\n return await this.#sdk.getIdentifier();\n }\n\n async signMessage(message: string): Promise<string> {\n return await this.#sdk.signMessage(message);\n }\n\n async pairIdentifiers(pairing: Pair[]): Promise<void> {\n const profile = await this.getUserProfile();\n const n = await getNonce(profile.profileId, this.#env);\n\n const logins = await Promise.all(\n pairing.map(async (p) => {\n try {\n const raw = `metamask:${n.nonce}:${p.identifier}`;\n const sig = await p.signMessage(raw);\n return {\n signature: sig,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n raw_message: raw,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n encrypted_storage_key: p.encryptedStorageKey,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n identifier_type: p.identifierType,\n };\n } catch (e) {\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n throw new PairError(\n `failed to sign pairing message: ${errorMessage}`,\n );\n }\n }),\n );\n\n const accessToken = await this.getAccessToken();\n await pairIdentifiers(n.nonce, logins, accessToken, this.#env);\n }\n\n prepare(signer: {\n address: string;\n chainId: number;\n signMessage: (message: string) => Promise<string>;\n domain: string;\n }): void {\n this.#assertSIWE(this.#type, this.#sdk);\n this.#sdk.prepare(signer);\n }\n\n #assertSIWE(\n type: AuthType,\n sdk: SIWEJwtBearerAuth | SRPJwtBearerAuth,\n ): asserts sdk is SIWEJwtBearerAuth {\n if (type === AuthType.SiWE) {\n return;\n }\n\n throw new UnsupportedAuthTypeError(\n 'This method is only available via SIWE auth type',\n );\n }\n}\n\nexport { SIWEJwtBearerAuth } from './authentication-jwt-bearer/flow-siwe';\nexport { SRPJwtBearerAuth } from './authentication-jwt-bearer/flow-srp';\nexport * from './authentication-jwt-bearer/types';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAsBO,IAAM,gBAAN,MAA2D;AAAA,EAOhE,eAAe,MAA2B;AA+E1C;AArFA;AAEA;AAEA;AAGE,uBAAK,OAAQ,KAAK,CAAC,EAAE;AACrB,uBAAK,MAAO,KAAK,CAAC,EAAE;AAEpB,QAAI,KAAK,CAAC,EAAE,0BAAuB;AACjC,yBAAK,MAAO,IAAI,iBAAiB,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;AACjD;AAAA,IACF;AAEA,QAAI,KAAK,CAAC,EAAE,4BAAwB;AAClC,yBAAK,MAAO,IAAI,kBAAkB,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;AAClD;AAAA,IACF;AAEA,UAAM,IAAI,yBAAyB,uBAAuB;AAAA,EAC5D;AAAA,EAEA,MAAM,iBAAkC;AACtC,WAAO,MAAM,mBAAK,MAAK,eAAe;AAAA,EACxC;AAAA,EAEA,MAAM,iBAAuC;AAC3C,WAAO,MAAM,mBAAK,MAAK,eAAe;AAAA,EACxC;AAAA,EAEA,MAAM,gBAAiC;AACrC,WAAO,MAAM,mBAAK,MAAK,cAAc;AAAA,EACvC;AAAA,EAEA,MAAM,YAAY,SAAkC;AAClD,WAAO,MAAM,mBAAK,MAAK,YAAY,OAAO;AAAA,EAC5C;AAAA,EAEA,MAAM,gBAAgB,SAAgC;AACpD,UAAM,UAAU,MAAM,KAAK,eAAe;AAC1C,UAAM,IAAI,MAAM,SAAS,QAAQ,WAAW,mBAAK,KAAI;AAErD,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,QAAQ,IAAI,OAAO,MAAM;AACvB,YAAI;AACF,gBAAM,MAAM,YAAY,EAAE,KAAK,IAAI,EAAE,UAAU;AAC/C,gBAAM,MAAM,MAAM,EAAE,YAAY,GAAG;AACnC,iBAAO;AAAA,YACL,WAAW;AAAA;AAAA;AAAA,YAGX,aAAa;AAAA;AAAA;AAAA,YAGb,uBAAuB,EAAE;AAAA;AAAA;AAAA,YAGzB,iBAAiB,EAAE;AAAA,UACrB;AAAA,QACF,SAAS,GAAG;AAEV,gBAAM,eACJ,aAAa,QAAQ,EAAE,UAAU,KAAK,UAAU,KAAK,EAAE;AACzD,gBAAM,IAAI;AAAA,YACR,mCAAmC,YAAY;AAAA,UACjD;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,cAAc,MAAM,KAAK,eAAe;AAC9C,UAAM,gBAAgB,EAAE,OAAO,QAAQ,aAAa,mBAAK,KAAI;AAAA,EAC/D;AAAA,EAEA,QAAQ,QAKC;AACP,0BAAK,4BAAL,WAAiB,mBAAK,QAAO,mBAAK;AAClC,uBAAK,MAAK,QAAQ,MAAM;AAAA,EAC1B;AAcF;AAjGE;AAEA;AAEA;AAiFA;AAAA,gBAAW,SACT,MACA,KACkC;AAClC,MAAI,4BAAwB;AAC1B;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/sdk/authentication.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAsBO,IAAM,gBAAN,MAA2D;AAAA,EAOhE,eAAe,MAA2B;AA+E1C;AArFA;AAEA;AAEA;AAGE,uBAAK,OAAQ,KAAK,CAAC,EAAE;AACrB,uBAAK,MAAO,KAAK,CAAC,EAAE;AAEpB,QAAI,KAAK,CAAC,EAAE,0BAAuB;AACjC,yBAAK,MAAO,IAAI,iBAAiB,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;AACjD;AAAA,IACF;AAEA,QAAI,KAAK,CAAC,EAAE,4BAAwB;AAClC,yBAAK,MAAO,IAAI,kBAAkB,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;AAClD;AAAA,IACF;AAEA,UAAM,IAAI,yBAAyB,uBAAuB;AAAA,EAC5D;AAAA,EAEA,MAAM,iBAAkC;AACtC,WAAO,MAAM,mBAAK,MAAK,eAAe;AAAA,EACxC;AAAA,EAEA,MAAM,iBAAuC;AAC3C,WAAO,MAAM,mBAAK,MAAK,eAAe;AAAA,EACxC;AAAA,EAEA,MAAM,gBAAiC;AACrC,WAAO,MAAM,mBAAK,MAAK,cAAc;AAAA,EACvC;AAAA,EAEA,MAAM,YAAY,SAAkC;AAClD,WAAO,MAAM,mBAAK,MAAK,YAAY,OAAO;AAAA,EAC5C;AAAA,EAEA,MAAM,gBAAgB,SAAgC;AACpD,UAAM,UAAU,MAAM,KAAK,eAAe;AAC1C,UAAM,IAAI,MAAM,SAAS,QAAQ,WAAW,mBAAK,KAAI;AAErD,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,QAAQ,IAAI,OAAO,MAAM;AACvB,YAAI;AACF,gBAAM,MAAM,YAAY,EAAE,KAAK,IAAI,EAAE,UAAU;AAC/C,gBAAM,MAAM,MAAM,EAAE,YAAY,GAAG;AACnC,iBAAO;AAAA,YACL,WAAW;AAAA;AAAA;AAAA,YAGX,aAAa;AAAA;AAAA;AAAA,YAGb,uBAAuB,EAAE;AAAA;AAAA;AAAA,YAGzB,iBAAiB,EAAE;AAAA,UACrB;AAAA,QACF,SAAS,GAAG;AAEV,gBAAM,eACJ,aAAa,QAAQ,EAAE,UAAU,KAAK,UAAU,KAAK,EAAE;AACzD,gBAAM,IAAI;AAAA,YACR,mCAAmC,YAAY;AAAA,UACjD;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,cAAc,MAAM,KAAK,eAAe;AAC9C,UAAM,gBAAgB,EAAE,OAAO,QAAQ,aAAa,mBAAK,KAAI;AAAA,EAC/D;AAAA,EAEA,QAAQ,QAKC;AACP,0BAAK,4BAAL,WAAiB,mBAAK,QAAO,mBAAK;AAClC,uBAAK,MAAK,QAAQ,MAAM;AAAA,EAC1B;AAcF;AAjGE;AAEA;AAEA;AAiFA;AAAA,gBAAW,SACT,MACA,KACkC;AAClC,MAAI,4BAAwB;AAC1B;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF","sourcesContent":["import { SIWEJwtBearerAuth } from './authentication-jwt-bearer/flow-siwe';\nimport { SRPJwtBearerAuth } from './authentication-jwt-bearer/flow-srp';\nimport {\n getNonce,\n pairIdentifiers,\n} from './authentication-jwt-bearer/services';\nimport type { UserProfile, Pair } from './authentication-jwt-bearer/types';\nimport { AuthType } from './authentication-jwt-bearer/types';\nimport type { Env } from './env';\nimport { PairError, UnsupportedAuthTypeError } from './errors';\n\n// Computing the Classes, so we only get back the public methods for the interface.\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\ntype Compute<T> = T extends infer U ? { [K in keyof U]: U[K] } : never;\ntype SIWEInterface = Compute<SIWEJwtBearerAuth>;\ntype SRPInterface = Compute<SRPJwtBearerAuth>;\n\ntype SiweParams = ConstructorParameters<typeof SIWEJwtBearerAuth>;\ntype SRPParams = ConstructorParameters<typeof SRPJwtBearerAuth>;\ntype JwtBearerAuthParams = SiweParams | SRPParams;\n\nexport class JwtBearerAuth implements SIWEInterface, SRPInterface {\n #type: AuthType;\n\n #env: Env;\n\n #sdk: SIWEJwtBearerAuth | SRPJwtBearerAuth;\n\n constructor(...args: JwtBearerAuthParams) {\n this.#type = args[0].type;\n this.#env = args[0].env;\n\n if (args[0].type === AuthType.SRP) {\n this.#sdk = new SRPJwtBearerAuth(args[0], args[1]);\n return;\n }\n\n if (args[0].type === AuthType.SiWE) {\n this.#sdk = new SIWEJwtBearerAuth(args[0], args[1]);\n return;\n }\n\n throw new UnsupportedAuthTypeError('unsupported auth type');\n }\n\n async getAccessToken(): Promise<string> {\n return await this.#sdk.getAccessToken();\n }\n\n async getUserProfile(): Promise<UserProfile> {\n return await this.#sdk.getUserProfile();\n }\n\n async getIdentifier(): Promise<string> {\n return await this.#sdk.getIdentifier();\n }\n\n async signMessage(message: string): Promise<string> {\n return await this.#sdk.signMessage(message);\n }\n\n async pairIdentifiers(pairing: Pair[]): Promise<void> {\n const profile = await this.getUserProfile();\n const n = await getNonce(profile.profileId, this.#env);\n\n const logins = await Promise.all(\n pairing.map(async (p) => {\n try {\n const raw = `metamask:${n.nonce}:${p.identifier}`;\n const sig = await p.signMessage(raw);\n return {\n signature: sig,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n raw_message: raw,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n encrypted_storage_key: p.encryptedStorageKey,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n identifier_type: p.identifierType,\n };\n } catch (e) {\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n throw new PairError(\n `failed to sign pairing message: ${errorMessage}`,\n );\n }\n }),\n );\n\n const accessToken = await this.getAccessToken();\n await pairIdentifiers(n.nonce, logins, accessToken, this.#env);\n }\n\n prepare(signer: {\n address: string;\n chainId: number;\n signMessage: (message: string) => Promise<string>;\n domain: string;\n }): void {\n this.#assertSIWE(this.#type, this.#sdk);\n this.#sdk.prepare(signer);\n }\n\n #assertSIWE(\n type: AuthType,\n sdk: SIWEJwtBearerAuth | SRPJwtBearerAuth,\n ): asserts sdk is SIWEJwtBearerAuth {\n if (type === AuthType.SiWE) {\n return;\n }\n\n throw new UnsupportedAuthTypeError(\n 'This method is only available via SIWE auth type',\n );\n }\n}\n\nexport { SIWEJwtBearerAuth } from './authentication-jwt-bearer/flow-siwe';\nexport { SRPJwtBearerAuth } from './authentication-jwt-bearer/flow-srp';\nexport * from './authentication-jwt-bearer/types';\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/sdk/user-storage.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IBaseAuth } from './authentication-jwt-bearer/types';\nimport encryption, { createSHA256Hash } from './encryption';\nimport type { Env } from './env';\nimport { getEnvUrls } from './env';\nimport { NotFoundError, UserStorageError, ValidationError } from './errors';\n\nexport const STORAGE_URL = (env: Env, feature: string, entry: string) =>\n `${getEnvUrls(env).userStorageApiUrl}/api/v1/userstorage/${feature}/${entry}`;\n\nexport type UserStorageConfig = {\n env: Env;\n auth: Pick<IBaseAuth, 'getAccessToken' | 'getUserProfile' | 'signMessage'>;\n};\n\nexport type StorageOptions = {\n getStorageKey: () => Promise<string | null>;\n setStorageKey: (val: string) => Promise<void>;\n};\n\nexport type UserStorageOptions = {\n storage?: StorageOptions;\n};\n\ntype ErrorMessage = {\n message: string;\n error: string;\n};\n\nexport class UserStorage {\n protected config: UserStorageConfig;\n\n protected options: UserStorageOptions;\n\n protected env: Env;\n\n constructor(config: UserStorageConfig, options: UserStorageOptions) {\n this.env = config.env;\n this.config = config;\n this.options = options;\n }\n\n async setItem(feature: string, key: string, value: string): Promise<void> {\n if (!feature.trim() || !key.trim()) {\n throw new ValidationError('feature or key cannot be empty strings');\n }\n await this.#upsertUserStorage(feature, key, value);\n }\n\n async getItem(feature: string, key: string): Promise<string> {\n if (!feature.trim() || !key.trim()) {\n throw new ValidationError('feature or key cannot be empty strings');\n }\n return this.#getUserStorage(feature, key);\n }\n\n async getStorageKey(): Promise<string> {\n const storageKey = await this.options.storage?.getStorageKey();\n if (storageKey) {\n return storageKey;\n }\n\n const userProfile = await this.config.auth.getUserProfile();\n const storageKeySignature = await this.config.auth.signMessage(\n `metamask:${userProfile.profileId}`,\n );\n const hashedStorageKeySignature = createSHA256Hash(storageKeySignature);\n await this.options.storage?.setStorageKey(hashedStorageKeySignature);\n return hashedStorageKeySignature;\n }\n\n async #upsertUserStorage(\n feature: string,\n key: string,\n data: string,\n ): Promise<void> {\n try {\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n const encryptedData = encryption.encryptString(data, storageKey);\n const url = new URL(\n STORAGE_URL(this.env, feature, this.#createEntryKey(key, storageKey)),\n );\n\n const response = await fetch(url.toString(), {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({ data: encryptedData }),\n });\n\n if (!response.ok) {\n const responseBody: ErrorMessage = await response.json().catch(() => ({\n message: 'unknown',\n error: 'unknown',\n }));\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n } catch (e) {\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n throw new UserStorageError(\n `failed to upsert user storage for feature '${feature}' and key '${key}'. ${errorMessage}`,\n );\n }\n }\n\n async #getUserStorage(feature: string, key: string): Promise<string> {\n try {\n const headers = await this.#getAuthorizationHeader();\n const storageKey = await this.getStorageKey();\n const url = new URL(\n STORAGE_URL(this.env, feature, this.#createEntryKey(key, storageKey)),\n );\n\n const response = await fetch(url.toString(), {\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n });\n\n if (response.status === 404) {\n throw new NotFoundError(\n `feature/key set not found for feature '${feature}' and key '${key}'.`,\n );\n }\n\n if (!response.ok) {\n const responseBody = (await response.json()) as ErrorMessage;\n throw new Error(\n `HTTP error message: ${responseBody.message}, error: ${responseBody.error}`,\n );\n }\n\n const { Data: encryptedData } = await response.json();\n return encryption.decryptString(encryptedData, storageKey);\n } catch (e) {\n if (e instanceof NotFoundError) {\n throw e;\n }\n\n /* istanbul ignore next */\n const errorMessage =\n e instanceof Error ? e.message : JSON.stringify(e ?? '');\n\n throw new UserStorageError(\n `failed to get user storage for feature '${feature}' and key '${key}'. ${errorMessage}`,\n );\n }\n }\n\n #createEntryKey(key: string, storageKey: string): string {\n const hashedKey = createSHA256Hash(key + storageKey);\n return hashedKey;\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n async #getAuthorizationHeader(): Promise<{ Authorization: string }> {\n const accessToken = await this.config.auth.getAccessToken();\n return { Authorization: `Bearer ${accessToken}` };\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/controllers/user-storage/UserStorageController.ts"],"sourcesContent":["import type {\n RestrictedControllerMessenger,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\n\nimport { createSnapSignMessageRequest } from '../authentication/auth-snap-requests';\nimport type {\n AuthenticationControllerGetBearerToken,\n AuthenticationControllerGetSessionProfile,\n AuthenticationControllerIsSignedIn,\n AuthenticationControllerPerformSignIn,\n AuthenticationControllerPerformSignOut,\n} from '../authentication/AuthenticationController';\nimport { createSHA256Hash } from './encryption';\nimport type { UserStorageEntryKeys } from './schema';\nimport { getUserStorage, upsertUserStorage } from './services';\n\n// TODO: fix external dependencies\nexport declare type NotificationServicesControllerDisableNotificationServices =\n {\n type: `NotificationServicesController:disableNotificationServices`;\n handler: () => Promise<void>;\n };\n\nexport declare type NotificationServicesControllerSelectIsNotificationServicesEnabled =\n {\n type: `NotificationServicesController:selectIsNotificationServicesEnabled`;\n handler: () => boolean;\n };\n\nconst controllerName = 'UserStorageController';\n\n// State\nexport type UserStorageControllerState = {\n /**\n * Condition used by UI and to determine if we can use some of the User Storage methods.\n */\n isProfileSyncingEnabled: boolean;\n /**\n * Loading state for the profile syncing update\n */\n isProfileSyncingUpdateLoading: boolean;\n};\n\nexport const defaultState: UserStorageControllerState = {\n isProfileSyncingEnabled: true,\n isProfileSyncingUpdateLoading: false,\n};\n\nconst metadata: StateMetadata<UserStorageControllerState> = {\n isProfileSyncingEnabled: {\n persist: true,\n anonymous: true,\n },\n isProfileSyncingUpdateLoading: {\n persist: false,\n anonymous: false,\n },\n};\n\n// Messenger Actions\ntype CreateActionsObj<Controller extends keyof UserStorageController> = {\n [K in Controller]: {\n type: `${typeof controllerName}:${K}`;\n handler: UserStorageController[K];\n };\n};\ntype ActionsObj = CreateActionsObj<\n | 'performGetStorage'\n | 'performSetStorage'\n | 'getStorageKey'\n | 'enableProfileSyncing'\n | 'disableProfileSyncing'\n>;\nexport type Actions = ActionsObj[keyof ActionsObj];\nexport type UserStorageControllerPerformGetStorage =\n ActionsObj['performGetStorage'];\nexport type UserStorageControllerPerformSetStorage =\n ActionsObj['performSetStorage'];\nexport type UserStorageControllerGetStorageKey = ActionsObj['getStorageKey'];\nexport type UserStorageControllerEnableProfileSyncing =\n ActionsObj['enableProfileSyncing'];\nexport type UserStorageControllerDisableProfileSyncing =\n ActionsObj['disableProfileSyncing'];\n\n// Allowed Actions\nexport type AllowedActions =\n // Snap Requests\n | HandleSnapRequest\n // Auth Requests\n | AuthenticationControllerGetBearerToken\n | AuthenticationControllerGetSessionProfile\n | AuthenticationControllerPerformSignIn\n | AuthenticationControllerIsSignedIn\n | AuthenticationControllerPerformSignOut\n // Metamask Notifications\n | NotificationServicesControllerDisableNotificationServices\n | NotificationServicesControllerSelectIsNotificationServicesEnabled;\n\n// Messenger\nexport type UserStorageControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n Actions | AllowedActions,\n never,\n AllowedActions['type'],\n never\n>;\n\n/**\n * Reusable controller that allows any team to store synchronized data for a given user.\n * These can be settings shared cross MetaMask clients, or data we want to persist when uninstalling/reinstalling.\n *\n * NOTE:\n * - data stored on UserStorage is FULLY encrypted, with the only keys stored/managed on the client.\n * - No one can access this data unless they are have the SRP and are able to run the signing snap.\n */\nexport default class UserStorageController extends BaseController<\n typeof controllerName,\n UserStorageControllerState,\n UserStorageControllerMessenger\n> {\n #auth = {\n getBearerToken: async () => {\n return await this.messagingSystem.call(\n 'AuthenticationController:getBearerToken',\n );\n },\n getProfileId: async () => {\n const sessionProfile = await this.messagingSystem.call(\n 'AuthenticationController:getSessionProfile',\n );\n return sessionProfile?.profileId;\n },\n isAuthEnabled: () => {\n return this.messagingSystem.call('AuthenticationController:isSignedIn');\n },\n signIn: async () => {\n return await this.messagingSystem.call(\n 'AuthenticationController:performSignIn',\n );\n },\n signOut: async () => {\n return this.messagingSystem.call(\n 'AuthenticationController:performSignOut',\n );\n },\n };\n\n #notificationServices = {\n disableNotificationServices: async () => {\n return await this.messagingSystem.call(\n 'NotificationServicesController:disableNotificationServices',\n );\n },\n selectIsNotificationServicesEnabled: async () => {\n return this.messagingSystem.call(\n 'NotificationServicesController:selectIsNotificationServicesEnabled',\n );\n },\n };\n\n getMetaMetricsState: () => boolean;\n\n constructor(params: {\n messenger: UserStorageControllerMessenger;\n state?: UserStorageControllerState;\n getMetaMetricsState: () => boolean;\n }) {\n super({\n messenger: params.messenger,\n metadata,\n name: controllerName,\n state: { ...defaultState, ...params.state },\n });\n\n this.getMetaMetricsState = params.getMetaMetricsState;\n this.#registerMessageHandlers();\n }\n\n /**\n * Constructor helper for registering this controller's messaging system\n * actions.\n */\n #registerMessageHandlers(): void {\n this.messagingSystem.registerActionHandler(\n 'UserStorageController:performGetStorage',\n this.performGetStorage.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n 'UserStorageController:performSetStorage',\n this.performSetStorage.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n 'UserStorageController:getStorageKey',\n this.getStorageKey.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n 'UserStorageController:enableProfileSyncing',\n this.enableProfileSyncing.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n 'UserStorageController:disableProfileSyncing',\n this.disableProfileSyncing.bind(this),\n );\n }\n\n public async enableProfileSyncing(): Promise<void> {\n try {\n this.#setIsProfileSyncingUpdateLoading(true);\n\n const authEnabled = this.#auth.isAuthEnabled();\n if (!authEnabled) {\n await this.#auth.signIn();\n }\n\n this.update((state) => {\n state.isProfileSyncingEnabled = true;\n });\n\n this.#setIsProfileSyncingUpdateLoading(false);\n } catch (e) {\n this.#setIsProfileSyncingUpdateLoading(false);\n const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);\n throw new Error(\n `${controllerName} - failed to enable profile syncing - ${errorMessage}`,\n );\n }\n }\n\n public async setIsProfileSyncingEnabled(\n isProfileSyncingEnabled: boolean,\n ): Promise<void> {\n this.update((state) => {\n state.isProfileSyncingEnabled = isProfileSyncingEnabled;\n });\n }\n\n public async disableProfileSyncing(): Promise<void> {\n const isAlreadyDisabled = !this.state.isProfileSyncingEnabled;\n if (isAlreadyDisabled) {\n return;\n }\n\n try {\n this.#setIsProfileSyncingUpdateLoading(true);\n\n const isNotificationServicesEnabled =\n await this.#notificationServices.selectIsNotificationServicesEnabled();\n\n if (isNotificationServicesEnabled) {\n await this.#notificationServices.disableNotificationServices();\n }\n\n const isMetaMetricsParticipation = this.getMetaMetricsState();\n\n if (!isMetaMetricsParticipation) {\n this.messagingSystem.call('AuthenticationController:performSignOut');\n }\n\n this.#setIsProfileSyncingUpdateLoading(false);\n\n this.update((state) => {\n state.isProfileSyncingEnabled = false;\n });\n } catch (e) {\n this.#setIsProfileSyncingUpdateLoading(false);\n const errorMessage = e instanceof Error ? e.message : JSON.stringify(e);\n throw new Error(\n `${controllerName} - failed to disable profile syncing - ${errorMessage}`,\n );\n }\n }\n\n /**\n * Allows retrieval of stored data. Data stored is string formatted.\n * Developers can extend the entry path and entry name through the `schema.ts` file.\n *\n * @param entryKey - entry key that matches schema\n * @returns the decrypted string contents found from user storage (or null if not found)\n */\n public async performGetStorage(\n entryKey: UserStorageEntryKeys,\n ): Promise<string | null> {\n this.#assertProfileSyncingEnabled();\n const { bearerToken, storageKey } =\n await this.#getStorageKeyAndBearerToken();\n const result = await getUserStorage({\n entryKey,\n bearerToken,\n storageKey,\n });\n\n return result;\n }\n\n /**\n * Allows storage of user data. Data stored must be string formatted.\n * Developers can extend the entry path and entry name through the `schema.ts` file.\n *\n * @param entryKey - entry key that matches schema\n * @param value - The string data you want to store.\n * @returns nothing. NOTE that an error is thrown if fails to store data.\n */\n public async performSetStorage(\n entryKey: UserStorageEntryKeys,\n value: string,\n ): Promise<void> {\n this.#assertProfileSyncingEnabled();\n const { bearerToken, storageKey } =\n await this.#getStorageKeyAndBearerToken();\n\n await upsertUserStorage(value, {\n entryKey,\n bearerToken,\n storageKey,\n });\n }\n\n /**\n * Retrieves the storage key, for internal use only!\n *\n * @returns the storage key\n */\n public async getStorageKey(): Promise<string> {\n this.#assertProfileSyncingEnabled();\n const storageKey = await this.#createStorageKey();\n return storageKey;\n }\n\n #assertProfileSyncingEnabled(): void {\n if (!this.state.isProfileSyncingEnabled) {\n throw new Error(\n `${controllerName}: Unable to call method, user is not authenticated`,\n );\n }\n }\n\n /**\n * Utility to get the bearer token and storage key\n */\n async #getStorageKeyAndBearerToken(): Promise<{\n bearerToken: string;\n storageKey: string;\n }> {\n const bearerToken = await this.#auth.getBearerToken();\n if (!bearerToken) {\n throw new Error('UserStorageController - unable to get bearer token');\n }\n const storageKey = await this.#createStorageKey();\n\n return { bearerToken, storageKey };\n }\n\n /**\n * Rather than storing the storage key, we can compute the storage key when needed.\n *\n * @returns the storage key\n */\n async #createStorageKey(): Promise<string> {\n const id: string = await this.#auth.getProfileId();\n if (!id) {\n throw new Error('UserStorageController - unable to create storage key');\n }\n\n const storageKeySignature = await this.#snapSignMessage(`metamask:${id}`);\n const storageKey = createSHA256Hash(storageKeySignature);\n return storageKey;\n }\n\n #_snapSignMessageCache: Record<`metamask:${string}`, string> = {};\n\n /**\n * Signs a specific message using an underlying auth snap.\n *\n * @param message - A specific tagged message to sign.\n * @returns A Signature created by the snap.\n */\n async #snapSignMessage(message: `metamask:${string}`): Promise<string> {\n if (this.#_snapSignMessageCache[message]) {\n return this.#_snapSignMessageCache[message];\n }\n\n const result = (await this.messagingSystem.call(\n 'SnapController:handleRequest',\n createSnapSignMessageRequest(message),\n )) as string;\n\n this.#_snapSignMessageCache[message] = result;\n\n return result;\n }\n\n #setIsProfileSyncingUpdateLoading(\n isProfileSyncingUpdateLoading: boolean,\n ): void {\n this.update((state) => {\n state.isProfileSyncingUpdateLoading = isProfileSyncingUpdateLoading;\n });\n }\n}\n"],"mappings":"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","names":[]}