@xkova/sdk 0.1.0-alpha.1 → 0.1.0-alpha.10

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.
Files changed (51) hide show
  1. package/README.md +324 -32
  2. package/dist/abi.d.ts +40 -0
  3. package/dist/abi.js +25 -0
  4. package/dist/client.d.ts +4 -0
  5. package/dist/client.js +62 -3
  6. package/dist/generated/types.d.ts +8629 -5182
  7. package/dist/held-approval.d.ts +41 -0
  8. package/dist/held-approval.js +33 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.js +1 -0
  11. package/dist/member-action-intents.js +2 -2
  12. package/dist/member-bff.d.ts +60 -21
  13. package/dist/member-bff.js +81 -79
  14. package/dist/member-resources.d.ts +67 -1
  15. package/dist/member-resources.js +9 -5
  16. package/dist/request-signing.js +6 -0
  17. package/dist/resources/account-holders.d.ts +131 -1
  18. package/dist/resources/account-holders.js +44 -9
  19. package/dist/resources/branding.d.ts +10 -0
  20. package/dist/resources/branding.js +2 -0
  21. package/dist/resources/contacts.d.ts +2 -2
  22. package/dist/resources/contacts.js +3 -3
  23. package/dist/resources/escrows.d.ts +3 -0
  24. package/dist/resources/payment-requests.d.ts +4 -0
  25. package/dist/resources/payments.d.ts +13 -0
  26. package/dist/resources/payments.js +7 -0
  27. package/dist/resources/ramps.d.ts +73 -64
  28. package/dist/resources/ramps.js +2 -2
  29. package/dist/resources/rwa.d.ts +9 -9
  30. package/dist/resources/tenant.d.ts +15 -0
  31. package/dist/resources/tenant.js +6 -1
  32. package/dist/resources/tokenization.d.ts +30 -11
  33. package/dist/resources/tokenization.js +10 -10
  34. package/dist/resources/treasury.d.ts +404 -0
  35. package/dist/resources/treasury.js +115 -0
  36. package/dist/resources/wallets.d.ts +2 -0
  37. package/dist/resources/webhooks.d.ts +1 -1
  38. package/dist/resources/webhooks.js +2 -2
  39. package/dist/resources/workflows.d.ts +7 -6
  40. package/dist/resources/workflows.js +87 -24
  41. package/dist/resources/workforce-wallets.d.ts +34 -0
  42. package/dist/resources/workforce-wallets.js +19 -0
  43. package/dist/url.d.ts +1 -0
  44. package/dist/url.js +4 -0
  45. package/dist/webhook.js +1 -1
  46. package/dist/workforce-bff.d.ts +202 -0
  47. package/dist/workforce-bff.js +462 -0
  48. package/examples/postgres-checkpoint-store.mjs +116 -0
  49. package/examples/postgres-checkpoints.sql +9 -0
  50. package/llms.txt +29 -9
  51. package/package.json +8 -3
package/dist/client.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { XKOVAApiError } from './errors.js';
2
+ import { isAllowedProtocol } from './url.js';
2
3
  import { generateIdempotencyKey } from './idempotency.js';
3
4
  import { signXKOVARequest, validateXKOVARequestSigner, xkovaContentDigest, } from './request-signing.js';
4
5
  import { AccountHoldersResource, } from './resources/account-holders.js';
@@ -15,6 +16,7 @@ import { RampsResource } from './resources/ramps.js';
15
16
  import { RwaResource } from './resources/rwa.js';
16
17
  import { TenantResource } from './resources/tenant.js';
17
18
  import { TokenizationResource } from './resources/tokenization.js';
19
+ import { TreasuryResource } from './resources/treasury.js';
18
20
  import { TransactionsResource } from './resources/transactions.js';
19
21
  import { WalletsResource } from './resources/wallets.js';
20
22
  import { WebhooksResource } from './resources/webhooks.js';
