@uverifyng/node 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -54,6 +54,12 @@ await uverify.aml.monitors.create({ name: 'Adaeze Okafor' }); //
54
54
 
55
55
  const link = await uverify.kyc.createLink({ customer_name: 'Ada', require_document: true }); // no-code: send link.url
56
56
 
57
+ await uverify.address.verify({ address: '12 Admiralty Way, Lekki Phase 1', lga: 'Eti-Osa', state: 'Lagos' }); // on the map, in that LGA and state?
58
+ const home = await uverify.address.createLink({ address: '12 Admiralty Way', state: 'Lagos', customer_name: 'Ada' });
59
+ // send home.url: they open it at home and share their phone's location; read home.result / location.distance_m later
60
+ // (require_document: true also asks them for a proof of address)
61
+ await uverify.address.verifyDocument({ front_image: fs.readFileSync('bill.jpg'), address: '12 Admiralty Way', state: 'Lagos', name: 'Adaeze Okafor' });
62
+
57
63
  await uverify.verifications.list({ status: 'verified' });
58
64
  await uverify.account.balance();
59
65
  ```
package/dist/index.cjs CHANGED
@@ -99,7 +99,7 @@ function signPayload(body, secret, timestamp = Math.floor(Date.now() / 1e3)) {
99
99
  }
100
100
 
101
101
  // src/client.ts
102
- var VERSION = "0.1.1";
102
+ var VERSION = "0.2.0";
103
103
  var DEFAULT_BASE_URL = "https://api.uverify.com.ng/v1";
104
104
  var IMAGE_FIELDS = ["selfie_image", "front_image", "back_image"];
105
105
  var newReference = (prefix) => `${prefix}_${(0, import_node_crypto2.randomBytes)(9).toString("base64url")}`;
@@ -114,6 +114,7 @@ var UVerify = class _UVerify {
114
114
  liveness;
115
115
  documents;
116
116
  aml;
117
+ address;
117
118
  kyc;
118
119
  account;
119
120
  static webhooks = { constructEvent, signPayload };
@@ -139,6 +140,7 @@ var UVerify = class _UVerify {
139
140
  this.liveness = new LivenessResource(this);
140
141
  this.documents = new DocumentsResource(this);
141
142
  this.aml = new AmlResource(this);
143
+ this.address = new AddressResource(this);
142
144
  this.kyc = new KycResource(this);
143
145
  this.account = new AccountResource(this);
144
146
  }
@@ -305,6 +307,42 @@ var AmlMonitorsResource = class extends Resource {
305
307
  return this.client.request("DELETE", `/aml/monitors/${encodeURIComponent(id)}`, { retryable: true });
306
308
  }
307
309
  };
310
+ var AddressResource = class extends Resource {
311
+ /** Is the address real, and in the LGA and state given? Found on the map and scored, instantly. */
312
+ verify(params) {
313
+ return this.client.create("/address/verify", params, "addr");
314
+ }
315
+ getCheck(id) {
316
+ return this.client.request("GET", `/address/checks/${encodeURIComponent(id)}`);
317
+ }
318
+ listChecks(params = {}) {
319
+ return this.client.request("GET", "/address/checks", { query: { ...params } });
320
+ }
321
+ /** A link the customer opens at home to share their phone's location. Send them `link.url`. */
322
+ createLink(params) {
323
+ return this.client.create("/address/links", params, "addrl");
324
+ }
325
+ getLink(id) {
326
+ return this.client.request("GET", `/address/links/${encodeURIComponent(id)}`);
327
+ }
328
+ listLinks(params = {}) {
329
+ return this.client.request("GET", "/address/links", { query: { ...params } });
330
+ }
331
+ /** A utility bill, bank statement or tenancy agreement, checked for the customer's name, the address, its date and editing. */
332
+ verifyDocument(params) {
333
+ return this.client.create("/address/documents", params, "addrd");
334
+ }
335
+ getDocument(id) {
336
+ return this.client.request("GET", `/address/documents/${encodeURIComponent(id)}`);
337
+ }
338
+ listDocuments(params = {}) {
339
+ return this.client.request("GET", "/address/documents", { query: { ...params } });
340
+ }
341
+ /** Sandbox only: finish a link without a phone. */
342
+ simulateLink(id, params) {
343
+ return this.client.request("POST", `/address/links/${encodeURIComponent(id)}/simulate`, { body: { ...params } });
344
+ }
345
+ };
308
346
  var AmlResource = class extends Resource {
309
347
  monitors = new AmlMonitorsResource(this.client);
310
348
  /** Screen a person or organisation against the UN, OFAC, UK, EU and Nigeria sanctions lists. */
package/dist/index.d.cts CHANGED
@@ -215,6 +215,211 @@ interface AmlScreening {
215
215
  created_at: string;
216
216
  }
217
217
  type MonitorParams = Omit<ScreenParams, 'monitor'>;
218
+ interface VerifyAddressParams {
219
+ /** House number and street, with the area or town, e.g. "12 Admiralty Way, Lekki Phase 1". */
220
+ address: string;
221
+ /** A Nigerian state or FCT, e.g. "Lagos". */
222
+ state: string;
223
+ /** Local government area, e.g. "Eti-Osa". Optional, but it sharpens the check. */
224
+ lga?: string;
225
+ reference?: string;
226
+ /** Sandbox only: the result to get back. */
227
+ sandbox_outcome?: 'verified' | 'partial' | 'not_found' | 'state_mismatch';
228
+ }
229
+ type AddressPrecision = 'building' | 'street' | 'area' | 'region';
230
+ interface AddressChecks {
231
+ address_found: {
232
+ result: 'pass' | 'fail';
233
+ precision: AddressPrecision | null;
234
+ };
235
+ state_match: {
236
+ result: 'pass' | 'fail';
237
+ found: string | null;
238
+ };
239
+ lga_match: {
240
+ result: 'pass' | 'fail' | 'unknown';
241
+ found: string | null;
242
+ };
243
+ }
244
+ /** An address found on the map and scored. */
245
+ interface AddressCheck {
246
+ id: string;
247
+ reference: string;
248
+ environment: Environment;
249
+ /** verified (score 75+), partial (45–74) or failed. */
250
+ status: 'verified' | 'partial' | 'failed';
251
+ score: number;
252
+ address: {
253
+ address: string;
254
+ lga: string | null;
255
+ state: string;
256
+ } | null;
257
+ checks: AddressChecks;
258
+ /** e.g. address_not_found, state_mismatch, lga_mismatch, only_area_found. */
259
+ reasons: string[];
260
+ location: {
261
+ formatted_address: string;
262
+ latitude: number;
263
+ longitude: number;
264
+ precision: AddressPrecision | null;
265
+ partial_match: boolean;
266
+ source: 'openstreetmap' | 'google' | 'sandbox';
267
+ /** Show it wherever you display an OpenStreetMap result. */
268
+ attribution?: string;
269
+ } | null;
270
+ data_deleted_at?: string;
271
+ amount_charged: number;
272
+ currency: 'NGN';
273
+ created_at: string;
274
+ }
275
+ interface ListAddressChecksParams extends PageParams {
276
+ status?: AddressCheck['status'];
277
+ }
278
+ interface CreateAddressLinkParams {
279
+ /** Must be findable on the map, or the API answers 422 and no link is made. */
280
+ address: string;
281
+ state: string;
282
+ lga?: string;
283
+ /** Greets the customer on the page. */
284
+ customer_name?: string;
285
+ /** https:// URL the customer goes to when done; address_link_id, status and reference are appended. */
286
+ redirect_url?: string;
287
+ reference?: string;
288
+ /** After their location, the customer also photographs a proof of address (charged as its own check). */
289
+ require_document?: boolean;
290
+ /** Sandbox only: the result sharing a location gives. */
291
+ sandbox_outcome?: 'verified' | 'partial' | 'failed';
292
+ }
293
+ /** A link the customer opens at home to share their phone's location, compared with the address. */
294
+ interface AddressLink {
295
+ id: string;
296
+ object: 'address_link';
297
+ reference: string;
298
+ environment: Environment;
299
+ status: 'pending' | 'completed' | 'expired';
300
+ /** Once completed: the weaker of the address check and the location check. */
301
+ result: 'verified' | 'partial' | 'failed' | null;
302
+ address: {
303
+ address: string;
304
+ lga: string | null;
305
+ state: string;
306
+ } | null;
307
+ customer_name: string | null;
308
+ address_check: {
309
+ status: AddressCheck['status'];
310
+ score: number;
311
+ checks: AddressChecks;
312
+ };
313
+ place: {
314
+ formatted_address: string;
315
+ latitude: number;
316
+ longitude: number;
317
+ precision: AddressPrecision | null;
318
+ source: string;
319
+ attribution?: string;
320
+ } | null;
321
+ location: {
322
+ distance_m: number | null;
323
+ accuracy_m: number | null;
324
+ /** The phone's own street, area or LGA was named in the address (checked when it was far from the map's pin). */
325
+ area_match: 'street' | 'area' | 'lga' | null;
326
+ latitude: number | null;
327
+ longitude: number | null;
328
+ captured_at: string | null;
329
+ } | null;
330
+ reasons: string[];
331
+ attempts: number;
332
+ require_document: boolean;
333
+ /** When asked for: the proof of address (fetch it with address.getDocument), or missing / unavailable. */
334
+ document: {
335
+ id: string | null;
336
+ status: AddressDocument['status'] | 'missing' | 'unavailable' | null;
337
+ } | null;
338
+ redirect_url: string | null;
339
+ expires_at: string;
340
+ completed_at: string | null;
341
+ data_deleted_at?: string;
342
+ amount_charged: number;
343
+ currency: 'NGN';
344
+ created_at: string;
345
+ /** Only on create: the link to send the customer (its token is in the #fragment). */
346
+ url?: string;
347
+ }
348
+ interface ListAddressLinksParams extends PageParams {
349
+ status?: AddressLink['status'];
350
+ }
351
+ interface VerifyAddressDocumentParams {
352
+ /** A photo or screenshot of the bill, statement or tenancy agreement (Buffer or base64; JPEG, PNG or WEBP). */
353
+ front_image: ImageInput;
354
+ /** A second page, if the name or address is on it. */
355
+ back_image?: ImageInput;
356
+ /** The address it should show. */
357
+ address: string;
358
+ state: string;
359
+ lga?: string;
360
+ /** The customer's full name, compared with the name on the document. */
361
+ name?: string;
362
+ /** How recent it must be, in days (default 92). */
363
+ max_age_days?: number;
364
+ reference?: string;
365
+ /** Sandbox only: the result to act out. */
366
+ sandbox_outcome?: 'verified' | 'address_mismatch' | 'name_mismatch' | 'too_old' | 'tampered' | 'unreadable';
367
+ }
368
+ /** A proof of address read and checked against the customer's name and address. */
369
+ interface AddressDocument {
370
+ id: string;
371
+ object: 'address_document';
372
+ reference: string;
373
+ environment: Environment;
374
+ /** unreadable is refunded: ask for a clearer photo. */
375
+ status: 'verified' | 'partial' | 'failed' | 'unreadable';
376
+ /** e.g. name_mismatch, address_partial, document_too_old, tampering_suspected. */
377
+ reasons: string[];
378
+ address: {
379
+ address: string;
380
+ lga: string | null;
381
+ state: string;
382
+ } | null;
383
+ name: string | null;
384
+ checks: {
385
+ document_type: 'utility_bill' | 'bank_statement' | 'tenancy_agreement' | 'government_letter' | 'other';
386
+ name_match: {
387
+ result: 'pass' | 'partial' | 'fail' | 'unknown';
388
+ };
389
+ address_match: {
390
+ result: 'pass' | 'partial' | 'fail';
391
+ score: number;
392
+ state_on_document: boolean | null;
393
+ lga_on_document: boolean | null;
394
+ };
395
+ recency: {
396
+ result: 'pass' | 'fail' | 'unknown';
397
+ issue_date: string | null;
398
+ age_days: number | null;
399
+ max_age_days: number;
400
+ };
401
+ tampering_signals: string[];
402
+ } | null;
403
+ /** What was read off it. */
404
+ extracted: {
405
+ document_type: string;
406
+ issuer: string | null;
407
+ name: string | null;
408
+ address: string | null;
409
+ issue_date: string | null;
410
+ } | null;
411
+ address_link_id: string | null;
412
+ data_deleted_at?: string;
413
+ amount_charged: number;
414
+ currency: 'NGN';
415
+ created_at: string;
416
+ }
417
+ interface ListAddressDocumentsParams extends PageParams {
418
+ status?: AddressDocument['status'];
419
+ }
420
+ interface SimulateAddressLinkParams {
421
+ outcome: 'verified' | 'partial' | 'failed' | 'expired';
422
+ }
218
423
  interface AmlMonitor {
219
424
  id: string;
220
425
  reference: string;
@@ -310,7 +515,7 @@ interface Price {
310
515
  currency: 'NGN';
311
516
  is_enabled: boolean;
312
517
  }
313
- type WebhookEventType = 'verification.completed' | 'liveness.completed' | 'kyc.completed' | 'document.completed' | 'aml.match_found' | 'webhook.test';
518
+ type WebhookEventType = 'verification.completed' | 'liveness.completed' | 'kyc.completed' | 'document.completed' | 'aml.match_found' | 'address.completed' | 'webhook.test';
314
519
  interface WebhookEvent<T = unknown> {
315
520
  /** Unique per event; deliveries can repeat, so dedupe on it. */
316
521
  id: string;
@@ -333,7 +538,7 @@ declare function constructEvent<T = unknown>(rawBody: string | Buffer | Uint8Arr
333
538
  /** Sign a payload the way UVerify does, for your own tests. */
334
539
  declare function signPayload(body: string, secret: string, timestamp?: number): string;
335
540
 
336
- declare const VERSION = "0.1.1";
541
+ declare const VERSION = "0.2.0";
337
542
  interface UVerifyOptions {
338
543
  /** uvk_test_… (sandbox, free) or uvk_live_…. Defaults to the UVERIFY_API_KEY environment variable. */
339
544
  apiKey?: string;
@@ -369,6 +574,7 @@ declare class UVerify {
369
574
  readonly liveness: LivenessResource;
370
575
  readonly documents: DocumentsResource;
371
576
  readonly aml: AmlResource;
577
+ readonly address: AddressResource;
372
578
  readonly kyc: KycResource;
373
579
  readonly account: AccountResource;
374
580
  static readonly webhooks: {
@@ -447,6 +653,22 @@ declare class AmlMonitorsResource extends Resource {
447
653
  /** Stop watching a name. */
448
654
  stop(id: string): Promise<AmlMonitor>;
449
655
  }
656
+ declare class AddressResource extends Resource {
657
+ /** Is the address real, and in the LGA and state given? Found on the map and scored, instantly. */
658
+ verify(params: VerifyAddressParams): Promise<AddressCheck>;
659
+ getCheck(id: string): Promise<AddressCheck>;
660
+ listChecks(params?: ListAddressChecksParams): Promise<Page<AddressCheck>>;
661
+ /** A link the customer opens at home to share their phone's location. Send them `link.url`. */
662
+ createLink(params: CreateAddressLinkParams): Promise<AddressLink>;
663
+ getLink(id: string): Promise<AddressLink>;
664
+ listLinks(params?: ListAddressLinksParams): Promise<Page<AddressLink>>;
665
+ /** A utility bill, bank statement or tenancy agreement, checked for the customer's name, the address, its date and editing. */
666
+ verifyDocument(params: VerifyAddressDocumentParams): Promise<AddressDocument>;
667
+ getDocument(id: string): Promise<AddressDocument>;
668
+ listDocuments(params?: ListAddressDocumentsParams): Promise<Page<AddressDocument>>;
669
+ /** Sandbox only: finish a link without a phone. */
670
+ simulateLink(id: string, params: SimulateAddressLinkParams): Promise<AddressLink>;
671
+ }
450
672
  declare class AmlResource extends Resource {
451
673
  readonly monitors: AmlMonitorsResource;
452
674
  /** Screen a person or organisation against the UN, OFAC, UK, EU and Nigeria sanctions lists. */
@@ -495,4 +717,4 @@ declare class UVerifySignatureError extends Error {
495
717
  constructor(message: string);
496
718
  }
497
719
 
498
- export { type AmlMatch, type AmlMonitor, type AmlScreening, type AmlSummary, type Balance, type CacCheckParams, type CreateKycLinkParams, type CreateLivenessParams, type DocumentType, type Environment, type FaceInput, type IdDocument, type ImageInput, type KycLink, type ListKycLinksParams, type ListVerificationsParams, type LivenessSession, type MonitorParams, type NamedCheckParams, type Page, type PageParams, type PersonCheckParams, type Price, type SanctionsList, type ScreenParams, type SimulateLivenessParams, UVerify, UVerifyConnectionError, UVerifyError, type UVerifyOptions, UVerifySignatureError, VERSION, type Verification, type VerifyDocumentParams, type WebhookEvent, type WebhookEventType, constructEvent, UVerify as default, signPayload };
720
+ export { type AddressCheck, type AddressChecks, type AddressDocument, type AddressLink, type AddressPrecision, type AmlMatch, type AmlMonitor, type AmlScreening, type AmlSummary, type Balance, type CacCheckParams, type CreateAddressLinkParams, type CreateKycLinkParams, type CreateLivenessParams, type DocumentType, type Environment, type FaceInput, type IdDocument, type ImageInput, type KycLink, type ListAddressChecksParams, type ListAddressDocumentsParams, type ListAddressLinksParams, type ListKycLinksParams, type ListVerificationsParams, type LivenessSession, type MonitorParams, type NamedCheckParams, type Page, type PageParams, type PersonCheckParams, type Price, type SanctionsList, type ScreenParams, type SimulateAddressLinkParams, type SimulateLivenessParams, UVerify, UVerifyConnectionError, UVerifyError, type UVerifyOptions, UVerifySignatureError, VERSION, type Verification, type VerifyAddressDocumentParams, type VerifyAddressParams, type VerifyDocumentParams, type WebhookEvent, type WebhookEventType, constructEvent, UVerify as default, signPayload };
package/dist/index.d.ts CHANGED
@@ -215,6 +215,211 @@ interface AmlScreening {
215
215
  created_at: string;
216
216
  }
217
217
  type MonitorParams = Omit<ScreenParams, 'monitor'>;
218
+ interface VerifyAddressParams {
219
+ /** House number and street, with the area or town, e.g. "12 Admiralty Way, Lekki Phase 1". */
220
+ address: string;
221
+ /** A Nigerian state or FCT, e.g. "Lagos". */
222
+ state: string;
223
+ /** Local government area, e.g. "Eti-Osa". Optional, but it sharpens the check. */
224
+ lga?: string;
225
+ reference?: string;
226
+ /** Sandbox only: the result to get back. */
227
+ sandbox_outcome?: 'verified' | 'partial' | 'not_found' | 'state_mismatch';
228
+ }
229
+ type AddressPrecision = 'building' | 'street' | 'area' | 'region';
230
+ interface AddressChecks {
231
+ address_found: {
232
+ result: 'pass' | 'fail';
233
+ precision: AddressPrecision | null;
234
+ };
235
+ state_match: {
236
+ result: 'pass' | 'fail';
237
+ found: string | null;
238
+ };
239
+ lga_match: {
240
+ result: 'pass' | 'fail' | 'unknown';
241
+ found: string | null;
242
+ };
243
+ }
244
+ /** An address found on the map and scored. */
245
+ interface AddressCheck {
246
+ id: string;
247
+ reference: string;
248
+ environment: Environment;
249
+ /** verified (score 75+), partial (45–74) or failed. */
250
+ status: 'verified' | 'partial' | 'failed';
251
+ score: number;
252
+ address: {
253
+ address: string;
254
+ lga: string | null;
255
+ state: string;
256
+ } | null;
257
+ checks: AddressChecks;
258
+ /** e.g. address_not_found, state_mismatch, lga_mismatch, only_area_found. */
259
+ reasons: string[];
260
+ location: {
261
+ formatted_address: string;
262
+ latitude: number;
263
+ longitude: number;
264
+ precision: AddressPrecision | null;
265
+ partial_match: boolean;
266
+ source: 'openstreetmap' | 'google' | 'sandbox';
267
+ /** Show it wherever you display an OpenStreetMap result. */
268
+ attribution?: string;
269
+ } | null;
270
+ data_deleted_at?: string;
271
+ amount_charged: number;
272
+ currency: 'NGN';
273
+ created_at: string;
274
+ }
275
+ interface ListAddressChecksParams extends PageParams {
276
+ status?: AddressCheck['status'];
277
+ }
278
+ interface CreateAddressLinkParams {
279
+ /** Must be findable on the map, or the API answers 422 and no link is made. */
280
+ address: string;
281
+ state: string;
282
+ lga?: string;
283
+ /** Greets the customer on the page. */
284
+ customer_name?: string;
285
+ /** https:// URL the customer goes to when done; address_link_id, status and reference are appended. */
286
+ redirect_url?: string;
287
+ reference?: string;
288
+ /** After their location, the customer also photographs a proof of address (charged as its own check). */
289
+ require_document?: boolean;
290
+ /** Sandbox only: the result sharing a location gives. */
291
+ sandbox_outcome?: 'verified' | 'partial' | 'failed';
292
+ }
293
+ /** A link the customer opens at home to share their phone's location, compared with the address. */
294
+ interface AddressLink {
295
+ id: string;
296
+ object: 'address_link';
297
+ reference: string;
298
+ environment: Environment;
299
+ status: 'pending' | 'completed' | 'expired';
300
+ /** Once completed: the weaker of the address check and the location check. */
301
+ result: 'verified' | 'partial' | 'failed' | null;
302
+ address: {
303
+ address: string;
304
+ lga: string | null;
305
+ state: string;
306
+ } | null;
307
+ customer_name: string | null;
308
+ address_check: {
309
+ status: AddressCheck['status'];
310
+ score: number;
311
+ checks: AddressChecks;
312
+ };
313
+ place: {
314
+ formatted_address: string;
315
+ latitude: number;
316
+ longitude: number;
317
+ precision: AddressPrecision | null;
318
+ source: string;
319
+ attribution?: string;
320
+ } | null;
321
+ location: {
322
+ distance_m: number | null;
323
+ accuracy_m: number | null;
324
+ /** The phone's own street, area or LGA was named in the address (checked when it was far from the map's pin). */
325
+ area_match: 'street' | 'area' | 'lga' | null;
326
+ latitude: number | null;
327
+ longitude: number | null;
328
+ captured_at: string | null;
329
+ } | null;
330
+ reasons: string[];
331
+ attempts: number;
332
+ require_document: boolean;
333
+ /** When asked for: the proof of address (fetch it with address.getDocument), or missing / unavailable. */
334
+ document: {
335
+ id: string | null;
336
+ status: AddressDocument['status'] | 'missing' | 'unavailable' | null;
337
+ } | null;
338
+ redirect_url: string | null;
339
+ expires_at: string;
340
+ completed_at: string | null;
341
+ data_deleted_at?: string;
342
+ amount_charged: number;
343
+ currency: 'NGN';
344
+ created_at: string;
345
+ /** Only on create: the link to send the customer (its token is in the #fragment). */
346
+ url?: string;
347
+ }
348
+ interface ListAddressLinksParams extends PageParams {
349
+ status?: AddressLink['status'];
350
+ }
351
+ interface VerifyAddressDocumentParams {
352
+ /** A photo or screenshot of the bill, statement or tenancy agreement (Buffer or base64; JPEG, PNG or WEBP). */
353
+ front_image: ImageInput;
354
+ /** A second page, if the name or address is on it. */
355
+ back_image?: ImageInput;
356
+ /** The address it should show. */
357
+ address: string;
358
+ state: string;
359
+ lga?: string;
360
+ /** The customer's full name, compared with the name on the document. */
361
+ name?: string;
362
+ /** How recent it must be, in days (default 92). */
363
+ max_age_days?: number;
364
+ reference?: string;
365
+ /** Sandbox only: the result to act out. */
366
+ sandbox_outcome?: 'verified' | 'address_mismatch' | 'name_mismatch' | 'too_old' | 'tampered' | 'unreadable';
367
+ }
368
+ /** A proof of address read and checked against the customer's name and address. */
369
+ interface AddressDocument {
370
+ id: string;
371
+ object: 'address_document';
372
+ reference: string;
373
+ environment: Environment;
374
+ /** unreadable is refunded: ask for a clearer photo. */
375
+ status: 'verified' | 'partial' | 'failed' | 'unreadable';
376
+ /** e.g. name_mismatch, address_partial, document_too_old, tampering_suspected. */
377
+ reasons: string[];
378
+ address: {
379
+ address: string;
380
+ lga: string | null;
381
+ state: string;
382
+ } | null;
383
+ name: string | null;
384
+ checks: {
385
+ document_type: 'utility_bill' | 'bank_statement' | 'tenancy_agreement' | 'government_letter' | 'other';
386
+ name_match: {
387
+ result: 'pass' | 'partial' | 'fail' | 'unknown';
388
+ };
389
+ address_match: {
390
+ result: 'pass' | 'partial' | 'fail';
391
+ score: number;
392
+ state_on_document: boolean | null;
393
+ lga_on_document: boolean | null;
394
+ };
395
+ recency: {
396
+ result: 'pass' | 'fail' | 'unknown';
397
+ issue_date: string | null;
398
+ age_days: number | null;
399
+ max_age_days: number;
400
+ };
401
+ tampering_signals: string[];
402
+ } | null;
403
+ /** What was read off it. */
404
+ extracted: {
405
+ document_type: string;
406
+ issuer: string | null;
407
+ name: string | null;
408
+ address: string | null;
409
+ issue_date: string | null;
410
+ } | null;
411
+ address_link_id: string | null;
412
+ data_deleted_at?: string;
413
+ amount_charged: number;
414
+ currency: 'NGN';
415
+ created_at: string;
416
+ }
417
+ interface ListAddressDocumentsParams extends PageParams {
418
+ status?: AddressDocument['status'];
419
+ }
420
+ interface SimulateAddressLinkParams {
421
+ outcome: 'verified' | 'partial' | 'failed' | 'expired';
422
+ }
218
423
  interface AmlMonitor {
219
424
  id: string;
220
425
  reference: string;
@@ -310,7 +515,7 @@ interface Price {
310
515
  currency: 'NGN';
311
516
  is_enabled: boolean;
312
517
  }
313
- type WebhookEventType = 'verification.completed' | 'liveness.completed' | 'kyc.completed' | 'document.completed' | 'aml.match_found' | 'webhook.test';
518
+ type WebhookEventType = 'verification.completed' | 'liveness.completed' | 'kyc.completed' | 'document.completed' | 'aml.match_found' | 'address.completed' | 'webhook.test';
314
519
  interface WebhookEvent<T = unknown> {
315
520
  /** Unique per event; deliveries can repeat, so dedupe on it. */
316
521
  id: string;
@@ -333,7 +538,7 @@ declare function constructEvent<T = unknown>(rawBody: string | Buffer | Uint8Arr
333
538
  /** Sign a payload the way UVerify does, for your own tests. */
334
539
  declare function signPayload(body: string, secret: string, timestamp?: number): string;
335
540
 
336
- declare const VERSION = "0.1.1";
541
+ declare const VERSION = "0.2.0";
337
542
  interface UVerifyOptions {
338
543
  /** uvk_test_… (sandbox, free) or uvk_live_…. Defaults to the UVERIFY_API_KEY environment variable. */
339
544
  apiKey?: string;
@@ -369,6 +574,7 @@ declare class UVerify {
369
574
  readonly liveness: LivenessResource;
370
575
  readonly documents: DocumentsResource;
371
576
  readonly aml: AmlResource;
577
+ readonly address: AddressResource;
372
578
  readonly kyc: KycResource;
373
579
  readonly account: AccountResource;
374
580
  static readonly webhooks: {
@@ -447,6 +653,22 @@ declare class AmlMonitorsResource extends Resource {
447
653
  /** Stop watching a name. */
448
654
  stop(id: string): Promise<AmlMonitor>;
449
655
  }
656
+ declare class AddressResource extends Resource {
657
+ /** Is the address real, and in the LGA and state given? Found on the map and scored, instantly. */
658
+ verify(params: VerifyAddressParams): Promise<AddressCheck>;
659
+ getCheck(id: string): Promise<AddressCheck>;
660
+ listChecks(params?: ListAddressChecksParams): Promise<Page<AddressCheck>>;
661
+ /** A link the customer opens at home to share their phone's location. Send them `link.url`. */
662
+ createLink(params: CreateAddressLinkParams): Promise<AddressLink>;
663
+ getLink(id: string): Promise<AddressLink>;
664
+ listLinks(params?: ListAddressLinksParams): Promise<Page<AddressLink>>;
665
+ /** A utility bill, bank statement or tenancy agreement, checked for the customer's name, the address, its date and editing. */
666
+ verifyDocument(params: VerifyAddressDocumentParams): Promise<AddressDocument>;
667
+ getDocument(id: string): Promise<AddressDocument>;
668
+ listDocuments(params?: ListAddressDocumentsParams): Promise<Page<AddressDocument>>;
669
+ /** Sandbox only: finish a link without a phone. */
670
+ simulateLink(id: string, params: SimulateAddressLinkParams): Promise<AddressLink>;
671
+ }
450
672
  declare class AmlResource extends Resource {
451
673
  readonly monitors: AmlMonitorsResource;
452
674
  /** Screen a person or organisation against the UN, OFAC, UK, EU and Nigeria sanctions lists. */
@@ -495,4 +717,4 @@ declare class UVerifySignatureError extends Error {
495
717
  constructor(message: string);
496
718
  }
497
719
 
498
- export { type AmlMatch, type AmlMonitor, type AmlScreening, type AmlSummary, type Balance, type CacCheckParams, type CreateKycLinkParams, type CreateLivenessParams, type DocumentType, type Environment, type FaceInput, type IdDocument, type ImageInput, type KycLink, type ListKycLinksParams, type ListVerificationsParams, type LivenessSession, type MonitorParams, type NamedCheckParams, type Page, type PageParams, type PersonCheckParams, type Price, type SanctionsList, type ScreenParams, type SimulateLivenessParams, UVerify, UVerifyConnectionError, UVerifyError, type UVerifyOptions, UVerifySignatureError, VERSION, type Verification, type VerifyDocumentParams, type WebhookEvent, type WebhookEventType, constructEvent, UVerify as default, signPayload };
720
+ export { type AddressCheck, type AddressChecks, type AddressDocument, type AddressLink, type AddressPrecision, type AmlMatch, type AmlMonitor, type AmlScreening, type AmlSummary, type Balance, type CacCheckParams, type CreateAddressLinkParams, type CreateKycLinkParams, type CreateLivenessParams, type DocumentType, type Environment, type FaceInput, type IdDocument, type ImageInput, type KycLink, type ListAddressChecksParams, type ListAddressDocumentsParams, type ListAddressLinksParams, type ListKycLinksParams, type ListVerificationsParams, type LivenessSession, type MonitorParams, type NamedCheckParams, type Page, type PageParams, type PersonCheckParams, type Price, type SanctionsList, type ScreenParams, type SimulateAddressLinkParams, type SimulateLivenessParams, UVerify, UVerifyConnectionError, UVerifyError, type UVerifyOptions, UVerifySignatureError, VERSION, type Verification, type VerifyAddressDocumentParams, type VerifyAddressParams, type VerifyDocumentParams, type WebhookEvent, type WebhookEventType, constructEvent, UVerify as default, signPayload };
package/dist/index.js CHANGED
@@ -66,7 +66,7 @@ function signPayload(body, secret, timestamp = Math.floor(Date.now() / 1e3)) {
66
66
  }
67
67
 
68
68
  // src/client.ts
69
- var VERSION = "0.1.1";
69
+ var VERSION = "0.2.0";
70
70
  var DEFAULT_BASE_URL = "https://api.uverify.com.ng/v1";
71
71
  var IMAGE_FIELDS = ["selfie_image", "front_image", "back_image"];
72
72
  var newReference = (prefix) => `${prefix}_${randomBytes(9).toString("base64url")}`;
@@ -81,6 +81,7 @@ var UVerify = class _UVerify {
81
81
  liveness;
82
82
  documents;
83
83
  aml;
84
+ address;
84
85
  kyc;
85
86
  account;
86
87
  static webhooks = { constructEvent, signPayload };
@@ -106,6 +107,7 @@ var UVerify = class _UVerify {
106
107
  this.liveness = new LivenessResource(this);
107
108
  this.documents = new DocumentsResource(this);
108
109
  this.aml = new AmlResource(this);
110
+ this.address = new AddressResource(this);
109
111
  this.kyc = new KycResource(this);
110
112
  this.account = new AccountResource(this);
111
113
  }
@@ -272,6 +274,42 @@ var AmlMonitorsResource = class extends Resource {
272
274
  return this.client.request("DELETE", `/aml/monitors/${encodeURIComponent(id)}`, { retryable: true });
273
275
  }
274
276
  };
277
+ var AddressResource = class extends Resource {
278
+ /** Is the address real, and in the LGA and state given? Found on the map and scored, instantly. */
279
+ verify(params) {
280
+ return this.client.create("/address/verify", params, "addr");
281
+ }
282
+ getCheck(id) {
283
+ return this.client.request("GET", `/address/checks/${encodeURIComponent(id)}`);
284
+ }
285
+ listChecks(params = {}) {
286
+ return this.client.request("GET", "/address/checks", { query: { ...params } });
287
+ }
288
+ /** A link the customer opens at home to share their phone's location. Send them `link.url`. */
289
+ createLink(params) {
290
+ return this.client.create("/address/links", params, "addrl");
291
+ }
292
+ getLink(id) {
293
+ return this.client.request("GET", `/address/links/${encodeURIComponent(id)}`);
294
+ }
295
+ listLinks(params = {}) {
296
+ return this.client.request("GET", "/address/links", { query: { ...params } });
297
+ }
298
+ /** A utility bill, bank statement or tenancy agreement, checked for the customer's name, the address, its date and editing. */
299
+ verifyDocument(params) {
300
+ return this.client.create("/address/documents", params, "addrd");
301
+ }
302
+ getDocument(id) {
303
+ return this.client.request("GET", `/address/documents/${encodeURIComponent(id)}`);
304
+ }
305
+ listDocuments(params = {}) {
306
+ return this.client.request("GET", "/address/documents", { query: { ...params } });
307
+ }
308
+ /** Sandbox only: finish a link without a phone. */
309
+ simulateLink(id, params) {
310
+ return this.client.request("POST", `/address/links/${encodeURIComponent(id)}/simulate`, { body: { ...params } });
311
+ }
312
+ };
275
313
  var AmlResource = class extends Resource {
276
314
  monitors = new AmlMonitorsResource(this.client);
277
315
  /** Screen a person or organisation against the UN, OFAC, UK, EU and Nigeria sanctions lists. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uverifyng/node",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Official Node.js library for the UVerify API: BVN, NIN and ID checks, liveness, face match, ID documents and AML screening for Nigeria.",
5
5
  "license": "MIT",
6
6
  "author": "Elasto Web Services Limited",