@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.
- package/dist/compliance-client.d.ts +9 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +1 -1
- package/dist/internal/wire-types.d.ts +206 -0
- package/dist/tiers/tiers-client.d.ts +27 -0
- package/dist/tiers/types.d.ts +66 -0
- package/dist/tos-gate/tos-gate-client.d.ts +40 -0
- package/dist/tos-gate/types.d.ts +59 -0
- package/dist/verification-gate/types.d.ts +89 -0
- package/dist/verification-gate/verification-gate-client.d.ts +42 -0
- package/package.json +2 -2
|
@@ -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
|
|
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
|
|
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.
|
|
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.
|
|
37
|
+
"@bloque/sdk-core": "0.4.0"
|
|
38
38
|
}
|
|
39
39
|
}
|