@arkyc/sdk 1.0.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 ADDED
@@ -0,0 +1,56 @@
1
+ # @arkyc/sdk
2
+
3
+ TypeScript SDK for [Arkyc](../../README.md) — a typed server client for the
4
+ Public Project API, webhook verification, and a browser widget launcher.
5
+
6
+ ## Install
7
+
8
+ ```bash
9
+ npm install @arkyc/sdk
10
+ ```
11
+
12
+ ## Server
13
+
14
+ ```ts
15
+ import { Arkyc } from '@arkyc/sdk'
16
+
17
+ const arkyc = new Arkyc({ secretKey: process.env.ARKYC_SECRET_KEY! })
18
+
19
+ // Open a verification session — returns the session and a one-time client token.
20
+ const { session, clientToken } = await arkyc.sessions.create({
21
+ userReference: 'user_123',
22
+ metadata: { plan: 'pro' },
23
+ })
24
+
25
+ await arkyc.sessions.retrieve(session.id)
26
+ await arkyc.sessions.cancel(session.id)
27
+ ```
28
+
29
+ Non-2xx responses throw a typed `ArkycApiError` (`.status`, `.message`, `.errors`).
30
+ Point at a non-default API with `new Arkyc({ secretKey, baseUrl })`.
31
+
32
+ ## Webhook verification
33
+
34
+ ```ts
35
+ // In your webhook route, with the raw request body + headers:
36
+ const ok = arkyc.webhooks.verify({
37
+ payload: rawBody,
38
+ secret: process.env.ARKYC_WEBHOOK_SECRET!,
39
+ signature: req.headers['x-arkyc-signature'],
40
+ timestamp: Number(req.headers['x-arkyc-timestamp']),
41
+ })
42
+ if (!ok) return res.status(400).end()
43
+ ```
44
+
45
+ ## Browser
46
+
47
+ ```ts
48
+ import { ArkycWidget } from '@arkyc/sdk/browser'
49
+
50
+ // `clientToken` comes from arkyc.sessions.create() on your server.
51
+ ArkycWidget.open({
52
+ token: clientToken,
53
+ onComplete: (result) => console.log('done', result.status),
54
+ onError: (err) => console.error(err),
55
+ })
56
+ ```
@@ -0,0 +1,32 @@
1
+ import { CreateSessionParams, CreatedSession, VerificationSession } from "./types.mjs";
2
+
3
+ //#region src/Sessions.d.ts
4
+ declare class Sessions {
5
+ private readonly request;
6
+ private readonly defaultWorkflowId;
7
+ constructor(request: (method: string, path: string, body?: unknown) => Promise<Record<string, unknown>>, defaultWorkflowId?: string | null);
8
+ /**
9
+ * Open a session and receive its one-time client token for the widget.
10
+ *
11
+ * @param params
12
+ * @returns
13
+ */
14
+ create(params?: CreateSessionParams): Promise<CreatedSession>;
15
+ /**
16
+ * Fetch a session by id.
17
+ *
18
+ * @param id
19
+ * @returns
20
+ */
21
+ retrieve(id: string): Promise<VerificationSession>;
22
+ /**
23
+ * Cancel a non-terminal session.
24
+ *
25
+ * @param id
26
+ * @returns
27
+ */
28
+ cancel(id: string): Promise<VerificationSession>;
29
+ }
30
+ //#endregion
31
+ export { Sessions };
32
+ //# sourceMappingURL=Sessions.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Sessions.d.mts","names":[],"sources":["../src/Sessions.ts"],"mappings":";;;cAEa,QAAA;EAAA,iBAEQ,OAAA;EAAA,iBACA,iBAAA;cADA,OAAA,GAAU,MAAA,UAAgB,IAAA,UAAc,IAAA,eAAmB,OAAA,CAAQ,MAAA,oBACnE,iBAAA;;;;;;;EASb,MAAA,CAAO,MAAA,GAAQ,mBAAA,GAA2B,OAAA,CAAQ,cAAA;EAmB5B;;;;;;EAAtB,QAAA,CAAS,EAAA,WAAa,OAAA,CAAQ,mBAAA;;;;;;;EAY9B,MAAA,CAAO,EAAA,WAAa,OAAA,CAAQ,mBAAA;AAAA"}
@@ -0,0 +1,48 @@
1
+ //#region src/Sessions.ts
2
+ var Sessions = class {
3
+ request;
4
+ defaultWorkflowId;
5
+ constructor(request, defaultWorkflowId = null) {
6
+ this.request = request;
7
+ this.defaultWorkflowId = defaultWorkflowId;
8
+ }
9
+ /**
10
+ * Open a session and receive its one-time client token for the widget.
11
+ *
12
+ * @param params
13
+ * @returns
14
+ */
15
+ async create(params = {}) {
16
+ const body = await this.request("POST", "/v1/sessions", {
17
+ user_reference: params.userReference ?? null,
18
+ metadata: params.metadata ?? null,
19
+ workflow_id: params.workflowId ?? this.defaultWorkflowId ?? null
20
+ });
21
+ return {
22
+ session: body.data,
23
+ clientToken: body.client_token
24
+ };
25
+ }
26
+ /**
27
+ * Fetch a session by id.
28
+ *
29
+ * @param id
30
+ * @returns
31
+ */
32
+ async retrieve(id) {
33
+ return (await this.request("GET", `/v1/sessions/${encodeURIComponent(id)}`)).data;
34
+ }
35
+ /**
36
+ * Cancel a non-terminal session.
37
+ *
38
+ * @param id
39
+ * @returns
40
+ */
41
+ async cancel(id) {
42
+ return (await this.request("POST", `/v1/sessions/${encodeURIComponent(id)}/cancel`)).data;
43
+ }
44
+ };
45
+ //#endregion
46
+ export { Sessions };
47
+
48
+ //# sourceMappingURL=Sessions.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Sessions.mjs","names":[],"sources":["../src/Sessions.ts"],"sourcesContent":["import type { CreateSessionParams, CreatedSession, VerificationSession } from './types'\n\nexport class Sessions {\n constructor(\n private readonly request: (method: string, path: string, body?: unknown) => Promise<Record<string, unknown>>,\n private readonly defaultWorkflowId: string | null = null,\n ) {}\n\n /**\n * Open a session and receive its one-time client token for the widget.\n *\n * @param params\n * @returns\n */\n async create(params: CreateSessionParams = {}): Promise<CreatedSession> {\n const body = await this.request('POST', '/v1/sessions', {\n user_reference: params.userReference ?? null,\n metadata: params.metadata ?? null,\n workflow_id: params.workflowId ?? this.defaultWorkflowId ?? null,\n })\n\n return {\n session: body.data as VerificationSession,\n clientToken: body.client_token as string,\n }\n }\n\n /**\n * Fetch a session by id.\n *\n * @param id\n * @returns\n */\n async retrieve(id: string): Promise<VerificationSession> {\n const body = await this.request('GET', `/v1/sessions/${encodeURIComponent(id)}`)\n\n return body.data as VerificationSession\n }\n\n /**\n * Cancel a non-terminal session.\n *\n * @param id\n * @returns\n */\n async cancel(id: string): Promise<VerificationSession> {\n const body = await this.request('POST', `/v1/sessions/${encodeURIComponent(id)}/cancel`)\n\n return body.data as VerificationSession\n }\n}\n"],"mappings":";AAEA,IAAa,WAAb,MAAsB;CAED;CACA;CAFnB,YACE,SACA,oBAAoD,MACpD;EAFiB,KAAA,UAAA;EACA,KAAA,oBAAA;CAChB;;;;;;;CAQH,MAAM,OAAO,SAA8B,CAAC,GAA4B;EACtE,MAAM,OAAO,MAAM,KAAK,QAAQ,QAAQ,gBAAgB;GACtD,gBAAgB,OAAO,iBAAiB;GACxC,UAAU,OAAO,YAAY;GAC7B,aAAa,OAAO,cAAc,KAAK,qBAAqB;EAC9D,CAAC;EAED,OAAO;GACL,SAAS,KAAK;GACd,aAAa,KAAK;EACpB;CACF;;;;;;;CAQA,MAAM,SAAS,IAA0C;EAGvD,QAAO,MAFY,KAAK,QAAQ,OAAO,gBAAgB,mBAAmB,EAAE,GAAG,EAAA,CAEnE;CACd;;;;;;;CAQA,MAAM,OAAO,IAA0C;EAGrD,QAAO,MAFY,KAAK,QAAQ,QAAQ,gBAAgB,mBAAmB,EAAE,EAAE,QAAQ,EAAA,CAE3E;CACd;AACF"}
@@ -0,0 +1,15 @@
1
+ import { VerifyWebhookInput } from "@arkyc/webhooks";
2
+
3
+ //#region src/Webhooks.d.ts
4
+ declare class Webhooks {
5
+ /**
6
+ * Verify a received webhook signature against the endpoint's signing secret.
7
+ *
8
+ * @param input
9
+ * @returns
10
+ */
11
+ verify(input: VerifyWebhookInput): boolean;
12
+ }
13
+ //#endregion
14
+ export { Webhooks };
15
+ //# sourceMappingURL=Webhooks.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Webhooks.d.mts","names":[],"sources":["../src/Webhooks.ts"],"mappings":";;;cAEa,QAAA;;AAAb;;;;;EAOE,MAAA,CAAO,KAAA,EAAO,kBAAkB;AAAA"}
@@ -0,0 +1,17 @@
1
+ import { WebhookSigner } from "@arkyc/webhooks";
2
+ //#region src/Webhooks.ts
3
+ var Webhooks = class {
4
+ /**
5
+ * Verify a received webhook signature against the endpoint's signing secret.
6
+ *
7
+ * @param input
8
+ * @returns
9
+ */
10
+ verify(input) {
11
+ return WebhookSigner.verify(input);
12
+ }
13
+ };
14
+ //#endregion
15
+ export { Webhooks };
16
+
17
+ //# sourceMappingURL=Webhooks.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Webhooks.mjs","names":[],"sources":["../src/Webhooks.ts"],"sourcesContent":["import { WebhookSigner, type VerifyWebhookInput } from '@arkyc/webhooks'\n\nexport class Webhooks {\n /**\n * Verify a received webhook signature against the endpoint's signing secret.\n *\n * @param input\n * @returns\n */\n verify(input: VerifyWebhookInput): boolean {\n return WebhookSigner.verify(input)\n }\n}\n"],"mappings":";;AAEA,IAAa,WAAb,MAAsB;;;;;;;CAOpB,OAAO,OAAoC;EACzC,OAAO,cAAc,OAAO,KAAK;CACnC;AACF"}
@@ -0,0 +1,27 @@
1
+ import { OpenWidgetOptions, WidgetHandle } from "./types.mjs";
2
+
3
+ //#region src/browser.d.ts
4
+ /**
5
+ * @arkyc/sdk/browser
6
+ *
7
+ * Browser launcher for the Arkyc verification widget. Opens the hosted widget
8
+ * in an overlay iframe and relays completion via `postMessage`.
9
+ *
10
+ * ```ts
11
+ * import { ArkycWidget } from '@arkyc/sdk/browser'
12
+ * ArkycWidget.open({ token: clientToken, onComplete: (r) => console.log(r.status) })
13
+ * ```
14
+ */
15
+ declare class ArkycWidget {
16
+ private static DEFAULT_WIDGET_URL;
17
+ /**
18
+ * Open the verification widget for a client token. Returns a close handle.
19
+ *
20
+ * @param options
21
+ * @returns
22
+ */
23
+ static open(options: OpenWidgetOptions): WidgetHandle;
24
+ }
25
+ //#endregion
26
+ export { ArkycWidget };
27
+ //# sourceMappingURL=browser.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.mts","names":[],"sources":["../src/browser.ts"],"mappings":";;;;;AAaA;;;;;;;;;cAAa,WAAA;EAAA,eACI,kBAAA;;;;;;;SAQR,IAAA,CAAK,OAAA,EAAS,iBAAA,GAAoB,YAAY;AAAA"}
@@ -0,0 +1,77 @@
1
+ //#region src/browser.ts
2
+ /**
3
+ * @arkyc/sdk/browser
4
+ *
5
+ * Browser launcher for the Arkyc verification widget. Opens the hosted widget
6
+ * in an overlay iframe and relays completion via `postMessage`.
7
+ *
8
+ * ```ts
9
+ * import { ArkycWidget } from '@arkyc/sdk/browser'
10
+ * ArkycWidget.open({ token: clientToken, onComplete: (r) => console.log(r.status) })
11
+ * ```
12
+ */
13
+ var ArkycWidget = class ArkycWidget {
14
+ static DEFAULT_WIDGET_URL = "https://verify.arkyc.dev";
15
+ /**
16
+ * Open the verification widget for a client token. Returns a close handle.
17
+ *
18
+ * @param options
19
+ * @returns
20
+ */
21
+ static open(options) {
22
+ if (!options.token) throw new Error("ArkycWidget.open requires a client `token`.");
23
+ const doc = options.doc ?? globalThis.document;
24
+ const win = options.win ?? globalThis.window;
25
+ if (!doc || !win) throw new Error("ArkycWidget.open must run in a browser environment.");
26
+ const src = `${(options.widgetUrl ?? ArkycWidget.DEFAULT_WIDGET_URL).replace(/\/$/, "")}?token=${encodeURIComponent(options.token)}`;
27
+ const overlay = doc.createElement("div");
28
+ overlay.setAttribute("data-arkyc-widget", "");
29
+ overlay.style.cssText = "position:fixed;inset:0;z-index:2147483647;background:rgba(0,0,0,0.6);display:flex;align-items:center;justify-content:center;";
30
+ const iframe = doc.createElement("iframe");
31
+ iframe.src = src;
32
+ iframe.allow = "camera; microphone";
33
+ iframe.style.cssText = "width:100%;max-width:480px;height:100%;max-height:720px;border:0;border-radius:12px;background:#fff;";
34
+ overlay.appendChild(iframe);
35
+ const listeners = /* @__PURE__ */ new Map();
36
+ const emit = (name, payload) => {
37
+ options.onEvent?.({
38
+ name,
39
+ data: payload
40
+ });
41
+ listeners.get(name)?.forEach((listener) => listener(payload));
42
+ };
43
+ const close = () => {
44
+ win.removeEventListener("message", onMessage);
45
+ overlay.remove();
46
+ options.onClose?.();
47
+ };
48
+ const onMessage = (event) => {
49
+ const data = event.data;
50
+ if (!data || typeof data.type !== "string" || !data.type.startsWith("arkyc:")) return;
51
+ if (data.type === "arkyc:event") {
52
+ if (typeof data.name === "string") emit(data.name, data.data);
53
+ } else if (data.type === "arkyc:complete") {
54
+ options.onComplete?.(data.payload ?? { status: "completed" });
55
+ close();
56
+ } else if (data.type === "arkyc:error") {
57
+ options.onError?.(data.error);
58
+ close();
59
+ } else if (data.type === "arkyc:close") close();
60
+ };
61
+ win.addEventListener("message", onMessage);
62
+ (doc.body ?? doc.documentElement).appendChild(overlay);
63
+ return {
64
+ close,
65
+ on: (event, listener) => {
66
+ const set = listeners.get(event) ?? /* @__PURE__ */ new Set();
67
+ set.add(listener);
68
+ listeners.set(event, set);
69
+ return () => set.delete(listener);
70
+ }
71
+ };
72
+ }
73
+ };
74
+ //#endregion
75
+ export { ArkycWidget };
76
+
77
+ //# sourceMappingURL=browser.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.mjs","names":[],"sources":["../src/browser.ts"],"sourcesContent":["import type { OpenWidgetOptions, WidgetEventListener, WidgetHandle, WidgetResult } from './types'\n\n/**\n * @arkyc/sdk/browser\n *\n * Browser launcher for the Arkyc verification widget. Opens the hosted widget\n * in an overlay iframe and relays completion via `postMessage`.\n *\n * ```ts\n * import { ArkycWidget } from '@arkyc/sdk/browser'\n * ArkycWidget.open({ token: clientToken, onComplete: (r) => console.log(r.status) })\n * ```\n */\nexport class ArkycWidget {\n private static DEFAULT_WIDGET_URL = 'https://verify.arkyc.dev'\n\n /**\n * Open the verification widget for a client token. Returns a close handle.\n *\n * @param options\n * @returns\n */\n static open(options: OpenWidgetOptions): WidgetHandle {\n if (!options.token) throw new Error('ArkycWidget.open requires a client `token`.')\n\n const doc = options.doc ?? globalThis.document\n const win = options.win ?? globalThis.window\n if (!doc || !win) throw new Error('ArkycWidget.open must run in a browser environment.')\n\n const widgetUrl = (options.widgetUrl ?? ArkycWidget.DEFAULT_WIDGET_URL).replace(/\\/$/, '')\n const src = `${widgetUrl}?token=${encodeURIComponent(options.token)}`\n\n const overlay = doc.createElement('div')\n overlay.setAttribute('data-arkyc-widget', '')\n overlay.style.cssText =\n 'position:fixed;inset:0;z-index:2147483647;background:rgba(0,0,0,0.6);display:flex;align-items:center;justify-content:center;'\n\n const iframe = doc.createElement('iframe')\n iframe.src = src\n iframe.allow = 'camera; microphone'\n iframe.style.cssText =\n 'width:100%;max-width:480px;height:100%;max-height:720px;border:0;border-radius:12px;background:#fff;'\n overlay.appendChild(iframe)\n\n // Named event listeners registered via the returned handle's `on`.\n const listeners = new Map<string, Set<WidgetEventListener>>()\n const emit = (name: string, payload?: unknown): void => {\n options.onEvent?.({ name, data: payload })\n listeners.get(name)?.forEach((listener) => listener(payload))\n }\n\n const close = (): void => {\n win.removeEventListener('message', onMessage)\n overlay.remove()\n options.onClose?.()\n }\n\n const onMessage = (event: MessageEvent): void => {\n const data = event.data as {\n type?: string\n payload?: WidgetResult\n error?: unknown\n name?: string\n data?: unknown\n } | null\n if (!data || typeof data.type !== 'string' || !data.type.startsWith('arkyc:')) return\n\n if (data.type === 'arkyc:event') {\n // The widget's event firehose, forwarded across the iframe.\n if (typeof data.name === 'string') emit(data.name, data.data)\n } else if (data.type === 'arkyc:complete') {\n options.onComplete?.(data.payload ?? { status: 'completed' })\n close()\n } else if (data.type === 'arkyc:error') {\n options.onError?.(data.error)\n close()\n } else if (data.type === 'arkyc:close') {\n close()\n }\n }\n\n win.addEventListener('message', onMessage)\n ;(doc.body ?? doc.documentElement).appendChild(overlay)\n\n return {\n close,\n on: (event, listener) => {\n const set = listeners.get(event) ?? new Set<WidgetEventListener>()\n set.add(listener)\n listeners.set(event, set)\n\n return () => set.delete(listener)\n },\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;AAaA,IAAa,cAAb,MAAa,YAAY;CACvB,OAAe,qBAAqB;;;;;;;CAQpC,OAAO,KAAK,SAA0C;EACpD,IAAI,CAAC,QAAQ,OAAO,MAAM,IAAI,MAAM,6CAA6C;EAEjF,MAAM,MAAM,QAAQ,OAAO,WAAW;EACtC,MAAM,MAAM,QAAQ,OAAO,WAAW;EACtC,IAAI,CAAC,OAAO,CAAC,KAAK,MAAM,IAAI,MAAM,qDAAqD;EAGvF,MAAM,MAAM,IADO,QAAQ,aAAa,YAAY,mBAAA,CAAoB,QAAQ,OAAO,EAChE,EAAE,SAAS,mBAAmB,QAAQ,KAAK;EAElE,MAAM,UAAU,IAAI,cAAc,KAAK;EACvC,QAAQ,aAAa,qBAAqB,EAAE;EAC5C,QAAQ,MAAM,UACZ;EAEF,MAAM,SAAS,IAAI,cAAc,QAAQ;EACzC,OAAO,MAAM;EACb,OAAO,QAAQ;EACf,OAAO,MAAM,UACX;EACF,QAAQ,YAAY,MAAM;EAG1B,MAAM,4BAAY,IAAI,IAAsC;EAC5D,MAAM,QAAQ,MAAc,YAA4B;GACtD,QAAQ,UAAU;IAAE;IAAM,MAAM;GAAQ,CAAC;GACzC,UAAU,IAAI,IAAI,CAAC,EAAE,SAAS,aAAa,SAAS,OAAO,CAAC;EAC9D;EAEA,MAAM,cAAoB;GACxB,IAAI,oBAAoB,WAAW,SAAS;GAC5C,QAAQ,OAAO;GACf,QAAQ,UAAU;EACpB;EAEA,MAAM,aAAa,UAA8B;GAC/C,MAAM,OAAO,MAAM;GAOnB,IAAI,CAAC,QAAQ,OAAO,KAAK,SAAS,YAAY,CAAC,KAAK,KAAK,WAAW,QAAQ,GAAG;GAE/E,IAAI,KAAK,SAAS;QAEZ,OAAO,KAAK,SAAS,UAAU,KAAK,KAAK,MAAM,KAAK,IAAI;GAAA,OACvD,IAAI,KAAK,SAAS,kBAAkB;IACzC,QAAQ,aAAa,KAAK,WAAW,EAAE,QAAQ,YAAY,CAAC;IAC5D,MAAM;GACR,OAAO,IAAI,KAAK,SAAS,eAAe;IACtC,QAAQ,UAAU,KAAK,KAAK;IAC5B,MAAM;GACR,OAAO,IAAI,KAAK,SAAS,eACvB,MAAM;EAEV;EAEA,IAAI,iBAAiB,WAAW,SAAS;EACxC,CAAC,IAAI,QAAQ,IAAI,gBAAA,CAAiB,YAAY,OAAO;EAEtD,OAAO;GACL;GACA,KAAK,OAAO,aAAa;IACvB,MAAM,MAAM,UAAU,IAAI,KAAK,qBAAK,IAAI,IAAyB;IACjE,IAAI,IAAI,QAAQ;IAChB,UAAU,IAAI,OAAO,GAAG;IAExB,aAAa,IAAI,OAAO,QAAQ;GAClC;EACF;CACF;AACF"}
@@ -0,0 +1,43 @@
1
+ import { ArkycOptions } from "./types.mjs";
2
+ import { Sessions } from "./Sessions.mjs";
3
+ import { Webhooks } from "./Webhooks.mjs";
4
+
5
+ //#region src/client.d.ts
6
+ /**
7
+ * Arkyc server SDK. Authenticates with a project secret key and wraps the
8
+ * Public Project API.
9
+ *
10
+ * ```ts
11
+ * const arkyc = new Arkyc({ secretKey: process.env.ARKYC_SECRET_KEY!, workflowId: 'wf_…' })
12
+ * const { session, clientToken } = await arkyc.sessions.create({ userReference: 'user_123' })
13
+ * ```
14
+ */
15
+ declare class Arkyc {
16
+ private static DEFAULT_BASE_URL;
17
+ private readonly secretKey;
18
+ private readonly baseUrl;
19
+ private readonly fetchImpl;
20
+ private readonly workflowId;
21
+ /**
22
+ * Verification session operations. `request` is bound so it keeps `this`
23
+ * (and thus `fetchImpl`) when invoked from the Sessions helper.
24
+ */
25
+ readonly sessions: Sessions;
26
+ /**
27
+ * Webhook helpers.
28
+ */
29
+ readonly webhooks: Webhooks;
30
+ constructor(options: ArkycOptions);
31
+ /**
32
+ * Issue an authenticated request and unwrap the `{ status, data, … }` envelope.
33
+ *
34
+ * @param method
35
+ * @param path
36
+ * @param body
37
+ * @returns
38
+ */
39
+ private request;
40
+ }
41
+ //#endregion
42
+ export { Arkyc };
43
+ //# sourceMappingURL=client.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.mts","names":[],"sources":["../src/client.ts"],"mappings":";;;;;;;AAcA;;;;;;;cAAa,KAAA;EAAA,eACI,gBAAA;EAAA,iBACE,SAAA;EAAA,iBACA,OAAA;EAAA,iBACA,SAAA;EAAA,iBACA,UAAA;EAMR;;;;EAAA,SAAA,QAAA,EAAU,QAAA;EAOE;;;EAAA,SAFZ,QAAA,EAAQ,QAAA;cAEL,OAAA,EAAS,YAAA;;;;;;;;;UAoBP,OAAA;AAAA"}
@@ -0,0 +1,62 @@
1
+ import { ArkycApiError } from "./errors.mjs";
2
+ import { Sessions } from "./Sessions.mjs";
3
+ import { Webhooks } from "./Webhooks.mjs";
4
+ //#region src/client.ts
5
+ /**
6
+ * Arkyc server SDK. Authenticates with a project secret key and wraps the
7
+ * Public Project API.
8
+ *
9
+ * ```ts
10
+ * const arkyc = new Arkyc({ secretKey: process.env.ARKYC_SECRET_KEY!, workflowId: 'wf_…' })
11
+ * const { session, clientToken } = await arkyc.sessions.create({ userReference: 'user_123' })
12
+ * ```
13
+ */
14
+ var Arkyc = class Arkyc {
15
+ static DEFAULT_BASE_URL = "https://api.arkyc.dev";
16
+ secretKey;
17
+ baseUrl;
18
+ fetchImpl;
19
+ workflowId;
20
+ /**
21
+ * Verification session operations. `request` is bound so it keeps `this`
22
+ * (and thus `fetchImpl`) when invoked from the Sessions helper.
23
+ */
24
+ sessions;
25
+ /**
26
+ * Webhook helpers.
27
+ */
28
+ webhooks = new Webhooks();
29
+ constructor(options) {
30
+ if (!options.secretKey) throw new Error("Arkyc requires a `secretKey`.");
31
+ this.secretKey = options.secretKey;
32
+ this.baseUrl = (options.baseUrl ?? Arkyc.DEFAULT_BASE_URL).replace(/\/$/, "");
33
+ this.fetchImpl = options.fetch ?? globalThis.fetch;
34
+ this.workflowId = options.workflowId ?? null;
35
+ this.sessions = new Sessions(this.request.bind(this), this.workflowId);
36
+ }
37
+ /**
38
+ * Issue an authenticated request and unwrap the `{ status, data, … }` envelope.
39
+ *
40
+ * @param method
41
+ * @param path
42
+ * @param body
43
+ * @returns
44
+ */
45
+ async request(method, path, body) {
46
+ const response = await this.fetchImpl(`${this.baseUrl}/api${path}`, {
47
+ method,
48
+ headers: {
49
+ authorization: `Bearer ${this.secretKey}`,
50
+ ...body !== void 0 ? { "content-type": "application/json" } : {}
51
+ },
52
+ body: body !== void 0 ? JSON.stringify(body) : void 0
53
+ });
54
+ const json = await response.json().catch(() => ({}));
55
+ if (!response.ok) throw new ArkycApiError(json.message ?? `Arkyc request failed with status ${response.status}`, response.status, json.errors);
56
+ return json;
57
+ }
58
+ };
59
+ //#endregion
60
+ export { Arkyc };
61
+
62
+ //# sourceMappingURL=client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import { ArkycApiError } from './errors'\nimport type { ArkycOptions } from './types'\nimport { Sessions } from './Sessions'\nimport { Webhooks } from './Webhooks'\n\n/**\n * Arkyc server SDK. Authenticates with a project secret key and wraps the\n * Public Project API.\n *\n * ```ts\n * const arkyc = new Arkyc({ secretKey: process.env.ARKYC_SECRET_KEY!, workflowId: 'wf_…' })\n * const { session, clientToken } = await arkyc.sessions.create({ userReference: 'user_123' })\n * ```\n */\nexport class Arkyc {\n private static DEFAULT_BASE_URL = 'https://api.arkyc.dev'\n private readonly secretKey: string\n private readonly baseUrl: string\n private readonly fetchImpl: typeof fetch\n private readonly workflowId: string | null\n\n /**\n * Verification session operations. `request` is bound so it keeps `this`\n * (and thus `fetchImpl`) when invoked from the Sessions helper.\n */\n readonly sessions: Sessions\n\n /**\n * Webhook helpers.\n */\n readonly webhooks = new Webhooks()\n\n constructor(options: ArkycOptions) {\n if (!options.secretKey) throw new Error('Arkyc requires a `secretKey`.')\n\n this.secretKey = options.secretKey\n this.baseUrl = (options.baseUrl ?? Arkyc.DEFAULT_BASE_URL).replace(/\\/$/, '')\n this.fetchImpl = options.fetch ?? globalThis.fetch\n // Optional default workflow applied to every session this client opens,\n // overridable per `sessions.create({ workflowId })`.\n this.workflowId = options.workflowId ?? null\n this.sessions = new Sessions(this.request.bind(this), this.workflowId)\n }\n\n /**\n * Issue an authenticated request and unwrap the `{ status, data, … }` envelope.\n *\n * @param method\n * @param path\n * @param body\n * @returns\n */\n private async request(method: string, path: string, body?: unknown): Promise<Record<string, unknown>> {\n const response = await this.fetchImpl(`${this.baseUrl}/api${path}`, {\n method,\n headers: {\n authorization: `Bearer ${this.secretKey}`,\n ...(body !== undefined ? { 'content-type': 'application/json' } : {}),\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n })\n\n const json = (await response.json().catch(() => ({}))) as Record<string, unknown>\n if (!response.ok) {\n throw new ArkycApiError(\n (json.message as string) ?? `Arkyc request failed with status ${response.status}`,\n response.status,\n json.errors as Record<string, string[] | string> | undefined,\n )\n }\n\n return json\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,IAAa,QAAb,MAAa,MAAM;CACjB,OAAe,mBAAmB;CAClC;CACA;CACA;CACA;;;;;CAMA;;;;CAKA,WAAoB,IAAI,SAAS;CAEjC,YAAY,SAAuB;EACjC,IAAI,CAAC,QAAQ,WAAW,MAAM,IAAI,MAAM,+BAA+B;EAEvE,KAAK,YAAY,QAAQ;EACzB,KAAK,WAAW,QAAQ,WAAW,MAAM,iBAAA,CAAkB,QAAQ,OAAO,EAAE;EAC5E,KAAK,YAAY,QAAQ,SAAS,WAAW;EAG7C,KAAK,aAAa,QAAQ,cAAc;EACxC,KAAK,WAAW,IAAI,SAAS,KAAK,QAAQ,KAAK,IAAI,GAAG,KAAK,UAAU;CACvE;;;;;;;;;CAUA,MAAc,QAAQ,QAAgB,MAAc,MAAkD;EACpG,MAAM,WAAW,MAAM,KAAK,UAAU,GAAG,KAAK,QAAQ,MAAM,QAAQ;GAClE;GACA,SAAS;IACP,eAAe,UAAU,KAAK;IAC9B,GAAI,SAAS,KAAA,IAAY,EAAE,gBAAgB,mBAAmB,IAAI,CAAC;GACrE;GACA,MAAM,SAAS,KAAA,IAAY,KAAK,UAAU,IAAI,IAAI,KAAA;EACpD,CAAC;EAED,MAAM,OAAQ,MAAM,SAAS,KAAK,CAAC,CAAC,aAAa,CAAC,EAAE;EACpD,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,cACP,KAAK,WAAsB,oCAAoC,SAAS,UACzE,SAAS,QACT,KAAK,MACP;EAGF,OAAO;CACT;AACF"}
@@ -0,0 +1,14 @@
1
+ //#region src/errors.d.ts
2
+ /**
3
+ * Error thrown when the Arkyc API returns a non-2xx response.
4
+ */
5
+ declare class ArkycApiError extends Error {
6
+ /** HTTP status code. */
7
+ readonly status: number;
8
+ /** Field-level validation errors, when present (422). */
9
+ readonly errors?: Record<string, string[] | string>;
10
+ constructor(message: string, status: number, errors?: Record<string, string[] | string>);
11
+ }
12
+ //#endregion
13
+ export { ArkycApiError };
14
+ //# sourceMappingURL=errors.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.mts","names":[],"sources":["../src/errors.ts"],"mappings":";;AAGA;;cAAa,aAAA,SAAsB,KAAA;EAIf;EAAA,SAFT,MAAA;EAFwB;EAAA,SAIxB,MAAA,GAAS,MAAA;cAEN,OAAA,UAAiB,MAAA,UAAgB,MAAA,GAAS,MAAA;AAAA"}
@@ -0,0 +1,20 @@
1
+ //#region src/errors.ts
2
+ /**
3
+ * Error thrown when the Arkyc API returns a non-2xx response.
4
+ */
5
+ var ArkycApiError = class extends Error {
6
+ /** HTTP status code. */
7
+ status;
8
+ /** Field-level validation errors, when present (422). */
9
+ errors;
10
+ constructor(message, status, errors) {
11
+ super(message);
12
+ this.name = "ArkycApiError";
13
+ this.status = status;
14
+ this.errors = errors;
15
+ }
16
+ };
17
+ //#endregion
18
+ export { ArkycApiError };
19
+
20
+ //# sourceMappingURL=errors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Error thrown when the Arkyc API returns a non-2xx response.\n */\nexport class ArkycApiError extends Error {\n /** HTTP status code. */\n readonly status: number\n /** Field-level validation errors, when present (422). */\n readonly errors?: Record<string, string[] | string>\n\n constructor(message: string, status: number, errors?: Record<string, string[] | string>) {\n super(message)\n this.name = 'ArkycApiError'\n this.status = status\n this.errors = errors\n }\n}\n"],"mappings":";;;;AAGA,IAAa,gBAAb,cAAmC,MAAM;;CAEvC;;CAEA;CAEA,YAAY,SAAiB,QAAgB,QAA4C;EACvF,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,KAAK,SAAS;CAChB;AACF"}
@@ -0,0 +1,7 @@
1
+ import { ArkycOptions, CreateSessionParams, CreatedSession, VerificationSession } from "./types.mjs";
2
+ import { Sessions } from "./Sessions.mjs";
3
+ import { Webhooks } from "./Webhooks.mjs";
4
+ import { Arkyc } from "./client.mjs";
5
+ import { ArkycApiError } from "./errors.mjs";
6
+ import { VerifyWebhookInput, WebhookSigner } from "@arkyc/webhooks";
7
+ export { Arkyc, ArkycApiError, type ArkycOptions, type CreateSessionParams, type CreatedSession, Sessions, type VerificationSession, type VerifyWebhookInput, WebhookSigner, Webhooks };
package/dist/index.mjs ADDED
@@ -0,0 +1,6 @@
1
+ import { ArkycApiError } from "./errors.mjs";
2
+ import { Sessions } from "./Sessions.mjs";
3
+ import { Webhooks } from "./Webhooks.mjs";
4
+ import { Arkyc } from "./client.mjs";
5
+ import { WebhookSigner } from "@arkyc/webhooks";
6
+ export { Arkyc, ArkycApiError, Sessions, WebhookSigner, Webhooks };
@@ -0,0 +1,97 @@
1
+ import { DecisionReason, Metadata, VerificationDecision, VerificationStatus, WorkflowConfig } from "@arkyc/types";
2
+
3
+ //#region src/types.d.ts
4
+ /** A verification session as returned by the public API (snake_case JSON). */
5
+ interface VerificationSession {
6
+ id: string;
7
+ project_id: string;
8
+ user_reference: string | null;
9
+ status: VerificationStatus;
10
+ auto_decision: VerificationDecision | null;
11
+ final_decision: VerificationDecision | null;
12
+ decision_reason: DecisionReason | null;
13
+ risk_score: number | null;
14
+ assigned_to: string | null;
15
+ /** The workflow applied to this session, if any (its ID), and the frozen config. */
16
+ workflow_id: string | null;
17
+ workflow: WorkflowConfig | null;
18
+ /** Signed, time-limited URLs for captured assets, served inline as images (present on retrieve). */
19
+ assets?: Record<string, string> | null;
20
+ expires_at: string;
21
+ completed_at: string | null;
22
+ created_at: string;
23
+ }
24
+ /** Parameters for opening a verification session. */
25
+ interface CreateSessionParams {
26
+ /** Your reference for the user being verified. */
27
+ userReference?: string | null;
28
+ /** Arbitrary metadata stored with the session. */
29
+ metadata?: Metadata | null;
30
+ /** Workflow to apply, overriding the client's default `workflowId` for this session. */
31
+ workflowId?: string | null;
32
+ }
33
+ /** A freshly opened session plus its one-time client token for the widget. */
34
+ interface CreatedSession {
35
+ session: VerificationSession;
36
+ clientToken: string;
37
+ }
38
+ /** Configuration for the server SDK client. */
39
+ interface ArkycOptions {
40
+ /** Project secret API key (`sk_…`). */
41
+ secretKey: string;
42
+ /** API base URL (default `https://api.arkyc.dev`). */
43
+ baseUrl?: string;
44
+ /**
45
+ * Optional workflow applied to every session this client opens (the workflow's
46
+ * ID, from the dashboard). Overridable per `sessions.create({ workflowId })`.
47
+ */
48
+ workflowId?: string | null;
49
+ /** Custom fetch implementation (defaults to global `fetch`). */
50
+ fetch?: typeof fetch;
51
+ }
52
+ /** Payload delivered when the widget flow completes. */
53
+ interface WidgetResult {
54
+ status: string;
55
+ [key: string]: unknown;
56
+ }
57
+ /** A widget event delivered to {@link OpenWidgetOptions.onEvent} / `handle.on`. */
58
+ interface WidgetEvent {
59
+ /** Event name, e.g. `session.transition`, `complete`, `error`, `close`. */
60
+ name: string;
61
+ /** Event payload (shape depends on `name`). */
62
+ data?: unknown;
63
+ }
64
+ /** Subscribe to a named widget event; returns an unsubscribe function. */
65
+ type WidgetEventListener = (data: unknown) => void;
66
+ /** Options for {@link ArkycWidget.open}. */
67
+ interface OpenWidgetOptions {
68
+ /** The session's client token (from `arkyc.sessions.create`). */
69
+ token: string;
70
+ /** Hosted widget origin (default `https://verify.arkyc.dev`). */
71
+ widgetUrl?: string;
72
+ onComplete?: (result: WidgetResult) => void;
73
+ onError?: (error: unknown) => void;
74
+ onClose?: () => void;
75
+ /**
76
+ * Firehose for live session events (`session.transition`) and lifecycle events
77
+ * (`complete` / `error` / `close`), delivered from the hosted widget over
78
+ * `postMessage`. Also subscribable per-name via {@link WidgetHandle.on}.
79
+ */
80
+ onEvent?: (event: WidgetEvent) => void;
81
+ /** Injectable for testing; defaults to the global `document`. */
82
+ doc?: Document;
83
+ /** Injectable for testing; defaults to the global `window`. */
84
+ win?: Window;
85
+ }
86
+ /** A handle to the open widget. */
87
+ interface WidgetHandle {
88
+ close: () => void;
89
+ /**
90
+ * Subscribe to a named widget event (e.g. `session.transition`, `complete`).
91
+ * Returns an unsubscribe function.
92
+ */
93
+ on: (event: string, listener: WidgetEventListener) => () => void;
94
+ }
95
+ //#endregion
96
+ export { ArkycOptions, CreateSessionParams, CreatedSession, OpenWidgetOptions, VerificationSession, WidgetHandle };
97
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;;;UAGiB,mBAAA;EACf,EAAA;EACA,UAAA;EACA,cAAA;EACA,MAAA,EAAQ,kBAAA;EACR,aAAA,EAAe,oBAAA;EACf,cAAA,EAAgB,oBAAA;EAChB,eAAA,EAAiB,cAAA;EACjB,UAAA;EACA,WAAA;EAKe;EAHf,WAAA;EACA,QAAA,EAAU,cAAA;EAVV;EAYA,MAAA,GAAS,MAAA;EACT,UAAA;EACA,YAAA;EACA,UAAA;AAAA;;UAIe,mBAAA;EAdf;EAgBA,aAAA;EAfA;EAiBA,QAAA,GAAW,QAAQ;EAdnB;EAgBA,UAAA;AAAA;;UAIe,cAAA;EACf,OAAA,EAAS,mBAAmB;EAC5B,WAAA;AAAA;;UAIe,YAAA;EAhBA;EAkBf,SAAA;;EAEA,OAAA;EAlBA;;;;EAuBA,UAAA;EAnBU;EAqBV,KAAA,UAAe,KAAK;AAAA;;UAIL,YAAA;EACf,MAAA;EAAA,CACC,GAAW;AAAA;;UAIG,WAAA;EArBA;EAuBf,IAAA;;EAEA,IAAI;AAAA;;KAIM,mBAAA,IAAuB,IAAa;;UAG/B,iBAAA;EArBK;EAuBpB,KAAA;EAnBe;EAqBf,SAAA;EACA,UAAA,IAAc,MAAA,EAAQ,YAAA;EACtB,OAAA,IAAW,KAAA;EACX,OAAA;EAlBe;;;;AAIX;EAoBJ,OAAA,IAAW,KAAA,EAAO,WAAA;EAhBW;EAkB7B,GAAA,GAAM,QAAA;EAlBwC;EAoB9C,GAAA,GAAM,MAAA;AAAA;;UAIS,YAAA;EACf,KAAA;EATkB;;;;EAclB,EAAA,GAAK,KAAA,UAAe,QAAA,EAAU,mBAAmB;AAAA"}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@arkyc/sdk",
3
+ "version": "1.0.0",
4
+ "description": "Arkyc TypeScript SDK (server + browser)",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.mjs",
8
+ "module": "./dist/index.mjs",
9
+ "types": "./dist/index.d.mts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.mts",
13
+ "import": "./dist/index.mjs"
14
+ },
15
+ "./browser": {
16
+ "types": "./dist/browser.d.mts",
17
+ "import": "./dist/browser.mjs"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "dependencies": {
24
+ "@arkyc/types": "^1.0.0",
25
+ "@arkyc/webhooks": "^1.0.0",
26
+ "@arkyc/core": "^1.0.0"
27
+ },
28
+ "scripts": {
29
+ "typecheck": "tsc --noEmit",
30
+ "test": "vitest run",
31
+ "lint": "eslint src",
32
+ "clean": "rm -rf dist"
33
+ }
34
+ }