@capxul/sdk 1.2.2 → 2.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 CHANGED
@@ -19,32 +19,30 @@ const client = created.value;
19
19
  Every public operation resolves a `Promise<CapxulResult<T>>`. Domain failures
20
20
  are values, not thrown exceptions.
21
21
 
22
- ## Engineering telemetry
22
+ ## Observability
23
23
 
24
- Production hosts can opt into sanitized Effect logs and traces through the
25
- public client input:
24
+ Hosts can attach the PostHog client they already initialized through one
25
+ product-and-failure module:
26
26
 
27
27
  ```ts
28
+ import { postHogObservability } from "@capxul/sdk";
29
+
28
30
  const created = await createCapxulClient({
29
31
  publishableKey: "cap_pk_…",
30
- engineeringTelemetry: {
31
- host: "https://us.i.posthog.com",
32
- headers: { Authorization: "Bearer phc_…" },
32
+ observability: postHogObservability(posthog, {
33
33
  capxulEnv: "production",
34
- serviceName: "capxul-sdk",
35
- },
34
+ context: () => ({ correlationId, journeyId, organizationId }),
35
+ }),
36
36
  });
37
37
  ```
38
38
 
39
- Use the browser-safe PostHog project token (`phc_...`), never a personal API
40
- key (`phx_...`) or another secret. The host URL must be a credential-free HTTPS
41
- origin; credentials belong only in the explicit header. The SDK supplies its
42
- runtime producer and version, permits only closed identity classifications and
43
- safe correlation identifiers, and excludes email, OTP, auth/session tokens,
44
- wallet data, request/response bodies, provider messages, raw causes, and
45
- stacks. Export is best-effort and cannot change the operation result. An OTLP
46
- HTTP 200 is not delivery proof: verify a live run by querying both PostHog
47
- `logs` and `posthog.trace_spans` for the same fresh trace.
39
+ The SDK initializes no analytics client and preserves host consent. Product
40
+ events and sanitized failures share one enable/context/delivery policy.
41
+ Engineering logs and traces are separate internally, but applications do not
42
+ configure them: the versioned bootstrap response optionally supplies the
43
+ governed PostHog ingest origin, public project token, and environment. The SDK
44
+ derives endpoints, service, producer, and version. Missing or invalid policy
45
+ disables engineering export without failing client creation.
48
46
 
49
47
  Onboarding uses explicit domain objects. Personal completion accepts
50
48
  `{ profile }`; Organization completion accepts independently validated
@@ -60,7 +58,8 @@ Public Profile reads include the durable `onboarded` flag and optional
60
58
  The packed npm package exposes only:
61
59
 
62
60
  - `@capxul/sdk` — the client factory, public method and value types, signers,
63
- and observation helpers.
61
+ host observability helper, and immutable Base Sepolia Payment contract
62
+ identity.
64
63
  - `@capxul/sdk/node` — Node-only signer and runtime helpers.
65
64
  - `@capxul/sdk/testing` — the real identity runtime assembled over
66
65
  deterministic in-memory ports, with OTP, advance-only clock, transition,
@@ -96,8 +95,8 @@ The testing entry is identity-scoped and hermetic. Fine-grained
96
95
  evidence, and update triggers.
97
96
  - [Architecture](./docs/architecture.md) — client assembly, flows, ports,
98
97
  adapters, and proof map.
99
- - [Observation](./docs/observation.md) — host-owned failure observation and
100
- bounded backend linkage.
98
+ - [Observation](./docs/observation.md) — unified host observability,
99
+ bootstrap-owned engineering policy, and bounded backend linkage.
101
100
  - [Public SDK documentation](../../apps/docs/content/docs/sdk/index.mdx) —
102
101
  tutorials, guides, reference, and explanation for npm consumers.
103
102
 
