@xkova/sdk 0.1.0-alpha.5 → 0.1.0-alpha.7

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.
@@ -11,6 +11,7 @@ export declare class PaymentRequestsResource extends Resource {
11
11
  has_more: boolean;
12
12
  }>;
13
13
  create(body: ReqBody<'createPaymentRequest'>, opts?: XKOVAMutationOptions): Promise<{
14
+ notification_status?: "queued" | "sent" | "failed" | "cancelled";
14
15
  id?: import("../generated/types.js").components["schemas"]["PaymentRequestId"];
15
16
  requester_id?: import("../generated/types.js").components["schemas"]["AccountHolderId"];
16
17
  payer_id?: import("../generated/types.js").components["schemas"]["AccountHolderId"] | null;
@@ -26,6 +27,7 @@ export declare class PaymentRequestsResource extends Resource {
26
27
  updated_at?: import("../generated/types.js").components["schemas"]["TimestampUtc"];
27
28
  }>;
28
29
  retrieve(id: string): Promise<{
30
+ notification_status?: "queued" | "sent" | "failed" | "cancelled";
29
31
  id?: import("../generated/types.js").components["schemas"]["PaymentRequestId"];
30
32
  requester_id?: import("../generated/types.js").components["schemas"]["AccountHolderId"];
31
33
  payer_id?: import("../generated/types.js").components["schemas"]["AccountHolderId"] | null;
@@ -82,6 +84,7 @@ export declare class PaymentRequestsResource extends Resource {
82
84
  finalized_at: import("../generated/types.js").components["schemas"]["TimestampUtc"] | null;
83
85
  }>;
84
86
  cancel(id: string, opts?: XKOVAMutationOptions): Promise<{
87
+ notification_status?: "queued" | "sent" | "failed" | "cancelled";
85
88
  id?: import("../generated/types.js").components["schemas"]["PaymentRequestId"];
86
89
  requester_id?: import("../generated/types.js").components["schemas"]["AccountHolderId"];
87
90
  payer_id?: import("../generated/types.js").components["schemas"]["AccountHolderId"] | null;
@@ -97,6 +100,7 @@ export declare class PaymentRequestsResource extends Resource {
97
100
  updated_at?: import("../generated/types.js").components["schemas"]["TimestampUtc"];
98
101
  }>;
99
102
  decline(id: string, body?: ReqBody<'declinePaymentRequest'>, opts?: XKOVAMutationOptions): Promise<{
103
+ notification_status?: "queued" | "sent" | "failed" | "cancelled";
100
104
  id?: import("../generated/types.js").components["schemas"]["PaymentRequestId"];
101
105
  requester_id?: import("../generated/types.js").components["schemas"]["AccountHolderId"];
102
106
  payer_id?: import("../generated/types.js").components["schemas"]["AccountHolderId"] | null;
@@ -47,6 +47,12 @@ export declare class TenantResource extends Resource {
47
47
  publishable_key: string;
48
48
  name: string;
49
49
  provider_kind: "xkova_hosted" | "oidc" | "signed_launch";
50
+ provider_namespace: string;
51
+ issuer: string | null;
52
+ audience: string | null;
53
+ jwks_uri: string | null;
54
+ allowed_jwt_algorithms: ("RS256" | "PS256" | "ES256" | "EdDSA")[];
55
+ proof_binding_mode: "authorization_nonce" | "server_assertion_jti";
50
56
  enrollment_mode: import("../generated/types.js").components["schemas"]["MemberAuthEnrollmentMode"];
51
57
  is_default: boolean;
52
58
  status: "active" | "principal_disabled";
@@ -73,6 +79,12 @@ export declare class TenantResource extends Resource {
73
79
  publishable_key: string;
74
80
  name: string;
75
81
  provider_kind: "xkova_hosted" | "oidc" | "signed_launch";
82
+ provider_namespace: string;
83
+ issuer: string | null;
84
+ audience: string | null;
85
+ jwks_uri: string | null;
86
+ allowed_jwt_algorithms: ("RS256" | "PS256" | "ES256" | "EdDSA")[];
87
+ proof_binding_mode: "authorization_nonce" | "server_assertion_jti";
76
88
  enrollment_mode: import("../generated/types.js").components["schemas"]["MemberAuthEnrollmentMode"];
77
89
  is_default: boolean;
78
90
  status: "active" | "principal_disabled";
@@ -90,6 +102,9 @@ export declare class TenantResource extends Resource {
90
102
  created_at: import("../generated/types.js").components["schemas"]["TimestampUtc"];
91
103
  updated_at: import("../generated/types.js").components["schemas"]["TimestampUtc"];
92
104
  }>;
105
+ /** Disables the exact Hosted Auth or OIDC member application. */
106
+ disableMemberAuthApplication(id: string, opts?: XKOVAMutationOptions): Promise<void>;
107
+ /** Existing Hosted Auth convenience name. */
93
108
  disableHostedApplication(id: string, opts?: XKOVAMutationOptions): Promise<void>;
94
109
  configureOidcApplication(body: ReqBody<'configureMemberAuthOidcApplication'>, opts?: XKOVAMutationOptions): Promise<{
95
110
  id: string;
@@ -15,9 +15,14 @@ export class TenantResource extends Resource {
15
15
  updateHostedApplication(id, body, opts) {
16
16
  return this.patchJson(`/tenant/member-auth/applications/${this.enc(id)}`, body, opts);
17
17
  }
18
- disableHostedApplication(id, opts) {
18
+ /** Disables the exact Hosted Auth or OIDC member application. */
19
+ disableMemberAuthApplication(id, opts) {
19
20
  return this.deleteJson(`/tenant/member-auth/applications/${this.enc(id)}`, opts);
20
21
  }
22
+ /** Existing Hosted Auth convenience name. */
23
+ disableHostedApplication(id, opts) {
24
+ return this.disableMemberAuthApplication(id, opts);
25
+ }
21
26
  configureOidcApplication(body, opts) {
22
27
  return this.putJson('/tenant/member-auth/application', body, opts);
23
28
  }
@@ -186,6 +186,9 @@ export declare class TokenizationResource extends Resource {
186
186
  raw_contract: string | null;
187
187
  raw_function: string | null;
188
188
  raw_args: string[] | null;
189
+ failure_reason_code: string | null;
190
+ failure_reason_detail: string | null;
191
+ failure_retryable: boolean;
189
192
  created_at: string;
190
193
  updated_at: string;
191
194
  }>;
@@ -222,6 +225,9 @@ export declare class TokenizationResource extends Resource {
222
225
  raw_contract: string | null;
223
226
  raw_function: string | null;
224
227
  raw_args: string[] | null;
228
+ failure_reason_code: string | null;
229
+ failure_reason_detail: string | null;
230
+ failure_retryable: boolean;
225
231
  created_at: string;
226
232
  updated_at: string;
227
233
  }>;
@@ -261,6 +267,9 @@ export declare class TokenizationResource extends Resource {
261
267
  raw_contract: string | null;
262
268
  raw_function: string | null;
263
269
  raw_args: string[] | null;
270
+ failure_reason_code: string | null;
271
+ failure_reason_detail: string | null;
272
+ failure_retryable: boolean;
264
273
  created_at: string;
265
274
  updated_at: string;
266
275
  }>;
@@ -292,6 +301,9 @@ export declare class TokenizationResource extends Resource {
292
301
  raw_contract: string | null;
293
302
  raw_function: string | null;
294
303
  raw_args: string[] | null;
304
+ failure_reason_code: string | null;
305
+ failure_reason_detail: string | null;
306
+ failure_retryable: boolean;
295
307
  created_at: string;
296
308
  updated_at: string;
297
309
  }>;
@@ -323,6 +335,9 @@ export declare class TokenizationResource extends Resource {
323
335
  raw_contract: string | null;
324
336
  raw_function: string | null;
325
337
  raw_args: string[] | null;
338
+ failure_reason_code: string | null;
339
+ failure_reason_detail: string | null;
340
+ failure_retryable: boolean;
326
341
  created_at: string;
327
342
  updated_at: string;
328
343
  }>;
@@ -16,6 +16,7 @@ export declare class WalletsResource extends Resource {
16
16
  updated_at: import("../generated/types.js").components["schemas"]["TimestampUtc"];
17
17
  }>;
18
18
  balance(id: string, query: Query<'getWalletBalance'>): Promise<{
19
+ data_freshness: import("../generated/types.js").components["schemas"]["DataFreshness"][];
19
20
  chain_id: number;
20
21
  wallet: string;
21
22
  token: string;
@@ -34,6 +35,7 @@ export declare class WalletsResource extends Resource {
34
35
  has_more: boolean;
35
36
  } & {
36
37
  data?: import("../generated/types.js").components["schemas"]["LedgerEntry"][];
38
+ data_freshness: import("../generated/types.js").components["schemas"]["DataFreshness"][];
37
39
  }>;
38
40
  decommission(id: string, opts?: XKOVAMutationOptions): Promise<{
39
41
  id: import("../generated/types.js").components["schemas"]["WalletId"];
@@ -0,0 +1,116 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';
3
+
4
+ /** Install pg separately. The application owns the pool, schema, retention and key rotation. */
5
+ export class PostgresCheckpointStore {
6
+ #context = new AsyncLocalStorage();
7
+ #key;
8
+
9
+ constructor(pool, namespace, encryptionKey) {
10
+ if (!/^[a-z][a-z0-9_-]{0,63}$/.test(namespace)) throw new Error('Invalid store namespace');
11
+ if (!Buffer.isBuffer(encryptionKey) || encryptionKey.length !== 32)
12
+ throw new Error('A 32-byte application encryption key is required');
13
+ this.pool = pool;
14
+ this.namespace = namespace;
15
+ this.#key = Buffer.from(encryptionKey);
16
+ }
17
+
18
+ #binding(reference) {
19
+ return JSON.stringify([this.namespace, reference]);
20
+ }
21
+
22
+ #encrypt(reference, record) {
23
+ const iv = randomBytes(12);
24
+ const cipher = createCipheriv('aes-256-gcm', this.#key, iv);
25
+ cipher.setAAD(Buffer.from(this.#binding(reference)));
26
+ const bytes = Buffer.concat([cipher.update(JSON.stringify(record), 'utf8'), cipher.final()]);
27
+ return Buffer.concat([iv, cipher.getAuthTag(), bytes]);
28
+ }
29
+
30
+ #decrypt(reference, bytes) {
31
+ if (!Buffer.isBuffer(bytes) || bytes.length < 29) throw new Error('Invalid stored envelope');
32
+ const decipher = createDecipheriv('aes-256-gcm', this.#key, bytes.subarray(0, 12));
33
+ decipher.setAAD(Buffer.from(this.#binding(reference)));
34
+ decipher.setAuthTag(bytes.subarray(12, 28));
35
+ return JSON.parse(
36
+ Buffer.concat([decipher.update(bytes.subarray(28)), decipher.final()]).toString('utf8'),
37
+ );
38
+ }
39
+
40
+ #db() {
41
+ return this.#context.getStore()?.client ?? this.pool;
42
+ }
43
+
44
+ async put(reference, record) {
45
+ await this.#db().query(
46
+ 'INSERT INTO xkova_helper_checkpoints(namespace, reference, envelope, expires_at) VALUES ($1,$2,$3,$4)',
47
+ [this.namespace, reference, this.#encrypt(reference, record), this.#expiry(record)],
48
+ );
49
+ }
50
+
51
+ async get(reference) {
52
+ const result = await this.#db().query(
53
+ 'SELECT envelope FROM xkova_helper_checkpoints WHERE namespace=$1 AND reference=$2 AND expires_at > now()',
54
+ [this.namespace, reference],
55
+ );
56
+ return result.rowCount ? this.#decrypt(reference, result.rows[0].envelope) : null;
57
+ }
58
+
59
+ async replace(reference, record) {
60
+ const result = await this.#db().query(
61
+ 'UPDATE xkova_helper_checkpoints SET envelope=$3, expires_at=$4 WHERE namespace=$1 AND reference=$2',
62
+ [this.namespace, reference, this.#encrypt(reference, record), this.#expiry(record)],
63
+ );
64
+ if (result.rowCount !== 1) throw new Error('Cannot replace a missing checkpoint');
65
+ }
66
+
67
+ async delete(reference) {
68
+ await this.#db().query(
69
+ 'DELETE FROM xkova_helper_checkpoints WHERE namespace=$1 AND reference=$2',
70
+ [this.namespace, reference],
71
+ );
72
+ }
73
+
74
+ #expiry(record) {
75
+ const value = record.applicationExpiresAt ?? record.expiresAt;
76
+ if (!Number.isSafeInteger(value)) throw new Error('Invalid checkpoint expiry');
77
+ return new Date(value);
78
+ }
79
+
80
+ /** A session lock, with separate autocommit checkpoints, never an outer SQL transaction. */
81
+ async runExclusive(reference, work) {
82
+ const existing = this.#context.getStore();
83
+ if (existing) {
84
+ if (existing.reference !== reference) throw new Error('Nested references are unsupported');
85
+ return work();
86
+ }
87
+ const client = await this.pool.connect();
88
+ let locked = false;
89
+ let discard = false;
90
+ try {
91
+ await client.query("SET lock_timeout = '5s'");
92
+ await client.query("SET statement_timeout = '10s'");
93
+ await client.query('SELECT pg_advisory_lock(hashtextextended($1, 0))', [
94
+ this.#binding(reference),
95
+ ]);
96
+ locked = true;
97
+ return await this.#context.run({ client, reference }, work);
98
+ } finally {
99
+ try {
100
+ if (locked) {
101
+ const result = await client.query(
102
+ 'SELECT pg_advisory_unlock(hashtextextended($1, 0)) AS released',
103
+ [this.#binding(reference)],
104
+ );
105
+ if (result.rows[0]?.released !== true) throw new Error('Checkpoint lock was lost');
106
+ }
107
+ await client.query('RESET lock_timeout');
108
+ await client.query('RESET statement_timeout');
109
+ } catch {
110
+ // A connection with an uncertain lock must never return to the pool.
111
+ discard = true;
112
+ }
113
+ client.release(discard);
114
+ }
115
+ }
116
+ }
@@ -0,0 +1,9 @@
1
+ -- Apply through your application's normal migration process, to its own database.
2
+ CREATE TABLE xkova_helper_checkpoints (
3
+ namespace text NOT NULL,
4
+ reference text NOT NULL,
5
+ envelope bytea NOT NULL,
6
+ expires_at timestamptz NOT NULL,
7
+ PRIMARY KEY (namespace, reference)
8
+ );
9
+ CREATE INDEX xkova_helper_checkpoints_expiry ON xkova_helper_checkpoints (expires_at);
package/llms.txt CHANGED
@@ -10,7 +10,7 @@ Use this package on a Node.js 22+ server. Read the installed declarations before
10
10
  - `dist/member-bff.d.ts`: authorization, session persistence, refresh, logout, action reviews, and human authorization.
11
11
  - `dist/member-resources.d.ts`: typed resources bound to the exact authenticated member.
12
12
  - [Quickstart](https://docs.xkova.com/getting-started.html): sandbox access and first authenticated call.
13
- - [Customer OpenAPI](https://github.com/XKOVA/typescript-sdk/blob/main/schema/customer-api.json): customer contract in this source repository. Installed declarations determine your release’s exact request and response types.
13
+ - [Customer OpenAPI](https://github.com/XKOVA/typescript-sdk/blob/main/schema/customer-api.json): machine-readable contract for the public SDK source. For an installed release, use its generated declarations.
14
14
  - [SDK guide](https://docs.xkova.com/sdk-overview.html): client and resource examples.
15
15
  - [Workflow guide](https://docs.xkova.com/sdk-workflows.html): supported workflow helpers.
16
16
  - [Member integration](https://docs.xkova.com/embedded-member.html): browser, BFF, identity, and signing boundaries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xkova/sdk",
3
- "version": "0.1.0-alpha.5",
3
+ "version": "0.1.0-alpha.7",
4
4
  "description": "TypeScript SDK for the XKOVA API.",
5
5
  "homepage": "https://docs.xkova.com",
6
6
  "repository": {
@@ -46,7 +46,8 @@
46
46
  },
47
47
  "files": [
48
48
  "dist",
49
- "llms.txt"
49
+ "llms.txt",
50
+ "examples"
50
51
  ],
51
52
  "dependencies": {
52
53
  "viem": "^2.21.0"