@metamask-previews/kyc-controller 0.0.0-preview-11d78534e
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 +21 -0
- package/LICENSE +6 -0
- package/LICENSE.APACHE2 +201 -0
- package/LICENSE.MIT +21 -0
- package/README.md +648 -0
- package/dist/KycController-method-action-types.cjs +7 -0
- package/dist/KycController-method-action-types.cjs.map +1 -0
- package/dist/KycController-method-action-types.d.cts +143 -0
- package/dist/KycController-method-action-types.d.cts.map +1 -0
- package/dist/KycController-method-action-types.d.mts +143 -0
- package/dist/KycController-method-action-types.d.mts.map +1 -0
- package/dist/KycController-method-action-types.mjs +6 -0
- package/dist/KycController-method-action-types.mjs.map +1 -0
- package/dist/KycController.cjs +800 -0
- package/dist/KycController.cjs.map +1 -0
- package/dist/KycController.d.cts +219 -0
- package/dist/KycController.d.cts.map +1 -0
- package/dist/KycController.d.mts +219 -0
- package/dist/KycController.d.mts.map +1 -0
- package/dist/KycController.mjs +795 -0
- package/dist/KycController.mjs.map +1 -0
- package/dist/KycService-method-action-types.cjs +7 -0
- package/dist/KycService-method-action-types.cjs.map +1 -0
- package/dist/KycService-method-action-types.d.cts +74 -0
- package/dist/KycService-method-action-types.d.cts.map +1 -0
- package/dist/KycService-method-action-types.d.mts +74 -0
- package/dist/KycService-method-action-types.d.mts.map +1 -0
- package/dist/KycService-method-action-types.mjs +6 -0
- package/dist/KycService-method-action-types.mjs.map +1 -0
- package/dist/KycService.cjs +238 -0
- package/dist/KycService.cjs.map +1 -0
- package/dist/KycService.d.cts +169 -0
- package/dist/KycService.d.cts.map +1 -0
- package/dist/KycService.d.mts +169 -0
- package/dist/KycService.d.mts.map +1 -0
- package/dist/KycService.mjs +234 -0
- package/dist/KycService.mjs.map +1 -0
- package/dist/countryCodes.cjs +274 -0
- package/dist/countryCodes.cjs.map +1 -0
- package/dist/countryCodes.d.cts +18 -0
- package/dist/countryCodes.d.cts.map +1 -0
- package/dist/countryCodes.d.mts +18 -0
- package/dist/countryCodes.d.mts.map +1 -0
- package/dist/countryCodes.mjs +270 -0
- package/dist/countryCodes.mjs.map +1 -0
- package/dist/crypto.cjs +165 -0
- package/dist/crypto.cjs.map +1 -0
- package/dist/crypto.d.cts +83 -0
- package/dist/crypto.d.cts.map +1 -0
- package/dist/crypto.d.mts +83 -0
- package/dist/crypto.d.mts.map +1 -0
- package/dist/crypto.mjs +160 -0
- package/dist/crypto.mjs.map +1 -0
- package/dist/index.cjs +21 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +12 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +12 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +6 -0
- package/dist/index.mjs.map +1 -0
- package/dist/selectors.cjs +30 -0
- package/dist/selectors.cjs.map +1 -0
- package/dist/selectors.d.cts +24 -0
- package/dist/selectors.d.cts.map +1 -0
- package/dist/selectors.d.mts +24 -0
- package/dist/selectors.d.mts.map +1 -0
- package/dist/selectors.mjs +24 -0
- package/dist/selectors.mjs.map +1 -0
- package/dist/types.cjs +10 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +93 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +93 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +9 -0
- package/dist/types.mjs.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import type { CreateServicePolicyOptions } from "@metamask/controller-utils";
|
|
2
|
+
import type { GeolocationControllerGetGeolocationAction } from "@metamask/geolocation-controller";
|
|
3
|
+
import type { Messenger } from "@metamask/messenger";
|
|
4
|
+
import type { AuthenticationControllerGetBearerTokenAction } from "@metamask/profile-sync-controller/auth";
|
|
5
|
+
import type { Infer, Struct } from "@metamask/superstruct";
|
|
6
|
+
import type { KycServiceMethodActions } from "./KycService-method-action-types.cjs";
|
|
7
|
+
import type { KycDisclaimer } from "./types.cjs";
|
|
8
|
+
/**
|
|
9
|
+
* The name of the {@link KycService}, used to namespace the service's actions.
|
|
10
|
+
*/
|
|
11
|
+
export declare const serviceName = "KycService";
|
|
12
|
+
/**
|
|
13
|
+
* The supported environments for the Universal KYC API.
|
|
14
|
+
*/
|
|
15
|
+
export type KycServiceEnvironment = 'production' | 'development';
|
|
16
|
+
/**
|
|
17
|
+
* Actions that {@link KycService} exposes to other consumers.
|
|
18
|
+
*/
|
|
19
|
+
export type KycServiceActions = KycServiceMethodActions;
|
|
20
|
+
/**
|
|
21
|
+
* Actions from other messengers that {@link KycService} calls.
|
|
22
|
+
*/
|
|
23
|
+
type AllowedActions = AuthenticationControllerGetBearerTokenAction | GeolocationControllerGetGeolocationAction;
|
|
24
|
+
/**
|
|
25
|
+
* Events that {@link KycService} exposes to other consumers.
|
|
26
|
+
*/
|
|
27
|
+
export type KycServiceEvents = never;
|
|
28
|
+
/**
|
|
29
|
+
* Events from other messengers that {@link KycService} subscribes to.
|
|
30
|
+
*/
|
|
31
|
+
type AllowedEvents = never;
|
|
32
|
+
/**
|
|
33
|
+
* The messenger restricted to actions and events accessed by
|
|
34
|
+
* {@link KycService}.
|
|
35
|
+
*/
|
|
36
|
+
export type KycServiceMessenger = Messenger<typeof serviceName, KycServiceActions | AllowedActions, KycServiceEvents | AllowedEvents>;
|
|
37
|
+
/**
|
|
38
|
+
* Options for constructing a {@link KycService}.
|
|
39
|
+
*/
|
|
40
|
+
export type KycServiceOptions = {
|
|
41
|
+
messenger: KycServiceMessenger;
|
|
42
|
+
fetch: typeof fetch;
|
|
43
|
+
env: KycServiceEnvironment;
|
|
44
|
+
/**
|
|
45
|
+
* Overrides the base URL derived from `env`. When provided, this value is
|
|
46
|
+
* used verbatim as the base URL for all requests, which is useful for
|
|
47
|
+
* targeting a local or staging KYC API.
|
|
48
|
+
*/
|
|
49
|
+
baseUrl?: string;
|
|
50
|
+
policyOptions?: CreateServicePolicyOptions;
|
|
51
|
+
};
|
|
52
|
+
declare const CreateSessionResponseStruct: Struct<{
|
|
53
|
+
sessionToken: string;
|
|
54
|
+
}, {
|
|
55
|
+
sessionToken: Struct<string, null>;
|
|
56
|
+
}>;
|
|
57
|
+
declare const UkycSessionResponseStruct: Struct<{
|
|
58
|
+
sessionId: string;
|
|
59
|
+
wrappingPublicKey: string;
|
|
60
|
+
idosSessionId: string;
|
|
61
|
+
}, {
|
|
62
|
+
sessionId: Struct<string, null>;
|
|
63
|
+
wrappingPublicKey: Struct<string, null>;
|
|
64
|
+
idosSessionId: Struct<string, null>;
|
|
65
|
+
}>;
|
|
66
|
+
export type UkycSessionResponse = Infer<typeof UkycSessionResponseStruct>;
|
|
67
|
+
declare const WrappedKeyResponseStruct: Struct<{
|
|
68
|
+
status: string;
|
|
69
|
+
applicantAccessToken: string;
|
|
70
|
+
}, {
|
|
71
|
+
status: Struct<string, null>;
|
|
72
|
+
applicantAccessToken: Struct<string, null>;
|
|
73
|
+
}>;
|
|
74
|
+
export type WrappedKeyResponse = Infer<typeof WrappedKeyResponseStruct>;
|
|
75
|
+
export type CreateSessionParams = {
|
|
76
|
+
email: string;
|
|
77
|
+
termsAcceptedAt: string;
|
|
78
|
+
disclaimerIds: string[];
|
|
79
|
+
};
|
|
80
|
+
export type CheckKycRequiredParams = {
|
|
81
|
+
accessToken: string;
|
|
82
|
+
country: string;
|
|
83
|
+
capabilities?: {
|
|
84
|
+
product: string;
|
|
85
|
+
}[];
|
|
86
|
+
};
|
|
87
|
+
export type CreateUkycSessionParams = {
|
|
88
|
+
jwtToken: string;
|
|
89
|
+
vendorMetadata: Record<string, unknown>;
|
|
90
|
+
};
|
|
91
|
+
export type SubmitWrappedKeyParams = {
|
|
92
|
+
sessionId: string;
|
|
93
|
+
wrappedUserKey: string;
|
|
94
|
+
idosSessionId: string;
|
|
95
|
+
jwtToken: string;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* `KycService` communicates with the Universal KYC (UKYC) backend to drive the
|
|
99
|
+
* identity + document-verification flow. It is stateless and platform-agnostic:
|
|
100
|
+
* HTTP is performed through an injected `fetch`, and the auth bearer token and
|
|
101
|
+
* geolocation come from other controllers via the messenger.
|
|
102
|
+
*/
|
|
103
|
+
export declare class KycService {
|
|
104
|
+
#private;
|
|
105
|
+
readonly name: typeof serviceName;
|
|
106
|
+
/**
|
|
107
|
+
* Constructs a new KycService.
|
|
108
|
+
*
|
|
109
|
+
* @param options - The constructor options.
|
|
110
|
+
* @param options.messenger - The messenger suited for this service.
|
|
111
|
+
* @param options.fetch - A function used to make HTTP requests.
|
|
112
|
+
* @param options.env - The environment; determines the base URL.
|
|
113
|
+
* @param options.baseUrl - Overrides the base URL derived from `env`.
|
|
114
|
+
* @param options.policyOptions - Options for the request service policy.
|
|
115
|
+
*/
|
|
116
|
+
constructor({ messenger, fetch: fetchFunction, env, baseUrl, policyOptions, }: KycServiceOptions);
|
|
117
|
+
/**
|
|
118
|
+
* Resolves the customer's country from the geolocation source and converts it
|
|
119
|
+
* to an ISO 3166-1 alpha-3 code.
|
|
120
|
+
*
|
|
121
|
+
* @returns The alpha-3 country code.
|
|
122
|
+
* @throws If the country cannot be determined or mapped.
|
|
123
|
+
*/
|
|
124
|
+
getGeoCountry(): Promise<string>;
|
|
125
|
+
/**
|
|
126
|
+
* Fetches the disclaimers the customer must accept before a session is
|
|
127
|
+
* created.
|
|
128
|
+
*
|
|
129
|
+
* @param params - The parameters.
|
|
130
|
+
* @param params.country - ISO 3166-1 alpha-3 country code.
|
|
131
|
+
* @returns The disclaimers.
|
|
132
|
+
*/
|
|
133
|
+
fetchDisclaimers({ country, }: {
|
|
134
|
+
country: string;
|
|
135
|
+
}): Promise<KycDisclaimer[]>;
|
|
136
|
+
/**
|
|
137
|
+
* Creates a vendor session via the UKYC backend.
|
|
138
|
+
*
|
|
139
|
+
* @param params - The session parameters.
|
|
140
|
+
* @returns The created session token.
|
|
141
|
+
*/
|
|
142
|
+
createSession(params: CreateSessionParams): Promise<Infer<typeof CreateSessionResponseStruct>>;
|
|
143
|
+
/**
|
|
144
|
+
* Checks whether KYC is required for the given access token, country, and
|
|
145
|
+
* capabilities.
|
|
146
|
+
*
|
|
147
|
+
* @param params - The check parameters.
|
|
148
|
+
* @returns Whether KYC is required.
|
|
149
|
+
*/
|
|
150
|
+
checkKycRequired(params: CheckKycRequiredParams): Promise<{
|
|
151
|
+
kycRequired: boolean;
|
|
152
|
+
}>;
|
|
153
|
+
/**
|
|
154
|
+
* Creates a UKYC session for the SumSub document-verification sub-flow.
|
|
155
|
+
*
|
|
156
|
+
* @param params - The session parameters.
|
|
157
|
+
* @returns The UKYC session identifiers and wrapped key.
|
|
158
|
+
*/
|
|
159
|
+
createUkycSession(params: CreateUkycSessionParams): Promise<UkycSessionResponse>;
|
|
160
|
+
/**
|
|
161
|
+
* Exchanges the wrapped user key for a SumSub applicant access token.
|
|
162
|
+
*
|
|
163
|
+
* @param params - The exchange parameters.
|
|
164
|
+
* @returns The applicant access token and status.
|
|
165
|
+
*/
|
|
166
|
+
submitWrappedKey(params: SubmitWrappedKeyParams): Promise<WrappedKeyResponse>;
|
|
167
|
+
}
|
|
168
|
+
export {};
|
|
169
|
+
//# sourceMappingURL=KycService.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KycService.d.cts","sourceRoot":"","sources":["../src/KycService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import type { CreateServicePolicyOptions } from "@metamask/controller-utils";
|
|
2
|
+
import type { GeolocationControllerGetGeolocationAction } from "@metamask/geolocation-controller";
|
|
3
|
+
import type { Messenger } from "@metamask/messenger";
|
|
4
|
+
import type { AuthenticationControllerGetBearerTokenAction } from "@metamask/profile-sync-controller/auth";
|
|
5
|
+
import type { Infer, Struct } from "@metamask/superstruct";
|
|
6
|
+
import type { KycServiceMethodActions } from "./KycService-method-action-types.mjs";
|
|
7
|
+
import type { KycDisclaimer } from "./types.mjs";
|
|
8
|
+
/**
|
|
9
|
+
* The name of the {@link KycService}, used to namespace the service's actions.
|
|
10
|
+
*/
|
|
11
|
+
export declare const serviceName = "KycService";
|
|
12
|
+
/**
|
|
13
|
+
* The supported environments for the Universal KYC API.
|
|
14
|
+
*/
|
|
15
|
+
export type KycServiceEnvironment = 'production' | 'development';
|
|
16
|
+
/**
|
|
17
|
+
* Actions that {@link KycService} exposes to other consumers.
|
|
18
|
+
*/
|
|
19
|
+
export type KycServiceActions = KycServiceMethodActions;
|
|
20
|
+
/**
|
|
21
|
+
* Actions from other messengers that {@link KycService} calls.
|
|
22
|
+
*/
|
|
23
|
+
type AllowedActions = AuthenticationControllerGetBearerTokenAction | GeolocationControllerGetGeolocationAction;
|
|
24
|
+
/**
|
|
25
|
+
* Events that {@link KycService} exposes to other consumers.
|
|
26
|
+
*/
|
|
27
|
+
export type KycServiceEvents = never;
|
|
28
|
+
/**
|
|
29
|
+
* Events from other messengers that {@link KycService} subscribes to.
|
|
30
|
+
*/
|
|
31
|
+
type AllowedEvents = never;
|
|
32
|
+
/**
|
|
33
|
+
* The messenger restricted to actions and events accessed by
|
|
34
|
+
* {@link KycService}.
|
|
35
|
+
*/
|
|
36
|
+
export type KycServiceMessenger = Messenger<typeof serviceName, KycServiceActions | AllowedActions, KycServiceEvents | AllowedEvents>;
|
|
37
|
+
/**
|
|
38
|
+
* Options for constructing a {@link KycService}.
|
|
39
|
+
*/
|
|
40
|
+
export type KycServiceOptions = {
|
|
41
|
+
messenger: KycServiceMessenger;
|
|
42
|
+
fetch: typeof fetch;
|
|
43
|
+
env: KycServiceEnvironment;
|
|
44
|
+
/**
|
|
45
|
+
* Overrides the base URL derived from `env`. When provided, this value is
|
|
46
|
+
* used verbatim as the base URL for all requests, which is useful for
|
|
47
|
+
* targeting a local or staging KYC API.
|
|
48
|
+
*/
|
|
49
|
+
baseUrl?: string;
|
|
50
|
+
policyOptions?: CreateServicePolicyOptions;
|
|
51
|
+
};
|
|
52
|
+
declare const CreateSessionResponseStruct: Struct<{
|
|
53
|
+
sessionToken: string;
|
|
54
|
+
}, {
|
|
55
|
+
sessionToken: Struct<string, null>;
|
|
56
|
+
}>;
|
|
57
|
+
declare const UkycSessionResponseStruct: Struct<{
|
|
58
|
+
sessionId: string;
|
|
59
|
+
wrappingPublicKey: string;
|
|
60
|
+
idosSessionId: string;
|
|
61
|
+
}, {
|
|
62
|
+
sessionId: Struct<string, null>;
|
|
63
|
+
wrappingPublicKey: Struct<string, null>;
|
|
64
|
+
idosSessionId: Struct<string, null>;
|
|
65
|
+
}>;
|
|
66
|
+
export type UkycSessionResponse = Infer<typeof UkycSessionResponseStruct>;
|
|
67
|
+
declare const WrappedKeyResponseStruct: Struct<{
|
|
68
|
+
status: string;
|
|
69
|
+
applicantAccessToken: string;
|
|
70
|
+
}, {
|
|
71
|
+
status: Struct<string, null>;
|
|
72
|
+
applicantAccessToken: Struct<string, null>;
|
|
73
|
+
}>;
|
|
74
|
+
export type WrappedKeyResponse = Infer<typeof WrappedKeyResponseStruct>;
|
|
75
|
+
export type CreateSessionParams = {
|
|
76
|
+
email: string;
|
|
77
|
+
termsAcceptedAt: string;
|
|
78
|
+
disclaimerIds: string[];
|
|
79
|
+
};
|
|
80
|
+
export type CheckKycRequiredParams = {
|
|
81
|
+
accessToken: string;
|
|
82
|
+
country: string;
|
|
83
|
+
capabilities?: {
|
|
84
|
+
product: string;
|
|
85
|
+
}[];
|
|
86
|
+
};
|
|
87
|
+
export type CreateUkycSessionParams = {
|
|
88
|
+
jwtToken: string;
|
|
89
|
+
vendorMetadata: Record<string, unknown>;
|
|
90
|
+
};
|
|
91
|
+
export type SubmitWrappedKeyParams = {
|
|
92
|
+
sessionId: string;
|
|
93
|
+
wrappedUserKey: string;
|
|
94
|
+
idosSessionId: string;
|
|
95
|
+
jwtToken: string;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* `KycService` communicates with the Universal KYC (UKYC) backend to drive the
|
|
99
|
+
* identity + document-verification flow. It is stateless and platform-agnostic:
|
|
100
|
+
* HTTP is performed through an injected `fetch`, and the auth bearer token and
|
|
101
|
+
* geolocation come from other controllers via the messenger.
|
|
102
|
+
*/
|
|
103
|
+
export declare class KycService {
|
|
104
|
+
#private;
|
|
105
|
+
readonly name: typeof serviceName;
|
|
106
|
+
/**
|
|
107
|
+
* Constructs a new KycService.
|
|
108
|
+
*
|
|
109
|
+
* @param options - The constructor options.
|
|
110
|
+
* @param options.messenger - The messenger suited for this service.
|
|
111
|
+
* @param options.fetch - A function used to make HTTP requests.
|
|
112
|
+
* @param options.env - The environment; determines the base URL.
|
|
113
|
+
* @param options.baseUrl - Overrides the base URL derived from `env`.
|
|
114
|
+
* @param options.policyOptions - Options for the request service policy.
|
|
115
|
+
*/
|
|
116
|
+
constructor({ messenger, fetch: fetchFunction, env, baseUrl, policyOptions, }: KycServiceOptions);
|
|
117
|
+
/**
|
|
118
|
+
* Resolves the customer's country from the geolocation source and converts it
|
|
119
|
+
* to an ISO 3166-1 alpha-3 code.
|
|
120
|
+
*
|
|
121
|
+
* @returns The alpha-3 country code.
|
|
122
|
+
* @throws If the country cannot be determined or mapped.
|
|
123
|
+
*/
|
|
124
|
+
getGeoCountry(): Promise<string>;
|
|
125
|
+
/**
|
|
126
|
+
* Fetches the disclaimers the customer must accept before a session is
|
|
127
|
+
* created.
|
|
128
|
+
*
|
|
129
|
+
* @param params - The parameters.
|
|
130
|
+
* @param params.country - ISO 3166-1 alpha-3 country code.
|
|
131
|
+
* @returns The disclaimers.
|
|
132
|
+
*/
|
|
133
|
+
fetchDisclaimers({ country, }: {
|
|
134
|
+
country: string;
|
|
135
|
+
}): Promise<KycDisclaimer[]>;
|
|
136
|
+
/**
|
|
137
|
+
* Creates a vendor session via the UKYC backend.
|
|
138
|
+
*
|
|
139
|
+
* @param params - The session parameters.
|
|
140
|
+
* @returns The created session token.
|
|
141
|
+
*/
|
|
142
|
+
createSession(params: CreateSessionParams): Promise<Infer<typeof CreateSessionResponseStruct>>;
|
|
143
|
+
/**
|
|
144
|
+
* Checks whether KYC is required for the given access token, country, and
|
|
145
|
+
* capabilities.
|
|
146
|
+
*
|
|
147
|
+
* @param params - The check parameters.
|
|
148
|
+
* @returns Whether KYC is required.
|
|
149
|
+
*/
|
|
150
|
+
checkKycRequired(params: CheckKycRequiredParams): Promise<{
|
|
151
|
+
kycRequired: boolean;
|
|
152
|
+
}>;
|
|
153
|
+
/**
|
|
154
|
+
* Creates a UKYC session for the SumSub document-verification sub-flow.
|
|
155
|
+
*
|
|
156
|
+
* @param params - The session parameters.
|
|
157
|
+
* @returns The UKYC session identifiers and wrapped key.
|
|
158
|
+
*/
|
|
159
|
+
createUkycSession(params: CreateUkycSessionParams): Promise<UkycSessionResponse>;
|
|
160
|
+
/**
|
|
161
|
+
* Exchanges the wrapped user key for a SumSub applicant access token.
|
|
162
|
+
*
|
|
163
|
+
* @param params - The exchange parameters.
|
|
164
|
+
* @returns The applicant access token and status.
|
|
165
|
+
*/
|
|
166
|
+
submitWrappedKey(params: SubmitWrappedKeyParams): Promise<WrappedKeyResponse>;
|
|
167
|
+
}
|
|
168
|
+
export {};
|
|
169
|
+
//# sourceMappingURL=KycService.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KycService.d.mts","sourceRoot":"","sources":["../src/KycService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAE3B,mCAAmC;AAEpC,OAAO,KAAK,EAAE,yCAAyC,EAAE,yCAAyC;AAClG,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAAE,4CAA4C,EAAE,+CAA+C;AAC3G,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B;AAW3D,OAAO,KAAK,EAAE,uBAAuB,EAAE,6CAAyC;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAgB;AAI7C;;GAEG;AACH,eAAO,MAAM,WAAW,eAAe,CAAC;AAExC;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,YAAY,GAAG,aAAa,CAAC;AAkBjE;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,uBAAuB,CAAC;AAExD;;GAEG;AACH,KAAK,cAAc,GACf,4CAA4C,GAC5C,yCAAyC,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAErC;;GAEG;AACH,KAAK,aAAa,GAAG,KAAK,CAAC;AAE3B;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,CACzC,OAAO,WAAW,EAClB,iBAAiB,GAAG,cAAc,EAClC,gBAAgB,GAAG,aAAa,CACjC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,mBAAmB,CAAC;IAC/B,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,GAAG,EAAE,qBAAqB,CAAC;IAC3B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,0BAA0B,CAAC;CAC5C,CAAC;AAWF,QAAA,MAAM,2BAA2B;;;;EAAmC,CAAC;AAMrE,QAAA,MAAM,yBAAyB;;;;;;;;EAI7B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE1E,QAAA,MAAM,wBAAwB;;;;;;EAG5B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAIxE,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAIF;;;;;GAKG;AACH,qBAAa,UAAU;;IACrB,QAAQ,CAAC,IAAI,EAAE,OAAO,WAAW,CAAC;IAUlC;;;;;;;;;OASG;gBACS,EACV,SAAS,EACT,KAAK,EAAE,aAAa,EACpB,GAAG,EACH,OAAO,EACP,aAAa,GACd,EAAE,iBAAiB;IAYpB;;;;;;OAMG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IA0BtC;;;;;;;OAOG;IACG,gBAAgB,CAAC,EACrB,OAAO,GACR,EAAE;QACD,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAW5B;;;;;OAKG;IACG,aAAa,CACjB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;IAarD;;;;;;OAMG;IACG,gBAAgB,CACpB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;IAkBpC;;;;;OAKG;IACG,iBAAiB,CACrB,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,mBAAmB,CAAC;IAkB/B;;;;;OAKG;IACG,gBAAgB,CACpB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,kBAAkB,CAAC;CA0F/B"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _KycService_instances, _KycService_messenger, _KycService_fetch, _KycService_baseUrl, _KycService_policy, _KycService_validateResponse, _KycService_request;
|
|
13
|
+
import { createServicePolicy, HttpError } from "@metamask/controller-utils";
|
|
14
|
+
import { array, assert, boolean, string, StructError, type } from "@metamask/superstruct";
|
|
15
|
+
import { alpha2ToAlpha3 } from "./countryCodes.mjs";
|
|
16
|
+
// === GENERAL ===
|
|
17
|
+
/**
|
|
18
|
+
* The name of the {@link KycService}, used to namespace the service's actions.
|
|
19
|
+
*/
|
|
20
|
+
export const serviceName = 'KycService';
|
|
21
|
+
const KYC_API_URLS = {
|
|
22
|
+
production: 'https://kyc-api.cx.metamask.io',
|
|
23
|
+
development: 'https://kyc-api.dev-api.cx.metamask.io',
|
|
24
|
+
};
|
|
25
|
+
// === MESSENGER ===
|
|
26
|
+
const MESSENGER_EXPOSED_METHODS = [
|
|
27
|
+
'getGeoCountry',
|
|
28
|
+
'fetchDisclaimers',
|
|
29
|
+
'createSession',
|
|
30
|
+
'checkKycRequired',
|
|
31
|
+
'createUkycSession',
|
|
32
|
+
'submitWrappedKey',
|
|
33
|
+
];
|
|
34
|
+
// === API RESPONSE SCHEMAS ===
|
|
35
|
+
const DisclaimerStruct = type({
|
|
36
|
+
id: string(),
|
|
37
|
+
display_name: string(),
|
|
38
|
+
url: string(),
|
|
39
|
+
});
|
|
40
|
+
const DisclaimersResponseStruct = array(DisclaimerStruct);
|
|
41
|
+
const CreateSessionResponseStruct = type({ sessionToken: string() });
|
|
42
|
+
// The live KYC API returns the flag under `required`; the service normalizes
|
|
43
|
+
// this to `kycRequired` for consumers (see `checkKycRequired`).
|
|
44
|
+
const KycRequiredResponseStruct = type({ required: boolean() });
|
|
45
|
+
const UkycSessionResponseStruct = type({
|
|
46
|
+
sessionId: string(),
|
|
47
|
+
wrappingPublicKey: string(),
|
|
48
|
+
idosSessionId: string(),
|
|
49
|
+
});
|
|
50
|
+
const WrappedKeyResponseStruct = type({
|
|
51
|
+
status: string(),
|
|
52
|
+
applicantAccessToken: string(),
|
|
53
|
+
});
|
|
54
|
+
// === SERVICE DEFINITION ===
|
|
55
|
+
/**
|
|
56
|
+
* `KycService` communicates with the Universal KYC (UKYC) backend to drive the
|
|
57
|
+
* identity + document-verification flow. It is stateless and platform-agnostic:
|
|
58
|
+
* HTTP is performed through an injected `fetch`, and the auth bearer token and
|
|
59
|
+
* geolocation come from other controllers via the messenger.
|
|
60
|
+
*/
|
|
61
|
+
export class KycService {
|
|
62
|
+
/**
|
|
63
|
+
* Constructs a new KycService.
|
|
64
|
+
*
|
|
65
|
+
* @param options - The constructor options.
|
|
66
|
+
* @param options.messenger - The messenger suited for this service.
|
|
67
|
+
* @param options.fetch - A function used to make HTTP requests.
|
|
68
|
+
* @param options.env - The environment; determines the base URL.
|
|
69
|
+
* @param options.baseUrl - Overrides the base URL derived from `env`.
|
|
70
|
+
* @param options.policyOptions - Options for the request service policy.
|
|
71
|
+
*/
|
|
72
|
+
constructor({ messenger, fetch: fetchFunction, env, baseUrl, policyOptions, }) {
|
|
73
|
+
_KycService_instances.add(this);
|
|
74
|
+
_KycService_messenger.set(this, void 0);
|
|
75
|
+
_KycService_fetch.set(this, void 0);
|
|
76
|
+
_KycService_baseUrl.set(this, void 0);
|
|
77
|
+
_KycService_policy.set(this, void 0);
|
|
78
|
+
this.name = serviceName;
|
|
79
|
+
__classPrivateFieldSet(this, _KycService_messenger, messenger, "f");
|
|
80
|
+
__classPrivateFieldSet(this, _KycService_fetch, fetchFunction, "f");
|
|
81
|
+
__classPrivateFieldSet(this, _KycService_baseUrl, baseUrl ?? KYC_API_URLS[env], "f");
|
|
82
|
+
__classPrivateFieldSet(this, _KycService_policy, createServicePolicy(policyOptions ?? {}), "f");
|
|
83
|
+
__classPrivateFieldGet(this, _KycService_messenger, "f").registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Resolves the customer's country from the geolocation source and converts it
|
|
87
|
+
* to an ISO 3166-1 alpha-3 code.
|
|
88
|
+
*
|
|
89
|
+
* @returns The alpha-3 country code.
|
|
90
|
+
* @throws If the country cannot be determined or mapped.
|
|
91
|
+
*/
|
|
92
|
+
async getGeoCountry() {
|
|
93
|
+
const location = await __classPrivateFieldGet(this, _KycService_messenger, "f").call('GeolocationController:getGeolocation');
|
|
94
|
+
// Guard nullish/empty geolocation with the documented domain error rather
|
|
95
|
+
// than letting `assert(location, string())` surface a superstruct
|
|
96
|
+
// assertion error (which would change how the failure reads in
|
|
97
|
+
// `disclaimersError`).
|
|
98
|
+
const alpha2 = typeof location === 'string' ? location.split('-')[0].toUpperCase() : '';
|
|
99
|
+
if (!alpha2 || alpha2 === 'UNKNOWN') {
|
|
100
|
+
throw new Error(`Unable to determine country from geolocation (got "${String(location)}").`);
|
|
101
|
+
}
|
|
102
|
+
const alpha3 = alpha2ToAlpha3(alpha2);
|
|
103
|
+
if (!alpha3) {
|
|
104
|
+
throw new Error(`Unable to map country code "${alpha2}" to an ISO 3166-1 alpha-3 code.`);
|
|
105
|
+
}
|
|
106
|
+
return alpha3;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Fetches the disclaimers the customer must accept before a session is
|
|
110
|
+
* created.
|
|
111
|
+
*
|
|
112
|
+
* @param params - The parameters.
|
|
113
|
+
* @param params.country - ISO 3166-1 alpha-3 country code.
|
|
114
|
+
* @returns The disclaimers.
|
|
115
|
+
*/
|
|
116
|
+
async fetchDisclaimers({ country, }) {
|
|
117
|
+
const url = new URL('/vendors/moonpay/disclaimers', __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
|
|
118
|
+
url.searchParams.set('country', country);
|
|
119
|
+
const data = await __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_request).call(this, url, { method: 'GET' });
|
|
120
|
+
return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, DisclaimersResponseStruct, 'disclaimers');
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Creates a vendor session via the UKYC backend.
|
|
124
|
+
*
|
|
125
|
+
* @param params - The session parameters.
|
|
126
|
+
* @returns The created session token.
|
|
127
|
+
*/
|
|
128
|
+
async createSession(params) {
|
|
129
|
+
const url = new URL('/vendors/moonpay/sessions', __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
|
|
130
|
+
const data = await __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_request).call(this, url, {
|
|
131
|
+
method: 'POST',
|
|
132
|
+
body: JSON.stringify(params),
|
|
133
|
+
});
|
|
134
|
+
return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, CreateSessionResponseStruct, 'sessions');
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Checks whether KYC is required for the given access token, country, and
|
|
138
|
+
* capabilities.
|
|
139
|
+
*
|
|
140
|
+
* @param params - The check parameters.
|
|
141
|
+
* @returns Whether KYC is required.
|
|
142
|
+
*/
|
|
143
|
+
async checkKycRequired(params) {
|
|
144
|
+
const url = new URL('/vendors/moonpay/kyc-required', __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
|
|
145
|
+
const data = await __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_request).call(this, url, {
|
|
146
|
+
method: 'POST',
|
|
147
|
+
body: JSON.stringify({
|
|
148
|
+
accessToken: params.accessToken,
|
|
149
|
+
country: params.country,
|
|
150
|
+
capabilities: params.capabilities ?? [{ product: 'ramps' }],
|
|
151
|
+
}),
|
|
152
|
+
});
|
|
153
|
+
const { required } = __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, KycRequiredResponseStruct, 'kyc-required');
|
|
154
|
+
return { kycRequired: required };
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Creates a UKYC session for the SumSub document-verification sub-flow.
|
|
158
|
+
*
|
|
159
|
+
* @param params - The session parameters.
|
|
160
|
+
* @returns The UKYC session identifiers and wrapped key.
|
|
161
|
+
*/
|
|
162
|
+
async createUkycSession(params) {
|
|
163
|
+
const url = new URL('/sessions', __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
|
|
164
|
+
const data = await __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_request).call(this, url, {
|
|
165
|
+
method: 'POST',
|
|
166
|
+
body: JSON.stringify({
|
|
167
|
+
vendorId: 'moonpay',
|
|
168
|
+
vendorUserId: 'mockedId',
|
|
169
|
+
jwtToken: params.jwtToken,
|
|
170
|
+
vendorMetadata: params.vendorMetadata,
|
|
171
|
+
}),
|
|
172
|
+
});
|
|
173
|
+
return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, UkycSessionResponseStruct, 'UKYC sessions');
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Exchanges the wrapped user key for a SumSub applicant access token.
|
|
177
|
+
*
|
|
178
|
+
* @param params - The exchange parameters.
|
|
179
|
+
* @returns The applicant access token and status.
|
|
180
|
+
*/
|
|
181
|
+
async submitWrappedKey(params) {
|
|
182
|
+
const url = new URL(`/sessions/${encodeURIComponent(params.sessionId)}/wrapped-key`, __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
|
|
183
|
+
const data = await __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_request).call(this, url, {
|
|
184
|
+
method: 'POST',
|
|
185
|
+
body: JSON.stringify({
|
|
186
|
+
wrappedUserKey: params.wrappedUserKey,
|
|
187
|
+
jwtToken: params.jwtToken,
|
|
188
|
+
idosSessionId: params.idosSessionId,
|
|
189
|
+
}),
|
|
190
|
+
});
|
|
191
|
+
return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, WrappedKeyResponseStruct, 'wrapped-key');
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
_KycService_messenger = new WeakMap(), _KycService_fetch = new WeakMap(), _KycService_baseUrl = new WeakMap(), _KycService_policy = new WeakMap(), _KycService_instances = new WeakSet(), _KycService_validateResponse = function _KycService_validateResponse(data, struct, apiName) {
|
|
195
|
+
try {
|
|
196
|
+
assert(data, struct);
|
|
197
|
+
return data;
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
const detail = error instanceof StructError
|
|
201
|
+
? `${error.message} (received: ${JSON.stringify(data)})`
|
|
202
|
+
: String(error);
|
|
203
|
+
throw new Error(`Malformed response received from ${apiName} API: ${detail}`);
|
|
204
|
+
}
|
|
205
|
+
}, _KycService_request =
|
|
206
|
+
/**
|
|
207
|
+
* Performs an authenticated JSON request wrapped in the service policy.
|
|
208
|
+
*
|
|
209
|
+
* @param url - The request URL.
|
|
210
|
+
* @param init - The request init (method, body).
|
|
211
|
+
* @returns The parsed JSON response.
|
|
212
|
+
*/
|
|
213
|
+
async function _KycService_request(url, init) {
|
|
214
|
+
const bearerToken = await __classPrivateFieldGet(this, _KycService_messenger, "f").call('AuthenticationController:getBearerToken');
|
|
215
|
+
assert(bearerToken, string());
|
|
216
|
+
if (!bearerToken) {
|
|
217
|
+
throw new Error('Unable to obtain an authentication bearer token — is the wallet signed in?');
|
|
218
|
+
}
|
|
219
|
+
const response = await __classPrivateFieldGet(this, _KycService_policy, "f").execute(async () => {
|
|
220
|
+
const localResponse = await __classPrivateFieldGet(this, _KycService_fetch, "f").call(this, url.toString(), {
|
|
221
|
+
...init,
|
|
222
|
+
headers: {
|
|
223
|
+
'Content-Type': 'application/json',
|
|
224
|
+
Authorization: `Bearer ${bearerToken}`,
|
|
225
|
+
},
|
|
226
|
+
});
|
|
227
|
+
if (!localResponse.ok) {
|
|
228
|
+
throw new HttpError(localResponse.status, `Fetching '${url.toString()}' failed with status '${localResponse.status}'`);
|
|
229
|
+
}
|
|
230
|
+
return localResponse;
|
|
231
|
+
});
|
|
232
|
+
return response.json();
|
|
233
|
+
};
|
|
234
|
+
//# sourceMappingURL=KycService.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KycService.mjs","sourceRoot":"","sources":["../src/KycService.ts"],"names":[],"mappings":";;;;;;;;;;;;AAIA,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,mCAAmC;AAK5E,OAAO,EACL,KAAK,EACL,MAAM,EACN,OAAO,EACP,MAAM,EACN,WAAW,EACX,IAAI,EACL,8BAA8B;AAE/B,OAAO,EAAE,cAAc,EAAE,2BAAuB;AAIhD,kBAAkB;AAElB;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC;AAOxC,MAAM,YAAY,GAA0C;IAC1D,UAAU,EAAE,gCAAgC;IAC5C,WAAW,EAAE,wCAAwC;CACtD,CAAC;AAEF,oBAAoB;AAEpB,MAAM,yBAAyB,GAAG;IAChC,eAAe;IACf,kBAAkB;IAClB,eAAe;IACf,kBAAkB;IAClB,mBAAmB;IACnB,kBAAkB;CACV,CAAC;AAkDX,+BAA+B;AAE/B,MAAM,gBAAgB,GAAG,IAAI,CAAC;IAC5B,EAAE,EAAE,MAAM,EAAE;IACZ,YAAY,EAAE,MAAM,EAAE;IACtB,GAAG,EAAE,MAAM,EAAE;CACd,CAAC,CAAC;AACH,MAAM,yBAAyB,GAAG,KAAK,CAAC,gBAAgB,CAAC,CAAC;AAE1D,MAAM,2BAA2B,GAAG,IAAI,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;AAErE,6EAA6E;AAC7E,gEAAgE;AAChE,MAAM,yBAAyB,GAAG,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;AAEhE,MAAM,yBAAyB,GAAG,IAAI,CAAC;IACrC,SAAS,EAAE,MAAM,EAAE;IACnB,iBAAiB,EAAE,MAAM,EAAE;IAC3B,aAAa,EAAE,MAAM,EAAE;CACxB,CAAC,CAAC;AAGH,MAAM,wBAAwB,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,MAAM,EAAE;IAChB,oBAAoB,EAAE,MAAM,EAAE;CAC/B,CAAC,CAAC;AA6BH,6BAA6B;AAE7B;;;;;GAKG;AACH,MAAM,OAAO,UAAU;IAWrB;;;;;;;;;OASG;IACH,YAAY,EACV,SAAS,EACT,KAAK,EAAE,aAAa,EACpB,GAAG,EACH,OAAO,EACP,aAAa,GACK;;QAxBX,wCAAgC;QAEhC,oCAAqB;QAErB,sCAAiB;QAEjB,qCAAuB;QAmB9B,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,uBAAA,IAAI,yBAAc,SAAS,MAAA,CAAC;QAC5B,uBAAA,IAAI,qBAAU,aAAa,MAAA,CAAC;QAC5B,uBAAA,IAAI,uBAAY,OAAO,IAAI,YAAY,CAAC,GAAG,CAAC,MAAA,CAAC;QAC7C,uBAAA,IAAI,sBAAW,mBAAmB,CAAC,aAAa,IAAI,EAAE,CAAC,MAAA,CAAC;QACxD,uBAAA,IAAI,6BAAW,CAAC,4BAA4B,CAC1C,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,QAAQ,GAAG,MAAM,uBAAA,IAAI,6BAAW,CAAC,IAAI,CACzC,sCAAsC,CACvC,CAAC;QACF,0EAA0E;QAC1E,kEAAkE;QAClE,+DAA+D;QAC/D,uBAAuB;QACvB,MAAM,MAAM,GACV,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3E,IAAI,CAAC,MAAM,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CACb,sDAAsD,MAAM,CAC1D,QAAQ,CACT,KAAK,CACP,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,+BAA+B,MAAM,kCAAkC,CACxE,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,gBAAgB,CAAC,EACrB,OAAO,GAGR;QACC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,8BAA8B,EAAE,uBAAA,IAAI,2BAAS,CAAC,CAAC;QACnE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,MAAM,uBAAA,IAAI,kDAAS,MAAb,IAAI,EAAU,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QACzD,OAAO,uBAAA,IAAI,2DAAkB,MAAtB,IAAI,EACT,IAAI,EACJ,yBAAyB,EACzB,aAAa,CACK,CAAC;IACvB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CACjB,MAA2B;QAE3B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,2BAA2B,EAAE,uBAAA,IAAI,2BAAS,CAAC,CAAC;QAChE,MAAM,IAAI,GAAG,MAAM,uBAAA,IAAI,kDAAS,MAAb,IAAI,EAAU,GAAG,EAAE;YACpC,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;SAC7B,CAAC,CAAC;QACH,OAAO,uBAAA,IAAI,2DAAkB,MAAtB,IAAI,EACT,IAAI,EACJ,2BAA2B,EAC3B,UAAU,CACX,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,gBAAgB,CACpB,MAA8B;QAE9B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,+BAA+B,EAAE,uBAAA,IAAI,2BAAS,CAAC,CAAC;QACpE,MAAM,IAAI,GAAG,MAAM,uBAAA,IAAI,kDAAS,MAAb,IAAI,EAAU,GAAG,EAAE;YACpC,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;aAC5D,CAAC;SACH,CAAC,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,uBAAA,IAAI,2DAAkB,MAAtB,IAAI,EACvB,IAAI,EACJ,yBAAyB,EACzB,cAAc,CACf,CAAC;QACF,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,iBAAiB,CACrB,MAA+B;QAE/B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,EAAE,uBAAA,IAAI,2BAAS,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,uBAAA,IAAI,kDAAS,MAAb,IAAI,EAAU,GAAG,EAAE;YACpC,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,QAAQ,EAAE,SAAS;gBACnB,YAAY,EAAE,UAAU;gBACxB,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,cAAc,EAAE,MAAM,CAAC,cAAc;aACtC,CAAC;SACH,CAAC,CAAC;QACH,OAAO,uBAAA,IAAI,2DAAkB,MAAtB,IAAI,EACT,IAAI,EACJ,yBAAyB,EACzB,eAAe,CAChB,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,gBAAgB,CACpB,MAA8B;QAE9B,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,aAAa,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,EAC/D,uBAAA,IAAI,2BAAS,CACd,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,uBAAA,IAAI,kDAAS,MAAb,IAAI,EAAU,GAAG,EAAE;YACpC,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,cAAc,EAAE,MAAM,CAAC,cAAc;gBACrC,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,aAAa,EAAE,MAAM,CAAC,aAAa;aACpC,CAAC;SACH,CAAC,CAAC;QACH,OAAO,uBAAA,IAAI,2DAAkB,MAAtB,IAAI,EACT,IAAI,EACJ,wBAAwB,EACxB,aAAa,CACd,CAAC;IACJ,CAAC;CAwEF;+PAvDG,IAAa,EACb,MAA4B,EAC5B,OAAe;IAEf,IAAI,CAAC;QACH,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GACV,KAAK,YAAY,WAAW;YAC1B,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,eAAe,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG;YACxD,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,oCAAoC,OAAO,SAAS,MAAM,EAAE,CAC7D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,KAAK,8BAAU,GAAQ,EAAE,IAAiB;IACxC,MAAM,WAAW,GAAG,MAAM,uBAAA,IAAI,6BAAW,CAAC,IAAI,CAC5C,yCAAyC,CAC1C,CAAC;IACF,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9B,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,4EAA4E,CAC7E,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,uBAAA,IAAI,0BAAQ,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;QACrD,MAAM,aAAa,GAAG,MAAM,uBAAA,IAAI,yBAAO,MAAX,IAAI,EAAQ,GAAG,CAAC,QAAQ,EAAE,EAAE;YACtD,GAAG,IAAI;YACP,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,WAAW,EAAE;aACvC;SACF,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;YACtB,MAAM,IAAI,SAAS,CACjB,aAAa,CAAC,MAAM,EACpB,aAAa,GAAG,CAAC,QAAQ,EAAE,yBAAyB,aAAa,CAAC,MAAM,GAAG,CAC5E,CAAC;QACJ,CAAC;QACD,OAAO,aAAa,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC","sourcesContent":["import type {\n CreateServicePolicyOptions,\n ServicePolicy,\n} from '@metamask/controller-utils';\nimport { createServicePolicy, HttpError } from '@metamask/controller-utils';\nimport type { GeolocationControllerGetGeolocationAction } from '@metamask/geolocation-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { AuthenticationControllerGetBearerTokenAction } from '@metamask/profile-sync-controller/auth';\nimport type { Infer, Struct } from '@metamask/superstruct';\nimport {\n array,\n assert,\n boolean,\n string,\n StructError,\n type,\n} from '@metamask/superstruct';\n\nimport { alpha2ToAlpha3 } from './countryCodes';\nimport type { KycServiceMethodActions } from './KycService-method-action-types';\nimport type { KycDisclaimer } from './types';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link KycService}, used to namespace the service's actions.\n */\nexport const serviceName = 'KycService';\n\n/**\n * The supported environments for the Universal KYC API.\n */\nexport type KycServiceEnvironment = 'production' | 'development';\n\nconst KYC_API_URLS: Record<KycServiceEnvironment, string> = {\n production: 'https://kyc-api.cx.metamask.io',\n development: 'https://kyc-api.dev-api.cx.metamask.io',\n};\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'getGeoCountry',\n 'fetchDisclaimers',\n 'createSession',\n 'checkKycRequired',\n 'createUkycSession',\n 'submitWrappedKey',\n] as const;\n\n/**\n * Actions that {@link KycService} exposes to other consumers.\n */\nexport type KycServiceActions = KycServiceMethodActions;\n\n/**\n * Actions from other messengers that {@link KycService} calls.\n */\ntype AllowedActions =\n | AuthenticationControllerGetBearerTokenAction\n | GeolocationControllerGetGeolocationAction;\n\n/**\n * Events that {@link KycService} exposes to other consumers.\n */\nexport type KycServiceEvents = never;\n\n/**\n * Events from other messengers that {@link KycService} subscribes to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger restricted to actions and events accessed by\n * {@link KycService}.\n */\nexport type KycServiceMessenger = Messenger<\n typeof serviceName,\n KycServiceActions | AllowedActions,\n KycServiceEvents | AllowedEvents\n>;\n\n/**\n * Options for constructing a {@link KycService}.\n */\nexport type KycServiceOptions = {\n messenger: KycServiceMessenger;\n fetch: typeof fetch;\n env: KycServiceEnvironment;\n /**\n * Overrides the base URL derived from `env`. When provided, this value is\n * used verbatim as the base URL for all requests, which is useful for\n * targeting a local or staging KYC API.\n */\n baseUrl?: string;\n policyOptions?: CreateServicePolicyOptions;\n};\n\n// === API RESPONSE SCHEMAS ===\n\nconst DisclaimerStruct = type({\n id: string(),\n display_name: string(),\n url: string(),\n});\nconst DisclaimersResponseStruct = array(DisclaimerStruct);\n\nconst CreateSessionResponseStruct = type({ sessionToken: string() });\n\n// The live KYC API returns the flag under `required`; the service normalizes\n// this to `kycRequired` for consumers (see `checkKycRequired`).\nconst KycRequiredResponseStruct = type({ required: boolean() });\n\nconst UkycSessionResponseStruct = type({\n sessionId: string(),\n wrappingPublicKey: string(),\n idosSessionId: string(),\n});\nexport type UkycSessionResponse = Infer<typeof UkycSessionResponseStruct>;\n\nconst WrappedKeyResponseStruct = type({\n status: string(),\n applicantAccessToken: string(),\n});\nexport type WrappedKeyResponse = Infer<typeof WrappedKeyResponseStruct>;\n\n// === PARAM TYPES ===\n\nexport type CreateSessionParams = {\n email: string;\n termsAcceptedAt: string;\n disclaimerIds: string[];\n};\n\nexport type CheckKycRequiredParams = {\n accessToken: string;\n country: string;\n capabilities?: { product: string }[];\n};\n\nexport type CreateUkycSessionParams = {\n jwtToken: string;\n vendorMetadata: Record<string, unknown>;\n};\n\nexport type SubmitWrappedKeyParams = {\n sessionId: string;\n wrappedUserKey: string;\n idosSessionId: string;\n jwtToken: string;\n};\n\n// === SERVICE DEFINITION ===\n\n/**\n * `KycService` communicates with the Universal KYC (UKYC) backend to drive the\n * identity + document-verification flow. It is stateless and platform-agnostic:\n * HTTP is performed through an injected `fetch`, and the auth bearer token and\n * geolocation come from other controllers via the messenger.\n */\nexport class KycService {\n readonly name: typeof serviceName;\n\n readonly #messenger: KycServiceMessenger;\n\n readonly #fetch: typeof fetch;\n\n readonly #baseUrl: string;\n\n readonly #policy: ServicePolicy;\n\n /**\n * Constructs a new KycService.\n *\n * @param options - The constructor options.\n * @param options.messenger - The messenger suited for this service.\n * @param options.fetch - A function used to make HTTP requests.\n * @param options.env - The environment; determines the base URL.\n * @param options.baseUrl - Overrides the base URL derived from `env`.\n * @param options.policyOptions - Options for the request service policy.\n */\n constructor({\n messenger,\n fetch: fetchFunction,\n env,\n baseUrl,\n policyOptions,\n }: KycServiceOptions) {\n this.name = serviceName;\n this.#messenger = messenger;\n this.#fetch = fetchFunction;\n this.#baseUrl = baseUrl ?? KYC_API_URLS[env];\n this.#policy = createServicePolicy(policyOptions ?? {});\n this.#messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Resolves the customer's country from the geolocation source and converts it\n * to an ISO 3166-1 alpha-3 code.\n *\n * @returns The alpha-3 country code.\n * @throws If the country cannot be determined or mapped.\n */\n async getGeoCountry(): Promise<string> {\n const location = await this.#messenger.call(\n 'GeolocationController:getGeolocation',\n );\n // Guard nullish/empty geolocation with the documented domain error rather\n // than letting `assert(location, string())` surface a superstruct\n // assertion error (which would change how the failure reads in\n // `disclaimersError`).\n const alpha2 =\n typeof location === 'string' ? location.split('-')[0].toUpperCase() : '';\n if (!alpha2 || alpha2 === 'UNKNOWN') {\n throw new Error(\n `Unable to determine country from geolocation (got \"${String(\n location,\n )}\").`,\n );\n }\n const alpha3 = alpha2ToAlpha3(alpha2);\n if (!alpha3) {\n throw new Error(\n `Unable to map country code \"${alpha2}\" to an ISO 3166-1 alpha-3 code.`,\n );\n }\n return alpha3;\n }\n\n /**\n * Fetches the disclaimers the customer must accept before a session is\n * created.\n *\n * @param params - The parameters.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The disclaimers.\n */\n async fetchDisclaimers({\n country,\n }: {\n country: string;\n }): Promise<KycDisclaimer[]> {\n const url = new URL('/vendors/moonpay/disclaimers', this.#baseUrl);\n url.searchParams.set('country', country);\n const data = await this.#request(url, { method: 'GET' });\n return this.#validateResponse(\n data,\n DisclaimersResponseStruct,\n 'disclaimers',\n ) as KycDisclaimer[];\n }\n\n /**\n * Creates a vendor session via the UKYC backend.\n *\n * @param params - The session parameters.\n * @returns The created session token.\n */\n async createSession(\n params: CreateSessionParams,\n ): Promise<Infer<typeof CreateSessionResponseStruct>> {\n const url = new URL('/vendors/moonpay/sessions', this.#baseUrl);\n const data = await this.#request(url, {\n method: 'POST',\n body: JSON.stringify(params),\n });\n return this.#validateResponse(\n data,\n CreateSessionResponseStruct,\n 'sessions',\n );\n }\n\n /**\n * Checks whether KYC is required for the given access token, country, and\n * capabilities.\n *\n * @param params - The check parameters.\n * @returns Whether KYC is required.\n */\n async checkKycRequired(\n params: CheckKycRequiredParams,\n ): Promise<{ kycRequired: boolean }> {\n const url = new URL('/vendors/moonpay/kyc-required', this.#baseUrl);\n const data = await this.#request(url, {\n method: 'POST',\n body: JSON.stringify({\n accessToken: params.accessToken,\n country: params.country,\n capabilities: params.capabilities ?? [{ product: 'ramps' }],\n }),\n });\n const { required } = this.#validateResponse(\n data,\n KycRequiredResponseStruct,\n 'kyc-required',\n );\n return { kycRequired: required };\n }\n\n /**\n * Creates a UKYC session for the SumSub document-verification sub-flow.\n *\n * @param params - The session parameters.\n * @returns The UKYC session identifiers and wrapped key.\n */\n async createUkycSession(\n params: CreateUkycSessionParams,\n ): Promise<UkycSessionResponse> {\n const url = new URL('/sessions', this.#baseUrl);\n const data = await this.#request(url, {\n method: 'POST',\n body: JSON.stringify({\n vendorId: 'moonpay',\n vendorUserId: 'mockedId',\n jwtToken: params.jwtToken,\n vendorMetadata: params.vendorMetadata,\n }),\n });\n return this.#validateResponse(\n data,\n UkycSessionResponseStruct,\n 'UKYC sessions',\n );\n }\n\n /**\n * Exchanges the wrapped user key for a SumSub applicant access token.\n *\n * @param params - The exchange parameters.\n * @returns The applicant access token and status.\n */\n async submitWrappedKey(\n params: SubmitWrappedKeyParams,\n ): Promise<WrappedKeyResponse> {\n const url = new URL(\n `/sessions/${encodeURIComponent(params.sessionId)}/wrapped-key`,\n this.#baseUrl,\n );\n const data = await this.#request(url, {\n method: 'POST',\n body: JSON.stringify({\n wrappedUserKey: params.wrappedUserKey,\n jwtToken: params.jwtToken,\n idosSessionId: params.idosSessionId,\n }),\n });\n return this.#validateResponse(\n data,\n WrappedKeyResponseStruct,\n 'wrapped-key',\n );\n }\n\n /**\n * Validates a parsed API response against a superstruct schema, throwing a\n * descriptive error when the response does not match.\n *\n * Unlike a bare `Struct.is` check, this surfaces exactly which field was\n * missing or had the wrong type, which is essential for diagnosing shape\n * mismatches between the client and the live API.\n *\n * @param data - The parsed response body.\n * @param struct - The superstruct schema the body is expected to satisfy.\n * @param apiName - A human-readable name of the API, used in the error message.\n * @returns The validated, typed response.\n * @throws If `data` does not match `struct`.\n */\n #validateResponse<Type, Schema>(\n data: unknown,\n struct: Struct<Type, Schema>,\n apiName: string,\n ): Type {\n try {\n assert(data, struct);\n return data;\n } catch (error) {\n const detail =\n error instanceof StructError\n ? `${error.message} (received: ${JSON.stringify(data)})`\n : String(error);\n throw new Error(\n `Malformed response received from ${apiName} API: ${detail}`,\n );\n }\n }\n\n /**\n * Performs an authenticated JSON request wrapped in the service policy.\n *\n * @param url - The request URL.\n * @param init - The request init (method, body).\n * @returns The parsed JSON response.\n */\n async #request(url: URL, init: RequestInit): Promise<unknown> {\n const bearerToken = await this.#messenger.call(\n 'AuthenticationController:getBearerToken',\n );\n assert(bearerToken, string());\n if (!bearerToken) {\n throw new Error(\n 'Unable to obtain an authentication bearer token — is the wallet signed in?',\n );\n }\n\n const response = await this.#policy.execute(async () => {\n const localResponse = await this.#fetch(url.toString(), {\n ...init,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${bearerToken}`,\n },\n });\n if (!localResponse.ok) {\n throw new HttpError(\n localResponse.status,\n `Fetching '${url.toString()}' failed with status '${localResponse.status}'`,\n );\n }\n return localResponse;\n });\n\n return response.json();\n }\n}\n"]}
|