@metamask-previews/profile-controller 0.0.0-preview-2848be6
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.
- package/CHANGELOG.md +15 -0
- package/LICENSE +6 -0
- package/LICENSE.APACHE2 +201 -0
- package/LICENSE.MIT +21 -0
- package/README.md +15 -0
- package/dist/ProfileController-method-action-types.d.ts +99 -0
- package/dist/ProfileController-method-action-types.d.ts.map +1 -0
- package/dist/ProfileController-method-action-types.js +6 -0
- package/dist/ProfileController-method-action-types.js.map +1 -0
- package/dist/ProfileController.d.ts +153 -0
- package/dist/ProfileController.d.ts.map +1 -0
- package/dist/ProfileController.js +241 -0
- package/dist/ProfileController.js.map +1 -0
- package/dist/ProfileService-method-action-types.d.ts +117 -0
- package/dist/ProfileService-method-action-types.d.ts.map +1 -0
- package/dist/ProfileService-method-action-types.js +6 -0
- package/dist/ProfileService-method-action-types.js.map +1 -0
- package/dist/ProfileService.d.ts +310 -0
- package/dist/ProfileService.d.ts.map +1 -0
- package/dist/ProfileService.js +327 -0
- package/dist/ProfileService.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { BaseController } from '@metamask/base-controller';
|
|
2
|
+
const controllerName = 'ProfileController';
|
|
3
|
+
// === STATE ===
|
|
4
|
+
const profileControllerMetadata = {
|
|
5
|
+
profile: {
|
|
6
|
+
includeInStateLogs: true,
|
|
7
|
+
persist: true,
|
|
8
|
+
includeInDebugSnapshot: false,
|
|
9
|
+
usedInUi: true,
|
|
10
|
+
},
|
|
11
|
+
xProfile: {
|
|
12
|
+
includeInStateLogs: false,
|
|
13
|
+
persist: true,
|
|
14
|
+
includeInDebugSnapshot: false,
|
|
15
|
+
usedInUi: true,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Returns the default initial state for ProfileController.
|
|
20
|
+
*
|
|
21
|
+
* @returns A ProfileControllerState with empty profile fields and no X profile.
|
|
22
|
+
*/
|
|
23
|
+
export function getDefaultProfileControllerState() {
|
|
24
|
+
return {
|
|
25
|
+
profile: {
|
|
26
|
+
profileId: '',
|
|
27
|
+
username: '',
|
|
28
|
+
displayName: '',
|
|
29
|
+
bio: '',
|
|
30
|
+
linkedAddresses: [],
|
|
31
|
+
avatarUrl: '',
|
|
32
|
+
tradingPrivacy: 'public',
|
|
33
|
+
connectedToX: false,
|
|
34
|
+
createdAt: '',
|
|
35
|
+
updatedAt: '',
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const MESSENGER_EXPOSED_METHODS = [
|
|
40
|
+
'getProfile',
|
|
41
|
+
'getXProfile',
|
|
42
|
+
'createProfile',
|
|
43
|
+
'replaceProfile',
|
|
44
|
+
'updateProfile',
|
|
45
|
+
'deleteProfile',
|
|
46
|
+
'checkUsernameAvailability',
|
|
47
|
+
'connectX',
|
|
48
|
+
'fetchAndUpdateXAccount',
|
|
49
|
+
];
|
|
50
|
+
// === CONTROLLER ===
|
|
51
|
+
/** Manages MetaMask profile state and delegates API operations to ProfileService. */
|
|
52
|
+
export class ProfileController extends BaseController {
|
|
53
|
+
/**
|
|
54
|
+
* Creates a new ProfileController instance.
|
|
55
|
+
*
|
|
56
|
+
* @param options - Constructor options.
|
|
57
|
+
* @param options.messenger - The messenger scoped to ProfileController.
|
|
58
|
+
* @param options.state - Optional partial initial state to merge with defaults.
|
|
59
|
+
*/
|
|
60
|
+
constructor({ messenger, state, }) {
|
|
61
|
+
super({
|
|
62
|
+
messenger,
|
|
63
|
+
name: controllerName,
|
|
64
|
+
metadata: profileControllerMetadata,
|
|
65
|
+
state: {
|
|
66
|
+
...getDefaultProfileControllerState(),
|
|
67
|
+
...state,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Returns true if a profile has been created and exists in state.
|
|
74
|
+
*
|
|
75
|
+
* @returns True if a profile exists, false otherwise.
|
|
76
|
+
*/
|
|
77
|
+
#hasProfile() {
|
|
78
|
+
return this.state.profile.profileId !== '';
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Returns the profile ID from state, throwing if no profile exists yet.
|
|
82
|
+
*
|
|
83
|
+
* @returns The current profile ID.
|
|
84
|
+
* @throws If no profile has been created.
|
|
85
|
+
*/
|
|
86
|
+
#getProfileIdOrThrow() {
|
|
87
|
+
const { profileId } = this.state.profile;
|
|
88
|
+
if (!profileId) {
|
|
89
|
+
throw new Error('ProfileController: no profile found in state');
|
|
90
|
+
}
|
|
91
|
+
return profileId;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Maps an API response to a MetaMask profile.
|
|
95
|
+
*
|
|
96
|
+
* @param response - The API response to map.
|
|
97
|
+
* @returns The mapped MetaMask profile.
|
|
98
|
+
*/
|
|
99
|
+
#mapApiResponseToProfile(response) {
|
|
100
|
+
return {
|
|
101
|
+
profileId: response.profile_id,
|
|
102
|
+
username: response.username,
|
|
103
|
+
displayName: response.display_name,
|
|
104
|
+
bio: response.bio ?? '',
|
|
105
|
+
linkedAddresses: response.linked_addresses,
|
|
106
|
+
avatarUrl: response.avatar_url ?? '',
|
|
107
|
+
tradingPrivacy: response.trading_privacy,
|
|
108
|
+
connectedToX: response.connected_to_x,
|
|
109
|
+
createdAt: response.created_at,
|
|
110
|
+
updatedAt: response.updated_at,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Maps an API response to an X profile.
|
|
115
|
+
*
|
|
116
|
+
* @param response - The API response to map.
|
|
117
|
+
* @returns The mapped X profile.
|
|
118
|
+
*/
|
|
119
|
+
#mapXResponseToXProfile(response) {
|
|
120
|
+
return {
|
|
121
|
+
xUserId: response.x_user_id,
|
|
122
|
+
xProfileUrl: response.x_profile_url,
|
|
123
|
+
username: response.username,
|
|
124
|
+
displayName: response.display_name,
|
|
125
|
+
avatarUrl: response.avatar_url,
|
|
126
|
+
createdAt: response.created_at,
|
|
127
|
+
updatedAt: response.updated_at,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Returns the current MetaMask profile from state, or undefined if none has been created.
|
|
132
|
+
*
|
|
133
|
+
* @returns The MetaMask profile, or undefined.
|
|
134
|
+
*/
|
|
135
|
+
getProfile() {
|
|
136
|
+
if (!this.#hasProfile()) {
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
return this.state.profile;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Returns the currently linked X profile from state, or undefined if none has been connected.
|
|
143
|
+
*
|
|
144
|
+
* @returns The X profile, or undefined.
|
|
145
|
+
*/
|
|
146
|
+
getXProfile() {
|
|
147
|
+
return this.state.xProfile;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Creates a new MetaMask profile, updates state, and returns the created profile.
|
|
151
|
+
* If the user had previously connected X, also updates xProfile in state.
|
|
152
|
+
*
|
|
153
|
+
* @param params - The profile creation parameters.
|
|
154
|
+
* @returns The created MetaMask profile.
|
|
155
|
+
*/
|
|
156
|
+
async createProfile(params) {
|
|
157
|
+
const response = await this.messenger.call('ProfileService:createProfile', params);
|
|
158
|
+
const mapped = this.#mapApiResponseToProfile(response);
|
|
159
|
+
this.update((state) => {
|
|
160
|
+
state.profile = mapped;
|
|
161
|
+
if (response.x_profile) {
|
|
162
|
+
state.xProfile = this.#mapXResponseToXProfile(response.x_profile);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
return mapped;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Fully replaces the current profile and updates state.
|
|
169
|
+
*
|
|
170
|
+
* @param input - The replacement profile data.
|
|
171
|
+
* @throws If no profile has been created yet.
|
|
172
|
+
*/
|
|
173
|
+
async replaceProfile(input) {
|
|
174
|
+
const profileId = this.#getProfileIdOrThrow();
|
|
175
|
+
const response = await this.messenger.call('ProfileService:replaceProfile', profileId, input);
|
|
176
|
+
this.update((state) => {
|
|
177
|
+
state.profile = this.#mapApiResponseToProfile(response);
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Partially updates the current profile and updates state.
|
|
182
|
+
*
|
|
183
|
+
* @param input - The fields to update.
|
|
184
|
+
* @throws If no profile has been created yet.
|
|
185
|
+
*/
|
|
186
|
+
async updateProfile(input) {
|
|
187
|
+
const profileId = this.#getProfileIdOrThrow();
|
|
188
|
+
const response = await this.messenger.call('ProfileService:updateProfile', profileId, input);
|
|
189
|
+
this.update((state) => {
|
|
190
|
+
state.profile = this.#mapApiResponseToProfile(response);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Deletes the current profile and resets state, including clearing any linked X profile.
|
|
195
|
+
*
|
|
196
|
+
* @throws If no profile has been created yet.
|
|
197
|
+
*/
|
|
198
|
+
async deleteProfile() {
|
|
199
|
+
const profileId = this.#getProfileIdOrThrow();
|
|
200
|
+
await this.messenger.call('ProfileService:deleteProfile', profileId);
|
|
201
|
+
this.update((state) => {
|
|
202
|
+
state.profile = getDefaultProfileControllerState().profile;
|
|
203
|
+
state.xProfile = undefined;
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Checks whether a username is available.
|
|
208
|
+
*
|
|
209
|
+
* @param username - The username to check.
|
|
210
|
+
* @returns Availability details including validity and normalized form.
|
|
211
|
+
*/
|
|
212
|
+
async checkUsernameAvailability(username) {
|
|
213
|
+
return await this.messenger.call('ProfileService:checkUsernameAvailability', username);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Completes the X OAuth PKCE flow, updates xProfile in state, and returns the X profile.
|
|
217
|
+
*
|
|
218
|
+
* @param params - The parameters for the X OAuth PKCE flow.
|
|
219
|
+
* @param params.code - The OAuth authorization code from the X redirect.
|
|
220
|
+
* @param params.state - The state parameter returned by the X redirect.
|
|
221
|
+
* @returns The linked X profile.
|
|
222
|
+
*/
|
|
223
|
+
async connectX(params) {
|
|
224
|
+
const response = await this.messenger.call('ProfileService:connectX', params);
|
|
225
|
+
return this.#mapXResponseToXProfile(response);
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Fetches the X account linked to the current profile, updates state, and returns the X profile.
|
|
229
|
+
*
|
|
230
|
+
* @returns The linked X profile.
|
|
231
|
+
*/
|
|
232
|
+
async fetchAndUpdateXAccount() {
|
|
233
|
+
const response = await this.messenger.call('ProfileService:getXAccount');
|
|
234
|
+
const mapped = this.#mapXResponseToXProfile(response);
|
|
235
|
+
this.update((state) => {
|
|
236
|
+
state.xProfile = mapped;
|
|
237
|
+
});
|
|
238
|
+
return mapped;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=ProfileController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProfileController.js","sourceRoot":"","sources":["../src/ProfileController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { CaipAccountId } from '@metamask/utils';\n\nimport type { ProfileControllerMethodActions } from './ProfileController-method-action-types.js';\nimport type {\n ProfileServiceCheckUsernameAvailabilityAction,\n ProfileServiceConnectXAction,\n ProfileServiceCreateProfileAction,\n ProfileServiceDeleteProfileAction,\n ProfileServiceGetXAccountAction,\n ProfileServiceReplaceProfileAction,\n ProfileServiceUpdateProfileAction,\n} from './ProfileService-method-action-types.js';\nimport type {\n CreateProfileParams,\n CreateProfileResponse,\n ProfileApiResponse,\n ReplaceProfileParams,\n UpdateProfileParams,\n UsernameAvailabilityResponse,\n XConnectResponse,\n} from './ProfileService.js';\n\nconst controllerName = 'ProfileController';\n\n// === TYPES ===\n\n/** Representation of a profile stored in controller state. */\nexport type Profile = {\n /** The canonical profile ID connected to the profile. */\n profileId: string;\n /** The username for the profile. */\n username: string;\n /** The display name for the profile. */\n displayName: string;\n /** The bio for the profile. */\n bio: string;\n /** The linked addresses for the profile. */\n linkedAddresses: CaipAccountId[];\n /** The avatar URL for the profile. */\n avatarUrl: string;\n /** Whether the profile's trading activity is visible to the public. */\n tradingPrivacy: 'public' | 'private';\n /** Whether the profile is connected to X. */\n connectedToX: boolean;\n /** The date and time the profile was created. */\n createdAt: string;\n /** The date and time the profile was updated. */\n updatedAt: string;\n};\n\n/** Representation of a linked X (Twitter) profile stored in controller state. */\nexport type XProfile = {\n /** The unique identifier for the X profile. This is the user ID of the X profile. */\n xUserId: string;\n /** The URL for the X profile. */\n xProfileUrl: string;\n /** The username for the X profile. */\n username: string;\n /** The display name for the X profile. */\n displayName: string;\n /** The avatar URL for the X profile. */\n avatarUrl: string;\n /** The date and time the X profile was created. */\n createdAt: string;\n /** The date and time the X profile was updated. */\n updatedAt: string;\n};\n\n/** State managed by ProfileController. */\nexport type ProfileControllerState = {\n profile: Profile;\n xProfile?: XProfile;\n};\n\n// === MESSENGER ===\n\n/** The `ProfileController:getState` action type. */\nexport type ProfileControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n ProfileControllerState\n>;\n\n/** Union of all actions exposed by ProfileController. */\nexport type ProfileControllerActions =\n | ProfileControllerGetStateAction\n | ProfileControllerMethodActions;\n\n/** The `ProfileController:stateChanged` event type. */\nexport type ProfileControllerChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ProfileControllerState\n>;\n\n/** Union of all events emitted by ProfileController. */\nexport type ProfileControllerEvents = ProfileControllerChangeEvent;\n\ntype AllowedActions =\n | ProfileServiceCreateProfileAction\n | ProfileServiceReplaceProfileAction\n | ProfileServiceUpdateProfileAction\n | ProfileServiceDeleteProfileAction\n | ProfileServiceCheckUsernameAvailabilityAction\n | ProfileServiceConnectXAction\n | ProfileServiceGetXAccountAction;\n\nexport type AllowedEvents = never;\n\n/** Messenger type for ProfileController, scoped to its actions, events, and allowed service calls. */\nexport type ProfileControllerMessenger = Messenger<\n typeof controllerName,\n ProfileControllerActions | AllowedActions,\n ProfileControllerEvents | AllowedEvents\n>;\n\n// === STATE ===\n\nconst profileControllerMetadata = {\n profile: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n xProfile: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n} satisfies StateMetadata<ProfileControllerState>;\n\n/**\n * Returns the default initial state for ProfileController.\n *\n * @returns A ProfileControllerState with empty profile fields and no X profile.\n */\nexport function getDefaultProfileControllerState(): ProfileControllerState {\n return {\n profile: {\n profileId: '',\n username: '',\n displayName: '',\n bio: '',\n linkedAddresses: [],\n avatarUrl: '',\n tradingPrivacy: 'public',\n connectedToX: false,\n createdAt: '',\n updatedAt: '',\n },\n };\n}\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'getProfile',\n 'getXProfile',\n 'createProfile',\n 'replaceProfile',\n 'updateProfile',\n 'deleteProfile',\n 'checkUsernameAvailability',\n 'connectX',\n 'fetchAndUpdateXAccount',\n] as const;\n\n// === CONTROLLER ===\n\n/** Manages MetaMask profile state and delegates API operations to ProfileService. */\nexport class ProfileController extends BaseController<\n typeof controllerName,\n ProfileControllerState,\n ProfileControllerMessenger\n> {\n /**\n * Creates a new ProfileController instance.\n *\n * @param options - Constructor options.\n * @param options.messenger - The messenger scoped to ProfileController.\n * @param options.state - Optional partial initial state to merge with defaults.\n */\n constructor({\n messenger,\n state,\n }: {\n messenger: ProfileControllerMessenger;\n state?: Partial<ProfileControllerState>;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: profileControllerMetadata,\n state: {\n ...getDefaultProfileControllerState(),\n ...state,\n },\n });\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Returns true if a profile has been created and exists in state.\n *\n * @returns True if a profile exists, false otherwise.\n */\n #hasProfile(): boolean {\n return this.state.profile.profileId !== '';\n }\n\n /**\n * Returns the profile ID from state, throwing if no profile exists yet.\n *\n * @returns The current profile ID.\n * @throws If no profile has been created.\n */\n #getProfileIdOrThrow(): string {\n const { profileId } = this.state.profile;\n if (!profileId) {\n throw new Error('ProfileController: no profile found in state');\n }\n return profileId;\n }\n\n /**\n * Maps an API response to a MetaMask profile.\n *\n * @param response - The API response to map.\n * @returns The mapped MetaMask profile.\n */\n #mapApiResponseToProfile(response: ProfileApiResponse): Profile {\n return {\n profileId: response.profile_id,\n username: response.username,\n displayName: response.display_name,\n bio: response.bio ?? '',\n linkedAddresses: response.linked_addresses,\n avatarUrl: response.avatar_url ?? '',\n tradingPrivacy: response.trading_privacy,\n connectedToX: response.connected_to_x,\n createdAt: response.created_at,\n updatedAt: response.updated_at,\n };\n }\n\n /**\n * Maps an API response to an X profile.\n *\n * @param response - The API response to map.\n * @returns The mapped X profile.\n */\n #mapXResponseToXProfile(response: XConnectResponse): XProfile {\n return {\n xUserId: response.x_user_id,\n xProfileUrl: response.x_profile_url,\n username: response.username,\n displayName: response.display_name,\n avatarUrl: response.avatar_url,\n createdAt: response.created_at,\n updatedAt: response.updated_at,\n };\n }\n\n /**\n * Returns the current MetaMask profile from state, or undefined if none has been created.\n *\n * @returns The MetaMask profile, or undefined.\n */\n getProfile(): Profile | undefined {\n if (!this.#hasProfile()) {\n return undefined;\n }\n return this.state.profile;\n }\n\n /**\n * Returns the currently linked X profile from state, or undefined if none has been connected.\n *\n * @returns The X profile, or undefined.\n */\n getXProfile(): XProfile | undefined {\n return this.state.xProfile;\n }\n\n /**\n * Creates a new MetaMask profile, updates state, and returns the created profile.\n * If the user had previously connected X, also updates xProfile in state.\n *\n * @param params - The profile creation parameters.\n * @returns The created MetaMask profile.\n */\n async createProfile(params: CreateProfileParams): Promise<Profile> {\n const response: CreateProfileResponse = await this.messenger.call(\n 'ProfileService:createProfile',\n params,\n );\n const mapped = this.#mapApiResponseToProfile(response);\n this.update((state) => {\n state.profile = mapped;\n if (response.x_profile) {\n state.xProfile = this.#mapXResponseToXProfile(response.x_profile);\n }\n });\n return mapped;\n }\n\n /**\n * Fully replaces the current profile and updates state.\n *\n * @param input - The replacement profile data.\n * @throws If no profile has been created yet.\n */\n async replaceProfile(input: ReplaceProfileParams): Promise<void> {\n const profileId = this.#getProfileIdOrThrow();\n const response = await this.messenger.call(\n 'ProfileService:replaceProfile',\n profileId,\n input,\n );\n this.update((state) => {\n state.profile = this.#mapApiResponseToProfile(response);\n });\n }\n\n /**\n * Partially updates the current profile and updates state.\n *\n * @param input - The fields to update.\n * @throws If no profile has been created yet.\n */\n async updateProfile(input: UpdateProfileParams): Promise<void> {\n const profileId = this.#getProfileIdOrThrow();\n const response = await this.messenger.call(\n 'ProfileService:updateProfile',\n profileId,\n input,\n );\n this.update((state) => {\n state.profile = this.#mapApiResponseToProfile(response);\n });\n }\n\n /**\n * Deletes the current profile and resets state, including clearing any linked X profile.\n *\n * @throws If no profile has been created yet.\n */\n async deleteProfile(): Promise<void> {\n const profileId = this.#getProfileIdOrThrow();\n await this.messenger.call('ProfileService:deleteProfile', profileId);\n this.update((state) => {\n state.profile = getDefaultProfileControllerState().profile;\n state.xProfile = undefined;\n });\n }\n\n /**\n * Checks whether a username is available.\n *\n * @param username - The username to check.\n * @returns Availability details including validity and normalized form.\n */\n async checkUsernameAvailability(\n username: string,\n ): Promise<UsernameAvailabilityResponse> {\n return await this.messenger.call(\n 'ProfileService:checkUsernameAvailability',\n username,\n );\n }\n\n /**\n * Completes the X OAuth PKCE flow, updates xProfile in state, and returns the X profile.\n *\n * @param params - The parameters for the X OAuth PKCE flow.\n * @param params.code - The OAuth authorization code from the X redirect.\n * @param params.state - The state parameter returned by the X redirect.\n * @returns The linked X profile.\n */\n async connectX(params: { code: string; state: string }): Promise<XProfile> {\n const response = await this.messenger.call(\n 'ProfileService:connectX',\n params,\n );\n return this.#mapXResponseToXProfile(response);\n }\n\n /**\n * Fetches the X account linked to the current profile, updates state, and returns the X profile.\n *\n * @returns The linked X profile.\n */\n async fetchAndUpdateXAccount(): Promise<XProfile> {\n const response = await this.messenger.call('ProfileService:getXAccount');\n const mapped = this.#mapXResponseToXProfile(response);\n this.update((state) => {\n state.xProfile = mapped;\n });\n return mapped;\n }\n}\n"]}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is auto generated.
|
|
3
|
+
* Do not edit manually.
|
|
4
|
+
*/
|
|
5
|
+
import type { ProfileService } from './ProfileService.js';
|
|
6
|
+
/**
|
|
7
|
+
* Fetches a profile by its identifier.
|
|
8
|
+
*
|
|
9
|
+
* @param profileId - The profile identifier to fetch.
|
|
10
|
+
* @returns The profile data from the API.
|
|
11
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
12
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
13
|
+
*/
|
|
14
|
+
export type ProfileServiceGetProfileAction = {
|
|
15
|
+
type: `ProfileService:getProfile`;
|
|
16
|
+
handler: ProfileService['getProfile'];
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new MetaMask profile.
|
|
20
|
+
*
|
|
21
|
+
* @param params - The profile creation parameters.
|
|
22
|
+
* @returns The created profile data.
|
|
23
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
24
|
+
* @throws {StructError} If the response do not match the expected shape.
|
|
25
|
+
*/
|
|
26
|
+
export type ProfileServiceCreateProfileAction = {
|
|
27
|
+
type: `ProfileService:createProfile`;
|
|
28
|
+
handler: ProfileService['createProfile'];
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Fully replaces an existing profile (PUT).
|
|
32
|
+
*
|
|
33
|
+
* @param profileId - The identifier of the profile to replace.
|
|
34
|
+
* @param params - The replacement profile data.
|
|
35
|
+
* @returns The updated profile data.
|
|
36
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
37
|
+
* @throws {StructError} If the response do not match the expected shape.
|
|
38
|
+
*/
|
|
39
|
+
export type ProfileServiceReplaceProfileAction = {
|
|
40
|
+
type: `ProfileService:replaceProfile`;
|
|
41
|
+
handler: ProfileService['replaceProfile'];
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Partially updates an existing profile (PATCH).
|
|
45
|
+
*
|
|
46
|
+
* @param profileId - The identifier of the profile to update.
|
|
47
|
+
* @param params - The fields to update.
|
|
48
|
+
* @returns The updated profile data.
|
|
49
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
50
|
+
* @throws {StructError} If the response do not match the expected shape.
|
|
51
|
+
*/
|
|
52
|
+
export type ProfileServiceUpdateProfileAction = {
|
|
53
|
+
type: `ProfileService:updateProfile`;
|
|
54
|
+
handler: ProfileService['updateProfile'];
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Deletes a profile by its identifier.
|
|
58
|
+
*
|
|
59
|
+
* @param profileId - The identifier of the profile to delete.
|
|
60
|
+
* @returns The result of the mutation.
|
|
61
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
62
|
+
*/
|
|
63
|
+
export type ProfileServiceDeleteProfileAction = {
|
|
64
|
+
type: `ProfileService:deleteProfile`;
|
|
65
|
+
handler: ProfileService['deleteProfile'];
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Checks whether a username is available.
|
|
69
|
+
*
|
|
70
|
+
* @param username - The username to check.
|
|
71
|
+
* @returns Availability details including validity and normalized form.
|
|
72
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
73
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
74
|
+
*/
|
|
75
|
+
export type ProfileServiceCheckUsernameAvailabilityAction = {
|
|
76
|
+
type: `ProfileService:checkUsernameAvailability`;
|
|
77
|
+
handler: ProfileService['checkUsernameAvailability'];
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Fetches the X OAuth PKCE authorization URL and its associated state parameter.
|
|
81
|
+
*
|
|
82
|
+
* @returns An object containing the authorization URL and the state token.
|
|
83
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
84
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
85
|
+
*/
|
|
86
|
+
export type ProfileServiceGetXAuthUrlAction = {
|
|
87
|
+
type: `ProfileService:getXAuthUrl`;
|
|
88
|
+
handler: ProfileService['getXAuthUrl'];
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Completes the X OAuth PKCE flow and links the X account to the profile.
|
|
92
|
+
*
|
|
93
|
+
* @param params - The OAuth callback code and state from the X redirect.
|
|
94
|
+
* @returns The linked X account data.
|
|
95
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
96
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
97
|
+
*/
|
|
98
|
+
export type ProfileServiceConnectXAction = {
|
|
99
|
+
type: `ProfileService:connectX`;
|
|
100
|
+
handler: ProfileService['connectX'];
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Fetches the X account currently linked to the authenticated profile.
|
|
104
|
+
*
|
|
105
|
+
* @returns The linked X account data.
|
|
106
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
107
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
108
|
+
*/
|
|
109
|
+
export type ProfileServiceGetXAccountAction = {
|
|
110
|
+
type: `ProfileService:getXAccount`;
|
|
111
|
+
handler: ProfileService['getXAccount'];
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Union of all ProfileService action types.
|
|
115
|
+
*/
|
|
116
|
+
export type ProfileServiceMethodActions = ProfileServiceGetProfileAction | ProfileServiceCreateProfileAction | ProfileServiceReplaceProfileAction | ProfileServiceUpdateProfileAction | ProfileServiceDeleteProfileAction | ProfileServiceCheckUsernameAvailabilityAction | ProfileServiceGetXAuthUrlAction | ProfileServiceConnectXAction | ProfileServiceGetXAccountAction;
|
|
117
|
+
//# sourceMappingURL=ProfileService-method-action-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProfileService-method-action-types.d.ts","sourceRoot":"","sources":["../src/ProfileService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,MAAM,8BAA8B,GAAG;IAC3C,IAAI,EAAE,2BAA2B,CAAC;IAClC,OAAO,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;CACvC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,IAAI,EAAE,8BAA8B,CAAC;IACrC,OAAO,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;CAC1C,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,EAAE,+BAA+B,CAAC;IACtC,OAAO,EAAE,cAAc,CAAC,gBAAgB,CAAC,CAAC;CAC3C,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,IAAI,EAAE,8BAA8B,CAAC;IACrC,OAAO,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;CAC1C,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,IAAI,EAAE,8BAA8B,CAAC;IACrC,OAAO,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;CAC1C,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,6CAA6C,GAAG;IAC1D,IAAI,EAAE,0CAA0C,CAAC;IACjD,OAAO,EAAE,cAAc,CAAC,2BAA2B,CAAC,CAAC;CACtD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,4BAA4B,CAAC;IACnC,OAAO,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;CACxC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,IAAI,EAAE,yBAAyB,CAAC;IAChC,OAAO,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;CACrC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,4BAA4B,CAAC;IACnC,OAAO,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;CACxC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,2BAA2B,GACnC,8BAA8B,GAC9B,iCAAiC,GACjC,kCAAkC,GAClC,iCAAiC,GACjC,iCAAiC,GACjC,6CAA6C,GAC7C,+BAA+B,GAC/B,4BAA4B,GAC5B,+BAA+B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProfileService-method-action-types.js","sourceRoot":"","sources":["../src/ProfileService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { ProfileService } from './ProfileService.js';\n\n/**\n * Fetches a profile by its identifier.\n *\n * @param profileId - The profile identifier to fetch.\n * @returns The profile data from the API.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceGetProfileAction = {\n type: `ProfileService:getProfile`;\n handler: ProfileService['getProfile'];\n};\n\n/**\n * Creates a new MetaMask profile.\n *\n * @param params - The profile creation parameters.\n * @returns The created profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\nexport type ProfileServiceCreateProfileAction = {\n type: `ProfileService:createProfile`;\n handler: ProfileService['createProfile'];\n};\n\n/**\n * Fully replaces an existing profile (PUT).\n *\n * @param profileId - The identifier of the profile to replace.\n * @param params - The replacement profile data.\n * @returns The updated profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\nexport type ProfileServiceReplaceProfileAction = {\n type: `ProfileService:replaceProfile`;\n handler: ProfileService['replaceProfile'];\n};\n\n/**\n * Partially updates an existing profile (PATCH).\n *\n * @param profileId - The identifier of the profile to update.\n * @param params - The fields to update.\n * @returns The updated profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\nexport type ProfileServiceUpdateProfileAction = {\n type: `ProfileService:updateProfile`;\n handler: ProfileService['updateProfile'];\n};\n\n/**\n * Deletes a profile by its identifier.\n *\n * @param profileId - The identifier of the profile to delete.\n * @returns The result of the mutation.\n * @throws {HttpError} If the API returns a non-2xx response.\n */\nexport type ProfileServiceDeleteProfileAction = {\n type: `ProfileService:deleteProfile`;\n handler: ProfileService['deleteProfile'];\n};\n\n/**\n * Checks whether a username is available.\n *\n * @param username - The username to check.\n * @returns Availability details including validity and normalized form.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceCheckUsernameAvailabilityAction = {\n type: `ProfileService:checkUsernameAvailability`;\n handler: ProfileService['checkUsernameAvailability'];\n};\n\n/**\n * Fetches the X OAuth PKCE authorization URL and its associated state parameter.\n *\n * @returns An object containing the authorization URL and the state token.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceGetXAuthUrlAction = {\n type: `ProfileService:getXAuthUrl`;\n handler: ProfileService['getXAuthUrl'];\n};\n\n/**\n * Completes the X OAuth PKCE flow and links the X account to the profile.\n *\n * @param params - The OAuth callback code and state from the X redirect.\n * @returns The linked X account data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceConnectXAction = {\n type: `ProfileService:connectX`;\n handler: ProfileService['connectX'];\n};\n\n/**\n * Fetches the X account currently linked to the authenticated profile.\n *\n * @returns The linked X account data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceGetXAccountAction = {\n type: `ProfileService:getXAccount`;\n handler: ProfileService['getXAccount'];\n};\n\n/**\n * Union of all ProfileService action types.\n */\nexport type ProfileServiceMethodActions =\n | ProfileServiceGetProfileAction\n | ProfileServiceCreateProfileAction\n | ProfileServiceReplaceProfileAction\n | ProfileServiceUpdateProfileAction\n | ProfileServiceDeleteProfileAction\n | ProfileServiceCheckUsernameAvailabilityAction\n | ProfileServiceGetXAuthUrlAction\n | ProfileServiceConnectXAction\n | ProfileServiceGetXAccountAction;\n"]}
|