@xkova/sdk 0.1.0-alpha.2 → 0.1.0-alpha.4
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 +114 -27
- package/dist/client.js +3 -2
- package/dist/generated/types.d.ts +526 -327
- package/dist/member-action-intents.js +2 -2
- package/dist/member-bff.d.ts +0 -16
- package/dist/member-bff.js +10 -70
- package/dist/member-resources.d.ts +50 -0
- package/dist/member-resources.js +3 -0
- package/dist/resources/account-holders.d.ts +24 -0
- package/dist/resources/account-holders.js +8 -2
- package/dist/resources/payments.d.ts +13 -0
- package/dist/resources/payments.js +7 -0
- package/dist/resources/ramps.d.ts +72 -63
- package/dist/resources/rwa.d.ts +9 -9
- package/dist/url.d.ts +1 -0
- package/dist/url.js +4 -0
- package/llms.txt +20 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ holders, wallets, payments, tokenization, and other customer resources.
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
|
-
npm install @xkova/sdk@
|
|
9
|
+
npm install @xkova/sdk@alpha
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
Requires Node.js 22 or newer. Keep this package and your API keys on the server.
|
|
@@ -197,26 +197,17 @@ For your own OIDC provider, use `beginAuthorization` and
|
|
|
197
197
|
code unless your integration explicitly assigns that exchange to XKOVA. Both
|
|
198
198
|
sign-in paths use the same XKOVA session and store contracts.
|
|
199
199
|
|
|
200
|
-
###
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
`
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
Keep the same pending reservation and transaction after an ambiguous admission
|
|
213
|
-
failure. Repeating the method uses the same idempotency key and recovers the
|
|
214
|
-
same demo account reservation. The method never retries automatically.
|
|
215
|
-
`isDefinitiveXKOVASandboxDemoAdmissionFailure(error)` identifies confirmed
|
|
216
|
-
rejection before an account was reserved; network, malformed-response, and
|
|
217
|
-
unknown server failures can leave the reservation outcome uncertain.
|
|
218
|
-
API errors retain their status, correlation ID, and Retry-After. Both admission
|
|
219
|
-
and session requests reject HTTP redirects.
|
|
200
|
+
### Local development
|
|
201
|
+
|
|
202
|
+
The SDK accepts HTTP API URLs, browser origins, callbacks, and storage URLs on
|
|
203
|
+
`localhost` and `127.0.0.1`. Remote hosts require HTTPS. Register each origin
|
|
204
|
+
and callback with its exact scheme, host, port, and path. These two local hosts
|
|
205
|
+
are distinct origins; cookies and browser storage are not shared between them.
|
|
206
|
+
|
|
207
|
+
For local passkeys, serve the authentication page on `localhost` and use
|
|
208
|
+
`localhost` as its relying-party ID. An IP address cannot be a passkey
|
|
209
|
+
relying-party ID. Keep API keys and member sessions in your BFF, including
|
|
210
|
+
during local development.
|
|
220
211
|
|
|
221
212
|
### Stores and callback recovery
|
|
222
213
|
|
|
@@ -344,6 +335,10 @@ Business requests use `no-store` and reject redirects so credentials cannot
|
|
|
344
335
|
follow a redirect. Network failures preserve the application session. Reuse the
|
|
345
336
|
original idempotency key when reconciling an uncertain write.
|
|
346
337
|
|
|
338
|
+
`resolved.resources.self.profile()` returns the current member's profile,
|
|
339
|
+
including email and name. These fields are display metadata, not authentication
|
|
340
|
+
proof. Read the profile when displaying it instead of caching it in the session.
|
|
341
|
+
|
|
347
342
|
`resolved.resources.self.verification()` returns the member's verification
|
|
348
343
|
requirements and sessions through the public self-verification operation.
|
|
349
344
|
`resolved.resources.self.uploadAvatar(image)` performs presign, object upload,
|
|
@@ -351,7 +346,7 @@ confirmation, and refreshed avatar lookup. Pass a nonempty PNG, JPEG, WebP, or G
|
|
|
351
346
|
`Blob` of at most 5 MiB. Storage receives only the image bytes and their content
|
|
352
347
|
headers, never bearer credentials, request signatures, member context, or cookies.
|
|
353
348
|
The helper rejects redirects, expired capabilities, URL credentials, and non-HTTPS
|
|
354
|
-
storage URLs (localhost
|
|
349
|
+
storage URLs (HTTP on `localhost` or `127.0.0.1` is permitted for local development). It does not
|
|
355
350
|
retry an upload. `XKOVAUploadError` identifies the object-storage stage without
|
|
356
351
|
exposing the signed URL; API failures retain `XKOVAApiError` metadata.
|
|
357
352
|
|
|
@@ -371,7 +366,44 @@ Durable application cookies use the host-only `__Host-` prefix, `Secure`, `HttpO
|
|
|
371
366
|
|
|
372
367
|
The publishable key is a non-secret application registration identifier. It grants no member or tenant authority by itself. The registered application pins tenant, workspace, environment, provider kind, issuer, audience, origins, redirects, and session policy, and must also match the authenticated workspace principal.
|
|
373
368
|
|
|
374
|
-
|
|
369
|
+
### Recover an existing member payment
|
|
370
|
+
|
|
371
|
+
Read recovery state through the resolved member resources:
|
|
372
|
+
|
|
373
|
+
```ts
|
|
374
|
+
const recovery = await resolved.resources.payments.recovery(paymentId);
|
|
375
|
+
// Call only after the member confirms cancellation in your app.
|
|
376
|
+
if (recovery.can_cancel) {
|
|
377
|
+
await resolved.resources.payments.cancelForMember(paymentId);
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
The API permits reads by the sender or recipient. Only the sender can cancel
|
|
382
|
+
or continue. The API principal needs `payment.read` and `payment.cancel`
|
|
383
|
+
permissions for these operations. Your BFF must validate the session, exact
|
|
384
|
+
Origin, and CSRF token before cancellation. Cancellation does not require a
|
|
385
|
+
passkey because it sends no value.
|
|
386
|
+
|
|
387
|
+
When `can_continue` is true, use `beginMemberAction()` with
|
|
388
|
+
`resourceType: 'payment'`, the existing `resourceId`, and `action: 'sign'`.
|
|
389
|
+
Complete fresh authorization through the registered provider. Keep the original
|
|
390
|
+
amount, recipient, fees, and deadline. Do not create a second payment or reuse
|
|
391
|
+
an expired signing credential. Recovery uses the payment ID, so a new valid
|
|
392
|
+
session for the same member can recover it without the original form draft.
|
|
393
|
+
|
|
394
|
+
`approval_expired` means the signing window has closed. It remains cancellable
|
|
395
|
+
until a signature has been accepted. After acceptance, `processing` disables
|
|
396
|
+
both actions. `cancelled`, `completed`, and `failed` are separate outcomes;
|
|
397
|
+
retain all three in history. These actions apply to payments; escrow
|
|
398
|
+
cancellation has its own authorization and settlement rules.
|
|
399
|
+
|
|
400
|
+
Availability can change between a read and a click. After a conflict or an
|
|
401
|
+
uncertain cancellation response, read recovery state again. Repeating an
|
|
402
|
+
already completed member cancellation returns the cancelled payment. Aborting
|
|
403
|
+
an HTTP request or cancelling an authorization ceremony does not cancel the
|
|
404
|
+
payment.
|
|
405
|
+
|
|
406
|
+
## Request cancellation and deadlines
|
|
375
407
|
|
|
376
408
|
Set `timeoutMs` on the client for a default request deadline. Mutation options and workflow polling also accept an `AbortSignal`:
|
|
377
409
|
|
|
@@ -386,6 +418,33 @@ await xkova.payments.cancel('pay_...', {
|
|
|
386
418
|
|
|
387
419
|
The SDK does not automatically retry writes. Use `withRetry` with a stable idempotency key when retry behavior is appropriate for your application.
|
|
388
420
|
|
|
421
|
+
## Product enrollment
|
|
422
|
+
|
|
423
|
+
After a member accepts your displayed terms, call
|
|
424
|
+
`resources.self.acceptProductEnrollment(product, { terms_version })` from the
|
|
425
|
+
BFF. Select the product and terms version on your server. Read the saved result
|
|
426
|
+
with `resources.self.productEnrollment(product)` when the member returns.
|
|
427
|
+
Acceptance does not require an `Idempotency-Key` header. Repeating the same
|
|
428
|
+
acceptance preserves its timestamp. Changed terms or credit parameters with the
|
|
429
|
+
same product are rejected.
|
|
430
|
+
|
|
431
|
+
Sandbox applications can include `sandbox_credit: { token_deployment_id,
|
|
432
|
+
amount }` to issue a test-token welcome credit. Use an active dUSDC deployment.
|
|
433
|
+
The credit is issued once per member, workspace, and product, across application
|
|
434
|
+
registrations. The daily workspace budget is 1000 dUSDC. Keep amounts and token
|
|
435
|
+
selection in the BFF, and give each product a stable identifier.
|
|
436
|
+
|
|
437
|
+
For Hosted Auth, set `require_passkey: true` to hold activation and the credit
|
|
438
|
+
until the member has an active passkey and has acknowledged recovery codes.
|
|
439
|
+
`setup_required` means terms are saved and security setup remains incomplete.
|
|
440
|
+
Open Account Center with the `security` intent, then read the enrollment again
|
|
441
|
+
on return. The setup requirement is fixed when the enrollment is accepted.
|
|
442
|
+
|
|
443
|
+
Poll the enrollment after acceptance. `opening` means delivery is pending;
|
|
444
|
+
`active` means the credit has a successful receipt and an indexed balance.
|
|
445
|
+
`requires_review` needs operator investigation. Do not create another product
|
|
446
|
+
identifier to retry an uncertain credit. Credits do not debit bank accounts.
|
|
447
|
+
|
|
389
448
|
## Errors
|
|
390
449
|
|
|
391
450
|
`XKOVAApiError.retryAfter` preserves the upstream `Retry-After` header when
|
|
@@ -432,11 +491,39 @@ idempotency, and settlement. It links the public customer OpenAPI and expanded
|
|
|
432
491
|
documentation. Installed declarations determine the methods available in your
|
|
433
492
|
version; live documentation may describe a newer release.
|
|
434
493
|
|
|
435
|
-
##
|
|
494
|
+
## Writing checks for contributors
|
|
495
|
+
|
|
496
|
+
Use plain verbs, concrete examples, and comments that explain non-obvious
|
|
497
|
+
decisions. Vary section length, remove repeated conclusions, and write each
|
|
498
|
+
guide for its reader. Test failure and recovery cases alongside successful
|
|
499
|
+
calls. Keep commits small and omit attribution or co-author trailers.
|
|
500
|
+
|
|
501
|
+
The local pre-push hook checks both public SDKs before the existing test gates.
|
|
502
|
+
It reads each pushed branch or tag's committed files, plus new commit messages
|
|
503
|
+
that touch either package. Uncommitted edits cannot change that result. No
|
|
504
|
+
build or network access is needed. Use the repository's pinned Node version,
|
|
505
|
+
then install workspace dependencies with `pnpm install` to set up the hook.
|
|
506
|
+
|
|
507
|
+
To check edits before committing:
|
|
508
|
+
|
|
509
|
+
```sh
|
|
510
|
+
pnpm --filter @xkova/sdk writing:check
|
|
511
|
+
```
|
|
436
512
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
513
|
+
The check covers package guides, examples, public source and generated types,
|
|
514
|
+
and descriptive package metadata. It rejects stock wording, emoji, em dashes,
|
|
515
|
+
attribution, internal decision narratives, and implementation-provider details.
|
|
516
|
+
Describe installation, supported methods, inputs, results, and the steps an
|
|
517
|
+
application developer needs. Do not turn release planning or maintainer
|
|
518
|
+
conversations into package documentation. Standard license text, rule
|
|
519
|
+
definitions, and negative test fixtures are checked separately.
|
|
520
|
+
|
|
521
|
+
A pass is a mechanical check, not a judgment of authorship. Before pushing,
|
|
522
|
+
reread the result for sentence rhythm, repeated structures, useful comments,
|
|
523
|
+
accurate examples, and test quality. This gate does not scan historical file
|
|
524
|
+
contents or replace secret scanning. It checks commit messages locally;
|
|
525
|
+
review PR descriptions separately. Run `pnpm --filter @xkova/sdk writing:test`
|
|
526
|
+
when changing the rules or hook.
|
|
440
527
|
|
|
441
528
|
## License
|
|
442
529
|
|
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';
|
|
@@ -240,8 +241,8 @@ function normalizeApiBaseUrl(baseUrl) {
|
|
|
240
241
|
if (url.username || url.password || url.search || url.hash) {
|
|
241
242
|
throw new TypeError('XKOVA SDK baseUrl must be an API origin or /v1 base URL');
|
|
242
243
|
}
|
|
243
|
-
if (
|
|
244
|
-
throw new TypeError('XKOVA SDK baseUrl must use HTTPS or
|
|
244
|
+
if (!isAllowedProtocol(url)) {
|
|
245
|
+
throw new TypeError('XKOVA SDK baseUrl must use HTTPS or loopback HTTP');
|
|
245
246
|
}
|
|
246
247
|
const pathname = url.pathname.replace(/\/+$/, '');
|
|
247
248
|
if (pathname !== '' && pathname !== '/v1') {
|