@bloque/sdk-compliance 0.2.7 → 0.4.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.
@@ -1,7 +1,16 @@
1
1
  import type { HttpClient } from '@bloque/sdk-core';
2
2
  import { BaseClient } from '@bloque/sdk-core';
3
3
  import { KycClient } from './kyc/kyc-client';
4
+ import { TiersClient } from './tiers/tiers-client';
5
+ import { TosGateClient } from './tos-gate/tos-gate-client';
6
+ import { VerificationGateClient } from './verification-gate/verification-gate-client';
4
7
  export declare class ComplianceClient extends BaseClient {
5
8
  readonly kyc: KycClient;
9
+ /** Read an identity's effective tier and requirement status. */
10
+ readonly tiers: TiersClient;
11
+ /** Level 0 TOS gate — hosted acceptance flow. */
12
+ readonly tosGate: TosGateClient;
13
+ /** Phase 3 hosted verification gate — document/form submission flow. */
14
+ readonly verificationGate: VerificationGateClient;
6
15
  constructor(httpClient: HttpClient);
7
16
  }
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,t)=>{for(var _ in t)__webpack_require__.o(t,_)&&!__webpack_require__.o(e,_)&&Object.defineProperty(e,_,{enumerable:!0,get:t[_]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{KycClient:()=>KycClient,ComplianceClient:()=>ComplianceClient});const sdk_core_namespaceObject=require("@bloque/sdk-core");class KycClient extends sdk_core_namespaceObject.BaseClient{async startVerification(e){let t=await this.httpClient.request({method:"POST",path:"/api/compliance",body:{urn:e.urn,type:"kyc",accompliceType:"person"}});return{url:t.url,status:t.status,completedAt:null}}async getVerification(e){let t=await this.httpClient.request({method:"GET",path:`/api/compliance/${e.urn}`});return{status:t.status,url:t.verification_url,completedAt:t.completed_at,result:t.result,documentsStatus:t.documents_status}}async getDocuments(e){let t=await this.httpClient.request({method:"GET",path:`/api/compliance/${e.urn}/documents`});return{documentsStatus:t.documents_status,documents:t.documents.map(e=>({documentType:e.document_type,side:e.side,imageBase64:e.image_base64,imageSizeBytes:e.image_size_bytes}))}}}class ComplianceClient extends sdk_core_namespaceObject.BaseClient{kyc;constructor(e){super(e),this.kyc=new KycClient(this.httpClient)}}for(var __rspack_i in exports.ComplianceClient=__webpack_exports__.ComplianceClient,exports.KycClient=__webpack_exports__.KycClient,__webpack_exports__)-1===["ComplianceClient","KycClient"].indexOf(__rspack_i)&&(exports[__rspack_i]=__webpack_exports__[__rspack_i]);Object.defineProperty(exports,"__esModule",{value:!0});
1
+ "use strict";const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,t)=>{for(var i in t)__webpack_require__.o(t,i)&&!__webpack_require__.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{VerificationGateClient:()=>VerificationGateClient,mapVerificationFlow:()=>mapVerificationFlow,KycClient:()=>KycClient,ComplianceClient:()=>ComplianceClient,mapRequirementField:()=>mapRequirementField,TiersClient:()=>TiersClient,TosGateClient:()=>TosGateClient});const sdk_core_namespaceObject=require("@bloque/sdk-core");class KycClient extends sdk_core_namespaceObject.BaseClient{async startVerification(e){let t=await this.httpClient.request({method:"POST",path:"/api/compliance",body:{urn:e.urn,type:"kyc",accompliceType:"person"}});return{url:t.url,status:t.status,completedAt:null}}async getVerification(e){let t=await this.httpClient.request({method:"GET",path:`/api/compliance/${e.urn}`});return{status:t.status,url:t.verification_url,completedAt:t.completed_at,result:t.result,documentsStatus:t.documents_status}}async getDocuments(e){let t=await this.httpClient.request({method:"GET",path:`/api/compliance/${e.urn}/documents`});return{documentsStatus:t.documents_status,documents:t.documents.map(e=>({documentType:e.document_type,side:e.side,imageBase64:e.image_base64,imageSizeBytes:e.image_size_bytes}))}}}function mapRequirementField(e){return{key:e.key,label:e.label,type:e.type,required:e.required,options:e.options}}function mapRequirementStatus(e){return{key:e.key,kind:e.kind,status:e.status,description:e.description,fields:e.fields?.map(mapRequirementField),submittedAt:e.submitted_at}}function mapVerificationFlow(e){if(e)return{type:e.type,method:e.method,startEndpoint:e.start_endpoint,responseUrlField:e.response_url_field}}class TiersClient extends sdk_core_namespaceObject.BaseClient{async getStatus(e){let t=await this.httpClient.request({method:"GET",path:`/api/compliance/${e.urn}/tier-status`});return{identityUrn:t.identity_urn,effectiveLevel:t.effective_level,policyVersion:t.policy_version,levels:t.levels.map(e=>({level:e.level,name:e.name,satisfied:e.satisfied,requirements:e.requirements.map(mapRequirementStatus)})),nextLevel:t.next_level,missingRequirements:t.missing_requirements??[],pendingRequirements:t.pending_requirements??[],verificationFlow:mapVerificationFlow(t.verification_flow)}}}function mapAcceptance(e){return{id:e.id,identityUrn:e.identity_urn,documentVersionId:e.document_version_id,documentVersionLabel:e.document_version_label,documentHash:e.document_hash,acceptedAt:e.accepted_at,authAssurance:e.auth_assurance}}class TosGateClient extends sdk_core_namespaceObject.BaseClient{async start(e){let t=await this.httpClient.request({method:"POST",path:"/api/tos-gate/start",body:{return_url:e.returnUrl}});return{token:t.token,url:t.url,expiresIn:t.expires_in}}async init(e){let t=await this.httpClient.request({method:"GET",path:"/api/tos-gate/init",authorizationOverride:`Bearer ${e.token}`});return{document:{documentVersionId:t.document.document_version_id,versionLabel:t.document.version_label,contentHash:t.document.content_hash,content:t.document.content},csrfToken:t.csrf_token,returnUrl:t.return_url,showHome:t.show_home}}async accept(e){let t={csrf_token:e.csrfToken,...e.deviceAttestation&&{device_attestation:e.deviceAttestation}},i=await this.httpClient.request({method:"POST",path:"/api/tos-gate/accept",body:t,authorizationOverride:`Bearer ${e.token}`});return{acceptance:mapAcceptance(i.acceptance),returnUrl:i.return_url}}}function mapUploadIntent(e){return{contentType:e.content_type,key:e.key,uploadUrl:e.upload_url,maxSizeBytes:e.max_size_bytes}}function mapRequirement(e){return{key:e.key,kind:e.kind,description:e.description,fields:e.fields?.map(mapRequirementField),uploadable:e.uploadable,uploadIntents:e.upload_intents?.map(mapUploadIntent)}}function mapDocumentToWire(e){return{requirement_key:e.requirementKey,s3_key:e.s3Key,document_type:e.documentType,side:e.side,original_filename:e.originalFilename}}function mapAnswerToWire(e){return{requirement_key:e.requirementKey,values:e.values}}class VerificationGateClient extends sdk_core_namespaceObject.BaseClient{async start(e){let t=await this.httpClient.request({method:"POST",path:"/api/verification-gate/start",body:{return_url:e.returnUrl}});return{token:t.token,url:t.url,expiresIn:t.expires_in}}async init(e){let t=await this.httpClient.request({method:"GET",path:"/api/verification-gate/init",authorizationOverride:`Bearer ${e.token}`});return{requirements:t.requirements.map(mapRequirement),pendingRequirements:(t.pending_requirements??[]).map(e=>({key:e.key,description:e.description,submittedAt:e.submitted_at})),csrfToken:t.csrf_token,returnUrl:t.return_url}}async submit(e){let t={csrf_token:e.csrfToken,documents:e.documents?.map(mapDocumentToWire),answers:e.answers?.map(mapAnswerToWire)},i=await this.httpClient.request({method:"POST",path:"/api/verification-gate/submit",body:t,authorizationOverride:`Bearer ${e.token}`});return{returnUrl:i.return_url,documents:i.documents,answers:i.answers}}}class ComplianceClient extends sdk_core_namespaceObject.BaseClient{kyc;tiers;tosGate;verificationGate;constructor(e){super(e),this.kyc=new KycClient(this.httpClient),this.tiers=new TiersClient(this.httpClient),this.tosGate=new TosGateClient(this.httpClient),this.verificationGate=new VerificationGateClient(this.httpClient)}}for(var __rspack_i in exports.ComplianceClient=__webpack_exports__.ComplianceClient,exports.KycClient=__webpack_exports__.KycClient,exports.TiersClient=__webpack_exports__.TiersClient,exports.TosGateClient=__webpack_exports__.TosGateClient,exports.VerificationGateClient=__webpack_exports__.VerificationGateClient,exports.mapRequirementField=__webpack_exports__.mapRequirementField,exports.mapVerificationFlow=__webpack_exports__.mapVerificationFlow,__webpack_exports__)-1===["ComplianceClient","KycClient","TiersClient","TosGateClient","VerificationGateClient","mapRequirementField","mapVerificationFlow"].indexOf(__rspack_i)&&(exports[__rspack_i]=__webpack_exports__[__rspack_i]);Object.defineProperty(exports,"__esModule",{value:!0});
package/dist/index.d.ts CHANGED
@@ -1,3 +1,9 @@
1
1
  export * from './compliance-client';
2
2
  export * from './kyc/kyc-client';
3
3
  export * from './kyc/types';
4
+ export * from './tiers/tiers-client';
5
+ export * from './tiers/types';
6
+ export * from './tos-gate/tos-gate-client';
7
+ export * from './tos-gate/types';
8
+ export * from './verification-gate/types';
9
+ export * from './verification-gate/verification-gate-client';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{BaseClient as t}from"@bloque/sdk-core";class e extends t{async startVerification(t){let e=await this.httpClient.request({method:"POST",path:"/api/compliance",body:{urn:t.urn,type:"kyc",accompliceType:"person"}});return{url:e.url,status:e.status,completedAt:null}}async getVerification(t){let e=await this.httpClient.request({method:"GET",path:`/api/compliance/${t.urn}`});return{status:e.status,url:e.verification_url,completedAt:e.completed_at,result:e.result,documentsStatus:e.documents_status}}async getDocuments(t){let e=await this.httpClient.request({method:"GET",path:`/api/compliance/${t.urn}/documents`});return{documentsStatus:e.documents_status,documents:e.documents.map(t=>({documentType:t.document_type,side:t.side,imageBase64:t.image_base64,imageSizeBytes:t.image_size_bytes}))}}}class s extends t{kyc;constructor(t){super(t),this.kyc=new e(this.httpClient)}}export{s as ComplianceClient,e as KycClient};
1
+ import{BaseClient as e}from"@bloque/sdk-core";class t extends e{async startVerification(e){let t=await this.httpClient.request({method:"POST",path:"/api/compliance",body:{urn:e.urn,type:"kyc",accompliceType:"person"}});return{url:t.url,status:t.status,completedAt:null}}async getVerification(e){let t=await this.httpClient.request({method:"GET",path:`/api/compliance/${e.urn}`});return{status:t.status,url:t.verification_url,completedAt:t.completed_at,result:t.result,documentsStatus:t.documents_status}}async getDocuments(e){let t=await this.httpClient.request({method:"GET",path:`/api/compliance/${e.urn}/documents`});return{documentsStatus:t.documents_status,documents:t.documents.map(e=>({documentType:e.document_type,side:e.side,imageBase64:e.image_base64,imageSizeBytes:e.image_size_bytes}))}}}function n(e){return{key:e.key,label:e.label,type:e.type,required:e.required,options:e.options}}function i(e){return{key:e.key,kind:e.kind,status:e.status,description:e.description,fields:e.fields?.map(n),submittedAt:e.submitted_at}}function r(e){if(e)return{type:e.type,method:e.method,startEndpoint:e.start_endpoint,responseUrlField:e.response_url_field}}class s extends e{async getStatus(e){let t=await this.httpClient.request({method:"GET",path:`/api/compliance/${e.urn}/tier-status`});return{identityUrn:t.identity_urn,effectiveLevel:t.effective_level,policyVersion:t.policy_version,levels:t.levels.map(e=>({level:e.level,name:e.name,satisfied:e.satisfied,requirements:e.requirements.map(i)})),nextLevel:t.next_level,missingRequirements:t.missing_requirements??[],pendingRequirements:t.pending_requirements??[],verificationFlow:r(t.verification_flow)}}}class a extends e{async start(e){let t=await this.httpClient.request({method:"POST",path:"/api/tos-gate/start",body:{return_url:e.returnUrl}});return{token:t.token,url:t.url,expiresIn:t.expires_in}}async init(e){let t=await this.httpClient.request({method:"GET",path:"/api/tos-gate/init",authorizationOverride:`Bearer ${e.token}`});return{document:{documentVersionId:t.document.document_version_id,versionLabel:t.document.version_label,contentHash:t.document.content_hash,content:t.document.content},csrfToken:t.csrf_token,returnUrl:t.return_url,showHome:t.show_home}}async accept(e){var t;let n={csrf_token:e.csrfToken,...e.deviceAttestation&&{device_attestation:e.deviceAttestation}},i=await this.httpClient.request({method:"POST",path:"/api/tos-gate/accept",body:n,authorizationOverride:`Bearer ${e.token}`});return{acceptance:{id:(t=i.acceptance).id,identityUrn:t.identity_urn,documentVersionId:t.document_version_id,documentVersionLabel:t.document_version_label,documentHash:t.document_hash,acceptedAt:t.accepted_at,authAssurance:t.auth_assurance},returnUrl:i.return_url}}}function o(e){return{contentType:e.content_type,key:e.key,uploadUrl:e.upload_url,maxSizeBytes:e.max_size_bytes}}function u(e){return{key:e.key,kind:e.kind,description:e.description,fields:e.fields?.map(n),uploadable:e.uploadable,uploadIntents:e.upload_intents?.map(o)}}function c(e){return{requirement_key:e.requirementKey,s3_key:e.s3Key,document_type:e.documentType,side:e.side,original_filename:e.originalFilename}}function l(e){return{requirement_key:e.requirementKey,values:e.values}}class d extends e{async start(e){let t=await this.httpClient.request({method:"POST",path:"/api/verification-gate/start",body:{return_url:e.returnUrl}});return{token:t.token,url:t.url,expiresIn:t.expires_in}}async init(e){let t=await this.httpClient.request({method:"GET",path:"/api/verification-gate/init",authorizationOverride:`Bearer ${e.token}`});return{requirements:t.requirements.map(u),pendingRequirements:(t.pending_requirements??[]).map(e=>({key:e.key,description:e.description,submittedAt:e.submitted_at})),csrfToken:t.csrf_token,returnUrl:t.return_url}}async submit(e){let t={csrf_token:e.csrfToken,documents:e.documents?.map(c),answers:e.answers?.map(l)},n=await this.httpClient.request({method:"POST",path:"/api/verification-gate/submit",body:t,authorizationOverride:`Bearer ${e.token}`});return{returnUrl:n.return_url,documents:n.documents,answers:n.answers}}}class p extends e{kyc;tiers;tosGate;verificationGate;constructor(e){super(e),this.kyc=new t(this.httpClient),this.tiers=new s(this.httpClient),this.tosGate=new a(this.httpClient),this.verificationGate=new d(this.httpClient)}}export{p as ComplianceClient,t as KycClient,s as TiersClient,a as TosGateClient,d as VerificationGateClient,n as mapRequirementField,r as mapVerificationFlow};
@@ -61,3 +61,209 @@ export interface GetKycDocumentsResponse {
61
61
  documents_status: string;
62
62
  documents: ComplianceDocumentImage[];
63
63
  }
64
+ /**
65
+ * @internal
66
+ * A form field a `document`/`manual_review` requirement may ask for.
67
+ */
68
+ export interface RequirementFieldWire {
69
+ key: string;
70
+ label: string;
71
+ type: 'text' | 'number' | 'date' | 'select' | 'boolean';
72
+ required?: boolean;
73
+ options?: string[];
74
+ }
75
+ /**
76
+ * @internal
77
+ * Status of a single requirement within a tier level.
78
+ */
79
+ export interface TierRequirementStatusWire {
80
+ key: string;
81
+ kind: string;
82
+ status: 'satisfied' | 'not_satisfied' | 'expired' | 'revoked' | 'pending_review';
83
+ description?: string;
84
+ fields?: RequirementFieldWire[];
85
+ submitted_at?: string;
86
+ }
87
+ /**
88
+ * @internal
89
+ * Status of a single tier level, including all of its requirements.
90
+ */
91
+ export interface TierLevelStatusWire {
92
+ level: number;
93
+ name: string;
94
+ satisfied: boolean;
95
+ requirements: TierRequirementStatusWire[];
96
+ }
97
+ /**
98
+ * @internal
99
+ * Handoff pointing a client at the Level 0 TOS gate.
100
+ */
101
+ export interface TosHostedAcceptanceFlowHandoffWire {
102
+ type: 'tos_hosted_acceptance';
103
+ method: 'POST';
104
+ start_endpoint: string;
105
+ response_url_field: string;
106
+ }
107
+ /**
108
+ * @internal
109
+ * Handoff pointing a client at the Phase 3 hosted verification gate.
110
+ */
111
+ export interface DocumentSubmissionFlowHandoffWire {
112
+ type: 'document_submission';
113
+ method: 'POST';
114
+ start_endpoint: string;
115
+ response_url_field: string;
116
+ }
117
+ /**
118
+ * @internal
119
+ * Machine-readable handoff describing which hosted gate to open next.
120
+ */
121
+ export type VerificationFlowHandoffWire = TosHostedAcceptanceFlowHandoffWire | DocumentSubmissionFlowHandoffWire;
122
+ /**
123
+ * @internal
124
+ * `GET /api/compliance/:urn/tier-status` response.
125
+ */
126
+ export interface GetTierStatusResponse {
127
+ identity_urn: string;
128
+ effective_level: number;
129
+ policy_version: string;
130
+ levels: TierLevelStatusWire[];
131
+ next_level?: number;
132
+ missing_requirements?: string[];
133
+ pending_requirements?: string[];
134
+ verification_flow?: VerificationFlowHandoffWire;
135
+ }
136
+ /**
137
+ * @internal
138
+ * `POST /api/tos-gate/start` and `POST /api/verification-gate/start`
139
+ * share this exact response shape.
140
+ */
141
+ export interface StartGateResponse {
142
+ token: string;
143
+ url: string;
144
+ expires_in: string;
145
+ }
146
+ /**
147
+ * @internal
148
+ * `GET /api/tos-gate/init` document payload.
149
+ */
150
+ export interface TosGateDocumentWire {
151
+ document_version_id: string;
152
+ version_label: string;
153
+ content_hash: string;
154
+ content: string;
155
+ }
156
+ /**
157
+ * @internal
158
+ * `GET /api/tos-gate/init` response.
159
+ */
160
+ export interface TosGateInitResponse {
161
+ document: TosGateDocumentWire;
162
+ csrf_token: string;
163
+ return_url: string;
164
+ show_home: boolean;
165
+ }
166
+ /**
167
+ * @internal
168
+ * `POST /api/tos-gate/accept` request body.
169
+ */
170
+ export interface TosGateAcceptRequest {
171
+ csrf_token: string;
172
+ device_attestation?: string;
173
+ }
174
+ /**
175
+ * @internal
176
+ * Recorded TOS acceptance, as returned by `POST /api/tos-gate/accept`.
177
+ */
178
+ export interface TosAcceptanceRecordWire {
179
+ id: string;
180
+ identity_urn: string;
181
+ document_version_id: string;
182
+ document_version_label: string;
183
+ document_hash: string;
184
+ accepted_at: string;
185
+ auth_assurance: string;
186
+ }
187
+ /**
188
+ * @internal
189
+ * `POST /api/tos-gate/accept` response.
190
+ */
191
+ export interface TosGateAcceptResponse {
192
+ acceptance: TosAcceptanceRecordWire;
193
+ return_url: string;
194
+ }
195
+ /**
196
+ * @internal
197
+ * One presigned upload URL for a requirement, for a single content type.
198
+ */
199
+ export interface VerificationUploadIntentWire {
200
+ content_type: string;
201
+ key: string;
202
+ upload_url: string;
203
+ max_size_bytes: number;
204
+ }
205
+ /**
206
+ * @internal
207
+ * One outstanding requirement, as surfaced by `GET /api/verification-gate/init`.
208
+ */
209
+ export interface VerificationRequirementWire {
210
+ key: string;
211
+ kind: string;
212
+ description?: string;
213
+ fields?: RequirementFieldWire[];
214
+ uploadable: boolean;
215
+ upload_intents?: VerificationUploadIntentWire[];
216
+ }
217
+ /**
218
+ * @internal
219
+ * `GET /api/verification-gate/init` response.
220
+ */
221
+ export interface PendingVerificationRequirementWire {
222
+ key: string;
223
+ description?: string;
224
+ submitted_at?: string;
225
+ }
226
+ export interface VerificationGateInitResponse {
227
+ requirements: VerificationRequirementWire[];
228
+ pending_requirements?: PendingVerificationRequirementWire[];
229
+ csrf_token: string;
230
+ return_url: string;
231
+ }
232
+ /**
233
+ * @internal
234
+ * A single confirmed document upload in a submit request.
235
+ */
236
+ export interface VerificationGateSubmitDocumentWire {
237
+ requirement_key: string;
238
+ s3_key: string;
239
+ document_type?: string;
240
+ side?: string;
241
+ original_filename?: string | null;
242
+ }
243
+ /**
244
+ * @internal
245
+ * A single form answer in a submit request.
246
+ */
247
+ export interface VerificationGateSubmitAnswerWire {
248
+ requirement_key: string;
249
+ values: Record<string, unknown>;
250
+ }
251
+ /**
252
+ * @internal
253
+ * `POST /api/verification-gate/submit` request body.
254
+ */
255
+ export interface VerificationGateSubmitRequest {
256
+ csrf_token: string;
257
+ documents?: VerificationGateSubmitDocumentWire[];
258
+ answers?: VerificationGateSubmitAnswerWire[];
259
+ }
260
+ /**
261
+ * @internal
262
+ * `POST /api/verification-gate/submit` response. `documents`/`answers` are
263
+ * untyped provider-passthrough results — not consumed by the SDK today.
264
+ */
265
+ export interface VerificationGateSubmitResponse {
266
+ return_url: string;
267
+ documents: unknown[];
268
+ answers: unknown[];
269
+ }
@@ -0,0 +1,27 @@
1
+ import { BaseClient } from '@bloque/sdk-core';
2
+ import type { RequirementFieldWire, VerificationFlowHandoffWire } from '../internal/wire-types';
3
+ import type { GetTierStatusParams, RequirementField, TierStatus, VerificationFlowHandoff } from './types';
4
+ /** @internal Shared by verification-gate-client.ts, which surfaces the same field descriptors. */
5
+ export declare function mapRequirementField(field: RequirementFieldWire): RequirementField;
6
+ /** @internal Shared by verification-gate-client.ts's start()/init() responses. */
7
+ export declare function mapVerificationFlow(flow: VerificationFlowHandoffWire | undefined): VerificationFlowHandoff | undefined;
8
+ /**
9
+ * Tier status client — the read side of the compliance engine's
10
+ * verification-tier control plane.
11
+ */
12
+ export declare class TiersClient extends BaseClient {
13
+ /**
14
+ * Get an identity's effective compliance tier, per-level requirement
15
+ * status, and (if not fully verified) which requirements are missing and
16
+ * which hosted gate resolves them.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const status = await bloque.compliance.tiers.getStatus({ urn: user.urn });
21
+ * if (status.verificationFlow?.type === 'tos_hosted_acceptance') {
22
+ * // caller needs to accept TOS — see compliance.tosGate
23
+ * }
24
+ * ```
25
+ */
26
+ getStatus(params: GetTierStatusParams): Promise<TierStatus>;
27
+ }
@@ -0,0 +1,66 @@
1
+ export interface GetTierStatusParams {
2
+ /**
3
+ * URN (Uniform Resource Name) that uniquely identifies the identity
4
+ * whose tier status is being read.
5
+ *
6
+ * @example "did:bloque:user:123e4567"
7
+ */
8
+ urn: string;
9
+ }
10
+ export interface RequirementField {
11
+ key: string;
12
+ label: string;
13
+ type: 'text' | 'number' | 'date' | 'select' | 'boolean';
14
+ required?: boolean;
15
+ /** Only meaningful for `type: 'select'`. */
16
+ options?: string[];
17
+ }
18
+ export interface TierRequirementStatus {
19
+ key: string;
20
+ /** e.g. `'tos'`, `'kyc'`, `'document'`, `'manual_review'`, `'provider_check'`. */
21
+ kind: string;
22
+ /** `'pending_review'` still blocks the level, but your user has already
23
+ * submitted it — show it as in progress rather than asking again. */
24
+ status: 'satisfied' | 'not_satisfied' | 'expired' | 'revoked' | 'pending_review';
25
+ /** What this requirement means, for display without hardcoding key strings. */
26
+ description?: string;
27
+ /** Only present for requirements that collect form answers. */
28
+ fields?: RequirementField[];
29
+ /** ISO-8601 timestamp of the submission behind a `'pending_review'`
30
+ * status, for a "submitted on X" line. */
31
+ submittedAt?: string;
32
+ }
33
+ export interface TierLevelStatus {
34
+ level: number;
35
+ name: string;
36
+ satisfied: boolean;
37
+ requirements: TierRequirementStatus[];
38
+ }
39
+ /**
40
+ * Machine-readable pointer to the hosted gate that resolves the caller's
41
+ * current verification gap. Feed `startEndpoint`/`method` into a direct
42
+ * request, or just catch the `BloqueVerificationRequiredError` this maps
43
+ * onto and call its `getVerificationLink()` instead.
44
+ */
45
+ export interface VerificationFlowHandoff {
46
+ type: 'tos_hosted_acceptance' | 'document_submission';
47
+ method: 'POST';
48
+ startEndpoint: string;
49
+ responseUrlField: string;
50
+ }
51
+ export interface TierStatus {
52
+ identityUrn: string;
53
+ /** Highest contiguous satisfied level; -1 if even Level 0 is unsatisfied. */
54
+ effectiveLevel: number;
55
+ policyVersion: string;
56
+ levels: TierLevelStatus[];
57
+ /** The next level that isn't fully satisfied, if any. */
58
+ nextLevel?: number;
59
+ /** Requirement keys still outstanding at `nextLevel`, actionable or not. */
60
+ missingRequirements: string[];
61
+ /** The subset of `missingRequirements` already submitted and awaiting a
62
+ * reviewer. When it covers all of them, `verificationFlow` is absent:
63
+ * there is nothing left for your user to do. */
64
+ pendingRequirements: string[];
65
+ verificationFlow?: VerificationFlowHandoff;
66
+ }
@@ -0,0 +1,40 @@
1
+ import { BaseClient } from '@bloque/sdk-core';
2
+ import type { StartGateResult, StartTosGateParams, TosGateAcceptParams, TosGateAcceptResult, TosGateInitParams, TosGateInitResult } from './types';
3
+ /**
4
+ * Level 0 TOS gate (`/api/tos-gate/*`) — the hosted page a user opens to
5
+ * accept the Terms of Service.
6
+ *
7
+ * `start()` authenticates as the SDK's connected session, same as any other
8
+ * call. `init()`/`accept()` authenticate solely via the capability `token`
9
+ * `start()` returns — the same bearer credential the hosted page itself
10
+ * uses — so they work without a live session for that identity (this is
11
+ * what makes the returned `url` portable to any browser).
12
+ *
13
+ * Usually you won't call these directly: catch a
14
+ * `BloqueVerificationRequiredError` with `reason === 'tos'` and call its
15
+ * `getVerificationLink()` instead, which calls `start()` for you.
16
+ */
17
+ export declare class TosGateClient extends BaseClient {
18
+ /**
19
+ * Mint a portable TOS gate capability token + hosted page URL.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const gate = await bloque.compliance.tosGate.start({
24
+ * returnUrl: 'https://myapp.com/verification-complete',
25
+ * });
26
+ * // Open gate.url in a browser, or drive it programmatically with init()/accept().
27
+ * ```
28
+ */
29
+ start(params: StartTosGateParams): Promise<StartGateResult>;
30
+ /**
31
+ * Fetch the active TOS document for the token's identity and mint a
32
+ * single-use acceptance nonce. Authorized solely by `params.token`.
33
+ */
34
+ init(params: TosGateInitParams): Promise<TosGateInitResult>;
35
+ /**
36
+ * Record TOS acceptance for the token's identity. Authorized solely by
37
+ * `params.token`; requires the single-use `csrfToken` from `init()`.
38
+ */
39
+ accept(params: TosGateAcceptParams): Promise<TosGateAcceptResult>;
40
+ }
@@ -0,0 +1,59 @@
1
+ export interface StartTosGateParams {
2
+ /**
3
+ * Where the hosted TOS gate page redirects back to after acceptance.
4
+ * Must be present in the backend's `TOS_GATE_RETURN_URL_ALLOWLIST`.
5
+ */
6
+ returnUrl: string;
7
+ }
8
+ export interface StartGateResult {
9
+ /** Capability token — pass as `token` to `init()`/`accept()` (or `verificationGate.init/submit`). */
10
+ token: string;
11
+ /** Fully-qualified hosted page URL a browser should open. */
12
+ url: string;
13
+ /** Token lifetime, e.g. `"30m"`. */
14
+ expiresIn: string;
15
+ }
16
+ export interface TosGateInitParams {
17
+ /** The capability token returned by `start()`. */
18
+ token: string;
19
+ }
20
+ export interface TosGateDocument {
21
+ documentVersionId: string;
22
+ versionLabel: string;
23
+ contentHash: string;
24
+ /** Rendered document content (Markdown-templated to HTML server-side). */
25
+ content: string;
26
+ }
27
+ export interface TosGateInitResult {
28
+ document: TosGateDocument;
29
+ /** Single-use acceptance nonce — pass as `csrfToken` to `accept()`. */
30
+ csrfToken: string;
31
+ returnUrl: string;
32
+ /** Whether the hosted page's intro screens should play before the document. */
33
+ showHome: boolean;
34
+ }
35
+ export interface TosGateAcceptParams {
36
+ /** The capability token returned by `start()`. */
37
+ token: string;
38
+ /** The single-use nonce returned by `init()`. */
39
+ csrfToken: string;
40
+ /**
41
+ * Optional Pass device attestation (0x-hex SCALE-encoded
42
+ * `PassDeviceAttestation`). When present, accepting the terms also hands
43
+ * control of the identity's Kreivo PassAccount to that device.
44
+ */
45
+ deviceAttestation?: string;
46
+ }
47
+ export interface TosAcceptanceRecord {
48
+ id: string;
49
+ identityUrn: string;
50
+ documentVersionId: string;
51
+ documentVersionLabel: string;
52
+ documentHash: string;
53
+ acceptedAt: string;
54
+ authAssurance: string;
55
+ }
56
+ export interface TosGateAcceptResult {
57
+ acceptance: TosAcceptanceRecord;
58
+ returnUrl: string;
59
+ }
@@ -0,0 +1,89 @@
1
+ import type { RequirementField } from '../tiers/types';
2
+ export type { StartGateResult } from '../tos-gate/types';
3
+ export interface StartVerificationGateParams {
4
+ /**
5
+ * Where the hosted verification gate page redirects back to after
6
+ * submission. Must be present in the backend's
7
+ * `VERIFICATION_GATE_RETURN_URL_ALLOWLIST` (enforced fail-closed).
8
+ */
9
+ returnUrl: string;
10
+ }
11
+ export interface VerificationGateInitParams {
12
+ /** The capability token returned by `start()`. */
13
+ token: string;
14
+ }
15
+ export interface VerificationUploadIntent {
16
+ contentType: string;
17
+ /** The S3 key to confirm in `submit()` once the PUT completes. */
18
+ key: string;
19
+ /** Presigned URL for a direct browser `PUT` upload. */
20
+ uploadUrl: string;
21
+ maxSizeBytes: number;
22
+ }
23
+ export interface VerificationRequirement {
24
+ key: string;
25
+ /** e.g. `'document'` or `'manual_review'` — TOS/KYC never appear here (they have no upload/form). */
26
+ kind: string;
27
+ description?: string;
28
+ /** Only present for requirements that collect form answers. */
29
+ fields?: RequirementField[];
30
+ uploadable: boolean;
31
+ /** One presigned upload URL per allowed content type, only when `uploadable`. */
32
+ uploadIntents?: VerificationUploadIntent[];
33
+ }
34
+ /** A requirement already submitted and waiting on a reviewer. No fields
35
+ * and no upload intents: there is nothing to collect, only something to
36
+ * report. */
37
+ export interface PendingVerificationRequirement {
38
+ key: string;
39
+ description?: string;
40
+ /** ISO-8601 timestamp of the submission. */
41
+ submittedAt?: string;
42
+ }
43
+ export interface VerificationGateInitResult {
44
+ /** Requirements the identity can still act on — unsatisfied, non-TOS/
45
+ * KYC, and not already under review. */
46
+ requirements: VerificationRequirement[];
47
+ /** Requirements already submitted and awaiting review. Show these as in
48
+ * progress; collecting them again would duplicate what a reviewer
49
+ * already holds. */
50
+ pendingRequirements: PendingVerificationRequirement[];
51
+ /** Single-use submit nonce — pass as `csrfToken` to `submit()`. */
52
+ csrfToken: string;
53
+ returnUrl: string;
54
+ }
55
+ export interface SubmitDocumentConfirmation {
56
+ requirementKey: string;
57
+ /** The `key` from the `VerificationUploadIntent` used for the completed PUT. */
58
+ s3Key: string;
59
+ documentType?: string;
60
+ side?: string;
61
+ originalFilename?: string | null;
62
+ }
63
+ export interface SubmitFormAnswer {
64
+ requirementKey: string;
65
+ /** Answer values keyed by the requirement's `RequirementField.key`. */
66
+ values: Record<string, unknown>;
67
+ }
68
+ export interface VerificationGateSubmitParams {
69
+ /** The capability token returned by `start()`. */
70
+ token: string;
71
+ /** The single-use nonce from `init()`. */
72
+ csrfToken: string;
73
+ documents?: SubmitDocumentConfirmation[];
74
+ answers?: SubmitFormAnswer[];
75
+ }
76
+ export interface VerificationGateSubmitResult {
77
+ returnUrl: string;
78
+ /**
79
+ * Recording confirms the submission reached compliance — it does not
80
+ * mean the requirement is now satisfied. A customer's own submission is
81
+ * always recorded as `pending_review` and requires ops review before it
82
+ * counts toward the identity's effective tier. Until then the identity
83
+ * gets `E_VERIFICATION_PENDING` rather than being sent back here.
84
+ */
85
+ documents: unknown[];
86
+ /** One evidence record per submitted requirement key — a requirement's
87
+ * form answers and its uploaded files land in the same record. */
88
+ answers: unknown[];
89
+ }
@@ -0,0 +1,42 @@
1
+ import { BaseClient } from '@bloque/sdk-core';
2
+ import type { StartGateResult, StartVerificationGateParams, VerificationGateInitParams, VerificationGateInitResult, VerificationGateSubmitParams, VerificationGateSubmitResult } from './types';
3
+ /**
4
+ * Phase 3 hosted verification gate (`/api/verification-gate/*`) — the
5
+ * single hosted page that collects both document uploads and form answers
6
+ * for any outstanding Level 2+ (non-TOS/non-KYC) requirement.
7
+ *
8
+ * Same capability-token shape as {@link TosGateClient}: `start()` uses the
9
+ * SDK's session auth, `init()`/`submit()` authenticate solely via the
10
+ * capability `token`.
11
+ *
12
+ * Usually you won't call these directly: catch a
13
+ * `BloqueVerificationRequiredError` with `reason === 'documents'` and call
14
+ * its `getVerificationLink()` instead, which calls `start()` for you.
15
+ *
16
+ * A `BloqueVerificationPendingError` is the one case where you should not
17
+ * open this gate at all — everything it would collect is already with a
18
+ * reviewer.
19
+ */
20
+ export declare class VerificationGateClient extends BaseClient {
21
+ /**
22
+ * Mint a portable verification gate capability token + hosted page URL.
23
+ */
24
+ start(params: StartVerificationGateParams): Promise<StartGateResult>;
25
+ /**
26
+ * Fetch the token identity's actionable requirements — with
27
+ * descriptions, form field definitions, and presigned upload URLs for
28
+ * uploadable ones — plus anything already under review (reported
29
+ * separately, never re-collected) and a single-use submit nonce.
30
+ * Authorized solely by `params.token`.
31
+ */
32
+ init(params: VerificationGateInitParams): Promise<VerificationGateInitResult>;
33
+ /**
34
+ * Submit confirmed document uploads and/or form answers for the token's
35
+ * identity. Authorized solely by `params.token`; requires the single-use
36
+ * `csrfToken` from `init()`.
37
+ *
38
+ * Recording a submission does not satisfy the requirement — see
39
+ * {@link VerificationGateSubmitResult.documents}.
40
+ */
41
+ submit(params: VerificationGateSubmitParams): Promise<VerificationGateSubmitResult>;
42
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bloque/sdk-compliance",
3
- "version": "0.2.7",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "keywords": [
6
6
  "bloque",
@@ -34,6 +34,6 @@
34
34
  "node": ">=22"
35
35
  },
36
36
  "dependencies": {
37
- "@bloque/sdk-core": "0.2.4"
37
+ "@bloque/sdk-core": "0.4.0"
38
38
  }
39
39
  }