@@ -8,6 +8,7 @@ const CAPXUL_ERROR_CODES = [
8
8
  "PLAYER_NOT_FOUND",
9
9
  "ACCOUNT_NOT_FOUND",
10
10
  "PROVIDER_ERROR",
11
+ "CAPABILITY_UNAVAILABLE",
11
12
  "INVALID_INPUT",
12
13
  "ENV_MISSING",
13
14
  "NOT_IMPLEMENTED",
@@ -46,6 +47,7 @@ const EXPECTED_OPERATION_OUTCOMES = new Set([
46
47
  "INSUFFICIENT_BALANCE",
47
48
  "INVALID_RECIPIENT",
48
49
  "ROLE_PERMISSION_DENIED",
50
+ "CAPABILITY_UNAVAILABLE",
49
51
  "RATE_LIMITED",
50
52
  "OTP_EXPIRED",
51
53
  "WRONG_STATE",
@@ -103,6 +105,10 @@ const Errors = {
103
105
  details
104
106
  });
105
107
  },
108
+ capabilityUnavailable: (provider, operation) => new CapxulError("CAPABILITY_UNAVAILABLE", "Provider capability is unavailable", { details: {
109
+ provider,
110
+ operation
111
+ } }),
106
112
  invalidInput: (field, reason) => new CapxulError("INVALID_INPUT", `Invalid ${field}: ${reason}`, { details: {
107
113
  field,
108
114
  reason
@@ -227,6 +233,7 @@ function decodeConvexError(err) {
227
233
  //#region ../types/src/index.ts
228
234
  const EVM_ADDRESS_RE = /^0x[0-9a-f]{40}$/i;
229
235
  const BYTES32_RE = /^0x[0-9a-f]{64}$/i;
236
+ const ZERO_BYTES32 = `0x${"0".repeat(64)}`;
230
237
  const PUBLISHABLE_KEY_PATTERN = /^cap_pk_(test|live)_[0-9A-HJKMNP-TV-Z]{32}$/;
231
238
  const SUPPORTED_CURRENCIES = [
232
239
  {
@@ -260,8 +267,8 @@ Object.fromEntries(SUPPORTED_CURRENCIES.map((currency) => [currency.code, curren
260
267
  const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
261
268
  const COUNTRY_CODE_RE = /^[A-Z]{2}$/;
262
269
  const ACCOUNT_ID_RE = /^account_[0-9A-Za-z]+$/;
263
- const SUBACCOUNT_ID_RE = /^subaccount_[0-9A-Za-z]+$/;
264
270
  const APP_ID_RE = /^app_[0-7][0-9A-HJKMNP-TV-Z]{25}$/;
271
+ const WEI_RE = /^[0-9]+$/;
265
272
  Math.floor(Number.MAX_SAFE_INTEGER / 1e3);
266
273
  function toAddress(raw) {
267
274
  if (typeof raw !== "string" || !EVM_ADDRESS_RE.test(raw)) throw Errors.invalidInput("address", invalidValueReason("invalid EVM address format", raw));
@@ -278,10 +285,6 @@ function toAccountId(raw) {
278
285
  if (typeof raw !== "string" || !ACCOUNT_ID_RE.test(raw)) throw Errors.invalidInput("accountId", invalidValueReason("must be account_ plus an alphanumeric id", raw));
279
286
  return raw;
280
287
  }
281
- function toSubAccountId(raw) {
282
- if (typeof raw !== "string" || !SUBACCOUNT_ID_RE.test(raw)) throw Errors.invalidInput("subAccountId", invalidValueReason("must be subaccount_ plus an alphanumeric id", raw));
283
- return raw;
284
- }
285
288
  function toOrgId(raw) {
286
289
  return toNonEmptyStringBrand(raw, "orgId");
287
290
  }
@@ -472,6 +475,4 @@ Layer.effect(AuthCachePortTag, Effect.sync(() => new InMemoryAuthCacheAdapter())
472
475
  cause
473
476
  }))));
474
477
  //#endregion
475
- export { decodeConvexError as A, toJwtToken as C, toRoleKey as D, toPublishableKey as E, EXPECTED_OPERATION_OUTCOMES as M, Errors as N, toSessionToken as O, isCapxulError as P, toEpochSeconds as S, toOrgId as T, toCountryCode as _, AuthCacheError as a, toEmail as b, BYTES32_RE as c, toAccountId as d, toAddress as f, toChainId as g, toAuthUserId as h, parseCachedJwt as i, CapxulError as j, toSubAccountId as k, EVM_ADDRESS_RE as l, toAppId as m, BrowserAuthCacheAdapter as n, AuthCachePortTag as o, toAllowedOrigin as p, parseAuthSession as r, APP_ID_RE as s, InMemoryAuthCacheAdapter as t, SUPPORTED_CURRENCY_CODES as u, toCurrencyCode as v, toKycTier as w, toEpochMs as x, toDurationMs as y };
476
-
477
- //# sourceMappingURL=InMemoryAuthCacheAdapter-Dr1sEd9y.mjs.map
478
+ export { toSessionToken as A, toEpochMs as C, toOrgId as D, toKycTier as E, isCapxulError as F, CapxulError as M, EXPECTED_OPERATION_OUTCOMES as N, toPublishableKey as O, Errors as P, toEmail as S, toJwtToken as T, toAuthUserId as _, AuthCacheError as a, toCurrencyCode as b, BYTES32_RE as c, WEI_RE as d, ZERO_BYTES32 as f, toAppId as g, toAllowedOrigin as h, parseCachedJwt as i, decodeConvexError as j, toRoleKey as k, EVM_ADDRESS_RE as l, toAddress as m, BrowserAuthCacheAdapter as n, AuthCachePortTag as o, toAccountId as p, parseAuthSession as r, APP_ID_RE as s, InMemoryAuthCacheAdapter as t, SUPPORTED_CURRENCY_CODES as u, toChainId as v, toEpochSeconds as w, toDurationMs as x, toCountryCode as y };