@@ -24,11 +26,13 @@ import { WorkspacesResource } from './resources/workspaces.js';
24
26
  export class XKOVAClient {
25
27
  config;
26
28
  memberContext;
29
+ workforceContext;
27
30
  apiBaseUrl;
28
31
  fetchImpl;
29
- constructor(config, memberContext) {
32
+ constructor(config, memberContext, workforceContext) {
30
33
  this.config = config;
31
34
  this.memberContext = memberContext;
35
+ this.workforceContext = workforceContext;
32
36
  if (config.timeoutMs !== undefined &&
33
37
  (!Number.isFinite(config.timeoutMs) || config.timeoutMs <= 0)) {
34
38
  throw new Error('XKOVAClient timeoutMs must be a positive finite number');
@@ -82,6 +86,10 @@ export class XKOVAClient {
82
86
  get tokenization() {
83
87
  return (this.namespaces.tokenization ??= new TokenizationResource(this));
84
88
  }
89
+ /** Tenant treasury operations retain server-side roles, governance and signer checks. */
90
+ get treasury() {
91
+ return (this.namespaces.treasury ??= new TreasuryResource(this));
92
+ }
85
93
  get transactions() {
86
94
  return (this.namespaces.transactions ??= new TransactionsResource(this));
87
95
  }
@@ -107,6 +115,20 @@ export class XKOVAClient {
107
115
  static forMemberSession(options, context) {
108
116
  return new XKOVAClient(options, Object.freeze({ ...context }));
109
117
  }
118
+ /** @internal Created only after the workforce BFF resolves its confidential store. */
119
+ static forWorkforceSession(options, context) {
120
+ if (!/^xkova_wf_[A-Za-z0-9_-]{43}$/.test(context.workforceKey) ||
121
+ !/^xwfs_[A-Za-z0-9_-]{43}$/.test(context.sessionToken) ||
122
+ (context.humanAuthorization !== undefined &&
123
+ !/^[A-Za-z0-9_-]{43}$/.test(context.humanAuthorization))) {
124
+ throw new TypeError('Invalid workforce session material');
125
+ }
126
+ const origin = new URL(context.browserOrigin);
127
+ if (origin.origin !== context.browserOrigin || !isAllowedProtocol(origin)) {
128
+ throw new TypeError('Invalid workforce application origin');
129
+ }
130
+ return new XKOVAClient(options, undefined, Object.freeze({ ...context }));
131
+ }
110
132
  /** @internal Resource transport. Use typed namespaces instead. */
111
133
  async requestJson(options) {
112
134
  const prepared = await this.prepareRequest(options);
@@ -210,6 +232,9 @@ export class XKOVAClient {
210
232
  headers.set(name, value);
211
233
  }
212
234
  if (this.memberContext) {
235
+ if (headers.has('X-Workforce-Session') || headers.has('X-XKOVA-Workforce-Key')) {
236
+ throw new TypeError('Member and workforce authority cannot be combined');
237
+ }
213
238
  const authority = {
214
239
  Authorization: `Bearer ${this.config.apiKey}`,
215
240
  'X-Member-Session-Id': this.memberContext.memberSessionId,
@@ -223,6 +248,40 @@ export class XKOVAClient {
223
248
  headers.set(name, value);
224
249
  }
225
250
  }
251
+ if (this.workforceContext) {
252
+ if (headers.has('X-XKOVA-Human-Authorization') && !this.workforceContext.humanAuthorization) {
253
+ throw new TypeError('A workforce action grant must come from the confidential context');
254
+ }
255
+ for (const name of [
256
+ 'Cookie',
257
+ 'X-Member-Session-Id',
258
+ 'X-XKOVA-Publishable-Key',
259
+ 'X-Account-Holder-Id',
260
+ 'X-End-User-Id',
261
+ 'X-OIDC-ID-Token',
262
+ 'X-Active-Scope',
263
+ 'X-Workspace-Id',
264
+ 'X-Workspace-Type',
265
+ ]) {
266
+ if (headers.has(name))
267
+ throw new TypeError('A workforce operation cannot mix identity or workspace contexts');
268
+ }
269
+ const authority = {
270
+ Authorization: `Bearer ${this.config.apiKey}`,
271
+ 'X-XKOVA-Workforce-Key': this.workforceContext.workforceKey,
272
+ 'X-Workforce-Session': this.workforceContext.sessionToken,
273
+ Origin: this.workforceContext.browserOrigin,
274
+ ...(this.workforceContext.humanAuthorization !== undefined && {
275
+ 'X-XKOVA-Human-Authorization': this.workforceContext.humanAuthorization,
276
+ }),
277
+ };
278
+ for (const [name, value] of Object.entries(authority)) {
279
+ if (headers.has(name) && headers.get(name) !== value) {
280
+ throw new TypeError('A workforce-bound operation cannot replace its session authority');
281
+ }
282
+ headers.set(name, value);
283
+ }
284
+ }
226
285
  return headers;
227
286
  }
228
287
  requestSignal(signal) {
@@ -240,8 +299,8 @@ function normalizeApiBaseUrl(baseUrl) {
240
299
  if (url.username || url.password || url.search || url.hash) {
241
300
  throw new TypeError('XKOVA SDK baseUrl must be an API origin or /v1 base URL');
242
301
  }
243
- if (url.protocol !== 'https:' && !(url.protocol === 'http:' && url.hostname === 'localhost')) {
244
- throw new TypeError('XKOVA SDK baseUrl must use HTTPS or localhost HTTP');
302
+ if (!isAllowedProtocol(url)) {
303
+ throw new TypeError('XKOVA SDK baseUrl must use HTTPS or loopback HTTP');
245
304
  }
246
305
  const pathname = url.pathname.replace(/\/+$/, '');
247
306
  if (pathname !== '' && pathname !== '/v1') {